Hikayeler

Reklam vermek için turkmmo@gmail.com

Düello sırasında onaylı düello iptali

apikomt2

Level 6
Uzman
Developer
Katılım
11 May 2023
Konular
237
Mesajlar
1,032
Online süresi
1ay 23g
Reaksiyon Skoru
678
Altın Konu
1
Başarım Puanı
176
TM Yaşı
2 Yıl 11 Ay 15 Gün
MmoLira
503
DevLira
315

Metin2 EP, Valorant VP dahil tüm oyun ürünlerini en uygun fiyatlarla bulabilir, Item ve Karakterlerinizi hızlıca satabilirsiniz. HEMEN TIKLA!

1776451250519.png


cmd_general.cpp
Kod:
#include "pvp.h"



#include "messenger_manager.h"
#include "guild.h"
#include "pvp.h"
#include <string>

// Yardımcı Fonksiyon (Paket Gonderimi)
void SendTPReq(LPCHARACTER ch, LPCHARACTER victim, int mode, int type) {
    if (!ch || !victim) return;
    victim->ChatPacket(CHAT_TYPE_COMMAND, "AskTP %d %d %u %s", mode, type, static_cast<DWORD>(ch->GetVID()), ch->GetName());
}

// --- DUELLO ?PTAL S?STEM? ---
ACMD(do_pvp_cancel_request)
{
    char arg1[256];
    one_argument(argument, arg1, sizeof(arg1));

    // E?er arguman bo?sa (VID gelmediyse)
    if (!*arg1)
    {
        ch->ChatPacket(CHAT_TYPE_INFO, "Hata: Hedef VID alinmadi.");
        return;
    }

    // Gelen metni sayıya (VID) ceviriyoruz
    DWORD targetVID = 0;
    try {
        targetVID = std::stoul(arg1);
    } catch (...) {
        return;
    }

    // Dunyadaki tum oyuncular icinde bu VID'ye sahip ki?iyi bul (En sa?lam yontem)
    LPCHARACTER victim = CHARACTER_MANAGER::instance().Find(targetVID);

    if (!victim)
    {
        ch->ChatPacket(CHAT_TYPE_INFO, "Hata: Rakip bulunamadi.");
        return;
    }

    // Guvenlik: Aktif duelloda mısın?
    if (!CPVPManager::instance().IsFighting(ch))
    {
        ch->ChatPacket(CHAT_TYPE_INFO, "Su an aktif bir duellonuz bulunmuyor.");
        return;
    }

    // Her ?ey tamamsa Said'e (victim) onay penceresini yolla
    victim->ChatPacket(CHAT_TYPE_COMMAND, "AskPvpCancel %u %s", static_cast<DWORD>(ch->GetVID()), ch->GetName());
    ch->ChatPacket(CHAT_TYPE_INFO, "%s adli rakibe iptal iste?i gonderildi.", victim->GetName());
}

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

    if (!*arg1)
        return;

    DWORD requesterVID = 0;
    try {
        requesterVID = std::stoul(arg1);
    } catch (...) {
        return;
    }

    LPCHARACTER requester = CHARACTER_MANAGER::instance().Find(requesterVID);

    if (requester)
    {
        // 1. ADIM: İki oyuncunun ID'lerini kullanarak düello nesnesini (CRC) oluşturup buluyoruz.
        // MartySama'da CRC hesaplaması constructor içinde yapıldığı için geçici bir nesne oluşturuyoruz.
        CPVP kPVP(ch->GetPlayerID(), requester->GetPlayerID());
        CPVP * pkPVP = CPVPManager::instance().Find(kPVP.GetCRC());

        if (pkPVP)
        {
            // 2. ADIM: GÖRSEL İPTAL
            // pkPVP->Packet(true) fonksiyonu senin pvp.cpp dosmanda tüm sunucuya
            // "PVP_MODE_NONE" paketini gönderir. Bu, kılıçların anında gitmesini sağlar.
            pkPVP->Packet(true);

            // 3. ADIM: TEKNİK İPTAL
            // Delete fonksiyonu düelloyu m_map_pkPVP ve m_map_pkPVPSetByID listelerinden siler
            // ve nesneyi bellekten (M2_DELETE) temizler.
            CPVPManager::instance().Delete(pkPVP);
        }

        // 4. ADIM: HASAR ENGELLEME
        // MartySama'da düello sırasında oyuncular birbirini QuestNPC olarak görür.
        // Bunu sıfırlamazsak birbirlerine vurmaya devam edebilirler.
        ch->SetQuestNPCID(0);
        requester->SetQuestNPCID(0);

        // Bilgilendirme
        ch->ChatPacket(CHAT_TYPE_INFO, "Duello basariyla iptal edildi.");
        requester->ChatPacket(CHAT_TYPE_INFO, "Rakibin istegi kabul etti, duello iptal edildi.");
    }
}









