2 Commits

Author SHA1 Message Date
server
64d1cc35c1 issue-9: add sash slot and actor part support 2026-04-16 21:08:27 +02:00
server
1eda856283 issue-4: expose biolog submit network helper 2026-04-16 17:26:51 +02:00
14 changed files with 80 additions and 8 deletions

View File

@@ -103,6 +103,7 @@ class CItemData
{
COSTUME_BODY, //0 갑옷(main look)
COSTUME_HAIR, //1 헤어(탈착가능)
COSTUME_SASH, //2 어깨/등 장식
COSTUME_NUM_TYPES,
};
@@ -252,6 +253,7 @@ class CItemData
WEAR_RING1, //21
WEAR_RING2, //22
WEAR_BELT, //23
WEAR_COSTUME_SASH, //24
WEAR_MAX_NUM,
};
@@ -273,6 +275,7 @@ class CItemData
WEARABLE_COSTUME_BODY = (1 << 12),
WEARABLE_COSTUME_HAIR = (1 << 13),
WEARABLE_BELT = (1 << 14),
WEARABLE_COSTUME_SASH = (1 << 15),
};
enum EApplyTypes

View File

@@ -23,6 +23,7 @@ class CRaceData
PART_HEAD,
PART_WEAPON_LEFT,
PART_HAIR,
PART_ACCE,
PART_MAX_NUM,
};

View File

@@ -101,11 +101,12 @@ enum EDragonSoulStepTypes
#ifdef ENABLE_COSTUME_SYSTEM
const DWORD c_Costume_Slot_Start = c_Equipment_Start + CItemData::WEAR_COSTUME_BODY;
const DWORD c_Costume_Slot_Body = c_Costume_Slot_Start + CItemData::COSTUME_BODY;
const DWORD c_Costume_Slot_Hair = c_Costume_Slot_Start + CItemData::COSTUME_HAIR;
const DWORD c_Costume_Slot_Body = c_Equipment_Start + CItemData::WEAR_COSTUME_BODY;
const DWORD c_Costume_Slot_Hair = c_Equipment_Start + CItemData::WEAR_COSTUME_HAIR;
const DWORD c_Costume_Slot_Sash = c_Equipment_Start + CItemData::WEAR_COSTUME_SASH;
const DWORD c_Costume_Slot_Count = CItemData::COSTUME_NUM_TYPES;
const DWORD c_Costume_Slot_End = c_Costume_Slot_Start + c_Costume_Slot_Count;
const DWORD c_Costume_Slot_End = c_Costume_Slot_Sash + 1;
#endif

View File

