182 changes: 140 additions & 42 deletions src/engine/server/server.cpp
Expand Up @@ -31,7 +31,6 @@
#include <mastersrv/mastersrv.h>

// DDRace
#include <string.h>
#include <vector>
#include <engine/shared/linereader.h>
#include <game/extrainfo.h>
Expand Down Expand Up @@ -285,6 +284,7 @@ CServer::CServer()

m_ServerInfoFirstRequest = 0;
m_ServerInfoNumRequests = 0;
m_ServerInfoNeedsUpdate = false;

#ifdef CONF_FAMILY_UNIX
m_ConnLoggingSocketCreated = false;
Expand Down Expand Up @@ -404,6 +404,10 @@ void CServer::SetClientScore(int ClientID, int Score)
{
if(ClientID < 0 || ClientID >= MAX_CLIENTS || m_aClients[ClientID].m_State < CClient::STATE_READY)
return;

if(m_aClients[ClientID].m_Score != Score)
ExpireServerInfo();

m_aClients[ClientID].m_Score = Score;
}

Expand Down Expand Up @@ -472,6 +476,7 @@ int CServer::Init()
m_aClients[i].m_TrafficSince = 0;
m_aClients[i].m_ShowIps = false;
m_aClients[i].m_AuthKey = -1;
m_aClients[i].m_Latency = 0;
}

m_CurrentGameTick = 0;
Expand Down Expand Up @@ -1502,8 +1507,46 @@ void CServer::SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type)
SendServerInfo(pAddr, Token, Type, SendClients);
}

void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients)
static inline int GetCacheIndex(int Type, bool SendClient)
{
if(Type == SERVERINFO_INGAME)
Type = SERVERINFO_VANILLA;
else if(Type == SERVERINFO_EXTENDED_MORE)
Type = SERVERINFO_EXTENDED;

return Type * 2 + SendClient;
}

CServer::CCache::CCache()
{
m_lCache.clear();
}

CServer::CCache::~CCache()
{
Clear();
}

CServer::CCache::CCacheChunk::CCacheChunk(const void *pData, int Size)
{
mem_copy(m_aData, pData, Size);
m_DataSize = Size;
}

void CServer::CCache::AddChunk(const void *pData, int Size)
{
m_lCache.emplace_back(pData, Size);
}

void CServer::CCache::Clear()
{
m_lCache.clear();
}

void CServer::CacheServerInfo(CCache *pCache, int Type, bool SendClients)
{
pCache->Clear();

// One chance to improve the protocol!
CPacker p;
char aBuf[128];
Expand All @@ -1526,17 +1569,6 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
#define ADD_RAW(p, x) (p).AddRaw(x, sizeof(x))
#define ADD_INT(p, x) do { str_format(aBuf, sizeof(aBuf), "%d", x); (p).AddString(aBuf, 0); } while(0)

switch(Type)
{
case SERVERINFO_EXTENDED: ADD_RAW(p, SERVERBROWSE_INFO_EXTENDED); break;
case SERVERINFO_64_LEGACY: ADD_RAW(p, SERVERBROWSE_INFO_64_LEGACY); break;
case SERVERINFO_VANILLA: ADD_RAW(p, SERVERBROWSE_INFO); break;
case SERVERINFO_INGAME: ADD_RAW(p, SERVERBROWSE_INFO); break;
default: dbg_assert(false, "unknown serverinfo type");
}

ADD_INT(p, Token);

p.AddString(GameServer()->Version(), 32);
if(Type != SERVERINFO_VANILLA)
{
Expand Down Expand Up @@ -1596,20 +1628,14 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
int PrefixSize = p.Size();

CPacker pp;
CNetChunk Packet;
int PacketsSent = 0;
int PlayersSent = 0;
Packet.m_ClientID = -1;
Packet.m_Address = *pAddr;
Packet.m_Flags = NETSENDFLAG_CONNLESS;
int ChunksStored = 0;
int PlayersStored = 0;

#define SEND(size) \
#define SAVE(size) \
do \
{ \
Packet.m_pData = pp.Data(); \
Packet.m_DataSize = size; \
m_NetServer.Send(&Packet); \
PacketsSent++; \
pCache->AddChunk(pp.Data(), size); \
ChunksStored++; \
} while(0)

#define RESET() \
Expand All @@ -1622,18 +1648,18 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
RESET();

if(Type == SERVERINFO_64_LEGACY)
pp.AddInt(PlayersSent); // offset
pp.AddInt(PlayersStored); // offset

if(!SendClients)
{
SEND(pp.Size());
SAVE(pp.Size());
return;
}

if(Type == SERVERINFO_EXTENDED)
{
pPrefix = SERVERBROWSE_INFO_EXTENDED_MORE;
PrefixSize = sizeof(SERVERBROWSE_INFO_EXTENDED_MORE);
pPrefix = "";
PrefixSize = 0;
}

int Remaining;
Expand Down Expand Up @@ -1661,9 +1687,9 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
break;

// Otherwise we're SERVERINFO_64_LEGACY.
SEND(pp.Size());
SAVE(pp.Size());
RESET();
pp.AddInt(PlayersSent); // offset
pp.AddInt(PlayersStored); // offset
Remaining = 24;
}
if(Remaining > 0)
Expand All @@ -1688,36 +1714,104 @@ void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool Sen
{
// Retry current player.
i--;
SEND(PreviousSize);
SAVE(PreviousSize);
RESET();
ADD_INT(pp, Token);
ADD_INT(pp, PacketsSent);
ADD_INT(pp, ChunksStored);
pp.AddString("", 0); // extra info, reserved
continue;
}
}
PlayersSent++;
PlayersStored++;
}
}

SEND(pp.Size());
#undef SEND
SAVE(pp.Size());
#undef SAVE
#undef RESET
#undef ADD_RAW
#undef ADD_INT
}

void CServer::UpdateServerInfo()
void CServer::SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients)
{
for(int i = 0; i < MAX_CLIENTS; ++i)
CPacker p;
char aBuf[128];
p.Reset();

CCache *pCache = &m_ServerInfoCache[GetCacheIndex(Type, SendClients)];
CCache::CCacheChunk &FirstChunk = pCache->m_lCache.front();

#define ADD_RAW(p, x) (p).AddRaw(x, sizeof(x))
#define ADD_INT(p, x) do { str_format(aBuf, sizeof(aBuf), "%d", x); (p).AddString(aBuf, 0); } while(0)

switch(Type)
{
if(m_aClients[i].m_State != CClient::STATE_EMPTY)
case SERVERINFO_EXTENDED: ADD_RAW(p, SERVERBROWSE_INFO_EXTENDED); break;
case SERVERINFO_64_LEGACY: ADD_RAW(p, SERVERBROWSE_INFO_64_LEGACY); break;
case SERVERINFO_VANILLA:
case SERVERINFO_INGAME: ADD_RAW(p, SERVERBROWSE_INFO); break;
default: dbg_assert(false, "unknown serverinfo type");
}

ADD_INT(p, Token);
p.AddRaw(FirstChunk.m_aData, FirstChunk.m_DataSize);

CNetChunk Packet;
Packet.m_ClientID = -1;
Packet.m_Address = *pAddr;
Packet.m_Flags = NETSENDFLAG_CONNLESS;
Packet.m_pData = p.Data();
Packet.m_DataSize = p.Size();

m_NetServer.Send(&Packet);

if(Type == SERVERINFO_INGAME || Type == SERVERINFO_VANILLA)
return;

for(const auto &Chunk : pCache->m_lCache)
{
p.Reset();
if(Type == SERVERINFO_EXTENDED)
{
SendServerInfo(m_NetServer.ClientAddr(i), -1, SERVERINFO_INGAME, false);
p.AddRaw(SERVERBROWSE_INFO_EXTENDED_MORE, sizeof(SERVERBROWSE_INFO_EXTENDED_MORE));
ADD_INT(p, Token);
}
else if(Type == SERVERINFO_64_LEGACY)
{
p.AddRaw(FirstChunk.m_aData, FirstChunk.m_DataSize);
}

p.AddRaw(Chunk.m_aData, Chunk.m_DataSize);
Packet.m_pData = p.Data();
Packet.m_DataSize = p.Size();
m_NetServer.Send(&Packet);
}
}

void CServer::ExpireServerInfo()
{
m_ServerInfoNeedsUpdate = true;
}

void CServer::UpdateServerInfo(bool Resend)
{
for(int i = 0; i < 3; i++)
for(int j = 0; j < 2; j++)
CacheServerInfo(&m_ServerInfoCache[i * 2 + j], i, j);

if(Resend)
{
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_aClients[i].m_State != CClient::STATE_EMPTY)
{
SendServerInfo(m_NetServer.ClientAddr(i), -1, SERVERINFO_INGAME, false);
}
}
}

m_ServerInfoNeedsUpdate = false;
}

void CServer::PumpNetwork()
{
Expand Down Expand Up @@ -1922,6 +2016,7 @@ int CServer::Run()
m_Lastheartbeat = 0;
m_GameStartTime = time_get();

UpdateServerInfo();
while(m_RunServer)
{
if(NonActive)
Expand Down Expand Up @@ -1962,7 +2057,7 @@ int CServer::Run()
{
break;
}
UpdateServerInfo();
UpdateServerInfo(true);
}
else
{
Expand Down Expand Up @@ -2066,6 +2161,9 @@ int CServer::Run()
// master server stuff
m_Register.RegisterUpdate(m_NetServer.NetType());

if(m_ServerInfoNeedsUpdate)
UpdateServerInfo();

if(!NonActive)
PumpNetwork();

Expand Down Expand Up @@ -2700,7 +2798,7 @@ void CServer::ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserD
{
pfnCallback(pResult, pCallbackUserData);
if(pResult->NumArguments())
((CServer *)pUserData)->UpdateServerInfo();
((CServer *)pUserData)->UpdateServerInfo(true);
}

void CServer::ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
Expand Down
28 changes: 27 additions & 1 deletion src/engine/server/server.h
Expand Up @@ -23,6 +23,8 @@

#include <base/tl/array.h>

#include <list>

#include "authmanager.h"
#include "name_ban.h"

Expand Down Expand Up @@ -291,9 +293,33 @@ class CServer : public IServer

void ProcessClientPacket(CNetChunk *pPacket);

class CCache {
public:
class CCacheChunk {
public:
CCacheChunk(const void *pData, int Size);
CCacheChunk(const CCacheChunk &) = delete;

int m_DataSize;
unsigned char m_aData[NET_MAX_PAYLOAD];
};

std::list<CCacheChunk> m_lCache;

CCache();
~CCache();

void AddChunk(const void *pData, int Size);
void Clear();
};
CCache m_ServerInfoCache[3 * 2];
bool m_ServerInfoNeedsUpdate;

void ExpireServerInfo();
void CacheServerInfo(CCache *pCache, int Type, bool SendClients);
void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients);
void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type);
void UpdateServerInfo();
void UpdateServerInfo(bool Resend = false);

void PumpNetwork();

Expand Down
6 changes: 3 additions & 3 deletions src/engine/server/sql_server.cpp
Expand Up @@ -177,16 +177,16 @@ void CSqlServer::CreateTables()
char aBuf[1024];

// create tables
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_race (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , Time FLOAT DEFAULT 0, Server CHAR(4), cp1 FLOAT DEFAULT 0, cp2 FLOAT DEFAULT 0, cp3 FLOAT DEFAULT 0, cp4 FLOAT DEFAULT 0, cp5 FLOAT DEFAULT 0, cp6 FLOAT DEFAULT 0, cp7 FLOAT DEFAULT 0, cp8 FLOAT DEFAULT 0, cp9 FLOAT DEFAULT 0, cp10 FLOAT DEFAULT 0, cp11 FLOAT DEFAULT 0, cp12 FLOAT DEFAULT 0, cp13 FLOAT DEFAULT 0, cp14 FLOAT DEFAULT 0, cp15 FLOAT DEFAULT 0, cp16 FLOAT DEFAULT 0, cp17 FLOAT DEFAULT 0, cp18 FLOAT DEFAULT 0, cp19 FLOAT DEFAULT 0, cp20 FLOAT DEFAULT 0, cp21 FLOAT DEFAULT 0, cp22 FLOAT DEFAULT 0, cp23 FLOAT DEFAULT 0, cp24 FLOAT DEFAULT 0, cp25 FLOAT DEFAULT 0, GameID VARCHAR(64), KEY (Map, Name)) CHARACTER SET utf8mb4;", m_aPrefix, MAX_NAME_LENGTH);
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_race (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, Server CHAR(4), cp1 FLOAT DEFAULT 0, cp2 FLOAT DEFAULT 0, cp3 FLOAT DEFAULT 0, cp4 FLOAT DEFAULT 0, cp5 FLOAT DEFAULT 0, cp6 FLOAT DEFAULT 0, cp7 FLOAT DEFAULT 0, cp8 FLOAT DEFAULT 0, cp9 FLOAT DEFAULT 0, cp10 FLOAT DEFAULT 0, cp11 FLOAT DEFAULT 0, cp12 FLOAT DEFAULT 0, cp13 FLOAT DEFAULT 0, cp14 FLOAT DEFAULT 0, cp15 FLOAT DEFAULT 0, cp16 FLOAT DEFAULT 0, cp17 FLOAT DEFAULT 0, cp18 FLOAT DEFAULT 0, cp19 FLOAT DEFAULT 0, cp20 FLOAT DEFAULT 0, cp21 FLOAT DEFAULT 0, cp22 FLOAT DEFAULT 0, cp23 FLOAT DEFAULT 0, cp24 FLOAT DEFAULT 0, cp25 FLOAT DEFAULT 0, GameID VARCHAR(64), DDNet7 BOOL DEFAULT FALSE, KEY (Map, Name)) CHARACTER SET utf8mb4;", m_aPrefix, MAX_NAME_LENGTH);
executeSql(aBuf);

str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_teamrace (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, ID VARBINARY(16) NOT NULL, GameID VARCHAR(64), KEY Map (Map)) CHARACTER SET utf8mb4;", m_aPrefix, MAX_NAME_LENGTH);
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_teamrace (Map VARCHAR(128) BINARY NOT NULL, Name VARCHAR(%d) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, ID VARBINARY(16) NOT NULL, GameID VARCHAR(64), DDNet7 BOOL DEFAULT FALSE, KEY Map (Map)) CHARACTER SET utf8mb4;", m_aPrefix, MAX_NAME_LENGTH);
executeSql(aBuf);

