romegames 1
romegames
Krutzo 1
Krutzo
shrpnl 1
shrpnl
Best Studio 1
Best Studio
D 1
delimuratt
Aliyldrim 1
Aliyldrim
Mt2Hizmet 1
Mt2Hizmet
noisiv 1
noisiv
Manwe Work 1
Manwe Work
melankolıa18 1
melankolıa18
Agora Metin2 1
Agora Metin2
Hikaye Ekle
Reklam vermek için turkmmo@gmail.com

Kill Ünvan Sistemi (KillStreak)

  • Konuyu başlatan Konuyu başlatan lTJA
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 20
  • Görüntüleme Görüntüleme 2K
5.00 yıldız(lar) 4 Değerlendirme Değerlendirenler

lTJA

Level 3
Banlı
TM Üye
Katılım
2 Eyl 2023
Konular
28
Mesajlar
108
Online süresi
6d 22h
Reaksiyon Skoru
85
Altın Konu
0
Başarım Puanı
59
MmoLira
965
DevLira
15
Ticaret - 0%
0   0   0

ROHAN2 WORLD 1-120 TR TİPİ OFFICIAL YOHARA, BALATHOR VE AMON! 80. GÜNÜNDE! +10.000 ONLİNE! HİLE VE BOT %100 ENGELLİ HEMEN TIKLA!

Kill Streak Sistemi – Mantık





Oyuncu art arda kill aldıkça:


Lakap kazanır (isim önünde görünür)
Kritik vuruş 'ı alır
Tüm sunucuya anons geçebilir
Log kaydı oluşur (kill.txt)
GM'ler lakap verebilir sıfırlayabilir kill streak'i sıfırlayabilir



Kill Sayısı - Ödüller:


KillLakapKritikAnons
5Savaşçı%3❌
10Katliamcı%6✅
15Yıkım Gücü%9❌
20İnfazcı%12✅
30Efsane Katil%15✅




Abuse Engelleme:


Aşağıdaki durumlarda kill sayılmaz
-
Aynı IP’den giriş yapan 2 karakter
Aynı lonca içindelerse
Arkadaş listesinde birbirleri varsa
Aynı Karakterden sadece 2 kez kill alabilirsin 3.kez kill aldıktan sonra kill sayılmaz



Ölüm Sonrası:


Kill streak tamamen sıfırlanır
Kritik silinir
Lakap temizlenir
Bilgilendirme mesajı gider

Loglama:

Her kill sonrası şu satır, şu dosyaya yazılır:


/usr/game/locale/turkey/kill.txt




Duyurular:

Şu kill sayılarında tüm oyunculara duyuru gönderilir:


10 kill: [BILDIRI] ITJA 10 kişiyi üst üste yok etti! [Katliamcı]
20 kill: [BILDIRI]ITJA 20 kill'e ulaştı! [İnfazcı]
30 kill: [BILDIRI] ITJA artık bir efsane! 30 kill! [Efsane Katil]



GM Komutları:​


KomutAçıklama
/lakapver ITJAKatliamcıOyuncuya manuel lakap verir
/lakapsil ITJAOyuncunun lakabını siler
/killreset ITJAKill streak + buff + lakap sıfırlar



UI Tarafı – Top Kill Sıralama Penceresi

F10 tuşuyla sıralama açılır. Python tarafında uiTopKill.py penceresi açılır Server /topkill komutuyla sıralama gönderir


Oyuncu 30 Kill Yapmışsa Eğer

Test Senaryosu:​


DurumSonuç
30 kill'den azKomut reddedilir
Geçersiz LakapKomut reddedilir
Daha önce kullanmışsa“Sadece 1 kez” hatası
Tüm şartlar uygunsalakap atanır, tekrar kullanılamaz
/unvansec SavaşKralıBaşarılı işlem → [SavaşKralı] ITJA görünür

char.h → class CHARACTER içine (public:)

void IncreaseKillStreak(CHARACTER* pkVictim);
void ResetKillStreak();
const char* GetKillTitle() const;
bool IsFriendByVID(DWORD dwVID);
std::string GetDisplayedName() const;

int m_iKillStreak;
DWORD m_dwLastKilledVID;
std::string m_strKillTitle;

char.h → class CHARACTER içine (public):

bool m_bUsedCustomTitle;
bool HasUsedCustomTitle() const { return m_bUsedCustomTitle; }
void SetUsedCustomTitle(bool val) { m_bUsedCustomTitle = val; }

char.cpp → Karakter constructor'una ekle (başlangıç değeri):

CHARACTER::CHARACTER()
{
...
m_bUsedCustomTitle = false;
}



char.cpp → Dosyanın en sonuna (en altına) EKLE:

void CHARACTER::IncreaseKillStreak(CHARACTER* pkVictim)
{
if (pkVictim)
m_dwLastKilledVID = pkVictim->GetVID();

++m_iKillStreak;

if (m_iKillStreak == 5)
{
m_strKillTitle = "Savaşçı";
ChatPacket(CHAT_TYPE_INFO, "5 kill! [Savaşçı] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 3, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);
}
else if (m_iKillStreak == 10)
{
m_strKillTitle = "Katliamcı";
ChatPacket(CHAT_TYPE_INFO, "10 kill! [Katliamcı] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 6, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);
}
else if (m_iKillStreak == 15)
{
m_strKillTitle = "Yıkım Gücü";
ChatPacket(CHAT_TYPE_INFO, "15 kill! [Yıkım Gücü] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 9, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);
}
else if (m_iKillStreak == 20)
{
m_strKillTitle = "İnfazcı";
ChatPacket(CHAT_TYPE_INFO, "20 kill! [İnfazcı] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 12, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);
}
else if (m_iKillStreak == 30)
{
m_strKillTitle = "Efsane Katil";
ChatPacket(CHAT_TYPE_INFO, "30 kill! [Efsane Katil] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 15, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);
}
}

void CHARACTER::ResetKillStreak()
{
if (m_iKillStreak >= 5)
ChatPacket(CHAT_TYPE_INFO, "Kill serin sona erdi. (%d kill)", m_iKillStreak);

m_iKillStreak = 0;
m_dwLastKilledVID = 0;
m_strKillTitle.clear();
RemoveAffect(AFFECT_CRITICAL);
}

const char* CHARACTER::GetKillTitle() const
{
return m_strKillTitle.c_str();
}

bool CHARACTER::IsFriendByVID(DWORD dwVID)
{
if (!GetDesc()) return false;
CMessengerManager* pMessenger = CMessengerManager::instance().Get(GetName());
return (pMessenger && pMessenger->IsFriendByVID(dwVID));
}

std::string CHARACTER::GetDisplayedName() const
{
if (!m_strKillTitle.empty())
return m_strKillTitle + " " + m_stName;
return m_stName;
}



battle.cpp → void battle_end_ex(LPCHARACTER ch) içine:

LPCHARACTER victim = ch->GetVictim();

if (ch && victim && ch->IsPC() && victim->IsPC())
{
if (ch->GetDesc() && victim->GetDesc() &&
strcmp(ch->GetDesc()->GetHostName(), victim->GetDesc()->GetHostName()) == 0)
return;

if (ch->GetGuild() && victim->GetGuild() &&
ch->GetGuild() == victim->GetGuild())
return;

if (ch->IsFriendByVID(victim->GetVID()))
return;

ch->IncreaseKillStreak(victim);
victim->ResetKillStreak();

char.cpp → Fonksiyon tanımı (sonuna ekle):

void CHARACTER::SetKillTitle(const std::string& title)
{
m_strKillTitle = title;
ChatPacket(CHAT_TYPE_INFO, "Yeni unvanınız: [%s]", title.c_str());
}

cmd_general.cpp → En uygun yere
ACMD(do_lakapver)
{
char arg1[256], arg2[256];
one_argument(two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg2, sizeof(arg2));

if (!*arg1 || !*arg2)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Kullanım: /lakapver [oyuncu_adı] [lakap]");
return;
}

LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
if (!tch)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Oyuncu bulunamadı: %s", arg1);
return;
}

tch->SetKillTitle(arg2);
ch->ChatPacket(CHAT_TYPE_INFO, "%s adlı oyuncuya [%s] lakabı verildi.", tch->GetName(), arg2);
}

cmd.cpp

{ "lakapver", do_lakapver, GM_HIGH_WIZARD },



char.cpp

void CHARACTER::SetKillTitle(const std::string& title)
{
m_strKillTitle = title;
if (title.empty())
ChatPacket(CHAT_TYPE_INFO, "Unvanın sıfırlandı.");
else
ChatPacket(CHAT_TYPE_INFO, "Yeni unvan: [%s]", title.c_str());
}

cmd_general.cpp

ACMD(do_lakapsil)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));

if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Kullanım: /lakapsil [oyuncu_adı]");
return;
}

LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
if (!tch)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Oyuncu bulunamadı: %s", arg1);
return;
}

tch->SetKillTitle("");
ch->ChatPacket(CHAT_TYPE_INFO, "%s adlı oyuncunun lakabı sıfırlandı.", tch->GetName());
}

Komut listesine ekle cmd.cpp

{ "lakapsil", do_lakapsil, GM_HIGH_WIZARD },

char.cpp → IncreaseKillStreak() Fonksiyonuna ŞUNU EKLE:

if (m_iKillStreak == 10)
{
m_strKillTitle = "Katliamcı";
ChatPacket(CHAT_TYPE_INFO, "10 kill! [Katliamcı] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 6, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);

BroadcastNotice(fmt::format("{} 10 kişiyi üst üste yok etti! [Katliamcı]", GetName()));
}

else if (m_iKillStreak == 20)
{
m_strKillTitle = "İnfazcı";
ChatPacket(CHAT_TYPE_INFO, "20 kill! [İnfazcı] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 12, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);

BroadcastNotice(fmt::format("{} 20 kill'e ulaştı! [İnfazcı]", GetName()));
}

else if (m_iKillStreak == 30)
{
m_strKillTitle = "Efsane Katil";
ChatPacket(CHAT_TYPE_INFO, "30 kill! [Efsane Katil] unvanı kazandın!");
AddAffect(AFFECT_CRITICAL, POINT_CRITICAL_PCT, 15, AFF_NONE, INFINITE_AFFECT_DURATION, 0, true);

BroadcastNotice(fmt::format("{} artık bir efsane! 30 kill yaptı! [Efsane Katil]", GetName()));
}

char.cpp → IncreaseKillStreak() fonksiyonu içine ŞUNU EKLE:
FILE* f = fopen("/usr/game/locale/turkey/kill.txt", "a+");
if (f)
{
fprintf(f, "[KillStreak] [%s] %s → %s | Seri: %d\n",
m_strKillTitle.c_str(),
GetName(),
pkVictim ? pkVictim->GetName() : "???",
m_iKillStreak);
fclose(f);

char.cpp → IncreaseKillStreak() içine ŞU SATIRI EKLE:

sys_log(0, "[KillStreak] %s(%s) → %s | Seri: %d",
GetName(), m_strKillTitle.c_str(),
pkVictim ? pkVictim->GetName() : "???",
m_iKillStreak);

cmd_general.cpp

ACMD(do_killreset)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));

if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Kullanım: /killreset [oyuncu_adi]");
return;
}

LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
if (!tch)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Oyuncu bulunamadı.");
return;
}

tch->ResetKillStreak();
tch->SetKillTitle(""); // Eğer varsa lakabı temizle

ch->ChatPacket(CHAT_TYPE_INFO, "%s adlı oyuncunun kill serisi ve unvanı sıfırlandı.", tch->GetName());
}


cmd.cpp

{ "killreset", do_killreset, GM_HIGH_WIZARD },

1. cmd_general.cpp

ACMD(do_topkill)
{
std::vector<CHARACTER*> players;

CHARACTER_MANAGER::instance().for_each_pc([&](CHARACTER* ch) {
if (ch->GetKillStreak() >= 1)
players.push_back(ch);
});

std::sort(players.begin(), players.end(), [](CHARACTER* a, CHARACTER* b) {
return a->GetKillStreak() > b->GetKillStreak();
});

std::string result = "SetTopKillList";

int count = 0;
for (CHARACTER* ch : players)
{
if (++count > 10)
break;

char line[128];
snprintf(line, sizeof(line), "|%s|%d|%s",
ch->GetName(),
ch->GetKillStreak(),
ch->GetKillTitle());

result += line;
}

// Python tarafına sıralamayı gönderiyoruz:
ch->ChatPacket(CHAT_TYPE_COMMAND, result.c_str());
}

cmd.cpp
{ "topkill", do_topkill, GM_PLAYER },


cmd_general.cpp

ACMD(do_unvansec)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));

if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Kullanım: /unvansec [Unvan]");
ch->ChatPacket(CHAT_TYPE_INFO, "Mevcut Unvanlar: Efsane, SavaşKralı, İntikamcı");
return;
}

if (ch->HasUsedCustomTitle())
{
ch->ChatPacket(CHAT_TYPE_INFO, "Bu komutu daha önce kullandın. Sadece 1 kez kullanılabilir.");
return;
}

if (ch->GetKillStreak() < 30)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Bu komutu kullanmak için en az 30 kill yapmalısın!");
return;
}

std::string title(arg1);

std::vector<std::string> allowed = { "Efsane", "SavaşKralı", "İntikamcı" };
if (std::find(allowed.begin(), allowed.end(), title) == allowed.end())
{
ch->ChatPacket(CHAT_TYPE_INFO, "Bu unvan seçilemez. Geçerli unvanlar: Efsane, SavaşKralı, İntikamcı");
return;
}

ch->SetKillTitle(title);
ch->SetUsedCustomTitle(true); // ❗ Artık tekrar kullanamaz
ch->ChatPacket(CHAT_TYPE_INFO, "[%s] unvanı başarıyla seçildi! Bu hak tek kullanımlıktır.", arg1);
}

cmd.cpp

{ "unvansec", do_unvansec, GM_PLAYER },

cmd.cpp

ACMD Tarafına:


ACMD(do_unvansec);
ACMD(do_killreset);
ACMD(do_topkill);
ACMD(do_lakapsil);
ACMD(do_lakapver);




Pyhton Ui Sıralama

interfaceModule.py Pencere Tanımı
Python:
import uiTopKill  # en üste ekle

[B][COLOR=rgb(184, 49, 47)]class Interface içinde bu fonksiyonu EKLE:[/COLOR][/B]

[CODE=python]def __MakeTopKillWindow(self):
    self.wndTopKill = uiTopKill.TopKillWindow()
    self.wndTopKill.Hide()


class Interface içinde bu fonksiyonu EKLE


Python:
def __MakeTopKillWindow(self):
    self.wndTopKill = uiTopKill.TopKillWindow()
    self.wndTopKill.Hide()



def MakeInterface(self): fonksiyonunun içine ŞU SATIRI EKLE:

Python:
self.__MakeTopKillWindow()



def CloseAllWindows(self): içine ekle (pencereyi kapatmak için)

Python:
if self.wndTopKill:
    self.wndTopKill.Hide()




game.py içine şunu ekle

Python:
elif line.startswith("SetTopKillList"):
    import constInfo
    parts = line.split("|")[1:]
    constInfo.KILL_LIST = []
    for entry in parts:
        vals = entry.split("\n")
        for val in vals:
            if val:
                name, kill, title = val.split("|")
                constInfo.KILL_LIST.append((name, int(kill), title))




Python:
self.__MakeTopKillWindow()

def CloseAllWindows(self): içine ekle (pencereyi kapatmak için)

Python:
if self.wndTopKill:
    self.wndTopKill.Hide()

uiTopKill.py
pack/root/ içine at


topkillrankingwindow.py

pack/uiscript/ sizde orda değilse root/uiscript e atın
 

Ekli dosyalar

Son düzenleme:

En Çok Reaksiyon Alan Mesajlar

Sözde Kanıt videosu burada yazacak olan ilk arkadaşa sistemi ben eklerim ve arkadaşta konu altına kanıt atar. bu sefer farklılık olsun
 
Paylaşımın için teşekkürler, farklı bi sistem olmuş
 
kullandığım filese göre kritik tanım fonskiyonu AFFECT_CRITICAL yani affect.h dosyasına girin kritiğin tanımı neyse ona göre entegre edin. sizde farklı olabilir
 
Kanıt olsa ve konudaki kodlar icerik editör yapisina göre olsa tadından yenmez
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst