Este es un tema popular. NazoX Publicado 30 de Marzo del 2020 Este es un tema popular. Reportar Compartir Publicado 30 de Marzo del 2020 Bueno pues como dice el título aquí pondré muchos fix que he ido viendo, probando y visto, y encontrado, no cabe decir que siempre haz copia de tus archivos antes de realizar ningún paso de a continuación. Quote 1- A veces ocurre un error cuando queremos vender un item en el npc que nos pone otro nombre, por ejemplo vendes unas negras y te pone que se llama caballo de troya por decirte algo. Debes iniciar sesión para ver el contenido del enlace en esta publicación. (brazalete de ébano y al vender pone casco de 41 de G) Debes iniciar sesión para ver el contenido del enlace en esta publicación. -Para este fix vamos a nuestro src del cliente y editamos el archivo UserInterface\PythonPlayerModule.cpp Ahora buscamos lo siguiente: Quote PyObject * playerIsValuableItem(PyObject* poSelf, PyObject* poArgs) { TItemPos SlotIndex; switch (PyTuple_Size (poArgs)) { case 1: if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) return Py_BuildException(); break; case 2: if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) return Py_BuildException(); break; default: return Py_BuildException(); } Debes iniciar sesión para ver el contenido del enlace en esta publicación. y lo remplazamos por el siguiente: Quote PyObject * playerIsValuableItem(PyObject* poSelf, PyObject* poArgs) { TItemPos SlotIndex; switch (PyTuple_Size (poArgs)) { case 1: if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.cell)) return Py_BuildException(); break; case 2: if (!PyTuple_GetInteger(poArgs, 0, &SlotIndex.window_type)) return Py_BuildException(); if (!PyTuple_GetInteger(poArgs, 1, &SlotIndex.cell)) return Py_BuildException(); break; default: return Py_BuildException(); } Debes iniciar sesión para ver el contenido del enlace en esta publicación. ##Instalado y funcionando. créditos: Paszka 2-Algo muy simple, todos sabemos que si escribías en masa a una persona podías llegar hacer que se congelara o le echara dependiendo su pc y el lag y todo eso, este es un fix de ese mini kickhack, hay muchos más fix y una mejor solución sería poner el sistema anti spam y eso, pero bueno aquí lo dejo. -Vamos a nuestro src game/char.h Ahora buscamos lo siguiente: Quote }; ESex GET_SEX(LPCHARACTER ch); Debes iniciar sesión para ver el contenido del enlace en esta publicación. Antes de eso agregamos esto: Quote public: void ClearPMCounter(void) { m_iPMCounter = 0; } void IncreasePMCounter(void) { m_iPMCounter++; } void SetLastPMPulse(void); int GetPMCounter(void) const { return m_iPMCounter; } int GetLastPMPulse(void) const { return m_iLastPMPulse; } protected: int m_iLastPMPulse; int m_iPMCounter; Debes iniciar sesión para ver el contenido del enlace en esta publicación. Ahora vamos a char.cpp y al final del todo añadimos: Quote void CHARACTER::SetLastPMPulse(void) { m_iLastPMPulse = thecore_pulse() + 25; } Debes iniciar sesión para ver el contenido del enlace en esta publicación. Ahora en el mismo archivo buscamos lo siguiente: Quote // MINING m_pkMiningEvent = NULL; // END_OF_MINING Debes iniciar sesión para ver el contenido del enlace en esta publicación. Y debajo de eso agregamos: Quote /////// FIX KICKHACK /////// m_iLastPMPulse = 0; m_iPMCounter = 0; //////////////////////////// Debes iniciar sesión para ver el contenido del enlace en esta publicación. Para terminar vamos al archivo input_main.cpp y buscamos: Quote int iExtraLen = pinfo->wSize - sizeof(TPacketCGWhisper); Debes iniciar sesión para ver el contenido del enlace en esta publicación. Debajo añadimos: Quote if (ch->GetLastPMPulse() < thecore_pulse()) ch->ClearPMCounter(); if (ch->GetPMCounter() > 3 && ch->GetLastPMPulse() > thecore_pulse()) { ch->GetDesc()->SetPhase(PHASE_CLOSE); return -1; } Debes iniciar sesión para ver el contenido del enlace en esta publicación. Buscamos por último: Quote if (pkChr == ch) return (iExtraLen); Debes iniciar sesión para ver el contenido del enlace en esta publicación. Y añadimos: abajo Quote ch->IncreasePMCounter(); ch->SetLastPMPulse(); Debes iniciar sesión para ver el contenido del enlace en esta publicación. ##No instalado y no probado. créditos: Marchewa Quote 3-A veces tenemos ese problema que los jugadores pueden dar shutdown o el famoso comando /2 2 o /5 5 Para desactivar el comando /2 2 o /5 5 vamos a cmd.cpp y buscamos: Quote { "2495602", do_priv_empire, 0, POS_DEAD, GM_PLAYER }, Debes iniciar sesión para ver el contenido del enlace en esta publicación. Simplemente lo comentamos con el // y listo. Ahora para quitar el shutdown o que solo puedan usarlo los <[GM's]> vamos a cmd_general.cpp y buscamos: Quote ACMD(do_shutdown) { if (NULL == ch) { sys_err("Accept shutdown command from %s.", ch->GetName()); } TPacketGGShutdown p; p.bHeader = HEADER_GG_SHUTDOWN; P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown)); Shutdown(10); ------------aquí como extra podéis reducir el tiempo en que se tarda en apagar el sv } Debes iniciar sesión para ver el contenido del enlace en esta publicación. Y remplazamos la función por la siguiente: Quote ACMD(do_shutdown) { if (!ch->IsGM()) -------------esto es lo nuevo return; ------------------- esto es lo nuevo if (NULL == ch) { sys_err("Accept shutdown command from %s.", ch->GetName()); } TPacketGGShutdown p; p.bHeader = HEADER_GG_SHUTDOWN; P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown)); Shutdown(10); } Debes iniciar sesión para ver el contenido del enlace en esta publicación. ##Probado y funcionando. 4-Poder crear nombres más largos al crear un personaje, ya que el límite es de 12. Vamos a nuestro src del game y abrimos el archivo input_login.cpp y buscamos: Quote if (true == g_BlockCharCreation) { d->Packet(&packFailure, sizeof(packFailure)); return; } Debes iniciar sesión para ver el contenido del enlace en esta publicación. Ahora remplazamos o añadimos lo que falta por: Quote if (true == g_BlockCharCreation) { d->Packet(&packFailure, sizeof(packFailure)); return; } if (strlen(pinfo->name) > 12) ------------nuevo { d->Packet(&packFailure, sizeof(packFailure)); return; } Debes iniciar sesión para ver el contenido del enlace en esta publicación. ##Probado y funcionando. Quote 5-Este no es un fix 100% pero ayuda bastante a solucionar el error de que cuando un pj sube nivel, seguimos viéndole el mismo lv, es decir, si tu eres nivel 15 y subes al 16 no se actualiza hasta que reconectas, o tomas un teleport, mueres o cualquier cosa, con este fix, logras que en el momento de subir al 16 todos vean ese nivel actualizado y no el mismo. Vamos al src game y editamos el archivo packet.h y buscamos: Quote typedef struct packet_update_char y añadimos lo siguiente: Quote short sAlignment; ---esto deberías tenerlo DWORD dwLevel; ----esto es lo que tienes que añadir Ahora vamos char.cpp y buscamos: Quote void CHARACTER::UpdatePacket() Y a continuación añadimos: Quote pack.sAlignment = m_iAlignment / 10; ----deberías tenerlo pack.dwLevel = GetLevel(); ---agregar Ahora nos vamos al source del cliente, editamos el packet.h y buscamos: Quote typedef struct packet_update_char Ahora añadimos lo siguiente: Quote short sAlignment; ---deberias tenerlo DWORD dwLevel; --agregar Ahora nos vamos a PythonNetworkStreamPhaseGameActor.cpp y buscamos: Quote bool CPythonNetworkStream::RecvCharacterUpdatePacket() Y añadimos lo siguiente: Quote kNetUpdateActorData.m_sAlignment=chrUpdatePacket.sAlignment; ---deberias tenerlo kNetUpdateActorData.m_dwLevel=chrUpdatePacket.dwLevel; --añadir Ahora buscamos NetworkActorManager.cpp y buscamos: Quote void CNetworkActorManager::UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData) Y ahora añadimos lo siguiente: Quote pkInstFind->SetAlignment(c_rkNetUpdateActorData.m_sAlignment); -Deberías tenerlo pkInstFind->SetLevel(c_rkNetUpdateActorData.m_dwLevel); --añadir Ahora abrimos el NetworkActorManager.h y buscamos lo siguiente: Quote struct SNetworkUpdateActorData Y añadimos lo siguiente: Quote short m_sAlignment; --deberias tenerlo DWORD m_dwLevel; --añadir Abrimos InstanceBaseEffect.cpp y buscamos: Quote void CInstanceBase::SetAlignment(short sAlignment) Y añadimos lo siguiente: Quote void CInstanceBase::SetLevel(DWORD level) { m_dwLevel = level; UpdateTextTailLevel(m_dwLevel); } Ahora buscamos lo siguiente: Quote void CInstanceBase::UpdateTextTailLevel(DWORD level) Y añadimos lo siguiente: Quote void CInstanceBase::UpdateTextTailLevel(DWORD level) { if (IsPC()) { static D3DXCOLOR s_kLevelColor = D3DXCOLOR(152.0f/255.0f, 255.0f/255.0f, 51.0f/255.0f, 1.0f); char szText[256]; sprintf(szText, "Lv %d", level); CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, s_kLevelColor); } } Ahora abrimos el InstanceBase.h y buscamos: Quote SetAlignment(short sAlignment); Y añadimos esto y terminaremos. Quote void SetLevel(DWORD level); ##Probado y funciona 6-Inyección SQL con este tendremos una pequeña de tantas medidas para el tema de inyecciones. para ello vamos al source game y abrimos el archivo DB.cpp y buscamos: Quote void DBManager::Query(const char * c_pszFormat, ...) { char szQuery[4096]; va_list args; va_start(args, c_pszFormat); vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args); va_end(args); std::string sQuery(szQuery); m_sql.AsyncQuery(sQuery.substr(0,sQuery.find_first_of(";")==-1?sQuery.length(): sQuery.find_first_of(";")).c_str()); } Y ahora remplazamos toda la función por lo siguiente y estaremos listo: Quote SQLMsg * DBManager::DirectQuery(const char * c_pszFormat, ...) { char szQuery[4096]; va_list args; va_start(args, c_pszFormat); vsnprintf(szQuery, sizeof(szQuery), c_pszFormat, args); va_end(args); std::string sQuery(szQuery); return m_sql_direct.DirectQuery(sQuery.substr(0, sQuery.find_first_of(";") == -1 ? sQuery.length() : sQuery.find_first_of(";")).c_str()); <--esto es lo nuevo por si no se nota diferencia. } ##Implementado pero no puedo confirmarlo al 100% porque no recibo ataques. 7-Mejora de sysser, aunque todos pensamos que esto arreglará todos los problemas del sysser no es así, lo que hace esto, es crear un archivo sysser cada vez que abramos el cliente con su fecha y todo, así lo tendremos ordenado y podremos observar los diferentes fallos a lo largo de los días si no nos acordamos de la última vez, algo práctico siempre y cuando no seas torpe. Para eso vamos al source del cliente, en la carpeta EterBase y buscamos el archivo Debug.cpp y buscamos lo siguiente: Quote void OpenLogFile(bool bUseLogFIle) Y a continuación remplazamos toda la función por la siguiente: Quote void OpenLogFile(bool bUseLogFIle) { time_t rawtime; struct tm * timeinfo; char buffer[80]; time(&rawtime); timeinfo = localtime(&rawtime); strftime(buffer, sizeof(buffer), "./syserr/%d-%m-%Y-%H-%M-%S-syserr.txt", timeinfo); <-------aquí ponemos la ruta de la carpeta donde queráis que se creen const char* str(buffer); #if !defined(_DISTRIBUTE) || defined(_USE_LOG_FILE) freopen(str, "w", stderr); if (bUseLogFIle) { isLogFile = true; CLogFile::Instance().Initialize(); } #endif } Nota##: para que os funcione, tenéis que crear una carpeta con el nombre que le hayáis puesto en el source, en mi caso y como en la guía mi carpeta se llama "syserr" ##Funciona implementado 8-Añadido también aquí el fix del herrero que no destruía items. buscas bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly en Char_item.cpp del servidor y remplazamos la función por esta: Quote DWORD result_fail_vnum = item->GetRefineFromVnum(); // Fix perder items if (result_fail_vnum == 0) { return false; } //Final del fix LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, true); BYTE bCell = item->GetCell(); ITEM_MANAGER::CopyAllAttrTo(item, pkNewItem); pkNewItem->AddToCharacter(this, TItemPos(INVENTORY, bCell)); //PointChange(POINT_GOLD, -cost); // asi no cobra, quitar // para cobrar. PayRefineFee(cost); } return true; } 9-Buff en party Se que hay muchos tutoriales de como añadir buff en un grupo con los chamanes, pero siempre hay algún bug, de que no funciona, o con el tiempo deja de funcionar, etc. Este funciona ya que lo tengo implementado, si estás en grupo, solo puedes dar auras a los miembros del grupo, esto quiere decir, que si viene alguien que no este en el grupo. no podrás darles auras (aunque hará el efecto), si dejas el grupo, todo volverá a la normalidad, podrás darles auras a todo los jugadores. Quote 1.Skill.h buscamos: SKILL_FLAG_FIRE = (1 << 27), #Añadimos: SKILL_FLAG_PARTY = (1 << 27), //Party buff Char_skill.cpp buscamos: SKILL_RESIST_PENETRATE }; #Añadimos: struct FPartyPIDCollector { std::vector <DWORD> vecPIDs; FPartyPIDCollector() { } void operator () (LPCHARACTER ch) { vecPIDs.push_back(ch->GetPlayerID()); } }; Buscamos: if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) pkVictim = this; #Añadimos: if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && !GetParty() && !pkVictim) pkVictim = this; Buscamos: if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) pkVictim = this; #Añadimos: if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) ComputeSkill(dwVnum, this); Si tienes lycan busca: #ifdef ENABLE_WOLFMAN_CHARACTER else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY)) ComputeSkillParty(dwVnum, this); #endif y remplaza con: #ifdef ENABLE_WOLFMAN_CHARACTER else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY)) ComputeSkillParty(dwVnum, this); #endif else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && !GetParty() && !pkVictim) ComputeSkill(dwVnum, this); else if (IS_SET(pkSk->dwFlag, SKILL_FLAG_PARTY) && GetParty()) { FPartyPIDCollector f; GetParty()->ForEachOnMapMember(f, GetMapIndex()); for (std::vector <DWORD>::iterator it = f.vecPIDs.begin(); it != f.vecPIDs.end(); it++) { LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(*it); ComputeSkill(dwVnum, ch); } } Guild.cpp buscamos: if ((pkSk->dwFlag & SKILL_FLAG_SELFONLY)) #Añadimos: if ((pkSk->dwFlag & SKILL_FLAG_PARTY)) { if (ch->FindAffect(pkSk->dwVnum)) return; victim = ch; } Navicat: Vamos a la tabla player y hacemos botón derecho en skill_proto->Design table y bajamos hasta la casilla setFlag. Hay añadimos PARTY o si la tenemos lo ponemos. Contar que sea si o si el número 27 y activamos la casilla. Solo no queda ir a nuestro skill_proto y buscar las habilidades de curación y luz y añadir PARTY en la casilla flag, reboot o reload y a probar. #Funciona Implementado : Debes iniciar sesión para ver el contenido del enlace en esta publicación. Quote 10-Como poner nivel colorido 1.Nos vamos al Source del cliente y abrimos el archivo InstanceBaseEffect.cpp y buscamos: Quote void CInstanceBase::UpdateTextTailLevel(DWORD level) Ahora remplazamos toda la función por esta: Quote void CInstanceBase::UpdateTextTailLevel(DWORD level) { static D3DXCOLOR Color_lv_1 = D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); static D3DXCOLOR Color_lv_2 = D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); static D3DXCOLOR Color_lv_3 = D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); static D3DXCOLOR Color_lv_4 = D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); static D3DXCOLOR Color_lv_5 = D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); char szText[256]; sprintf(szText, "[Lv %d]", level); if (level >= 1 && level <= 50) { CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, Color_lv_1); } else if (level >= 51 && level <= 74) { CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, Color_lv_2); } else if (level >= 75 && level <= 89) { CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, Color_lv_3); } else if (level >= 90 && level <= 99) { CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, Color_lv_4); } else { CPythonTextTail::Instance().AttachLevel(GetVirtualID(), szText, Color_lv_5); } } Para cambiar los colores tenéis que cambiar esto: D3DXCOLOR(152.0f / 255.0f, 255.0f / 255.0f, 51.0f / 255.0f, 1.0f); #Funciona (pero lo tengo desactivado) 11.Problema al abrir un sistema con un recuadro negro a la hora de escribir, como el caso de Debes iniciar sesión para ver el contenido del enlace en esta publicación. Quote el fix es el siguiente: 1.Vamos a nuestro constInfo y añadimos en cualquier parte: Quote INPUT_IGNORE = 0 Guardamos y vamos nuesgro game.py y buscmaos: Quote def OpenQuestWindow(self, skin, idx): Remplazamos toda la función por la siguiente: Quote def OpenQuestWindow(self, skin, idx): if constInfo.INPUT_IGNORE == 1: return else: self.interface.OpenQuestWindow(skin, idx) añade los tabs y listo. #fix funcional y testeado prueba: Debes iniciar sesión para ver el contenido del enlace en esta publicación. 12.Las bolas Polimorfas no funcionan - Gracias Debes iniciar sesión para ver el contenido del enlace en esta publicación. + Fix que algunos no hacen daño, ya que debería darnos un bonus extra de ataque o solo funciona para alguna raza. 1-Para el fix vamos a nuestro source game y editamos el archivo char.cpp y buscamos: Quote void CHARACTER::ComputeBattlePoints() Ahora remplazamos toda la función hasta if (IsPC()) por la siguiente: Quote void CHARACTER::ComputeBattlePoints() { /* if (IsPolymorphed()) { DWORD dwMobVnum = GetPolymorphVnum(); const CMob * pMob = CMobManager::instance().Get(dwMobVnum); int iAtt = 0; int iDef = 0; if (pMob) { iAtt = GetLevel() * 2 + GetPolymorphPoint(POINT_ST) * 2; lev + con iDef = GetLevel() + GetPolymorphPoint(POINT_HT) + pMob->m_table.wDef; } SetPoint(POINT_ATT_GRADE, iAtt); SetPoint(POINT_DEF_GRADE, iDef); SetPoint(POINT_MAGIC_ATT_GRADE, GetPoint(POINT_ATT_GRADE)); SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE)); } */ else if (IsPC()) if (IsPC()) 2.Ahora para que funcione el drop de las bolas_polimorfas y funcione al dar click, hacemos lo siguiente: 1.1-Vamos a nuestro navicat / mob_proto.txt y buscamos la columna : polymorph_item En esta columna, a veces vienen completa, o vacía, bueno, aquí pondremos el id de la bola que va a dropear, puede ser : Quote 70104, 70105, 70106, 70107 y 71093 2.1-Ahora elegimos la que vamos a querer, que tire el mob. NOTA: Con eso hacemos que se asigne ese mob a ese id, lo que significa que cuando el mob tire esa bola se transformará en ese mob que lo dropea. Nota2: Podemos ir poniendo el id que queramos de esos en todos los mobs, o usar el mismo id en todos. 3.Una vez echo eso, vamos a nuestro Winscp/FTP hasta encontrar el archivo: Quote mob_drop_item.txt Como sabéis aquí va el drop de los mobs, ahora, si habéis puesto el mismo id en polymorph_item le ponéis ese id a todos los mobs, si habéis puesto otro distinto a cada mob, buscáis el grupo de cada mob y le ponéis el id correspondiente. #Funciona implementado: Debes iniciar sesión para ver el contenido del enlace en esta publicación. 13.Fix bug de que aveces usa .txt o usa sql, <-también sirve para dejar tus files por sql o por txt. 1.Primer paso, vamos a nuestro src db y editamos el archivo -> ClientManagerBoot.cpp: buscamos la siguiente línea: Quote if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; } if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; } Bien, esa es la función que hace que usemos .txt o sql. Si queremos que sel servidor sea por sql, los comentamos así: Quote /*if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; } if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; }*/ Bien, si queremos que sea por .txt puede pasar 2 cosas, que tengas un #ifdef, por ejemplo #ifdef NOT_ENABLE_TXT que lo que hace es que ejecute sql siempre. entonces la solución es bloquear todo los #ifdef #else y #endif que tenga el #idfed NOT_ENABLE_TXT o tu función. O el segundo caso que lo tengas ya comentado con /* y */ entonces los quitamos para que se active la función. 2.Ahora buscamos un poco más abajo las funciones : bool CClientManager::MirrorItemTableIntoDB y bool CClientManager::MirrorMobTableIntoDB() Bien, una vez localizadas las funciones, si queremos que sea mediante .sql las comentamos con // o /* y */ . Si queremos que sea por .txt, si tienen // o /* y */ lo quitamos, y si usamos un #ifdef algo, normalmente tienen: Quote #ifdef Nazox { nazox 1 #else { nazox 1 #endif pues quitamos el ifdef, else y endif y su función o la comentamos, (ahora dejaré un ejemplo.) y a compilar! Este sería un ejemplo, para los files MartySama v4 que se que hay mucha gente que lo usa. está función, es la original, leyendo sql o con el bug mencionado anteriormente. (solo pondré las funciones si no se hará muy largo: Quote #define ENABLE_NO_TXT_SYSTEM #ifdef ENABLE_NO_TXT_SYSTEM /* if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; }*/ #else if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; } #endif if (!InitializeItemTable()) { sys_err("InitializeItemTable FAILED"); return false; } #ifdef ENABLE_NO_TXT_SYSTEM /* if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; }*/ #else if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; } #endif Funciones #ifdef ENABLE_NO_TXT_SYSTEM bool CClientManager::InitializeMobTable() { char query[4096]; snprintf(query, sizeof(query), "SELECT vnum, name, %s, type, rank, battle_type, level, " "size+0, ai_flag+0, setRaceFlag+0, setImmuneFlag+0, " "on_click, empire, drop_item, resurrection_vnum, folder, " "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, " "gold_min, gold_max, def, attack_speed, move_speed, " "aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, " "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, " "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2," "skill_vnum3, skill_level3, skill_vnum4, skill_level4 , sp_berserk, sp_stoneskin, " "sp_godspeed, sp_deathblow, sp_revive " "FROM mob_proto%s ORDER BY vnum", g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) { sys_err("Could not load mob_proto. No results!"); return false; } sys_log(0, "MOB_PROTO loading..."); if (!m_vec_mobTable.empty()) { sys_log(0, "RELOAD: mob_proto"); m_vec_mobTable.clear(); } m_vec_mobTable.resize(pRes->uiNumRows); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; MYSQL_ROW data; int col; while ((data = mysql_fetch_row(pRes->pSQLResult))) { col = 0; str_to_number(mob_table->dwVnum, data[col++]); 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->bType, data[col++]); str_to_number(mob_table->bRank, 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++]); str_to_number(mob_table->dwAIFlag, data[col++]); str_to_number(mob_table->dwRaceFlag, data[col++]); str_to_number(mob_table->dwImmuneFlag, data[col++]); str_to_number(mob_table->bOnClickType, data[col++]); str_to_number(mob_table->bEmpire, data[col++]); str_to_number(mob_table->dwDropItemVnum, data[col++]); str_to_number(mob_table->dwResurrectionVnum, data[col++]); strlcpy(mob_table->szFolder, data[col++], sizeof(mob_table->szFolder)); str_to_number(mob_table->bStr, data[col++]); str_to_number(mob_table->bDex, data[col++]); str_to_number(mob_table->bCon, data[col++]); str_to_number(mob_table->bInt, data[col++]); str_to_number(mob_table->dwDamageRange[0], data[col++]); str_to_number(mob_table->dwDamageRange[1], data[col++]); str_to_number(mob_table->dwMaxHP, data[col++]); str_to_number(mob_table->bRegenCycle, data[col++]); str_to_number(mob_table->bRegenPercent, data[col++]); str_to_number(mob_table->dwExp, data[col++]); str_to_number(mob_table->dwGoldMin, data[col++]); str_to_number(mob_table->dwGoldMax, data[col++]); str_to_number(mob_table->wDef, data[col++]); str_to_number(mob_table->sAttackSpeed, data[col++]); str_to_number(mob_table->sMovingSpeed, data[col++]); str_to_number(mob_table->bAggresiveHPPct, data[col++]); str_to_number(mob_table->wAggressiveSight, data[col++]); str_to_number(mob_table->wAttackRange, data[col++]); str_to_number(mob_table->dwPolymorphItemVnum, data[col++]); int i; for (i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i) str_to_number(mob_table->cEnchants, data[col++]); for (i = 0; i < MOB_RESISTS_MAX_NUM; ++i) str_to_number(mob_table->cResists, 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++]); for (i = 0; i < MOB_SKILL_MAX_NUM; ++i) { str_to_number(mob_table->Skills.dwVnum, data[col++]); str_to_number(mob_table->Skills.bLevel, 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++]); 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; } sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); sys_log(0, "CClientManager::InitializeMobTable:: %d mobs loaded.n", m_vec_mobTable.size()); fprintf(stderr, "CClientManager::InitializeMobTable:: %d mobs loaded\n", m_vec_mobTable.size()); return true; } #else 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<int,const char*> localMap; //bool isNameFile = true; //<ÆÄÀÏ Àбâ> cCsvTable nameData; if(!nameData.Load("mob_names.txt",'\t')) { fprintf(stderr, "Could not load mob_names.txt\n"); } else { nameData.Next(); //¼³¸írow »ý·«. while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //________________________________________________// cCsvTable data; if(!data.Load("mob_proto.txt",'\t')) { fprintf(stderr, "Could not load mob_proto.txt. Wrong file format?\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); memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size()); TMobTable * mob_table = &m_vec_mobTable[0]; //2.3 µ¥ÀÌÅÍ Ã¤¿ì±â while (data.Next()) { if (!Set_Proto_Mob_Table(mob_table, data, localMap)) { fprintf(stderr, "Could not process entry.\n"); } 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; } //_____________________________________________________// sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum()); return true; } #endif #ifdef ENABLE_NO_TXT_SYSTEM bool CClientManager::InitializeItemTable() { char query[4096]; snprintf(query, sizeof(query), "SELECT vnum, vnum_range, name, %s, type, subtype, gold, shop_buy_price, weight, size, flag, wearflag, " "antiflag, immuneflag+0, refined_vnum, refine_set, magic_pct, socket_pct, addon_type, " "limittype0, limitvalue0, limittype1, limitvalue1, " "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, " "value0, value1, value2, value3, value4, value5 " "FROM item_proto%s ORDER BY vnum", g_stLocaleNameColumn.c_str(), GetTablePostfix()); std::auto_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult * pRes = pkMsg->Get(); if (!pRes->uiNumRows) { sys_err("Could not load item_proto. No results!"); return false; } sys_log(0, "ITEM_PROTO loading..."); if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } m_vec_itemTable.resize(pRes->uiNumRows); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); TItemTable * item_table = &m_vec_itemTable[0]; MYSQL_ROW data; int col; while ((data = mysql_fetch_row(pRes->pSQLResult))) { col = 0; str_to_number(item_table->dwVnum, data[col++]); str_to_number(item_table->dwVnumRange, data[col++]); strlcpy(item_table->szName, data[col++], sizeof(item_table->szName)); strlcpy(item_table->szLocaleName, data[col++], sizeof(item_table->szLocaleName)); str_to_number(item_table->bType, data[col++]); str_to_number(item_table->bSubType, data[col++]); str_to_number(item_table->dwGold, data[col++]); str_to_number(item_table->dwShopBuyPrice, data[col++]); str_to_number(item_table->bWeight, data[col++]); str_to_number(item_table->bSize, data[col++]); str_to_number(item_table->dwFlags, data[col++]); str_to_number(item_table->dwWearFlags, data[col++]); str_to_number(item_table->dwAntiFlags, data[col++]); str_to_number(item_table->dwImmuneFlag, data[col++]); str_to_number(item_table->dwRefinedVnum, data[col++]); str_to_number(item_table->wRefineSet, data[col++]); str_to_number(item_table->bAlterToMagicItemPct, data[col++]); str_to_number(item_table->bGainSocketPct, data[col++]); str_to_number(item_table->sAddonType, data[col++]); item_table->cLimitRealTimeFirstUseIndex = -1; item_table->cLimitTimerBasedOnWearIndex = -1; int i; for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i) { str_to_number(item_table->aLimits.bType, data[col++]); str_to_number(item_table->aLimits.lValue, data[col++]); 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) { str_to_number(item_table->aApplies.bType, data[col++]); str_to_number(item_table->aApplies.lValue, data[col++]); } for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i) str_to_number(item_table->alValues, data[col++]); 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<DWORD, TItemTable *>::value_type(item_table->dwVnum, item_table)); ++item_table; } sort(m_vec_itemTable.begin(), m_vec_itemTable.end(), FCompareVnum()); sys_log(0, "CClientManager::InitializeItemTable:: %d items loaded.n", m_vec_itemTable.size()); fprintf(stderr, "CClientManager::InitializeItemTable:: %d items loaded\n", m_vec_itemTable.size()); return true; } #else bool CClientManager::InitializeItemTable() { //================== ÇÔ¼ö ¼³¸í ==================// //1. ¿ä¾à : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' ÆÄÀÏÀ» Àаí, // <item_table>(TItemTable), <m_map_itemTableByVnum> ¿ÀºêÁ§Æ®¸¦ »ý¼ºÇÑ´Ù. //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], <m_map_itemTableByVnum>À» ¸¸µç´Ù. // <Âü°í> // °¢ 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) ¸ÊÀ» ¸¸µç´Ù. //=================================================================================// map<int,const char*> localMap; cCsvTable nameData; if(!nameData.Load("item_names.txt",'\t')) { fprintf(stderr, "Could not load item_names.txt.\n"); } else { nameData.Next(); while(nameData.Next()) { localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1); } } //_________________________________________________________________// //ÆÄÀÏ Àоî¿À±â. cCsvTable data; if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "Could not load item_proto.txt. Wrong file format?\n"); return false; } data.Next(); //¸Ç ÀÁÙ Á¦¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸íÇÏ´Â ºÎºÐ) if (!m_vec_itemTable.empty()) { sys_log(0, "RELOAD: item_proto"); m_vec_itemTable.clear(); m_map_itemTableByVnum.clear(); } //data¸¦ ´Ù½Ã ùÁÙ·Î ¿Å±ä´Ù.(´Ù½Ã Àоî¿Â´Ù;;) data.Destroy(); if(!data.Load("item_proto.txt",'\t')) { fprintf(stderr, "Could not load item_proto.txt. Wrong file format?\n"); return false; } data.Next(); //¸Ç ÀÁÙ Á¦¿Ü (¾ÆÀÌÅÛ Ä®·³À» ¼³¸íÇÏ´Â ºÎºÐ) m_vec_itemTable.resize(data.m_File.GetRowCount() - 1); memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size()); TItemTable * item_table = &m_vec_itemTable[0]; while (data.Next()) { if (!Set_Proto_Item_Table(item_table, data, localMap)) { fprintf(stderr, "Failed to load item_proto table.\n"); } m_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::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<DWORD, TItemTable *>::value_type(item_table->dwVnum, item_table)); } sort(m_vec_itemTable.begin(), m_vec_itemTable.end(), FCompareVnum()); return true; } #endif Y esta la función corregida y que utilize .txt: Quote //#define ENABLE_NO_TXT_SYSTEM //#ifdef ENABLE_NO_TXT_SYSTEM /* if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; }*/ //#else if (!MirrorMobTableIntoDB()) { sys_err("MirrorMobTableIntoDB FAILED"); return false; } //#endif if (!InitializeItemTable()) { sys_err("InitializeItemTable FAILED"); return false; } //#ifdef ENABLE_NO_TXT_SYSTEM /* if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; }*/ //#else if (!MirrorItemTableIntoDB()) { sys_err("MirrorItemTableIntoDB FAILED"); return false; } //#endif funciones: #ifdef ENABLE_NO_TXT_SYSTEM /*bool CClientManager::MirrorMobTableIntoDB() { for (itertype(m_vec_mobTable) it = m_vec_mobTable.begin(); it != m_vec_mobTable.end(); it++) { const TMobTable& t = *it; char query[4096]; if (g_stLocaleNameColumn == "name") { snprintf(query, sizeof(query), "replace into mob_proto%s " "(" "vnum, name, type, rank, battle_type, level, size, ai_flag, setRaceFlag, setImmuneFlag, " "on_click, empire, drop_item, resurrection_vnum, folder, " "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, " "gold_min, gold_max, def, attack_speed, move_speed, aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, " "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, " "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2, " "skill_vnum3, skill_level3, skill_vnum4, skill_level4, " "sp_berserk, sp_stoneskin, sp_godspeed, sp_deathblow, sp_revive" ") " "values (" "%d, \"%s\", %d, %d, %d, %d, %d, %u, %u, %u, " "%d, %d, %d, %d, '%s', " "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%f, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d" ")", GetTablePostfix(), g_stLocaleNameColumn.c_str(), t.dwVnum, t.szName, t.szLocaleName, t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag, t.bOnClickType, t.bEmpire, t.dwDropItemVnum, t.dwResurrectionVnum, t.szFolder, t.bStr, t.bDex, t.bCon, t.bInt, t.dwDamageRange[0], t.dwDamageRange[1], t.dwMaxHP, t.bRegenCycle, t.bRegenPercent, t.dwExp, t.dwGoldMin, t.dwGoldMax, t.wDef, t.sAttackSpeed, t.sMovingSpeed, t.bAggresiveHPPct, t.wAggressiveSight, t.wAttackRange, t.dwPolymorphItemVnum, t.cEnchants[0], t.cEnchants[1], t.cEnchants[2], t.cEnchants[3], t.cEnchants[4], t.cEnchants[5], t.cResists[0], t.cResists[1], t.cResists[2], t.cResists[3], t.cResists[4], t.cResists[5], t.cResists[6], t.cResists[7], t.cResists[8], t.cResists[9], t.cResists[10], t.fDamMultiply, t.dwSummonVnum, t.dwDrainSP, t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel, t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel, t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint ); } else { snprintf(query, sizeof(query), "replace into mob_proto%s " "(" "vnum, name, %s, type, rank, battle_type, level, size, ai_flag, setRaceFlag, setImmuneFlag, " "on_click, empire, drop_item, resurrection_vnum, folder, " "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, " "gold_min, gold_max, def, attack_speed, move_speed, aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, " "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, " "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2, " "skill_vnum3, skill_level3, skill_vnum4, skill_level4, " "sp_berserk, sp_stoneskin, sp_godspeed, sp_deathblow, sp_revive" ") " "values (" "%d, \"%s\", \"%s\", %d, %d, %d, %d, %d, %u, %u, %u, " "%d, %d, %d, %d, '%s', " "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%f, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d" ")", GetTablePostfix(), g_stLocaleNameColumn.c_str(), t.dwVnum, t.szName, t.szLocaleName, t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag, t.bOnClickType, t.bEmpire, t.dwDropItemVnum, t.dwResurrectionVnum, t.szFolder, t.bStr, t.bDex, t.bCon, t.bInt, t.dwDamageRange[0], t.dwDamageRange[1], t.dwMaxHP, t.bRegenCycle, t.bRegenPercent, t.dwExp, t.dwGoldMin, t.dwGoldMax, t.wDef, t.sAttackSpeed, t.sMovingSpeed, t.bAggresiveHPPct, t.wAggressiveSight, t.wAttackRange, t.dwPolymorphItemVnum, t.cEnchants[0], t.cEnchants[1], t.cEnchants[2], t.cEnchants[3], t.cEnchants[4], t.cEnchants[5], t.cResists[0], t.cResists[1], t.cResists[2], t.cResists[3], t.cResists[4], t.cResists[5], t.cResists[6], t.cResists[7], t.cResists[8], t.cResists[9], t.cResists[10], t.fDamMultiply, t.dwSummonVnum, t.dwDrainSP, t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel, t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel, t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint ); } CDBManager::instance().AsyncQuery(query); } return true; }*/ #else bool CClientManager::MirrorMobTableIntoDB() { for (itertype(m_vec_mobTable) it = m_vec_mobTable.begin(); it != m_vec_mobTable.end(); it++) { const TMobTable& t = *it; char query[4096]; if (g_stLocaleNameColumn == "name") { snprintf(query, sizeof(query), "replace into mob_proto%s " "(" "vnum, name, type, rank, battle_type, level, size, ai_flag, setRaceFlag, setImmuneFlag, " "on_click, empire, drop_item, resurrection_vnum, folder, " "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, " "gold_min, gold_max, def, attack_speed, move_speed, aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, " "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, " "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2, " "skill_vnum3, skill_level3, skill_vnum4, skill_level4, " "sp_berserk, sp_stoneskin, sp_godspeed, sp_deathblow, sp_revive" ") " "values (" "%d, \"%s\", %d, %d, %d, %d, %d, %u, %u, %u, " "%d, %d, %d, %d, '%s', " "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%f, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d" ")", GetTablePostfix(), /*g_stLocaleNameColumn.c_str(),*/ t.dwVnum, t.szName, /*t.szLocaleName, */t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag, t.bOnClickType, t.bEmpire, t.dwDropItemVnum, t.dwResurrectionVnum, t.szFolder, t.bStr, t.bDex, t.bCon, t.bInt, t.dwDamageRange[0], t.dwDamageRange[1], t.dwMaxHP, t.bRegenCycle, t.bRegenPercent, t.dwExp, t.dwGoldMin, t.dwGoldMax, t.wDef, t.sAttackSpeed, t.sMovingSpeed, t.bAggresiveHPPct, t.wAggressiveSight, t.wAttackRange, t.dwPolymorphItemVnum, t.cEnchants[0], t.cEnchants[1], t.cEnchants[2], t.cEnchants[3], t.cEnchants[4], t.cEnchants[5], t.cResists[0], t.cResists[1], t.cResists[2], t.cResists[3], t.cResists[4], t.cResists[5], t.cResists[6], t.cResists[7], t.cResists[8], t.cResists[9], t.cResists[10], t.fDamMultiply, t.dwSummonVnum, t.dwDrainSP, t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel, t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel, t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint ); } else { snprintf(query, sizeof(query), "replace into mob_proto%s " "(" "vnum, name, %s, type, rank, battle_type, level, size, ai_flag, setRaceFlag, setImmuneFlag, " "on_click, empire, drop_item, resurrection_vnum, folder, " "st, dx, ht, iq, damage_min, damage_max, max_hp, regen_cycle, regen_percent, exp, " "gold_min, gold_max, def, attack_speed, move_speed, aggressive_hp_pct, aggressive_sight, attack_range, polymorph_item, " "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, " "skill_vnum0, skill_level0, skill_vnum1, skill_level1, skill_vnum2, skill_level2, " "skill_vnum3, skill_level3, skill_vnum4, skill_level4, " "sp_berserk, sp_stoneskin, sp_godspeed, sp_deathblow, sp_revive" ") " "values (" "%d, \"%s\", \"%s\", %d, %d, %d, %d, %d, %u, %u, %u, " "%d, %d, %d, %d, '%s', " "%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%f, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d" ")", GetTablePostfix(), g_stLocaleNameColumn.c_str(), t.dwVnum, t.szName, t.szLocaleName, t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag, t.bOnClickType, t.bEmpire, t.dwDropItemVnum, t.dwResurrectionVnum, t.szFolder, t.bStr, t.bDex, t.bCon, t.bInt, t.dwDamageRange[0], t.dwDamageRange[1], t.dwMaxHP, t.bRegenCycle, t.bRegenPercent, t.dwExp, t.dwGoldMin, t.dwGoldMax, t.wDef, t.sAttackSpeed, t.sMovingSpeed, t.bAggresiveHPPct, t.wAggressiveSight, t.wAttackRange, t.dwPolymorphItemVnum, t.cEnchants[0], t.cEnchants[1], t.cEnchants[2], t.cEnchants[3], t.cEnchants[4], t.cEnchants[5], t.cResists[0], t.cResists[1], t.cResists[2], t.cResists[3], t.cResists[4], t.cResists[5], t.cResists[6], t.cResists[7], t.cResists[8], t.cResists[9], t.cResists[10], t.fDamMultiply, t.dwSummonVnum, t.dwDrainSP, t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel, t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel, t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint ); } CDBManager::instance().AsyncQuery(query); } return true; } #endif #ifdef ENABLE_NO_TXT_SYSTEM /*bool CClientManager::MirrorItemTableIntoDB() { for (itertype(m_vec_itemTable) it = m_vec_itemTable.begin(); it != m_vec_itemTable.end(); it++) { if (g_stLocaleNameColumn != "name") { const TItemTable& t = *it; char query[4096]; snprintf(query, sizeof(query), "replace into item_proto%s (" "vnum, type, subtype, name, %s, gold, shop_buy_price, weight, size, " "flag, wearflag, antiflag, immuneflag, " "refined_vnum, refine_set, magic_pct, socket_pct, addon_type, " "limittype0, limitvalue0, limittype1, limitvalue1, " "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, " "value0, value1, value2, value3, value4, value5 ) " "values (" "%d, %d, %d, \"%s\", \"%s\", %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d )", GetTablePostfix(), g_stLocaleNameColumn.c_str(), t.dwVnum, t.bType, t.bSubType, t.szName, t.szLocaleName, t.dwGold, t.dwShopBuyPrice, t.bWeight, t.bSize, t.dwFlags, t.dwWearFlags, t.dwAntiFlags, t.dwImmuneFlag, t.dwRefinedVnum, t.wRefineSet, t.bAlterToMagicItemPct, t.bGainSocketPct, t.sAddonType, t.aLimits[0].bType, t.aLimits[0].lValue, t.aLimits[1].bType, t.aLimits[1].lValue, t.aApplies[0].bType, t.aApplies[0].lValue, t.aApplies[1].bType, t.aApplies[1].lValue, t.aApplies[2].bType, t.aApplies[2].lValue, t.alValues[0], t.alValues[1], t.alValues[2], t.alValues[3], t.alValues[4], t.alValues[5]); CDBManager::instance().AsyncQuery(query); } else { const TItemTable& t = *it; char query[4096]; snprintf(query, sizeof(query), "replace into item_proto%s (" "vnum, type, subtype, name, gold, shop_buy_price, weight, size, " "flag, wearflag, antiflag, immuneflag, " "refined_vnum, refine_set, magic_pct, socket_pct, addon_type, " "limittype0, limitvalue0, limittype1, limitvalue1, " "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, " "value0, value1, value2, value3, value4, value5 ) " "values (" "%d, %d, %d, \"%s\", %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d, " "%d, %d, %d, %d, %d, %d )", GetTablePostfix(), t.dwVnum, t.bType, t.bSubType, t.szName, t.dwGold, t.dwShopBuyPrice, t.bWeight, t.bSize, t.dwFlags, t.dwWearFlags, t.dwAntiFlags, t.dwImmuneFlag, t.dwRefinedVnum, t.wRefineSet, t.bAlterToMagicItemPct, t.bGainSocketPct, t.sAddonType, t.aLimits[0].bType, t.aLimits[0].lValue, t.aLimits[1].bType, t.aLimits[1].lValue, t.aApplies[0].bType, t.aApplies[0].lValue, t.aApplies[1].bType, t.aApplies[1].lValue, t.aApplies[2].bType, t.aApplies[2].lValue, t.alValues[0], t.alValues[1], t.alValues[2], t.alValues[3], t.alValues[4], t.alValues[5]); CDBManager::instance().AsyncQuery(query); } } return true; }*/ #else bool CClientManager::MirrorItemTableIntoDB() { for (itertype(m_vec_itemTable) it = m_vec_itemTable.begin(); it != m_vec_itemTable.end(); it++) { if (g_stLocaleNameColumn != "name") { const TItemTable& t = *it; char query[4096]; snprintf(query, sizeof(query), "replace into item_proto%s (" "vnum, type, subtype, name, %s, gold, shop_buy_price, weight, size, " "flag, wearflag, antiflag, immuneflag, " "refined_vnum, refine_set, magic_pct, socket_pct, addon_type, " "limittype0, limitvalue0, limittype1, limitvalue1, " "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, " "value0, value1, value2, value3, value4, value5 ) " "values (" "%d, %d, %d, \"%s\", \"%s\", %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%d, %ld, %d, %ld, " "%d, %ld, %d, %ld, %d, %ld, " "%ld, %ld, %ld, %ld, %ld, %ld )", GetTablePostfix(), g_stLocaleNameColumn.c_str(), t.dwVnum, t.bType, t.bSubType, t.szName, t.szLocaleName, t.dwGold, t.dwShopBuyPrice, t.bWeight, t.bSize, t.dwFlags, t.dwWearFlags, t.dwAntiFlags, t.dwImmuneFlag, t.dwRefinedVnum, t.wRefineSet, t.bAlterToMagicItemPct, t.bGainSocketPct, t.sAddonType, t.aLimits[0].bType, t.aLimits[0].lValue, t.aLimits[1].bType, t.aLimits[1].lValue, t.aApplies[0].bType, t.aApplies[0].lValue, t.aApplies[1].bType, t.aApplies[1].lValue, t.aApplies[2].bType, t.aApplies[2].lValue, t.alValues[0], t.alValues[1], t.alValues[2], t.alValues[3], t.alValues[4], t.alValues[5]); CDBManager::instance().AsyncQuery(query); } else { const TItemTable& t = *it; char query[4096]; snprintf(query, sizeof(query), "replace into item_proto%s (" "vnum, type, subtype, name, gold, shop_buy_price, weight, size, " "flag, wearflag, antiflag, immuneflag, " "refined_vnum, refine_set, magic_pct, socket_pct, addon_type, " "limittype0, limitvalue0, limittype1, limitvalue1, " "applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, " "value0, value1, value2, value3, value4, value5 ) " "values (" "%d, %d, %d, \"%s\", %d, %d, %d, %d, " "%d, %d, %d, %d, " "%d, %d, %d, %d, %d, " "%d, %ld, %d, %ld, " "%d, %ld, %d, %ld, %d, %ld, " "%ld, %ld, %ld, %ld, %ld, %ld )", GetTablePostfix(), t.dwVnum, t.bType, t.bSubType, t.szName, t.dwGold, t.dwShopBuyPrice, t.bWeight, t.bSize, t.dwFlags, t.dwWearFlags, t.dwAntiFlags, t.dwImmuneFlag, t.dwRefinedVnum, t.wRefineSet, t.bAlterToMagicItemPct, t.bGainSocketPct, t.sAddonType, t.aLimits[0].bType, t.aLimits[0].lValue, t.aLimits[1].bType, t.aLimits[1].lValue, t.aApplies[0].bType, t.aApplies[0].lValue, t.aApplies[1].bType, t.aApplies[1].lValue, t.aApplies[2].bType, t.aApplies[2].lValue, t.alValues[0], t.alValues[1], t.alValues[2], t.alValues[3], t.alValues[4], t.alValues[5]); CDBManager::instance().AsyncQuery(query); } } return true; } #endif #Funciona instalado, testado. 14.Fix título de todas las offlines shops, cuando hay tiendas al entrar al juego, o x cosa, nos sale arriba a la izquierda, muy famosa en la shop de Ken y great (funciona para todas) 1.Vamos a nuestra carpeta root y editamos el archivo uiofflineshopbuilder.py (ken, kory, tc, etc) o uiprivateshopbuilder.py (great, una propia, etc) buscamos: Quote self.SetPosition(-70, 0) y remplazamos por: Quote self.SetPosition(-70, -2000) Ese es el método 1, lo que hace, es que corrige la posición de la flecha de los ajustes, es decir, ya no te hace falta moverla, una vez inicias sesión, ya a parece las tiendas de forma normal, en caso que quieras quitar el título por x motivo, vas a ajustes y realizas la operación. 2.Dejamos el paso anterior de forma original sin modificar, y buscamos: Quote if systemSetting.GetShopNameRange() === xxx: <-las X pueden ser el número aleatorio que tengáis vosotros. y remplazamos por: Quote if systemSetting.GetShopNameRange() === 000: Con este 2 método, lo que logramos, es que podemos quitar el botón o la función, como queráis llamarlo, de mostrar o ocultar títulos de tienda, con eso, siempre estará activada. #Funciona instalado, testado. 15.Quitar la tasa de 3% al vender un objeto + que al vender item nos lo venda a 0 yang. 1.Para la tasa vamos a los archivos shop.cpp & shop_manager.cpp y buscamos en ambos archivos: Quote ival = 3; si no encontráis el 3 buscar solo ival = (solo hay 1 en todo el archivo) y remplazamos por: Quote iVal = 0; 2.Vender todo a 0 yang, vamos a shop.cpp y buscamos: Quote if (r_item.price <= 0) reemplazamos por: Quote if (r_item.price < 0 ) diferencia, es que hemos borrado el = #Funciona, testado. 16.Si tenéis tiempo a la hora de cambiar un bonus, (tienes que esperar x minutos/horas/dias/etc) y en los configs, no disponéis de la función TIME_CHANGE_BONUS o algo así esta es una solución alternativa, vamos a char_item.cpp y buscamos: Quote if (pPC) { DWORD dwNowMin = get_global_time() / 60; DWORD dwLastChangeItemAttrMin = pPC->GetFlag(msc_szLastChangeItemAttrFlag); if (dwLastChangeItemAttrMin + dwChangeItemAttrCycle > dwNowMin) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼Ó¼ºÀ» ¹Ù²ÛÁö %dºÐ À̳»¿¡´Â ´Ù½Ã º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù.(%d ºÐ ³²À½)"), dwChangeItemAttrCycle, dwChangeItemAttrCycle - (dwNowMin - dwLastChangeItemAttrMin)); return false; } pPC->SetFlag(msc_szLastChangeItemAttrFlag, dwNowMin); } y remplazamos por esto: Quote /*if (pPC) { DWORD dwNowMin = get_global_time() / 60; DWORD dwLastChangeItemAttrMin = pPC->GetFlag(msc_szLastChangeItemAttrFlag); if (dwLastChangeItemAttrMin + dwChangeItemAttrCycle > dwNowMin) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼Ó¼ºÀ» ¹Ù²ÛÁö %dºÐ À̳»¿¡´Â ´Ù½Ã º¯°æÇÒ ¼ö ¾ø½À´Ï´Ù.(%d ºÐ ³²À½)"), dwChangeItemAttrCycle, dwChangeItemAttrCycle - (dwNowMin - dwLastChangeItemAttrMin)); return false; } pPC->SetFlag(msc_szLastChangeItemAttrFlag, dwNowMin); }*/ 17.Hemos creado un nuevo refine_vnum con sus items para mejorar, pero solo me pide yang. Izquierda bug, derecha corregido : -Esto se debe a que si utilizamos vnum4 y count4, el refinamiento ya no funcionará porque utiliza material_count = 0 y no detecta ninguna columna "vnum" que sea 0. -Para solucionarlo nos vamos a nuestro src db archivo ClientManagerBoot.cpp y buscamos: if (prt->materials[i].vnum == 0) { prt->material_count = i; break; } y remplazamos por : if (!prt->materials[i].vnum || !prt->materials[i].count) break; prt->material_count++; -Tiene que quedar algo así: for (int i = 0; i < REFINE_MATERIAL_MAX_NUM; i++) { str_to_number(prt->materials[i].vnum, data[col++]); str_to_number(prt->materials[i].count, data[col++]); if (!prt->materials[i].vnum || !prt->materials[i].count) break; prt->material_count++; } 18.Arreglar ITEM_QUEST, CONFIRM_WHEN_USE , etc en los items. -Este problema surge cuando queremos usar ciertas funciones en los items, como por ejemplo STACKABLE para apilar (no ITEM_STACKABLE), CONFIRM_WHEN_USE (te pregunta si quieres usar el objeto, como anillo de exp, guante, etc) o ITEM_QUEST para como indica usar el objeto para una quest, resulta que por alguna razón, los valores no coinciden y en algunos casos no existe ni ciertas definiciones así que seré muy breve, vamos al grano. 1.Vamos a source game -> Item_lenght.h buscamos la función y la remplazamos por lo siguiente: Quote enum EItemFlag { ITEM_FLAG_REFINEABLE = (1 << 0), ITEM_FLAG_SAVE = (1 << 1), ITEM_FLAG_STACKABLE = (1 << 2), // ¿©·¯°³ ÇÕÄ¥ ¼ö ÀÖÀ½ ITEM_FLAG_COUNT_PER_1GOLD = (1 << 3), ITEM_FLAG_SLOW_QUERY = (1 << 4), //ITEM_FLAG_UNUSED01 = (1 << 5), // UNUSED ITEM_FLAG_UNIQUE = (1 << 5), ITEM_FLAG_MAKECOUNT = (1 << 6), ITEM_FLAG_IRREMOVABLE = (1 << 7), ITEM_FLAG_CONFIRM_WHEN_USE = (1 << 8), ITEM_FLAG_QUEST_USE = (1 << 9), ITEM_FLAG_QUEST_USE_MULTIPLE = (1 << 10), ITEM_FLAG_QUEST_GIVE = (1 << 11), ITEM_FLAG_ITEM_QUEST = (1 << 12), ITEM_FLAG_LOG = (1 << 13), ITEM_FLAG_APPLICABLE = (1 << 14), }; 2.Vamos source DB -> ProtoReader.cpp buscamos la función y remplazamos: Quote string arFlag[] = {"ITEM_REFINEABLE", "ITEM_SAVE", "ITEM_STACKABLE", "COUNT_PER_1GOLD", "ITEM_SLOW_QUERY", "ITEM_UNIQUE", "ITEM_MAKECOUNT", "ITEM_IRREMOVABLE", "CONFIRM_WHEN_USE", "QUEST_USE", "QUEST_USE_MULTIPLE", "QUEST_GIVE", "ITEM_QUEST", "LOG", "ITEM_APPLICABLE"}; 3.Compilamos DB y Game, y de mientras vamos al source cliente -> GameLib -> itemData.h buscamos la función y remplazamos: Quote enum EItemFlag { ITEM_FLAG_REFINEABLE = (1 << 0), // °³·® °¡´É ITEM_FLAG_SAVE = (1 << 1), ITEM_FLAG_STACKABLE = (1 << 2), // ¿©·¯°³ ÇÕÄ¥ ¼ö ÀÖÀ½ ITEM_FLAG_COUNT_PER_1GOLD = (1 << 3), // °¡°ÝÀÌ °³¼ö / °¡°ÝÀ¸·Î º¯ÇÔ ITEM_FLAG_SLOW_QUERY = (1 << 4), // °ÔÀÓ Á¾·á½Ã¿¡¸¸ SQL¿¡ Äõ¸®ÇÔ //ITEM_FLAG_RARE = (1 << 5), ITEM_FLAG_UNIQUE = (1 << 5), ITEM_FLAG_MAKECOUNT = (1 << 6), ITEM_FLAG_IRREMOVABLE = (1 << 7), ITEM_FLAG_CONFIRM_WHEN_USE = (1 << 8), ITEM_FLAG_QUEST_USE = (1 << 9), // Äù½ºÆ® ½ºÅ©¸³Æ® µ¹¸®´ÂÁö? ITEM_FLAG_QUEST_USE_MULTIPLE= (1 << 10), // Äù½ºÆ® ½ºÅ©¸³Æ® µ¹¸®´ÂÁö? ITEM_QUEST_GIVE = (1 << 11), ITEM_FLAG_ITEM_QUEST = (1 << 12), // UNUSED03 ITEM_FLAG_LOG = (1 << 13), // »ç¿ë½Ã ·Î±×¸¦ ³²±â´Â ¾ÆÀÌÅÛÀΰ¡? ITEM_FLAG_APPLICABLE = (1 << 14), }; 3.1.Ahora vamos a UserInterface -> PythonItemModule.cpp y comentamos esta linea: Quote //PyModule_AddIntConstant(poModule, "ITEM_FLAG_RARE", CItemData::ITEM_FLAG_RARE); 4.Para finalizar vamos a nuestro source de dum_proto ->ItemCSVReader.cpp y buscamos y remplazamos: Quote int get_Item_Flag_Value(string inputString) { string arFlag[] = {"ITEM_REFINEABLE", "ITEM_SAVE", "ITEM_STACKABLE", "COUNT_PER_1GOLD", "ITEM_SLOW_QUERY", "ITEM_UNIQUE", "ITEM_MAKECOUNT", "ITEM_IRREMOVABLE", "CONFIRM_WHEN_USE", "QUEST_USE", "QUEST_USE_MULTIPLE", "QUEST_GIVE", "ITEM_QUEST", "LOG", "ITEM_APPLICABLE"}; Y listo, ya tendremos todo funcionando, ejemplo de lo que puedes hacer: Gracias a Debes iniciar sesión para ver el contenido del enlace en esta publicación. por orientarme para el fix Debes iniciar sesión para ver el contenido del enlace en esta publicación. Iré actualizando todos los días que me sea posible con nuevas cosas. Actualizado 31/03/2020 Actualizado 02/04/2020 Actualizado 03/04/2020 Actualizado 16/04/2020 Actualizado 26/04/2020 Actualizado 18/05/2020 Actualizado 21/05/2020 Actualizado 28/05/2020 Actualizado 05/ 06/2020 Actualizado 20/03/2021 Actualizado 16/09/2023 Hakos, Anibal Estela Ramos, José Javier Romero Álvarez y 87 mas reacciono a esto 77 8 3 2 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 16 de Abril del 2020 Author Reportar Compartir Publicado 16 de Abril del 2020 Estaría bien que si queréis ayudar, o tenéis sistemas arreglados, o como se implementan con éxito o adaptar, o anti hacks etc,me mandaseis un txt como hago yo en la guía para publicarlo, e ir ampliando la sección, si queréis no es obligatorio, aún así ir tirando con lo que voy poniendo. XxBJPxX y Rarity reacciono a esto 2 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
anyi parra Publicado 26 de Abril del 2020 Reportar Compartir Publicado 26 de Abril del 2020 <3 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
Ghost Publicado 21 de Mayo del 2020 Reportar Compartir Publicado 21 de Mayo del 2020 Gracias por tomarte el tiempo de hacer esto vedat1089 reacciono a esto 1 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 22 de Mayo del 2020 Author Reportar Compartir Publicado 22 de Mayo del 2020 hace 5 horas, Ghost dijo: Gracias por tomarte el tiempo de hacer esto De nada, espero que te sirva. Ghost reacciono a esto 1 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
Painter Publicado 25 de Mayo del 2020 Reportar Compartir Publicado 25 de Mayo del 2020 Woo bro tu siempre ayudando a la comunidad, te agradezco esto, me servira bastante.. ojala hubiera mas gente como tu xD yo ayudo hasta donde puedo :v Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 25 de Mayo del 2020 Author Reportar Compartir Publicado 25 de Mayo del 2020 hace 16 horas, Painter dijo: Woo bro tu siempre ayudando a la comunidad, te agradezco esto, me servira bastante.. ojala hubiera mas gente como tu xD yo ayudo hasta donde puedo :v Gracias, se hace lo que se puede, espero que te sirva. Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 28 de Mayo del 2020 Author Reportar Compartir Publicado 28 de Mayo del 2020 #up último importante por si quieres txt o sql. Jeo reacciono a esto 1 Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
NazoX Publicado 4 de Junio del 2020 Author Reportar Compartir Publicado 4 de Junio del 2020 #3 cosas nuevas agregadas. Citar Enlace para comentar Compartir en otros sitios Mas opciones de compartir...
n1njutsu Publicado 4 de Septiembre del 2020 Reportar Compartir Publicado 4 de Septiembre del 2020 Thx Break reacciono a esto 1 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.