2987: Modulize skins, particles, emoticons and game r=def- a=Jupeyy

fixes #2203 

Puh, something i always wanted todo.
Need to error read, bcs alot of copy paste.

Modulizes all images, so that all images are mipmap indepedent, without texeloffset problems

I also added the ninja bar analyzer for #2921


Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
bors[bot] 2020-10-09 15:20:48 +00:00 committed by GitHub
commit f93c8e4fdb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1039 additions and 293 deletions

View file

@ -1397,6 +1397,8 @@ generate_source("src/game/generated/server_data.h" "server_content_header")
generate_source7("src/game/generated/protocol7.cpp" "network_source")
generate_source7("src/game/generated/protocol7.h" "network_header")
generate_source7("src/game/generated/client_data7.cpp" "client_content_source")
generate_source7("src/game/generated/client_data7.h" "client_content_header")
generate_maps("src/game/generated/protocolglue.h")
@ -1756,6 +1758,7 @@ if(CLIENT)
render.cpp
render.h
render_map.cpp
skin.h
ui.cpp
ui.h
)
@ -1775,6 +1778,8 @@ if(CLIENT)
set(GAME_GENERATED_CLIENT
src/game/generated/client_data.cpp
src/game/generated/client_data.h
src/game/generated/client_data7.cpp
src/game/generated/client_data7.h
)
set(CLIENT_SRC ${ENGINE_CLIENT} ${PLATFORM_CLIENT} ${GAME_CLIENT} ${GAME_EDITOR} ${GAME_GENERATED_CLIENT})

View file

@ -55,18 +55,19 @@ if "server_content_header" in sys.argv: gen_server_content_header = True
if "server_content_source" in sys.argv: gen_server_content_source = True
if gen_client_content_header:
print("#ifndef CLIENT_CONTENT_HEADER")
print("#define CLIENT_CONTENT_HEADER")
print("#ifndef CLIENT_CONTENT7_HEADER")
print("#define CLIENT_CONTENT7_HEADER")
if gen_server_content_header:
print("#ifndef SERVER_CONTENT_HEADER")
print("#define SERVER_CONTENT_HEADER")
print("#ifndef SERVER_CONTENT7_HEADER")
print("#define SERVER_CONTENT7_HEADER")
if gen_client_content_header or gen_server_content_header:
# print some includes
print('#include <engine/graphics.h>')
print('#include <engine/sound.h>')
print("namespace client_data7 {")
# emit the type declarations
contentlines = open("datasrc/content.py", "rb").readlines()
@ -88,11 +89,13 @@ if gen_client_content_header or gen_server_content_header:
if gen_client_content_source or gen_server_content_source:
if gen_client_content_source:
print('#include "client_data.h"')
print('#include "client_data7.h"')
if gen_server_content_source:
print('#include "server_data.h"')
print("namespace client_data7 {")
EmitDefinition(content.container, "datacontainer")
print('CDataContainer *g_pData = &datacontainer;')
print("}")
# NETWORK
if gen_network_header:
@ -356,4 +359,5 @@ if gen_network_source:
print(l)
if gen_client_content_header or gen_server_content_header:
print("}")
print("#endif")

View file

@ -173,7 +173,7 @@ class DataContainer(Struct):
self.sprites = Array(Sprite())
self.animations = Array(Animation())
self.weapons = Weapons()
self.explosion = Explosion()
#self.explosion = Explosion()
def FileList(format, num):
return [format%(x+1) for x in range(0,num)]

View file

@ -18,6 +18,8 @@
#include <engine/keys.h>
#include <engine/shared/config.h>
#include <engine/storage.h>
#include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/localization.h>
#include <math.h> // cosf, sinf, log2f
@ -102,7 +104,7 @@ void CGraphics_Threaded::FlushVerticesTex3D()
void CGraphics_Threaded::AddVertices(int Count)
{
m_NumVertices += Count;
if((m_NumVertices + Count) >= MAX_VERTICES)
if((m_NumVertices + Count) >= CCommandBuffer::MAX_VERTICES)
FlushVertices();
}
@ -114,7 +116,7 @@ void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertex *pVertic
void CGraphics_Threaded::AddVertices(int Count, CCommandBuffer::SVertexTex3DStream *pVertices)
{
m_NumVertices += Count;
if((m_NumVertices + Count) >= MAX_VERTICES)
if((m_NumVertices + Count) >= CCommandBuffer::MAX_VERTICES)
FlushVerticesTex3D();
}
@ -273,6 +275,13 @@ int CGraphics_Threaded::UnloadTexture(CTextureHandle Index)
return 0;
}
int CGraphics_Threaded::UnloadTextureNew(CTextureHandle &TextureHandle)
{
int Ret = UnloadTexture(TextureHandle);
TextureHandle = IGraphics::CTextureHandle();
return Ret;
}
static int ImageFormatToTexFormat(int Format)
{
if(Format == CImageInfo::FORMAT_RGB)
@ -322,6 +331,74 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
return 0;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, int w, int h)
{
int bpp = ImageFormatToPixelSize(FromImageInfo.m_Format);
m_SpriteHelper.resize(w * h * bpp);
CopyTextureFromTextureBufferSub(&m_SpriteHelper[0], w, h, (uint8_t *)FromImageInfo.m_pData, FromImageInfo.m_Width, FromImageInfo.m_Height, bpp, x, y, w, h);
IGraphics::CTextureHandle RetHandle = LoadTextureRaw(w, h, FromImageInfo.m_Format, &m_SpriteHelper[0], FromImageInfo.m_Format, 0);
return RetHandle;
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(CImageInfo &FromImageInfo, CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadSpriteTexture(CImageInfo &FromImageInfo, client_data7::CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return LoadSpriteTextureImpl(FromImageInfo, x, y, w, h);
}
bool CGraphics_Threaded::IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h)
{
if(FromImageInfo.m_Format == CImageInfo::FORMAT_ALPHA || FromImageInfo.m_Format == CImageInfo::FORMAT_RGBA)
{
uint8_t *pImgData = (uint8_t *)FromImageInfo.m_pData;
int bpp = ImageFormatToPixelSize(FromImageInfo.m_Format);
for(int iy = 0; iy < h; ++iy)
{
for(int ix = 0; ix < w; ++ix)
{
int RealOffset = (x + ix) * bpp + (y + iy) * bpp * FromImageInfo.m_Width;
if(pImgData[RealOffset + (bpp - 1)] > 0)
return false;
}
}
return true;
}
return false;
}
bool CGraphics_Threaded::IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, client_data7::CDataSprite *pSprite)
{
int imggx = FromImageInfo.m_Width / pSprite->m_pSet->m_Gridx;
int imggy = FromImageInfo.m_Height / pSprite->m_pSet->m_Gridy;
int x = pSprite->m_X * imggx;
int y = pSprite->m_Y * imggy;
int w = pSprite->m_W * imggx;
int h = pSprite->m_H * imggy;
return IsImageSubFullyTransparent(FromImageInfo, x, y, w, h);
}
IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName)
{
// don't waste memory on texture if we are stress testing
@ -488,6 +565,17 @@ void CGraphics_Threaded::CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSo
}
}
void CGraphics_Threaded::CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight)
{
for(int Y = 0; Y < SrcSubCopyHeight; ++Y)
{
int SrcImgOffset = ((SrcSubOffsetY + Y) * SrcWidth * ColorChannelCount) + (SrcSubOffsetX * ColorChannelCount);
int DstImgOffset = (Y * DestWidth * ColorChannelCount);
int CopySize = SrcSubCopyWidth * ColorChannelCount;
mem_copy(&pDestBuffer[DstImgOffset], &pSourceBuffer[SrcImgOffset], CopySize);
}
}
void CGraphics_Threaded::KickCommandBuffer()
{
m_pBackend->RunBuffer(m_pCommandBuffer);
@ -1183,7 +1271,7 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CQuadItem *pA
{
SQuadContainer &Container = m_QuadContainers[ContainerIndex];
if((int)Container.m_Quads.size() > Num + CCommandBuffer::MAX_VERTICES)
if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES)
return;
for(int i = 0; i < Num; ++i)
@ -1228,7 +1316,7 @@ void CGraphics_Threaded::QuadContainerAddQuads(int ContainerIndex, CFreeformItem
{
SQuadContainer &Container = m_QuadContainers[ContainerIndex];
if((int)Container.m_Quads.size() > Num + CCommandBuffer::MAX_VERTICES)
if((int)Container.m_Quads.size() > Num + CCommandBuffer::CCommandBuffer::MAX_VERTICES)
return;
for(int i = 0; i < Num; ++i)
@ -1301,6 +1389,8 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
if(Container.m_QuadBufferContainerIndex == -1)
return;
WrapClamp();
CCommandBuffer::SCommand_RenderQuadContainer Cmd;
Cmd.m_State = m_State;
Cmd.m_DrawNum = (unsigned int)QuadDrawNum * 6;
@ -1342,9 +1432,11 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
m_NumVertices += 4 * QuadDrawNum;
}
m_Drawing = DRAWING_QUADS;
WrapClamp();
FlushVertices(false);
m_Drawing = 0;
}
WrapNormal();
}
void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX, float ScaleY)
@ -1362,6 +1454,8 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
SQuadContainer::SQuad &Quad = Container.m_Quads[QuadOffset];
CCommandBuffer::SCommand_RenderQuadContainerAsSprite Cmd;
WrapClamp();
float ScreenX0, ScreenY0, ScreenX1, ScreenY1;
GetScreen(&ScreenX0, &ScreenY0, &ScreenX1, &ScreenY1);
MapScreen((ScreenX0 - X) / ScaleX, (ScreenY0 - Y) / ScaleY, (ScreenX1 - X) / ScaleX, (ScreenY1 - Y) / ScaleY);
@ -1468,9 +1562,11 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
m_NumVertices += 4;
}
m_Drawing = DRAWING_QUADS;
WrapClamp();
FlushVertices(false);
m_Drawing = 0;
}
WrapNormal();
}
void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo)
@ -1485,6 +1581,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex,
if(Container.m_QuadBufferContainerIndex == -1)
return;
WrapClamp();
SQuadContainer::SQuad &Quad = Container.m_Quads[0];
CCommandBuffer::SCommand_RenderQuadContainerAsSpriteMultiple Cmd;
@ -1539,6 +1636,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex,
}
mem_copy(Cmd.m_pRenderInfo, pRenderInfo, sizeof(IGraphics::SRenderSpriteInfo) * DrawCount);
WrapNormal();
}
else
{
@ -2094,9 +2192,9 @@ int CGraphics_Threaded::Init()
// init textures
m_FirstFreeTexture = 0;
for(int i = 0; i < MAX_TEXTURES - 1; i++)
for(int i = 0; i < CCommandBuffer::MAX_TEXTURES - 1; i++)
m_aTextureIndices[i] = i + 1;
m_aTextureIndices[MAX_TEXTURES - 1] = -1;
m_aTextureIndices[CCommandBuffer::MAX_TEXTURES - 1] = -1;
m_FirstFreeVertexArrayInfo = -1;
m_FirstFreeBufferObjectIndex = -1;

View file

@ -58,7 +58,7 @@ public:
enum
{
MAX_TEXTURES = 1024 * 4,
MAX_TEXTURES = 1024 * 32,
MAX_VERTICES = 32 * 1024,
};
@ -665,9 +665,6 @@ class CGraphics_Threaded : public IEngineGraphics
{
NUM_CMDBUFFERS = 2,
MAX_VERTICES = 32 * 1024,
MAX_TEXTURES = 1024 * 4,
DRAWING_QUADS = 1,
DRAWING_LINES = 2
};
@ -691,8 +688,8 @@ class CGraphics_Threaded : public IEngineGraphics
int m_CurIndex;
CCommandBuffer::SVertex m_aVertices[MAX_VERTICES];
CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[MAX_VERTICES];
CCommandBuffer::SVertex m_aVertices[CCommandBuffer::MAX_VERTICES];
CCommandBuffer::SVertexTex3DStream m_aVerticesTex3D[CCommandBuffer::MAX_VERTICES];
int m_NumVertices;
CCommandBuffer::SColor m_aColor[4];
@ -707,10 +704,12 @@ class CGraphics_Threaded : public IEngineGraphics
CTextureHandle m_InvalidTexture;
int m_aTextureIndices[MAX_TEXTURES];
int m_aTextureIndices[CCommandBuffer::MAX_TEXTURES];
int m_FirstFreeTexture;
int m_TextureMemoryUsage;
std::vector<uint8_t> m_SpriteHelper;
std::vector<SWarning> m_Warnings;
struct SVertexArrayInfo
@ -813,14 +812,23 @@ public:
void LinesDraw(const CLineItem *pArray, int Num) override;
int UnloadTexture(IGraphics::CTextureHandle Index) override;
int UnloadTextureNew(CTextureHandle &TextureHandle) override;
IGraphics::CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) override;
int LoadTextureRawSub(IGraphics::CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) override;
CTextureHandle LoadSpriteTextureImpl(CImageInfo &FromImageInfo, int x, int y, int w, int h);
CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) override;
CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) override;
bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) override;
bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) override;
// simple uncompressed RGBA loaders
IGraphics::CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) override;
int LoadPNG(CImageInfo *pImg, const char *pFilename, int StorageType) override;
void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) override;
void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) override;
void ScreenshotDirect();

