Jump to content
metin2dev

Leaderboard


Popular Content

Showing content with the highest reputation since 07/17/2018 in all areas

  1. 6 points
    Here are the item and mob proto from .DE The mob_proto struct isn't 100%! https://mega.nz/#!HdJUhKjQ!IItX_szmsg8miDPWEe64iNoyYnhaFnz190D7CNpBse4
  2. 5 points
    A long time ago I had to initiate the development of a small tool as a nesassary requirement for a huge project as seen above. Though a development of such a tool is not an easy thing - more rather it's a really difficult thing, but I got it done in the end.. The tool is called "GR2 Converter". Now I'm able to use any Metin2 Asset in the Unreal Engine 4 and the development of the game can really begin. The first preview of Metin2 map parts rendered by the Unreal Engine 4: (Click to see video)
  3. 4 points
    Link: MEGA Web: Lynx3D Info:
  4. 4 points
    How the bug manifests? Client closes without any syserr How to reproduce the bug? Let' say you got textureset/metin2_map_c1.txt and inside you got an empty string like this: TextureSet TextureCount 17 Start Texture001 "" 5.000000 5.000000 0.000000 0.000000 0 0 0 End Texture001 Start Texture002 "d:\ymir work\terrainmaps\b\field\field 02.dds" 6.000000 6.000000 0.000000 0.000000 0 0 0 End Texture002 binary/src/source/PRTerrainLib/TextureSet.cpp Search this lin inside bool CTextureSet::SetTexture if (!pResource->IsType(CGraphicImage::Type())) And add before if (!pResource) return false; Search this line inside bool CTextureSet::AddTexture if (!pResource->IsType(CGraphicImage::Type())) And add before if (!pResource) return false;
  5. 4 points
    Hi metin2dev! Today i would like to present you my latest project which is League Emote System. Presentation video: Functions available: - The system has 32 emotes. Players recieve only 1 emote, rest of them have to be unlocked with specific emote item. - Emotes can be unlocked individually! - The emotes are saved per character. - The selected emote will remain saved even if u log out. - The Emote Inventory is split in 2 pages 16 emotes / page. - Contain most of league coolest emotes. - To emote you have to hold 'K' key and click on the emote picture. The interface will close and show above your character head the emote. - The emote interface can be drag anywhere on the screen to have easy accces. Last but not least 'muje zenu'! Regards, meleme18
  6. 3 points
    The textures of this water are ideally joined by no visible textures (seams). Colors are well matched to the climate of the metin. Download: You can find the link in the video description! If you want to see more of my work, look here: https://metin2dev.org/board/index.php?/topic/16751-3d-art-tatsumaru/
  7. 3 points
  8. 3 points
    Hi guys, Metin2 programming was kinda of a fun hobby for me. I've been working on this source files for about 10 months, but I have now more projects and academic work ahead of me, so I kinda won't have the time anymore to play with it. I was going to delete it today, but thought of sharing it first, it could help someone out there. It's not a great source code, but every problem I have encountered, I solved it. Here is a list of the things I've done (which I remember, there could be more):- Server Side: All upgrading scrolls are activated and working probably Devil Tower Blacksmith give 20% boost (and I believe that he give a fee discount also) Some pets can pickup items (CPetActor::isPickUpPet in PetSystem.cpp) Skills manuals now do give a success boost of 20% 7/8 skills now can be trained by books even before they reach m1, like the official version Guild banks have been activated (only depositing) Guild lands and other guild NPCs will now be bought by the yang in the guild's bank New quest function the change guild's gold (change_gold) Guild blacksmiths now have levels (will be explained later in the topic) Rituals Stone, Anti-Resistances and new monsters bonuses have been added eg. Strong Against Desert Monsters Transmutation system is working probably, even with weapons costumes Most events drops now is managed by the source, you won't need to make a quest for the drop. as soon as you activated the game flag, the associated item will start dropping (managed in void ITEM_MANAGER::CreateQuestDropItem in item_manager.cpp) Events that has special NPCs eg. Christmas and Ramadan event, the NPCs will summoned automatically in their respected location (managed in questmanager.cpp in void CQuestManager::SetEventFlag) mapindex GM command will return the map index GM restrict system is in place, they can't trade, friend, duel with normal players. IMPLEMENTOR Level is not affected by that restriction. Almost everything I've added is controllable by a macro Client Side: A lot of function has been added:- GetMasterPID returns the Guild leader PID, used later to prevent a visual bug where a member with withdraw authority can kick the leader (the leader won't be kicked actually, but it will look like s/he was kicked) itemBindable checks if the item is bind-able GetMonsterRaceFlag returns the monster's race. (doesn't work probably if the monster have more than one flag) CItemData::GetLevelLimit returns the level limit of an item, 0 if there was not any level limit. And much more you find them out yourself... The solution has been upgraded to VS2017, hadn't much time to test it, but seems to be working well, a old not upgraded version will be attached as well Root: Fixed a lot of bugs with (uiinventory.py and uitooltip.py) Visual bug with the Change attributes item, if you placed it on a item that doesn't have any bonuses, it will be green. Same bug with Blessing Marble, now it will only be green if the item has 4 bonuses if the item has 4 of more bonuses, add attribute will have a red effect Bind and unbind working perfectly with right effects Deleted some of the unnecessary files Tried to move all localized text to locale_game, not sure if there's more. Now let me explain the upgradable guild NPCs, at the moment it's only the blacksmith. So there are 3 levels, as levels go up, the upgrade fees increase, and the succeeding rate go up as well. at Level 3, the blacksmith return 10% of the upgrade cost to the guild bank, of course only when the player is not a member of the blacksmith's guild. They are upgraded by a quest (which will be attached as well). if anyone need more explanation, I'm happy to explain it more. Other thing that I've changed dramatically is the New pet system. So the public version of the pet system, the time of the pet doesn't change unless the pet is summoned, and that doesn't make any sense. I've changed that so the timer will change even if the pet is not summoned. I've also changed the system that most of the data will be saved on the item, and less data will be queried form the DB each time the player summon the pet, it's not perfect, but it's better version, atleast for me. the number of skills will appear once you open the egg on the item, just like official. the timer of transportation box will not begin now until the pet is placed in it. and more information about the pet now appear on the transportation box. I was trying to communicate the pet's information using packets instead of commands, put didn't have the time to finish it. you will find the basis of it there, so you always can complete my job. I think I have mentioned everything, If I remember any more information, I will update the topic. Please note that the EterPack is changed, you can access them from here The Client is in Arabic language, so I don't think anyone will use it, but I'm gonna upload it anyway. I'll upload the root, locale and uiscript separately if anyone needed them. Downloads Server Source Client Source Client Virus Scans Cheers, Abood
  9. 3 points
    Hello I'm Anohros, I'am a software- and game-developer and working on an game. It's a metin2 clone. I'm working on the player-controller at the moment: Game is developed with the Unreal Engine 4. With regards, Anohros
  10. 3 points
    binary/source/SpeedTreeLib/SpeedTreeForest.cpp Search and replace this function CSpeedTreeForest::SpeedTreeWrapperPtr CSpeedTreeForest::CreateInstance(float x, float y, float z, DWORD dwTreeCRC, const char * c_szTreeName) { SpeedTreeWrapperPtr pMainTree; if (!GetMainTree(dwTreeCRC, pMainTree, c_szTreeName)) { TraceError("CSpeedTreeForest::CreateInstance - Cannot find: %s", c_szTreeName); // 1 iunie 2018 return NULL; } SpeedTreeWrapperPtr pTreeInst = pMainTree->MakeInstance(); pTreeInst->SetPosition(x, y, z); pTreeInst->RegisterBoundingSphere(); return pTreeInst; }
  11. 3 points
    Here is the official-like version if someone interested in, yeah, I know, it's weird code. The official is in the CPythonCharacterManager class I think, I've put it into the CInstanceBase, and they use different map, but doesn't matter. I did some tests but I didn't stressed out in every situations, so I'm not sure this is safe enough to use. Oh, and I'm using it via python: Pseudo.c
  12. 3 points
    https://gyazo.com/feb2b32474c88856fba34fee8dfdba35 The gif shows everything
  13. 2 points
    Hello, here's a tutorial on how to update your MySQL Connector C (i think it's not supported anymore thanks oracle @.@) into MariaDB Connector C extracted from my source. You must need MariaDB, if you use MySQL with this connector don't ask help because it's not ment to be compatible. With this edit you could use MariaDB Connector v3.x without any problem. 1) Makefile update Open your libsql, db and game makefile and on the CFLAGS/IFLAGS add this: -I<your Extern source>/include/mariadb (ie.: ../Extern/include/mariadb) Also, if you have a -I referencing mysql please delete it Then, add this to your libsql, db and game CFLAGS this -D__MARIADB__ Finally, change on your db and game LIBS this -lmysqlclient into -lmariadbclient -lssl -lcrypto NOTE: If you already link libssl and libcrypto you can skip them NOTE ON 64BIT ENVIRONMENT: 2) Source Update Edit this code from libsql/AsyncSQL.h: #include <mysql/mysql.h> #include <mysql/errmsg.h> #include <mysql/mysqld_error.h> into: #ifdef __MARIADB__ #include <mariadb/mysql.h> #include <mariadb/errmsg.h> #include <mariadb/mysqld_error.h> #else #include <mysql/mysql.h> #include <mysql/errmsg.h> #include <mysql/mysqld_error.h> #endif Edit this code on db/DBManager.h #include <mysql/mysql.h> into this: #ifdef __MARIADB__ #include <mariadb/mysql.h> #else #include <mysql/mysql.h> #endif Finally, edit this file on libsql/AsyncSQL.cpp fprintf(stdout, "AsyncSQL: connected to %s (reconnect %d)\n", m_stHost.c_str(), m_hDB.reconnect); into: #ifdef __MARIADB__ fprintf(stdout, "AsyncSQL: connected to %s\n", m_stHost.c_str()); #else fprintf(stdout, "AsyncSQL: connected to %s (reconnect %d)\n", m_stHost.c_str(), m_hDB.reconnect); #endif 3) Database Server Update Now we're gonna replace the name "window" because MariaDB introduce the window operator that conflict with the query name What we will basicly do is change any "window" in query into "windows" db/AuctionManager.cpp function LoadAuctionItem() Replace: FROM item WHERE window = 'AUCTION' To: FROM item WHERE windows = 'AUCTION' db/ClientManagerPlayer.cpp Replace: ///////////////////////////////////////////// // 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴 ///////////////////////////////////////////// else { snprintf(szQuery, sizeof(szQuery), "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)", GetTablePostfix(), pTab->id, SAFEBOX, DRAGON_SOUL_INVENTORY); CDBManager::instance().ReturnQuery(szQuery, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); into: ///////////////////////////////////////////// // 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴 ///////////////////////////////////////////// else { snprintf(szQuery, sizeof(szQuery), "SELECT id,windows+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (windows < %d or windows = %d)", GetTablePostfix(), pTab->id, SAFEBOX, DRAGON_SOUL_INVENTORY); CDBManager::instance().ReturnQuery(szQuery, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, pTab->id)); Also replace: ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id); pkInfo->account_id = packet->account_id; CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo); //-------------------------------------------------------------- // 아이템 가져오기 //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)", GetTablePostfix(), packet->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY); CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id)); Into: ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id); pkInfo->account_id = packet->account_id; CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo); //-------------------------------------------------------------- // 아이템 가져오기 //-------------------------------------------------------------- snprintf(queryStr, sizeof(queryStr), "SELECT id,windows+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 " "FROM item%s WHERE owner_id=%d AND (windows < %d or windows = %d)", GetTablePostfix(), packet->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY); CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id)); Finally replace: snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), pi->player_id); delete CDBManager::instance().DirectQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM item%s WHERE owner_id=%d AND (window < %d or window = %d)", GetTablePostfix(), pi->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY); delete CDBManager::instance().DirectQuery(queryStr); Into: snprintf(queryStr, sizeof(queryStr), "DELETE FROM player%s WHERE id=%d", GetTablePostfix(), pi->player_id); delete CDBManager::instance().DirectQuery(queryStr); snprintf(queryStr, sizeof(queryStr), "DELETE FROM item%s WHERE owner_id=%d AND (windows < %d or windows = %d)", GetTablePostfix(), pi->player_id, SAFEBOX, DRAGON_SOUL_INVENTORY); delete CDBManager::instance().DirectQuery(queryStr); 4) Query update Design your player.item table, and change "window" to "windows". We have update into the new connector (mariadb connector c 3.x safetly), if you would like to downgrade change -lmariadbclient into -lmysqlclient, remove -D__MARIADB__ and change the -I referencing mariadb into mysql. Thanks for reading UPDATE: I've found other place to edit "window" into "windows" Open ClientManager.cpp From: else sys_log(0, "SAFEBOX id[%d] size[%d]", pSafebox->dwID, pSafebox->bSize); } if (0 == pSafebox->dwID) pSafebox->dwID = pi->account_id; pi->pSafebox = pSafebox; m2char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "SELECT id, window+0, pos, count, vnum, socket0, socket1, socket2, " "attrtype0, attrvalue0, " "attrtype1, attrvalue1, " "attrtype2, attrvalue2, " "attrtype3, attrvalue3, " "attrtype4, attrvalue4, " "attrtype5, attrvalue5, " "attrtype6, attrvalue6 " "FROM item%s WHERE owner_id=%d AND window='%s'", GetTablePostfix(), pi->account_id, pi->ip[0] == 0 ? "SAFEBOX" : "MALL"); To: else sys_log(0, "SAFEBOX id[%d] size[%d]", pSafebox->dwID, pSafebox->bSize); } if (0 == pSafebox->dwID) pSafebox->dwID = pi->account_id; pi->pSafebox = pSafebox; m2char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "SELECT id, windows+0, pos, count, vnum, socket0, socket1, socket2, " "attrtype0, attrvalue0, " "attrtype1, attrvalue1, " "attrtype2, attrvalue2, " "attrtype3, attrvalue3, " "attrtype4, attrvalue4, " "attrtype5, attrvalue5, " "attrtype6, attrvalue6 " "FROM item%s WHERE owner_id=%d AND windows='%s'", GetTablePostfix(), pi->account_id, pi->ip[0] == 0 ? "SAFEBOX" : "MALL"); From: else pItemAward->dwSocket0 = item_table->aLimits[i].lValue; break; } } } snprintf(szQuery, sizeof(szQuery), "INSERT INTO item%s (id, owner_id, window, pos, vnum, count, socket0, socket1, socket2) " "VALUES(%u, %u, '%s', %d, %u, %u, %u, %u, %u)", GetTablePostfix(), GainItemID(), pi->account_id, pi->ip[0] == 0 ? "SAFEBOX" : "MALL", iPos, pItemAward->dwVnum, pItemAward->dwCount, pItemAward->dwSocket0, pItemAward->dwSocket1, dwSocket2); } To: else pItemAward->dwSocket0 = item_table->aLimits[i].lValue; break; } } } snprintf(szQuery, sizeof(szQuery), "INSERT INTO item%s (id, owner_id, windows, pos, vnum, count, socket0, socket1, socket2) " "VALUES(%u, %u, '%s', %d, %u, %u, %u, %u, %u)", GetTablePostfix(), GainItemID(), pi->account_id, pi->ip[0] == 0 ? "SAFEBOX" : "MALL", iPos, pItemAward->dwVnum, pItemAward->dwCount, pItemAward->dwSocket0, pItemAward->dwSocket1, dwSocket2); } From: m_map_itemCache.erase(p->id); delete c; } m2char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "REPLACE INTO item%s (id, owner_id, window, pos, count, vnum, socket0, socket1, socket2, " "attrtype0, attrvalue0, " "attrtype1, attrvalue1, " "attrtype2, attrvalue2, " "attrtype3, attrvalue3, " "attrtype4, attrvalue4, " "attrtype5, attrvalue5, " "attrtype6, attrvalue6 " ") " "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d" ")", GetTablePostfix(), p->id, p->owner, p->window, To: m_map_itemCache.erase(p->id); delete c; } m2char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "REPLACE INTO item%s (id, owner_id, windows, pos, count, vnum, socket0, socket1, socket2, " "attrtype0, attrvalue0, " "attrtype1, attrvalue1, " "attrtype2, attrvalue2, " "attrtype3, attrvalue3, " "attrtype4, attrvalue4, " "attrtype5, attrvalue5, " "attrtype6, attrvalue6 " ") " "VALUES(%u, %u, %d, %d, %u, %u, %ld, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d" ")", GetTablePostfix(), p->id, p->owner, p->window, UPDATE2: Open db/Cache.cpp and find: if (memcmp(aAttr, p->aAttr, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM)) isAttr = true; char szColumns[QUERY_MAX_LEN]; char szValues[QUERY_MAX_LEN]; char szUpdate[QUERY_MAX_LEN]; int iLen = snprintf(szColumns, sizeof(szColumns), "id, owner_id, window, pos, count, vnum"); int iValueLen = snprintf(szValues, sizeof(szValues), "%u, %u, %d, %d, %u, %u", p->id, p->owner, p->window, p->pos, p->count, p->vnum); int iUpdateLen = snprintf(szUpdate, sizeof(szUpdate), "owner_id=%u, window=%d, pos=%d, count=%u, vnum=%u", p->owner, p->window, p->pos, p->count, p->vnum); Replace into: if (memcmp(aAttr, p->aAttr, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM)) isAttr = true; char szColumns[QUERY_MAX_LEN]; char szValues[QUERY_MAX_LEN]; char szUpdate[QUERY_MAX_LEN]; int iLen = snprintf(szColumns, sizeof(szColumns), "id, owner_id, windows, pos, count, vnum"); int iValueLen = snprintf(szValues, sizeof(szValues), "%u, %u, %d, %d, %u, %u", p->id, p->owner, p->window, p->pos, p->count, p->vnum); int iUpdateLen = snprintf(szUpdate, sizeof(szUpdate), "owner_id=%u, windows=%d, pos=%d, count=%u, vnum=%u", p->owner, p->window, p->pos, p->count, p->vnum);
  14. 2 points
    Hello, This little thing is marks your pet seal into your inventory like the autopotion. This arrives with the v17.5 patch. Open PetSystem.cpp and replace or make it fit for you: void CPetActor::SetSummonItem(LPITEM pItem) { if (NULL == pItem) { LPITEM pSummonItem = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID); if (NULL != pSummonItem) pSummonItem->SetSocket(1, FALSE); m_dwSummonItemVID = 0; m_dwSummonItemVnum = 0; return; } pItem->SetSocket(1, TRUE); m_dwSummonItemVID = pItem->GetVID(); m_dwSummonItemVnum = pItem->GetVnum(); } After that open the uiInventory.py and paste this code below the autopotion if-statement in the RefreshBagSlotWindow function. elif itemVnum >= 53001 and itemVnum <= 53256: metinSocket = [player.GetItemMetinSocket(globalSlotNumber, j) for j in xrange(player.METIN_SOCKET_MAX_NUM)]# <!> globalSlotNumber may be different <!> isActivated = 0 != metinSocket[1] if isActivated: self.wndItem.ActivateSlot(i) else: self.wndItem.DeactivateSlot(i)
  15. 2 points
    Hello, let's start! [15 Reactions == New Thread] 1- char_item.cpp Find for double ;; Yeah Monkeys, surprised XD? 2- On bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) find: if (iWearCell < 0) return false; add below: //FIX BLOCK MARRIAGE ITEMS WHILE RIDING if (iWearCell == WEAR_BODY && IsRiding() && (item->GetVnum() >= 11901 && item->GetVnum() <= 11914)) //Marriage Armors { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("?????????????????????????????")); return false; } if (iWearCell == WEAR_WEAPON && IsRiding() && (item->GetVnum() == 50201)) //Marriage Weapon { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("?????????????????????????????")); return false; } 3- SMALL PREVENTS ON questlua_global.cpp int _clear_server_timer(lua_State* L) { CQuestManager & q = CQuestManager::instance(); const char * name = lua_tostring(L, 1); DWORD arg = (DWORD) lua_tonumber(L, 2); if (name && arg) q.ClearServerTimer(name, arg); else sys_err("LUA PREVENT: Wrong argument on ClearServerTimer!"); return 0; } int _char_log(lua_State * L) { CQuestManager& q = CQuestManager::instance(); LPCHARACTER ch = q.GetCurrentCharacterPtr(); DWORD what = 0; const char* how = ""; const char* hint = ""; if (lua_isnumber(L, 1)) what = (DWORD)lua_tonumber(L, 1); if (lua_isstring(L, 2)) how = lua_tostring(L, 2); if (lua_tostring(L, 3)) hint = lua_tostring(L, 3); if (ch) LogManager::instance().CharLog(ch, what, how, hint); else sys_err("LUA PREVENT: !ch on _char_log!"); return 0; } 4- FIX ISSUE ON WAR (Not for all sources, but you can put it also if you haven't the problem): find: battle_is_attackable on battle.cpp first IF for victim must be like this: if (victim->IsDead() || victim->IsObserverMode()) return false; second IF for Char must be like this: if (ch->IsStun() || ch->IsDead() || ch->IsObserverMode()) return false; Thx to read here, hope it'll be useful. Regards Hex
  16. 2 points
    Only 1 modification is neccessary in the GuildMarkUploader.cpp file in this funcition: CGuildMarkUploader::__Load: ilCopyPixels(0, 0, 0, SGuildMark::WIDTH, SGuildMark::HEIGHT, 1, IL_BGRA, IL_BYTE, (ILvoid*)m_kMark.m_apxBuf); The ILvoid isn't defined anymore in the il.h, so or you define it by yourself like the following way bellow or just change it to void. typedef void ILvoid;
  17. 2 points
    Heya, as title says it's party dice system self written (without CHAT_TYPE_DICE_INFO, it's up to you) https://i.imgur.com/sj3EZ64.gifv (sry for laggs - "wooden pc" ^^) You can test possibility of same score there: https://repl.it/@Nevisor/Dice-FORINFOR char_battle.cpp //find if (ch->GetParty()) ch = ch->GetParty()->GetNextOwnership(ch, GetX(), GetY()); //replace with if (ch->GetParty()) { ch = ch->GetParty()->GetNextOwnership(ch, GetX(), GetY()); #ifdef __ENABLE_DICE_SYSTEM__ ch = ch->GetParty()->Dice(ch, GetX(), GetY(), item->GetName()); #endif } party.cpp //at the end of file add #ifdef __ENABLE_DICE_SYSTEM__ LPCHARACTER CParty::Dice(LPCHARACTER ch, long x, long y, const char * szName) //item name { for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (it->second.pCharacter->GetDesc() && DISTANCE_APPROX(it->second.pCharacter->GetX() - x, it->second.pCharacter->GetY() - y) < PARTY_DEFAULT_RANGE) { ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, "|cffffe6ba*** Rolling for the following item: %s ***", szName); while (1) { LPCHARACTER pkWinner; int iDice = 0; int iDraw = 0; for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) if (it->second.pCharacter->GetDesc() && DISTANCE_APPROX(it->second.pCharacter->GetX() - x, it->second.pCharacter->GetY() - y) < PARTY_DEFAULT_RANGE) { int iScore = number(1, 10000); if (iScore == iDice) iDraw == iScore; else if (iDice == 0 || iScore > iDice) { pkWinner = it->second.pCharacter; iDice = iScore; } ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, "|cffffe6ba*** ->\t\t\t\t\t%s - Dice score: %d ***", it->second.pCharacter->GetName(), iScore); } if (iDice != iDraw) { ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, "|cffbb00ff*** Winner of the item %s is: %s ***", szName, pkWinner->GetName()); return pkWinner; } else { ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, ""); ChatPacketToAllMember(CHAT_TYPE_DICE_INFO, "|cffffe6ba*** Rolling again for the following item: %s ***", szName); } } } } return ch; } #endif party.h //find void P2PSetMemberLevel(DWORD pid, BYTE level); //or bool IsPartyInDungeon(int mapIndex); //add bellow #ifdef __ENABLE_DICE_SYSTEM__ LPCHARACTER Dice(LPCHARACTER ch, long x, long y, const char * szName); #endif length.h enum EChatType { CHAT_TYPE_TALKING, /* 그냥 채팅 */ CHAT_TYPE_INFO, /* 정보 (아이템을 집었다, 경험치를 얻었다. 등) */ CHAT_TYPE_NOTICE, /* 공지사항 */ CHAT_TYPE_PARTY, /* 파티말 */ CHAT_TYPE_GUILD, /* 길드말 */ CHAT_TYPE_COMMAND, /* 일반 명령 */ CHAT_TYPE_SHOUT, /* 외치기 */ CHAT_TYPE_WHISPER, CHAT_TYPE_BIG_NOTICE, CHAT_TYPE_MONARCH_NOTICE, #ifdef __ENABLE_DICE_SYSTEM__ CHAT_TYPE_DICE_INFO, #endif CHAT_TYPE_MAX_NUM };
  18. 2 points
    // PythonNetworkStreamPhaseGame.cpp // Under bool CPythonNetworkStream::SendClientVersionPacket() from // add bool CPythonNetworkStream::SendClientVersionPacketNew(int32_t arg) { auto ver_arg = std::to_string(arg); std::string filename; GetExcutedFileName(filename); filename = CFileNameHelper::NoPath(filename); CFileNameHelper::ChangeDosPath(filename); TPacketCGClientVersion kVersionPacket; kVersionPacket.header = HEADER_CG_CLIENT_VERSION; strncpy(kVersionPacket.filename, filename.c_str(), sizeof(kVersionPacket.filename) - 1); strncpy(kVersionPacket.timestamp, ver_arg.c_str(), sizeof(kVersionPacket.timestamp) - 1); if (!Send(sizeof(kVersionPacket), &kVersionPacket)) { Tracef("SendClientReportPacket Error"); } return true; } //PythnNetworkStram.h // bool SendClientVersionPacket(); Under // add bool SendClientVersionPacketNew(int32_t arg); // PythonNetwoStramModule.cpp PyObject* netSendCheckVersionPacket(PyObject* poSelf, PyObject* poArgs) { int32_t iVer; if (!PyTuple_GetInteger(poArgs, 0, &iVer)) { return Py_BuildException(); } CPythonNetworkStream &rns = CPythonNetworkStream::Instance(); rns.SendClientVersionPacketNew(iVer); return Py_BuildNone(); } // static PyMethodDef s_methods[] = { "SendVersionPacket", netSendVersionPacket, METH_VARARGS }, Python usage def IsVersion(self, arg) net.SendClientVersionPacket(arg) if IsVersion(1111) #Do stuff I did not test it.
  19. 2 points
    Hi Dev`s here my new Multi Kill System. [Project] Angel vs Demon. [System] Multi Kill - Effects & Sounds.
  20. 2 points
    Enumeration must be identical in client / server / SQL/ dump_proto Example of a wrong enumeration OF source. enum Server : std::uint8_t { POINT_WOLFMAN, // OK POINT_WARRIOR, // OK } enum Client : std::uint8_t { POINT_WARRIOR, // WRONG POINT_WOLFMAN, // WRONG } Example of a correct enumeration. enum Server : std::uint8_t { POINT_WOLFMAN, // OK POINT_WARRIOR, // OK } enum client : std::uint8_t { POINT_WOLFMAN, // OK POINT_WARRIOR, // OK } Read more about how enum works here. https://en.cppreference.com/w/cpp/language/enum Most likely, I think you fucked the dump_proto enumerations. Example of wrong dump_proto enumeration. //Dump_proto int get_Item_ApplyType_Value(string inputString) { string arApplyType[] = { "APPLY_WOLFMAN", // ok "APPLY_BLEEDING", // ok }; int retInt = -1; // ProtoReader.cpp int get_Item_ApplyType_Value(std::string inputString) { std::string arApplyType[] = { "APPLY_BLEEDING", // wrong "APPLY_WOLFMAN", // wrong }; int retInt = -1; Check also the SQL enumeration order, from item_attr
  21. 1 point
    Other items have? Why don't you just make new MSM for this item then?
  22. 1 point
    AMAZING I love it :O Best regards Raylee
  23. 1 point
    File Name: WorldEditor ReMIX File Submitter: martysama0134 File Submitted: 27 Aug 2014 File Category: Tools Intro: This WE is a version compiled directly by me which includes infinite fixes and features. It's certain that you won't longer use the worldeditor_en! To make it simple, I wrote all the details about this feature and the common WE inside the relative config file: (called WorldEditor.txt) // I recently built a new worldeditor version with new features, so: Be a guinea pig of mine and test it all! // Info: (v24) // -) 100% translated // -) granny2.9 // -) F6 as Insert alternative // -) many default features not present inside the worldeditor_en (probably, that binary was taken out from an SVN long time ago and resource hacked) such as Ins for all regions and skyboxes // -) WASD UPLEFTDOWNRIGHT to move around (+asynchronous diagonally movements) // -) UP-LEFT-DOWN-RIGHT to move around*10 (+asynchronous diagonally movements) // -) config file for few things // Output options by default // few others such as default WASD movement // whether or not Insert should let you go where you were before the press // no MAI dump when saving atlas // whether or not DevIL should compress and remove alpha from minimap.dds // whether or not loading .mdatr building heights // default textureset when creating maps // overlapped tabs // other stuff // -) few bugfixes // default title app name // attempting to write to an empty textureset name when creating new maps // ViewRadius doubled every load&save // shadowmap.dds creation // assert when saving atlas // crash when adjusting height // many buffer under/overflows // *.mdc collision data saving (for game_test) // not checking output options when loading maps // water brush waterid bug (the id was increased until 256 each time the function was called; now it's based on the water height just like it should be) // init texture map reload map crash and last 2px always blank // if pack/property exists, it'll be read! (note: if found, the local property/ directory will not be considered!) // square shape even for up/down height brushes // add textureset texture button (+multiselection) // remove textureset texture feature (just selecting a texture from the list and pressing DELETE) // creation of empty textureset with index -1 (changed to 0) // change baseposition button // misspelled stuff // skybox bottom image (nb: you also need a fixed launcher for this) // removed the boring CTRL requirement (to move the camera) when editing daylight/attr // fixed refresh texture imagebox when onKey-pressing the down/up keys (like when onClicking them) // fixed TextureSet file creation if not existing // fixed new wolfman motion event handling // -) created new TextureSet field when creating new maps // -) created new Change/Delete Texture buttons when double-clicking a texture // -) created Background Music playback and Shadow Recalculate buttons // -) created water height "set 0z", "+1z", "-1z" buttons // -) server_attr generator // Note: // 0) there are no regressions in this version! a bug here means it'd also be present in older WE versions too! // 1) the shadow output option is tricky: when UpdateUI is called, shadows are hidden although the check is pressed (i implemented the shadow recalculate function for that) #fixed since v11 // 2) the bgm player requires /miles and the fadein/out doesn't work until you load the map // 3) the adjusting height button works only if mdatr height is detected // 4) the Debug version is laggy when working on maps such as n_flame_dungeon and n_ice_dungeon (by default, because SphereRadius are intensively checked in SphereLib\spherepack.h) // 5) if you load a map, the script panels (where you load .msa et similia) will have the camera perspective a little fucked up (0z instead of -32767z or 0x 0y -163,94z) // 6) few tree objects are not movable and/or highlightable after placed on the ground and their selection is invisible (you can still delete 'em) // trick: draw a square selecting a normal building and 'em, then move the building and you'll see all of 'em will be moved! // 7) the server_attr generator will clean all the unused flags! attr[idx]&=~0xFFFFFFF8; // 8) you can read files from pack/Index 'n stuff but be aware that Property will not be considered! #fixed since v15 // 9) the MonsterAreaInfo features are laggy and buggy as fuck // 10) even though you can select many textures at once (using ctrl+click on textureset list; for brushing or initializing a base texture), you can't delete more than one at the same time // 11) the .mdatr height is tricky; if you move a building, the height will not be refreshed until you put a new building or whatever you want to trigger the update event // 12) by default, the worldeditor tries to render only the first 8 terrain textures of a 32x32px region (nb: a 1x1 map is a 256x256 px region) // 13) the minimap rendering cannot catch the buildings/trees inside the first 2x2 regions due a ymir cache fault and you need to set the camera to "see" them // 14) when the textureset, environment, etc load fails, the old filename still remains loaded // 15) the attr flag "3" (three) has no implementation, so don't use it! // TODO: // A) look at more than 8 textures for region -> DONE // B) create a shortcut to fix the #5 note -> DONE // C) disable the radius <= GetRadius()+0.0001f check to fix the #4 note -> REJECTED // the worldeditor_en calls this assert and, if ignored, the lag ceases to exist (this will not occur in source version) // at least, if the release version is not a problem for you, use that in those few cases when .mse are abused and try to kill the debug one // D) translation in more languages other than english -> REJECTED // english should be enough! // E) alternative path for d: -> REJECTED // you can mount d as a subpath of c like this: // subst d: "c:\mt2stuff" // ### WE CONFIG FILE VIEW_CHAR_OUTPUT_BY_DEFAULT = 1 VIEW_SHADOW_OUTPUT_BY_DEFAULT = 1 VIEW_WATER_OUTPUT_BY_DEFAULT = 1 // WINDOW_HEIGHT_SIZE = 1080 // WINDOW_WIDTH_SIZE = 1920 WINDOW_FOV_SIZE = 45 // #100 = 1px (minimal px movement when pressing WASD) WASD_MINIMAL_MOVE = 100 // came back from where you were before pressing Insert/F6 NO_GOTO_AFTER_INSERT = 1 // disable MAI dumps when saving atlas and/or pressing Insert/F6 NOMAI_ATLAS_DUMP = 1 // disable minimap.dds alpha saving and enable compression NOMINIMAP_RAWALPHA = 1 // enable .mdatr height collision loading when moving on buildings or adjusting terrain DETECT_MDATR_HEIGHT = 1 // disable fog when loading maps NOFOG_ONMAPLOAD = 1 // refresh all checkbox configurations when loading maps 'n stuff REFRESHALL_ONUPDATEUI = 0 // set a default mapname prefix when creating new maps ("" to disable) NEW_MAP_MAPNAME_PREFIX = "metin2_map_" // display a default textureset when creating new maps ("" to disable) // note: it loads the filepath if exists, otherwise it will create an empty textureset file NEWMAP_TEXTURESETLOADPATH = "textureset\metin2_a1.txt" // create a default textureset as "textureset/{mapname}.txt" // note: this option is not considered if NEWMAP_TEXTURESETLOADPATH is not empty. [before v24] // note: this option is not considered if the TextureSet path input is not empty when creating a new map [since v24] NEWMAP_TEXTURESETSAVEASMAPNAME = 1 // ## SHORT-CUTs // # ESC(ape) Clean cursor // # Canc(el|Delete) Delete stuff such as selected buildings // # Ctrl+S Save map // # Ins(ert) or F6 Save shadowmap|minimap.dds // # F3 BoundGrid Show/Hide // # F4 Render UI Show/Hide // # F11 WireFrame Show/Hide // # R Reload Texture // # Z and X Decrease/Increase Texture Splat by 0.1 // # CapsLock Show GaussianCubic effect if shadows are displayed // # L-Shift+1-6 Show TextureCountThreshold flags (&2-7) as colors on the ground // # L-Shift+8 Set Max Showable texture to 8 (de-fix note 12) // # L-Shift+0 Set Max Showable texture to 255 (fix note 12) // # H Refresh MDATR Heights (useful when you move an object) (fix note 11) // # Y Set Perspective as default (fix note 5) // # T Set the Camera to catch all the object on the screen (w/a note 13) then you'll be ready to press Insert/F6 // # DO NOT HAVE AN OBJECT SELECTED WHEN USING THOSE SHORTCUTS (MW1-7) // # MouseWheel+1 move cursor x rotation // # MouseWheel+2 move cursor y rotation // # MouseWheel+3 move cursor z rotation // # MouseWheel+4 move cursor height base (1x) // # MouseWheel+5 move cursor height base (0.5x) // # MouseWheel+6 move cursor height base (0.05x) // # MouseWheel+7 move cursor ambience scale (1x) // # MouseWheel+Q move selected object height base (1x) // # MouseWheel+9 move selected object x position (1x) (+asyncronous) // # MouseWheel+0 move selected object y position (1x) (+asyncronous) // # MW+RSHIFT+9|0 as above but *10x (+asyncronous) // # MW+RCONTROL+9|0 as above but *100x (+asyncronous) // # MouseLeft Insert Objects // # MouseRight Move camera (it could require CTRL too) // # SPACE Start move/selected animation in Object/Effect/Fly CB // # ESC Stop animation in Effect/Fly CB NB: A space is required for such things: //*space*stuff KEY*space*=*space*VALUE Download: http://www.mediafire.com/download/c4yhd41ruy97c88/we_remix_v23__20140801-1859.rar http://www.mediafire.com/download/jxmemazw50vmnmj/we_remix_v24__20150621-0154.rar​ How To Map: This release will not cover this part. Look at CryPrime`s tutorials to understand how to do it. About the ServerAttr Generator: (since v14) This is a beta function but it should work fine. I tested it on gm_guild_build (1x1), metin2_map_a1 (4x5), metin2_map_trent (2x2), metin2_n_snowm_01 (6x6) and the result was the same as the blackyuko map editor. (I use a different lzo version and I clean deprecated and useless flags, so the size is different from this last one but the "final image" will be the same; using game_test to fix his server_attr will let mine and his perfectly equal byte per byte) I also give you the source code of my server_attr generator function. CLICK A server_attr file is based on all the attr.atr files merged into a one raw RGBA image and each one scaled from 256x256 to 512x512. After that, the image will be splitted into sectors of 128x128 px and each one compressed using lzo compression. The server_attr header is composed by the size of the map*4. (e.g. a 4x4 will have a 16x16 size with 256 sectors inside) (gj ymir CLICK) An uncompressed server_attr sector is just like this: CLICK (the sub 4 byte header is the size returned by the LzoCompress which indicates how much the compressed sector data are large) Each attr.atr is just like this: CLICK (the header is composed of 6 byte in total: 3 WORDs respectively for version, width and height; they are always 2634, 1, 1 so don't bother about it) A single attr.atr scaled from 256x256 to 512x512 will be just like this: CLICK You can use the game_test (from source) to perform few tasks like:Create a server_attr from a .mcd file (I won't suggest it) a <collision data filename> <map directory>Regenerate an old server_attr to server_attr.new using the current lzo compression and cleaning useless flag CLICK c <filename>Other stuff such as b to create a character instance or q to quit About the SkyBox Bottom pic fix: (since v21) Both metin2launch.exe and worldeditor.exe should be edited to see the bottom pic of the skybox. Ymir messed up the code wrongly flipping the bottom image. Open .SrcsClientEterLibSkyBox.cpp and replace ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f);with ////// Face 5: BOTTOM v3QuadPoints[0] = D3DXVECTOR3(1.0f, 1.0f, -1.0f); v3QuadPoints[1] = D3DXVECTOR3(1.0f, -1.0f, -1.0f); v3QuadPoints[2] = D3DXVECTOR3(-1.0f, 1.0f, -1.0f); v3QuadPoints[3] = D3DXVECTOR3(-1.0f, -1.0f, -1.0f); then recompile. Credits: Click here to download this file
  24. 1 point
    Thanks for nothing this time. Solved myself editing item.cpp like this: #if defined __WEAPON_COSTUME_SYSTEM__ && !defined __CHANGELOOK_SYSTEM__ else if (GetSubType() == COSTUME_WEAPON) { toSetPart = PART_WEAPON; if (!bAdd) { const CItem* pWeapon = m_pOwner->GetWear(WEAR_WEAPON); toSetValue = (NULL != pWeapon) ? pWeapon->GetVnum() : m_pOwner->GetPart(PART_WEAPON); } } #endif #if defined __WEAPON_COSTUME_SYSTEM__ && defined __CHANGELOOK_SYSTEM__ else if (GetSubType() == COSTUME_WEAPON) { toSetPart = PART_WEAPON; if (!bAdd) { const CItem* pWeapon = m_pOwner->GetWear(WEAR_WEAPON); if(NULL != pWeapon) { if(pWeapon->GetTransmutation() != 0) toSetValue = pWeapon->GetTransmutation(); else toSetValue = pWeapon->GetVnum(); } } } #endif
  25. 1 point
    The only two errors you could get when you compile your root are:"Decoding error, missing or incorrect coding"Since all the .py files are processed as korean strings, all of them written with a different charset (arabic) will trigger this issue. It's explained in the .txt file, and you can simply bypass this just writing the text in the locale_game.txt file. "Expected an increase in indentation level"This happens when the .py file has a bad tabulation, so bad written: It's clear that you won't be able to compile unworkable/unrunnable/broken .py files.
×