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ş :