str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_maps (Map VARCHAR(128) BINARY NOT NULL, Server VARCHAR(32) BINARY NOT NULL, Mapper VARCHAR(128) BINARY NOT NULL, Points INT DEFAULT 0, Stars INT DEFAULT 0, Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY Map (Map)) CHARACTER SET utf8mb4;", m_aPrefix);
executeSql(aBuf);

str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_saves (Savegame TEXT CHARACTER SET utf8mb4 BINARY NOT NULL, Map VARCHAR(128) BINARY NOT NULL, Code VARCHAR(128) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Server CHAR(4), UNIQUE KEY (Map, Code)) CHARACTER SET utf8mb4;", m_aPrefix);
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_saves (Savegame TEXT CHARACTER SET utf8mb4 BINARY NOT NULL, Map VARCHAR(128) BINARY NOT NULL, Code VARCHAR(128) BINARY NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Server CHAR(4), DDNet7 BOOL DEFAULT FALSE, UNIQUE KEY (Map, Code)) CHARACTER SET utf8mb4;", m_aPrefix);
executeSql(aBuf);

str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_points (Name VARCHAR(%d) BINARY NOT NULL, Points INT DEFAULT 0, UNIQUE KEY Name (Name)) CHARACTER SET utf8mb4;", m_aPrefix, MAX_NAME_LENGTH);
Expand Down
2 changes: 1 addition & 1 deletion src/engine/shared/config_variables.h
Expand Up @@ -285,7 +285,7 @@ MACRO_CONFIG_COL(ClBackgroundColor, cl_background_color, 128, CFGFLAG_CLIENT|CFG
MACRO_CONFIG_COL(ClBackgroundEntitiesColor, cl_background_entities_color, 128, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Background (entities) color") //0 0 128
MACRO_CONFIG_STR(ClBackgroundEntities, cl_background_entities, 100, "", CFGFLAG_CLIENT|CFGFLAG_SAVE, "Background (entities)")
MACRO_CONFIG_INT(ClBackgroundShowTilesLayers, cl_background_show_tiles_layers, 0, 0, 1, CFGFLAG_CLIENT|CFGFLAG_SAVE, "Whether draw tiles layers when using custom background (entities)")
MACRO_CONFIG_INT(SvShowOthers, sv_show_others, 1, 0, 1, CFGFLAG_SERVER, "Whether players can user the command showothers or not")
MACRO_CONFIG_INT(SvShowOthers, sv_show_others, 1, 0, 1, CFGFLAG_SERVER, "Whether players can use the command showothers or not")
MACRO_CONFIG_INT(SvShowOthersDefault, sv_show_others_default, 0, 0, 1, CFGFLAG_SERVER, "Whether players see others by default")
MACRO_CONFIG_INT(SvShowAllDefault, sv_show_all_default, 0, 0, 1, CFGFLAG_SERVER, "Whether players see all tees by default")
MACRO_CONFIG_INT(SvMaxAfkTime, sv_max_afk_time, 0, 0, 9999, CFGFLAG_SERVER, "The time in seconds a player is allowed to be afk (0 = disabled)")
Expand Down
2 changes: 1 addition & 1 deletion src/engine/shared/console.cpp
Expand Up @@ -46,7 +46,7 @@ ColorHSLA CConsole::CResult::GetColor(unsigned Index, bool Light)
const char *pStr = m_apArgs[Index];
if(str_isallnum(pStr) || ((pStr[0] == '-' || pStr[0] == '+') && str_isallnum(pStr+1))) // Teeworlds Color (Packed HSL)
{
hsl = ColorHSLA(str_toint(pStr), true);
hsl = ColorHSLA(str_toulong_base(pStr, 10), true);
}
else if(*pStr == '$') // Hex RGB
{
Expand Down
8 changes: 4 additions & 4 deletions src/engine/shared/datafile.cpp
Expand Up @@ -578,10 +578,10 @@ CDataFileWriter::~CDataFileWriter()
m_pDatas = 0;
}

bool CDataFileWriter::OpenFile(class IStorage *pStorage, const char *pFilename)
bool CDataFileWriter::OpenFile(class IStorage *pStorage, const char *pFilename, int StorageType)
{
dbg_assert(!m_File, "a file already exists");
m_File = pStorage->OpenFile(pFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
m_File = pStorage->OpenFile(pFilename, IOFLAG_WRITE, StorageType);
return m_File != 0;
}

Expand All @@ -602,10 +602,10 @@ void CDataFileWriter::Init()
}
}

bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename)
bool CDataFileWriter::Open(class IStorage *pStorage, const char *pFilename, int StorageType)
{
Init();
return OpenFile(pStorage, pFilename);
return OpenFile(pStorage, pFilename, StorageType);
}

int CDataFileWriter::GetExtendedItemTypeIndex(int Type)
Expand Down
6 changes: 4 additions & 2 deletions src/engine/shared/datafile.h
Expand Up @@ -3,6 +3,8 @@
#ifndef ENGINE_SHARED_DATAFILE_H
#define ENGINE_SHARED_DATAFILE_H

#include <engine/storage.h>

#include <base/system.h>
#include <base/hash.h>

Expand Down Expand Up @@ -95,8 +97,8 @@ class CDataFileWriter
CDataFileWriter();
~CDataFileWriter();
void Init();
bool OpenFile(class IStorage *pStorage, const char *pFilename);
bool Open(class IStorage *pStorage, const char *Filename);
bool OpenFile(class IStorage *pStorage, const char *pFilename, int StorageType = IStorage::TYPE_SAVE);
bool Open(class IStorage *pStorage, const char *Filename, int StorageType = IStorage::TYPE_SAVE);
int AddData(int Size, void *pData);
int AddDataSwapped(int Size, void *pData);
int AddItem(int Type, int ID, int Size, void *pData);
Expand Down
139 changes: 107 additions & 32 deletions src/engine/shared/demo.cpp
Expand Up @@ -15,8 +15,9 @@
#include "snapshot.h"

static const unsigned char gs_aHeaderMarker[7] = {'T', 'W', 'D', 'E', 'M', 'O', 0};
static const unsigned char gs_ActVersion = 5;
static const unsigned char gs_ActVersion = 6;
static const unsigned char gs_OldVersion = 3;
static const unsigned char gs_Sha256Version = 6;
static const unsigned char gs_VersionTickCompression = 5; // demo files with this version or higher will use `CHUNKTICKFLAG_TICK_COMPRESSED`
static const int gs_LengthOffset = 152;
static const int gs_NumMarkersOffset = 176;
Expand All @@ -25,6 +26,7 @@ static const int gs_NumMarkersOffset = 176;
CDemoRecorder::CDemoRecorder(class CSnapshotDelta *pSnapshotDelta, bool NoMapData)
{
m_File = 0;
m_aCurrentFilename[0] = '\0';
m_pfnFilter = 0;
m_pUser = 0;
m_LastTickMarker = -1;
Expand Down Expand Up @@ -121,6 +123,10 @@ int CDemoRecorder::Start(class IStorage *pStorage, class IConsole *pConsole, con
io_write(DemoFile, &Header, sizeof(Header));
io_write(DemoFile, &TimelineMarkers, sizeof(TimelineMarkers)); // fill this on stop

//Write Sha256
io_write(DemoFile, SHA256_EXTENSION.m_aData, sizeof(SHA256_EXTENSION.m_aData));
io_write(DemoFile, &Sha256, sizeof(SHA256_DIGEST));

if(m_NoMapData)
{
}
Expand Down Expand Up @@ -717,6 +723,24 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
else if(m_Info.m_Header.m_Version > gs_OldVersion)
io_read(m_File, &m_Info.m_TimelineMarkers, sizeof(m_Info.m_TimelineMarkers));

SHA256_DIGEST Sha256 = SHA256_ZEROED;
if(m_Info.m_Header.m_Version >= gs_Sha256Version)
{
CUuid ExtensionUuid = {};
io_read(m_File, &ExtensionUuid.m_aData, sizeof(ExtensionUuid.m_aData));

if(ExtensionUuid == SHA256_EXTENSION)
{
io_read(m_File, &Sha256, sizeof(SHA256_DIGEST)); // need a safe read
}
else
{
// This hopes whatever happened during the version increment didn't add something here
dbg_msg("demo", "demo version incremented, but not by ddnet");
io_seek(m_File, -(int)sizeof(ExtensionUuid.m_aData), IOSEEK_CUR);
}
}

// get demo type
if(!str_comp(m_Info.m_Header.m_aType, "client"))
m_DemoType = DEMOTYPE_CLIENT;
Expand All @@ -731,36 +755,17 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
// check if we already have the map
// TODO: improve map checking (maps folder, check crc)
unsigned Crc = (m_Info.m_Header.m_aMapCrc[0]<<24) | (m_Info.m_Header.m_aMapCrc[1]<<16) | (m_Info.m_Header.m_aMapCrc[2]<<8) | (m_Info.m_Header.m_aMapCrc[3]);
char aMapFilename[128];
str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x.map", m_Info.m_Header.m_aMapName, Crc);
IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_READ, IStorage::TYPE_ALL);

if(MapFile)
{
io_skip(m_File, MapSize);
io_close(MapFile);
}
else if(MapSize > 0)
{
// get map data
unsigned char *pMapData = (unsigned char *)malloc(MapSize);
io_read(m_File, pMapData, MapSize);

// save map
MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
io_write(MapFile, pMapData, MapSize);
io_close(MapFile);

// free data
free(pMapData);
}
// save byte offset of map for later use
m_MapOffset = io_tell(m_File);
io_skip(m_File, MapSize);

// store map information
m_MapInfo.m_Crc = Crc;
m_MapInfo.m_Sha256 = Sha256;
m_MapInfo.m_Size = MapSize;
str_copy(m_MapInfo.m_aName, m_Info.m_Header.m_aMapName, sizeof(m_MapInfo.m_aName));


if(m_Info.m_Header.m_Version > gs_OldVersion)
{
// get timeline markers
Expand All @@ -786,6 +791,48 @@ int CDemoPlayer::Load(class IStorage *pStorage, class IConsole *pConsole, const
return 0;
}

bool CDemoPlayer::ExtractMap(class IStorage *pStorage)
{
if(!m_MapInfo.m_Size)
return false;

long CurSeek = io_tell(m_File);

// get map data
io_seek(m_File, m_MapOffset, IOSEEK_START);
unsigned char *pMapData = (unsigned char *)malloc(m_MapInfo.m_Size);
io_read(m_File, pMapData, m_MapInfo.m_Size);
io_seek(m_File, CurSeek, IOSEEK_START);

// handle sha256
SHA256_DIGEST Sha256 = SHA256_ZEROED;
if(m_Info.m_Header.m_Version >= gs_Sha256Version)
Sha256 = m_MapInfo.m_Sha256;
else
{
Sha256 = sha256(pMapData, m_MapInfo.m_Size);
m_MapInfo.m_Sha256 = Sha256;
}

// construct name
char aSha[SHA256_MAXSTRSIZE], aMapFilename[128];
sha256_str(Sha256, aSha, sizeof(aSha));
str_format(aMapFilename, sizeof(aMapFilename), "downloadedmaps/%s_%08x_%s.map", m_Info.m_Header.m_aMapName, m_MapInfo.m_Crc, aSha);

// save map
IOHANDLE MapFile = pStorage->OpenFile(aMapFilename, IOFLAG_WRITE, IStorage::TYPE_SAVE);
if(!MapFile)
return false;

io_write(MapFile, pMapData, m_MapInfo.m_Size);
io_close(MapFile);

// free data
free(pMapData);

return true;
}

int CDemoPlayer::NextFrame()
{
DoTick();
Expand Down Expand Up @@ -953,9 +1000,9 @@ void CDemoPlayer::GetDemoName(char *pBuffer, int BufferSize) const
str_copy(pBuffer, pExtractedName, Length);
}

bool CDemoPlayer::GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader, CTimelineMarkers *pTimelineMarkers) const
bool CDemoPlayer::GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader, CTimelineMarkers *pTimelineMarkers, CMapInfo *pMapInfo) const
{
if(!pDemoHeader || !pTimelineMarkers)
if(!pDemoHeader || !pTimelineMarkers || !pMapInfo)
return false;

mem_zero(pDemoHeader, sizeof(CDemoHeader));
Expand All @@ -967,6 +1014,31 @@ bool CDemoPlayer::GetDemoInfo(class IStorage *pStorage, const char *pFilename, i

io_read(File, pDemoHeader, sizeof(CDemoHeader));
io_read(File, pTimelineMarkers, sizeof(CTimelineMarkers));

str_copy(pMapInfo->m_aName, pDemoHeader->m_aMapName, sizeof(pMapInfo->m_aName));
pMapInfo->m_Crc = (pDemoHeader->m_aMapCrc[0]<<24) | (pDemoHeader->m_aMapCrc[1]<<16) | (pDemoHeader->m_aMapCrc[2]<<8) | (pDemoHeader->m_aMapCrc[3]);

SHA256_DIGEST Sha256 = SHA256_ZEROED;
if(pDemoHeader->m_Version >= gs_Sha256Version)
{
CUuid ExtensionUuid = {};
io_read(File, &ExtensionUuid.m_aData, sizeof(ExtensionUuid.m_aData));

if(ExtensionUuid == SHA256_EXTENSION)
{
io_read(File, &Sha256, sizeof(SHA256_DIGEST)); // need a safe read
}
else
{
// This hopes whatever happened during the version increment didn't add something here
dbg_msg("demo", "demo version incremented, but not by ddnet");
io_seek(File, -(int)sizeof(ExtensionUuid.m_aData), IOSEEK_CUR);
}
}
pMapInfo->m_Sha256 = Sha256;

pMapInfo->m_Size = (pDemoHeader->m_aMapSize[0]<<24) | (pDemoHeader->m_aMapSize[1]<<16) | (pDemoHeader->m_aMapSize[2]<<8) | (pDemoHeader->m_aMapSize[3]);

io_close(File);
return !(mem_comp(pDemoHeader->m_aMarker, gs_aHeaderMarker, sizeof(gs_aHeaderMarker)) || pDemoHeader->m_Version < gs_OldVersion);
}
Expand Down Expand Up @@ -1003,18 +1075,21 @@ void CDemoEditor::Slice(const char *pDemo, const char *pDst, int StartTick, int
if (m_pDemoPlayer->Load(m_pStorage, m_pConsole, pDemo, IStorage::TYPE_ALL) == -1)
return;

const CDemoPlayer::CMapInfo *pMapInfo = m_pDemoPlayer->GetMapInfo();
SHA256_DIGEST Fake;
for(unsigned i = 0; i < sizeof(Fake.data); i++)
const CMapInfo *pMapInfo = m_pDemoPlayer->GetMapInfo();
const CDemoPlayer::CPlaybackInfo *pInfo = m_pDemoPlayer->Info();

SHA256_DIGEST Sha256 = pMapInfo->m_Sha256;
if(pInfo->m_Header.m_Version < gs_Sha256Version)
{
Fake.data[i] = 0xff;
if(m_pDemoPlayer->ExtractMap(m_pStorage))
Sha256 = pMapInfo->m_Sha256;
}
if (m_pDemoRecorder->Start(m_pStorage, m_pConsole, pDst, m_pNetVersion, pMapInfo->m_aName, Fake, pMapInfo->m_Crc, "client", pMapInfo->m_Size, NULL, NULL, pfnFilter, pUser) == -1)

if (m_pDemoRecorder->Start(m_pStorage, m_pConsole, pDst, m_pNetVersion, pMapInfo->m_aName, Sha256, pMapInfo->m_Crc, "client", pMapInfo->m_Size, NULL, NULL, pfnFilter, pUser) == -1)
return;


m_pDemoPlayer->Play();
const CDemoPlayer::CPlaybackInfo *pInfo = m_pDemoPlayer->Info();

while (m_pDemoPlayer->IsPlaying() && !m_Stop) {
m_pDemoPlayer->Update(false);
Expand Down
12 changes: 3 additions & 9 deletions src/engine/shared/demo.h
Expand Up @@ -78,14 +78,6 @@ class CDemoPlayer : public IDemoPlayer
float m_TickTime;
};

struct CMapInfo
{
char m_aName[128];
SHA256_DIGEST m_Sha256;
int m_Crc;
int m_Size;
};

private:
IListener *m_pListener;

Expand All @@ -105,6 +97,7 @@ class CDemoPlayer : public IDemoPlayer

class IConsole *m_pConsole;
IOHANDLE m_File;
long m_MapOffset;
char m_aFilename[256];
CKeyFrame *m_pKeyFrames;
CMapInfo m_MapInfo;
Expand All @@ -128,6 +121,7 @@ class CDemoPlayer : public IDemoPlayer
void SetListener(IListener *pListener);

int Load(class IStorage *pStorage, class IConsole *pConsole, const char *pFilename, int StorageType);
bool ExtractMap(class IStorage *pStorage);
int Play();
void Pause();
void Unpause();
Expand All @@ -139,7 +133,7 @@ class CDemoPlayer : public IDemoPlayer
int SetPos(int WantedTick);
const CInfo *BaseInfo() const { return &m_Info.m_Info; }
void GetDemoName(char *pBuffer, int BufferSize) const;
bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader, CTimelineMarkers *pTimelineMarkers) const;
bool GetDemoInfo(class IStorage *pStorage, const char *pFilename, int StorageType, CDemoHeader *pDemoHeader, CTimelineMarkers *pTimelineMarkers, CMapInfo *pMapInfo) const;
const char *GetDemoFileName() { return m_aFilename; };
int GetDemoType() const;

Expand Down
3 changes: 2 additions & 1 deletion src/engine/textrender.h
Expand Up @@ -5,6 +5,7 @@
#include "kernel.h"

#include <base/color.h>
#include <engine/graphics.h>

enum
{
Expand Down Expand Up @@ -98,7 +99,7 @@ class ITextRender : public IInterface
virtual void RenderTextContainer(int TextContainerIndex, STextRenderColor *pTextColor, STextRenderColor *pTextOutlineColor) = 0;
virtual void RenderTextContainer(int TextContainerIndex, STextRenderColor *pTextColor, STextRenderColor *pTextOutlineColor, float X, float Y) = 0;

virtual void UploadEntityLayerText(int TextureID, const char *pText, int Length, float x, float y, int FontHeight) = 0;
virtual void UploadEntityLayerText(IGraphics::CTextureHandle Texture, const char *pText, int Length, float x, float y, int FontHeight) = 0;
virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize = -1) = 0;
virtual int CalculateTextWidth(const char *pText, int TextLength, int FontWidth, int FontHeight) = 0;

Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/chat.cpp
Expand Up @@ -810,7 +810,7 @@ void CChat::OnPrepareLines()
if(g_Config.m_ClMessageFriend)
{
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageFriendColor));
TextRender()->TextColor(rgb.SetAlpha(m_aLines[r].m_Friend ? 1.f : 0.f)); //Less ugly hack to align messages
TextRender()->TextColor(rgb.WithAlpha(m_aLines[r].m_Friend ? 1.f : 0.f)); //Less ugly hack to align messages
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, "♥ ");
}

