Last active
January 7, 2024 14:11
-
-
Save MegaManSec/645a642a6149810a3a03 to your computer and use it in GitHub Desktop.
Teeworlds BBM Mod Trunk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -Naur Coding/teeworlds/src/banmaster/banmaster.cpp BBM/src/banmaster/banmaster.cpp | |
--- Coding/teeworlds/src/banmaster/banmaster.cpp 1970-01-01 10:00:00.000000000 +1000 | |
+++ BBM/src/banmaster/banmaster.cpp 2011-02-15 23:07:48.040565002 +1100 | |
@@ -0,0 +1,250 @@ | |
+/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ | |
+/* If you are missing that file, acquire a complete release at teeworlds.com. */ | |
+#include <base/system.h> | |
+#include <engine/shared/network.h> | |
+#include <engine/console.h> | |
+#include <engine/storage.h> | |
+ | |
+#include "banmaster.h" | |
+ | |
+enum | |
+{ | |
+ MAX_BANS=1024, | |
+ BAN_REREAD_TIME=300, | |
+ CFGFLAG_BANMASTER=16 | |
+}; | |
+ | |
+static const char BANMASTER_BANFILE[] = "bans.cfg"; | |
+ | |
+struct CBan | |
+{ | |
+ NETADDR m_Address; | |
+ char m_aReason[256]; | |
+ int64 m_Expire; | |
+}; | |
+ | |
+static CBan m_aBans[MAX_BANS]; | |
+static int m_NumBans = 0; | |
+static CNetClient m_Net; | |
+static IConsole *m_pConsole; | |
+static char m_aBindAddr[64] = ""; | |
+ | |
+CBan* CheckBan(NETADDR *pCheck) | |
+{ | |
+ for(int i = 0; i < m_NumBans; i++) | |
+ { | |
+ if(pCheck->ip[0] == m_aBans[i].m_Address.ip[0] && pCheck->ip[1] == m_aBans[i].m_Address.ip[1] && | |
+ pCheck->ip[2] == m_aBans[i].m_Address.ip[2] && pCheck->ip[3] == m_aBans[i].m_Address.ip[3]) | |
+ return &m_aBans[i]; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+int SendResponse(NETADDR *pAddr, NETADDR *pCheck) | |
+{ | |
+ static char aIpBan[sizeof(BANMASTER_IPBAN) + 32 + 256] = { 0 }; | |
+ static char *pIpBanContent = aIpBan + sizeof(BANMASTER_IPBAN); | |
+ if (!aIpBan[0]) | |
+ mem_copy(aIpBan, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)); | |
+ | |
+ static CNetChunk p; | |
+ | |
+ p.m_ClientID = -1; | |
+ p.m_Address = *pAddr; | |
+ p.m_Flags = NETSENDFLAG_CONNLESS; | |
+ | |
+ CBan* pBan = CheckBan(pCheck); | |
+ if(pBan) | |
+ { | |
+ str_format(pIpBanContent, 32, "%d.%d.%d.%d", pCheck->ip[0], pCheck->ip[1], pCheck->ip[2], pCheck->ip[3]); | |
+ char *pIpBanReason = pIpBanContent + (str_length(pIpBanContent) + 1); | |
+ str_copy(pIpBanReason, pBan->m_aReason, 256); | |
+ | |
+ p.m_pData = aIpBan; | |
+ p.m_DataSize = sizeof(BANMASTER_IPBAN) + str_length(pIpBanContent) + 1 + str_length(pIpBanReason) + 1; | |
+ m_Net.Send(&p); | |
+ return 1; | |
+ } | |
+ else | |
+ { | |
+ p.m_DataSize = sizeof(BANMASTER_IPOK); | |
+ p.m_pData = BANMASTER_IPOK; | |
+ m_Net.Send(&p); | |
+ return 0; | |
+ } | |
+} | |
+ | |
+void AddBan(NETADDR *pAddr, const char *pReason) | |
+{ | |
+ CBan *pBan = CheckBan(pAddr); | |
+ if(pBan) | |
+ { | |
+ dbg_msg("banmaster", "updated ban: %d.%d.%d.%d \'%s\' -> \'%s\'", | |
+ pAddr->ip[0], pAddr->ip[1], pAddr->ip[2], pAddr->ip[3], pBan->m_aReason, pReason); | |
+ | |
+ str_copy(pBan->m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); | |
+ pBan->m_Expire = -1; | |
+ } | |
+ else | |
+ { | |
+ if(m_NumBans == MAX_BANS) | |
+ { | |
+ dbg_msg("banmaster", "error: banmaster is full"); | |
+ return; | |
+ } | |
+ | |
+ m_aBans[m_NumBans].m_Address = *pAddr; | |
+ str_copy(m_aBans[m_NumBans].m_aReason, pReason, sizeof(m_aBans[m_NumBans].m_aReason)); | |
+ m_aBans[m_NumBans].m_Expire = -1; | |
+ | |
+ dbg_msg("banmaster", "added ban: %d.%d.%d.%d \'%s\'", | |
+ pAddr->ip[0], pAddr->ip[1], pAddr->ip[2], pAddr->ip[3], m_aBans[m_NumBans].m_aReason); | |
+ | |
+ m_NumBans++; | |
+ } | |
+} | |
+ | |
+void ClearBans() | |
+{ | |
+ dbg_msg("banmaster", "cleared bans"); | |
+ m_NumBans = 0; | |
+} | |
+ | |
+void PurgeBans() | |
+{ | |
+ int64 Now = time_get(); | |
+ int i = 0; | |
+ while(i < m_NumBans) | |
+ { | |
+ if(m_aBans[i].m_Expire != -1 && m_aBans[i].m_Expire < Now) | |
+ { | |
+ // remove ban | |
+ dbg_msg("banmaster", "expired: %d.%d.%d.%d \'%s\'", | |
+ m_aBans[i].m_Address.ip[0], m_aBans[i].m_Address.ip[1], | |
+ m_aBans[i].m_Address.ip[2], m_aBans[i].m_Address.ip[3], m_aBans[i].m_aReason); | |
+ m_aBans[i] = m_aBans[m_NumBans-1]; | |
+ m_NumBans--; | |
+ } | |
+ else | |
+ i++; | |
+ } | |
+} | |
+ | |
+void ConBan(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ NETADDR Addr; | |
+ const char *pStr = pResult->GetString(0); | |
+ const char *pReason = ""; | |
+ | |
+ if(pResult->NumArguments() > 1) | |
+ pReason = pResult->GetString(1); | |
+ | |
+ if(!net_addr_from_str(&Addr, pStr)) | |
+ AddBan(&Addr, pReason); | |
+ else | |
+ dbg_msg("banmaster", "invalid network address to ban"); | |
+} | |
+ | |
+void ConUnbanAll(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ ClearBans(); | |
+} | |
+ | |
+void ConSetBindAddr(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ if(m_aBindAddr[0]) | |
+ return; | |
+ str_copy(m_aBindAddr, pResult->GetString(0), sizeof(m_aBindAddr)); | |
+ dbg_msg("banmaster/network", "bound to %s", m_aBindAddr); | |
+} | |
+ | |
+void StandardOutput(const char *pLine, void *pUser) | |
+{ | |
+} | |
+ | |
+int main(int argc, const char **argv) // ignore_convention | |
+{ | |
+ int64 LastUpdate = time_get(); | |
+ | |
+ dbg_logger_stdout(); | |
+ net_init(); | |
+ | |
+ IKernel *pKernel = IKernel::Create(); | |
+ IStorage *pStorage = CreateStorage("Teeworlds", argc, argv); // ignore_convention | |
+ | |
+ m_pConsole = CreateConsole(CFGFLAG_BANMASTER); | |
+ m_pConsole->RegisterPrintCallback(StandardOutput, 0); | |
+ m_pConsole->Register("ban", "s?r", CFGFLAG_BANMASTER, ConBan, 0, "Bans the specified ip"); | |
+ m_pConsole->Register("unban_all", "", CFGFLAG_BANMASTER, ConUnbanAll, 0, "Unbans all ips"); | |
+ m_pConsole->Register("bind", "s", CFGFLAG_BANMASTER, ConSetBindAddr, 0, "Binds to the specified address"); | |
+ | |
+ { | |
+ bool RegisterFail = false; | |
+ | |
+ RegisterFail = RegisterFail || !pKernel->RegisterInterface(m_pConsole); | |
+ RegisterFail = RegisterFail || !pKernel->RegisterInterface(pStorage); | |
+ | |
+ if(RegisterFail) | |
+ return -1; | |
+ } | |
+ | |
+ m_pConsole->ExecuteFile(BANMASTER_BANFILE); | |
+ | |
+ NETADDR BindAddr; | |
+ if(m_aBindAddr[0] && net_host_lookup(m_aBindAddr, &BindAddr, NETTYPE_IPV4) == 0) | |
+ { | |
+ if(BindAddr.port == 0) | |
+ BindAddr.port = BANMASTER_PORT; | |
+ } | |
+ else | |
+ { | |
+ mem_zero(&BindAddr, sizeof(BindAddr)); | |
+ BindAddr.port = BANMASTER_PORT; | |
+ } | |
+ | |
+ m_Net.Open(BindAddr, 0); | |
+ // TODO: check socket for errors | |
+ | |
+ dbg_msg("banmaster", "started"); | |
+ | |
+ while(1) | |
+ { | |
+ m_Net.Update(); | |
+ | |
+ // process m_aPackets | |
+ CNetChunk p; | |
+ while(m_Net.Recv(&p)) | |
+ { | |
+ if(p.m_DataSize >= sizeof(BANMASTER_IPCHECK) && | |
+ !mem_comp(p.m_pData, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK))) | |
+ { | |
+ char *pAddr = (char*)p.m_pData + sizeof(BANMASTER_IPCHECK); | |
+ NETADDR CheckAddr; | |
+ if(net_addr_from_str(&CheckAddr, pAddr)) | |
+ { | |
+ dbg_msg("banmaster", "dropped weird message ip=%d.%d.%d.%d checkaddr='%s'", | |
+ p.m_Address.ip[0], p.m_Address.ip[1], p.m_Address.ip[2], p.m_Address.ip[3], pAddr); | |
+ } | |
+ else | |
+ { | |
+ int Banned = SendResponse(&p.m_Address, &CheckAddr); | |
+ dbg_msg("banmaster", "responded to checkmsg ip=%d.%d.%d.%d checkaddr=%d.%d.%d.%d result=%s", | |
+ p.m_Address.ip[0], p.m_Address.ip[1], p.m_Address.ip[2], p.m_Address.ip[3], | |
+ CheckAddr.ip[0], CheckAddr.ip[1], CheckAddr.ip[2], CheckAddr.ip[3], (Banned) ? "ban" : "ok"); | |
+ } | |
+ } | |
+ } | |
+ | |
+ if(time_get() - LastUpdate > time_freq() * BAN_REREAD_TIME) | |
+ { | |
+ ClearBans(); | |
+ LastUpdate = time_get(); | |
+ m_pConsole->ExecuteFile(BANMASTER_BANFILE); | |
+ } | |
+ | |
+ // be nice to the CPU | |
+ thread_sleep(1); | |
+ } | |
+ | |
+ return 0; | |
+} | |
diff -Naur Coding/teeworlds/src/banmaster/banmaster.h BBM/src/banmaster/banmaster.h | |
--- Coding/teeworlds/src/banmaster/banmaster.h 1970-01-01 10:00:00.000000000 +1000 | |
+++ BBM/src/banmaster/banmaster.h 2011-02-15 23:07:48.056565002 +1100 | |
@@ -0,0 +1,12 @@ | |
+/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ | |
+/* If you are missing that file, acquire a complete release at teeworlds.com. */ | |
+#ifndef BANMASTER_BANMASTER_H | |
+#define BANMASTER_BANMASTER_H | |
+ | |
+static const int BANMASTER_PORT = 8302; | |
+ | |
+static const char BANMASTER_IPOK[] = {255, 255, 255, 255, 'i', 'p', 'o', 'k'}; | |
+static const char BANMASTER_IPBAN[] = {255, 255, 255, 255, 'i', 'p', 'b', 'a'}; | |
+static const char BANMASTER_IPCHECK[] = {255, 255, 255, 255, 'i', 'p', 'c', 'h'}; | |
+ | |
+#endif | |
diff -Naur Coding/teeworlds/src/engine/client/client.cpp BBM/src/engine/client/client.cpp | |
--- Coding/teeworlds/src/engine/client/client.cpp 2011-02-17 07:36:24.859621001 +1100 | |
+++ BBM/src/engine/client/client.cpp 2011-02-14 01:19:12.675685001 +1100 | |
@@ -1709,15 +1709,6 @@ | |
ActionTaken = Now; | |
} | |
} | |
- else | |
- { | |
- if(Now > ActionTaken+time_freq()*(10+g_Config.m_DbgStress)) | |
- { | |
- m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "stress", "disconnecting!"); | |
- Disconnect(); | |
- ActionTaken = Now; | |
- } | |
- } | |
} | |
// pump the network | |
diff -Naur Coding/teeworlds/src/engine/server/server.cpp BBM/src/engine/server/server.cpp | |
--- Coding/teeworlds/src/engine/server/server.cpp 2011-02-17 07:36:24.867621001 +1100 | |
+++ BBM/src/engine/server/server.cpp 2011-02-15 23:07:48.076565002 +1100 | |
@@ -26,6 +26,8 @@ | |
#include <mastersrv/mastersrv.h> | |
+#include <banmaster/banmaster.h> | |
+ | |
#include "register.h" | |
#include "server.h" | |
@@ -35,6 +37,8 @@ | |
#include <windows.h> | |
#endif | |
+static const char SERVER_BANMASTERFILE[] = "banmasters.cfg"; | |
+ | |
static const char *StrLtrim(const char *pStr) | |
{ | |
while(*pStr && *pStr >= 0 && *pStr <= 32) | |
@@ -1001,6 +1005,33 @@ | |
{ | |
SendServerInfo(&Packet.m_Address, -1); | |
} | |
+ | |
+ if(Packet.m_DataSize >= sizeof(BANMASTER_IPOK) && | |
+ mem_comp(Packet.m_pData, BANMASTER_IPOK, sizeof(BANMASTER_IPOK)) == 0 && | |
+ m_NetServer.BanmasterCheck(&Packet.m_Address) != -1) | |
+ { | |
+ } | |
+ | |
+ if(Packet.m_DataSize >= sizeof(BANMASTER_IPBAN) && | |
+ mem_comp(Packet.m_pData, BANMASTER_IPBAN, sizeof(BANMASTER_IPBAN)) == 0 && | |
+ g_Config.m_SvGlobalBantime && | |
+ m_NetServer.BanmasterCheck(&Packet.m_Address) != -1) | |
+ { | |
+ CUnpacker Up; | |
+ char aIp[32]; | |
+ char aReason[256]; | |
+ NETADDR Addr; | |
+ Up.Reset((unsigned char*)Packet.m_pData + sizeof(BANMASTER_IPBAN), Packet.m_DataSize - sizeof(BANMASTER_IPBAN)); | |
+ str_copy(aIp, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aIp)); | |
+ str_copy(aReason, Up.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(aReason)); | |
+ if (net_addr_from_str(&Addr, aIp)) | |
+ { | |
+ dbg_msg("globalbans", "dropped weird message from banmaster"); | |
+ return; | |
+ } | |
+ m_NetServer.BanAdd(Addr, g_Config.m_SvGlobalBantime * 60, aReason); | |
+ dbg_msg("globalbans", "added ban, ip=%d.%d.%d.%d, reason=\"%s\"", Addr.ip[0], Addr.ip[1], Addr.ip[2], Addr.ip[3], aReason); | |
+ } | |
} | |
} | |
else | |
@@ -1112,7 +1143,9 @@ | |
} | |
m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this); | |
- | |
+ | |
+ Console()->ExecuteFile(SERVER_BANMASTERFILE); | |
+ | |
char aBuf[256]; | |
str_format(aBuf, sizeof(aBuf), "server name is '%s'", g_Config.m_SvName); | |
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); | |
@@ -1435,6 +1468,45 @@ | |
((CServer *)pUser)->m_MapReload = 1; | |
} | |
+void CServer::ConAddBanmaster(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ CServer *pServer = (CServer *)pUser; | |
+ | |
+ int Result = pServer->m_NetServer.BanmasterAdd(pResult->GetString(0)); | |
+ | |
+ if(Result == 0) | |
+ pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "succesfully added banmaster"); | |
+ else if (Result == 1) | |
+ pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "invalid address for banmaster / net lookup failed"); | |
+ else | |
+ pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "too many banmasters"); | |
+} | |
+ | |
+void CServer::ConBanmasters(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ CServer *pServer = (CServer *)pUser; | |
+ int NumBanmasters = pServer->m_NetServer.BanmasterNum(); | |
+ | |
+ char aBuf[128]; | |
+ char aIpString[64]; | |
+ | |
+ for(int i = 0; i < NumBanmasters; i++) | |
+ { | |
+ NETADDR *pBanmaster = pServer->m_NetServer.BanmasterGet(i); | |
+ net_addr_str(pBanmaster, aIpString, sizeof(aIpString)); | |
+ str_format(aBuf, sizeof(aBuf), "%d: %s", i, aIpString); | |
+ pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", aBuf); | |
+ } | |
+} | |
+ | |
+void CServer::ConClearBanmasters(IConsole::IResult *pResult, void *pUser) | |
+{ | |
+ CServer *pServer = (CServer *)pUser; | |
+ | |
+ pServer->m_NetServer.BanmastersClear(); | |
+ pServer->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server/banmaster", "cleared banmaster list"); | |
+} | |
+ | |
void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData) | |
{ | |
pfnCallback(pResult, pCallbackUserData); | |
@@ -1462,13 +1534,19 @@ | |
Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, ""); | |
Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, ""); | |
- | |
- Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, ""); | |
+ Console()->Register("add_banmaster", "s", CFGFLAG_SERVER, ConAddBanmaster, this, ""); | |
+ Console()->Register("banmasters", "", CFGFLAG_SERVER, ConBanmasters, this, ""); | |
+ Console()->Register("clear_banmasters", "", CFGFLAG_SERVER, ConClearBanmasters, this, ""); | |
+ | |
+ Console()->Register("add_banmaster", "s", CFGFLAG_SERVER, ConAddBanmaster, this, ""); | |
+ Console()->Register("banmasters", "", CFGFLAG_SERVER, ConBanmasters, this, ""); | |
+ Console()->Register("clear_banmasters", "", CFGFLAG_SERVER, ConClearBanmasters, this, ""); | |
+ //Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, ""); | |
- Console()->Chain("sv_name", ConchainSpecialInfoupdate, this); | |
- Console()->Chain("password", ConchainSpecialInfoupdate, this); | |
+ //Console()->Chain("sv_name", ConchainSpecialInfoupdate, this); | |
+ //Console()->Chain("password", ConchainSpecialInfoupdate, this); | |
- Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); | |
+ //Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this); | |
} | |
diff -Naur Coding/teeworlds/src/engine/server/server.h BBM/src/engine/server/server.h | |
--- Coding/teeworlds/src/engine/server/server.h 2011-02-17 07:36:24.867621001 +1100 | |
+++ BBM/src/engine/server/server.h 2011-02-14 05:07:30.199685001 +1100 | |
@@ -189,6 +189,9 @@ | |
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 ConAddBanmaster(IConsole::IResult *pResult, void *pUser); | |
+ static void ConBanmasters(IConsole::IResult *pResult, void *pUser); | |
+ static void ConClearBanmasters(IConsole::IResult *pResult, void *pUser); | |
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 -Naur Coding/teeworlds/src/engine/shared/config_variables.h BBM/src/engine/shared/config_variables.h | |
--- Coding/teeworlds/src/engine/shared/config_variables.h 2011-02-17 07:36:24.867621001 +1100 | |
+++ BBM/src/engine/shared/config_variables.h 2011-02-14 05:07:30.199685001 +1100 | |
@@ -78,6 +78,7 @@ | |
MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password") | |
MACRO_CONFIG_INT(SvRconMaxTries, sv_rcon_max_tries, 3, 0, 100, CFGFLAG_SERVER, "Maximum number of tries for remote console authentication") | |
MACRO_CONFIG_INT(SvRconBantime, sv_rcon_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if remote console authentication fails. 0 makes it just use kick") | |
+MACRO_CONFIG_INT(SvGlobalBantime, sv_global_ban_time, 60, 0, 1440, CFGFLAG_SERVER, "The time a client gets banned if the ban server reports it. 0 to disable") | |
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 -Naur Coding/teeworlds/src/engine/shared/network.h BBM/src/engine/shared/network.h | |
--- Coding/teeworlds/src/engine/shared/network.h 2011-02-17 07:36:24.871621001 +1100 | |
+++ BBM/src/engine/shared/network.h 2011-02-14 05:07:30.199685001 +1100 | |
@@ -215,13 +215,18 @@ | |
class CNetServer | |
{ | |
public: | |
+ enum | |
+ { | |
+ MAX_BANMASTERS=16, | |
+ NETSERVER_DISABLEBANMASTER=1, | |
+ }; | |
struct CBanInfo | |
{ | |
NETADDR m_Addr; | |
int m_Expires; | |
char m_Reason[128]; | |
}; | |
- | |
+ | |
private: | |
class CSlot | |
{ | |
@@ -254,10 +259,15 @@ | |
CBan *m_BanPool_FirstFree; | |
CBan *m_BanPool_FirstUsed; | |
+ NETADDR m_aBanmasters[MAX_BANMASTERS]; | |
+ int m_NumBanmasters; | |
+ | |
NETFUNC_NEWCLIENT m_pfnNewClient; | |
NETFUNC_DELCLIENT m_pfnDelClient; | |
void *m_UserPtr; | |
+ int m_Flags; | |
+ | |
CNetRecvUnpacker m_RecvUnpacker; | |
void BanRemoveByObject(CBan *pBan); | |
@@ -290,6 +300,11 @@ | |
// | |
void SetMaxClientsPerIP(int Max); | |
+ int BanmasterAdd(const char *pAddrStr); | |
+ int BanmasterNum() const; | |
+ NETADDR* BanmasterGet(int Index); | |
+ int BanmasterCheck(NETADDR *pAddr); | |
+ void BanmastersClear(); | |
}; | |
diff -Naur Coding/teeworlds/src/engine/shared/network_server.cpp BBM/src/engine/shared/network_server.cpp | |
--- Coding/teeworlds/src/engine/shared/network_server.cpp 2011-02-17 07:36:24.871621001 +1100 | |
+++ BBM/src/engine/shared/network_server.cpp 2011-02-14 05:07:30.199685001 +1100 | |
@@ -1,6 +1,7 @@ | |
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ | |
/* If you are missing that file, acquire a complete release at teeworlds.com. */ | |
#include <base/system.h> | |
+#include <banmaster/banmaster.h> | |
#include "network.h" | |
#define MACRO_LIST_LINK_FIRST(Object, First, Prev, Next) \ | |
@@ -59,6 +60,8 @@ | |
m_BanPool[NET_SERVER_MAXBANS-1].m_pPrev = &m_BanPool[NET_SERVER_MAXBANS-2]; | |
m_BanPool_FirstFree = &m_BanPool[0]; | |
+ m_Flags = Flags; | |
+ | |
return true; | |
} | |
@@ -345,6 +348,25 @@ | |
// client that wants to connect | |
if(!Found) | |
{ | |
+ if(!(m_Flags & NETSERVER_DISABLEBANMASTER)) | |
+ { | |
+ CNetChunk Packet; | |
+ char aBuffer[64]; | |
+ mem_copy(aBuffer, BANMASTER_IPCHECK, sizeof(BANMASTER_IPCHECK)); | |
+ net_addr_str(&Addr, aBuffer + sizeof(BANMASTER_IPCHECK), sizeof(aBuffer) - sizeof(BANMASTER_IPCHECK)); | |
+ | |
+ Packet.m_ClientID = -1; | |
+ Packet.m_Flags = NETSENDFLAG_CONNLESS; | |
+ Packet.m_DataSize = str_length(aBuffer) + 1; | |
+ Packet.m_pData = aBuffer; | |
+ | |
+ for(int i = 0; i < m_NumBanmasters; i++) | |
+ { | |
+ Packet.m_Address = m_aBanmasters[i]; | |
+ Send(&Packet); | |
+ } | |
+ } | |
+ | |
// only allow a specific number of players with the same ip | |
NETADDR ThisAddr = Addr, OtherAddr; | |
int FoundAddr = 1; | |
@@ -376,6 +398,7 @@ | |
m_aSlots[i].m_Connection.Feed(&m_RecvUnpacker.m_Data, &Addr); | |
if(m_pfnNewClient) | |
m_pfnNewClient(i, m_UserPtr); | |
+ | |
break; | |
} | |
} | |
@@ -454,3 +477,48 @@ | |
m_MaxClientsPerIP = Max; | |
} | |
+ | |
+int CNetServer::BanmasterAdd(const char *pAddrStr) | |
+{ | |
+ if(m_NumBanmasters >= MAX_BANMASTERS) | |
+ return 2; | |
+ | |
+ if(net_host_lookup(pAddrStr, &m_aBanmasters[m_NumBanmasters], NETTYPE_IPV4)) | |
+ return 1; | |
+ | |
+ if(m_aBanmasters[m_NumBanmasters].port == 0) | |
+ m_aBanmasters[m_NumBanmasters].port = BANMASTER_PORT; | |
+ | |
+ m_NumBanmasters++; | |
+ return 0; | |
+} | |
+ | |
+int CNetServer::BanmasterNum() const | |
+{ | |
+ return m_NumBanmasters; | |
+} | |
+ | |
+NETADDR* CNetServer::BanmasterGet(int Index) | |
+{ | |
+ if(Index < 0 || Index >= m_NumBanmasters) | |
+ return 0; | |
+ | |
+ return &m_aBanmasters[Index]; | |
+} | |
+ | |
+int CNetServer::BanmasterCheck(NETADDR *pAddr) | |
+{ | |
+ for(int i = 0; i < m_NumBanmasters; i++) | |
+ { | |
+ if(!net_addr_comp(&m_aBanmasters[i], pAddr)) | |
+ return i; | |
+ } | |
+ | |
+ return -1; | |
+} | |
+ | |
+void CNetServer::BanmastersClear() | |
+{ | |
+ m_NumBanmasters = 0; | |
+} | |
+ | |
diff -Naur Coding/teeworlds/src/game/collision.cpp BBM/src/game/collision.cpp | |
--- Coding/teeworlds/src/game/collision.cpp 2011-02-17 07:36:24.879621001 +1100 | |
+++ BBM/src/game/collision.cpp 2011-02-14 01:19:12.683685001 +1100 | |
@@ -27,11 +27,30 @@ | |
m_Height = m_pLayers->GameLayer()->m_Height; | |
m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data)); | |
+ int tpnum=(TILE_TPORT_LAST-TILE_TPORT_FIRST+1)>>1; | |
+ int *destcount=(int*)malloc(sizeof(int)*tpnum); | |
+ dc=(int*)malloc(sizeof(int)*tpnum); | |
+ dest=(int**)malloc(sizeof(int*)*tpnum); | |
+ for(int z=0;z<tpnum;++z) destcount[z]=dc[z]=0; | |
+ for(int i = 0; i < m_Width*m_Height; i++) //tport first | |
+ { | |
+ int index = m_pTiles[i].m_Index; | |
+ if(index >= TILE_TPORT_FIRST && index <= TILE_TPORT_LAST && !(index&1)) { | |
+ int tind = ((index-TILE_TPORT_FIRST) >> 1); | |
+ destcount[tind]++;dc[tind]++; | |
+ } | |
+ } | |
+ for(int z=0;z<tpnum;++z) { | |
+ if (destcount[z]) { | |
+ dest[z]=(int*)malloc(sizeof(int)*destcount[z]); | |
+ } | |
+ } | |
+ | |
for(int i = 0; i < m_Width*m_Height; i++) | |
{ | |
int Index = m_pTiles[i].m_Index; | |
- if(Index > 128) | |
+ if(Index > TILE_CUSTOM_END) | |
continue; | |
switch(Index) | |
@@ -46,9 +65,16 @@ | |
m_pTiles[i].m_Index = COLFLAG_SOLID|COLFLAG_NOHOOK; | |
break; | |
default: | |
- m_pTiles[i].m_Index = 0; | |
+ /*m_pTiles[i].m_Index = 0*/; | |
} | |
+ | |
+ if(Index >= TILE_TPORT_FIRST && Index <= TILE_TPORT_LAST && !(Index&1)) { | |
+ int tind = ((Index-TILE_TPORT_FIRST) >> 1); | |
+ dest[tind][--destcount[tind]]=i; | |
+ } else if (Index >= TILE_CUSTOM_END) | |
+ m_pTiles[i].m_Index = 0; | |
} | |
+ free(destcount); | |
} | |
int CCollision::GetTile(int x, int y) | |
@@ -56,12 +82,33 @@ | |
int Nx = clamp(x/32, 0, m_Width-1); | |
int Ny = clamp(y/32, 0, m_Height-1); | |
- return m_pTiles[Ny*m_Width+Nx].m_Index > 128 ? 0 : m_pTiles[Ny*m_Width+Nx].m_Index; | |
+ return m_pTiles[Ny*m_Width+Nx].m_Index > TILE_CUSTOM_END ? 0 : m_pTiles[Ny*m_Width+Nx].m_Index; | |
} | |
bool CCollision::IsTileSolid(int x, int y) | |
{ | |
- return GetTile(x, y)&COLFLAG_SOLID; | |
+ int i = GetTile(x,y); | |
+ return (i<=5) && (i&COLFLAG_SOLID); | |
+} | |
+ | |
+vec2 CCollision::GetTeleDest(int tind) | |
+{ | |
+ if (dc[tind]) { | |
+ int r = rand() % dc[tind]; | |
+ int x = (dest[tind][r] % m_Width) << 5; | |
+ int y = (dest[tind][r] / m_Width) << 5; | |
+ return vec2((float)x + 16.0, (float)y + 16.0); | |
+ } else return vec2(0, 0); | |
+} | |
+ | |
+vec2 CCollision::boost_accel(int index) | |
+{ | |
+ if (index == TILE_BOOST_L) return vec2(-15, 0); | |
+ else if (index == TILE_BOOST_R) return vec2(15, 0); | |
+ else if (index == TILE_BOOST_D) return vec2(0, 15); | |
+ else if (index == TILE_BOOST_U) return vec2(0, -15); | |
+ | |
+ return vec2(0, 0); | |
} | |
// TODO: rewrite this smarter! | |
diff -Naur Coding/teeworlds/src/game/collision.h BBM/src/game/collision.h | |
--- Coding/teeworlds/src/game/collision.h 2011-02-17 07:36:24.883621001 +1100 | |
+++ BBM/src/game/collision.h 2011-02-14 01:19:12.683685001 +1100 | |
@@ -3,6 +3,17 @@ | |
#ifndef GAME_COLLISION_H | |
#define GAME_COLLISION_H | |
+#define PUP_JUMP 0 | |
+#define PUP_HAMMER 1 | |
+#define PUP_LFREEZE 2 | |
+#define PUP_SFREEZE 3 | |
+#define PUP_HOOKDUR 4 | |
+#define PUP_HOOKLEN 5 | |
+#define PUP_WALKSPD 6 | |
+#define PUP_EPICNINJA 7 | |
+#define NUM_PUPS 8 | |
+ | |
+ | |
#include <base/vmath.h> | |
class CCollision | |
@@ -13,9 +24,10 @@ | |
class CLayers *m_pLayers; | |
bool IsTileSolid(int x, int y); | |
- int GetTile(int x, int y); | |
- | |
+ int *dc; | |
+ int **dest; | |
public: | |
+ int GetTile(int x, int y); | |
enum | |
{ | |
COLFLAG_SOLID=1, | |
@@ -34,6 +46,8 @@ | |
void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *pBounces); | |
void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity); | |
bool TestBox(vec2 Pos, vec2 Size); | |
+ vec2 GetTeleDest(int tind); | |
+ vec2 boost_accel(int index); | |
}; | |
#endif | |
diff -Naur Coding/teeworlds/src/game/gamecore.cpp BBM/src/game/gamecore.cpp | |
--- Coding/teeworlds/src/game/gamecore.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/gamecore.cpp 2011-02-16 01:54:12.840565001 +1100 | |
@@ -72,6 +72,7 @@ | |
m_HookedPlayer = -1; | |
m_Jumped = 0; | |
m_TriggeredEvents = 0; | |
+ fuc = 0; | |
} | |
void CCharacterCore::Tick(bool UseInput) | |
@@ -79,6 +80,8 @@ | |
float PhysSize = 28.0f; | |
m_TriggeredEvents = 0; | |
+ forceupdate = false; | |
+ | |
// get ground state | |
bool Grounded = false; | |
if(m_pCollision->CheckPoint(m_Pos.x+PhysSize/2, m_Pos.y+PhysSize/2+5)) | |
@@ -90,15 +93,32 @@ | |
m_Vel.y += m_pWorld->m_Tuning.m_Gravity; | |
- float MaxSpeed = Grounded ? m_pWorld->m_Tuning.m_GroundControlSpeed : m_pWorld->m_Tuning.m_AirControlSpeed; | |
+ float MaxSpeed = Grounded ? (m_pWorld->m_Tuning.m_GroundControlSpeed*(1.0f+(skills?(skills[PUP_WALKSPD]/10.0f):0.0f))) : m_pWorld->m_Tuning.m_AirControlSpeed; | |
float Accel = Grounded ? m_pWorld->m_Tuning.m_GroundControlAccel : m_pWorld->m_Tuning.m_AirControlAccel; | |
float Friction = Grounded ? m_pWorld->m_Tuning.m_GroundFriction : m_pWorld->m_Tuning.m_AirFriction; | |
+ if (Grounded) | |
+ extrajumpsleft=skills?skills[PUP_JUMP]:0; | |
+ | |
+ | |
// handle input | |
if(UseInput) | |
{ | |
+ ldir=m_Direction; | |
+ | |
m_Direction = m_Input.m_Direction; | |
+ if (skills?(skills[PUP_WALKSPD]):0) { | |
+ if (m_Direction != ldir) { | |
+ fuc=1000; | |
+ } | |
+ } | |
+ if (fuc > 0) { | |
+ if ((--fuc % 10) == 5) { | |
+ forceupdate = true; | |
+ } | |
+ } | |
+ | |
// setup angle | |
float a = 0; | |
if(m_Input.m_TargetX == 0) | |
@@ -127,6 +147,10 @@ | |
m_TriggeredEvents |= COREEVENT_AIR_JUMP; | |
m_Vel.y = -m_pWorld->m_Tuning.m_AirJumpImpulse; | |
m_Jumped |= 3; | |
+ if (extrajumpsleft-- > 0) { | |
+ m_Jumped&=~2; | |
+ } | |
+ | |
} | |
} | |
} | |
@@ -187,11 +211,14 @@ | |
} | |
else if(m_HookState == HOOK_FLYING) | |
{ | |
- vec2 NewPos = m_HookPos+m_HookDir*m_pWorld->m_Tuning.m_HookFireSpeed; | |
- if(distance(m_Pos, NewPos) > m_pWorld->m_Tuning.m_HookLength) | |
+ float hookfac = 1.0f+(skills?(skills[PUP_HOOKLEN]/5.0f):0.0f); | |
+ vec2 NewPos = m_HookPos+m_HookDir*(m_pWorld->m_Tuning.m_HookFireSpeed * hookfac); | |
+ float hole = m_pWorld->m_Tuning.m_HookLength*hookfac; | |
+ if(distance(m_Pos, NewPos) > hole) | |
{ | |
m_HookState = HOOK_RETRACT_START; | |
- NewPos = m_Pos + normalize(NewPos-m_Pos) * m_pWorld->m_Tuning.m_HookLength; | |
+ NewPos = m_Pos + normalize(NewPos-m_Pos) * hole; | |
+ forceupdate = true; | |
} | |
// make sure that the hook doesn't go though the ground | |
@@ -200,7 +227,7 @@ | |
int Hit = m_pCollision->IntersectLine(m_HookPos, NewPos, &NewPos, 0); | |
if(Hit) | |
{ | |
- if(Hit&CCollision::COLFLAG_NOHOOK) | |
+ if(Hit<=5 && (Hit&CCollision::COLFLAG_NOHOOK)) | |
GoingToRetract = true; | |
else | |
GoingToHitGround = true; | |
@@ -223,6 +250,7 @@ | |
{ | |
m_TriggeredEvents |= COREEVENT_HOOK_ATTACH_PLAYER; | |
m_HookState = HOOK_GRABBED; | |
+ forceupdate = true; | |
m_HookedPlayer = i; | |
Distance = distance(m_HookPos, pCharCore->m_Pos); | |
} | |
@@ -237,11 +265,13 @@ | |
{ | |
m_TriggeredEvents |= COREEVENT_HOOK_ATTACH_GROUND; | |
m_HookState = HOOK_GRABBED; | |
+ forceupdate = true; | |
} | |
else if(GoingToRetract) | |
{ | |
m_TriggeredEvents |= COREEVENT_HOOK_HIT_NOHOOK; | |
m_HookState = HOOK_RETRACT_START; | |
+ forceupdate = true; | |
} | |
m_HookPos = NewPos; | |
@@ -264,7 +294,7 @@ | |
} | |
// keep players hooked for a max of 1.5sec | |
- //if(Server()->Tick() > hook_tick+(Server()->TickSpeed()*3)/2) | |
+// if(Server()->Tick() > hook_tick+(Server()->TickSpeed()*3)/2) | |
//release_hooked(); | |
} | |
@@ -294,7 +324,7 @@ | |
// release hook (max hook time is 1.25 | |
m_HookTick++; | |
- if(m_HookedPlayer != -1 && (m_HookTick > SERVER_TICK_SPEED+SERVER_TICK_SPEED/5 || !m_pWorld->m_apCharacters[m_HookedPlayer])) | |
+ if(m_HookedPlayer != -1 && (m_HookTick > ((SERVER_TICK_SPEED+SERVER_TICK_SPEED/5)*(1.0f+(skills?(skills[PUP_HOOKDUR]/2.0f):0.0f))) || !m_pWorld->m_apCharacters[m_HookedPlayer])) | |
{ | |
m_HookedPlayer = -1; | |
m_HookState = HOOK_RETRACTED; | |
@@ -320,15 +350,13 @@ | |
if(Distance < PhysSize*1.25f && Distance > 1.0f) | |
{ | |
float a = (PhysSize*1.45f - Distance); | |
- float Velocity = 0.5f; | |
// make sure that we don't add excess force by checking the | |
- // direction against the current velocity. if not zero. | |
- if (length(m_Vel) > 0.0001) | |
- Velocity = 1-(dot(normalize(m_Vel), Dir)+1)/2; | |
- | |
- m_Vel += Dir*a*(Velocity*0.75f); | |
- m_Vel *= 0.85f; | |
+ // 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 | |
diff -Naur Coding/teeworlds/src/game/gamecore.h BBM/src/game/gamecore.h | |
--- Coding/teeworlds/src/game/gamecore.h 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/gamecore.h 2011-02-14 01:19:12.683685001 +1100 | |
@@ -194,6 +194,13 @@ | |
int m_TriggeredEvents; | |
+ int ldir; | |
+ int forceupdate; | |
+ int fuc; | |
+ int *skills; | |
+ int extrajumpsleft; | |
+ | |
+ | |
void Init(CWorldCore *pWorld, CCollision *pCollision); | |
void Reset(); | |
void Tick(bool UseInput); | |
diff -Naur Coding/teeworlds/src/game/mapitems.h BBM/src/game/mapitems.h | |
--- Coding/teeworlds/src/game/mapitems.h 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/mapitems.h 2011-02-14 01:19:12.687685001 +1100 | |
@@ -42,11 +42,54 @@ | |
ENTITY_WEAPON_RIFLE, | |
NUM_ENTITIES, | |
+ | |
TILE_AIR=0, | |
TILE_SOLID, | |
TILE_DEATH, | |
TILE_NOHOOK, | |
+ TILE_FREEZE = 9, | |
+ TILE_KICK, | |
+ TILE_UNFREEZE, | |
+ | |
+ TILE_COLFRZ_GREEN, | |
+ TILE_COLFRZ_BLUE, | |
+ TILE_COLFRZ_RED, | |
+ TILE_COLFRZ_WHITE, | |
+ TILE_COLFRZ_GREY, | |
+ TILE_COLFRZ_YELLOW, | |
+ TILE_COLFRZ_PINK, | |
+ TILE_COLFRZ_RESET, | |
+ | |
+ TILE_PUP_JUMP, | |
+ TILE_PUP_HAMMER, | |
+ TILE_PUP_LFREEZE, | |
+ TILE_PUP_SFREEZE, | |
+ TILE_PUP_HOOKDUR, | |
+ TILE_PUP_HOOKLEN, | |
+ TILE_PUP_WALKSPD, | |
+ TILE_PUP_EPICNINJA, | |
+ | |
+ TILE_BOOST_L = 28, | |
+ TILE_BOOST_R, | |
+ TILE_BOOST_D, | |
+ TILE_BOOST_U, | |
+ TILE_GREEN, | |
+ TILE_BLUE, | |
+ TILE_RED, | |
+ TILE_WHITE, | |
+ TILE_GREY, | |
+ TILE_YELLOW, | |
+ TILE_PINK, | |
+ | |
+ TILE_PUP_RESET = 48, | |
+ TILE_1ON1TOGGLE, | |
+ | |
+ TILE_TPORT_FIRST = 112, | |
+ TILE_TPORT_LAST = 191, | |
+ | |
+ TILE_CUSTOM_END, | |
+ | |
TILEFLAG_VFLIP=1, | |
TILEFLAG_HFLIP=2, | |
TILEFLAG_OPAQUE=4, | |
diff -Naur Coding/teeworlds/src/game/server/entities/character.cpp BBM/src/game/server/entities/character.cpp | |
--- Coding/teeworlds/src/game/server/entities/character.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/entities/character.cpp 2011-02-15 23:07:48.056565002 +1100 | |
@@ -1,6 +1,11 @@ | |
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ | |
/* If you are missing that file, acquire a complete release at teeworlds.com. */ | |
#include <new> | |
+ | |
+#include <cstdlib> | |
+#include <cstdio> | |
+#include <cstring> | |
+ | |
#include <engine/shared/config.h> | |
#include <game/server/gamecontext.h> | |
#include <game/mapitems.h> | |
@@ -9,6 +14,8 @@ | |
#include "laser.h" | |
#include "projectile.h" | |
+static char bbuf[512]; | |
+ | |
//input count | |
struct CInputCount | |
{ | |
@@ -57,8 +64,8 @@ | |
m_PlayerState = PLAYERSTATE_UNKNOWN; | |
m_EmoteStop = -1; | |
m_LastAction = -1; | |
- m_ActiveWeapon = WEAPON_GUN; | |
- m_LastWeapon = WEAPON_HAMMER; | |
+ m_ActiveWeapon = WEAPON_HAMMER; | |
+ m_LastWeapon = WEAPON_GUN; | |
m_QueuedWeapon = -1; | |
m_pPlayer = pPlayer; | |
@@ -76,6 +83,21 @@ | |
GameServer()->m_World.InsertEntity(this); | |
m_Alive = true; | |
+ m_Core.skills=m_pPlayer->skills; | |
+ if (m_pPlayer->is1on1) { | |
+ int *sl = m_pPlayer->slot3; | |
+ if (sl) { | |
+ for (int z = 0; z < NUM_PUPS; ++z) | |
+ m_pPlayer->skills[z] = sl[z]; | |
+ } | |
+ Server()->SetClientName(m_pPlayer->GetCID(), m_pPlayer->oname); | |
+ free(m_pPlayer->oname); | |
+ m_pPlayer->oname = NULL; | |
+ m_pPlayer->is1on1=0; | |
+ } | |
+ lastepicninja=0; | |
+ epicninjaannounced=0; | |
+ | |
GameServer()->m_pController->OnCharacterSpawn(this); | |
return true; | |
@@ -138,7 +160,9 @@ | |
if (m_Ninja.m_CurrentMoveTime == 0) | |
{ | |
// reset velocity | |
- m_Core.m_Vel *= 0.2f; | |
+ m_Core.m_Vel.x = 0.0f; | |
+ m_Core.m_Vel.y = 0.0f; | |
+ m_Core.m_Pos = epicninjaoldpos; | |
} | |
if (m_Ninja.m_CurrentMoveTime > 0) | |
@@ -184,7 +208,7 @@ | |
if(m_NumObjectsHit < 10) | |
m_apHitObjects[m_NumObjectsHit++] = aEnts[i]; | |
- aEnts[i]->TakeDamage(vec2(0, 10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA); | |
+ aEnts[i]->TakeDamage(vec2(0, 10.0f), 0, m_pPlayer->GetCID(), WEAPON_NINJA); | |
} | |
} | |
@@ -298,23 +322,25 @@ | |
{ | |
CCharacter *pTarget = apEnts[i]; | |
- if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL)) | |
+ //for race mod or any other mod, which needs hammer hits through the wall remove second condition | |
+ if ((pTarget == this) /* || GameServer()->Collision()->IntersectLine(ProjStartPos, Target->m_Pos, NULL, NULL) */) | |
continue; | |
// set his velocity to fast upward (for now) | |
- if(length(pTarget->m_Pos-ProjStartPos) > 0.0f) | |
- GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f); | |
- else | |
- GameServer()->CreateHammerHit(ProjStartPos); | |
+ GameServer()->CreateHammerHit(m_Pos); | |
+ //aEnts[i]->TakeDamage(vec2(0.f, -1.f), g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon); | |
+ | |
+ apEnts[i]->TakeDamage(vec2(0.f,-1.f),0,m_pPlayer->GetCID(),m_ActiveWeapon); | |
+ apEnts[i]->lasthammeredat = Server()->Tick(); | |
+ apEnts[i]->lasthammeredby = m_pPlayer->GetCID(); | |
vec2 Dir; | |
if (length(pTarget->m_Pos - m_Pos) > 0.0f) | |
Dir = normalize(pTarget->m_Pos - m_Pos); | |
else | |
Dir = vec2(0.f, -1.f); | |
- | |
- pTarget->TakeDamage(vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, | |
- m_pPlayer->GetCID(), m_ActiveWeapon); | |
+ pTarget->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * (10.0f + (m_pPlayer->skills[PUP_HAMMER] * 3)); | |
+ pTarget->Unfreeze(); | |
Hits++; | |
} | |
@@ -331,7 +357,7 @@ | |
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; | |
@@ -411,6 +437,20 @@ | |
case WEAPON_NINJA: | |
{ | |
+ if (m_pPlayer->skills[PUP_EPICNINJA]) { | |
+ if ((lastepicninja + 10 * Server()->TickSpeed()) < Server()->Tick()) { | |
+ lastepicninja=Server()->Tick(); | |
+ epicninjaoldpos=m_Pos; | |
+ epicninjaannounced=0; | |
+ } else { | |
+ str_format(bbuf, 128, "epic ninja not yet ready."); | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), bbuf); | |
+ return; | |
+ } | |
+ } else { | |
+ return; | |
+ } | |
+// ----------- | |
// reset Hit objects | |
m_NumObjectsHit = 0; | |
@@ -425,8 +465,8 @@ | |
m_AttackTick = Server()->Tick(); | |
- if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited | |
- m_aWeapons[m_ActiveWeapon].m_Ammo--; | |
+// 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; | |
@@ -542,16 +582,262 @@ | |
m_pPlayer->m_ForceBalanced = false; | |
} | |
+ if (frz_time > 0) { | |
+ if (frz_time % (REFREEZE_INTERVAL_TICKS) == 0) { | |
+ GameServer()->CreateDamageInd(m_Pos, 0, frz_time / REFREEZE_INTERVAL_TICKS); | |
+ } | |
+ frz_time--; | |
+ m_Input.m_Direction = 0; | |
+ m_Input.m_Jump = 0; | |
+ m_Input.m_Hook = 0; | |
+ m_Input.m_Fire = 0; | |
+ if (frz_time - 1 == 0) { | |
+ Unfreeze(); | |
+ } | |
+ } | |
+ if (frz_tick && m_pPlayer->skills[PUP_EPICNINJA] && ((lastepicninja+10*Server()->TickSpeed()) < Server()->Tick()) && !epicninjaannounced) { | |
+ str_format(bbuf, 128, "epic ninja ready!"); | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), bbuf); | |
+ epicninjaannounced=1; | |
+ } | |
m_Core.m_Input = m_Input; | |
m_Core.Tick(true); | |
- // handle death-tiles and leaving gamelayer | |
- 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 || | |
- GameLayerClipped(m_Pos)) | |
+ | |
+ if (m_Core.m_HookedPlayer >= 0) { | |
+ if (GameServer()->m_apPlayers[m_Core.m_HookedPlayer] && GameServer()->m_apPlayers[m_Core.m_HookedPlayer]->GetCharacter()) { | |
+ // GameServer()->m_apPlayers[m_Core.m_HookedPlayer]->GetCharacter()->lasthookedat = Server()->Tick(); | |
+ // GameServer()->m_apPlayers[m_Core.m_HookedPlayer]->GetCharacter()->lasthookedby = m_pPlayer->GetCID(); | |
+ } | |
+ } | |
+ | |
+ int col = GameServer()->Collision()->GetTile(m_Pos.x, m_Pos.y); | |
+ | |
+ if (col == TILE_KICK) { | |
+ Server()->Kick(m_pPlayer->GetCID(), "Kicked by evil kick zone"); | |
+ } else if (col == TILE_FREEZE || (col >= TILE_COLFRZ_GREEN && col <= TILE_COLFRZ_PINK)) { | |
+ int ft = Server()->TickSpeed() * 3; | |
+ int add=0; | |
+ if ((wasout || frz_tick == 0) && (((lasthookedat + (Server()->TickSpeed()<<1)) > Server()->Tick()) || ((lasthammeredat + Server()->TickSpeed()) > Server()->Tick()))) | |
+ { | |
+ int hooked = lasthookedat > lasthammeredat; | |
+ int by = hooked ? lasthookedby : lasthammeredby; | |
+ if (GameServer()->m_apPlayers[by] && GameServer()->m_apPlayers[by]->GetCharacter()) { | |
+ add = GameServer()->m_apPlayers[by]->skills[PUP_LFREEZE]; | |
+ } | |
+ blockedby=by; | |
+ if (blockedby>=0) blocktime=ft+(add * (Server()->TickSpeed()>>1)); | |
+ } else { | |
+ if (frz_tick==0) { | |
+ blockedby=-1; | |
+ } | |
+ if (blockedby>=0) | |
+ ft=blocktime; | |
+ } | |
+ add -=m_pPlayer->skills[PUP_SFREEZE]; | |
+ ft += (add * (Server()->TickSpeed()>>1)); | |
+ wasout=0; | |
+ Freeze(ft); | |
+ if ((col >= TILE_COLFRZ_GREEN && col <= TILE_COLFRZ_PINK) && lastcolfrz + REFREEZE_INTERVAL_TICKS < Server()->Tick()) | |
+ { | |
+ lastcolfrz = Server()->Tick(); | |
+ int prevfc = m_pPlayer->forcecolor; | |
+ switch (col) | |
+ { | |
+ case TILE_COLFRZ_GREEN: | |
+ if(!m_pPlayer->m_NoGreen) | |
+ m_pPlayer->forcecolor = COL_GREEN; | |
+ break; | |
+ case TILE_COLFRZ_BLUE: | |
+ if(!m_pPlayer->m_NoBlue) | |
+ m_pPlayer->forcecolor = COL_BLUE; | |
+ break; | |
+ case TILE_COLFRZ_RED: | |
+ if(!m_pPlayer->m_NoRed) | |
+ m_pPlayer->forcecolor = COL_RED; | |
+ break; | |
+ case TILE_COLFRZ_WHITE: | |
+ if(!m_pPlayer->m_NoWhite) | |
+ m_pPlayer->forcecolor = COL_WHITE; | |
+ break; | |
+ case TILE_COLFRZ_GREY: | |
+ if(!m_pPlayer->m_NoGrey) | |
+ m_pPlayer->forcecolor = COL_GREY; | |
+ break; | |
+ case TILE_COLFRZ_YELLOW: | |
+ if(!m_pPlayer->m_NoYellow) | |
+ m_pPlayer->forcecolor = COL_YELLOW; | |
+ break; | |
+ case TILE_COLFRZ_PINK: | |
+ if(!m_pPlayer->m_NoPink) | |
+ m_pPlayer->forcecolor = COL_PINK; | |
+ break; | |
+ } | |
+ if (m_pPlayer->forcecolor != prevfc) | |
+ { | |
+ m_pPlayer->m_TeeInfos.m_UseCustomColor = (m_pPlayer->forcecolor) ? 1 : m_pPlayer->origusecustcolor; | |
+ m_pPlayer->m_TeeInfos.m_ColorBody = (m_pPlayer->forcecolor) ? m_pPlayer->forcecolor : m_pPlayer->origbodycolor; | |
+ m_pPlayer->m_TeeInfos.m_ColorFeet = (m_pPlayer->forcecolor) ? m_pPlayer->forcecolor : m_pPlayer->origfeetcolor; | |
+ GameServer()->m_pController->OnPlayerInfoChange(m_pPlayer); | |
+ } | |
+ } | |
+ | |
+ } | |
+ | |
+ if ((col >= TILE_GREEN && col <= TILE_PINK) && lastcolfrz + REFREEZE_INTERVAL_TICKS < Server()->Tick()) | |
+ { | |
+ lastcolfrz = Server()->Tick(); | |
+ switch (col) | |
+ { | |
+ case TILE_GREEN: | |
+ m_pPlayer->m_NoGreen = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Green will no longer effect you!"); | |
+ break; | |
+ case TILE_BLUE: | |
+ m_pPlayer->m_NoBlue = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Blue will no longer effect you!"); | |
+ break; | |
+ case TILE_RED: | |
+ m_pPlayer->m_NoRed = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Red will no longer effect you!"); | |
+ break; | |
+ case TILE_WHITE: | |
+ m_pPlayer->m_NoWhite = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "White will no longer effect you!"); | |
+ break; | |
+ case TILE_GREY: | |
+ m_pPlayer->m_NoGrey = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Grey will no longer effect you!"); | |
+ break; | |
+ case TILE_YELLOW: | |
+ m_pPlayer->m_NoYellow = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Yellow will no longer effect you!"); | |
+ break; | |
+ case TILE_PINK: | |
+ m_pPlayer->m_NoPink = true; | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "Pink will no longer effect you!"); | |
+ break; | |
+ } | |
+ | |
+ } | |
+ else if (col == TILE_UNFREEZE) { | |
+ Unfreeze(); | |
+ wasout=1; | |
+ | |
+ } else if (col == TILE_1ON1TOGGLE) { | |
+ if ((lastloadsave + Server()->TickSpeed()) < Server()->Tick()) | |
+ { | |
+ lastloadsave = Server()->Tick(); | |
+ if ((m_pPlayer->is1on1 = 1 - m_pPlayer->is1on1)) | |
+ { | |
+ int *sl = m_pPlayer->slot3; | |
+ if (sl) | |
+ free(sl); | |
+ sl = (int*) malloc(sizeof(int) * NUM_PUPS); | |
+ for (int z = 0; z < NUM_PUPS; ++z) | |
+ { | |
+ sl[z] = m_pPlayer->skills[z]; | |
+ m_pPlayer->skills[z] = 0; | |
+ } | |
+ m_pPlayer->slot3 = sl; | |
+ m_pPlayer->oname = strdup(Server()->ClientName(m_pPlayer->GetCID())); | |
+ char *buf = (char*) malloc(strlen(m_pPlayer->oname) + 8); | |
+ sprintf(buf, "[1on1] %s", m_pPlayer->oname); | |
+ Server()->SetClientName(m_pPlayer->GetCID(), buf); | |
+ | |
+ } | |
+ else | |
+ { | |
+ int *sl = m_pPlayer->slot3; | |
+ if (sl) | |
+ { | |
+ for (int z = 0; z < NUM_PUPS; ++z) | |
+ m_pPlayer->skills[z] = sl[z]; | |
+ } | |
+ Server()->SetClientName(m_pPlayer->GetCID(), m_pPlayer->oname); | |
+ free(m_pPlayer->oname); | |
+ m_pPlayer->oname = NULL; | |
+ } | |
+ | |
+ str_format(bbuf, 128, "1on1 mode %s", (m_pPlayer->is1on1) ? "ON" : "OFF"); | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), bbuf); | |
+ } | |
+ | |
+ } else if (col >= TILE_BOOST_L && col <= TILE_BOOST_U) { | |
+ m_Core.m_Vel += GameServer()->Collision()->boost_accel(col); | |
+ } else if (col == TILE_COLFRZ_RESET) { | |
+ if (lastcolfrz + REFREEZE_INTERVAL_TICKS < Server()->Tick()) | |
+ { | |
+ if (m_pPlayer->forcecolor) | |
+ | |
+ { | |
+ m_pPlayer->forcecolor = 0; | |
+ m_pPlayer->m_TeeInfos.m_UseCustomColor = (m_pPlayer->forcecolor) ? 1 : m_pPlayer->origusecustcolor; | |
+ m_pPlayer->m_TeeInfos.m_ColorBody = (m_pPlayer->forcecolor) ? m_pPlayer->forcecolor : m_pPlayer->origbodycolor; | |
+ m_pPlayer->m_TeeInfos.m_ColorFeet = (m_pPlayer->forcecolor) ? m_pPlayer->forcecolor : m_pPlayer->origfeetcolor; | |
+ GameServer()->m_pController->OnPlayerInfoChange(m_pPlayer); | |
+ } | |
+ } | |
+ } else if (col >= TILE_PUP_JUMP && col <= TILE_PUP_EPICNINJA) { | |
+ int tmp = col - TILE_PUP_JUMP; | |
+ if ((lastup + Server()->TickSpeed()) < Server()->Tick()) | |
+ { | |
+ lastup = Server()->Tick(); | |
+ if (m_pPlayer->is1on1) | |
+ { | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "leave 1on1 mode first!"); | |
+ } | |
+ if ((lastepicninja + Server()->TickSpeed()) > Server()->Tick()) | |
+ { | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "bad luck..."); | |
+ } | |
+ else | |
+ { | |
+ if (m_pPlayer->skills[tmp] < 10) { | |
+ m_pPlayer->skills[tmp]++; | |
+ tell_powerup_info(m_pPlayer->GetCID(), tmp); | |
+ } | |
+ } | |
+ } | |
+ | |
+ } else if (col == TILE_PUP_RESET) { | |
+ if ((lastup + (Server()->TickSpeed() >> 2)) < Server()->Tick()) | |
+ { | |
+ lastup = Server()->Tick(); | |
+ for (int z = 0; z < NUM_PUPS; ++z) | |
+ { | |
+ m_pPlayer->skills[z] = 0; | |
+ } | |
+ GameServer()->SendChatTarget(m_pPlayer->GetCID(), "select new powerups!"); | |
+ } | |
+ } else if (col >= TILE_TPORT_FIRST && col <= TILE_TPORT_LAST) { | |
+ int tmp = col-TILE_TPORT_FIRST; | |
+ if (tmp&1) { | |
+ 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()->GetTeleDest(tmp>>1); | |
+ } | |
+ } else { | |
+ wasout = 1; | |
+ } | |
+ | |
+ // handle death-tiles | |
+ int a,b,c,d; | |
+ | |
+ if(((a=GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)) <= 5 && (a&CCollision::COLFLAG_DEATH)) || | |
+ ((b=GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)) <= 5 && (b&CCollision::COLFLAG_DEATH)) || | |
+ ((c=GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)) <= 5 && (c&CCollision::COLFLAG_DEATH)) || | |
+ ((d=GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)) <= 5 && (d&CCollision::COLFLAG_DEATH))) | |
+ { | |
+ Die(m_pPlayer->GetCID(), WEAPON_WORLD); | |
+ } | |
+ | |
+ // kill player when leaving gamelayer | |
+ if((int)m_Pos.x/32 < -200 || (int)m_Pos.x/32 > GameServer()->Collision()->GetWidth()+200 || | |
+ (int)m_Pos.y/32 < -200 || (int)m_Pos.y/32 > GameServer()->Collision()->GetHeight()+200) | |
{ | |
Die(m_pPlayer->GetCID(), WEAPON_WORLD); | |
} | |
@@ -640,7 +926,7 @@ | |
m_Core.Write(&Current); | |
// only allow dead reackoning for a top of 3 seconds | |
- if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0) | |
+ if(m_Core.forceupdate || (m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0)) | |
{ | |
m_ReckoningTick = Server()->Tick(); | |
m_SendCore = m_Core; | |
@@ -665,6 +951,68 @@ | |
return true; | |
} | |
+bool CCharacter::Freeze(int ticks) | |
+{ | |
+ if (ticks <= 1) return false; | |
+ if (frz_tick > 0) { //already frozen | |
+ if (frz_tick + REFREEZE_INTERVAL_TICKS > Server()->Tick()) return true; | |
+ } else { | |
+ frz_start=Server()->Tick(); | |
+ epicninjaannounced=0; | |
+ lastepicninja=Server()->Tick()-5*Server()->TickSpeed(); | |
+ } | |
+ frz_tick=Server()->Tick(); | |
+ frz_time=ticks; | |
+ m_Ninja.m_ActivationTick = Server()->Tick(); | |
+ m_aWeapons[WEAPON_NINJA].m_Got = true; | |
+ m_aWeapons[WEAPON_NINJA].m_Ammo = -1; | |
+ if (m_ActiveWeapon != WEAPON_NINJA) { | |
+ SetWeapon(WEAPON_NINJA); | |
+ } | |
+ return true; | |
+} | |
+ | |
+bool CCharacter::Unfreeze(){ | |
+ if (frz_time > 0) { | |
+ frz_tick = frz_time = frz_start = 0; | |
+ m_Ninja.m_CurrentMoveTime=-1;//prevent magic teleport when unfreezing while epic ninja | |
+ m_aWeapons[WEAPON_NINJA].m_Got = false; | |
+ if (m_LastWeapon < 0 || m_LastWeapon >= NUM_WEAPONS || m_LastWeapon == WEAPON_NINJA || (!m_aWeapons[m_LastWeapon].m_Got)) m_LastWeapon = WEAPON_HAMMER; | |
+ SetWeapon(m_LastWeapon); | |
+ epicninjaannounced=0; | |
+ return true; | |
+ } | |
+ return false; | |
+ | |
+return true; | |
+} | |
+ | |
+void CCharacter::tell_powerup_info(int client_id, int skill) | |
+{ | |
+ static char bbuf[256]; | |
+ switch(skill) { | |
+ case PUP_JUMP: | |
+ str_format(bbuf, 128, "you got an extra air jump!");break; | |
+ case PUP_HAMMER: | |
+ str_format(bbuf, 128, "hammer powered!");break; | |
+ case PUP_LFREEZE: | |
+ str_format(bbuf, 128, "enemy freeze time increased!");break; | |
+ case PUP_SFREEZE: | |
+ str_format(bbuf, 128, "own freeze time shortened!");break; | |
+ case PUP_HOOKDUR: | |
+ str_format(bbuf, 128, "hook duration increased (you wont see it but it works!)!");break; | |
+ case PUP_HOOKLEN: | |
+ str_format(bbuf, 128, "hook length extended (its not smooth, however)");break; | |
+ case PUP_WALKSPD: | |
+ str_format(bbuf, 128, "walk speed increased");break; | |
+ case PUP_EPICNINJA: | |
+ str_format(bbuf, 128, "eeeeeeeeeeeeeeeeepic ninja! (freeze attack)");break; | |
+ default: | |
+ str_format(bbuf, 128, "wtf");break; | |
+ } | |
+ GameServer()->SendChatTarget(client_id, bbuf); | |
+} | |
+ | |
void CCharacter::Die(int Killer, int Weapon) | |
{ | |
int ModeSpecial = GameServer()->m_pController->OnCharacterDeath(this, GameServer()->m_apPlayers[Killer], Weapon); | |
@@ -687,7 +1035,7 @@ | |
GameServer()->CreateSound(m_Pos, SOUND_PLAYER_DIE); | |
// this is for auto respawn after 3 secs | |
- m_pPlayer->m_DieTick = Server()->Tick(); | |
+// m_pPlayer->m_DieTick = Server()->Tick(); | |
m_Alive = false; | |
GameServer()->m_World.RemoveEntity(this); | |
@@ -695,14 +1043,14 @@ | |
GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID()); | |
// we got to wait 0.5 secs before respawning | |
- m_pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2; | |
+ //m_pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2; | |
} | |
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) | |
+ /*if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage) | |
return false; | |
// m_pPlayer only inflicts half damage on self | |
@@ -721,9 +1069,12 @@ | |
{ | |
m_DamageTaken = 0; | |
GameServer()->CreateDamageInd(m_Pos, 0, Dmg); | |
- } | |
+ }*/ | |
+ | |
+ if (Weapon == WEAPON_NINJA) | |
+ Freeze(3 * Server()->TickSpeed()); | |
- if(Dmg) | |
+ /*if(Dmg) | |
{ | |
if(m_Armor) | |
{ | |
@@ -752,8 +1103,8 @@ | |
// do damage Hit sound | |
if(From >= 0 && From != m_pPlayer->GetCID() && GameServer()->m_apPlayers[From]) | |
- GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, CmaskOne(From)); | |
- | |
+ */GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, CmaskOne(From)); | |
+/* | |
// check for death | |
if(m_Health <= 0) | |
{ | |
@@ -780,8 +1131,8 @@ | |
m_EmoteType = EMOTE_PAIN; | |
m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000; | |
- | |
- return true; | |
+ | |
+ */return true; | |
} | |
void CCharacter::Snap(int SnappingClient) | |
@@ -835,8 +1186,8 @@ | |
if(pCharacter->m_Emote == EMOTE_NORMAL) | |
{ | |
- if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5) | |
- pCharacter->m_Emote = EMOTE_BLINK; | |
+ // if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5) | |
+ // pCharacter->m_Emote = EMOTE_BLINK; | |
} | |
pCharacter->m_PlayerState = m_PlayerState; | |
diff -Naur Coding/teeworlds/src/game/server/entities/character.h BBM/src/game/server/entities/character.h | |
--- Coding/teeworlds/src/game/server/entities/character.h 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/entities/character.h 2011-02-14 01:19:12.687685001 +1100 | |
@@ -9,6 +9,16 @@ | |
#include <game/gamecore.h> | |
+#define REFREEZE_INTERVAL_TICKS (Server()->TickSpeed()>>1) | |
+ | |
+#define COL_BLUE 0x90ff4d | |
+#define COL_GREEN 0x51ff4d | |
+#define COL_WHITE 0xffffff | |
+#define COL_GREY 0x1 | |
+#define COL_RED 0xff00 | |
+#define COL_YELLOW 0x2bff00 | |
+#define COL_PINK 0xd6ff5b | |
+ | |
enum | |
{ | |
WEAPON_GAME = -3, // team switching etc | |
@@ -61,13 +71,21 @@ | |
bool IsAlive() const { return m_Alive; } | |
class CPlayer *GetPlayer() { return m_pPlayer; } | |
+ void SetEmoteStop(int EmoteStop) { m_EmoteStop = EmoteStop; }; | |
+ bool Freeze(int time); | |
+ bool Unfreeze(); | |
+ void SetEmoteType(int EmoteType) { m_EmoteType = EmoteType; }; | |
+ | |
private: | |
+ void tell_powerup_info(int client_id, int skill); | |
+ | |
// player controlling this character | |
class CPlayer *m_pPlayer; | |
bool m_Alive; | |
- | |
+ int m_EmoteType; | |
+ int m_EmoteStop; | |
// weapon info | |
CEntity *m_apHitObjects[10]; | |
int m_NumObjectsHit; | |
@@ -78,7 +96,7 @@ | |
int m_Ammo; | |
int m_Ammocost; | |
bool m_Got; | |
- | |
+ | |
} m_aWeapons[NUM_WEAPONS]; | |
int m_ActiveWeapon; | |
@@ -90,8 +108,6 @@ | |
int m_DamageTaken; | |
- int m_EmoteType; | |
- int m_EmoteStop; | |
// last tick that the player took any action ie some input | |
int m_LastAction; | |
@@ -111,6 +127,22 @@ | |
int m_Health; | |
int m_Armor; | |
+ int frz_time;//will be higher when blocker has lfreeze, for instance | |
+ int frz_tick;//will get updated on every REFREEZE_INTERVAL ticks | |
+ int frz_start;//will be set on the first freeze | |
+ | |
+ int lastcolfrz; | |
+ int lastloadsave; | |
+ int lasthammeredby, lasthammeredat; | |
+ int lasthookedby, lasthookedat; | |
+ int lastup; | |
+ int wasout; | |
+ int lastepicninja; | |
+ int epicninjaannounced; | |
+ int blockedby; | |
+ int blocktime; | |
+ vec2 epicninjaoldpos; | |
+ | |
// ninja | |
struct | |
{ | |
diff -Naur Coding/teeworlds/src/game/server/entities/projectile.cpp BBM/src/game/server/entities/projectile.cpp | |
--- Coding/teeworlds/src/game/server/entities/projectile.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/entities/projectile.cpp 2011-02-14 01:19:12.687685001 +1100 | |
@@ -75,8 +75,8 @@ | |
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); | |
+ //else if(TargetChr) | |
+ // TargetChr->TakeDamage(m_Direction * max(0.001f, m_Force), m_Damage, m_Owner, m_Weapon); | |
GameServer()->m_World.DestroyEntity(this); | |
} | |
diff -Naur Coding/teeworlds/src/game/server/gamecontext.cpp BBM/src/game/server/gamecontext.cpp | |
--- Coding/teeworlds/src/game/server/gamecontext.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/gamecontext.cpp 2011-02-16 00:11:38.836565002 +1100 | |
@@ -585,7 +585,61 @@ | |
*pMessage = ' '; | |
pMessage++; | |
} | |
- | |
+ CCharacter* pChr = pPlayer->GetCharacter(); | |
+ if(!str_comp_nocase(pMsg->m_pMessage, "/angry")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_ANGRY); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/blink") || !str_comp_nocase(pMsg->m_pMessage, "/close")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_BLINK); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/pain")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_PAIN); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/happy")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_HAPPY); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/surprise")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_SURPRISE); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/normal")) | |
+ { | |
+ pChr->SetEmoteType(EMOTE_NORMAL); | |
+ pChr->SetEmoteStop(Server()->Tick() + 9 * Server()->TickSpeed() * 999999 + Server()->TickSpeed() * (950478^995)); | |
+ } | |
+ else if(!str_comp_num(pMsg->m_pMessage, "/emote", 6)) | |
+ SendChatTarget(ClientID, "Emotes are as followed: /normal /surprise /happy /pain /blink /angry and /close"); | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/info")) | |
+ { | |
+ SendChatTarget(ClientID, "****Mod by \"[BBM]Julian->Assange\" and some great help by \"Learath\"****"); | |
+ SendChatTarget(ClientID, "Commands: /emote and /powerups"); | |
+ } | |
+ else if(!str_comp_nocase(pMsg->m_pMessage, "/powerups")) | |
+ { | |
+ SendChatTarget(ClientID, "********Powerups*********"); | |
+ char aBuf[256]; | |
+ char PUP_NAME[8][32]= {"Jump", "Hammer", "Plus Enemy Freeze Time", "Minus Self Freeze Time", "Hook Duration", "Hook Length", "Run", "Epic Ninja"}; | |
+ for(int i = 0; i < NUM_PUPS; i++) | |
+ { | |
+ str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->skills[i]); | |
+ SendChatTarget(ClientID, aBuf); | |
+ } | |
+ SendChatTarget(ClientID, "**************************"); | |
+ return; | |
+ } | |
+ else if(!str_comp_num(pMsg->m_pMessage, "/", 1)) | |
+ SendChatTarget(ClientID, "Invalid command! Do /info"); | |
+ else | |
SendChat(ClientID, Team, pMsg->m_pMessage); | |
} | |
else if(MsgID == NETMSGTYPE_CL_CALLVOTE) | |
@@ -756,9 +810,17 @@ | |
pPlayer->m_Last_ChangeInfo = Server()->Tick(); | |
- pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; | |
- pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; | |
- pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; | |
+ if (!pPlayer->forcecolor) { | |
+ pPlayer->origusecustcolor=pMsg->m_UseCustomColor; | |
+ pPlayer->origbodycolor=pMsg->m_ColorBody; | |
+ pPlayer->origfeetcolor=pMsg->m_ColorFeet; | |
+ } | |
+ pPlayer->m_TeeInfos.m_UseCustomColor = (pPlayer->forcecolor)?1:pMsg->m_UseCustomColor; | |
+ pPlayer->m_TeeInfos.m_ColorBody = (pPlayer->forcecolor)?pPlayer->forcecolor:pMsg->m_ColorBody; | |
+ pPlayer->m_TeeInfos.m_ColorFeet = (pPlayer->forcecolor)?pPlayer->forcecolor:pMsg->m_ColorFeet; | |
+ // pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; | |
+ //pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; | |
+ //pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; | |
// copy old name | |
char aOldName[MAX_NAME_LENGTH]; | |
@@ -803,7 +865,7 @@ | |
{ | |
CNetMsg_Cl_Emoticon *pMsg = (CNetMsg_Cl_Emoticon *)pRawMsg; | |
- if(g_Config.m_SvSpamprotection && pPlayer->m_Last_Emote && pPlayer->m_Last_Emote+Server()->TickSpeed()*3 > Server()->Tick()) | |
+ if(g_Config.m_SvSpamprotection && pPlayer->m_Last_Emote && pPlayer->m_Last_Emote+Server()->TickSpeed()*1 > Server()->Tick()) | |
return; | |
pPlayer->m_Last_Emote = Server()->Tick(); | |
@@ -817,7 +879,7 @@ | |
pPlayer->m_Last_Kill = Server()->Tick(); | |
pPlayer->KillCharacter(WEAPON_SELF); | |
- pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3; | |
+ //pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3; | |
} | |
} | |
diff -Naur Coding/teeworlds/src/game/server/gamecontext.h BBM/src/game/server/gamecontext.h | |
--- Coding/teeworlds/src/game/server/gamecontext.h 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/gamecontext.h 2011-02-14 04:01:36.151685002 +1100 | |
@@ -50,6 +50,7 @@ | |
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 ConEyeEmote(IConsole::IResult *pResult, void *pUserData); | |
static void ConSay(IConsole::IResult *pResult, void *pUserData); | |
static void ConSetTeam(IConsole::IResult *pResult, void *pUserData); | |
static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData); | |
@@ -72,6 +73,13 @@ | |
~CGameContext(); | |
void Clear(); | |
+ static void SendChatResponse(const char *pLine, void *pUser); | |
+ static void SendChatResponseAll(const char *pLine, void *pUser); | |
+ struct ChatResponseInfo | |
+ { | |
+ CGameContext *m_GameContext; | |
+ int m_To; | |
+ }; | |
CEventHandler m_Events; | |
CPlayer *m_apPlayers[MAX_CLIENTS]; | |
diff -Naur Coding/teeworlds/src/game/server/gamecontroller.cpp BBM/src/game/server/gamecontroller.cpp | |
--- Coding/teeworlds/src/game/server/gamecontroller.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/gamecontroller.cpp 2011-02-14 01:19:12.687685001 +1100 | |
@@ -320,7 +320,7 @@ | |
if(!pKiller || Weapon == WEAPON_GAME) | |
return 0; | |
if(pKiller == pVictim->GetPlayer()) | |
- pVictim->GetPlayer()->m_Score--; // suicide | |
+ {} //pVictim->GetPlayer()->m_Score--; // suicide | |
else | |
{ | |
if(IsTeamplay() && pVictim->GetPlayer()->GetTeam() == pKiller->GetTeam()) | |
diff -Naur Coding/teeworlds/src/game/server/gamemodes/mod.cpp BBM/src/game/server/gamemodes/mod.cpp | |
--- Coding/teeworlds/src/game/server/gamemodes/mod.cpp 2011-02-17 07:36:24.887621001 +1100 | |
+++ BBM/src/game/server/gamemodes/mod.cpp 2011-02-14 01:19:12.687685001 +1100 | |
@@ -7,7 +7,7 @@ | |
{ | |
// Exchange this to a string that identifies your game mode. | |
// DM, TDM and CTF are reserved for teeworlds original modes. | |
- m_pGameType = "MOD"; | |
+ m_pGameType = "BBM"; | |
//m_GameFlags = GAMEFLAG_TEAMS; // GAMEFLAG_TEAMS makes it a two-team gamemode | |
} | |
diff -Naur Coding/teeworlds/src/game/server/player.cpp BBM/src/game/server/player.cpp | |
--- Coding/teeworlds/src/game/server/player.cpp 2011-02-17 07:36:24.891621001 +1100 | |
+++ BBM/src/game/server/player.cpp 2011-02-14 04:01:36.151685002 +1100 | |
@@ -19,6 +19,7 @@ | |
this->m_ClientID = ClientID; | |
m_Team = GameServer()->m_pController->ClampTeam(Team); | |
m_LastActionTick = Server()->Tick(); | |
+ slot3 = 0; | |
} | |
CPlayer::~CPlayer() | |
diff -Naur Coding/teeworlds/src/game/server/player.h BBM/src/game/server/player.h | |
--- Coding/teeworlds/src/game/server/player.h 2011-02-17 07:36:24.891621001 +1100 | |
+++ BBM/src/game/server/player.h 2011-02-14 04:01:36.151685002 +1100 | |
@@ -38,6 +38,27 @@ | |
// this is used for snapping so we know how we can clip the view for the player | |
vec2 m_ViewPos; | |
+ int forcecolor; | |
+ | |
+ int origusecustcolor; | |
+ int origbodycolor; | |
+ int origfeetcolor; | |
+ int m_NoGreen; | |
+ int m_NoBlue; | |
+ int m_NoRed; | |
+ int m_NoWhite; | |
+ int m_NoGrey; | |
+ int m_NoYellow; | |
+ int m_NoPink; | |
+ | |
+ | |
+ int skills[NUM_PUPS]; | |
+ | |
+ int *slot3; | |
+ | |
+ int is1on1; | |
+ char *oname; | |
+ | |
// | |
int m_Vote; | |
int m_VotePos; | |
diff -Naur Coding/teeworlds/src/game/tuning.h BBM/src/game/tuning.h | |
--- Coding/teeworlds/src/game/tuning.h 2011-02-17 07:36:24.891621001 +1100 | |
+++ BBM/src/game/tuning.h 2011-02-14 01:19:12.687685001 +1100 | |
@@ -24,8 +24,8 @@ | |
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, 1000.0f) | |
MACRO_TUNING_PARAM(GunLifetime, gun_lifetime, 2.0f) | |
MACRO_TUNING_PARAM(ShotgunCurvature, shotgun_curvature, 1.25f) | |
diff -Naur Coding/teeworlds/src/game/variables.h BBM/src/game/variables.h | |
--- Coding/teeworlds/src/game/variables.h 2011-02-17 07:36:24.891621001 +1100 | |
+++ BBM/src/game/variables.h 2011-02-14 01:19:12.687685001 +1100 | |
@@ -60,13 +60,13 @@ | |
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, "mod", 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(SvInactiveKickTime, sv_inactivekick_time, 3, 0, 1000, CFGFLAG_SERVER, "How many minutes to wait before taking care of inactive players") | |
+MACRO_CONFIG_INT(SvInactiveKickTime, sv_inactivekick_time, 0, 0, 1000, CFGFLAG_SERVER, "How many minutes to wait before taking care of inactive players") | |
MACRO_CONFIG_INT(SvInactiveKick, sv_inactivekick, 1, 0, 2, CFGFLAG_SERVER, "How to deal with inactive players (0=move to spectator, 1=move to free spectator slot/kick, 2=kick)") | |
MACRO_CONFIG_INT(SvVoteKick, sv_vote_kick, 1, 0, 1, CFGFLAG_SERVER, "Allow voting to kick players") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment