Bu Bölümde Herşeyin Kalbi Olan GameSource Bölümüne Geçiyoruz.
Kısaca Anlatmak Gerekirse:
Python'da Lonca Bağışı Butonuna Bastığımızda offerDialog açılır. (Aslı: uiCommon'da Bir Class)
Bu Pencere İçinde Bağışlayacağımız amount (Verilecek Exp Sayısı) Değerimizi Yazıyoruz ve Tamam Diyoruz.
Tamam Dedikten Sonra Aslında
self.offerDialog.SetAcceptEvent(ui.__mem_func__(self.OnOffer))
Çalıştığını Göreceksiniz.
Gördüğünüz Gibi Bizi ClientSource'ye Gönderiyor. ve Oradan Girdiğimiz Exp Değeri ile Birlikte GameSourceye Gönderiyor. Fakat bir bHeader ve bir'de bSubHeader.
İşte Gelelim.
input_main.cpp'de SubHeader İsmimize Gelelim
case GUILD_SUBHEADER_CG_OFFER:
if (pGuild->OfferExp(ch, offer))
OfferExp'nin Çalıştırılacağını Söylüyor. 2 Argüman Olarak Bir Karakter Sınıfı ve offerDialog'a Yazdığımız Exp'i Sayımız ile Birlikte.
Guild.cpp Açalım ve Aratalım:
bool CGuild::OfferExp(LPCHARACTER ch, int amount)
Birazcık Alt Tarafa Geldiğimizde Sürekli Karakter Sınıfından GetExp Adında Bir Tanımı Sorguluyor.
İşte Burayı Değiştiriyoruz.
Ardından Sorgular Bittikten Sonra Exp'lerin Silinme İşlemine Gelelim. Biraz Daha Aşağıya İnin ve Bunu Göreceksiniz.
ch->PointChange(POINT_EXP, -amount);
Değiştirelim:
Birazcık Daha Aşağıya İnelim ve Bunu Göreceksiniz:
GuildPointChange(POINT_EXP, amount / 100, true);
Değiştirelim:
Guild.cpp İçinde Tekrar Aratalım:
void CGuild::GuildPointChange(BYTE type, int amount, bool save)
Altında switch (type) Yapısındaki case Parçalarını Göreceksiniz ve Orada POINT_EXP Var Hemen Üstüne Ekleyelim:
case POINT_CONQUEROR_EXP:
HERŞEY BU KADAR KOLAY GELSİN
Kısaca Anlatmak Gerekirse:
Python'da Lonca Bağışı Butonuna Bastığımızda offerDialog açılır. (Aslı: uiCommon'da Bir Class)
Bu Pencere İçinde Bağışlayacağımız amount (Verilecek Exp Sayısı) Değerimizi Yazıyoruz ve Tamam Diyoruz.
Tamam Dedikten Sonra Aslında
self.offerDialog.SetAcceptEvent(ui.__mem_func__(self.OnOffer))
Çalıştığını Göreceksiniz.
Kod:
def OnOffer(self, exp): net.SendGuildOfferPacket(exp)
Gördüğünüz Gibi Bizi ClientSource'ye Gönderiyor. ve Oradan Girdiğimiz Exp Değeri ile Birlikte GameSourceye Gönderiyor. Fakat bir bHeader ve bir'de bSubHeader.
İşte Gelelim.
input_main.cpp'de SubHeader İsmimize Gelelim
case GUILD_SUBHEADER_CG_OFFER:
if (pGuild->OfferExp(ch, offer))
OfferExp'nin Çalıştırılacağını Söylüyor. 2 Argüman Olarak Bir Karakter Sınıfı ve offerDialog'a Yazdığımız Exp'i Sayımız ile Birlikte.
Guild.cpp Açalım ve Aratalım:
bool CGuild::OfferExp(LPCHARACTER ch, int amount)
Birazcık Alt Tarafa Geldiğimizde Sürekli Karakter Sınıfından GetExp Adında Bir Tanımı Sorguluyor.
Kod:
if (ch->GetExp() < (DWORD)amount) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Á¦°øÇϰíÀÚ ÇÏ´Â °æÇèÄ¡°¡ ³²Àº °æÇèÄ¡º¸´Ù ¸¹½À´Ï´Ù.")); return false; } if (ch->GetExp() - (DWORD)amount > ch->GetExp()) { sys_err("Wrong guild offer amount %d by %s[%u]", amount, ch->GetName(), ch->GetPlayerID()); return false; }
İşte Burayı Değiştiriyoruz.
Kod:
const auto CharacterExp = ch->GetConquerorExp() ? ch->GetConquerorExp() : ch->GetExp(); if (CharacterExp < (DWORD)amount) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<±æµå> Á¦°øÇϰíÀÚ ÇÏ´Â °æÇèÄ¡°¡ ³²Àº °æÇèÄ¡º¸´Ù ¸¹½À´Ï´Ù.")); return false; } if (CharacterExp - (DWORD)amount > CharacterExp) { sys_err("Wrong guild offer amount %d by %s[%u]", amount, ch->GetName(), ch->GetPlayerID()); return false; }
Ardından Sorgular Bittikten Sonra Exp'lerin Silinme İşlemine Gelelim. Biraz Daha Aşağıya İnin ve Bunu Göreceksiniz.
ch->PointChange(POINT_EXP, -amount);
Değiştirelim:
Kod:
if (ch->GetConquerorLevel() >= 1) ch->PointChange(POINT_CONQUEROR_EXP, -amount); else ch->PointChange(POINT_EXP, -amount);
Birazcık Daha Aşağıya İnelim ve Bunu Göreceksiniz:
GuildPointChange(POINT_EXP, amount / 100, true);
Değiştirelim:
Kod:
if (ch->GetConquerorLevel() >= 1) ch->GuildPointChange(POINT_CONQUEROR_EXP, amount / 100, true); else ch->GuildPointChange(POINT_EXP, amount / 100, true);
Guild.cpp İçinde Tekrar Aratalım:
void CGuild::GuildPointChange(BYTE type, int amount, bool save)
Altında switch (type) Yapısındaki case Parçalarını Göreceksiniz ve Orada POINT_EXP Var Hemen Üstüne Ekleyelim:
case POINT_CONQUEROR_EXP:
HERŞEY BU KADAR KOLAY GELSİN
Metin2'de C++ ile Şampiyon Seviye Sistemi Oluşturmak
Metin2 özel sunucularında gelişmiş seviye sistemleri oluşturmak, oyuncu deneyimini ciddi anlamda artırabilir. Bu yazıda, C++ kullanarak Şampiyon Seviye Sistemini nasıl genişleteceğinizi ve Exp (deneyim) yöntemini nasıl değiştireceğinizi detaylı olarak inceleyeceğiz. Bu sistem sayesinde oyuncuların normal seviyelerinin ötesine geçerek Şampiyon seviyesine ulaşması mümkün olacaktır.
Sistem Mimarisi ve Hedef
Bu sistemde, oyuncular normal Lv. 120 gibi bir seviyeye ulaştığında artık deneyim kazanamazlar. Ancak bazı özel etkinlikler, görevler veya PvP zaferleri sayesinde Şampiyon Exp kazanabilirler. Bu exp ile Champion Level adı verilen yeni bir seviye sistemine geçiş yapabilirler. Bu sistem PvP odaklı sunucularda özellikle popülerdir çünkü oyuncular kendi aralarında statü kazanmak için yarışır.
C++ Kaynak Kodlarında Gerekli Değişiklikler
Öncelikle game core üzerinde değişiklik yapmamız gerekir. Client-Server iletişiminde yeni bir packet tanımlamamız ve oyuncunun champion level bilgisini saklayacak yeni alanları tanımlamamız gerekir.
1. Character Struct Üzerinde Değişiklikler:
struct CHARACTER içine şu alanları eklememiz gerekir:
Kod:
[COLOR=#0000cc]DWORD m_dwChampionExp;[BR][/BR]int m_nChampionLevel;[/COLOR]
2. Exp Kazanma Sistemi:
Oyuncu normal seviyeye ulaştıktan sonra belirli eylemlerle Champion Exp kazanacak. Örneğin:
- PvP galibiyeti ile +X exp
- Bosslarla savaşma ve öldürme
- Özel etkinlik kazanımları
3. Exp Hesaplama Fonksiyonu:
void CHARACTER::GainChampionExp(DWORD amount) fonksiyonu ile oyuncuya Champion Exp verilebilir. Bu fonksiyon şu işlemleri yapar:
- Exp miktarını ekler
- Seviye atlama kontrolü yapar
- Gerekirse UI'a bilgi gönderir
UI Tarafında Gösterim
Python GUI tarafında da oyuncunun Champion Level bilgisi gösterilmelidir. uiscript dosyasında yeni bir label tanımlanmalı ve bu değer dinamik olarak güncellenmelidir. Örnek:
Kod:
[COLOR=#0000cc]self.championLevelValue = self.GetChild('ChampionLevelValue')[/COLOR]
Veritabanı Entegrasyonu
DB Core üzerinde oyuncu karakter bilgileri arasında Champion Exp ve Level bilgileri de saklanmalıdır. Bunun için player tablosuna iki yeni alan eklenmelidir:
Kod:
[COLOR=#0000cc]ALTER TABLE player ADD COLUMN champion_exp INT DEFAULT 0;[BR][/BR]ALTER TABLE player ADD COLUMN champion_level INT DEFAULT 0;[/COLOR]
Güvenlik ve Hile Önleme
Hile engelleme açısından exp kazanma işlemleri doğrulanmalıdır. Sunucu tarafında her exp kazanımı kontrol edilmeli ve geçersiz işlemler reddedilmelidir. Ayrıca loglama sistemi ile tüm Champion Exp kazanımları kayıt altına alınmalıdır.
Sonuç
Bu sistem sayesinde Metin2 özel sunucularında daha rekabetçi ve uzun ömürlü bir oyun döngüsü sağlanabilir. Oyuncuların hedefe yönelik motivasyonu artar ve PvP sistemleri daha cazip hale gelir. C++ ve Python bilgisiyle bu sistem kolayca entegre edilebilir.
Creating a Champion Level System in Metin2 with C++
In Metin2 private servers, creating advanced level systems can significantly enhance the player experience. In this article, we will examine in detail how to expand the Champion Level System using C++ and how to change the Experience (Exp) method. Thanks to this system, players will be able to reach a new level called Champion Level after surpassing their normal level cap.
System Architecture and Goals
In this system, once players reach a certain level like Lv. 120, they can no longer gain experience normally. However, through special events, quests, or PvP victories, they can earn Champion Exp and advance into the Champion Level system. This system is especially popular in PvP oriented servers because players compete for status among themselves.
Required Changes in C++ Source Code
Firstly, we need to make changes on the game core. We must define a new packet for client-server communication and add new fields to store the player's champion level information.
1. Modifications in Character Struct:
We need to add the following fields inside the struct CHARACTER:
Kod:
[COLOR=#0000cc]DWORD m_dwChampionExp;[BR][/BR]int m_nChampionLevel;[/COLOR]
2. Exp Gain System:
After reaching the max normal level, players will gain Champion Exp through specific actions such as:
- Gaining +X exp from PvP wins
- Fighting and killing boss monsters
- Participating in special events
3. Exp Calculation Function:
The function void CHARACTER::GainChampionExp(DWORD amount) will award Champion Exp to the player. It performs these operations:
- Adds exp amount
- Checks for level up
- Sends info to UI if needed
Display in UI
On the Python GUI side, the player's Champion Level should also be displayed. A new label must be defined in the uiscript file and updated dynamically. Example:
Kod:
[COLOR=#0000cc]self.championLevelValue = self.GetChild('ChampionLevelValue')[/COLOR]
Database Integration
Within the DB Core, Champion Exp and Level information must be stored in the player character data. For this purpose, two new columns must be added to the player table:
Kod:
[COLOR=#0000cc]ALTER TABLE player ADD COLUMN champion_exp INT DEFAULT 0;[BR][/BR]ALTER TABLE player ADD COLUMN champion_level INT DEFAULT 0;[/COLOR]
Security and Anti-Cheat Measures
To prevent cheating, all exp gain processes must be validated. Each exp gain event should be checked on the server-side and invalid attempts should be rejected. Additionally, a logging system should record all Champion Exp gains.
Conclusion
Thanks to this system, more competitive and longer-lasting gameplay can be achieved in Metin2 private servers. Player motivation toward goals increases, and PvP systems become more attractive. With knowledge of C++ and Python, this system can be easily integrated.
