Jump to content

Search the Community

Showing results for tags 'mt2 fr systeme'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Espace Communautaire
    • Funky Emulation
    • Services
    • Bureau de la Communauté
    • Espace Premium
  • Emulation & Co
    • Suggest a Release / Tutorial
    • M2 Project
  • Emulation de jeux
    • Metin2
    • Metin2 Dev
    • Minecraft
    • Dofus
    • World of Warcraft
    • Voir plus...
  • Espace Divers
  • PassionDev's Forum
  • EmuTarkov's Liens importants
  • EmuTarkov's Discussions

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Nationality


Sexe


Discord


Skype


Site


Steam ID


Minecraft


Dofus


Metin2


RaiderZ


X


World of Warcraft


Aion


Habbo


GTA


Roblox


Wakfu


PHP


SQL


HTML


CSS


JavaScript


Java


LUA


Python


VisualBasic


C++


c#


C


3D


2D


Mapper


PHP

Found 27 results

  1. Bonjour à tous , j'ai décidé de partagé et d'expliquer comment implanter les systèmes que j'ai sur mon DD. (Tous fonctionnel) Aujourd'hui , ce sera un système qui vous permet de voir ce que drop le mob que vous pointez. !!!!! ATTENTION AUX TABULATIONS!!!!! 1) Pré-requis: -Source Server/Client -Un client On va commencer par les sources Serveur: Ouvre le fichier service.h qui ce trouve dans le dossier common : Ajouter: #define __SEND_TARGET_INFO__ Maintenant aller dans game/src puis ouvrez le fichier char.h: Cherchez: ////////////////////////////////////////////////////////////////////////////////// // Basic Points Ajoutez en dessous : #ifdef __SEND_TARGET_INFO__ private: DWORD dwLastTargetInfoPulse; public: DWORD GetLastTargetInfoPulse() const { return dwLastTargetInfoPulse; } void SetLastTargetInfoPulse(DWORD pulse) { dwLastTargetInfoPulse = pulse; } #endif Ouvrez le dossier char.cpp: Cherchez: #include "DragonSoul.h" Puis ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ #include #include using namespace std; #endif Cherchez: m_dwKillerPID = 0; Puis ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ dwLastTargetInfoPulse = 0; #endif Maintenant , ouvrez le fichier input.h Cherchez: void Roulette(LPCHARACTER ch, const char* c_pData); Ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ void TargetInfoLoad(LPCHARACTER ch, const char* c_pData); #endif Ouvrez le dossier input_main.cpp: Cherchez: static int __deposit_limit() { return (1000*10000); // 1õ¸¸ } Ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ void CInputMain::TargetInfoLoad(LPCHARACTER ch, const char* c_pData) { TPacketCGTargetInfoLoad* p = (TPacketCGTargetInfoLoad*)c_pData; TPacketGCTargetInfo pInfo; pInfo.header = HEADER_GC_TARGET_INFO; static std::vector s_vec_item; s_vec_item.clear(); LPITEM pkInfoItem; LPCHARACTER m_pkChrTarget = CHARACTER_MANAGER::instance().Find(p->dwVID); // if (m_pkChrTarget && (m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone())) // { // if (thecore_heart->pulse - (int) ch->GetLastTargetInfoPulse() < passes_per_sec * 3) // return; // ch->SetLastTargetInfoPulse(thecore_heart->pulse); if (ITEM_MANAGER::instance().CreateDropItemVector(m_pkChrTarget, ch, s_vec_item) && (m_pkChrTarget->IsMonster() || m_pkChrTarget->IsStone())) { if (s_vec_item.size() == 0); else if (s_vec_item.size() == 1) { pkInfoItem = s_vec_item[0]; pInfo.dwVID = m_pkChrTarget->GetVID(); pInfo.race = m_pkChrTarget->GetRaceNum(); pInfo.dwVnum = pkInfoItem->GetVnum(); pInfo.count = pkInfoItem->GetCount(); ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo)); } else { int iItemIdx = s_vec_item.size() - 1; while (iItemIdx >= 0) { pkInfoItem = s_vec_item[iItemIdx--]; if (!pkInfoItem) { sys_err("pkInfoItem null in vector idx %d", iItemIdx + 1); continue; } pInfo.dwVID = m_pkChrTarget->GetVID(); pInfo.race = m_pkChrTarget->GetRaceNum(); pInfo.dwVnum = pkInfoItem->GetVnum(); pInfo.count = pkInfoItem->GetCount(); ch->GetDesc()->Packet(&pInfo, sizeof(TPacketGCTargetInfo)); } } } // } } #endif Cherchez: case HEADER_CG_XTRAP_ACK: { TPacketXTrapCSVerify* p = reinterpret_cast((void*)c_pData); CXTrapManager::instance().Verify_CSStep3(d->GetCharacter(), p->bPacketData); } break; Mettez en dessous : #ifdef __SEND_TARGET_INFO__ case HEADER_CG_TARGET_INFO_LOAD: { TargetInfoLoad(ch, c_pData); } break; #endif Ouvre le fichier item_manager.cpp: Cherchez: bool ITEM_MANAGER::GetDropPct(LPCHARACTER pkChr, LPCHARACTER pkKiller, OUT int& iDeltaPercent, OUT int& iRandRange) Ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ bool ITEM_MANAGER::CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector & vec_item) { if (pkChr->IsPolymorphed() || pkChr->IsPC()) { return false; } int iLevel = pkKiller->GetLevel(); BYTE bRank = pkChr->GetMobRank(); LPITEM item = NULL; std::vector::iterator it = g_vec_pkCommonDropItem[bRank].begin(); while (it != g_vec_pkCommonDropItem[bRank].end()) { const CItemDropInfo & c_rInfo = *(it++); if (iLevel < c_rInfo.m_iLevelStart || iLevel > c_rInfo.m_iLevelEnd) continue; TItemTable * table = GetTable(c_rInfo.m_dwVnum); if (!table) continue; item = NULL; if (table->bType == ITEM_POLYMORPH) { if (c_rInfo.m_dwVnum == pkChr->GetPolymorphItemVnum()) { item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true); if (item) item->SetSocket(0, pkChr->GetRaceNum()); } } else item = CreateItem(c_rInfo.m_dwVnum, 1, 0, true); if (item) vec_item.push_back(item); } // Drop Item Group { itertype(m_map_pkDropItemGroup) it; it = m_map_pkDropItemGroup.find(pkChr->GetRaceNum()); if (it != m_map_pkDropItemGroup.end()) { typeof(it->second->GetVector()) v = it->second->GetVector(); for (DWORD i = 0; i < v.size(); ++i) { item = CreateItem(v[i].dwVnum, v[i].iCount, 0, true); if (item) { if (item->GetType() == ITEM_POLYMORPH) { if (item->GetVnum() == pkChr->GetPolymorphItemVnum()) { item->SetSocket(0, pkChr->GetRaceNum()); } } vec_item.push_back(item); } } } } // MobDropItem Group { itertype(m_map_pkMobItemGroup) it; it = m_map_pkMobItemGroup.find(pkChr->GetRaceNum()); if ( it != m_map_pkMobItemGroup.end() ) { CMobItemGroup* pGroup = it->second; // MOB_DROP_ITEM_BUG_FIX // 20050805.myevan.MobDropItem ? ???? ?? ?? CMobItemGroup::GetOne() ??? ?? ?? ?? if (pGroup && !pGroup->IsEmpty()) { const CMobItemGroup::SMobItemGroupInfo& info = pGroup->GetOne(); item = CreateItem(info.dwItemVnum, info.iCount, 0, true, info.iRarePct); if (item) vec_item.push_back(item); } // END_OF_MOB_DROP_ITEM_BUG_FIX } } // Level Item Group { itertype(m_map_pkLevelItemGroup) it; it = m_map_pkLevelItemGroup.find(pkChr->GetRaceNum()); if ( it != m_map_pkLevelItemGroup.end() ) { if ( it->second->GetLevelLimit() <= (DWORD)iLevel ) { typeof(it->second->GetVector()) v = it->second->GetVector(); for ( DWORD i=0; i < v.size(); i++ ) { DWORD dwVnum = v[i].dwVNum; item = CreateItem(dwVnum, v[i].iCount, 0, true); if ( item ) vec_item.push_back(item); } } } } // BuyerTheitGloves Item Group { // by mhh ?? ??? ??? ?? drop ? ???? ?? if (pkKiller->GetPremiumRemainSeconds(PREMIUM_ITEM) > 0 || pkKiller->IsEquipUniqueGroup(UNIQUE_GROUP_DOUBLE_ITEM)) { itertype(m_map_pkGloveItemGroup) it; it = m_map_pkGloveItemGroup.find(pkChr->GetRaceNum()); if (it != m_map_pkGloveItemGroup.end()) { typeof(it->second->GetVector()) v = it->second->GetVector(); for (DWORD i = 0; i < v.size(); ++i) { DWORD dwVnum = v[i].dwVnum; item = CreateItem(dwVnum, v[i].iCount, 0, true); if (item) vec_item.push_back(item); } } } } // ?? if (pkChr->GetMobDropItemVnum()) { itertype(m_map_dwEtcItemDropProb) it = m_map_dwEtcItemDropProb.find(pkChr->GetMobDropItemVnum()); if (it != m_map_dwEtcItemDropProb.end()) { item = CreateItem(pkChr->GetMobDropItemVnum(), 1, 0, true); if (item) vec_item.push_back(item); } } if (pkChr->IsStone()) { if (pkChr->GetDropMetinStoneVnum()) { item = CreateItem(pkChr->GetDropMetinStoneVnum(), 1, 0, true); if (item) vec_item.push_back(item); } } return vec_item.size(); } #endif Ouvrez le fichier item_manager.h Cherchez: bool CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector & vec_item); Ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ bool CreateDropItemVector(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector & vec_item); #endif Ouvrez le fichier packet.h Cherchez: HEADER_GC_TARGET = 63, Mettez en dessous: #ifdef __SEND_TARGET_INFO__ HEADER_GC_TARGET_INFO = 58, HEADER_CG_TARGET_INFO_LOAD = 59, #endif Cherchez: typedef struct packet_target Ajoutez apres la fonction: #ifdef __SEND_TARGET_INFO__ typedef struct packet_target_info { BYTE header; DWORD dwVID; DWORD race; DWORD dwVnum; BYTE count; } TPacketGCTargetInfo; typedef struct packet_target_info_load { BYTE header; DWORD dwVID; } TPacketCGTargetInfoLoad; #endif Ouvre le fichiez packet_info.cpp Cherchez: Set(HEADER_CG_STATE_CHECKER, sizeof(BYTE), "ServerStateCheck", false); Ajoutez en dessous: #ifdef __SEND_TARGET_INFO__ Set(HEADER_CG_TARGET_INFO_LOAD, sizeof(TPacketCGTargetInfoLoad), "TargetInfoLoad", true); #endif Voilà on en a fini avec la partie "Source Server" , maintenant attaquons la partie "Source client": Aller dans le dossier UserInterface: Cherchez le fichier Locale_inc.h Ajoutez: #define ENABLE_SEND_TARGET_INFO Ouvrez le fichier Packet.h Cherchez: HEADER_GC_TARGET = 63, Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO HEADER_GC_TARGET_INFO = 58, HEADER_CG_TARGET_INFO_LOAD = 59, #endif Cherchez: typedef struct packet_target Ajoutez après la fonction: #ifdef ENABLE_SEND_TARGET_INFO typedef struct packet_target_info { BYTE header; DWORD dwVID; DWORD race; DWORD dwVnum; BYTE count; } TPacketGCTargetInfo; typedef struct packet_target_info_load { BYTE header; DWORD dwVID; } TPacketCGTargetInfoLoad; #endif Ouvrez le fichier PythonApplicationModule.cpp Cherchez: #ifdef ENABLE_COSTUME_SYSTEM Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO PyModule_AddIntConstant(poModule, "ENABLE_SEND_TARGET_INFO", 1); #else PyModule_AddIntConstant(poModule, "ENABLE_SEND_TARGET_INFO", 0); #endif Ouvrez le fichier PythonNetworkStream.cpp Cherchez: Set(HEADER_GC_TARGET, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTarget), STATIC_SIZE_PACKET)); Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO Set(HEADER_GC_TARGET_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCTargetInfo), STATIC_SIZE_PACKET)); #endif Ouvrez le fichier PythonNetworkStream.h Cherchez: bool RecvDamageInfoPacket(); Inserez en dessous : #ifdef ENABLE_SEND_TARGET_INFO bool RecvTargetInfoPacket(); public: bool SendTargetInfoLoadPacket(DWORD dwVID); protected: #endif Ouvre le fichier PythonNetworkStreamModule.cpp Cherchez: PyObject* netConnectToAccountServer(PyObject* poSelf, PyObject* poArgs) Ajoutez après la fonction : #ifdef ENABLE_SEND_TARGET_INFO PyObject* netTargetInfoLoad(PyObject* poSelf, PyObject* poArgs) { DWORD dwVID; if (!PyArg_ParseTuple(poArgs, "i", &dwVID)) { return Py_BuildException(); } if (dwVID < 0) { return Py_BuildNone(); } CPythonNetworkStream& rns = CPythonNetworkStream::Instance(); rns.SendTargetInfoLoadPacket(dwVID); return Py_BuildNone(); } #endif Cherchez: { "ConnectToAccountServer", netConnectToAccountServer, METH_VARARGS }, Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO { "SendTargetInfoLoad", netTargetInfoLoad, METH_VARARGS }, #endif Ouvrez le fichier PythonNetworkStreamPhaseGame.cpp Cherchez: case HEADER_GC_TARGET: Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO case HEADER_GC_TARGET_INFO: ret = RecvTargetInfoPacket(); break; #endif Cherchez : bool CPythonNetworkStream::RecvTargetPacket() Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO bool CPythonNetworkStream::RecvTargetInfoPacket() { TPacketGCTargetInfo pInfoTargetPacket; if (!Recv(sizeof(TPacketGCTargetInfo), &pInfoTargetPacket)) { Tracen("Recv Info Target Packet Error"); return false; } CInstanceBase * pInstPlayer = CPythonCharacterManager::Instance().GetMainInstancePtr(); CInstanceBase * pInstTarget = CPythonCharacterManager::Instance().GetInstancePtr(pInfoTargetPacket.dwVID); if (pInstPlayer && pInstTarget) { if (!pInstTarget->IsDead()) { if (pInstTarget->IsEnemy() || pInstTarget->IsStone()) { PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_AddTargetMonsterDropInfo", Py_BuildValue("(iii)", pInfoTargetPacket.race, pInfoTargetPacket.dwVnum, pInfoTargetPacket.count)); PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_RefreshTargetMonsterDropInfo", Py_BuildValue("(i)", pInfoTargetPacket.race)); } else PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); // m_pInstTarget = pInstTarget; } } else { PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "CloseTargetBoard", Py_BuildValue("()")); } return true; } #endif Cherchez : bool CPythonNetworkStream::RecvObserverAddPacket() Ajoutez après la fonction: #ifdef ENABLE_SEND_TARGET_INFO bool CPythonNetworkStream::SendTargetInfoLoadPacket(DWORD dwVID) { TPacketCGTargetInfoLoad TargetInfoLoadPacket; TargetInfoLoadPacket.header = HEADER_CG_TARGET_INFO_LOAD; TargetInfoLoadPacket.dwVID = dwVID; if (!Send(sizeof(TargetInfoLoadPacket), &TargetInfoLoadPacket)) return false; return SendSequence(); } #endif Ouvrez le fichier PythonNonPlayer.cpp Cherchez: void CPythonNonPlayer::GetMatchableMobList(int iLevel, int iInterval, TMobTableList * pMobTableList) Ajoutez après la fonction: #ifdef ENABLE_SEND_TARGET_INFO DWORD CPythonNonPlayer::GetMonsterMaxHP(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD dwMaxHP = 0; return dwMaxHP; } return c_pTable->dwMaxHP; } DWORD CPythonNonPlayer::GetMonsterRaceFlag(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD dwRaceFlag = 0; return dwRaceFlag; } return c_pTable->dwRaceFlag; } DWORD CPythonNonPlayer::GetMonsterLevel(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD level = 0; return level; } return c_pTable->bLevel; } DWORD CPythonNonPlayer::GetMonsterDamage1(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD range = 0; return range; } return c_pTable->dwDamageRange[0]; } DWORD CPythonNonPlayer::GetMonsterDamage2(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD range = 0; return range; } return c_pTable->dwDamageRange[1]; } DWORD CPythonNonPlayer::GetMonsterExp(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD dwExp = 0; return dwExp; } return c_pTable->dwExp; } float CPythonNonPlayer::GetMonsterDamageMultiply(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD fDamMultiply = 0; return fDamMultiply; } return c_pTable->fDamMultiply; } DWORD CPythonNonPlayer::GetMonsterST(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD bStr = 0; return bStr; } return c_pTable->bStr; } DWORD CPythonNonPlayer::GetMonsterDX(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD bDex = 0; return bDex; } return c_pTable->bDex; } bool CPythonNonPlayer::IsMonsterStone(DWORD dwVnum) { const CPythonNonPlayer::TMobTable * c_pTable = GetTable(dwVnum); if (!c_pTable) { DWORD bType = 0; return bType; } return c_pTable->bType == 2; } #endif Ouvrez le fichier PythonNonPlayer.h Cherchez: const char* GetMonsterName(DWORD dwVnum); Ajoutez en dessous : #ifdef ENABLE_SEND_TARGET_INFO // TARGET_INFO DWORD GetMonsterMaxHP(DWORD dwVnum); DWORD GetMonsterRaceFlag(DWORD dwVnum); DWORD GetMonsterLevel(DWORD dwVnum); DWORD GetMonsterDamage1(DWORD dwVnum); DWORD GetMonsterDamage2(DWORD dwVnum); DWORD GetMonsterExp(DWORD dwVnum); float GetMonsterDamageMultiply(DWORD dwVnum); DWORD GetMonsterST(DWORD dwVnum); DWORD GetMonsterDX(DWORD dwVnum); bool IsMonsterStone(DWORD dwVnum); #endif Enfin , ouvrez le fichier PythonNonPlayerModule.cpp Cherchez: PyObject * nonplayerLoadNonPlayerData(PyObject * poSelf, PyObject * poArgs) Ajoutez après la fonction: #ifdef ENABLE_SEND_TARGET_INFO PyObject * nonplayerGetMonsterMaxHP(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterMaxHP(race)); } PyObject * nonplayerGetRaceNumByVID(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->dwVnum); } PyObject * nonplayerGetMonsterRaceFlag(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterRaceFlag(race)); } PyObject * nonplayerGetMonsterLevel(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterLevel(race)); } PyObject * nonplayerGetMonsterDamage(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); DWORD dmg1 = rkNonPlayer.GetMonsterDamage1(race); DWORD dmg2 = rkNonPlayer.GetMonsterDamage2(race); return Py_BuildValue("ii", dmg1,dmg2); } PyObject * nonplayerGetMonsterExp(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterExp(race)); } PyObject * nonplayerGetMonsterDamageMultiply(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("f", rkNonPlayer.GetMonsterDamageMultiply(race)); } PyObject * nonplayerGetMonsterST(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterST(race)); } PyObject * nonplayerGetMonsterDX(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer=CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.GetMonsterDX(race)); } PyObject * nonplayerIsMonsterStone(PyObject * poSelf, PyObject * poArgs) { int race; if (!PyTuple_GetInteger(poArgs, 0, &race)) return Py_BuildException(); CPythonNonPlayer& rkNonPlayer = CPythonNonPlayer::Instance(); return Py_BuildValue("i", rkNonPlayer.IsMonsterStone(race) ? 1 : 0); } #endif Cherchez: { "GetMonsterName", nonplayerGetMonsterName, METH_VARARGS }, Ajoutez en dessous: #ifdef ENABLE_SEND_TARGET_INFO // TARGET_INFO { "GetRaceNumByVID", nonplayerGetRaceNumByVID, METH_VARARGS }, { "GetMonsterMaxHP", nonplayerGetMonsterMaxHP, METH_VARARGS }, { "GetMonsterRaceFlag", nonplayerGetMonsterRaceFlag, METH_VARARGS }, { "GetMonsterLevel", nonplayerGetMonsterLevel, METH_VARARGS }, { "GetMonsterDamage", nonplayerGetMonsterDamage, METH_VARARGS }, { "GetMonsterExp", nonplayerGetMonsterExp, METH_VARARGS }, { "GetMonsterDamageMultiply", nonplayerGetMonsterDamageMultiply, METH_VARARGS }, { "GetMonsterST", nonplayerGetMonsterST, METH_VARARGS }, { "GetMonsterDX", nonplayerGetMonsterDX, METH_VARARGS }, { "IsMonsterStone", nonplayerIsMonsterStone, METH_VARARGS }, #endif Voilà , nous avons enfin terminez la partie Source , pour le coté Client , vous devez depacker locale et root , les choses à modifier sont dans l'archive à télécharger : [Hidden Content] EDIT: Screen: Source: FreaksGamers
  2. Skill Sage Grand Maître. 1) Qu'est ce que cela? 2) Les Prérequis. 3) Le téléchargement. 1) Qu'est ce que cela? Alors, les skill Sage Grand Maître sont des skills au-dessus de P ( Oui vous l'avez compris, vous pourrez up vos skills plus de P) Les skills s'upent de la même manière que pour up en P (de G1 à P ) Ils s'up de P1 à S Pour up vos skills vous aurez besoin de lire des Sage Pierre d'âme (Oh non pas encore des PA !!!!!!!!!!!!!!!!) Vidéos Une vidéo est toujours explicite que quelques mots sur une page blanche. 2) Les Prérequis. Des Files et un client Sources Client/Game/Db De l'archive en téléchargement et votre tête. Sachez encore une fois que ce partage n'est pas de moi et provient de Board Legend, ce système à été créé par Lennt. La traduction est cependant de moi. (Si quelqu'un pourrais traduire le skilldesc.txt je suis preneur.) 3) Le téléchargement. Cliquez ici FE Cordialement, History.
  3. Salut à tous , je vais vous expliquer comment mettre 4 pages d'inventaire. Tout d'abord, allez ici : Server/common/ puis ouvrez length.h Ensuite cherchez : INVENTORY_MAX_NUM = 90, et remplacez par : INVENTORY_MAX_NUM = 180, Ensuite, dans le répertoire : game/src ouvrez char_item.cpp et cherchez : BYTE bPage = bCell / (INVENTORY_MAX_NUM / 2); et remplacez cette ligne par : BYTE bPage = bCell / (INVENTORY_MAX_NUM / 4); Cherchez ensuite(toujours dans le char_item.cpp) : if (p / (INVENTORY_MAX_NUM / 2) != bPage) puis remplacez par : if (p / (INVENTORY_MAX_NUM / 4) != bPage) Ensuite ouvrez exchange.cpp et cherchez : static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 2); // inven page 1 puis complétez comme ici : static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 4); // inven page 1 static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 4); // inven page 2 static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 4); // inven page 3 static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 4); // inven page 4 s_grid1.Clear(); s_grid2.Clear(); s_grid3.Clear(); s_grid4.Clear(); Ensuite, rajoutez en début de fichier ces lignes (en dessous des #include) : /* 4 INVENTORY DEFINES */ #define INVEN_PAGES 4 #define INVEN_PAGE_SIZE (INVENTORY_MAX_NUM / INVEN_PAGES) Ensuite dans la fonction " bool CExchange::CheckSpace() " , remplacez les lignes ci-dessous : for (i = 0; i < INVEN_PAGE_SIZE; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid1.Put(i, 1, item->GetSize()); } for (i = INVEN_PAGE_SIZE; i < INVEN_PAGE_SIZE*2; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid2.Put(i - INVEN_PAGE_SIZE, 1, item->GetSize()); } for (i = INVEN_PAGE_SIZE*2; i < INVEN_PAGE_SIZE*3; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid3.Put(i - INVEN_PAGE_SIZE*2, 1, item->GetSize()); } for (i = INVEN_PAGE_SIZE*3; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid4.Put(i - INVEN_PAGE_SIZE*3, 1, item->GetSize()); } Ensuite, chercher : int iPos = s_grid1.FindBlank(1, item->GetSize()); vous devriez y voir ca : int iPos = s_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid1.Put(iPos, 1, item->GetSize()); } else { iPos = s_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid2.Put(iPos, 1, item->GetSize()); } else { return false; } } modifier par int iPos = s_grid1.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid1.Put(iPos, 1, item->GetSize()); } else { iPos = s_grid2.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid2.Put(iPos, 1, item->GetSize()); } else { iPos = s_grid3.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid3.Put(iPos, 1, item->GetSize()); } else { iPos = s_grid4.FindBlank(1, item->GetSize()); if (iPos >= 0) { s_grid4.Put(iPos, 1, item->GetSize()); } else { return false; } } } } PARTIE SERVEUR TERMINÉE Passons maintenant Partie client. Pour commencer , allez ici : Client/Userinterface et ouvrez GameType.h et cherchez : const DWORD c_Inventory_Page_Count = 2; et remplacez par : const DWORD c_Inventory_Page_Count = 4; Ouvrez ensuite inventorywindow.py et cherchez : EQUIPMENT_START_INDEX = 90 que vous remplacez par : EQUIPMENT_START_INDEX = 180 Ensuite, (eh oui, c'est toujours pas terminé !) ouvrez uiinventory.py et cherchez : self.inventoryTab.append(self.GetChild("Inventory_Tab_02")) que vous ajoutez en dessous : self.inventoryTab.append(self.GetChild("Inventory_Tab_03")) self.inventoryTab.append(self.GetChild("Inventory_Tab_04")) ensuite cherchez : self.inventoryTab[1].SetEvent(lambda arg=1: self.SetInventoryPage(arg)) et ajoutez en dessous : self.inventoryTab[2].SetEvent(lambda arg=2: self.SetInventoryPage(arg)) self.inventoryTab[3].SetEvent(lambda arg=3: self.SetInventoryPage(arg)) cherchez ensuite : self.inventoryTab[0].Down() rajoutez en dessous : self.inventoryPageIndex = 0 Ensuite cherchez la fonction SetInventoryPage et remplacez par ça : def SetInventoryPage(self, page): self.inventoryTab[self.inventoryPageIndex].SetUp() self.inventoryPageIndex = page self.inventoryTab[self.inventoryPageIndex].Down() self.RefreshBagSlotWindow() PARTIE CLIENT TERMINÉE Vous pouvez tout recompiler et la partie source est terminée. Je vous partage mon inventorywindow.py qui se trouve dans locale_fr/ui : import uiScriptLocale import item EQUIPMENT_START_INDEX = 180 window = { "name" : "InventoryWindow", ## 600 - (width + i?¢´e¡Í¢¬i¨£¨öi©«¨ùe¢®©« e¢Ò¢æi?¡Æ e?i?¡Æe¢¬¡Æ 24 px) "x" : SCREEN_WIDTH - 176, "y" : SCREEN_HEIGHT - 37 - 565, "style" : ("movable", "float",), "width" : 176, "height" : 585, "children" : ( ## Inventory, Equipment Slots { "name" : "board", "type" : "board", "style" : ("attach",), "x" : 0, "y" : 0, "width" : 176, "height" : 585, "children" : ( ## Title { "name" : "TitleBar", "type" : "titlebar", "style" : ("attach",), "x" : 8, "y" : 7, "width" : 161, "color" : "yellow", "children" : ( { "name":"TitleName", "type":"text", "x":77, "y":3, "text":uiScriptLocale.INVENTORY_TITLE, "text_horizontal_align":"center" }, ), }, ## Equipment Slot { "name" : "Equipment_Base", "type" : "image", "x" : 10, "y" : 33, "image" : "d:/ymir work/ui/equipment_bg_without_ring.tga", "children" : ( { "name" : "EquipmentSlot", "type" : "slot", "x" : 3, "y" : 3, "width" : 150, "height" : 182, "slot" : ( {"index":EQUIPMENT_START_INDEX+0, "x":39, "y":37, "width":32, "height":64}, {"index":EQUIPMENT_START_INDEX+1, "x":39, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+2, "x":39, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+3, "x":75, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+4, "x":3, "y":3, "width":32, "height":96}, {"index":EQUIPMENT_START_INDEX+5, "x":114, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+6, "x":114, "y":35, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+7, "x":2, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+8, "x":75, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+9, "x":114, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+10, "x":75, "y":35, "width":32, "height":32}, ## i?? e¡Æ?i¡×¢æ1 ##{"index":item.EQUIPMENT_RING1, "x":2, "y":106, "width":32, "height":32}, ## i?? e¡Æ?i¡×¢æ2 ##{"index":item.EQUIPMENT_RING2, "x":75, "y":106, "width":32, "height":32}, ## i?? e©÷¡§i?¢¬ {"index":item.EQUIPMENT_BELT, "x":39, "y":106, "width":32, "height":32}, ), }, ## Dragon Soul Button { "name" : "DSSButton", "type" : "button", "x" : 114, "y" : 107, "tooltip_text" : uiScriptLocale.TASKBAR_DRAGON_SOUL, "default_image" : "d:/ymir work/ui/dragonsoul/dss_inventory_button_01.tga", "over_image" : "d:/ymir work/ui/dragonsoul/dss_inventory_button_02.tga", "down_image" : "d:/ymir work/ui/dragonsoul/dss_inventory_button_03.tga", }, ## MallButton { "name" : "MallButton", "type" : "button", "x" : 118, "y" : 148, "tooltip_text" : uiScriptLocale.MALL_TITLE, "default_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_01.tga", "over_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_02.tga", "down_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_03.tga", }, ## CostumeButton { "name" : "CostumeButton", "type" : "button", "x" : 78, "y" : 5, "tooltip_text" : uiScriptLocale.COSTUME_TITLE, "default_image" : "d:/ymir work/ui/game/taskbar/costume_Button_01.tga", "over_image" : "d:/ymir work/ui/game/taskbar/costume_Button_02.tga", "down_image" : "d:/ymir work/ui/game/taskbar/costume_Button_03.tga", }, { "name" : "Equipment_Tab_01", "type" : "radio_button", "x" : 86, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Equipment_Tab_02", "type" : "radio_button", "x" : 86 + 32, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, ), }, { "name" : "Inventory_Tab_01", "type" : "radio_button", "x" : 10, "y" : 33 + 189, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_1, "children" : ( { "name" : "Inventory_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Inventory_Tab_02", "type" : "radio_button", "x" : 10 + 78, "y" : 33 + 189, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_2, "children" : ( { "name" : "Inventory_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, { "name" : "Inventory_Tab_03", "type" : "radio_button", "x" : 10, "y" : 33 + 210, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_3, "children" : ( { "name" : "Inventory_Tab_03_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "III", }, ), }, { "name" : "Inventory_Tab_04", "type" : "radio_button", "x" : 10 + 78, "y" : 33 + 210, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_4, "children" : ( { "name" : "Inventory_Tab_04_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "IV", }, ), }, ## Item Slot { "name" : "ItemSlot", "type" : "grid_table", "x" : 8, "y" : 264, "start_index" : 0, "x_count" : 5, "y_count" : 9, "x_step" : 32, "y_step" : 32, "image" : "d:/ymir work/ui/public/Slot_Base.sub" }, ## Print { "name":"Money_Slot", "type":"button", "x":8, "y":28, "horizontal_align":"center", "vertical_align":"bottom", "default_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "over_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "down_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "children" : ( { "name":"Money_Icon", "type":"image", "x":-18, "y":2, "image":"d:/ymir work/ui/game/windows/money_icon.sub", }, { "name" : "Money", "type" : "text", "x" : 3, "y" : 3, "horizontal_align" : "right", "text_horizontal_align" : "right", "text" : "123456789", }, ), }, ), }, ), } Pour clore le tutoriel , allez dans locale_interface.txt et cherchez : INVENTORY_PAGE_BUTTON_TOOLTIP_2 2e inventaire et ajoutez en dessous : INVENTORY_PAGE_BUTTON_TOOLTIP_3 3e inventaire INVENTORY_PAGE_BUTTON_TOOLTIP_4 4e inventaire Vous pouvez tout recompiler, repacker et regarder le résultat. Voila, tutoriel terminé, bonne chance ! Source : M2Dev, Corrigé par Kameyu, et merci à History, Galet et Calypso pour leur participation au débug.
  4. Verrouillage/Déverrouillage d'inventaire système de l'officiel. 1) Qu'est ce que c'est ? 2) Les Prérequis 3) Les téléchargements 1) Qu'est ce que c'est ? Le Système de Verrouillage/Déverrouillage d'inventaire est un verrou poser sur certains espaces de vos inventaire ( jusqu'à 4 inventaires ) Pour les déverrouiller il vous faut un item appeler Clé d'inventaire . Vidéos Screens Des images et vidéos valent mieux qu'un tas de mots sur une page blanche. 2) Les Prérequis Avoir des files et un client Disposez des 4 inventaires ( L'inventaires 3 et 4 doit être vide autrement cela vous empêchera de connecter le personnages en question.) Sources Client / Game / DB Les fichiers à télécharger et votre tête! 3) Les téléchargements Comme à mon habitude le tutoriel ce trouve à l'intérieur du .rar. Changelog : Sachez encore une fois que ce partage n'est pas de moi mais qu'il provient de TurkMmo. La traduction/réorganisation du tutoriel est cependant de moi. Lien mis à jour avec la correction : Cliquez ici FEV1 FEV2 GitHubV2 Cordialement, History.
  5. Bonjour à tous, je vous partage donc un partage d'epvps pour ne plus avoir besoin de txt et reprendre donc l'ancien systeme via mysql. Pour ce faire on se rend donc dans ClientManagerBoot.cpp qui se trouve donc dans mainline/srcs/server/db/src. Ensuite il vous faudra remplacer bool CClientManager::InitializeItemTable() { //================== ÇÔ¼ö ¼³¸à ==================// //1. ¿ä¾à : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' ÆÄÀÃÀ» ÀðÃ, // (TItemTable), ¿ÀºêçƮ¸¦ »ý¼ºÇÑ´Ù. //2. ¼ø¼ // 1) 'item_names.txt' ÆÄÀÃÀ» ÀÃ¾î¼ (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. // 2) 'item_proto_text.txt'ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_itemTableByVnum](vnum:TItemTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. // 3) 'item_proto.txt' ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (!)[item_table], À» ¸¸µç´Ù. // <Âü°Ã> // °¢ row µé Ãß, // (b)[test_map_itemTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_itemTableByVnum]ÀÇ °ÃÀ» »ç¿ëÇÑ´Ù. // 4) (b)[test_map_itemTableByVnum]ÀÇ rowÃß, (!)[item_table]¿¡ ¾ø´Â °ÃÀ» Ãß°¡ÇÑ´Ù. //3. Å×½ºÆ® // 1)'item_proto.txt' 亸°¡ item_table¿¡ Àß µé¾î°¬´ÂÃö. -> ¿Ã·á // 2)'item_names.txt' 亸°¡ item_table¿¡ Àß µé¾î°¬´ÂÃö. // 3)'item_proto_test.txt' ¿¡¼ [°ãÄ¡´Â] 亸°¡ item_table ¿¡ Àß µé¾î°¬´ÂÃö. // 4)'item_proto_test.txt' ¿¡¼ [»õ·Î¿î] 亸°¡ item_table ¿¡ Àß µé¾î°¬´ÂÃö. // 5) (ÃÖþ) °ÔÀÓ Ŭ¶óÀ̾ðÆ®¿¡¼ æ´ë·Î ÀÛµ¿ ÇôÂÃö. //_______________________________________________// //=================================================================================// // 1) 'item_names.txt' ÆÄÀÃÀ» ÀÃ¾î¼ (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. //=================================================================================// bool isNameFile = true; map localMap; cCsvTable nameData; if(!nameData.Load("item_names.txt",'\t')) { fprintf(stderr, "item_names.txt was loaded successfully.\n"); isNameFile = false; } else { nameData.Next(); while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //_________________________________________________________________// //=================================================================// // 2) 'item_proto_text.txt'ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_itemTableByVnum](vnum:TItemTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. //=================================================================// map test_map_itemTableByVnum; //1. ÆÄÀà Àþî¿À±â. cCsvTable test_data; if(!test_data.Load("item_proto_test.txt",'\t')) { fprintf(stderr, "item_proto_test.txt was loaded successfully.\n"); //return false; } else { test_data.Next(); //¼³¸à ·Î¿ì ³Ñ¾î°¡±â. //2. Å×½ºÆ® ¾ÆÀÌÅÛ Å×ÀÌºà »ý¼º. TItemTable * test_item_table = NULL; int test_itemTableSize = test_data.m_File.GetRowCount()-1; test_item_table = new TItemTable[test_itemTableSize]; memset(test_item_table, 0, sizeof(TItemTable) * test_itemTableSize); //3. Å×½ºÆ® ¾ÆÀÌÅÛ Å×À̺ÿ¡ °ªÀ» ³Ö°Ã, ¸Ê¿¡±îÃö ³Ö±â. while(test_data.Next()) { if (!Set_Proto_Item_Table(test_item_table, test_data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } test_map_itemTableByVnum.insert(std::map::value_type(test_item_table->dwVnum, test_item_table)); test_item_table++; } } //______________________________________________________________________// //========================================================================// // 3) 'item_proto.txt' ÆÄÀðú (a)[localMap] ¸ÊÀ¸·Î // (!)[item_table], À» ¸¸µç´Ù. // <Âü°Ã> // °¢ row µé Ãß, // (b)[test_map_itemTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_itemTableByVnum]ÀÇ °ÃÀ» »ç¿ëÇÑ´Ù. //========================================================================// //vnumµéÀ» ÀúÀåÇÒ ¼Â. »õ·Î¿î Å×½ºÆ® ¾ÆÀÌÅÛÀ» ÆǺ°ÇÒ¶§ »ç¿ëµÈ´Ù. set vnumSet; //ÆÄÀà Àþî¿À±â. cCsvTable data; if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "item_proto.txt was loaded successfully.\n"); return false; } data.Next(); //¸Ç ÀÃ٠æ¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸ÃÇô ºÎºÃ) if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } //===== ¾ÆÀÌÅÛ Å×ÀÌºà »ý¼º =====// //»õ·Î Ãß°¡µÇ´Â °¹¼ö¸¦ ÆľÇÇÑ´Ù. int addNumber = 0; while(data.Next()) { int vnum = atoi(data.AsStringByIndex(0)); std::map::iterator it_map_itemTable; it_map_itemTable = test_map_itemTableByVnum.find(vnum); if(it_map_itemTable != test_map_itemTableByVnum.end()) { addNumber++; } } //data¸¦ ´Ù½Ã ùÃÙ·Î ¿Å±ä´Ù.(´Ù½Ã Àþî¿Â´Ù; data.Destroy(); if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "item_proto.txt was loaded successfully.\n"); return false; } data.Next(); //¸Ç ÀÃ٠æ¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸ÃÇô ºÎºÃ) m_vec_itemTable.resize(data.m_File.GetRowCount() - 1 + addNumber); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); int testValue = m_vec_itemTable.size(); TItemTable * item_table = &m_vec_itemTable[0]; while (data.Next()) { int col = 0; std::map::iterator it_map_itemTable; it_map_itemTable = test_map_itemTableByVnum.find(atoi(data.AsStringByIndex(col))); if(it_map_itemTable == test_map_itemTableByVnum.end()) { //°¢ Ä®·³ µ¥ÀÌÅà ÀúÀå if (!Set_Proto_Item_Table(item_table, data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } } else { //$$$$$$$$$$$$$$$$$$$$$$$ Å×½ºÆ® ¾ÆÀÌÅÛ Ã¤º¸°¡ ÀÖ´Ù! TItemTable *tempTable = it_map_itemTable->second; item_table->dwVnum = tempTable->dwVnum; strlcpy(item_table->szName, tempTable->szName, sizeof(item_table->szName)); strlcpy(item_table->szLocaleName, tempTable->szLocaleName, sizeof(item_table->szLocaleName)); item_table->bType = tempTable->bType; item_table->bSubType = tempTable->bSubType; item_table->bSize = tempTable->bSize; item_table->dwAntiFlags = tempTable->dwAntiFlags; item_table->dwFlags = tempTable->dwFlags; item_table->dwWearFlags = tempTable->dwWearFlags; item_table->dwImmuneFlag = tempTable->dwImmuneFlag; item_table->dwGold = tempTable->dwGold; item_table->dwShopBuyPrice = tempTable->dwShopBuyPrice; item_table->dwRefinedVnum =tempTable->dwRefinedVnum; item_table->wRefineSet =tempTable->wRefineSet; item_table->bAlterToMagicItemPct = tempTable->bAlterToMagicItemPct; item_table->cLimitRealTimeFirstUseIndex = -1; item_table->cLimitTimerBasedOnWearIndex = -1; int i; for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i) { item_table->aLimits.bType = tempTable->aLimits.bType; item_table->aLimits.lValue = tempTable->aLimits.lValue; if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits.bType) item_table->cLimitRealTimeFirstUseIndex = (char)i; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits.bType) item_table->cLimitTimerBasedOnWearIndex = (char)i; } for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i) { item_table->aApplies.bType = tempTable->aApplies.bType; item_table->aApplies.lValue = tempTable->aApplies.lValue; } for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i) item_table->alValues = tempTable->alValues; item_table->bGainSocketPct = tempTable->bGainSocketPct; item_table->sAddonType = tempTable->sAddonType; item_table->bWeight = tempTable->bWeight; } vnumSet.insert(item_table->dwVnum); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); ++item_table; } //_______________________________________________________________________// //========================================================================// // 4) (b)[test_map_itemTableByVnum]ÀÇ rowÃß, (!)[item_table]¿¡ ¾ø´Â °ÃÀ» Ãß°¡ÇÑ´Ù. //========================================================================// test_data.Destroy(); if(!test_data.Load("item_proto_test.txt",'\t')) { fprintf(stderr, "item_proto_test.txt was loaded successfully.\n"); //return false; } else { test_data.Next(); //¼³¸à ·Î¿ì ³Ñ¾î°¡±â. while (test_data.Next()) //Å×½ºÆ® µ¥ÀÌÅà °¢°¢À» ÈȾ°¡¸ç,»õ·Î¿î °ÃÀ» Ãß°¡ÇÑ´Ù. { //Ãߺ¹µÇ´Â ºÎºÃÀ̸é ³Ñ¾î°£´Ù. set::iterator itVnum; itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); if (itVnum != vnumSet.end()) { continue; } if (!Set_Proto_Item_Table(item_table, test_data, localMap)) { fprintf(stderr, "¾ÆÀÌÅÛ Ç÷ÎÅä Å×ÀÌºà ¼ÂÆà ½ÇÆÃ.\n"); } m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); item_table++; } } // QUEST_ITEM_PROTO_DISABLE // InitializeQuestItemTable(); // END_OF_QUEST_ITEM_PROTO_DISABLE m_map_itemTableByVnum.clear(); itertype(m_vec_itemTable) it = m_vec_itemTable.begin(); while (it != m_vec_itemTable.end()) { TItemTable * item_table = &(*(it++)); sys_log(1, "ITEM: #%-5lu %-24s %-24s VAL: %ld %ld %ld %ld %ld %ld WEAR %lu ANTI %lu IMMUNE %lu REFINE %lu REFINE_SET %u MAGIC_PCT %u", item_table->dwVnum, item_table->szName, item_table->szLocaleName, item_table->alValues[0], item_table->alValues[1], item_table->alValues[2], item_table->alValues[3], item_table->alValues[4], item_table->alValues[5], item_table->dwWearFlags, item_table->dwAntiFlags, item_table->dwImmuneFlag, item_table->dwRefinedVnum, item_table->wRefineSet, item_table->bAlterToMagicItemPct); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); } sort(m_vec_itemTable.begin(), m_vec_itemTable.end(), FCompareVnum()); return true; } par bool CClientManager::InitializeItemTable() { char query[2048]; fprintf(stderr,"Loading item_proto from MySQL"); snprintf(query, sizeof(query), "SELECT vnum,name,%s,type,subtype,weight,size,antiflag,flag,wearflag,immuneflag+0,gold,shop_buy_price,refined_vnum," "refine_set,magic_pct,limittype0,limitvalue0,limittype1,limitvalue1,applytype0,applyvalue0," "applytype1,applyvalue1,applytype2,applyvalue2,value0,value1,value2,value3,value4,value5,socket_pct,addon_type FROM item_proto%s ORDER BY vnum", g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) return false; int addNumber = pRes->uiNumRows; if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } m_vec_itemTable.resize(addNumber-1); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); TItemTable * item_table = &m_vec_itemTable[0]; MYSQL_ROW data; //return true; set vnumSet; while ((data = mysql_fetch_row(pRes->pSQLResult))) { str_to_number(item_table->dwVnum, data[0]); strlcpy(item_table->szName,data[1] , sizeof(item_table->szName)); strlcpy(item_table->szLocaleName, data[2], sizeof(item_table->szLocaleName)); str_to_number(item_table->bType, data[3]); str_to_number(item_table->bSubType, data[4]); str_to_number(item_table->bWeight, data[5]); str_to_number(item_table->bSize, data[6]); str_to_number(item_table->dwAntiFlags, data[7]); str_to_number(item_table->dwFlags, data[8]); str_to_number(item_table->dwWearFlags, data[9]); str_to_number(item_table->dwImmuneFlag, data[10]); str_to_number(item_table->dwGold, data[11]); str_to_number(item_table->dwShopBuyPrice, data[12]); str_to_number(item_table->dwRefinedVnum, data[13]); str_to_number(item_table->wRefineSet, data[14]); str_to_number(item_table->bAlterToMagicItemPct, data[15]); item_table->cLimitRealTimeFirstUseIndex = -1; item_table->cLimitTimerBasedOnWearIndex = -1; str_to_number(item_table->aLimits[0].bType, data[16]); str_to_number(item_table->aLimits[0].lValue, data[17]); if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits[0].bType) item_table->cLimitRealTimeFirstUseIndex = (char)0; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits[0].bType) item_table->cLimitTimerBasedOnWearIndex = (char)0; str_to_number(item_table->aLimits[1].bType, data[18]); str_to_number(item_table->aLimits[1].lValue, data[19]); if (LIMIT_REAL_TIME_START_FIRST_USE == item_table->aLimits[1].bType) item_table->cLimitRealTimeFirstUseIndex = (char)1; if (LIMIT_TIMER_BASED_ON_WEAR == item_table->aLimits[1].bType) item_table->cLimitTimerBasedOnWearIndex = (char)1; str_to_number(item_table->aApplies[0].bType, data[20]); str_to_number(item_table->aApplies[0].lValue, data[21]); str_to_number(item_table->aApplies[1].bType, data[22]); str_to_number(item_table->aApplies[1].lValue, data[23]); str_to_number(item_table->aApplies[2].bType, data[24]); str_to_number(item_table->aApplies[2].lValue, data[25]); str_to_number(item_table->alValues[0], data[26]); str_to_number(item_table->alValues[1], data[27]); str_to_number(item_table->alValues[2], data[28]); str_to_number(item_table->alValues[3], data[29]); str_to_number(item_table->alValues[4], data[30]); str_to_number(item_table->alValues[5], data[31]); str_to_number(item_table->bGainSocketPct, data[32]); str_to_number(item_table->sAddonType, data[33]); vnumSet.insert(item_table->dwVnum); m_map_itemTableByVnum.insert(std::map::value_type(item_table->dwVnum, item_table)); sys_log(0, "ITEM: #%-5lu %-24s %-24s VAL: %d %ld %d %d %d %d WEAR %d ANTI %d IMMUNE %d REFINE %lu REFINE_SET %u MAGIC_PCT %u", item_table->dwVnum, item_table->szName, item_table->szLocaleName, item_table->alValues[0], item_table->alValues[1], item_table->alValues[2], item_table->alValues[3], item_table->alValues[4], item_table->alValues[5], item_table->dwWearFlags, item_table->dwAntiFlags, item_table->dwImmuneFlag, item_table->dwRefinedVnum, item_table->wRefineSet, item_table->bAlterToMagicItemPct); item_table++; } fprintf(stderr," Complete! %d Items loaded.\r\n",addNumber); return true; } et bool CClientManager::InitializeMobTable() { //================== ÇÔ¼ö ¼³¸í ==================// //1. ¿ä¾à : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' ÆÄÀÏÀ» Àаí, // (!)[mob_table] Å×ÀÌºí ¿ÀºêÁ§Æ®¸¦ »ý¼ºÇÑ´Ù. (ŸÀÔ : TMobTable) //2. ¼ø¼­ // 1) 'mob_names.txt' ÆÄÀÏÀ» Àо (a)[localMap](vnum:name) ¸ÊÀ» ¸¸µç´Ù. // 2) 'mob_proto_test.txt'ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (b)[test_map_mobTableByVnum](vnum:TMobTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. // 3) 'mob_proto.txt' ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (!)[mob_table] Å×À̺íÀ» ¸¸µç´Ù. // <Âü°í> // °¢ row µé Áß, // (b)[test_map_mobTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_mobTableByVnum]ÀÇ °ÍÀ» »ç¿ëÇÑ´Ù. // 4) (b)[test_map_mobTableByVnum]ÀÇ rowÁß, (!)[mob_table]¿¡ ¾ø´Â °ÍÀ» Ãß°¡ÇÑ´Ù. //3. Å×½ºÆ® // 1)'mob_proto.txt' Á¤º¸°¡ mob_table¿¡ Àß µé¾î°¬´ÂÁö. -> ¿Ï·á // 2)'mob_names.txt' Á¤º¸°¡ mob_table¿¡ Àß µé¾î°¬´ÂÁö. // 3)'mob_proto_test.txt' ¿¡¼­ [°ãÄ¡´Â] Á¤º¸°¡ mob_table ¿¡ Àß µé¾î°¬´ÂÁö. // 4)'mob_proto_test.txt' ¿¡¼­ [»õ·Î¿î] Á¤º¸°¡ mob_table ¿¡ Àß µé¾î°¬´ÂÁö. // 5) (ÃÖÁ¾) °ÔÀÓ Å¬¶óÀ̾ðÆ®¿¡¼­ Á¦´ë·Î ÀÛµ¿ ÇÏ´ÂÁö. //_______________________________________________// //===============================================// // 1) 'mob_names.txt' ÆÄÀÏÀ» Àо (a)[localMap] ¸ÊÀ» ¸¸µç´Ù. //<(a)localMap ¸Ê »ý¼º> map localMap; bool isNameFile = true; //<ÆÄÀÏ Àбâ> cCsvTable nameData; if(!nameData.Load("mob_names.txt",'\t')) { fprintf(stderr, "mob_names.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); isNameFile = false; } else { nameData.Next(); //¼³¸írow »ý·«. while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //________________________________________________// //===============================================// // 2) 'mob_proto_test.txt'ÆÄÀÏ°ú (a)localMap ¸ÊÀ¸·Î // (b)[test_map_mobTableByVnum](vnum:TMobTable) ¸ÊÀ» »ý¼ºÇÑ´Ù. //0. set vnumSet; //Å×½ºÆ®¿ë ÆÄÀÏ µ¥ÀÌÅÍÁß, ½Å±Ô¿©ºÎ È®Àο¡ »ç¿ë. //1. ÆÄÀÏ Àоî¿À±â bool isTestFile = true; cCsvTable test_data; if(!test_data.Load("mob_proto_test.txt",'\t')) { fprintf(stderr, "Å×½ºÆ® ÆÄÀÏÀÌ ¾ø½À´Ï´Ù. ±×´ë·Î ÁøÇàÇÕ´Ï´Ù.\n"); isTestFile = false; } //2. (c)[test_map_mobTableByVnum](vnum:TMobTable) ¸Ê »ý¼º. map test_map_mobTableByVnum; if (isTestFile) { test_data.Next(); //¼³¸í ·Î¿ì ³Ñ¾î°¡±â. //¤¡. Å×½ºÆ® ¸ó½ºÅÍ Å×ÀÌºí »ý¼º. TMobTable * test_mob_table = NULL; int test_MobTableSize = test_data.m_File.GetRowCount()-1; test_mob_table = new TMobTable[test_MobTableSize]; memset(test_mob_table, 0, sizeof(TMobTable) * test_MobTableSize); //¤¤. Å×½ºÆ® ¸ó½ºÅÍ Å×ÀÌºí¿¡ °ªÀ» ³Ö°í, ¸Ê¿¡±îÁö ³Ö±â. while(test_data.Next()) { if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } test_map_mobTableByVnum.insert(std::map::value_type(test_mob_table->dwVnum, test_mob_table)); ++test_mob_table; } } // 3) 'mob_proto.txt' ÆÄÀÏ°ú (a)[localMap] ¸ÊÀ¸·Î // (!)[mob_table] Å×À̺íÀ» ¸¸µç´Ù. // <Âü°í> // °¢ row µé Áß, // (b)[test_map_mobTableByVnum],(!)[mob_table] ¸ðµÎ¿¡ ÀÖ´Â row´Â // (b)[test_map_mobTableByVnum]ÀÇ °ÍÀ» »ç¿ëÇÑ´Ù. //1. ÆÄÀÏ Àбâ. cCsvTable data; if(!data.Load("mob_proto.txt",'\t')) { fprintf(stderr, "mob_proto.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); return false; } data.Next(); //¼³¸í row ³Ñ¾î°¡±â //2. (!)[mob_table] »ý¼ºÇϱâ //2.1 »õ·Î Ãß°¡µÇ´Â °¹¼ö¸¦ ÆÄ¾Ç int addNumber = 0; while(data.Next()) { int vnum = atoi(data.AsStringByIndex(0)); std::map::iterator it_map_mobTable; it_map_mobTable = test_map_mobTableByVnum.find(vnum); if(it_map_mobTable != test_map_mobTableByVnum.end()) { addNumber++; } } //data¸¦ ´Ù½Ã ùÁÙ·Î ¿Å±ä´Ù.(´Ù½Ã Àоî¿Â´Ù; data.Destroy(); if(!data.Load("mob_proto.txt",'\t')) { fprintf(stderr, "mob_proto.txt ÆÄÀÏÀ» Àоî¿ÀÁö ¸øÇß½À´Ï´Ù\n"); return false; } data.Next(); //¸Ç À­ÁÙ Á¦¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸íÇÏ´Â ºÎºÐ) //2.2 Å©±â¿¡ ¸Â°Ô mob_table »ý¼º if (!m_vec_mobTable.empty()) { sys_log(0, "RELOAD: mob_proto"); m_vec_mobTable.clear(); } m_vec_mobTable.resize(data.m_File.GetRowCount()-1 + addNumber); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; //2.3 µ¥ÀÌÅÍ Ã¤¿ì±â while (data.Next()) { int col = 0; //(b)[test_map_mobTableByVnum]¿¡ °°Àº row°¡ ÀÖ´ÂÁö Á¶»ç. bool isSameRow = true; std::map::iterator it_map_mobTable; it_map_mobTable = test_map_mobTableByVnum.find(atoi(data.AsStringByIndex(col))); if(it_map_mobTable == test_map_mobTableByVnum.end()) { isSameRow = false; } //°°Àº row °¡ ÀÖÀ¸¸é (b)¿¡¼­ Àоî¿Â´Ù. if(isSameRow) { TMobTable *tempTable = it_map_mobTable->second; mob_table->dwVnum = tempTable->dwVnum; strlcpy(mob_table->szName, tempTable->szName, sizeof(tempTable->szName)); strlcpy(mob_table->szLocaleName, tempTable->szLocaleName, sizeof(tempTable->szName)); mob_table->bRank = tempTable->bRank; mob_table->bType = tempTable->bType; mob_table->bBattleType = tempTable->bBattleType; mob_table->bLevel = tempTable->bLevel; mob_table->bSize = tempTable->bSize; mob_table->dwAIFlag = tempTable->dwAIFlag; mob_table->dwRaceFlag = tempTable->dwRaceFlag; mob_table->dwImmuneFlag = tempTable->dwImmuneFlag; mob_table->bEmpire = tempTable->bEmpire; strlcpy(mob_table->szFolder, tempTable->szFolder, sizeof(tempTable->szName)); mob_table->bOnClickType = tempTable->bOnClickType; mob_table->bStr = tempTable->bStr; mob_table->bDex = tempTable->bDex; mob_table->bCon = tempTable->bCon; mob_table->bInt = tempTable->bInt; mob_table->dwDamageRange[0] = tempTable->dwDamageRange[0]; mob_table->dwDamageRange[1] = tempTable->dwDamageRange[1]; mob_table->dwMaxHP = tempTable->dwMaxHP; mob_table->bRegenCycle = tempTable->bRegenCycle; mob_table->bRegenPercent = tempTable->bRegenPercent; mob_table->dwGoldMin = tempTable->dwGoldMin; mob_table->dwGoldMax = tempTable->dwGoldMax; mob_table->dwExp = tempTable->dwExp; mob_table->wDef = tempTable->wDef; mob_table->sAttackSpeed = tempTable->sAttackSpeed; mob_table->sMovingSpeed = tempTable->sMovingSpeed; mob_table->bAggresiveHPPct = tempTable->bAggresiveHPPct; mob_table->wAggressiveSight = tempTable->wAggressiveSight; mob_table->wAttackRange = tempTable->wAttackRange; mob_table->dwDropItemVnum = tempTable->dwDropItemVnum; mob_table->dwResurrectionVnum = tempTable->dwResurrectionVnum; for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) mob_table->cEnchants[i] = tempTable->cEnchants[i]; for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) mob_table->cResists[i] = tempTable->cResists[i]; mob_table->fDamMultiply = tempTable->fDamMultiply; mob_table->dwSummonVnum = tempTable->dwSummonVnum; mob_table->dwDrainSP = tempTable->dwDrainSP; mob_table->dwPolymorphItemVnum = tempTable->dwPolymorphItemVnum; mob_table->Skills[0].bLevel = tempTable->Skills[0].bLevel; mob_table->Skills[0].dwVnum = tempTable->Skills[0].dwVnum; mob_table->Skills[1].bLevel = tempTable->Skills[1].bLevel; mob_table->Skills[1].dwVnum = tempTable->Skills[1].dwVnum; mob_table->Skills[2].bLevel = tempTable->Skills[2].bLevel; mob_table->Skills[2].dwVnum = tempTable->Skills[2].dwVnum; mob_table->Skills[3].bLevel = tempTable->Skills[3].bLevel; mob_table->Skills[3].dwVnum = tempTable->Skills[3].dwVnum; mob_table->Skills[4].bLevel = tempTable->Skills[4].bLevel; mob_table->Skills[4].dwVnum = tempTable->Skills[4].dwVnum; mob_table->bBerserkPoint = tempTable->bBerserkPoint; mob_table->bStoneSkinPoint = tempTable->bStoneSkinPoint; mob_table->bGodSpeedPoint = tempTable->bGodSpeedPoint; mob_table->bDeathBlowPoint = tempTable->bDeathBlowPoint; mob_table->bRevivePoint = tempTable->bRevivePoint; } else { if (!Set_Proto_Mob_Table(mob_table, data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } } //¼Â¿¡ vnum Ãß°¡ vnumSet.insert(mob_table->dwVnum); sys_log(1, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } //_____________________________________________________// // 4) (b)[test_map_mobTableByVnum]ÀÇ rowÁß, (!)[mob_table]¿¡ ¾ø´Â °ÍÀ» Ãß°¡ÇÑ´Ù. //ÆÄÀÏ ´Ù½Ã Àоî¿À±â. test_data.Destroy(); isTestFile = true; test_data; if(!test_data.Load("mob_proto_test.txt",'\t')) { fprintf(stderr, "Å×½ºÆ® ÆÄÀÏÀÌ ¾ø½À´Ï´Ù. ±×´ë·Î ÁøÇàÇÕ´Ï´Ù.\n"); isTestFile = false; } if(isTestFile) { test_data.Next(); //¼³¸í ·Î¿ì ³Ñ¾î°¡±â. while (test_data.Next()) //Å×½ºÆ® µ¥ÀÌÅÍ °¢°¢À» ÈȾ°¡¸ç,»õ·Î¿î °ÍÀ» Ãß°¡ÇÑ´Ù. { //Áߺ¹µÇ´Â ºÎºÐÀÌ¸é ³Ñ¾î°£´Ù. set::iterator itVnum; itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0))); if (itVnum != vnumSet.end()) { continue; } if (!Set_Proto_Mob_Table(mob_table, test_data, localMap)) { fprintf(stderr, "¸÷ ÇÁ·ÎÅä Å×ÀÌºí ¼ÂÆà ½ÇÆÐ.\n"); } sys_log(0, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } } sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); return true; } par bool CClientManager::InitializeMobTable() { char query[2048]; fprintf(stderr,"Loading mob_proto from MySQL "); snprintf(query, sizeof(query), "SELECT vnum,name,%s,rank,type,battle_type,level,size,ai_flag,mount_capacity,setRaceFlag,setImmuneFlag," "empire,folder,on_click,st,dx,ht,iq,damage_min,damage_max,max_hp,regen_cycle,regen_percent,gold_min," "gold_max,exp,def,attack_speed,move_speed,aggressive_hp_pct,aggressive_sight,attack_range,drop_item," "resurrection_vnum,enchant_curse,enchant_slow,enchant_poison,enchant_stun,enchant_critical,enchant_penetrate," "resist_sword,resist_twohand,resist_dagger,resist_bell,resist_fan,resist_bow,resist_fire,resist_elect," "resist_magic,resist_wind,resist_poison,dam_multiply,summon,drain_sp,mob_color,polymorph_item,skill_level0," "skill_vnum0,skill_level1,skill_vnum1,sp_berserk,sp_stoneskin,sp_godspeed,sp_deathblow,sp_revive,skill_level2," "skill_vnum2,skill_level3,skill_vnum3,skill_level4,skill_vnum4 FROM mob_proto%s" ,g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) return false; if (!m_vec_mobTable.empty()) { sys_log(0, "RELOAD: mob_proto"); m_vec_mobTable.clear(); } int size = pRes->uiNumRows; m_vec_mobTable.resize(size); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; MYSQL_ROW data; //return true; set vnumSet; while ((data = mysql_fetch_row(pRes->pSQLResult))) { /* "SELECT vnum,name,locale_name,rank,type,battle_type,level,size,ai_flag,mount_capacity,setRaceFlag,setImmuneFlag," "empire,folder,on_click,st,dx,ht,iq,damage_min,damage_max,max_hp,regen_cycle,regen_percent,gold_min," "gold_max,exp,def,attack_speed,move_speed,aggressive_hp_pct,aggressive_sight,attack_range,drop_item," "resurrection_vnum,enchant_curse,enchant_slow,enchant_poison,enchant_stun,enchant_critical,enchant_penetrate," "resist_sword,resist_twohand,resist_dagger,resist_bell,resist_fan,resist_bow,resist_fire,resist_elect," "resist_magic,resist_wind,resist_poison,dam_multiply,summon,drain_sp,mob_color,polymorph_item,skill_level0," "skill_vnum0,skill_level1,skill_vnum1,sp_berserk,sp_stoneskin,sp_godspeed,sp_deathblow,sp_revive,skill_level2," "skill_vnum2,skill_level3,skill_vnum3,skill_level4,skill_vnum4 FROM mob_proto%s */ int col = 0; str_to_number(mob_table->dwVnum, data[col++]); if(mob_table->dwVnum ==0) continue; strlcpy(mob_table->szName,data[col++] , sizeof(mob_table->szName)); strlcpy(mob_table->szLocaleName, data[col++], sizeof(mob_table->szLocaleName)); str_to_number(mob_table->bRank,data[col++]); str_to_number(mob_table->bType,data[col++]); str_to_number(mob_table->bBattleType,data[col++]); str_to_number(mob_table->bLevel,data[col++]); str_to_number(mob_table->bSize,data[col++]); //AI_FLAG mob_table->dwAIFlag = get_Mob_AIFlag_Value(data[col++]); //mount_capacity; col++; //RACE_FLAG mob_table->dwRaceFlag = get_Mob_RaceFlag_Value(data[col++]); //IMMUNE_FLAG mob_table->dwImmuneFlag = get_Mob_ImmuneFlag_Value(data[col++]); mob_table->bEmpire = atoi(data[col++]); strlcpy(mob_table->szFolder, data[col++], sizeof(mob_table->szFolder)); mob_table->bOnClickType = atoi(data[col++]); mob_table->bStr = atoi(data[col++]); mob_table->bDex = atoi(data[col++]); mob_table->bCon = atoi(data[col++]); mob_table->bInt = atoi(data[col++]); mob_table->dwDamageRange[0] = atoi(data[col++]); mob_table->dwDamageRange[1] = atoi(data[col++]); mob_table->dwMaxHP = atoi(data[col++]); mob_table->bRegenCycle = atoi(data[col++]); mob_table->bRegenPercent = atoi(data[col++]); mob_table->dwGoldMin = atoi(data[col++]); mob_table->dwGoldMax = atoi(data[col++]); mob_table->dwExp = atoi(data[col++]); mob_table->wDef = atoi(data[col++]); mob_table->sAttackSpeed = atoi(data[col++]); mob_table->sMovingSpeed = atoi(data[col++]); mob_table->bAggresiveHPPct = atoi(data[col++]); mob_table->wAggressiveSight = atoi(data[col++]); mob_table->wAttackRange = atoi(data[col++]); str_to_number(mob_table->dwDropItemVnum, data[col++]); //32 str_to_number(mob_table->dwResurrectionVnum, data[col++]); for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) str_to_number(mob_table->cEnchants[i], data[col++]); for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i) str_to_number(mob_table->cResists[i], data[col++]); str_to_number(mob_table->fDamMultiply, data[col++]); str_to_number(mob_table->dwSummonVnum, data[col++]); str_to_number(mob_table->dwDrainSP, data[col++]); //Mob_Color ++col; str_to_number(mob_table->dwPolymorphItemVnum, data[col++]); str_to_number(mob_table->Skills[0].bLevel, data[col++]); str_to_number(mob_table->Skills[0].dwVnum, data[col++]); str_to_number(mob_table->Skills[1].bLevel, data[col++]); str_to_number(mob_table->Skills[1].dwVnum, data[col++]); str_to_number(mob_table->Skills[2].bLevel, data[col++]); str_to_number(mob_table->Skills[2].dwVnum, data[col++]); str_to_number(mob_table->Skills[3].bLevel, data[col++]); str_to_number(mob_table->Skills[3].dwVnum, data[col++]); str_to_number(mob_table->Skills[4].bLevel, data[col++]); str_to_number(mob_table->Skills[4].dwVnum, data[col++]); str_to_number(mob_table->bBerserkPoint, data[col++]); str_to_number(mob_table->bStoneSkinPoint, data[col++]); str_to_number(mob_table->bGodSpeedPoint, data[col++]); str_to_number(mob_table->bDeathBlowPoint, data[col++]); str_to_number(mob_table->bRevivePoint, data[col++]); //ĽÂżˇ vnum Ăß°ˇ vnumSet.insert(mob_table->dwVnum); //fprintf(stderr, "MOB #%d %s %s level: %u rank: %u empire: %d\n", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); sys_log(0, "MOB #%-5d %-24s %-24s level: %-3u rank: %u empire: %d", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire); ++mob_table; } fprintf(stderr," Complete! %d/%d Mobs loaded.\r\n",size,vnumSet.size()); sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); return true; } Attention dans bool CClientManager::InitializeTables() vous devrez supprimez donc MirrorMobTableIntoDB() and MirrorItemTableIntoDB() Source : EPvP
  6. Niveau requis : Débutant Temps estimé : Entre 10 et 15 minutes Réécriture by Xayah Bonjour, voici un système qui vous permettra d'équiper des stuffs pré-enregistrés dans une fenêtre ! Pré-requis: Cette archive : Téléchargement ou FE Votre client Eternexus I. Tutoriel II. Placer les fichiers Succès ! Vous pouvez désormais profiter pleinement de ce système, Enjoy ! A savoir : Si vous ne savez pas comment utiliser Eternexus, je vous invite à bien lire ce tutoriel : Depack & Repack avec Eternexus Si vous avez un problème, n'hésitez pas à rédiger un sujet dans la section A/Q/S
  7. Hellow, Je vous partage un petit "systeme ?" pour choisir le skin de son magasin ==> ICI FE Le tuto est dans le dossier , petit screen de ce petit système a l'ouverture d'un magasin : source : turkmmo feat. iRyZz ^_-
  8. Bonjour la communauté! Après avoir été sur Epvp j'ai trouvé un joli système en python. Je vous glisse une aperçu. Pour commencer ouvrez: game.py Recherchez: import ime Ajoutez en dessous: import uisidebar Recherchez: self.__ServerCommand_Build() self.__ProcessPreservedServerCommand() Passer une ligne et ajoutez: self.sideBar = uisidebar.SideBar() self.sideBar.Show() Recherchez: self.KillFocus() app.HideCursor() Passer une ligne et ajoutez: self.sideBar.Destroy() self.sideBar = None Téléchargez-ici FE Bonne journée!
  9. Salut à tous, aujourd'hui, je vais vous faire un petit tutoriel sur comment implanter le BonusPage, alors commençons d'abord, téléchargez le fichier suivant : ICI FE Ouvrez votre game.py Cherchez la ligne import chat Ajoutez en dessous import uibonuspage Cherchez la ligne onPressKeyDict[app.DIK_F4] = lambda : self.__PressQuickSlot(7) Ajoutez en dessous onPressKeyDict[app.DIK_U] = lambda : self.__BonusPage() Allez à la fin de votre game.py et ajoutez # Page de bonus def __showbonus(self): import uiBonusPage global bonuspp try: if bonuspp != 1: exec 'uiBonusPage.BonusBoardDialog().Show()' else: pass except ImportError: import dbg,app dbg.Trace('uiBonusPage.py Importing error') app.Abort() def __BonusPage(self): import uibonuspage self.wndBonus = uibonuspage.BonusBoardDialog() self.wndBonus.Show() Enregistrez votre game.py, fermez le et ouvrez ui.py Cherchez la ligne def SetOverVisual(self, filename): wndMgr.SetOverVisual(self.hWnd, filename) Ajoutez en dessous en sautant une ligne # Page de bonus def GetText(self): if not self.ButtonText: return return self.ButtonText.GetText() Voilà, le tutoriel est fini, le BonusPage apparaîtra quand vous appuierez sur la touche U Le BonusPage est totalement traduit en français, il n'y aura donc pas besoin de le traduire Sources : J'ai copié ce système sur le client de Metin2 World Bonne journée !
  10. Bonjour à tous, je partage donc aujourd'hui le système de costume weapon. Je tiens à signialer que celui si bug au niveau des arc et des dagues, en effet, le personnage porte l'arc du mauvais coter, et la dague une seul partie est apparente l'autre c'est la dague normal. Je vous met tout de même deux screen vous montrant les bug Le liens de téléchargement : ICI FE
  11. Plop, je vous partage un système que j'ai trouvé avec l'aide de Franch Chaque grade comporte un grade IMPLEMENTOR = GA HIGH_WIZARD = SGM GOD = GM LOW_WIZARD = MOD Il faudra modifier la partie Source serveur ( tutoriel dans le fichier rar ) Il faudra modifier la partie source client ( tutoriel dans le fichier rar ) Il faudra modifier la partie root.eix Il faudra modifier la partie locale_fr.eix Toute les informations ce trouve dans le fichiers rar, Le partage vient du forum turkmmo l'auteur c'est Suky Voici les screens qui vont avec : Virus Total : ICI Download : ICI FE Mirroir : Yeni Yetkili Tagları.rar J’espère que sa pourra vous intéressé
  12. Carquois de flèche. 1) Qu'est-ce que c'est? 2) Les prérequis. 3) Les téléchargements. 1) Qu'est-ce que c'est? Il existe 4 type de carquois qui ont chacun un temps différent. Durée de 24 Heures. Durée de 7 Jours. Durée de 15 Jours. Durée de 30 Jours. Une carquois c'est un stock de flèche illimité sauf en temps comme indiqué ci-dessus, Les dégâts infligés ne sont pas réduit par la distances. 2) Les prérequis. Sources Client / Server. Un Client. Files. Les fichiers en téléchargement. Votre tête qui encore une fois vous sera utile. 3) Les téléchargements. Cliquez ici FE Sources : Board-Legend LeNn't. Traduction : Moi. Bonne installation. Cordialement, History.
  13. Shop Hors-Ligne. 1) Qu'est-ce que c'est? 2) Les prérequis. 3) Le téléchargement. 1) Qu'est-ce que c'est? Les shop hors-ligne sont des shop ou sont propriétaire est soit déconnecter ou soit en train de jouer les shops sont séparer de sont propriétaire! Finit de ce déshabiller pour ce mettre en shop! Maintenant vous être libre de jouer tout en ayant un shop ouvert! 2) Les prérequis. Sources Client/Serveur. Un Client. Des files. Les fichiers en téléchargement. Votre tête qui est encore une fois utile. 3) Le téléchargement. Cliquez ici FE Autres fonctions: Support multi-prix. Montre l'emplacement de l'item vendu. Possibilité d'ouvrir jusqu'à 2 shop par joueurs. Source: BoardLegend/Koray. Traduction: Moi. ( Temps de traduction environ 2 à 3h.) Cordialement, History.
  14. Bon nombre d'entre nous sont fatigué sur metin. Alors pourquoi pas faire une pause? 1) Comment ? Qu'est ce que c'est ? 2) Les pré requis. 3) Les fichiers. 1) Comment ? Qu'est ce que c'est ? Depuis peu, j'ai remarqué que beaucoup de joueurs étaient fatigué après avoir exp etc ... Alors je me suis dit pourquoi pas installer cela qui pourrais vraiment être sympa ! Vous-vous dites mais il est fous, il va nous mettre des système de malade et tout ! Et bien oui, je suis fous °-°. Comme vous l'avez vu sur le screen et bien on peux désormais s'asseoir sur metin. Ce système vous permet de vous asseoir le temps d'une pause. Utilisation: /stand /sit Bon repos les amis 2) Les prérequis. Sources Client Sources game/db Des Files Un Client Être en Granny 2.9 3) Les fichiers. Cliquez ici :) Lien mis à jours le 15/01/2018 Nouvelles Animation Sitting FE (contient les 2) #Ajout 25/11/17: Nouvelles animations pour s’asseoir avec en bonus une animation pour ce lever ! Ces animations sont pour toutes classes et viennent de Ymir. Edit: Merci à Keito pour avoir implanté le système et avoir refait tout les screens de l'archive. (Screens présent dans l'archive directement.) Sources: Board Legend Traduction par moi même. Cordialement, History.
  15. Bonjour à tous. J'ai remarqué grâce à un screen de l'officiel posté par @ASIKOO sur le Discord que l'officiel avait implanté de nouvelles potions lors de la nouvelle mise à jour 18.0. Ces potions sont des Potions Bleues et Rouges de taille XXL qui restaurent respectivement 2400 PV et 800 PM. Donc après un peu de fouille dans le client de l'officiel ainsi qu'à une extraction de protos et à une rapide création de query, voici les potions XXL. Le pack contient la partie client & serveur ainsi que la partie base de donnée. Cependant, vous devrez packer vous même votre "item_proto". Vidéo de présentation : Rapide tutoriel d'implantation : Dépackez votre pack "icon" et glissez y le dossier "icon" présent dans "ymir work/icon" de ce pack. Il faut que Windows vous demande si vous souhaitez fusionner les dossiers. Faites oui et repackez icon. Rendez-vous côté serveur, ouvrez votre "item_names.txt" et votre "item_proto.txt " et rajoutez le contenu des fichiers"item_names.txt" et "item_proto.txt" présent dans le dossier "files_db" du pack. Dépackez "locale_fr", ouvrez le fichier "locale" présent dans ce pack et rajoutez le contenu du fichier "item_list.txt" dans le fichier "item_list.txt" du pack "locale_fr" que vous venez de dépacker. La même manipulation est requise pour le fichier "itemdesc.txt". Une fois ceci fait, packez les protos serveur avec les potions rajoutées. Placez le nouvel "item_proto" dans votre pack "locale". Vous pouvez repacker "locale_fr" une fois ces trois fichiers à jour. Ouvrez Navicat, ouvrez la base de donnée "player", puis copiez le contenu de "shop_item.sql" présent dans le dossier "sql_db_player" du pack. Puis, dans Navicat, appuyez sur F6 en ayant la base de donnée "player" sélectionnée et collez le contenu du fichier "shop_item.sql" précédement copié. Appuyez sur votre touche "Entrée" pour valider la query. Une fois les étapes-ci dessus effectuées, lancez votre serveur. Les potions seront disponibles à l'achat à la marchande. Lien du pack : ICI FE (Futures ?) Mises à jours : La version actuelle est la version 0.1, elle contient les potions identiques à l'officiel (22/04/2018) ainsi que leur présence à la Marchande. Je mettrai le pack à jour si l'officiel fait une mise à jour (je pense notamment au modèle 3D lorsque dropées au sol qui n'existe pas pour ces potions (vous pouvez utiliser celui des autres potions, l'officiel n'en n'utilise pas)). Je peux aussi mettre ce pack à jour si quelqu'un me fait part de plus d'info : Est-ce que ces potions se droppent et si oui, où, à partir de quel level etc. Le pack sera à jour au fil des informations que vous me donnerez. Libre à vous de vous même effectuer ces modifications et de les partager (ou pas, selon vous) ici. PS : Selon le patchnote, la Potion Rouge (XL) existe, cependant je n'ai pas regardé les shops, mais il me semble que cette dernière n'est pas répertoriée. Si jamais vous avez des infos, n'hésitez pas ! Bonne implantation et journée
  16. Bonjour à toutes et à tous ! J'ai fais quelques recherches sur ce forum mais je n'ai rien trouvé à ce sujet donc je vais vous expliquer comment mettre en place une GUI (Graphical User Interface) montrant les statistiques sans passer par une quête. Bien sûr, il y a possibilité de désactiver ou réactiver l'affichage de cette interface à tout moment à l'aide d'une petite quête. Bref, au travail ! Pour commencer vous aurez besoin de dépack le fichier "root" afin d'avoir accès au fichier "game.py" puis ouvrez le. Petite précision: le copier-coller c'est pas terrible vu que le python n'aime pas les espaces. Donc si vous avez des problèmes à la fin du tuto, remplacez les espaces par des tabulations. /!\La quête est nécessaire pour afficher l'interface/!\ Cherchez la ligne: self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) Puis faites un copier/coller de ceci: #START_KILLGUI KillGuiBg = ui.AniImageBox() KillGuiBg.AppendImage("d:/ymir work/ui/blue_killgui_interface.tga") self.KillGuiBg = KillGuiBg self.KillGuiBg.SetPosition(wndMgr.GetScreenWidth()-235,185) self.KillBlauReich = ui.TextLine() self.KillBlauReich.SetDefaultFontName() self.KillBlauReich.SetPosition((wndMgr.GetScreenWidth()-285)+120, 412) self.KillBlauReich.SetText("Royaume bleu: NaN") self.KillBlauReich.SetOutline() self.KillGelbReich = ui.TextLine() self.KillGelbReich.SetDefaultFontName() self.KillGelbReich.SetPosition((wndMgr.GetScreenWidth()-289)+120, 332) self.KillGelbReich.SetText("Royaume jaune: NaN") self.KillGelbReich.SetOutline() self.KillRotReich = ui.TextLine() self.KillRotReich.SetDefaultFontName() self.KillRotReich.SetPosition((wndMgr.GetScreenWidth()-289)+120, 255) self.KillRotReich.SetText("Royaume Rouge: NaN") self.KillRotReich.SetOutline() self.KillMob = ui.TextLine() self.KillMob.SetDefaultFontName() self.KillMob.SetPosition((wndMgr.GetScreenWidth()-268)+120, 490) self.KillMob.SetText("Monstre: NaN") self.KillMob.SetOutline() ##END_KILLGUI Cherchez maintenant la ligne: serverCommandList={ Puis faites un copier/coller de ceci: ##KILLGUI "ShowKillGui" : self.__showkillgui, "HideKillGui" : self.__hidekillgui, "KillBlauReich" : self.__KillBlauReich, "KillGelbReich" : self.__KillGelbReich, "KillRotReich" : self.__KillRotReich, "KillMob" : self.__KillMob, ##END_KILLGUI Maintenant, allez à la fin de votre fichier game.py, personnellement je l'ai mis au dessus de cette ligne: def __ProcessPreservedServerCommand(self): Lorsque vous avez repéré cette ligne, faites un copier/coller de ceci: def __hidekillgui(self): self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() def __showkillgui(self): self.KillGuiBg.Show() self.KillBlauReich.Show() self.KillGelbReich.Show() self.KillRotReich.Show() self.KillMob.Show() def __KillBlauReich(self, KillBlauReich): self.KillBlauReich.SetText("Royaume bleu " + KillBlauReich) def __KillGelbReich(self, KillGelbReich): self.KillGelbReich.SetText("Royaume jaune " + KillGelbReich) def __KillRotReich(self, KillRotReich): self.KillRotReich.SetText("Royaume rouge " + KillRotReich) def __KillMob(self, KillMob): self.KillMob.SetText("Monstre " + KillMob) Repackez votre fichier root. Vous devez maintenant extraire "etc" pour avoir accès à votre dossier "ui" Téléchargez ce fichier: [Hidden Content] Placez le dans le dossier "ui" d:/ymir work/ui/blue_killgui_interface.tga Ouvrez le fichier "etc_repack.xml" et ajoutez cette ligne: depack\ymir work\ui\blue_killgui_interface.tga Sauvegardez et repackez "etc" Le côté client est terminé ! maintenant il faut implanter la quête permettant de cacher ou afficher l'interface. Allez dans le dossier "quest" via winscp ou filezilla. Créez un fichier nommé: kill_gui.quest Puis ajoutez la quête au fichier: quest killgui begin state start begin when kill begin if npc.is_pc() then local new_point = pc.getqf("empire"..npc.get_empire())+1 pc.setqf("empire"..npc.get_empire(), new_point) cmdchat("KillRotReich "..pc.getqf("empire1")) cmdchat("KillGelbReich "..pc.getqf("empire2")) cmdchat("KillBlauReich "..pc.getqf("empire3")) else local new_point = pc.getqf("mob")+1 pc.setqf("mob", new_point) cmdchat("KillMob "..pc.getqf("mob")) end end when login begin if pc.getqf("showkillgui") == 1 then cmdchat("ShowKillGui") cmdchat("KillRotReich "..pc.getqf("empire1")) cmdchat("KillGelbReich "..pc.getqf("empire2")) cmdchat("KillBlauReich "..pc.getqf("empire3")) cmdchat("KillMob "..pc.getqf("mob")) else cmdchat("HideKillGui") end end when letter begin send_letter("Statistiques") end when info or button begin say_title("Statistiques") say("Voulez-vous désactiver l'affichage de vos") say("statistiques ?") say("Les personnes ou mobs tués seront tout de même") say("comptabilisés. Vous pourrez réactiver à tout moment") say("l'affichage des statistiques.") local janein = select("Afficher", "Cacher") if janein == 2 then pc.setqf("showkillgui", 0) cmdchat("HideKillGui") else pc.setqf("showkillgui", 1) cmdchat("ShowKillGui") cmdchat("KillRotReich "..pc.getqf("empire1")) cmdchat("KillGelbReich "..pc.getqf("empire2")) cmdchat("KillBlauReich "..pc.getqf("empire3")) cmdchat("KillMob "..pc.getqf("mob")) end end end end Ajoutez le fichier à filezilla ou winscp puis ouvrez le fichier: locale_list et ajoutez cette ligne: kill_gui.quest (N'oubliez pas de laisser une ligne vide en dessous de la dernière ligne ajoutée) Sauvegardez puis recompilez la quête. Dans la liste des quêtes vous verrez la quête "Statistiques" cliquez dessus puis activez l'affichage de la GUI, le tour est joué ! Petit plus ! Il y a en tout 5 interfaces (en comptant celle-ci) j'ai choisis de vous partager cette interface car je trouve que c'est la plus belle, mais après chacun ses goûts. Téléchargement: [Hidden Content] Téléchargement: [Hidden Content] Pour changer d'interface, renommez le fichier téléchargé en "blue_killgui_interface.tga" puis déplacez le ici en remplaçant l'ancienne interface si besoin est: d:/ymir work/ui/blue_killgui_interface.tga Changer l'emplacement de l'écriture Si vous changez d'interface, vous aurez sans doute besoin de régler la position du texte. Ouvrez le fichier "game.py" puis cherchez la ligne: self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) Vous verrez donc les coordonnées de chaque ligne: Si vous souhaitez changer le texte, c'est simple. Cherchez la ligne: def __hidekillgui(self): Laisser la GUI affichée après chaque téléportation: Merci à Spark pour la modification du python et de la quête ! Pour commencer, remplacez la quête implantée précédemment par celle-ci: quest killgui begin state start begin when kill begin if npc.is_pc() then local new_point = pc.getqf("empire"..npc.get_empire())+1 local tab = {"KillRotReich", "KillGelbReich", "KillBlauReich"} pc.setqf("empire"..npc.get_empire(), new_point) cmdchat(tab[npc.get_empire()].." "..new_point) else local new_point = pc.getqf("mob")+1 pc.setqf("mob", new_point) cmdchat("KillMob "..new_point) end end when login begin cmdchat("ShowKillGui") cmdchat("KillRotReich "..pc.getqf("empire1")) cmdchat("KillGelbReich "..pc.getqf("empire2")) cmdchat("KillBlauReich "..pc.getqf("empire3")) cmdchat("KillMob "..pc.getqf("mob")) end end end Allez dans vitre game.py puis remplacez: "ShowKillGui" : self.__showkillgui, Par: "ShowKillGui" : self.__showkillgui2, Remplacez ensuite: def __hidekillgui(self): self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() Par: def __showkillgui2(self): constInfo.killgui = 1 self.KillGuiBg.Show() self.KillBlauReich.Show() self.KillGelbReich.Show() self.KillRotReich.Show() self.KillMob.Show() Repackez votre root puis testez ! Merci à Spark ! Afficher/cacher l'interface à l'aide d'un raccourcis (F5)Passer par une quête à chaque fois pour afficher ou cacher l'interface peut être assez chiant, voilà la solution: un raccourcis sur la touche F5 ! Ouvrez le fichier game.py de votre root puis allez à la fin de votre fichier pour trouver ces lignes: Remplacez donc: def __hidekillgui(self): self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() def __showkillgui(self): self.KillGuiBg.Show() self.KillBlauReich.Show() self.KillGelbReich.Show() self.KillRotReich.Show() self.KillMob.Show() Par ceci: def __hidekillgui(self): self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() def __showkillgui(self): if constInfo.killgui == 0: constInfo.killgui = 1 self.KillGuiBg.Show() self.KillBlauReich.Show() self.KillGelbReich.Show() self.KillRotReich.Show() self.KillMob.Show() elif constInfo.killgui == 1: constInfo.killgui = 0 self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() Cherchez la ligne: onPressKeyDict[app.DIK_F4] = lambda : self.__PressQuickSlot(7) Puis ajoutez en dessous: onPressKeyDict[app.DIK_F5] = lambda : self.__showkillgui() (ne rien ajouter dans la parenthèse en fin de ligne) Sauvegardez puis quittez le fichier game.py. Toujours dans root ouvre le fichier "constinfo.py" Cherchez la ligne: PVPMODE_PROTECTED_LEVEL = 30 (la valeur à la fin de cette ligne peut changer) Puis en dessous ajoutez cette ligne: killgui = 0 Sauvegardez, repackez et en jeu, appuyez sur F5 ! Après ça on a toujours besoin de la quête, donc ne la supprimez pas ! Optimisé pour l'interface V4 (avec raccourcis) Je me suis intéressé à la version 4 de l'interface, voilà donc les emplacements que je trouve optimaux pour cet interface: /!\Vous devez avoir installé le raccourcis de la partie juste au dessus/!\ En dessous de la ligne: self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) Mettre ceci: ##START_KILLGUI KillGuiBg = ui.AniImageBox() KillGuiBg.AppendImage("d:/ymir work/ui/blue_killgui_interface.tga") self.KillGuiBg = KillGuiBg self.KillGuiBg.SetPosition(wndMgr.GetScreenWidth()-245,171) self.KillBlauReich = ui.TextLine() self.KillBlauReich.SetDefaultFontName() self.KillBlauReich.SetPosition((wndMgr.GetScreenWidth()-285)+120, 445) self.KillBlauReich.SetText("Royaume bleu: NaN") self.KillBlauReich.SetOutline() self.KillGelbReich = ui.TextLine() self.KillGelbReich.SetDefaultFontName() self.KillGelbReich.SetPosition((wndMgr.GetScreenWidth()-289)+120, 340) self.KillGelbReich.SetText("Royaume jaune: NaN") self.KillGelbReich.SetOutline() self.KillRotReich = ui.TextLine() self.KillRotReich.SetDefaultFontName() self.KillRotReich.SetPosition((wndMgr.GetScreenWidth()-289)+120, 231) self.KillRotReich.SetText("Royaume Rouge: NaN") self.KillRotReich.SetOutline() self.KillMob = ui.TextLine() self.KillMob.SetDefaultFontName() self.KillMob.SetPosition((wndMgr.GetScreenWidth()-268)+120, 557) self.KillMob.SetText("Monstre: NaN") self.KillMob.SetOutline() ##END_KILLGUI Puis au dessus de la ligne: def __ProcessPreservedServerCommand(self): Ceci: def __hidekillgui(self): self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() def __showkillgui(self): if constInfo.killgui == 0: constInfo.killgui = 1 self.KillGuiBg.Show() self.KillBlauReich.Show() self.KillGelbReich.Show() self.KillRotReich.Show() self.KillMob.Show() elif constInfo.killgui == 1: constInfo.killgui = 0 self.KillGuiBg.Hide() self.KillBlauReich.Hide() self.KillGelbReich.Hide() self.KillRotReich.Hide() self.KillMob.Hide() def __KillBlauReich(self, KillBlauReich): self.KillBlauReich.SetText(" " + KillBlauReich) def __KillGelbReich(self, KillGelbReich): self.KillGelbReich.SetText(" " + KillGelbReich) def __KillRotReich(self, KillRotReich): self.KillRotReich.SetText(" " + KillRotReich) def __KillMob(self, KillMob): self.KillMob.SetText(" " + KillMob) Repackez votre fichier root et c'est bon. Optimisé pour l'interface V5 (avec raccourcis) Par LordGune Nul besoin de faire tout un pitch pour expliquer comment mettre ce changement: #START_KILLGUI KillGuiBg = ui.AniImageBox() KillGuiBg.AppendImage("d:/ymir work/ui/blue_killgui_interface.tga") self.KillGuiBg = KillGuiBg self.KillGuiBg.SetPosition(wndMgr.GetScreenWidth()-235,185) self.KillBlauReich = ui.TextLine() self.KillBlauReich.SetDefaultFontName() self.KillBlauReich.SetPosition((wndMgr.GetScreenWidth()-207)+120, 458) self.KillBlauReich.SetText("Bleue Tuer: NaN") self.KillBlauReich.SetOutline() self.KillGelbReich = ui.TextLine() self.KillGelbReich.SetDefaultFontName() self.KillGelbReich.SetPosition((wndMgr.GetScreenWidth()-209)+120, 354) self.KillGelbReich.SetText("Jaune Tuer: NaN") self.KillGelbReich.SetOutline() self.KillRotReich = ui.TextLine() self.KillRotReich.SetDefaultFontName() self.KillRotReich.SetPosition((wndMgr.GetScreenWidth()-209)+120, 246) self.KillRotReich.SetText("Rouge Tuer: NaN") self.KillRotReich.SetOutline() self.KillMob = ui.TextLine() self.KillMob.SetDefaultFontName() self.KillMob.SetPosition((wndMgr.GetScreenWidth()-215)+120, 572) self.KillMob.SetText("Monstre: NaN") self.KillMob.SetOutline() ##END_KILLGUI Merci à LordGune pour avoir partagé cette version optimisée ! Sources: Tuto, screens, adaptation de l'interface/écriture, (petite) traduction de la quête entièrement par moi. Le reste est de ©ChaoSS sur epvp. L'option "raccourcis" provient de "ToBii™" sur epvp. GUI v5 par .ωєιя∂ sur epvp. J'espère ne rien avoir oublié. Bon jeu à tous et bonne chance ! Source : Craven LIEN DE DL GENERAL
  17. Les 7 et 8 ième skills. 1) Qu'est ce que c'est , comment ça fonctionne? 2) Les prérequis. 3) Les fichiers. 1) Qu'est ce que c'est , comment ça fonctionne? La 7ème compétence. La 7ième compétence offre un bonus de résistance contre une compétence choisie par le joueur parmi 9 compétences. Pour apprendre la 7ème compétence il vous faut un Livre de parade, un message s'ouvre alors pour choisir la compétences de parade. Listes des compétences : La 8ème compétence. La 8ème compétence offre un Bonus d'attaque à l'une de vos compétences, déterminée par votre classe. Pour apprendre ces compétences, deux conditions doivent-être réunies: La 7ième compétences doit être en Maître Parfait La compétences que vous voulez booster doit avoir au minimum 2 points de compétences dessus. Une fois les conditions réunies, il vous faut un Livre de bonus . Ce qui aura pour effet de débloquer la 8ième compétence. Voici les 9 compétences qui peuvent-être booster: Améliorations des compétences 7 et 8 L'amélioration de ces 2 compétences sont similaires à celle des compétences de classes. Elles comportent également 4 stades ( 1 / M / G / P ) Pour les améliorer vous devez: Soit Attribuer des points de compétences à cet compétence. Soit en réussissant la lecture ( Manuel Parade pour le parade ou Bonus pour le bonus ) 1 niveau augmenté pour un manuel utiliser. Niveau 0 à 19: La compétences passe niveau M1 Soit à 17 points soit 18 soit 19 soit 20. ( Les points sont différents de celle de vos personnages et ne dérange absolument en rien la progression de votre personnage.) La lecture d'un manuel de parade ou bonus Consomme toujours 20.000 points d'expérience et il faut attendre entre 18 et 30 heures entre 2 lectures. Niveau M1 à M10: Le système est le même que les compétences classes et il vous faut 55 Manuels pour la passer en G1. Niveau G1 à G10: Le système est le même que les compétences classes il vous faut réussir au total 10 Pierres d'âme ( Rose / Rouge ) Pour que la compétence passe au Stade P. Si le choix de l'une de vos 2 compétences ne vous conviens plus ou pas vous pouvez les réinitialiser via le Parchemin de modification d'entraînement. Sources des explications sur le système ( Wikipedia ) Screens ingame 2) Les prérequis. Pour les prérequis voici ce dont vous aurez besoin de: Sources client Sources DB Sources Game Un Client Des Files Pour le bon fonctionnement du système veuillez suivre le tutoriel (qui se trouve dans l'archive) à la lettre et faites attentions aux tabulations ! 3) Les fichiers. Cliquez ici FE Ces fichiers ne sont en aucun cas les miens , la traduction est de moi même ( Si toutes fois il as une erreur de traduction ou un manque merci de me l'indiquer je le corrigerai a la suite.) Cordialement, History.
  18. Ban ordinateur. 1) Qu'est-ce que c'est? 2) Les prérequis. 3) Le téléchargement. 1) Qu'est-ce que c'est? Je sais que bon nombre d'entre nous ont été embêté par des joueurs sans respect et qui en soit utilise un vpn pour contrer vos bans defs ! Et bien cet fois vous pouvez les bannir à partir de leurs ordinateur et non via l'ip ! Je sent déjà des joueurs qui vont me haïr, mais je vous aimes moi ! 2) Les prérequis. Des sources Client/Serveur. Un Client. Des Files. Une connexion Mysql. Votre tête. 3) Le téléchargement. Cliquez ici Coucou Calypso, je suis un lien FE Le partage n'est pas de moi ni même de la Team-Emu. Ce partage proviens de Koray. La traduction est de moi même. Bon bans à tout les joueurs qui vont pas aimer . Cordialement, History.
  19. Les pierres anti-magie. 1) Qu'est ce que c'est? 2) Les prérequis. 3) Le téléchargement. 1) Qu'est ce que c'est? Les pierres anti-magie sont des pierres qui vous apportent une résistance à la magie. Lorsque cet pierre est utilisée par un Sura la valeur de résistance magique est divisée par 2. Elles sont uppable jusqu'à +4 et vous donnent: 2) Les prérequis. Sources serveur/Client/Dump-proto. Des Files. Un Client. L'archive en téléchargement. 3) Le téléchargement. Cliquez ici Un lien FE Source: BoardLegend/LeNn't Traduction: Moi. Bonne implantation! Cordialement, History.
  20. Bonjour, Voici un petit changeur d'environnement, vous pouvez le modifier à votre guise. Résultat : 1) Ouvrir uigameoption.py (-> dépack root) 2) Ouvrir constInfo.py (-> dépack root) 3) Ouvrir gameoptiondialog.py (-> dépack uiscript) PS : ATTENTION AU TAB ! *** Ce tutoriel a été réédité pour la V6.***
  21. Bonjour, Je vais vous montrer comment accéder à l'entrepôt via l'inventaire: Partie python 1/ Ouvrir uiinventory.py Cherchez et remplacez [b def ClickMallButton[/b] par] def ClickMallButton(self): self.choix = ui.BoardWithTitleBar() self.choix.SetSize(210, 80) self.choix.SetCenterPosition() self.choix.AddFlag('float') self.choix.AddFlag('movable') self.choix.SetTitleName("Ouverture entrepôt") self.choix.Show() self.EntrepotIs = ui.Button() self.EntrepotIs.SetEvent(self.OpenIs) self.EntrepotIs.SetParent(self.choix) self.EntrepotIs.SetPosition(35, 40) self.EntrepotIs.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.EntrepotIs.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.EntrepotIs.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.EntrepotIs.SetText("ItemShop") self.EntrepotIs.SetToolTipText("Ouvrir l'entrepot ItemShop") self.EntrepotIs.Show() self.Magasinier = ui.Button() self.Magasinier.SetEvent(self._normal_mall) self.Magasinier.SetParent(self.choix) self.Magasinier.SetPosition(105, 40) self.Magasinier.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.Magasinier.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.Magasinier.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.Magasinier.SetText("Magasinier") self.Magasinier.SetToolTipText("Ouvrir le magasinier") self.Magasinier.Show() En-dessous ajoutez def OpenIs(self): self.EntrepotIs.Hide() self.choix.Hide() self.Magasinier.Hide() net.SendChatPacket("/click_mall") def _normal_mall(self): self.EntrepotIs.Hide() self.Magasinier.Hide() self.choix.Hide() net.SendChatPacket("/click_safebox") Partie C++ Ouvrir le fichier cmd_general.cpp et cherchez ACMD(do_click_mall) { ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeMallPassword"); } En-dessous ajoutez ACMD(do_click_safebox) { ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeSafeboxPassword"); } Ouvrir le fichier cmd.cpp et cherchez ACMD(do_click_mall); En-dessous ajoutez ACMD(do_click_safebox); Dans ce même fichier, cherchez { "click_mall", do_click_mall, 0, POS_DEAD, GM_PLAYER }, En-dessous ajoutez { "click_safebox", do_click_safebox, 0, POS_DEAD, GM_PLAYER }, Ouvrir le fichier [b char.cpp[/b] (pour retirer la distance limite entre le magasinier et le joueur pour l'accès à l'entrepôt) et cherchez] else if (GetDistanceFromSafeboxOpen() > 1000) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> °Å¸®°¡ ¸Ö¾î¼* â°í¸¦ ¿* ¼ö ¾ø½À´Ï´Ù.")); return; } Commentez tout simplement /* else if (GetDistanceFromSafeboxOpen() > 1000) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<â°í> °Å¸®°¡ ¸Ö¾î¼* â°í¸¦ ¿* ¼ö ¾ø½À´Ï´Ù.")); return; } */ Et pour finir, le résultat: Afficher le résultat
  22. Je vous partage aujourd'hui mon système de sauvegarde vers FTP distant. Connectez-vous tout d'abord à WinSCP et créez un dossier qui se nommera "sauvegarde" dans root, Il vous suffira ensuite de crée un fichier "sauv.sh" lui aussi dans le répertoire root Avec à l’intérieur ceci #!/bin/bash cd /usr/metin2/ sh clear.sh cd /usr/ tar cvf sauv.metin2.tar.gz metin2 mv sauv.metin2.tar.gz /root/sauvegarde/ rm sauv.metin2.tar.gz cd /var/db/ tar cvf sauv.mysql.tar.gz mysql mv sauv.mysql.tar.gz /root/sauvegarde/ rm sauv.mysql.tar.gz cd /root/sauvegarde HOST='Host_De_fotre_ftp' USER='User_De_fotre_ftp' PASSWD='Password_De_fotre_ftp' ftp -n -v $HOST << EOT user $USER $PASSWD mput sauv.mysql.tar.gz prompt mput sauv.metin2.tar.gz prompt Reste plus qu'à faire un sh sauv.sh sur putty et votre sauvegarde est lancée. Gros point fort de cette sauvegarde ? - Un lieu de sauvegarde en dehors du dédier - Un taux de transfert allant jusqu’à 2Mo/s - Une possibilité de rendre la sauvegarde automatique grâce au "cron" Je rajouterai plus tard sur ce partage - il nettoie les logs avant l'envoie sur le ftp - il fait une sauvegarde des bases SQL et du fichier metin2 Mauvais point - La sauvegarde fait lager le serveur le temps de l'envoie sur le ftp
  23. Bonjour/soir à toutes et à tous ! Vos joueurs ne se sont jamais plaint du manque de place dans l'inventaire ? entre les stuff PVP, le stuff PVE, les potions etc, on ne sait plus mettre les items ! Un très aimable allemand nous a donc partagé son système de "coffre portable" (qu'ils sont gentils nos confrères allemands !) Comment ça fonctionne ? très simple. Vous parlez pour commencer à un PNJ qui vous donne un coffre qui pourra ensuite contenir 10 items (vous pouvez demander plusieurs coffres ayant chacun son propre ID). Pour faire fonctionner tout ça, on a besoin de requête SQL, il vous faut donc le système de requête SQL installé sur votre serveur. Votre coffre peut être protégé par un mot de passe, si c'est pas beau ! Pour commencer, voilà le lien de téléchargement de la bête traduite par moi-même: Téléchargement : ICI FE Nous voilà fin prêt pour l'installation. A vrai dire faire un tuto pour ça n'est pas très utile, dans l'archive .rar tout est placé là où il faut le mettre, mais comme je n'aime pas les partages de 2 lignes, j'écris tout un tuto (et je comble les trous avec des phrases plus inutiles les unes que les autres ) Pour commencer: pas de secret, téléchargez l'archive .rar On va commencer par le clientside, il vous faut donc "icon" ainsi que "local_fr" de depack puis dans l'archive, allez dans Coffre de Stockage\Clientside\icon puis déplacez l'icône dans depack\icon\item. Allez ensuite dans "Coffre de Stockage\Clientside\locale" pour y trouver 3 fichiers. Faites donc simplement des copier/coller des lignes présente dans ces fichiers dans les différents fichiers indiqués. C'est le moment de repack ! n'oubliez pas de faire "recréer" pour l'item_proto avant de repack ainsi que "modifier" pour le fichier "icon". Le côté client est déjà fini, vous voyez que c'était pas compliqué ! Passons maintenant côté serveur, rien de très compliqué non plus, ne vous en faites pas ! Allez maintenant dans "Coffre de Stockage\Serverside\mysql" pour y trouver 3 fichiers avec l'extension .sql. Lancez Navicat puis allez dans "Player". Faites un clic droit dans le vide puis "Execute Biatch file" pour tomber sur une nouvelle page. Au bout de la ligne "File" cliquez sur " ... " puis choisissez le premier fichier se trouvant dans le dossier précédemment ouvert (c'est à ce moment que je me rend compte l'inutilité de vous avoir fait ouvrir ce dossier via l'explorer ) à savoir "chest_storage.sql" ce qui doit vous donner: Faites ensuite "Start" puis une fois que c'est fini "Close" (c'était l'instant Captain Obvious, par Craven.) Recommencez pour les 2 autres fichiers "chest_storage_properties.sql" ainsi que "item_proto.sql". Si vous souhaitez voir le résultat, faites un clic droit puis "refresh" pour voir 2 nouvelles tables servant à la quête ainsi que le nouvel item dans l'item proto. C'est maintenant fini sur Navicat ! allez sur votre FTP puis dans le dossier des quêtes. Uploadez les fichiers "chest_storage_nu.quest" et "chest_storage_nu.lua" dans le dossier. N'oubliez d'ajouter "chest_storage_nu.quest" à votre locale_list. Nul besoin d'ajouter le second fichier à votre locale_list. Ouvrez "quest_functions" de votre FTP pour y mettre les fonctions se trouvant dans le fichier "questfunctions.txt": Coffre de Stockage\Serverside\quest. Enregistrez le tout. Ouvrez ensuite "questlib.lua" de votre FTP pour ajouter à la fin du fichier la ligne se trouvant dans le fichier "questlib.txt". Puis pour finir, enregistrez. Un reboot avec une recompilation des quêtes et c'est fini ! /!\N'oubliez pas que vous devez avoir le système de requête SQL installé/!\ Si, lorsque vous voulez stocker une arme ou une armure, vous recevez le message "*Nom de l'item* ne peut être ranger dans le coffre." c'est parce qu'on peut choisir quel item a le droit d'être stocké ou non. Ouvrez la quête "chest_storage_nu.quest" puis allez à la ligne 132, vous verrez ça: if itemType != 1 and itemType != 2 and itemType != 16 and itemVnum != 999985 then --keine Special Items/Ruestungsteile/Waffen Il vous suffit de supprimer le itemType de l'item que vous voulez rendre stockable, par exemple pour rendre les armes stockable supprimez "itemType !=1 ": if itemType != 2 and itemType != 16 and itemType != 5 and itemVnum != 999985 then --keine Special Items/Ruestungsteile/Waffen Bon, je sens que vous avez été sage tout le long de ce tuto, je vous ai donc préparé une vidéo pour que vous puissiez voir à quoi ça ressemble en jeu: [video=youtube] Sur ce, bonne émulation à toutes et à tous et bonne chance ! Source: epvp
  24. Bonjour, Je viens de trouver un système sympathique sur epvp qui permet de transférer vos yangs a un autre personnage présent sur le même compte, et le banquier traditionnelle qui stock vos yangs bien évidemment, et tout ca, en passant par une gui qui sera ffichable n'importe ou sans avoir à cliquer sur un Pnj , simplement par un raccourci ! Oui les screens sont en allemand mais j'ai pris la peine de tout vous traduire -------------------------------------------- PARTIE : Tutoriel installation de la gui -------------------------------------------- - Ouvrez naviat, allez dans player et player. Faites un Ctrl + D et créez la colonne comme ceci : Name : bank Type : int Lenght : 255 Decimals : 0 Pensez à faire une sauvegarde au cas ou ! - Ensuite, munissez vous d'un depacker, et extrayez root . Allez dans le fichier constinfo.py et rajoutez ceci : load_bank_einzahlen = 0 load_bank_abheben = 0 load_bank_uberweisen = 0 load_bank_abfragen = 0 bank = 0 yang_input = 0 - Maintenant, allez dans le fichier game.py et cherchez : def __ServerCommand_Build(self): serverCommandList={ ( Conseil : Dans notepad ++ , faites CTRL + F => rechercher => tapez : def __ServerCommand_Build(self): en disant d'aller chercher cette ligne vers le bas ) Une fois trouvé, rajoutez ceci juste aprés : "bank_einzahlen" : self.__bank_einzahlen, "bank_abheben" : self.__bank_abheben, "bank_uberweisen" : self.__bank_uberweisen, "bank_abfragen" : self.__bank_abfragen, - Toujours par la même technique que je vous ai enseigné, recherchez cette ligne : onPressKeyDict[app.DIK_F4] = lambda : self.__PressQuickSlot(7) Et rajoutez ceci : onPressKeyDict[app.DIK_U] = lambda : self.__money_in_bank() onPressKeyDict[app.DIK_F7] = lambda : self._open_bank_() /!\ app.DIK_U ----- [app.DIK_F7] ------ Ca veut dire que si vous appuyez soit sur U ou sur F7 la gui s'affichera. Vous pouvez modifier la lettre U par F8 par exemple et et F7 par F11 , vous faites ce que vous voulez tant que ces raccourcis ne sont pas utilisés sur le jeu. - Pour terminer, rajoutez a la fin de game.py ceci : def __bank_einzahlen(self, id): constInfo.load_bank_einzahlen = int(id) def __bank_abheben(self, id): constInfo.load_bank_abheben = int(id) def __bank_uberweisen(self, id): constInfo.load_bank_uberweisen = int(id) def __bank_abfragen(self, id): constInfo.load_bank_abfragen = int(id) def _open_bank_(self): if constInfo.bank == 0: self.__Bank() constInfo.bank = 1 return if constInfo.bank == 1: self.bank.Hide() constInfo.bank = 0 def __Bank(self): self.bank = ui.BoardWithTitleBar() self.bank.SetSize(180, 100) self.bank.SetCenterPosition() self.bank.AddFlag('movable') self.bank.AddFlag('float') self.bank.SetTitleName('Banque') self.bank.SetCloseEvent(self._bank_close) self.bank.Show() self.bank_Einzahlen = ui.Button() self.bank_Einzahlen.SetEvent(self._bank_einzahlen) self.bank_Einzahlen.SetParent(self.bank) self.bank_Einzahlen.SetPosition(20, 35) self.bank_Einzahlen.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.bank_Einzahlen.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.bank_Einzahlen.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.bank_Einzahlen.SetText("Dépôt") self.bank_Einzahlen.SetToolTipText("Stocker les yangs dans la banque") self.bank_Einzahlen.Show() self.bank_Abheben = ui.Button() self.bank_Abheben.SetEvent(self._bank_abheben) self.bank_Abheben.SetParent(self.bank) self.bank_Abheben.SetPosition(100, 35) self.bank_Abheben.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.bank_Abheben.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.bank_Abheben.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.bank_Abheben.SetText("Retirer") self.bank_Abheben.SetToolTipText("Retirer des yangs de votre banque") self.bank_Abheben.Show() self.bank_Abfragen = ui.Button() self.bank_Abfragen.SetEvent(self._bank_abfragen) self.bank_Abfragen.SetParent(self.bank) self.bank_Abfragen.SetPosition(20, 65) self.bank_Abfragen.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.bank_Abfragen.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.bank_Abfragen.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.bank_Abfragen.SetText("Retirer") self.bank_Abfragen.SetToolTipText("Voir l'etat de votre compte") self.bank_Abfragen.Show() self.bank_uberweisen = ui.Button() self.bank_uberweisen.SetEvent(self._bank_uberweisen) self.bank_uberweisen.SetParent(self.bank) self.bank_uberweisen.SetPosition(100, 65) self.bank_uberweisen.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.bank_uberweisen.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.bank_uberweisen.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.bank_uberweisen.SetText("Transférer") self.bank_uberweisen.SetToolTipText("Transférer des yangs a un autre joueur") self.bank_uberweisen.Show() def _bank_einzahlen(self): self.bank.SetTitleName('Dépôt') self.bank.SetSize(125, 100) self.bank_Einzahlen.Hide() self.bank_Abheben.Hide() self.bank_Abfragen.Hide() self.bank_uberweisen.Hide() self.bank_YangSlotBar = ui.SlotBar() self.bank_YangSlotBar.SetParent(self.bank) self.bank_YangSlotBar.SetSize(60, 15) self.bank_YangSlotBar.SetPosition(15, 35) self.bank_YangSlotBar.SetWindowHorizontalAlignCenter() self.bank_YangSlotBar.Show() self.bank_Yang = ui.EditLine() self.bank_Yang.SetParent(self.bank_YangSlotBar) self.bank_Yang.SetSize(60, 15) self.bank_Yang.SetPosition(4, 1) self.bank_Yang.SetMax(10) self.bank_Yang.SetNumberMode() self.bank_Yang.SetText(constInfo.yang_input) self.bank_Yang.SetFocus() self.bank_Yang.Show() self.bank_yang_text = ui.TextLine() self.bank_yang_text.SetParent(self.bank) self.bank_yang_text.SetDefaultFontName() self.bank_yang_text.SetPosition(15, 35) self.bank_yang_text.SetFeather() self.bank_yang_text.SetText("Yang: ") self.bank_yang_text.SetOutline() self.bank_yang_text.Show() self.bank_Annehmen = ui.Button() self.bank_Annehmen.SetParent(self.bank) self.bank_Annehmen.SetEvent(self.bank_annehmen) self.bank_Annehmen.SetPosition(15, 60) self.bank_Annehmen.SetUpVisual("d:/ymir work/ui/public/large_button_01.sub") self.bank_Annehmen.SetOverVisual("d:/ymir work/ui/public/large_button_02.sub") self.bank_Annehmen.SetDownVisual("d:/ymir work/ui/public/large_button_03.sub") self.bank_Annehmen.SetText("Déposer") self.bank_Annehmen.SetToolTipText("Mettez vos yangs ici") self.bank_Annehmen.Show() def _bank_abheben(self): self.bank.SetTitleName('Retirer') self.bank.SetSize(130, 100) self.bank_Einzahlen.Hide() self.bank_Abheben.Hide() self.bank_Abfragen.Hide() self.bank_uberweisen.Hide() self.bank_YangSlotBar = ui.SlotBar() self.bank_YangSlotBar.SetParent(self.bank) self.bank_YangSlotBar.SetSize(60, 15) self.bank_YangSlotBar.SetPosition(15, 35) self.bank_YangSlotBar.SetWindowHorizontalAlignCenter() self.bank_YangSlotBar.Show() self.bank_Yang = ui.EditLine() self.bank_Yang.SetParent(self.bank_YangSlotBar) self.bank_Yang.SetSize(60, 15) self.bank_Yang.SetPosition(4, 1) self.bank_Yang.SetMax(10) self.bank_Yang.SetNumberMode() self.bank_Yang.SetText(constInfo.yang_input) self.bank_Yang.SetFocus() self.bank_Yang.Show() self.bank_yang_text = ui.TextLine() self.bank_yang_text.SetParent(self.bank) self.bank_yang_text.SetDefaultFontName() self.bank_yang_text.SetPosition(15, 35) self.bank_yang_text.SetFeather() self.bank_yang_text.SetText("Yang: ") self.bank_yang_text.SetOutline() self.bank_yang_text.Show() self.bank_Annehmen = ui.Button() self.bank_Annehmen.SetParent(self.bank) self.bank_Annehmen.SetEvent(self.bank_annehmen_b) self.bank_Annehmen.SetPosition(15, 60) self.bank_Annehmen.SetUpVisual("d:/ymir work/ui/public/large_button_01.sub") self.bank_Annehmen.SetOverVisual("d:/ymir work/ui/public/large_button_02.sub") self.bank_Annehmen.SetDownVisual("d:/ymir work/ui/public/large_button_03.sub") self.bank_Annehmen.SetText("Déposer") self.bank_Annehmen.SetToolTipText("Selectionner le nombre de yangs") self.bank_Annehmen.Show() def _bank_abfragen(self): event.QuestButtonClick(constInfo.load_bank_abfragen) def _bank_uberweisen(self): self.bank.SetTitleName('Transférer) self.bank.SetSize(160, 145) self.bank_Einzahlen.Hide() self.bank_Abheben.Hide() self.bank_Abfragen.Hide() self.bank_uberweisen.Hide() self.bank_yang_text = ui.TextLine() self.bank_yang_text.SetParent(self.bank) self.bank_yang_text.SetDefaultFontName() self.bank_yang_text.SetPosition(15, 35) self.bank_yang_text.SetFeather() self.bank_yang_text.SetText("Yang: ") self.bank_yang_text.SetOutline() self.bank_yang_text.Show() self.bank_empfanger_text = ui.TextLine() self.bank_empfanger_text.SetParent(self.bank) self.bank_empfanger_text.SetDefaultFontName() self.bank_empfanger_text.SetPosition(15, 60) self.bank_empfanger_text.SetFeather() self.bank_empfanger_text.SetText("Empfänger: ") self.bank_empfanger_text.SetOutline() self.bank_empfanger_text.Show() self.bank_YangSlotBar = ui.SlotBar() self.bank_YangSlotBar.SetParent(self.bank) self.bank_YangSlotBar.SetSize(72, 15) self.bank_YangSlotBar.SetPosition(30, 35) self.bank_YangSlotBar.SetWindowHorizontalAlignCenter() self.bank_YangSlotBar.Show() self.bank_Yang = ui.EditLine() self.bank_Yang.SetParent(self.bank_YangSlotBar) self.bank_Yang.SetSize(72, 15) self.bank_Yang.SetPosition(4, 1) self.bank_Yang.SetMax(12) self.bank_Yang.SetNumberMode() self.bank_Yang.SetText(constInfo.yang_input) self.bank_Yang.SetFocus() self.bank_Yang.Show() self.bank_EmpfangerSlotBar = ui.SlotBar() self.bank_EmpfangerSlotBar.SetParent(self.bank) self.bank_EmpfangerSlotBar.SetSize(72, 15) self.bank_EmpfangerSlotBar.SetPosition(30, 60) self.bank_EmpfangerSlotBar.SetWindowHorizontalAlignCenter() self.bank_EmpfangerSlotBar.Show() self.bank_Empfanger = ui.EditLine() self.bank_Empfanger.SetParent(self.bank_EmpfangerSlotBar) self.bank_Empfanger.SetSize(72, 15) self.bank_Empfanger.SetPosition(4, 1) self.bank_Empfanger.SetMax(12) self.bank_Empfanger.Show() self.from_bank_pressed = ui.Button() self.from_bank_pressed.SetParent(self.bank) self.from_bank_pressed.SetPosition(15, 85) self.from_bank_pressed.SetUpVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_bank_pressed.SetOverVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_bank_pressed.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_bank_pressed.SetEvent(self.from_bank) self.from_bank_pressed.SetToolTipText("Nimmt den angegebenen Betrag von der Bank") self.from_bank_pressed.SetText("Vers la banque") self.from_bank_pressed.Hide() self.from_inven_pressed = ui.Button() self.from_inven_pressed.SetParent(self.bank) self.from_inven_pressed.SetPosition(80, 85) self.from_inven_pressed.SetUpVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_inven_pressed.SetOverVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_inven_pressed.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_inven_pressed.SetEvent(self.from_inven) self.from_inven_pressed.SetToolTipText("Nimmt den angegebenen Betrag aus deinem Inventar") self.from_inven_pressed.SetText("Vers l'inventaire") self.from_inven_pressed.Show() self.from_bank_not_pressed = ui.Button() self.from_bank_not_pressed.SetParent(self.bank) self.from_bank_not_pressed.SetPosition(15, 85) self.from_bank_not_pressed.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.from_bank_not_pressed.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.from_bank_not_pressed.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_bank_not_pressed.SetEvent(self.from_bank) self.from_bank_not_pressed.SetToolTipText("Nimmt den angegebenen Betrag von der Bank") self.from_bank_not_pressed.SetText("Vers la banque") self.from_bank_not_pressed.Show() self.from_inven_not_pressed = ui.Button() self.from_inven_not_pressed.SetParent(self.bank) self.from_inven_not_pressed.SetPosition(80, 85) self.from_inven_not_pressed.SetUpVisual("d:/ymir work/ui/public/middle_button_01.sub") self.from_inven_not_pressed.SetOverVisual("d:/ymir work/ui/public/middle_button_02.sub") self.from_inven_not_pressed.SetDownVisual("d:/ymir work/ui/public/middle_button_03.sub") self.from_inven_not_pressed.SetEvent(self.from_inven) self.from_inven_not_pressed.SetToolTipText("Nimmt den angegebenen Betrag aus deinem Inventar") self.from_inven_not_pressed.SetText("Vers l'inventaire") self.from_inven_not_pressed.Hide() self.Themp = ui.EditLine() self.Themp.SetMax(1) self.Themp.SetText("0") self.Themp.Hide() self.bank_Annehmen = ui.Button() self.bank_Annehmen.SetParent(self.bank) self.bank_Annehmen.SetEvent(self.bank_annehmen_c) self.bank_Annehmen.SetPosition(15, 110) self.bank_Annehmen.SetUpVisual("d:/ymir work/ui/public/large_button_01.sub") self.bank_Annehmen.SetOverVisual("d:/ymir work/ui/public/large_button_02.sub") self.bank_Annehmen.SetDownVisual("d:/ymir work/ui/public/large_button_03.sub") self.bank_Annehmen.SetText("Déposer") self.bank_Annehmen.SetToolTipText('Transférer le montant') self.bank_Annehmen.Show() def bank_annehmen(self): constInfo.yang_input = self.bank_Yang.GetText() event.QuestButtonClick(constInfo.load_bank_einzahlen) net.SendQuestInputStringPacket(self.bank_Yang.GetText()) def bank_annehmen_b(self): constInfo.yang_input = self.bank_Yang.GetText() event.QuestButtonClick(constInfo.load_bank_abheben) net.SendQuestInputStringPacket(self.bank_Yang.GetText()) def bank_annehmen_c(self): constInfo.yang_input = self.bank_Yang.GetText() event.QuestButtonClick(constInfo.load_bank_uberweisen) net.SendQuestInputStringPacket(self.bank_Yang.GetText()) net.SendQuestInputStringPacket(self.bank_Empfanger.GetText()) net.SendQuestInputStringPacket(self.Themp.GetText()) def from_bank(self): self.from_bank_pressed.Show() self.from_bank_not_pressed.Hide() self.from_inven_pressed.Hide() self.from_inven_not_pressed.Show() self.Themp.SetText("1") def from_inven(self): self.from_bank_pressed.Hide() self.from_bank_not_pressed.Show() self.from_inven_pressed.Show() self.from_inven_not_pressed.Hide() self.Themp.SetText("0") def _bank_close(self): self.bank.Hide() constInfo.bank = 0 - Non non non, ce n'est pas terminé , bande de fénéants Il vous reste ces quêtes que j'ai traduite à mettre sur votre serveur afin d'assurer le bon déroulement des transferts, c'est pas magique :mad: quest bank_af begin state start begin when login begin cmdchat("bank_abfragen "..q.getcurrentquestindex()) end when info or button begin chat("Vous avez "..mysql_query("SELECT bank FROM player.player WHERE name = '"..pc.get_name().."' LIMIT 1;").bank[1].." yangs dans votre banque.") end end end quest bank_az begin state start begin when login begin cmdchat("bank_abheben "..q.getcurrentquestindex()) end when info or button begin a = tonumber(getinput("getinput")) b = tonumber(mysql_query("SELECT bank FROM player.player WHERE name = '"..pc.get_name().."' LIMIT 1;").bank[1]) if (pc.get_gold() + a) >= 2000000000 then chat("Les yangs de l'inventaire sont pleins.") elseif b < a then chat("Pas assez de Yang dans la banque") else chat("Réalisée avec succès") pc.change_gold(a) mysql_query("UPDATE player.player SET bank = bank - "..a.." WHERE name = '"..pc.get_name().."' LIMIT 1;") end end end end quest bank_ez begin state start begin when login begin cmdchat("bank_einzahlen "..q.getcurrentquestindex()) end when info or button begin a = getinput("getinput") if pc.get_gold() >= tonumber(a) then mysql_query("UPDATE player.player SET bank = bank + "..a.." WHERE name = '"..pc.get_name().."' LIMIT 1;") chat("Réalisée avec succès") pc.change_gold(-a) else chat("Vous n'avez pas assez de Yang.") end end end end quest bank_uw begin state start begin when login begin cmdchat("bank_uberweisen "..q.getcurrentquestindex()) end when info or button begin local yang = tonumber(getinput("getinput")) local empfanger = tostring(getinput("getinput")) local way = tonumber(getinput("getinput")) if table.getn(mysql_query("SELECT name FROM player.player where name = '"..empfanger.."' LIMIT 1;").name) != 1 then chat("Le joueur spécifié est introuvable.") return elseif way == 0 then local myyang = pc.get_gold() if yang > myyang then chat("Vous n'avez pas assez de yangs.") return else pc.change_gold(-yang) mysql_query("UPDATE player.player SET bank = bank + "..yang.." WHERE name = '"..empfanger.."' LIMIT 1;") chat("Réalisée avec succès") return end elseif way == 1 then local myyang = tonumber(mysql_query("SELECT bank FROM player.player WHERE name = '"..pc.get_name().."' LIMIT 1;").bank[1]) local myyang = pc.get_gold() if yang > myyang then chat("Vous n'avez pas assez de yangs.") return else mysql_query("UPDATE player.player SET bank = bank - "..yang.." WHERE name = '"..pc.get_name().."' LIMIT 1;") mysql_query("UPDATE player.player SET bank = bank + "..yang.." WHERE name = '"..empfanger.."' LIMIT 1;") chat("Réalisée avec succès !") return end end end end end - Oh et puis j'allais oublier, pensez à reboot afin de prendre en compte la nouvelle colonne créé ! Vous pouvez maintenant vous amusez avec cette gui. Faites la découvrir à vos joueurs, ils seront séduits par son efficacité. Plus besoin de créer un autre compte pour transférer ces yangs. Plus besoin de retournez map 1 pour voir le pnj. Plus besoin d'utiliser d'anneau de banquier. Plus rapide, plus efficace, plus pratique, bonne émulation !
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.