Hikayeler

Reklam vermek için turkmmo@gmail.com

Target Info - Scrollbar Yerine Grid (Kutu) Görünümü (Syserr Fixli)

Cankira

Cankira
Telefon Numarası Onaylanmış Üye TC Kimlik Numarası Doğrulanmış Üye
Moderator
Admin
Paylaşım
Katılım
18 Ağu 2009
Konular
143
Mesajlar
859
Online süresi
13g 60386s
Reaksiyon Skoru
228
Altın Konu
19
Başarım Puanı
171
TM Yaşı
16 Yıl 8 Ay 8 Gün
MmoLira
6,196
DevLira
6

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

[Python] Target Info - Scrollbar Yerine Grid (Kutu) Görünümü (Syserr Fixli)

Selamlar herkese,

Bildiğiniz gibi forumda paylaşılan detaylı mob target info sistemi (orijinal konu için tıklayın) standart olarak scrollbar (aşağı kaydırmalı) liste şeklinde geliyor. Bana bu yapı biraz hantal geldiği için geçenlerde şu konumda bunu grid (kutu) sistemine nasıl geçirebileceğimi sormuştum.

Konu içindeki açıklamalar ile uitarget.py de değişiklikler yapmaya çalıştım fakat eksiklikler nedeni ile düzenleme gerçekleşmedi.
İnternette dolaşan bazı eksik/yarım kodlarla yapmaya çalıştığımda itemlerin üzerine gelince Tooltip (OverInItem) yüzünden sürekli syserr patlatıyordu ve itemler düzgün oturmuyordu. Oturup sistemi düzenledim. ui.ListBoxExNew ve ui.ScrollBar yapısını tamamen söktüm, yerine 7x7 (49 slot) sorunsuz bir grid sistemi entegre ettim.

Benim gibi bu görünüme geçmek isteyip syserr ile boğuşanlar veya görünümü değiştirmek isteyenler için tam çözümü paylaşıyorum. Güle güle kullanın.

(GÜNCELLEME: Dinamik Grid Yüksekliği ve Akıllı İtem Sıralaması) konunun sonunda.


ESKİ GÖRÜNÜM:
Ekran görüntüsü 2026-03-22 012558.png


YENİ GÖRÜNÜM:
1774132223195.png



Düzenlenecek Dosya: root/uitarget.py

UYARI: Kopyala-yapıştır yaparken Notepad++ veya Visual Studio Code kullanın ve satır başlarındaki boşlukların "Tab" olduğuna emin olun. Biliyorsunuz Python girinti konusunda hiç affetmez, direkt syserr atar.



Adım 1: Grid Altyapısını Kurma
Önce listbox yerine kullanacağımız 49 slotluk grid altyapısını ve arrayleri tanımlıyoruz.

Arat (__init__ fonksiyonu içinde):
Python:
                self.stoneImg = None
                self.stoneVnum = None
                self.lastStoneVnum = 0
                self.nextStoneIconChange = 0

                self.SetSize(self.BOARD_WIDTH, 0)

Değiştir:
Python:
                self.stoneImg = None
                self.stoneVnum = None
                self.lastStoneVnum = 0
                self.nextStoneIconChange = 0

                # Yeni Grid (Kutu) Sistemi Altyapısı
                self.itemArray = [0] * 49
                self.itemVnums = [0] * 49

                self.wndItem = ui.GridSlotWindow()
                self.wndItem.SetParent(self)
                self.wndItem.ArrangeSlot(0, 7, 7, 32, 32, 0, 0)
                self.wndItem.RefreshSlot()
                self.wndItem.SetSlotBaseImage("d:/ymir work/ui/public/Slot_Base.sub", 1.0, 1.0, 1.0, 1.0)
                self.wndItem.SetOverInItemEvent(ui.__mem_func__(self.OverInItem))
                self.wndItem.SetOverOutItemEvent(ui.__mem_func__(self.OnHideItemTooltip))
                self.wndItem.Hide()

                self.SetSize(self.BOARD_WIDTH, 0)




Adım 2: Slotları Temizleme
Farklı bir moba tıkladığımızda eski mobun itemlerinin ekranda kalmaması için gridi sıfırlıyoruz.

Arat (__LoadInformation fonksiyonu içinde):
Python:
                self.stoneImg = None
                self.stoneVnum = None
                self.nextStoneIconChange = 0

                self.__LoadInformation_Default(race)

Değiştir:
Python:
                self.stoneImg = None
                self.stoneVnum = None
                self.nextStoneIconChange = 0

                # Grid hafızasını ve kutularını temizle
                self.itemArray = [0] * 49
                self.itemVnums = [0] * 49
                for i in xrange(49):
                    self.wndItem.ClearSlot(i)

                self.__LoadInformation_Default(race)




Adım 3: Boş Yer Arama Fonksiyonu
İtem boyutuna (zırh, kılıç vb.) göre yerleşeceği uygun boş slotu bulacak fonksiyonumuz.

Arat:
Python:
            def __LoadInformation_Drops(self, race):

Üstüne Ekle:
Python:
            def SearchEmptySlot(self, size):
                # İtemlerin 1, 2 veya 3 slotluk yerlerine göre boşluk arar
                for i in xrange(49):
                    if self.itemArray[i] == 0:
                        if size == 1:
                            return i
                        elif size == 2:
                            if i + 7 < 49 and self.itemArray[i+7] == 0:
                                return i
                        elif size == 3:
                            if i + 14 < 49 and self.itemArray[i+7] == 0 and self.itemArray[i+14] == 0:
                                return i
                return -1




Adım 4: İtemleri Gride Dizme
Burada eski sistemdeki o uzun scrollbar hesaplamalarını silip atıyoruz.

Arat (__LoadInformation_Drops fonksiyonu içinde else: bloğunu bul):
Python:
                    else:
                        itemListBox = ui.ListBoxExNew(32 + 5, self.MAX_ITEM_COUNT)
(Not: else: bloğunun başından self.AppendTextLine(localeInfo.TARGET_INFO_NO_ITEM_TEXT) kısmına kadar olan eski ListBox/Scrollbar kodlarını komple silebilirsiniz. Aşağıdaki kodla değiştireceğiz.)

Değiştir (else: bloğu komple şu şekilde olacak):
Python:
                    else:
                        # Grid penceresini konumlandır
                        self.wndItem.SetPosition(13, self.yPos - 7)
                        self.yPos += 32*7 + 5
                        self.SetSize(self.BOARD_WIDTH, self.yPos + 5)
                        self.UpdateRect()
                        self.wndItem.Show()

                        for curItem in constInfo.MONSTER_INFO_DATA[race]["items"]:
                            getItemID = 0
                            if curItem.has_key("vnum_list"):
                                getItemID = curItem["vnum_list"][0]
                                vnum = curItem["vnum_list"][0]
                            else:
                                getItemID = curItem["vnum"]
                                vnum=curItem["vnum"]

                            getItemCount=curItem["count"]
                            item.SelectItem(getItemID)
                            itemSize = item.GetItemSize()

                            if item.GetItemType() == item.ITEM_TYPE_METIN:
                                self.stoneVnum = getItemID
                                self.lastStoneVnum = 28430

                            # Boş yeri bul ve eşyayı oraya oturt
                            emptySlotPos = self.SearchEmptySlot(itemSize[1])

                            if -1 != emptySlotPos:
                                self.itemArray[emptySlotPos] = 1 # Slotu dolu olarak işaretle

                                if itemSize[1] == 2:
                                    self.itemArray[emptySlotPos + 7] = 1
                                elif itemSize[1] == 3:
                                    self.itemArray[emptySlotPos + 7] = 1
                                    self.itemArray[emptySlotPos + 14] = 1

                                if item.GetItemType() == item.ITEM_TYPE_METIN:
                                    self.stoneImg = emptySlotPos

                                # Eşyayı Grid üzerine çiz
                                self.wndItem.SetItemSlot(emptySlotPos, getItemID, getItemCount)
                                self.itemVnums[emptySlotPos] = getItemID

                        self.wndItem.RefreshSlot()




Adım 5: Tooltip Syserr Çözümü
En sinir bozucu kısım burasıydı. "OverInItem() takes exactly 2 arguments (1 given)" hatasının kesin çözümü.

Arat:
Python:
            def OnShowItemTooltip(self, vnum):

Üstüne Ekle:
Python:
            def OverInItem(self, slotIndex):
                # Üzerine gelinen spesifik slotun (kutunun) içindeki item idsini bulur
                vnum = self.itemVnums[slotIndex]
                if vnum != 0:
                    self.OnShowItemTooltip(vnum)

Arat:
Python:
            def OnHideItemTooltip(self):
                self.itemTooltip.HideToolTip()

Değiştir:
Python:
            # Olası fazla argüman gönderimine karşı *args eklendi
            def OnHideItemTooltip(self, *args):
                self.itemTooltip.HideToolTip()




İşlem bu kadar beyler. Dosyayı kaydedip packi kapatabilirsiniz.
Takıldığınız veya syserr aldığınız bir yer olursa konunun altına yazabilirsiniz.





GÜNCELLEME: Dinamik Grid Yüksekliği ve Akıllı İtem Sıralaması

Konuya gelen güzel öneriler üzerine sistemi daha da profesyonel ve kusursuz bir hale getirdim! Yorum atan, fikir veren herkese teşekkürler.

Neler Eklendi / Değişti?
1. Dinamik Yükseklik: 49 slotluk alan yerine artık item kadar slot sırası görünüyor.
2. Akıllı Sıralama: Artık sistem itemleri boyutuna göre sıralıyor. Önce 3 slotluk (silah/zırh) itemleri en üste yerleştiriyor, ardından 2 slotlukları diziyor ve en son kalan boşluklara 1 slotluk (taş, bk, yüzük vs.) itemleri dolduruyor.

Aşağıdaki adımları uygulayarak eski grid kodunuzu bu yeni "Akıllı" sürümle güncelleyebilirsiniz.




Kurulum (Güncelleme Adımı)
Dosya: root/uitarget.py

Arat (Fonksiyonu komple seçin):
Python:
            def __LoadInformation_Drops(self, race):
(İpucu: def __LoadInformation_Drops(self, race): satırından başlayıp fonksiyonun en sonundaki self.wndItem.Hide() kısmına kadar olan tüm bloğu silin.)

Değiştir (Aşağıdaki yeni kodla):
Python:
            def __LoadInformation_Drops(self, race):
                self.AppendSeperator()

                if race in constInfo.MONSTER_INFO_DATA:
                    if len(constInfo.MONSTER_INFO_DATA[race]["items"]) == 0:
                        self.AppendTextLine(localeInfo.TARGET_INFO_NO_ITEM_TEXT)
                        self.wndItem.Hide()
                    else:
                        # 1. Aşama: İtemleri Boyutlarına Göre Sırala (Büyükler Başa, Küçükler Sona)
                        itemList = []
                        for curItem in constInfo.MONSTER_INFO_DATA[race]["items"]:
                            getItemID = curItem["vnum_list"][0] if curItem.has_key("vnum_list") else curItem["vnum"]
                            item.SelectItem(getItemID)
                            itemSize = item.GetItemSize()[1]
                           
                            # Öncelik 1: 3 Slot (Silah/Zırh) | Öncelik 2: 2 Slot | Öncelik 3: 1 Slot (Taş, BK, Yüzük)
                            priority = 3
                            if itemSize == 3:
                                priority = 1
                            elif itemSize == 2:
                                priority = 2
                            elif itemSize == 1:
                                priority = 3
                               
                            # Sözlük (dictionary) karşılaştırması hatasını önlemek için araya getItemID ekliyoruz.
                            itemList.append((priority, getItemID, curItem))
                           
                        itemList.sort() # Önceliğe göre listeyi düzenle (Çöpler sona gitti)
                       
                        # 2. Aşama: İtemleri Sanal Olarak Diz ve Dinamik Satır Sayısını (max_row) Bul
                        packed_items = []
                        max_row = 1
                       
                        for priority, getItemID, curItem in itemList:
                            getItemID = curItem["vnum_list"][0] if curItem.has_key("vnum_list") else curItem["vnum"]
                            getItemCount = curItem["count"]
                           
                            item.SelectItem(getItemID)
                            itemSize = item.GetItemSize()[1]
                           
                            emptySlotPos = self.SearchEmptySlot(itemSize)
                           
                            if emptySlotPos != -1:
                                self.itemArray[emptySlotPos] = 1 # Slotu dolu olarak işaretle
                                if itemSize == 2:
                                    self.itemArray[emptySlotPos + 7] = 1
                                elif itemSize == 3:
                                    self.itemArray[emptySlotPos + 7] = 1
                                    self.itemArray[emptySlotPos + 14] = 1
                                   
                                packed_items.append((emptySlotPos, getItemID, getItemCount))
                                self.itemVnums[emptySlotPos] = getItemID
                               
                                # Kullanılan en son satırı hesapla
                                bottom_slot = emptySlotPos + 7 * (itemSize - 1)
                                row = (bottom_slot / 7) + 1
                                if row > max_row:
                                    max_row = row
                                   
                        # 3. Aşama: Grid'i Sadece İhtiyaç Duyulan Satır Kadar (Dinamik) Oluştur
                        self.wndItem.ArrangeSlot(0, 7, max_row, 32, 32, 0, 0)
                        self.wndItem.RefreshSlot()
                        self.wndItem.SetSlotBaseImage("d:/ymir work/ui/public/Slot_Base.sub", 1.0, 1.0, 1.0, 1.0)
                       
                        self.wndItem.SetPosition(13, self.yPos - 7)
                        self.yPos += 32 * max_row + 5
                        self.SetSize(self.BOARD_WIDTH, self.yPos + 5)
                        self.UpdateRect()
                        self.wndItem.Show()
                       
                        # 4. Aşama: Paketlenmiş İtemleri Ekrana Çiz
                        for emptySlotPos, getItemID, getItemCount in packed_items:
                            item.SelectItem(getItemID)
                            if item.GetItemType() == item.ITEM_TYPE_METIN:
                                self.stoneVnum = getItemID
                                self.lastStoneVnum = 28430
                                self.stoneImg = emptySlotPos
                               
                            self.wndItem.SetItemSlot(emptySlotPos, getItemID, getItemCount)
                           
                        self.wndItem.RefreshSlot()
                else:
                    self.AppendTextLine(localeInfo.TARGET_INFO_NO_ITEM_TEXT)
                    self.wndItem.Hide()

Oyuna girip çok eşya atan veya az eşya atan canavarlara tıkladığınızda pencerenin ne kadar akıllı çalıştığını görebilirsiniz. İyi kullanımlar!
 
Son düzenleme:

En Çok Reaksiyon Alan Mesajlar

Teşekkürler.
 
İşime yaradı hocam, üzerine itemleri itemtype'a göre tersten sıralayınca çer çöp itemler (zırh silah iç item
falan) gridin en sonunda çıkıyor öneririm. Ayrıca sabit 7x7 lik grid oluşturmak yerine dynamic gibi yapabilirsin, önce itemleri sıralayıp sonra boş rowları silerek.
 
PAYLAŞIM İÇİN TEŞEKKÜRLER,ELİNE SAĞLIK.
 
İşime yaradı hocam, üzerine itemleri itemtype'a göre tersten sıralayınca çer çöp itemler (zırh silah iç item
falan) gridin en sonunda çıkıyor öneririm. Ayrıca sabit 7x7 lik grid oluşturmak yerine dynamic gibi yapabilirsin, önce itemleri sıralayıp sonra boş rowları silerek.
Çok haklısın. İlk müsait anımda konuyu güncelleyeceğim. Teşekkür ederim.
 

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

Geri
Üst