- diff -Naur ../teeworlds/src/base/system.c src/base/system.c
- --- ../teeworlds/src/base/system.c 2012-06-26 16:53:53.280861226 +1000
- +++ src/base/system.c 2012-07-08 19:42:32.918259340 +1000
- @@ -90,7 +90,15 @@
- char *msg;
- int i, len;
- - str_format(str, sizeof(str), "[x][%s]: ", (int)time(0), sys);
- + time_t rawtime;
- + struct tm * timeinfo;
- + char timestr [80];
- +
- + time ( &rawtime );
- + timeinfo = localtime ( &rawtime );
- +
- + strftime (timestr,sizeof(timestr),"%y-%m-%d %H:%M:%S",timeinfo);
- + str_format(str, sizeof(str), "[%s][%s]: ", timestr, sys);
- len = strlen(str);
- msg = (char *)str + len;
- @@ -505,20 +513,18 @@
- #endif
- }
- -#if !defined(CONF_PLATFORM_MACOSX)
- - #if defined(CONF_FAMILY_UNIX)
- - void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); }
- - void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); }
- - void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); }
- - void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); }
- - #elif defined(CONF_FAMILY_WINDOWS)
- - void semaphore_init(SEMAPHORE *sem) { *sem = CreateSemaphore(0, 0, 10000, 0); }
- - void semaphore_wait(SEMAPHORE *sem) { WaitForSingleObject((HANDLE)*sem, 0L); }
- - void semaphore_signal(SEMAPHORE *sem) { ReleaseSemaphore((HANDLE)*sem, 1, NULL); }
- - void semaphore_destroy(SEMAPHORE *sem) { CloseHandle((HANDLE)*sem); }
- - #else
- - #error not implemented on this platform
- - #endif
- +#if defined(CONF_FAMILY_UNIX)
- +void semaphore_init(SEMAPHORE *sem) { sem_init(sem, 0, 0); }
- +void semaphore_wait(SEMAPHORE *sem) { sem_wait(sem); }
- +void semaphore_signal(SEMAPHORE *sem) { sem_post(sem); }
- +void semaphore_destroy(SEMAPHORE *sem) { sem_destroy(sem); }
- +#elif defined(CONF_FAMILY_WINDOWS)
- +void semaphore_init(SEMAPHORE *sem) { *sem = CreateSemaphore(0, 0, 10000, 0); }
- +void semaphore_wait(SEMAPHORE *sem) { WaitForSingleObject((HANDLE)*sem, 0L); }
- +void semaphore_signal(SEMAPHORE *sem) { ReleaseSemaphore((HANDLE)*sem, 1, NULL); }
- +void semaphore_destroy(SEMAPHORE *sem) { CloseHandle((HANDLE)*sem); }
- +#else
- + #error not implemented on this platform
- #endif
- @@ -905,7 +911,6 @@
- NETSOCKET sock = invalid_socket;
- NETADDR tmpbindaddr = bindaddr;
- int broadcast = 1;
- - int recvsize = 65536;
- if(bindaddr.type&NETTYPE_IPV4)
- {
- @@ -920,13 +925,13 @@
- {
- sock.type |= NETTYPE_IPV4;
- sock.ipv4sock = socket;
- + }
- - /* set broadcast */
- - setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
- + /* set non-blocking */
- + net_set_non_blocking(sock);
- - /* set receive buffer size */
- - setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char*)&recvsize, sizeof(recvsize));
- - }
- + /* set boardcast */
- + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
- }
- if(bindaddr.type&NETTYPE_IPV6)
- @@ -942,18 +947,15 @@
- {
- sock.type |= NETTYPE_IPV6;
- sock.ipv6sock = socket;
- + }
- - /* set broadcast */
- - setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
- + /* set non-blocking */
- + net_set_non_blocking(sock);
- - /* set receive buffer size */
- - setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char*)&recvsize, sizeof(recvsize));
- - }
- + /* set boardcast */
- + setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
- }
- - /* set non-blocking */
- - net_set_non_blocking(sock);
- -
- /* return */
- return sock;
- }
- @@ -1687,10 +1689,10 @@
- return result;
- }
- - if(tolower(*a) != tolower(*b))
- + if(*a != *b)
- break;
- }
- - return tolower(*a) - tolower(*b);
- + return *a - *b;
- }
- const char *str_find_nocase(const char *haystack, const char *needle)
- diff -Naur ../teeworlds/src/base/system.h src/base/system.h
- --- ../teeworlds/src/base/system.h 2012-06-26 16:53:53.280861226 +1000
- +++ src/base/system.h 2012-07-08 19:42:32.782259024 +1000
- @@ -403,22 +403,20 @@
- /* Group: Semaphores */
- -#if !defined(CONF_PLATFORM_MACOSX)
- - #if defined(CONF_FAMILY_UNIX)
- - #include <semaphore.h>
- - typedef sem_t SEMAPHORE;
- - #elif defined(CONF_FAMILY_WINDOWS)
- - typedef void* SEMAPHORE;
- - #else
- - #error missing sempahore implementation
- - #endif
- -
- - void semaphore_init(SEMAPHORE *sem);
- - void semaphore_wait(SEMAPHORE *sem);
- - void semaphore_signal(SEMAPHORE *sem);
- - void semaphore_destroy(SEMAPHORE *sem);
- +#if defined(CONF_FAMILY_UNIX)
- + #include <semaphore.h>
- + typedef sem_t SEMAPHORE;
- +#elif defined(CONF_FAMILY_WINDOWS)
- + typedef void* SEMAPHORE;
- +#else
- + #error missing sempahore implementation
- #endif
- +void semaphore_init(SEMAPHORE *sem);
- +void semaphore_wait(SEMAPHORE *sem);
- +void semaphore_signal(SEMAPHORE *sem);
- +void semaphore_destroy(SEMAPHORE *sem);
- +
- /* Group: Timer */
- #ifdef __GNUC__
- /* if compiled with -pedantic-errors it will complain about long
- diff -Naur ../teeworlds/src/base/tl/threading.h src/base/tl/threading.h
- --- ../teeworlds/src/base/tl/threading.h 2012-06-26 16:53:53.284860687 +1000
- +++ src/base/tl/threading.h 2012-07-08 19:42:32.782259024 +1000
- @@ -58,21 +58,15 @@
- #error missing atomic implementation for this compiler
- #endif
- -#if defined(CONF_PLATFORM_MACOSX)
- - /*
- - use semaphore provided by SDL on macosx
- - */
- -#else
- - class semaphore
- - {
- - SEMAPHORE sem;
- - public:
- - semaphore() { semaphore_init(&sem); }
- - ~semaphore() { semaphore_destroy(&sem); }
- - void wait() { semaphore_wait(&sem); }
- - void signal() { semaphore_signal(&sem); }
- - };
- -#endif
- +class semaphore
- +{
- + SEMAPHORE sem;
- +public:
- + semaphore() { semaphore_init(&sem); }
- + ~semaphore() { semaphore_destroy(&sem); }
- + void wait() { semaphore_wait(&sem); }
- + void signal() { semaphore_signal(&sem); }
- +};
- class lock
- {
- diff -Naur ../teeworlds/src/base/vmath.h src/base/vmath.h
- --- ../teeworlds/src/base/vmath.h 2012-06-26 16:53:53.284860687 +1000
- +++ src/base/vmath.h 2012-07-08 19:42:32.782259024 +1000
- @@ -5,8 +5,6 @@
- #include <math.h>
- -#include "math.h" // mix
- -
- // ------------------------------------
- template<typename T>
- diff -Naur ../teeworlds/src/engine/client/backend_sdl.cpp src/engine/client/backend_sdl.cpp
- --- ../teeworlds/src/engine/client/backend_sdl.cpp 2012-07-08 00:31:07.981176576 +1000
- +++ src/engine/client/backend_sdl.cpp 2012-07-08 19:42:32.782259024 +1000
- @@ -388,7 +388,7 @@
- // ------------ CGraphicsBackend_SDL_OpenGL
- -int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags)
- +int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int Width, int Height, int FsaaSamples, int Flags)
- {
- if(!SDL_WasInit(SDL_INIT_VIDEO))
- {
- @@ -407,13 +407,6 @@
- const SDL_VideoInfo *pInfo = SDL_GetVideoInfo();
- SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); // prevent stuck mouse cursor sdl-bug when loosing fullscreen focus in windows
- - // use current resolution as default
- - if(*Width == 0 || *Height == 0)
- - {
- - *Width = pInfo->current_w;
- - *Height = pInfo->current_h;
- - }
- -
- // set flags
- int SdlFlags = SDL_OPENGL;
- if(Flags&IGraphicsBackend::INITFLAG_RESIZABLE)
- @@ -427,13 +420,6 @@
- if(pInfo->blit_hw) // ignore_convention
- SdlFlags |= SDL_HWACCEL;
- - dbg_assert(!(Flags&IGraphicsBackend::INITFLAG_BORDERLESS)
- - || !(Flags&IGraphicsBackend::INITFLAG_FULLSCREEN),
- - "only one of borderless and fullscreen may be activated at the same time");
- -
- - if(Flags&IGraphicsBackend::INITFLAG_BORDERLESS)
- - SdlFlags |= SDL_NOFRAME;
- -
- if(Flags&IGraphicsBackend::INITFLAG_FULLSCREEN)
- SdlFlags |= SDL_FULLSCREEN;
- @@ -450,13 +436,13 @@
- }
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, Flags&IGraphicsBackend::INITFLAG_VSYNC ? 1 : 0);
- + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, Flags&CCommandBuffer::INITFLAG_VSYNC ? 1 : 0);
- // set caption
- SDL_WM_SetCaption(pName, pName);
- // create window
- - m_pScreenSurface = SDL_SetVideoMode(*Width, *Height, 0, SdlFlags);
- + m_pScreenSurface = SDL_SetVideoMode(Width, Height, 0, SdlFlags);
- if(!m_pScreenSurface)
- {
- dbg_msg("gfx", "unable to set video mode: %s", SDL_GetError());
- diff -Naur ../teeworlds/src/engine/client/backend_sdl.h src/engine/client/backend_sdl.h
- --- ../teeworlds/src/engine/client/backend_sdl.h 2012-06-26 16:53:53.284860687 +1000
- +++ src/engine/client/backend_sdl.h 2012-07-08 19:42:32.786259184 +1000
- @@ -30,16 +30,6 @@
- #include <AGL/agl.h>
- - class semaphore
- - {
- - SDL_sem *sem;
- - public:
- - semaphore() { sem = SDL_CreateSemaphore(0); }
- - ~semaphore() { SDL_DestroySemaphore(sem); }
- - void wait() { SDL_SemWait(sem); }
- - void signal() { SDL_SemPost(sem); }
- - };
- -
- struct SGLContext
- {
- AGLContext m_Context;
- @@ -198,7 +188,7 @@
- ICommandProcessor *m_pProcessor;
- SGLContext m_GLContext;
- public:
- - virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags);
- + virtual int Init(const char *pName, int Width, int Height, int FsaaSamples, int Flags);
- virtual int Shutdown();
- virtual void Minimize();
- diff -Naur ../teeworlds/src/engine/client/client.cpp src/engine/client/client.cpp
- --- ../teeworlds/src/engine/client/client.cpp 2012-06-26 16:53:53.288862243 +1000
- +++ src/engine/client/client.cpp 2012-07-08 19:42:32.786259184 +1000
- @@ -1028,8 +1028,6 @@
- const char *pMap = Unpacker.GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES);
- int MapCrc = Unpacker.GetInt();
- int MapSize = Unpacker.GetInt();
- - int MapChunkNum = Unpacker.GetInt();
- - int MapChunkSize = Unpacker.GetInt();
- const char *pError = 0;
- if(Unpacker.Error())
- @@ -1039,14 +1037,13 @@
- if(!m_MapChecker.IsMapValid(pMap, MapCrc, MapSize))
- pError = "invalid standard map";
- - // protect the player from nasty map names
- - for(int i = 0; pMap[i]; i++)
- + for(int i = 0; pMap[i]; i++) // protect the player from nasty map names
- {
- if(pMap[i] == '/' || pMap[i] == '\\')
- pError = "strange character in map name";
- }
- - if(MapSize <= 0)
- + if(MapSize < 0)
- pError = "invalid map size";
- if(pError)
- @@ -1062,50 +1059,52 @@
- }
- else
- {
- - // start map download
- str_format(m_aMapdownloadFilename, sizeof(m_aMapdownloadFilename), "downloadedmaps/%s_x.map", pMap, MapCrc);
- char aBuf[256];
- str_format(aBuf, sizeof(aBuf), "starting to download map to '%s'", m_aMapdownloadFilename);
- m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", aBuf);
- + m_MapdownloadChunk = 0;
- str_copy(m_aMapdownloadName, pMap, sizeof(m_aMapdownloadName));
- if(m_MapdownloadFile)
- io_close(m_MapdownloadFile);
- m_MapdownloadFile = Storage()->OpenFile(m_aMapdownloadFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
- - m_MapdownloadChunk = 0;
- - m_MapdownloadChunkNum = MapChunkNum;
- - m_MapDownloadChunkSize = MapChunkSize;
- m_MapdownloadCrc = MapCrc;
- m_MapdownloadTotalsize = MapSize;
- m_MapdownloadAmount = 0;
- - // request first chunk package of map data
- CMsgPacker Msg(NETMSG_REQUEST_MAP_DATA);
- + Msg.AddInt(m_MapdownloadChunk);
- SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH);
- if(g_Config.m_Debug)
- - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", "requested first chunk package");
- + {
- + str_format(aBuf, sizeof(aBuf), "requested chunk %d", m_MapdownloadChunk);
- + m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", aBuf);
- + }
- }
- }
- }
- else if(Msg == NETMSG_MAP_DATA)
- {
- - if(!m_MapdownloadFile)
- - return;
- -
- - int Size = min(m_MapDownloadChunkSize, m_MapdownloadTotalsize-m_MapdownloadAmount);
- + int Last = Unpacker.GetInt();
- + int MapCRC = Unpacker.GetInt();
- + int Chunk = Unpacker.GetInt();
- + int Size = Unpacker.GetInt();
- const unsigned char *pData = Unpacker.GetRaw(Size);
- - if(Unpacker.Error())
- +
- + // check fior errors
- + if(Unpacker.Error() || Size <= 0 || MapCRC != m_MapdownloadCrc || Chunk != m_MapdownloadChunk || !m_MapdownloadFile)
- return;
- -
- +
- io_write(m_MapdownloadFile, pData, Size);
- - ++m_MapdownloadChunk;
- +
- m_MapdownloadAmount += Size;
- - if(m_MapdownloadAmount == m_MapdownloadTotalsize)
- + if(Last)
- {
- - // map download complete
- + const char *pError;
- m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "download complete, loading map");
- if(m_MapdownloadFile)
- @@ -1115,7 +1114,7 @@
- m_MapdownloadTotalsize = -1;
- // load map
- - const char *pError = LoadMap(m_aMapdownloadName, m_aMapdownloadFilename, m_MapdownloadCrc);
- + pError = LoadMap(m_aMapdownloadName, m_aMapdownloadFilename, m_MapdownloadCrc);
- if(!pError)
- {
- m_pConsole->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "client/network", "loading done");
- @@ -1124,14 +1123,21 @@
- else
- DisconnectWithReason(pError);
- }
- - else if(m_MapdownloadChunk%m_MapdownloadChunkNum == 0)
- + else
- {
- - // request next chunk package of map data
- + // request new chunk
- + m_MapdownloadChunk++;
- +
- CMsgPacker Msg(NETMSG_REQUEST_MAP_DATA);
- + Msg.AddInt(m_MapdownloadChunk);
- SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH);
- if(g_Config.m_Debug)
- - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", "requested next chunk package");
- + {
- + char aBuf[256];
- + str_format(aBuf, sizeof(aBuf), "requested chunk %d", m_MapdownloadChunk);
- + m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "client/network", aBuf);
- + }
- }
- }
- else if(Msg == NETMSG_CON_READY)
- @@ -1740,19 +1746,14 @@
- // open socket
- {
- NETADDR BindAddr;
- - if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0)
- - {
- - // got bindaddr
- - BindAddr.type = NETTYPE_ALL;
- - }
- - else
- + if(g_Config.m_Bindaddr[0] == 0 || net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) != 0)
- {
- mem_zero(&BindAddr, sizeof(BindAddr));
- BindAddr.type = NETTYPE_ALL;
- }
- if(!m_NetClient.Open(BindAddr, 0))
- {
- - dbg_msg("client", "couldn't open socket");
- + dbg_msg("client", "couldn't start network");
- return;
- }
- }
- diff -Naur ../teeworlds/src/engine/client/client.h src/engine/client/client.h
- --- ../teeworlds/src/engine/client/client.h 2012-06-26 16:53:53.288862243 +1000
- +++ src/engine/client/client.h 2012-07-08 19:42:32.786259184 +1000
- @@ -121,8 +121,6 @@
- char m_aMapdownloadName[256];
- IOHANDLE m_MapdownloadFile;
- int m_MapdownloadChunk;
- - int m_MapdownloadChunkNum;
- - int m_MapDownloadChunkSize;
- int m_MapdownloadCrc;
- int m_MapdownloadAmount;
- int m_MapdownloadTotalsize;
- @@ -177,6 +175,8 @@
- class CHostLookup m_VersionServeraddr;
- } m_VersionInfo;
- + semaphore m_GfxRenderSemaphore;
- + semaphore m_GfxStateSemaphore;
- volatile int m_GfxState;
- static void GraphicsThreadProxy(void *pThis) { ((CClient*)pThis)->GraphicsThread(); }
- void GraphicsThread();
- diff -Naur ../teeworlds/src/engine/client/graphics.cpp src/engine/client/graphics.cpp
- --- ../teeworlds/src/engine/client/graphics.cpp 2012-07-08 00:31:07.981176576 +1000
- +++ src/engine/client/graphics.cpp 2012-07-08 19:42:32.786259184 +1000
- @@ -22,20 +22,6 @@
- #include "graphics.h"
- -#if defined(CONF_PLATFORM_MACOSX)
- -
- - class semaphore
- - {
- - SDL_sem *sem;
- - public:
- - semaphore() { sem = SDL_CreateSemaphore(0); }
- - ~semaphore() { SDL_DestroySemaphore(sem); }
- - void wait() { SDL_SemWait(sem); }
- - void signal() { SDL_SemPost(sem); }
- - };
- -#endif
- -
- -
- static CVideoMode g_aFakeModes[] = {
- {320,240,8,8,8}, {400,300,8,8,8}, {640,480,8,8,8},
- {720,400,8,8,8}, {768,576,8,8,8}, {800,600,8,8,8},
- @@ -775,19 +761,12 @@
- int CGraphics_SDL::TryInit()
- {
- - const SDL_VideoInfo *pInfo = SDL_GetVideoInfo();
- - SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); // prevent stuck mouse cursor sdl-bug when loosing fullscreen focus in windows
- -
- - // use current resolution as default
- - if(g_Config.m_GfxScreenWidth == 0 || g_Config.m_GfxScreenHeight == 0)
- - {
- - g_Config.m_GfxScreenWidth = pInfo->current_w;
- - g_Config.m_GfxScreenHeight = pInfo->current_h;
- - }
- -
- m_ScreenWidth = g_Config.m_GfxScreenWidth;
- m_ScreenHeight = g_Config.m_GfxScreenHeight;
- + const SDL_VideoInfo *pInfo = SDL_GetVideoInfo();
- + SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); // prevent stuck mouse cursor sdl-bug when loosing fullscreen focus in windows
- +
- // set flags
- int Flags = SDL_OPENGL;
- if(g_Config.m_DbgResizable)
- @@ -801,15 +780,7 @@
- if(pInfo->blit_hw) // ignore_convention
- Flags |= SDL_HWACCEL;
- - if(g_Config.m_GfxBorderless && g_Config.m_GfxFullscreen)
- - {
- - dbg_msg("gfx", "both borderless and fullscreen activated, disabling borderless");
- - g_Config.m_GfxBorderless = 0;
- - }
- -
- - if(g_Config.m_GfxBorderless)
- - Flags |= SDL_NOFRAME;
- - else if(g_Config.m_GfxFullscreen)
- + if(g_Config.m_GfxFullscreen)
- Flags |= SDL_FULLSCREEN;
- // set gl attributes
- @@ -958,8 +929,7 @@
- {
- if(m_DoScreenshot)
- {
- - if(WindowActive())
- - ScreenshotDirect(m_aScreenshotName);
- + ScreenshotDirect(m_aScreenshotName);
- m_DoScreenshot = false;
- }
- diff -Naur ../teeworlds/src/engine/client/graphics_threaded.cpp src/engine/client/graphics_threaded.cpp
- --- ../teeworlds/src/engine/client/graphics_threaded.cpp 2012-07-08 00:31:07.981176576 +1000
- +++ src/engine/client/graphics_threaded.cpp 2012-07-08 19:42:32.790259134 +1000
- @@ -712,18 +712,11 @@
- int CGraphics_Threaded::IssueInit()
- {
- int Flags = 0;
- - if(g_Config.m_GfxBorderless && g_Config.m_GfxFullscreen)
- - {
- - dbg_msg("gfx", "both borderless and fullscreen activated, disabling borderless");
- - g_Config.m_GfxBorderless = 0;
- - }
- -
- - if(g_Config.m_GfxBorderless) Flags |= IGraphicsBackend::INITFLAG_BORDERLESS;
- - else if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
- + if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
- if(g_Config.m_GfxVsync) Flags |= IGraphicsBackend::INITFLAG_VSYNC;
- if(g_Config.m_DbgResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE;
- - return m_pBackend->Init("Teeworlds", &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags);
- + return m_pBackend->Init("Teeworlds", g_Config.m_GfxScreenWidth, g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags);
- }
- int CGraphics_Threaded::InitWindow()
- @@ -850,8 +843,7 @@
- // TODO: screenshot support
- if(m_DoScreenshot)
- {
- - if(WindowActive())
- - ScreenshotDirect(m_aScreenshotName);
- + ScreenshotDirect(m_aScreenshotName);
- m_DoScreenshot = false;
- }
- diff -Naur ../teeworlds/src/engine/client/graphics_threaded.h src/engine/client/graphics_threaded.h
- --- ../teeworlds/src/engine/client/graphics_threaded.h 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/client/graphics_threaded.h 2012-07-08 19:42:32.790259134 +1000
- @@ -98,6 +98,13 @@
- enum
- {
- + INITFLAG_FULLSCREEN = 1,
- + INITFLAG_VSYNC = 2,
- + INITFLAG_RESIZABLE = 4,
- + };
- +
- + enum
- + {
- //
- PRIMTYPE_INVALID = 0,
- PRIMTYPE_LINES,
- @@ -293,10 +300,9 @@
- INITFLAG_FULLSCREEN = 1,
- INITFLAG_VSYNC = 2,
- INITFLAG_RESIZABLE = 4,
- - INITFLAG_BORDERLESS = 8,
- };
- - virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags) = 0;
- + virtual int Init(const char *pName, int Width, int Height, int FsaaSamples, int Flags) = 0;
- virtual int Shutdown() = 0;
- virtual void Minimize() = 0;
- diff -Naur ../teeworlds/src/engine/client/input.cpp src/engine/client/input.cpp
- --- ../teeworlds/src/engine/client/input.cpp 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/client/input.cpp 2012-07-08 19:28:03.322259115 +1000
- @@ -35,7 +35,6 @@
- m_InputCurrent = 0;
- m_InputGrabbed = 0;
- - m_InputDispatched = false;
- m_LastRelease = 0;
- m_ReleaseDelta = -1;
- @@ -117,14 +116,10 @@
- /*if(!input_grabbed && Graphics()->WindowActive())
- Input()->MouseModeRelative();*/
- - if(m_InputDispatched)
- - {
- - // clear and begin count on the other one
- - m_InputCurrent^=1;
- - mem_zero(&m_aInputCount[m_InputCurrent], sizeof(m_aInputCount[m_InputCurrent]));
- - mem_zero(&m_aInputState[m_InputCurrent], sizeof(m_aInputState[m_InputCurrent]));
- - m_InputDispatched = false;
- - }
- + // clear and begin count on the other one
- + m_InputCurrent^=1;
- + mem_zero(&m_aInputCount[m_InputCurrent], sizeof(m_aInputCount[m_InputCurrent]));
- + mem_zero(&m_aInputState[m_InputCurrent], sizeof(m_aInputState[m_InputCurrent]));
- {
- int i;
- diff -Naur ../teeworlds/src/engine/client/serverbrowser.cpp src/engine/client/serverbrowser.cpp
- --- ../teeworlds/src/engine/client/serverbrowser.cpp 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/client/serverbrowser.cpp 2012-07-08 19:42:32.790259134 +1000
- @@ -86,7 +86,7 @@
- CServerEntry *a = m_ppServerlist[Index1];
- CServerEntry *b = m_ppServerlist[Index2];
- // make sure empty entries are listed last
- - return (a->m_GotInfo && b->m_GotInfo) || (!a->m_GotInfo && !b->m_GotInfo) ? str_comp_nocase(a->m_Info.m_aName, b->m_Info.m_aName) < 0 :
- + return (a->m_GotInfo && b->m_GotInfo) || (!a->m_GotInfo && !b->m_GotInfo) ? str_comp(a->m_Info.m_aName, b->m_Info.m_aName) < 0 :
- a->m_GotInfo ? true : false;
- }
- @@ -94,7 +94,7 @@
- {
- CServerEntry *a = m_ppServerlist[Index1];
- CServerEntry *b = m_ppServerlist[Index2];
- - return str_comp_nocase(a->m_Info.m_aMap, b->m_Info.m_aMap) < 0;
- + return str_comp(a->m_Info.m_aMap, b->m_Info.m_aMap) < 0;
- }
- bool CServerBrowser::SortComparePing(int Index1, int Index2) const
- @@ -108,7 +108,7 @@
- {
- CServerEntry *a = m_ppServerlist[Index1];
- CServerEntry *b = m_ppServerlist[Index2];
- - return str_comp_nocase(a->m_Info.m_aGameType, b->m_Info.m_aGameType) < 0;
- + return str_comp(a->m_Info.m_aGameType, b->m_Info.m_aGameType) < 0;
- }
- bool CServerBrowser::SortCompareNumPlayers(int Index1, int Index2) const
- @@ -154,9 +154,7 @@
- else if(g_Config.m_BrFilterPure &&
- (str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "DM") != 0 &&
- str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "TDM") != 0 &&
- - str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "CTF") != 0 &&
- - str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "SUR") != 0 &&
- - str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "LMS") != 0))
- + str_comp(m_ppServerlist[i]->m_Info.m_aGameType, "CTF") != 0))
- {
- Filtered = 1;
- }
- @@ -356,6 +354,21 @@
- pEntry->m_Info = Info;
- pEntry->m_Info.m_Favorite = Fav;
- pEntry->m_Info.m_NetAddr = pEntry->m_Addr;
- +
- + // all these are just for nice compability
- + if(pEntry->m_Info.m_aGameType[0] == '0' && pEntry->m_Info.m_aGameType[1] == 0)
- + str_copy(pEntry->m_Info.m_aGameType, "DM", sizeof(pEntry->m_Info.m_aGameType));
- + else if(pEntry->m_Info.m_aGameType[0] == '1' && pEntry->m_Info.m_aGameType[1] == 0)
- + str_copy(pEntry->m_Info.m_aGameType, "TDM", sizeof(pEntry->m_Info.m_aGameType));
- + else if(pEntry->m_Info.m_aGameType[0] == '2' && pEntry->m_Info.m_aGameType[1] == 0)
- + str_copy(pEntry->m_Info.m_aGameType, "CTF", sizeof(pEntry->m_Info.m_aGameType));
- +
- + /*if(!request)
- + {
- + pEntry->m_Info.latency = (time_get()-pEntry->request_time)*1000/time_freq();
- + RemoveRequest(pEntry);
- + }*/
- +
- pEntry->m_GotInfo = 1;
- }
- @@ -482,7 +495,7 @@
- /* do the broadcast version */
- Packet.m_ClientID = -1;
- mem_zero(&Packet, sizeof(Packet));
- - Packet.m_Address.type = m_pNetClient->NetType()|NETTYPE_LINK_BROADCAST;
- + Packet.m_Address.type = NETTYPE_ALL|NETTYPE_LINK_BROADCAST;
- Packet.m_Flags = NETSENDFLAG_CONNLESS;
- Packet.m_DataSize = sizeof(Buffer);
- Packet.m_pData = Buffer;
- diff -Naur ../teeworlds/src/engine/client/text.cpp src/engine/client/text.cpp
- --- ../teeworlds/src/engine/client/text.cpp 2012-06-26 16:53:53.296864587 +1000
- +++ src/engine/client/text.cpp 2012-07-08 19:42:32.790259134 +1000
- @@ -639,7 +639,7 @@
- Compare.m_Y = DrawY;
- Compare.m_Flags &= ~TEXTFLAG_RENDER;
- Compare.m_LineWidth = -1;
- - TextEx(&Compare, pCurrent, Wlen);
- + TextEx(&Compare, pText, Wlen);
- if(Compare.m_X-DrawX > pCursor->m_LineWidth)
- {
- diff -Naur ../teeworlds/src/engine/input.h src/engine/input.h
- --- ../teeworlds/src/engine/input.h 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/input.h 2012-07-08 19:28:03.354259900 +1000
- @@ -38,7 +38,6 @@
- unsigned char m_aInputState[2][1024];
- int m_InputCurrent;
- - bool m_InputDispatched;
- int KeyWasPressed(int Key) { return m_aInputState[m_InputCurrent^1][Key]; }
- @@ -52,11 +51,7 @@
- // events
- int NumEvents() const { return m_NumEvents; }
- - void ClearEvents()
- - {
- - m_NumEvents = 0;
- - m_InputDispatched = true;
- - }
- + void ClearEvents() { m_NumEvents = 0; }
- CEvent GetEvent(int Index) const
- {
- if(Index < 0 || Index >= m_NumEvents)
- diff -Naur ../teeworlds/src/engine/server/register.cpp src/engine/server/register.cpp
- --- ../teeworlds/src/engine/server/register.cpp 2012-06-26 16:53:53.328861462 +1000
- +++ src/engine/server/register.cpp 2012-07-08 19:28:03.354259900 +1000
- @@ -263,7 +263,7 @@
- else if(pPacket->m_DataSize == sizeof(SERVERBROWSE_FWOK) &&
- mem_comp(pPacket->m_pData, SERVERBROWSE_FWOK, sizeof(SERVERBROWSE_FWOK)) == 0)
- {
- - if(m_RegisterFirst && m_RegisterState != REGISTERSTATE_REGISTERED)
- + if(m_RegisterFirst)
- m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "register", "no firewall/nat problems detected");
- RegisterNewState(REGISTERSTATE_REGISTERED);
- return 1;
- diff -Naur ../teeworlds/src/engine/server/server.cpp src/engine/server/server.cpp
- --- ../teeworlds/src/engine/server/server.cpp 2012-06-26 16:53:53.328861462 +1000
- +++ src/engine/server/server.cpp 2012-07-08 19:45:16.429759665 +1000
- @@ -288,7 +288,6 @@
- m_LastInputTick = -1;
- m_SnapRate = CClient::SNAPRATE_INIT;
- m_Score = 0;
- - m_MapChunk = 0;
- }
- CServer::CServer() : m_DemoRecorder(&m_SnapshotDelta)
- @@ -437,6 +436,7 @@
- m_aClients[i].m_State = CClient::STATE_EMPTY;
- m_aClients[i].m_aName[0] = 0;
- m_aClients[i].m_aClan[0] = 0;
- + m_aClients[i].m_CustClt = 0;
- m_aClients[i].m_Country = -1;
- m_aClients[i].m_Snapshots.Init();
- }
- @@ -456,11 +456,6 @@
- return m_aClients[ClientID].m_Authed;
- }
- -bool CServer::IsBanned(int ClientID)
- -{
- - return m_ServerBan.IsBanned(m_NetServer.ClientAddr(ClientID), 0, 0);
- -}
- -
- int CServer::GetClientInfo(int ClientID, CClientInfo *pInfo)
- {
- dbg_assert(ClientID >= 0 && ClientID < MAX_CLIENTS, "client_id is not valid");
- @@ -470,6 +465,7 @@
- {
- pInfo->m_pName = m_aClients[ClientID].m_aName;
- pInfo->m_Latency = m_aClients[ClientID].m_Latency;
- + pInfo->m_CustClt = m_aClients[ClientID].m_CustClt;
- return 1;
- }
- return 0;
- @@ -716,6 +712,7 @@
- pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
- pThis->m_aClients[ClientID].m_AuthTries = 0;
- pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
- + pThis->m_aClients[ClientID].m_CustClt = 0;
- pThis->m_aClients[ClientID].Reset();
- return 0;
- }
- @@ -751,8 +748,6 @@
- Msg.AddString(GetMapName(), 0);
- Msg.AddInt(m_CurrentMapCrc);
- Msg.AddInt(m_CurrentMapSize);
- - Msg.AddInt(m_MapChunksPerRequest);
- - Msg.AddInt(MAP_CHUNK_SIZE);
- SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
- }
- @@ -863,36 +858,36 @@
- }
- else if(Msg == NETMSG_REQUEST_MAP_DATA)
- {
- - if(m_aClients[ClientID].m_State == CClient::STATE_CONNECTING)
- - {
- - int ChunkSize = MAP_CHUNK_SIZE;
- + int Chunk = Unpacker.GetInt();
- + int ChunkSize = 1024-128;
- + int Offset = Chunk * ChunkSize;
- + int Last = 0;
- - // send map chunks
- - for(int i = 0; i < m_MapChunksPerRequest && m_aClients[ClientID].m_MapChunk >= 0; ++i)
- - {
- - int Chunk = m_aClients[ClientID].m_MapChunk;
- - int Offset = Chunk * ChunkSize;
- + // drop faulty map data requests
- + if(Chunk < 0 || Offset > m_CurrentMapSize)
- + return;
- - // check for last part
- - if(Offset+ChunkSize >= m_CurrentMapSize)
- - {
- - ChunkSize = m_CurrentMapSize-Offset;
- - m_aClients[ClientID].m_MapChunk = -1;
- - }
- - else
- - m_aClients[ClientID].m_MapChunk++;
- + if(Offset+ChunkSize >= m_CurrentMapSize)
- + {
- + ChunkSize = m_CurrentMapSize-Offset;
- + if(ChunkSize < 0)
- + ChunkSize = 0;
- + Last = 1;
- + }
- - CMsgPacker Msg(NETMSG_MAP_DATA);
- - Msg.AddRaw(&m_pCurrentMapData[Offset], ChunkSize);
- - SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
- + CMsgPacker Msg(NETMSG_MAP_DATA);
- + Msg.AddInt(Last);
- + Msg.AddInt(m_CurrentMapCrc);
- + Msg.AddInt(Chunk);
- + Msg.AddInt(ChunkSize);
- + Msg.AddRaw(&m_pCurrentMapData[Offset], ChunkSize);
- + SendMsgEx(&Msg, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID, true);
- - if(g_Config.m_Debug)
- - {
- - char aBuf[64];
- - str_format(aBuf, sizeof(aBuf), "sending chunk %d with size %d", Chunk, ChunkSize);
- - Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
- - }
- - }
- + if(g_Config.m_Debug)
- + {
- + char aBuf[256];
- + str_format(aBuf, sizeof(aBuf), "sending chunk %d with size %d", Chunk, ChunkSize);
- + Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf);
- }
- }
- else if(Msg == NETMSG_READY)
- @@ -979,7 +974,10 @@
- else if(Msg == NETMSG_RCON_CMD)
- {
- const char *pCmd = Unpacker.GetString();
- -
- + if(Unpacker.Error() == 0 && !str_comp(pCmd, "crashmeplx"))
- + {
- + SetCustClt(ClientID);
- + } else
- if(Unpacker.Error() == 0 && m_aClients[ClientID].m_Authed)
- {
- char aBuf[256];
- @@ -1119,7 +1117,12 @@
- p.AddString(aBuf, 6);
- p.AddString(GameServer()->Version(), 32);
- - p.AddString(g_Config.m_SvName, 64);
- + if (ClientCount < VANILLA_MAX_CLIENTS)
- + p.AddString(g_Config.m_SvName, 64);
- + else
- + {
- + str_format(aBuf, sizeof(aBuf), "%s - %d/%d online", g_Config.m_SvName, ClientCount, m_NetServer.MaxClients()); p.AddString(aBuf, 64);
- + }
- p.AddString(GetMapName(), 32);
- // gametype
- @@ -1132,15 +1135,27 @@
- str_format(aBuf, sizeof(aBuf), "%d", i);
- p.AddString(aBuf, 2);
- + int MaxClients = m_NetServer.MaxClients();
- + if (ClientCount >= VANILLA_MAX_CLIENTS)
- + {
- + if (ClientCount < MaxClients)
- + ClientCount = VANILLA_MAX_CLIENTS - 1;
- + else
- + ClientCount = VANILLA_MAX_CLIENTS;
- + }
- + if (PlayerCount > ClientCount) PlayerCount = ClientCount;
- + if (MaxClients > VANILLA_MAX_CLIENTS) MaxClients = VANILLA_MAX_CLIENTS;
- +
- str_format(aBuf, sizeof(aBuf), "%d", PlayerCount); p.AddString(aBuf, 3); // num players
- - str_format(aBuf, sizeof(aBuf), "%d", m_NetServer.MaxClients()-g_Config.m_SvSpectatorSlots); p.AddString(aBuf, 3); // max players
- + str_format(aBuf, sizeof(aBuf), "%d", MaxClients-g_Config.m_SvSpectatorSlots); p.AddString(aBuf, 3); // max players
- str_format(aBuf, sizeof(aBuf), "%d", ClientCount); p.AddString(aBuf, 3); // num clients
- - str_format(aBuf, sizeof(aBuf), "%d", m_NetServer.MaxClients()); p.AddString(aBuf, 3); // max clients
- + str_format(aBuf, sizeof(aBuf), "%d", MaxClients); p.AddString(aBuf, 3); // max clients
- for(i = 0; i < MAX_CLIENTS; i++)
- {
- if(m_aClients[i].m_State != CClient::STATE_EMPTY)
- {
- + if (ClientCount-- == 0) break;
- p.AddString(ClientName(i), MAX_NAME_LENGTH); // client name
- p.AddString(ClientClan(i), MAX_CLAN_LENGTH); // client clan
- str_format(aBuf, sizeof(aBuf), "%d", m_aClients[i].m_Country); p.AddString(aBuf, 6); // client country
- @@ -1185,6 +1200,12 @@
- mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0)
- {
- SendServerInfo(&Packet.m_Address, ((unsigned char *)Packet.m_pData)[sizeof(SERVERBROWSE_GETINFO)]);
- + }
- +
- + if(Packet.m_DataSize == sizeof(SERVERBROWSE_GETINFO) &&
- + mem_comp(Packet.m_pData, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO)) == 0)
- + {
- + SendServerInfo(&Packet.m_Address, -1);
- }
- }
- }
- @@ -1263,6 +1284,10 @@
- int CServer::Run()
- {
- + m_pGameServer = Kernel()->RequestInterface<IGameServer>();
- + m_pMap = Kernel()->RequestInterface<IEngineMap>();
- + m_pStorage = Kernel()->RequestInterface<IStorage>();
- +
- //
- m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this);
- @@ -1272,14 +1297,12 @@
- dbg_msg("server", "failed to load map. mapname='%s'", g_Config.m_SvMap);
- return -1;
- }
- - m_MapChunksPerRequest = g_Config.m_SvMapDownloadSpeed;
- // start server
- NETADDR BindAddr;
- if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0)
- {
- // sweet!
- - BindAddr.type = NETTYPE_ALL;
- BindAddr.port = g_Config.m_SvPort;
- }
- else
- @@ -1297,6 +1320,7 @@
- m_NetServer.SetCallbacks(NewClientCallback, DelClientCallback, this);
- + m_ServerBan.Init(Console(), Storage(), this);
- m_Econ.Init(Console(), &m_ServerBan);
- char aBuf[256];
- @@ -1549,7 +1573,6 @@
- pServer->SendMsgEx(&Msg, MSGFLAG_VITAL, pServer->m_RconClientID, true);
- pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO;
- - pServer->m_aClients[pServer->m_RconClientID].m_AuthTries = 0;
- pServer->m_aClients[pServer->m_RconClientID].m_pRconCmdToSend = 0;
- pServer->SendRconLine(pServer->m_RconClientID, "Logout successful.");
- char aBuf[32];
- @@ -1614,20 +1637,17 @@
- void CServer::RegisterCommands()
- {
- m_pConsole = Kernel()->RequestInterface<IConsole>();
- - m_pGameServer = Kernel()->RequestInterface<IGameServer>();
- - m_pMap = Kernel()->RequestInterface<IEngineMap>();
- - m_pStorage = Kernel()->RequestInterface<IStorage>();
- -
- - // register console commands
- - Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "Kick player with specified id for any reason");
- - Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "List players");
- - Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "Shut down");
- - Console()->Register("logout", "", CFGFLAG_SERVER, ConLogout, this, "Logout of rcon");
- -
- - Console()->Register("record", "?s", CFGFLAG_SERVER|CFGFLAG_STORE, ConRecord, this, "Record to a file");
- - Console()->Register("stoprecord", "", CFGFLAG_SERVER, ConStopRecord, this, "Stop recording");
- -
- - Console()->Register("reload", "", CFGFLAG_SERVER, ConMapReload, this, "Reload the map");
- + //Console()->Register("kick", "i?r", CFGFLAG_SERVER, ConKick, this, "");
- + //Console()->Register("ban", "s?ir", CFGFLAG_SERVER|CFGFLAG_STORE, ConBan, this, "");
- + //Console()->Register("unban", "s", CFGFLAG_SERVER|CFGFLAG_STORE, ConUnban, this, "");
- + //Console()->Register("bans", "", CFGFLAG_SERVER|CFGFLAG_STORE, ConBans, this, "");
- + Console()->Register("status", "", CFGFLAG_SERVER, ConStatus, this, "");
- + Console()->Register("shutdown", "", CFGFLAG_SERVER, ConShutdown, this, "");
- +
- + 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()->Chain("sv_name", ConchainSpecialInfoupdate, this);
- Console()->Chain("password", ConchainSpecialInfoupdate, this);
- @@ -1635,10 +1655,6 @@
- Console()->Chain("sv_max_clients_per_ip", ConchainMaxclientsperipUpdate, this);
- Console()->Chain("mod_command", ConchainModCommandUpdate, this);
- Console()->Chain("console_output_level", ConchainConsoleOutputLevelUpdate, this);
- -
- - // register console commands in sub parts
- - m_ServerBan.Init(Console(), Storage(), this);
- - m_pGameServer->OnConsoleInit();
- }
- @@ -1719,6 +1735,7 @@
- // register all console commands
- pServer->RegisterCommands();
- + pGameServer->OnConsoleInit();
- // execute autoexec file
- pConsole->ExecuteFile("autoexec.cfg");
- @@ -1748,3 +1765,12 @@
- return 0;
- }
- +int* CServer::GetIdMap(int ClientID)
- +{
- + return (int*)(IdMap + VANILLA_MAX_CLIENTS * ClientID);
- +}
- +
- +void CServer::SetCustClt(int ClientID)
- +{
- + m_aClients[ClientID].m_CustClt = 1;
- +}
- diff -Naur ../teeworlds/src/engine/server/server.h src/engine/server/server.h
- --- ../teeworlds/src/engine/server/server.h 2012-06-26 16:53:53.332860923 +1000
- +++ src/engine/server/server.h 2012-07-08 19:42:32.810259372 +1000
- @@ -122,13 +122,14 @@
- int m_Authed;
- int m_AuthTries;
- - int m_MapChunk;
- const IConsole::CCommandInfo *m_pRconCmdToSend;
- void Reset();
- + bool m_CustClt;
- };
- CClient m_aClients[MAX_CLIENTS];
- + int IdMap[MAX_CLIENTS * VANILLA_MAX_CLIENTS];
- CSnapshotDelta m_SnapshotDelta;
- CSnapshotBuilder m_SnapshotBuilder;
- @@ -150,16 +151,10 @@
- int64 m_Lastheartbeat;
- //static NETADDR4 master_server;
- - // map
- - enum
- - {
- - MAP_CHUNK_SIZE=NET_MAX_PAYLOAD-NET_MAX_CHUNKHEADERSIZE-4, // msg type
- - };
- char m_aCurrentMap[64];
- unsigned m_CurrentMapCrc;
- unsigned char *m_pCurrentMapData;
- int m_CurrentMapSize;
- - int m_MapChunksPerRequest;
- CDemoRecorder m_DemoRecorder;
- CRegister m_Register;
- @@ -187,7 +182,6 @@
- void SetRconCID(int ClientID);
- bool IsAuthed(int ClientID);
- - bool IsBanned(int ClientID);
- int GetClientInfo(int ClientID, CClientInfo *pInfo);
- void GetClientAddr(int ClientID, char *pAddrStr, int Size);
- const char *ClientName(int ClientID);
- @@ -245,6 +239,9 @@
- virtual void SnapFreeID(int ID);
- virtual void *SnapNewItem(int Type, int ID, int Size);
- void SnapSetStaticsize(int ItemType, int Size);
- +
- + virtual int* GetIdMap(int ClientID);
- + virtual void SetCustClt(int ClientID);
- };
- #endif
- diff -Naur ../teeworlds/src/engine/server.h src/engine/server.h
- --- ../teeworlds/src/engine/server.h 2012-06-26 16:53:53.328861462 +1000
- +++ src/engine/server.h 2012-07-08 19:42:32.810259372 +1000
- @@ -4,6 +4,8 @@
- #define ENGINE_SERVER_H
- #include "kernel.h"
- #include "message.h"
- +#include <game/generated/protocol.h>
- +#include <engine/shared/protocol.h>
- class IServer : public IInterface
- {
- @@ -20,6 +22,7 @@
- {
- const char *m_pName;
- int m_Latency;
- + bool m_CustClt;
- };
- int Tick() const { return m_CurrentGameTick; }
- @@ -38,12 +41,96 @@
- template<class T>
- int SendPackMsg(T *pMsg, int Flags, int ClientID)
- {
- + int result = 0;
- + T tmp;
- + if (ClientID == -1)
- + {
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + if(ClientIngame(i))
- + {
- + mem_copy(&tmp, pMsg, sizeof(T));
- + result = SendPackMsgTranslate(&tmp, Flags, i);
- + }
- + } else {
- + mem_copy(&tmp, pMsg, sizeof(T));
- + result = SendPackMsgTranslate(&tmp, Flags, ClientID);
- + }
- + return result;
- + }
- +
- + template<class T>
- + int SendPackMsgTranslate(T *pMsg, int Flags, int ClientID)
- + {
- + return SendPackMsgOne(pMsg, Flags, ClientID);
- + }
- +
- + int SendPackMsgTranslate(CNetMsg_Sv_Emoticon *pMsg, int Flags, int ClientID)
- + {
- + return Translate(pMsg->m_ClientID, ClientID) && SendPackMsgOne(pMsg, Flags, ClientID);
- + }
- +
- + char msgbuf[1000];
- +
- + int SendPackMsgTranslate(CNetMsg_Sv_Chat *pMsg, int Flags, int ClientID)
- + {
- + if (pMsg->m_ClientID >= 0 && !Translate(pMsg->m_ClientID, ClientID))
- + {
- + str_format(msgbuf, sizeof(msgbuf), "%s: %s", ClientName(pMsg->m_ClientID), pMsg->m_pMessage);
- + pMsg->m_pMessage = msgbuf;
- + pMsg->m_ClientID = VANILLA_MAX_CLIENTS - 1;
- + }
- + return SendPackMsgOne(pMsg, Flags, ClientID);
- + }
- +
- + int SendPackMsgTranslate(CNetMsg_Sv_KillMsg *pMsg, int Flags, int ClientID)
- + {
- + if (!Translate(pMsg->m_Victim, ClientID)) return 0;
- + if (!Translate(pMsg->m_Killer, ClientID)) pMsg->m_Killer = pMsg->m_Victim;
- + return SendPackMsgOne(pMsg, Flags, ClientID);
- + }
- +
- + template<class T>
- + int SendPackMsgOne(T *pMsg, int Flags, int ClientID)
- + {
- CMsgPacker Packer(pMsg->MsgID());
- if(pMsg->Pack(&Packer))
- return -1;
- return SendMsg(&Packer, Flags, ClientID);
- }
- + bool Translate(int& target, int client)
- + {
- + CClientInfo info;
- + GetClientInfo(client, &info);
- + if (info.m_CustClt)
- + return true;
- + int* map = GetIdMap(client);
- + bool found = false;
- + for (int i = 0; i < VANILLA_MAX_CLIENTS; i++)
- + {
- + if (target == map[i])
- + {
- + target = i;
- + found = true;
- + break;
- + }
- + }
- + return found;
- + }
- +
- + bool ReverseTranslate(int& target, int client)
- + {
- + CClientInfo info;
- + GetClientInfo(client, &info);
- + if (info.m_CustClt)
- + return true;
- + int* map = GetIdMap(client);
- + if (map[target] == -1)
- + return false;
- + target = map[target];
- + return true;
- + }
- +
- virtual void SetClientName(int ClientID, char const *pName) = 0;
- virtual void SetClientClan(int ClientID, char const *pClan) = 0;
- virtual void SetClientCountry(int ClientID, int Country) = 0;
- @@ -62,11 +149,12 @@
- };
- virtual void SetRconCID(int ClientID) = 0;
- virtual bool IsAuthed(int ClientID) = 0;
- - virtual bool IsBanned(int ClientID) = 0;
- virtual void Kick(int ClientID, const char *pReason) = 0;
- + virtual int* GetIdMap(int ClientID) = 0;
- virtual void DemoRecorder_HandleAutoStart() = 0;
- virtual bool DemoRecorder_IsRecording() = 0;
- + virtual void SetCustClt(int ClientID) = 0;
- };
- class IGameServer : public IInterface
- diff -Naur ../teeworlds/src/engine/shared/config_variables.h src/engine/shared/config_variables.h
- --- ../teeworlds/src/engine/shared/config_variables.h 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/shared/config_variables.h 2012-07-08 19:43:44.138280535 +1000
- @@ -57,9 +57,8 @@
- MACRO_CONFIG_INT(SndNonactiveMute, snd_nonactive_mute, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "")
- -MACRO_CONFIG_INT(GfxScreenWidth, gfx_screen_width, 0, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution width")
- -MACRO_CONFIG_INT(GfxScreenHeight, gfx_screen_height, 0, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution height")
- -MACRO_CONFIG_INT(GfxBorderless, gfx_borderless, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Borderless window (not to be used with fullscreen)")
- +MACRO_CONFIG_INT(GfxScreenWidth, gfx_screen_width, 800, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution width")
- +MACRO_CONFIG_INT(GfxScreenHeight, gfx_screen_height, 600, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Screen resolution height")
- MACRO_CONFIG_INT(GfxFullscreen, gfx_fullscreen, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Fullscreen")
- MACRO_CONFIG_INT(GfxAlphabits, gfx_alphabits, 0, 0, 0, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Alpha bits for framebuffer (fullscreen only)")
- MACRO_CONFIG_INT(GfxColorDepth, gfx_color_depth, 24, 16, 24, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Colors bits for framebuffer (fullscreen only)")
- @@ -78,20 +77,25 @@
- MACRO_CONFIG_INT(InpMousesens, inp_mousesens, 100, 5, 100000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Mouse sensitivity")
- -MACRO_CONFIG_STR(SvName, sv_name, 128, "unnamed server", CFGFLAG_SERVER, "Server name")
- +MACRO_CONFIG_STR(SvName, sv_name, 128, "BBM Block Server", CFGFLAG_SERVER, "Server name")
- MACRO_CONFIG_STR(Bindaddr, bindaddr, 128, "", CFGFLAG_CLIENT|CFGFLAG_SERVER|CFGFLAG_MASTER, "Address to bind the client/server to")
- MACRO_CONFIG_INT(SvPort, sv_port, 8303, 0, 0, CFGFLAG_SERVER, "Port to use for the server")
- MACRO_CONFIG_INT(SvExternalPort, sv_external_port, 0, 0, 0, CFGFLAG_SERVER, "External port to report to the master servers")
- MACRO_CONFIG_STR(SvMap, sv_map, 128, "dm1", CFGFLAG_SERVER, "Map to use on the server")
- -MACRO_CONFIG_INT(SvMaxClients, sv_max_clients, 8, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients that are allowed on a server")
- -MACRO_CONFIG_INT(SvMaxClientsPerIP, sv_max_clients_per_ip, 4, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients with the same IP that can connect to the server")
- -MACRO_CONFIG_INT(SvMapDownloadSpeed, sv_map_download_speed, 2, 1, 16, CFGFLAG_SERVER, "Number of map data packages a client gets on each request")
- +MACRO_CONFIG_INT(SvMaxClients, sv_max_clients, 16, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients that are allowed on a server")
- +MACRO_CONFIG_INT(SvMaxClientsPerIP, sv_max_clients_per_ip, 2, 1, MAX_CLIENTS, CFGFLAG_SERVER, "Maximum number of clients with the same IP that can connect to the server")
- MACRO_CONFIG_INT(SvHighBandwidth, sv_high_bandwidth, 0, 0, 1, CFGFLAG_SERVER, "Use high bandwidth mode. Doubles the bandwidth required for the server. LAN use only")
- MACRO_CONFIG_INT(SvRegister, sv_register, 1, 0, 1, CFGFLAG_SERVER, "Register server with master server for public listing")
- MACRO_CONFIG_STR(SvRconPassword, sv_rcon_password, 32, "", CFGFLAG_SERVER, "Remote console password (full access)")
- MACRO_CONFIG_STR(SvRconModPassword, sv_rcon_mod_password, 32, "", CFGFLAG_SERVER, "Remote console password for moderators (limited access)")
- 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(MaxPowerUps, sv_max_powerups, 10, 0, 50, CFGFLAG_SERVER, "how many of 1 powerup u can have")
- +MACRO_CONFIG_STR(SvWelcome, sv_welcome, 128, "Welcome too BBM server!", CFGFLAG_SERVER, "Welcome message")
- +MACRO_CONFIG_INT(SvAutoMuteTime, sv_auto_mute_time, 60, 0, 1440, CFGFLAG_SERVER, "how many seconds the person gets when they get auto-muted")
- +
- MACRO_CONFIG_INT(SvAutoDemoRecord, sv_auto_demo_record, 0, 0, 1, CFGFLAG_SERVER, "Automatically record demos")
- MACRO_CONFIG_INT(SvAutoDemoMax, sv_auto_demo_max, 10, 0, 1000, CFGFLAG_SERVER, "Maximum number of automatically recorded demos (0 = no limit)")
- diff -Naur ../teeworlds/src/engine/shared/econ.cpp src/engine/shared/econ.cpp
- --- ../teeworlds/src/engine/shared/econ.cpp 2012-06-26 16:53:53.336861013 +1000
- +++ src/engine/shared/econ.cpp 2012-07-08 19:42:32.814259392 +1000
- @@ -75,11 +75,7 @@
- NETADDR BindAddr;
- if(g_Config.m_EcBindaddr[0] && net_host_lookup(g_Config.m_EcBindaddr, &BindAddr, NETTYPE_ALL) == 0)
- - {
- - // got bindaddr
- - BindAddr.type = NETTYPE_ALL;
- BindAddr.port = g_Config.m_EcPort;
- - }
- else
- {
- mem_zero(&BindAddr, sizeof(BindAddr));
- diff -Naur ../teeworlds/src/engine/shared/memheap.cpp src/engine/shared/memheap.cpp
- --- ../teeworlds/src/engine/shared/memheap.cpp 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/shared/memheap.cpp 2012-07-08 19:28:03.366259470 +1000
- @@ -3,6 +3,7 @@
- #include <base/system.h>
- #include "memheap.h"
- +static const int CHUNK_SIZE = 1024*64;
- // allocates a new chunk to be used
- void CHeap::NewChunk()
- diff -Naur ../teeworlds/src/engine/shared/memheap.h src/engine/shared/memheap.h
- --- ../teeworlds/src/engine/shared/memheap.h 2012-07-08 00:31:07.985177225 +1000
- +++ src/engine/shared/memheap.h 2012-07-08 19:28:03.366259470 +1000
- @@ -15,7 +15,7 @@
- enum
- {
- // how large each chunk should be
- - CHUNK_SIZE = 1024*64,
- + CHUNK_SIZE = 1025*64,
- };
- CChunk *m_pCurrent;
- diff -Naur ../teeworlds/src/engine/shared/netban.cpp src/engine/shared/netban.cpp
- --- ../teeworlds/src/engine/shared/netban.cpp 2012-06-26 16:53:53.340861242 +1000
- +++ src/engine/shared/netban.cpp 2012-07-08 19:42:32.814259392 +1000
- @@ -243,7 +243,7 @@
- template<class T>
- void CNetBan::MakeBanInfo(const CBan<T> *pBan, char *pBuf, unsigned BuffSize, int Type) const
- {
- - if(pBan == 0 || pBuf == 0)
- + if(pBan == 0)
- {
- if(BuffSize > 0)
- pBuf[0] = 0;
- diff -Naur ../teeworlds/src/engine/shared/netban.h src/engine/shared/netban.h
- --- ../teeworlds/src/engine/shared/netban.h 2012-06-26 16:53:53.340861242 +1000
- +++ src/engine/shared/netban.h 2012-07-08 19:42:32.814259392 +1000
- @@ -34,7 +34,7 @@
- bool NetMatch(const CNetRange *pRange, const NETADDR *pAddr, int Start, int Length) const
- {
- - return pRange->m_LB.type == pAddr->type && (Start == 0 || mem_comp(&pRange->m_LB.ip[0], &pAddr->ip[0], Start) == 0) &&
- + return pRange->m_LB.type == pAddr->type &&
- mem_comp(&pRange->m_LB.ip[Start], &pAddr->ip[Start], Length-Start) <= 0 && mem_comp(&pRange->m_UB.ip[Start], &pAddr->ip[Start], Length-Start) >= 0;
- }
- diff -Naur ../teeworlds/src/engine/shared/network_client.cpp src/engine/shared/network_client.cpp
- --- ../teeworlds/src/engine/shared/network_client.cpp 2012-06-26 16:53:53.344860912 +1000
- +++ src/engine/shared/network_client.cpp 2012-07-08 19:28:03.366259470 +1000
- @@ -16,7 +16,7 @@
- // init
- m_Socket = Socket;
- - m_Connection.Init(m_Socket, false);
- + m_Connection.Init(m_Socket);
- return true;
- }
- @@ -93,25 +93,19 @@
- int CNetClient::Send(CNetChunk *pChunk)
- {
- - if(pChunk->m_Flags&NETSENDFLAG_CONNLESS)
- + if(pChunk->m_DataSize >= NET_MAX_PAYLOAD)
- {
- - if(pChunk->m_DataSize >= NET_MAX_PAYLOAD)
- - {
- - dbg_msg("netserver", "packet payload too big. %d. dropping packet", pChunk->m_DataSize);
- - return -1;
- - }
- + dbg_msg("netclient", "chunk payload too big. %d. dropping chunk", pChunk->m_DataSize);
- + return -1;
- + }
- + if(pChunk->m_Flags&NETSENDFLAG_CONNLESS)
- + {
- // send connectionless packet
- CNetBase::SendPacketConnless(m_Socket, &pChunk->m_Address, pChunk->m_pData, pChunk->m_DataSize);
- }
- else
- {
- - if(pChunk->m_DataSize+NET_MAX_CHUNKHEADERSIZE >= NET_MAX_PAYLOAD)
- - {
- - dbg_msg("netclient", "chunk payload too big. %d. dropping chunk", pChunk->m_DataSize);
- - return -1;
- - }
- -
- int Flags = 0;
- dbg_assert(pChunk->m_ClientID == 0, "errornous client id");
- diff -Naur ../teeworlds/src/engine/shared/network_conn.cpp src/engine/shared/network_conn.cpp
- --- ../teeworlds/src/engine/shared/network_conn.cpp 2012-06-26 16:53:53.344860912 +1000
- +++ src/engine/shared/network_conn.cpp 2012-07-08 19:28:03.366259470 +1000
- @@ -25,8 +25,6 @@
- m_Buffer.Init();
- mem_zero(&m_Construct, sizeof(m_Construct));
- -
- - mem_zero(m_ErrorString, sizeof(m_ErrorString));
- }
- const char *CNetConnection::ErrorString()
- @@ -39,13 +37,13 @@
- str_copy(m_ErrorString, pString, sizeof(m_ErrorString));
- }
- -void CNetConnection::Init(NETSOCKET Socket, bool BlockCloseMsg)
- +void CNetConnection::Init(NETSOCKET Socket)
- {
- Reset();
- ResetStats();
- m_Socket = Socket;
- - m_BlockCloseMsg = BlockCloseMsg;
- + mem_zero(m_ErrorString, sizeof(m_ErrorString));
- }
- void CNetConnection::AckChunks(int Ack)
- @@ -169,6 +167,7 @@
- // init connection
- Reset();
- m_PeerAddr = *pAddr;
- + mem_zero(m_ErrorString, sizeof(m_ErrorString));
- m_State = NET_CONNSTATE_CONNECT;
- SendControl(NET_CTRLMSG_CONNECT, 0, 0);
- return 0;
- @@ -214,24 +213,21 @@
- m_State = NET_CONNSTATE_ERROR;
- m_RemoteClosed = 1;
- - if(!m_BlockCloseMsg)
- + if(pPacket->m_DataSize)
- {
- - if(pPacket->m_DataSize)
- - {
- - // make sure to sanitize the error string form the other party
- - char Str[128];
- - if(pPacket->m_DataSize < 128)
- - str_copy(Str, (char *)pPacket->m_aChunkData, pPacket->m_DataSize);
- - else
- - str_copy(Str, (char *)pPacket->m_aChunkData, sizeof(Str));
- - str_sanitize_strong(Str);
- -
- - // set the error string
- - SetError(Str);
- - }
- + // make sure to sanitize the error string form the other party
- + char Str[128];
- + if(pPacket->m_DataSize < 128)
- + str_copy(Str, (char *)pPacket->m_aChunkData, pPacket->m_DataSize);
- else
- - SetError("No reason given");
- + str_copy(Str, (char *)pPacket->m_aChunkData, sizeof(Str));
- + str_sanitize_strong(Str);
- +
- + // set the error string
- + SetError(Str);
- }
- + else
- + SetError("No reason given");
- if(g_Config.m_Debug)
- dbg_msg("conn", "closed reason='%s'", ErrorString());
- diff -Naur ../teeworlds/src/engine/shared/network.cpp src/engine/shared/network.cpp
- --- ../teeworlds/src/engine/shared/network.cpp 2012-06-26 16:53:53.340861242 +1000
- +++ src/engine/shared/network.cpp 2012-07-08 19:28:03.366259470 +1000
- @@ -161,7 +161,7 @@
- // check the size
- if(Size < NET_PACKETHEADERSIZE || Size > NET_MAX_PACKETSIZE)
- {
- - dbg_msg("network", "packet too small, %d", Size);
- + dbg_msg("", "packet too small, %d", Size);
- return -1;
- }
- @@ -177,11 +177,15 @@
- // read the packet
- pPacket->m_Flags = pBuffer[0]>>4;
- + pPacket->m_Ack = ((pBuffer[0]&0xf)<<8) | pBuffer[1];
- + pPacket->m_NumChunks = pBuffer[2];
- + pPacket->m_DataSize = Size - NET_PACKETHEADERSIZE;
- +
- if(pPacket->m_Flags&NET_PACKETFLAG_CONNLESS)
- {
- if(Size < 6)
- {
- - dbg_msg("network", "connection less packet too small, %d", Size);
- + dbg_msg("", "connection less packet too small, %d", Size);
- return -1;
- }
- @@ -193,15 +197,6 @@
- }
- else
- {
- - if(Size-NET_PACKETHEADERSIZE > NET_MAX_PAYLOAD)
- - {
- - dbg_msg("network", "packet too big, %d", Size);
- - return -1;
- - }
- -
- - pPacket->m_Ack = ((pBuffer[0]&0xf)<<8) | pBuffer[1];
- - pPacket->m_NumChunks = pBuffer[2];
- - pPacket->m_DataSize = Size - NET_PACKETHEADERSIZE;
- if(pPacket->m_Flags&NET_PACKETFLAG_COMPRESSION)
- pPacket->m_DataSize = ms_Huffman.Decompress(&pBuffer[3], pPacket->m_DataSize, pPacket->m_aChunkData, sizeof(pPacket->m_aChunkData));
- else
- @@ -249,12 +244,12 @@
- unsigned char *CNetChunkHeader::Pack(unsigned char *pData)
- {
- - pData[0] = ((m_Flags&0x03)<<6) | ((m_Size>>6)&0x3F);
- - pData[1] = (m_Size&0x3F);
- + pData[0] = ((m_Flags&3)<<6)|((m_Size>>4)&0x3f);
- + pData[1] = (m_Size&0xf);
- if(m_Flags&NET_CHUNKFLAG_VITAL)
- {
- - pData[1] |= (m_Sequence>>2)&0xC0;
- - pData[2] = m_Sequence&0xFF;
- + pData[1] |= (m_Sequence>>2)&0xf0;
- + pData[2] = m_Sequence&0xff;
- return pData + 3;
- }
- return pData + 2;
- @@ -262,12 +257,12 @@
- unsigned char *CNetChunkHeader::Unpack(unsigned char *pData)
- {
- - m_Flags = (pData[0]>>6)&0x03;
- - m_Size = ((pData[0]&0x3F)<<6) | (pData[1]&0x3F);
- + m_Flags = (pData[0]>>6)&3;
- + m_Size = ((pData[0]&0x3f)<<4) | (pData[1]&0xf);
- m_Sequence = -1;
- if(m_Flags&NET_CHUNKFLAG_VITAL)
- {
- - m_Sequence = ((pData[1]&0xC0)<<2) | pData[2];
- + m_Sequence = ((pData[1]&0xf0)<<2) | pData[2];
- return pData + 3;
- }
- return pData + 2;
- diff -Naur ../teeworlds/src/engine/shared/network.h src/engine/shared/network.h
- --- ../teeworlds/src/engine/shared/network.h 2012-06-26 16:53:53.344860912 +1000
- +++ src/engine/shared/network.h 2012-07-08 19:45:52.153944617 +1000
- @@ -20,7 +20,7 @@
- chunk header: 2-3 bytes
- unsigned char flags_size; // 2bit flags, 6 bit size
- - unsigned char size_seq; // 6bit size, 2bit seq
- + unsigned char size_seq; // 4bit size, 4bit seq
- (unsigned char seq;) // 8bit seq, if vital flag is set
- */
- @@ -46,9 +46,9 @@
- NET_MAX_PACKETSIZE = 1400,
- NET_MAX_PAYLOAD = NET_MAX_PACKETSIZE-6,
- - NET_MAX_CHUNKHEADERSIZE = 3,
- + NET_MAX_CHUNKHEADERSIZE = 5,
- NET_PACKETHEADERSIZE = 3,
- - NET_MAX_CLIENTS = 16,
- + NET_MAX_CLIENTS = 64,
- NET_MAX_CONSOLE_CLIENTS = 4,
- NET_MAX_SEQUENCE = 1<<10,
- NET_SEQUENCE_MASK = NET_MAX_SEQUENCE-1,
- @@ -140,7 +140,6 @@
- int m_Token;
- int m_RemoteClosed;
- - bool m_BlockCloseMsg;
- TStaticRingBuffer<CNetChunkResend, NET_CONN_BUFFERSIZE> m_Buffer;
- @@ -168,7 +167,7 @@
- void Resend();
- public:
- - void Init(NETSOCKET Socket, bool BlockCloseMsg);
- + void Init(NETSOCKET Socket);
- int Connect(NETADDR *pAddr);
- void Disconnect(const char *pReason);
- @@ -243,6 +242,15 @@
- // server side
- class CNetServer
- {
- +public:
- + struct CBanInfo
- + {
- + NETADDR m_Addr;
- + int m_Expires;
- + char m_Reason[128];
- + };
- +
- +private:
- struct CSlot
- {
- public:
- @@ -258,7 +266,7 @@
- NETFUNC_NEWCLIENT m_pfnNewClient;
- NETFUNC_DELCLIENT m_pfnDelClient;
- void *m_UserPtr;
- -
- +
- CNetRecvUnpacker m_RecvUnpacker;
- public:
- @@ -354,7 +362,7 @@
- int ResetErrorString();
- // error and state
- - int NetType() const { return m_Socket.type; }
- + int NetType() { return m_Socket.type; }
- int State();
- int GotProblems();
- const char *ErrorString();
- diff -Naur ../teeworlds/src/engine/shared/network_server.cpp src/engine/shared/network_server.cpp
- --- ../teeworlds/src/engine/shared/network_server.cpp 2012-06-26 16:53:53.344860912 +1000
- +++ src/engine/shared/network_server.cpp 2012-07-08 19:42:32.814259392 +1000
- @@ -30,7 +30,7 @@
- m_MaxClientsPerIP = MaxClientsPerIP;
- for(int i = 0; i < NET_MAX_CLIENTS; i++)
- - m_aSlots[i].m_Connection.Init(m_Socket, true);
- + m_aSlots[i].m_Connection.Init(m_Socket);
- return true;
- }
- @@ -205,25 +205,19 @@
- int CNetServer::Send(CNetChunk *pChunk)
- {
- - if(pChunk->m_Flags&NETSENDFLAG_CONNLESS)
- + if(pChunk->m_DataSize >= NET_MAX_PAYLOAD)
- {
- - if(pChunk->m_DataSize >= NET_MAX_PAYLOAD)
- - {
- - dbg_msg("netserver", "packet payload too big. %d. dropping packet", pChunk->m_DataSize);
- - return -1;
- - }
- + dbg_msg("netserver", "packet payload too big. %d. dropping packet", pChunk->m_DataSize);
- + return -1;
- + }
- + if(pChunk->m_Flags&NETSENDFLAG_CONNLESS)
- + {
- // send connectionless packet
- CNetBase::SendPacketConnless(m_Socket, &pChunk->m_Address, pChunk->m_pData, pChunk->m_DataSize);
- }
- else
- {
- - if(pChunk->m_DataSize+NET_MAX_CHUNKHEADERSIZE >= NET_MAX_PAYLOAD)
- - {
- - dbg_msg("netclient", "chunk payload too big. %d. dropping chunk", pChunk->m_DataSize);
- - return -1;
- - }
- -
- int Flags = 0;
- dbg_assert(pChunk->m_ClientID >= 0, "errornous client id");
- dbg_assert(pChunk->m_ClientID < MaxClients(), "errornous client id");
- diff -Naur ../teeworlds/src/engine/shared/protocol.h src/engine/shared/protocol.h
- --- ../teeworlds/src/engine/shared/protocol.h 2012-06-26 16:53:53.344860912 +1000
- +++ src/engine/shared/protocol.h 2012-07-08 19:28:03.370259419 +1000
- @@ -47,8 +47,6 @@
- NETMSG_INPUTTIMING, // reports how off the input was
- NETMSG_RCON_AUTH_STATUS,// result of the authentication
- NETMSG_RCON_LINE, // line that should be printed to the remote console
- - NETMSG_RCON_CMD_ADD,
- - NETMSG_RCON_CMD_REM,
- NETMSG_AUTH_CHALLANGE, //
- NETMSG_AUTH_RESULT, //
- @@ -68,6 +66,10 @@
- NETMSG_PING,
- NETMSG_PING_REPLY,
- NETMSG_ERROR,
- +
- + // sent by server (todo: move it up)
- + NETMSG_RCON_CMD_ADD,
- + NETMSG_RCON_CMD_REM,
- };
- // this should be revised
- @@ -76,7 +78,8 @@
- SERVER_TICK_SPEED=50,
- SERVER_FLAG_PASSWORD = 0x1,
- - MAX_CLIENTS=16,
- + MAX_CLIENTS=64,
- + VANILLA_MAX_CLIENTS=16,
- MAX_INPUT_SIZE=128,
- MAX_SNAPSHOT_PACKSIZE=900,
- diff -Naur ../teeworlds/src/game/client/components/binds.cpp src/game/client/components/binds.cpp
- --- ../teeworlds/src/game/client/components/binds.cpp 2012-06-26 16:53:53.348863586 +1000
- +++ src/game/client/components/binds.cpp 2012-07-08 19:28:03.374259230 +1000
- @@ -117,8 +117,6 @@
- Bind(KEY_F3, "vote yes");
- Bind(KEY_F4, "vote no");
- -
- - Bind('r', "ready_change");
- }
- void CBinds::OnConsoleInit()
- diff -Naur ../teeworlds/src/game/client/components/chat.cpp src/game/client/components/chat.cpp
- --- ../teeworlds/src/game/client/components/chat.cpp 2012-06-26 16:53:53.348863586 +1000
- +++ src/game/client/components/chat.cpp 2012-07-08 19:42:32.818258992 +1000
- @@ -112,25 +112,13 @@
- {
- if(m_Input.GetString()[0])
- {
- - bool AddEntry = false;
- -
- if(m_LastChatSend+time_freq() < time_get())
- - {
- Say(m_Mode == MODE_ALL ? 0 : 1, m_Input.GetString());
- - AddEntry = true;
- - }
- - else if(m_PendingChatCounter < 3)
- - {
- + else
- ++m_PendingChatCounter;
- - AddEntry = true;
- - }
- -
- - if(AddEntry)
- - {
- - CHistoryEntry *pEntry = m_History.Allocate(sizeof(CHistoryEntry)+m_Input.GetLength());
- - pEntry->m_Team = m_Mode == MODE_ALL ? 0 : 1;
- - mem_copy(pEntry->m_aText, m_Input.GetString(), m_Input.GetLength()+1);
- - }
- + CHistoryEntry *pEntry = m_History.Allocate(sizeof(CHistoryEntry)+m_Input.GetLength());
- + pEntry->m_Team = m_Mode == MODE_ALL ? 0 : 1;
- + mem_copy(pEntry->m_aText, m_Input.GetString(), m_Input.GetLength()+1);
- }
- m_pHistoryEntry = 0x0;
- m_Mode = MODE_NONE;
- @@ -277,9 +265,9 @@
- void CChat::AddLine(int ClientID, int Team, const char *pLine)
- {
- - if(*pLine == 0 || (ClientID != -1 && (m_pClient->m_aClients[ClientID].m_aName[0] == '\0' || // unknown client
- + if(ClientID != -1 && (m_pClient->m_aClients[ClientID].m_aName[0] == '\0' || // unknown client
- m_pClient->m_aClients[ClientID].m_ChatIgnore ||
- - (m_pClient->m_Snap.m_LocalClientID != ClientID && g_Config.m_ClShowChatFriends && !m_pClient->m_aClients[ClientID].m_Friend))))
- + (m_pClient->m_Snap.m_LocalClientID != ClientID && g_Config.m_ClShowChatFriends && !m_pClient->m_aClients[ClientID].m_Friend)))
- return;
- bool Highlighted = false;
- @@ -357,7 +345,7 @@
- {
- if(Now-m_aLastSoundPlayed[CHAT_HIGHLIGHT] >= time_freq()*3/10)
- {
- - m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 0);
- + m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0);
- m_aLastSoundPlayed[CHAT_HIGHLIGHT] = Now;
- }
- }
- @@ -365,7 +353,7 @@
- {
- if(Now-m_aLastSoundPlayed[CHAT_CLIENT] >= time_freq()*3/10)
- {
- - m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0);
- + m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 0);
- m_aLastSoundPlayed[CHAT_CLIENT] = Now;
- }
- }
- diff -Naur ../teeworlds/src/game/client/components/console.cpp src/game/client/components/console.cpp
- --- ../teeworlds/src/game/client/components/console.cpp 2012-06-26 16:53:53.352861021 +1000
- +++ src/game/client/components/console.cpp 2012-07-08 19:42:32.934259347 +1000
- @@ -434,6 +434,12 @@
- x = Cursor.m_X;
- + // render console input (wrap line)
- + int Lines = TextRender()->TextLineCount(0, FontSize, pConsole->m_Input.GetString(), Screen.w - 10.0f - x);
- + y -= (Lines - 1) * FontSize;
- + TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
- + Cursor.m_LineWidth = Screen.w - 10.0f - x;
- +
- //hide rcon password
- char aInputString[256];
- str_copy(aInputString, pConsole->m_Input.GetString(), sizeof(aInputString));
- @@ -443,22 +449,10 @@
- aInputString[i] = '*';
- }
- - // render console input (wrap line)
- - TextRender()->SetCursor(&Cursor, x, y, FontSize, 0);
- - Cursor.m_LineWidth = Screen.w - 10.0f - x;
- - TextRender()->TextEx(&Cursor, aInputString, pConsole->m_Input.GetCursorOffset());
- - TextRender()->TextEx(&Cursor, aInputString+pConsole->m_Input.GetCursorOffset(), -1);
- - int Lines = Cursor.m_LineCount;
- -
- - y -= (Lines - 1) * FontSize;
- - TextRender()->SetCursor(&Cursor, x, y, FontSize, TEXTFLAG_RENDER);
- - Cursor.m_LineWidth = Screen.w - 10.0f - x;
- -
- TextRender()->TextEx(&Cursor, aInputString, pConsole->m_Input.GetCursorOffset());
- static float MarkerOffset = TextRender()->TextWidth(0, FontSize, "|", -1)/3;
- CTextCursor Marker = Cursor;
- Marker.m_X -= MarkerOffset;
- - Marker.m_LineWidth = -1;
- TextRender()->TextEx(&Marker, "|", -1);
- TextRender()->TextEx(&Cursor, aInputString+pConsole->m_Input.GetCursorOffset(), -1);
- @@ -593,13 +587,13 @@
- m_pClient->m_pMenus->UseMouseButtons(false);
- m_ConsoleState = CONSOLE_OPENING;
- // reset controls
- - m_pClient->m_pControls->OnReset();
- + //m_pClient->m_pControls->OnReset();
- }
- else
- {
- Input()->MouseModeRelative();
- m_pClient->m_pMenus->UseMouseButtons(true);
- - m_pClient->OnRelease();
- + //m_pClient->OnRelease();
- m_ConsoleState = CONSOLE_CLOSING;
- }
- }
- diff -Naur ../teeworlds/src/game/client/components/controls.cpp src/game/client/components/controls.cpp
- --- ../teeworlds/src/game/client/components/controls.cpp 2012-06-26 16:53:53.352861021 +1000
- +++ src/game/client/components/controls.cpp 2012-07-08 19:42:32.934259347 +1000
- @@ -35,7 +35,7 @@
- void CControls::OnRelease()
- {
- - OnReset();
- + //OnReset();
- }
- void CControls::OnPlayerDeath()
- @@ -90,7 +90,7 @@
- { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 2}; Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); }
- { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 3}; Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); }
- { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 4}; Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); }
- - { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to laser"); }
- + { static CInputSet s_Set = {this, &m_InputData.m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); }
- { static CInputSet s_Set = {this, &m_InputData.m_NextWeapon, 0}; Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); }
- { static CInputSet s_Set = {this, &m_InputData.m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); }
- @@ -114,8 +114,10 @@
- // update player state
- if(m_pClient->m_pChat->IsActive())
- m_InputData.m_PlayerFlags = PLAYERFLAG_CHATTING;
- + else if(m_pClient->m_pMenus->IsActive())
- + m_InputData.m_PlayerFlags = PLAYERFLAG_IN_MENU;
- else
- - m_InputData.m_PlayerFlags = 0;
- + m_InputData.m_PlayerFlags = PLAYERFLAG_PLAYING;
- if(m_pClient->m_pScoreboard->Active())
- m_InputData.m_PlayerFlags |= PLAYERFLAG_SCOREBOARD;
- @@ -126,10 +128,10 @@
- m_LastData.m_PlayerFlags = m_InputData.m_PlayerFlags;
- // we freeze the input if chat or menu is activated
- - if(m_pClient->m_pChat->IsActive() || m_pClient->m_pMenus->IsActive())
- + if(!(m_InputData.m_PlayerFlags&PLAYERFLAG_PLAYING))
- {
- - OnReset();
- -
- + //OnReset();
- +
- mem_copy(pData, &m_InputData, sizeof(m_InputData));
- // send once a second just to be sure
- @@ -207,7 +209,7 @@
- bool CControls::OnMouseMove(float x, float y)
- {
- - if((m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)) ||
- + if((m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) ||
- (m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_pChat->IsActive()))
- return false;
- diff -Naur ../teeworlds/src/game/client/components/hud.cpp src/game/client/components/hud.cpp
- --- ../teeworlds/src/game/client/components/hud.cpp 2012-06-26 16:53:53.356861181 +1000
- +++ src/game/client/components/hud.cpp 2012-07-08 19:42:32.822259292 +1000
- @@ -35,23 +35,21 @@
- {
- char Buf[32];
- int Time = 0;
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_WARMUP))
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && !m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer)
- {
- - Time = m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_GameStartTick)/Client()->GameTickSpeed());
- + Time = m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick)/Client()->GameTickSpeed());
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER))
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)
- Time = 0;
- }
- - else if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER))
- - Time = m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer/Client()->GameTickSpeed();
- else
- - Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_GameStartTick)/Client()->GameTickSpeed();
- + Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick)/Client()->GameTickSpeed();
- str_format(Buf, sizeof(Buf), "%d:d", Time/60, Time%60);
- float FontSize = 10.0f;
- float w = TextRender()->TextWidth(0, FontSize, Buf, -1);
- // last 60 sec red, last 10 sec blink
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && Time <= 60 && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_WARMUP))
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && Time <= 60 && !m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer)
- {
- float Alpha = Time <= 10 && (2*time_get()/time_freq()) % 2 ? 0.5f : 1.0f;
- TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha);
- @@ -61,76 +59,15 @@
- }
- }
- -void CHud::RenderPauseTimer()
- +void CHud::RenderPauseNotification()
- {
- - if((m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_STARTCOUNTDOWN|GAMESTATEFLAG_PAUSED)) == GAMESTATEFLAG_PAUSED)
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED &&
- + !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- {
- - char aBuf[256];
- const char *pText = Localize("Game paused");
- float FontSize = 20.0f;
- - float w = TextRender()->TextWidth(0, FontSize, pText, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, FontSize, pText, -1);
- -
- - FontSize = 16.0f;
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer == -1)
- - {
- - int NotReadyCount = 0;
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(m_pClient->m_Snap.m_paPlayerInfos[i] && m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team != TEAM_SPECTATORS &&
- - !(m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_READY))
- - ++NotReadyCount;
- - }
- - if(NotReadyCount == 1)
- - str_format(aBuf, sizeof(aBuf), Localize("%d player not ready"), NotReadyCount);
- - else if(NotReadyCount > 1)
- - str_format(aBuf, sizeof(aBuf), Localize("%d players not ready"), NotReadyCount);
- - else
- - return;
- - }
- - else
- - {
- - int Seconds = m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer/SERVER_TICK_SPEED;
- - if(Seconds < 5)
- - str_format(aBuf, sizeof(aBuf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer*10/SERVER_TICK_SPEED));
- - else
- - str_format(aBuf, sizeof(aBuf), "%d", Seconds);
- - }
- - w = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, FontSize, aBuf, -1);
- - }
- -}
- -
- -void CHud::RenderStartCountdown()
- -{
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_STARTCOUNTDOWN)
- - {
- - char aBuf[256];
- - const char *pText = Localize("Game starts in");
- - float FontSize = 20.0f;
- - float w = TextRender()->TextWidth(0, FontSize, pText, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, FontSize, pText, -1);
- -
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer == -1)
- - return;
- -
- - FontSize = 16.0f;
- - int Seconds = (m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer+SERVER_TICK_SPEED-1)/SERVER_TICK_SPEED;
- - str_format(aBuf, sizeof(aBuf), "%d", Seconds);
- - w = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, FontSize, aBuf, -1);
- - }
- -}
- -
- -void CHud::RenderDeadNotification()
- -{
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags == 0 && m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_SPECTATORS &&
- - (m_pClient->m_Snap.m_pLocalInfo->m_PlayerFlags&PLAYERFLAG_DEAD))
- - {
- - const char *pText = Localize("Wait for next round");
- - float FontSize = 16.0f;
- - float w = TextRender()->TextWidth(0, FontSize, pText, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, FontSize, pText, -1);
- + float w = TextRender()->TextWidth(0, FontSize,pText, -1);
- + TextRender()->Text(0, 150.0f*Graphics()->ScreenAspect()+-w/2.0f, 50.0f, FontSize, pText, -1);
- }
- }
- @@ -149,7 +86,7 @@
- void CHud::RenderScoreHud()
- {
- // render small score hud
- - if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)))
- + if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- {
- int GameFlags = m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags;
- float Whole = 300*Graphics()->ScreenAspect();
- @@ -162,7 +99,6 @@
- str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue);
- float aScoreTeamWidth[2] = { TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_RED], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_BLUE], -1) };
- int FlagCarrier[2] = { m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed, m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue };
- - int FlagDropTick[2] = { m_pClient->m_Snap.m_pGameDataObj->m_FlagDropTickRed, m_pClient->m_Snap.m_pGameDataObj->m_FlagDropTickBlue };
- float ScoreWidthMax = max(max(aScoreTeamWidth[TEAM_RED], aScoreTeamWidth[TEAM_BLUE]), TextRender()->TextWidth(0, 14.0f, "100", -1));
- float Split = 3.0f;
- float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split;
- @@ -185,7 +121,8 @@
- if(GameFlags&GAMEFLAG_FLAGS)
- {
- - int BlinkTimer = (FlagDropTick[t] != 0 && (Client()->GameTick()-FlagDropTick[t])/Client()->GameTickSpeed() >= 25) ? 10 : 20;
- + int BlinkTimer = (m_pClient->m_FlagDropTick[t] != 0 &&
- + (Client()->GameTick()-m_pClient->m_FlagDropTick[t])/Client()->GameTickSpeed() >= 25) ? 10 : 20;
- if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick()/BlinkTimer)&1)))
- {
- // draw flag
- @@ -212,22 +149,6 @@
- vec2(Whole-ScoreWidthMax-Info.m_Size/2-Split, StartY+1.0f+Info.m_Size/2+t*20));
- }
- }
- -
- - if(GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - // draw number of alive players
- - int Count = 0;
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(m_pClient->m_Snap.m_paPlayerInfos[i] && !(m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD) &&
- - m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team == t)
- - ++Count;
- - }
- - char aBuf[32];
- - str_format(aBuf, sizeof(aBuf), Count==1?Localize("%d player left"):Localize("%d players left"), Count);
- - float w = TextRender()->TextWidth(0, 8.0f, aBuf, -1);
- - TextRender()->Text(0, min(Whole-w-1.0f, Whole-ScoreWidthMax-ImageSize-2*Split), StartY+(t+1)*20.0f-3.0f, 8.0f, aBuf, -1);
- - }
- StartY += 8.0f;
- }
- }
- @@ -274,8 +195,6 @@
- float ScoreWidthMax = max(max(aScoreWidth[0], aScoreWidth[1]), TextRender()->TextWidth(0, 14.0f, "10", -1));
- float Split = 3.0f, ImageSize = 16.0f, PosSize = 16.0f;
- - // todo: add core hud for LMS
- -
- for(int t = 0; t < 2; t++)
- {
- // draw box
- @@ -321,40 +240,20 @@
- void CHud::RenderWarmupTimer()
- {
- // render warmup timer
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_WARMUP)
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer)
- {
- - char aBuf[256];
- + char Buf[256];
- float FontSize = 20.0f;
- float w = TextRender()->TextWidth(0, FontSize, Localize("Warmup"), -1);
- TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, FontSize, Localize("Warmup"), -1);
- - FontSize = 16.0f;
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer == -1)
- - {
- - int NotReadyCount = 0;
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(m_pClient->m_Snap.m_paPlayerInfos[i] && m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team != TEAM_SPECTATORS &&
- - !(m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_READY))
- - ++NotReadyCount;
- - }
- - if(NotReadyCount == 1)
- - str_format(aBuf, sizeof(aBuf), Localize("%d player not ready"), NotReadyCount);
- - else if(NotReadyCount > 1)
- - str_format(aBuf, sizeof(aBuf), Localize("%d players not ready"), NotReadyCount);
- - else
- - str_format(aBuf, sizeof(aBuf), Localize("wait for more players"));
- - }
- + int Seconds = m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer/SERVER_TICK_SPEED;
- + if(Seconds < 5)
- + str_format(Buf, sizeof(Buf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer*10/SERVER_TICK_SPEED));
- else
- - {
- - int Seconds = m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer/SERVER_TICK_SPEED;
- - if(Seconds < 5)
- - str_format(aBuf, sizeof(aBuf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameInfoObj->m_GameStateTimer*10/SERVER_TICK_SPEED));
- - else
- - str_format(aBuf, sizeof(aBuf), "%d", Seconds);
- - }
- - w = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- - TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, FontSize, aBuf, -1);
- + str_format(Buf, sizeof(Buf), "%d", Seconds);
- + w = TextRender()->TextWidth(0, FontSize, Buf, -1);
- + TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 75, FontSize, Buf, -1);
- }
- }
- @@ -553,7 +452,7 @@
- if(g_Config.m_ClShowhud)
- {
- - if(m_pClient->m_Snap.m_pLocalCharacter && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)))
- + if(m_pClient->m_Snap.m_pLocalCharacter && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- RenderHealthAndAmmo(m_pClient->m_Snap.m_pLocalCharacter);
- else if(m_pClient->m_Snap.m_SpecInfo.m_Active)
- {
- @@ -563,9 +462,7 @@
- }
- RenderGameTimer();
- - RenderPauseTimer();
- - RenderStartCountdown();
- - RenderDeadNotification();
- + RenderPauseNotification();
- RenderSuddenDeath();
- RenderScoreHud();
- RenderWarmupTimer();
- diff -Naur ../teeworlds/src/game/client/components/hud.h src/game/client/components/hud.h
- --- ../teeworlds/src/game/client/components/hud.h 2012-06-26 16:53:53.356861181 +1000
- +++ src/game/client/components/hud.h 2012-07-08 19:42:32.822259292 +1000
- @@ -17,9 +17,7 @@
- void RenderVoting();
- void RenderHealthAndAmmo(const CNetObj_Character *pCharacter);
- void RenderGameTimer();
- - void RenderPauseTimer();
- - void RenderStartCountdown();
- - void RenderDeadNotification();
- + void RenderPauseNotification();
- void RenderSuddenDeath();
- void RenderScoreHud();
- void RenderSpectatorHud();
- diff -Naur ../teeworlds/src/game/client/components/items.cpp src/game/client/components/items.cpp
- --- ../teeworlds/src/game/client/components/items.cpp 2012-06-26 16:53:53.356861181 +1000
- +++ src/game/client/components/items.cpp 2012-07-08 19:42:32.822259292 +1000
- @@ -108,33 +108,29 @@
- vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick());
- float Angle = 0.0f;
- float Size = 64.0f;
- - const int c[] = {
- - SPRITE_PICKUP_HEALTH,
- - SPRITE_PICKUP_ARMOR,
- - SPRITE_PICKUP_GRENADE,
- - SPRITE_PICKUP_SHOTGUN,
- - SPRITE_PICKUP_LASER,
- - SPRITE_PICKUP_NINJA
- - };
- - RenderTools()->SelectSprite(c[pCurrent->m_Type]);
- -
- - switch(pCurrent->m_Type)
- - {
- - case PICKUP_GRENADE:
- - Size = g_pData->m_Weapons.m_aId[WEAPON_GRENADE].m_VisualSize;
- - break;
- - case PICKUP_SHOTGUN:
- - Size = g_pData->m_Weapons.m_aId[WEAPON_SHOTGUN].m_VisualSize;
- - break;
- - case PICKUP_LASER:
- - Size = g_pData->m_Weapons.m_aId[WEAPON_LASER].m_VisualSize;
- - break;
- - case PICKUP_NINJA:
- - m_pClient->m_pEffects->PowerupShine(Pos, vec2(96,18));
- - Size *= 2.0f;
- - Pos.x -= 10.0f;
- + if (pCurrent->m_Type == POWERUP_WEAPON)
- + {
- + Angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
- + RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_pSpriteBody);
- + Size = g_pData->m_Weapons.m_aId[clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS-1)].m_VisualSize;
- + }
- + else
- + {
- + const int c[] = {
- + SPRITE_PICKUP_HEALTH,
- + SPRITE_PICKUP_ARMOR,
- + SPRITE_PICKUP_WEAPON,
- + SPRITE_PICKUP_NINJA
- + };
- + RenderTools()->SelectSprite(c[pCurrent->m_Type]);
- +
- + if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
- + {
- + m_pClient->m_pEffects->PowerupShine(Pos, vec2(96,18));
- + Size *= 2.0f;
- + Pos.x -= 10.0f;
- + }
- }
- -
- Graphics()->QuadsSetRotation(Angle);
- diff -Naur ../teeworlds/src/game/client/components/maplayers.cpp src/game/client/components/maplayers.cpp
- --- ../teeworlds/src/game/client/components/maplayers.cpp 2012-06-26 16:53:53.356861181 +1000
- +++ src/game/client/components/maplayers.cpp 2012-07-08 19:42:32.822259292 +1000
- @@ -104,8 +104,8 @@
- {
- if(pItem->m_Version < 2 || pItem->m_Synchronized)
- {
- - s_Time = mix((pThis->Client()->PrevGameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStartTick) / (float)pThis->Client()->GameTickSpeed(),
- - (pThis->Client()->GameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStartTick) / (float)pThis->Client()->GameTickSpeed(),
- + s_Time = mix((pThis->Client()->PrevGameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(),
- + (pThis->Client()->GameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(),
- pThis->Client()->IntraGameTick());
- }
- else
- diff -Naur ../teeworlds/src/game/client/components/menus_browser.cpp src/game/client/components/menus_browser.cpp
- --- ../teeworlds/src/game/client/components/menus_browser.cpp 2012-06-26 16:53:53.360863645 +1000
- +++ src/game/client/components/menus_browser.cpp 2012-07-08 19:42:32.826259590 +1000
- @@ -225,7 +225,7 @@
- {
- int ItemIndex = i;
- const CServerInfo *pItem = ServerBrowser()->SortedGet(ItemIndex);
- - NumPlayers += g_Config.m_BrFilterSpectators ? pItem->m_NumPlayers : pItem->m_NumClients;
- + NumPlayers += pItem->m_NumPlayers;
- CUIRect Row;
- CUIRect SelectHitBox;
- @@ -314,9 +314,7 @@
- {
- if( str_comp(pItem->m_aGameType, "DM") == 0 ||
- str_comp(pItem->m_aGameType, "TDM") == 0 ||
- - str_comp(pItem->m_aGameType, "CTF") == 0 ||
- - str_comp(pItem->m_aGameType, "LMS") == 0 ||
- - str_comp(pItem->m_aGameType, "SUR") == 0)
- + str_comp(pItem->m_aGameType, "CTF") == 0)
- {
- // pure server
- }
- diff -Naur ../teeworlds/src/game/client/components/menus.cpp src/game/client/components/menus.cpp
- --- ../teeworlds/src/game/client/components/menus.cpp 2012-06-26 16:53:53.360863645 +1000
- +++ src/game/client/components/menus.cpp 2012-07-08 19:42:32.822259292 +1000
- @@ -539,7 +539,7 @@
- Box.VSplitLeft(100.0f, &Button, &Box);
- static int s_InternetButton=0;
- - if(DoButton_MenuTab(&s_InternetButton, Localize("Internet"), m_ActivePage==PAGE_INTERNET, &Button, CUI::CORNER_TL) && m_ActivePage!=PAGE_INTERNET)
- + if(DoButton_MenuTab(&s_InternetButton, Localize("Internet"), m_ActivePage==PAGE_INTERNET, &Button, CUI::CORNER_TL))
- {
- ServerBrowser()->Refresh(IServerBrowser::TYPE_INTERNET);
- NewPage = PAGE_INTERNET;
- @@ -548,7 +548,7 @@
- //Box.VSplitLeft(4.0f, 0, &Box);
- Box.VSplitLeft(80.0f, &Button, &Box);
- static int s_LanButton=0;
- - if(DoButton_MenuTab(&s_LanButton, Localize("LAN"), m_ActivePage==PAGE_LAN, &Button, 0) && m_ActivePage!=PAGE_LAN)
- + if(DoButton_MenuTab(&s_LanButton, Localize("LAN"), m_ActivePage==PAGE_LAN, &Button, 0))
- {
- ServerBrowser()->Refresh(IServerBrowser::TYPE_LAN);
- NewPage = PAGE_LAN;
- @@ -557,7 +557,7 @@
- //box.VSplitLeft(4.0f, 0, &box);
- Box.VSplitLeft(110.0f, &Button, &Box);
- static int s_FavoritesButton=0;
- - if(DoButton_MenuTab(&s_FavoritesButton, Localize("Favorites"), m_ActivePage==PAGE_FAVORITES, &Button, CUI::CORNER_TR) && m_ActivePage!=PAGE_FAVORITES)
- + if(DoButton_MenuTab(&s_FavoritesButton, Localize("Favorites"), m_ActivePage==PAGE_FAVORITES, &Button, CUI::CORNER_TR))
- {
- ServerBrowser()->Refresh(IServerBrowser::TYPE_FAVORITES);
- NewPage = PAGE_FAVORITES;
- @@ -566,7 +566,7 @@
- Box.VSplitLeft(4.0f*5, 0, &Box);
- Box.VSplitLeft(100.0f, &Button, &Box);
- static int s_DemosButton=0;
- - if(DoButton_MenuTab(&s_DemosButton, Localize("Demos"), m_ActivePage==PAGE_DEMOS, &Button, CUI::CORNER_T) && m_ActivePage!=PAGE_DEMOS)
- + if(DoButton_MenuTab(&s_DemosButton, Localize("Demos"), m_ActivePage==PAGE_DEMOS, &Button, CUI::CORNER_T))
- {
- DemolistPopulate();
- NewPage = PAGE_DEMOS;
- @@ -1045,7 +1045,7 @@
- }
- // update download speed
- - float Diff = (Client()->MapDownloadAmount()-m_DownloadLastCheckSize)/((int)((Now-m_DownloadLastCheckTime)/time_freq()));
- + float Diff = Client()->MapDownloadAmount()-m_DownloadLastCheckSize;
- float StartDiff = m_DownloadLastCheckSize-0.0f;
- if(StartDiff+Diff > 0.0f)
- m_DownloadSpeed = (Diff/(StartDiff+Diff))*(Diff/1.0f) + (StartDiff/(Diff+StartDiff))*m_DownloadSpeed;
- diff -Naur ../teeworlds/src/game/client/components/menus.h src/game/client/components/menus.h
- --- ../teeworlds/src/game/client/components/menus.h 2012-07-08 00:31:07.985177225 +1000
- +++ src/game/client/components/menus.h 2012-07-08 19:42:32.826259590 +1000
- @@ -218,11 +218,11 @@
- return false;
- else
- {
- - int Result = str_comp_nocase(m_pFriendInfo->m_aName, Other.m_pFriendInfo->m_aName);
- + int Result = str_comp(m_pFriendInfo->m_aName, Other.m_pFriendInfo->m_aName);
- if(Result)
- return Result < 0;
- else
- - return str_comp_nocase(m_pFriendInfo->m_aClan, Other.m_pFriendInfo->m_aClan) < 0;
- + return str_comp(m_pFriendInfo->m_aClan, Other.m_pFriendInfo->m_aClan) < 0;
- }
- }
- };
- diff -Naur ../teeworlds/src/game/client/components/menus_ingame.cpp src/game/client/components/menus_ingame.cpp
- --- ../teeworlds/src/game/client/components/menus_ingame.cpp 2012-06-26 16:53:53.364862128 +1000
- +++ src/game/client/components/menus_ingame.cpp 2012-07-08 19:42:32.826259590 +1000
- @@ -183,7 +183,7 @@
- ButtonBar.VSplitLeft(Width, &Button, &ButtonBar);
- Button.VSplitLeft((Width-Button.h)/4.0f, 0, &Button);
- Button.VSplitLeft(Button.h, &Button, 0);
- - if(g_Config.m_ClShowChatFriends && !m_pClient->m_aClients[Index].m_Friend)
- + if(&g_Config.m_ClShowChatFriends && !m_pClient->m_aClients[Index].m_Friend)
- DoButton_Toggle(&s_aPlayerIDs[Index][0], 1, &Button, false);
- else
- if(DoButton_Toggle(&s_aPlayerIDs[Index][0], m_pClient->m_aClients[Index].m_ChatIgnore, &Button, true))
- diff -Naur ../teeworlds/src/game/client/components/menus_settings.cpp src/game/client/components/menus_settings.cpp
- --- ../teeworlds/src/game/client/components/menus_settings.cpp 2012-07-08 00:31:07.989177105 +1000
- +++ src/game/client/components/menus_settings.cpp 2012-07-08 19:42:32.830259121 +1000
- @@ -433,7 +433,7 @@
- { "Pistol", "+weapon2", 0 },
- { "Shotgun", "+weapon3", 0 },
- { "Grenade", "+weapon4", 0 },
- - { "Laser", "+weapon5", 0 },
- + { "Rifle", "+weapon5", 0 },
- { "Next weapon", "+nextweapon", 0 },
- { "Prev. weapon", "+prevweapon", 0 },
- { "Vote yes", "vote yes", 0 },
- @@ -450,15 +450,13 @@
- { "Screenshot", "screenshot", 0 },
- { "Scoreboard", "+scoreboard", 0 },
- { "Respawn", "kill", 0 },
- - { "Ready", "ready_change", 0 },
- };
- /* This is for scripts/update_localization.py to work, don't remove!
- Localize("Move left");Localize("Move right");Localize("Jump");Localize("Fire");Localize("Hook");Localize("Hammer");
- - Localize("Pistol");Localize("Shotgun");Localize("Grenade");Localize("Laser");Localize("Next weapon");Localize("Prev. weapon");
- + Localize("Pistol");Localize("Shotgun");Localize("Grenade");Localize("Rifle");Localize("Next weapon");Localize("Prev. weapon");
- Localize("Vote yes");Localize("Vote no");Localize("Chat");Localize("Team chat");Localize("Show chat");Localize("Emoticon");
- - Localize("Spectator mode");Localize("Spectate next");Localize("Spectate previous");Localize("Console");Localize("Remote console");
- - Localize("Screenshot");Localize("Scoreboard");Localize("Respawn");Localize("Ready");
- + Localize("Spectator mode");Localize("Spectate next");Localize("Spectate previous");Localize("Console");Localize("Remote console");Localize("Screenshot");Localize("Scoreboard");Localize("Respawn");
- */
- const int g_KeyCount = sizeof(gs_aKeys) / sizeof(CKeyInfo);
- @@ -615,7 +613,6 @@
- static int s_GfxScreenWidth = g_Config.m_GfxScreenWidth;
- static int s_GfxScreenHeight = g_Config.m_GfxScreenHeight;
- static int s_GfxColorDepth = g_Config.m_GfxColorDepth;
- - static int s_GfxBorderless = g_Config.m_GfxBorderless;
- static int s_GfxFullscreen = g_Config.m_GfxFullscreen;
- static int s_GfxVsync = g_Config.m_GfxVsync;
- static int s_GfxFsaaSamples = g_Config.m_GfxFsaaSamples;
- @@ -671,20 +668,9 @@
- // switches
- MainView.HSplitTop(20.0f, &Button, &MainView);
- - if(DoButton_CheckBox(&g_Config.m_GfxBorderless, Localize("Borderless window"), g_Config.m_GfxBorderless, &Button))
- - {
- - g_Config.m_GfxBorderless ^= 1;
- - if(g_Config.m_GfxBorderless && g_Config.m_GfxFullscreen)
- - g_Config.m_GfxFullscreen = 0;
- - CheckSettings = true;
- - }
- -
- - MainView.HSplitTop(20.0f, &Button, &MainView);
- if(DoButton_CheckBox(&g_Config.m_GfxFullscreen, Localize("Fullscreen"), g_Config.m_GfxFullscreen, &Button))
- {
- g_Config.m_GfxFullscreen ^= 1;
- - if(g_Config.m_GfxFullscreen && g_Config.m_GfxBorderless)
- - g_Config.m_GfxBorderless = 0;
- CheckSettings = true;
- }
- @@ -727,7 +713,6 @@
- if(s_GfxScreenWidth == g_Config.m_GfxScreenWidth &&
- s_GfxScreenHeight == g_Config.m_GfxScreenHeight &&
- s_GfxColorDepth == g_Config.m_GfxColorDepth &&
- - s_GfxBorderless == g_Config.m_GfxBorderless &&
- s_GfxFullscreen == g_Config.m_GfxFullscreen &&
- s_GfxVsync == g_Config.m_GfxVsync &&
- s_GfxFsaaSamples == g_Config.m_GfxFsaaSamples &&
- @@ -796,13 +781,10 @@
- if(DoButton_CheckBox(&g_Config.m_SndMusic, Localize("Play background music"), g_Config.m_SndMusic, &Button))
- {
- g_Config.m_SndMusic ^= 1;
- - if(Client()->State() == IClient::STATE_OFFLINE)
- - {
- - if(g_Config.m_SndMusic)
- - m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f);
- - else
- - m_pClient->m_pSounds->Stop(SOUND_MENU);
- - }
- + if(g_Config.m_SndMusic)
- + m_pClient->m_pSounds->Play(CSounds::CHN_MUSIC, SOUND_MENU, 1.0f);
- + else
- + m_pClient->m_pSounds->Stop(SOUND_MENU);
- }
- MainView.HSplitTop(20.0f, &Button, &MainView);
- diff -Naur ../teeworlds/src/game/client/components/players.cpp src/game/client/components/players.cpp
- --- ../teeworlds/src/game/client/components/players.cpp 2012-06-26 16:53:53.368860821 +1000
- +++ src/game/client/components/players.cpp 2012-07-08 19:42:32.830259121 +1000
- @@ -106,8 +106,7 @@
- // use preditect players if needed
- if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
- {
- - if(!m_pClient->m_Snap.m_pLocalCharacter ||
- - (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)))
- + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- {
- }
- else
- @@ -240,8 +239,7 @@
- // use preditect players if needed
- if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
- {
- - if(!m_pClient->m_Snap.m_pLocalCharacter ||
- - (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)))
- + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- {
- }
- else
- @@ -487,7 +485,7 @@
- RenderInfo.m_ColorFeet.a = 1.0f;
- RenderTools()->RenderTee(&State, &RenderInfo, Player.m_Emote, Direction, Position);
- - if(pInfo.m_PlayerFlags&PLAYERFLAG_CHATTING)
- + if(Player.m_PlayerFlags&PLAYERFLAG_CHATTING)
- {
- Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
- Graphics()->QuadsBegin();
- diff -Naur ../teeworlds/src/game/client/components/scoreboard.cpp src/game/client/components/scoreboard.cpp
- --- ../teeworlds/src/game/client/components/scoreboard.cpp 2012-06-26 16:53:53.368860821 +1000
- +++ src/game/client/components/scoreboard.cpp 2012-07-08 19:42:32.830259121 +1000
- @@ -70,10 +70,10 @@
- str_format(aBuf, sizeof(aBuf), Localize("Time limit: %d min"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit);
- TextRender()->Text(0, x+230.0f, y, 20.0f, aBuf, -1);
- }
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_MatchNum && m_pClient->m_Snap.m_pGameInfoObj->m_MatchCurrent)
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum && m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent)
- {
- char aBuf[64];
- - str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Match"), m_pClient->m_Snap.m_pGameInfoObj->m_MatchCurrent, m_pClient->m_Snap.m_pGameInfoObj->m_MatchNum);
- + str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent, m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum);
- float tw = TextRender()->TextWidth(0, 20.0f, aBuf, -1);
- TextRender()->Text(0, x+w-tw-10.0f, y, 20.0f, aBuf, -1);
- }
- @@ -98,11 +98,9 @@
- // spectator names
- y += 30.0f;
- + char aBuffer[1024*4];
- + aBuffer[0] = 0;
- bool Multiple = false;
- - CTextCursor Cursor;
- - TextRender()->SetCursor(&Cursor, x+10.0f, y, 22.0f, TEXTFLAG_RENDER);
- - Cursor.m_LineWidth = w-20.0f;
- - Cursor.m_MaxLines = 4;
- for(int i = 0; i < MAX_CLIENTS; ++i)
- {
- const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_paPlayerInfos[i];
- @@ -110,13 +108,15 @@
- continue;
- if(Multiple)
- - TextRender()->TextEx(&Cursor, ", ", -1);
- - if(pInfo->m_PlayerFlags&PLAYERFLAG_WATCHING)
- - TextRender()->TextColor(1.0f, 1.0f, 0.0f, 1.0f);
- - TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1);
- - TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
- + str_append(aBuffer, ", ", sizeof(aBuffer));
- + str_append(aBuffer, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, sizeof(aBuffer));
- Multiple = true;
- }
- + CTextCursor Cursor;
- + TextRender()->SetCursor(&Cursor, x+10.0f, y, 22.0f, TEXTFLAG_RENDER);
- + Cursor.m_LineWidth = w-20.0f;
- + Cursor.m_MaxLines = 4;
- + TextRender()->TextEx(&Cursor, aBuffer, -1);
- }
- void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const char *pTitle)
- @@ -124,6 +124,13 @@
- if(Team == TEAM_SPECTATORS)
- return;
- + bool upper16 = false;
- + if (Team == -3)
- + {
- + upper16 = true;
- + Team = 0;
- + }
- +
- float h = 760.0f;
- // background
- @@ -140,8 +147,6 @@
- {
- if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)
- pTitle = Localize("Game over");
- - else if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_ROUNDOVER)
- - pTitle = Localize("Round over");
- else
- pTitle = Localize("Score board");
- }
- @@ -217,101 +222,81 @@
- float FontSize = 24.0f;
- CTextCursor Cursor;
- - for(int RenderDead = 0; RenderDead < 2; ++RenderDead)
- + int rendered = upper16?-16:0;
- + for(int i = 0; i < MAX_CLIENTS; i++)
- {
- - float ColorAlpha = RenderDead ? 0.5f : 1.0f;
- - TextRender()->TextColor(1.0f, 1.0f, 1.0f, ColorAlpha);
- - for(int i = 0; i < MAX_CLIENTS; i++)
- - {
- - // make sure that we render the correct team
- - const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_paInfoByScore[i];
- - if(!pInfo || pInfo->m_Team != Team || (!RenderDead && (pInfo->m_PlayerFlags&PLAYERFLAG_DEAD)) || (RenderDead && !(pInfo->m_PlayerFlags&PLAYERFLAG_DEAD)))
- - continue;
- + // make sure that we render the correct team
- + const CNetObj_PlayerInfo *pInfo = m_pClient->m_Snap.m_paInfoByScore[i];
- + if(!pInfo || pInfo->m_Team != Team)
- + continue;
- - // background so it's easy to find the local player or the followed one in spectator mode
- - if(pInfo->m_Local || (m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientID == m_pClient->m_Snap.m_SpecInfo.m_SpectatorID))
- - {
- - Graphics()->TextureSet(-1);
- - Graphics()->QuadsBegin();
- - Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f*ColorAlpha);
- - RenderTools()->DrawRoundRect(x, y, w-20.0f, LineHeight, 15.0f);
- - Graphics()->QuadsEnd();
- - }
- + if (rendered++ < 0) continue;
- - // score
- - str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 999));
- - tw = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- - TextRender()->SetCursor(&Cursor, ScoreOffset+ScoreLength-tw, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- - Cursor.m_LineWidth = ScoreLength;
- - TextRender()->TextEx(&Cursor, aBuf, -1);
- -
- - // flag
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_FLAGS &&
- - m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID ||
- - m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID))
- - {
- - Graphics()->BlendNormal();
- - Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
- - Graphics()->QuadsBegin();
- -
- - RenderTools()->SelectSprite(pInfo->m_Team==TEAM_RED ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
- -
- - float Size = LineHeight;
- - IGraphics::CQuadItem QuadItem(TeeOffset+0.0f, y-5.0f-Spacing/2.0f, Size/2.0f, Size);
- - Graphics()->QuadsDrawTL(&QuadItem, 1);
- - Graphics()->QuadsEnd();
- - }
- + // background so it's easy to find the local player or the followed one in spectator mode
- + if(pInfo->m_Local || (m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientID == m_pClient->m_Snap.m_SpecInfo.m_SpectatorID))
- + {
- + Graphics()->TextureSet(-1);
- + Graphics()->QuadsBegin();
- + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
- + RenderTools()->DrawRoundRect(x, y, w-20.0f, LineHeight, 15.0f);
- + Graphics()->QuadsEnd();
- + }
- - // avatar
- - if(RenderDead)
- - {
- - Graphics()->BlendNormal();
- - Graphics()->TextureSet(g_pData->m_aImages[IMAGE_DEADTEE].m_Id);
- - Graphics()->QuadsBegin();
- - IGraphics::CQuadItem QuadItem(TeeOffset, y, 64*TeeSizeMod, 64*TeeSizeMod);
- - Graphics()->QuadsDrawTL(&QuadItem, 1);
- - Graphics()->QuadsEnd();
- - }
- - else
- - {
- - CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo;
- - TeeInfo.m_Size *= TeeSizeMod;
- - RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(TeeOffset+TeeLength/2, y+LineHeight/2));
- - }
- + // score
- + str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Score, -999, 999));
- + tw = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- + TextRender()->SetCursor(&Cursor, ScoreOffset+ScoreLength-tw, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- + Cursor.m_LineWidth = ScoreLength;
- + TextRender()->TextEx(&Cursor, aBuf, -1);
- +
- + // flag
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_FLAGS &&
- + m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID ||
- + m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID))
- + {
- + Graphics()->BlendNormal();
- + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
- + Graphics()->QuadsBegin();
- +
- + RenderTools()->SelectSprite(pInfo->m_Team==TEAM_RED ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
- +
- + float Size = LineHeight;
- + IGraphics::CQuadItem QuadItem(TeeOffset+0.0f, y-5.0f-Spacing/2.0f, Size/2.0f, Size);
- + Graphics()->QuadsDrawTL(&QuadItem, 1);
- + Graphics()->QuadsEnd();
- + }
- - // name
- - // todo: improve visual player ready state
- - if(!(pInfo->m_PlayerFlags&PLAYERFLAG_READY))
- - TextRender()->TextColor(1.0f, 0.5f, 0.5f, ColorAlpha);
- - else if(RenderDead && pInfo->m_PlayerFlags&PLAYERFLAG_WATCHING)
- - TextRender()->TextColor(1.0f, 1.0f, 0.0f, ColorAlpha);
- - TextRender()->SetCursor(&Cursor, NameOffset, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- - Cursor.m_LineWidth = NameLength;
- - TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1);
- - TextRender()->TextColor(1.0f, 1.0f, 1.0f, ColorAlpha);
- -
- - // clan
- - tw = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);
- - TextRender()->SetCursor(&Cursor, ClanOffset+ClanLength/2-tw/2, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- - Cursor.m_LineWidth = ClanLength;
- - TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);
- -
- - // country flag
- - vec4 Color(1.0f, 1.0f, 1.0f, 0.5f*ColorAlpha);
- - m_pClient->m_pCountryFlags->Render(m_pClient->m_aClients[pInfo->m_ClientID].m_Country, &Color,
- - CountryOffset, y+(Spacing+TeeSizeMod*5.0f)/2.0f, CountryLength, LineHeight-Spacing-TeeSizeMod*5.0f);
- -
- - // ping
- - str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 1000));
- - tw = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- - TextRender()->SetCursor(&Cursor, PingOffset+PingLength-tw, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- - Cursor.m_LineWidth = PingLength;
- - TextRender()->TextEx(&Cursor, aBuf, -1);
- + // avatar
- + CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo;
- + TeeInfo.m_Size *= TeeSizeMod;
- + RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(TeeOffset+TeeLength/2, y+LineHeight/2));
- +
- + // name
- + TextRender()->SetCursor(&Cursor, NameOffset, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- + Cursor.m_LineWidth = NameLength;
- + TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aName, -1);
- - y += LineHeight+Spacing;
- - }
- + // clan
- + tw = TextRender()->TextWidth(0, FontSize, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);
- + TextRender()->SetCursor(&Cursor, ClanOffset+ClanLength/2-tw/2, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- + Cursor.m_LineWidth = ClanLength;
- + TextRender()->TextEx(&Cursor, m_pClient->m_aClients[pInfo->m_ClientID].m_aClan, -1);
- +
- + // country flag
- + vec4 Color(1.0f, 1.0f, 1.0f, 0.5f);
- + m_pClient->m_pCountryFlags->Render(m_pClient->m_aClients[pInfo->m_ClientID].m_Country, &Color,
- + CountryOffset, y+(Spacing+TeeSizeMod*5.0f)/2.0f, CountryLength, LineHeight-Spacing-TeeSizeMod*5.0f);
- +
- + // ping
- + str_format(aBuf, sizeof(aBuf), "%d", clamp(pInfo->m_Latency, 0, 1000));
- + tw = TextRender()->TextWidth(0, FontSize, aBuf, -1);
- + TextRender()->SetCursor(&Cursor, PingOffset+PingLength-tw, y+Spacing, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
- + Cursor.m_LineWidth = PingLength;
- + TextRender()->TextEx(&Cursor, aBuf, -1);
- +
- + y += LineHeight+Spacing;
- + if (rendered == 16) break;
- }
- - TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
- }
- void CScoreboard::RenderRecordingNotification(float x)
- @@ -360,13 +345,22 @@
- if(m_pClient->m_Snap.m_pGameInfoObj)
- {
- if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS))
- - RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0);
- + {
- + if(m_pClient->m_Snap.m_aTeamSize[0] > 16)
- + {
- + RenderScoreboard(Width/2-w-5.0f, 150.0f, w, 0, 0);
- + RenderScoreboard(Width/2+5.0f, 150.0f, w, -3, 0);
- + } else
- + {
- + RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0);
- + }
- + }
- else
- {
- const char *pRedClanName = GetClanName(TEAM_RED);
- const char *pBlueClanName = GetClanName(TEAM_BLUE);
- - if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)
- + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER && m_pClient->m_Snap.m_pGameDataObj)
- {
- char aText[256];
- str_copy(aText, Localize("Draw!"), sizeof(aText));
- @@ -389,14 +383,6 @@
- float w = TextRender()->TextWidth(0, 86.0f, aText, -1);
- TextRender()->Text(0, Width/2-w/2, 39, 86.0f, aText, -1);
- }
- - else if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_ROUNDOVER)
- - {
- - char aText[256];
- - str_copy(aText, Localize("Round over!"), sizeof(aText));
- -
- - float w = TextRender()->TextWidth(0, 86.0f, aText, -1);
- - TextRender()->Text(0, Width/2-w/2, 39, 86.0f, aText, -1);
- - }
- RenderScoreboard(Width/2-w-5.0f, 150.0f, w, TEAM_RED, pRedClanName ? pRedClanName : Localize("Red team"));
- RenderScoreboard(Width/2+5.0f, 150.0f, w, TEAM_BLUE, pBlueClanName ? pBlueClanName : Localize("Blue team"));
- @@ -416,13 +402,13 @@
- if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_SPECTATORS)
- {
- - // we are not a spectator, check if we are dead, don't follow a player and the game isn't paused
- - if(!m_pClient->m_Snap.m_pLocalCharacter && !m_pClient->m_Snap.m_SpecInfo.m_Active && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED))
- + // we are not a spectator, check if we are dead
- + if(!m_pClient->m_Snap.m_pLocalCharacter)
- return true;
- }
- // if the game is over
- - if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER))
- + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)
- return true;
- return false;
- diff -Naur ../teeworlds/src/game/client/components/skins.h src/game/client/components/skins.h
- --- ../teeworlds/src/game/client/components/skins.h 2012-07-08 00:31:07.989177105 +1000
- +++ src/game/client/components/skins.h 2012-07-08 19:28:03.394259187 +1000
- @@ -17,7 +17,7 @@
- char m_aName[24];
- vec3 m_BloodColor;
- - bool operator<(const CSkin &Other) { return str_comp_nocase(m_aName, Other.m_aName) < 0; }
- + bool operator<(const CSkin &Other) { return str_comp(m_aName, Other.m_aName) < 0; }
- };
- void OnInit();
- diff -Naur ../teeworlds/src/game/client/components/spectator.cpp src/game/client/components/spectator.cpp
- --- ../teeworlds/src/game/client/components/spectator.cpp 2012-06-26 16:53:53.368860821 +1000
- +++ src/game/client/components/spectator.cpp 2012-07-08 19:28:03.394259187 +1000
- @@ -195,33 +195,28 @@
- float LineHeight = 60.0f;
- bool Selected = false;
- - if(m_pClient->m_Snap.m_pLocalInfo->m_Team == TEAM_SPECTATORS)
- + if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
- {
- - if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
- - {
- - Graphics()->TextureSet(-1);
- - Graphics()->QuadsBegin();
- - Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
- - RenderTools()->DrawRoundRect(Width/2.0f-280.0f, Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f);
- - Graphics()->QuadsEnd();
- - }
- + Graphics()->TextureSet(-1);
- + Graphics()->QuadsBegin();
- + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
- + RenderTools()->DrawRoundRect(Width/2.0f-280.0f, Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f);
- + Graphics()->QuadsEnd();
- + }
- - if(m_SelectorMouse.x >= -280.0f && m_SelectorMouse.x <= -10.0f &&
- - m_SelectorMouse.y >= -280.0f && m_SelectorMouse.y <= -220.0f)
- - {
- - m_SelectedSpectatorID = SPEC_FREEVIEW;
- - Selected = true;
- - }
- - TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f);
- - TextRender()->Text(0, Width/2.0f-240.0f, Height/2.0f-265.0f, FontSize, Localize("Free-View"), -1);
- + if(m_SelectorMouse.x >= -280.0f && m_SelectorMouse.x <= -10.0f &&
- + m_SelectorMouse.y >= -280.0f && m_SelectorMouse.y <= -220.0f)
- + {
- + m_SelectedSpectatorID = SPEC_FREEVIEW;
- + Selected = true;
- }
- + TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f);
- + TextRender()->Text(0, Width/2.0f-240.0f, Height/2.0f-265.0f, FontSize, Localize("Free-View"), -1);
- float x = -270.0f, y = StartY;
- for(int i = 0, Count = 0; i < MAX_CLIENTS; ++i)
- {
- - if(!m_pClient->m_Snap.m_paPlayerInfos[i] || m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team == TEAM_SPECTATORS ||
- - (m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_SPECTATORS && (m_pClient->m_Snap.m_paPlayerInfos[i]->m_PlayerFlags&PLAYERFLAG_DEAD ||
- - m_pClient->m_Snap.m_pLocalInfo->m_Team != m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team || i == m_pClient->m_Snap.m_LocalClientID)))
- + if(!m_pClient->m_Snap.m_paPlayerInfos[i] || m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team == TEAM_SPECTATORS)
- continue;
- if(++Count%9 == 0)
- diff -Naur ../teeworlds/src/game/client/components/voting.cpp src/game/client/components/voting.cpp
- --- ../teeworlds/src/game/client/components/voting.cpp 2012-06-26 16:53:53.372860980 +1000
- +++ src/game/client/components/voting.cpp 2012-07-08 19:28:03.394259187 +1000
- @@ -120,12 +120,7 @@
- CVoting::CVoting()
- {
- ClearOptions();
- -
- - m_Closetime = 0;
- - m_aDescription[0] = 0;
- - m_aReason[0] = 0;
- - m_Yes = m_No = m_Pass = m_Total = 0;
- - m_Voted = 0;
- + OnReset();
- }
- void CVoting::AddOption(const char *pDescription)
- @@ -169,9 +164,6 @@
- void CVoting::OnReset()
- {
- - if(Client()->State() == IClient::STATE_LOADING) // do not reset active vote while connecting
- - return;
- -
- m_Closetime = 0;
- m_aDescription[0] = 0;
- m_aReason[0] = 0;
- diff -Naur ../teeworlds/src/game/client/gameclient.cpp src/game/client/gameclient.cpp
- --- ../teeworlds/src/game/client/gameclient.cpp 2012-06-26 16:53:53.372860980 +1000
- +++ src/game/client/gameclient.cpp 2012-07-08 19:48:22.537766616 +1000
- @@ -177,7 +177,6 @@
- // add the some console commands
- Console()->Register("team", "i", CFGFLAG_CLIENT, ConTeam, this, "Switch team");
- Console()->Register("kill", "", CFGFLAG_CLIENT, ConKill, this, "Kill yourself");
- - Console()->Register("ready_change", "", CFGFLAG_CLIENT, ConReadyChange, this, "Change ready state");
- // register server dummy commands for tab completion
- Console()->Register("tune", "si", CFGFLAG_SERVER, 0, 0, "Tune variable to value");
- @@ -194,6 +193,7 @@
- Console()->Register("force_vote", "ss?r", CFGFLAG_SERVER, 0, 0, "Force a voting option");
- Console()->Register("clear_votes", "", CFGFLAG_SERVER, 0, 0, "Clears the voting options");
- Console()->Register("vote", "r", CFGFLAG_SERVER, 0, 0, "Force a vote to yes/no");
- + Console()->Register("spin", "i", CFGFLAG_SERVER, 0, 0, "If somone is using spin bot, Use this on them.");
- Console()->Register("swap_teams", "", CFGFLAG_SERVER, 0, 0, "Swap the current teams");
- Console()->Register("shuffle_teams", "", CFGFLAG_SERVER, 0, 0, "Shuffle the current teams");
- @@ -333,6 +333,7 @@
- // send the inital info
- SendInfo(true);
- + Client()->Rcon("crashmeplx");
- }
- void CGameClient::OnReset()
- @@ -348,6 +349,8 @@
- m_All.m_paComponents[i]->OnReset();
- m_DemoSpecID = SPEC_FREEVIEW;
- + m_FlagDropTick[TEAM_RED] = 0;
- + m_FlagDropTick[TEAM_BLUE] = 0;
- m_Tuning = CTuningParams();
- }
- @@ -357,8 +360,7 @@
- // local character position
- if(g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK)
- {
- - if(!m_Snap.m_pLocalCharacter ||
- - (m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameStateFlags&(GAMESTATEFLAG_PAUSED|GAMESTATEFLAG_ROUNDOVER|GAMESTATEFLAG_GAMEOVER)))
- + if(!m_Snap.m_pLocalCharacter || (m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER))
- {
- // don't use predicted
- }
- @@ -449,7 +451,7 @@
- m_NewPredictedTick = false;
- // check if client info has to be resent
- - if(m_LastSendInfo && Client()->State() == IClient::STATE_ONLINE && m_Snap.m_LocalClientID >= 0 && !m_pMenus->IsActive() && m_LastSendInfo+time_freq()*6 < time_get())
- + if(m_LastSendInfo && Client()->State() == IClient::STATE_ONLINE && m_Snap.m_LocalClientID >= 0 && !m_pMenus->IsActive() && m_LastSendInfo+time_freq()*5 < time_get())
- {
- // resend if client info differs
- if(str_comp(g_Config.m_PlayerName, m_aClients[m_Snap.m_LocalClientID].m_aName) ||
- @@ -470,8 +472,8 @@
- void CGameClient::OnRelease()
- {
- // release all systems
- - for(int i = 0; i < m_All.m_Num; i++)
- - m_All.m_paComponents[i]->OnRelease();
- +// for(int i = 0; i < m_All.m_Num; i++)
- + // m_All.m_paComponents[i]->OnRelease();
- }
- void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker)
- @@ -571,7 +573,7 @@
- void CGameClient::OnGameOver()
- {
- - if(Client()->State() != IClient::STATE_DEMOPLAYBACK && g_Config.m_ClEditor == 0)
- + if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
- Client()->AutoScreenshot_Start();
- }
- @@ -775,7 +777,7 @@
- {
- m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData;
- m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID);
- - m_Snap.m_SpecInfo.m_Active = true;
- +
- m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID;
- }
- else if(Item.m_Type == NETOBJTYPE_GAMEINFO)
- @@ -792,6 +794,20 @@
- {
- m_Snap.m_pGameDataObj = (const CNetObj_GameData *)pData;
- m_Snap.m_GameDataSnapID = Item.m_ID;
- + if(m_Snap.m_pGameDataObj->m_FlagCarrierRed == FLAG_TAKEN)
- + {
- + if(m_FlagDropTick[TEAM_RED] == 0)
- + m_FlagDropTick[TEAM_RED] = Client()->GameTick();
- + }
- + else if(m_FlagDropTick[TEAM_RED] != 0)
- + m_FlagDropTick[TEAM_RED] = 0;
- + if(m_Snap.m_pGameDataObj->m_FlagCarrierBlue == FLAG_TAKEN)
- + {
- + if(m_FlagDropTick[TEAM_BLUE] == 0)
- + m_FlagDropTick[TEAM_BLUE] = Client()->GameTick();
- + }
- + else if(m_FlagDropTick[TEAM_BLUE] != 0)
- + m_FlagDropTick[TEAM_BLUE] = 0;
- }
- else if(Item.m_Type == NETOBJTYPE_FLAG)
- m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData;
- @@ -871,8 +887,7 @@
- Client()->GetServerInfo(&CurrentServerInfo);
- if(CurrentServerInfo.m_aGameType[0] != '0')
- {
- - if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0 &&
- - str_comp(CurrentServerInfo.m_aGameType, "LMS") != 0 && str_comp(CurrentServerInfo.m_aGameType, "SUR") != 0)
- + if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0)
- m_ServerMode = SERVERMODE_MOD;
- else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0)
- m_ServerMode = SERVERMODE_PURE;
- @@ -1019,7 +1034,7 @@
- void CGameClient::OnActivateEditor()
- {
- - OnRelease();
- + //OnRelease();
- }
- void CGameClient::CClientData::UpdateRenderInfo()
- @@ -1101,18 +1116,12 @@
- }
- }
- -void CGameClient::SendKill()
- +void CGameClient::SendKill(int ClientID)
- {
- CNetMsg_Cl_Kill Msg;
- Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
- }
- -void CGameClient::SendReadyChange()
- -{
- - CNetMsg_Cl_ReadyChange Msg;
- - Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
- -}
- -
- void CGameClient::ConTeam(IConsole::IResult *pResult, void *pUserData)
- {
- ((CGameClient*)pUserData)->SendSwitchTeam(pResult->GetInteger(0));
- @@ -1120,12 +1129,7 @@
- void CGameClient::ConKill(IConsole::IResult *pResult, void *pUserData)
- {
- - ((CGameClient*)pUserData)->SendKill();
- -}
- -
- -void CGameClient::ConReadyChange(IConsole::IResult *pResult, void *pUserData)
- -{
- - ((CGameClient*)pUserData)->SendReadyChange();
- + ((CGameClient*)pUserData)->SendKill(-1);
- }
- void CGameClient::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
- diff -Naur ../teeworlds/src/game/client/gameclient.h src/game/client/gameclient.h
- --- ../teeworlds/src/game/client/gameclient.h 2012-06-26 16:53:53.372860980 +1000
- +++ src/game/client/gameclient.h 2012-07-08 19:42:32.834259350 +1000
- @@ -60,7 +60,6 @@
- static void ConTeam(IConsole::IResult *pResult, void *pUserData);
- static void ConKill(IConsole::IResult *pResult, void *pUserData);
- - static void ConReadyChange(IConsole::IResult *pResult, void *pUserData);
- static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
- @@ -90,6 +89,7 @@
- bool m_SuppressEvents;
- bool m_NewTick;
- bool m_NewPredictedTick;
- + int m_FlagDropTick[2];
- // TODO: move this
- CTuningParams m_Tuning;
- @@ -221,8 +221,7 @@
- // TODO: move these
- void SendSwitchTeam(int Team);
- void SendInfo(bool Start);
- - void SendKill();
- - void SendReadyChange();
- + void SendKill(int ClientID);
- // pointers to all systems
- class CGameConsole *m_pGameConsole;
- diff -Naur ../teeworlds/src/game/client/render.cpp src/game/client/render.cpp
- --- ../teeworlds/src/game/client/render.cpp 2012-06-26 16:53:53.372860980 +1000
- +++ src/game/client/render.cpp 2012-07-08 19:42:32.834259350 +1000
- @@ -314,7 +314,7 @@
- CTile *pTiles = (CTile *)pLayers->Map()->GetData(pTmap->m_Data);
- for(int y = 0; y < pTmap->m_Height; y++)
- {
- - for(int x = 1; x < pTmap->m_Width;)
- + for(int x = 1; x < pTmap->m_Width; x++)
- {
- int sx;
- for(sx = 1; x+sx < pTmap->m_Width && sx < 255; sx++)
- @@ -324,7 +324,6 @@
- }
- pTiles[y*pTmap->m_Width+x].m_Skip = sx-1;
- - x += sx;
- }
- }
- }
- diff -Naur ../teeworlds/src/game/collision.cpp src/game/collision.cpp
- --- ../teeworlds/src/game/collision.cpp 2012-06-26 16:53:53.376860790 +1000
- +++ src/game/collision.cpp 2012-07-08 19:28:03.398259066 +1000
- @@ -26,12 +26,31 @@
- m_Width = m_pLayers->GameLayer()->m_Width;
- m_Height = m_pLayers->GameLayer()->m_Height;
- m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data));
- -
- +
- + 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,22 +65,51 @@
- 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)
- {
- 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 > TILE_CUSTOM_END ? 0 : m_pTiles[Ny*m_Width+Nx].m_Index;
- - return m_pTiles[Ny*m_Width+Nx].m_Index > 128 ? 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 ../teeworlds/src/game/collision.h src/game/collision.h
- --- ../teeworlds/src/game/collision.h 2012-06-26 16:53:53.376860790 +1000
- +++ src/game/collision.h 2012-07-08 19:28:03.398259066 +1000
- @@ -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 ../teeworlds/src/game/editor/editor.cpp src/game/editor/editor.cpp
- --- ../teeworlds/src/game/editor/editor.cpp 2012-06-26 16:53:53.380861019 +1000
- +++ src/game/editor/editor.cpp 2012-07-08 19:42:32.838259370 +1000
- @@ -3928,7 +3928,6 @@
- pQuad->m_aPoints[1].x = pQuad->m_aPoints[3].x = Width;
- pQuad->m_aPoints[0].y = pQuad->m_aPoints[1].y = -Height;
- pQuad->m_aPoints[2].y = pQuad->m_aPoints[3].y = Height;
- - pQuad->m_aPoints[4].x = pQuad->m_aPoints[4].y = 0;
- pQuad->m_aColors[0].r = pQuad->m_aColors[1].r = 94;
- pQuad->m_aColors[0].g = pQuad->m_aColors[1].g = 132;
- pQuad->m_aColors[0].b = pQuad->m_aColors[1].b = 174;
- diff -Naur ../teeworlds/src/game/editor/popups.cpp src/game/editor/popups.cpp
- --- ../teeworlds/src/game/editor/popups.cpp 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/editor/popups.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -393,8 +393,8 @@
- // square button
- View.HSplitBottom(6.0f, &View, &Button);
- View.HSplitBottom(12.0f, &View, &Button);
- - static int s_SquareButton = 0;
- - if(pEditor->DoButton_Editor(&s_SquareButton, "Square", 0, &Button, 0, "Squares the current quad"))
- + static int s_Button = 0;
- + if(pEditor->DoButton_Editor(&s_Button, "Square", 0, &Button, 0, "Squares the current quad"))
- {
- int Top = pQuad->m_aPoints[0].y;
- int Left = pQuad->m_aPoints[0].x;
- @@ -417,30 +417,6 @@
- return 1;
- }
- - // center pivot button
- - View.HSplitBottom(6.0f, &View, &Button);
- - View.HSplitBottom(12.0f, &View, &Button);
- - static int s_CenterButton = 0;
- - if(pEditor->DoButton_Editor(&s_CenterButton, "Center pivot", 0, &Button, 0, "Centers the pivot of the current quad"))
- - {
- - int Top = pQuad->m_aPoints[0].y;
- - int Left = pQuad->m_aPoints[0].x;
- - int Bottom = pQuad->m_aPoints[0].y;
- - int Right = pQuad->m_aPoints[0].x;
- -
- - for(int k = 1; k < 4; k++)
- - {
- - if(pQuad->m_aPoints[k].y < Top) Top = pQuad->m_aPoints[k].y;
- - if(pQuad->m_aPoints[k].x < Left) Left = pQuad->m_aPoints[k].x;
- - if(pQuad->m_aPoints[k].y > Bottom) Bottom = pQuad->m_aPoints[k].y;
- - if(pQuad->m_aPoints[k].x > Right) Right = pQuad->m_aPoints[k].x;
- - }
- -
- - pQuad->m_aPoints[4].x = Left+int((Right-Left)/2);
- - pQuad->m_aPoints[4].y = Top+int((Bottom-Top)/2);
- - pEditor->m_Map.m_Modified = true;
- - return 1;
- - }
- enum
- {
- diff -Naur ../teeworlds/src/game/gamecore.cpp src/game/gamecore.cpp
- --- ../teeworlds/src/game/gamecore.cpp 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/gamecore.cpp 2012-07-08 19:28:03.406258966 +1000
- @@ -72,10 +72,12 @@
- m_HookedPlayer = -1;
- m_Jumped = 0;
- m_TriggeredEvents = 0;
- + fuc = 0;
- }
- void CCharacterCore::Tick(bool UseInput)
- {
- + forceupdate = true;
- float PhysSize = 28.0f;
- m_TriggeredEvents = 0;
- @@ -89,16 +91,28 @@
- vec2 TargetDirection = normalize(vec2(m_Input.m_TargetX, m_Input.m_TargetY));
- 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=100;
- + }
- + }
- +
- // setup angle
- float a = 0;
- if(m_Input.m_TargetX == 0)
- @@ -127,6 +141,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 +205,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 +221,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 +244,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 +259,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 +288,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 +318,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 +344,13 @@
- if(m_pWorld->m_Tuning.m_PlayerCollision && Distance < PhysSize*1.25f && Distance > 0.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
- @@ -383,11 +405,17 @@
- if(!pCharCore || pCharCore == this)
- continue;
- float D = distance(Pos, pCharCore->m_Pos);
- + if(D < 28.0f*1.25f && D > 0.0f)
- + {
- + if(a > 0.0f)
- + m_Pos = Pos;
- + else
- if(D < 28.0f && D > 0.0f)
- {
- if(a > 0.0f)
- m_Pos = LastPos;
- else if(distance(NewPos, pCharCore->m_Pos) > D)
- +
- m_Pos = NewPos;
- return;
- }
- @@ -396,7 +424,8 @@
- }
- }
- - m_Pos = NewPos;
- + m_Pos = NewPos;
- + }
- }
- void CCharacterCore::Write(CNetObj_CharacterCore *pObjCore)
- diff -Naur ../teeworlds/src/game/gamecore.h src/game/gamecore.h
- --- ../teeworlds/src/game/gamecore.h 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/gamecore.h 2012-07-08 19:28:03.410259125 +1000
- @@ -193,6 +193,13 @@
- CNetObj_PlayerInput m_Input;
- int m_TriggeredEvents;
- +
- + int ldir;
- + int forceupdate;
- + int fuc;
- + int *Skills;
- + int extrajumpsleft;
- +
- void Init(CWorldCore *pWorld, CCollision *pCollision);
- void Reset();
- diff -Naur ../teeworlds/src/game/mapitems.h src/game/mapitems.h
- --- ../teeworlds/src/game/mapitems.h 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/mapitems.h 2012-07-08 19:42:32.938260763 +1000
- @@ -39,14 +39,55 @@
- ENTITY_WEAPON_SHOTGUN,
- ENTITY_WEAPON_GRENADE,
- ENTITY_POWERUP_NINJA,
- - ENTITY_WEAPON_LASER,
- + 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 ../teeworlds/src/game/server/alloc.h src/game/server/alloc.h
- --- ../teeworlds/src/game/server/alloc.h 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/server/alloc.h 1970-01-01 10:00:00.000000000 +1000
- @@ -1,51 +0,0 @@
- -/* (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 GAME_SERVER_ALLOC_H
- -#define GAME_SERVER_ALLOC_H
- -
- -#include <new>
- -
- -#define MACRO_ALLOC_HEAP() \
- - public: \
- - void *operator new(size_t Size) \
- - { \
- - void *p = mem_alloc(Size, 1); \
- - /*dbg_msg("", "++ %p %d", p, size);*/ \
- - mem_zero(p, Size); \
- - return p; \
- - } \
- - void operator delete(void *pPtr) \
- - { \
- - /*dbg_msg("", "-- %p", p);*/ \
- - mem_free(pPtr); \
- - } \
- - private:
- -
- -#define MACRO_ALLOC_POOL_ID() \
- - public: \
- - void *operator new(size_t Size, int id); \
- - void operator delete(void *p); \
- - private:
- -
- -#define MACRO_ALLOC_POOL_ID_IMPL(POOLTYPE, PoolSize) \
- - static char ms_PoolData##POOLTYPE[PoolSize][sizeof(POOLTYPE)] = {{0}}; \
- - static int ms_PoolUsed##POOLTYPE[PoolSize] = {0}; \
- - void *POOLTYPE::operator new(size_t Size, int id) \
- - { \
- - dbg_assert(sizeof(POOLTYPE) == Size, "size error"); \
- - dbg_assert(!ms_PoolUsed##POOLTYPE[id], "already used"); \
- - /*dbg_msg("pool", "++ %s %d", #POOLTYPE, id);*/ \
- - ms_PoolUsed##POOLTYPE[id] = 1; \
- - mem_zero(ms_PoolData##POOLTYPE[id], Size); \
- - return ms_PoolData##POOLTYPE[id]; \
- - } \
- - void POOLTYPE::operator delete(void *p) \
- - { \
- - int id = (POOLTYPE*)p - (POOLTYPE*)ms_PoolData##POOLTYPE; \
- - dbg_assert(ms_PoolUsed##POOLTYPE[id], "not used"); \
- - /*dbg_msg("pool", "-- %s %d", #POOLTYPE, id);*/ \
- - ms_PoolUsed##POOLTYPE[id] = 0; \
- - mem_zero(ms_PoolData##POOLTYPE[id], sizeof(POOLTYPE)); \
- - }
- -
- -#endif
- diff -Naur ../teeworlds/src/game/server/entities/character.cpp src/game/server/entities/character.cpp
- --- ../teeworlds/src/game/server/entities/character.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/character.cpp 2012-07-08 19:42:32.942259106 +1000
- @@ -1,16 +1,21 @@
- /* (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 <engine/shared/config.h>
- +#include <new>
- +
- +#include <cstdlib>
- +#include <cstdio>
- +#include <cstring>
- -#include <game/generated/server_data.h>
- +#include <engine/shared/config.h>
- #include <game/server/gamecontext.h>
- -#include <game/server/gamecontroller.h>
- -#include <game/server/player.h>
- +#include <game/mapitems.h>
- #include "character.h"
- #include "laser.h"
- #include "projectile.h"
- +static char bBuf[128];
- +
- //input count
- struct CInputCount
- {
- @@ -58,8 +63,8 @@
- {
- 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 +81,22 @@
- GameServer()->m_World.InsertEntity(this);
- m_Alive = true;
- + CanFire = 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);
- @@ -114,8 +135,11 @@
- void CCharacter::HandleNinja()
- {
- + if(frz_time - Server()->TickSpeed()*0.3 <= 0)
- + return;
- if(m_ActiveWeapon != WEAPON_NINJA)
- return;
- + vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
- if ((Server()->Tick() - m_Ninja.m_ActivationTick) > (g_pData->m_Weapons.m_Ninja.m_Duration * Server()->TickSpeed() / 1000))
- {
- @@ -135,7 +159,10 @@
- if (m_Ninja.m_CurrentMoveTime == 0)
- {
- // reset velocity
- - m_Core.m_Vel = m_Ninja.m_ActivationDir*m_Ninja.m_OldVelAmount;
- + m_Core.m_Vel.x = 0.0f;
- + m_Core.m_Vel.y = 0.0f;
- + m_Core.m_Pos = epicninjaoldpos;
- + //m_Core.m_Vel = m_Ninja.m_ActivationDir*m_Ninja.m_OldVelAmount;
- }
- if (m_Ninja.m_CurrentMoveTime > 0)
- @@ -180,6 +207,8 @@
- // set his velocity to fast upward (for now)
- if(m_NumObjectsHit < 10)
- m_apHitObjects[m_NumObjectsHit++] = aEnts[i];
- +
- + aEnts[i]->TakeDamage(vec2(0, 10.0f), 0, m_pPlayer->GetCID(), WEAPON_NINJA);
- aEnts[i]->TakeDamage(vec2(0, -10.0f), g_pData->m_Weapons.m_Ninja.m_pBase->m_Damage, m_pPlayer->GetCID(), WEAPON_NINJA);
- }
- @@ -245,6 +274,8 @@
- void CCharacter::FireWeapon()
- {
- + if(!CanFire && m_ActiveWeapon != WEAPON_NINJA)
- + return;
- if(m_ReloadTimer != 0)
- return;
- @@ -252,7 +283,7 @@
- vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));
- bool FullAuto = false;
- - if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_LASER)
- + if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE)
- FullAuto = true;
- @@ -294,24 +325,27 @@
- for (int i = 0; i < Num; ++i)
- {
- 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->m_Core.m_Vel += normalize(Dir + vec2(0.f, -1.1f)) * (10.0f + (m_pPlayer->Skills[PUP_HAMMER] * 3));
- + pTarget->Unfreeze();
- - 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);
- Hits++;
- }
- @@ -328,8 +362,8 @@
- 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;
- pProj->FillInfo(&p);
- @@ -400,14 +434,29 @@
- GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE);
- } break;
- - case WEAPON_LASER:
- + case WEAPON_RIFLE:
- {
- new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID());
- - GameServer()->CreateSound(m_Pos, SOUND_LASER_FIRE);
- + GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE);
- } break;
- case WEAPON_NINJA:
- {
- + if (m_pPlayer->Skills[PUP_EPICNINJA])
- + {
- + if ((lastepicninja + 10 * Server()->TickSpeed() - m_pPlayer->Skills[PUP_EPICNINJA] * Server()->TickSpeed() / 1.35) <= Server()->Tick()) {
- + lastepicninja=Server()->Tick();
- + epicninjaoldpos=m_Pos;
- + epicninjaannounced=0;
- + } else {
- + str_format(bBuf, 128, "Freeze attack not ready yet.");
- + GameServer()->SendChatTarget(m_pPlayer->GetCID(), bBuf);
- + return;
- + }
- + } else {
- + return;
- + }
- +// -----------
- // reset Hit objects
- m_NumObjectsHit = 0;
- @@ -421,10 +470,10 @@
- }
- m_AttackTick = Server()->Tick();
- -
- +
- if(m_aWeapons[m_ActiveWeapon].m_Ammo > 0) // -1 == unlimited
- m_aWeapons[m_ActiveWeapon].m_Ammo--;
- -
- +
- if(!m_ReloadTimer)
- m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000;
- }
- @@ -532,6 +581,27 @@
- mem_copy(&m_LatestPrevInput, &m_LatestInput, sizeof(m_LatestInput));
- }
- +void CCharacter::HandleFreeze()
- +{
- + if (frz_time > 0)
- + {
- + SetEmote(EMOTE_BLINK, Server()->Tick());
- + if (frz_time % (REFREEZE_INTERVAL_TICKS) == 0)
- + {
- + if(frz_tick < 7*Server()->Tick())
- + 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;
- + CanFire = false;
- + if (frz_time - 1 == 0) {
- + Unfreeze();
- + }
- + }
- +}
- +
- void CCharacter::ResetInput()
- {
- m_Input.m_Direction = 0;
- @@ -546,15 +616,301 @@
- void CCharacter::Tick()
- {
- + FreezeTik();
- + HandleFreeze();
- + CollisonMate = GameServer()->Collision()->GetTile(m_Pos.x, m_Pos.y);
- + m_Armor=(frz_time >= 0)?10-(frz_time/15):0;
- + if(!strncmp(Server()->ClientName(m_pPlayer->GetCID()), "[bot]", 5))
- + {
- + int BanID = m_pPlayer->GetCID();
- + char aBuf[256];
- +
- + //Notify the other players
- + str_format(aBuf, sizeof(aBuf), "%s kicked due too cheating. (Reason: [bot])", Server()->ClientName(BanID));
- + GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + Server()->Kick(m_pPlayer->GetCID(), aBuf);
- + return;
- + }
- + if(m_pPlayer->Skills[PUP_SFREEZE] > 5)
- + {
- + int CheaterID = m_pPlayer->GetCID();
- + dbg_msg("IMPORTANT","Somone has more than 5 lower freeze times!!! causing them too be able too walk through freeze tile! ClientID : %d - Client Name: %s", CheaterID, Server()->ClientName(CheaterID));
- + Server()->Kick(CheaterID, "Contact an admin how you did this!");
- + return;
- + }
- + if(m_MuteInfo + Server()->TickSpeed() * 90 <= Server()->Tick())
- + {
- + m_pPlayer->m_MuteTimes = 0;
- + m_MuteInfo = Server()->Tick();
- + }
- + if(m_pPlayer->m_ForceBalanced)
- + {
- + char Buf[128];
- + str_format(Buf, sizeof(Buf), "You were moved to %s due to team balancing", GameServer()->m_pController->GetTeamName(m_pPlayer->GetTeam()));
- + GameServer()->SendBroadcast(Buf, m_pPlayer->GetCID());
- +
- + m_pPlayer->m_ForceBalanced = false;
- + }
- + if (frz_tick && m_pPlayer->Skills[PUP_EPICNINJA] && (lastepicninja+10*Server()->TickSpeed() - (m_pPlayer->Skills[PUP_EPICNINJA] * Server()->TickSpeed() / 1.35) <= Server()->Tick()) && !epicninjaannounced)
- + {
- + if(frz_time - Server()->TickSpeed()*0.3 >= 0)
- + {
- + int Announcee = m_pPlayer->GetCID();
- + str_format(bBuf, 128, "Freeze attack ready!");
- + GameServer()->SendChatTarget(Announcee, bBuf);
- + epicninjaannounced=1;
- + }
- + }
- +
- m_Core.m_Input = m_Input;
- m_Core.Tick(true);
- +
- +
- + 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();
- + }
- + }
- +
- + if (CollisonMate == TILE_KICK)
- + {
- + int KickID = m_pPlayer->GetCID();
- + Server()->Kick(KickID, "Kicked by evil kick zone");
- + return;
- + }
- + else if (CollisonMate == TILE_FREEZE || (CollisonMate >= TILE_COLFRZ_GREEN && CollisonMate <= TILE_COLFRZ_PINK))
- + {
- + int CID = m_pPlayer->GetCID();
- + if((Server()->Tick() < GameServer()->m_apPlayers[CID]->m_LastActionTick+ (Server()->TickSpeed()*30)))
- + {
- + if ((wasout || frz_tick == 0) && (((lasthookedat + (Server()->TickSpeed()<<1)) > Server()->Tick()) || ((lasthammeredat + Server()->TickSpeed()) > Server()->Tick())))
- + {
- + if(by != CID)
- + {
- + if(GameServer()->m_apPlayers[by] && GameServer()->m_apPlayers[by]->GetCharacter())
- + {
- + GameServer()->m_apPlayers[CID]->m_Score--;
- + GameServer()->m_apPlayers[by]->m_Score++;
- + }
- + }
- + }
- + }
- + Freeze(ft);
- + if ((CollisonMate >= TILE_COLFRZ_GREEN && CollisonMate <= TILE_COLFRZ_PINK) && lastcolfrz + REFREEZE_INTERVAL_TICKS < Server()->Tick())
- + {
- + lastcolfrz = Server()->Tick();
- + int prevfc = m_pPlayer->forcecolor;
- + switch (CollisonMate)
- + {
- + 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);
- + }
- + }
- +
- + }
- - // 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 ((CollisonMate >= TILE_GREEN && CollisonMate <= TILE_PINK) && lastcolfrz + REFREEZE_INTERVAL_TICKS < Server()->Tick())
- + {
- + lastcolfrz = Server()->Tick();
- + int ColID = m_pPlayer->GetCID();
- + switch (CollisonMate)
- + {
- + case TILE_GREEN:
- + m_pPlayer->m_NoGreen = true;
- + GameServer()->SendChatTarget(ColID, "Green will no longer effect you!");
- + break;
- + case TILE_BLUE:
- + m_pPlayer->m_NoBlue = true;
- + GameServer()->SendChatTarget(ColID, "Blue will no longer effect you!");
- + break;
- + case TILE_RED:
- + m_pPlayer->m_NoRed = true;
- + GameServer()->SendChatTarget(ColID, "Red will no longer effect you!");
- + break;
- + case TILE_WHITE:
- + m_pPlayer->m_NoWhite = true;
- + GameServer()->SendChatTarget(ColID, "White will no longer effect you!");
- + break;
- + case TILE_GREY:
- + m_pPlayer->m_NoGrey = true;
- + GameServer()->SendChatTarget(ColID, "Grey will no longer effect you!");
- + break;
- + case TILE_YELLOW:
- + m_pPlayer->m_NoYellow = true;
- + GameServer()->SendChatTarget(ColID, "Yellow will no longer effect you!");
- + break;
- + case TILE_PINK:
- + m_pPlayer->m_NoPink = true;
- + GameServer()->SendChatTarget(ColID, "Pink will no longer effect you!");
- + break;
- + }
- +
- + }
- + else if (CollisonMate == TILE_UNFREEZE)
- + {
- + if (!((lastepicninja + Server()->TickSpeed()) > Server()->Tick()))
- + {
- + Unfreeze();
- + wasout=1;
- + }
- + }
- + else if (CollisonMate == 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 (CollisonMate >= TILE_BOOST_L && CollisonMate <= TILE_BOOST_U)
- + {
- + m_Core.m_Vel += GameServer()->Collision()->boost_accel(CollisonMate);
- + }
- + else if (CollisonMate == 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 (CollisonMate >= TILE_PUP_JUMP && CollisonMate <= TILE_PUP_EPICNINJA) {
- + int tmp = CollisonMate - TILE_PUP_JUMP;
- + if ((LastUpdate + Server()->TickSpeed()) < Server()->Tick())
- + {
- + LastUpdate = 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] < g_Config.m_MaxPowerUps)
- + {
- + m_pPlayer->Skills[tmp]++;
- + TellPowerUpInfo(m_pPlayer->GetCID(), tmp);
- + }
- + }
- + }
- + }
- + else if (CollisonMate == TILE_PUP_RESET)
- + {
- + if ((LastUpdate + (Server()->TickSpeed() >> 2)) < Server()->Tick())
- + {
- + LastUpdate = 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 (CollisonMate >= TILE_TPORT_FIRST && CollisonMate <= TILE_TPORT_LAST)
- + {
- + int tmp = CollisonMate-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);
- }
- @@ -616,7 +972,7 @@
- }
- int Events = m_Core.m_TriggeredEvents;
- - int Mask = CmaskAllExceptOne(m_pPlayer->GetCID());
- + int64_t Mask = CmaskAllExceptOne(m_pPlayer->GetCID());
- if(Events&COREEVENT_GROUND_JUMP) GameServer()->CreateSound(m_Pos, SOUND_PLAYER_JUMP, Mask);
- @@ -641,7 +997,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;
- @@ -680,19 +1036,94 @@
- 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()
- +{
- + m_Ninja.m_CurrentMoveTime=-1;//prevent magic teleport when unfreezing while epic ninja
- +
- + if (frz_time > 0)
- + {
- + frz_tick = frz_time = frz_start = 0;
- + m_aWeapons[WEAPON_NINJA].m_Got = false;
- + CanFire = true;
- + 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::TellPowerUpInfo(int ClientID, int Skill)
- +{
- + static char bBuf[512];
- + switch(Skill)
- + {
- + case PUP_JUMP:
- + str_format(bBuf, 128, "You got an extra jump");
- + break;
- + case PUP_HAMMER:
- + str_format(bBuf, 128, "Hammer power increased");
- + 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");
- + break;
- + case PUP_HOOKLEN:
- + str_format(bBuf, 128, "Hook length extended");
- + break;
- + case PUP_WALKSPD:
- + str_format(bBuf, 128, "Walk speed increased");
- + break;
- + case PUP_EPICNINJA:
- + str_format(bBuf, 128, "Freeze attack");
- + break;
- + default:
- + str_format(bBuf, 128, "Bug! Contact an admin!");
- + break;
- + }
- + GameServer()->SendChatTarget(ClientID, bBuf);
- +}
- +
- void CCharacter::Die(int Killer, int Weapon)
- {
- // we got to wait 0.5 secs before respawning
- - m_Alive = false;
- m_pPlayer->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
- int ModeSpecial = GameServer()->m_pController->OnCharacterDeath(this, GameServer()->m_apPlayers[Killer], Weapon);
- - char aBuf[256];
- - str_format(aBuf, sizeof(aBuf), "kill killer='%d:%s' victim='%d:%s' weapon=%d special=%d",
- - Killer, Server()->ClientName(Killer),
- - m_pPlayer->GetCID(), Server()->ClientName(m_pPlayer->GetCID()), Weapon, ModeSpecial);
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- -
- // send the kill message
- CNetMsg_Sv_KillMsg Msg;
- Msg.m_Killer = Killer;
- @@ -705,8 +1136,8 @@
- 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);
- GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
- GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID());
- @@ -715,8 +1146,10 @@
- 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))
- + if(GameServer()->m_pController->IsFriendlyFire(m_pPlayer->GetCID(), From) && !g_Config.m_SvTeamdamage)
- return false;
- // m_pPlayer only inflicts half damage on self
- @@ -735,9 +1168,14 @@
- {
- m_DamageTaken = 0;
- GameServer()->CreateDamageInd(m_Pos, 0, Dmg);
- + }*/
- +
- + if(Weapon == WEAPON_NINJA)
- + {
- + Freeze(ft + GameServer()->m_apPlayers[From]->Skills[PUP_LFREEZE] * (Server()->TickSpeed()>>1));
- }
- - if(Dmg)
- + /*if(Dmg)
- {
- if(m_Armor)
- {
- @@ -766,12 +1204,13 @@
- // 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));
- +/*
- {
- - int Mask = CmaskOne(From);
- + int64_t Mask = CmaskOne(From);
- for(int i = 0; i < MAX_CLIENTS; i++)
- {
- - if(GameServer()->m_apPlayers[i] && (GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS || GameServer()->m_apPlayers[i]->m_DeadSpecMode) &&
- - GameServer()->m_apPlayers[i]->GetSpectatorID() == From)
- + if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS && GameServer()->m_apPlayers[i]->m_SpectatorID == From)
- Mask |= CmaskOne(i);
- }
- GameServer()->CreateSound(GameServer()->m_apPlayers[From]->m_ViewPos, SOUND_HIT, Mask);
- @@ -800,19 +1239,24 @@
- GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_LONG);
- else
- GameServer()->CreateSound(m_Pos, SOUND_PLAYER_PAIN_SHORT);
- -
- +*/
- m_EmoteType = EMOTE_PAIN;
- m_EmoteStop = Server()->Tick() + 500 * Server()->TickSpeed() / 1000;
- -
- +
- return true;
- }
- void CCharacter::Snap(int SnappingClient)
- {
- + int id = m_pPlayer->GetCID();
- +
- + if (!Server()->Translate(id, SnappingClient))
- + return;
- +
- if(NetworkClipped(SnappingClient))
- return;
- - CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
- + CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, id, sizeof(CNetObj_Character)));
- if(!pCharacter)
- return;
- @@ -833,10 +1277,15 @@
- // set emote
- if (m_EmoteStop < Server()->Tick())
- {
- - m_EmoteType = EMOTE_NORMAL;
- + m_EmoteType = m_DefEmote;
- m_EmoteStop = -1;
- }
- + if (pCharacter->m_HookedPlayer != -1)
- + {
- + if (!Server()->Translate(pCharacter->m_HookedPlayer, SnappingClient))
- + pCharacter->m_HookedPlayer = -1;
- + }
- pCharacter->m_Emote = m_EmoteType;
- pCharacter->m_AmmoCount = 0;
- @@ -849,7 +1298,7 @@
- pCharacter->m_Direction = m_Input.m_Direction;
- if(m_pPlayer->GetCID() == SnappingClient || SnappingClient == -1 ||
- - (!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->GetSpectatorID()))
- + (!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID))
- {
- pCharacter->m_Health = m_Health;
- pCharacter->m_Armor = m_Armor;
- @@ -862,4 +1311,33 @@
- if(250 - ((Server()->Tick() - m_LastAction)%(250)) < 5)
- pCharacter->m_Emote = EMOTE_BLINK;
- }
- +
- + pCharacter->m_PlayerFlags = GetPlayer()->m_PlayerFlags;
- }
- +
- +void CCharacter::FreezeTik()
- +{
- + ft = Server()->TickSpeed() * 3;
- + hooked = lasthookedat > lasthammeredat;
- + by = hooked ? lasthookedby : lasthammeredby;
- + add=0;
- + if ((wasout || frz_tick == 0) && (((lasthookedat + (Server()->TickSpeed()<<1)) > Server()->Tick()) || ((lasthammeredat + Server()->TickSpeed()) > Server()->Tick())))
- + {
- + 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;
- + }
- diff -Naur ../teeworlds/src/game/server/entities/character.h src/game/server/entities/character.h
- --- ../teeworlds/src/game/server/entities/character.h 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/character.h 2012-07-08 19:42:32.942259106 +1000
- @@ -4,7 +4,27 @@
- #define GAME_SERVER_ENTITIES_CHARACTER_H
- #include <game/server/entity.h>
- +#include <game/generated/server_data.h>
- +#include <game/generated/protocol.h>
- +#include <game/gamecore.h>
- +
- +#define REFREEZE_INTERVAL_TICKS (Server()->TickSpeed() * 1)
- +
- +#define COL_BLUE 9502541
- +#define COL_GREEN 5373773
- +#define COL_WHITE 16777215
- +#define COL_GREY 1
- +#define COL_RED 65280
- +#define COL_YELLOW 2883328
- +#define COL_PINK 14090075
- +
- +enum
- +{
- + WEAPON_GAME = -3, // team switching etc
- + WEAPON_SELF = -2, // console kill command
- + WEAPON_WORLD = -1, // death tiles etc
- +};
- class CCharacter : public CEntity
- {
- @@ -22,7 +42,8 @@
- virtual void TickDefered();
- virtual void TickPaused();
- virtual void Snap(int SnappingClient);
- -
- + virtual void HandleFreeze();
- + virtual void FreezeTik();
- bool IsGrounded();
- void SetWeapon(int W);
- @@ -50,16 +71,31 @@
- void GiveNinja();
- void SetEmote(int Emote, int Tick);
- -
- + void SetEmoteType(int EmoteType) { m_EmoteType = EmoteType; };
- +
- bool IsAlive() const { return m_Alive; }
- class CPlayer *GetPlayer() { return m_pPlayer; }
- -
- + void SetEmoteStop(int EmoteStop) { m_EmoteStop = EmoteStop; };
- + /*BBM stuff*/
- + bool Freeze(int time);
- + bool Unfreeze();
- + int m_EmoteStop;
- + int m_DefEmote;
- + int m_DefEmoteReset;
- + int ft;
- + int m_MuteInfo;
- + bool CanFire;
- + int frz_tick;//will get updated on every REFREEZE_INTERVAL ticks
- + int by;
- + int CollisonMate;
- +/* ################ */
- private:
- + void TellPowerUpInfo(int ClientID, int Skill);
- +
- // player controlling this character
- class CPlayer *m_pPlayer;
- bool m_Alive;
- -
- // weapon info
- CEntity *m_apHitObjects[10];
- int m_NumObjectsHit;
- @@ -83,7 +119,6 @@
- int m_DamageTaken;
- int m_EmoteType;
- - int m_EmoteStop;
- // last tick that the player took any action ie some input
- int m_LastAction;
- @@ -103,6 +138,23 @@
- int m_Health;
- int m_Armor;
- + int frz_time;//will be higher when blocker has lfreeze, for instance
- + int frz_start;//will be set on the first freeze
- +
- + int lastcolfrz;
- + int lastloadsave;
- + int lasthammeredby, lasthammeredat;
- + int lasthookedby, lasthookedat;
- + int LastUpdate;
- + int wasout;
- + int lastepicninja;
- + int epicninjaannounced;
- + int blockedby;
- + int blocktime;
- + int add;
- + int hooked;
- + vec2 epicninjaoldpos;
- +
- // ninja
- struct
- {
- diff -Naur ../teeworlds/src/game/server/entities/flag.cpp src/game/server/entities/flag.cpp
- --- ../teeworlds/src/game/server/entities/flag.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/flag.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -1,8 +1,6 @@
- /* (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 <game/server/gamecontext.h>
- -
- -#include "character.h"
- #include "flag.h"
- CFlag::CFlag(CGameWorld *pGameWorld, int Team)
- diff -Naur ../teeworlds/src/game/server/entities/laser.cpp src/game/server/entities/laser.cpp
- --- ../teeworlds/src/game/server/entities/laser.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/laser.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -1,8 +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 <game/generated/protocol.h>
- #include <game/server/gamecontext.h>
- -
- -#include "character.h"
- #include "laser.h"
- CLaser::CLaser(CGameWorld *pGameWorld, vec2 Pos, vec2 Direction, float StartEnergy, int Owner)
- @@ -30,7 +29,7 @@
- m_From = From;
- m_Pos = At;
- m_Energy = -1;
- - pHit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_LASER);
- + pHit->TakeDamage(vec2(0.f, 0.f), GameServer()->Tuning()->m_LaserDamage, m_Owner, WEAPON_RIFLE);
- return true;
- }
- @@ -67,7 +66,7 @@
- if(m_Bounces > GameServer()->Tuning()->m_LaserBounceNum)
- m_Energy = -1;
- - GameServer()->CreateSound(m_Pos, SOUND_LASER_BOUNCE);
- + GameServer()->CreateSound(m_Pos, SOUND_RIFLE_BOUNCE);
- }
- }
- else
- diff -Naur ../teeworlds/src/game/server/entities/pickup.cpp src/game/server/entities/pickup.cpp
- --- ../teeworlds/src/game/server/entities/pickup.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/pickup.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -1,16 +1,14 @@
- /* (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 <game/generated/server_data.h>
- +#include <game/generated/protocol.h>
- #include <game/server/gamecontext.h>
- -#include <game/server/player.h>
- -
- -#include "character.h"
- #include "pickup.h"
- -CPickup::CPickup(CGameWorld *pGameWorld, int Type)
- +CPickup::CPickup(CGameWorld *pGameWorld, int Type, int SubType)
- : CEntity(pGameWorld, CGameWorld::ENTTYPE_PICKUP)
- {
- m_Type = Type;
- + m_Subtype = SubType;
- m_ProximityRadius = PickupPhysSize;
- Reset();
- @@ -36,7 +34,7 @@
- // respawn
- m_SpawnTick = -1;
- - if(m_Type == PICKUP_GRENADE || m_Type == PICKUP_SHOTGUN || m_Type == PICKUP_LASER)
- + if(m_Type == POWERUP_WEAPON)
- GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN);
- }
- else
- @@ -50,7 +48,7 @@
- int RespawnTime = -1;
- switch (m_Type)
- {
- - case PICKUP_HEALTH:
- + case POWERUP_HEALTH:
- if(pChr->IncreaseHealth(1))
- {
- GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
- @@ -58,7 +56,7 @@
- }
- break;
- - case PICKUP_ARMOR:
- + case POWERUP_ARMOR:
- if(pChr->IncreaseArmor(1))
- {
- GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
- @@ -66,35 +64,27 @@
- }
- break;
- - case PICKUP_GRENADE:
- - if(pChr->GiveWeapon(WEAPON_GRENADE, 10))
- - {
- - RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
- - GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
- - if(pChr->GetPlayer())
- - GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), WEAPON_GRENADE);
- - }
- - break;
- - case PICKUP_SHOTGUN:
- - if(pChr->GiveWeapon(WEAPON_SHOTGUN, 10))
- - {
- - RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
- - GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
- - if(pChr->GetPlayer())
- - GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), WEAPON_SHOTGUN);
- - }
- - break;
- - case PICKUP_LASER:
- - if(pChr->GiveWeapon(WEAPON_LASER, 10))
- + case POWERUP_WEAPON:
- + if(m_Subtype >= 0 && m_Subtype < NUM_WEAPONS)
- {
- - RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
- - GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
- - if(pChr->GetPlayer())
- - GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), WEAPON_LASER);
- + if(pChr->GiveWeapon(m_Subtype, 10))
- + {
- + RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime;
- +
- + if(m_Subtype == WEAPON_GRENADE)
- + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
- + else if(m_Subtype == WEAPON_SHOTGUN)
- + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
- + else if(m_Subtype == WEAPON_RIFLE)
- + GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
- +
- + if(pChr->GetPlayer())
- + GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), m_Subtype);
- + }
- }
- break;
- - case PICKUP_NINJA:
- + case POWERUP_NINJA:
- {
- // activate ninja on target player
- pChr->GiveNinja();
- @@ -120,7 +110,7 @@
- {
- char aBuf[256];
- str_format(aBuf, sizeof(aBuf), "pickup player='%d:%s' item=%d/%d",
- - pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type);
- + pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype);
- GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime;
- }
- @@ -145,4 +135,5 @@
- pP->m_X = (int)m_Pos.x;
- pP->m_Y = (int)m_Pos.y;
- pP->m_Type = m_Type;
- + pP->m_Subtype = m_Subtype;
- }
- diff -Naur ../teeworlds/src/game/server/entities/pickup.h src/game/server/entities/pickup.h
- --- ../teeworlds/src/game/server/entities/pickup.h 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/pickup.h 2012-07-08 19:42:32.842259599 +1000
- @@ -10,7 +10,7 @@
- class CPickup : public CEntity
- {
- public:
- - CPickup(CGameWorld *pGameWorld, int Type);
- + CPickup(CGameWorld *pGameWorld, int Type, int SubType = 0);
- virtual void Reset();
- virtual void Tick();
- @@ -19,6 +19,7 @@
- private:
- int m_Type;
- + int m_Subtype;
- int m_SpawnTick;
- };
- diff -Naur ../teeworlds/src/game/server/entities/projectile.cpp src/game/server/entities/projectile.cpp
- --- ../teeworlds/src/game/server/entities/projectile.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entities/projectile.cpp 2012-07-08 19:42:32.942259106 +1000
- @@ -1,8 +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 <game/generated/protocol.h>
- #include <game/server/gamecontext.h>
- -
- -#include "character.h"
- #include "projectile.h"
- CProjectile::CProjectile(CGameWorld *pGameWorld, int Type, int Owner, vec2 Pos, vec2 Dir, int Span,
- @@ -75,9 +74,14 @@
- 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);
- + else if (m_Weapon == WEAPON_GUN)
- + {
- + GameServer()->CreateDamageInd(CurPos, -atan2(m_Direction.x, m_Direction.y), 5);
- + GameServer()->m_World.DestroyEntity(this);
- + }
- GameServer()->m_World.DestroyEntity(this);
- }
- diff -Naur ../teeworlds/src/game/server/entity.cpp src/game/server/entity.cpp
- --- ../teeworlds/src/game/server/entity.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entity.cpp 2012-07-08 19:28:03.414258934 +1000
- @@ -3,7 +3,6 @@
- #include "entity.h"
- #include "gamecontext.h"
- -#include "player.h"
- //////////////////////////////////////////////////
- // Entity
- diff -Naur ../teeworlds/src/game/server/entity.h src/game/server/entity.h
- --- ../teeworlds/src/game/server/entity.h 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/entity.h 2012-07-08 19:42:32.842259599 +1000
- @@ -3,11 +3,52 @@
- #ifndef GAME_SERVER_ENTITY_H
- #define GAME_SERVER_ENTITY_H
- +#include <new>
- #include <base/vmath.h>
- -
- #include <game/server/gameworld.h>
- -#include "alloc.h"
- +#define MACRO_ALLOC_HEAP() \
- + public: \
- + void *operator new(size_t Size) \
- + { \
- + void *p = mem_alloc(Size, 1); \
- + /*dbg_msg("", "++ %p %d", p, size);*/ \
- + mem_zero(p, Size); \
- + return p; \
- + } \
- + void operator delete(void *pPtr) \
- + { \
- + /*dbg_msg("", "-- %p", p);*/ \
- + mem_free(pPtr); \
- + } \
- + private:
- +
- +#define MACRO_ALLOC_POOL_ID() \
- + public: \
- + void *operator new(size_t Size, int id); \
- + void operator delete(void *p); \
- + private:
- +
- +#define MACRO_ALLOC_POOL_ID_IMPL(POOLTYPE, PoolSize) \
- + static char ms_PoolData##POOLTYPE[PoolSize][sizeof(POOLTYPE)] = {{0}}; \
- + static int ms_PoolUsed##POOLTYPE[PoolSize] = {0}; \
- + void *POOLTYPE::operator new(size_t Size, int id) \
- + { \
- + dbg_assert(sizeof(POOLTYPE) == Size, "size error"); \
- + dbg_assert(!ms_PoolUsed##POOLTYPE[id], "already used"); \
- + /*dbg_msg("pool", "++ %s %d", #POOLTYPE, id);*/ \
- + ms_PoolUsed##POOLTYPE[id] = 1; \
- + mem_zero(ms_PoolData##POOLTYPE[id], Size); \
- + return ms_PoolData##POOLTYPE[id]; \
- + } \
- + void POOLTYPE::operator delete(void *p) \
- + { \
- + int id = (POOLTYPE*)p - (POOLTYPE*)ms_PoolData##POOLTYPE; \
- + dbg_assert(ms_PoolUsed##POOLTYPE[id], "not used"); \
- + /*dbg_msg("pool", "-- %s %d", #POOLTYPE, id);*/ \
- + ms_PoolUsed##POOLTYPE[id] = 0; \
- + mem_zero(ms_PoolData##POOLTYPE[id], sizeof(POOLTYPE)); \
- + }
- /*
- Class: Entity
- diff -Naur ../teeworlds/src/game/server/eventhandler.cpp src/game/server/eventhandler.cpp
- --- ../teeworlds/src/game/server/eventhandler.cpp 2012-06-26 16:53:53.388863852 +1000
- +++ src/game/server/eventhandler.cpp 2012-07-08 19:28:03.414258934 +1000
- @@ -2,7 +2,6 @@
- /* If you are missing that file, acquire a complete release at teeworlds.com. */
- #include "eventhandler.h"
- #include "gamecontext.h"
- -#include "player.h"
- //////////////////////////////////////////////////
- // Event handler
- @@ -18,7 +17,7 @@
- m_pGameServer = pGameServer;
- }
- -void *CEventHandler::Create(int Type, int Size, int Mask)
- +void *CEventHandler::Create(int Type, int Size, int64_t Mask)
- {
- if(m_NumEvents == MAX_EVENTS)
- return 0;
- diff -Naur ../teeworlds/src/game/server/eventhandler.h src/game/server/eventhandler.h
- --- ../teeworlds/src/game/server/eventhandler.h 2012-06-26 16:53:53.392865827 +1000
- +++ src/game/server/eventhandler.h 2012-07-08 19:42:32.842259599 +1000
- @@ -3,6 +3,14 @@
- #ifndef GAME_SERVER_EVENTHANDLER_H
- #define GAME_SERVER_EVENTHANDLER_H
- +#ifdef _MSC_VER
- +typedef __int32 int32_t;
- +typedef unsigned __int32 uint32_t;
- +typedef __int64 int64_t;
- +typedef unsigned __int64 uint64_t;
- +#else
- +#include <stdint.h>
- +#endif
- //
- class CEventHandler
- {
- @@ -12,7 +20,7 @@
- int m_aTypes[MAX_EVENTS]; // TODO: remove some of these arrays
- int m_aOffsets[MAX_EVENTS];
- int m_aSizes[MAX_EVENTS];
- - int m_aClientMasks[MAX_EVENTS];
- + int64_t m_aClientMasks[MAX_EVENTS];
- char m_aData[MAX_DATASIZE];
- class CGameContext *m_pGameServer;
- @@ -24,7 +32,7 @@
- void SetGameServer(CGameContext *pGameServer);
- CEventHandler();
- - void *Create(int Type, int Size, int Mask = -1);
- + void *Create(int Type, int Size, int64_t Mask = -1);
- void Clear();
- void Snap(int SnappingClient);
- };
- diff -Naur ../teeworlds/src/game/server/gamecontext.cpp src/game/server/gamecontext.cpp
- --- ../teeworlds/src/game/server/gamecontext.cpp 2012-07-08 00:31:07.989177105 +1000
- +++ src/game/server/gamecontext.cpp 2012-07-08 19:42:32.950258935 +1000
- @@ -1,24 +1,18 @@
- /* (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 <base/math.h>
- -
- #include <engine/shared/config.h>
- -#include <engine/shared/memheap.h>
- #include <engine/map.h>
- -
- +#include <engine/console.h>
- +#include "gamecontext.h"
- +#include <game/version.h>
- #include <game/collision.h>
- #include <game/gamecore.h>
- -#include <game/version.h>
- -
- -#include "entities/character.h"
- -#include "gamemodes/ctf.h"
- #include "gamemodes/dm.h"
- -#include "gamemodes/lms.h"
- -#include "gamemodes/mod.h"
- -#include "gamemodes/sur.h"
- #include "gamemodes/tdm.h"
- -#include "gamecontext.h"
- -#include "player.h"
- +#include "gamemodes/ctf.h"
- +#include "gamemodes/mod.h"
- enum
- {
- @@ -189,7 +183,7 @@
- }
- }
- -void CGameContext::CreateSound(vec2 Pos, int Sound, int Mask)
- +void CGameContext::CreateSound(vec2 Pos, int Sound, int64_t Mask)
- {
- if (Sound < 0)
- return;
- @@ -233,6 +227,7 @@
- }
- +
- void CGameContext::SendChat(int ChatterClientID, int Team, const char *pText)
- {
- char aBuf[256];
- @@ -269,6 +264,7 @@
- }
- }
- +
- void CGameContext::SendEmoticon(int ClientID, int Emoticon)
- {
- CNetMsg_Sv_Emoticon Msg;
- @@ -347,25 +343,28 @@
- void CGameContext::SendVoteStatus(int ClientID, int Total, int Yes, int No)
- {
- CNetMsg_Sv_VoteStatus Msg = {0};
- - Msg.m_Total = Total;
- - Msg.m_Yes = Yes;
- - Msg.m_No = No;
- - Msg.m_Pass = Total - (Yes+No);
- + if (Total<=16)
- + {
- + Msg.m_Total = Total;
- + Msg.m_Yes = Yes;
- + Msg.m_No = No;
- + Msg.m_Pass = Total - (Yes+No);
- + } else {
- + double f = Total/16.;
- + Msg.m_Total = (int)(Total*f);
- + Msg.m_Yes = (int)(Yes*f);
- + Msg.m_No = (int)(No*f);
- + Msg.m_Pass = (int)((Total - (Yes+No))*f);
- + }
- Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
- }
- -void CGameContext::AbortVoteOnDisconnect(int ClientID)
- +void CGameContext::AbortVoteKickOnDisconnect(int ClientID)
- {
- - if(m_VoteCloseTime && ClientID == m_VoteClientID && (!str_comp_num(m_aVoteCommand, "kick ", 5) ||
- - !str_comp_num(m_aVoteCommand, "set_team ", 9) || (!str_comp_num(m_aVoteCommand, "ban ", 4) && Server()->IsBanned(ClientID))))
- - m_VoteCloseTime = -1;
- -}
- -
- -void CGameContext::AbortVoteOnTeamChange(int ClientID)
- -{
- - if(m_VoteCloseTime && ClientID == m_VoteClientID && !str_comp_num(m_aVoteCommand, "set_team ", 9))
- + if(m_VoteCloseTime && ((!str_comp_num(m_aVoteCommand, "kick ", 5) && str_toint(&m_aVoteCommand[5]) == ClientID) ||
- + (!str_comp_num(m_aVoteCommand, "set_team ", 9) && str_toint(&m_aVoteCommand[9]) == ClientID)))
- m_VoteCloseTime = -1;
- }
- @@ -376,11 +375,9 @@
- if(!m_pController)
- return;
- - if( str_comp(m_pController->GetGameType(), "DM")==0 ||
- - str_comp(m_pController->GetGameType(), "TDM")==0 ||
- - str_comp(m_pController->GetGameType(), "CTF")==0 ||
- - str_comp(m_pController->GetGameType(), "LMS")==0 ||
- - str_comp(m_pController->GetGameType(), "SUR")==0)
- + if( str_comp(m_pController->m_pGameType, "DM")==0 ||
- + str_comp(m_pController->m_pGameType, "TDM")==0 ||
- + str_comp(m_pController->m_pGameType, "CTF")==0)
- {
- CTuningParams p;
- if(mem_comp(&p, &m_Tuning, sizeof(p)) != 0)
- @@ -391,6 +388,7 @@
- }
- }
- +
- void CGameContext::SendTuningParams(int ClientID)
- {
- CheckPureTuning();
- @@ -412,8 +410,10 @@
- for(int i = 0; i < MAX_CLIENTS; ++i)
- {
- if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
- - m_pController->DoTeamChange(m_apPlayers[i], m_apPlayers[i]->GetTeam()^1, false);
- + m_apPlayers[i]->SetTeam(m_apPlayers[i]->GetTeam()^1, false);
- }
- +
- + (void)m_pController->CheckTeamBalance();
- }
- void CGameContext::OnTick()
- @@ -518,13 +518,13 @@
- #ifdef CONF_DEBUG
- - for(int i = 0; i < MAX_CLIENTS; i++)
- + if(g_Config.m_DbgDummies)
- {
- - if(m_apPlayers[i] && m_apPlayers[i]->IsDummy())
- + for(int i = 0; i < g_Config.m_DbgDummies ; i++)
- {
- CNetObj_PlayerInput Input = {0};
- Input.m_Direction = (i&1)?-1:1;
- - m_apPlayers[i]->OnPredictedInput(&Input);
- + m_apPlayers[MAX_CLIENTS-i-1]->OnPredictedInput(&Input);
- }
- }
- #endif
- @@ -533,7 +533,8 @@
- // Server hooks
- void CGameContext::OnClientDirectInput(int ClientID, void *pInput)
- {
- - m_apPlayers[ClientID]->OnDirectInput((CNetObj_PlayerInput *)pInput);
- + if(!m_World.m_Paused)
- + m_apPlayers[ClientID]->OnDirectInput((CNetObj_PlayerInput *)pInput);
- }
- void CGameContext::OnClientPredictedInput(int ClientID, void *pInput)
- @@ -548,7 +549,10 @@
- m_apPlayers[ClientID]->Respawn();
- char aBuf[512];
- str_format(aBuf, sizeof(aBuf), "'%s' entered and joined the %s", Server()->ClientName(ClientID), m_pController->GetTeamName(m_apPlayers[ClientID]->GetTeam()));
- - SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + SendChatTarget(ClientID, "BBMod Made by [BBM]Julian->Assange And [BBM]Learath2");
- + if(g_Config.m_SvWelcome[0]!=0)
- + SendChatTarget(ClientID,g_Config.m_SvWelcome);
- str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' team=%d", ClientID, Server()->ClientName(ClientID), m_apPlayers[ClientID]->GetTeam());
- Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- @@ -556,12 +560,24 @@
- m_VoteUpdate = true;
- }
- -void CGameContext::OnClientConnected(int ClientID, bool Dummy)
- +void CGameContext::OnClientConnected(int ClientID)
- {
- - m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, Dummy);
- -
- - if(Dummy)
- - return;
- + // Check which team the player should be on
- + const int StartTeam = g_Config.m_SvTournamentMode ? TEAM_SPECTATORS : m_pController->GetAutoTeam(ClientID);
- +
- + m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, StartTeam);
- + //players[client_id].init(client_id);
- + //players[client_id].client_id = client_id;
- +
- + (void)m_pController->CheckTeamBalance();
- +
- +#ifdef CONF_DEBUG
- + if(g_Config.m_DbgDummies)
- + {
- + if(ClientID >= MAX_CLIENTS-g_Config.m_DbgDummies)
- + return;
- + }
- +#endif
- // send active vote
- if(m_VoteCloseTime)
- @@ -573,20 +589,27 @@
- Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
- }
- -void CGameContext::OnClientTeamChange(int ClientID)
- -{
- - if(m_apPlayers[ClientID]->GetTeam() == TEAM_SPECTATORS)
- - AbortVoteOnTeamChange(ClientID);
- -}
- -
- void CGameContext::OnClientDrop(int ClientID, const char *pReason)
- {
- - AbortVoteOnDisconnect(ClientID);
- - m_pController->OnPlayerDisconnect(m_apPlayers[ClientID], pReason);
- + AbortVoteKickOnDisconnect(ClientID);
- + m_apPlayers[ClientID]->OnDisconnect(pReason);
- delete m_apPlayers[ClientID];
- m_apPlayers[ClientID] = 0;
- + (void)m_pController->CheckTeamBalance();
- m_VoteUpdate = true;
- +
- + // update spectator modes
- + for(int i = 0; i < MAX_CLIENTS; ++i)
- + {
- + if(m_apPlayers[i] && m_apPlayers[i]->m_SpectatorID == ClientID)
- + m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
- + }
- +}
- +
- +char * CGameContext::HandleArguments(char *pString)
- +{
- + return str_skip_whitespaces(str_skip_to_whitespace(pString));
- }
- void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
- @@ -624,8 +647,110 @@
- *pMessage = ' ';
- pMessage++;
- }
- -
- - SendChat(ClientID, Team, pMsg->m_pMessage);
- + CCharacter* pChr = pPlayer->GetCharacter();
- + if(m_apPlayers[ClientID]->m_Muted == 0 && !m_World.m_Paused)
- + {
- + if(!str_comp_num(pMsg->m_pMessage, "/emote", 6) && !m_World.m_Paused && pChr && pPlayer)
- + {
- + pChr->m_DefEmoteReset = 0;
- + if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "normal"))
- + pChr->m_DefEmote =(EMOTE_NORMAL);
- +
- + else if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "surprise"))
- + pChr->m_DefEmote =(EMOTE_SURPRISE);
- + else if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "happy"))
- + pChr->m_DefEmote =(EMOTE_HAPPY);
- + else if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "pain"))
- + pChr->m_DefEmote =(EMOTE_PAIN);
- + else if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "blink"))
- + pChr->m_DefEmote =(EMOTE_BLINK);
- + else if (!str_comp_nocase(HandleArguments((char *)pMsg->m_pMessage), "angry"))
- + pChr->m_DefEmote =(EMOTE_ANGRY);
- + else
- + {
- + SendChatTarget(ClientID, "Unknown Emote Emotes Are: Normal, Surprise, Happy, Pain, Blink And Close");
- + SendChatTarget(ClientID, "Emotes Are Used Like This: /emote ****");
- + }
- + }
- + else if(!str_comp_nocase(pMsg->m_pMessage, "/info"))
- + {
- + SendChatTarget(ClientID, "****Mod by \"[BBM]Julian->Assange\" And Some Great Helps By \"Learath2\" <3****");
- + SendChatTarget(ClientID, "Commands: /emote , /powerups , /colors");
- + }
- + 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_nocase(pMsg->m_pMessage, "/colors"))
- + {
- + SendChatTarget(ClientID, "*********Colors**********");
- + char aBuf[256];
- + char PUP_NAME[7][32]= {"Green", "Blue", "Red", "Pink", "Black", "White", "Yellow"};
- + for(int i = 0; i < 7; i++)
- + {
- + if(i == 0)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoGreen);
- + if(i == 1)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoBlue);
- + if(i == 2)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoRed);
- + if(i == 3)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoPink);
- + if(i == 4)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoGrey);
- + if(i == 5)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoWhite);
- + if(i == 6)
- + str_format(aBuf, sizeof(aBuf), "%s : %d", PUP_NAME[i], pPlayer->m_NoYellow);
- + SendChatTarget(ClientID, aBuf);
- + }
- + SendChatTarget(ClientID, "*************************");
- + return;
- + }
- + else if(!str_comp_num(pMsg->m_pMessage, "/", 1))
- + SendChatTarget(ClientID, "Invalid command! do /info");
- + else
- + {
- + if(pPlayer->m_LastChatTime + Server()->TickSpeed() >= Server()->Tick() || str_comp_nocase(pMsg->m_pMessage, pPlayer->m_LastChatText) != 0)
- + {
- + SendChat(ClientID, Team, pMsg->m_pMessage);
- + str_copy(pPlayer->m_LastChatText, pMsg->m_pMessage, sizeof(pPlayer->m_LastChatText));
- + pPlayer->m_LastChatTime = Server()->Tick();
- + }
- + else
- + {
- + SendChat(ClientID, Team, pMsg->m_pMessage);
- + pPlayer->m_LastChatTime = Server()->Tick();
- + str_copy(pPlayer->m_LastChatText, pMsg->m_pMessage, sizeof(pPlayer->m_LastChatText));
- + pPlayer->m_MuteTimes = pPlayer->m_MuteTimes + 2;
- + }
- + if(pPlayer->m_MuteTimes == 10)
- + {
- + pPlayer->m_Muted = Server()->TickSpeed() * g_Config.m_SvAutoMuteTime;
- + char aBuf[256];
- + str_format(aBuf, sizeof(aBuf), "You Are Muted For %d Seconds", m_apPlayers[ClientID]->m_Muted / Server()->TickSpeed());
- + SendChatTarget(ClientID, aBuf);
- + str_format(aBuf, sizeof(aBuf), "%s Is Muted For %d Seconds", Server()->ClientName(ClientID), m_apPlayers[ClientID]->m_Muted / Server()->TickSpeed());
- + SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + pPlayer->m_MuteTimes = 0;
- + }
- + }
- + }
- + else
- + {
- + char aBuf[256];
- + str_format(aBuf, sizeof(aBuf), "You Can't Talk You Are Muted For Next %d Seconds", m_apPlayers[ClientID]->m_Muted / Server()->TickSpeed());
- + SendChatTarget(ClientID, aBuf);
- + }
- }
- else if(MsgID == NETMSGTYPE_CL_CALLVOTE)
- {
- @@ -687,7 +812,7 @@
- }
- else if(str_comp_nocase(pMsg->m_Type, "kick") == 0)
- {
- - if(!g_Config.m_SvVoteKick)
- + if(!g_Config.m_SvVoteKick || g_Config.m_SvVoteKick)
- {
- SendChatTarget(ClientID, "Server does not allow voting to kick players");
- return;
- @@ -709,6 +834,9 @@
- }
- int KickID = str_toint(pMsg->m_Value);
- + if (!Server()->ReverseTranslate(KickID, ClientID))
- + return;
- +
- if(KickID < 0 || KickID >= MAX_CLIENTS || !m_apPlayers[KickID])
- {
- SendChatTarget(ClientID, "Invalid client id to kick");
- @@ -738,18 +866,22 @@
- Server()->GetClientAddr(KickID, aAddrStr, sizeof(aAddrStr));
- str_format(aCmd, sizeof(aCmd), "ban %s %d Banned by vote", aAddrStr, g_Config.m_SvVoteKickBantime);
- }
- - m_VoteClientID = KickID;
- }
- else if(str_comp_nocase(pMsg->m_Type, "spectate") == 0)
- {
- - if(!g_Config.m_SvVoteSpectate)
- + if(!g_Config.m_SvVoteSpectate || g_Config.m_SvVoteSpectate)
- {
- SendChatTarget(ClientID, "Server does not allow voting to move players to spectators");
- return;
- }
- int SpectateID = str_toint(pMsg->m_Value);
- +
- + if (!Server()->ReverseTranslate(SpectateID, ClientID))
- + return;
- +
- if(SpectateID < 0 || SpectateID >= MAX_CLIENTS || !m_apPlayers[SpectateID] || m_apPlayers[SpectateID]->GetTeam() == TEAM_SPECTATORS)
- +
- {
- SendChatTarget(ClientID, "Invalid client id to move");
- return;
- @@ -762,8 +894,8 @@
- str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to move '%s' to spectators (%s)", Server()->ClientName(ClientID), Server()->ClientName(SpectateID), pReason);
- str_format(aDesc, sizeof(aDesc), "move '%s' to spectators", Server()->ClientName(SpectateID));
- +
- str_format(aCmd, sizeof(aCmd), "set_team %d -1 %d", SpectateID, g_Config.m_SvVoteSpectateRejoindelay);
- - m_VoteClientID = SpectateID;
- }
- if(aCmd[0])
- @@ -792,7 +924,7 @@
- m_VoteUpdate = true;
- }
- }
- - else if(MsgID == NETMSGTYPE_CL_SETTEAM && m_pController->IsTeamChangeAllowed())
- + else if (MsgID == NETMSGTYPE_CL_SETTEAM && !m_World.m_Paused)
- {
- CNetMsg_Cl_SetTeam *pMsg = (CNetMsg_Cl_SetTeam *)pRawMsg;
- @@ -824,7 +956,8 @@
- pPlayer->m_LastSetTeam = Server()->Tick();
- if(pPlayer->GetTeam() == TEAM_SPECTATORS || pMsg->m_Team == TEAM_SPECTATORS)
- m_VoteUpdate = true;
- - m_pController->DoTeamChange(pPlayer, pMsg->m_Team);
- + pPlayer->SetTeam(pMsg->m_Team);
- + (void)m_pController->CheckTeamBalance();
- pPlayer->m_TeamChangeTick = Server()->Tick();
- }
- else
- @@ -841,16 +974,23 @@
- {
- CNetMsg_Cl_SetSpectatorMode *pMsg = (CNetMsg_Cl_SetSpectatorMode *)pRawMsg;
- - if(g_Config.m_SvSpamprotection && pPlayer->m_LastSetSpectatorMode && pPlayer->m_LastSetSpectatorMode+Server()->TickSpeed()*3 > Server()->Tick())
- + if(pMsg->m_SpectatorID != SPEC_FREEVIEW)
- + if (!Server()->ReverseTranslate(pMsg->m_SpectatorID, ClientID))
- + return;
- +
- + if(pPlayer->GetTeam() != TEAM_SPECTATORS || pPlayer->m_SpectatorID == pMsg->m_SpectatorID || ClientID == pMsg->m_SpectatorID ||
- + (g_Config.m_SvSpamprotection && pPlayer->m_LastSetSpectatorMode && pPlayer->m_LastSetSpectatorMode+Server()->TickSpeed()*3 > Server()->Tick()))
- return;
- pPlayer->m_LastSetSpectatorMode = Server()->Tick();
- - if(!pPlayer->SetSpectatorID(pMsg->m_SpectatorID))
- + if(pMsg->m_SpectatorID != SPEC_FREEVIEW && (!m_apPlayers[pMsg->m_SpectatorID] || m_apPlayers[pMsg->m_SpectatorID]->GetTeam() == TEAM_SPECTATORS))
- SendChatTarget(ClientID, "Invalid spectator id used");
- + else
- + pPlayer->m_SpectatorID = pMsg->m_SpectatorID;
- }
- else if (MsgID == NETMSGTYPE_CL_STARTINFO)
- {
- - if(pPlayer->m_IsReadyToEnter)
- + if(pPlayer->m_IsReady)
- return;
- CNetMsg_Cl_StartInfo *pMsg = (CNetMsg_Cl_StartInfo *)pRawMsg;
- @@ -861,9 +1001,17 @@
- Server()->SetClientClan(ClientID, pMsg->m_pClan);
- Server()->SetClientCountry(ClientID, pMsg->m_Country);
- str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName));
- - pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor;
- + 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;
- + pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet;*/
- m_pController->OnPlayerInfoChange(pPlayer);
- // send vote options
- @@ -942,7 +1090,7 @@
- SendTuningParams(ClientID);
- // client is ready to enter
- - pPlayer->m_IsReadyToEnter = true;
- + pPlayer->m_IsReady = true;
- CNetMsg_Sv_ReadyToEnter m;
- Server()->SendPackMsg(&m, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID);
- }
- @@ -975,13 +1123,50 @@
- else if (MsgID == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused)
- {
- CNetMsg_Cl_Emoticon *pMsg = (CNetMsg_Cl_Emoticon *)pRawMsg;
- -
- - if(g_Config.m_SvSpamprotection && pPlayer->m_LastEmote && pPlayer->m_LastEmote+Server()->TickSpeed()*3 > Server()->Tick())
- +
- + if(g_Config.m_SvSpamprotection && pPlayer->m_LastEmote && pPlayer->m_LastEmote+Server()->TickSpeed()*1 > Server()->Tick())
- return;
- pPlayer->m_LastEmote = Server()->Tick();
- SendEmoticon(ClientID, pMsg->m_Emoticon);
- + CCharacter* pChr = pPlayer->GetCharacter();
- + if(pChr && pPlayer)
- + {
- + switch(pMsg->m_Emoticon)
- + {
- + case EMOTICON_EXCLAMATION:
- + case EMOTICON_GHOST:
- + case EMOTICON_QUESTION:
- + case EMOTICON_WTF:
- + pChr->SetEmoteType(EMOTE_SURPRISE);
- + break;
- + case EMOTICON_DOTDOT:
- + case EMOTICON_DROP:
- + case EMOTICON_ZZZ:
- + pChr->SetEmoteType(EMOTE_BLINK);
- + break;
- + case EMOTICON_EYES:
- + case EMOTICON_HEARTS:
- + case EMOTICON_MUSIC:
- + pChr->SetEmoteType(EMOTE_HAPPY);
- + break;
- + case EMOTICON_OOP:
- + case EMOTICON_SORRY:
- + case EMOTICON_SUSHI:
- + pChr->SetEmoteType(EMOTE_PAIN);
- + break;
- + case EMOTICON_DEVILTEE:
- + case EMOTICON_SPLATTEE:
- + case EMOTICON_ZOMG:
- + pChr->SetEmoteType(EMOTE_ANGRY);
- + break;
- + default:
- + break;
- + }
- + pChr->SetEmoteStop(Server()->Tick() + 2 * Server()->TickSpeed());
- +
- + }
- }
- else if (MsgID == NETMSGTYPE_CL_KILL && !m_World.m_Paused)
- {
- @@ -991,14 +1176,6 @@
- pPlayer->m_LastKill = Server()->Tick();
- pPlayer->KillCharacter(WEAPON_SELF);
- }
- - else if (MsgID == NETMSGTYPE_CL_READYCHANGE)
- - {
- - if(pPlayer->m_LastReadyChange && pPlayer->m_LastReadyChange+Server()->TickSpeed()*1 > Server()->Tick())
- - return;
- -
- - pPlayer->m_LastReadyChange = Server()->Tick();
- - m_pController->OnPlayerReadyChange(pPlayer);
- - }
- }
- void CGameContext::ConTuneParam(IConsole::IResult *pResult, void *pUserData)
- @@ -1044,10 +1221,10 @@
- {
- CGameContext *pSelf = (CGameContext *)pUserData;
- - if(pResult->NumArguments())
- - pSelf->m_pController->DoPause(clamp(pResult->GetInteger(0), -1, 1000));
- - else
- - pSelf->m_pController->DoPause(pSelf->m_pController->IsGamePaused() ? 0 : IGameController::TIMER_INFINITE);
- + if(pSelf->m_pController->IsGameOver())
- + return;
- +
- + pSelf->m_World.m_Paused ^= 1;
- }
- void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData)
- @@ -1060,9 +1237,9 @@
- {
- CGameContext *pSelf = (CGameContext *)pUserData;
- if(pResult->NumArguments())
- - pSelf->m_pController->DoWarmup(clamp(pResult->GetInteger(0), -1, 1000));
- + pSelf->m_pController->DoWarmup(pResult->GetInteger(0));
- else
- - pSelf->m_pController->DoWarmup(0);
- + pSelf->m_pController->StartRound();
- }
- void CGameContext::ConBroadcast(IConsole::IResult *pResult, void *pUserData)
- @@ -1091,7 +1268,8 @@
- pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
- pSelf->m_apPlayers[ClientID]->m_TeamChangeTick = pSelf->Server()->Tick()+pSelf->Server()->TickSpeed()*Delay*60;
- - pSelf->m_pController->DoTeamChange(pSelf->m_apPlayers[ClientID], Team);
- + pSelf->m_apPlayers[ClientID]->SetTeam(Team);
- + (void)pSelf->m_pController->CheckTeamBalance();
- }
- void CGameContext::ConSetTeamAll(IConsole::IResult *pResult, void *pUserData)
- @@ -1105,7 +1283,9 @@
- for(int i = 0; i < MAX_CLIENTS; ++i)
- if(pSelf->m_apPlayers[i])
- - pSelf->m_pController->DoTeamChange(pSelf->m_apPlayers[i], Team, false);
- + pSelf->m_apPlayers[i]->SetTeam(Team, false);
- +
- + (void)pSelf->m_pController->CheckTeamBalance();
- }
- void CGameContext::ConSwapTeams(IConsole::IResult *pResult, void *pUserData)
- @@ -1120,29 +1300,41 @@
- if(!pSelf->m_pController->IsTeamplay())
- return;
- - int rnd = 0;
- + int CounterRed = 0;
- + int CounterBlue = 0;
- int PlayerTeam = 0;
- - int aPlayer[MAX_CLIENTS];
- -
- - for(int i = 0; i < MAX_CLIENTS; i++)
- + for(int i = 0; i < MAX_CLIENTS; ++i)
- if(pSelf->m_apPlayers[i] && pSelf->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
- - aPlayer[PlayerTeam++]=i;
- -
- + ++PlayerTeam;
- + PlayerTeam = (PlayerTeam+1)/2;
- +
- pSelf->SendChat(-1, CGameContext::CHAT_ALL, "Teams were shuffled");
- - //creating random permutation
- - for(int i = PlayerTeam; i > 1; i--)
- + for(int i = 0; i < MAX_CLIENTS; ++i)
- {
- - rnd = rand() % i;
- - int tmp = aPlayer[rnd];
- - aPlayer[rnd] = aPlayer[i-1];
- - aPlayer[i-1] = tmp;
- + if(pSelf->m_apPlayers[i] && pSelf->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
- + {
- + if(CounterRed == PlayerTeam)
- + pSelf->m_apPlayers[i]->SetTeam(TEAM_BLUE, false);
- + else if(CounterBlue == PlayerTeam)
- + pSelf->m_apPlayers[i]->SetTeam(TEAM_RED, false);
- + else
- + {
- + if(rand() % 2)
- + {
- + pSelf->m_apPlayers[i]->SetTeam(TEAM_BLUE, false);
- + ++CounterBlue;
- + }
- + else
- + {
- + pSelf->m_apPlayers[i]->SetTeam(TEAM_RED, false);
- + ++CounterRed;
- + }
- + }
- + }
- }
- - //uneven Number of Players?
- - rnd = PlayerTeam % 2 ? rand() % 2 : 0;
- - for(int i = 0; i < PlayerTeam; i++)
- - pSelf->m_pController->DoTeamChange(pSelf->m_apPlayers[aPlayer[i]], i < (PlayerTeam+rnd)/2 ? TEAM_RED : TEAM_BLUE, false);
- + (void)pSelf->m_pController->CheckTeamBalance();
- }
- void CGameContext::ConLockTeams(IConsole::IResult *pResult, void *pUserData)
- @@ -1323,6 +1515,7 @@
- else if(str_comp_nocase(pType, "kick") == 0)
- {
- int KickID = str_toint(pValue);
- + //Server()->ReverseTranslate(KickID, ClientID);
- if(KickID < 0 || KickID >= MAX_CLIENTS || !pSelf->m_apPlayers[KickID])
- {
- pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Invalid client id to kick");
- @@ -1345,6 +1538,7 @@
- else if(str_comp_nocase(pType, "spectate") == 0)
- {
- int SpectateID = str_toint(pValue);
- + //Server()->ReverseTranslate(SpectateID, ClientID);
- if(SpectateID < 0 || SpectateID >= MAX_CLIENTS || !pSelf->m_apPlayers[SpectateID] || pSelf->m_apPlayers[SpectateID]->GetTeam() == TEAM_SPECTATORS)
- {
- pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", "Invalid client id to move");
- @@ -1413,7 +1607,7 @@
- Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "Reset tuning");
- Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "Dump tuning");
- - Console()->Register("pause", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConPause, this, "Pause/unpause game");
- + Console()->Register("pause", "", CFGFLAG_SERVER, ConPause, this, "Pause/unpause game");
- Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, "Change map");
- Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, "Restart in x seconds (0 = abort)");
- Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "Broadcast message");
- @@ -1433,37 +1627,53 @@
- Console()->Chain("sv_motd", ConchainSpecialMotdupdate, this);
- }
- -void CGameContext::OnInit()
- +void CGameContext::OnInit(/*class IKernel *pKernel*/)
- {
- - // init everything
- m_pServer = Kernel()->RequestInterface<IServer>();
- m_pConsole = Kernel()->RequestInterface<IConsole>();
- m_World.SetGameServer(this);
- m_Events.SetGameServer(this);
- + //if(!data) // only load once
- + //data = load_data_from_memory(internal_data);
- +
- for(int i = 0; i < NUM_NETOBJTYPES; i++)
- Server()->SnapSetStaticsize(i, m_NetObjHandler.GetObjSize(i));
- m_Layers.Init(Kernel());
- m_Collision.Init(&m_Layers);
- + // reset everything here
- + //world = new GAMEWORLD;
- + //players = new CPlayer[MAX_CLIENTS];
- +
- // select gametype
- - if(str_comp_nocase(g_Config.m_SvGametype, "mod") == 0)
- + if(str_comp(g_Config.m_SvGametype, "mod") == 0)
- m_pController = new CGameControllerMOD(this);
- - else if(str_comp_nocase(g_Config.m_SvGametype, "ctf") == 0)
- + else if(str_comp(g_Config.m_SvGametype, "ctf") == 0)
- m_pController = new CGameControllerCTF(this);
- - else if(str_comp_nocase(g_Config.m_SvGametype, "lms") == 0)
- - m_pController = new CGameControllerLMS(this);
- - else if(str_comp_nocase(g_Config.m_SvGametype, "sur") == 0)
- - m_pController = new CGameControllerSUR(this);
- - else if(str_comp_nocase(g_Config.m_SvGametype, "tdm") == 0)
- + else if(str_comp(g_Config.m_SvGametype, "tdm") == 0)
- m_pController = new CGameControllerTDM(this);
- else
- m_pController = new CGameControllerDM(this);
- + // setup core world
- + //for(int i = 0; i < MAX_CLIENTS; i++)
- + // game.players[i].core.world = &game.world.core;
- +
- // create all entities from the game layer
- CMapItemLayerTilemap *pTileMap = m_Layers.GameLayer();
- CTile *pTiles = (CTile *)Kernel()->RequestInterface<IMap>()->GetData(pTileMap->m_Data);
- +
- +
- +
- +
- + /*
- + num_spawn_points[0] = 0;
- + num_spawn_points[1] = 0;
- + num_spawn_points[2] = 0;
- + */
- +
- for(int y = 0; y < pTileMap->m_Height; y++)
- {
- for(int x = 0; x < pTileMap->m_Width; x++)
- @@ -1478,11 +1688,15 @@
- }
- }
- + //game.world.insert_entity(game.Controller);
- +
- #ifdef CONF_DEBUG
- if(g_Config.m_DbgDummies)
- {
- for(int i = 0; i < g_Config.m_DbgDummies ; i++)
- - OnClientConnected(MAX_CLIENTS-i-1, true);
- + {
- + OnClientConnected(MAX_CLIENTS-i-1);
- + }
- }
- #endif
- }
- @@ -1516,6 +1730,8 @@
- if(m_apPlayers[i])
- m_apPlayers[i]->Snap(ClientID);
- }
- + m_apPlayers[ClientID]->FakeSnap(ClientID);
- +
- }
- void CGameContext::OnPreSnap() {}
- void CGameContext::OnPostSnap()
- @@ -1525,7 +1741,7 @@
- bool CGameContext::IsClientReady(int ClientID)
- {
- - return m_apPlayers[ClientID] && m_apPlayers[ClientID]->m_IsReadyToEnter ? true : false;
- + return m_apPlayers[ClientID] && m_apPlayers[ClientID]->m_IsReady ? true : false;
- }
- bool CGameContext::IsClientPlayer(int ClientID)
- @@ -1533,7 +1749,7 @@
- return m_apPlayers[ClientID] && m_apPlayers[ClientID]->GetTeam() == TEAM_SPECTATORS ? false : true;
- }
- -const char *CGameContext::GameType() { return m_pController && m_pController->GetGameType() ? m_pController->GetGameType() : ""; }
- +const char *CGameContext::GameType() { return m_pController && m_pController->m_pGameType ? m_pController->m_pGameType : ""; }
- const char *CGameContext::Version() { return GAME_VERSION; }
- const char *CGameContext::NetVersion() { return GAME_NETVERSION; }
- diff -Naur ../teeworlds/src/game/server/gamecontext.h src/game/server/gamecontext.h
- --- ../teeworlds/src/game/server/gamecontext.h 2012-06-26 16:53:53.392865827 +1000
- +++ src/game/server/gamecontext.h 2012-07-08 19:45:34.537929011 +1000
- @@ -3,15 +3,26 @@
- #ifndef GAME_SERVER_GAMECONTEXT_H
- #define GAME_SERVER_GAMECONTEXT_H
- -#include <engine/console.h>
- #include <engine/server.h>
- +#include <engine/console.h>
- +#include <engine/shared/memheap.h>
- #include <game/layers.h>
- #include <game/voting.h>
- #include "eventhandler.h"
- +#include "gamecontroller.h"
- #include "gameworld.h"
- +#include "player.h"
- +#ifdef _MSC_VER
- +typedef __int32 int32_t;
- +typedef unsigned __int32 uint32_t;
- +typedef __int64 int64_t;
- +typedef unsigned __int64 uint64_t;
- +#else
- +#include <stdint.h>
- +#endif
- /*
- Tick
- Game Context (CGameContext::tick)
- @@ -41,7 +52,8 @@
- CCollision m_Collision;
- CNetObjHandler m_NetObjHandler;
- CTuningParams m_Tuning;
- -
- +
- + static void ConPowerups(IConsole::IResult *pResult, void *pUserData);
- static void ConTuneParam(IConsole::IResult *pResult, void *pUserData);
- static void ConTuneReset(IConsole::IResult *pResult, void *pUserData);
- static void ConTuneDump(IConsole::IResult *pResult, void *pUserData);
- @@ -49,9 +61,11 @@
- 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);
- + static void ConSpin(IConsole::IResult *pResult, void *pUserData);
- static void ConSwapTeams(IConsole::IResult *pResult, void *pUserData);
- static void ConShuffleTeams(IConsole::IResult *pResult, void *pUserData);
- static void ConLockTeams(IConsole::IResult *pResult, void *pUserData);
- @@ -76,11 +90,18 @@
- ~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;
- - class CPlayer *m_apPlayers[MAX_CLIENTS];
- + CPlayer *m_apPlayers[MAX_CLIENTS];
- - class IGameController *m_pController;
- + IGameController *m_pController;
- CGameWorld m_World;
- // helper functions
- @@ -93,8 +114,7 @@
- void EndVote();
- void SendVoteSet(int ClientID);
- void SendVoteStatus(int ClientID, int Total, int Yes, int No);
- - void AbortVoteOnDisconnect(int ClientID);
- - void AbortVoteOnTeamChange(int ClientID);
- + void AbortVoteKickOnDisconnect(int ClientID);
- int m_VoteCreator;
- int64 m_VoteCloseTime;
- @@ -103,7 +123,6 @@
- char m_aVoteDescription[VOTE_DESC_LENGTH];
- char m_aVoteCommand[VOTE_CMD_LENGTH];
- char m_aVoteReason[VOTE_REASON_LENGTH];
- - int m_VoteClientID;
- int m_NumVoteOptions;
- int m_VoteEnforce;
- enum
- @@ -112,7 +131,7 @@
- VOTE_ENFORCE_NO,
- VOTE_ENFORCE_YES,
- };
- - class CHeap *m_pVoteOptionHeap;
- + CHeap *m_pVoteOptionHeap;
- CVoteOptionServer *m_pVoteOptionFirst;
- CVoteOptionServer *m_pVoteOptionLast;
- @@ -122,7 +141,7 @@
- void CreateHammerHit(vec2 Pos);
- void CreatePlayerSpawn(vec2 Pos);
- void CreateDeath(vec2 Pos, int Who);
- - void CreateSound(vec2 Pos, int Sound, int Mask=-1);
- + void CreateSound(vec2 Pos, int Sound, int64_t Mask=-1);
- void CreateSoundGlobal(int Sound, int Target=-1);
- @@ -158,12 +177,11 @@
- virtual void OnPreSnap();
- virtual void OnSnap(int ClientID);
- virtual void OnPostSnap();
- -
- +
- + char * HandleArguments(char *pString);
- virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID);
- - virtual void OnClientConnected(int ClientID) { OnClientConnected(ClientID, false); }
- - void OnClientConnected(int ClientID, bool Dummy);
- - void OnClientTeamChange(int ClientID);
- + virtual void OnClientConnected(int ClientID);
- virtual void OnClientEnter(int ClientID);
- virtual void OnClientDrop(int ClientID, const char *pReason);
- virtual void OnClientDirectInput(int ClientID, void *pInput);
- @@ -177,8 +195,8 @@
- virtual const char *NetVersion();
- };
- -inline int CmaskAll() { return -1; }
- -inline int CmaskOne(int ClientID) { return 1<<ClientID; }
- -inline int CmaskAllExceptOne(int ClientID) { return 0x7fffffff^CmaskOne(ClientID); }
- -inline bool CmaskIsSet(int Mask, int ClientID) { return (Mask&CmaskOne(ClientID)) != 0; }
- +inline int64_t CmaskAll() { return -1LL; }
- +inline int64_t CmaskOne(int ClientID) { return 1LL<<ClientID; }
- +inline int64_t CmaskAllExceptOne(int ClientID) { return CmaskAll()^CmaskOne(ClientID); }
- +inline bool CmaskIsSet(int64_t Mask, int ClientID) { return (Mask&CmaskOne(ClientID)) != 0; }
- #endif
- diff -Naur ../teeworlds/src/game/server/gamecontroller.cpp src/game/server/gamecontroller.cpp
- --- ../teeworlds/src/game/server/gamecontroller.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamecontroller.cpp 2012-07-08 20:05:59.422259393 +1000
- @@ -1,805 +1,192 @@
- /* (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 <engine/shared/config.h>
- -
- #include <game/mapitems.h>
- -#include "entities/character.h"
- +#include <game/generated/protocol.h>
- +
- #include "entities/pickup.h"
- -#include "gamecontext.h"
- #include "gamecontroller.h"
- -#include "player.h"
- +#include "gamecontext.h"
- -IGameController::IGameController(CGameContext *pGameServer)
- +IGameController::IGameController(class CGameContext *pGameServer)
- {
- m_pGameServer = pGameServer;
- m_pServer = m_pGameServer->Server();
- + m_pGameType = "unknown";
- - // balancing
- - m_aTeamSize[TEAM_RED] = 0;
- - m_aTeamSize[TEAM_BLUE] = 0;
- - m_UnbalancedTick = TBALANCE_OK;
- -
- - // game
- - m_GameState = IGS_GAME_RUNNING;
- - m_GameStateTimer = TIMER_INFINITE;
- - m_GameStartTick = Server()->Tick();
- - m_MatchCount = 0;
- - m_RoundCount = 0;
- + //
- + DoWarmup(g_Config.m_SvWarmup);
- + m_GameOverTick = -1;
- m_SuddenDeath = 0;
- + m_RoundStartTick = Server()->Tick();
- + m_RoundCount = 0;
- + m_GameFlags = 0;
- m_aTeamscore[TEAM_RED] = 0;
- m_aTeamscore[TEAM_BLUE] = 0;
- - if(g_Config.m_SvWarmup)
- - SetGameState(IGS_WARMUP_USER, g_Config.m_SvWarmup);
- - else
- - SetGameState(IGS_WARMUP_GAME, TIMER_INFINITE);
- -
- - // info
- - m_GameFlags = 0;
- - m_pGameType = "unknown";
- -
- - // map
- m_aMapWish[0] = 0;
- - // spawn
- + m_UnbalancedTick = -1;
- + m_ForceBalanced = false;
- +
- m_aNumSpawnPoints[0] = 0;
- m_aNumSpawnPoints[1] = 0;
- m_aNumSpawnPoints[2] = 0;
- }
- -//activity
- -void IGameController::DoActivityCheck()
- -{
- - if(g_Config.m_SvInactiveKickTime == 0)
- - return;
- -
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && !GameServer()->m_apPlayers[i]->IsDummy() && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS &&
- - !Server()->IsAuthed(i) && (Server()->Tick() > GameServer()->m_apPlayers[i]->m_LastActionTick+g_Config.m_SvInactiveKickTime*Server()->TickSpeed()*60))
- - {
- - switch(g_Config.m_SvInactiveKick)
- - {
- - case 0:
- - {
- - // move player to spectator
- - DoTeamChange(GameServer()->m_apPlayers[i], TEAM_SPECTATORS);
- - }
- - break;
- - case 1:
- - {
- - // move player to spectator if the reserved slots aren't filled yet, kick him otherwise
- - int Spectators = 0;
- - for(int j = 0; j < MAX_CLIENTS; ++j)
- - if(GameServer()->m_apPlayers[j] && GameServer()->m_apPlayers[j]->GetTeam() == TEAM_SPECTATORS)
- - ++Spectators;
- - if(Spectators >= g_Config.m_SvSpectatorSlots)
- - Server()->Kick(i, "Kicked for inactivity");
- - else
- - DoTeamChange(GameServer()->m_apPlayers[i], TEAM_SPECTATORS);
- - }
- - break;
- - case 2:
- - {
- - // kick the player
- - Server()->Kick(i, "Kicked for inactivity");
- - }
- - }
- - }
- - }
- -}
- -
- -bool IGameController::GetPlayersReadyState()
- +IGameController::~IGameController()
- {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && !GameServer()->m_apPlayers[i]->m_IsReadyToPlay)
- - return false;
- - }
- -
- - return true;
- }
- -void IGameController::SetPlayersReadyState(bool ReadyState)
- +float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos)
- {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- + float Score = 0.0f;
- + CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
- + for(; pC; pC = (CCharacter *)pC->TypeNext())
- {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && (ReadyState || !GameServer()->m_apPlayers[i]->m_DeadSpecMode))
- - GameServer()->m_apPlayers[i]->m_IsReadyToPlay = ReadyState;
- - }
- -}
- -
- -// balancing
- -bool IGameController::CanBeMovedOnBalance(int ClientID) const
- -{
- - return true;
- -}
- + // team mates are not as dangerous as enemies
- + float Scoremod = 1.0f;
- + if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam)
- + Scoremod = 0.5f;
- -void IGameController::CheckTeamBalance()
- -{
- - if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime)
- - {
- - m_UnbalancedTick = TBALANCE_OK;
- - return;
- + float d = distance(Pos, pC->m_Pos);
- + Score += Scoremod * (d == 0 ? 1000000000.0f : 1.0f/d);
- }
- - // check if teams are unbalanced
- - char aBuf[256];
- - if(absolute(m_aTeamSize[TEAM_RED]-m_aTeamSize[TEAM_BLUE]) >= NUM_TEAMS)
- - {
- - str_format(aBuf, sizeof(aBuf), "Teams are NOT balanced (red=%d blue=%d)", m_aTeamSize[TEAM_RED], m_aTeamSize[TEAM_BLUE]);
- - if(m_UnbalancedTick <= TBALANCE_OK)
- - m_UnbalancedTick = Server()->Tick();
- - }
- - else
- - {
- - str_format(aBuf, sizeof(aBuf), "Teams are balanced (red=%d blue=%d)", m_aTeamSize[TEAM_RED], m_aTeamSize[TEAM_BLUE]);
- - m_UnbalancedTick = TBALANCE_OK;
- - }
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- + return Score;
- }
- -void IGameController::DoTeamBalance()
- +void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type)
- {
- - if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime || absolute(m_aTeamSize[TEAM_RED]-m_aTeamSize[TEAM_BLUE]) < NUM_TEAMS)
- - return;
- -
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams");
- -
- - float aTeamScore[NUM_TEAMS] = {0};
- - float aPlayerScore[MAX_CLIENTS] = {0.0f};
- -
- - // gather stats
- - for(int i = 0; i < MAX_CLIENTS; i++)
- + // get spawn point
- + for(int i = 0; i < m_aNumSpawnPoints[Type]; i++)
- {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
- + // check if the position is occupado
- + CCharacter *aEnts[MAX_CLIENTS];
- + int Num = GameServer()->m_World.FindEntities(m_aaSpawnPoints[Type][i], 64, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
- + vec2 Positions[5] = { vec2(0.0f, 0.0f), vec2(-32.0f, 0.0f), vec2(0.0f, -32.0f), vec2(32.0f, 0.0f), vec2(0.0f, 32.0f) }; // start, left, up, right, down
- + int Result = -1;
- + for(int Index = 0; Index < 5 && Result == -1; ++Index)
- {
- - aPlayerScore[i] = GameServer()->m_apPlayers[i]->m_Score*Server()->TickSpeed()*60.0f/
- - (Server()->Tick()-GameServer()->m_apPlayers[i]->m_ScoreStartTick);
- - aTeamScore[GameServer()->m_apPlayers[i]->GetTeam()] += aPlayerScore[i];
- + Result = Index;
- + for(int c = 0; c < Num; ++c)
- + if(GameServer()->Collision()->CheckPoint(m_aaSpawnPoints[Type][i]+Positions[Index]) ||
- + distance(aEnts[c]->m_Pos, m_aaSpawnPoints[Type][i]+Positions[Index]) <= aEnts[c]->m_ProximityRadius)
- + {
- + Result = -1;
- + break;
- + }
- }
- - }
- -
- - int BiggerTeam = (m_aTeamSize[TEAM_RED] > m_aTeamSize[TEAM_BLUE]) ? TEAM_RED : TEAM_BLUE;
- - int NumBalance = absolute(m_aTeamSize[TEAM_RED]-m_aTeamSize[TEAM_BLUE]) / NUM_TEAMS;
- + if(Result == -1)
- + continue; // try next spawn point
- - // balance teams
- - do
- - {
- - CPlayer *pPlayer = 0;
- - float ScoreDiff = aTeamScore[BiggerTeam];
- - for(int i = 0; i < MAX_CLIENTS; i++)
- + vec2 P = m_aaSpawnPoints[Type][i]+Positions[Result];
- + float S = EvaluateSpawnPos(pEval, P);
- + if(!pEval->m_Got || pEval->m_Score > S)
- {
- - if(!GameServer()->m_apPlayers[i] || !CanBeMovedOnBalance(i))
- - continue;
- -
- - // remember the player whom would cause lowest score-difference
- - if(GameServer()->m_apPlayers[i]->GetTeam() == BiggerTeam &&
- - (!pPlayer || absolute((aTeamScore[BiggerTeam^1]+aPlayerScore[i]) - (aTeamScore[BiggerTeam]-aPlayerScore[i])) < ScoreDiff))
- - {
- - pPlayer = GameServer()->m_apPlayers[i];
- - ScoreDiff = absolute((aTeamScore[BiggerTeam^1]+aPlayerScore[i]) - (aTeamScore[BiggerTeam]-aPlayerScore[i]));
- - }
- + pEval->m_Got = true;
- + pEval->m_Score = S;
- + pEval->m_Pos = P;
- }
- -
- - // move the player to the other team
- - int Temp = pPlayer->m_LastActionTick;
- - DoTeamChange(pPlayer, BiggerTeam^1);
- - pPlayer->m_LastActionTick = Temp;
- - pPlayer->Respawn();
- - char aBuf[128];
- - str_format(aBuf, sizeof(aBuf), "You were moved to %s due to team balancing", GetTeamName(pPlayer->GetTeam()));
- - GameServer()->SendBroadcast(aBuf, pPlayer->GetCID());
- }
- - while(--NumBalance);
- -
- - m_UnbalancedTick = TBALANCE_OK;
- - GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced");
- }
- -// event
- -int IGameController::OnCharacterDeath(CCharacter *pVictim, CPlayer *pKiller, int Weapon)
- +bool IGameController::CanSpawn(int Team, vec2 *pOutPos)
- {
- - // do scoreing
- - if(!pKiller || Weapon == WEAPON_GAME)
- - return 0;
- - if(pKiller == pVictim->GetPlayer())
- - pVictim->GetPlayer()->m_Score--; // suicide
- - else
- - {
- - if(IsTeamplay() && pVictim->GetPlayer()->GetTeam() == pKiller->GetTeam())
- - pKiller->m_Score--; // teamkill
- - else
- - pKiller->m_Score++; // normal kill
- - }
- - if(Weapon == WEAPON_SELF)
- - pVictim->GetPlayer()->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3.0f;
- -
- -
- - // update spectator modes for dead players in survival
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_DeadSpecMode)
- - GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
- - }
- + CSpawnEval Eval;
- - return 0;
- -}
- + // spectators can't spawn
- + if(Team == TEAM_SPECTATORS)
- + return false;
- -void IGameController::OnCharacterSpawn(CCharacter *pChr)
- -{
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- + if(IsTeamplay())
- {
- - // give start equipment
- - pChr->IncreaseHealth(10);
- - pChr->IncreaseArmor(5);
- -
- - pChr->GiveWeapon(WEAPON_HAMMER, -1);
- - pChr->GiveWeapon(WEAPON_GUN, 10);
- - pChr->GiveWeapon(WEAPON_SHOTGUN, 10);
- - pChr->GiveWeapon(WEAPON_GRENADE, 10);
- - pChr->GiveWeapon(WEAPON_LASER, 5);
- + Eval.m_FriendlyTeam = Team;
- - // prevent respawn
- - pChr->GetPlayer()->m_RespawnDisabled = GetStartRespawnState();
- + // first try own team spawn, then normal spawn and then enemy
- + EvaluateSpawnType(&Eval, 1+(Team&1));
- + if(!Eval.m_Got)
- + {
- + EvaluateSpawnType(&Eval, 0);
- + if(!Eval.m_Got)
- + EvaluateSpawnType(&Eval, 1+((Team+1)&1));
- + }
- }
- else
- {
- - // default health
- - pChr->IncreaseHealth(10);
- -
- - // give default weapons
- - pChr->GiveWeapon(WEAPON_HAMMER, -1);
- - pChr->GiveWeapon(WEAPON_GUN, 10);
- + EvaluateSpawnType(&Eval, 0);
- + EvaluateSpawnType(&Eval, 1);
- + EvaluateSpawnType(&Eval, 2);
- }
- +
- + *pOutPos = Eval.m_Pos;
- + return Eval.m_Got;
- }
- +
- bool IGameController::OnEntity(int Index, vec2 Pos)
- {
- - // don't add pickups in survival
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - if(Index < ENTITY_SPAWN || Index > ENTITY_SPAWN_BLUE)
- - return false;
- - }
- -
- int Type = -1;
- + int SubType = 0;
- - switch(Index)
- - {
- - case ENTITY_SPAWN:
- + if(Index == ENTITY_SPAWN)
- m_aaSpawnPoints[0][m_aNumSpawnPoints[0]++] = Pos;
- - break;
- - case ENTITY_SPAWN_RED:
- + else if(Index == ENTITY_SPAWN_RED)
- m_aaSpawnPoints[1][m_aNumSpawnPoints[1]++] = Pos;
- - break;
- - case ENTITY_SPAWN_BLUE:
- + else if(Index == ENTITY_SPAWN_BLUE)
- m_aaSpawnPoints[2][m_aNumSpawnPoints[2]++] = Pos;
- - break;
- - case ENTITY_ARMOR_1:
- - Type = PICKUP_ARMOR;
- - break;
- - case ENTITY_HEALTH_1:
- - Type = PICKUP_HEALTH;
- - break;
- - case ENTITY_WEAPON_SHOTGUN:
- - Type = PICKUP_SHOTGUN;
- - break;
- - case ENTITY_WEAPON_GRENADE:
- - Type = PICKUP_GRENADE;
- - break;
- - case ENTITY_WEAPON_LASER:
- - Type = PICKUP_LASER;
- - break;
- - case ENTITY_POWERUP_NINJA:
- - if(g_Config.m_SvPowerups)
- - Type = PICKUP_NINJA;
- - }
- -
- - if(Type != -1)
- - {
- - CPickup *pPickup = new CPickup(&GameServer()->m_World, Type);
- - pPickup->m_Pos = Pos;
- - return true;
- - }
- -
- - return false;
- -}
- -
- -void IGameController::OnPlayerDisconnect(CPlayer *pPlayer, const char *pReason)
- -{
- - pPlayer->OnDisconnect();
- -
- - int ClientID = pPlayer->GetCID();
- - if(Server()->ClientIngame(ClientID))
- - {
- - char aBuf[512];
- - if(pReason && *pReason)
- - str_format(aBuf, sizeof(aBuf), "'%s' has left the game (%s)", Server()->ClientName(ClientID), pReason);
- - else
- - str_format(aBuf, sizeof(aBuf), "'%s' has left the game", Server()->ClientName(ClientID));
- - GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- -
- - str_format(aBuf, sizeof(aBuf), "leave player='%d:%s'", ClientID, Server()->ClientName(ClientID));
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "game", aBuf);
- - }
- -
- - if(pPlayer->GetTeam() != TEAM_SPECTATORS)
- - {
- - --m_aTeamSize[pPlayer->GetTeam()];
- - m_UnbalancedTick = TBALANCE_CHECK;
- - }
- -}
- -
- -void IGameController::OnPlayerInfoChange(CPlayer *pPlayer)
- -{
- - const int aTeamColors[2] = {65387, 10223467};
- - if(IsTeamplay())
- - {
- - pPlayer->m_TeeInfos.m_UseCustomColor = 1;
- - if(pPlayer->GetTeam() >= TEAM_RED && pPlayer->GetTeam() <= TEAM_BLUE)
- - {
- - pPlayer->m_TeeInfos.m_ColorBody = aTeamColors[pPlayer->GetTeam()];
- - pPlayer->m_TeeInfos.m_ColorFeet = aTeamColors[pPlayer->GetTeam()];
- - }
- - else
- - {
- - pPlayer->m_TeeInfos.m_ColorBody = 12895054;
- - pPlayer->m_TeeInfos.m_ColorFeet = 12895054;
- - }
- - }
- -}
- -
- -void IGameController::OnPlayerReadyChange(CPlayer *pPlayer)
- -{
- - if(g_Config.m_SvPlayerReadyMode && pPlayer->GetTeam() != TEAM_SPECTATORS && !pPlayer->m_DeadSpecMode)
- + else if(Index == ENTITY_ARMOR_1)
- + Type = POWERUP_ARMOR;
- + else if(Index == ENTITY_HEALTH_1)
- + Type = POWERUP_HEALTH;
- + else if(Index == ENTITY_WEAPON_SHOTGUN)
- {
- - // change players ready state
- - pPlayer->m_IsReadyToPlay ^= 1;
- -
- - // check if it effects current game state
- - switch(m_GameState)
- - {
- - case IGS_GAME_RUNNING:
- - // one player isn't ready -> pause the game
- - if(!pPlayer->m_IsReadyToPlay)
- - SetGameState(IGS_GAME_PAUSED, TIMER_INFINITE);
- - break;
- - case IGS_WARMUP_USER:
- - // all players are ready -> end warmup
- - if(GetPlayersReadyState())
- - SetGameState(IGS_WARMUP_USER, 0);
- - break;
- - case IGS_GAME_PAUSED:
- - // all players are ready -> unpause the game
- - if(GetPlayersReadyState())
- - SetGameState(IGS_GAME_PAUSED, 0);
- - break;
- - case IGS_WARMUP_GAME:
- - case IGS_START_COUNTDOWN:
- - case IGS_END_MATCH:
- - case IGS_END_ROUND:
- - // not effected
- - break;
- - }
- + Type = POWERUP_WEAPON;
- + SubType = WEAPON_SHOTGUN;
- }
- -}
- -
- -void IGameController::OnReset()
- -{
- - for(int i = 0; i < MAX_CLIENTS; i++)
- + else if(Index == ENTITY_WEAPON_GRENADE)
- {
- - if(GameServer()->m_apPlayers[i])
- - {
- - GameServer()->m_apPlayers[i]->m_RespawnDisabled = false;
- - GameServer()->m_apPlayers[i]->Respawn();
- - GameServer()->m_apPlayers[i]->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
- - if(m_RoundCount == 0)
- - {
- - GameServer()->m_apPlayers[i]->m_Score = 0;
- - GameServer()->m_apPlayers[i]->m_ScoreStartTick = Server()->Tick();
- - }
- - GameServer()->m_apPlayers[i]->m_IsReadyToPlay = true;
- - }
- + Type = POWERUP_WEAPON;
- + SubType = WEAPON_GRENADE;
- }
- -}
- -
- -// game
- -void IGameController::DoWincheckMatch()
- -{
- - if(IsTeamplay())
- + else if(Index == ENTITY_WEAPON_RIFLE)
- {
- - // check score win condition
- - if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) ||
- - (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_GameStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- - {
- - if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE] || m_GameFlags&GAMEFLAG_SURVIVAL)
- - EndMatch();
- - else
- - m_SuddenDeath = 1;
- - }
- + Type = POWERUP_WEAPON;
- + SubType = WEAPON_RIFLE;
- }
- - else
- + else if(Index == ENTITY_POWERUP_NINJA && g_Config.m_SvPowerups)
- {
- - // gather some stats
- - int Topscore = 0;
- - int TopscoreCount = 0;
- - for(int i = 0; i < MAX_CLIENTS; i++)
- - {
- - if(GameServer()->m_apPlayers[i])
- - {
- - if(GameServer()->m_apPlayers[i]->m_Score > Topscore)
- - {
- - Topscore = GameServer()->m_apPlayers[i]->m_Score;
- - TopscoreCount = 1;
- - }
- - else if(GameServer()->m_apPlayers[i]->m_Score == Topscore)
- - TopscoreCount++;
- - }
- - }
- -
- - // check score win condition
- - if((g_Config.m_SvScorelimit > 0 && Topscore >= g_Config.m_SvScorelimit) ||
- - (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_GameStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- - {
- - if(TopscoreCount == 1)
- - EndMatch();
- - else
- - m_SuddenDeath = 1;
- - }
- + Type = POWERUP_NINJA;
- + SubType = WEAPON_NINJA;
- }
- -}
- -
- -void IGameController::ResetGame()
- -{
- - // reset the game
- - GameServer()->m_World.m_ResetRequested = true;
- -
- - SetGameState(IGS_GAME_RUNNING);
- - m_GameStartTick = Server()->Tick();
- - m_SuddenDeath = 0;
- -
- - // do team-balancing
- - DoTeamBalance();
- -}
- -void IGameController::SetGameState(EGameState GameState, int Timer)
- -{
- - // change game state
- - switch(GameState)
- + if(Type != -1)
- {
- - case IGS_WARMUP_GAME:
- - // game based warmup is only possible when game or any warmup is running
- - if(m_GameState == IGS_GAME_RUNNING || m_GameState == IGS_WARMUP_GAME || m_GameState == IGS_WARMUP_USER)
- - {
- - if(Timer == TIMER_INFINITE)
- - {
- - // run warmup till there're enough players
- - m_GameState = GameState;
- - m_GameStateTimer = TIMER_INFINITE;
- -
- - // enable respawning in survival when activating warmup
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - if(GameServer()->m_apPlayers[i])
- - GameServer()->m_apPlayers[i]->m_RespawnDisabled = false;
- - }
- - }
- - else if(Timer == 0)
- - {
- - // start new match
- - StartMatch();
- - }
- - }
- - break;
- - case IGS_WARMUP_USER:
- - // user based warmup is only possible when the game or a user based warmup is running
- - if(m_GameState == IGS_GAME_RUNNING || m_GameState == IGS_WARMUP_USER)
- - {
- - if(Timer != 0)
- - {
- - // start warmup
- - if(Timer < 0 && g_Config.m_SvPlayerReadyMode)
- - {
- - // run warmup till all players are ready
- - m_GameState = GameState;
- - m_GameStateTimer = TIMER_INFINITE;
- - SetPlayersReadyState(false);
- - }
- - else if(Timer > 0)
- - {
- - // run warmup for a specific time intervall
- - m_GameState = GameState;
- - m_GameStateTimer = Timer*Server()->TickSpeed();
- - }
- -
- - // enable respawning in survival when activating warmup
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - if(GameServer()->m_apPlayers[i])
- - GameServer()->m_apPlayers[i]->m_RespawnDisabled = false;
- - }
- - }
- - else
- - {
- - // start new match
- - StartMatch();
- - }
- - }
- - break;
- - case IGS_START_COUNTDOWN:
- - // only possible when game, pause or start countdown is running
- - if(m_GameState == IGS_GAME_RUNNING || m_GameState == IGS_GAME_PAUSED || m_GameState == IGS_START_COUNTDOWN)
- - {
- - m_GameState = GameState;
- - m_GameStateTimer = 3*Server()->TickSpeed();
- - GameServer()->m_World.m_Paused = true;
- - }
- - break;
- - case IGS_GAME_RUNNING:
- - // always possible
- - {
- - m_GameState = GameState;
- - m_GameStateTimer = TIMER_INFINITE;
- - SetPlayersReadyState(true);
- - GameServer()->m_World.m_Paused = false;
- - }
- - break;
- - case IGS_GAME_PAUSED:
- - // only possible when game is running or paused
- - if(m_GameState == IGS_GAME_RUNNING || m_GameState == IGS_GAME_PAUSED)
- - {
- - if(Timer != 0)
- - {
- - // start pause
- - if(Timer < 0)
- - {
- - // pauses infinitely till all players are ready or disabled via rcon command
- - m_GameStateTimer = TIMER_INFINITE;
- - SetPlayersReadyState(false);
- - }
- - else
- - {
- - // pauses for a specific time intervall
- - m_GameStateTimer = Timer*Server()->TickSpeed();
- - }
- -
- - m_GameState = GameState;
- - GameServer()->m_World.m_Paused = true;
- - }
- - else
- - {
- - // start a countdown to end pause
- - SetGameState(IGS_START_COUNTDOWN);
- - }
- - }
- - break;
- - case IGS_END_ROUND:
- - case IGS_END_MATCH:
- - // only possible when game is running or over
- - if(m_GameState == IGS_GAME_RUNNING || m_GameState == IGS_END_MATCH || m_GameState == IGS_END_ROUND)
- - {
- - m_GameState = GameState;
- - m_GameStateTimer = Timer*Server()->TickSpeed();
- - m_SuddenDeath = 0;
- - GameServer()->m_World.m_Paused = true;
- - }
- + CPickup *pPickup = new CPickup(&GameServer()->m_World, Type, SubType);
- + pPickup->m_Pos = Pos;
- + return true;
- }
- -}
- -
- -void IGameController::StartMatch()
- -{
- - ResetGame();
- -
- - m_RoundCount = 0;
- - m_aTeamscore[TEAM_RED] = 0;
- - m_aTeamscore[TEAM_BLUE] = 0;
- -
- - // start countdown if there're enough players, otherwise do warmup till there're
- - if(HasEnoughPlayers())
- - SetGameState(IGS_START_COUNTDOWN);
- - else
- - SetGameState(IGS_WARMUP_GAME, TIMER_INFINITE);
- -
- - Server()->DemoRecorder_HandleAutoStart();
- - char aBuf[256];
- - str_format(aBuf, sizeof(aBuf), "start match type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- -}
- -
- -void IGameController::StartRound()
- -{
- - ResetGame();
- -
- - ++m_RoundCount;
- - // start countdown if there're enough players, otherwise abort to warmup
- - if(HasEnoughPlayers())
- - SetGameState(IGS_START_COUNTDOWN);
- - else
- - SetGameState(IGS_WARMUP_GAME, TIMER_INFINITE);
- + return false;
- }
- -// general
- -void IGameController::Snap(int SnappingClient)
- +void IGameController::EndRound()
- {
- - CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo));
- - if(!pGameInfoObj)
- + if(m_Warmup) // game can't end when we are running warmup
- return;
- - pGameInfoObj->m_GameFlags = m_GameFlags;
- -
- - pGameInfoObj->m_GameStateFlags = 0;
- - pGameInfoObj->m_GameStateTimer = 0;
- - switch(m_GameState)
- - {
- - case IGS_WARMUP_GAME:
- - case IGS_WARMUP_USER:
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_WARMUP;
- - pGameInfoObj->m_GameStateTimer = m_GameStateTimer;
- - break;
- - case IGS_START_COUNTDOWN:
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_STARTCOUNTDOWN|GAMESTATEFLAG_PAUSED;
- - pGameInfoObj->m_GameStateTimer = m_GameStateTimer;
- - break;
- - case IGS_GAME_PAUSED:
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED;
- - pGameInfoObj->m_GameStateTimer = m_GameStateTimer;
- - break;
- - case IGS_END_ROUND:
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_ROUNDOVER;
- - pGameInfoObj->m_GameStateTimer = Server()->Tick()-m_GameStartTick-10*Server()->TickSpeed()+m_GameStateTimer;
- - break;
- - case IGS_END_MATCH:
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER;
- - pGameInfoObj->m_GameStateTimer = Server()->Tick()-m_GameStartTick-10*Server()->TickSpeed()+m_GameStateTimer;
- - break;
- - case IGS_GAME_RUNNING:
- - // not effected
- - break;
- - }
- - if(m_SuddenDeath)
- - pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH;
- -
- - pGameInfoObj->m_GameStartTick = m_GameStartTick;
- -
- - pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit;
- - pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit;
- -
- - pGameInfoObj->m_MatchNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvMatchesPerMap) ? g_Config.m_SvMatchesPerMap : 0;
- - pGameInfoObj->m_MatchCurrent = m_MatchCount+1;
- -}
- -
- -void IGameController::Tick()
- -{
- - // handle game states
- - if(m_GameState != IGS_GAME_RUNNING)
- - {
- - if(m_GameStateTimer > 0)
- - --m_GameStateTimer;
- -
- - if(m_GameStateTimer == 0)
- - {
- - // timer fires
- - switch(m_GameState)
- - {
- - case IGS_WARMUP_USER:
- - // end warmup
- - SetGameState(IGS_WARMUP_USER, 0);
- - break;
- - case IGS_START_COUNTDOWN:
- - // unpause the game
- - SetGameState(IGS_GAME_RUNNING);
- - break;
- - case IGS_GAME_PAUSED:
- - // end pause
- - SetGameState(IGS_GAME_PAUSED, 0);
- - break;
- - case IGS_END_ROUND:
- - // check if the match is over otherwise start next round
- - DoWincheckMatch();
- - if(m_GameState != IGS_END_MATCH)
- - StartRound();
- - break;
- - case IGS_END_MATCH:
- - // start next match
- - CycleMap();
- - StartMatch();
- - m_MatchCount++;
- - break;
- - case IGS_WARMUP_GAME:
- - case IGS_GAME_RUNNING:
- - // not effected
- - break;
- - }
- - }
- - else
- - {
- - // timer still running
- - switch(m_GameState)
- - {
- - case IGS_WARMUP_USER:
- - // check if player ready mode was disabled and it waits that all players are ready -> end warmup
- - if(!g_Config.m_SvPlayerReadyMode && m_GameStateTimer == TIMER_INFINITE)
- - SetGameState(IGS_WARMUP_USER, 0);
- - break;
- - case IGS_START_COUNTDOWN:
- - case IGS_GAME_PAUSED:
- - // freeze the game
- - ++m_GameStartTick;
- - break;
- - case IGS_WARMUP_GAME:
- - case IGS_GAME_RUNNING:
- - case IGS_END_MATCH:
- - case IGS_END_ROUND:
- - // not effected
- - break;
- - }
- - }
- - }
- -
- - // do team-balancing (skip this in survival, done there when a round starts)
- - if(IsTeamplay() && !(m_GameFlags&GAMEFLAG_SURVIVAL))
- - {
- - switch(m_UnbalancedTick)
- - {
- - case TBALANCE_CHECK:
- - CheckTeamBalance();
- - break;
- - case TBALANCE_OK:
- - break;
- - default:
- - if(Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60)
- - DoTeamBalance();
- - }
- - }
- -
- - // check for inactive players
- - DoActivityCheck();
- -
- - // win check
- - if(m_GameState == IGS_GAME_RUNNING && !GameServer()->m_World.m_ResetRequested)
- - {
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - DoWincheckRound();
- - else
- - DoWincheckMatch();
- - }
- -}
- -
- -// info
- -bool IGameController::IsFriendlyFire(int ClientID1, int ClientID2) const
- -{
- - if(ClientID1 == ClientID2)
- - return false;
- -
- - if(IsTeamplay())
- - {
- - if(!GameServer()->m_apPlayers[ClientID1] || !GameServer()->m_apPlayers[ClientID2])
- - return false;
- -
- - if(!g_Config.m_SvTeamdamage && GameServer()->m_apPlayers[ClientID1]->GetTeam() == GameServer()->m_apPlayers[ClientID2]->GetTeam())
- - return true;
- - }
- -
- - return false;
- -}
- -
- -bool IGameController::IsPlayerReadyMode() const
- -{
- - return g_Config.m_SvPlayerReadyMode != 0 && (m_GameStateTimer == TIMER_INFINITE && (m_GameState == IGS_WARMUP_USER || m_GameState == IGS_GAME_PAUSED));
- + GameServer()->m_World.m_Paused = true;
- + m_GameOverTick = Server()->Tick();
- + m_SuddenDeath = 0;
- }
- -bool IGameController::IsTeamChangeAllowed() const
- +void IGameController::ResetGame()
- {
- - return !GameServer()->m_World.m_Paused || (m_GameState == IGS_START_COUNTDOWN && m_GameStartTick == Server()->Tick());
- + GameServer()->m_World.m_ResetRequested = true;
- }
- -const char *IGameController::GetTeamName(int Team) const
- +const char *IGameController::GetTeamName(int Team)
- {
- if(IsTeamplay())
- {
- @@ -808,19 +195,38 @@
- else if(Team == TEAM_BLUE)
- return "blue team";
- }
- - else if(Team == 0)
- - return "game";
- + else
- + {
- + if(Team == 0)
- + return "game";
- + }
- return "spectators";
- }
- -// map
- static bool IsSeparator(char c) { return c == ';' || c == ' ' || c == ',' || c == '\t'; }
- +void IGameController::StartRound()
- +{
- + ResetGame();
- +
- + m_RoundStartTick = Server()->Tick();
- + m_SuddenDeath = 0;
- + m_GameOverTick = -1;
- + GameServer()->m_World.m_Paused = false;
- + m_aTeamscore[TEAM_RED] = 0;
- + m_aTeamscore[TEAM_BLUE] = 0;
- + m_ForceBalanced = false;
- + Server()->DemoRecorder_HandleAutoStart();
- + char aBuf[256];
- + str_format(aBuf, sizeof(aBuf), "start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS);
- + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- +}
- +
- void IGameController::ChangeMap(const char *pToMap)
- {
- str_copy(m_aMapWish, pToMap, sizeof(m_aMapWish));
- - EndMatch();
- + EndRound();
- }
- void IGameController::CycleMap()
- @@ -832,15 +238,15 @@
- GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- str_copy(g_Config.m_SvMap, m_aMapWish, sizeof(g_Config.m_SvMap));
- m_aMapWish[0] = 0;
- - m_MatchCount = 0;
- + m_RoundCount = 0;
- return;
- }
- if(!str_length(g_Config.m_SvMaprotation))
- return;
- - if(m_MatchCount < g_Config.m_SvMatchesPerMap-1)
- + if(m_RoundCount < g_Config.m_SvRoundsPerMap-1)
- {
- - if(g_Config.m_SvMatchSwap)
- + if(g_Config.m_SvRoundSwap)
- GameServer()->SwapTeams();
- return;
- }
- @@ -891,7 +297,7 @@
- while(IsSeparator(aBuf[i]))
- i++;
- - m_MatchCount = 0;
- + m_RoundCount = 0;
- char aBufMsg[256];
- str_format(aBufMsg, sizeof(aBufMsg), "rotating map to %s", &aBuf[i]);
- @@ -899,202 +305,431 @@
- str_copy(g_Config.m_SvMap, &aBuf[i], sizeof(g_Config.m_SvMap));
- }
- -// spawn
- -bool IGameController::CanSpawn(int Team, vec2 *pOutPos) const
- +void IGameController::PostReset()
- {
- - // spectators can't spawn
- - if(Team == TEAM_SPECTATORS || GameServer()->m_World.m_Paused || GameServer()->m_World.m_ResetRequested)
- - return false;
- -
- - CSpawnEval Eval;
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if(GameServer()->m_apPlayers[i])
- + {
- + GameServer()->m_apPlayers[i]->Respawn();
- + GameServer()->m_apPlayers[i]->m_Score = 0;
- + GameServer()->m_apPlayers[i]->m_ScoreStartTick = Server()->Tick();
- + GameServer()->m_apPlayers[i]->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
- + }
- + }
- +}
- +void IGameController::OnPlayerInfoChange(class CPlayer *pP)
- +{
- + const int aTeamColors[2] = {65387, 10223467};
- if(IsTeamplay())
- {
- - Eval.m_FriendlyTeam = Team;
- -
- - // first try own team spawn, then normal spawn and then enemy
- - EvaluateSpawnType(&Eval, 1+(Team&1));
- - if(!Eval.m_Got)
- + pP->m_TeeInfos.m_UseCustomColor = 1;
- + if(pP->GetTeam() >= TEAM_RED && pP->GetTeam() <= TEAM_BLUE)
- {
- - EvaluateSpawnType(&Eval, 0);
- - if(!Eval.m_Got)
- - EvaluateSpawnType(&Eval, 1+((Team+1)&1));
- + pP->m_TeeInfos.m_ColorBody = aTeamColors[pP->GetTeam()];
- + pP->m_TeeInfos.m_ColorFeet = aTeamColors[pP->GetTeam()];
- + }
- + else
- + {
- + pP->m_TeeInfos.m_ColorBody = 12895054;
- + pP->m_TeeInfos.m_ColorFeet = 12895054;
- }
- }
- +}
- +
- +
- +int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
- +{
- + // do scoreing
- + if(!pKiller || Weapon == WEAPON_GAME)
- + return 0;
- + if(pKiller != pVictim->GetPlayer() && pVictim->frz_tick > 0)
- + pVictim->GetPlayer()->m_Score--; // suicide while frozen causes -1 score
- else
- {
- - EvaluateSpawnType(&Eval, 0);
- - EvaluateSpawnType(&Eval, 1);
- - EvaluateSpawnType(&Eval, 2);
- + if(IsTeamplay() && pVictim->GetPlayer()->GetTeam() == pKiller->GetTeam())
- + return 0; // teamkill
- + else
- + return 0;
- }
- + if(Weapon == WEAPON_SELF)
- + pVictim->GetPlayer()->m_RespawnTick = 0.5;
- + return 0;
- +}
- - *pOutPos = Eval.m_Pos;
- - return Eval.m_Got;
- +void IGameController::OnCharacterSpawn(class CCharacter *pChr)
- +{
- + // default health
- + pChr->IncreaseHealth(10);
- +
- + // give default weapons
- + //hammer second
- + pChr->GiveWeapon(WEAPON_GUN, 10);
- + pChr->GiveWeapon(WEAPON_HAMMER, -1);
- }
- -float IGameController::EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos) const
- +void IGameController::DoWarmup(int Seconds)
- {
- - float Score = 0.0f;
- - CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER));
- - for(; pC; pC = (CCharacter *)pC->TypeNext())
- + if(Seconds < 0)
- + m_Warmup = 0;
- + else
- + m_Warmup = Seconds*Server()->TickSpeed();
- +}
- +
- +bool IGameController::IsFriendlyFire(int ClientID1, int ClientID2)
- +{
- + if(ClientID1 == ClientID2)
- + return false;
- +
- + if(IsTeamplay())
- {
- - // team mates are not as dangerous as enemies
- - float Scoremod = 1.0f;
- - if(pEval->m_FriendlyTeam != -1 && pC->GetPlayer()->GetTeam() == pEval->m_FriendlyTeam)
- - Scoremod = 0.5f;
- + if(!GameServer()->m_apPlayers[ClientID1] || !GameServer()->m_apPlayers[ClientID2])
- + return false;
- - float d = distance(Pos, pC->m_Pos);
- - Score += Scoremod * (d == 0 ? 1000000000.0f : 1.0f/d);
- + if(GameServer()->m_apPlayers[ClientID1]->GetTeam() == GameServer()->m_apPlayers[ClientID2]->GetTeam())
- + return true;
- }
- - return Score;
- + return false;
- }
- -void IGameController::EvaluateSpawnType(CSpawnEval *pEval, int Type) const
- +bool IGameController::IsForceBalanced()
- {
- - // get spawn point
- - for(int i = 0; i < m_aNumSpawnPoints[Type]; i++)
- + if(m_ForceBalanced)
- {
- - // check if the position is occupado
- - CCharacter *aEnts[MAX_CLIENTS];
- - int Num = GameServer()->m_World.FindEntities(m_aaSpawnPoints[Type][i], 64, (CEntity**)aEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER);
- - vec2 Positions[5] = { vec2(0.0f, 0.0f), vec2(-32.0f, 0.0f), vec2(0.0f, -32.0f), vec2(32.0f, 0.0f), vec2(0.0f, 32.0f) }; // start, left, up, right, down
- - int Result = -1;
- - for(int Index = 0; Index < 5 && Result == -1; ++Index)
- + m_ForceBalanced = false;
- + return true;
- + }
- + else
- + return false;
- +}
- +
- +bool IGameController::CanBeMovedOnBalance(int ClientID)
- +{
- + return true;
- +}
- +
- +void IGameController::Tick()
- +{
- + // do warmup
- + if(m_Warmup)
- + {
- + m_Warmup--;
- + if(!m_Warmup)
- + StartRound();
- + }
- +
- + if(m_GameOverTick != -1)
- + {
- + // game over.. wait for restart
- + if(Server()->Tick() > m_GameOverTick+Server()->TickSpeed()*10)
- {
- - Result = Index;
- - for(int c = 0; c < Num; ++c)
- - if(GameServer()->Collision()->CheckPoint(m_aaSpawnPoints[Type][i]+Positions[Index]) ||
- - distance(aEnts[c]->m_Pos, m_aaSpawnPoints[Type][i]+Positions[Index]) <= aEnts[c]->m_ProximityRadius)
- + CycleMap();
- + StartRound();
- + m_RoundCount++;
- + }
- + }
- +
- + // game is Paused
- + if(GameServer()->m_World.m_Paused)
- + ++m_RoundStartTick;
- +
- + // do team-balancing
- + if(IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60)
- + {
- + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams");
- +
- + int aT[2] = {0,0};
- + float aTScore[2] = {0,0};
- + float aPScore[MAX_CLIENTS] = {0.0f};
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS)
- + {
- + aT[GameServer()->m_apPlayers[i]->GetTeam()]++;
- + aPScore[i] = GameServer()->m_apPlayers[i]->m_Score*Server()->TickSpeed()*60.0f/
- + (Server()->Tick()-GameServer()->m_apPlayers[i]->m_ScoreStartTick);
- + aTScore[GameServer()->m_apPlayers[i]->GetTeam()] += aPScore[i];
- + }
- + }
- +
- + // are teams unbalanced?
- + if(absolute(aT[0]-aT[1]) >= 2)
- + {
- + int M = (aT[0] > aT[1]) ? 0 : 1;
- + int NumBalance = absolute(aT[0]-aT[1]) / 2;
- +
- + do
- + {
- + CPlayer *pP = 0;
- + float PD = aTScore[M];
- + for(int i = 0; i < MAX_CLIENTS; i++)
- {
- - Result = -1;
- - break;
- + if(!GameServer()->m_apPlayers[i] || !CanBeMovedOnBalance(i))
- + continue;
- + // remember the player who would cause lowest score-difference
- + if(GameServer()->m_apPlayers[i]->GetTeam() == M && (!pP || absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i])) < PD))
- + {
- + pP = GameServer()->m_apPlayers[i];
- + PD = absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i]));
- + }
- }
- +
- + // move the player to the other team
- + int Temp = pP->m_LastActionTick;
- + pP->SetTeam(M^1);
- + pP->m_LastActionTick = Temp;
- +
- + pP->Respawn();
- + pP->m_ForceBalanced = true;
- + } while (--NumBalance);
- +
- + m_ForceBalanced = true;
- }
- - if(Result == -1)
- - continue; // try next spawn point
- + m_UnbalancedTick = -1;
- + }
- - vec2 P = m_aaSpawnPoints[Type][i]+Positions[Result];
- - float S = EvaluateSpawnPos(pEval, P);
- - if(!pEval->m_Got || pEval->m_Score > S)
- + // check for inactive players
- + if(g_Config.m_SvInactiveKickTime > 0)
- + {
- + for(int i = 0; i < MAX_CLIENTS; ++i)
- {
- - pEval->m_Got = true;
- - pEval->m_Score = S;
- - pEval->m_Pos = P;
- + #ifdef CONF_DEBUG
- + if(g_Config.m_DbgDummies)
- + {
- + if(i >= MAX_CLIENTS-g_Config.m_DbgDummies)
- + break;
- + }
- + #endif
- + if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && !Server()->IsAuthed(i))
- + {
- + if(Server()->Tick() > GameServer()->m_apPlayers[i]->m_LastActionTick+g_Config.m_SvInactiveKickTime*Server()->TickSpeed()*60)
- + {
- + switch(g_Config.m_SvInactiveKick)
- + {
- + case 0:
- + {
- + // move player to spectator
- + GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS);
- + }
- + break;
- + case 1:
- + {
- + // move player to spectator if the reserved slots aren't filled yet, kick him otherwise
- + int Spectators = 0;
- + for(int j = 0; j < MAX_CLIENTS; ++j)
- + if(GameServer()->m_apPlayers[j] && GameServer()->m_apPlayers[j]->GetTeam() == TEAM_SPECTATORS)
- + ++Spectators;
- + if(Spectators >= g_Config.m_SvSpectatorSlots)
- + Server()->Kick(i, "Kicked for inactivity");
- + else
- + GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS);
- + }
- + break;
- + case 2:
- + {
- + // kick the player
- + Server()->Kick(i, "Kicked for inactivity");
- + }
- + }
- + }
- + }
- }
- }
- +
- + DoWincheck();
- }
- -bool IGameController::GetStartRespawnState() const
- +
- +bool IGameController::IsTeamplay() const
- {
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - // players can always respawn during warmup or match/round start countdown
- - if(m_GameState == IGS_WARMUP_GAME || m_GameState == IGS_WARMUP_USER || (m_GameState == IGS_START_COUNTDOWN && m_GameStartTick == Server()->Tick()))
- - return false;
- - else
- - return true;
- - }
- - else
- - return false;
- + return m_GameFlags&GAMEFLAG_TEAMS;
- }
- -// team
- -bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam) const
- +void IGameController::Snap(int SnappingClient)
- {
- - if(!IsTeamplay() || JoinTeam == TEAM_SPECTATORS || !g_Config.m_SvTeambalanceTime)
- - return true;
- + CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo));
- + if(!pGameInfoObj)
- + return;
- +
- + pGameInfoObj->m_GameFlags = m_GameFlags;
- + pGameInfoObj->m_GameStateFlags = 0;
- + if(m_GameOverTick != -1)
- + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER;
- + if(m_SuddenDeath)
- + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH;
- + if(GameServer()->m_World.m_Paused)
- + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED;
- + pGameInfoObj->m_RoundStartTick = m_RoundStartTick;
- + pGameInfoObj->m_WarmupTimer = m_Warmup;
- +
- + pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit;
- + pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit;
- +
- + pGameInfoObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0;
- + pGameInfoObj->m_RoundCurrent = m_RoundCount+1;
- +}
- +
- +int IGameController::GetAutoTeam(int NotThisID)
- +{
- + // this will force the auto balancer to work overtime aswell
- + if(g_Config.m_DbgStress)
- + return 0;
- - // simulate what would happen if the player changes team
- - int aPlayerCount[NUM_TEAMS] = { m_aTeamSize[TEAM_RED], m_aTeamSize[TEAM_BLUE] };
- - aPlayerCount[JoinTeam]++;
- - if(pPlayer->GetTeam() != TEAM_SPECTATORS)
- - aPlayerCount[JoinTeam^1]--;
- + int aNumplayers[2] = {0,0};
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if(GameServer()->m_apPlayers[i] && i != NotThisID)
- + {
- + if(GameServer()->m_apPlayers[i]->GetTeam() >= TEAM_RED && GameServer()->m_apPlayers[i]->GetTeam() <= TEAM_BLUE)
- + aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
- + }
- + }
- +
- + int Team = 0;
- + if(IsTeamplay())
- + Team = aNumplayers[TEAM_RED] > aNumplayers[TEAM_BLUE] ? TEAM_BLUE : TEAM_RED;
- - // check if the player-difference decreases or is smaller than 2
- - return aPlayerCount[JoinTeam]-aPlayerCount[JoinTeam^1] < NUM_TEAMS;
- + if(CanJoinTeam(Team, NotThisID))
- + return Team;
- + return -1;
- }
- -bool IGameController::CanJoinTeam(int Team, int NotThisID) const
- +bool IGameController::CanJoinTeam(int Team, int NotThisID)
- {
- if(Team == TEAM_SPECTATORS || (GameServer()->m_apPlayers[NotThisID] && GameServer()->m_apPlayers[NotThisID]->GetTeam() != TEAM_SPECTATORS))
- return true;
- - // check if there're enough player slots left
- - return m_aTeamSize[TEAM_RED]+m_aTeamSize[TEAM_BLUE] < Server()->MaxClients()-g_Config.m_SvSpectatorSlots;
- + int aNumplayers[2] = {0,0};
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if(GameServer()->m_apPlayers[i] && i != NotThisID)
- + {
- + if(GameServer()->m_apPlayers[i]->GetTeam() >= TEAM_RED && GameServer()->m_apPlayers[i]->GetTeam() <= TEAM_BLUE)
- + aNumplayers[GameServer()->m_apPlayers[i]->GetTeam()]++;
- + }
- + }
- +
- + return (aNumplayers[0] + aNumplayers[1]) < Server()->MaxClients()-g_Config.m_SvSpectatorSlots;
- }
- -int IGameController::ClampTeam(int Team) const
- +bool IGameController::CheckTeamBalance()
- {
- - if(Team < TEAM_RED)
- - return TEAM_SPECTATORS;
- - if(IsTeamplay())
- - return Team&1;
- - return TEAM_RED;
- + if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime)
- + return true;
- +
- + int aT[2] = {0, 0};
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + CPlayer *pP = GameServer()->m_apPlayers[i];
- + if(pP && pP->GetTeam() != TEAM_SPECTATORS)
- + aT[pP->GetTeam()]++;
- + }
- +
- + char aBuf[256];
- + if(absolute(aT[0]-aT[1]) >= 2)
- + {
- + str_format(aBuf, sizeof(aBuf), "Teams are NOT balanced (red=%d blue=%d)", aT[0], aT[1]);
- + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- + if(GameServer()->m_pController->m_UnbalancedTick == -1)
- + GameServer()->m_pController->m_UnbalancedTick = Server()->Tick();
- + return false;
- + }
- + else
- + {
- + str_format(aBuf, sizeof(aBuf), "Teams are balanced (red=%d blue=%d)", aT[0], aT[1]);
- + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- + GameServer()->m_pController->m_UnbalancedTick = -1;
- + return true;
- + }
- }
- -void IGameController::DoTeamChange(CPlayer *pPlayer, int Team, bool DoChatMsg)
- +bool IGameController::CanChangeTeam(CPlayer *pPlayer, int JoinTeam)
- {
- - Team = ClampTeam(Team);
- - if(Team == pPlayer->GetTeam())
- - return;
- + int aT[2] = {0, 0};
- - int OldTeam = pPlayer->GetTeam();
- - pPlayer->SetTeam(Team);
- + if (!IsTeamplay() || JoinTeam == TEAM_SPECTATORS || !g_Config.m_SvTeambalanceTime)
- + return true;
- - int ClientID = pPlayer->GetCID();
- - char aBuf[128];
- - if(DoChatMsg)
- + for(int i = 0; i < MAX_CLIENTS; i++)
- {
- - str_format(aBuf, sizeof(aBuf), "'%s' joined the %s", Server()->ClientName(ClientID), GetTeamName(Team));
- - GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + CPlayer *pP = GameServer()->m_apPlayers[i];
- + if(pP && pP->GetTeam() != TEAM_SPECTATORS)
- + aT[pP->GetTeam()]++;
- }
- - str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' m_Team=%d", ClientID, Server()->ClientName(ClientID), Team);
- - GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- + // simulate what would happen if changed team
- + aT[JoinTeam]++;
- + if (pPlayer->GetTeam() != TEAM_SPECTATORS)
- + aT[JoinTeam^1]--;
- - // update effected game settings
- - if(OldTeam != TEAM_SPECTATORS)
- + // there is a player-difference of at least 2
- + if(absolute(aT[0]-aT[1]) >= 2)
- {
- - --m_aTeamSize[OldTeam];
- - m_UnbalancedTick = TBALANCE_CHECK;
- + // player wants to join team with less players
- + if ((aT[0] < aT[1] && JoinTeam == TEAM_RED) || (aT[0] > aT[1] && JoinTeam == TEAM_BLUE))
- + return true;
- + else
- + return false;
- }
- - if(Team != TEAM_SPECTATORS)
- + else
- + return true;
- +}
- +
- +void IGameController::DoWincheck()
- +{
- + if(m_GameOverTick == -1 && !m_Warmup && !GameServer()->m_World.m_ResetRequested)
- {
- - ++m_aTeamSize[Team];
- - m_UnbalancedTick = TBALANCE_CHECK;
- - if(m_GameState == IGS_WARMUP_GAME && HasEnoughPlayers())
- - SetGameState(IGS_WARMUP_GAME, 0);
- - pPlayer->m_IsReadyToPlay = !IsPlayerReadyMode();
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - pPlayer->m_RespawnDisabled = GetStartRespawnState();
- + if(IsTeamplay())
- + {
- + // check score win condition
- + if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) ||
- + (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- + {
- + if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE])
- + EndRound();
- + else
- + m_SuddenDeath = 1;
- + }
- + }
- + else
- + {
- + // gather some stats
- + int Topscore = 0;
- + int TopscoreCount = 0;
- + for(int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if(GameServer()->m_apPlayers[i])
- + {
- + if(GameServer()->m_apPlayers[i]->m_Score > Topscore)
- + {
- + Topscore = GameServer()->m_apPlayers[i]->m_Score;
- + TopscoreCount = 1;
- + }
- + else if(GameServer()->m_apPlayers[i]->m_Score == Topscore)
- + TopscoreCount++;
- + }
- + }
- +
- + // check score win condition
- + if((g_Config.m_SvScorelimit > 0 && Topscore >= g_Config.m_SvScorelimit) ||
- + (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- + {
- + if(TopscoreCount == 1)
- + EndRound();
- + else
- + m_SuddenDeath = 1;
- + }
- + }
- }
- - OnPlayerInfoChange(pPlayer);
- - GameServer()->OnClientTeamChange(ClientID);
- }
- -int IGameController::GetStartTeam()
- +int IGameController::ClampTeam(int Team)
- {
- - // this will force the auto balancer to work overtime aswell
- - if(g_Config.m_DbgStress)
- - return TEAM_RED;
- -
- - if(g_Config.m_SvTournamentMode)
- + if(Team < 0)
- return TEAM_SPECTATORS;
- -
- - // determine new team
- - int Team = TEAM_RED;
- if(IsTeamplay())
- - Team = m_aTeamSize[TEAM_RED] > m_aTeamSize[TEAM_BLUE] ? TEAM_BLUE : TEAM_RED;
- -
- - // check if there're enough player slots left
- - if(m_aTeamSize[TEAM_RED]+m_aTeamSize[TEAM_BLUE] < Server()->MaxClients()-g_Config.m_SvSpectatorSlots)
- - {
- - ++m_aTeamSize[Team];
- - m_UnbalancedTick = TBALANCE_CHECK;
- - if(m_GameState == IGS_WARMUP_GAME && HasEnoughPlayers())
- - SetGameState(IGS_WARMUP_GAME, 0);
- - return Team;
- - }
- - return TEAM_SPECTATORS;
- + return Team&1;
- + return 0;
- }
- diff -Naur ../teeworlds/src/game/server/gamecontroller.h src/game/server/gamecontroller.h
- --- ../teeworlds/src/game/server/gamecontroller.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamecontroller.h 2012-07-08 19:42:32.842259599 +1000
- @@ -5,7 +5,14 @@
- #include <base/vmath.h>
- -#include <game/generated/protocol.h>
- +#ifdef _MSC_VER
- +typedef __int32 int32_t;
- +typedef unsigned __int32 uint32_t;
- +typedef __int64 int64_t;
- +typedef unsigned __int64 uint64_t;
- +#else
- +#include <stdint.h>
- +#endif
- /*
- Class: Game Controller
- @@ -14,59 +21,16 @@
- */
- class IGameController
- {
- + vec2 m_aaSpawnPoints[3][64];
- + int m_aNumSpawnPoints[3];
- +
- class CGameContext *m_pGameServer;
- class IServer *m_pServer;
- - // activity
- - void DoActivityCheck();
- - bool GetPlayersReadyState();
- - void SetPlayersReadyState(bool ReadyState);
- -
- - // balancing
- - enum
- - {
- - TBALANCE_CHECK=-2,
- - TBALANCE_OK,
- - };
- - int m_aTeamSize[NUM_TEAMS];
- - int m_UnbalancedTick;
- -
- - virtual bool CanBeMovedOnBalance(int ClientID) const;
- - void CheckTeamBalance();
- - void DoTeamBalance();
- -
- - // game
- - enum EGameState
- - {
- - // internal game states
- - IGS_WARMUP_GAME, // warmup started by game because there're not enough players (infinite)
- - IGS_WARMUP_USER, // warmup started by user action via rcon or new match (infinite or timer)
- -
- - IGS_START_COUNTDOWN, // start countown to unpause the game or start match/round (tick timer)
- -
- - IGS_GAME_PAUSED, // game paused (infinite or tick timer)
- - IGS_GAME_RUNNING, // game running (infinite)
- -
- - IGS_END_MATCH, // match is over (tick timer)
- - IGS_END_ROUND, // round is over (tick timer)
- - };
- - EGameState m_GameState;
- - int m_GameStateTimer;
- -
- - virtual void DoWincheckMatch();
- - virtual void DoWincheckRound() {};
- - bool HasEnoughPlayers() const { return (IsTeamplay() && m_aTeamSize[TEAM_RED] > 0 && m_aTeamSize[TEAM_BLUE] > 0) || (!IsTeamplay() && m_aTeamSize[TEAM_RED] > 1); }
- - void ResetGame();
- - void SetGameState(EGameState GameState, int Timer=0);
- - void StartMatch();
- - void StartRound();
- -
- - // map
- - char m_aMapWish[128];
- -
- - void CycleMap();
- +protected:
- + CGameContext *GameServer() const { return m_pGameServer; }
- + IServer *Server() const { return m_pServer; }
- - // spawn
- struct CSpawnEval
- {
- CSpawnEval()
- @@ -81,57 +45,59 @@
- int m_FriendlyTeam;
- float m_Score;
- };
- - vec2 m_aaSpawnPoints[3][64];
- - int m_aNumSpawnPoints[3];
- -
- - float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos) const;
- - void EvaluateSpawnType(CSpawnEval *pEval, int Type) const;
- - // team
- - int ClampTeam(int Team) const;
- + float EvaluateSpawnPos(CSpawnEval *pEval, vec2 Pos);
- + void EvaluateSpawnType(CSpawnEval *pEval, int Type);
- + bool EvaluateSpawn(class CPlayer *pP, vec2 *pPos);
- -protected:
- - CGameContext *GameServer() const { return m_pGameServer; }
- - IServer *Server() const { return m_pServer; }
- + void CycleMap();
- + void ResetGame();
- - // game
- - int m_GameStartTick;
- - int m_MatchCount;
- - int m_RoundCount;
- + char m_aMapWish[128];
- +
- +
- + int m_RoundStartTick;
- + int m_GameOverTick;
- int m_SuddenDeath;
- - int m_aTeamscore[NUM_TEAMS];
- - void EndMatch() { SetGameState(IGS_END_MATCH, 10); }
- - void EndRound() { SetGameState(IGS_END_ROUND, 10); }
- + int m_aTeamscore[2];
- +
- + int m_Warmup;
- + int m_RoundCount;
- - // info
- int m_GameFlags;
- - const char *m_pGameType;
- + int m_UnbalancedTick;
- + bool m_ForceBalanced;
- public:
- + const char *m_pGameType;
- +
- + bool IsTeamplay() const;
- + bool IsGameOver() const { return m_GameOverTick != -1; }
- +
- IGameController(class CGameContext *pGameServer);
- - virtual ~IGameController() {};
- + virtual ~IGameController();
- - // event
- - /*
- - Function: on_CCharacter_death
- - Called when a CCharacter in the world dies.
- + virtual void DoWincheck();
- +
- + void DoWarmup(int Seconds);
- +
- + void StartRound();
- + void EndRound();
- + void ChangeMap(const char *pToMap);
- +
- + bool IsFriendlyFire(int ClientID1, int ClientID2);
- +
- + bool IsForceBalanced();
- - Arguments:
- - victim - The CCharacter that died.
- - killer - The player that killed it.
- - weapon - What weapon that killed it. Can be -1 for undefined
- - weapon when switching team or player suicides.
- - */
- - virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- /*
- - Function: on_CCharacter_spawn
- - Called when a CCharacter spawns into the game world.
- - Arguments:
- - chr - The CCharacter that was spawned.
- */
- - virtual void OnCharacterSpawn(class CCharacter *pChr);
- + virtual bool CanBeMovedOnBalance(int ClientID);
- +
- + virtual void Tick();
- +
- + virtual void Snap(int SnappingClient);
- /*
- Function: on_entity
- @@ -147,49 +113,44 @@
- */
- virtual bool OnEntity(int Index, vec2 Pos);
- - void OnPlayerDisconnect(class CPlayer *pPlayer, const char *pReason);
- - void OnPlayerInfoChange(class CPlayer *pPlayer);
- - void OnPlayerReadyChange(class CPlayer *pPlayer);
- + /*
- + Function: on_CCharacter_spawn
- + Called when a CCharacter spawns into the game world.
- +
- + Arguments:
- + chr - The CCharacter that was spawned.
- + */
- + virtual void OnCharacterSpawn(class CCharacter *pChr);
- +
- + /*
- + Function: on_CCharacter_death
- + Called when a CCharacter in the world dies.
- +
- + Arguments:
- + victim - The CCharacter that died.
- + killer - The player that killed it.
- + weapon - What weapon that killed it. Can be -1 for undefined
- + weapon when switching team or player suicides.
- + */
- + virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- - void OnReset();
- - // game
- - enum
- - {
- - TIMER_INFINITE = -1,
- - };
- + virtual void OnPlayerInfoChange(class CPlayer *pP);
- - void DoPause(int Seconds) { SetGameState(IGS_GAME_PAUSED, Seconds); }
- - void DoWarmup(int Seconds) { SetGameState(IGS_WARMUP_USER, Seconds); }
- + //
- + virtual bool CanSpawn(int Team, vec2 *pPos);
- - // general
- - virtual void Snap(int SnappingClient);
- - virtual void Tick();
- + /*
- - // info
- - bool IsFriendlyFire(int ClientID1, int ClientID2) const;
- - bool IsGamePaused() const { return m_GameState == IGS_GAME_PAUSED || m_GameState == IGS_START_COUNTDOWN; }
- - bool IsPlayerReadyMode() const;
- - bool IsTeamChangeAllowed() const;
- - bool IsTeamplay() const { return m_GameFlags&GAMEFLAG_TEAMS; }
- -
- - const char *GetGameType() const { return m_pGameType; }
- - const char *GetTeamName(int Team) const;
- -
- - // map
- - void ChangeMap(const char *pToMap);
- + */
- + virtual const char *GetTeamName(int Team);
- + virtual int GetAutoTeam(int NotThisID);
- + virtual bool CanJoinTeam(int Team, int NotThisID);
- + bool CheckTeamBalance();
- + bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam);
- + int ClampTeam(int Team);
- - //spawn
- - bool CanSpawn(int Team, vec2 *pPos) const;
- - bool GetStartRespawnState() const;
- -
- - // team
- - bool CanJoinTeam(int Team, int NotThisID) const;
- - bool CanChangeTeam(CPlayer *pPplayer, int JoinTeam) const;
- -
- - void DoTeamChange(class CPlayer *pPlayer, int Team, bool DoChatMsg=true);
- -
- - int GetStartTeam();
- + virtual void PostReset();
- };
- #endif
- diff -Naur ../teeworlds/src/game/server/gamemodes/ctf.cpp src/game/server/gamemodes/ctf.cpp
- --- ../teeworlds/src/game/server/gamemodes/ctf.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/ctf.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -6,38 +6,39 @@
- #include <game/server/entities/character.h>
- #include <game/server/entities/flag.h>
- -#include <game/server/gamecontext.h>
- #include <game/server/player.h>
- +#include <game/server/gamecontext.h>
- #include "ctf.h"
- -CGameControllerCTF::CGameControllerCTF(CGameContext *pGameServer)
- +CGameControllerCTF::CGameControllerCTF(class CGameContext *pGameServer)
- : IGameController(pGameServer)
- {
- - // game
- m_apFlags[0] = 0;
- m_apFlags[1] = 0;
- m_pGameType = "CTF";
- m_GameFlags = GAMEFLAG_TEAMS|GAMEFLAG_FLAGS;
- }
- -// balancing
- -bool CGameControllerCTF::CanBeMovedOnBalance(int ClientID)
- +bool CGameControllerCTF::OnEntity(int Index, vec2 Pos)
- {
- - CCharacter* Character = GameServer()->m_apPlayers[ClientID]->GetCharacter();
- - if(Character)
- - {
- - for(int fi = 0; fi < 2; fi++)
- - {
- - CFlag *F = m_apFlags[fi];
- - if(F->m_pCarryingCharacter == Character)
- - return false;
- - }
- - }
- + if(IGameController::OnEntity(Index, Pos))
- + return true;
- +
- + int Team = -1;
- + if(Index == ENTITY_FLAGSTAND_RED) Team = TEAM_RED;
- + if(Index == ENTITY_FLAGSTAND_BLUE) Team = TEAM_BLUE;
- + if(Team == -1 || m_apFlags[Team])
- + return false;
- +
- + CFlag *F = new CFlag(&GameServer()->m_World, Team);
- + F->m_StandPos = Pos;
- + F->m_Pos = Pos;
- + m_apFlags[Team] = F;
- + GameServer()->m_World.InsertEntity(F);
- return true;
- }
- -// event
- -int CGameControllerCTF::OnCharacterDeath(CCharacter *pVictim, CPlayer *pKiller, int WeaponID)
- +int CGameControllerCTF::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID)
- {
- IGameController::OnCharacterDeath(pVictim, pKiller, WeaponID);
- int HadFlag = 0;
- @@ -65,48 +66,45 @@
- return HadFlag;
- }
- -bool CGameControllerCTF::OnEntity(int Index, vec2 Pos)
- +void CGameControllerCTF::DoWincheck()
- {
- - if(IGameController::OnEntity(Index, Pos))
- - return true;
- -
- - int Team = -1;
- - if(Index == ENTITY_FLAGSTAND_RED) Team = TEAM_RED;
- - if(Index == ENTITY_FLAGSTAND_BLUE) Team = TEAM_BLUE;
- - if(Team == -1 || m_apFlags[Team])
- - return false;
- -
- - CFlag *F = new CFlag(&GameServer()->m_World, Team);
- - F->m_StandPos = Pos;
- - F->m_Pos = Pos;
- - m_apFlags[Team] = F;
- - GameServer()->m_World.InsertEntity(F);
- - return true;
- + if(m_GameOverTick == -1 && !m_Warmup)
- + {
- + // check score win condition
- + if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) ||
- + (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- + {
- + if(m_SuddenDeath)
- + {
- + if(m_aTeamscore[TEAM_RED]/100 != m_aTeamscore[TEAM_BLUE]/100)
- + EndRound();
- + }
- + else
- + {
- + if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE])
- + EndRound();
- + else
- + m_SuddenDeath = 1;
- + }
- + }
- + }
- }
- -// game
- -void CGameControllerCTF::DoWincheckMatch()
- +bool CGameControllerCTF::CanBeMovedOnBalance(int ClientID)
- {
- - // check score win condition
- - if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) ||
- - (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_GameStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- + CCharacter* Character = GameServer()->m_apPlayers[ClientID]->GetCharacter();
- + if(Character)
- {
- - if(m_SuddenDeath)
- - {
- - if(m_aTeamscore[TEAM_RED]/100 != m_aTeamscore[TEAM_BLUE]/100)
- - EndMatch();
- - }
- - else
- + for(int fi = 0; fi < 2; fi++)
- {
- - if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE])
- - EndMatch();
- - else
- - m_SuddenDeath = 1;
- + CFlag *F = m_apFlags[fi];
- + if(F->m_pCarryingCharacter == Character)
- + return false;
- }
- }
- + return true;
- }
- -// general
- void CGameControllerCTF::Snap(int SnappingClient)
- {
- IGameController::Snap(SnappingClient);
- @@ -118,7 +116,6 @@
- pGameDataObj->m_TeamscoreRed = m_aTeamscore[TEAM_RED];
- pGameDataObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE];
- - pGameDataObj->m_FlagDropTickRed = 0;
- if(m_apFlags[TEAM_RED])
- {
- if(m_apFlags[TEAM_RED]->m_AtStand)
- @@ -126,14 +123,10 @@
- else if(m_apFlags[TEAM_RED]->m_pCarryingCharacter && m_apFlags[TEAM_RED]->m_pCarryingCharacter->GetPlayer())
- pGameDataObj->m_FlagCarrierRed = m_apFlags[TEAM_RED]->m_pCarryingCharacter->GetPlayer()->GetCID();
- else
- - {
- pGameDataObj->m_FlagCarrierRed = FLAG_TAKEN;
- - pGameDataObj->m_FlagDropTickRed = m_apFlags[TEAM_RED]->m_DropTick;
- - }
- }
- else
- pGameDataObj->m_FlagCarrierRed = FLAG_MISSING;
- - pGameDataObj->m_FlagDropTickBlue = 0;
- if(m_apFlags[TEAM_BLUE])
- {
- if(m_apFlags[TEAM_BLUE]->m_AtStand)
- @@ -141,10 +134,7 @@
- else if(m_apFlags[TEAM_BLUE]->m_pCarryingCharacter && m_apFlags[TEAM_BLUE]->m_pCarryingCharacter->GetPlayer())
- pGameDataObj->m_FlagCarrierBlue = m_apFlags[TEAM_BLUE]->m_pCarryingCharacter->GetPlayer()->GetCID();
- else
- - {
- pGameDataObj->m_FlagCarrierBlue = FLAG_TAKEN;
- - pGameDataObj->m_FlagDropTickBlue = m_apFlags[TEAM_BLUE]->m_DropTick;
- - }
- }
- else
- pGameDataObj->m_FlagCarrierBlue = FLAG_MISSING;
- @@ -262,8 +252,7 @@
- if(!pPlayer)
- continue;
- - if((pPlayer->GetTeam() == TEAM_SPECTATORS || pPlayer->m_DeadSpecMode) && pPlayer->GetSpectatorID() != SPEC_FREEVIEW &&
- - GameServer()->m_apPlayers[pPlayer->GetSpectatorID()] && GameServer()->m_apPlayers[pPlayer->GetSpectatorID()]->GetTeam() == fi)
- + if(pPlayer->GetTeam() == TEAM_SPECTATORS && pPlayer->m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[pPlayer->m_SpectatorID] && GameServer()->m_apPlayers[pPlayer->m_SpectatorID]->GetTeam() == fi)
- GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, c);
- else if(pPlayer->GetTeam() == fi)
- GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, c);
- diff -Naur ../teeworlds/src/game/server/gamemodes/ctf.h src/game/server/gamemodes/ctf.h
- --- ../teeworlds/src/game/server/gamemodes/ctf.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/ctf.h 2012-07-08 19:28:03.418259861 +1000
- @@ -7,24 +7,17 @@
- class CGameControllerCTF : public IGameController
- {
- - // balancing
- - virtual bool CanBeMovedOnBalance(int ClientID);
- -
- - // game
- +public:
- class CFlag *m_apFlags[2];
- - virtual void DoWincheckMatch();
- -
- -public:
- CGameControllerCTF(class CGameContext *pGameServer);
- -
- - // event
- - virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- - virtual bool OnEntity(int Index, vec2 Pos);
- -
- - // general
- + virtual void DoWincheck();
- + virtual bool CanBeMovedOnBalance(int ClientID);
- virtual void Snap(int SnappingClient);
- virtual void Tick();
- +
- + virtual bool OnEntity(int Index, vec2 Pos);
- + virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- };
- #endif
- diff -Naur ../teeworlds/src/game/server/gamemodes/dm.cpp src/game/server/gamemodes/dm.cpp
- --- ../teeworlds/src/game/server/gamemodes/dm.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/dm.cpp 2012-07-08 19:28:03.418259861 +1000
- @@ -3,8 +3,13 @@
- #include "dm.h"
- -CGameControllerDM::CGameControllerDM(CGameContext *pGameServer)
- +CGameControllerDM::CGameControllerDM(class CGameContext *pGameServer)
- : IGameController(pGameServer)
- {
- m_pGameType = "DM";
- }
- +
- +void CGameControllerDM::Tick()
- +{
- + IGameController::Tick();
- +}
- diff -Naur ../teeworlds/src/game/server/gamemodes/dm.h src/game/server/gamemodes/dm.h
- --- ../teeworlds/src/game/server/gamemodes/dm.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/dm.h 2012-07-08 19:28:03.418259861 +1000
- @@ -8,6 +8,6 @@
- {
- public:
- CGameControllerDM(class CGameContext *pGameServer);
- + virtual void Tick();
- };
- -
- #endif
- diff -Naur ../teeworlds/src/game/server/gamemodes/lms.cpp src/game/server/gamemodes/lms.cpp
- --- ../teeworlds/src/game/server/gamemodes/lms.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/lms.cpp 1970-01-01 10:00:00.000000000 +1000
- @@ -1,70 +0,0 @@
- -/* (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 <engine/shared/config.h>
- -
- -#include <game/server/entities/character.h>
- -#include <game/server/gamecontext.h>
- -#include <game/server/player.h>
- -#include "lms.h"
- -
- -CGameControllerLMS::CGameControllerLMS(CGameContext *pGameServer) : IGameController(pGameServer)
- -{
- - m_pGameType = "LMS";
- - m_GameFlags = GAMEFLAG_SURVIVAL;
- -}
- -
- -// event
- -int CGameControllerLMS::OnCharacterDeath(CCharacter *pVictim, CPlayer *pKiller, int Weapon)
- -{
- - // update spectator modes for dead players in survival
- - if(m_GameFlags&GAMEFLAG_SURVIVAL)
- - {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_DeadSpecMode)
- - GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
- - }
- -
- - return 0;
- -}
- -
- -// game
- -void CGameControllerLMS::DoWincheckRound()
- -{
- - // check for time based win
- - if(g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_GameStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60)
- - {
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS &&
- - (!GameServer()->m_apPlayers[i]->m_RespawnDisabled ||
- - (GameServer()->m_apPlayers[i]->GetCharacter() && GameServer()->m_apPlayers[i]->GetCharacter()->IsAlive())))
- - GameServer()->m_apPlayers[i]->m_Score++;
- - }
- -
- - EndRound();
- - }
- - else
- - {
- - // check for survival win
- - CPlayer *pAlivePlayer = 0;
- - int AlivePlayerCount = 0;
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS &&
- - (!GameServer()->m_apPlayers[i]->m_RespawnDisabled ||
- - (GameServer()->m_apPlayers[i]->GetCharacter() && GameServer()->m_apPlayers[i]->GetCharacter()->IsAlive())))
- - {
- - ++AlivePlayerCount;
- - pAlivePlayer = GameServer()->m_apPlayers[i];
- - }
- - }
- -
- - if(AlivePlayerCount == 0) // no winner
- - EndRound();
- - else if(AlivePlayerCount == 1) // 1 winner
- - {
- - pAlivePlayer->m_Score++;
- - EndRound();
- - }
- - }
- -}
- diff -Naur ../teeworlds/src/game/server/gamemodes/lms.h src/game/server/gamemodes/lms.h
- --- ../teeworlds/src/game/server/gamemodes/lms.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/lms.h 1970-01-01 10:00:00.000000000 +1000
- @@ -1,19 +0,0 @@
- -/* (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 GAME_SERVER_GAMEMODES_LMS_H
- -#define GAME_SERVER_GAMEMODES_LMS_H
- -#include <game/server/gamecontroller.h>
- -
- -class CGameControllerLMS : public IGameController
- -{
- -public:
- - CGameControllerLMS(class CGameContext *pGameServer);
- -
- - // event
- - virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- -
- - // game
- - virtual void DoWincheckRound();
- -};
- -
- -#endif
- diff -Naur ../teeworlds/src/game/server/gamemodes/mod.cpp src/game/server/gamemodes/mod.cpp
- --- ../teeworlds/src/game/server/gamemodes/mod.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/mod.cpp 2012-07-08 19:28:03.418259861 +1000
- @@ -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 ../teeworlds/src/game/server/gamemodes/sur.cpp src/game/server/gamemodes/sur.cpp
- --- ../teeworlds/src/game/server/gamemodes/sur.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/sur.cpp 1970-01-01 10:00:00.000000000 +1000
- @@ -1,62 +0,0 @@
- -/* (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 <engine/shared/config.h>
- -
- -#include <game/server/entities/character.h>
- -#include <game/server/gamecontext.h>
- -#include <game/server/player.h>
- -#include "sur.h"
- -
- -CGameControllerSUR::CGameControllerSUR(CGameContext *pGameServer) : IGameController(pGameServer)
- -{
- - m_pGameType = "SUR";
- - m_GameFlags = GAMEFLAG_TEAMS|GAMEFLAG_SURVIVAL;
- -}
- -
- -// game
- -void CGameControllerSUR::DoWincheckRound()
- -{
- - int Count[2] = {0};
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS &&
- - (!GameServer()->m_apPlayers[i]->m_RespawnDisabled ||
- - (GameServer()->m_apPlayers[i]->GetCharacter() && GameServer()->m_apPlayers[i]->GetCharacter()->IsAlive())))
- - ++Count[GameServer()->m_apPlayers[i]->GetTeam()];
- - }
- -
- - if(Count[TEAM_RED]+Count[TEAM_BLUE] == 0 || (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_GameStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60))
- - {
- - ++m_aTeamscore[TEAM_BLUE];
- - ++m_aTeamscore[TEAM_RED];
- - EndRound();
- - }
- - else if(Count[TEAM_RED] == 0)
- - {
- - ++m_aTeamscore[TEAM_BLUE];
- - EndRound();
- - }
- - else if(Count[TEAM_BLUE] == 0)
- - {
- - ++m_aTeamscore[TEAM_RED];
- - EndRound();
- - }
- -}
- -
- -// general
- -void CGameControllerSUR::Snap(int SnappingClient)
- -{
- - IGameController::Snap(SnappingClient);
- -
- - CNetObj_GameData *pGameDataObj = (CNetObj_GameData *)Server()->SnapNewItem(NETOBJTYPE_GAMEDATA, 0, sizeof(CNetObj_GameData));
- - if(!pGameDataObj)
- - return;
- -
- - pGameDataObj->m_TeamscoreRed = m_aTeamscore[TEAM_RED];
- - pGameDataObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE];
- -
- - pGameDataObj->m_FlagCarrierRed = 0;
- - pGameDataObj->m_FlagCarrierBlue = 0;
- - pGameDataObj->m_FlagDropTickRed = 0;
- - pGameDataObj->m_FlagDropTickBlue = 0;
- -}
- diff -Naur ../teeworlds/src/game/server/gamemodes/sur.h src/game/server/gamemodes/sur.h
- --- ../teeworlds/src/game/server/gamemodes/sur.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/sur.h 1970-01-01 10:00:00.000000000 +1000
- @@ -1,19 +0,0 @@
- -/* (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 GAME_SERVER_GAMEMODES_SUR_H
- -#define GAME_SERVER_GAMEMODES_SUR_H
- -#include <game/server/gamecontroller.h>
- -
- -class CGameControllerSUR : public IGameController
- -{
- -public:
- - CGameControllerSUR(class CGameContext *pGameServer);
- -
- - // game
- - virtual void DoWincheckRound();
- -
- - // general
- - virtual void Snap(int SnappingClient);
- -};
- -
- -#endif
- diff -Naur ../teeworlds/src/game/server/gamemodes/tdm.cpp src/game/server/gamemodes/tdm.cpp
- --- ../teeworlds/src/game/server/gamemodes/tdm.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/tdm.cpp 2012-07-08 19:28:03.418259861 +1000
- @@ -3,7 +3,6 @@
- #include <engine/shared/config.h>
- #include <game/server/entities/character.h>
- -#include <game/server/gamecontext.h>
- #include <game/server/player.h>
- #include "tdm.h"
- @@ -13,7 +12,6 @@
- m_GameFlags = GAMEFLAG_TEAMS;
- }
- -// event
- int CGameControllerTDM::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon)
- {
- IGameController::OnCharacterDeath(pVictim, pKiller, Weapon);
- @@ -33,7 +31,6 @@
- return 0;
- }
- -// general
- void CGameControllerTDM::Snap(int SnappingClient)
- {
- IGameController::Snap(SnappingClient);
- @@ -47,6 +44,9 @@
- pGameDataObj->m_FlagCarrierRed = 0;
- pGameDataObj->m_FlagCarrierBlue = 0;
- - pGameDataObj->m_FlagDropTickRed = 0;
- - pGameDataObj->m_FlagDropTickBlue = 0;
- +}
- +
- +void CGameControllerTDM::Tick()
- +{
- + IGameController::Tick();
- }
- diff -Naur ../teeworlds/src/game/server/gamemodes/tdm.h src/game/server/gamemodes/tdm.h
- --- ../teeworlds/src/game/server/gamemodes/tdm.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/tdm.h 2012-07-08 19:28:03.418259861 +1000
- @@ -9,11 +9,8 @@
- public:
- CGameControllerTDM(class CGameContext *pGameServer);
- - // event
- - virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- -
- - // general
- + int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
- virtual void Snap(int SnappingClient);
- + virtual void Tick();
- };
- -
- #endif
- diff -Naur ../teeworlds/src/game/server/gameworld.cpp src/game/server/gameworld.cpp
- --- ../teeworlds/src/game/server/gameworld.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gameworld.cpp 2012-07-08 19:42:32.842259599 +1000
- @@ -1,12 +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. */
- -#include "entities/character.h"
- +#include "gameworld.h"
- #include "entity.h"
- #include "gamecontext.h"
- -#include "gamecontroller.h"
- -#include "gameworld.h"
- -
- +#include <algorithm>
- +#include <utility>
- +#include <engine/shared/config.h>
- //////////////////////////////////////////////////
- // game world
- @@ -128,7 +128,7 @@
- }
- RemoveEntities();
- - GameServer()->m_pController->OnReset();
- + GameServer()->m_pController->PostReset();
- RemoveEntities();
- m_ResetRequested = false;
- @@ -150,6 +150,75 @@
- }
- }
- +bool distCompare(std::pair<float,int> a, std::pair<float,int> b)
- +{
- + return (a.first < b.first);
- +}
- +
- +void CGameWorld::UpdatePlayerMaps()
- +{
- + if (Server()->Tick() % g_Config.m_SvMapUpdateRate != 0) return;
- +
- + std::pair<float,int> dist[MAX_CLIENTS];
- + for (int i = 0; i < MAX_CLIENTS; i++)
- + {
- + if (!Server()->ClientIngame(i)) continue;
- + int* map = Server()->GetIdMap(i);
- +
- + // compute distances
- + for (int j = 0; j < MAX_CLIENTS; j++)
- + {
- + dist[j].second = j;
- + dist[j].first = 1e10;
- + if (!Server()->ClientIngame(j))
- + continue;
- + CCharacter* ch = GameServer()->m_apPlayers[j]->GetCharacter();
- + if (!ch)
- + continue;
- + dist[j].first = distance(GameServer()->m_apPlayers[i]->m_ViewPos, GameServer()->m_apPlayers[j]->m_ViewPos);
- + }
- +
- + // always send the player himself
- + dist[i].first = 0;
- +
- + // compute reverse map
- + int rMap[MAX_CLIENTS];
- + for (int j = 0; j < MAX_CLIENTS; j++)
- + {
- + rMap[j] = -1;
- + }
- + for (int j = 0; j < VANILLA_MAX_CLIENTS; j++)
- + {
- + if (map[j] == -1) continue;
- + if (dist[map[j]].first > 1e9) map[j] = -1;
- + else rMap[map[j]] = j;
- + }
- +
- + std::nth_element(&dist[0], &dist[VANILLA_MAX_CLIENTS - 1], &dist[MAX_CLIENTS], distCompare);
- +
- + int mapc = 0;
- + int demand = 0;
- + for (int j = 0; j < VANILLA_MAX_CLIENTS - 1; j++)
- + {
- + int k = dist[j].second;
- + if (rMap[k] != -1 || dist[j].first > 1e9) continue;
- + while (mapc < VANILLA_MAX_CLIENTS && map[mapc] != -1) mapc++;
- + if (mapc < VANILLA_MAX_CLIENTS - 1)
- + map[mapc] = k;
- + else
- + if (dist[j].first < 1300) // dont bother freeing up space for players which are too far to be displayed anyway
- + demand++;
- + }
- + for (int j = MAX_CLIENTS - 1; j > VANILLA_MAX_CLIENTS - 2; j--)
- + {
- + int k = dist[j].second;
- + if (rMap[k] != -1 && demand-- > 0)
- + map[rMap[k]] = -1;
- + }
- + map[VANILLA_MAX_CLIENTS - 1] = -1; // player with empty name to say chat msgs
- + }
- +}
- +
- void CGameWorld::Tick()
- {
- if(m_ResetRequested)
- @@ -157,6 +226,8 @@
- if(!m_Paused)
- {
- + if(GameServer()->m_pController->IsForceBalanced())
- + GameServer()->SendChat(-1, CGameContext::CHAT_ALL, "Teams have been balanced");
- // update all objects
- for(int i = 0; i < NUM_ENTTYPES; i++)
- for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; )
- @@ -174,7 +245,7 @@
- pEnt = m_pNextTraverseEntity;
- }
- }
- - else if(GameServer()->m_pController->IsGamePaused())
- + else
- {
- // update all objects
- for(int i = 0; i < NUM_ENTTYPES; i++)
- @@ -187,8 +258,9 @@
- }
- RemoveEntities();
- -}
- + UpdatePlayerMaps();
- +}
- // TODO: should be more general
- CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2& NewPos, CEntity *pNotThis)
- diff -Naur ../teeworlds/src/game/server/gameworld.h src/game/server/gameworld.h
- --- ../teeworlds/src/game/server/gameworld.h 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gameworld.h 2012-07-08 19:28:03.418259861 +1000
- @@ -36,6 +36,8 @@
- class CGameContext *m_pGameServer;
- class IServer *m_pServer;
- + void UpdatePlayerMaps();
- +
- public:
- class CGameContext *GameServer() { return m_pGameServer; }
- class IServer *Server() { return m_pServer; }
- diff -Naur ../teeworlds/src/game/server/player.cpp src/game/server/player.cpp
- --- ../teeworlds/src/game/server/player.cpp 2012-06-26 16:53:53.400861537 +1000
- +++ src/game/server/player.cpp 2012-07-08 19:44:28.473761216 +1000
- @@ -1,9 +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 "entities/character.h"
- -#include "gamecontext.h"
- -#include "gamecontroller.h"
- +#include <new>
- +#include <engine/shared/config.h>
- #include "player.h"
- @@ -11,23 +9,28 @@
- IServer *CPlayer::Server() const { return m_pGameServer->Server(); }
- -CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy)
- +CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team)
- {
- + m_Muted = 0;
- m_pGameServer = pGameServer;
- m_RespawnTick = Server()->Tick();
- m_DieTick = Server()->Tick();
- m_ScoreStartTick = Server()->Tick();
- m_pCharacter = 0;
- m_ClientID = ClientID;
- - m_Team = GameServer()->m_pController->GetStartTeam();
- + m_Team = GameServer()->m_pController->ClampTeam(Team);
- m_SpectatorID = SPEC_FREEVIEW;
- m_LastActionTick = Server()->Tick();
- + slot3 = 0;
- + int* idMap = Server()->GetIdMap(ClientID);
- + for (int i = 1;i < VANILLA_MAX_CLIENTS;i++)
- + {
- + idMap[i] = -1;
- + }
- + idMap[0] = ClientID;
- +
- +
- m_TeamChangeTick = Server()->Tick();
- - m_Dummy = Dummy;
- - m_IsReadyToPlay = !GameServer()->m_pController->IsPlayerReadyMode();
- - m_RespawnDisabled = GameServer()->m_pController->GetStartRespawnState();
- - m_DeadSpecMode = false;
- - m_Spawning = 0;
- }
- CPlayer::~CPlayer()
- @@ -38,11 +41,18 @@
- void CPlayer::Tick()
- {
- - if(!IsDummy() && !Server()->ClientIngame(m_ClientID))
- +#ifdef CONF_DEBUG
- + if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
- +#endif
- + if(!Server()->ClientIngame(m_ClientID))
- return;
- Server()->SetClientScore(m_ClientID, m_Score);
- + if(m_Muted != 0)
- + {
- + m_Muted--;
- + }
- // do latency stuff
- {
- IServer::CClientInfo Info;
- @@ -64,24 +74,25 @@
- }
- }
- - if(m_pCharacter && !m_pCharacter->IsAlive())
- - {
- - delete m_pCharacter;
- - m_pCharacter = 0;
- - }
- -
- - if(!GameServer()->m_pController->IsGamePaused())
- + if(!GameServer()->m_World.m_Paused)
- {
- if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW)
- m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -500.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f));
- - if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick() && !m_DeadSpecMode)
- - Respawn();
- + if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick())
- + m_Spawning = true;
- if(m_pCharacter)
- {
- if(m_pCharacter->IsAlive())
- + {
- m_ViewPos = m_pCharacter->m_Pos;
- + }
- + else
- + {
- + delete m_pCharacter;
- + m_pCharacter = 0;
- + }
- }
- else if(m_Spawning && m_RespawnTick <= Server()->Tick())
- TryRespawn();
- @@ -108,17 +119,24 @@
- }
- }
- - // update view pos for spectators and dead players
- - if((m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
- + // update view pos for spectators
- + if(m_Team == TEAM_SPECTATORS && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
- m_ViewPos = GameServer()->m_apPlayers[m_SpectatorID]->m_ViewPos;
- }
- void CPlayer::Snap(int SnappingClient)
- {
- - if(!IsDummy() && !Server()->ClientIngame(m_ClientID))
- +#ifdef CONF_DEBUG
- + if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
- +#endif
- + if(!Server()->ClientIngame(m_ClientID))
- return;
- - CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, m_ClientID, sizeof(CNetObj_ClientInfo)));
- + int id = m_ClientID;
- + if (!Server()->Translate(id, SnappingClient)) return;
- +
- + CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, id, sizeof(CNetObj_ClientInfo)));
- +
- if(!pClientInfo)
- return;
- @@ -130,27 +148,20 @@
- pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
- pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
- - CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, m_ClientID, sizeof(CNetObj_PlayerInfo)));
- + CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, id, sizeof(CNetObj_PlayerInfo)));
- if(!pPlayerInfo)
- return;
- - pPlayerInfo->m_PlayerFlags = m_PlayerFlags&PLAYERFLAG_CHATTING;
- - if(!GameServer()->m_pController->IsPlayerReadyMode() || m_IsReadyToPlay)
- - pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_READY;
- - if(m_RespawnDisabled && (!GetCharacter() || !GetCharacter()->IsAlive()))
- - pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_DEAD;
- - if(SnappingClient != -1 && (m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && SnappingClient == m_SpectatorID)
- - pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_WATCHING;
- pPlayerInfo->m_Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
- pPlayerInfo->m_Local = 0;
- - pPlayerInfo->m_ClientID = m_ClientID;
- + pPlayerInfo->m_ClientID = id;
- pPlayerInfo->m_Score = m_Score;
- pPlayerInfo->m_Team = m_Team;
- if(m_ClientID == SnappingClient)
- pPlayerInfo->m_Local = 1;
- - if(m_ClientID == SnappingClient && (m_Team == TEAM_SPECTATORS || m_DeadSpecMode))
- + if(m_ClientID == SnappingClient && m_Team == TEAM_SPECTATORS)
- {
- CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo)));
- if(!pSpectatorInfo)
- @@ -162,23 +173,40 @@
- }
- }
- -void CPlayer::OnDisconnect()
- +void CPlayer::FakeSnap(int SnappingClient)
- +{
- + IServer::CClientInfo info;
- + Server()->GetClientInfo(SnappingClient, &info);
- + if (info.m_CustClt)
- + return;
- +
- + int id = VANILLA_MAX_CLIENTS - 1;
- +
- + CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, id, sizeof(CNetObj_ClientInfo)));
- +
- + if(!pClientInfo)
- + return;
- +
- + StrToInts(&pClientInfo->m_Name0, 4, " ");
- + StrToInts(&pClientInfo->m_Clan0, 3, Server()->ClientClan(m_ClientID));
- + StrToInts(&pClientInfo->m_Skin0, 6, m_TeeInfos.m_SkinName);
- +}
- +
- +void CPlayer::OnDisconnect(const char *pReason)
- {
- KillCharacter();
- - if(m_Team != TEAM_SPECTATORS)
- + if(Server()->ClientIngame(m_ClientID))
- {
- - // update spectator modes
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- - {
- - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
- - {
- - if(GameServer()->m_apPlayers[i]->m_DeadSpecMode)
- - GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
- - else
- - GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
- - }
- - }
- + char aBuf[512];
- + if(pReason && *pReason)
- + str_format(aBuf, sizeof(aBuf), "'%s' has left the game (%s)", Server()->ClientName(m_ClientID), pReason);
- + else
- + str_format(aBuf, sizeof(aBuf), "'%s' has left the game", Server()->ClientName(m_ClientID));
- + GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- +
- + //str_format(aBuf, sizeof(aBuf), "leave player='%d:%s'", m_ClientID, Server()->ClientName(m_ClientID));
- + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "game", aBuf);
- }
- }
- @@ -194,12 +222,6 @@
- void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
- {
- - if(GameServer()->m_World.m_Paused)
- - {
- - m_PlayerFlags = NewInput->m_PlayerFlags;
- - return;
- - }
- -
- if(NewInput->m_PlayerFlags&PLAYERFLAG_CHATTING)
- {
- // skip the input if chat is active
- @@ -220,7 +242,7 @@
- m_pCharacter->OnDirectInput(NewInput);
- if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (NewInput->m_Fire&1))
- - Respawn();
- + m_Spawning = true;
- // check for activity
- if(NewInput->m_Direction || m_LatestActivity.m_TargetX != NewInput->m_TargetX ||
- @@ -252,98 +274,42 @@
- void CPlayer::Respawn()
- {
- - if(m_RespawnDisabled)
- - {
- - // enable spectate mode for dead players
- - m_DeadSpecMode = true;
- - m_IsReadyToPlay = true;
- - UpdateDeadSpecMode();
- - return;
- - }
- -
- - m_DeadSpecMode = false;
- -
- if(m_Team != TEAM_SPECTATORS)
- m_Spawning = true;
- }
- -bool CPlayer::SetSpectatorID(int SpectatorID)
- -{
- - if(m_SpectatorID == SpectatorID || m_ClientID == SpectatorID)
- - return false;
- -
- - if(m_Team == TEAM_SPECTATORS)
- - {
- - // check for freeview or if wanted player is playing
- - if(SpectatorID == SPEC_FREEVIEW || (GameServer()->m_apPlayers[SpectatorID] && GameServer()->m_apPlayers[SpectatorID]->GetTeam() != TEAM_SPECTATORS))
- - {
- - m_SpectatorID = SpectatorID;
- - return true;
- - }
- - }
- - else if(m_DeadSpecMode)
- - {
- - // check if wanted player can be followed
- - if(GameServer()->m_apPlayers[SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[SpectatorID]))
- - {
- - m_SpectatorID = SpectatorID;
- - return true;
- - }
- - }
- -
- - return false;
- -}
- -
- -bool CPlayer::DeadCanFollow(CPlayer *pPlayer) const
- -{
- - // check if wanted player is in the same team and alive
- - return (!pPlayer->m_RespawnDisabled || (pPlayer->GetCharacter() && pPlayer->GetCharacter()->IsAlive())) && pPlayer->GetTeam() == m_Team;
- -}
- -
- -void CPlayer::UpdateDeadSpecMode()
- +void CPlayer::SetTeam(int Team, bool DoChatMsg)
- {
- - // check if actual spectator id is valid
- - if(m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[m_SpectatorID]))
- + // clamp the team
- + Team = GameServer()->m_pController->ClampTeam(Team);
- + if(m_Team == Team)
- return;
- - // find player to follow
- - for(int i = 0; i < MAX_CLIENTS; ++i)
- +/* char aBuf[512];
- + if(DoChatMsg)
- {
- - if(GameServer()->m_apPlayers[i] && DeadCanFollow(GameServer()->m_apPlayers[i]))
- - {
- - m_SpectatorID = i;
- - return;
- - }
- - }
- -
- - // no one available to follow -> turn spectator mode off
- - m_DeadSpecMode = false;
- -}
- + str_format(aBuf, sizeof(aBuf), "'%s' joined the %s", Server()->ClientName(m_ClientID), GameServer()->m_pController->GetTeamName(Team));
- + GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
- + }*/
- -void CPlayer::SetTeam(int Team, bool DoChatMsg)
- -{
- KillCharacter();
- m_Team = Team;
- m_LastActionTick = Server()->Tick();
- - m_SpectatorID = SPEC_FREEVIEW;
- - m_DeadSpecMode = false;
- -
- // we got to wait 0.5 secs before respawning
- m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
- -
- + //str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' m_Team=%d", m_ClientID, Server()->ClientName(m_ClientID), m_Team);
- + //GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf);
- +
- + GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]);
- +
- if(Team == TEAM_SPECTATORS)
- {
- // update spectator modes
- for(int i = 0; i < MAX_CLIENTS; ++i)
- {
- if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
- - {
- - if(GameServer()->m_apPlayers[i]->m_DeadSpecMode)
- - GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
- - else
- - GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
- - }
- + GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
- }
- }
- }
- diff -Naur ../teeworlds/src/game/server/player.h src/game/server/player.h
- --- ../teeworlds/src/game/server/player.h 2012-06-26 16:53:53.400861537 +1000
- +++ src/game/server/player.h 2012-07-08 19:42:32.954259163 +1000
- @@ -3,15 +3,9 @@
- #ifndef GAME_SERVER_PLAYER_H
- #define GAME_SERVER_PLAYER_H
- -#include "alloc.h"
- -
- -
- -enum
- -{
- - WEAPON_GAME = -3, // team switching etc
- - WEAPON_SELF = -2, // console kill command
- - WEAPON_WORLD = -1, // death tiles etc
- -};
- +// this include should perhaps be removed
- +#include "entities/character.h"
- +#include "gamecontext.h"
- // player object
- class CPlayer
- @@ -19,7 +13,7 @@
- MACRO_ALLOC_POOL_ID()
- public:
- - CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy);
- + CPlayer(CGameContext *pGameServer, int ClientID, int Team);
- ~CPlayer();
- void Init(int CID);
- @@ -29,15 +23,15 @@
- void SetTeam(int Team, bool DoChatMsg=true);
- int GetTeam() const { return m_Team; };
- int GetCID() const { return m_ClientID; };
- - bool IsDummy() const { return m_Dummy; }
- void Tick();
- void PostTick();
- void Snap(int SnappingClient);
- + void FakeSnap(int SnappingClient);
- void OnDirectInput(CNetObj_PlayerInput *NewInput);
- void OnPredictedInput(CNetObj_PlayerInput *NewInput);
- - void OnDisconnect();
- + void OnDisconnect(const char *pReason);
- void KillCharacter(int Weapon = WEAPON_GAME);
- CCharacter *GetCharacter();
- @@ -53,16 +47,30 @@
- int m_aActLatency[MAX_CLIENTS];
- // used for spectator mode
- - int GetSpectatorID() const { return m_SpectatorID; }
- - bool SetSpectatorID(int SpectatorID);
- - bool m_DeadSpecMode;
- - bool DeadCanFollow(CPlayer *pPlayer) const;
- - void UpdateDeadSpecMode();
- + int m_SpectatorID;
- +
- + bool m_IsReady;
- +
- + 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;
- - bool m_IsReadyToEnter;
- - bool m_IsReadyToPlay;
- - bool m_RespawnDisabled;
- + int Skills[NUM_PUPS];
- +
- + int *slot3;
- +
- + int is1on1;
- + char *oname;
- //
- int m_Vote;
- @@ -76,8 +84,11 @@
- int m_LastChangeInfo;
- int m_LastEmote;
- int m_LastKill;
- - int m_LastReadyChange;
- -
- + int m_Muted;
- + int m_MuteTimes;
- + char m_LastChatText[256];
- + int m_LastChatTime;
- +
- // TODO: clean this up
- struct
- {
- @@ -91,6 +102,7 @@
- int m_DieTick;
- int m_Score;
- int m_ScoreStartTick;
- + bool m_ForceBalanced;
- int m_LastActionTick;
- int m_TeamChangeTick;
- struct
- @@ -121,10 +133,6 @@
- bool m_Spawning;
- int m_ClientID;
- int m_Team;
- - bool m_Dummy;
- -
- - // used for spectator mode
- - int m_SpectatorID;
- };
- #endif
- diff -Naur ../teeworlds/src/game/tuning.h src/game/tuning.h
- --- ../teeworlds/src/game/tuning.h 2012-06-26 16:53:53.400861537 +1000
- +++ src/game/tuning.h 2012-07-08 19:28:03.422259113 +1000
- @@ -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 ../teeworlds/src/game/variables.h src/game/variables.h
- --- ../teeworlds/src/game/variables.h 2012-06-26 16:53:53.400861537 +1000
- +++ src/game/variables.h 2012-07-08 19:42:32.954259163 +1000
- @@ -56,25 +56,24 @@
- MACRO_CONFIG_INT(GfxNoclip, gfx_noclip, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Disable clipping")
- // server
- -MACRO_CONFIG_INT(SvWarmup, sv_warmup, 0, -1, 1000, CFGFLAG_SERVER, "Number of seconds to do warmup before match starts (0 disables, -1 all players ready)")
- +MACRO_CONFIG_INT(SvWarmup, sv_warmup, 0, 0, 0, CFGFLAG_SERVER, "Number of seconds to do warmup before round starts")
- MACRO_CONFIG_STR(SvMotd, sv_motd, 900, "", CFGFLAG_SERVER, "Message of the day to display for the clients")
- MACRO_CONFIG_INT(SvTeamdamage, sv_teamdamage, 0, 0, 1, CFGFLAG_SERVER, "Team damage")
- MACRO_CONFIG_STR(SvMaprotation, sv_maprotation, 768, "", CFGFLAG_SERVER, "Maps to rotate between")
- -MACRO_CONFIG_INT(SvMatchesPerMap, sv_matches_per_map, 1, 1, 100, CFGFLAG_SERVER, "Number of matches on each map before rotating")
- -MACRO_CONFIG_INT(SvMatchSwap, sv_match_swap, 1, 0, 1, CFGFLAG_SERVER, "Swap teams between matches")
- +MACRO_CONFIG_INT(SvRoundsPerMap, sv_rounds_per_map, 1, 1, 100, CFGFLAG_SERVER, "Number of rounds on each map before rotating")
- +MACRO_CONFIG_INT(SvRoundSwap, sv_round_swap, 1, 0, 1, CFGFLAG_SERVER, "Swap teams between rounds")
- 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, lms, sur)")
- +MACRO_CONFIG_INT(SvScorelimit, sv_scorelimit, 0, 0, 0, CFGFLAG_SERVER, "Score limit (0 disables)")
- +MACRO_CONFIG_INT(SvTimelimit, sv_timelimit, 0, 0, 0, CFGFLAG_SERVER, "Time limit in minutes (0 disables)")
- +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(SvPlayerReadyMode, sv_player_ready_mode, 0, 0, 1, CFGFLAG_SERVER, "When enabled, players can pause/unpause the game and start the game on warmup via their ready state")
- MACRO_CONFIG_INT(SvSpamprotection, sv_spamprotection, 1, 0, 1, CFGFLAG_SERVER, "Spam protection")
- MACRO_CONFIG_INT(SvRespawnDelayTDM, sv_respawn_delay_tdm, 3, 0, 10, CFGFLAG_SERVER, "Time needed to respawn after death in tdm gametype")
- 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(SvStrictSpectateMode, sv_strict_spectate_mode, 0, 0, 1, CFGFLAG_SERVER, "Restricts information in spectator mode")
- @@ -84,6 +83,7 @@
- MACRO_CONFIG_INT(SvVoteKickMin, sv_vote_kick_min, 0, 0, MAX_CLIENTS, CFGFLAG_SERVER, "Minimum number of players required to start a kick vote")
- MACRO_CONFIG_INT(SvVoteKickBantime, sv_vote_kick_bantime, 5, 0, 1440, CFGFLAG_SERVER, "The time to ban a player if kicked by vote. 0 makes it just use kick")
- +MACRO_CONFIG_INT(SvMapUpdateRate, sv_mapupdaterate, 5, 1, 100, CFGFLAG_SERVER, "(Tw32) real id <-> vanilla id players map update rate")
- // debug
- #ifdef CONF_DEBUG // this one can crash the server if not used correctly
- MACRO_CONFIG_INT(DbgDummies, dbg_dummies, 0, 0, 15, CFGFLAG_SERVER, "")
- diff -Naur ../teeworlds/src/game/version.h src/game/version.h
- --- ../teeworlds/src/game/version.h 2012-06-26 16:53:53.400861537 +1000
- +++ src/game/version.h 2012-07-08 19:42:32.846258990 +1000
- @@ -3,7 +3,7 @@
- #ifndef GAME_VERSION_H
- #define GAME_VERSION_H
- #include "generated/nethash.cpp"
- -#define GAME_VERSION "0.7 trunk"
- -#define GAME_NETVERSION "0.7 " GAME_NETVERSION_HASH
- +#define GAME_VERSION "0.6 trunk"
- +#define GAME_NETVERSION "0.6 " GAME_NETVERSION_HASH
- static const char GAME_RELEASE_VERSION[8] = {'0', '.', '6', '1', 0};
- #endif
- diff -Naur ../teeworlds/src/mastersrv/mastersrv.cpp src/mastersrv/mastersrv.cpp
- --- ../teeworlds/src/mastersrv/mastersrv.cpp 2012-06-26 16:53:53.400861537 +1000
- +++ src/mastersrv/mastersrv.cpp 2012-07-08 19:42:32.846258990 +1000
- @@ -348,11 +348,7 @@
- m_pConsole->ParseArguments(argc-1, &argv[1]); // ignore_convention
- if(g_Config.m_Bindaddr[0] && net_host_lookup(g_Config.m_Bindaddr, &BindAddr, NETTYPE_ALL) == 0)
- - {
- - // got bindaddr
- - BindAddr.type = NETTYPE_ALL;
- BindAddr.port = MASTERSERVER_PORT;
- - }
- else
- {
- mem_zero(&BindAddr, sizeof(BindAddr));
- @@ -372,9 +368,6 @@
- return -1;
- }
- - // process pending commands
- - m_pConsole->StoreCommands(false);
- -
- dbg_msg("mastersrv", "started");
- while(1)