View file

@ -149,6 +149,10 @@ struct GL_SVertexTex3DStream
typedef void (*WINDOW_RESIZE_FUNC)(void *pUser);
namespace client_data7 {
struct CDataSprite;
}
class IGraphics : public IInterface
{
MACRO_INTERFACE("graphics", 0)
@ -221,13 +225,23 @@ public:
// destination and source buffer require to have the same width and height
virtual void CopyTextureBufferSub(uint8_t *pDestBuffer, uint8_t *pSourceBuffer, int FullWidth, int FullHeight, int ColorChannelCount, int SubOffsetX, int SubOffsetY, int SubCopyWidth, int SubCopyHeight) = 0;
// destination width must be equal to the subwidth of the source
virtual void CopyTextureFromTextureBufferSub(uint8_t *pDestBuffer, int DestWidth, int DestHeight, uint8_t *pSourceBuffer, int SrcWidth, int SrcHeight, int ColorChannelCount, int SrcSubOffsetX, int SrcSubOffsetY, int SrcSubCopyWidth, int SrcSubCopyHeight) = 0;
virtual int UnloadTexture(CTextureHandle Index) = 0;
virtual int UnloadTextureNew(CTextureHandle &TextureHandle) = 0;
virtual CTextureHandle LoadTextureRaw(int Width, int Height, int Format, const void *pData, int StoreFormat, int Flags, const char *pTexName = NULL) = 0;
virtual int LoadTextureRawSub(CTextureHandle TextureID, int x, int y, int Width, int Height, int Format, const void *pData) = 0;
virtual CTextureHandle LoadTexture(const char *pFilename, int StorageType, int StoreFormat, int Flags) = 0;
virtual void TextureSet(CTextureHandle Texture) = 0;
void TextureClear() { TextureSet(CTextureHandle()); }
virtual CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct CDataSprite *pSprite) = 0;
virtual CTextureHandle LoadSpriteTexture(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) = 0;
virtual bool IsImageSubFullyTransparent(CImageInfo &FromImageInfo, int x, int y, int w, int h) = 0;
virtual bool IsSpriteTextureFullyTransparent(CImageInfo &FromImageInfo, struct client_data7::CDataSprite *pSprite) = 0;
virtual void FlushVertices(bool KeepVertices = false) = 0;
virtual void FlushTextVertices(int TextureSize, int TextTextureIndex, int TextOutlineTextureIndex, float *pOutlineTextColor) = 0;
virtual void FlushVerticesTex3D() = 0;

View file

@ -23,6 +23,12 @@ public:
SHAPE_RECTANGLE,
};
// unused
struct CSampleHandle
{
int m_SampleID;
};
struct CVoiceShapeCircle
{
float m_Radius;

View file

@ -47,7 +47,7 @@ void CDamageInd::Create(vec2 Pos, vec2 Dir)
void CDamageInd::OnRender()
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteStars[0]);
static float s_LastLocalTime = LocalTime();
for(int i = 0; i < m_NumItems;)
{
@ -89,8 +89,10 @@ void CDamageInd::OnInit()
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
m_DmgIndQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_STAR1);
RenderTools()->QuadContainerAddSprite(m_DmgIndQuadContainerIndex, 48.f);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(SPRITE_STAR1, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_DmgIndQuadContainerIndex, 48.f * ScaleX, 48.f * ScaleY);
}
void CDamageInd::Reset()

View file

@ -170,9 +170,7 @@ void CEffects::PlayerDeath(vec2 Pos, int ClientID)
BloodColor = m_pClient->m_aClients[ClientID].m_RenderInfo.m_ColorBody;
else
{
const CSkins::CSkin *s = m_pClient->m_pSkins->Get(m_pClient->m_aClients[ClientID].m_SkinID);
if(s)
BloodColor = s->m_BloodColor;
BloodColor = m_pClient->m_aClients[ClientID].m_RenderInfo.m_BloodColor;
}
}

View file

@ -111,9 +111,7 @@ void CEmoticon::OnRender()
DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64);
Graphics()->QuadsEnd();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
Graphics()->QuadsBegin();
Graphics()->WrapClamp();
for(int i = 0; i < NUM_EMOTICONS; i++)
{
float Angle = 2 * pi * i / NUM_EMOTICONS;
@ -124,14 +122,17 @@ void CEmoticon::OnRender()
float Size = Selected ? 80.0f : 50.0f;
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[i]);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
Graphics()->QuadsBegin();
float NudgeX = 150.0f * cosf(Angle);
float NudgeY = 150.0f * sinf(Angle);
RenderTools()->SelectSprite(SPRITE_OOP + i);
IGraphics::CQuadItem QuadItem(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY, Size, Size);
Graphics()->QuadsDraw(&QuadItem, 1);
Graphics()->QuadsEnd();
}
Graphics()->QuadsEnd();
Graphics()->WrapNormal();
if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
{
@ -143,8 +144,6 @@ void CEmoticon::OnRender()
CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[g_Config.m_ClDummy]].m_RenderInfo;
Graphics()->TextureSet(pTeeInfo->m_Texture);
for(int i = 0; i < NUM_EMOTES; i++)
{
float Angle = 2 * pi * i / NUM_EMOTES;

View file

@ -352,16 +352,18 @@ void CGhost::InitRenderInfos(CGhostItem *pGhost)
CTeeRenderInfo *pRenderInfo = &pGhost->m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pRenderInfo->m_BloodColor = pSkin->m_BloodColor;
pRenderInfo->m_CustomColoredSkin = pGhost->m_Skin.m_UseCustomColor;
if(pGhost->m_Skin.m_UseCustomColor)
{
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_ColorTexture;
pRenderInfo->m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorBody));
pRenderInfo->m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(pGhost->m_Skin.m_ColorFeet));
}
else
{
pRenderInfo->m_Texture = m_pClient->m_pSkins->Get(SkinId)->m_OrgTexture;
pRenderInfo->m_ColorBody = ColorRGBA(1, 1, 1);
pRenderInfo->m_ColorFeet = ColorRGBA(1, 1, 1);
}
@ -624,3 +626,31 @@ int CGhost::GetLastRaceTick()
{
return m_LastRaceTick;
}
void CGhost::RefindSkin()
{
char aSkinName[64];
for(int i = 0; i < (int)(sizeof(m_aActiveGhosts) / sizeof(m_aActiveGhosts[0])); ++i)
{
IntsToStr(&m_aActiveGhosts[i].m_Skin.m_Skin0, 6, aSkinName);
if(aSkinName[0] != '\0')
{
CTeeRenderInfo *pRenderInfo = &m_aActiveGhosts[i].m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}
IntsToStr(&m_CurGhost.m_Skin.m_Skin0, 6, aSkinName);
if(aSkinName[0] != '\0')
{
CTeeRenderInfo *pRenderInfo = &m_CurGhost.m_RenderInfo;
int SkinId = m_pClient->m_pSkins->Find(aSkinName);
const CSkin *pSkin = m_pClient->m_pSkins->Get(SkinId);
pRenderInfo->m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pRenderInfo->m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}

View file

@ -168,6 +168,8 @@ public:
class IGhostRecorder *GhostRecorder() const { return m_pGhostRecorder; }
int GetLastRaceTick();
void RefindSkin();
};
#endif

View file

@ -87,14 +87,16 @@ void CHud::OnInit()
// all cursors
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteCursor);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 64.f);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteCursor, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
}
// the flags
RenderTools()->SelectSprite(SPRITE_FLAG_RED);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_HudQuadContainerIndex, 0.f, 0.f, 8.f, 16.f);
}
@ -257,7 +259,7 @@ void CHud::RenderScoreHud()
if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick(g_Config.m_ClDummy) / BlinkTimer) & 1)))
{
// draw flag
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->TextureSet(t == 0 ? GameClient()->m_GameSkin.m_SpriteFlagRed : GameClient()->m_GameSkin.m_SpriteFlagBlue);
int QuadOffset = NUM_WEAPONS * 10 + 40 + NUM_WEAPONS + t;
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, Whole - ScoreWidthMax - ImageSize, StartY + 1.0f + t * 20);
@ -659,10 +661,13 @@ void CHud::RenderCursor()
return;
MapscreenToGroup(m_pClient->m_pCamera->m_Center.x, m_pClient->m_pCamera->m_Center.y, Layers()->GameGroup());
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int CurWeapon = m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponCursors[CurWeapon]);
// render cursor
int QuadOffset = NUM_WEAPONS * 10 + 40 + (m_pClient->m_Snap.m_pLocalCharacter->m_Weapon % NUM_WEAPONS);
int QuadOffset = NUM_WEAPONS * 10 + 40 + (CurWeapon);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
Graphics()->RenderQuadContainerAsSprite(m_HudQuadContainerIndex, QuadOffset, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].x, m_pClient->m_pControls->m_TargetPos[g_Config.m_ClDummy].y);
}
@ -677,30 +682,30 @@ void CHud::PrepareHealthAmoQuads()
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i % NUM_WEAPONS].m_pSpriteProj);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int n = 0; n < 10; n++)
Array[n] = IGraphics::CQuadItem(x + n * 12, y + 24, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
}
// health
RenderTools()->SelectSprite(SPRITE_HEALTH_FULL);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
RenderTools()->SelectSprite(SPRITE_HEALTH_EMPTY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
// armor meter
RenderTools()->SelectSprite(SPRITE_ARMOR_FULL);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
RenderTools()->SelectSprite(SPRITE_ARMOR_EMPTY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
for(int i = 0; i < 10; ++i)
Array[i] = IGraphics::CQuadItem(x + i * 12, y + 12, 10, 10);
Graphics()->QuadContainerAddQuads(m_HudQuadContainerIndex, Array, 10);
@ -713,21 +718,34 @@ void CHud::RenderHealthAndAmmo(const CNetObj_Character *pCharacter)
// render ammo count
// render gui stuff
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int CurWeapon = pCharacter->m_Weapon % NUM_WEAPONS;
int QuadOffset = CurWeapon * 10;
int QuadOffset = pCharacter->m_Weapon % NUM_WEAPONS * 10;
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_AmmoCount, 10));
if(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon] != -1)
{
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon]);
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_AmmoCount, 10));
}
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHealthFull);
QuadOffset = NUM_WEAPONS * 10;
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Health, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHealthEmpty);
QuadOffset += 10 + minimum(pCharacter->m_Health, 10);
if(minimum(pCharacter->m_Health, 10) < 10)
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Health, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteArmorFull);
QuadOffset = NUM_WEAPONS * 10 + 20;
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, minimum(pCharacter->m_Armor, 10));
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteArmorEmpty);
QuadOffset += 10 + minimum(pCharacter->m_Armor, 10);
if(minimum(pCharacter->m_Armor, 10) < 10)
Graphics()->RenderQuadContainer(m_HudQuadContainerIndex, QuadOffset, 10 - minimum(pCharacter->m_Armor, 10));