Expand Down
6 changes: 3 additions & 3 deletions src/game/client/components/console.cpp
Expand Up @@ -405,7 +405,7 @@ void CGameConsole::PossibleCommandsRenderCallback(const char *pStr, void *pUser)
if(pInfo->m_EnumCount == pInfo->m_WantedCompletion)
{
float tw = pInfo->m_pSelf->TextRender()->TextWidth(pInfo->m_Cursor.m_pFont, pInfo->m_Cursor.m_FontSize, pStr, -1);
pInfo->m_pSelf->Graphics()->TextureSet(-1);
pInfo->m_pSelf->Graphics()->TextureClear();
pInfo->m_pSelf->Graphics()->QuadsBegin();
pInfo->m_pSelf->Graphics()->SetColor(229.0f/255.0f,185.0f/255.0f,4.0f/255.0f,0.85f);
pInfo->m_pSelf->RenderTools()->DrawRoundRect(pInfo->m_Cursor.m_X - 2.5f, pInfo->m_Cursor.m_Y - 4.f / 2.f, tw + 5.f, pInfo->m_Cursor.m_FontSize + 4.f, pInfo->m_Cursor.m_FontSize / 3.f);
Expand Down Expand Up @@ -485,7 +485,7 @@ void CGameConsole::OnRender()
Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h);

// do console shadow
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
IGraphics::CColorVertex Array[4] = {
IGraphics::CColorVertex(0, 0,0,0, 0.5f),
Expand All @@ -509,7 +509,7 @@ void CGameConsole::OnRender()
Graphics()->QuadsEnd();

// do small bar shadow
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Array[0] = IGraphics::CColorVertex(0, 0,0,0, 0.0f);
Array[1] = IGraphics::CColorVertex(1, 0,0,0, 0.0f);
Expand Down
4 changes: 2 additions & 2 deletions src/game/client/components/controls.cpp
Expand Up @@ -178,7 +178,7 @@ void CControls::OnConsoleInit()
{ static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[1].m_WantedWeapon, 2}; Console()->Register("+weapon2", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to gun"); }
{ static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[1].m_WantedWeapon, 3}; Console()->Register("+weapon3", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to shotgun"); }
{ static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[1].m_WantedWeapon, 4}; Console()->Register("+weapon4", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to grenade"); }
{ static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[1].m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to rifle"); }
{ static CInputSet s_Set = {this, &m_InputData[0].m_WantedWeapon, &m_InputData[1].m_WantedWeapon, 5}; Console()->Register("+weapon5", "", CFGFLAG_CLIENT, ConKeyInputSet, (void *)&s_Set, "Switch to laser"); }

{ static CInputSet s_Set = {this, &m_InputData[0].m_NextWeapon, &m_InputData[1].m_NextWeapon, 0}; Console()->Register("+nextweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to next weapon"); }
{ static CInputSet s_Set = {this, &m_InputData[0].m_PrevWeapon, &m_InputData[1].m_PrevWeapon, 0}; Console()->Register("+prevweapon", "", CFGFLAG_CLIENT, ConKeyInputNextPrevWeapon, (void *)&s_Set, "Switch to previous weapon"); }
Expand Down Expand Up @@ -457,7 +457,7 @@ void CControls::OnRender()
m_pClient->m_Snap.m_pLocalCharacter->m_Weapon != WEAPON_NINJA )
{
int w;
for( w = WEAPON_RIFLE; w > WEAPON_GUN; w-- )
for( w = WEAPON_LASER; w > WEAPON_GUN; w-- )
{
if( w == m_pClient->m_Snap.m_pLocalCharacter->m_Weapon )
continue;
Expand Down
4 changes: 1 addition & 3 deletions src/game/client/components/countryflags.cpp
Expand Up @@ -80,8 +80,7 @@ void CCountryFlags::LoadCountryflagsIndexfile()
CountryFlag.m_Texture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
free(Info.m_pData);
}
else
CountryFlag.m_Texture = -1;

if(g_Config.m_Debug)
{
str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", aOrigin);
Expand Down Expand Up @@ -121,7 +120,6 @@ void CCountryFlags::OnInit()
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "countryflags", "failed to load country flags. folder='countryflags/'");
CCountryFlag DummyEntry;
DummyEntry.m_CountryCode = -1;
DummyEntry.m_Texture = -1;
mem_zero(DummyEntry.m_aCountryCodeString, sizeof(DummyEntry.m_aCountryCodeString));
m_aCountryFlags.add(DummyEntry);
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/countryflags.h
Expand Up @@ -13,7 +13,7 @@ class CCountryFlags : public CComponent
{
int m_CountryCode;
char m_aCountryCodeString[8];
int m_Texture;
IGraphics::CTextureHandle m_Texture;

bool operator<(const CCountryFlag &Other) { return str_comp(m_aCountryCodeString, Other.m_aCountryCodeString) < 0; }
};
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/debughud.cpp
Expand Up @@ -119,7 +119,7 @@ void CDebugHud::RenderTuning()

y = y+Count*6;

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->BlendNormal();
Graphics()->LinesBegin();
float Height = 50.0f;
Expand Down
6 changes: 3 additions & 3 deletions src/game/client/components/emoticon.cpp
Expand Up @@ -107,7 +107,7 @@ void CEmoticon::OnRender()

Graphics()->BlendNormal();

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.3f);
DrawCircle(Screen.w/2, Screen.h/2, 190.0f, 64);
Expand Down Expand Up @@ -137,7 +137,7 @@ void CEmoticon::OnRender()

if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0,1.0,1.0,0.3f);
DrawCircle(Screen.w/2, Screen.h/2, 100.0f, 64);
Expand All @@ -163,7 +163,7 @@ void CEmoticon::OnRender()
pTeeInfo->m_Size = 64.0f;
}

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.3f);
DrawCircle(Screen.w/2, Screen.h/2, 30.0f, 64);
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/flow.cpp
Expand Up @@ -20,7 +20,7 @@ void CFlow::DbgRender()

IGraphics::CLineItem Array[1024];
int NumItems = 0;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->LinesBegin();
for(int y = 0; y < m_Height; y++)
for(int x = 0; x < m_Width; x++)
Expand Down
10 changes: 5 additions & 5 deletions src/game/client/components/hud.cpp
Expand Up @@ -225,7 +225,7 @@ void CHud::RenderScoreHud()
Graphics()->SetColor(0.0f, 0.0f, 1.0f, 0.25f);
m_aScoreInfo[t].m_RoundRectQuadContainerIndex = RenderTools()->CreateRoundRectQuadContainer(Whole - ScoreWidthMax - ImageSize - 2 * Split, StartY + t * 20, ScoreWidthMax + ImageSize + 2 * Split, 18.0f, 5.0f, CUI::CORNER_L);
}
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
if(m_aScoreInfo[t].m_RoundRectQuadContainerIndex != -1)
Graphics()->RenderQuadContainer(m_aScoreInfo[t].m_RoundRectQuadContainerIndex, -1);
Expand Down Expand Up @@ -399,7 +399,7 @@ void CHud::RenderScoreHud()
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.25f);
m_aScoreInfo[t].m_RoundRectQuadContainerIndex = RenderTools()->CreateRoundRectQuadContainer(Whole - ScoreWidthMax - ImageSize - 2 * Split - PosSize, StartY + t * 20, ScoreWidthMax + ImageSize + 2 * Split + PosSize, 18.0f, 5.0f, CUI::CORNER_L);
}
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
if(m_aScoreInfo[t].m_RoundRectQuadContainerIndex != -1)
Graphics()->RenderQuadContainer(m_aScoreInfo[t].m_RoundRectQuadContainerIndex, -1);
Expand Down Expand Up @@ -603,7 +603,7 @@ void CHud::RenderVoting()
if((!g_Config.m_ClShowVotesAfterVoting && !m_pClient->m_pScoreboard->Active() && m_pClient->m_pVoting->TakenChoice()) || !m_pClient->m_pVoting->IsVoting() || Client()->State() == IClient::STATE_DEMOPLAYBACK)
return;

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.40f);

Expand Down Expand Up @@ -729,7 +729,7 @@ void CHud::RenderHealthAndAmmo(const CNetObj_Character *pCharacter)
void CHud::RenderSpectatorHud()
{
// draw the box
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.4f);
RenderTools()->DrawRoundRectExt(m_Width-180.0f, m_Height-15.0f, 180.0f, 15.0f, 5.0f, CUI::CORNER_TL);
Expand All @@ -749,7 +749,7 @@ void CHud::RenderLocalTime(float x)

//draw the box
Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.4f);
RenderTools()->DrawRoundRectExt(x-30.0f, 0.0f, 25.0f, 12.5f, 3.75f, CUI::CORNER_B);
Expand Down
3 changes: 1 addition & 2 deletions src/game/client/components/items.cpp
Expand Up @@ -15,7 +15,6 @@
#include <game/client/components/effects.h>

#include "items.h"
#include <stdio.h>

void CItems::OnReset()
{
Expand Down Expand Up @@ -231,7 +230,7 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)

vec2 Out, Border;

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();

// do outline
Expand Down
44 changes: 18 additions & 26 deletions src/game/client/components/mapimages.cpp
Expand Up @@ -17,11 +17,8 @@ CMapImages::CMapImages() : CMapImages(100)
CMapImages::CMapImages(int TextureSize)
{
m_Count = 0;
m_EntitiesTextures = -1;
m_OverlayBottomTexture = -1;
m_OverlayTopTexture = -1;
m_OverlayCenterTexture = -1;
m_TextureScale = TextureSize;
m_EntitiesIsLoaded = false;
}

