Metin2 Pvp Dünyasında Yepyeni Bir Özellik: Grup Üyelerinin Exp Miktarını Görme Sistemi!

Merhaba mmooyun.com takipçileri!

Bugün sizlerle Metin2 dünyasında oyun deneyiminizi bir adım öteye taşıyacak harika bir sistemi paylaşacağız. Hepimiz grupla kasılırken “Ne kadar exp kaldı?”, “Kaç kutu doldu?” gibi sorular sormuşuzdur. İşte bu sistem sayesinde artık grup üyelerinizin ne kadar deneyim puanına (EXP) sahip olduğunu ve kaç kutularının dolduğunu görebileceksiniz!

Bu sistem, hem arkadaşlarınızla koordinasyonunuzu artıracak hem de kimin ne zaman seviye atlayacağını kolayca takip etmenizi sağlayacak. Gelin lafı fazla uzatmadan, adım adım kurulumuna geçelim!

1. Sunucu (Server) Taraflı Düzenlemeler

Sistemimizin temelini atmak için sunucu dosyalarımızda ufak tefek değişiklikler yapmamız gerekiyor.

common/service.h dosyasına şu satırı ekleyin:

C++

#define EXTENDED_PARTY_INFO

char.cpp dosyasında ilgili yeri bulup şu şekilde güncelleyin:

C++

bool CHARACTER::BuildUpdatePartyPacket(TPacketGCPartyUpdate & out)
{
    out.role = GetParty()->GetRole(GetPlayerID());
#ifdef EXTENDED_PARTY_INFO
    out.bLevel = GetLevel();
    out.dwCurExp = GetExp();
    out.dwMaxExp = GetNextExp();
#endif
    // ... (kodun devamı) ...

Aynı dosya içerisinde (char.cpp) “PointChange” fonksiyonunda şu değişikliği yapın:

C++

void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast)
{
    // ...
    val = GetExp();
    // ...
#ifdef EXTENDED_PARTY_INFO
    if (GetParty()) {
        GetParty()->SendPartyInfoOneToAll(this);
    }
#endif
    // ...
}

packet.h dosyasını güncelleyin:

C++

typedef struct packet_party_update
{
    BYTE header;
    DWORD pid;
    BYTE role;
    BYTE percent_hp;
#ifdef EXTENDED_PARTY_INFO
    BYTE bLevel;
    DWORD dwCurExp;
    DWORD dwMaxExp;
#endif
    short affects[7];
} TPacketGCPartyUpdate;

party.cpp dosyasında ilgili yerleri bulup şu şekilde güncelleyin:

C++

void CParty::SendPartyInfoOneToAll(DWORD pid)
{
    // ...
    TPacketGCPartyUpdate p;
    memset(&p, 0, sizeof(p));
    p.header = HEADER_GC_PARTY_UPDATE;
    p.pid = pid;
    p.percent_hp = 255;
    p.role = it->second.bRole;
#ifdef EXTENDED_PARTY_INFO
    p.bLevel = it->second.bLevel;
    p.dwCurExp = 0;
    p.dwMaxExp = 0;
#endif
    // ...
}

void CParty::SendPartyInfoAllToOne(LPCHARACTER ch)
{
    // ...
    TPacketGCPartyUpdate p;
    // ...
    p.header = HEADER_GC_PARTY_UPDATE;
    p.pid = pid;
    p.percent_hp = 255;
    p.role = it->second.bRole;
#ifdef EXTENDED_PARTY_INFO
    p.bLevel = it->second.bLevel;
    p.dwCurExp = 0;
    p.dwMaxExp = 0;
#endif
    // ...
}

2. İstemci (Client – Binary) Taraflı Düzenlemeler

Şimdi de oyunumuzun arka planında (Binary) bu bilgileri alabilmesi için gerekenleri yapalım.

Packet.h dosyasını güncelleyin:

C++

