diff --git a/deps/nanodbc b/deps/nanodbc index 82f3770ec..a5b89ecf4 160000 --- a/deps/nanodbc +++ b/deps/nanodbc @@ -1 +1 @@ -Subproject commit 82f3770ecce56c580cee1c7d1b298aaa8fd862b9 +Subproject commit a5b89ecf469cef1a3927cff3ad0e35f1672f170a diff --git a/deps/zlib b/deps/zlib index 570720b0c..51b7f2abd 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 570720b0c24f9686c33f35a1b3165c1f568b96be +Subproject commit 51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf diff --git a/src/Client/WarFare/GameDef.h b/src/Client/WarFare/GameDef.h index 5c4018840..7ec3f6285 100644 --- a/src/Client/WarFare/GameDef.h +++ b/src/Client/WarFare/GameDef.h @@ -419,17 +419,18 @@ struct __TABLE_PLAYER; struct __InfoPlayerOther { - int iFace; // Face type - int iHair; // Hair type + int iFace; // Face type + int iHair; // Hair type - int iCity; // Affiliated city - std::string szKnights; // Clan name - int iKnightsGrade; // Clan grade - int iKnightsRank; // Clan ranking + int iCity; // Affiliated city + std::string szKnights; // Clan name + int iKnightsGrade; // Clan grade + int iKnightsRank; // Clan ranking + e_KnightsDuty eKnightsDuty; // Clan role/duty - int iRank; // Noble rank - used to identify high-ranking titles like King [1], Senator [2]. - int iTitle; // Bitmask representing various titles/roles including: - // Clan Leader, Clan Assistant, Castle Lord, Feudal Lord, King, Emperor, Party leader, Solo player + int iRank; // Noble rank - used to identify high-ranking titles like King [1], Senator [2]. + int iTitle; // Bitmask representing various titles/roles including: + // Clan Leader, Clan Assistant, Castle Lord, Feudal Lord, King, Emperor, Party leader, Solo player __InfoPlayerOther() { @@ -443,6 +444,7 @@ struct __InfoPlayerOther iCity = 0; iKnightsGrade = 0; iKnightsRank = 0; + eKnightsDuty = KNIGHTS_DUTY_UNKNOWN; iTitle = 0; szKnights.clear(); @@ -465,43 +467,42 @@ struct __InfoPlayerMySelf : public __InfoPlayerOther int iGold; int64_t iExpNext; int64_t iExp; - int iRealmPoint; // National Points - int iRealmPointMonthly; // Monthly National Points - e_KnightsDuty eKnightsDuty; // Clan member position/role/duty - int iWeightMax; // Max weight - int iWeight; // Current weight - int iStrength; // Strength - int iStrength_Delta; // Bonus strength - int iStamina; // Stamina - int iStamina_Delta; // Bonus stamina - int iDexterity; // Dexterity - int iDexterity_Delta; // Bonus dexterity - int iIntelligence; // Intelligence - int iIntelligence_Delta; // Bonus intelligence - int iMagicAttak; // Charisma/Magic Power - int iMagicAttak_Delta; // Bonus Charisma/Magic Power - - int iAttack; // Attack Power - int iAttack_Delta; // Bonus Attack Power - int iGuard; // Defense - int iGuard_Delta; // Bonus Defense - - int iRegistFire; // Fire resistance - int iRegistFire_Delta; // Bonus fire resistance - int iRegistCold; // Cold resistance - int iRegistCold_Delta; // Bonus cold resistance - int iRegistLight; // Lightning resistance - int iRegistLight_Delta; // Bonus lightning resistance - int iRegistMagic; // Magic resistance - int iRegistMagic_Delta; // Bonus magic resistance - int iRegistCurse; // Curse resistance - int iRegistCurse_Delta; // Bonus curse resistance - int iRegistPoison; // Poison resistance - int iRegistPoison_Delta; // Bonus poison resistance - - int iZoneInit; // Initial Zone ID received from the server - int iZoneCur; // Current zone ID - int iVictoryNation; // Last war outcome - 0: Draw, 1: El Morad victory, 2: Karus victory + int iRealmPoint; // National Points + int iRealmPointMonthly; // Monthly National Points + int iWeightMax; // Max weight + int iWeight; // Current weight + int iStrength; // Strength + int iStrength_Delta; // Bonus strength + int iStamina; // Stamina + int iStamina_Delta; // Bonus stamina + int iDexterity; // Dexterity + int iDexterity_Delta; // Bonus dexterity + int iIntelligence; // Intelligence + int iIntelligence_Delta; // Bonus intelligence + int iMagicAttak; // Charisma/Magic Power + int iMagicAttak_Delta; // Bonus Charisma/Magic Power + + int iAttack; // Attack Power + int iAttack_Delta; // Bonus Attack Power + int iGuard; // Defense + int iGuard_Delta; // Bonus Defense + + int iRegistFire; // Fire resistance + int iRegistFire_Delta; // Bonus fire resistance + int iRegistCold; // Cold resistance + int iRegistCold_Delta; // Bonus cold resistance + int iRegistLight; // Lightning resistance + int iRegistLight_Delta; // Bonus lightning resistance + int iRegistMagic; // Magic resistance + int iRegistMagic_Delta; // Bonus magic resistance + int iRegistCurse; // Curse resistance + int iRegistCurse_Delta; // Bonus curse resistance + int iRegistPoison; // Poison resistance + int iRegistPoison_Delta; // Bonus poison resistance + + int iZoneInit; // Initial Zone ID received from the server + int iZoneCur; // Current zone ID + int iVictoryNation; // Last war outcome - 0: Draw, 1: El Morad victory, 2: Karus victory e_ZoneAbilityType eZoneAbilityType; bool bCanTradeWithOtherNation; @@ -529,7 +530,6 @@ struct __InfoPlayerMySelf : public __InfoPlayerOther iExp = 0; iRealmPoint = 0; iRealmPointMonthly = 0; - eKnightsDuty = KNIGHTS_DUTY_UNKNOWN; iWeightMax = 0; iWeight = 0; iStrength = 0; diff --git a/src/Client/WarFare/GameProcMain.cpp b/src/Client/WarFare/GameProcMain.cpp index 76a620e26..dcec36da8 100644 --- a/src/Client/WarFare/GameProcMain.cpp +++ b/src/Client/WarFare/GameProcMain.cpp @@ -1460,14 +1460,14 @@ void CGameProcMain::MsgSend_Continous() // 특정 조건(?)하에서 서버에 // ////////////////////////////////////////////////////////////////////// -void CGameProcMain::MsgSend_Attack( - int iTargetID, float fInterval, float fDistance) // 공격 패킷 날리기 - 테이블의 공격 주기를 같이 줘서 해킹을 막는다. +void CGameProcMain::MsgSend_Attack(int iTargetID, float fInterval, + float fDistance) // 공격 패킷 날리기 - 테이블의 공격 주기를 같이 줘서 해킹을 막는다. { if (s_pPlayer->m_fTimeAfterDeath > 0 || s_pPlayer->IsDead()) - return; // 죽은 넘이다.. + return; // 죽은 넘이다.. - uint8_t byBuff[32]; // 버퍼.. - int iOffset = 0; // 옵셋.. + uint8_t byBuff[32]; // 버퍼.. + int iOffset = 0; // 옵셋.. uint8_t bySuccess = true; @@ -1883,10 +1883,10 @@ bool CGameProcMain::MsgRecv_MyInfo_All(Packet& pkt) s_pPlayer->m_InfoExt.iCity = pkt.read(); std::string szKnightsName = ""; - int iKnightsID = pkt.read(); // 소속 기사단 ID - e_KnightsDuty eKnightsDuty = (e_KnightsDuty) pkt.read(); // 기사단에서의 권한.. + int iKnightsID = pkt.read(); // 소속 기사단 ID + e_KnightsDuty eKnightsDuty = static_cast(pkt.read()); // 기사단에서의 권한.. - // NOTE(srmeier): adding alliance ID and knight's byFlag + // NOTE(srmeier): adding alliance ID and knight's byFlag /*int iAllianceID =*/pkt.read(); /*uint8_t byFlag =*/pkt.read(); @@ -1899,8 +1899,8 @@ bool CGameProcMain::MsgRecv_MyInfo_All(Packet& pkt) /*int16_t sCapeID =*/pkt.read(); // 기사단 관련 세팅.. - s_pPlayer->m_InfoExt.eKnightsDuty = eKnightsDuty; // 기사단에서의 권한.. - s_pPlayer->KnightsInfoSet(iKnightsID, szKnightsName, iKnightsGrade, iKnightsRank); + // s_pPlayer->m_InfoExt.eKnightsDuty = eKnightsDuty; // 기사단에서의 권한.. + s_pPlayer->KnightsInfoSet(iKnightsID, szKnightsName, iKnightsGrade, iKnightsRank, eKnightsDuty); m_pUIVar->UpdateKnightsInfo(); s_pPlayer->m_InfoBase.iHPMax = pkt.read(); @@ -2033,8 +2033,8 @@ bool CGameProcMain::MsgRecv_MyInfo_All(Packet& pkt) e_PartPosition ePart = PART_POS_UNKNOWN; e_PlugPosition ePlug = PLUG_POS_UNKNOWN; - e_ItemType eType = MakeResrcFileNameForUPC( - pItem, pItemExt, &szResrcFN, &szIconFN, ePart, ePlug, s_pPlayer->m_InfoBase.eRace); // 아이템에 따른 파일 이름을 만들어서 + e_ItemType eType = MakeResrcFileNameForUPC(pItem, pItemExt, &szResrcFN, &szIconFN, ePart, ePlug, + s_pPlayer->m_InfoBase.eRace); // 아이템에 따른 파일 이름을 만들어서 if (ITEM_TYPE_UNKNOWN == eType) CLogWriter::Write("MyInfo - slot - Unknown Item"); __ASSERT(ITEM_TYPE_UNKNOWN != eType, "Unknown Item Type"); @@ -2117,8 +2117,8 @@ bool CGameProcMain::MsgRecv_MyInfo_All(Packet& pkt) e_PartPosition ePart = PART_POS_UNKNOWN; e_PlugPosition ePlug = PLUG_POS_UNKNOWN; - e_ItemType eType = MakeResrcFileNameForUPC( - pItem, pItemExt, nullptr, &szIconFN, ePart, ePlug, s_pPlayer->m_InfoBase.eRace); // 아이템에 따른 파일 이름을 만들어서 + e_ItemType eType = MakeResrcFileNameForUPC(pItem, pItemExt, nullptr, &szIconFN, ePart, ePlug, + s_pPlayer->m_InfoBase.eRace); // 아이템에 따른 파일 이름을 만들어서 if (ITEM_TYPE_UNKNOWN == eType) CLogWriter::Write("MyInfo - slot - Unknown Item"); __ASSERT(ITEM_TYPE_UNKNOWN != eType, "Unknown Item"); @@ -2534,11 +2534,11 @@ bool CGameProcMain::MsgRecv_UserIn(Packet& pkt, bool bWithFX) int iNameLen = pkt.read(); pkt.readString(szName, iNameLen); - e_Nation eNation = (e_Nation) pkt.read(); // 소속 국가. 0 이면 없다. 1 + e_Nation eNation = (e_Nation) pkt.read(); // 소속 국가. 0 이면 없다. 1 // 기사단 관련 - int iKnightsID = pkt.read(); // 기사단 ID - /*e_KnightsDuty eKnightsDuty = (e_KnightsDuty)*/ pkt.read(); // 소속 국가. 0 이면 없다. 1 + int iKnightsID = pkt.read(); // 기사단 ID + e_KnightsDuty eKnightsDuty = static_cast(pkt.read()); // 소속 국가. 0 이면 없다. 1 /*int16_t sAllianceID =*/pkt.read(); @@ -2631,7 +2631,7 @@ bool CGameProcMain::MsgRecv_UserIn(Packet& pkt, bool bWithFX) pUPC->m_InfoBase.iAuthority = byAuthority; pUPC->Init(eRace, iFace, iHair, dwItemIDs, iItemDurabilities, byItemFlags); pUPC->RotateTo(DegreesToRadians(rand() % 360), true); - pUPC->KnightsInfoSet(iKnightsID, szKnightsName, iKnightsGrade, iKnightsRank); + pUPC->KnightsInfoSet(iKnightsID, szKnightsName, iKnightsGrade, iKnightsRank, eKnightsDuty); //__KnightsInfoBase* pKIB = m_pUIKnightsOp->KnightsInfoFind(iKightsID); //if(pKIB) pUPC->KnightsNameSet(pKIB->szName, 0xffff0000); @@ -3810,8 +3810,8 @@ void CGameProcMain::MsgRecv_MyInfo_RealmPoint(Packet& pkt) if (m_pUIVar->m_pPageState != nullptr) { - m_pUIVar->m_pPageState->UpdateRealmPoint( - s_pPlayer->m_InfoExt.iRealmPoint, s_pPlayer->m_InfoExt.iRealmPointMonthly); // 국가 기여도는 10을 나누어서 표시 + m_pUIVar->m_pPageState->UpdateRealmPoint(s_pPlayer->m_InfoExt.iRealmPoint, + s_pPlayer->m_InfoExt.iRealmPointMonthly); // 국가 기여도는 10을 나누어서 표시 } } else if (opcode == LOYALTY_CHANGE_MANNER) @@ -6366,8 +6366,7 @@ void CGameProcMain::MsgRecv_Knights(Packet& pkt) break; } - s_pPlayer->m_InfoExt.eKnightsDuty = KNIGHTS_DUTY_UNKNOWN; - s_pPlayer->KnightsInfoSet(0, "", 0, 0); + s_pPlayer->KnightsInfoSet(0, "", 0, 0, KNIGHTS_DUTY_UNKNOWN); m_pUIVar->UpdateKnightsInfo(); } break; @@ -6886,8 +6885,7 @@ void CGameProcMain::MsgRecv_Knights_Create(Packet& pkt) m_pSubProcPerTrade->m_pUIPerTradeDlg->GoldUpdate(); //기사단(클랜)UI업데이트...해라... - s_pPlayer->m_InfoExt.eKnightsDuty = KNIGHTS_DUTY_CHIEF; - s_pPlayer->KnightsInfoSet(iID, szID, iGrade, iRank); + s_pPlayer->KnightsInfoSet(iID, szID, iGrade, iRank, KNIGHTS_DUTY_CHIEF); m_pUIVar->UpdateKnightsInfo(); if (m_pUIVar->m_pPageKnights->IsVisible()) @@ -6945,7 +6943,7 @@ void CGameProcMain::MsgRecv_Knights_Withdraw(Packet& pkt) if (s_pPlayer->IDNumber() == sid) { s_pPlayer->m_InfoBase.iKnightsID = pkt.read(); - s_pPlayer->m_InfoExt.eKnightsDuty = (e_KnightsDuty) pkt.read(); + s_pPlayer->m_InfoExt.eKnightsDuty = static_cast(pkt.read()); m_pUIVar->UpdateKnightsInfo(); s_pPlayer->KnightsInfoSet(s_pPlayer->m_InfoBase.iKnightsID, "", 0, 0); @@ -7021,8 +7019,7 @@ void CGameProcMain::MsgRecv_Knights_Join(Packet& pkt) if (s_pPlayer->IDNumber() == sid) { - s_pPlayer->m_InfoExt.eKnightsDuty = eDuty; - s_pPlayer->KnightsInfoSet(iID, szKnightsName, iGrade, iRank); + s_pPlayer->KnightsInfoSet(iID, szKnightsName, iGrade, iRank, eDuty); m_pUIVar->UpdateKnightsInfo(); szMsg = fmt::format_text_resource(IDS_CLAN_JOIN_SUCCESS); @@ -7120,8 +7117,7 @@ void CGameProcMain::MsgRecv_Knights_Leave(Packet& pkt) if (s_pPlayer->IDNumber() == sid) { - s_pPlayer->m_InfoExt.eKnightsDuty = eDuty; - s_pPlayer->KnightsInfoSet(iID, szKnightsName, iGrade, iRank); + s_pPlayer->KnightsInfoSet(iID, szKnightsName, iGrade, iRank, eDuty); m_pUIVar->UpdateKnightsInfo(); szMsg = fmt::format_text_resource(IDS_CLAN_JOIN_SUCCESS); @@ -7343,7 +7339,7 @@ void CGameProcMain::MsgRecv_Knights_Duty_Change(Packet& pkt) { int sid = pkt.read(); int iID = pkt.read(); - e_KnightsDuty eDuty = (e_KnightsDuty) pkt.read(); + e_KnightsDuty eDuty = static_cast(pkt.read()); if (s_pPlayer->IDNumber() == sid) { diff --git a/src/Client/WarFare/PlayerBase.cpp b/src/Client/WarFare/PlayerBase.cpp index f004cb020..aca7bbfdd 100644 --- a/src/Client/WarFare/PlayerBase.cpp +++ b/src/Client/WarFare/PlayerBase.cpp @@ -295,7 +295,7 @@ void CPlayerBase::IDSet(int iID, const std::string& szID, D3DCOLOR crID) #endif } -void CPlayerBase::KnightsInfoSet(int iID, const std::string& /*szName*/, int iGrade, int iRank) +void CPlayerBase::KnightsInfoSet(int iID, const std::string& /*szName*/, int iGrade, int iRank, e_KnightsDuty /*eDuty*/) { std::string szPlug; if (iGrade > 0 && iGrade <= 5) @@ -744,6 +744,55 @@ void CPlayerBase::Tick() // 회전, 지정된 에니메이션 Tick 및 색깔 } } +constexpr int CLAN_LEADER_LINE_OFFSET = 1; // gap between name baseline and clan leader bar +constexpr int CLAN_LEADER_LINE_THICKNESS = 1; // thickness the clan leader bar + +void CPlayerBase::DrawClanLeaderIndicator(const _POINT& pt) +{ + SIZE nameSize = m_pIDFont->GetSize(); + float fLeft = static_cast(pt.x) - (static_cast(nameSize.cx) / 2.0f); + float fRight = static_cast(pt.x) + (static_cast(nameSize.cx) / 2.0f); + float fTop = static_cast(pt.y + nameSize.cy + CLAN_LEADER_LINE_OFFSET); + float fBottom = static_cast(pt.y + nameSize.cy + CLAN_LEADER_LINE_OFFSET + CLAN_LEADER_LINE_THICKNESS); + + __VertexTransformedColor vLine[4] = { + { fLeft, fTop, 0.0f, 1.0f, 0xff00ff00 }, + { fRight, fTop, 0.0f, 1.0f, 0xff00ff00 }, + { fRight, fBottom, 0.0f, 1.0f, 0xff00ff00 }, + { fLeft, fBottom, 0.0f, 1.0f, 0xff00ff00 }, + }; + + DWORD dwPrevFVF = 0; + if (FAILED(s_lpD3DDev->GetFVF(&dwPrevFVF))) + return; + + IDirect3DBaseTexture9* pPrevTexture = nullptr; + s_lpD3DDev->GetTexture(0, &pPrevTexture); + + if (FAILED(s_lpD3DDev->SetTexture(0, nullptr))) + { + if (pPrevTexture != nullptr) + pPrevTexture->Release(); + return; + } + + if (FAILED(s_lpD3DDev->SetFVF(FVF_TRANSFORMEDCOLOR))) + { + s_lpD3DDev->SetTexture(0, pPrevTexture); + if (pPrevTexture != nullptr) + pPrevTexture->Release(); + return; + } + + s_lpD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vLine, sizeof(__VertexTransformedColor)); + + s_lpD3DDev->SetTexture(0, pPrevTexture); + if (pPrevTexture != nullptr) + pPrevTexture->Release(); + + s_lpD3DDev->SetFVF(dwPrevFVF); +} + void CPlayerBase::Render(float fSunAngle) { if (m_Chr.m_nLOD < 0 || m_Chr.m_nLOD >= MAX_CHR_LOD) @@ -861,6 +910,10 @@ void CPlayerBase::Render(float fSunAngle) m_pIDFont->DrawText(pt.x - (size.cx / 2.0f) + 1.0f, pt.y + 1.0f, 0xff000000, 0); m_pIDFont->DrawText(pt.x - (size.cx / 2.0f) + 0.0f, pt.y + 0.0f, crFont, 0); + // Draw green line under name if clan leader + if (KnightsDuty() == KNIGHTS_DUTY_CHIEF) + DrawClanLeaderIndicator(pt); + //Knight & clan 렌더링.. if (m_pClanFont && m_pClanFont->IsSetText()) { diff --git a/src/Client/WarFare/PlayerBase.h b/src/Client/WarFare/PlayerBase.h index 5464ca35f..cd0b09fcf 100644 --- a/src/Client/WarFare/PlayerBase.h +++ b/src/Client/WarFare/PlayerBase.h @@ -371,7 +371,14 @@ class CPlayerBase : public CGameBase void InfoStringSet(const std::string& szInfo, D3DCOLOR crFont); void BalloonStringSet(const std::string& szBalloon, D3DCOLOR crFont); void IDSet(int iID, const std::string& szID, D3DCOLOR crID); - virtual void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank); + + virtual e_KnightsDuty KnightsDuty() const + { + return KNIGHTS_DUTY_UNKNOWN; + } + + void DrawClanLeaderIndicator(const _POINT& pt); + virtual void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank, e_KnightsDuty eDuty = KNIGHTS_DUTY_UNKNOWN); // ID 는 Character 포인터의 이름으로 대신한다. const std::string& IDString() const diff --git a/src/Client/WarFare/PlayerMySelf.cpp b/src/Client/WarFare/PlayerMySelf.cpp index 3cf30ce04..bdb823349 100644 --- a/src/Client/WarFare/PlayerMySelf.cpp +++ b/src/Client/WarFare/PlayerMySelf.cpp @@ -990,13 +990,14 @@ void CPlayerMySelf::InitHair() } } -void CPlayerMySelf::KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank) +void CPlayerMySelf::KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank, e_KnightsDuty eDuty) { - CPlayerBase::KnightsInfoSet(iID, szName, iGrade, iRank); + CPlayerBase::KnightsInfoSet(iID, szName, iGrade, iRank, eDuty); m_InfoExt.szKnights = szName; m_InfoExt.iKnightsGrade = iGrade; m_InfoExt.iKnightsRank = iRank; + m_InfoExt.eKnightsDuty = eDuty; if (m_InfoExt.szKnights.empty()) { diff --git a/src/Client/WarFare/PlayerMySelf.h b/src/Client/WarFare/PlayerMySelf.h index 8648a3169..f6581560c 100644 --- a/src/Client/WarFare/PlayerMySelf.h +++ b/src/Client/WarFare/PlayerMySelf.h @@ -45,6 +45,11 @@ class CPlayerMySelf : public CPlayerBase void SetMoveTargetPos(const __Vector3& vPos); public: + e_KnightsDuty KnightsDuty() const override + { + return m_InfoExt.eKnightsDuty; + } + void TargetOrPosMove(); void Stun(float fTime); // 일정한 시간동안 기절 시키기. void StunRelease(); // 기절 풀기.. @@ -57,7 +62,7 @@ class CPlayerMySelf : public CPlayerBase // 갖고 있는 정보로 머리카락을 초기화 한다.. void InitHair() override; - void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank) override; + void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank, e_KnightsDuty eDuty = KNIGHTS_DUTY_UNKNOWN) override; void SetSoundAndInitFont(uint32_t dwFontFlag = 0U) override; float AttackableDistance(CPlayerBase* pTarget); diff --git a/src/Client/WarFare/PlayerOther.cpp b/src/Client/WarFare/PlayerOther.cpp index 4e776c7ee..603bd5340 100644 --- a/src/Client/WarFare/PlayerOther.cpp +++ b/src/Client/WarFare/PlayerOther.cpp @@ -201,13 +201,14 @@ void CPlayerOther::InitHair() } } -void CPlayerOther::KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank) +void CPlayerOther::KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank, e_KnightsDuty eDuty) { - CPlayerBase::KnightsInfoSet(iID, szName, iGrade, iRank); + CPlayerBase::KnightsInfoSet(iID, szName, iGrade, iRank, eDuty); m_InfoExt.szKnights = szName; m_InfoExt.iKnightsGrade = iGrade; m_InfoExt.iKnightsRank = iRank; + m_InfoExt.eKnightsDuty = eDuty; if (m_InfoExt.szKnights.empty()) { diff --git a/src/Client/WarFare/PlayerOther.h b/src/Client/WarFare/PlayerOther.h index 043645fe1..07e48fa7a 100644 --- a/src/Client/WarFare/PlayerOther.h +++ b/src/Client/WarFare/PlayerOther.h @@ -17,11 +17,15 @@ class CPlayerOther : public CPlayerNPC public: __InfoPlayerOther m_InfoExt; // 캐릭터 정보 확장.. bool m_bSit; + e_KnightsDuty KnightsDuty() const override + { + return m_InfoExt.eKnightsDuty; + } public: void InitFace() override; void InitHair() override; - void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank) override; + void KnightsInfoSet(int iID, const std::string& szName, int iGrade, int iRank, e_KnightsDuty eDuty = KNIGHTS_DUTY_UNKNOWN) override; void SetSoundAndInitFont(uint32_t dwFontFlag = 0U) override; bool Init(enum e_Race eRace, int iFace, int iHair, uint32_t* pdwItemIDs, int* piItenDurabilities, uint8_t* pbyItemFlags);