NazoX Publicado 15 de Febrero del 2022 Reportar Compartir Publicado 15 de Febrero del 2022 Buenas, como sabréis llevo un tiempo sin actividad, dado por varios motivos familiares, personales, etc, y bueno me he animado después de un tiempo a volver a Metin, se que la guía esta existe por todas partes, pero está mal, o faltan cosas, o explicado a medias etc, yo lo tengo adaptado con 4 Piedras, pero he hecho la guía para que podáis usar 6 piedras, con esta guía orientativa podéis usar 6 piedras, 4, 12 o las que queráis, e imagino que sirve para poner solo 1 o 2 piedras si lo hacemos a la inversa, en fin, empecemos. 1.Vamos a nuestro source y nos dirigimos a editar el archivo "item_length.h", una vez abierto buscamos: Quote ITEM_SOCKET_MAX_NUM = 3, 1.1 Ahora remplazamos por la cantidad de piedras que queráis (guía para 6 piedras) Quote ITEM_SOCKET_MAX_NUM = 6, 2.Ahora Editamos el archivo "Constants.cpp", y buscamos lo siguiente: Quote 3, // WEAPON_SWORD, 3, // WEAPON_DAGGER, 3, // WEAPON_BOW, 3, // WEAPON_TWO_HANDED, 3, // WEAPON_BELL, 3, // WEAPON_FAN, 3, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR #ifdef ENABLE_WOLFMAN_CHARACTER 3, // WEAPON_CLAW #endif 2.1 Ahora lo remplazamos por lo siguiente: Quote 6, // WEAPON_SWORD, 6, // WEAPON_DAGGER, 6, // WEAPON_BOW, 6, // WEAPON_TWO_HANDED, 6, // WEAPON_BELL, 6, // WEAPON_FAN, 6, // WEAPON_CLAW 0, // WEAPON_ARROW, 0, // WEAPON_MOUNT_SPEAR #ifdef ENABLE_WOLFMAN_CHARACTER 6, // WEAPON_CLAW #endif 2.2 Ahora buscamos: Quote 3, // ARMOR_BODY, 2.3 Y remplazamos por: Quote 6, // ARMOR_BODY, #Nota: Si no tienes wolfman solo borra la línea o coméntala con // 3.Ahora nos vamos al source DB, mas concretamente al archivo "Cache.cpp" y buscamos: Quote if (isSocket) { iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2"); iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen, ", %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]); iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen, ", socket0=%lu, socket1=%lu, socket2=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]); } #Nota: Puede ser un poco diferente al vuestro, si no encontráis nada buscar "socket0, socket1" o "socket0 , socket1" 3.1 Remplazamos por: Quote if (isSocket) { iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2, socket3, socket4, socket5"); iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen, ", %lu, %lu, %lu, %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]); iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen, ", socket0=%lu, socket1=%lu, socket2=%lu, socket3=%lu, socket4=%lu, socket5=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2], p->alSockets[3], p->alSockets[4], p->alSockets[5]); } #Nota2: Si no queremos remplazar nada porque tenemos otro sistema, simplemente podéis añadir a continuación de "socket2" los demás, es decir socket2, socket3, socket4, socket5"); (tranquil@s no esta mal ni falta un socket6) 4.Ahora vamos al archivo "ClientManagerPlayer.cpp" y buscamos: Quote str_to_number(item.alSockets[2], row[cur++]); 4.1 A continuación de este, añadiremos lo siguiente: Quote str_to_number(item.alSockets[3], row[cur++]); str_to_number(item.alSockets[4], row[cur++]); str_to_number(item.alSockets[5], row[cur++]); 4.2 Ahora buscamos x2: Quote "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " #Nota: esto se realiza 2 veces, si no encontramos nada, probar a buscar "Select id" y lo veréis enseguida. 4.3 Ahora remplazamos por: Quote "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,socket3,socket4,socket5,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " #Nota2: Como antes, si tenéis algún sistema y no queréis remplazar solo añadir "socket3,socket4,socket5" después del "socket2," 4.4 Buscamos el siguiente y repetimos el proceso. 5.Ahora nos vamos al Source Cliente ->GameLib->ItemData.h y buscamos: Quote ITEM_SOCKET_MAX_NUM = 3, 5.1 Remplazamos por: Quote Item_SOCKET_MAX_NUM = 6, 6.Ahora vamos a UserInterface->PythonPlayerModule.cpp y buscamos la función: Quote PyObject * chatGetLinkFromHyperlink(PyObject * poSelf, PyObject * poArgs) 6.1 Remplazamos por: Quote PyObject * chatGetLinkFromHyperlink(PyObject * poSelf, PyObject * poArgs) { char * szHyperlink; if (!PyTuple_GetString(poArgs, 0, &szHyperlink)) return Py_BuildException(); std::string stHyperlink(szHyperlink); std::vector<std::string> results; split_string(stHyperlink, ":", results, false); // item:vnum:flag:socket0:socket1:socket2:socket3:socket4:socket5 if (0 == results[0].compare("item")) { if (results.size() < 9) return Py_BuildValue("s", ""); CItemData * pItemData = NULL; if (CItemManager::Instance().GetItemDataPointer(htoi(results[1].c_str()), &pItemData)) { char buf[1024] = { 0 }; char itemlink[256]; int len; bool isAttr = false; len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x:%x:%x:%x", htoi(results[1].c_str()), htoi(results[2].c_str()), htoi(results[3].c_str()), htoi(results[4].c_str()), htoi(results[5].c_str()), htoi(results[6].c_str()), htoi(results[7].c_str()), htoi(results[8].c_str())); if (results.size() >= 11) { for (int i = 9; i < results.size(); i += 2) { len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", htoi(results.c_str()), atoi(results[i+1].c_str())); isAttr = true; } } if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); else snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); return Py_BuildValue("s", buf); } } return Py_BuildValue("s", ""); } 7.Ahora abrimos el archivo "PythonChatModule.cpp" y buscamos: Quote PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs) 7.1 Remplazamos la función por: Quote PyObject * playerGetItemLink(PyObject * poSelf, PyObject * poArgs) { TItemPos Cell; switch (PyTuple_Size(poArgs)) { case 1: if (!PyTuple_GetInteger(poArgs, 0, &Cell.cell)) return Py_BuildException(); break; case 2: if (!PyTuple_GetByte(poArgs, 0, &Cell.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &Cell.cell)) return Py_BuildException(); break; default: return Py_BuildException(); } const TItemData * pPlayerItem = CPythonPlayer::Instance().GetItemData(Cell); CItemData * pItemData = NULL; char buf[1024]; if (pPlayerItem && CItemManager::Instance().GetItemDataPointer(pPlayerItem->vnum, &pItemData)) { char itemlink[256]; int len; bool isAttr = false; len = snprintf(itemlink, sizeof(itemlink), "item:%x:%x:%x:%x:%x:%x:%x:%x", //6 Piedras pPlayerItem->vnum, pPlayerItem->flags, pPlayerItem->alSockets[0], //1 Piedras pPlayerItem->alSockets[1], //2 Piedras pPlayerItem->alSockets[2], //3 Piedras pPlayerItem->alSockets[3], //4 Piedras pPlayerItem->alSockets[4], //5 Piedras pPlayerItem->alSockets[5]); //6 Piedras for (int i = 0; i < ITEM_ATTRIBUTE_SLOT_MAX_NUM; ++i) if (pPlayerItem->aAttr.bType != 0) { len += snprintf(itemlink + len, sizeof(itemlink) - len, ":%x:%d", pPlayerItem->aAttr.bType, pPlayerItem->aAttr.sValue); isAttr = true; } if( GetDefaultCodePage() == CP_ARABIC ) { if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), " |h|r[%s]|cffffc700|H%s|h", pItemData->GetName(), itemlink); else snprintf(buf, sizeof(buf), " |h|r[%s]|cfff1e6c0|H%s|h", pItemData->GetName(), itemlink); } else { if (isAttr) //"item:¹øÈ£:Ç÷¡±×:¼ÒÄÏ0:¼ÒÄÏ1:¼ÒÄÏ2" snprintf(buf, sizeof(buf), "|cffffc700|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); else snprintf(buf, sizeof(buf), "|cfff1e6c0|H%s|h[%s]|h|r", itemlink, pItemData->GetName()); } } else buf[0] = '0'; return Py_BuildValue("s", buf); } 8.Compilamos binario/source game & db 9.Ahora tenemos que editar nuestro dump_proto, asi que lo abrimos y editamos el archivo "dump_proto.cpp" y buscamos: Quote enum EItemMisc { ITEM_NAME_MAX_LEN = 24, ITEM_VALUES_MAX_NUM = 6, ITEM_SMALL_DESCR_MAX_LEN = 256, ITEM_LIMIT_MAX_NUM = 2, ITEM_APPLY_MAX_NUM = 3, ITEM_SOCKET_MAX_NUM = 3, ITEM_MAX_COUNT = 200, ITEM_ATTRIBUTE_MAX_NUM = 7, ITEM_ATTRIBUTE_MAX_LEVEL = 5, ITEM_AWARD_WHY_MAX_LEN = 50, 9.1 Remplazamos por : Quote enum EItemMisc { ITEM_NAME_MAX_LEN = 24, ITEM_VALUES_MAX_NUM = 6, ITEM_SMALL_DESCR_MAX_LEN = 256, ITEM_LIMIT_MAX_NUM = 2, ITEM_APPLY_MAX_NUM = 3, ITEM_SOCKET_MAX_NUM = 6, //6 Piedras ITEM_MAX_COUNT = 200, ITEM_ATTRIBUTE_MAX_NUM = 7, ITEM_ATTRIBUTE_MAX_LEVEL = 5, ITEM_AWARD_WHY_MAX_LEN = 50, 10.Nos vamos a nuestro cliente, descompilamos el root y editamos el archivo "uiToolTip.py" y buscamos: Quote def SetHyperlinkItem(self, tokens): 10.1 Remplazamos la función por: Quote def SetHyperlinkItem(self, tokens): minTokenCount = 3 + player.METIN_SOCKET_MAX_NUM maxTokenCount = minTokenCount + 2 * player.ATTRIBUTE_SLOT_MAX_NUM if tokens and len(tokens) >= minTokenCount and len(tokens) <= maxTokenCount: head, vnum, flag = tokens[:3] itemVnum = int(vnum, 16) metinSlot = [int(metin, 16) for metin in tokens[3:9]] rests = tokens[9:] if rests: attrSlot = [] rests.reverse() while rests: key = int(rests.pop(), 16) if rests: val = int(rests.pop()) attrSlot.append((key, val)) attrSlot += [(0, 0)] * (player.ATTRIBUTE_SLOT_MAX_NUM - len(attrSlot)) else: attrSlot = [(0, 0)] * player.ATTRIBUTE_SLOT_MAX_NUM self.ClearToolTip() self.AddItemData(itemVnum, metinSlot, attrSlot) ItemToolTip.OnUpdate(self) #Nota: en caso que no podamos modificarlo por otro sistema o el motivo que sea, debemos editar esta 2 partes: Quote metinSlot = [int(metin, 16) for metin in tokens[3:5]] rests = tokens[6:] por: Quote metinSlot = [int(metin, 16) for metin in tokens[3:9]] rests = tokens[9:] #Update 1.1 11.Vamos a nuestro Source DB y abrimos el archivo ClientManager.cpp y buscamos: Quote void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg) en esta función un poco más abajo añadimos lo siguiente (junto a las demás): Quote "socket3, socket4, socket5, socket6," 11.2.Ahora buscamos otra vez: Quote void CClientManager::QUERY_ITEM_SAVE(CPeer * pkPeer, const char * c_pData) Y un poco más abajo añadimos junto a las demás lo siguiente: Quote "socket3, socket4, socket5, socket6," 11.3.Un poco más abajo veremos lo siguiente: Quote "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", Pues lo remplazamos por lo siguiente (si no quieres remplazar solo añade %ld, %ld, %ld, %ld): Quote "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", 11.4.Y un poco más abajo veremos: Quote p->alSockets[0], p->alSockets[1], p->alSockets[2], Para terminar añadimos: Quote p->alSockets[3], p->alSockets[4], p->alSockets[5], p->alSockets[6], 12.Vamos a nuestro source Binario y abrimos el archivo GameType.h y buscamos: Quote ITEM_SOCKET_SLOT_MAX_NUM = 3, Remplazamos por: Quote ITEM_SOCKET_SLOT_MAX_NUM = 7, 13.Una vez hayamos remplazado el nuevo Game, DB, .exe, compilado el root y compilado dump_proto, dumpeamos los locales, es decir, ponemos nuestros item_proto.txt e item_names.txt en el nuevo dump_proto y generamos los archivos para el locale, compilamos locale, hacemos reboot y a jugar. Imagen propia: Varios puntos a destacar: 1.Tienes que adaptarlo a tu Offline Shop ya que tendrás los sockets básicos Socket0 1 y 2, tendrás que añadir más en función de los que tengas. 2.No se cuantas piedras son el máximo que puedes añadir, 6 es seguro, pero 7,8,9,10 o + quizás te ocasionen bugs. 3.Si tienes otros sistemas que utilizen casillas con sockets, como Offline Shop, almacén especial, etc tendrás que adaptarlo o tendrás problemas, 4.A disfrutar y un saludo. ♥ TesT ♥ y morstamayo reacciono a esto 2 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 1 de Mayo del 2022 Author Reportar Compartir Publicado 1 de Mayo del 2022 #Tema actualizado faltaban algunas partes que se me olvido añadir. Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
Mensajes recomendados
Unirse a la conversación
Puedes publicar ahora y registrarte más tarde. Si tienes una cuenta, regístrate para publicar con su cuenta.