void CMapImages::OnInit()
Expand All @@ -37,7 +34,7 @@ void CMapImages::OnMapLoad()
for(int i = 0; i < m_Count; i++)
{
Graphics()->UnloadTexture(m_aTextures[i]);
m_aTextures[i] = -1;
m_aTextures[i] = IGraphics::CTextureHandle();
}
m_Count = 0;

Expand All @@ -47,8 +44,6 @@ void CMapImages::OnMapLoad()
// load new textures
for(int i = 0; i < m_Count; i++)
{
m_aTextures[i] = 0;

CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0);
if(pImg->m_External)
{
Expand All @@ -72,7 +67,7 @@ void CMapImages::LoadBackground(class IMap *pMap)
for(int i = 0; i < m_Count; i++)
{
Graphics()->UnloadTexture(m_aTextures[i]);
m_aTextures[i] = -1;
m_aTextures[i] = IGraphics::CTextureHandle();
}
m_Count = 0;

Expand All @@ -82,8 +77,6 @@ void CMapImages::LoadBackground(class IMap *pMap)
// load new textures
for(int i = 0; i < m_Count; i++)
{
m_aTextures[i] = 0;

CMapItemImage *pImg = (CMapItemImage *)pMap->GetItem(Start+i, 0, 0);
if(pImg->m_External)
{
Expand All @@ -101,7 +94,7 @@ void CMapImages::LoadBackground(class IMap *pMap)
}
}

int CMapImages::GetEntities()
IGraphics::CTextureHandle CMapImages::GetEntities()
{
// DDNet default to prevent delay in seeing entities
const char *pEntities = "ddnet";
Expand All @@ -116,31 +109,31 @@ int CMapImages::GetEntities()
else if(GameClient()->m_GameInfo.m_EntitiesVanilla)
pEntities = "vanilla";

if(m_EntitiesTextures == -1 || m_pEntitiesGameType != pEntities)
if(!m_EntitiesIsLoaded || m_pEntitiesGameType != pEntities)
{
char aPath[64];
str_format(aPath, sizeof(aPath), "editor/entities_clear/%s.png", pEntities);

if(m_EntitiesTextures >= 0)
Graphics()->UnloadTexture(m_EntitiesTextures);
m_EntitiesTextures = Graphics()->LoadTexture(aPath, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);

m_EntitiesIsLoaded = true;
m_pEntitiesGameType = pEntities;
}
return m_EntitiesTextures;
}

int CMapImages::GetOverlayBottom()
IGraphics::CTextureHandle CMapImages::GetOverlayBottom()
{
return m_OverlayBottomTexture;
}

int CMapImages::GetOverlayTop()
IGraphics::CTextureHandle CMapImages::GetOverlayTop()
{
return m_OverlayTopTexture;
}

int CMapImages::GetOverlayCenter()
IGraphics::CTextureHandle CMapImages::GetOverlayCenter()
{
return m_OverlayCenterTexture;
}
Expand All @@ -158,7 +151,6 @@ void CMapImages::SetTextureScale(int Scale)
Graphics()->UnloadTexture(m_OverlayBottomTexture);
Graphics()->UnloadTexture(m_OverlayTopTexture);
Graphics()->UnloadTexture(m_OverlayCenterTexture);
m_OverlayBottomTexture = m_OverlayTopTexture = m_OverlayCenterTexture = -1;

InitOverlayTextures();
}
Expand All @@ -169,20 +161,20 @@ int CMapImages::GetTextureScale()
return m_TextureScale;
}

int CMapImages::UploadEntityLayerText(int TextureSize, int YOffset)
IGraphics::CTextureHandle CMapImages::UploadEntityLayerText(int TextureSize, int YOffset)
{
void *pMem = calloc(1024 * 1024, 1);
int TextureID = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_ALPHA, pMem, CImageInfo::FORMAT_ALPHA, IGraphics::TEXLOAD_NOMIPMAPS);
IGraphics::CTextureHandle Texture = Graphics()->LoadTextureRaw(1024, 1024, CImageInfo::FORMAT_ALPHA, pMem, CImageInfo::FORMAT_ALPHA, IGraphics::TEXLOAD_NOMIPMAPS);
free(pMem);

UpdateEntityLayerText(TextureID, TextureSize, YOffset, 0);
UpdateEntityLayerText(TextureID, TextureSize, YOffset, 1);
UpdateEntityLayerText(TextureID, TextureSize, YOffset, 2, 255);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 0);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 1);
UpdateEntityLayerText(Texture, TextureSize, YOffset, 2, 255);

return TextureID;
return Texture;
}

void CMapImages::UpdateEntityLayerText(int TextureID, int TextureSize, int YOffset, int NumbersPower, int MaxNumber)
void CMapImages::UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int TextureSize, int YOffset, int NumbersPower, int MaxNumber)
{
char aBuf[4];
int DigitsCount = NumbersPower+1;
Expand All @@ -199,7 +191,7 @@ void CMapImages::UpdateEntityLayerText(int TextureID, int TextureSize, int YOffs

if (UniversalSuitableFontSize < 1)
{
dbg_msg("pFont", "texture with id '%d' will not be loaded. Reason - font is too small", TextureID);
dbg_msg("pFont", "texture with id '%d' will not be loaded. Reason - font is too small", (int)Texture);
}

int ApproximateTextWidth = TextRender()->CalculateTextWidth(aBuf, DigitsCount, 0, UniversalSuitableFontSize);
Expand All @@ -213,7 +205,7 @@ void CMapImages::UpdateEntityLayerText(int TextureID, int TextureSize, int YOffs
float x = (CurrentNumber%16)*64;
float y = (CurrentNumber/16)*64;

TextRender()->UploadEntityLayerText(TextureID, aBuf, DigitsCount, x+XOffSet, y+YOffset, UniversalSuitableFontSize);
TextRender()->UploadEntityLayerText(Texture, aBuf, DigitsCount, x+XOffSet, y+YOffset, UniversalSuitableFontSize);
}
}

Expand Down
25 changes: 13 additions & 12 deletions src/game/client/components/mapimages.h
Expand Up @@ -8,42 +8,43 @@ class CMapImages : public CComponent
{
friend class CBackground;

int m_aTextures[64];
IGraphics::CTextureHandle m_aTextures[64];
int m_Count;

const char *m_pEntitiesGameType;
public:
CMapImages();
CMapImages(int ImageSize);

int Get(int Index) const { return m_aTextures[Index]; }
IGraphics::CTextureHandle Get(int Index) const { return m_aTextures[Index]; }
int Num() const { return m_Count; }

virtual void OnMapLoad();
virtual void OnInit();
void LoadBackground(class IMap *pMap);

// DDRace
int GetEntities();
IGraphics::CTextureHandle GetEntities();

int GetOverlayBottom();
int GetOverlayTop();
int GetOverlayCenter();
IGraphics::CTextureHandle GetOverlayBottom();
IGraphics::CTextureHandle GetOverlayTop();
IGraphics::CTextureHandle GetOverlayCenter();

void SetTextureScale(int Size);
int GetTextureScale();

private:

int m_EntitiesTextures;
int m_OverlayBottomTexture;
int m_OverlayTopTexture;
int m_OverlayCenterTexture;
bool m_EntitiesIsLoaded;
IGraphics::CTextureHandle m_EntitiesTextures;
IGraphics::CTextureHandle m_OverlayBottomTexture;
IGraphics::CTextureHandle m_OverlayTopTexture;
IGraphics::CTextureHandle m_OverlayCenterTexture;
int m_TextureScale;

void InitOverlayTextures();
int UploadEntityLayerText(int TextureSize, int YOffset);
void UpdateEntityLayerText(int TextureID, int TextureSize, int YOffset, int NumbersPower, int MaxNumber = -1);
IGraphics::CTextureHandle UploadEntityLayerText(int TextureSize, int YOffset);
void UpdateEntityLayerText(IGraphics::CTextureHandle Texture, int TextureSize, int YOffset, int NumbersPower, int MaxNumber = -1);
};

#endif
4 changes: 2 additions & 2 deletions src/game/client/components/maplayers.cpp
Expand Up @@ -1721,7 +1721,7 @@ void CMapLayers::OnRender()
if(pTMap->m_Image == -1)
{
if(!IsGameLayer)
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
else
Graphics()->TextureSet(m_pImages->GetEntities());
}
Expand Down Expand Up @@ -1782,7 +1782,7 @@ void CMapLayers::OnRender()
{
CMapItemLayerQuads *pQLayer = (CMapItemLayerQuads *)pLayer;
if(pQLayer->m_Image == -1)
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
else
Graphics()->TextureSet(m_pImages->Get(pQLayer->m_Image));

Expand Down
22 changes: 9 additions & 13 deletions src/game/client/components/menus.cpp
Expand Up @@ -864,7 +864,7 @@ void CMenus::RenderLoading()

Graphics()->BlendNormal();

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.50f);
RenderTools()->DrawRoundRect(x, y, w, h, 40.0f);
Expand All @@ -880,7 +880,7 @@ void CMenus::RenderLoading()
r.h = h - 130;
UI()->DoLabel(&r, pCaption, 48.0f, 0, -1);

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1,1,1,0.75f);
RenderTools()->DrawRoundRect(x+40, y+h-75, (w-80)*Percent, 25, 5.0f);
Expand Down Expand Up @@ -927,6 +927,8 @@ void CMenus::OnInit()
Console()->Chain("add_friend", ConchainFriendlistUpdate, this);
Console()->Chain("remove_friend", ConchainFriendlistUpdate, this);

m_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);

// setup load amount
m_LoadCurrent = 0;
m_LoadTotal = g_pData->m_NumImages;
Expand Down Expand Up @@ -1835,20 +1837,14 @@ void CMenus::OnRender()
m_NumInputEvents = 0;
}

static int gs_TextureBlob = -1;

void CMenus::RenderBackground()
{
if(gs_TextureBlob == -1)
gs_TextureBlob = Graphics()->LoadTexture("blob.png", IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);


float sw = 300*Graphics()->ScreenAspect();
float sh = 300;
Graphics()->MapScreen(0, 0, sw, sh);

// render background color
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
ColorRGBA Bottom(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
ColorRGBA Top(ms_GuiColor.r, ms_GuiColor.g, ms_GuiColor.b, 1.0f);
Expand All @@ -1863,7 +1859,7 @@ void CMenus::RenderBackground()
Graphics()->QuadsEnd();

// render the tiles
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
float Size = 15.0f;
float OffsetTime = fmod(Client()->LocalTime()*0.15f, 2.0f);
Expand All @@ -1877,7 +1873,7 @@ void CMenus::RenderBackground()
Graphics()->QuadsEnd();

// render border fade
Graphics()->TextureSet(gs_TextureBlob);
Graphics()->TextureSet(m_TextureBlob);
Graphics()->QuadsBegin();
Graphics()->SetColor(1,1,1,1);
QuadItem = IGraphics::CQuadItem(-100, -100, sw+200, sh+200);
Expand Down Expand Up @@ -1927,7 +1923,7 @@ void CMenus::RenderUpdating(const char *pCaption, int current, int total)
float x = Screen.w/2-w/2;
float y = Screen.h/2-h/2;

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.50f);
RenderTools()->DrawRoundRect(0, y, Screen.w, h, 0.0f);
Expand All @@ -1943,7 +1939,7 @@ void CMenus::RenderUpdating(const char *pCaption, int current, int total)
if(total>0)
{
float Percent = current/(float)total;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.15f,0.15f,0.15f,0.75f);
RenderTools()->DrawRoundRect(x+40, y+h-75, w-80, 30, 5.0f);
Expand Down
15 changes: 14 additions & 1 deletion src/game/client/components/menus.h
Expand Up @@ -174,6 +174,7 @@ class CMenus : public CComponent
bool m_Valid;
CDemoHeader m_Info;
CTimelineMarkers m_TimelineMarkers;
CMapInfo m_MapInfo;

int NumMarkers() const
{
Expand Down Expand Up @@ -306,6 +307,8 @@ class CMenus : public CComponent
void RenderSettings(CUIRect MainView);

void SetActive(bool Active);

IGraphics::CTextureHandle m_TextureBlob;
public:
void RenderBackground();

Expand Down Expand Up @@ -344,7 +347,17 @@ class CMenus : public CComponent
PAGE_SETTINGS,
PAGE_SYSTEM,
PAGE_NETWORK,
PAGE_GHOST
PAGE_GHOST,

SETTINGS_LANGUAGE=0,
SETTINGS_GENERAL,
SETTINGS_PLAYER,
SETTINGS_TEE,
SETTINGS_HUD,
SETTINGS_CONTROLS,
SETTINGS_GRAPHICS,
SETTINGS_SOUND,
SETTINGS_DDNET,
};

// DDRace
Expand Down
25 changes: 18 additions & 7 deletions src/game/client/components/menus_demo.cpp
Expand Up @@ -4,6 +4,7 @@
#include <base/tl/string.h>

#include <base/math.h>
#include <base/hash.h>

#include <engine/demo.h>
#include <engine/keys.h>
Expand Down Expand Up @@ -283,7 +284,7 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
for(int i = 0; i < pInfo->m_NumTimelineMarkers; i++)
{
float Ratio = (pInfo->m_aTimelineMarkers[i]-pInfo->m_FirstTick) / (float)TotalTicks;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
IGraphics::CQuadItem QuadItem(SeekBar.x + (SeekBar.w-10.0f)*Ratio, SeekBar.y, UI()->PixelSize(), SeekBar.h);
Expand All @@ -296,7 +297,7 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
if(g_Config.m_ClDemoSliceBegin != -1)
{
float Ratio = (g_Config.m_ClDemoSliceBegin-pInfo->m_FirstTick) / (float)TotalTicks;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 0.0f, 0.0f, 1.0f);
IGraphics::CQuadItem QuadItem(10.0f + SeekBar.x + (SeekBar.w-10.0f)*Ratio, SeekBar.y, UI()->PixelSize(), SeekBar.h);
Expand All @@ -308,7 +309,7 @@ void CMenus::RenderDemoPlayer(CUIRect MainView)
if(g_Config.m_ClDemoSliceEnd != -1)
{
float Ratio = (g_Config.m_ClDemoSliceEnd-pInfo->m_FirstTick) / (float)TotalTicks;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 0.0f, 0.0f, 1.0f);
IGraphics::CQuadItem QuadItem(10.0f + SeekBar.x + (SeekBar.w-10.0f)*Ratio, SeekBar.y, UI()->PixelSize(), SeekBar.h);
Expand Down Expand Up @@ -805,7 +806,7 @@ bool CMenus::FetchHeader(CDemoItem &Item)
{
char aBuffer[512];
str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aCurrentDemoFolder, Item.m_aFilename);
Item.m_Valid = DemoPlayer()->GetDemoInfo(Storage(), aBuffer, Item.m_StorageType, &Item.m_Info, &Item.m_TimelineMarkers);
Item.m_Valid = DemoPlayer()->GetDemoInfo(Storage(), aBuffer, Item.m_StorageType, &Item.m_Info, &Item.m_TimelineMarkers, &Item.m_MapInfo);
Item.m_InfosLoaded = true;
}
return Item.m_Valid;
Expand Down Expand Up @@ -930,12 +931,22 @@ void CMenus::RenderDemoList(CUIRect MainView)
Labels.HSplitTop(20.0f, &Left, &Labels);
Left.VSplitLeft(150.0f, &Left, &Right);
UI()->DoLabelScaled(&Left, Localize("Crc:"), 14.0f, -1);
unsigned Crc = (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[0]<<24) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[1]<<16) |
(m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[2]<<8) | (m_lDemos[m_DemolistSelectedIndex].m_Info.m_aMapCrc[3]);
str_format(aBuf, sizeof(aBuf), "%08x", Crc);
str_format(aBuf, sizeof(aBuf), "%08x", m_lDemos[m_DemolistSelectedIndex].m_MapInfo.m_Crc);
UI()->DoLabelScaled(&Right, aBuf, 14.0f, -1);
Labels.HSplitTop(5.0f, 0, &Labels);
Labels.HSplitTop(20.0f, &Left, &Labels);

