port: ItemData, ItemManager, PythonNonPlayer + LoadLocaleData (batch 2 P3-a)

Verbatim 40250 GameLib ItemData/ItemManager and UserInterface
PythonNonPlayer(+Module) replace their pending stand-ins and the
nonplayer module stub. LoadLocaleData's body moves into the platform
CPythonApplication stand-in, so the select phase loads item_proto and
mob_proto; CPythonSkill is still pending, so it returns false after the
tables load. login_flow checks item 19 (Sword+9) and mob 101 (Wild Dog),
offline and live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-24 00:36:10 +09:00
co-authored by Claude Opus 5.5
parent ce9f96398e
commit f0564a7f12
21 changed files with 1960 additions and 250 deletions
@@ -0,0 +1,197 @@
#include "StdAfx.h"
#include "../EterPack/EterPackManager.h"
#include "PythonNonPlayer.h"
#include "InstanceBase.h"
#include "PythonCharacterManager.h"
bool CPythonNonPlayer::LoadNonPlayerData(const char * c_szFileName)
{
static DWORD s_adwMobProtoKey[4] =
{
4813894,
18955,
552631,
6822045
};
CMappedFile file;
LPCVOID pvData;
Tracef("CPythonNonPlayer::LoadNonPlayerData: %s, sizeof(TMobTable)=%u\n", c_szFileName, sizeof(TMobTable));
if (!CEterPackManager::Instance().Get(file, c_szFileName, &pvData))
return false;
DWORD dwFourCC, dwElements, dwDataSize;
file.Read(&dwFourCC, sizeof(DWORD));
if (dwFourCC != MAKEFOURCC('M', 'M', 'P', 'T'))
{
TraceError("CPythonNonPlayer::LoadNonPlayerData: invalid Mob proto type %s", c_szFileName);
return false;
}
file.Read(&dwElements, sizeof(DWORD));
file.Read(&dwDataSize, sizeof(DWORD));
BYTE * pbData = new BYTE[dwDataSize];
file.Read(pbData, dwDataSize);
/////
CLZObject zObj;
if (!CLZO::Instance().Decompress(zObj, pbData, s_adwMobProtoKey))
{
delete [] pbData;
return false;
}
if ((zObj.GetSize() % sizeof(TMobTable)) != 0)
{
TraceError("CPythonNonPlayer::LoadNonPlayerData: invalid size %u check data format.", zObj.GetSize());
return false;
}
TMobTable * pTable = (TMobTable *) zObj.GetBuffer();
for (DWORD i = 0; i < dwElements; ++i, ++pTable)
{
TMobTable * pNonPlayerData = new TMobTable;
memcpy(pNonPlayerData, pTable, sizeof(TMobTable));
//TraceError("%d : %s type[%d] color[%d]", pNonPlayerData->dwVnum, pNonPlayerData->szLocaleName, pNonPlayerData->bType, pNonPlayerData->dwMonsterColor);
m_NonPlayerDataMap.insert(TNonPlayerDataMap::value_type(pNonPlayerData->dwVnum, pNonPlayerData));
}
delete [] pbData;
return true;
}
bool CPythonNonPlayer::GetName(DWORD dwVnum, const char ** c_pszName)
{
const TMobTable * p = GetTable(dwVnum);
if (!p)
return false;
*c_pszName = p->szLocaleName;
return true;
}
bool CPythonNonPlayer::GetInstanceType(DWORD dwVnum, BYTE* pbType)
{
const TMobTable * p = GetTable(dwVnum);
// dwVnum를 찾을 수 없으면 플레이어 캐릭터로 간주 한다. 문제성 코드 -_- [cronan]
if (!p)
return false;
*pbType=p->bType;
return true;
}
const CPythonNonPlayer::TMobTable * CPythonNonPlayer::GetTable(DWORD dwVnum)
{
TNonPlayerDataMap::iterator itor = m_NonPlayerDataMap.find(dwVnum);
if (itor == m_NonPlayerDataMap.end())
return NULL;
return itor->second;
}
BYTE CPythonNonPlayer::GetEventType(DWORD dwVnum)
{
const TMobTable * p = GetTable(dwVnum);
if (!p)
{
//Tracef("CPythonNonPlayer::GetEventType - Failed to find virtual number\n");
return ON_CLICK_EVENT_NONE;
}
return p->bOnClickType;
}
BYTE CPythonNonPlayer::GetEventTypeByVID(DWORD dwVID)
{
CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(dwVID);
if (NULL == pInstance)
{
//Tracef("CPythonNonPlayer::GetEventTypeByVID - There is no Virtual Number\n");
return ON_CLICK_EVENT_NONE;
}
WORD dwVnum = pInstance->GetVirtualNumber();
return GetEventType(dwVnum);
}
const char* CPythonNonPlayer::GetMonsterName(DWORD dwVnum)
{
const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum);
if (!c_pTable)
{
static const char* sc_szEmpty="";
return sc_szEmpty;
}
return c_pTable->szLocaleName;
}
DWORD CPythonNonPlayer::GetMonsterColor(DWORD dwVnum)
{
const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum);
if (!c_pTable)
return 0;
return c_pTable->dwMonsterColor;
}
void CPythonNonPlayer::GetMatchableMobList(int iLevel, int iInterval, TMobTableList * pMobTableList)
{
/*
pMobTableList->clear();
TNonPlayerDataMap::iterator itor = m_NonPlayerDataMap.begin();
for (; itor != m_NonPlayerDataMap.end(); ++itor)
{
TMobTable * pMobTable = itor->second;
int iLowerLevelLimit = iLevel-iInterval;
int iUpperLevelLimit = iLevel+iInterval;
if ((pMobTable->abLevelRange[0] >= iLowerLevelLimit && pMobTable->abLevelRange[0] <= iUpperLevelLimit) ||
(pMobTable->abLevelRange[1] >= iLowerLevelLimit && pMobTable->abLevelRange[1] <= iUpperLevelLimit))
{
pMobTableList->push_back(pMobTable);
}
}
*/
}
void CPythonNonPlayer::Clear()
{
}
void CPythonNonPlayer::Destroy()
{
for (TNonPlayerDataMap::iterator itor=m_NonPlayerDataMap.begin(); itor!=m_NonPlayerDataMap.end(); ++itor)
{
delete itor->second;
}
m_NonPlayerDataMap.clear();
}
CPythonNonPlayer::CPythonNonPlayer()
{
Clear();
}
CPythonNonPlayer::~CPythonNonPlayer(void)
{
Destroy();
}
@@ -0,0 +1,119 @@
#include "StdAfx.h"
#include "PythonNonPlayer.h"
#include "InstanceBase.h"
#include "PythonCharacterManager.h"
PyObject * nonplayerGetEventType(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualNumber;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualNumber))
return Py_BuildException();
BYTE iType = CPythonNonPlayer::Instance().GetEventType(iVirtualNumber);
return Py_BuildValue("i", iType);
}
PyObject * nonplayerGetEventTypeByVID(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
return Py_BuildException();
BYTE iType = CPythonNonPlayer::Instance().GetEventTypeByVID(iVirtualID);
return Py_BuildValue("i", iType);
}
PyObject * nonplayerGetLevelByVID(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
return Py_BuildException();
CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID);
if (!pInstance)
return Py_BuildValue("i", -1);
const CPythonNonPlayer::TMobTable * pMobTable = CPythonNonPlayer::Instance().GetTable(pInstance->GetVirtualNumber());
if (!pMobTable)
return Py_BuildValue("i", -1);
float fAverageLevel = pMobTable->bLevel;//(float(pMobTable->abLevelRange[0]) + float(pMobTable->abLevelRange[1])) / 2.0f;
fAverageLevel = floor(fAverageLevel + 0.5f);
return Py_BuildValue("i", int(fAverageLevel));
}
PyObject * nonplayerGetGradeByVID(PyObject * poSelf, PyObject * poArgs)
{
int iVirtualID;
if (!PyTuple_GetInteger(poArgs, 0, &iVirtualID))
return Py_BuildException();
CInstanceBase * pInstance = CPythonCharacterManager::Instance().GetInstancePtr(iVirtualID);
if (!pInstance)
return Py_BuildValue("i", -1);
const CPythonNonPlayer::TMobTable * pMobTable = CPythonNonPlayer::Instance().GetTable(pInstance->GetVirtualNumber());
if (!pMobTable)
return Py_BuildValue("i", -1);
return Py_BuildValue("i", pMobTable->bRank);
}
PyObject * nonplayerGetMonsterName(PyObject * poSelf, PyObject * poArgs)
{
int iVNum;
if (!PyTuple_GetInteger(poArgs, 0, &iVNum))
return Py_BuildException();
CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance();
return Py_BuildValue("s", rkNonPlayer.GetMonsterName(iVNum));
}
PyObject * nonplayerLoadNonPlayerData(PyObject * poSelf, PyObject * poArgs)
{
char * szFileName;
if(!PyTuple_GetString(poArgs, 0, &szFileName))
return Py_BuildException();
CPythonNonPlayer::Instance().LoadNonPlayerData(szFileName);
return Py_BuildNone();
}
void initNonPlayer()
{
static PyMethodDef s_methods[] =
{
{ "GetEventType", nonplayerGetEventType, METH_VARARGS },
{ "GetEventTypeByVID", nonplayerGetEventTypeByVID, METH_VARARGS },
{ "GetLevelByVID", nonplayerGetLevelByVID, METH_VARARGS },
{ "GetGradeByVID", nonplayerGetGradeByVID, METH_VARARGS },
{ "GetMonsterName", nonplayerGetMonsterName, METH_VARARGS },
{ "LoadNonPlayerData", nonplayerLoadNonPlayerData, METH_VARARGS },
{ NULL, NULL, NULL },
};
PyObject * poModule = Py_InitModule("nonplayer", s_methods);
PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_NONE", CPythonNonPlayer::ON_CLICK_EVENT_NONE);
PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_BATTLE", CPythonNonPlayer::ON_CLICK_EVENT_BATTLE);
PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_SHOP", CPythonNonPlayer::ON_CLICK_EVENT_SHOP);
PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_TALK", CPythonNonPlayer::ON_CLICK_EVENT_TALK);
PyModule_AddIntConstant(poModule, "ON_CLICK_EVENT_VEHICLE", CPythonNonPlayer::ON_CLICK_EVENT_VEHICLE);
PyModule_AddIntConstant(poModule, "PAWN", 0);
PyModule_AddIntConstant(poModule, "S_PAWN", 1);
PyModule_AddIntConstant(poModule, "KNIGHT", 2);
PyModule_AddIntConstant(poModule, "S_KNIGHT", 3);
PyModule_AddIntConstant(poModule, "BOSS", 4);
PyModule_AddIntConstant(poModule, "KING", 5);
}
@@ -47,6 +47,7 @@ void initapp();
void initchr();
void initchrmgr();
void initPlayer();
void initNonPlayer();
void initChat();
void initnet();
void initeffect();