- Katılım
- 30 Ocak 2026
- Konular
- 42
- Mesajlar
- 449
- Online süresi
- 2g 51924s
- Reaksiyon Skoru
- 261
- Altın Konu
- 0
- Başarım Puanı
- 73
- TM Yaşı
- 2 Ay 19 Gün
- MmoLira
- 4,019
- DevLira
- 18
Metin2 EP, Valorant VP dahil tüm oyun ürünlerini en uygun fiyatlarla bulabilir, Item ve Karakterlerinizi hızlıca satabilirsiniz. HEMEN TIKLA!
Paylaşım İçin Teşekkürler.
- Katılım
- 9 Kas 2011
- Konular
- 2
- Mesajlar
- 8
- Online süresi
- 8043s
- Reaksiyon Skoru
- 5
- Altın Konu
- 0
- Başarım Puanı
- 72
- TM Yaşı
- 14 Yıl 5 Ay 14 Gün
- MmoLira
- 147
- DevLira
- 0
teşekkürler
- Katılım
- 5 Eki 2015
- Konular
- 97
- Mesajlar
- 2,113
- Online süresi
- 1ay 21g
- Reaksiyon Skoru
- 3,359
- Altın Konu
- 2
- Başarım Puanı
- 253
- TM Yaşı
- 10 Yıl 6 Ay 18 Gün
- MmoLira
- 18,400
- DevLira
- 61
Paylaşım için teşekkürler geliştirmeye açık
- Katılım
- 13 Mar 2026
- Konular
- 8
- Mesajlar
- 60
- Online süresi
- 79115s
- Reaksiyon Skoru
- 12
- Altın Konu
- 0
- Başarım Puanı
- 12
- TM Yaşı
- 1 Ay 6 Gün
- MmoLira
- 905
- DevLira
- 0
VezirSOFT — GM Edit Paneli Kurulum Rehberi
Linkleri görebilmek için Turkmmo Forumuna ÜYE olmanız gerekmektedir.
1) İşlem sırası (özet)
- Sunucu: cmd.cpp → ön bildirim + cmd_info satırı → cmd_gm.cpp → derle
- İstemci: uigmitempanel.py + gmpanel_item.py → interfacemodule.py → game.py → root paketle
2) Sunucu — cmd.cpp
Adım A1 — Ön bildirim
Ne yapıyoruz: Derleyiciye do_item_gm7 fonksiyonunun varlığını bildiriyoruz.
Ara:Kod:ACMD(do_item);
Bulacağın örnek:
Kod:ACMD(do_item); ACMD(do_mob);
Yap:satırının hemen altına ekle:Kod:ACMD(do_item);
Kod:ACMD(do_item_gm7);
Adım A2 — Komut tablosu
Ne yapıyoruz: Sohbette /item7 yazılınca hangi fonksiyon ve GM seviyesi çalışacak, cmd_info[] içine yazıyoruz.
Ara:Kod:{ "item", do_item,
Bulacağın örnek:
Kod:{ "item", do_item, 0, POS_DEAD, GM_GOD }, { "mob", do_mob, 0, POS_DEAD, GM_HIGH_WIZARD },
Yap: item satırının altına ekle:
Not: GM seviyesini kendi sunucuna göre (ör. GM_IMPLEMENTOR) değiştirebilirsin.Kod:{ "item7", do_item_gm7, 0, POS_DEAD, GM_GOD },
3) Sunucu — cmd_gm.cpp
Ne yapıyoruz: /item7 gövdesi: vnum veya isim, adet, ITEM_ATTRIBUTE_MAX_NUM kadar (tip, değer) çifti, ITEM_SOCKET_MAX_NUM kadar socket, CreateItem, SetForceAttribute, SetSocket, AutoGiveItem, log.
Ara:— klasik GM item komutu (vnum + adet).Kod:ACMD(do_item)
Nereye: do_item fonksiyonunun kapatanile bir sonrakiKod:}satırı arasına aşağıdaki bloğun tamamını yapıştır.Kod:ACMD(do_...)
Kod:ACMD(do_item_gm7) { const char * line = argument; char arg[256]; line = one_argument(line, arg, sizeof(arg)); if (!*arg) { ch->ChatPacket(CHAT_TYPE_INFO, "Usage: item7 <vnum|name> <count> [tip0 val0] x7 [socket0 socket1 socket2] (tas vnum, 0=bos)"); return; } DWORD dwVnum = 0; if (isnhdigit(*arg)) str_to_number(dwVnum, arg); else if (!ITEM_MANAGER::instance().GetVnum(arg, dwVnum)) { ch->ChatPacket(CHAT_TYPE_INFO, "Item bulunamadi: %s", arg); return; } line = one_argument(line, arg, sizeof(arg)); int iCount = 1; if (*arg) { str_to_number(iCount, arg); iCount = MINMAX(1, iCount, g_bItemCountLimit); } long attr_type[ITEM_ATTRIBUTE_MAX_NUM]; long attr_val[ITEM_ATTRIBUTE_MAX_NUM]; memset(attr_type, 0, sizeof(attr_type)); memset(attr_val, 0, sizeof(attr_val)); for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i) { line = one_argument(line, arg, sizeof(arg)); if (!*arg) break; str_to_number(attr_type[i], arg); line = one_argument(line, arg, sizeof(arg)); if (!*arg) break; str_to_number(attr_val[i], arg); } LPITEM item = ITEM_MANAGER::instance().CreateItem(dwVnum, iCount, 0, true); if (!item) { ch->ChatPacket(CHAT_TYPE_INFO, "item7: #%u olusturulamadi.", dwVnum); return; } for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i) item->SetForceAttribute(i, (BYTE) attr_type[i], (short) attr_val[i]); long socket_val[ITEM_SOCKET_MAX_NUM]; memset(socket_val, 0, sizeof(socket_val)); for (int s = 0; s < ITEM_SOCKET_MAX_NUM; ++s) { line = one_argument(line, arg, sizeof(arg)); if (*arg) str_to_number(socket_val[s], arg); } for (int s = 0; s < ITEM_SOCKET_MAX_NUM; ++s) item->SetSocket(s, socket_val[s]); #ifdef __WJ_PICKUP_ITEM_EFFECT__ ch->AutoGiveItem(item, false, true); #else ch->AutoGiveItem(item, false); #endif LogManager::instance().ItemLog(ch, item, "GM_ITEM7", item->GetName()); ch->ChatPacket(CHAT_TYPE_INFO, "item7: %s verildi.", item->GetName()); }
Derleme: cmd_gm.cpp zaten projendeyse ekstra .cpp ekleme; game core’u yeniden derle.
Ek dosya: Birçok sürümde cmd.h içinde ayrıca tanım gerekmez; ön bildirimler cmd.cpp içindeki ACMD(...) satırlarıyla gider.
4) İstemci — uigmitempanel.py
Ne yapıyoruz: Panel mantığı: arama, 7 efsun + 3 taş, açılır liste (alt satır gizleme), /item7 satırını net.SendChatPacket ile gönderme.
Yol:Kod:pack/root/uigmitempanel.py
Yap: Aşağıdaki spoiler içindeki metni uigmitempanel.py dosyasına komple yapıştır (UTF-8 veya cp1254, sunucu diline göre).
Kod:# -*- coding: utf-8 -*- import ui import net import player import chr import chat import app import item import localeInfo def _wnd_text(s): """WndMgr genelde byte string ister; unicode kaynakli 'Nesne' kalmasini onler.""" if s is None: return "" if isinstance(s, str): return s if isinstance(s, unicode): try: return s.encode("cp1254") except UnicodeEncodeError: return s.encode("utf-8", "replace") return str(s) def _short_label(s): if not isinstance(s, basestring): s = str(s) if len(s) > 52: return s[:49] + "..." return s COMBO_DROP_MAX_H = 240 class GmComboBox(ui.ComboBox): """Satirda acilir secilebilir liste (Metin2 ComboBox).""" MAX_DROP = COMBO_DROP_MAX_H def __init__(self): # ComboBox.__init__ listeyi TOP_MOST'ta acar; Board cocuklari UI katmaninda # sonra cizildigi icin liste gorunurde altta kalir. Liste UI katmaninda olmali. ui.Window.__init__(self) self.x = 0 self.y = 0 self.width = 0 self.height = 0 self.isSelected = False self.isOver = False self.isListOpened = False self.event = lambda *arg: None self.enable = True self.textLine = ui.MakeTextLine(self) self.textLine.SetText(localeInfo.UI_ITEM) self.listBox = ui.ComboBox.ListBoxWithBoard("UI") self.listBox.SetPickAlways() self.listBox.SetParent(self) self.listBox.SetEvent(ui.__mem_func__(self.OnSelectItem)) self.listBox.Hide() self._gm_z_panel = None self._gm_z_kind = None self._gm_z_idx = 0 try: self.listBox.AddFlag("float") except Exception: pass if app.ENABLE_MOUSEWHEEL_EVENT: try: self.listBox.SetMouseWheelScrollEvent(ui.__mem_func__(self._on_combo_list_wheel)) except Exception: pass def SetGmDropdownShield(self, panel, kind, index): """kind: 'attr' | 'stone' — acilir liste acikken alt satirlar panel tarafindan gizlenir.""" self._gm_z_panel = panel self._gm_z_kind = kind self._gm_z_idx = index def _on_combo_list_wheel(self, mode): if not self.isListOpened: return n = self.listBox.GetItemCount() v = max(1, self.listBox.GetViewItemCount()) mx = max(0, n - v) if mx <= 0: return bp = getattr(self.listBox, "basePos", 0) if mode == "UP": bp = max(0, bp - 1) else: bp = min(mx, bp + 1) self.listBox.SetBasePos(bp) def CloseListBox(self): self.isListOpened = False p = getattr(self, "_gm_z_panel", None) if p: try: p.OnGmComboDropdownClose(self) except Exception: pass if self.listBox: self.listBox.Hide() def OnSelectItem(self, index, name): self.CloseListBox() self.SetCurrentItem(_wnd_text(_short_label(name))) self.event(index) def InsertItem(self, index, name): self.listBox.InsertItem(index, name) n = self.listBox.GetItemCount() step = getattr(self.listBox, "stepSize", 17) h = min(max(n * step, 17), self.MAX_DROP) self.listBox.SetSize(self.width, h) self.listBox._LocateItem() def OnMouseLeftButtonUp(self): if not self.enable: return self.isSelected = False if self.isListOpened: self.CloseListBox() else: if self.listBox.GetItemCount() > 0: p = getattr(self, "_gm_z_panel", None) if p: try: p.OnGmComboDropdownOpen(self) except Exception: pass self.isListOpened = True self.listBox.Show() self.__ArrangeListBox() try: self.listBox.SetTop() except Exception: pass # --- Ayarlar --- MAX_ARAMA_SONUC = 50 ATTR_SATIR = 7 TAS_SOCKET_SAYISI = 3 ATTR_ROW_STEP = 26 # Sunucu APPLY tipi (byte) = ilk sütun; isimler sabit TR (uitooltip yerine) GM_APPLY_OPTIONS = ( (0, u"- Efsun yok -"), (1, u"Maximum HP"), (2, u"Maximum MP"), (3, u"Ya\u015fam Enerjisi"), (4, u"G\xfc\xe7"), (5, u"Dayan\u0131kl\u0131l\u0131k"), (6, u"\xc7eviklik"), (7, u"Sald\u0131r\u0131 H\u0131z\u0131"), (8, u"Hareket H\u0131z\u0131"), (9, u"B\xfcy\xfc H\u0131z\u0131"), (10, u"Hp \xdcretimi"), (11, u"MP \xdcretimi"), (12, u"Zehirlenme De\u011fi\u015fimi"), (13, u"Sersemletme \u015eans\u0131"), (14, u"Yava\u015fl\u0131k De\u011fi\u015fimi"), (15, u"Kritik Vuru\u015f \u015eans\u0131"), (16, u"Delici Vuru\u015f \u015eans\u0131"), (17, u"Yar\u0131 \u0130nsana Kar\u015f\u0131 G\xfc\xe7l\xfc"), (18, u"Hayvanlara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (19, u"Orklara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (20, u"Misiklere Kar\u015f\u0131 G\xfc\xe7l\xfc"), (21, u"\xd6l\xfcms\xfczlere Kar\u015f\u0131 G\xfc\xe7l\xfc"), (22, u"\u015eytanlara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (23, u"%? Hasar Hp Taraf\u0131ndan Emilecek"), (24, u"%? Hasar Mp Taraf\u0131ndan Emilecek"), (25, u"D\xfc\u015fmandan Sp \xe7alma \u015eans\u0131"), (26, u"%? Vururken Sp Alma \u015eans\u0131"), (27, u"Beden Kar\u015f\u0131s\u0131nda Atak Bloklanmas\u0131"), (28, u"Oklardan Korunma \u015eans\u0131"), (29, u"K\u0131l\u0131\xe7 Savunmas\u0131"), (30, u"\xc7ift El Savunma"), (31, u"Han\xe7er Savunmas\u0131"), (32, u"\xc7an Savunmas\u0131"), (33, u"Yelpaze Savunmas\u0131"), (34, u"Oka Kar\u015f\u0131 Dayan\u0131kl\u0131l\u0131k"), (35, u"Ate\u015fe Kar\u015f\u0131 Dayan\u0131kl\u0131l\u0131k"), (36, u"\u015eim\u015fek Kar\u015f\u0131 Dayan\u0131kl\u0131l\u0131k"), (37, u"B\xfcy\xfcye Kar\u015f\u0131 Dayan\u0131kl\u0131l\u0131k"), (38, u"R\xfczgara Kar\u015f\u0131 Dayan\u0131kl\u0131l\u0131k"), (39, u"V\xfccut Darbelerini Yans\u0131tma \u015eans\u0131"), (40, u"Lanet Yans\u0131tmas\u0131"), (41, u"Giftwiderstand"), (42, u"Sp Y\xfcklemesi %? De\u011fi\u015fti"), (43, u"%? Exp Bonus \u015eans\u0131"), (44, u"% Kat Yang D\xfc\u015fme \u015eans\u0131"), (45, u"% Kat E\u015fya d\xfc\u015fme \u015eans\u0131"), (46, u"\u0130ksir %? Etki G\xf6sterdi"), (47, u"Hp Y\xfcklemesi %? De\u011fi\u015fti"), (48, u"Sersemlik Ba\u011f\u0131\u015f\u0131kl\u0131k"), (49, u"Yava\u015flatma Ba\u011f\u0131\u015f\u0131kl\u0131k"), (50, u"Yere D\xfc\u015fme Ba\u011f\u0131\u015f\u0131kl\u0131k"), (51, u"UNKNOW_TYPE[51]"), (52, u"Yay Menzili +? Metre"), (53, u"Sald\u0131r\u0131 De\u011feri +"), (54, u"Savunma +"), (55, u"B\xfcy\xfcl\xfc Sald\u0131r\u0131 De\u011feri +"), (56, u"B\xfcy\xfcl\xfc Savunma De\u011feri +"), (57, u"UNKNOW_TYPE[57]"), (58, u"Max. Dayan\u0131kl\u0131l\u0131k"), (59, u"Sava\u015f\xe7\u0131lara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (60, u"Ninjalara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (61, u"Suralara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (62, u"\u015eamanlara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (63, u"Yarat\u0131klara Kar\u015f\u0131 G\xfc\xe7l\xfc"), (64, u"Sald\u0131r\u0131 De\u011feri +?%"), (65, u"Savunma +?%"), (66, u"EXP +?%"), (67, u"Elde Edilen Nesne Kat Say\u0131s\u0131"), (68, u"Elde Edilen Yang Kat Say\u0131s\u0131"), (69, u"UNKNOW_TYPE[69]"), (70, u"UNKNOW_TYPE[70]"), (71, u"Beceri Hasar\u0131"), (72, u"Ortalama Zarar"), (73, u"Tekrarlanan Beceri Hasar\u0131na Kar\u015f\u0131 Koyma"), (74, u"Ortalama Zarara Direni\u015f"), (75, u"UNKNOW_TYPE[75]"), (76, u"\u0130cafe Exp Bonus +?%"), (77, u"E\u015fya Ele Ge\xe7irme Art\u0131\u015f\u0131 ?/2"), (78, u"Sava\u015f\xe7\u0131 Sald\u0131r\u0131lar\u0131na Kar\u015f\u0131 Savunma \u015eans\u0131"), (79, u"Ninja Sald\u0131r\u0131lar\u0131na Kar\u015f\u0131 Savunma \u015eans\u0131"), (80, u"Sura Sald\u0131r\u0131lar\u0131na Kar\u015f\u0131 Savunma \u015eans\u0131"), (81, u"\u015eaman Sald\u0131r\u0131lar\u0131na Kar\u015f\u0131 Savunma \u015eans\u0131"), ) _itemdesc_cache = None def _load_itemdesc(): global _itemdesc_cache if _itemdesc_cache is not None: return _itemdesc_cache _itemdesc_cache = {} path = app.GetLocalePath() + "/itemdesc.txt" try: f = open(path, "r") except IOError: return _itemdesc_cache for line in f: line = line.strip() if not line or line.startswith("#"): continue parts = line.split("\t") if len(parts) < 2: continue try: vid = int(parts[0].strip()) name = parts[1].strip() if name: _itemdesc_cache[vid] = name except ValueError: continue f.close() return _itemdesc_cache def _build_apply_list(): return list(GM_APPLY_OPTIONS) def _build_metin_list(desc_dict): out = [(0, "- Tas yok -")] for vnum, name in sorted(desc_dict.iteritems(), key=lambda x: x[1].lower()): if item.IsMetin(vnum): out.append((vnum, "%s (%d)" % (name, vnum))) return out def _search_items(desc_dict, needle, limit): if not needle: return [] n = needle.lower() res = [] for vnum, name in desc_dict.iteritems(): if n in name.lower(): res.append((vnum, name)) res.sort(key=lambda x: x[1].lower()) return res[:limit] class GmItemPanel(ui.ScriptWindow): def __init__(self): ui.ScriptWindow.__init__(self) self.board = None self.searchEdit = None self.resultList = None self.selectedLabel = None self.countEdit = None self.spawnBtn = None self.cancelBtn = None self.btnSearch = None self.previewImg = None self.selectedVnum = 0 self._attr_apply = [0] * ATTR_SATIR self._stone_vnum = [0] * TAS_SOCKET_SAYISI self._attr_combos = [] self._attr_val_edits = [] self._attr_pct_edits = [] self._stone_combos = [] self._apply_items = [] self._metin_items = [] self.resultScroll = None self._dyn = [] self._attr_row_blocks = [] self._stone_row_blocks = [] self._stone_title_line = None self._gm_footer_btns = [] self._gm_dd_hidden = [] def __del__(self): ui.ScriptWindow.__del__(self) def _dyn_add(self, w): self._dyn.append(w) def _gm_dd_restore(self): for w in getattr(self, "_gm_dd_hidden", []): try: w.Show() except Exception: pass self._gm_dd_hidden = [] def OnGmComboDropdownClose(self, opener=None): self._gm_dd_restore() def OnGmComboDropdownOpen(self, opener): for cb in self._attr_combos + self._stone_combos: if cb is not opener and getattr(cb, "isListOpened", False): try: cb.CloseListBox() except Exception: pass self._gm_dd_restore() self._gm_dd_hidden = [] k = getattr(opener, "_gm_z_kind", None) idx = getattr(opener, "_gm_z_idx", 0) to_hide = [] if k == "attr": for j in xrange(idx + 1, ATTR_SATIR): to_hide.extend(self._attr_row_blocks[j]) if self._stone_title_line: to_hide.append(self._stone_title_line) for blk in self._stone_row_blocks: to_hide.extend(blk) to_hide.extend(self._gm_footer_btns) elif k == "stone": for j in xrange(idx + 1, TAS_SOCKET_SAYISI): to_hide.extend(self._stone_row_blocks[j]) to_hide.extend(self._gm_footer_btns) for w in to_hide: if w is None: continue try: w.Hide() self._gm_dd_hidden.append(w) except Exception: pass def LoadWindow(self): try: py = ui.PythonScriptLoader() py.LoadScriptFile(self, "uiscript/gmpanel_item.py") except: import exception exception.Abort("GmItemPanel.LoadWindow") try: self.board = self.GetChild("Board") self.searchEdit = self.GetChild("SearchEdit") self.resultList = self.GetChild("ResultList") self.selectedLabel = self.GetChild("SelectedLabel") self.countEdit = self.GetChild("CountValue") self.spawnBtn = self.GetChild("SpawnButton") self.cancelBtn = self.GetChild("CancelButton") self.btnSearch = self.GetChild("SearchButton") self.btnSearch.SetEvent(ui.__mem_func__(self.OnSearch)) self.resultScroll = self.GetChild("ResultScrollBar") except: import exception exception.Abort("GmItemPanel.Bind") self.resultScroll.SetScrollBarSize(100) self.resultScroll.SetScrollEvent(ui.__mem_func__(self._on_result_scroll)) if app.ENABLE_MOUSEWHEEL_EVENT: self.resultList.SetMouseWheelScrollEvent(ui.__mem_func__(self._on_result_list_wheel)) self.board.SetCloseEvent(ui.__mem_func__(self.Close)) self.spawnBtn.SetEvent(ui.__mem_func__(self.OnSpawn)) self.cancelBtn.SetEvent(ui.__mem_func__(self.Close)) self.searchEdit.SetReturnEvent(ui.__mem_func__(self.OnSearch)) self.searchEdit.SetEscapeEvent(ui.__mem_func__(self.Close)) self.countEdit.SetEscapeEvent(ui.__mem_func__(self.Close)) self.resultList.SetEvent(ui.__mem_func__(self.OnPickResult)) desc = _load_itemdesc() self._apply_items = _build_apply_list() self._metin_items = _build_metin_list(desc) self.previewImg = ui.ImageBox() self.previewImg.SetParent(self.board) self.previewImg.SetPosition(300, 168) try: self.previewImg.AddFlag("not_pick") except Exception: pass self.previewImg.Hide() t = ui.TextLine() t.SetParent(self.board) t.SetPosition(12, 216) t.SetText("Efsunlar:") t.Show() self._dyn_add(t) base_y = 232 self._attr_row_blocks = [] for i in xrange(ATTR_SATIR): row_y = base_y + i * ATTR_ROW_STEP lb = ui.TextLine() lb.SetParent(self.board) lb.SetPosition(12, row_y + 3) lb.SetText("%d." % (i + 1)) lb.Show() self._dyn_add(lb) cb = GmComboBox() cb.SetParent(self.board) cb.SetPosition(32, row_y) cb.SetSize(214, 18) cb.SetGmDropdownShield(self, "attr", i) self._fill_gm_combo(cb, self._apply_items) cb.SetEvent(lambda aid, r=i: self._on_attr_apply(r, aid)) cb.Enable() cb.Show() self._attr_combos.append(cb) sb = ui.SlotBar() sb.SetParent(self.board) sb.SetPosition(256, row_y) sb.SetSize(48, 18) sb.Show() self._dyn_add(sb) ev = ui.EditLine() ev.SetParent(sb) ev.SetPosition(3, 3) ev.SetSize(42, 16) ev.SetMax(5) ev.SetNumberMode() ev.Show() self._attr_val_edits.append(ev) self._dyn_add(ev) sb2 = ui.SlotBar() sb2.SetParent(self.board) sb2.SetPosition(310, row_y) sb2.SetSize(44, 18) sb2.Show() self._dyn_add(sb2) pv = ui.EditLine() pv.SetParent(sb2) pv.SetPosition(3, 3) pv.SetSize(38, 16) pv.SetMax(4) pv.SetNumberMode() pv.SetText("100") pv.Show() self._attr_pct_edits.append(pv) self._dyn_add(pv) self._attr_row_blocks.append([lb, cb, sb, sb2]) ts = ui.TextLine() ts.SetParent(self.board) ts.SetPosition(12, base_y + ATTR_SATIR * ATTR_ROW_STEP + 14) ts.SetText("Taslar (max %d socket):" % TAS_SOCKET_SAYISI) ts.Show() self._dyn_add(ts) self._stone_title_line = ts stone_y = base_y + ATTR_SATIR * ATTR_ROW_STEP + 34 self._stone_row_blocks = [] for s in xrange(TAS_SOCKET_SAYISI): sy = stone_y + s * ATTR_ROW_STEP lb = ui.TextLine() lb.SetParent(self.board) lb.SetPosition(12, sy + 3) lb.SetText("Tas %d:" % (s + 1)) lb.Show() self._dyn_add(lb) cb = GmComboBox() cb.SetParent(self.board) cb.SetPosition(52, sy) cb.SetSize(368, 18) cb.SetGmDropdownShield(self, "stone", s) self._fill_gm_combo(cb, self._metin_items) cb.SetEvent(lambda vid, idx=s: self._on_stone_pick(idx, vid)) cb.Enable() cb.Show() self._stone_combos.append(cb) self._stone_row_blocks.append([lb, cb]) self._gm_footer_btns = [self.spawnBtn, self.cancelBtn] self._sync_result_scroll() def _fill_gm_combo(self, combo, pairs): combo.ClearItem() for k, t in pairs: combo.InsertItem(k, _wnd_text(t)) if pairs: combo.SetCurrentItem(_wnd_text(_short_label(pairs[0][1]))) def _on_attr_apply(self, row, apply_id): self._attr_apply[row] = apply_id def _on_stone_pick(self, slot_idx, vnum): self._stone_vnum[slot_idx] = vnum def _result_scroll_max(self): n = self.resultList.GetItemCount() v = max(1, self.resultList.GetViewItemCount()) return max(0, n - v) def _on_result_scroll(self): mx = self._result_scroll_max() if mx <= 0: self.resultList.SetBasePos(0) return pos = self.resultScroll.GetPos() bp = int(round(pos * mx)) if bp > mx: bp = mx self.resultList.SetBasePos(bp) def _on_result_list_wheel(self, mode): mx = self._result_scroll_max() if mx <= 0: return bp = getattr(self.resultList, "basePos", 0) if mode == "UP": bp = max(0, bp - 1) else: bp = min(mx, bp + 1) self.resultList.SetBasePos(bp) self.resultScroll.SetPos(float(bp) / float(mx)) def _sync_result_scroll(self): n = self.resultList.GetItemCount() if n == 0: self.resultScroll.Hide() self.resultScroll.SetPos(0.0) self.resultList.SetBasePos(0) return mx = self._result_scroll_max() if mx <= 0: self.resultScroll.Hide() self.resultScroll.SetPos(0.0) self.resultList.SetBasePos(0) return self.resultScroll.Show() v = max(1, self.resultList.GetViewItemCount()) self.resultScroll.SetMiddleBarSize(min(1.0, float(v) / float(n))) bp = getattr(self.resultList, "basePos", 0) if bp > mx: bp = mx self.resultList.SetBasePos(bp) self.resultScroll.SetPos(float(bp) / float(mx)) def OnSearch(self): desc = _load_itemdesc() if not desc: chat.AppendChat(chat.CHAT_TYPE_INFO, "[GM] itemdesc.txt yuklenemedi: %s" % (app.GetLocalePath() + "/itemdesc.txt")) return q = self.searchEdit.GetText().strip() self.resultList.ClearItem() self.resultList.SetBasePos(0) self.resultScroll.SetPos(0.0) found = _search_items(desc, q, MAX_ARAMA_SONUC) for vnum, name in found: self.resultList.InsertItem(vnum, "%d | %s" % (vnum, name)) self._sync_result_scroll() if not found: chat.AppendChat(chat.CHAT_TYPE_INFO, "[GM] Sonuc yok.") def OnPickResult(self, vnum, text): self.selectedVnum = vnum self.selectedLabel.SetText("Secilen: %s" % text[:60]) self._refresh_preview() def _refresh_preview(self): if self.selectedVnum <= 0: self.previewImg.Hide() return item.SelectItem(self.selectedVnum) fn = item.GetIconImageFileName() if not fn or fn == "Noname": self.previewImg.Hide() return try: self.previewImg.LoadImage(fn) self.previewImg.Show() except RuntimeError: self.previewImg.Hide() def Destroy(self): if self.board: self.board.SetCloseEvent(None) if self.spawnBtn: self.spawnBtn.SetEvent(None) if self.cancelBtn: self.cancelBtn.SetEvent(None) if self.btnSearch: self.btnSearch.SetEvent(None) if self.searchEdit: self.searchEdit.SetReturnEvent(ui.Window.NoneMethod) self.searchEdit.SetEscapeEvent(ui.Window.NoneMethod) if self.countEdit: self.countEdit.SetEscapeEvent(ui.Window.NoneMethod) if self.resultList: self.resultList.SetEvent(None) if app.ENABLE_MOUSEWHEEL_EVENT: self.resultList.SetMouseWheelScrollEvent(None) if self.resultScroll: self.resultScroll.SetScrollEvent(None) for cb in self._attr_combos: try: cb.CloseListBox() except Exception: pass try: cb.SetEvent(None) cb.Destroy() except Exception: pass for cb in self._stone_combos: try: cb.CloseListBox() except Exception: pass try: cb.SetEvent(None) cb.Destroy() except Exception: pass self._attr_combos = [] self._stone_combos = [] for w in self._dyn: try: w.Destroy() except Exception: pass self._dyn = [] if self.previewImg: try: self.previewImg.Destroy() except Exception: pass self.previewImg = None self.ClearDictionary() self.board = None self.searchEdit = None self.resultList = None self.selectedLabel = None self.countEdit = None self.spawnBtn = None self.cancelBtn = None self.btnSearch = None def Open(self): if not chr.IsGameMaster(player.GetMainCharacterIndex()): return self.SetCenterPosition() self.SetTop() self.Show() self.searchEdit.SetFocus() def Close(self): self._gm_dd_restore() for cb in self._attr_combos + self._stone_combos: try: cb.CloseListBox() except Exception: pass self.Hide() return True def Toggle(self): if not chr.IsGameMaster(player.GetMainCharacterIndex()): return if self.IsShow(): self.Close() else: self.Open() def OnSpawn(self): if not chr.IsGameMaster(player.GetMainCharacterIndex()): return if self.selectedVnum <= 0: chat.AppendChat(chat.CHAT_TYPE_INFO, "[GM] Once listeden item secin.") return c = self.countEdit.GetText().strip() if not c: c = "1" self._refresh_preview() cmd = "/item7 %d %s" % (self.selectedVnum, c) for i in xrange(ATTR_SATIR): t = self._attr_apply[i] try: val = int(self._attr_val_edits[i].GetText() or 0) except ValueError: val = 0 try: pct = int(self._attr_pct_edits[i].GetText() or 100) except ValueError: pct = 100 if pct <= 0: pct = 100 final = (val * pct) / 100 cmd += " %d %d" % (t, final) for s in xrange(TAS_SOCKET_SAYISI): cmd += " %d" % (self._stone_vnum[s]) net.SendChatPacket(cmd) def OnPressEscapeKey(self): for cb in self._attr_combos + self._stone_combos: try: if cb.isListOpened: cb.CloseListBox() return True except Exception: pass return self.Close()
5) İstemci — uiscript/gmpanel_item.py
Ne yapıyoruz: Pencere iskeleti (GmItemPanel): başlık, arama, liste, scrollbar, adet, Ekle / İptal. Efsun/taş satırları LoadWindow içinde Python ile eklenir.
Yol:Kod:pack/root/uiscript/gmpanel_item.py
Kod:import uiScriptLocale W = 440 H = 650 window = { "name" : "GmItemPanel", "x" : 0, "y" : 0, "style" : ("movable", "float",), "width" : W, "height" : H, "children" : ( { "name" : "Board", "type" : "board_with_titlebar", "x" : 0, "y" : 0, "width" : W, "height" : H, "title" : "VezirSOFT - GM Edit Paneli", "children" : ( { "name" : "SearchLabel", "type" : "text", "x" : 12, "y" : 30, "text" : "Item adi ara:", }, { "name" : "SearchSlot", "type" : "slotbar", "x" : 12, "y" : 46, "width" : 220, "height" : 18, "children" : ( { "name" : "SearchEdit", "type" : "editline", "x" : 3, "y" : 3, "width" : 214, "height" : 18, "input_limit" : 40, }, ), }, { "name" : "SearchButton", "type" : "button", "x" : 242, "y" : 44, "width" : 70, "height" : 21, "text" : "Ara", "default_image" : "d:/ymir work/ui/public/middle_button_01.sub", "over_image" : "d:/ymir work/ui/public/middle_button_02.sub", "down_image" : "d:/ymir work/ui/public/middle_button_03.sub", }, { "name" : "ResultList", "type" : "listbox", "x" : 12, "y" : 72, "width" : 372, "height" : 100, }, { "name" : "ResultScrollBar", "type" : "scrollbar", "x" : 388, "y" : 72, "size" : 100, }, { "name" : "SelectedLabel", "type" : "text", "x" : 12, "y" : 178, "text" : "Secilen: (liste tikla)", }, { "name" : "CountLabel", "type" : "text", "x" : 12, "y" : 196, "text" : "Adet", }, { "name" : "CountSlot", "type" : "slotbar", "x" : 52, "y" : 194, "width" : 50, "height" : 18, "children" : ( { "name" : "CountValue", "type" : "editline", "x" : 3, "y" : 3, "width" : 44, "height" : 18, "input_limit" : 4, "only_number" : 1, "text" : "1", }, ), }, { "name" : "SpawnButton", "type" : "button", "x" : -70, "y" : 612, "width" : 61, "height" : 21, "horizontal_align" : "center", "text" : "Ekle", "default_image" : "d:/ymir work/ui/public/middle_button_01.sub", "over_image" : "d:/ymir work/ui/public/middle_button_02.sub", "down_image" : "d:/ymir work/ui/public/middle_button_03.sub", }, { "name" : "CancelButton", "type" : "button", "x" : 70, "y" : 612, "width" : 61, "height" : 21, "horizontal_align" : "center", "text" : uiScriptLocale.CANCEL, "default_image" : "d:/ymir work/ui/public/middle_button_01.sub", "over_image" : "d:/ymir work/ui/public/middle_button_02.sub", "down_image" : "d:/ymir work/ui/public/middle_button_03.sub", }, ), }, ), }
6) İstemci — interfacemodule.py
B3-1 — Import
Ara: Diğersatırları.Kod:importyoksa ekle.Kod:import uigmitempanel
B3-2 — Oluşturma (Interface.__init__)
Ara:Kod:self.dlgPointReset.Hide()
Hemen altına:
Kod:self.dlgItemEdit = uigmitempanel.GmItemPanel() self.dlgItemEdit.LoadWindow() self.dlgItemEdit.Hide()
B3-3 — Destroy
Ara:Altına:Kod:self.dlgPointReset.Destroy()
Kod:if self.dlgItemEdit: self.dlgItemEdit.Destroy()
B3-4 — del
Ara:Altına:Kod:del self.dlgPointResetKod:del self.dlgItemEdit
B3-5 — Toggle
Ara:civarı / Calling Functions bölümü.Kod:def OpenPointResetDialog(self):
Ekle:
Kod:def ToggleItemEditPanel(self): if self.dlgItemEdit: self.dlgItemEdit.Toggle()
B3-6 — Toplu Hide
Çok pencereninolduğu yere:Kod:.Hide()
Kod:if self.dlgItemEdit: self.dlgItemEdit.Hide()
7) İstemci — game.py
Ara:Kod:onPressKeyDict[app.DIK_F4]
Örnek altına ekle:
F10 doluysa F11 vb. kullan; önemli olan ToggleItemEditPanel çağrısı.Kod:onPressKeyDict[app.DIK_F10] = lambda : self.interface.ToggleItemEditPanel()
8) Sohbet formatı (uyum)
Panel Ekle deyince örnek yapı:
Sunucu one_argument ile sırayla okur; apply sayısı ITEM_ATTRIBUTE_MAX_NUM, socket ITEM_SOCKET_MAX_NUM.
Kod:/item7 <vnum> <adet>- 7 kez:
— final = değer × yüzde / 100Kod:<apply_tipi> <final_deger> Kod:<socket0> <socket1> <socket2>
9) Özet tablo
Dosya İş cmd.cpp ACMD(do_item_gm7); + cmd_info "item7" cmd_gm.cpp do_item bitişi + ACMD(do_item_gm7) uigmitempanel.py Üstteki spoiler tam metin gmpanel_item.py Üstteki uiscript tam metin interfacemodule.py Import, init, Destroy, del, Toggle, Hide game.py Tuş → ToggleItemEditPanel
İtemleri nereden çekiyor txt kullanıyorum ben
Şu an konuyu görüntüleyenler (Toplam : 1, Üye: 0, Misafir: 1)
Benzer konular
- Cevaplar
- 14
- Görüntüleme
- 1K
- Cevaplar
- 13
- Görüntüleme
- 2K
- Cevaplar
- 5
- Görüntüleme
- 2K






