Fix default guild mark, color and format
This commit is contained in:
@@ -42,9 +42,7 @@ void CGuildMarkImage::Create()
|
|||||||
|
|
||||||
bool CGuildMarkImage::Save(const char* c_szFileName)
|
bool CGuildMarkImage::Save(const char* c_szFileName)
|
||||||
{
|
{
|
||||||
if (stbi_write_tga(c_szFileName, WIDTH, HEIGHT, 4, m_apxImage) == 0)
|
return stbi_write_tga(c_szFileName, WIDTH, HEIGHT, 4, m_apxImage) != 0;
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGuildMarkImage::Build(const char * c_szFileName)
|
bool CGuildMarkImage::Build(const char * c_szFileName)
|
||||||
@@ -59,6 +57,25 @@ bool CGuildMarkImage::Build(const char * c_szFileName)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadSingleMarkFromFile(const char* path, Pixel* outBuf)
|
||||||
|
{
|
||||||
|
int w, h, channels;
|
||||||
|
unsigned char* data = stbi_load(path, &w, &h, &channels, 4);
|
||||||
|
if (!data)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (w != SGuildMark::WIDTH || h != SGuildMark::HEIGHT)
|
||||||
|
{
|
||||||
|
sys_err("LoadSingleMarkFromFile: '%s' is %dx%d, expected %dx%d", path, w, h, SGuildMark::WIDTH, SGuildMark::HEIGHT);
|
||||||
|
stbi_image_free(data);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(outBuf, data, SGuildMark::SIZE * sizeof(Pixel));
|
||||||
|
stbi_image_free(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGuildMarkImage::Load(const char * c_szFileName)
|
bool CGuildMarkImage::Load(const char * c_szFileName)
|
||||||
{
|
{
|
||||||
int w, h, channels;
|
int w, h, channels;
|
||||||
|
|||||||
@@ -105,4 +105,6 @@ class CGuildMarkImage
|
|||||||
Pixel m_apxImage[WIDTH * HEIGHT];
|
Pixel m_apxImage[WIDTH * HEIGHT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool LoadSingleMarkFromFile(const char* path, Pixel* outBuf);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -70,6 +70,41 @@ bool CGuildMarkManager::LoadMarkIndex()
|
|||||||
|
|
||||||
LoadMarkImages();
|
LoadMarkImages();
|
||||||
|
|
||||||
|
// Re-apply default mark to any empty slots (handles deleted/rebuilt atlas on restart)
|
||||||
|
Pixel defaultPixels[SGuildMark::SIZE];
|
||||||
|
if (__LoadDefaultMark(defaultPixels))
|
||||||
|
{
|
||||||
|
std::set<DWORD> setModifiedImages;
|
||||||
|
|
||||||
|
for (std::map<DWORD, DWORD>::iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it)
|
||||||
|
{
|
||||||
|
DWORD mID = it->second;
|
||||||
|
DWORD imgIdx = mID / CGuildMarkImage::MARK_TOTAL_COUNT;
|
||||||
|
DWORD posMark = mID % CGuildMarkImage::MARK_TOTAL_COUNT;
|
||||||
|
|
||||||
|
CGuildMarkImage* pkImage = __GetImage(imgIdx);
|
||||||
|
if (!pkImage)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DWORD colMark = posMark % CGuildMarkImage::MARK_COL_COUNT;
|
||||||
|
DWORD rowMark = posMark / CGuildMarkImage::MARK_COL_COUNT;
|
||||||
|
|
||||||
|
SGuildMark kMark;
|
||||||
|
pkImage->GetData(colMark * SGuildMark::WIDTH, rowMark * SGuildMark::HEIGHT,
|
||||||
|
SGuildMark::WIDTH, SGuildMark::HEIGHT, kMark.m_apxBuf);
|
||||||
|
|
||||||
|
if (kMark.IsEmpty())
|
||||||
|
{
|
||||||
|
sys_log(0, "LoadMarkIndex: guild %u slot %u empty, re-applying default mark", it->first, mID);
|
||||||
|
pkImage->SaveMark(posMark, (BYTE*)defaultPixels);
|
||||||
|
setModifiedImages.insert(imgIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::set<DWORD>::iterator it = setModifiedImages.begin(); it != setModifiedImages.end(); ++it)
|
||||||
|
SaveMarkImage(*it);
|
||||||
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -165,7 +200,10 @@ DWORD CGuildMarkManager::GetMarkID(DWORD guildID)
|
|||||||
std::map<DWORD, DWORD>::iterator it = m_mapGID_MarkID.find(guildID);
|
std::map<DWORD, DWORD>::iterator it = m_mapGID_MarkID.find(guildID);
|
||||||
|
|
||||||
if (it == m_mapGID_MarkID.end())
|
if (it == m_mapGID_MarkID.end())
|
||||||
|
{
|
||||||
|
sys_log(0, "Server GetMarkID: guildID=%u NOT FOUND (map size=%zu)", guildID, m_mapGID_MarkID.size());
|
||||||
return INVALID_MARK_ID;
|
return INVALID_MARK_ID;
|
||||||
|
}
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@@ -203,8 +241,10 @@ void CGuildMarkManager::CopyMarkIdx(char * pcBuf) const
|
|||||||
{
|
{
|
||||||
WORD * pwBuf = (WORD *) pcBuf;
|
WORD * pwBuf = (WORD *) pcBuf;
|
||||||
|
|
||||||
|
sys_log(0, "CopyMarkIdx: sending %zu entries", m_mapGID_MarkID.size());
|
||||||
for (std::map<DWORD, DWORD>::const_iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it)
|
for (std::map<DWORD, DWORD>::const_iterator it = m_mapGID_MarkID.begin(); it != m_mapGID_MarkID.end(); ++it)
|
||||||
{
|
{
|
||||||
|
sys_log(0, "CopyMarkIdx: guildID=%u -> markID=%u", it->first, it->second);
|
||||||
*(pwBuf++) = it->first; // guild id
|
*(pwBuf++) = it->first; // guild id
|
||||||
*(pwBuf++) = it->second; // mark id
|
*(pwBuf++) = it->second; // mark id
|
||||||
}
|
}
|
||||||
@@ -242,7 +282,28 @@ DWORD CGuildMarkManager::SaveMark(DWORD guildID, BYTE * pbMarkImage)
|
|||||||
return idMark;
|
return idMark;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SERVER - Allocate a mark slot with default (empty) image for a new guild
|
bool CGuildMarkManager::__LoadDefaultMark(Pixel* outBuf)
|
||||||
|
{
|
||||||
|
static const char* candidates[] = {
|
||||||
|
"mark/default_mark.tga",
|
||||||
|
"mark/default_mark.png",
|
||||||
|
"mark/default_mark.jpg",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(candidates) / sizeof(candidates[0]); ++i)
|
||||||
|
{
|
||||||
|
if (LoadSingleMarkFromFile(candidates[i], outBuf))
|
||||||
|
{
|
||||||
|
sys_log(0, "AllocMark: loaded default mark from '%s'", candidates[i]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sys_log(0, "AllocMark: no default mark found (tried .tga/.png/.jpg); new guild slot will be transparent");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SERVER - Allocate a mark slot for a new guild and fill it with the default mark.
|
||||||
DWORD CGuildMarkManager::AllocMark(DWORD guildID)
|
DWORD CGuildMarkManager::AllocMark(DWORD guildID)
|
||||||
{
|
{
|
||||||
// Check if guild already has a mark
|
// Check if guild already has a mark
|
||||||
@@ -261,6 +322,18 @@ DWORD CGuildMarkManager::AllocMark(DWORD guildID)
|
|||||||
|
|
||||||
sys_log(0, "AllocMark: allocated mark id %u for guild %u", idMark, guildID);
|
sys_log(0, "AllocMark: allocated mark id %u for guild %u", idMark, guildID);
|
||||||
|
|
||||||
|
DWORD imgIdx = idMark / CGuildMarkImage::MARK_TOTAL_COUNT;
|
||||||
|
CGuildMarkImage* pkImage = __GetImage(imgIdx);
|
||||||
|
if (pkImage)
|
||||||
|
{
|
||||||
|
Pixel defaultPixels[SGuildMark::SIZE];
|
||||||
|
if (__LoadDefaultMark(defaultPixels))
|
||||||
|
{
|
||||||
|
pkImage->SaveMark(idMark % CGuildMarkImage::MARK_TOTAL_COUNT, (BYTE*)defaultPixels);
|
||||||
|
SaveMarkImage(imgIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Save the index so the mark slot is persisted
|
// Save the index so the mark slot is persisted
|
||||||
SaveMarkIndex();
|
SaveMarkIndex();
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class CGuildMarkManager : public singleton<CGuildMarkManager>
|
|||||||
CGuildMarkImage * __GetImage(DWORD imgIdx);
|
CGuildMarkImage * __GetImage(DWORD imgIdx);
|
||||||
CGuildMarkImage * __GetImagePtr(DWORD idMark);
|
CGuildMarkImage * __GetImagePtr(DWORD idMark);
|
||||||
|
|
||||||
|
bool __LoadDefaultMark(Pixel* outBuf);
|
||||||
|
|
||||||
std::map<DWORD, CGuildMarkImage *> m_mapIdx_Image; // index = image index
|
std::map<DWORD, CGuildMarkImage *> m_mapIdx_Image; // index = image index
|
||||||
std::map<DWORD, DWORD> m_mapGID_MarkID; // index = guild id
|
std::map<DWORD, DWORD> m_mapGID_MarkID; // index = guild id
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "questmanager.h"
|
#include "questmanager.h"
|
||||||
#include "MarkManager.h"
|
#include "MarkManager.h"
|
||||||
|
#include "MarkImage.h"
|
||||||
|
|
||||||
SGuildMember::SGuildMember(LPCHARACTER ch, BYTE grade, DWORD offer_exp)
|
SGuildMember::SGuildMember(LPCHARACTER ch, BYTE grade, DWORD offer_exp)
|
||||||
: pid(ch->GetPlayerID()), grade(grade), is_general(0), job(ch->GetJob()), level(ch->GetLevel()), offer_exp(offer_exp), name(ch->GetName())
|
: pid(ch->GetPlayerID()), grade(grade), is_general(0), job(ch->GetJob()), level(ch->GetLevel()), offer_exp(offer_exp), name(ch->GetName())
|
||||||
@@ -116,7 +117,16 @@ CGuild::CGuild(TGuildCreateParameter & cp)
|
|||||||
RequestAddMember(cp.master, GUILD_LEADER_GRADE);
|
RequestAddMember(cp.master, GUILD_LEADER_GRADE);
|
||||||
|
|
||||||
// Allocate a mark slot for the new guild
|
// Allocate a mark slot for the new guild
|
||||||
CGuildMarkManager::instance().AllocMark(GetID());
|
DWORD markID = CGuildMarkManager::instance().AllocMark(GetID());
|
||||||
|
sys_log(0, "Guild created: guildID=%u allocated markID=%u", GetID(), markID);
|
||||||
|
|
||||||
|
if (markID != CGuildMarkManager::INVALID_MARK_ID)
|
||||||
|
{
|
||||||
|
WORD imgIdx = static_cast<WORD>(markID / CGuildMarkImage::MARK_TOTAL_COUNT);
|
||||||
|
extern void BroadcastGuildMarkUpdate(DWORD dwGuildID, WORD wImgIdx);
|
||||||
|
BroadcastGuildMarkUpdate(GetID(), imgIdx);
|
||||||
|
sys_log(0, "Broadcast mark update for new guild %u imgIdx %u", GetID(), imgIdx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGuild::Initialize()
|
void CGuild::Initialize()
|
||||||
|
|||||||
Reference in New Issue
Block a user