if(m_lDemos[m_DemolistSelectedIndex].m_MapInfo.m_Sha256 != SHA256_ZEROED)
{
Left.VSplitLeft(150.0f, &Left, &Right);
UI()->DoLabelScaled(&Left, Localize("SHA256:"), 14.0f, -1);
char aSha[SHA256_MAXSTRSIZE];
sha256_str(m_lDemos[m_DemolistSelectedIndex].m_MapInfo.m_Sha256, aSha, sizeof(aSha)/2);
UI()->DoLabelScaled(&Right, aSha, 14.0f, -1);
Labels.HSplitTop(5.0f, 0, &Labels);
Labels.HSplitTop(20.0f, &Left, &Labels);
}

Left.VSplitLeft(150.0f, &Left, &Right);
UI()->DoLabelScaled(&Left, Localize("Netversion:"), 14.0f, -1);
UI()->DoLabelScaled(&Right, m_lDemos[m_DemolistSelectedIndex].m_Info.m_aNetversion, 14.0f, -1);
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/menus_ingame.cpp
Expand Up @@ -1053,7 +1053,7 @@ void CMenus::RenderGhost(CUIRect MainView)
if(pItem->m_Own)
rgb = color_cast<ColorRGBA>(ColorHSLA(0.33f, 1.0f, 0.75f));

TextRender()->TextColor(rgb.SetAlpha(pItem->HasFile() ? 1.0f : 0.5f));
TextRender()->TextColor(rgb.WithAlpha(pItem->HasFile() ? 1.0f : 0.5f));

for(int c = 0; c < NumCols; c++)
{
Expand Down
48 changes: 26 additions & 22 deletions src/game/client/components/menus_settings.cpp
Expand Up @@ -615,7 +615,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(g_Config.m_Debug)
{
ColorRGBA BloodColor = *UseCustomColor ? color_cast<ColorRGBA>(ColorHSLA(*ColorBody)) : s->m_BloodColor;
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(BloodColor.r, BloodColor.g, BloodColor.b, 1.0f);
IGraphics::CQuadItem QuadItem(Item.m_Rect.x, Item.m_Rect.y, 12.0f, 12.0f);
Expand Down Expand Up @@ -695,7 +695,7 @@ static CKeyInfo gs_aKeys[] =
{ "Pistol", "+weapon2", 0, 0 },
{ "Shotgun", "+weapon3", 0, 0 },
{ "Grenade", "+weapon4", 0, 0 },
{ "Rifle", "+weapon5", 0, 0 },
{ "Laser", "+weapon5", 0, 0 },
{ "Next weapon", "+nextweapon", 0, 0 },
{ "Prev. weapon", "+prevweapon", 0, 0 },

Expand All @@ -721,11 +721,17 @@ static CKeyInfo gs_aKeys[] =
{ "Show HUD", "toggle cl_showhud 0 1", 0, 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("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");
/* This is for scripts/languages to work, don't remove!
Localize("Move left");Localize("Move right");Localize("Jump");Localize("Fire");Localize("Hook");
Localize("Hook collisions");Localize("Pause");Localize("Kill");Localize("Zoom in");Localize("Zoom out");
Localize("Default zoom");Localize("Show others");Localize("Show all");Localize("Toggle dyncam");
Localize("Toggle dummy");Localize("Toggle ghost");Localize("Dummy copy");Localize("Hammerfly dummy");
Localize("Hammer");Localize("Pistol");Localize("Shotgun");Localize("Grenade");Localize("Laser");
Localize("Next weapon");Localize("Prev. weapon");Localize("Vote yes");Localize("Vote no");
Localize("Chat");Localize("Team chat");Localize("Converse");Localize("Show chat");Localize("Emoticon");
Localize("Spectator mode");Localize("Spectate next");Localize("Spectate previous");Localize("Console");
Localize("Remote console");Localize("Screenshot");Localize("Scoreboard");Localize("Statboard");
Localize("Lock team");Localize("Show entities");Localize("Show HUD");
*/

const int g_KeyCount = sizeof(gs_aKeys) / sizeof(CKeyInfo);
Expand Down Expand Up @@ -1364,8 +1370,6 @@ void CMenus::RenderLanguageSelection(CUIRect MainView)

void CMenus::RenderSettings(CUIRect MainView)
{
static int s_SettingsPage = 0;

// render background
CUIRect Temp, TabBar, RestartWarning;
MainView.VSplitRight(120.0f, &MainView, &TabBar);
Expand Down Expand Up @@ -1397,29 +1401,29 @@ void CMenus::RenderSettings(CUIRect MainView)
{
TabBar.HSplitTop(10, &Button, &TabBar);
TabBar.HSplitTop(26, &Button, &TabBar);
if(DoButton_MenuTab(aTabs[i], aTabs[i], s_SettingsPage == i, &Button, CUI::CORNER_R))
s_SettingsPage = i;
if(DoButton_MenuTab(aTabs[i], aTabs[i], g_Config.m_UiSettingsPage == i, &Button, CUI::CORNER_R))
g_Config.m_UiSettingsPage = i;
}

MainView.Margin(10.0f, &MainView);

if(s_SettingsPage == 0)
if(g_Config.m_UiSettingsPage == SETTINGS_LANGUAGE)
RenderLanguageSelection(MainView);
else if(s_SettingsPage == 1)
else if(g_Config.m_UiSettingsPage == SETTINGS_GENERAL)
RenderSettingsGeneral(MainView);
else if(s_SettingsPage == 2)
else if(g_Config.m_UiSettingsPage == SETTINGS_PLAYER)
RenderSettingsPlayer(MainView);
else if(s_SettingsPage == 3)
else if(g_Config.m_UiSettingsPage == SETTINGS_TEE)
RenderSettingsTee(MainView);
else if(s_SettingsPage == 4)
else if(g_Config.m_UiSettingsPage == SETTINGS_HUD)
RenderSettingsHUD(MainView);
else if(s_SettingsPage == 5)
else if(g_Config.m_UiSettingsPage == SETTINGS_CONTROLS)
RenderSettingsControls(MainView);
else if(s_SettingsPage == 6)
else if(g_Config.m_UiSettingsPage == SETTINGS_GRAPHICS)
RenderSettingsGraphics(MainView);
else if(s_SettingsPage == 7)
else if(g_Config.m_UiSettingsPage == SETTINGS_SOUND)
RenderSettingsSound(MainView);
else if(s_SettingsPage == 8)
else if(g_Config.m_UiSettingsPage == SETTINGS_DDNET)
RenderSettingsDDNet(MainView);

if(m_NeedRestartUpdate)
Expand Down Expand Up @@ -1908,7 +1912,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
vec2 Out, Border;

Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();

// do outline
Expand Down Expand Up @@ -1960,7 +1964,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();

RenderTools()->SelectSprite(SPRITE_WEAPON_RIFLE_BODY);
RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY);
RenderTools()->DrawSprite(Weapon.x, Weapon.y + Weapon.h / 2.0f, 60.0f);

Graphics()->QuadsEnd();
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/components/motd.cpp
Expand Up @@ -43,7 +43,7 @@ void CMotd::OnRender()
float y = 150.0f;

Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.5f);
RenderTools()->DrawRoundRect(x, y, w, h, 40.0f);
Expand Down
25 changes: 16 additions & 9 deletions src/game/client/components/players.cpp
Expand Up @@ -26,7 +26,6 @@
#include <engine/textrender.h>

#include "players.h"
#include <stdio.h>

void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float AngleOffset, vec2 PostRotOffset, float Alpha)
{
Expand Down Expand Up @@ -287,12 +286,12 @@ void CPlayers::RenderPlayer(
if(Local && Client()->State() != IClient::STATE_DEMOPLAYBACK)
ExDirection = normalize(vec2(m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetX, m_pClient->m_pControls->m_InputData[g_Config.m_ClDummy].m_TargetY));

Graphics()->TextureSet(-1);
Graphics()->TextureClear();
vec2 InitPos = Position;
vec2 FinishPos = InitPos + ExDirection * (m_pClient->m_Tuning[g_Config.m_ClDummy].m_HookLength-42.0f);

Graphics()->LinesBegin();
Graphics()->SetColor(1.00f, 0.0f, 0.0f, Alpha);
ColorRGBA HookCollColor(1.0f, 0.0f, 0.0f);

float PhysSize = 28.0f;

Expand All @@ -318,12 +317,14 @@ void CPlayers::RenderPlayer(
if(!DoBreak && Hit)
{
if(Hit != TILE_NOHOOK)
Graphics()->SetColor(130.0f/255.0f, 232.0f/255.0f, 160.0f/255.0f, Alpha);
{
HookCollColor = ColorRGBA(130.0f/255.0f, 232.0f/255.0f, 160.0f/255.0f);
}
}

if(m_pClient->IntersectCharacter(OldPos, FinishPos, FinishPos, ClientID) != -1)
{
Graphics()->SetColor(1.0f, 1.0f, 0.0f, Alpha);
HookCollColor = ColorRGBA(1.0f, 1.0f, 0.0f);
break;
}

Expand All @@ -340,6 +341,12 @@ void CPlayers::RenderPlayer(
ExDirection.y = round_to_int(ExDirection.y*256.0f) / 256.0f;
} while (!DoBreak);

if(g_Config.m_ClShowHookCollAlways && (Player.m_PlayerFlags&PLAYERFLAG_AIM))
{
// invert the hook coll colors when using cl_show_hook_coll_always and +showhookcoll is pressed
HookCollColor = color_invert(HookCollColor);
}
Graphics()->SetColor(HookCollColor.WithAlpha(Alpha));
IGraphics::CLineItem LineItem(InitPos.x, InitPos.y, FinishPos.x, FinishPos.y);
Graphics()->LinesDraw(&LineItem, 1);
Graphics()->LinesEnd();
Expand Down Expand Up @@ -561,7 +568,10 @@ void CPlayers::RenderPlayer(
Graphics()->QuadsSetRotation(0);
}

if(g_Config.m_ClAfkEmote && m_pClient->m_aClients[ClientID].m_Afk && !(Player.m_PlayerFlags&PLAYERFLAG_CHATTING) && !(m_pClient->Client()->DummyConnected() && ClientID == m_pClient->m_LocalIDs[!g_Config.m_ClDummy]))
if(ClientID < 0)
return;

if(g_Config.m_ClAfkEmote && m_pClient->m_aClients[ClientID].m_Afk && !(Player.m_PlayerFlags&PLAYERFLAG_CHATTING) && !(Client()->DummyConnected() && ClientID == m_pClient->m_LocalIDs[!g_Config.m_ClDummy]))
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
int QuadOffset = QuadOffsetToEmoticon + (SPRITE_ZZZ - SPRITE_OOP);
Expand All @@ -572,9 +582,6 @@ void CPlayers::RenderPlayer(
Graphics()->QuadsSetRotation(0);
}

if(ClientID < 0)
return;

if(g_Config.m_ClShowEmotes && m_pClient->m_aClients[ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick())
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
Expand Down
12 changes: 6 additions & 6 deletions src/game/client/components/scoreboard.cpp
Expand Up @@ -64,7 +64,7 @@ void CScoreboard::RenderGoals(float x, float y, float w)
float h = 50.0f;

Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.5f);
RenderTools()->DrawRoundRect(x, y, w, h, 10.0f);
Expand Down Expand Up @@ -101,7 +101,7 @@ void CScoreboard::RenderSpectators(float x, float y, float w)

// background
Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.5f);
RenderTools()->DrawRoundRect(x, y, w, h, 10.0f);
Expand Down Expand Up @@ -180,7 +180,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch

// background
Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.5f);
if(upper16 || upper32 || upper24)
Expand Down Expand Up @@ -372,7 +372,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch

if (DDTeam != TEAM_FLOCK)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(DDTeam / 64.0f, 1.0f, 0.5f, 0.5f));
Graphics()->SetColor(rgb);
Expand Down Expand Up @@ -413,7 +413,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
// 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()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
RenderTools()->DrawRoundRect(x, y, w-20.0f, LineHeight, RoundRadius);
Expand Down Expand Up @@ -572,7 +572,7 @@ void CScoreboard::RenderRecordingNotification(float x)

//draw the box
Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.4f);
RenderTools()->DrawRoundRectExt(x, 0.0f, w+60.0f, 50.0f, 15.0f, CUI::CORNER_B);
Expand Down
2 changes: 0 additions & 2 deletions src/game/client/components/skins.cpp
Expand Up @@ -172,8 +172,6 @@ void CSkins::OnInit()
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load skins. folder='skins/'");
CSkin DummySkin;
DummySkin.m_IsVanilla = true;
DummySkin.m_OrgTexture = -1;
DummySkin.m_ColorTexture = -1;
str_copy(DummySkin.m_aName, "dummy", sizeof(DummySkin.m_aName));
DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f);
m_aSkins.add(DummySkin);
Expand Down
4 changes: 2 additions & 2 deletions src/game/client/components/skins.h
Expand Up @@ -14,8 +14,8 @@ class CSkins : public CComponent
struct CSkin
{
bool m_IsVanilla;
int m_OrgTexture;
int m_ColorTexture;
IGraphics::CTextureHandle m_OrgTexture;
IGraphics::CTextureHandle m_ColorTexture;
char m_aName[24];
ColorRGBA m_BloodColor;

Expand Down
10 changes: 5 additions & 5 deletions src/game/client/components/spectator.cpp
Expand Up @@ -225,7 +225,7 @@ void CSpectator::OnRender()
Graphics()->MapScreen(0, 0, Width, Height);

Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.3f);
RenderTools()->DrawRoundRect(Width/2.0f-ObjWidth, Height/2.0f-300.0f, ObjWidth*2, 600.0f, 20.0f);
Expand All @@ -239,7 +239,7 @@ void CSpectator::OnRender()
if((Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecID == SPEC_FREEVIEW) ||
m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
RenderTools()->DrawRoundRect(Width/2.0f-(ObjWidth - 20.0f), Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f);
Expand All @@ -248,7 +248,7 @@ void CSpectator::OnRender()

if(Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecID == SPEC_FOLLOW)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
RenderTools()->DrawRoundRect(Width/2.0f-(ObjWidth - 310.0f), Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f);
Expand Down Expand Up @@ -325,7 +325,7 @@ void CSpectator::OnRender()

if (DDTeam != TEAM_FLOCK)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(DDTeam / 64.0f, 1.0f, 0.5f, 0.5f));
Graphics()->SetColor(rgb);
Expand All @@ -347,7 +347,7 @@ void CSpectator::OnRender()
if((Client()->State() == IClient::STATE_DEMOPLAYBACK && m_pClient->m_DemoSpecID == m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_ClientID)
|| (Client()->State() != IClient::STATE_DEMOPLAYBACK && m_pClient ->m_Snap.m_SpecInfo.m_SpectatorID == m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_ClientID))
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f);
RenderTools()->DrawRoundRect(Width/2.0f+x-10.0f, Height/2.0f+y+BoxMove, 270.0f, LineHeight, RoundRadius);
Expand Down
6 changes: 3 additions & 3 deletions src/game/client/components/statboard.cpp
Expand Up @@ -192,7 +192,7 @@ void CStatboard::RenderGlobalStats()
Graphics()->MapScreen(0, 0, StatboardWidth, StatboardHeight);