View file

@ -4,6 +4,7 @@
#include <engine/graphics.h>
#include <engine/shared/config.h>
#include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h>
#include <game/client/gameclient.h>
@ -76,52 +77,74 @@ void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID)
Alpha = g_Config.m_ClShowOthersAlpha / 100.0f;
}
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
int CurWeapon = clamp(pCurrent->m_Type, 0, NUM_WEAPONS - 1);
int QuadOffset = 2 + 4 + NUM_WEAPONS + clamp(pCurrent->m_Type, 0, NUM_WEAPONS - 1);
vec2 Vel = Pos - PrevPos;
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick(g_Config.m_ClDummy));
// add particle for this projectile
if(pCurrent->m_Type == WEAPON_GRENADE)
if(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon] != -1)
{
m_pClient->m_pEffects->SmokeTrail(Pos, Vel * -1, Alpha);
static float s_Time = 0.0f;
static float s_LastLocalTime = LocalTime();
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponProjectiles[CurWeapon]);
Graphics()->SetColor(1.f, 1.f, 1.f, Alpha);
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
int QuadOffset = 2 + 8 + NUM_WEAPONS + CurWeapon;
vec2 Vel = Pos - PrevPos;
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), Client()->IntraGameTick(g_Config.m_ClDummy));
// add particle for this projectile
if(pCurrent->m_Type == WEAPON_GRENADE)
{
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
if(!pInfo->m_Paused)
s_Time += (LocalTime() - s_LastLocalTime) * pInfo->m_Speed;
m_pClient->m_pEffects->SmokeTrail(Pos, Vel * -1, Alpha);
static float s_Time = 0.0f;
static float s_LastLocalTime = LocalTime();
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
{
const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo();
if(!pInfo->m_Paused)
s_Time += (LocalTime() - s_LastLocalTime) * pInfo->m_Speed;
}
else
{
if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED))
s_Time += LocalTime() - s_LastLocalTime;
}
Graphics()->QuadsSetRotation(s_Time * pi * 2 * 2 + ItemID);
s_LastLocalTime = LocalTime();
}
else
{
if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED))
s_Time += LocalTime() - s_LastLocalTime;
m_pClient->m_pEffects->BulletTrail(Pos, Alpha);
if(length(Vel) > 0.00001f)
Graphics()->QuadsSetRotation(GetAngle(Vel));
else
Graphics()->QuadsSetRotation(0);
}
Graphics()->QuadsSetRotation(s_Time * pi * 2 * 2 + ItemID);
s_LastLocalTime = LocalTime();
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
}
else
{
m_pClient->m_pEffects->BulletTrail(Pos, Alpha);
if(length(Vel) > 0.00001f)
Graphics()->QuadsSetRotation(GetAngle(Vel));
else
Graphics()->QuadsSetRotation(0);
}
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
}
void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent, bool IsPredicted)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
const int c[] = {
SPRITE_PICKUP_HEALTH,
SPRITE_PICKUP_ARMOR,
SPRITE_PICKUP_WEAPON,
SPRITE_PICKUP_NINJA};
int CurWeapon = clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS - 1);
if(c[pCurrent->m_Type] == SPRITE_PICKUP_HEALTH)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupHealth);
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_ARMOR)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupArmor);
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_WEAPON)
{
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupWeapons[CurWeapon]);
}
else if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpritePickupNinja);
Graphics()->QuadsSetRotation(0);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
@ -133,19 +156,15 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu
if(pCurrent->m_Type == POWERUP_WEAPON)
{
Angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
QuadOffset += 4 + clamp(pCurrent->m_Subtype, 0, NUM_WEAPONS - 1);
QuadOffset += 2 + CurWeapon;
}
else
{
const int c[] = {
SPRITE_PICKUP_HEALTH,
SPRITE_PICKUP_ARMOR,
SPRITE_PICKUP_WEAPON,
SPRITE_PICKUP_NINJA};
QuadOffset += pCurrent->m_Type;
if(c[pCurrent->m_Type] == SPRITE_PICKUP_NINJA)
{
QuadOffset = 2 + 8 - 1; // ninja is the last weapon
m_pClient->m_pEffects->PowerupShine(Pos, vec2(96, 18));
Pos.x -= 10.0f;
}
@ -179,7 +198,10 @@ void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent,
float Angle = 0.0f;
float Size = 42.0f;
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
if(pCurrent->m_Team == TEAM_RED)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->QuadsSetRotation(0);
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
int QuadOffset = 0;
@ -260,9 +282,10 @@ void CItems::RenderLaser(const struct CNetObj_Laser *pCurrent, bool IsPredicted)
// render head
{
int QuadOffset = 2 + 4 + NUM_WEAPONS * 2 + (Client()->GameTick(g_Config.m_ClDummy) % 3);
int CurParticle = (Client()->GameTick(g_Config.m_ClDummy) % 3);
int QuadOffset = 2 + 8 + NUM_WEAPONS * 2 + CurParticle;
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticleSplat[CurParticle]);
Graphics()->QuadsSetRotation(Client()->GameTick(g_Config.m_ClDummy));
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
Graphics()->RenderQuadContainerAsSprite(m_ItemsQuadContainerIndex, QuadOffset, Pos.x, Pos.y);
@ -394,38 +417,56 @@ void CItems::OnInit()
m_ItemsQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_FLAG_RED);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, -21.f, -42.f, 42.f, 84.f);
RenderTools()->SelectSprite(SPRITE_PICKUP_HEALTH);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f);
RenderTools()->SelectSprite(SPRITE_PICKUP_ARMOR);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f);
RenderTools()->SelectSprite(SPRITE_PICKUP_WEAPON);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f);
RenderTools()->SelectSprite(SPRITE_PICKUP_NINJA);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 128.f);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(SPRITE_PICKUP_HEALTH, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
RenderTools()->GetSpriteScale(SPRITE_PICKUP_ARMOR, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 64.f * ScaleX, 64.f * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_HAMMER], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_HAMMER].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_HAMMER].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GUN], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GUN].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GUN].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_SHOTGUN], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_SHOTGUN].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_SHOTGUN].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GRENADE], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GRENADE].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_GRENADE].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(&client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_LASER], ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, client_data7::g_pData->m_Weapons.m_aId[WEAPON_LASER].m_VisualSize * ScaleX, client_data7::g_pData->m_Weapons.m_aId[WEAPON_LASER].m_VisualSize * ScaleY);
RenderTools()->GetSpriteScale(SPRITE_PICKUP_NINJA, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 128.f * ScaleX, 128.f * ScaleY);
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize);
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
}
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteProj);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 32.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 32.f);
}
RenderTools()->SelectSprite(SPRITE_PART_SPLAT01);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false);
RenderTools()->SelectSprite(SPRITE_PART_SPLAT02);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false);
RenderTools()->SelectSprite(SPRITE_PART_SPLAT03);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ItemsQuadContainerIndex, 24.f);
}
void CItems::AddExtraProjectile(CNetObj_Projectile *pProj)

View file

@ -44,20 +44,22 @@ void CKillMessages::OnInit()
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
m_SpriteQuadContainerIndex = Graphics()->CreateQuadContainer();
RenderTools()->SelectSprite(SPRITE_FLAG_RED);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
Graphics()->QuadsSetSubset(1, 0, 0, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X);
Graphics()->QuadsSetSubset(1, 0, 0, 1);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 0.f, 0.f, 28.f, 56.f);
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 96.f);
float ScaleX, ScaleY;
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
RenderTools()->QuadContainerAddSprite(m_SpriteQuadContainerIndex, 96.f * ScaleX, 96.f * ScaleY);
}
}
@ -178,11 +180,15 @@ void CKillMessages::OnRender()
{
if(m_aKillmsgs[r].m_ModeSpecial & 1)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int QuadOffset = 0;
if(m_aKillmsgs[r].m_VictimID == m_aKillmsgs[r].m_FlagCarrierBlue)
++QuadOffset;
if(QuadOffset == 0)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x, y - 16);
}
}
@ -194,7 +200,7 @@ void CKillMessages::OnRender()
x -= 44.0f;
if(m_aKillmsgs[r].m_Weapon >= 0)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[m_aKillmsgs[r].m_Weapon]);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, 4 + m_aKillmsgs[r].m_Weapon, x, y + 28);
}
x -= 52.0f;
@ -205,12 +211,15 @@ void CKillMessages::OnRender()
{
if(m_aKillmsgs[r].m_ModeSpecial & 2)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
int QuadOffset = 2;
if(m_aKillmsgs[r].m_KillerID == m_aKillmsgs[r].m_FlagCarrierBlue)
++QuadOffset;
if(QuadOffset == 2)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
Graphics()->RenderQuadContainerAsSprite(m_SpriteQuadContainerIndex, QuadOffset, x - 56, y - 16);
}
}

View file

@ -1127,13 +1127,14 @@ void CMenus::RenderGhost(CUIRect MainView)
{
if(pItem->Active())
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
Graphics()->WrapClamp();
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[(SPRITE_OOP + 7) - SPRITE_OOP]);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_OOP + 7);
IGraphics::CQuadItem QuadItem(Button.x + Button.w / 2, Button.y + Button.h / 2, 20.0f, 20.0f);
Graphics()->QuadsDraw(&QuadItem, 1);
Graphics()->QuadsEnd();
Graphics()->WrapNormal();
}
}
else if(Id == COL_NAME)

View file

