Herkese merhabalar
.
Bugün sizlerle 5 envanter yapımını anlatacağım. Şimdi diyenler olacaktır. Konusu var ztn diye evet
Şimdi yazımı 4 envantere göre anlatacağım 2 envanter
Şimdi hemen konuya geçiyorum uzatmak istemeyiz. Sorun veya syser verirse konu altına yorum atın çözelim.
İlk öncelikle src klasörünüz içince ki common klasörü açılır ve içinden length.h bulunur ve açılır.
aratılır ve bulunur.
aşağıdaki ile değiştirilir.
sonra kaydedilip kapatılır.
Sonra game/src içindeki char_item.cpp açılır ve aratılır
aşağıdaki ile değiştirilir.
aynı klasör içinde tekrar aratılır
aşağıdaki ile değiştirilir
eğer bulamassanız ilk kodun hemen aşağı kısımlarında.
Sonra gene aynı klasör dizininde exchange.cpp açılır ve aratılır.
kodun altına eklenir hemen altına
yani son şekli şöyle olacak.
aynı dosya içinde tekrar aratılır.
altına eklenir hemen altına
son hali şöyle olacak
tekrar aynı dosya içinde aratıyoruz.
kod bloğunu aynı şu şekilde değiştiriyoruz
4 olan yerleri 5 olarak değiştirip sonuna 1 tane daha for döngüsü ekledik oda 5.envanter için.
Game işimiz bitti build edebiliriz.
Şimdi client e gelelim.
Client/Userinterface açılır ve içinden GameType.h bulunur aratılır.
aşağıda ki ile değiştirilir
Kaydedilip derlenir.
Pack kısmına gelicek olursak.
root/uiinventory.py açılır ve aratılır
aşağıda ki ile değiştirilir.
tekrar aratılır
altına aşağıda ki kod eklenir hemen altına
son hali şu şekilde olacak
root la işimiz bitti kaydedip atabilir sıra locale_tr de.
açılır
aratılır
aşağıdaki ile değiştirilir
Şimdi konu 2'ye ayrıldığı için saltanat tipi ve tr tipi olmak üzere 2 tane ayrı kod vereceğim için ayırdım aşağıdan istediğini seçin.
altındaki "height" değeri 607 yapılır yani son hali şöyle olacak
sonra gene aynı dosya içinden aratılır
altındaki "height" değeri 607 yapılır yani son hali şöyle olacak
tekrar aratılır
hemen altındaki y değeri 284 yapılır yani son hali şöyle olacak
sonra tekrar aratılır
kod bloğunun sonuna aşağıda ki eklenir
yani şöyle olacak
Packleyip locale_tr ve root u atın. 5 envanter hayırlı olsun
Kanıt:
Eğer ful py ye bakmak isterseniz buyrun.
altındaki "height" değeri 565 yapılır yani son hali şöyle olacak
sonra gene aynı dosya içinden aratılır
altındaki "height" değeri 565 yapılır yani son hali şöyle olacak
tekrar aratılır
hemen altındaki y değeri 246 yapılır yani son hali şöyle olacak
sonra tekrar aratılır
kod bloğunun sonuna eklenir
packleyip atabilirsiniz.
Kanıt:
Kanıt alıntıdır.
Eğer full py ye bakmak isterseniz buyrun
Bir teşekkür yeterlidir. Sağlıcakla kalın
.
Metin2 Özel Sunucu Geliştirme Serisi
Tr ve Saltanat tipi envanter yapımı, Metin2 özel sunucularında oyun deneyimini artırmak isteyen geliştiriciler için önemli bir konudur. Bu yazıda C++, Python ve Client tarafında nasıl gelişmiş envanter sistemleri kurulacağını adım adım ele alacağız. Bu sistemler sayesinde oyuncular hem savaş hem de günlük aktiviteler için farklı envanter alanlarına sahip olabilirler. Bu da PvP odaklı sunucularda stratejik bir üstünlük sağlar.
Tr ve Saltanat Envanter Sistemleri Nedir?
Tr ve Saltanat sistemleri, Metin2 özel sunucularında yaygın olarak kullanılan iki farklı envanter türüdür. Bu envanterler, oyuncuların farklı ekipman setlerini hızlıca değiştirmesine olanak tanır. Özellikle savaş esnasında zırh, silah ve aksesuar değişimi çok önemlidir. Bu sistemler sayesinde oyuncular, bir savaşta Tr zırhı giyerken diğerinde Saltanat zırhı giyebilirler. Bu da hem PvP hem de PvE oyun tarzını çeşitlendirir.
Geliştirme Ortamı Hazırlığı
Bu sistemleri kurabilmek için öncelikle Metin2 client, game server ve auth server kaynak kodlarına erişiminiz olması gerekir. Bu kaynak kodlar genellikle C++ ile yazılmıştır. Ayrıca Python kullanılarak UI Script (uiscript) dosyaları ile client tarafında arayüz geliştirebilirsiniz. Py Root ve UI Script bilgisi bu aşamada kritik öneme sahiptir. Paketleme ve derleme işlemleri için compile bilgisi de gereklidir.
Client Tarafında Envanter Arayüzü Oluşturma
Client tarafında envanter ekranını genişletmek için UI Script dosyalarında değişiklik yapılmalıdır. Python GUI kullanarak yeni bir pencere tasarımı yapılabileceği gibi, mevcut envanter ekranına butonlar ekleyerek farklı envanterlere geçiş sağlanabilir. Örneğin 'Tr Envanter', 'Saltanat Envanter' gibi butonlar eklenir. Bu butonlara tıklandığında ilgili envanter verileri serverdan çekilir ve ekrana yansıtılır. Bu işlem sırasında Py GUI bilgisi büyük kolaylık sağlar.
Game Server Tarafında Veri Yönetimi
Game server tarafında, her oyuncunun birden fazla envanteri saklanmalıdır. Bu veriler genellikle DB Core üzerinden MySQL veya MSSQL tabanlı veritabanlarında tutulur. Oyuncu profiline ekstra alanlar (örneğin tr_inventory, saltanat_inventory) eklenmelidir. Bu alanlarda envanterdeki eşyaların ID, miktar, özellikler gibi bilgileri saklanır. Bu verileri yönetmek için C++ script geliştirme bilgisi çok önemlidir. Martysama ve benzeri kaynaklar bu konuda rehber alınabilir.
Auth Server ile Eşgüdüm
Auth server, oyuncu giriş çıkışlarını yönetir. Bu sistemde envanter verilerinin doğru şekilde aktarılması için auth-server ile game-server arasında senkronizasyon sağlanmalıdır. Bu işlem genellikle socket bağlantısı ile yapılır. Auth server tarafında da kullanıcıya özel envanter ayarları saklanabilir. Bu sayede oyuncu farklı sunucularda oturum açtığında bile envanteri korunur.
Python GUI ile Hızlı Geçiş Fonksiyonu
Python ile yazılmış GUI sayesinde kullanıcı dostu bir geçiş sistemi geliştirilebilir. Butonlara tıklanması ile farklı envanterlere hızlıca geçilebilir. Bu geçişler sırasında client-server arasında veri alışverişi yapılır. Bu işlemde Py Root dosyaları ile servera istek atılır ve gerekli veriler geri alınır. Bu sayede oyuncu saniyeler içinde envanter değiştirme imkanına sahip olur.
Sistem Testi ve Hata Ayıklama
Sistemi canlıya almadan önce test sunucusunda tüm fonksiyonların çalışıp çalışmadığı kontrol edilmelidir. Oyuncu verilerinin eksiksiz ve güvenli şekilde saklandığından emin olunmalıdır. DB Core üzerinde veri kaybı yaşanmaması için yedekleme süreçleri de planlanmalıdır. Hata ayıklama sırasında loglama sistemleri devreye girer ve her işlem detaylı şekilde takip edilir.
Sonuç
Tr ve Saltanat tipi envanter sistemleri, Metin2 özel sunucularında oyun deneyimini ciddi anlamda artırır. Bu sistemlerin geliştirilmesi için C++, Python ve client tarafında derinlemesine bilgi sahibi olmak gerekir. Ancak doğru yapılandırıldığında, oyuncular için stratejik bir avantaj sunar. Bu sistemler, hem PvP hem de PvE içerikte kullanıcının daha rahat hareket etmesini sağlar.
Metin2 Private Server Development Series
Creating Tr and Sultan inventory systems is an important topic for developers looking to enhance the gaming experience on Metin2 private servers. In this article, we will explain step by step how to build advanced inventory systems on the C++, Python, and Client sides. Thanks to these systems, players can have different inventory slots for both combat and daily activities. This provides strategic advantages especially in PvP-oriented servers.
What are Tr and Sultan Inventory Systems?
Tr and Sultan systems are two distinct types of inventories widely used in Metin2 private servers. These inventories allow players to quickly switch between different equipment sets. Especially during battles, changing armor, weapons, and accessories is crucial. With these systems, players can wear Tr armor during one battle and Sultan armor during another. This diversifies both PvP and PvE gameplay styles.
Preparation of the Development Environment
To implement these systems, you first need access to the source codes of Metin2 client, game server, and auth server. These source codes are generally written in C++. Additionally, with Python, you can develop UIs using UI Script files. Knowledge of Py Root and UI Script is critical at this stage. Compilation knowledge is also required for packaging and building processes.
Creating Inventory Interface on Client Side
To expand the inventory screen on the client side, modifications must be made in the UI Script files. A new window design can be created using Python GUI, or buttons can be added to the existing inventory screen to switch between different inventories. For example, buttons such as 'Tr Inventory' and 'Sultan Inventory' can be added. When clicked, the corresponding inventory data is retrieved from the server and displayed on screen. At this point, Py GUI knowledge provides great convenience.
Data Management on Game Server Side
On the game server side, each player’s multiple inventories must be stored. These data are usually kept in MySQL or MSSQL-based databases via DB Core. Extra fields (e.g., tr_inventory, sultanat_inventory) should be added to the player profile. The ID, quantity, properties, etc. of items in the inventory are stored in these fields. Knowledge of C++ scripting is very important for managing this data. Sources like Martysama can serve as guides in this regard.
Coordination with Auth Server
The auth server manages player login and logout processes. To ensure inventory data is transferred correctly, synchronization must be established between the auth-server and the game-server. This process is typically done via socket connection. Special inventory settings for users can also be stored on the auth server side. This way, even if the player logs in on different servers, their inventory remains preserved.
Quick Switch Function with Python GUI
With a user-friendly GUI written in Python, a smooth switching system can be developed. By clicking the buttons, players can quickly switch to different inventories. During these transitions, data exchange occurs between the client and server. Requests are sent to the server using Py Root files, and necessary data is retrieved back. This way, the player gains the ability to switch inventories within seconds.
System Testing and Debugging
Before going live, all functions should be tested on a test server to ensure they work properly. It must be ensured that player data is stored completely and securely. Backup processes should also be planned to avoid data loss in the DB Core. During debugging, logging systems come into play and every action is monitored in detail.
Conclusion
Tr and Sultan-type inventory systems significantly enhance the gaming experience in Metin2 private servers. Developing these systems requires in-depth knowledge of C++, Python, and the client side. However, when configured correctly, they provide strategic advantages for players. These systems enable smoother movement for users in both PvP and PvE content.
Bugün sizlerle 5 envanter yapımını anlatacağım. Şimdi diyenler olacaktır. Konusu var ztn diye evet
Ziyaretçiler için gizlenmiş link,görmek için üye olmalısınız!
Giriş yap veya üye ol.
konu var fakat kilitlenmiş ve düzgün çalışmamaktadır kod eksikliği vardır.Şimdi yazımı 4 envantere göre anlatacağım 2 envanter
Ziyaretçiler için gizlenmiş link,görmek için üye olmalısınız!
Giriş yap veya üye ol.
kaldımı hala düşünmekteyim :confused2:.Şimdi hemen konuya geçiyorum uzatmak istemeyiz. Sorun veya syser verirse konu altına yorum atın çözelim.
İlk öncelikle src klasörünüz içince ki common klasörü açılır ve içinden length.h bulunur ve açılır.
Kod:
INVENTORY_MAX_NUM = 180,
aratılır ve bulunur.
aşağıdaki ile değiştirilir.
Kod:
INVENTORY_MAX_NUM = 225,
sonra kaydedilip kapatılır.
Sonra game/src içindeki char_item.cpp açılır ve aratılır
Kod:
BYTE bPage = bCell / (INVENTORY_MAX_NUM / 4);
aşağıdaki ile değiştirilir.
Kod:
BYTE bPage = bCell / (INVENTORY_MAX_NUM / 5);
aynı klasör içinde tekrar aratılır
Kod:
if (p / (INVENTORY_MAX_NUM / 4) != bPage)
aşağıdaki ile değiştirilir
Kod:
if (p / (INVENTORY_MAX_NUM / 5) != bPage)
eğer bulamassanız ilk kodun hemen aşağı kısımlarında.
Sonra gene aynı klasör dizininde exchange.cpp açılır ve aratılır.
Kod:
static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 2); // inven page 4
kodun altına eklenir hemen altına
Kod:
static CGrid s_grid5(5, INVENTORY_MAX_NUM/5 / 2); // inven page 5
yani son şekli şöyle olacak.
Kod:
static CGrid s_grid1(5, INVENTORY_MAX_NUM/5 / 2); // inven page 1 static CGrid s_grid2(5, INVENTORY_MAX_NUM/5 / 2); // inven page 2 static CGrid s_grid3(5, INVENTORY_MAX_NUM/5 / 2); // inven page 3 static CGrid s_grid4(5, INVENTORY_MAX_NUM/5 / 2); // inven page 4 static CGrid s_grid5(5, INVENTORY_MAX_NUM/5 / 2); // inven page 5
aynı dosya içinde tekrar aratılır.
Kod:
s_grid4.Clear();
altına eklenir hemen altına
Kod:
s_grid5.Clear();
son hali şöyle olacak
Kod:
s_grid1.Clear(); s_grid2.Clear(); s_grid3.Clear(); s_grid4.Clear(); s_grid5.Clear();
tekrar aynı dosya içinde aratıyoruz.
Kod:
for (i = 0; i < INVENTORY_MAX_NUM / 4; ++i)
kod bloğunu aynı şu şekilde değiştiriyoruz
Kod:
for (i = 0; i < INVENTORY_MAX_NUM / 5; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid1.Put(i, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 5; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid2.Put(i - INVENTORY_MAX_NUM / 5, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 5; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid3.Put(i - INVENTORY_MAX_NUM / 5, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 5; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid4.Put(i - INVENTORY_MAX_NUM / 5, 1, item->GetSize()); } for (i = INVENTORY_MAX_NUM / 5; i < INVENTORY_MAX_NUM; ++i) { if (!(item = victim->GetInventoryItem(i))) continue; s_grid5.Put(i - INVENTORY_MAX_NUM / 5, 1, item->GetSize()); }
4 olan yerleri 5 olarak değiştirip sonuna 1 tane daha for döngüsü ekledik oda 5.envanter için.
Game işimiz bitti build edebiliriz.
Şimdi client e gelelim.
Client/Userinterface açılır ve içinden GameType.h bulunur aratılır.
Kod:
const DWORD c_Inventory_Page_Count = 4;
aşağıda ki ile değiştirilir
Kod:
const DWORD c_Inventory_Page_Count = 5;
Kaydedilip derlenir.
Pack kısmına gelicek olursak.
root/uiinventory.py açılır ve aratılır
Kod:
self.inventoryTab.append(self.GetChild("Inventory_Tab_04"))
aşağıda ki ile değiştirilir.
Kod:
self.inventoryTab.append(self.GetChild("Inventory_Tab_05"))
tekrar aratılır
Kod:
self.inventoryTab[3].SetEvent(lambda arg=3: self.SetInventoryPage(arg))
altına aşağıda ki kod eklenir hemen altına
Kod:
self.inventoryTab[4].SetEvent(lambda arg=4: self.SetInventoryPage(arg))
son hali şu şekilde olacak
Kod:
self.inventoryTab[0].SetEvent(lambda arg=0: self.SetInventoryPage(arg)) self.inventoryTab[1].SetEvent(lambda arg=1: self.SetInventoryPage(arg)) self.inventoryTab[2].SetEvent(lambda arg=2: self.SetInventoryPage(arg)) self.inventoryTab[3].SetEvent(lambda arg=3: self.SetInventoryPage(arg)) self.inventoryTab[4].SetEvent(lambda arg=4: self.SetInventoryPage(arg)) self.inventoryPageIndex = 0
root la işimiz bitti kaydedip atabilir sıra locale_tr de.
Kod:
locale_tr\locale\tr\ui\inventorywindow.py
aratılır
Kod:
EQUIPMENT_START_INDEX = 180
aşağıdaki ile değiştirilir
Kod:
EQUIPMENT_START_INDEX = 225
Şimdi konu 2'ye ayrıldığı için saltanat tipi ve tr tipi olmak üzere 2 tane ayrı kod vereceğim için ayırdım aşağıdan istediğini seçin.
Kod:
"name" : "InventoryWindow",
altındaki "height" değeri 607 yapılır yani son hali şöyle olacak
Kod:
"name" : "InventoryWindow", "x" : SCREEN_WIDTH - 176, "y" : SCREEN_HEIGHT - 37 - 565 -21, "style" : ("movable", "float",), "width" : 176, "height" : 607,
sonra gene aynı dosya içinden aratılır
Kod:
## Inventory, Equipment Slots
altındaki "height" değeri 607 yapılır yani son hali şöyle olacak
Kod:
## Inventory, Equipment Slots { "name" : "board", "type" : "board", "style" : ("attach",), "x" : 0, "y" : 0, "width" : 176, "height" : 607,
tekrar aratılır
Kod:
"name" : "ItemSlot",
hemen altındaki y değeri 284 yapılır yani son hali şöyle olacak
Kod:
"name" : "ItemSlot", "type" : "grid_table", "x" : 8, "y" : 284,
sonra tekrar aratılır
Kod:
"name" : "Inventory_Tab_04_Print",
kod bloğunun sonuna aşağıda ki eklenir
Kod:
{ "name" : "Inventory_Tab_05", "type" : "radio_button", "x" : 10 + 44, "y" : 33 + 231, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_5, "children" : ( { "name" : "Inventory_Tab_05_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "V", }, ), },
yani şöyle olacak
Kod:
"name" : "Inventory_Tab_04_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "IV", }, ), }, { "name" : "Inventory_Tab_05", "type" : "radio_button", "x" : 10 + 44, "y" : 33 + 231, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_5, "children" : ( { "name" : "Inventory_Tab_05_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "V", }, ), },
Packleyip locale_tr ve root u atın. 5 envanter hayırlı olsun
Kanıt:
Eğer ful py ye bakmak isterseniz buyrun.
Kod:
import uiScriptLocale import item import gameInfo EQUIPMENT_START_INDEX = 225 window = { "name" : "InventoryWindow", "x" : SCREEN_WIDTH - 176, "y" : SCREEN_HEIGHT - 37 - 565 -21, "style" : ("movable", "float",), "width" : 176, "height" : 607, "children" : ( ## Inventory, Equipment Slots { "name" : "board", "type" : "board", "style" : ("attach",), "x" : 0, "y" : 0, "width" : 176, "height" : 607, "children" : ( ## Title { "name" : "TitleBar", "type" : "titlebar", "style" : ("attach",), "x" : 8, "y" : 7, "width" : 161, "color" : "yellow", "children" : ( { "name":"TitleName", "type":"text", "x":77, "y":3, "text":uiScriptLocale.INVENTORY_TITLE, "text_horizontal_align":"center" }, ), }, ## Equipment Slot { "name" : "Equipment_Base", "type" : "image", "x" : 10, "y" : 33, "image" : "d:/ymir work/ui/equipment_bg_without_ring.tga", "children" : ( { "name" : "EquipmentSlot", "type" : "slot", "x" : 3, "y" : 3, "width" : 150, "height" : 182, "slot" : ( {"index":EQUIPMENT_START_INDEX+0, "x":39, "y":37, "width":32, "height":64}, {"index":EQUIPMENT_START_INDEX+1, "x":39, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+2, "x":39, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+3, "x":75, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+4, "x":3, "y":3, "width":32, "height":96}, {"index":EQUIPMENT_START_INDEX+5, "x":114, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+6, "x":114, "y":35, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+7, "x":2, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+8, "x":75, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+9, "x":114, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+10, "x":75, "y":35, "width":32, "height":32}, ## 새 반지1 ##{"index":item.EQUIPMENT_RING1, "x":2, "y":106, "width":32, "height":32}, ## 새 반지2 ##{"index":item.EQUIPMENT_RING2, "x":75, "y":106, "width":32, "height":32}, ## 새 벨트 {"index":item.EQUIPMENT_BELT, "x":39, "y":106, "width":32, "height":32}, ), }, ## Dragon Soul Button { "name" : "PaketButton", "type" : "button", "x" : 114, "y" : 107, "tooltip_text" : "Paket Sistemi", "default_image" : "d:/ymir work/ui/6094.tga", "over_image" : "d:/ymir work/ui/6095.tga", "down_image" : "d:/ymir work/ui/6094.tga", }, ## MallButton { "name" : "MallButton", "type" : "button", "x" : 118, "y" : 148, "tooltip_text" : uiScriptLocale.MALL_TITLE, "default_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_01.tga", "over_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_02.tga", "down_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_03.tga", }, ## CostumeButton { "name" : "CostumeButton", "type" : "button", "x" : 78, "y" : 5, "tooltip_text" : uiScriptLocale.COSTUME_TITLE, "default_image" : "d:/ymir work/ui/game/taskbar/costume_Button_01.tga", "over_image" : "d:/ymir work/ui/game/taskbar/costume_Button_02.tga", "down_image" : "d:/ymir work/ui/game/taskbar/costume_Button_03.tga", }, { "name" : "Equipment_Tab_01", "type" : "radio_button", "x" : 86, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Equipment_Tab_02", "type" : "radio_button", "x" : 86 + 32, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, ), }, { "name" : "Inventory_Tab_01", "type" : "radio_button", "x" : 10, "y" : 33 + 189, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_1, "children" : ( { "name" : "Inventory_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Inventory_Tab_02", "type" : "radio_button", "x" : 10 + 78, "y" : 33 + 189, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_2, "children" : ( { "name" : "Inventory_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, { "name" : "Inventory_Tab_03", "type" : "radio_button", "x" : 10, "y" : 33 + 210, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_3, "children" : ( { "name" : "Inventory_Tab_03_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "III", }, ), }, { "name" : "Inventory_Tab_04", "type" : "radio_button", "x" : 10 + 78, "y" : 33 + 210, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_4, "children" : ( { "name" : "Inventory_Tab_04_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "IV", }, ), }, { "name" : "Inventory_Tab_05", "type" : "radio_button", "x" : 10 + 44, "y" : 33 + 231, "default_image" : "d:/ymir work/ui/game/windows/tab_button_large_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_large_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_large_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_5, "children" : ( { "name" : "Inventory_Tab_05_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "V", }, ), }, ## Item Slot { "name" : "ItemSlot", "type" : "grid_table", "x" : 8, "y" : 284, "start_index" : 0, "x_count" : 5, "y_count" : 9, "x_step" : 32, "y_step" : 32, "image" : "d:/ymir work/ui/public/Slot_Base.sub" }, { "name" : "Kilit_Slot", "type" : "grid_table", "x" : 87, "y" : 142, "start_index" : 0, "x_count" : 1, "y_count" : 1, "x_step" : 34, "y_step" : 32, "image" : str(gameInfo.CONFIG_YOL)+"kilit_slot.tga", "tooltip_text" : "?em Kilitle", }, ## Print { "name":"Money_Slot", "type":"button", "x":8, "y":28, "horizontal_align":"center", "vertical_align":"bottom", "default_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "over_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "down_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "children" : ( { "name":"Money_Icon", "type":"image", "x":-18, "y":2, "image":"d:/ymir work/ui/game/windows/money_icon.sub", }, { "name" : "Money", "type" : "text", "x" : 3, "y" : 3, "horizontal_align" : "right", "text_horizontal_align" : "right", "text" : "123456789", }, ), }, ), }, ), }
Kod:
## Inventory, Equipment Slots
altındaki "height" değeri 565 yapılır yani son hali şöyle olacak
Kod:
"name" : "InventoryWindow", "x" : SCREEN_WIDTH - 176, "y" : SCREEN_HEIGHT - 37 - 565, "style" : ("movable", "float",), "width" : 176, "height" : 565,
sonra gene aynı dosya içinden aratılır
Kod:
## Inventory, Equipment Slots
altındaki "height" değeri 565 yapılır yani son hali şöyle olacak
Kod:
## Inventory, Equipment Slots { "name" : "board", "type" : "board", "style" : ("attach",), "x" : 0, "y" : 0, "width" : 176, "height" : 565,
tekrar aratılır
Kod:
"name" : "ItemSlot",
hemen altındaki y değeri 246 yapılır yani son hali şöyle olacak
Kod:
"name" : "ItemSlot", "type" : "grid_table", "x" : 8, "y" : 246,
sonra tekrar aratılır
Kod:
"name" : "Inventory_Tab_04_Print",
kod bloğunun sonuna eklenir
Kod:
{ "name" : "Inventory_Tab_05", "type" : "radio_button", "x" : 7 + 32*4, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_5, "children" : ( { "name" : "Inventory_Tab_05_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "V", }, ), },
packleyip atabilirsiniz.
Kanıt:
Kanıt alıntıdır.
Eğer full py ye bakmak isterseniz buyrun
Kod:
import uiScriptLocale import item EQUIPMENT_START_INDEX = 225 window = { "name" : "InventoryWindow", ## 600 - (width + 오른쪽으로 부터 띄우기 24 px) "x" : SCREEN_WIDTH - 176, "y" : SCREEN_HEIGHT - 37 - 565, "style" : ("movable", "float",), "width" : 176, "height" : 565, "children" : ( ## Inventory, Equipment Slots { "name" : "board", "type" : "board", "style" : ("attach",), "x" : 0, "y" : 0, "width" : 176, "height" : 565, "children" : ( ## Title { "name" : "TitleBar", "type" : "titlebar", "style" : ("attach",), "x" : 8, "y" : 7, "width" : 161, "color" : "yellow", "children" : ( { "name":"TitleName", "type":"text", "x":77, "y":3, "text":uiScriptLocale.INVENTORY_TITLE, "text_horizontal_align":"center" }, ), }, ## Equipment Slot { "name" : "Equipment_Base", "type" : "image", "x" : 10, "y" : 33, "image" : "d:/ymir work/ui/equipment_bg_without_ring.tga", "image" : "d:/ymir work/ui/equipment_bg_with_ring.tga", "children" : ( { "name" : "EquipmentSlot", "type" : "slot", "x" : 3, "y" : 3, "width" : 150, "height" : 182, "slot" : ( {"index":EQUIPMENT_START_INDEX+0, "x":39, "y":37, "width":32, "height":64}, {"index":EQUIPMENT_START_INDEX+1, "x":39, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+2, "x":39, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+3, "x":75, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+4, "x":3, "y":3, "width":32, "height":96}, {"index":EQUIPMENT_START_INDEX+5, "x":114, "y":67, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+6, "x":114, "y":35, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+7, "x":2, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+8, "x":75, "y":145, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+9, "x":114, "y":2, "width":32, "height":32}, {"index":EQUIPMENT_START_INDEX+10, "x":75, "y":35, "width":32, "height":32}, ## 새 반지1 ##{"index":item.EQUIPMENT_RING1, "x":2, "y":106, "width":32, "height":32}, ## 새 반지2 ##{"index":item.EQUIPMENT_RING2, "x":75, "y":106, "width":32, "height":32}, ## 새 벨트 {"index":item.EQUIPMENT_BELT, "x":39, "y":106, "width":32, "height":32}, ), }, ## Dragon Soul Button { "name" : "DSSButton", "type" : "button", "x" : 114, "y" : 107, "tooltip_text" : uiScriptLocale.TASKBAR_DRAGON_SOUL, "default_image" : "d:/ymir work/ui/dragonsoul/cakmavector.tga", "over_image" : "d:/ymir work/ui/dragonsoul/cakmavector.tga", "down_image" : "d:/ymir work/ui/dragonsoul/cakmavector.tga", }, ## MallButton { "name" : "MallButton", "type" : "button", "x" : 118, "y" : 148, "tooltip_text" : uiScriptLocale.MALL_TITLE, "default_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_01.tga", "over_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_02.tga", "down_image" : "d:/ymir work/ui/game/TaskBar/Mall_Button_03.tga", }, ## CostumeButton { "name" : "CostumeButton", "type" : "button", "x" : 78, "y" : 5, "tooltip_text" : uiScriptLocale.COSTUME_TITLE, "default_image" : "d:/ymir work/ui/game/taskbar/costume_Button_01.tga", "over_image" : "d:/ymir work/ui/game/taskbar/costume_Button_02.tga", "down_image" : "d:/ymir work/ui/game/taskbar/costume_Button_03.tga", }, { "name" : "Equipment_Tab_01", "type" : "radio_button", "x" : 86, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Equipment_Tab_02", "type" : "radio_button", "x" : 86 + 32, "y" : 161, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "children" : ( { "name" : "Equipment_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, ), }, { "name" : "Inventory_Tab_01", "type" : "radio_button", "x" : 7, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_1, "children" : ( { "name" : "Inventory_Tab_01_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "I", }, ), }, { "name" : "Inventory_Tab_02", "type" : "radio_button", "x" : 7 + 32, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_2, "children" : ( { "name" : "Inventory_Tab_02_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "II", }, ), }, { "name" : "Inventory_Tab_03", "type" : "radio_button", "x" : 7 + 32*2, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_3, "children" : ( { "name" : "Inventory_Tab_03_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "III", }, ), }, { "name" : "Inventory_Tab_04", "type" : "radio_button", "x" : 7 + 32*3, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_4, "children" : ( { "name" : "Inventory_Tab_04_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "IV", }, ), }, { "name" : "Inventory_Tab_05", "type" : "radio_button", "x" : 7 + 32*4, "y" : 33 + 191, "default_image" : "d:/ymir work/ui/game/windows/tab_button_small_01.sub", "over_image" : "d:/ymir work/ui/game/windows/tab_button_small_02.sub", "down_image" : "d:/ymir work/ui/game/windows/tab_button_small_03.sub", "tooltip_text" : uiScriptLocale.INVENTORY_PAGE_BUTTON_TOOLTIP_5, "children" : ( { "name" : "Inventory_Tab_05_Print", "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : "V", }, ), }, ## Item Slot { "name" : "ItemSlot", "type" : "grid_table", "x" : 8, "y" : 246, "start_index" : 0, "x_count" : 5, "y_count" : 9, "x_step" : 32, "y_step" : 32, "image" : "d:/ymir work/ui/public/Slot_Base.sub" }, ## Print { "name":"Money_Slot", "type":"button", "x":8, "y":28, "horizontal_align":"center", "vertical_align":"bottom", "default_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "over_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "down_image" : "d:/ymir work/ui/public/parameter_slot_05.sub", "children" : ( { "name":"Money_Icon", "type":"image", "x":-18, "y":2, "image":"d:/ymir work/ui/game/windows/money_icon.sub", }, { "name" : "Money", "type" : "text", "x" : 3, "y" : 3, "horizontal_align" : "right", "text_horizontal_align" : "right", "text" : "123456789", }, ), }, ), }, ), }
Bir teşekkür yeterlidir. Sağlıcakla kalın
Metin2 Özel Sunucu Geliştirme Serisi
Tr ve Saltanat tipi envanter yapımı, Metin2 özel sunucularında oyun deneyimini artırmak isteyen geliştiriciler için önemli bir konudur. Bu yazıda C++, Python ve Client tarafında nasıl gelişmiş envanter sistemleri kurulacağını adım adım ele alacağız. Bu sistemler sayesinde oyuncular hem savaş hem de günlük aktiviteler için farklı envanter alanlarına sahip olabilirler. Bu da PvP odaklı sunucularda stratejik bir üstünlük sağlar.
Tr ve Saltanat Envanter Sistemleri Nedir?
Tr ve Saltanat sistemleri, Metin2 özel sunucularında yaygın olarak kullanılan iki farklı envanter türüdür. Bu envanterler, oyuncuların farklı ekipman setlerini hızlıca değiştirmesine olanak tanır. Özellikle savaş esnasında zırh, silah ve aksesuar değişimi çok önemlidir. Bu sistemler sayesinde oyuncular, bir savaşta Tr zırhı giyerken diğerinde Saltanat zırhı giyebilirler. Bu da hem PvP hem de PvE oyun tarzını çeşitlendirir.
Geliştirme Ortamı Hazırlığı
Bu sistemleri kurabilmek için öncelikle Metin2 client, game server ve auth server kaynak kodlarına erişiminiz olması gerekir. Bu kaynak kodlar genellikle C++ ile yazılmıştır. Ayrıca Python kullanılarak UI Script (uiscript) dosyaları ile client tarafında arayüz geliştirebilirsiniz. Py Root ve UI Script bilgisi bu aşamada kritik öneme sahiptir. Paketleme ve derleme işlemleri için compile bilgisi de gereklidir.
Client Tarafında Envanter Arayüzü Oluşturma
Client tarafında envanter ekranını genişletmek için UI Script dosyalarında değişiklik yapılmalıdır. Python GUI kullanarak yeni bir pencere tasarımı yapılabileceği gibi, mevcut envanter ekranına butonlar ekleyerek farklı envanterlere geçiş sağlanabilir. Örneğin 'Tr Envanter', 'Saltanat Envanter' gibi butonlar eklenir. Bu butonlara tıklandığında ilgili envanter verileri serverdan çekilir ve ekrana yansıtılır. Bu işlem sırasında Py GUI bilgisi büyük kolaylık sağlar.
Game Server Tarafında Veri Yönetimi
Game server tarafında, her oyuncunun birden fazla envanteri saklanmalıdır. Bu veriler genellikle DB Core üzerinden MySQL veya MSSQL tabanlı veritabanlarında tutulur. Oyuncu profiline ekstra alanlar (örneğin tr_inventory, saltanat_inventory) eklenmelidir. Bu alanlarda envanterdeki eşyaların ID, miktar, özellikler gibi bilgileri saklanır. Bu verileri yönetmek için C++ script geliştirme bilgisi çok önemlidir. Martysama ve benzeri kaynaklar bu konuda rehber alınabilir.
Auth Server ile Eşgüdüm
Auth server, oyuncu giriş çıkışlarını yönetir. Bu sistemde envanter verilerinin doğru şekilde aktarılması için auth-server ile game-server arasında senkronizasyon sağlanmalıdır. Bu işlem genellikle socket bağlantısı ile yapılır. Auth server tarafında da kullanıcıya özel envanter ayarları saklanabilir. Bu sayede oyuncu farklı sunucularda oturum açtığında bile envanteri korunur.
Python GUI ile Hızlı Geçiş Fonksiyonu
Python ile yazılmış GUI sayesinde kullanıcı dostu bir geçiş sistemi geliştirilebilir. Butonlara tıklanması ile farklı envanterlere hızlıca geçilebilir. Bu geçişler sırasında client-server arasında veri alışverişi yapılır. Bu işlemde Py Root dosyaları ile servera istek atılır ve gerekli veriler geri alınır. Bu sayede oyuncu saniyeler içinde envanter değiştirme imkanına sahip olur.
Sistem Testi ve Hata Ayıklama
Sistemi canlıya almadan önce test sunucusunda tüm fonksiyonların çalışıp çalışmadığı kontrol edilmelidir. Oyuncu verilerinin eksiksiz ve güvenli şekilde saklandığından emin olunmalıdır. DB Core üzerinde veri kaybı yaşanmaması için yedekleme süreçleri de planlanmalıdır. Hata ayıklama sırasında loglama sistemleri devreye girer ve her işlem detaylı şekilde takip edilir.
Sonuç
Tr ve Saltanat tipi envanter sistemleri, Metin2 özel sunucularında oyun deneyimini ciddi anlamda artırır. Bu sistemlerin geliştirilmesi için C++, Python ve client tarafında derinlemesine bilgi sahibi olmak gerekir. Ancak doğru yapılandırıldığında, oyuncular için stratejik bir avantaj sunar. Bu sistemler, hem PvP hem de PvE içerikte kullanıcının daha rahat hareket etmesini sağlar.
Metin2 Private Server Development Series
Creating Tr and Sultan inventory systems is an important topic for developers looking to enhance the gaming experience on Metin2 private servers. In this article, we will explain step by step how to build advanced inventory systems on the C++, Python, and Client sides. Thanks to these systems, players can have different inventory slots for both combat and daily activities. This provides strategic advantages especially in PvP-oriented servers.
What are Tr and Sultan Inventory Systems?
Tr and Sultan systems are two distinct types of inventories widely used in Metin2 private servers. These inventories allow players to quickly switch between different equipment sets. Especially during battles, changing armor, weapons, and accessories is crucial. With these systems, players can wear Tr armor during one battle and Sultan armor during another. This diversifies both PvP and PvE gameplay styles.
Preparation of the Development Environment
To implement these systems, you first need access to the source codes of Metin2 client, game server, and auth server. These source codes are generally written in C++. Additionally, with Python, you can develop UIs using UI Script files. Knowledge of Py Root and UI Script is critical at this stage. Compilation knowledge is also required for packaging and building processes.
Creating Inventory Interface on Client Side
To expand the inventory screen on the client side, modifications must be made in the UI Script files. A new window design can be created using Python GUI, or buttons can be added to the existing inventory screen to switch between different inventories. For example, buttons such as 'Tr Inventory' and 'Sultan Inventory' can be added. When clicked, the corresponding inventory data is retrieved from the server and displayed on screen. At this point, Py GUI knowledge provides great convenience.
Data Management on Game Server Side
On the game server side, each player’s multiple inventories must be stored. These data are usually kept in MySQL or MSSQL-based databases via DB Core. Extra fields (e.g., tr_inventory, sultanat_inventory) should be added to the player profile. The ID, quantity, properties, etc. of items in the inventory are stored in these fields. Knowledge of C++ scripting is very important for managing this data. Sources like Martysama can serve as guides in this regard.
Coordination with Auth Server
The auth server manages player login and logout processes. To ensure inventory data is transferred correctly, synchronization must be established between the auth-server and the game-server. This process is typically done via socket connection. Special inventory settings for users can also be stored on the auth server side. This way, even if the player logs in on different servers, their inventory remains preserved.
Quick Switch Function with Python GUI
With a user-friendly GUI written in Python, a smooth switching system can be developed. By clicking the buttons, players can quickly switch to different inventories. During these transitions, data exchange occurs between the client and server. Requests are sent to the server using Py Root files, and necessary data is retrieved back. This way, the player gains the ability to switch inventories within seconds.
System Testing and Debugging
Before going live, all functions should be tested on a test server to ensure they work properly. It must be ensured that player data is stored completely and securely. Backup processes should also be planned to avoid data loss in the DB Core. During debugging, logging systems come into play and every action is monitored in detail.
Conclusion
Tr and Sultan-type inventory systems significantly enhance the gaming experience in Metin2 private servers. Developing these systems requires in-depth knowledge of C++, Python, and the client side. However, when configured correctly, they provide strategic advantages for players. These systems enable smoother movement for users in both PvP and PvE content.