@@ -762,6 +762,7 @@ bool CInstanceBase::Create(const SCreateData& c_rkCreateData)
{
SetHair(c_rkCreateData.m_dwHair);
SetWeapon(c_rkCreateData.m_dwWeapon);
SetAcce(c_rkCreateData.m_dwAcce);
}
__Create_SetName(c_rkCreateData);
@@ -2654,6 +2655,25 @@ void CInstanceBase::SetHair(DWORD eHair)
m_GraphicThingInstance.SetHair(eHair);
}
void CInstanceBase::SetAcce(DWORD eAcce)
{
if (IsPC() == false)
return;
m_awPart[CRaceData::PART_ACCE] = eAcce;
m_GraphicThingInstance.DetachModelInstance(CRaceData::PART_MAIN, m_GraphicThingInstance, CRaceData::PART_ACCE);
if (0 == eAcce)
return;
CItemData* pItemData;
if (!CItemManager::Instance().GetItemDataPointer(eAcce, &pItemData))
return;
m_GraphicThingInstance.AttachWeapon(eAcce, CRaceData::PART_MAIN, CRaceData::PART_ACCE);
}
void CInstanceBase::ChangeHair(DWORD eHair)
{
if (!HAIR_COLOR_ENABLE)
@@ -2673,6 +2693,18 @@ void CInstanceBase::ChangeHair(DWORD eHair)
//RefreshState(type, true);
}
void CInstanceBase::ChangeAcce(DWORD eAcce)
{
if (IsPC() == false)
return;
if (GetPart(CRaceData::PART_ACCE) == eAcce)
return;
SetAcce(eAcce);
RefreshState(CRaceMotionData::NAME_WAIT, true);
}
void CInstanceBase::SetArmor(DWORD dwArmor)
{
DWORD dwShape;
@@ -2852,6 +2884,7 @@ bool CInstanceBase::ChangeArmor(DWORD dwArmor)
DWORD dwRace = GetRace();
DWORD eHair = GetPart(CRaceData::PART_HAIR);
DWORD eWeapon = GetPart(CRaceData::PART_WEAPON);
DWORD eAcce = GetPart(CRaceData::PART_ACCE);
float fRot = GetRotation();
float fAdvRot = GetAdvancingRotation();
@@ -2872,6 +2905,7 @@ bool CInstanceBase::ChangeArmor(DWORD dwArmor)
SetArmor(dwArmor);
SetHair(eHair);
SetWeapon(eWeapon);
SetAcce(eAcce);
SetRotation(fRot);
SetAdvancingRotation(fAdvRot);

View File

@@ -26,6 +26,7 @@ class CInstanceBase
DWORD m_dwArmor;
DWORD m_dwWeapon;
DWORD m_dwHair;
DWORD m_dwAcce;
DWORD m_dwMountVnum;
short m_sAlignment;
@@ -497,10 +498,12 @@ class CInstanceBase
void SetArmor(DWORD dwArmor);
void SetShape(DWORD eShape, float fSpecular=0.0f);
void SetHair(DWORD eHair);
void SetAcce(DWORD eAcce);
bool SetWeapon(DWORD eWeapon);
bool ChangeArmor(DWORD dwArmor);
void ChangeWeapon(DWORD eWeapon);
void ChangeHair(DWORD eHair);
void ChangeAcce(DWORD eAcce);
void ChangeGuild(DWORD dwGuildID);
DWORD GetWeaponType();

View File

@@ -77,6 +77,7 @@ void SNetworkActorData::__copy__(const SNetworkActorData& src)
m_dwArmor = src.m_dwArmor;
m_dwWeapon = src.m_dwWeapon;
m_dwHair = src.m_dwHair;
m_dwAcce = src.m_dwAcce;
m_dwOwnerVID = src.m_dwOwnerVID;
@@ -104,6 +105,7 @@ SNetworkActorData::SNetworkActorData()
m_dwArmor=0;
m_dwWeapon=0;
m_dwHair=0;
m_dwAcce=0;
m_dwEmpireID=0;
m_dwOwnerVID=0;
@@ -356,6 +358,7 @@ CInstanceBase* CNetworkActorManager::__AppendCharacterManagerActor(SNetworkActor
kCreateData.m_dwArmor=rkNetActorData.m_dwArmor;
kCreateData.m_dwWeapon=rkNetActorData.m_dwWeapon;
kCreateData.m_dwHair=rkNetActorData.m_dwHair;
kCreateData.m_dwAcce=rkNetActorData.m_dwAcce;
kCreateData.m_isMain=__IsMainActorVID(dwVID);
CInstanceBase* pOldInstance = rkChrMgr.GetInstancePtr(dwVID);
@@ -472,7 +475,8 @@ void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpd
{
pkInstFind->ChangeArmor(c_rkNetUpdateActorData.m_dwArmor);
pkInstFind->ChangeWeapon(c_rkNetUpdateActorData.m_dwWeapon);
pkInstFind->ChangeHair(c_rkNetUpdateActorData.m_dwHair);
pkInstFind->ChangeHair(c_rkNetUpdateActorData.m_dwHair);
pkInstFind->ChangeAcce(c_rkNetUpdateActorData.m_dwAcce);
pkInstFind->ChangeGuild(c_rkNetUpdateActorData.m_dwGuildID);
pkInstFind->SetAffectFlagContainer(c_rkNetUpdateActorData.m_kAffectFlags);
pkInstFind->SetMoveSpeed(c_rkNetUpdateActorData.m_dwMovSpd);
@@ -502,6 +506,7 @@ void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpd
rkNetActorData.m_dwArmor=c_rkNetUpdateActorData.m_dwArmor;
rkNetActorData.m_dwWeapon=c_rkNetUpdateActorData.m_dwWeapon;
rkNetActorData.m_dwHair=c_rkNetUpdateActorData.m_dwHair;
rkNetActorData.m_dwAcce=c_rkNetUpdateActorData.m_dwAcce;
rkNetActorData.m_sAlignment=c_rkNetUpdateActorData.m_sAlignment;
rkNetActorData.m_byPKMode=c_rkNetUpdateActorData.m_byPKMode;
}

View File

@@ -31,6 +31,7 @@ struct SNetworkActorData
DWORD m_dwArmor;
DWORD m_dwWeapon;
DWORD m_dwHair;
DWORD m_dwAcce;
DWORD m_dwOwnerVID;
@@ -85,6 +86,7 @@ struct SNetworkUpdateActorData
DWORD m_dwArmor;
DWORD m_dwWeapon;
DWORD m_dwHair;
DWORD m_dwAcce;
DWORD m_dwMovSpd;
DWORD m_dwAtkSpd;
short m_sAlignment;
@@ -100,6 +102,7 @@ struct SNetworkUpdateActorData
m_dwArmor=0;
m_dwWeapon=0;
m_dwHair=0;
m_dwAcce=0;
m_dwMovSpd=0;
m_dwAtkSpd=0;
m_sAlignment=0;

View File

@@ -1278,6 +1278,7 @@ enum ECharacterEquipmentPart
CHR_EQUIPPART_WEAPON,
CHR_EQUIPPART_HEAD,
CHR_EQUIPPART_HAIR,
CHR_EQUIPPART_ACCE,
CHR_EQUIPPART_NUM,
};

View File

@@ -1437,6 +1437,7 @@ void initchr()
PyModule_AddIntConstant(poModule, "PART_WEAPON", CRaceData::PART_WEAPON);
PyModule_AddIntConstant(poModule, "PART_HEAD", CRaceData::PART_HEAD);
PyModule_AddIntConstant(poModule, "PART_WEAPON_LEFT", CRaceData::PART_WEAPON_LEFT);
PyModule_AddIntConstant(poModule, "PART_ACCE", CRaceData::PART_ACCE);
/////

View File

@@ -654,12 +654,14 @@ void initItem()
// Item Sub Type
PyModule_AddIntConstant(poModule, "COSTUME_TYPE_BODY", CItemData::COSTUME_BODY);
PyModule_AddIntConstant(poModule, "COSTUME_TYPE_HAIR", CItemData::COSTUME_HAIR);
PyModule_AddIntConstant(poModule, "COSTUME_TYPE_SASH", CItemData::COSTUME_SASH);
// 인벤토리 및 장비창에서의 슬롯 번호
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_START", c_Costume_Slot_Start);
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_COUNT", c_Costume_Slot_Count);
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_BODY", c_Costume_Slot_Body);
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_HAIR", c_Costume_Slot_Hair);
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_SASH", c_Costume_Slot_Sash);
PyModule_AddIntConstant(poModule, "COSTUME_SLOT_END", c_Costume_Slot_End);
#endif

View File

@@ -317,6 +317,7 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
// Main Game Phase
bool SendC2CPacket(DWORD dwSize, void * pData);
bool SendChatPacket(const char * c_szChat, BYTE byType = CHAT_TYPE_TALKING);
bool SendBiologSubmit();
bool SendWhisperPacket(const char * name, const char * c_szChat);
bool SendMessengerAddByVIDPacket(DWORD vid);
bool SendMessengerAddByNamePacket(const char * c_szName);

View File

@@ -499,6 +499,13 @@ PyObject* netSendChatPacket(PyObject* poSelf, PyObject* poArgs)
return Py_BuildNone();
}
PyObject* netSendBiologSubmit(PyObject* poSelf, PyObject* poArgs)
{
CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
rkNetStream.SendBiologSubmit();
return Py_BuildNone();
}
PyObject* netSendEmoticon(PyObject* poSelf, PyObject* poArgs)
{
int eEmoticon;
@@ -1700,6 +1707,7 @@ void initnet()
{ "IsConnect", netIsConnect, METH_VARARGS },
{ "SendChatPacket", netSendChatPacket, METH_VARARGS },
{ "SendBiologSubmit", netSendBiologSubmit, METH_VARARGS },
{ "SendEmoticon", netSendEmoticon, METH_VARARGS },
{ "SendWhisperPacket", netSendWhisperPacket, METH_VARARGS },

View File

@@ -788,6 +788,11 @@ bool CPythonNetworkStream::SendChatPacket(const char * c_szChat, BYTE byType)
return true;
}
bool CPythonNetworkStream::SendBiologSubmit()
{
return SendChatPacket("/biolog_submit");
}
//////////////////////////////////////////////////////////////////////////
// Emoticon
void CPythonNetworkStream::RegisterEmoticonString(const char * pcEmoticonString)
@@ -4357,4 +4362,4 @@ void CPythonNetworkStream::Discord_Close()
{
Discord_Shutdown();
}
#endif
#endif