@ -31,6 +31,8 @@
#include "menus.h"
#include "skins.h"
#include <utility>
CMenusKeyBinder CMenus::m_Binder;
CMenusKeyBinder::CMenusKeyBinder()
@ -443,17 +445,18 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
}
// skin info
const CSkins::CSkin *pOwnSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(Skin));
CTeeRenderInfo OwnSkinInfo;
const CSkin *pSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(Skin));
OwnSkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
OwnSkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
OwnSkinInfo.m_CustomColoredSkin = *UseCustomColor;
if(*UseCustomColor)
{
OwnSkinInfo.m_Texture = pOwnSkin->m_ColorTexture;
OwnSkinInfo.m_ColorBody = color_cast<ColorRGBA>(ColorHSLA(*ColorBody).UnclampLighting());
OwnSkinInfo.m_ColorFeet = color_cast<ColorRGBA>(ColorHSLA(*ColorFeet).UnclampLighting());
}
else
{
OwnSkinInfo.m_Texture = pOwnSkin->m_OrgTexture;
OwnSkinInfo.m_ColorBody = ColorRGBA(1.0f, 1.0f, 1.0f);
OwnSkinInfo.m_ColorFeet = ColorRGBA(1.0f, 1.0f, 1.0f);
}
@ -579,7 +582,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
// skin selector
MainView.HSplitTop(20.0f, 0, &MainView);
MainView.HSplitTop(230.0f, &SkinList, &MainView);
static sorted_array<const CSkins::CSkin *> s_paSkinList;
static sorted_array<const CSkin *> s_paSkinList;
static int s_SkinCount = 0;
static float s_ScrollValue = 0.0f;
if(s_InitSkinlist || m_pClient->m_pSkins->Num() != s_SkinCount)
@ -587,7 +590,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
s_paSkinList.clear();
for(int i = 0; i < m_pClient->m_pSkins->Num(); ++i)
{
const CSkins::CSkin *s = m_pClient->m_pSkins->Get(i);
const CSkin *s = m_pClient->m_pSkins->Get(i);
// filter quick search
if(g_Config.m_ClSkinFilterString[0] != '\0' && !str_find_nocase(s->m_aName, g_Config.m_ClSkinFilterString))
@ -611,7 +614,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
UiDoListboxStart(&s_InitSkinlist, &SkinList, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue);
for(int i = 0; i < s_paSkinList.size(); ++i)
{
const CSkins::CSkin *s = s_paSkinList[i];
const CSkin *s = s_paSkinList[i];
if(s == 0)
continue;
@ -623,7 +626,10 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
if(Item.m_Visible)
{
CTeeRenderInfo Info = OwnSkinInfo;
Info.m_Texture = *UseCustomColor ? s->m_ColorTexture : s->m_OrgTexture;
Info.m_CustomColoredSkin = *UseCustomColor;
Info.m_OriginalRenderSkin = s->m_OriginalSkin;
Info.m_ColorableRenderSkin = s->m_ColorableSkin;
Item.m_Rect.HSplitTop(5.0f, 0, &Item.m_Rect); // some margin from the top
RenderTools()->RenderTee(CAnimState::GetIdle(), &Info, 0, vec2(1.0f, 0.0f), vec2(Item.m_Rect.x + 30, Item.m_Rect.y + Item.m_Rect.h / 2));
@ -707,6 +713,10 @@ void CMenus::RenderSettingsTee(CUIRect MainView)
{
m_pClient->m_pSkins->Refresh();
s_InitSkinlist = true;
if(Client()->State() >= IClient::STATE_ONLINE)
{
m_pClient->RefindSkins();
}
}
TextRender()->SetRenderFlags(0);
TextRender()->SetCurFont(NULL);
@ -1910,11 +1920,10 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
// render head
{
Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
int SpriteIndex = time_get() % 3;
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticleSplat[SpriteIndex]);
Graphics()->QuadsBegin();
int Sprites[] = {SPRITE_PART_SPLAT01, SPRITE_PART_SPLAT02, SPRITE_PART_SPLAT03};
RenderTools()->SelectSprite(Sprites[time_get() % 3]);
Graphics()->QuadsSetRotation(time_get());
Graphics()->SetColor(OuterColor.r, OuterColor.g, OuterColor.b, 1.0f);
IGraphics::CQuadItem QuadItem(Pos.x, Pos.y, 24, 24);
@ -1925,10 +1934,11 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
Graphics()->QuadsEnd();
}
// draw laser weapon
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponLaser);
Graphics()->QuadsBegin();
RenderTools()->SelectSprite(SPRITE_WEAPON_LASER_BODY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->DrawSprite(Weapon.x, Weapon.y + Weapon.h / 2.0f, 60.0f);
Graphics()->QuadsEnd();

View file

@ -167,15 +167,13 @@ void CParticles::OnInit()
for(int i = 0; i <= (SPRITE_PART9 - SPRITE_PART_SLICE); ++i)
{
RenderTools()->SelectSprite(i);
RenderTools()->QuadContainerAddSprite(m_ParticleQuadContainerIndex, 1.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_ParticleQuadContainerIndex, 1.f);
}
}
void CParticles::RenderGroup(int Group)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
// don't use the buffer methods here, else the old renderer gets many draw calls
if(Graphics()->IsQuadContainerBufferingEnabled())
{
@ -214,6 +212,7 @@ void CParticles::RenderGroup(int Group)
if(LastColor[0] != m_aParticles[i].m_Color.r || LastColor[1] != m_aParticles[i].m_Color.g || LastColor[2] != m_aParticles[i].m_Color.b || LastColor[3] != m_aParticles[i].m_Color.a || LastQuadOffset != QuadOffset)
{
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[LastQuadOffset - SPRITE_PART_SLICE]);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo);
CurParticleRenderCount = 0;
LastQuadOffset = QuadOffset;
@ -241,6 +240,7 @@ void CParticles::RenderGroup(int Group)
i = m_aParticles[i].m_NextPart;
}
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[LastQuadOffset - SPRITE_PART_SLICE]);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_ParticleQuadContainerIndex, LastQuadOffset, CurParticleRenderCount, s_aParticleRenderInfo);
}
else
@ -248,13 +248,12 @@ void CParticles::RenderGroup(int Group)
int i = m_aFirstPart[Group];
Graphics()->BlendNormal();
//gfx_blend_additive();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
Graphics()->QuadsBegin();
Graphics()->WrapClamp();
while(i != -1)
{
RenderTools()->SelectSprite(m_aParticles[i].m_Spr);
Graphics()->TextureSet(GameClient()->m_ParticlesSkin.m_SpriteParticles[m_aParticles[i].m_Spr - SPRITE_PART_SLICE]);
Graphics()->QuadsBegin();
float a = m_aParticles[i].m_Life / m_aParticles[i].m_LifeSpan;
vec2 p = m_aParticles[i].m_Pos;
float Size = mix(m_aParticles[i].m_StartSize, m_aParticles[i].m_EndSize, a);
@ -271,8 +270,9 @@ void CParticles::RenderGroup(int Group)
Graphics()->QuadsDraw(&QuadItem, 1);
i = m_aParticles[i].m_NextPart;
Graphics()->QuadsEnd();
}
Graphics()->QuadsEnd();
Graphics()->WrapNormal();
Graphics()->BlendNormal();
}
}

View file

@ -45,8 +45,8 @@ void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float
HandPos += DirX * PostRotOffset.x;
HandPos += DirY * PostRotOffset.y;
//Graphics()->TextureSet(data->m_aImages[IMAGE_CHAR_DEFAULT].id);
Graphics()->TextureSet(pInfo->m_Texture);
const CSkin::SSkinTextures *pSkinTextures = pInfo->m_CustomColoredSkin ? &pInfo->m_ColorableRenderSkin : &pInfo->m_OriginalRenderSkin;
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
// two passes
@ -54,6 +54,7 @@ void CPlayers::RenderHand(CTeeRenderInfo *pInfo, vec2 CenterPos, vec2 Dir, float
{
int QuadOffset = NUM_WEAPONS * 2 + i;
Graphics()->QuadsSetRotation(Angle);
Graphics()->TextureSet(i == 0 ? pSkinTextures->m_HandsOutline : pSkinTextures->m_Hands);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, HandPos.x, HandPos.y);
}
}
@ -110,8 +111,6 @@ void CPlayers::RenderHook(
// draw hook
if(Prev.m_HookState > 0 && Player.m_HookState > 0)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
if(ClientID < 0)
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.5f);
@ -127,6 +126,7 @@ void CPlayers::RenderHook(
float d = distance(Pos, HookPos);
vec2 Dir = normalize(Pos - HookPos);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHookHead);
Graphics()->QuadsSetRotation(GetAngle(Dir) + pi);
// render head
int QuadOffset = NUM_WEAPONS * 2 + 2;
@ -148,6 +148,7 @@ void CPlayers::RenderHook(
s_HookChainRenderInfo[HookChainCount].m_Rotation = GetAngle(Dir) + pi;
++HookChainCount;
}
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteHookChain);
Graphics()->RenderQuadContainerAsSpriteMultiple(m_WeaponEmoteQuadContainerIndex, QuadOffset, HookChainCount, s_HookChainRenderInfo);
Graphics()->QuadsSetRotation(0);
@ -356,7 +357,6 @@ void CPlayers::RenderPlayer(
Graphics()->LinesEnd();
}
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Graphics()->QuadsSetRotation(State.GetAttach()->m_Angle * pi * 2 + Angle);
@ -365,6 +365,7 @@ void CPlayers::RenderPlayer(
// normal weapons
int iw = clamp(Player.m_Weapon, 0, NUM_WEAPONS - 1);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[iw]);
int QuadOffset = iw * 2 + (Direction.x < 0 ? 1 : 0);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
@ -442,6 +443,7 @@ void CPlayers::RenderPlayer(
p = Position;
float OffsetX = g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx;
p -= Dir * OffsetX;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponsMuzzles[iw][IteX]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, p.x, p.y);
}
}
@ -498,6 +500,7 @@ void CPlayers::RenderPlayer(
vec2 DirY(-Dir.y, Dir.x);
vec2 MuzzlePos = p + Dir * g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsetx + DirY * OffsetY;
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeaponsMuzzles[iw][IteX]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponSpriteMuzzleQuadContainerIndex[iw], QuadOffset, MuzzlePos.x, MuzzlePos.y);
}
}
@ -566,8 +569,9 @@ void CPlayers::RenderPlayer(
int QuadOffsetToEmoticon = NUM_WEAPONS * 2 + 2 + 2;
if((Player.m_PlayerFlags & PLAYERFLAG_CHATTING) && !m_pClient->m_aClients[ClientID].m_Afk)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
int QuadOffset = QuadOffsetToEmoticon + (SPRITE_DOTDOT - SPRITE_OOP);
int CurEmoticon = (SPRITE_DOTDOT - SPRITE_OOP);
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[CurEmoticon]);
int QuadOffset = QuadOffsetToEmoticon + CurEmoticon;
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f);
@ -580,8 +584,9 @@ void CPlayers::RenderPlayer(
if(g_Config.m_ClAfkEmote && m_pClient->m_aClients[ClientID].m_Afk && !(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);
int CurEmoticon = (SPRITE_ZZZ - SPRITE_OOP);
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[CurEmoticon]);
int QuadOffset = QuadOffsetToEmoticon + CurEmoticon;
Graphics()->SetColor(1.0f, 1.0f, 1.0f, Alpha);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x + 24.f, Position.y - 40.f);
@ -591,8 +596,6 @@ void CPlayers::RenderPlayer(
if(g_Config.m_ClShowEmotes && !m_pClient->m_aClients[ClientID].m_EmoticonIgnore && m_pClient->m_aClients[ClientID].m_EmoticonStart != -1 && m_pClient->m_aClients[ClientID].m_EmoticonStart <= Client()->GameTick(g_Config.m_ClDummy) && m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() > Client()->GameTick(g_Config.m_ClDummy))
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
int SinceStart = Client()->GameTick(g_Config.m_ClDummy) - m_pClient->m_aClients[ClientID].m_EmoticonStart;
int FromEnd = m_pClient->m_aClients[ClientID].m_EmoticonStart + 2 * Client()->GameTickSpeed() - Client()->GameTick(g_Config.m_ClDummy);
@ -616,6 +619,7 @@ void CPlayers::RenderPlayer(
Graphics()->SetColor(1.0f, 1.0f, 1.0f, a * Alpha);
// client_datas::emoticon is an offset from the first emoticon
int QuadOffset = QuadOffsetToEmoticon + m_pClient->m_aClients[ClientID].m_Emoticon;
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[m_pClient->m_aClients[ClientID].m_Emoticon]);
Graphics()->RenderQuadContainerAsSprite(m_WeaponEmoteQuadContainerIndex, QuadOffset, Position.x, Position.y - 23.f - 32.f * h, 1.f, (64.f * h) / 64.f);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
@ -638,18 +642,25 @@ void CPlayers::OnRender()
int Skin = m_pClient->m_pSkins->Find("x_ninja");
if(Skin != -1)
{
if(IsTeamplay)
m_aRenderInfo[i].m_Texture = m_pClient->m_pSkins->Get(Skin)->m_ColorTexture;
else
const CSkin *pSkin = m_pClient->m_pSkins->Get(Skin);
m_aRenderInfo[i].m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_aRenderInfo[i].m_ColorableRenderSkin = pSkin->m_ColorableSkin;
m_aRenderInfo[i].m_BloodColor = pSkin->m_BloodColor;
m_aRenderInfo[i].m_CustomColoredSkin = IsTeamplay;
if(!IsTeamplay)
{
m_aRenderInfo[i].m_Texture = m_pClient->m_pSkins->Get(Skin)->m_OrgTexture;
m_aRenderInfo[i].m_ColorBody = ColorRGBA(1, 1, 1);
m_aRenderInfo[i].m_ColorFeet = ColorRGBA(1, 1, 1);
}
}
}
}
m_RenderInfoSpec.m_Texture = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find("x_spec"))->m_OrgTexture;
int Skin = m_pClient->m_pSkins->Find("x_spec");
const CSkin *pSkin = m_pClient->m_pSkins->Get(Skin);
m_RenderInfoSpec.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_RenderInfoSpec.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
m_RenderInfoSpec.m_BloodColor = pSkin->m_BloodColor;
m_RenderInfoSpec.m_CustomColoredSkin = false;
m_RenderInfoSpec.m_Size = 64.0f;
// render other players in three passes, first pass we render spectees,
@ -714,27 +725,30 @@ void CPlayers::OnInit()
for(int i = 0; i < NUM_WEAPONS; ++i)
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, 0);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize);
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, SPRITE_FLAG_FLIP_Y);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
Graphics()->QuadsSetSubset(0, 1, 1, 0);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
}
float ScaleX, ScaleY;
// at the end the hand
RenderTools()->SelectSprite(SPRITE_TEE_HAND_OUTLINE, 0, 0, 0);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f, false);
RenderTools()->SelectSprite(SPRITE_TEE_HAND, 0, 0, 0);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 20.f);
RenderTools()->SelectSprite(SPRITE_HOOK_HEAD);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f);
RenderTools()->SelectSprite(SPRITE_HOOK_CHAIN);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, -12.f, -8.f, 24.f, 16.f);
for(int i = 0; i < NUM_EMOTICONS; ++i)
{
RenderTools()->SelectSprite(SPRITE_OOP + i);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 64.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
RenderTools()->QuadContainerAddSprite(m_WeaponEmoteQuadContainerIndex, 64.f);
}
for(int i = 0; i < NUM_WEAPONS; ++i)
@ -744,21 +758,18 @@ void CPlayers::OnInit()
{
if(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n])
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], 0);
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], ScaleX, ScaleY);
}
if(WEAPON_NINJA == i)
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f);
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f * ScaleX, 160.f * ScaleY);
else
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize);
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
if(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n])
{
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_aSpriteMuzzles[n], SPRITE_FLAG_FLIP_Y);
}
Graphics()->QuadsSetSubset(0, 1, 1, 0);
if(WEAPON_NINJA == i)
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f);
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], 160.f * ScaleX, 160.f * ScaleY);
else
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize);
RenderTools()->QuadContainerAddSprite(m_WeaponSpriteMuzzleQuadContainerIndex[i], g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
}
}