Graphics()->BlendNormal();
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(0,0,0,0.5f);
RenderTools()->DrawRoundRect(x-10.f, y-10.f, StatboardContentWidth, StatboardContentHeight, 17.0f);
Expand Down Expand Up @@ -272,7 +272,7 @@ void CStatboard::RenderGlobalStats()
|| (m_pClient->m_Snap.m_SpecInfo.m_Active && pInfo->m_ClientID == m_pClient->m_Snap.m_SpecInfo.m_SpectatorID))
{
// background so it's easy to find the local player
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->QuadsBegin();
Graphics()->SetColor(1,1,1,0.25f);
RenderTools()->DrawRoundRect(x, y, StatboardContentWidth-20, LineHeight*0.95f, 17.0f);
Expand Down Expand Up @@ -480,7 +480,7 @@ void CStatboard::FormatStats()
}

char aPlayerStats[1024 * VANILLA_MAX_CLIENTS];
str_format(aPlayerStats, sizeof(aPlayerStats), "Local-player,Team,Name,Clan,Score,Frags,Deaths,Suicides,F/D-ratio,Net,FPM,Spree,Best,Hammer-F/D,Gun-F/D,Shotgun-F/D,Grenade-F/D,Rifle-F/D,Ninja-F/D,GameWithFlags,Flag-grabs,Flag-captures\n");
str_format(aPlayerStats, sizeof(aPlayerStats), "Local-player,Team,Name,Clan,Score,Frags,Deaths,Suicides,F/D-ratio,Net,FPM,Spree,Best,Hammer-F/D,Gun-F/D,Shotgun-F/D,Grenade-F/D,Laser-F/D,Ninja-F/D,GameWithFlags,Flag-grabs,Flag-captures\n");
for (int i = 0; i < NumPlayers; i++)
{
const CNetObj_PlayerInfo *pInfo = apPlayers[i];
Expand Down
24 changes: 21 additions & 3 deletions src/game/client/gameclient.cpp
Expand Up @@ -833,7 +833,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker, bool IsDummy)
{
CNetMsg_Sv_KillMsg *pMsg = (CNetMsg_Sv_KillMsg *)pRawMsg;
// reset character prediction
if(!(m_GameWorld.m_WorldConfig.m_IsFNG && pMsg->m_Weapon == WEAPON_RIFLE))
if(!(m_GameWorld.m_WorldConfig.m_IsFNG && pMsg->m_Weapon == WEAPON_LASER))
{
m_CharOrder.GiveWeak(pMsg->m_Victim);
m_aLastWorldCharacters[pMsg->m_Victim].m_Alive = false;
Expand Down Expand Up @@ -1214,10 +1214,26 @@ void CGameClient::OnNewSnapshot()
m_Snap.m_aCharacters[Item.m_ID].m_Active = true;
m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld);

// reuse the result from the previous evolve if the snapped character didn't change since the previous snapshot
if(m_aClients[Item.m_ID].m_Evolved.m_Tick == Client()->PrevGameTick())
{
if(mem_comp(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, &m_aClients[Item.m_ID].m_Snapped, sizeof(CNetObj_Character)) == 0)
m_Snap.m_aCharacters[Item.m_ID].m_Prev = m_aClients[Item.m_ID].m_Evolved;
if(mem_comp(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, &m_aClients[Item.m_ID].m_Snapped, sizeof(CNetObj_Character)) == 0)
m_Snap.m_aCharacters[Item.m_ID].m_Cur = m_aClients[Item.m_ID].m_Evolved;
}

if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick)
Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick());
if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick)
Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick());

m_aClients[Item.m_ID].m_Snapped = *((const CNetObj_Character *)pData);
m_aClients[Item.m_ID].m_Evolved = m_Snap.m_aCharacters[Item.m_ID].m_Cur;
}
else
{
m_aClients[Item.m_ID].m_Evolved.m_Tick = -1;
}
}
else if(Item.m_Type == NETOBJTYPE_DDNETCHARACTER)
Expand All @@ -1232,7 +1248,7 @@ void CGameClient::OnNewSnapshot()
m_aClients[Item.m_ID].m_NoCollision = pCharacterData->m_Flags & CHARACTERFLAG_NO_COLLISION;
m_aClients[Item.m_ID].m_NoHammerHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_HAMMER_HIT;
m_aClients[Item.m_ID].m_NoGrenadeHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_GRENADE_HIT;
m_aClients[Item.m_ID].m_NoRifleHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_RIFLE_HIT;
m_aClients[Item.m_ID].m_NoLaserHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_LASER_HIT;
m_aClients[Item.m_ID].m_NoShotgunHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_SHOTGUN_HIT;
m_aClients[Item.m_ID].m_NoHookHit = pCharacterData->m_Flags & CHARACTERFLAG_NO_HOOK;
m_aClients[Item.m_ID].m_Super = pCharacterData->m_Flags & CHARACTERFLAG_SUPER;
Expand Down Expand Up @@ -1788,7 +1804,7 @@ void CGameClient::CClientData::Reset()
m_EndlessJump = false;
m_NoHammerHit = false;
m_NoGrenadeHit = false;
m_NoRifleHit = false;
m_NoLaserHit = false;
m_NoShotgunHit = false;
m_NoHookHit = false;
m_Super = false;
Expand All @@ -1798,6 +1814,8 @@ void CGameClient::CClientData::Reset()
m_FreezeEnd = 0;
m_DeepFrozen = false;

m_Evolved.m_Tick = -1;

UpdateRenderInfo();
}

Expand Down
5 changes: 4 additions & 1 deletion src/game/client/gameclient.h
Expand Up @@ -282,7 +282,7 @@ class CGameClient : public IGameClient
bool m_EndlessJump;
bool m_NoHammerHit;
bool m_NoGrenadeHit;
bool m_NoRifleHit;
bool m_NoLaserHit;
bool m_NoShotgunHit;
bool m_NoHookHit;
bool m_Super;
Expand Down Expand Up @@ -310,6 +310,9 @@ class CGameClient : public IGameClient
bool m_Paused;
bool m_Spec;

CNetObj_Character m_Snapped;
CNetObj_Character m_Evolved;

void UpdateRenderInfo();
void Reset();

Expand Down
17 changes: 7 additions & 10 deletions src/game/client/prediction/entities/character.cpp
Expand Up @@ -8,9 +8,6 @@
#include "projectile.h"
#include "laser.h"

#include <stdio.h>
#include <string.h>

// Character, "physical" player's part

void CCharacter::SetWeapon(int W)
Expand Down Expand Up @@ -55,7 +52,7 @@ void CCharacter::HandleJetpack()
vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));

bool FullAuto = false;
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_RIFLE)
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_LASER)
FullAuto = true;
if (m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN)
FullAuto = true;
Expand Down Expand Up @@ -265,7 +262,7 @@ void CCharacter::FireWeapon()
vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY));

bool FullAuto = false;
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_RIFLE)
if(m_Core.m_ActiveWeapon == WEAPON_GRENADE || m_Core.m_ActiveWeapon == WEAPON_SHOTGUN || m_Core.m_ActiveWeapon == WEAPON_LASER)
FullAuto = true;
if (m_Jetpack && m_Core.m_ActiveWeapon == WEAPON_GUN)
FullAuto = true;
Expand Down Expand Up @@ -438,11 +435,11 @@ void CCharacter::FireWeapon()
);//SoundImpact
} break;

case WEAPON_RIFLE:
case WEAPON_LASER:
{
float LaserReach = GetTuning(m_TuneZone)->m_LaserReach;

new CLaser(GameWorld(), m_Pos, Direction, LaserReach, GetCID(), WEAPON_RIFLE);
new CLaser(GameWorld(), m_Pos, Direction, LaserReach, GetCID(), WEAPON_LASER);
} break;

case WEAPON_NINJA:
Expand Down Expand Up @@ -1041,16 +1038,16 @@ void CCharacter::Read(CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtende
m_Hit |= DISABLE_HIT_GRENADE;
if(pExtended->m_Flags & CHARACTERFLAG_NO_HAMMER_HIT)
m_Hit |= DISABLE_HIT_HAMMER;
if(pExtended->m_Flags & CHARACTERFLAG_NO_RIFLE_HIT)
m_Hit |= DISABLE_HIT_RIFLE;
if(pExtended->m_Flags & CHARACTERFLAG_NO_LASER_HIT)
m_Hit |= DISABLE_HIT_LASER;
if(pExtended->m_Flags & CHARACTERFLAG_NO_SHOTGUN_HIT)
m_Hit |= DISABLE_HIT_SHOTGUN;

m_aWeapons[WEAPON_HAMMER].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_HAMMER) != 0;
m_aWeapons[WEAPON_GUN].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_GUN) != 0;
m_aWeapons[WEAPON_SHOTGUN].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_SHOTGUN) != 0;
m_aWeapons[WEAPON_GRENADE].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_GRENADE) != 0;
m_aWeapons[WEAPON_RIFLE].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_LASER) != 0;
m_aWeapons[WEAPON_LASER].m_Got = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_LASER) != 0;

const bool Ninja = (pExtended->m_Flags & CHARACTERFLAG_WEAPON_NINJA) != 0;
if(Ninja && m_Core.m_ActiveWeapon != WEAPON_NINJA)
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/prediction/entities/character.h
Expand Up @@ -85,7 +85,7 @@ class CCharacter : public CEntity
DISABLE_HIT_HAMMER=1,
DISABLE_HIT_SHOTGUN=2,
DISABLE_HIT_GRENADE=4,
DISABLE_HIT_RIFLE=8
DISABLE_HIT_LASER=8
};
int m_Hit;
int m_TuneZone;
Expand Down
8 changes: 4 additions & 4 deletions src/game/client/prediction/entities/laser.cpp
Expand Up @@ -32,12 +32,12 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
CCharacter *pHit;
bool pDontHitSelf = g_Config.m_SvOldLaser || (m_Bounces == 0 && !m_WasTele);

if(pOwnerChar ? (!(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_RIFLE) && m_Type == WEAPON_RIFLE) || (!(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_SHOTGUN) && m_Type == WEAPON_SHOTGUN) : g_Config.m_SvHit)
if(pOwnerChar ? (!(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_LASER) && m_Type == WEAPON_LASER) || (!(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_SHOTGUN) && m_Type == WEAPON_SHOTGUN) : g_Config.m_SvHit)
pHit = GameWorld()->IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner);
else
pHit = GameWorld()->IntersectCharacter(m_Pos, To, 0.f, At, pDontHitSelf ? pOwnerChar : 0, m_Owner, pOwnerChar);

if(!pHit || (pHit == pOwnerChar && g_Config.m_SvOldLaser) || (pHit != pOwnerChar && pOwnerChar ? (pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_RIFLE && m_Type == WEAPON_RIFLE) || (pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_SHOTGUN && m_Type == WEAPON_SHOTGUN) : !g_Config.m_SvHit))
if(!pHit || (pHit == pOwnerChar && g_Config.m_SvOldLaser) || (pHit != pOwnerChar && pOwnerChar ? (pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_LASER && m_Type == WEAPON_LASER) || (pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_SHOTGUN && m_Type == WEAPON_SHOTGUN) : !g_Config.m_SvHit))
return false;
m_From = From;
m_Pos = At;
Expand All @@ -54,7 +54,7 @@ bool CLaser::HitCharacter(vec2 From, vec2 To)
Temp = pHit->Core()->m_Vel + normalize(pOwnerChar->Core()->m_Pos - pHit->Core()->m_Pos) * Strength;
pHit->Core()->m_Vel = ClampVel(pHit->m_MoveRestrictions, Temp);
}
else if (m_Type == WEAPON_RIFLE)
else if (m_Type == WEAPON_LASER)
{
pHit->UnFreeze();
}
Expand Down Expand Up @@ -169,7 +169,7 @@ CLaser::CLaser(CGameWorld *pGameWorld, int ID, CNetObj_Laser *pLaser)
m_Dir = normalize(m_Dir);
else
m_Energy = 0;
m_Type = WEAPON_RIFLE;
m_Type = WEAPON_LASER;
m_PrevPos = m_From;
m_ID = ID;
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/client/render.cpp
Expand Up @@ -286,7 +286,7 @@ void CRenderTools::DrawRoundRect(float x, float y, float w, float h, float r)

