metin2united

Search the Community

Showing results for tags 'c++' in content posted in Programming / Scripts.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • 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

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website URL


Discord


Skype


ICQ


Yahoo


Location

Found 172 results

  1. https://github.com/blackdragonx61/Metin2-Typing-Information--Whisper-
  2. https://github.com/blackdragonx61/Metin2-Sort-Inventory-Items/tree/master/V2
  3. What's the issue? SYSERR: Aug 22 18:36:42.624296 :: ReadEtcDropItemFile: No such an item (name: Èò»ö ´ó±â+) SYSERR: Aug 22 18:36:42.624379 :: Boot: cannot load ETCDropItem: locale/germany/etc_drop_item.txt Some people fixed it long time ago by replacing the column name from item_proto (which is korean) with vnum. If you want to do it like this and don't want the source change (from below) or you don't have the source code of your game core, you can use a update query and copy the vnum to name just if the vnum from item_proto exists inside of mob_proto.drop_item by a specific mob. UPDATE player.item_proto SET name = vnum WHERE vnum IN (SELECT drop_item FROM player.mob_proto WHERE drop_item >= 10); # Affected rows: 83 # Time: 35.919ms How can i know where the items are dropped? So, the structure of etc_drop_item.txt is based on dropping a item with a probability from a specific mob where that mob have the item vnum attached in column mob_drop -> drop_item. SELECT DISTINCT locale_name, vnum, drop_item FROM player.mob_proto where drop_item >= 10; locale_name vnum drop_item Wolf 102 30028 Alpha Wolf 103 30069 Alpha Blue Wolf 105 30027 Grey Wolf 106 30070 How-To-Fix Default structure: item_proto.name prob 늑대발톱 2.0 늑대발톱+ 2.0 늑대털 2.0 멧돼지의 어금니 2.0 With the fix you can use both of methods: item_proto.[name or vnum] prob 30028 2.0 30069 2.0 30027 2.0 멧돼지의 어금니 2.0 Srcs/Server/game/src/item_manager_read_tables.cpp Srcs/Server/common/service.h
  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: https://cxl.services/freebies/RenderTarget (CxL).rar Password: Cxl.Services
  5. Description : The mount will follow you. The bonuses is set from item_proto. https://i.gyazo.com/9dac9deaada344672a153f37575d0b13.mp4 https://i.gyazo.com/05713068360a55cbbe25db6761925030.mp4https://i.gyazo.com/de7397f26a0b7aeeb66e1b4ce4af5b0d.mp4 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: https://mega.nz/#!eMIgVajA!uxIaISsLj3S5BipWsgEHIX4k84AcyGByIcF8DsTfv_E
  6. 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 playersettingmodule.py, 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 ^^
  7. GithHub repository: https://github.com/Vegas007/Metin2-Chat-Log-Viewer
  8. https://github.com/blackdragonx61/Metin2-Official-Inventory-Expansion
  9. 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!
  10. 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: metin2.dev Best regards.
  11. 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
  12. 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): https://github.com/Vegas007/Metin2-Extended-Item-Award
  13. serex

    c++ Revive event

    Revive event for use in quests like when kill, when login... The event is triggered when the player revive. Source: https://github.com/ajpelaez/Metin2-Revive-Event Example of usage: when revive begin chat("Hello metin2dev.") end 
  14. 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 uiQuest.py selection by keyboard-usage with "Next" and "Prev" buttons. Test-example: when 9010.chat."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 uiquest.py file from my client: Download 0x07.) Little SQL-Script: SELECT log.log.time AS "When", player.player.`name` AS Who, log.log.how 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 = player.player.id INNER JOIN player.item ON log.log.what = player.item.id INNER JOIN player.item_proto ON log.log.vnum = player.item_proto.vnum WHERE log.how 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
  15. 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: https://pastebin.com/65KpMgMF (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 uiinventory.py 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 uiinventory.py 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: https://pastebin.com/kiavCCKx (10) Open tooltip.py 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: https://pastebin.com/GVkW824Y 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: https://pastebin.com/HNxK6tfc Video : https://www.youtube.com/watch?v=728yoPapNCw I hope i didn't forgot anything . Have a nice day.
  16. 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 = guild.id " "INNER JOIN player ON guild.`master` = player.id " "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 land.id = object.land_id " "WHERE land.guild_id=0; " ); Extracted from Inception source.
  17. 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!
  18. Github repository: https://github.com/Vegas007/Metin2-Messenger-Get-Friend-Names
  19. Some months ago a user asked here how to do it. Github repository: https://github.com/Vegas007/Metin2-Private-Shop-Auto-Close
  20. 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: https://github.com/Vegas007/Metin2-Tab-Targeting-GF-v16.1 Copyright infringement:
  21. 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:
  22. 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
  23. 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.
  24. If you want to allow only one player per IP in certain maps you can use this Example of usage: when login with pc.is_pc_ip_in_map() begin chat("En este mapa solo puede entrar 1 personaje por IP, serás transportado en 5 segundos.") warp_to_village() end For add/remove maps, just edit: std::map<DWORD, std::map<DWORD, DWORD>> maps = { { 181, {} }, { 182, {} }, { 183, {} } }; In map_manager.h Implementation: https://github.com/ajpelaez/Metin2-One-Player-Per-Ip-In-Certain-Maps Enjoy
  25. Showing a message by specific error type when a item failed into refine. GitHub repository