View file

@ -440,10 +440,13 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch
m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID))
{
Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
if(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
RenderTools()->SelectSprite(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
Graphics()->QuadsBegin();
Graphics()->QuadsSetSubset(1, 0, 0, 1);
float Size = LineHeight;
IGraphics::CQuadItem QuadItem(TeeOffset + 0.0f, y - 5.0f - Spacing / 2.0f, Size / 2.0f, Size);

View file

@ -55,7 +55,7 @@ int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser)
return pSelf->LoadSkin(aNameWithoutPng, aBuf, DirType);
}
int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType, int *pGetSkinID)
{
char aBuf[512];
CImageInfo Info;
@ -68,7 +68,15 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
CSkin Skin;
Skin.m_IsVanilla = IsVanillaSkin(pName);
Skin.m_OrgTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
Skin.m_OriginalSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]);
Skin.m_OriginalSkin.m_BodyOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY_OUTLINE]);
Skin.m_OriginalSkin.m_Feet = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT]);
Skin.m_OriginalSkin.m_FeetOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT_OUTLINE]);
Skin.m_OriginalSkin.m_Hands = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND]);
Skin.m_OriginalSkin.m_HandsOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND_OUTLINE]);
for(int i = 0; i < 6; ++i)
Skin.m_OriginalSkin.m_Eyes[i] = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_EYE_NORMAL + i]);
int BodySize = 96; // body size
if(BodySize > Info.m_Height)
@ -139,7 +147,16 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
d[y * Pitch + x * 4 + 2] = v;
}
Skin.m_ColorTexture = Graphics()->LoadTextureRaw(Info.m_Width, Info.m_Height, Info.m_Format, Info.m_pData, Info.m_Format, 0);
Skin.m_ColorableSkin.m_Body = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY]);
Skin.m_ColorableSkin.m_BodyOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_BODY_OUTLINE]);
Skin.m_ColorableSkin.m_Feet = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT]);
Skin.m_ColorableSkin.m_FeetOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_FOOT_OUTLINE]);
Skin.m_ColorableSkin.m_Hands = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND]);
Skin.m_ColorableSkin.m_HandsOutline = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_HAND_OUTLINE]);
for(int i = 0; i < 6; ++i)
Skin.m_ColorableSkin.m_Eyes[i] = Graphics()->LoadSpriteTexture(Info, &g_pData->m_aSprites[SPRITE_TEE_EYE_NORMAL + i]);
free(Info.m_pData);
// set skin data
@ -151,6 +168,9 @@ int CSkins::LoadSkin(const char *pName, const char *pPath, int DirType)
}
m_aSkins.add(Skin);
if(pGetSkinID)
*pGetSkinID = m_aSkins.size() - 1;
return 0;
}
@ -178,12 +198,23 @@ void CSkins::Refresh()
{
for(int i = 0; i < m_aSkins.size(); ++i)
{
if(m_aSkins[i].m_OrgTexture != -1)
Graphics()->UnloadTexture(m_aSkins[i].m_OrgTexture);
m_aSkins[i].m_OrgTexture = IGraphics::CTextureHandle();
if(m_aSkins[i].m_ColorTexture != -1)
Graphics()->UnloadTexture(m_aSkins[i].m_ColorTexture);
m_aSkins[i].m_ColorTexture = IGraphics::CTextureHandle();
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Body);
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_BodyOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Feet);
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_FeetOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Hands);
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_HandsOutline);
for(int n = 0; n < 6; ++n)
Graphics()->UnloadTextureNew(m_aSkins[i].m_OriginalSkin.m_Eyes[n]);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Body);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_BodyOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Feet);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_FeetOutline);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Hands);
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_HandsOutline);
for(int n = 0; n < 6; ++n)
Graphics()->UnloadTextureNew(m_aSkins[i].m_ColorableSkin.m_Eyes[n]);
}
m_aSkins.clear();
@ -205,7 +236,7 @@ int CSkins::Num()
return m_aSkins.size();
}
const CSkins::CSkin *CSkins::Get(int Index)
const CSkin *CSkins::Get(int Index)
{
if(Index < 0)
{
@ -256,19 +287,20 @@ int CSkins::FindImpl(const char *pName)
auto d = ::find_binary(m_aDownloadSkins.all(), pName);
if(!d.empty())
{
int SkinID = -1;
if(d.front().m_pTask && d.front().m_pTask->State() == HTTP_DONE)
{
char aPath[MAX_PATH_LENGTH];
str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", d.front().m_aName);
Storage()->RenameFile(d.front().m_aPath, aPath, IStorage::TYPE_SAVE);
LoadSkin(d.front().m_aName, aPath, IStorage::TYPE_SAVE);
LoadSkin(d.front().m_aName, aPath, IStorage::TYPE_SAVE, &SkinID);
d.front().m_pTask = nullptr;
}
if(d.front().m_pTask && (d.front().m_pTask->State() == HTTP_ERROR || d.front().m_pTask->State() == HTTP_ABORTED))
{
d.front().m_pTask = nullptr;
}
return -1;
return SkinID;
}
CDownloadSkin Skin;

View file

@ -7,25 +7,11 @@
#include <base/vmath.h>
#include <engine/client/http.h>
#include <game/client/component.h>
#include <game/client/skin.h>
class CSkins : public CComponent
{
public:
// do this better and nicer
struct CSkin
{
bool m_IsVanilla;
IGraphics::CTextureHandle m_OrgTexture;
IGraphics::CTextureHandle m_ColorTexture;
char m_aName[24];
ColorRGBA m_BloodColor;
bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
bool operator<(const char *pOther) const { return str_comp(m_aName, pOther) < 0; }
bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); }
};
struct CDownloadSkin
{
std::shared_ptr<CGetFile> m_pTask;
@ -49,7 +35,7 @@ private:
sorted_array<CDownloadSkin> m_aDownloadSkins;
char m_EventSkinPrefix[24];
int LoadSkin(const char *pName, const char *pPath, int DirType);
int LoadSkin(const char *pName, const char *pPath, int DirType, int *pGetSkinID = NULL);
int FindImpl(const char *pName);
static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser);
};

View file

@ -395,10 +395,13 @@ void CSpectator::OnRender()
m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID || m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID))
{
Graphics()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
if(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID)
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagBlue);
else
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
RenderTools()->SelectSprite(m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == m_pClient->m_Snap.m_paInfoByDDTeamName[i]->m_ClientID ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
Graphics()->QuadsBegin();
Graphics()->QuadsSetSubset(1, 0, 0, 1);
float Size = LineHeight;
IGraphics::CQuadItem QuadItem(Width / 2.0f + x - LineHeight / 5.0f, Height / 2.0f + y - LineHeight / 3.0f, Size / 2.0f, Size);

View file

@ -217,29 +217,31 @@ void CStatboard::RenderGlobalStats()
px += 85;
}
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin();
px -= 40;
for(int i = 0; i < NUM_WEAPONS; i++)
{
if(!aDisplayWeapon[i])
continue;
RenderTools()->SelectSprite(g_pData->m_Weapons.m_aId[i].m_pSpriteBody);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(g_pData->m_Weapons.m_aId[i].m_pSpriteBody, ScaleX, ScaleY);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteWeapons[i]);
Graphics()->QuadsBegin();
if(i == 0)
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f);
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * 0.8f * ScaleY);
else
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize);
RenderTools()->DrawSprite(x + px, y + 10, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleX, g_pData->m_Weapons.m_aId[i].m_VisualSize * ScaleY);
px += 80;
Graphics()->QuadsEnd();
}
Graphics()->QuadsEnd();
if(GameWithFlags)
{
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->TextureSet(GameClient()->m_GameSkin.m_SpriteFlagRed);
float ScaleX, ScaleY;
RenderTools()->GetSpriteScale(SPRITE_FLAG_RED, ScaleX, ScaleY);
Graphics()->QuadsBegin();
Graphics()->QuadsSetRotation(0.78f);
RenderTools()->SelectSprite(SPRITE_FLAG_RED);
RenderTools()->DrawSprite(x + px, y + 15, 48);
RenderTools()->DrawSprite(x + px, y + 15, 48 * ScaleX, 48 * ScaleY);
Graphics()->QuadsEnd();
}
else

