-
Posts
41 -
Joined
-
Last visited
-
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Valki
-
-
Amazing! I also think that if anyone really wants to upgrade the sound system they should look at fmod.
-
2 hours ago, Jettyx said:
Regarding what happened:
The information about the Zenaris leak is true. The version from the Beta phase was leaked approximately a month ago. However, it's important to note that the database remained secure and was not compromised.
I am no longer affiliated with the Zenaris Team. My contributions were primarily in the realms of graphic design, mapping, and environmental design. I worked for Graphics for 3 years. While some might not find it particularly impressive, the lack of resources regarding older DirectX9 and shader technologies posed significant challenges. A considerable amount of my time was dedicated to studying books and old documentation to overcome these obstacles.
As for the coding aspect:
The graphics of Zenaris are intentionally coded very bad/chaotic, like true is false sometimes, serving as my final safeguard. Only me and me knows what's inside and how the things are working. There are no defines. This complexity is the primary reason why no one has successfully implemented or extracted the graphics in the past month, except for two servers where I provided assistance. Additionally, even if someone were to understand the chaotic code from the leak, the graphics are plagued with numerous bugs, crashes, and other graphical issues, rendering them ineffective.In conclusion, I intend to continue my journey, focusing on updating and creating new graphics in service to others.
Furthermore, I am committed to assisting others with my current implementations.Sad to hear this and I really understand, when I talked with friends I even said maybe 3 years was mostly learning shaders and rendering in dx9, great to hear that it was really because of that, because the server itself doesnt provide anything new except your shaders and graphics. Also, glad to hear that the code is complex enough so we won't see 15 """"full hd metin""""", except if they open servers from the zenaris files itself.
-
1 hour ago, nmeyo said:
Ouch, looks like it’s real.
Sad, @Jettyx bafta unchiule, data viitoare cu contract semnat.
I don’t even want to think about working for 3 years on something to be set aside when payday comes. Disgusting.
@ SpeachlessWhere is he moving his work now? So i Know where to spend my money
Honestly? I don't know what was 3 years in it. As far as I know N2 was made in 5 years and if you look at it's source code it really looks like that. Looking at Zenaris's source and I only see the shader which is interesting in it, nothing else.
-
I’m more than glad that you’ll be our next administrator!
-
1 hour ago, Intel said:
If anyone is interested in some light reading: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list
Also this can be very helpful as well: https://www.learncpp.com/
EDIT: Almost forgot, The Cherno on YouTube:
Cherno is just amazing, I fully recommend his videos
- 1
- 2
-
Hello!
So I just noticed that if you want to join to the ship defense after the leader started AND the cooldown is enabled the other characters cannot connect (idk if it's fixed already or not, sorry if it is.) because the cooldown is put on the characters on creating the instance and when you're trying to join it's already on cooldown.
Here's a fix for it:
/// In ShipDefense.h add after: bool IsRunning(const LPCHARACTER c_lpChar); /// This: bool CanJoin(const LPCHARACTER c_lpChar); /// In ShipDefense.cpp add after: bool CShipDefenseManager::IsRunning(const LPCHARACTER c_lpChar) { [...] } /// This: bool CShipDefenseManager::CanJoin(const LPCHARACTER c_lpChar) { if (c_lpChar == nullptr) return false; const LPPARTY c_lpParty = c_lpChar->GetParty(); if (c_lpParty == nullptr) return false; if (m_mapShipDefense.empty()) return false; ShipDefenseMap::const_iterator f = m_mapShipDefense.find(c_lpParty->GetLeaderPID()); if (f != m_mapShipDefense.end()) return true; return false; } /// In questlua_shipdefense_mgr.cpp /// Add before: void RegisterShipDefenseManagerFunctionTable() { [...] } /// This: int ship_defense_mgr_can_join(lua_State* L) { const LPCHARACTER c_lpChar = CQuestManager::instance().GetCurrentCharacterPtr(); if (c_lpChar == nullptr) { lua_pushboolean(L, false); return 1; } CShipDefenseManager& rkShipDefenseMgr = CShipDefenseManager::instance(); lua_pushboolean(L, rkShipDefenseMgr.CanJoin(c_lpChar)); return 1; } /// Add after: { "set_alliance_hp_pct", ship_defense_mgr_set_alliance_hp_pct }, /// This: { "can_join", ship_defense_mgr_can_join},
-- In quest_functions add: ship_defense_mgr.can_join -- In shipdefense.quest change this: if pc.getqf("cooldown") > get_time() then -- To this: if pc.getqf("cooldown") > get_time() and not ship_defense_mgr.can_join() then
- 8
- 1
- 1
-
9 minutes ago, Powell said:
Should we install a swap system before ?
I don't think it's needed, iirc I had one, but I did not touch any of it's code.
- 1
-
Great work, good job!
- 1
-
2 hours ago, Gurgarath said:
Hello,
Thank you, but I guess the tutorial is incomplete, can you provide us with "CanUnequipNow" function please? Also, is it possible to have a small gif of what it does exactly?
Hi! Added what I forgot, also made a small video of what it actually does.
- 1
-
Hi!
Today I'm sharing small changes about changing equipments.
I experienced that in metin2 basically it can't replace for example a two handed weapon (which is equipped) with a simple sword if there's an item in the next row under our item that we want to equip.
Video of the result:
Small explanation:
So, if we want to make it work like we want we will need to check if basically it couldn't replace the inventory item with our equipped item then is there any space for that item, and if there is it can unequip it to that slot.
So, let's get to the work.
We will work in 2 files, char.h and char.cpp
- 63
- 1
- 10
- 2
- 16
-
Nice work!
- 1
- 1
-
If we're talking about the same thing, just add the needed header files in extern/include.
- 1
-
Search for:
#ifdef ENABLE_EMOJI_SYSTEM if (m_emojiVector.empty() == false) { for(auto& rEmo : m_emojiVector) { if (rEmo.pInstance) { rEmo.pInstance->SetPosition(fStanX + rEmo.x, (fStanY + 7.0) - (rEmo.pInstance->GetHeight() / 2)); rEmo.pInstance->Render(); } } } #endif
in GrpTextInstance.cpp's ::Render function and change it like that:
#ifdef ENABLE_EMOJI_SYSTEM if (m_emojiVector.empty() == false) { for(auto& rEmo : m_emojiVector) { if (rEmo.pInstance) { rEmo.pInstance->SetPosition(fStanX + rEmo.x, (fStanY + 7.0) - (rEmo.pInstance->GetHeight() / 2)); #if defined(__BL_CLIP_MASK__) if (pClipRect) rEmo.pInstance->Render(pClipRect); else rEmo.pInstance->Render(); #else rEmo.pInstance->Render(); #endif } } } #endif
- 1
- 1
- 1
-
Nice release!
- 1
-
Hello!
QuoteRecently I was facing with a problem that it would take too much time to replace all the locale string in the source code, so I wrote a program for this.
This program will read your file in ANSI, and will rewrite it (in a new folder) to ANSI, but will replace all the locale strings to the desired one.
For this I used "locale_string_vnum.txt" file from @ Owsap's LocaleString Builder, so if you already have custom locale strings then you should add it by yourself.
It replaces the basic locale strings in your source code to STRINGS, so if you using some number based identification for this in your source or something like that you need to make some changes in the program.
I tried to test it as much as I can, for me it works, but I recommend everyone (especially for those people who aren't using any version control like git or svn) to make a backup for your files and test it out well before you publish it if you have a currently running server.
I tested it with VirusTotal, it rated 1/59, but the source code is in the package so you can check it anytime.
In the rar there's a basic folder setup for your files (you will need to put the same files in the output/files folder too, and the program will rewrite those files), but you can change it anytime.
Links:
- 36
- 1
- 1
- 1
- 5
- 1
- 13
-
21 hours ago, Mafuyu said:
its already public. Dont know where it was but i have something like that already implemented month ago. i guess it was here on metin2dev
Well, I did not know that.
-
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; } } }
- 1
- 1
-
Welcome folks!
I brought you a small "system" (would call it modification instead), which will instantly pick up 45 (you can increase or decrease its size).
My goal was not to send packets each time we're trying to pick up items. I did not test it for hours, so I wouldn't recommend using it on a live server without proper tests.
So let's get started!
First, we will start on the client side, and there we will work in the UserInterface project.
Locale_inc.h:
SpoilerAdd: #define ENABLE_FAST_PICKUP
Packet.h:
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP HEADER_CG_ITEM_PICKUP_ALL = 32, #endif After: HEADER_CG_QUEST_CONFIRM = 31, Add: #ifdef ENABLE_FAST_PICKUP typedef struct command_item_pickup_all { BYTE header; DWORD vids[FAST_PICKUP_MAX_NUM]; } TPacketCGItemPickUpAll; #endif After: typedef struct command_item_pickup { BYTE header; DWORD vid; } TPacketCGItemPickUp;
PythonItem.h:
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP bool GetCloseItems(const TPixelPosition& c_rPixelPosition, std::vector<DWORD>* pdwItemIDs, DWORD dwDistance = 300); #endif After: bool GetCloseItem(const TPixelPosition & c_rPixelPosition, DWORD* pdwItemID, DWORD dwDistance=300);
PythonItem.cpp
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP bool CPythonItem::GetCloseItems(const TPixelPosition& c_rPixelPosition, std::vector<DWORD>* pdwItemIDs, DWORD dwDistance) { DWORD dwCloseItemDistance = 1000 * 1000; TGroundItemInstanceMap::iterator i; int counter = 0; pdwItemIDs->reserve(FAST_PICKUP_MAX_NUM); for (i = m_GroundItemInstanceMap.begin(); i != m_GroundItemInstanceMap.end(); ++i) { if (counter == FAST_PICKUP_MAX_NUM) return true; TGroundItemInstance* pInstance = i->second; DWORD dwxDistance = DWORD(c_rPixelPosition.x - pInstance->v3EndPosition.x); DWORD dwyDistance = DWORD(c_rPixelPosition.y - (-pInstance->v3EndPosition.y)); DWORD dwDistance = DWORD(dwxDistance * dwxDistance + dwyDistance * dwyDistance); if (dwDistance < dwCloseItemDistance) { pdwItemIDs->emplace_back(i->first); } counter++; } return true; } #endif After: bool CPythonItem::GetCloseMoney(const TPixelPosition & c_rPixelPosition, DWORD * pdwItemID, DWORD dwDistance) { [...] }
PythonNetworkStream.h
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP bool SendItemPickUpAllPacket(TPacketCGItemPickUpAll& pack); #endif After: bool SendItemPickUpPacket(DWORD vid);
PythonNetworkStreamPhaseGameItem.cpp
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP bool CPythonNetworkStream::SendItemPickUpAllPacket(TPacketCGItemPickUpAll& pack) { if (!__CanActMainInstance()) return true; if (!Send(sizeof(TPacketCGItemPickUpAll), &pack)) { Tracen("SendItemPickUpPacket Error"); return false; } return SendSequence(); } #endif After: bool CPythonNetworkStream::SendItemPickUpPacket(DWORD vid) { [...] }
PythonPlayerInput.cpp:
SpoilerModify void CPythonPlayer::PickCloseItem() like this: void CPythonPlayer::PickCloseItem() { CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); if (!pkInstMain) return; TPixelPosition kPPosMain; pkInstMain->NEW_GetPixelPosition(&kPPosMain); #ifndef ENABLE_FAST_PICKUP DWORD dwItemID; #endif CPythonItem& rkItem=CPythonItem::Instance(); #ifdef ENABLE_FAST_PICKUP std::vector<DWORD> itemIds; if (!rkItem.GetCloseItems(kPPosMain, &itemIds, __GetPickableDistance())) return; TPacketCGItemPickUpAll pack; pack.header = HEADER_CG_ITEM_PICKUP_ALL; memset(pack.vids, 0, sizeof(pack.vids)); for (int i = 0; i < itemIds.size(); i++) { if (!itemIds[i] || itemIds[i] == 0) continue; pack.vids[i] = itemIds[i]; } itemIds.clear(); #else if (!rkItem.GetCloseItem(kPPosMain, &dwItemID, __GetPickableDistance())) return; #endif #ifdef ENABLE_FAST_PICKUP CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance(); rkNetStream.SendItemPickUpAllPacket(pack); #else SendClickItemPacket(dwItemID); #endif }
StdAfx.h
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP FAST_PICKUP_MAX_NUM = 45, #endif After: PLAYER_NAME_MAX_LEN = 12,
And now the server side.
common/serivice.h or common/CommonDefines.h
SpoilerAdd: #define ENABLE_FAST_PICKUP
common/length.h
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP FAST_PICKUP_MAX_NUM = 45, #endif After: BELT_INVENTORY_SLOT_COUNT = BELT_INVENTORY_SLOT_WIDTH * BELT_INVENTORY_SLOT_HEIGHT,
packet.h
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP HEADER_CG_ITEM_PICKUP_ALL = 32, #endif After: HEADER_CG_QUEST_CONFIRM = 31, Add: #ifdef ENABLE_FAST_PICKUP typedef struct command_item_pickup_all { BYTE header; DWORD vids[FAST_PICKUP_MAX_NUM]; } TPacketCGItemPickupAll; #endif After: typedef struct command_item_pickup { BYTE header; DWORD vid; } TPacketCGItemPickup;
packet_info.cpp
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP Set(HEADER_CG_ITEM_PICKUP_ALL, sizeof(TPacketCGItemPickupAll), "ItemPickup", true); #endif After: Set(HEADER_CG_ITEM_PICKUP, sizeof(TPacketCGItemPickup), "ItemPickup", true);
input.h
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP void ItemPickupAll(LPCHARACTER ch, const char* data); #endif After: void ItemPickup(LPCHARACTER ch, const char * data);
input_main.cpp
SpoilerAdd: #ifdef ENABLE_FAST_PICKUP void CInputMain::ItemPickupAll(LPCHARACTER ch, const char* data) { struct command_item_pickup_all* pinfo = (struct command_item_pickup_all*)data; if (!ch) return; for (int i = 0; i < FAST_PICKUP_MAX_NUM; i++) { if (!ch->PickupItem(pinfo->vids[i])) return; } } #endif After: void CInputMain::ItemPickup(LPCHARACTER ch, const char * data) { struct command_item_pickup * pinfo = (struct command_item_pickup*) data; if (ch) ch->PickupItem(pinfo->vid); } Add: #ifdef ENABLE_FAST_PICKUP case HEADER_CG_ITEM_PICKUP_ALL: if (!ch->IsObserverMode()) ItemPickupAll(ch, c_pData); break; #endif After: case HEADER_CG_ITEM_PICKUP: if (!ch->IsObserverMode()) ItemPickup(ch, c_pData); break;
Good look with the system and please if there's any bug leave a comment so I can fix it.
Have a good day!
- 55
- 1
- 1
- 1
- 1
- 10
- 1
- 28
-
@ ASIKOO #honorablefordistraught
- 1
- 1
- 1
-
Hello everyone!
Today I saw a basic item system on metin2.download and I was wondering why not to make it with JSON.
There are better ways to do this, but it can be a great start to learn some JSON for people (also, it's my first work with JSON file(s))
Almost everything in the .rar, you just have to download and put the dependencies in the right folder, or if you change it don't forget to rewrite the AutoGiveItems.cpp's include.
Links:
Spoiler- 171
- 2
- 1
- 3
- 1
- 1
- 2
- 3
- 1
- 25
- 5
- 36
-
Thank you guys!
-
Is there any public style or something like that for this cms? Cuz some other private servers has the same design, just some recolor/logo change.
-
Hello! My problem is I'm trying to make a mount bonus system in source. I succesfully add the bonuses (via affect), when I login I'm getting the bonuses, but after a relog/teleport it doubles itself. Do you guys have any idea how could I fix this?
-
So, I guess I found it. It's just like the packets, you need matching number on server and on clientside for WEAR_NEW and ITEM_NEW (may called ITEM_TYPE_NEW in your client).
MSS32_6.5C SDK
in Programming & Scripts
Posted
You're 100% right, it's not necessary because miles is doing it's job more than perfectly. But I'd like to mention that if you want to go further than metin2 in the future (so if you're really interested in the programming part of it) it's better to know alternatives, other options too and if you can do it properly it also won't hurt since for example "FMOD" is also a great library to handle sounds in m2's source. But I'm really agreeing with you, because if you're not interested in these kind of stuffs then it's not necessary, even if other sound engines has better support than mss