Search the Community

Showing results for tags 'c++'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • Community
    • Announcements
    • Feedback
  • Metin2
    • General
    • Questions and Answers
    • Guides & HowTo
    • Design
    • Private Servers
    • Services
    • Videos
  • Releases
    • General
    • Tools
    • Programming / Scripts
    • Quests
    • Binaries & Clients/Serverfiles
    • 3D Models
    • 2D Graphics
    • Operating Systems
  • Safe Zone
    • Offtopic
    • Games Talk
    • Music/Videos/Art
  • D:\YMIR WORK\'s Topics

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Website URL






Found 343 results

  1. I think the title should explain all. The system give way to set mob's drops via tables (Database) instead to use mob_drop_item.txt, common_drop_item.txt, drop_item_group.txt which can be buggy (easly, just a wrong space) without trace any error in your game expirience. WARNING : The System doens't disable the txts so you can use the txts and the tables without any problems. I have inserted "/reload d" command to reload the drop tables without restart channels. i will code a small tool in python to convert the txts to tables (i will be added to the repository). The drop chance by default is set to 1/1000 (so in table you should set it to 1000 to give 100% drop chance 'base' , it will change via the ymir's algorithm depend on the levels killer/victim). you can chance this scale to use 100 instead 1000 basically changing in lenght.h the value of DROP_SCALE_TABLE here you can find the repository. MySkype: live:ikarus.developer update: Added a small part to install only if you are using __SEND_TARGET_INFO__ to show the drop in the target board WARNING: i noticed some people think this system is a realtime database reading based system. i want explain it better , to make sure every body know how this system works. This system works using caching, it reading the tables once on boot, then the db core will update all core during core boot using cache. Only if you want to reload (refreshing the cache) the db core will read again the tables and will send to every core the "update".
  4. CxL'Mufuku

    c++ [RLS]RenderTarget

    Hi, I don't think I have to tell much about this. It'll look like the official one, some code is c&p from the official root files. Most of the own written code is NOT like the offical one. I added a new python module ("renderTarget"), so you don't need methods which officials use, like this: "playerm2g2.MyShopDecoShow( True )" You are able to display more than one render target at the same time. If you want to know more, take a look at the code. If there are any bugs, just message me. Download: (CxL).rar Password: Cxl.Services
  5. xP3NG3Rx

    [RLS] Quiver-System

    Hi guys. First of all, I also know this system is public already, but I was boring, so I had to reverse something, so here it is: Quiver System.7z If you have extra systems which might ignore the quivers, you must to extend them by yourself. Just couple of them from the official: acce, costume bonus transfer, change look, skillbook combination, sealbind and so on. Anything is wrong in the guide or missing something let me know, hit a comment below.
  6. Description : The mount will follow you. The bonuses is set from item_proto. Code is based on default pet code from Ymir, i don't offer support for extra features, details, anyway easy for use. (Sorry for tutorial, not so perfect.) Download:!eMIgVajA!uxIaISsLj3S5BipWsgEHIX4k84AcyGByIcF8DsTfv_E
  7. A few days ago I saw a post where someone asked how to hide the effects of the character and if there was a way, it would be better to do it with options to enabled/disabled. So I was trying to replicate the feature that the official servers implemented in version 18.4 Here I leave you an advance, it is not finished. At the moment only the options for hiding effects of items (such as "EFFECT_AUTO_HPUP", "EFFECT_HAPPINESS_RING_EQUIP", etc.) work. I know that you can also hide the effects such as skills, emoticons, etc. But I still can not find the way to do it (I could do it from, but in that case it would not be updated in real time, the client.exe would have to be restarted for the changes to be made.) I suppose that somewhere in the client src it will be possible to , but I still can not find it. But you can also try! So if you like you can do it and share in this thread. Screenshot: Download link: click me ^^
  8. xP3NG3Rx

    Emoji in TextLine

    Hi, folks! With this guide you will be able to combine textlines with images, like rubinum does. Usage is simple: emojiTextLine.SetText("|Eemoji/key_ctrl|e + |Eemoji/key_x|e + |Eemoji/key_rclick|e - Direct sell") The files are located in the icon pack, so basically the code will load from icon/{GIVEN_PATH}.tga - in the sample the path for the X is: icon/emoji/key_x.tga Here are the images from rubinum client:  Howto: Have fun Sorry for arab players , for sure they have also developers, so let's go guys, finish it If you have problem, maybe I made a mistake in the guide of missed out something, just leave a comment below. PS.: Sometimes the code tag of the board puts an extra invisible character mostly the end of the lines, if your IDE cries for syntax error, but it seems correct, check that part of the file with notepad++, it will show a ?(question mark) where the problem is.
  9. GithHub repository:
  11. Find the function: void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast) Find the case: POINT_GOLD And put this: case POINT_GOLD: { unsigned int nTotalMoney = GetGold() + amount; if (nTotalMoney > GOLD_MAX) { return; }else if (nTotalMoney < 0) { return; }else{ SetGold(GetGold() + amount); val = GetGold(); } } break; Your YANGS never been negatives!
  12. Cheque system full ~ like official This is my second release. I hope the tut is understood perfectly. Any error that you find in the system can comment here. I hope you find it useful. PS: Sorry for the quest, I know it's not very optimized, but it's functional and you can modify it yourself. If you want, you can install expanded money taskbar that I released in this same forum. Clic here to download VirusTotal Password: Best regards.
  13. Lets do ex: 16x9. I dont know if i something forgot, but its little tutorial how do it, im tired af so sorry for errors THANKS // tables.h #define SAFEBOX_MAX_NUM 135 to #define SAFEBOX_MAX_NUM 432 // Packet.h typedef struct command_safebox_checkout { BYTE bHeader; BYTE bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckout; typedef struct command_safebox_checkin { BYTE bHeader; BYTE bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckin; // Like that typedef struct command_safebox_checkout { BYTE bHeader; UINT bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckout; typedef struct command_safebox_checkin { BYTE bHeader; UINT bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckin; // Safebox.cpp if (m_iSize) m_pkGrid = M2_NEW CGrid(5, m_iSize); else m_pkGrid = NULL; // if (m_iSize) m_pkGrid = M2_NEW CGrid(16, m_iSize); else m_pkGrid = NULL; // ------------------------------ if (pkOldGrid) m_pkGrid = M2_NEW CGrid(pkOldGrid, 5, m_iSize); else m_pkGrid = M2_NEW CGrid(5, m_iSize); // if (pkOldGrid) m_pkGrid = M2_NEW CGrid(pkOldGrid, 16, m_iSize); else m_pkGrid = M2_NEW CGrid(16, m_iSize); // ---------------------------------- if (bCell >= 5 * m_iSize) // if (bCell >= 16 * m_iSize) // ---------------------------- int max_position = 5 * m_iSize; // int max_position = 16 * m_iSize; //Search for: LPITEM CSafebox::GetItem(BYTE bCell) //Replace with: LPITEM CSafebox::GetItem(UINT bCell) //Search for: bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, BYTE count) //Replace with bool CSafebox::MoveItem(UINT bCell, UINT bDestCell, DWORD count) // Safebox.h //Search for: LPITEM CSafebox::GetItem(BYTE bCell) //Replace with: LPITEM CSafebox::GetItem(UINT bCell) //Search for: bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, BYTE count) //Replace with bool CSafebox::MoveItem(UINT bCell, UINT bDestCell, DWORD count) Client/ // Packet.h typedef struct command_safebox_checkout { uint8_t bHeader; BYTE bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckout; typedef struct command_safebox_checkin { uint8_t bHeader; BYTE bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckin; // -------------- typedef struct command_safebox_checkout { uint8_t bHeader; UINT bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckout; typedef struct command_safebox_checkin { uint8_t bHeader; UINT bSafePos; TItemPos ItemPos; } TPacketCGSafeboxCheckin; // PythonNetworkStream.h //Search for: bool SendSafeBoxCheckinPacket(TItemPos InventoryPos, BYTE bySafeBoxPos); //edit: bool SendSafeBoxCheckinPacket(TItemPos InventoryPos, UINT bySafeBoxPos); //Search for: bool SendSafeBoxCheckoutPacket(BYTE bySafeBoxPos, TItemPos InventoryPos); //edit: bool SendSafeBoxCheckoutPacket(UINT bySafeBoxPos, TItemPos InventoryPos); // search for: bool SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, uint8_t byCount); //edit: bool SendSafeBoxItemMovePacket(UINT bySourcePos, UINT byTargetPos, uint8_t byCount); // Python****PhaseGameItem.cpp //Search for: bool CPythonNetworkStream::SendSafeBoxCheckinPacket(TItemPos InventoryPos, BYTE bySafeBoxPos) //edit bool CPythonNetworkStream::SendSafeBoxCheckinPacket(TItemPos InventoryPos, UINT bySafeBoxPos) //Search for: bool CPythonNetworkStream::SendSafeBoxCheckoutPacket(BYTE bySafeBoxPos, TItemPos InventoryPos) //edit bool CPythonNetworkStream::SendSafeBoxCheckoutPacket(UINT bySafeBoxPos, TItemPos InventoryPos) // bool CPythonNetworkStream::SendSafeBoxItemMovePacket(BYTE bySourcePos, BYTE byTargetPos, uint8_t byCount) // edit bool CPythonNetworkStream::SendSafeBoxItemMovePacket(UINT bySourcePos, UINT byTargetPos, uint8_t byCount) // PythonSafebox.h enum { SAFEBOX_SLOT_X_COUNT = 5, SAFEBOX_SLOT_Y_COUNT = 9, SAFEBOX_PAGE_SIZE = SAFEBOX_SLOT_X_COUNT * SAFEBOX_SLOT_Y_COUNT }; // edit enum { SAFEBOX_SLOT_X_COUNT = 16, SAFEBOX_SLOT_Y_COUNT = 9, SAFEBOX_PAGE_SIZE = SAFEBOX_SLOT_X_COUNT * SAFEBOX_SLOT_Y_COUNT }; Update: [C++] Change maximum number of inventory slots and more
  14. Metin2 Extended Item Award You can store all bonuses and stones for items. I wrote that as request from @ProfessorEnte, more informations at repository. 2018-04-02 14:02:11 Monday Fixed problem with save bonus after reload items. Fixed problem with unknown values. Correction for socket real time and more. Fixed unknown average/skill damage bonus value. player.item_proto.addon_type = -1 (Eg. 189, 199, 299, 1139, 1179, 2159, 2179, 3169, 3219, 5119, 5129, 6019, 6069, 6079, 7169)[+0 - +9] That's for the items which have addon type (-1) and you added them in item shop without bonuses like skill damage or hit damage, value x, y as default, so they'll will be without bonuses and get bugged. Now when the item will be inserted there'll be a check if item doesn't have those bonuses (from query) add a random average/skill damage bonus value. INSERT INTO player.item_award(`login`, `vnum`, `count`, `mall`) VALUES ('account', 189, 1, 1); 2019-04-12 02:31:18 Friday Fixed unique items based on the real time. Fixed unstackable items. Fixed if item count overflow occured, then set it to maximum. Added support for books. (check skill types, unknown skill), skill vnum need to be saved into socket0, (4=Aura of the Sword < player.skill_proto), if the skill vnum is unknown, there will be a random book based on pc races, excluded skills PASSIVE, GUILD, SUPPORT. Added a to-do for ITEM_BLEND, check if apply_type exists in bonuses, check if apply_value/apply_duration is equal with grades (1/2/3/4/5) from settings, blend.txt Added auto query. # Random book INSERT INTO player.item_award(`login`, `vnum`, `count`, `mall`) VALUES ('account', 50300, 1, 1); # Specific book by skill vnum INSERT INTO player.item_award(`login`, `vnum`, `count`, `socket0`, `mall`) VALUES ('account', 50300, 1, 4, 1); 2019-04-16 14:54:48 Tuesday (Video - Click) Added a check for attr types and values min - max. You can't insert wrong bonuses into a specific item. Eg. Add 2000 MAX_HP on your Sword+9, was possible, now not. Eg. Add +500 INT to your shield, now there's a check for min-max value of player.item_attr Lv.1 - Lv.5 and your 500 INTvalue will be replaced with max value from lvl5 of bonus, like 12 (lv5), that happen with all the bonuses, same thing with the values lower than lvl1, like 5 HP_REGEN on your neck, when the minimum (lv1) is 10, the value will be replaced with 10. If the bonus type can't be added into a specific item, the bonus will be ignored > deleted. (example: critical pct to armor) Refactorized all the code and moved all features into ItemAwardManager.cpp. C++11 or higher is required for checking attributes. # Test unknown types + higher and lower values in game. INSERT INTO `player`.`item_award`(`login`, `vnum`, `count`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`, `mall`) VALUES ( 'test', 149, 1, 17, 25, -- ATTBONUS_HUMAN 22, 35, -- ATTBONUS_DEVIL, 32, 175, -- RESIST_BELL 33, -150, -- RESIST_FAN 48, 1, -- IMMUNE_STUN 1 ); # See the min-max values for all the bonuses from weapon. SELECT apply+0 AS `index`, apply AS `name`, lv1 as `min_value`, lv5 as `max_value` FROM `item_attr` WHERE weapon > 0; # See if a specific bonus is included in bonuses of weapon. SELECT apply, apply+0 FROM `item_attr` WHERE weapon > 0 AND apply in ('ATTBONUS_HUMAN', 'ATTBONUS_DEVIL', 'RESIST_BELL', 'RESIST_FAN', 'IMMUNE_STUN'); Sockets & attrs INSERT INTO `player`.`item_award`(`login`, `vnum`, `count`, `given_time`, `why`, `socket0`, `socket1`, `socket2`, `attrtype0`, `attrvalue0`, `attrtype1`, `attrvalue1`, `attrtype2`, `attrvalue2`, `attrtype3`, `attrvalue3`, `attrtype4`, `attrvalue4`, `mall`) VALUES ( 'test', -- ACCOUNT_NAME 12029, -- ITEM_VNUM 1, -- ITEM_COUNT '2018-03-25 05:53:17', -- GIVEN_TIME 'ITEM_SHOP', -- REASON 28442, 28441, 28438, -- SOCKET 1 & 2 & 3 1, 1500, -- APPLY_MAX_HP 29, 10, -- APPLY_RESIST_SWORD, 30, 10, -- APPLY_RESIST_TWOHAND 31, 10, -- APPLY_RESIST_DAGGER 32, 10, -- APPLY_RESIST_BELL 1 -- MALL ); For those who use @martysama0134 source: //@Srcs/Server/db/src/ClientManager.cpp #define ENABLE_ITEMAWARD_REFRESH // Should be enabled Github repository or download - (click here):
  15. serex

    c++ Revive event

    Revive event for use in quests like when kill, when login... The event is triggered when the player revive. Source: Example of usage: when revive begin chat("Hello metin2dev.") end 
  16. Hi m2dev, I release my modifications of game core. 0x01.) Here are "some" new questfunctions to you ^^ If either of them is already public I'm sorry :> but these works perfectly. A short list of them: * Item module: - get_flag | Return: Integer | Args: None - get_wearflag | Return: Integer | Args: None - get_antiflag | Return: Integer | Args: None - has_antiflag | Return: Boolean | Args: int Antiflag - get_refine_set | Return: Integer | Args: None - get_limit | Return: Table1 | Args: byte LimitIndex[0..1] - get_apply | Return: Table1 | Args: byte ApplyIndex[0..2] - get_applies | Return: Table2 | Args: None - get_refine_materials | Return: Table3 | Args: None - get_addon_type | Return: Integer | Args: None - dec | Return: Nil | Args: None or byte Count - inc | Return: Nil | Args: None or byte Count - add_attribute | Return: Boolean | Args: None - get_attribute | Return: Table1 | Args: byte AttrIndex[0..4] - set_attribute | Return: Boolean | Args: byte AttrIndex[0..4], byte AttrType[1..94], short AttrValue[-32768..32767] - change_attribute | Return: Boolean | Args: None - add_rare_attribute | Return: Boolean | Args: None - get_rare_attribute | Return: Table1 | Args: byte AttrIndex[0..1] - set_rare_attribute | Return: Boolean | Args: byte AttrIndex[0..1], byte AttrType[1..94], short AttrValue[-32768..32767] - change_rare_attribute | Return: Boolean | Args: None - equip | Return: Boolean | Args: byte EquipCell[0..32] - set_count | Return: Nil | Args: byte/short Count(short with increased item stack number) Returning item table-structures: Table1 = { -- Type, Value 1, 2000 } Table2 = { -- [idx] = {Type, Value} -- Triton sword+9: [0] = { 7, 30 }, [1] = { 22, 12 }, [2] = { 17, 12 } } Table3 = { -- Poison sword+8(refineSet:27): material_count = 2, materials = { -- { Vnum, Count } { 30091, 2 }, { 27994, 1 } }, cost = 150000, prob = 10, } * NPC module: - get_level | Return: Integer | Args: None - get_name | Return: String | Args: None - get_type | Return: Byte | Args: None - get_rank | Return: Byte | Args: None - is_metin | Return: Boolean | Args: None - is_boss | Return: Boolean | Args: None - show_effect_on_target | Return: Boolean | Args: string EffectRealPath - get_ip | Return: String | Args: None - get_client_version | Return: String | Args: None - get_job | Return: Byte | Args: None - get_pid | Return: Integer | Args: None - get_exp | Return: Long | Args: None * PC module: - get_mount_vnum | Return: Integer | Args: None - get_point | Return: Integer | Args: byte PointNumber - get_real_point | Return: Integer | Args: byte PointNumber - show_effect | Return: Boolean | Args: string EffectRealPath - disconnect_with_delay | Return: Nil | Args: int Delay - get_max_level | Return: Integer | Args: None - get_ip | Return: String | Args: None - get_client_version | Return: String | Args: None - kill | Return: Nil | Args: None * Game module: - drop_item_and_select | Return: Nil | Args: int Vnum, byte/short Count=1, bool HasOwnership=false, short OwnershipTime=180 Example call: game.drop_item_and_select(19, 1, true, 30); item.set_attribute(0, apply.CRITICAL_PCT, 10) * Pet module: - is_mine | Return: Boolean | Args: None * Global: - purge_vid | Return: Nil | Args: int Vid Here are the codes: questlua_item.cpp questlua_npc.cpp questlua_pc.cpp questlua_game.cpp questlua_pet.cpp questlua_global.cpp 0x02.) Two GM commands: - "/kill_all" -> Kill all players inside your view-range/horizon - "/drop_item" -> Drop an item from arg1, or drop all items from range(arg1, arg2) Commands: Clientside version of kill_all: 0x03.) refine_proto reloading without server restart. Extend your "/reload Proto" command with the refine_proto reloading with this code parts: - Open your db/src/ClientManager.cpp file and replace your "void CClientManager::QUERY_RELOAD_PROTO()" function to this: void CClientManager::QUERY_RELOAD_PROTO() { if (!InitializeTables()) { sys_err("QUERY_RELOAD_PROTO: cannot load tables"); return; } for (TPeerList::iterator i = m_peerList.begin(); i != m_peerList.end(); ++i) { CPeer * tmp = *i; if (!tmp->GetChannel()) continue; tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TRefineTable) * m_iRefineTableSize); tmp->EncodeWORD(m_vec_skillTable.size()); tmp->Encode(&m_vec_skillTable[0], sizeof(TSkillTable) * m_vec_skillTable.size()); tmp->EncodeWORD(m_vec_banwordTable.size()); tmp->Encode(&m_vec_banwordTable[0], sizeof(TBanwordTable) * m_vec_banwordTable.size()); tmp->EncodeWORD(m_vec_itemTable.size()); tmp->Encode(&m_vec_itemTable[0], sizeof(TItemTable) * m_vec_itemTable.size()); tmp->EncodeWORD(m_vec_mobTable.size()); tmp->Encode(&m_vec_mobTable[0], sizeof(TMobTable) * m_vec_mobTable.size()); tmp->EncodeWORD(m_iRefineTableSize); tmp->Encode(m_pRefineTable, sizeof(TRefineTable) * m_iRefineTableSize); } } - Then open game/src/refine.cpp and replace this function: "bool CRefineManager::Initialize(TRefineTable * table, int size)" to this: bool CRefineManager::Initialize(TRefineTable * table, int size) { if (!m_map_RefineRecipe.empty()) m_map_RefineRecipe.clear(); for (int i = 0; i < size; ++i, ++table) { sys_log(0, "REFINE %d prob %d cost %d", table->id, table->prob, table->cost); m_map_RefineRecipe.insert(std::make_pair(table->id, *table)); } sys_log(0, "REFINE: COUNT %d", m_map_RefineRecipe.size()); return true; } - If you are done with these, open game/src/input_db.cpp and extend this event "void CInputDB::ReloadProto(const char * c_pData)" with this: /* * REFINE */ wSize = decode_2bytes(c_pData); c_pData += 2; sys_log(0, "RELOAD: REFINE: %d", wSize); if (wSize) { CRefineManager::instance().Initialize((TRefineTable *) c_pData, wSize); c_pData += wSize * sizeof(TRefineTable); } - Done. 0x04.) kill quest trigger fix (when kill / when race.kill) With this change you can use every kill methods with mobs and players and runs by once per kills. Examples: when 101.kill begin -> Works when you are killing Wild dogs. when kill begin -> Works with mobs and players too. when kill with npc.is_pc() begin -> Works with players only. when kill with npc.is_pc() == false begin -> Works with monsters only. when kill with npc.get_race() == 102 begin -> Works when you hunt Wolf. I tested with these codes: when kill begin if npc.is_pc() then chat("kill pc") end if npc.get_race() > 100 then chat("kill by race: "..tostring(npc.race)) end end when kill with npc.is_pc() begin chat("kill with npc.is_pc") end when kill with npc.get_race() == 102 begin chat("kill with npc.get_race 102") end when 101.kill begin chat("101.kill") end Follow these steps to fix it: - Open game/src/questmanager.h and search for this: "void Kill(unsigned int pc, unsigned int npc);" replace to: "void Kill(unsigned int pc, unsigned int npc, unsigned int pc2 = 0);" - Save&Close, open game/src/questmanager.cpp and search this function: "void CQuestManager::Kill(unsigned int pc, unsigned int npc)" - and replace to this: void CQuestManager::Kill(unsigned int pc, unsigned int npc, unsigned int pc2) { //m_CurrentNPCRace = npc; PC * pPC; sys_log(0, "CQuestManager::Kill QUEST_KILL_EVENT (pc=%d, npc=%d, pc2=%d)", pc, npc, pc2); if ((pPC = GetPC(pc))) { if (!CheckQuestLoaded(pPC)) return; /* [hyo] ¸÷ kill˝Ă Áßşą Ä«żîĆĂ ŔĚ˝´ °ü·ĂÇŃ ĽöÁ¤»çÇ× quest scriptżˇ when 171.kill begin ... µîŔÇ ÄÚµĺ·Î ŔÎÇĎż© ˝şĹ©¸łĆ®°ˇ Ăł¸®µÇľú´ő¶óµµ ąŮ·Î returnÇĎÁö ľĘ°í ´Ů¸Ą °Ë»çµµ ĽöÇŕÇϵµ·Ď şŻ°ćÇÔ. (2011/07/21) */ // call script if (npc > 0 && pc2 == 0) m_mapNPC[npc].OnKill(*pPC); LPCHARACTER ch = GetCurrentCharacterPtr(); LPPARTY pParty = ch->GetParty(); LPCHARACTER leader = pParty ? pParty->GetLeaderCharacter() : ch; if (leader) { m_pCurrentPartyMember = ch; if (m_mapNPC[npc].OnPartyKill(*GetPC(leader->GetPlayerID()))) return; pPC = GetPC(pc); } LPCHARACTER victim = CHARACTER_MANAGER::instance().FindByPID(pc2); if (victim && victim->IsPC() && m_mapNPC[QUEST_NO_NPC].OnKill(*pPC)) return; else if (m_mapNPC[QUEST_NO_NPC].OnKill(*pPC)) return; if (leader) { m_pCurrentPartyMember = ch; m_mapNPC[QUEST_NO_NPC].OnPartyKill(*GetPC(leader->GetPlayerID())); } } else sys_err("QUEST: no such pc id : %d", pc); } - Save&Close, open game/src/char_battle.cpp and search this call: "quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC)" - and replace to this: "quest::CQuestManager::instance().Kill(pkKiller->GetPlayerID(), quest::QUEST_NO_NPC, GetPlayerID());" - Done. 0x05.) ImmuneBug fix. I know there are some fixes but this is a working solution.. Everything inside two functions into item.cpp file by names: "CItem::EquipTo" and "CItem::Unequip". Every two functions are containing this sh*!&t: DWORD dwImmuneFlag = 0; for (int i = 0; i < WEAR_MAX_NUM; ++i) if (m_pOwner->GetWear(i)) SET_BIT(dwImmuneFlag, m_pOwner->GetWear(i)->m_pProto->dwImmuneFlag); m_pOwner->SetImmuneFlag(dwImmuneFlag); Hm, you have to replace those to this: DWORD dwImmuneFlag = 0; LPITEM item = NULL; for (int i = 0; i < WEAR_MAX_NUM; ++i) { if (item=m_pOwner->GetWear(i)) { if (item->GetImmuneFlag() != 0) SET_BIT(dwImmuneFlag, item->GetImmuneFlag()); if (item->GetAttributeCount() > 0) { if (item->HasAttr(APPLY_IMMUNE_STUN)) SET_BIT(dwImmuneFlag, IMMUNE_STUN); if (item->HasAttr(APPLY_IMMUNE_SLOW)) SET_BIT(dwImmuneFlag, IMMUNE_SLOW); if (item->HasAttr(APPLY_IMMUNE_FALL)) SET_BIT(dwImmuneFlag, IMMUNE_FALL); } } } m_pOwner->SetImmuneFlag(dwImmuneFlag); - Done. 0x06.) Finished selection by keyboard-usage with "Next" and "Prev" buttons. Test-example: when"TEST selection pages" begin local sTab = { "01","02","03","04","05","06","07","08","09","10", "11","12","13","14","15","16","17","18","19","20", "Exit"--to make exit by Escape key } local s=select_table(sTab) if s==table.getn(sTab) then return end chat("You'r choice: sTab["..tostring(s).."] -> "..sTab[s]) end Here you can download the full file from my client: Download 0x07.) Little SQL-Script: SELECT log.log.time AS "When", player.player.`name` AS Who, AS WhatDid, log.log.what AS ItemID, log.log.vnum AS ItemVnum, player.item_proto.locale_name AS ItemName, player.item.count AS Count, player.item.Socket0, player.item.Socket1, player.item.Socket2, player.item.AttrType0, player.item.AttrValue0, player.item.AttrType1, player.item.AttrValue1, player.item.AttrType2, player.item.AttrValue2, player.item.AttrType3, player.item.AttrValue3, player.item.AttrType4, player.item.AttrValue4, player.item.AttrType5, player.item.AttrValue5, player.item.AttrType6, player.item.AttrValue6 FROM log.log INNER JOIN player.player ON log.log.who = INNER JOIN player.item ON log.log.what = INNER JOIN player.item_proto ON log.log.vnum = player.item_proto.vnum WHERE in ("EXCHANGE_GIVE", "EXCHANGE_TAKE", "DROP", "SAFEBOX PUT", "SAFEBOX GET", "DEAD_DROP") AND player.`name` = "Xeriesey"; * You have to give a name where you can see Xeriesey ^-^ Result of query: I hope you like it. If you have any questions or find an error/mistake, just post a message into this thread and I will try to make answer when I'll be online. ps.: Sorry for my bad English. "(" + "c" + ")" == © -> F**k Changelog: - 2014.09.22. 16:29 / 04:29 PM ~ Added forgotten include to questlua_npc.cpp. - 2014.09.22. 16:48 / 04:48 PM ~ Added more forgotten things :S - 2014.09.27. 13:08 / 01:08 PM ~ SQL syntax fix With Regards, P3NG3R
  17. Hello everyone, What this can do ? This item can set a fix attribute that you set from item_proto (value0 and value1). This is just an example, it's made just for costume_body, if you want to make it for something else just make a new subtype. (1) Open char_item.cpp and search this: case USE_RESET_COSTUME_ATTR: After this case put this: (2) Open item_length.h and search this: enum EUseSubTypes Add in the end: USE_SET_ATT_COSTUME, [(Don't forget to put on service.h/CommonDefines.h this: #define SET_ATT_ITEM ) if you don't want "define" just remove the "#ifdef SET_ATT_ITEM from char_item ] (3) DB, Open ProtoReader.cpp and searchi: static string arSub3[] = { Add in the end: "USE_SET_ATT_COSTUME" (4) Binary source, Gamelib, Open ItemData.h and search: enum EUseSubTypes Add in the end: USE_SET_ATT_COSTUME, (5) Gamelib, Open ItemData.cpp and search: } return "USE_UNKNOWN_TYPE"; Before this add: case USE_SET_ATT_COSTUME: return DEF_STR(USE_SET_ATT_COSTUME); (6) Userinterface, Open PythonItemModule.cpp and search: PyModule_AddIntConstant(poModule, "USE_SPECIAL", CItemData::USE_SPECIAL); Put this after: PyModule_AddIntConstant(poModule, "USE_SET_ATT_COSTUME", CItemData::USE_SET_ATT_COSTUME); (7) Open from root and search: class InventoryWindow(ui.ScriptWindow): After this we need to have: USE_TYPE_TUPLE = ("USE_CLEAN_SOCKET", "USE_CHANGE_ATTRIBUTE", "USE_ADD_ATTRIBUTE", "USE_ADD_ATTRIBUTE2", "USE_ADD_ACCESSORY_SOCKET", "USE_PUT_INTO_ACCESSORY_SOCKET", "USE_PUT_INTO_BELT_SOCKET", "USE_PUT_INTO_RING_SOCKET") In this list we add in the end this: , "USE_SET_ATT_COSTUME" (8) In search: elif "USE_ADD_ATTRIBUTE2" == useType: After this elif we need to add this: elif "USE_SET_ATT_COSTUME" == useType: if self.__CanSetItemAttr(dstSlotPos): return True (9) In uiinventory search: def __CanAddItemAttr(self, dstSlotPos): After this def, add this: (10) Open and search : elif item.USE_ABILITY_UP == itemSubType: From elif item.ITEM_TYPE_USE == itemType: After this: elif item.USE_ABILITY_UP == itemSubType: We need to add this: After you completed all the steps above create a new item with type ITEM_USE and subtype USE_SET_ATT_COSTUME. Here are some examples of items: Video : I hope i didn't forgot anything . Have a nice day.
  18. Open db/ClientManagerBoot.cpp bool CClientManager::InitializeLandTable() { using namespace building; under this add CDBManager::instance().DirectQuery( "update land " "INNER JOIN guild ON land.guild_id = " "INNER JOIN player ON guild.`master` = " "set guild_id=0 " "where guild_id > 0 and " "DATE_SUB(NOW(),INTERVAL 21 DAY) > last_play; " ); CDBManager::instance().DirectQuery( "DELETE object " "FROM object " "INNER JOIN land ON = object.land_id " "WHERE land.guild_id=0; " ); Extracted from Inception source.
  19. Hello everybody, since I've heard that a lot of servers (and even the most recent vanilla source release) have no fix for this hack I decided to release this. It's not too big, but I really would like to make it visible for everybody. I highly dislike hacks in every form and I'll gladly develop such fixes. So, the fix is quite easy. It's a bug from metin2. They decided to add a check if the target is too far away to be attacked and yeah, that works. Targets only receive damage once they're within range. But the problem is that modern moblock tools do that a different way. They send attack packets to every mob in the near surrounding which triggers aggr towards the player. You may ask: Why does it trigger aggr and let the mobs move to the player? Well, as mentioned, the source has a fix for that - but it's implemented too late. 1. Open char_battle.cpp and search for this function: CHARACTER::Attack First you may notice that there's literally no check for distance. The distance check is implemented in battle.cpp in the function battle_melee_attack. That's fine and we don't need to modify anything about this. 2. If you scroll down you'll see the following lines: pkVictim->SetSyncOwner(this); if (pkVictim->CanBeginFight()) pkVictim->BeginFight(this); Noticed something? Yeah, the check is - as mentioned before - in the function battle_melee_attack. The problem is, that these lines are executed before the check happens. So hackers will be visible in logfiles (syslog should spam distance errors) but they're still free to hack like they want to. 3. Move the lines below the battle type segment So, how do we fix this? We'd simply move it down below the battle type functions. So you'd move it just before the line "if (iRet == BATTLE_DAMAGE || iRet == BATTLE_DEAD)". But still that won't be enough since these lines would still be executed. We don't want them to be executed. So we wrap a condition around it. 4. modify these lines so they look like this: if(iRet != BATTLE_NONE) { pkVictim->SetSyncOwner(this); if (pkVictim->CanBeginFight()) pkVictim->BeginFight(this); } If we take a look on the battle type functions we'll notice that they return the BATTLE_NONE if something goes wrong - for example the distance is invalid. 5. you're done! The fix pretty much solves this issue. If you still know hacks that work feel free to write in this topic, I'll gladly share solutions once I've developed them. Enjoy!
  20. Github repository:
  21. Some months ago a user asked here how to do it. Github repository:
  22. Tab Targeting: Player has the possibility to select the nearest monster around the character by pressing the Tab key. NOTE: Players are not able to select NPCs, Metin Stones and players as target! Repository at GitHub: Copyright infringement:
  23. You can use like this: Locale.hpp add; const char *locale_number(const char *string); const char *locale_number2(unsigned int mynumber); #define NUMBER_TEXT(str) locale_number(str) #define NUMBER_TEXT_INT(str) locale_number2(str) Locale.cpp add; #include <sstream> #include <string.h> using namespace std; const char * locale_number(const char *string2) { string str = string2; auto len = str.length(); auto counter = 2; while (counter < len) { if (counter % 3 == 0) str.insert(len - counter, "."); ++counter; } return str.c_str(); } const char * locale_number2(unsigned int mynumber) { stringstream strr; strr << mynumber; return locale_number(strr.str().c_str()); } TEST IN SERVER: auto gold = 10; ChatPacket(CHAT_TYPE_INFO, "We are testing(NUMBER_TEXT): %s", NUMBER_TEXT("123456789")); for (auto i : {10, 100, 1000, 10000, 500000}) { ch->ChatPacket(CHAT_TYPE_INFO, "We are testing(NUMBER_TEXT_INT): %s(i:%d)", NUMBER_TEXT_INT(gold*i), i); } TEST: #include <iostream> #include <string.h> using namespace std; #define NUMBER_TEXT(str) locale_number(str) #define NUMBER_TEXT_INT(str) locale_number2(str) const char *locale_number(const char *string); const char *locale_number2(int mynumber); const char * locale_number(const char *string2) { string str = string2; auto len = str.length(); auto counter = 2; /////// while (counter < len) { if (counter % 3 == 0) str.insert(len - counter, "."); ++counter; } return str.c_str(); } const char * locale_number2(int mynumber) { auto str = std::to_string(mynumber); return locale_number(str.c_str()); } int main () { auto gold = 10; for (auto i: {10, 100, 1000, 10000, 500000}) { cout << NUMBER_TEXT_INT(gold*i) << endl; } return 0; } Test result:
  24. Hey guys, Today I'm releasing a tutorial for Boss Effect Over Head. Download link: Pastebin tutorial (only): Picture of system: Special thanks to: @Syreldar @M.Sorin for some functions which I used in the tutorial. I believe someone will use it Have a nice day/night! Sincerely, ReFresh
  25. Dungeon.cpp: We are looking for : deadEvent = event_create (dungeon_dead_event, info, PASSES_PER_SEC (10)); PASSES_PER_SEC (10)); // 10 seconds PASSES_PER_SEC (300)); // 5 minutes Will be like: deadEvent = event_create (dungeon_dead_event, info, PASSES_PER_SEC (300)); The session will be destroyed in 5 minutes. Into quest from the respective dungeon you have to save logout and login, you can use questFlag.