Jump to content

Search the Community

Showing results for tags 'c++'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Metin2 Dev
    • Announcements
  • Community
    • Member Representations
    • Off Topic
  • Miscellaneous
    • Metin2
    • Showcase
    • File Requests
    • Community Support - Questions & Answers
    • Paid Support / Searching / Recruiting
  • Metin2 Development
  • Metin2 Development
    • Basic Tutorials / Beginners
    • Guides & HowTo
    • Binaries
    • Programming & Development
    • Web Development & Scripts / Systems
    • Tools & Programs
    • Maps
    • Quests
    • 3D Models
    • 2D Graphics
    • Operating Systems
    • Miscellaneous
  • Private Servers
    • Private Servers
  • Uncategorized
    • Drafts
    • Trash
    • Archive
    • Temporary
    • Metin2 Download

Product Groups

  • Small Advertisement
  • Large Advertisement
  • Advertising

Categories

  • Third Party - Providers Directory

Categories

  • Overview
  • Pages
    • Overview
    • File Formats
    • Network
    • Extensions

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Pillory


Marketplace


Game Server


Country


Nationality


Github


Gitlab


Discord


Skype


Website

  1. Hello! I was testing something on my server and I had to use /i a tons, so I just extended it instead. With this extension you can get as many items as you want (of course with limitation of your max inventory space.) For this we will working in only one file, called "cmd_gm.cpp". So, in cmd_gm.cpp fine ACMD(do_item) and edit the following things in the function. Be careful, because there's a chance that you don't use "g_bItemCountLimit" but "MAX_ITEM_COUNT" (or something like that) instead. //Find this: if (*arg2) { str_to_number(iCount, arg2); iCount = MINMAX(1, iCount, g_bItemCountLimit); } //And comment out iCount limitations like this: if (*arg2) { str_to_number(iCount, arg2); //iCount = MINMAX(1, iCount, g_bItemCountLimit); } //Find this: if (item->IsDragonSoul()) { [...] } //and after that add this: else if (!item->IsStackable()) { M2_DESTROY_ITEM(item); for (int i = 0; i < iCount; i++) { LPITEM newItem = ITEM_MANAGER::instance().CreateItem(dwVnum, 1); int iEmptyPos = ch->GetEmptyInventory(newItem->GetSize()); if (iEmptyPos != -1) { newItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); LogManager::instance().ItemLog(ch, newItem, "GM", item->GetName()); } else { M2_DESTROY_ITEM(item); ch->ChatPacket(CHAT_TYPE_INFO, "Not enough inventory space."); break; } } } else if (item->IsStackable() && iCount > g_bItemCountLimit) { M2_DESTROY_ITEM(item); while (iCount != 0) { LPITEM newItem; if (iCount >= g_bItemCountLimit) { newItem = ITEM_MANAGER::instance().CreateItem(dwVnum, g_bItemCountLimit); iCount -= g_bItemCountLimit; } else { newItem = ITEM_MANAGER::instance().CreateItem(dwVnum, iCount); iCount -= iCount; } int iEmptyPos = ch->GetEmptyInventory(newItem->GetSize()); if (iEmptyPos != -1) { newItem->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); LogManager::instance().ItemLog(ch, newItem, "GM", item->GetName()); } else { M2_DESTROY_ITEM(newItem); ch->ChatPacket(CHAT_TYPE_INFO, "Not enough inventory space."); break; } } }
  2. Download By Aslan The World Lottery System is comparable to the real lottery in the real world. However, in order to make the jackpot a little easier to win, you don't play 6out of 49 but 4out of 30. So the chance of winning is 1:27,405. But of course you also win with 1 identical, 2 identical and 3 identical numbers. The winning amount can be determined as a percentage of the jackpot and additionally by a cap. Features If you buy a lottery ticket, x% of the purchase price is added to the lottery pot and is active in the next draw. With each new draw, all lottery tickets for the corresponding draw are evaluated and, if you win, the winnings are spilled. Players' winning totals are deducted from the jackpot for the next draw. If a player has won the jackpot or if the value of the jackpot is below the sum X due to the payouts, the jackpot starts at the specified sum from the configs. If a player has won with his lottery ticket, the "Collect prize" button must be pressed. The prize then ends up in Yangspeicher and from there it can be collected in the correct inventory. Miscellaneous In addition to the basic system, there are 3 more windows: Information board The last X lottery draws Lotto ranking list Options_lottery.h #define ENABLE_ASLAN_LOTTERY #ifdef ENABLE_ASLAN_LOTTERY // General Options #define NEW_LOTTERY_NUMBERS_ACTIVATE 1 // New draws take place #define LOTTO_TICKET_COST 5000000 // How much a new ticket costs #define LOTTO_PUT_TICKET_COST_PERC_TO_JACKPOT 75 // What percentage of the ticket cost goes into the next jackpot // Percent per same number (1 = 0,01% || 10 = 0,1% || 100 = 1% > 5% from 100.000.000 = 5.000.000) #define PERC_REWARD_FOR_1_SAME_NUMBER 3 // Percent reward of Jackpot for 1 same number #define MAX_REWARD_FOR_1_SAME_NUMBER 5000000 // Max reward of Jackpot for 1 same number ( Deactivate when is 0 ) #define PERC_REWARD_FOR_2_SAME_NUMBER 10 // Percent reward of Jackpot for 2 same number #define MAX_REWARD_FOR_2_SAME_NUMBER 0 // Max reward of Jackpot for 2 same number ( Deactivate when is 0 ) #define PERC_REWARD_FOR_3_SAME_NUMBER 100 // Percent reward of Jackpot for 3 same number #define MAX_REWARD_FOR_3_SAME_NUMBER 0 // Max reward of Jackpot for 3 same number ( Deactivate when is 0 ) //#define TEST_MODE #ifdef TEST_MODE #define LOTTO_NUMBER_1 1 #define LOTTO_NUMBER_2 1 #define LOTTO_NUMBER_3 1 #define LOTTO_NUMBER_4 1 #define GEN_NEXT_NUMBER_TIME_SEC 60 #endif // TEST_MODE #define MIN_JACKPOT_MONEY 250000000 #define GENERATE_NEW_LOTTO_NUMBERS_PULSE_MIN 2 // The intervals at which new lottery numbers are generated #endif
  3. Download This system stores as a file for each player (in Metin2 client). So it is multi-window compatible as well, nothing about MySQL or server, only Python. In the tutorial, there is only a HowTo for the inventory, but you can easily transfer it to other windows. Basically, you have to do everything in the inventory window in other windows. Just make sure the SetPositions and SavePositions are called in the right places. It's better to always use Show directly after for example ui.ScriptWindow.Show(self) or Hide / Close before ui.ScriptWindow.Hide(self). By Aslan.
  4. M2 Download Center Download Here ( Internal ) With this change, slow effect will also reduce attack speed, and will reduce movement speed more than before, making it a good bonus (and slow immunity relevant). Video: 1. Client Source/UserInterface/InstanceBase.h Search: AFFECT_NUM = 64, Add above: AFFECT_SLOW_AS = 45, Search: NEW_AFFECT_BOW_DISTANCE, Add below: NEW_AFFECT_SLOW_AS = 227, PythonCharacterModule.cpp: Search: PyModule_AddIntConstant(poModule, "AFFECT_SLOW", CInstanceBase::AFFECT_SLOW); Add below: PyModule_AddIntConstant(poModule, "AFFECT_SLOW_AS", CInstanceBase::AFFECT_SLOW_AS); 2. game/src/affect.h Cauta: AFFECT_DEF_GRADE, Add below: AFFECT_SLOW_AS = 227, Cauta: AFF_BITS_MAX Add above: AFF_SLOW_AS=45, battle.cpp: Search: AttackAffect(pkAttacker, pkVictim, POINT_SLOW_PCT, IMMUNE_SLOW, AFFECT_SLOW, POINT_MOV_SPEED, -30, AFF_SLOW, 20, "SLOW"); Replace with: if (pkAttacker->GetPoint(POINT_SLOW_PCT) && !pkVictim->IsAffectFlag(AFF_SLOW)) { if (number(1, 100) <= pkAttacker->GetPoint(POINT_SLOW_PCT) && !pkVictim->IsImmune(IMMUNE_SLOW)) { pkVictim->AddAffect(AFFECT_SLOW, POINT_MOV_SPEED, -50, AFF_SLOW, 10, 0, true); pkVictim->AddAffect(AFFECT_SLOW_AS, POINT_ATT_SPEED, -40, AFF_SLOW_AS, 10, 0, true); } } char_affect.cpp: Search: RemoveAffect(AFFECT_SLOW); Add below: RemoveAffect(AFFECT_SLOW_AS); char_skill.cpp: Search: else if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_SLOW)) Replace the content with: { if (iPct && !pkChrVictim->IsAffectFlag(AFF_SLOW)) { if (number(1, 1000) <= iPct && !pkChrVictim->IsImmune(IMMUNE_SLOW)) { pkChrVictim->AddAffect(AFFECT_SLOW, POINT_MOV_SPEED, -50, AFF_SLOW, 10, 0, true); pkChrVictim->AddAffect(AFFECT_SLOW_AS, POINT_ATT_SPEED, -40, AFF_SLOW_AS, 10, 0, true); } } } Note: to modify the values, change the values inside the AddAffect function call. Example: pkChrVictim->AddAffect(AFFECT_SLOW_AS, POINT_ATT_SPEED, -40, AFF_SLOW_AS, 10, 0, true); -40 is the value reduced, 10 is the duration of the debuff.
  5. Hello guys, I didn't like the basic memory pooling solution in the client so I extended and rewrote some parts of it. now it allocates memory in chunks instead of one by one, the chunk's size can grow Alloc can have any parameters, so you don't need to use only default constructors ctors and dtors are called properly for each object created by the pool and also on unfreed objects on Clear Keep in mind, that it's not a drop-in replacement for every case where the old one was used, you may need to modify your code at some places, so I suggest porting to this new version one by one. Good luck! template<typename T> class CMemoryPoolNew { public: CMemoryPoolNew(size_t uChunkSize = 16, bool bGrowChunkSize = true) : m_uChunkSize(uChunkSize) , m_bGrowChunkSize(bGrowChunkSize) { } ~CMemoryPoolNew() { Clear(); } void Clear() { assert(m_Free.size() == m_Data.size() && "Memory pool has unfreed objects!"); if (m_Free.size() != m_Data.size()) { for (T* pData : m_Data) { if (std::find(m_Free.begin(), m_Free.end(), pData) == m_Free.end()) { pData->~T(); } } } m_Data.clear(); m_Data.shrink_to_fit(); m_Free.clear(); m_Free.shrink_to_fit(); for (T* pChunk : m_Chunk) { ::free(pChunk); } m_Chunk.clear(); m_Chunk.shrink_to_fit(); } template<class... _Types> T* Alloc(_Types&&... _Args) { if (m_Free.empty()) Grow(); T* pNew = m_Free.back(); m_Free.pop_back(); return new(pNew) T(std::forward<_Types>(_Args)...); } void Free(T* pData) { pData->~T(); m_Free.push_back(pData); } size_t GetCapacity() const { return m_Data.size(); } private: void Grow() { size_t uChunkSize = m_uChunkSize; if (m_bGrowChunkSize) uChunkSize += uChunkSize * m_Chunk.size(); T* pStart = (T*) ::malloc(uChunkSize * sizeof(T)); m_Chunk.push_back(pStart); m_Data.reserve(m_Data.size() + uChunkSize); m_Free.reserve(m_Free.size() + uChunkSize); for (size_t i = 0; i < uChunkSize; ++i) { m_Data.push_back(pStart + i); m_Free.push_back(pStart + i); } } private: size_t m_uChunkSize; bool m_bGrowChunkSize; std::vector<T*> m_Data; std::vector<T*> m_Free; std::vector<T*> m_Chunk; };
  6. M2 Download Center Download Here ( Internal ) Download Here ( GitHub )
  7. M2 Download Center Download Here ( Internal NEW V2 ) Download Here ( GitHub ) Includes winter and day-night change.
  8. Download Center Download Github Hello. So, i was bored and saw that nobody coded this (or someone did but never released) even though it was made like 3 years ago, so there you go.
  9. M2 Download Center Download Here ( Internal ) Hello, To extend NPC Shop to 80 Items follow these steps. ServerSide Open "common/length.h" and search: SHOP_HOST_ITEM_MAX_NUM = 40 Replace with: SHOP_HOST_ITEM_MAX_NUM = 80 In the same file search: SHOP_PRICELIST_MAX_NUM = 40 Replace with: SHOP_PRICELIST_MAX_NUM = 80 Now open "game/shop.cpp" and search: m_pGrid = M2_NEW CGrid(5, 9) Replace with: m_pGrid = M2_NEW CGrid(10, 9) Now open "game/shop_manager.cpp" and search: CGrid grid = CGrid(5, 9) Replace with: CGrid grid = CGrid(10, 9) Now compile Db File & Game File and ServerSide's steps complete. ClientSide NOTE: If you want Only NPC Shop's with 80 Items follow this guide, else if you want NPC Shop & Private Shop follow the Update Istruction. Extract "pack/uiscript" from your Client and open "shopdialog.py". Now reaplace all content with: Shopdialog.py ~ 80 Items Now create "shopdialog2.py" and insert this content: ShopDialog2 ~ 80 Items for Shop Ok, at this point you can compress your UiScript with the new file "shopdialog2.py". Extract "pack/root" from your Client and open "interfacemodule.py" Search this: self.dlgShop = uiShop.ShopDialog() self.dlgShop.LoadDialog() self.dlgShop.Hide() After add: self.dlgShop2 = uiShop.ShopDialog2() self.dlgShop2.LoadDialog() self.dlgShop2.Hide() Same file, search this: def OpenShopDialog(self, vid): self.wndInventory.Show() self.wndInventory.SetTop() self.dlgShop.Open(vid) self.dlgShop.SetTop() After add: def OpenShopDialog2(self, vid): self.wndInventory.Show() self.wndInventory.SetTop() self.dlgShop2.Open(vid) self.dlgShop2.SetTop() Now open "game.py" and Search: def StartShop(self, vid): self.interface.OpenShopDialog(vid) Replace with: def StartShop(self, vid): if chr.IsNPC(vid): self.interface.OpenShopDialog(vid) else: self.interface.OpenShopDialog2(vid) Now open "uishop.py" and Search: def Close(self): self.OnCloseQuestionDialog() shop.Close() net.SendShopEndPacket() self.CancelShopping() self.tooltipItem.HideToolTip() self.Hide() Replace with: def Close(self): self.OnCloseQuestionDialog() shop.Close() net.SendShopEndPacket() self.CancelShopping() self.Hide() Same file, search: def OnUpdate(self): USE_SHOP_LIMIT_RANGE = 1000 (x, y, z) = player.GetMainCharacterPosition() if abs(x - self.xShopStart) > USE_SHOP_LIMIT_RANGE or abs(y - self.yShopStart) > USE_SHOP_LIMIT_RANGE: self.Close() After add: UiShop.py ~ ShopDialog2 Now you can compress "root" file. #Update [24-02-15] Fixed Client Bug. Changes in "shop_manager.cpp" added. #Update [26-02-15] Added PrivateShop with 80 Items. NPC & PrivateShop with 80 Items ClientSide: Open "UserInterface/Packet.h" in you Binary Client Source and Search: SHOP_HOST_ITEM_MAX_NUM = 40 Replace with: SHOP_HOST_ITEM_MAX_NUM = 80 Now you can compile your Binary Source. Open your Client File and extract "pack/uiscript". Open "shopdialog.py" and replace all contentwith: Shopdialog.py ~ 80 Items Now open "privateshopbuilder.py" and replace all content with: PrivateShopBuilder ~ 80 Items Now you can compress your UiScript. Screen Private Shop: [Hidden Content] Et Voilà, we ended. [Hidden Content] Good work, Bye.
  10. Hey guys, Today I was facing with a guild melting problem, the problem was that the stones which are in the special inventory is not shown in the SelectItemWindow. I managed to solve this by adding a new check for special inventory size && special inventory slot end. In this tutorial the codes may be different from yours, if you have Sanii Special Inventory you have to check your GameType.h how is page size calculated and your PythonPlayerModule.cpp to see how it's defined. For example: PythonPlayerModule.cpp-> PyModule_AddIntConstant(poModule, "SPECIAL_INVENTORY_PAGE_SIZE", SPECIAL_INVENTORY_PAGE_SIZE); PyModule_AddIntConstant(poModule, "SPECIAL_INVENTORY_SLOT_END", c_Special_Inventory_Slot_End); GameType.h-> SPECIAL_INVENTORY_WIDTH = 5, SPECIAL_INVENTORY_HEIGHT = 9, SPECIAL_INVENTORY_PAGE_SIZE = SPECIAL_INVENTORY_WIDTH * SPECIAL_INVENTORY_HEIGHT, const DWORD c_Special_Inventory_Slot_Start = c_Belt_Inventory_Slot_End; const DWORD c_Special_Inventory_Skillbook_Slot_Start = c_Special_Inventory_Slot_Start; const DWORD c_Special_Inventory_Skillbook_Slot_End = c_Special_Inventory_Skillbook_Slot_Start +SPECIAL_INVENTORY_PAGE_SIZE * c_Inventory_Page_Count; const DWORD c_Special_Inventory_Stone_Slot_Start = c_Special_Inventory_Skillbook_Slot_End; const DWORD c_Special_Inventory_Stone_Slot_End = c_Special_Inventory_Stone_Slot_Start + SPECIAL_INVENTORY_PAGE_SIZE * c_Inventory_Page_Count; const DWORD c_Special_Inventory_Material_Slot_Start = c_Special_Inventory_Stone_Slot_End; const DWORD c_Special_Inventory_Material_Slot_End = c_Special_Inventory_Material_Slot_Start + SPECIAL_INVENTORY_PAGE_SIZE * c_Inventory_Page_Count; const DWORD c_Special_Inventory_Slot_End = c_Special_Inventory_Material_Slot_End; const DWORD c_Inventory_Count = c_Special_Inventory_Slot_End; Solution: root/uiselect.py In def RefreshSlot(self): search for: for i in xrange(player.INVENTORY_PAGE_SIZE*player.INVENTORY_PAGE_COUNT): After for loop add a new for loop for the special inventory: for i in xrange(player.SPECIAL_INVENTORY_PAGE_SIZE*player.SPECIAL_INVENTORY_SLOT_END): slotNumber = i itemVNum = getItemVNum(slotNumber) if 0 == itemVNum: continue if not item.IsMetin(itemVNum): continue itemGrade = player.GetItemGrade(slotNumber) if itemGrade > 2: continue self.inventorySlotPosDict[slotPos] = i slotPos += 1 if slotPos > 54: break Another problem is that if you select 100 stack of stone in the SelectItemWindow, they all disappear from the inventory, so instead of one piece, all of them disappear. Solution: mining.cpp Search for: ITEM_MANAGER::instance().RemoveItem(metinstone_item, "REMOVE (MELT)"); Replace with: metinstone_item->SetCount(metinstone_item->GetCount() - 1); I hope it will be useful for you Author of special inventory: @Sanii. @LordZiege approved me to share this fix.
  11. An annoying bug which need a fix. Gif with the problem (from ѕeмa™) : // PythonApplicationProcedure.cpp // After: if (m_isWindowFullScreenEnable) { __MinimizeFullScreenWindow(hWnd, m_dwWidth, m_dwHeight); } // Just add: OnMouseMiddleButtonUp(0, 0);
  12. Hello guys, I am once again coming with a really little fix that is related to rare attribute (6/7 bonuses). This bug is extra rare because to trigger it you must have a way to add 6 and 7 bonuses to an item and you must have an incorrect field or an error in your item_attr_rare table. So this is most likely a code sanitization but it's always good to avoid such errors as I encountered people having this bug. When you add a rare bonus, the game will fill a vector with the bonuses from the table and randomly pick one in the vector. However, if you have an error in the table, this vector will be empty and the randomization will result in doing "number(0, -1)", which is obviously incorrect and your core will crash. For searching purposes (if someone in the future is looking for a fix), the error is this one : The fix is really simple, we must check if the vector is empty and then exit at this moment. In item_attribute.cpp, in the following function: bool CItem::AddRareAttribute() Under this block of code: for (int i = 0; i < MAX_APPLY_NUM; ++i) { const TItemAttrTable& r = g_map_itemRare[i]; if (r.dwApplyIndex != 0 && r.bMaxLevelBySet[nAttrSet] > 0 && HasRareAttr(i) != true) { avail.push_back(i); } } Add the following check: [Hidden Content] And that's pretty much it, pretty straightforward, but instead of crashing, you will have a syserr and you will know what to check next!
  13. You can gain performance by turning off the spawn effects of monsters spawned in groups. Before: After: /**************************************************Game********************************************/ //Game/char.cpp //X2 Search: m_afAffectFlag.Set(AFF_SPAWN); //And Replace: // m_afAffectFlag.Set(AFF_SPAWN); /**************************************************Client*******************************************/ //UserInterFace/InstanceBase.cpp //Search: if (IsAffect(AFFECT_SPAWN)) __AttachEffect(EFFECT_SPAWN_APPEAR); //Replace: /*if (IsAffect(AFFECT_SPAWN)) __AttachEffect(EFFECT_SPAWN_APPEAR);*/ // UserInterFace/InstanceBaseBattle.cpp //Search: if (IsAffect(AFFECT_SPAWN)) __AttachEffect(EFFECT_SPAWN_DISAPPEAR); //Replace: /*if (IsAffect(AFFECT_SPAWN)) __AttachEffect(EFFECT_SPAWN_DISAPPEAR);*/
  14. Hello guys, Today I had the need to make a quest that had to trigger an action upon taking a goto. I didn't find any vanilla way to do it, so here we are, maybe it will be useful to someone. Please note that I did that on the fly, quickly and it's very rudimental, so if you have any comments about it, feel free to tell me or to contribute to this. I would be grateful as well. The tutorial is written for any vanilla 2014 files, so edit as you should for you. [Hidden Content] You can also refine it with other checks. But now you are able to check for example when someone is crossing a goto portal. Enjoy!
  15. If anyone had bought the VegaS' client optimization, they know that the loading of the motion files, depending on the loading vector's size, can take a bit of time, especially if you have 3642 files to load (totally random number ) N.B. I won't display even a single byte of the VegaS system's code. I would be happy to assist you if you are a customer of his and have purchased his client optimization (I will confirm with him, but I won't offer support for leaked stuff). Alrright, so, at first I thought to simply create a new "HWND" and work on that one, but, since it would run on the same instance as the client, it wouldn't be just as smooth. So just initialize a different instance and load the window on that instance? Sure, but, also no, too much of an hassle. A simpler solution would be to start a new app with the client who would receive the progress of the loading and show a progress bar or something, just to inform the player that the client is actually opening. Technically the project can be used for just anything else, like a separate menu integrated into the client or something, although the framework I used is not intended to fully work with DX8, so there might be some glitches considering what you wanna do with it. Now, let's dive into it, because it's not just a plug-and-play thing. Let's start by saying the app is made using a framework called ImGui: [Hidden Content] What's need to be done? Let's start with the name and the size (in this case 1280x800) of the main Application. You can find it on LoadingWindowHandler.cpp: m_HWND = ::CreateWindow(m_WCEX.lpszClassName, _T("Dear ImGui DirectX8 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, m_WCEX.hInstance, NULL); If you've had any experience on Win32 APIs, do not do this: SetWindowLong(hWnd, GWL_STYLE, 0); It breaks the text. If there is a fix, I haven't found one, yet. Second thing, ImGui stores the position and the size of the child windows inside a .ini file, called imgui.ini For example, in my case, I have: [Window][MainWindow] Pos=98,165 Size=1266,750 Collapsed=0 (declared in imgui.cpp line 4556) and then: [Window][TopWindow] Pos=0,0 Size=1265,762 Collapsed=0 Which is the window where we're gonna render the background, text and progressbar. Obviously, depending on your image size, these settings should be changed. We can also edit the size of the "TopWindow" actually running the application and resize it there. To do that, we can just de-comment: #define TEST_PROGRESS_BAR in LoadingWindowHandler.h After that, we need to change the Configuration Type: then we can open the application and move the window: Or resize it: Once closed, the application will have changed the settings in the ini file: [Window][MainWindow] Pos=98,165 Size=1266,750 Collapsed=0 [Window][TopWindow] Pos=-78,-120 Size=967,524 Collapsed=0 This way you can resize/move the window according to your background image. It is also possible to change the name of the ini file in imgui.cpp IniFilename = "imgui.ini"; To change the background image you want to edit the directory and name here: std::string filepath = cwd.string() + "\\movie\\splash.bmp"; From Microsoft docs the formats supported are: .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga. How are the positions of the ProgressBar, Text and background handled? Well, let's start from the background: ImGui::SetCursorPosY(0); auto size = ImGui::GetContentRegionAvail(); ImGui::Image((void*)SplashImage, ImVec2(size.x, size.y)); ImGui::SetCursorPosY(0); is like saying "go to the Y coord 0", then the rest is to "resize" the background image to the Area of the "TopWindow". The style of the ProgressBar is in LoadingWindowDesigner.cpp: #include "LoadingWindowDesigner.h" #include <ImGui/imgui.h> namespace LoadingWindowDesigner { void RenderUI(float progress, std::string loading_text) { auto window_size = ImGui::GetWindowSize(); ImGui::SetCursorPosY(window_size.y - 30); ImGui::Text(loading_text.c_str()); ImGui::ProgressBar(progress, ImVec2(window_size.x - 15.0f, 5.0f), ""); } } Again, with SetCursorPosY we are saying to go specific Y coords, in this case at the bottom of the window minus 30 pixels, that's where it's gonna write the text, then we draw the ProgressBar. The numbers inside ImVec2 are the dimensions of the ProgressBar. There's a third parameter where you could set an overlay text to the ProgressBar. If you wanna change the Font, well: [Hidden Content]/blob/master/docs/FAQ.md#q-how-can-i-load-a-different-font-than-the-default If you wanna change the color of the moving bar, you can go to imgui_widgets.cpp and change this line: RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_ButtonHovered), 0.0f, fraction, style.FrameRounding); The background instead is on this line: RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); The colors specified are the ones with the index: ImGuiCol_ButtonHovered and ImGuiCol_FrameBg. All this stuff can be seen by downloading the framework from the github repository and launching a project from the examples folder. The ImGui Demo window will show every possible option that you can then check on the source code (even the colors, that I found playing around with the demo window). One thing you'd notice from the window, is that there are some weird borders, and we can delete those (in my example, they actually fit pretty well with the background, so I left them. To do that just de-comment the other define: //#define LOADING_WINDOW_NOBORDERS P.S. There might be a few pixel modification on the ini file to do afterwards on the "TopWindow", noticeable when opening the client, because of the removal of the borders (if you did). Usually the correction is around 8px, which is the default padding of the framework, if I am not mistaken. You could also adjust the padding). So, we chose a background image, set the window size accordingly, positioned the text and rendered the progressbar as we wanted. And for now, we are done with the library (remember to change the configuration type to .lib and comment: #define TEST_PROGRESS_BAR Now compile the library both in Debug and Release mode, and add them to the lib folder of the client. After that open LinkerLibraries.h and add: #ifdef _DEBUG #pragma comment(lib, "LoadingWindowLib_d.lib") #else #pragma comment(lib, "LoadingWindowLib.lib") #endif then in StdAfx.h we add: #include "LoadingWindowMain.h" Then add on your include folder: LoadingWindowDesigner.h LoadingWindowHandler.h LoadingWindowMain.h You also need to add the ImGui folder (only the header files): Now if you have linking/compile errors, that's because your DirectX folder or your include directory, on the Project Settings, are different. To fix it you need to change the path in "Additional Include Properties" in the lib project so that your #include <directxheader> directive is the same as in the client. After confirming that everything works, how to use it: auto LoadingWindow = std::thread(LoadingWindow::InitializeLibrary); LoadingWindow.detach(); CPythonApplication *app = new CPythonApplication(); app->Initialize(hInstance); This will start a new thread running the library. How to change the progress percentage and the text? Let's say you have a number of executions: static auto EXECUTION_TIMES = 100000; float progress_adder = (1.0f - progress)/static_cast<float>(EXECUTION_TIMES); the "number" we are gonna add to the progress bar is gonna be his total (1.0f) minus the actual progress in that moment (if 0, you could just do 1.0f/static_cast<float>(EXECUTION_TIMES). Then on the loop of your loading stuff function you can change the text before the loop, or inside (if you wanna show something for every execution) and the actual progress: LoadingWindow::UpdateProgressText("Executing tasks..."); for (auto i = 0; i < EXECUTION_TIMES; ++i) { progress += progress_adder; // call a function here LoadingWindow::UpdateProgress(progress); } Always remember that the progress is a float and the "percentage" goes from 0.0f to 1.0f Now, in theory, the library should close itself when it gets to 1.0: if (m_Progress >= 1.0f) m_Done = true; but, at least in my case, it's also possible that it ends with a number such as 0.9999628 or something like that, so we can just call the CleanUpLibrary method to just close it when we want it. And that's it. Result: [Hidden Content] N.B. Despite working, if you intend to use this framework for other stuff, like some external menus to open from the client or w/e you have in mind, the DX8 version is super glitchy when there are two windows open: [Hidden Content]/issues/5379 and if you think you can use a different DirectX version, I am sorry to disappoint you: As you can see, when trying to load the texture, it's calling the "AddRef()" method: bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) { ImGuiIO& io = ImGui::GetIO(); IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!"); // Setup backend capabilities flags ImGui_ImplDX9_Data* bd = IM_NEW(ImGui_ImplDX9_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_dx9"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. bd->pd3dDevice = device; bd->pd3dDevice->AddRef(); //<----------- return true; } but, the client calls the DX8 APIs, not DX9, ergo no DirectX different than 8.1 Can you use a different framework? Sure, you may always use a similar approach with another similar GUI App, like the CefWebBrowser, but on a different thread, because the webbrowser runs on the same instance of the client: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { #ifdef _DEBUG _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_CRT_DF | _CRTDBG_LEAK_CHECK_DF ); //_CrtSetBreakAlloc( 110247 ); #endif LocaleService_LoadConfig("locale.cfg"); SetDefaultCodePage(LocaleService_GetCodePage()); CefWebBrowser_Startup(hInstance); //<------------- Credits: ocornuti, the owner of ImGui's repository KsaNL for providing a base for ImGui on DX8 Ikarus for dealing with my mental illness during this mini-project Project Download: Mega (or Metin2 Download)
  16. Download Metin2 Download You can enchant your items directly from the chosen NPC. *You can set the average & skill dmg from the quest. Preview: [Hidden Content] Download: MEGA VirusTotal
  17. M2 Download Center Download Here ( Internal ) Hello, To make the shout chat work for all kingdoms you need to open the file: input_p2p.cpp and search for this: struct FuncShout then replace this: if (!d->GetCharacter() || (d->GetCharacter()->GetGMLevel() == GM_PLAYER && d->GetEmpire() != m_bEmpire)) with this: if (!d->GetCharacter() /*|| (d->GetCharacter()->GetGMLevel() == GM_PLAYER && d->GetEmpire() != m_bEmpire)*/) After that open the file input_main.cpp and find this: TPacketGGShout p; p.bHeader = HEADER_GG_SHOUT; p.bEmpire = ch->GetEmpire(); strlcpy(p.szText, chatbuf, sizeof(p.szText)); P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShout)); SendShout(chatbuf, ch->GetEmpire()); and make it look like this: const char* kingdoms[3] = {"|cFFff000|h|h[Shinsoo]|cFFA7FFD4|H|h","|CFFFFFF00|H|h[Chunjo]|cFFA7FFD4|H|h","|cFF0080FF|H|h[Jinno]|cFFA7FFD4|H|h"}; char chatbuf_global[CHAT_MAX_LEN + 1]; int len_global_ = snprintf(chatbuf_global, sizeof(chatbuf_global), "%s %s",kingdoms[ch->GetEmpire()-1], chatbuf); TPacketGGShout p; p.bHeader = HEADER_GG_SHOUT; p.bEmpire = ch->GetEmpire(); strlcpy(p.szText, chatbuf_global, sizeof(p.szText)); P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShout)); SendShout(chatbuf_global, ch->GetEmpire());
  18. M2 Download Center Download Here ( Internal ) Hey, Move Channel System with countdown (same as logout, change character and quit), similar to gf. command: /move_channel number Files to edit char.cpp, char.h, cmd.cpp, cmd.h, cmd_general.cpp char.cpp char.h cmd.cpp cmd.h cmd_general.cpp CALCULATE YOUR PORTS HERE [Hidden Content]
  19. M2 Download Center Download Here ( Internal ) [Hidden Content]- You can think of it as the lite version. More features are likely to come in the future. + Mount Restrict + Start and Win Effects If you have a problem,
  20. M2 Download Center Download Here ( Internal ) [Hidden Content]
  21. M2 Download Center Download Here ( Internal ) Maybe somebody works. I actually shared it in a different community. I wanted to share it with my family even though it is now a dead community. Without forgetting, you can get a lot by following the links. [Hidden Content] EXTRA: EXTRA:
  22. M2 Download Center Download Here ( Internal )
  23. Download Metin2 Download or Mega Is made for this select character [Hidden Content]
  24. M2 Download Center Downlaod Here ( Internal ) Download Here ( GitHub ) Please dont flame me. @Mali61 push me to pubblish here. Video
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.