Skip to content

Instantly share code, notes, and snippets.

@MegaManSec
Last active January 7, 2024 14:11
Show Gist options
  • Save MegaManSec/645a642a6149810a3a03 to your computer and use it in GitHub Desktop.
Save MegaManSec/645a642a6149810a3a03 to your computer and use it in GitHub Desktop.
Teeworlds BBM Mod Trunk
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