void CRenderTools::DrawUIRect(const CUIRect *r, ColorRGBA Color, int Corners, float Rounding)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();

// TODO: FIX US
Graphics()->QuadsBegin();
Expand Down
5 changes: 2 additions & 3 deletions src/game/client/render.h
Expand Up @@ -3,25 +3,24 @@
#ifndef GAME_CLIENT_RENDER_H
#define GAME_CLIENT_RENDER_H

#include <engine/graphics.h>
#include <base/vmath.h>
#include <base/color.h>
#include <game/mapitems.h>
#include "ui.h"


class CTeeRenderInfo
{
public:
CTeeRenderInfo()
{
m_Texture = -1;
m_ColorBody = ColorRGBA(1,1,1);
m_ColorFeet = ColorRGBA(1,1,1);
m_Size = 1.0f;
m_GotAirJump = 1;
};

int m_Texture;
IGraphics::CTextureHandle m_Texture;
ColorRGBA m_ColorBody;
ColorRGBA m_ColorFeet;
float m_Size;
Expand Down
8 changes: 4 additions & 4 deletions src/game/ddracecommands.h
Expand Up @@ -10,16 +10,16 @@ CONSOLE_COMMAND("kill_pl", "v[id]", CFGFLAG_SERVER, ConKillPlayer, this, "Kills
CONSOLE_COMMAND("totele", "i[number]", CFGFLAG_SERVER|CMDFLAG_TEST, ConToTeleporter, this, "Teleports you to teleporter v")
CONSOLE_COMMAND("totelecp", "i[number]", CFGFLAG_SERVER|CMDFLAG_TEST, ConToCheckTeleporter, this, "Teleports you to checkpoint teleporter v")
CONSOLE_COMMAND("tele", "?i[id] ?i[id]", CFGFLAG_SERVER|CMDFLAG_TEST, ConTeleport, this, "Teleports player i (or you) to player i (or you to where you look at)")
CONSOLE_COMMAND("addweapon", "i[weapon-id]", CFGFLAG_SERVER|CMDFLAG_TEST, ConAddWeapon, this, "Gives weapon with id i to you (all = -1, hammer = 0, gun = 1, shotgun = 2, grenade = 3, rifle = 4, ninja = 5)")
CONSOLE_COMMAND("removeweapon", "i[weapon-id]", CFGFLAG_SERVER|CMDFLAG_TEST, ConRemoveWeapon, this, "removes weapon with id i from you (all = -1, hammer = 0, gun = 1, shotgun = 2, grenade = 3, rifle = 4, ninja = 5)")
CONSOLE_COMMAND("addweapon", "i[weapon-id]", CFGFLAG_SERVER|CMDFLAG_TEST, ConAddWeapon, this, "Gives weapon with id i to you (all = -1, hammer = 0, gun = 1, shotgun = 2, grenade = 3, laser = 4, ninja = 5)")
CONSOLE_COMMAND("removeweapon", "i[weapon-id]", CFGFLAG_SERVER|CMDFLAG_TEST, ConRemoveWeapon, this, "removes weapon with id i from you (all = -1, hammer = 0, gun = 1, shotgun = 2, grenade = 3, laser = 4, ninja = 5)")
CONSOLE_COMMAND("shotgun", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConShotgun, this, "Gives a shotgun to you")
CONSOLE_COMMAND("grenade", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConGrenade, this, "Gives a grenade launcher to you")
CONSOLE_COMMAND("rifle", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConRifle, this, "Gives a rifle to you")
CONSOLE_COMMAND("laser", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConLaser, this, "Gives a laser to you")
CONSOLE_COMMAND("jetpack","", CFGFLAG_SERVER|CMDFLAG_TEST, ConJetpack, this, "Gives jetpack to you")
CONSOLE_COMMAND("weapons", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConWeapons, this, "Gives all weapons to you")
CONSOLE_COMMAND("unshotgun", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnShotgun, this, "Takes the shotgun from you")
CONSOLE_COMMAND("ungrenade", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnGrenade, this, "Takes the grenade launcher you")
CONSOLE_COMMAND("unrifle", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnRifle, this, "Takes the rifle from you")
CONSOLE_COMMAND("unlaser", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnLaser, this, "Takes the laser from you")
CONSOLE_COMMAND("unjetpack", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnJetpack, this, "Takes the jetpack from you")
CONSOLE_COMMAND("unweapons", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConUnWeapons, this, "Takes all weapons from you")
CONSOLE_COMMAND("ninja", "", CFGFLAG_SERVER|CMDFLAG_TEST, ConNinja, this, "Makes you a ninja")
Expand Down
1 change: 1 addition & 0 deletions src/game/editor/auto_map.cpp
Expand Up @@ -330,6 +330,7 @@ void CAutoMapper::Load(const char* pTileName)
}
if(pIndexRule->m_SkipEmpty && pIndexRule->m_SkipFull)
{
pIndexRule->m_SkipEmpty = false;
pIndexRule->m_SkipFull = false;
}
}
Expand Down
140 changes: 66 additions & 74 deletions src/game/editor/editor.cpp

Large diffs are not rendered by default.

45 changes: 18 additions & 27 deletions src/game/editor/editor.h
Expand Up @@ -281,7 +281,6 @@ class CEditorImage : public CImageInfo
: m_AutoMapper(pEditor)
{
m_pEditor = pEditor;
m_TexID = -1;
m_aName[0] = 0;
m_External = 0;
m_Width = 0;
Expand All @@ -294,7 +293,7 @@ class CEditorImage : public CImageInfo

void AnalyseTileFlags();

int m_TexID;
IGraphics::CTextureHandle m_Texture;
int m_External;
char m_aName[128];
unsigned char m_aTileFlags[256];
Expand Down Expand Up @@ -454,7 +453,7 @@ class CEditorMap
}

void Clean();
void CreateDefault(int EntitiesTexture);
void CreateDefault(IGraphics::CTextureHandle EntitiesTexture);

// io
int Save(class IStorage *pStorage, const char *pFilename);
Expand Down Expand Up @@ -547,7 +546,7 @@ class CLayerTiles : public CLayer

void FlagModified(int x, int y, int w, int h);

int m_TexID;
IGraphics::CTextureHandle m_Texture;
int m_Game;
int m_Image;
int m_Width;
Expand Down Expand Up @@ -709,20 +708,10 @@ class CEditor : public IEditor
m_CommandBox = 0.0f;
m_aSettingsCommand[0] = 0;

ms_CheckerTexture = 0;
ms_BackgroundTexture = 0;
ms_CursorTexture = 0;
ms_EntitiesTexture = 0;

ms_pUiGotContext = 0;

// DDRace

ms_FrontTexture = 0;
ms_TeleTexture = 0;
ms_SpeedupTexture = 0;
ms_SwitchTexture = 0;
ms_TuneTexture = 0;
m_TeleNumber = 1;
m_SwitchNum = 1;
m_TuningNum = 1;
Expand Down Expand Up @@ -754,7 +743,8 @@ class CEditor : public IEditor
int m_FileNum;
int m_ButtonId;
char m_aName[128];
int m_PreviewImage;
IGraphics::CTextureHandle m_PreviewImage;
bool m_PreviewImageIsLoaded;
};
array<CUndo> m_lUndoSteps;
bool m_Undo;
Expand Down Expand Up @@ -848,7 +838,8 @@ class CEditor : public IEditor
int m_FilesSelectedIndex;
char m_FileDialogNewFolderName[64];
char m_FileDialogErrString[64];
int m_FilePreviewImage;
IGraphics::CTextureHandle m_FilePreviewImage;
bool m_PreviewImageIsLoaded;
CImageInfo m_FilePreviewImageInfo;


Expand Down Expand Up @@ -913,10 +904,10 @@ class CEditor : public IEditor
int m_SelectedSound;
int m_SelectedSource;

static int ms_CheckerTexture;
static int ms_BackgroundTexture;
static int ms_CursorTexture;
static int ms_EntitiesTexture;
IGraphics::CTextureHandle m_CheckerTexture;
IGraphics::CTextureHandle m_BackgroundTexture;
IGraphics::CTextureHandle m_CursorTexture;
IGraphics::CTextureHandle m_EntitiesTexture;

CLayerGroup m_Brush;
CLayerTiles m_TilesetPicker;
Expand Down Expand Up @@ -951,7 +942,7 @@ class CEditor : public IEditor

int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden=false, int Corners=CUI::CORNER_ALL);

void RenderBackground(CUIRect View, int Texture, float Size, float Brightness);
void RenderBackground(CUIRect View, IGraphics::CTextureHandle Texture, float Size, float Brightness);

void RenderGrid(CLayerGroup *pGroup);

Expand Down Expand Up @@ -997,7 +988,7 @@ class CEditor : public IEditor

float ButtonColorMul(const void *pID);

void DoQuadEnvelopes(const array<CQuad> &m_lQuads, int TexID = -1);
void DoQuadEnvelopes(const array<CQuad> &m_lQuads, IGraphics::CTextureHandle Texture = IGraphics::CTextureHandle());
void DoQuadEnvPoint(const CQuad *pQuad, int QIndex, int pIndex);
void DoQuadPoint(CQuad *pQuad, int QuadIndex, int v);

Expand Down Expand Up @@ -1041,11 +1032,11 @@ class CEditor : public IEditor

// DDRace

static int ms_FrontTexture;
static int ms_TeleTexture;
static int ms_SpeedupTexture;
static int ms_SwitchTexture;
static int ms_TuneTexture;
IGraphics::CTextureHandle m_FrontTexture;
IGraphics::CTextureHandle m_TeleTexture;
IGraphics::CTextureHandle m_SpeedupTexture;
IGraphics::CTextureHandle m_SwitchTexture;
IGraphics::CTextureHandle m_TuneTexture;
static int PopupTele(CEditor *pEditor, CUIRect View);
static int PopupSpeedup(CEditor *pEditor, CUIRect View);
static int PopupSwitch(CEditor *pEditor, CUIRect View);
Expand Down
4 changes: 2 additions & 2 deletions src/game/editor/explanations.cpp
Expand Up @@ -300,9 +300,9 @@ const char *CEditor::Explain(int Tile, int Layer)
if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
return "NINJA: Makes you invisible in the darkest nights.";
break;
case ENTITY_OFFSET + ENTITY_WEAPON_RIFLE:
case ENTITY_OFFSET + ENTITY_WEAPON_LASER:
if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
return "RIFLE: Unfreezes hit tee. Bounces off the walls. Also known as laser.";
return "LASER: Unfreezes hit tee. Bounces off the walls. Also known as laser.";
break;
case ENTITY_OFFSET + ENTITY_LASER_FAST_CCW:
if(Layer == LAYER_GAME || Layer == LAYER_FRONT || Layer == LAYER_SWITCH)
Expand Down
4 changes: 2 additions & 2 deletions src/game/editor/io.cpp
Expand Up @@ -677,7 +677,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
if(m_pEditor->Graphics()->LoadPNG(&ImgInfo, aBuf, IStorage::TYPE_ALL))
{
*pImg = ImgInfo;
pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, CImageInfo::FORMAT_AUTO, 0);
ImgInfo.m_pData = 0;
pImg->m_External = 1;
}
Expand All @@ -692,7 +692,7 @@ int CEditorMap::Load(class IStorage *pStorage, const char *pFileName, int Storag
void *pData = DataFile.GetData(pItem->m_ImageData);
pImg->m_pData = malloc(pImg->m_Width*pImg->m_Height*4);
mem_copy(pImg->m_pData, pData, pImg->m_Width*pImg->m_Height*4);
pImg->m_TexID = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0);
pImg->m_Texture = m_pEditor->Graphics()->LoadTextureRaw(pImg->m_Width, pImg->m_Height, pImg->m_Format, pImg->m_pData, CImageInfo::FORMAT_AUTO, 0);
}

// copy image name
Expand Down
6 changes: 3 additions & 3 deletions src/game/editor/layer_quads.cpp
Expand Up @@ -23,9 +23,9 @@ CLayerQuads::~CLayerQuads()

void CLayerQuads::Render(bool QuadPicker)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
if(m_Image >= 0 && m_Image < m_pEditor->m_Map.m_lImages.size())
Graphics()->TextureSet(m_pEditor->m_Map.m_lImages[m_Image]->m_TexID);
Graphics()->TextureSet(m_pEditor->m_Map.m_lImages[m_Image]->m_Texture);