View File

@@ -120,7 +120,8 @@ bool CPythonNetworkStream::RecvCharacterAppendPacket()
kNetActorData.m_dwEmpireID=0;/*chrAddPacket.bEmpire*/;
kNetActorData.m_dwArmor=0;/*chrAddPacket.awPart[CHR_EQUIPPART_ARMOR]*/;
kNetActorData.m_dwWeapon=0;/*chrAddPacket.awPart[CHR_EQUIPPART_WEAPON]*/;
kNetActorData.m_dwHair=0;/*chrAddPacket.awPart[CHR_EQUIPPART_HAIR]*/;
kNetActorData.m_dwHair=0;/*chrAddPacket.awPart[CHR_EQUIPPART_HAIR]*/;
kNetActorData.m_dwAcce=0;/*chrAddPacket.awPart[CHR_EQUIPPART_ACCE]*/;
kNetActorData.m_dwMountVnum=0;/*chrAddPacket.dwMountVnum*/;
kNetActorData.m_dwLevel = 0; // 몬스터 레벨 표시 안함
@@ -178,7 +179,8 @@ bool CPythonNetworkStream::RecvCharacterAdditionalInfo()
kNetActorData.m_dwEmpireID=chrInfoPacket.bEmpire;
kNetActorData.m_dwArmor=chrInfoPacket.awPart[CHR_EQUIPPART_ARMOR];
kNetActorData.m_dwWeapon=chrInfoPacket.awPart[CHR_EQUIPPART_WEAPON];
kNetActorData.m_dwHair=chrInfoPacket.awPart[CHR_EQUIPPART_HAIR];
kNetActorData.m_dwHair=chrInfoPacket.awPart[CHR_EQUIPPART_HAIR];
kNetActorData.m_dwAcce=chrInfoPacket.awPart[CHR_EQUIPPART_ACCE];
kNetActorData.m_dwMountVnum=chrInfoPacket.dwMountVnum;
__RecvCharacterAppendPacket(&kNetActorData);
@@ -212,6 +214,7 @@ bool CPythonNetworkStream::RecvCharacterAppendPacketNew()
kNetActorData.m_dwArmor=chrAddPacket.awPart[CHR_EQUIPPART_ARMOR];
kNetActorData.m_dwWeapon=chrAddPacket.awPart[CHR_EQUIPPART_WEAPON];
kNetActorData.m_dwHair=chrAddPacket.awPart[CHR_EQUIPPART_HAIR];
kNetActorData.m_dwAcce=chrAddPacket.awPart[CHR_EQUIPPART_ACCE];
kNetActorData.m_dwStateFlags=chrAddPacket.bStateFlag;
kNetActorData.m_dwVID=chrAddPacket.dwVID;
kNetActorData.m_dwMountVnum=chrAddPacket.dwMountVnum;
@@ -240,6 +243,7 @@ bool CPythonNetworkStream::RecvCharacterUpdatePacket()
kNetUpdateActorData.m_dwArmor=chrUpdatePacket.awPart[CHR_EQUIPPART_ARMOR];
kNetUpdateActorData.m_dwWeapon=chrUpdatePacket.awPart[CHR_EQUIPPART_WEAPON];
kNetUpdateActorData.m_dwHair=chrUpdatePacket.awPart[CHR_EQUIPPART_HAIR];
kNetUpdateActorData.m_dwAcce=chrUpdatePacket.awPart[CHR_EQUIPPART_ACCE];
kNetUpdateActorData.m_dwVID=chrUpdatePacket.dwVID;
kNetUpdateActorData.m_kAffectFlags.CopyData(0, sizeof(chrUpdatePacket.dwAffectFlag[0]), &chrUpdatePacket.dwAffectFlag[0]);
kNetUpdateActorData.m_kAffectFlags.CopyData(32, sizeof(chrUpdatePacket.dwAffectFlag[1]), &chrUpdatePacket.dwAffectFlag[1]);
@@ -265,6 +269,7 @@ bool CPythonNetworkStream::RecvCharacterUpdatePacketNew()
kNetUpdateActorData.m_dwArmor=chrUpdatePacket.awPart[CHR_EQUIPPART_ARMOR];
kNetUpdateActorData.m_dwWeapon=chrUpdatePacket.awPart[CHR_EQUIPPART_WEAPON];
kNetUpdateActorData.m_dwHair=chrUpdatePacket.awPart[CHR_EQUIPPART_HAIR];
kNetUpdateActorData.m_dwAcce=chrUpdatePacket.awPart[CHR_EQUIPPART_ACCE];
kNetUpdateActorData.m_dwVID=chrUpdatePacket.dwVID;
kNetUpdateActorData.m_kAffectFlags.CopyData(0, sizeof(chrUpdatePacket.dwAffectFlag[0]), &chrUpdatePacket.dwAffectFlag[0]);
kNetUpdateActorData.m_kAffectFlags.CopyData(32, sizeof(chrUpdatePacket.dwAffectFlag[1]), &chrUpdatePacket.dwAffectFlag[1]);
@@ -473,4 +478,3 @@ bool CPythonNetworkStream::RecvCharacterAppendPacket()
return true;
}
*/