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)
|
||||
{
|
||||
if (stbi_write_tga(c_szFileName, WIDTH, HEIGHT, 4, m_apxImage) == 0)
|
||||
return false;
|
||||
return true;
|
||||
return stbi_write_tga(c_szFileName, WIDTH, HEIGHT, 4, m_apxImage) != 0;
|
||||
}
|
||||
|
||||
bool CGuildMarkImage::Build(const char * c_szFileName)
|
||||
@@ -59,6 +57,25 @@ bool CGuildMarkImage::Build(const char * c_szFileName)
|
||||
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)
|
||||
{
|
||||
int w, h, channels;
|
||||
|
||||
@@ -105,4 +105,6 @@ class CGuildMarkImage
|
||||
Pixel m_apxImage[WIDTH * HEIGHT];
|
||||
};
|
||||
|
||||
bool LoadSingleMarkFromFile(const char* path, Pixel* outBuf);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -70,6 +70,41 @@ bool CGuildMarkManager::LoadMarkIndex()
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
@@ -165,7 +200,10 @@ DWORD CGuildMarkManager::GetMarkID(DWORD guildID)
|
||||
std::map<DWORD, DWORD>::iterator it = m_mapGID_MarkID.find(guildID);
|
||||
|
||||
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 it->second;
|
||||
}
|
||||
@@ -203,8 +241,10 @@ void CGuildMarkManager::CopyMarkIdx(char * pcBuf) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
sys_log(0, "CopyMarkIdx: guildID=%u -> markID=%u", it->first, it->second);
|
||||
*(pwBuf++) = it->first; // guild id
|
||||
*(pwBuf++) = it->second; // mark id
|
||||
}
|
||||
@@ -242,7 +282,28 @@ DWORD CGuildMarkManager::SaveMark(DWORD guildID, BYTE * pbMarkImage)
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
|
||||
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
|
||||
SaveMarkIndex();
|
||||
|
||||
|
||||
@@ -65,6 +65,8 @@ class CGuildMarkManager : public singleton<CGuildMarkManager>
|
||||
CGuildMarkImage * __GetImage(DWORD imgIdx);
|
||||
CGuildMarkImage * __GetImagePtr(DWORD idMark);
|
||||
|
||||
bool __LoadDefaultMark(Pixel* outBuf);
|
||||
|
||||
std::map<DWORD, CGuildMarkImage *> m_mapIdx_Image; // index = image index
|
||||
std::map<DWORD, DWORD> m_mapGID_MarkID; // index = guild id
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "log.h"
|
||||
#include "questmanager.h"
|
||||
#include "MarkManager.h"
|
||||
#include "MarkImage.h"
|
||||
|
||||
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())
|
||||
@@ -116,7 +117,16 @@ CGuild::CGuild(TGuildCreateParameter & cp)
|
||||
RequestAddMember(cp.master, GUILD_LEADER_GRADE);
|
||||
|
||||
// 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()
|
||||
|
||||
Reference in New Issue
Block a user