View file

@ -18,6 +18,7 @@
#include <engine/updater.h>
#include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h>
#include <base/math.h>
@ -292,8 +293,8 @@ void CGameClient::OnInit()
// propagate pointers
m_UI.SetGraphics(Graphics(), TextRender());
m_RenderTools.m_pGraphics = Graphics();
m_RenderTools.m_pUI = UI();
m_RenderTools.Init(Graphics(), UI(), this);
int64 Start = time_get();
@ -322,6 +323,10 @@ void CGameClient::OnInit()
char aBuf[256];
m_GameSkinLoaded = false;
m_ParticlesSkinLoaded = false;
m_EmoticonsSkinLoaded = false;
// setup load amount// load textures
for(int i = 0; i < g_pData->m_NumImages; i++)
{
@ -1238,13 +1243,14 @@ void CGameClient::OnNewSnapshot()
pClient->m_SkinInfo.m_Size = 64;
// find new skin
pClient->m_SkinID = g_GameClient.m_pSkins->Find(pClient->m_aSkinName);
const CSkin *pSkin = m_pSkins->Get(m_pSkins->Find(pClient->m_aSkinName));
pClient->m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
pClient->m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
pClient->m_SkinInfo.m_BloodColor = pSkin->m_BloodColor;
pClient->m_SkinInfo.m_CustomColoredSkin = pClient->m_UseCustomColor;
if(pClient->m_UseCustomColor)
pClient->m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(pClient->m_SkinID)->m_ColorTexture;
else
if(!pClient->m_UseCustomColor)
{
pClient->m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(pClient->m_SkinID)->m_OrgTexture;
pClient->m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1);
pClient->m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
}
@ -1923,7 +1929,7 @@ void CGameClient::CClientData::UpdateRenderInfo()
// force team colors
if(g_GameClient.m_Snap.m_pGameInfoObj && g_GameClient.m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS)
{
m_RenderInfo.m_Texture = g_GameClient.m_pSkins->Get(m_SkinID)->m_ColorTexture;
m_RenderInfo.m_CustomColoredSkin = true;
const int TeamColors[2] = {65461, 10223541};
if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE)
{
@ -1943,7 +1949,6 @@ void CGameClient::CClientData::Reset()
m_aName[0] = 0;
m_aClan[0] = 0;
m_Country = -1;
m_SkinID = -1;
m_Team = 0;
m_Angle = 0;
m_Emoticon = 0;
@ -1957,7 +1962,10 @@ void CGameClient::CClientData::Reset()
m_Afk = false;
m_Paused = false;
m_Spec = false;
m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(-1)->m_OrgTexture;
m_SkinInfo.m_BloodColor = ColorRGBA(1, 1, 1);
m_SkinInfo.m_ColorableRenderSkin.Reset();
m_SkinInfo.m_OriginalRenderSkin.Reset();
m_SkinInfo.m_CustomColoredSkin = false;
m_SkinInfo.m_ColorBody = ColorRGBA(1, 1, 1);
m_SkinInfo.m_ColorFeet = ColorRGBA(1, 1, 1);
@ -2514,10 +2522,99 @@ bool CGameClient::IsOtherTeam(int ClientID)
void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
{
if(g_pData->m_aImages[IMAGE_GAME].m_Id != -1)
if(m_GameSkinLoaded)
{
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_GAME].m_Id);
g_pData->m_aImages[IMAGE_GAME].m_Id = IGraphics::CTextureHandle();
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHealthFull);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHealthEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteArmorFull);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteArmorEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammerCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenadeCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaCursor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaserCursor);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeaponCursors[i] = IGraphics::CTextureHandle();
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHookChain);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteHookHead);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammer);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenade);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinja);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaser);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeapons[i] = IGraphics::CTextureHandle();
}
for(int i = 0; i < 9; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteParticles[i]);
}
for(int i = 0; i < 3; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteStars[i]);
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGrenadeProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponHammerProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaProjectile);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponLaserProjectile);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpriteWeaponProjectiles[i] = IGraphics::CTextureHandle();
}
for(int i = 0; i < 3; ++i)
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponGunMuzzles[i]);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponShotgunMuzzles[i]);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteWeaponNinjaMuzzles[i]);
for(int n = 0; n < 6; ++n)
{
m_GameSkin.m_SpriteWeaponsMuzzles[n][i] = IGraphics::CTextureHandle();
}
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupHealth);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupArmor);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupGrenade);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupShotgun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupLaser);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupNinja);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupGun);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpritePickupHammer);
for(int i = 0; i < 6; ++i)
{
m_GameSkin.m_SpritePickupWeapons[i] = IGraphics::CTextureHandle();
}
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteFlagBlue);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteFlagRed);
if(m_GameSkin.IsSixup())
{
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarFullLeft);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarFull);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarEmpty);
Graphics()->UnloadTextureNew(m_GameSkin.m_SpriteNinjaBarEmptyRight);
}
m_GameSkinLoaded = false;
}
char aPath[MAX_PATH_LENGTH];
@ -2546,17 +2643,131 @@ void CGameClient::LoadGameSkin(const char *pPath, bool AsDir)
}
else if(PngLoaded)
{
g_pData->m_aImages[IMAGE_GAME].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
m_GameSkin.m_SpriteHealthFull = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_FULL]);
m_GameSkin.m_SpriteHealthEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HEALTH_EMPTY]);
m_GameSkin.m_SpriteArmorFull = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_ARMOR_FULL]);
m_GameSkin.m_SpriteArmorEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_ARMOR_EMPTY]);
m_GameSkin.m_SpriteWeaponHammerCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_HAMMER_CURSOR]);
m_GameSkin.m_SpriteWeaponGunCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_CURSOR]);
m_GameSkin.m_SpriteWeaponShotgunCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_CURSOR]);
m_GameSkin.m_SpriteWeaponGrenadeCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_CURSOR]);
m_GameSkin.m_SpriteWeaponNinjaCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_CURSOR]);
m_GameSkin.m_SpriteWeaponLaserCursor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_CURSOR]);
m_GameSkin.m_SpriteWeaponCursors[0] = m_GameSkin.m_SpriteWeaponHammerCursor;
m_GameSkin.m_SpriteWeaponCursors[1] = m_GameSkin.m_SpriteWeaponGunCursor;
m_GameSkin.m_SpriteWeaponCursors[2] = m_GameSkin.m_SpriteWeaponShotgunCursor;
m_GameSkin.m_SpriteWeaponCursors[3] = m_GameSkin.m_SpriteWeaponGrenadeCursor;
m_GameSkin.m_SpriteWeaponCursors[4] = m_GameSkin.m_SpriteWeaponLaserCursor;
m_GameSkin.m_SpriteWeaponCursors[5] = m_GameSkin.m_SpriteWeaponNinjaCursor;
// weapons and hook
m_GameSkin.m_SpriteHookChain = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HOOK_CHAIN]);
m_GameSkin.m_SpriteHookHead = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_HOOK_HEAD]);
m_GameSkin.m_SpriteWeaponHammer = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_HAMMER_BODY]);
m_GameSkin.m_SpriteWeaponGun = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_BODY]);
m_GameSkin.m_SpriteWeaponShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_BODY]);
m_GameSkin.m_SpriteWeaponGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_BODY]);
m_GameSkin.m_SpriteWeaponNinja = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_BODY]);
m_GameSkin.m_SpriteWeaponLaser = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_BODY]);
m_GameSkin.m_SpriteWeapons[0] = m_GameSkin.m_SpriteWeaponHammer;
m_GameSkin.m_SpriteWeapons[1] = m_GameSkin.m_SpriteWeaponGun;
m_GameSkin.m_SpriteWeapons[2] = m_GameSkin.m_SpriteWeaponShotgun;
m_GameSkin.m_SpriteWeapons[3] = m_GameSkin.m_SpriteWeaponGrenade;
m_GameSkin.m_SpriteWeapons[4] = m_GameSkin.m_SpriteWeaponLaser;
m_GameSkin.m_SpriteWeapons[5] = m_GameSkin.m_SpriteWeaponNinja;
// particles
for(int i = 0; i < 9; ++i)
{
m_GameSkin.m_SpriteParticles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART1 + i]);
}
// stars
for(int i = 0; i < 3; ++i)
{
m_GameSkin.m_SpriteStars[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_STAR1 + i]);
}
// projectiles
m_GameSkin.m_SpriteWeaponGunProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_PROJ]);
m_GameSkin.m_SpriteWeaponShotgunProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_PROJ]);
m_GameSkin.m_SpriteWeaponGrenadeProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GRENADE_PROJ]);
// these weapons have no projectiles
m_GameSkin.m_SpriteWeaponHammerProjectile = IGraphics::CTextureHandle();
m_GameSkin.m_SpriteWeaponNinjaProjectile = IGraphics::CTextureHandle();
m_GameSkin.m_SpriteWeaponLaserProjectile = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_LASER_PROJ]);
m_GameSkin.m_SpriteWeaponProjectiles[0] = m_GameSkin.m_SpriteWeaponHammerProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[1] = m_GameSkin.m_SpriteWeaponGunProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[2] = m_GameSkin.m_SpriteWeaponShotgunProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[3] = m_GameSkin.m_SpriteWeaponGrenadeProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[4] = m_GameSkin.m_SpriteWeaponLaserProjectile;
m_GameSkin.m_SpriteWeaponProjectiles[5] = m_GameSkin.m_SpriteWeaponNinjaProjectile;
// muzzles
for(int i = 0; i < 3; ++i)
{
m_GameSkin.m_SpriteWeaponGunMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_GUN_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponShotgunMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_SHOTGUN_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponNinjaMuzzles[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_WEAPON_NINJA_MUZZLE1 + i]);
m_GameSkin.m_SpriteWeaponsMuzzles[1][i] = m_GameSkin.m_SpriteWeaponGunMuzzles[i];
m_GameSkin.m_SpriteWeaponsMuzzles[2][i] = m_GameSkin.m_SpriteWeaponShotgunMuzzles[i];
m_GameSkin.m_SpriteWeaponsMuzzles[5][i] = m_GameSkin.m_SpriteWeaponNinjaMuzzles[i];
}
// pickups
m_GameSkin.m_SpritePickupHealth = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_HEALTH]);
m_GameSkin.m_SpritePickupArmor = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_ARMOR]);
m_GameSkin.m_SpritePickupGrenade = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GRENADE]);
m_GameSkin.m_SpritePickupShotgun = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_SHOTGUN]);
m_GameSkin.m_SpritePickupLaser = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_LASER]);
m_GameSkin.m_SpritePickupNinja = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PICKUP_NINJA]);
m_GameSkin.m_SpritePickupGun = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_GUN]);
m_GameSkin.m_SpritePickupHammer = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_PICKUP_HAMMER]);
m_GameSkin.m_SpritePickupWeapons[0] = m_GameSkin.m_SpritePickupHammer;
m_GameSkin.m_SpritePickupWeapons[1] = m_GameSkin.m_SpritePickupGun;
m_GameSkin.m_SpritePickupWeapons[2] = m_GameSkin.m_SpritePickupShotgun;
m_GameSkin.m_SpritePickupWeapons[3] = m_GameSkin.m_SpritePickupGrenade;
m_GameSkin.m_SpritePickupWeapons[4] = m_GameSkin.m_SpritePickupLaser;
m_GameSkin.m_SpritePickupWeapons[5] = m_GameSkin.m_SpritePickupNinja;
// flags
m_GameSkin.m_SpriteFlagBlue = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_FLAG_BLUE]);
m_GameSkin.m_SpriteFlagRed = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_FLAG_RED]);
// ninja bar (0.7)
if(!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL_LEFT]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY]) ||
!Graphics()->IsSpriteTextureFullyTransparent(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY_RIGHT]))
{
m_GameSkin.m_SpriteNinjaBarFullLeft = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL_LEFT]);
m_GameSkin.m_SpriteNinjaBarFull = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_FULL]);
m_GameSkin.m_SpriteNinjaBarEmpty = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY]);
m_GameSkin.m_SpriteNinjaBarEmptyRight = Graphics()->LoadSpriteTexture(ImgInfo, &client_data7::g_pData->m_aSprites[client_data7::SPRITE_NINJA_BAR_EMPTY_RIGHT]);
}
m_GameSkinLoaded = true;
free(ImgInfo.m_pData);
}
}
void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
{
if(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id != -1)
if(m_EmoticonsSkinLoaded)
{
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id);
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = IGraphics::CTextureHandle();
for(int i = 0; i < 16; ++i)
Graphics()->UnloadTextureNew(m_EmoticonsSkin.m_SpriteEmoticons[i]);
m_EmoticonsSkinLoaded = false;
}
char aPath[MAX_PATH_LENGTH];
@ -2585,17 +2796,32 @@ void CGameClient::LoadEmoticonsSkin(const char *pPath, bool AsDir)
}
else if(PngLoaded)
{
g_pData->m_aImages[IMAGE_EMOTICONS].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
for(int i = 0; i < 16; ++i)
m_EmoticonsSkin.m_SpriteEmoticons[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_OOP + i]);
m_EmoticonsSkinLoaded = true;
free(ImgInfo.m_pData);
}
}
void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
{
if(g_pData->m_aImages[IMAGE_PARTICLES].m_Id != -1)
if(m_ParticlesSkinLoaded)
{
Graphics()->UnloadTexture(g_pData->m_aImages[IMAGE_PARTICLES].m_Id);
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = IGraphics::CTextureHandle();
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSlice);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleBall);
for(int i = 0; i < 3; ++i)
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSplat[i]);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleSmoke);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleShell);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleExpl);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleAirJump);
Graphics()->UnloadTextureNew(m_ParticlesSkin.m_SpriteParticleHit);
for(int i = 0; i < (int)(sizeof(m_ParticlesSkin.m_SpriteParticles) / sizeof(m_ParticlesSkin.m_SpriteParticles[0])); ++i)
m_ParticlesSkin.m_SpriteParticles[i] = IGraphics::CTextureHandle();
m_ParticlesSkinLoaded = false;
}
char aPath[MAX_PATH_LENGTH];
@ -2624,11 +2850,45 @@ void CGameClient::LoadParticlesSkin(const char *pPath, bool AsDir)
}
else if(PngLoaded)
{
g_pData->m_aImages[IMAGE_PARTICLES].m_Id = Graphics()->LoadTextureRaw(ImgInfo.m_Width, ImgInfo.m_Height, ImgInfo.m_Format, ImgInfo.m_pData, ImgInfo.m_Format, 0, aPath);
m_ParticlesSkin.m_SpriteParticleSlice = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SLICE]);
m_ParticlesSkin.m_SpriteParticleBall = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_BALL]);
for(int i = 0; i < 3; ++i)
m_ParticlesSkin.m_SpriteParticleSplat[i] = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SPLAT01 + i]);
m_ParticlesSkin.m_SpriteParticleSmoke = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SMOKE]);
m_ParticlesSkin.m_SpriteParticleShell = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_SHELL]);
m_ParticlesSkin.m_SpriteParticleExpl = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_EXPL01]);
m_ParticlesSkin.m_SpriteParticleAirJump = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_AIRJUMP]);
m_ParticlesSkin.m_SpriteParticleHit = Graphics()->LoadSpriteTexture(ImgInfo, &g_pData->m_aSprites[SPRITE_PART_HIT01]);
m_ParticlesSkin.m_SpriteParticles[0] = m_ParticlesSkin.m_SpriteParticleSlice;
m_ParticlesSkin.m_SpriteParticles[1] = m_ParticlesSkin.m_SpriteParticleBall;
for(int i = 0; i < 3; ++i)
m_ParticlesSkin.m_SpriteParticles[2 + i] = m_ParticlesSkin.m_SpriteParticleSplat[i];
m_ParticlesSkin.m_SpriteParticles[5] = m_ParticlesSkin.m_SpriteParticleSmoke;
m_ParticlesSkin.m_SpriteParticles[6] = m_ParticlesSkin.m_SpriteParticleShell;
m_ParticlesSkin.m_SpriteParticles[7] = m_ParticlesSkin.m_SpriteParticleExpl;
m_ParticlesSkin.m_SpriteParticles[8] = m_ParticlesSkin.m_SpriteParticleAirJump;
m_ParticlesSkin.m_SpriteParticles[9] = m_ParticlesSkin.m_SpriteParticleHit;
m_ParticlesSkinLoaded = true;
free(ImgInfo.m_pData);
}
}
void CGameClient::RefindSkins()
{
for(int i = 0; i < MAX_CLIENTS; ++i)
{
if(m_aClients[i].m_aSkinName[0] != '\0')
{
const CSkin *pSkin = m_pSkins->Get(m_pSkins->Find(m_aClients[i].m_aSkinName));
m_aClients[i].m_SkinInfo.m_OriginalRenderSkin = pSkin->m_OriginalSkin;
m_aClients[i].m_SkinInfo.m_ColorableRenderSkin = pSkin->m_ColorableSkin;
}
}
m_pGhost->RefindSkin();
}
void CGameClient::LoadMapSettings()
{
// Reset Tunezones

View file

@ -247,7 +247,6 @@ public:
char m_aClan[MAX_CLAN_LENGTH];
int m_Country;
char m_aSkinName[64];
int m_SkinID;
int m_SkinColor;
int m_Team;
int m_Emoticon;
@ -456,6 +455,116 @@ public:
void LoadEmoticonsSkin(const char *pPath, bool AsDir = false);
void LoadParticlesSkin(const char *pPath, bool AsDir = false);
void RefindSkins();
struct SClientGameSkin
{
// health armor hud
IGraphics::CTextureHandle m_SpriteHealthFull;
IGraphics::CTextureHandle m_SpriteHealthEmpty;
IGraphics::CTextureHandle m_SpriteArmorFull;
IGraphics::CTextureHandle m_SpriteArmorEmpty;
// cursors
IGraphics::CTextureHandle m_SpriteWeaponHammerCursor;
IGraphics::CTextureHandle m_SpriteWeaponGunCursor;
IGraphics::CTextureHandle m_SpriteWeaponShotgunCursor;
IGraphics::CTextureHandle m_SpriteWeaponGrenadeCursor;
IGraphics::CTextureHandle m_SpriteWeaponNinjaCursor;
IGraphics::CTextureHandle m_SpriteWeaponLaserCursor;
IGraphics::CTextureHandle m_SpriteWeaponCursors[6];
// weapons and hook
IGraphics::CTextureHandle m_SpriteHookChain;
IGraphics::CTextureHandle m_SpriteHookHead;
IGraphics::CTextureHandle m_SpriteWeaponHammer;
IGraphics::CTextureHandle m_SpriteWeaponGun;
IGraphics::CTextureHandle m_SpriteWeaponShotgun;
IGraphics::CTextureHandle m_SpriteWeaponGrenade;
IGraphics::CTextureHandle m_SpriteWeaponNinja;
IGraphics::CTextureHandle m_SpriteWeaponLaser;
IGraphics::CTextureHandle m_SpriteWeapons[6];
// particles
IGraphics::CTextureHandle m_SpriteParticles[9];
// stars
IGraphics::CTextureHandle m_SpriteStars[3];
// projectiles
IGraphics::CTextureHandle m_SpriteWeaponGunProjectile;
IGraphics::CTextureHandle m_SpriteWeaponShotgunProjectile;
IGraphics::CTextureHandle m_SpriteWeaponGrenadeProjectile;
IGraphics::CTextureHandle m_SpriteWeaponHammerProjectile;
IGraphics::CTextureHandle m_SpriteWeaponNinjaProjectile;
IGraphics::CTextureHandle m_SpriteWeaponLaserProjectile;
IGraphics::CTextureHandle m_SpriteWeaponProjectiles[6];
// muzzles
IGraphics::CTextureHandle m_SpriteWeaponGunMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponShotgunMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponNinjaMuzzles[3];
IGraphics::CTextureHandle m_SpriteWeaponsMuzzles[6][3];
// pickups
IGraphics::CTextureHandle m_SpritePickupHealth;
IGraphics::CTextureHandle m_SpritePickupArmor;
IGraphics::CTextureHandle m_SpritePickupGrenade;
IGraphics::CTextureHandle m_SpritePickupShotgun;
IGraphics::CTextureHandle m_SpritePickupLaser;
IGraphics::CTextureHandle m_SpritePickupNinja;
IGraphics::CTextureHandle m_SpritePickupGun;
IGraphics::CTextureHandle m_SpritePickupHammer;
IGraphics::CTextureHandle m_SpritePickupWeapons[6];
// flags
IGraphics::CTextureHandle m_SpriteFlagBlue;
IGraphics::CTextureHandle m_SpriteFlagRed;
// ninja bar (0.7)
IGraphics::CTextureHandle m_SpriteNinjaBarFullLeft;
IGraphics::CTextureHandle m_SpriteNinjaBarFull;
IGraphics::CTextureHandle m_SpriteNinjaBarEmpty;
IGraphics::CTextureHandle m_SpriteNinjaBarEmptyRight;
bool IsSixup()
{
return m_SpriteNinjaBarFullLeft != -1;
}
};
SClientGameSkin m_GameSkin;
bool m_GameSkinLoaded;
struct SClientParticlesSkin
{
IGraphics::CTextureHandle m_SpriteParticleSlice;
IGraphics::CTextureHandle m_SpriteParticleBall;
IGraphics::CTextureHandle m_SpriteParticleSplat[3];
IGraphics::CTextureHandle m_SpriteParticleSmoke;
IGraphics::CTextureHandle m_SpriteParticleShell;
IGraphics::CTextureHandle m_SpriteParticleExpl;
IGraphics::CTextureHandle m_SpriteParticleAirJump;
IGraphics::CTextureHandle m_SpriteParticleHit;
IGraphics::CTextureHandle m_SpriteParticles[10];
};
SClientParticlesSkin m_ParticlesSkin;
bool m_ParticlesSkinLoaded;
struct SClientEmoticonsSkin
{
IGraphics::CTextureHandle m_SpriteEmoticons[16];
};
SClientEmoticonsSkin m_EmoticonsSkin;
bool m_EmoticonsSkinLoaded;
private:
bool m_DDRaceMsgSent[2];
int m_ShowOthers[2];

View file

@ -9,7 +9,10 @@
#include <engine/graphics.h>
#include <engine/map.h>
#include <engine/shared/config.h>
#include <game/client/components/skins.h>
#include <game/client/gameclient.h>
#include <game/generated/client_data.h>
#include <game/generated/client_data7.h>
#include <game/generated/protocol.h>
#include <game/layers.h>
@ -36,32 +39,33 @@ static void layershot_end()
config.cl_layershot++;
}*/
void CRenderTools::Init(IGraphics *pGraphics, CUI *pUI)
void CRenderTools::Init(IGraphics *pGraphics, CUI *pUI, CGameClient *pGameClient)
{
m_pGraphics = pGraphics;
m_pUI = pUI;
m_pGameClient = (CGameClient *)pGameClient;
m_TeeQuadContainerIndex = Graphics()->CreateQuadContainer();
Graphics()->SetColor(1.f, 1.f, 1.f, 1.f);
SelectSprite(SPRITE_TEE_BODY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false);
SelectSprite(SPRITE_TEE_BODY_OUTLINE, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f);
SelectSprite(SPRITE_TEE_EYE_PAIN, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false);
SelectSprite(SPRITE_TEE_EYE_HAPPY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false);
SelectSprite(SPRITE_TEE_EYE_SURPRISE, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false);
SelectSprite(SPRITE_TEE_EYE_ANGRY, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false);
SelectSprite(SPRITE_TEE_EYE_NORMAL, 0, 0, 0);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f, false);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, 64.f * 0.4f);
SelectSprite(SPRITE_TEE_FOOT_OUTLINE, 0, 0, 0);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
SelectSprite(SPRITE_TEE_FOOT, 0, 0, 0);
Graphics()->QuadsSetSubset(0, 0, 1, 1);
QuadContainerAddSprite(m_TeeQuadContainerIndex, -32.f, -16.f, 64.f, 32.f);
}
@ -108,38 +112,57 @@ void CRenderTools::SelectSprite(int Id, int Flags, int sx, int sy)
SelectSprite(&g_pData->m_aSprites[Id], Flags, sx, sy);
}
void CRenderTools::GetSpriteScale(client_data7::CDataSprite *pSprite, float &ScaleX, float &ScaleY)
{
int w = pSprite->m_W;
int h = pSprite->m_H;
float f = sqrtf(h * h + w * w);
ScaleX = w / f;
ScaleY = h / f;
}
void CRenderTools::GetSpriteScale(struct CDataSprite *pSprite, float &ScaleX, float &ScaleY)
{
int w = pSprite->m_W;
int h = pSprite->m_H;
float f = sqrtf(h * h + w * w);
ScaleX = w / f;
ScaleY = h / f;
}
void CRenderTools::GetSpriteScale(int id, float &ScaleX, float &ScaleY)
{
GetSpriteScale(&g_pData->m_aSprites[id], ScaleX, ScaleY);
}
void CRenderTools::DrawSprite(float x, float y, float Size)
{
IGraphics::CQuadItem QuadItem(x, y, Size * gs_SpriteWScale, Size * gs_SpriteHScale);
Graphics()->QuadsDraw(&QuadItem, 1);
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size, bool DoSpriteScale)
void CRenderTools::DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight)
{
if(DoSpriteScale)
{
IGraphics::CQuadItem QuadItem(x, y, Size * gs_SpriteWScale, Size * gs_SpriteHScale);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
else
{
IGraphics::CQuadItem QuadItem(x, y, Size, Size);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
IGraphics::CQuadItem QuadItem(x, y, ScaledWidth, ScaledHeight);
Graphics()->QuadsDraw(&QuadItem, 1);
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size, bool DoSpriteScale)
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float Size)
{
if(DoSpriteScale)
{
IGraphics::CQuadItem QuadItem(-(Size * gs_SpriteWScale) / 2.f, -(Size * gs_SpriteHScale) / 2.f, (Size * gs_SpriteWScale), (Size * gs_SpriteHScale));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
else
{
IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
IGraphics::CQuadItem QuadItem(x, y, Size, Size);
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Size)
{
IGraphics::CQuadItem QuadItem(-(Size) / 2.f, -(Size) / 2.f, (Size), (Size));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height)
{
IGraphics::CQuadItem QuadItem(-(Width) / 2.f, -(Height) / 2.f, (Width), (Height));
Graphics()->QuadContainerAddQuads(QuadContainerIndex, &QuadItem, 1);
}
void CRenderTools::QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height)
@ -494,8 +517,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
vec2 Direction = Dir;
vec2 Position = Pos;
//Graphics()->TextureSet(data->images[IMAGE_CHAR_DEFAULT].id);
Graphics()->TextureSet(pInfo->m_Texture);
const CSkin::SSkinTextures *pSkinTextures = pInfo->m_CustomColoredSkin ? &pInfo->m_ColorableRenderSkin : &pInfo->m_OriginalRenderSkin;
// first pass we draw the outline
// second pass we draw the filling
@ -515,6 +537,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
Graphics()->SetColor(pInfo->m_ColorBody.r, pInfo->m_ColorBody.g, pInfo->m_ColorBody.b, Alpha);
vec2 BodyPos = Position + vec2(pAnim->GetBody()->m_X, pAnim->GetBody()->m_Y) * AnimScale;
float BodySize = g_Config.m_ClFatSkins ? BaseSize * 1.3f : BaseSize;
Graphics()->TextureSet(OutLine == 1 ? pSkinTextures->m_BodyOutline : pSkinTextures->m_Body);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, OutLine, BodyPos.x, BodyPos.y, BodySize / 64.f, BodySize / 64.f);
// draw eyes
@ -522,19 +545,24 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
{
int QuadOffset = 2;
int EyeQuadOffset = 0;
int TeeEye = 0;
switch(Emote)
{
case EMOTE_PAIN:
EyeQuadOffset = 0;
TeeEye = SPRITE_TEE_EYE_PAIN - SPRITE_TEE_EYE_NORMAL;
break;
case EMOTE_HAPPY:
EyeQuadOffset = 1;
TeeEye = SPRITE_TEE_EYE_HAPPY - SPRITE_TEE_EYE_NORMAL;
break;
case EMOTE_SURPRISE:
EyeQuadOffset = 2;
TeeEye = SPRITE_TEE_EYE_SURPRISE - SPRITE_TEE_EYE_NORMAL;
break;
case EMOTE_ANGRY:
EyeQuadOffset = 3;
TeeEye = SPRITE_TEE_EYE_ANGRY - SPRITE_TEE_EYE_NORMAL;
break;
default:
EyeQuadOffset = 4;
@ -546,6 +574,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
float EyeSeparation = (0.075f - 0.010f * absolute(Direction.x)) * BaseSize;
vec2 Offset = vec2(Direction.x * 0.125f, -0.05f + Direction.y * 0.10f) * BaseSize;
Graphics()->TextureSet(pSkinTextures->m_Eyes[TeeEye]);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x - EyeSeparation + Offset.x, BodyPos.y + Offset.y, EyeScale / (64.f * 0.4f), h / (64.f * 0.4f));
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset + EyeQuadOffset, BodyPos.x + EyeSeparation + Offset.x, BodyPos.y + Offset.y, -EyeScale / (64.f * 0.4f), h / (64.f * 0.4f));
}
@ -573,6 +602,7 @@ void CRenderTools::RenderTee(CAnimState *pAnim, CTeeRenderInfo *pInfo, int Emote
Graphics()->SetColor(pInfo->m_ColorFeet.r * cs, pInfo->m_ColorFeet.g * cs, pInfo->m_ColorFeet.b * cs, Alpha);
Graphics()->TextureSet(OutLine == 1 ? pSkinTextures->m_FeetOutline : pSkinTextures->m_Feet);
Graphics()->RenderQuadContainerAsSprite(m_TeeQuadContainerIndex, QuadOffset, Position.x + pFoot->m_X * AnimScale, Position.y + pFoot->m_Y * AnimScale, w / 64.f, h / 32.f);
}
}