typedef struct packet_party_update
{
    BYTE header;
    DWORD pid;
    BYTE state;
    BYTE percent_hp;
#ifdef EXTENDED_PARTY_INFO
    BYTE bLevel;
    DWORD dwCurExp;
    DWORD dwMaxExp;
#endif
    short affects[PARTY_AFFECT_SLOT_MAX_NUM];
} TPacketGCPartyUpdate;

PythonApplicationModule.cpp dosyasına şu eklemeyi yapın:

C++

#ifdef EXTENDED_PARTY_INFO
    PyModule_AddIntConstant(poModule, "EXTENDED_PARTY_INFO", 1);
#else
    PyModule_AddIntConstant(poModule, "EXTENDED_PARTY_INFO", 0);
#endif

PythonNetworkStreamPhaseGame.cpp dosyasında ilgili yeri güncelleyin:

C++

bool CPythonNetworkStream::RecvPartyUpdate()
{
    // ...
#ifdef EXTENDED_PARTY_INFO
    CPythonPlayer::Instance().UpdatePartyMemberInfo(kPartyUpdatePacket.pid, kPartyUpdatePacket.state, kPartyUpdatePacket.percent_hp, kPartyUpdatePacket.bLevel, kPartyUpdatePacket.dwCurExp, kPartyUpdatePacket.dwMaxExp);
#else
    CPythonPlayer::Instance().UpdatePartyMemberInfo(kPartyUpdatePacket.pid, kPartyUpdatePacket.state, kPartyUpdatePacket.percent_hp);
#endif
    // ...
}

PythonPlayer.cpp dosyasını güncelleyin:

C++

#ifdef EXTENDED_PARTY_INFO
void CPythonPlayer::UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage, BYTE bLevel, DWORD dwCurExp, DWORD dwMaxExp)
#else
void CPythonPlayer::UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage)
#endif
{
    // ...
    pPartyMemberInfo->byState = byState;
    pPartyMemberInfo->byHPPercentage = byHPPercentage;
#ifdef EXTENDED_PARTY_INFO
    pPartyMemberInfo->bLevel = bLevel;
    pPartyMemberInfo->dwCurExp = dwCurExp;
    pPartyMemberInfo->dwMaxExp = dwMaxExp;
#endif
}

PythonPlayer.h dosyasını güncelleyin:

C++

typedef struct SPartyMemberInfo
{
    // ...
    BYTE byState;
    BYTE byHPPercentage;
#ifdef EXTENDED_PARTY_INFO
    BYTE bLevel;
    DWORD dwCurExp;
    DWORD dwMaxExp;
#endif
    // ...
} TPartyMemberInfo;

#ifdef EXTENDED_PARTY_INFO
void UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage, BYTE bLevel, DWORD dwCurExp, DWORD dwMaxExp);
#else
void UpdatePartyMemberInfo(DWORD dwPID, BYTE byState, BYTE byHPPercentage);
#endif

PythonPlayerModule.cpp dosyasını güncelleyin:

C++

// ... (playerGetPartyMemberHPPercentage fonksiyonundan sonra ekleyin)
#ifdef EXTENDED_PARTY_INFO
PyObject* playerGetPartyMemberDetail(PyObject* poSelf, PyObject* poArgs)
{
    int pid;
    if (!PyTuple_GetInteger(poArgs, 0, &pid))
        return Py_BuildException();

    CPythonPlayer::TPartyMemberInfo* pPartyMemberInfo;
    if (!CPythonPlayer::Instance().GetPartyMemberPtr(pid, &pPartyMemberInfo))
        return Py_BuildNone();

    return Py_BuildValue("iii", pPartyMemberInfo->bLevel, pPartyMemberInfo->dwCurExp, pPartyMemberInfo->dwMaxExp);
}
#endif

// ... (fonksiyon kayıt kısmına ekleyin)
    { "GetPartyMemberHPPercentage", playerGetPartyMemberHPPercentage, METH_VARARGS },
#ifdef EXTENDED_PARTY_INFO
    { "GetPartyMemberDetail", playerGetPartyMemberDetail, METH_VARARGS },
#endif
// ...

3. Arayüz (UI) ve Python Dosyası Düzenlemeleri