Graphics()->BlendNone();
m_pEditor->RenderTools()->ForceRenderQuads(m_lQuads.base_ptr(), m_lQuads.size(), LAYERRENDERFLAG_OPAQUE, m_pEditor->EnvelopeEval, m_pEditor);
Expand Down Expand Up @@ -93,7 +93,7 @@ void CLayerQuads::BrushSelecting(CUIRect Rect)
IGraphics::CLineItem(Rect.x+Rect.w, Rect.y, Rect.x+Rect.w, Rect.y+Rect.h),
IGraphics::CLineItem(Rect.x+Rect.w, Rect.y+Rect.h, Rect.x, Rect.y+Rect.h),
IGraphics::CLineItem(Rect.x, Rect.y+Rect.h, Rect.x, Rect.y)};
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->LinesBegin();
Graphics()->LinesDraw(Array, 4);
Graphics()->LinesEnd();
Expand Down
4 changes: 2 additions & 2 deletions src/game/editor/layer_sounds.cpp
Expand Up @@ -19,7 +19,7 @@ CLayerSounds::~CLayerSounds()
void CLayerSounds::Render(bool Tileset)
{
// TODO: nice texture
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->BlendNormal();
Graphics()->QuadsBegin();

Expand Down Expand Up @@ -139,7 +139,7 @@ void CLayerSounds::BrushSelecting(CUIRect Rect)
IGraphics::CLineItem(Rect.x+Rect.w, Rect.y, Rect.x+Rect.w, Rect.y+Rect.h),
IGraphics::CLineItem(Rect.x+Rect.w, Rect.y+Rect.h, Rect.x, Rect.y+Rect.h),
IGraphics::CLineItem(Rect.x, Rect.y+Rect.h, Rect.x, Rect.y)};
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
Graphics()->LinesBegin();
Graphics()->LinesDraw(Array, 4);
Graphics()->LinesEnd();
Expand Down
24 changes: 12 additions & 12 deletions src/game/editor/layer_tiles.cpp
Expand Up @@ -22,7 +22,6 @@ CLayerTiles::CLayerTiles(int w, int h)
m_Width = w;
m_Height = h;
m_Image = -1;
m_TexID = -1;
m_Game = 0;
m_Color.r = 255;
m_Color.g = 255;
Expand Down Expand Up @@ -83,8 +82,8 @@ void CLayerTiles::MakePalette()
void CLayerTiles::Render(bool Tileset)
{
if(m_Image >= 0 && m_Image < m_pEditor->m_Map.m_lImages.size())
m_TexID = m_pEditor->m_Map.m_lImages[m_Image]->m_TexID;
Graphics()->TextureSet(m_TexID);
m_Texture = m_pEditor->m_Map.m_lImages[m_Image]->m_Texture;
Graphics()->TextureSet(m_Texture);
ColorRGBA Color = ColorRGBA(m_Color.r/255.0f, m_Color.g/255.0f, m_Color.b/255.0f, m_Color.a/255.0f);
Graphics()->BlendNone();
m_pEditor->RenderTools()->RenderTilemap(m_pTiles, m_Width, m_Height, 32.0f, Color, LAYERRENDERFLAG_OPAQUE,
Expand Down Expand Up @@ -182,7 +181,7 @@ bool CLayerTiles::IsEmpty(CLayerTiles *pLayer)

void CLayerTiles::BrushSelecting(CUIRect Rect)
{
Graphics()->TextureSet(-1);
Graphics()->TextureClear();
m_pEditor->Graphics()->QuadsBegin();
m_pEditor->Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.4f);
Snap(&Rect);
Expand All @@ -208,7 +207,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerTele *pGrabbed = new CLayerTele(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand Down Expand Up @@ -240,7 +239,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerSpeedup *pGrabbed = new CLayerSpeedup(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand Down Expand Up @@ -278,7 +277,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerSwitch *pGrabbed = new CLayerSwitch(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand Down Expand Up @@ -329,7 +328,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerTune *pGrabbed = new CLayerTune(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand Down Expand Up @@ -363,7 +362,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerFront *pGrabbed = new CLayerFront(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand All @@ -384,7 +383,7 @@ int CLayerTiles::BrushGrab(CLayerGroup *pBrush, CUIRect Rect)
{
CLayerTiles *pGrabbed = new CLayerTiles(r.w, r.h);
pGrabbed->m_pEditor = m_pEditor;
pGrabbed->m_TexID = m_TexID;
pGrabbed->m_Texture = m_Texture;
pGrabbed->m_Image = m_Image;
pGrabbed->m_Game = m_Game;
if (m_pEditor->m_BrushColorEnabled)
Expand Down Expand Up @@ -913,7 +912,7 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox)
{
if (NewVal == -1)
{
m_TexID = -1;
m_Texture = IGraphics::CTextureHandle();
m_Image = -1;
}
else
Expand Down Expand Up @@ -961,7 +960,8 @@ int CLayerTiles::RenderProperties(CUIRect *pToolBox)
return 0;
}

void CLayerTiles::FlagModified(int x, int y, int w, int h) {
void CLayerTiles::FlagModified(int x, int y, int w, int h)
{
m_pEditor->m_Map.m_Modified = true;
if (m_Seed != 0 && m_AutoMapperConfig != -1 && m_AutoAutoMap) {
m_pEditor->m_Map.m_lImages[m_Image]->m_AutoMapper.ProceedLocalized(this, m_AutoMapperConfig, m_Seed, x, y, w, h);
Expand Down
22 changes: 11 additions & 11 deletions src/game/editor/popups.cpp
Expand Up @@ -162,8 +162,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View)
// new tele layer
View.HSplitBottom(5.0f, &View, &Button);
View.HSplitBottom(12.0f, &View, &Button);
static int s_NewSwitchLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewSwitchLayerButton, "Add tele layer", 0, &Button, 0, "Creates a new tele layer"))
static int s_NewTeleLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewTeleLayerButton, "Add tele layer", 0, &Button, 0, "Creates a new tele layer"))
{
CLayer *l = new CLayerTele(pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height);
pEditor->m_Map.MakeTeleLayer(l);
Expand All @@ -179,8 +179,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View)
// new speedup layer
View.HSplitBottom(5.0f, &View, &Button);
View.HSplitBottom(12.0f, &View, &Button);
static int s_NewSwitchLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewSwitchLayerButton, "Add speedup layer", 0, &Button, 0, "Creates a new speedup layer"))
static int s_NewSpeedupLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewSpeedupLayerButton, "Add speedup layer", 0, &Button, 0, "Creates a new speedup layer"))
{
CLayer *l = new CLayerSpeedup(pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height);
pEditor->m_Map.MakeSpeedupLayer(l);
Expand All @@ -196,8 +196,8 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View)
// new tune layer
View.HSplitBottom(5.0f, &View, &Button);
View.HSplitBottom(12.0f, &View, &Button);
static int s_NewSwitchLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewSwitchLayerButton, "Add tune layer", 0, &Button, 0, "Creates a new tuning layer"))
static int s_NewTuneLayerButton = 0;
if(pEditor->DoButton_Editor(&s_NewTuneLayerButton, "Add tune layer", 0, &Button, 0, "Creates a new tuning layer"))
{
CLayer *l = new CLayerTune(pEditor->m_Map.m_pGameLayer->m_Width, pEditor->m_Map.m_pGameLayer->m_Height);
pEditor->m_Map.MakeTuneLayer(l);
Expand All @@ -210,7 +210,7 @@ int CEditor::PopupGroup(CEditor *pEditor, CUIRect View)

if(pEditor->GetSelectedGroup()->m_GameGroup && !pEditor->m_Map.m_pFrontLayer)
{
// new force layer
// new front layer
View.HSplitBottom(5.0f, &View, &Button);
View.HSplitBottom(12.0f, &View, &Button);
static int s_NewFrontLayerButton = 0;
Expand Down Expand Up @@ -1215,7 +1215,7 @@ int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View)
float Max = (float)(maximum(pEditor->m_Map.m_lImages[ShowImage]->m_Width, pEditor->m_Map.m_lImages[ShowImage]->m_Height));
ImageView.w *= pEditor->m_Map.m_lImages[ShowImage]->m_Width/Max;
ImageView.h *= pEditor->m_Map.m_lImages[ShowImage]->m_Height/Max;
pEditor->Graphics()->TextureSet(pEditor->m_Map.m_lImages[ShowImage]->m_TexID);
pEditor->Graphics()->TextureSet(pEditor->m_Map.m_lImages[ShowImage]->m_Texture);
pEditor->Graphics()->BlendNormal();
pEditor->Graphics()->WrapClamp();
pEditor->Graphics()->QuadsBegin();
Expand Down Expand Up @@ -1581,7 +1581,7 @@ int CEditor::PopupColorPicker(CEditor *pEditor, CUIRect View)
View.VSplitRight(20.0f, &SVPicker, &HuePicker);
HuePicker.VSplitLeft(4.0f, 0x0, &HuePicker);

pEditor->Graphics()->TextureSet(-1);
pEditor->Graphics()->TextureClear();
pEditor->Graphics()->QuadsBegin();

// base: white - hue
Expand Down Expand Up @@ -1695,8 +1695,8 @@ int CEditor::PopupEntities(CEditor *pEditor, CUIRect View)
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "editor/entities/%s.png", Name);

pEditor->Graphics()->UnloadTexture(ms_EntitiesTexture);
ms_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
pEditor->Graphics()->UnloadTexture(pEditor->m_EntitiesTexture);
pEditor->m_EntitiesTexture = pEditor->Graphics()->LoadTexture(aBuf, IStorage::TYPE_ALL, CImageInfo::FORMAT_AUTO, 0);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/gamecore.cpp
Expand Up @@ -110,7 +110,7 @@ void CCharacterCore::Reset()
m_EndlessJump = false;
m_NoHammerHit = false;
m_NoGrenadeHit = false;
m_NoRifleHit = false;
m_NoLaserHit = false;
m_NoShotgunHit = false;
m_NoHookHit = false;
m_Super = false;
Expand Down Expand Up @@ -562,7 +562,7 @@ void CCharacterCore::ReadDDNet(const CNetObj_DDNetCharacter *pObjDDNet)
m_NoCollision = pObjDDNet->m_Flags & CHARACTERFLAG_NO_COLLISION;
m_NoHammerHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_HAMMER_HIT;
m_NoGrenadeHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_GRENADE_HIT;
m_NoRifleHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_RIFLE_HIT;
m_NoLaserHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_LASER_HIT;
m_NoShotgunHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_SHOTGUN_HIT;
m_NoHookHit = pObjDDNet->m_Flags & CHARACTERFLAG_NO_HOOK;
m_Super = pObjDDNet->m_Flags & CHARACTERFLAG_SUPER;
Expand Down
2 changes: 1 addition & 1 deletion src/game/gamecore.h
Expand Up @@ -247,7 +247,7 @@ class CCharacterCore
bool m_EndlessJump;
bool m_NoHammerHit;
bool m_NoGrenadeHit;
bool m_NoRifleHit;
bool m_NoLaserHit;
bool m_NoShotgunHit;
bool m_NoHookHit;
bool m_Super;
Expand Down
2 changes: 1 addition & 1 deletion src/game/mapitems.h
Expand Up @@ -54,7 +54,7 @@ enum
ENTITY_WEAPON_SHOTGUN,
ENTITY_WEAPON_GRENADE,
ENTITY_POWERUP_NINJA,
ENTITY_WEAPON_RIFLE,
ENTITY_WEAPON_LASER,
//DDRace - Main Lasers
ENTITY_LASER_FAST_CCW,
ENTITY_LASER_NORMAL_CCW,
Expand Down
4 changes: 3 additions & 1 deletion src/game/server/ddracechat.cpp
Expand Up @@ -35,7 +35,9 @@ void CGameContext::ConCredits(IConsole::IResult *pResult, void *pUserData)
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "credits",
"Piepow, QingGo, RafaelFF, sctt, jao, daverck, fokkonaut,");
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "credits",
"Bojidar, FallenKN, ardadem, archimede67, sirius1242 & others.");
"Bojidar, FallenKN, ardadem, archimede67, sirius1242, Aerll");
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "credits",
"& others.");
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "credits",
"Based on DDRace by the DDRace developers,");
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "credits",
Expand Down
10 changes: 5 additions & 5 deletions src/game/server/ddracechat.h
Expand Up @@ -31,12 +31,12 @@ CHAT_COMMAND("map", "?r[map]", CFGFLAG_CHAT|CFGFLAG_SERVER|CFGFLAG_NONTEEHISTORI
CHAT_COMMAND("rankteam", "?r[player name]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
CHAT_COMMAND("teamrank", "?r[player name]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
CHAT_COMMAND("rank", "?r[player name]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)")
CHAT_COMMAND("top5team", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default)")
CHAT_COMMAND("teamtop5", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default)")
CHAT_COMMAND("top5", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTop5, this, "Shows five ranks of the ladder beginning with rank i (1 by default)")
CHAT_COMMAND("times", "?s[player name] ?i[number of times to skip]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTimes, this, "/times ?s?i shows last 5 times of the server or of a player beginning with name s starting with time i (i = 1 by default)")
CHAT_COMMAND("top5team", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
CHAT_COMMAND("teamtop5", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
CHAT_COMMAND("top5", "?i[rank to start with]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTop5, this, "Shows five ranks of the ladder beginning with rank i (1 by default, -1 for worst)")
CHAT_COMMAND("times", "?s[player name] ?i[number of times to skip]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTimes, this, "/times ?s?i shows last 5 times of the server or of a player beginning with name s starting with time i (i = 1 by default, -1 for first)")
CHAT_COMMAND("points", "?r[player name]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConPoints, this, "Shows the global points of a player beginning with name r (your rank by default)")
CHAT_COMMAND("top5points", "?i[number]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTopPoints, this, "Shows five points of the global point ladder beginning with rank i (1 by default)")
CHAT_COMMAND("top5points", "?i[number]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTopPoints, this, "Shows five points of the global point ladder beginning with rank i (1 by default, -1 for worst)")

CHAT_COMMAND("team", "?i[id]", CFGFLAG_CHAT|CFGFLAG_SERVER, ConJoinTeam, this, "Lets you join team i (shows your team if left blank)")
CHAT_COMMAND("lock", "?i['0'|'1']", CFGFLAG_CHAT|CFGFLAG_SERVER, ConLockTeam, this, "Lock team so no-one else can join it")
Expand Down
10 changes: 5 additions & 5 deletions src/game/server/ddracecommands.cpp
Expand Up @@ -160,10 +160,10 @@ void CGameContext::ConGrenade(IConsole::IResult *pResult, void *pUserData)
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_GRENADE, false);
}

void CGameContext::ConRifle(IConsole::IResult *pResult, void *pUserData)
void CGameContext::ConLaser(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_RIFLE, false);
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_LASER, false);
}

void CGameContext::ConJetpack(IConsole::IResult *pResult, void *pUserData)
Expand Down Expand Up @@ -192,10 +192,10 @@ void CGameContext::ConUnGrenade(IConsole::IResult *pResult, void *pUserData)
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_GRENADE, true);
}

void CGameContext::ConUnRifle(IConsole::IResult *pResult, void *pUserData)
void CGameContext::ConUnLaser(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_RIFLE, true);
pSelf->ModifyWeapons(pResult, pUserData, WEAPON_LASER, true);
}

void CGameContext::ConUnJetpack(IConsole::IResult *pResult, void *pUserData)
Expand Down Expand Up @@ -243,7 +243,7 @@ void CGameContext::ModifyWeapons(IConsole::IResult *pResult, void *pUserData,
{
pChr->GiveWeapon(WEAPON_SHOTGUN, Remove);
pChr->GiveWeapon(WEAPON_GRENADE, Remove);
pChr->GiveWeapon(WEAPON_RIFLE, Remove);
pChr->GiveWeapon(WEAPON_LASER, Remove);
}
else
{
Expand Down