View file

@ -7,6 +7,7 @@
#include <base/color.h>
#include <base/vmath.h>
#include <engine/graphics.h>
#include <game/client/skin.h>
#include <game/mapitems.h>
class CTeeRenderInfo
@ -20,7 +21,11 @@ public:
m_GotAirJump = 1;
};
IGraphics::CTextureHandle m_Texture;
CSkin::SSkinTextures m_OriginalRenderSkin;
CSkin::SSkinTextures m_ColorableRenderSkin;
bool m_CustomColoredSkin;
ColorRGBA m_BloodColor;
ColorRGBA m_ColorBody;
ColorRGBA m_ColorFeet;
float m_Size;
@ -48,20 +53,28 @@ class CRenderTools
public:
class IGraphics *m_pGraphics;
class CUI *m_pUI;
class CGameClient *m_pGameClient;
class IGraphics *Graphics() const { return m_pGraphics; }
class CUI *UI() const { return m_pUI; }
class CGameClient *GameClient() const { return m_pGameClient; }
void Init(class IGraphics *pGraphics, class CUI *pUI);
void Init(class IGraphics *pGraphics, class CUI *pUI, class CGameClient *pGameClient);
//typedef struct SPRITE;
void SelectSprite(struct CDataSprite *pSprite, int Flags = 0, int sx = 0, int sy = 0);
void SelectSprite(int id, int Flags = 0, int sx = 0, int sy = 0);
void GetSpriteScale(client_data7::CDataSprite *pSprite, float &ScaleX, float &ScaleY);
void GetSpriteScale(struct CDataSprite *pSprite, float &ScaleX, float &ScaleY);
void GetSpriteScale(int id, float &ScaleX, float &ScaleY);
void DrawSprite(float x, float y, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size, bool DoSpriteScale = true);
void QuadContainerAddSprite(int QuadContainerIndex, float size, bool DoSpriteScale = true);
void DrawSprite(float x, float y, float ScaledWidth, float ScaledHeight);
void QuadContainerAddSprite(int QuadContainerIndex, float x, float y, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float size);
void QuadContainerAddSprite(int QuadContainerIndex, float Width, float Height);
void QuadContainerAddSprite(int QuadContainerIndex, float X, float Y, float Width, float Height);
// rects