cmd.cpp
Kod:
ACMD(do_pvp_cancel_request);


ACMD(do_pvp_cancel_confirm);


    { "do_pvp_cancel_request",    do_pvp_cancel_request, 0, POS_FIGHTING, GM_PLAYER },
   
    { "do_pvp_cancel_confirm",    do_pvp_cancel_confirm, 0, POS_FIGHTING, GM_PLAYER },


game.py
Kod:
örnek
    def __ServerCommand_Build(self):
        serverCommandList={
            "ConsoleEnable"            : self.__Console_Enable,
            "DayMode"                : self.__DayMode_Update,
            "PRESERVE_DayMode"        : self.__PRESERVE_DayMode_Update,
            "CloseRestartWindow"    : self.__RestartDialog_Close,
            "OpenPrivateShop"        : self.__PrivateShop_Open,
            "PartyHealReady"        : self.PartyHealReady,
            "ShowMeSafeboxPassword"    : self.AskSafeboxPassword,
            "CloseSafebox"            : self.CommandCloseSafebox,
           
           
           
           
            "AskTP": self.AskTeleportRequest,
            "AskPvpCancel": self.AskPvpCancel,


en asagi ekle

    def AskPvpCancel(self, vid, name):
        import uiCommon
        self.pvpCancelDialog = uiCommon.QuestionDialog()
        self.pvpCancelDialog.SetText(name + " duelloyu iptal etmek istiyor. Kabul ediyor musun?")
        self.pvpCancelDialog.SetAcceptEvent(lambda v=vid: self.OnAnswerPvpCancel(v, True))
        self.pvpCancelDialog.SetCancelEvent(lambda v=vid: self.OnAnswerPvpCancel(v, False))
        self.pvpCancelDialog.Open()

    def OnAnswerPvpCancel(self, vid, isAccept):
        if isAccept:
            import net
            # Onay komutun da cmd.cpp'deki isminle aynı olmalı:
            net.SendChatPacket("/do_pvp_cancel_confirm %d" % int(vid))
       
        if self.pvpCancelDialog:
            self.pvpCancelDialog.Close()
            self.pvpCancelDialog = None


uitarget.py
Kod:
örneğin
class TargetBoard(ui.ThinBoard):

    BUTTON_NAME_LIST = (
        localeInfo.TARGET_BUTTON_WHISPER,
        localeInfo.TARGET_BUTTON_EXCHANGE,
        localeInfo.TARGET_BUTTON_FIGHT,
        localeInfo.TARGET_BUTTON_ACCEPT_FIGHT,
        localeInfo.TARGET_BUTTON_AVENGE,
        localeInfo.TARGET_BUTTON_FRIEND,
        localeInfo.TARGET_BUTTON_INVITE_PARTY,
        localeInfo.TARGET_BUTTON_LEAVE_PARTY,
        localeInfo.TARGET_BUTTON_EXCLUDE,
        localeInfo.TARGET_BUTTON_INVITE_GUILD,
        localeInfo.TARGET_BUTTON_DISMOUNT,
        localeInfo.TARGET_BUTTON_EXIT_OBSERVER,
        localeInfo.TARGET_BUTTON_VIEW_EQUIPMENT,
        localeInfo.TARGET_BUTTON_REQUEST_ENTER_PARTY,
        localeInfo.TARGET_BUTTON_BUILDING_DESTROY,
        localeInfo.TARGET_BUTTON_EMOTION_ALLOW,
        "DUEL_CANCEL",
        "VOTE_BLOCK_CHAT",
    )


örnek

        self.buttonDict[localeInfo.TARGET_BUTTON_INVITE_GUILD].SAFE_SetEvent(self.__OnGuildAddMember)
        self.buttonDict[localeInfo.TARGET_BUTTON_DISMOUNT].SAFE_SetEvent(self.__OnDismount)
        self.buttonDict[localeInfo.TARGET_BUTTON_EXIT_OBSERVER].SAFE_SetEvent(self.__OnExitObserver)
        self.buttonDict[localeInfo.TARGET_BUTTON_VIEW_EQUIPMENT].SAFE_SetEvent(self.__OnViewEquipment)
        self.buttonDict[localeInfo.TARGET_BUTTON_REQUEST_ENTER_PARTY].SAFE_SetEvent(self.__OnRequestParty)
        self.buttonDict[localeInfo.TARGET_BUTTON_BUILDING_DESTROY].SAFE_SetEvent(self.__OnDestroyBuilding)
        self.buttonDict[localeInfo.TARGET_BUTTON_EMOTION_ALLOW].SAFE_SetEvent(self.__OnEmotionAllow)
        self.buttonDict["DUEL_CANCEL"].SetEvent(ui.__mem_func__(self.OnDuelCancel))
        self.buttonDict["VOTE_BLOCK_CHAT"].SetEvent(ui.__mem_func__(self.__OnVoteBlockChat))


örnek

    def RefreshButton(self):

        self.HideAllButton()

        if chr.INSTANCE_TYPE_BUILDING == chr.GetInstanceType(self.vid):
            return

        # PVP başladığında normalde butonlar gizlenir (return edilir).
        # "Duello Iptal" butonunun görünmesi için bu bloğu düzenliyoruz.
        if player.IsPVPInstance(self.vid):
            # PVP_INFO_SIZE_BUG_FIX
            self.SetSize(200 + 7*self.nameLength, 40)
            self.UpdatePosition()
           
            # PVP halindeyken sadece İptal butonunu göster
            self.__ShowButton("DUEL_CANCEL")
            self.__ArrangeButtonPosition()
            return # Diğer normal butonların (Ticaret, Grup vb.) yüklenmesini engeller

        if player.IsObserverMode():
            return

        self.ShowDefaultButton()

        if guild.MainPlayerHasAuthority(guild.AUTH_ADD_MEMBER):
            if not guild.IsMemberByName(self.nameString):
                if 0 == chr.GetGuildID(self.vid):
                    self.__ShowButton(localeInfo.TARGET_BUTTON_INVITE_GUILD)

        if not messenger.IsFriendByName(self.nameString):
            self.__ShowButton(localeInfo.TARGET_BUTTON_FRIEND)

        if player.IsPartyMember(self.vid):
            self.__HideButton(localeInfo.TARGET_BUTTON_FIGHT)
            if player.IsPartyLeader(self.vid):
                self.__ShowButton(localeInfo.TARGET_BUTTON_LEAVE_PARTY)
            elif player.IsPartyLeader(player.GetMainCharacterIndex()):
                self.__ShowButton(localeInfo.TARGET_BUTTON_EXCLUDE)
        else:
            if player.IsPartyMember(player.GetMainCharacterIndex()):
                if player.IsPartyLeader(player.GetMainCharacterIndex()):
                    self.__ShowButton(localeInfo.TARGET_BUTTON_INVITE_PARTY)
            else:
                if chr.IsPartyMember(self.vid):
                    self.__ShowButton(localeInfo.TARGET_BUTTON_REQUEST_ENTER_PARTY)
                else:
                    self.__ShowButton(localeInfo.TARGET_BUTTON_INVITE_PARTY)

            if player.IsRevengeInstance(self.vid):
                self.__HideButton(localeInfo.TARGET_BUTTON_FIGHT)
                self.__ShowButton(localeInfo.TARGET_BUTTON_AVENGE)
            elif player.IsChallengeInstance(self.vid):
                self.__HideButton(localeInfo.TARGET_BUTTON_FIGHT)
                self.__ShowButton(localeInfo.TARGET_BUTTON_ACCEPT_FIGHT)
            elif player.IsCantFightInstance(self.vid):
                self.__HideButton(localeInfo.TARGET_BUTTON_FIGHT)

            if not player.IsSameEmpire(self.vid):
                self.__HideButton(localeInfo.TARGET_BUTTON_INVITE_PARTY)
                self.__HideButton(localeInfo.TARGET_BUTTON_FRIEND)
                self.__HideButton(localeInfo.TARGET_BUTTON_FIGHT)

        distance = player.GetCharacterDistance(self.vid)
        if distance > self.EXCHANGE_LIMIT_RANGE:
            self.__HideButton(localeInfo.TARGET_BUTTON_EXCHANGE)

        self.__ArrangeButtonPosition()



en asagi
    def OnUpdate(self):
        if self.isShowButton:
            distance = player.GetCharacterDistance(self.vid)
            if distance < 0:
                return

            # Düello İptal Butonu Kontrolü
            # player.IsPVPInstance(self.vid) aktif bir düello olup olmadığını kontrol eder
            if player.IsPVPInstance(self.vid):
                if not self.buttonDict["DUEL_CANCEL"].IsShow():
                    self.RefreshButton() # Buton listesini yeniden yapılandır
            else:
                if self.buttonDict["DUEL_CANCEL"].IsShow():
                    self.RefreshButton() # Düello bittiyse butonu listeden çıkar ve hizala

            # Mesafe Kontrolü (Ticaret vb. butonlar için)
            exchangeButton = self.buttonDict[localeInfo.TARGET_BUTTON_EXCHANGE]
            if exchangeButton.IsShow():
                if distance > self.EXCHANGE_LIMIT_RANGE:
                    self.RefreshButton()
            else:
                if distance < self.EXCHANGE_LIMIT_RANGE:
                    self.RefreshButton()
                   
    def OnDuelCancel(self):
        import net
        if self.vid == 0: # Eğer hedef seçili değilse işlem yapma
            return
           
        # HATA BURADAYDI: Komutun yanına boşluk bırakıp VID değerini eklemelisin
        # Eğer cmd.cpp'de "duello_iptal" yaptıysan onu yaz:
        # net.SendChatPacket("/duello_iptal %d" % int(self.vid))
       
        # Eğer cmd.cpp'de ismi "/do_pvp_cancel_request" yaptıysan (ki genelde yapılmaz):
        net.SendChatPacket("/do_pvp_cancel_request %d" % int(self.vid))


 

Ekli dosyalar

  • root.rar
    19.1 KB · Görüntüleme: 0
  • Desktop.rar
    26.6 KB · Görüntüleme: 0
Moderatör tarafında düzenlendi:
Kod:
        ch->SetQuestNPCID(0);
        requester->SetQuestNPCID(0);

burada yapılan işlem item kopyalamaya bile neden olabilir
 
Kod:
        ch->SetQuestNPCID(0);
        requester->SetQuestNPCID(0);

burada yapılan işlem item kopyalamaya bile neden olabilir
birşey sorcaktım.

.msa ları server taraflı nasıl okutabilirim.

örneğin saldırı yaparken kullanılan .msaları 6. skilie eklyicem.
msalrıda server taraflı okutucucam

client sadece render yapıcak.

6. skill örnek
 
birşey sorcaktım.

.msa ları server taraflı nasıl okutabilirim.

örneğin saldırı yaparken kullanılan .msaları 6. skilie eklyicem.
msalrıda server taraflı okutucucam

client sadece render yapıcak.

6. skill örnek
"#ifdef OFFLINE_FARM" arat
 

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

Geri
Üst