Son olarak, bu bilgileri ekranda görsel bir şölene dönüştürmemiz gerekiyor. İşin en eğlenceli kısmı burası!

uiparty.py dosyasındaki değişiklikler oldukça detaylı. Lütfen bu kısımları kod yapısını bozmadan dikkatlice ekleyin. Bu dosyada PartyMemberInfoBoard, PartyMenu ve PartyWindow sınıflarında değişiklikler yapacaksınız. Tüm kod bloğunu paylaşmak yerine, ana eklentileri özetliyoruz:

Python

# uiparty.py içerisindeki önemli eklemelerden bir kesit:

class PartyMemberInfoBoard(ui.ScriptWindow):
    # ...
    def __init__(self):
        # ...
        if app.EXTENDED_PARTY_INFO:
            self.isMouseOver = False
            self.expToolTip = None
            self.curExp = 0
            self.maxExp = 0
            self.level = 0
            self.charName = ""
        # ...
        
    def SetCharacterExp(self, curExp, maxExp):
        self.curExp = curExp
        self.maxExp = maxExp
        if maxExp > 0:
            percentage = (float(curExp) / float(maxExp)) * 100.0
            self.expGauge.SetPercentage(percentage, 100.0)
        else:
            self.expGauge.SetPercentage(0, 100)
# ...

(Not: uiparty.py dosyasındaki orijinal kod bloğunda verilen tüm EXTENDED_PARTY_INFO eklentilerini uygun sınıfların içine yerleştirin.)

ui.py dosyasını güncelleyin:

Python

class Window(object):
    # ...
    def __init__(self, layer = "UI"):
        # ...
        if app.EXTENDED_PARTY_INFO:
            self.eventOverIn = None
            self.eventOverOut = None
        # ...
        
    if app.EXTENDED_PARTY_INFO:
        def SetOverEvent(self, event):
            self.eventOverIn = event
        def SetOverOutEvent(self, event):
            self.eventOverOut = event
        def OnMouseOverIn(self):
            if self.eventOverIn:
                self.eventOverIn()
        def OnMouseOverOut(self):
            if self.eventOverOut:
                self.eventOverOut()
                
# Button sınıfı içerisine eklenecekler
    if app.EXTENDED_PARTY_INFO:
        def OnMouseOverIn(self):
            self.ShowToolTip()
            if self.eventOverIn:
                self.eventOverIn()
        def OnMouseOverOut(self):
            self.HideToolTip()
            if self.eventOverOut:
                self.eventOverOut()

uiscript/partymemberinfoboard.py dosyasını şu şekilde güncelleyin:

Python

import uiScriptLocale
import app

BOARD_HEIGHT = 36
ICON_Y_POS = 24
GAUGE_WIDTH = 84

if app.EXTENDED_PARTY_INFO:
    BOARD_HEIGHT = 47
    ICON_Y_POS = 34

window = {
    "name" : "PartyMemeberInfoBoard",
    "x" : 0, "y" : 0,
    "width" : 106,
    "height" : BOARD_HEIGHT,
    # ... (diğer arayüz elemanları) ...
}

if app.EXTENDED_PARTY_INFO:
    window["children"] += (
        {
            "name" : "ExpGauge", "type" : "gauge", "style" : ("not_pick",),
            "x" : 22, "y" : 26, "width" : GAUGE_WIDTH, "color" : "yellow",
        },
    )

Son bir dokunuş: gauge_yellow.tga adlı dosyayı etc\ymir work\ui\pattern\ dizinine atmayı unutmayın. Bu dosya exp barınızın o göz alıcı sarı rengini sağlayacaktır!

İşte bu kadar! Artık Metin2 sunucunuzda grup arkadaşlarınızın exp durumlarını anlık olarak takip edebilirsiniz. mmooyun.com olarak sizlere en iyi rehberleri sunmaya devam edeceğiz. Takıldığınız bir yer olursa yorumlarda buluşalım!

Görselin indirme bağlantısı : TIKLA

Paylaş :