51
src/game/client/skin.h Normal file
View file

@ -0,0 +1,51 @@
#ifndef GAME_CLIENT_SKIN_H
#define GAME_CLIENT_SKIN_H
#include <base/color.h>
#include <base/tl/sorted_array.h>
#include <base/vmath.h>
#include <engine/graphics.h>
// do this better and nicer
struct CSkin
{
bool m_IsVanilla;
struct SSkinTextures
{
IGraphics::CTextureHandle m_Body;
IGraphics::CTextureHandle m_BodyOutline;
IGraphics::CTextureHandle m_Feet;
IGraphics::CTextureHandle m_FeetOutline;
IGraphics::CTextureHandle m_Hands;
IGraphics::CTextureHandle m_HandsOutline;
IGraphics::CTextureHandle m_Eyes[6];
void Reset()
{
m_Body = IGraphics::CTextureHandle();
m_BodyOutline = IGraphics::CTextureHandle();
m_Feet = IGraphics::CTextureHandle();
m_FeetOutline = IGraphics::CTextureHandle();
m_Hands = IGraphics::CTextureHandle();
m_HandsOutline = IGraphics::CTextureHandle();
for(int i = 0; i < 6; ++i)
m_Eyes[i] = IGraphics::CTextureHandle();
}
};
SSkinTextures m_OriginalSkin;
SSkinTextures m_ColorableSkin;
char m_aName[24];
ColorRGBA m_BloodColor;
bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; }
bool operator<(const char *pOther) const { return str_comp(m_aName, pOther) < 0; }
bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); }
};
#endif

View file

@ -6417,7 +6417,8 @@ void CEditor::Init()
m_pTextRender = Kernel()->RequestInterface<ITextRender>();
m_pStorage = Kernel()->RequestInterface<IStorage>();
m_pSound = Kernel()->RequestInterface<ISound>();
m_RenderTools.Init(m_pGraphics, &m_UI);
CGameClient *pGameClient = (CGameClient *)Kernel()->RequestInterface<IGameClient>();
m_RenderTools.Init(m_pGraphics, &m_UI, pGameClient);
m_UI.SetGraphics(m_pGraphics, m_pTextRender);
m_Map.m_pEditor = this;