Acest sistem adaugă un board separat cu butoane GM în fereastra de whisper.
Ce face:
Afișează butoane GM doar pentru GM
Butoanele apar doar când există un target
Butoanele sunt aranjate automat și centrate
Board-ul se redimensionează corect (fără glitch-uri)
Zona este pickable corect (nu dai click prin ea)
De ce e mai bun decât variantele vechi:
Nu mai sunt butoane puse „din pix” sub numele targetului
Nu mai depinde de whisperdialog.py
Poți adauga / scoate butoane ușor
Poți schimba spacing, padding, dimensiuni rapid
Cum funcționează:
Fiecare buton trimite o comandă în chat (ex: /ban, /warp, etc.)
Codul este gândit să fie ușor de extins pe viitor
Nu sunt expert în cod. Încă învăț și am avut ajutor de la AI pe parcursul dezvoltării. Încep să prind din ce în ce mai bine lucrurile, dar nu e ușor și mai durează, așa că… nu mă înjurați
Important e că funcționează, e stabil și e gândit să fie ușor de extins pe viitor.
ATENTIE, uiwhisper.py al meu are modificari facute are si emoji bagat pe langa noile butoane gm si board ul plus functiilor lor, va luati doar referinte , nu faceti copy / paste la tot si gata. daca nu aveti acele emoji , nu recomand decat pas cu pas sa urmariti si sa vedeti ce v-am scris bucati de cod intregi de copiat, daca apar erori sau va scoate din client, puteti lasa aici erorile ca sa vedem unde s a gresit.
Pasi Copy / Paste:
Cauta:
class WhisperButton(ui.Button):
def __init__(self):
ui.Button.__init__(self, "TOP_MOST") # Inițializează butonul în stratul Top Most
def __del__(self):
ui.Button.__del__(self) # Destructor pentru eliberarea memoriei
def SetToolTipText(self, text, x=0, y=32):
ui.Button.SetToolTipText(self, text, x, y) # Setează text standard tooltip
self.ToolTipText.Show() # Afișează tooltip-ul
def SetToolTipTextWithColor(self, text, color, x=0, y=32):
ui.Button.SetToolTipText(self, text, x, y) # Setează text tooltip
self.ToolTipText.SetPackedFontColor(color) # Aplică culoare font
self.ToolTipText.Show() # Afișează tooltip-ul colorat
def ShowToolTip(self):
if 0 != self.ToolTipText:
self.ToolTipText.Show() # Forțează afișarea tooltip-ului dacă există
def HideToolTip(self):
if 0 != self.ToolTipText:
self.ToolTipText.Hide() # Ascunde tooltip-ul dacă există
# =======================================
# CLASA GM BUTTON LIBRARY
# =======================================
class GMButtonLibrary:
def __init__(self):
self.groups = {} # Dicționar pentru grupuri de butoane GM
def RegisterGroupWithColors(self, group_name, buttons_with_colors):
self.groups[group_name] = {} # Creează grupul dacă nu există
for name, (btn, color) in buttons_with_colors.items():
self.groups[group_name][name] = btn # Adaugă butonul în grup
if btn and hasattr(btn, "SetTextColor"): # Verifică dacă butonul suportă SetTextColor
btn.SetTextColor(color) # Setează culoarea textului butonului
def ShowGroup(self, group_name):
group = self.groups.get(group_name) # Obține grupul de butoane
if not group:
return # Dacă nu există grupul, nu face nimic
for btn in group.values():
if btn:
btn.Show() # Afișează fiecare buton din grup
def HideGroup(self, group_name):
group = self.groups.get(group_name)
if not group:
return # Dacă nu există grupul, nu face nimic
for btn in group.values():
if btn:
btn.Hide() # Ascunde fiecare buton din grup
def __init__(self, eventMinimize, eventClose):
ui.ScriptWindow.__init__(self) # Inițializează ScriptWindow
self.targetName = "" # Numele destinatarului curent
self.eventMinimize = eventMinimize # Funcție de minimizare
self.eventClose = eventClose # Funcție de închidere
self.eventAcceptTarget = None # Funcție pentru accept target
self.gm_button_library = GMButtonLibrary() # Gestionare butoane GM
self.resizeButton = self.ResizeButton() # Creează buton resize
self.resizeButton.SetParent(self) # Set parent
self.resizeButton.SetSize(20, 20) # Dimensiune resize button
self.resizeButton.SetPosition(280, 180) # Poziție inițială
self.resizeButton.SetMoveEvent(ui.__mem_func__(self.ResizeWhisperDialog)) # Event la drag
self.resizeButton.Show() # Afișează butonul
# =======================================
# GM Buttons Board setup (cu randuri si centrare)
# =======================================
# ===============================
# SETĂRI BOARD GM FAȚĂ DE WHISPER
# ===============================
self.gm_buttons_board_min_height = 25
# => Înălțimea minimă a board-ului GM (nu micșorează mai jos de atât)
# Modifică doar dimensiunea board-ului, nu afectează butoanele.
self.gm_board_padding_top = 23 # => Distanța board-ului GM față de Whisper în sus (sus board față de bordură / fereastră Whisper)
self.gm_board_padding_bottom = 23 # => Distanța board-ului GM față de bordură jos pe inaltime
self.gm_board_padding_left = 10 # => Distanța board-ului GM față de stânga ferestrei Whisper
self.gm_board_padding_right = 10 # => Distanța board-ului GM față de dreapta ferestrei Whisper
self.gm_button_padding_left = 15 # distanța butoanelor față de stânga board GM
self.gm_button_padding_right = 15 # distanța butoanelor față de dreapta board GM
self.gm_buttons_distance_from_whisper = 3
# => Spațiul dintre Whisper (partea de jos a ferestrei) și bordul GM
# Toate acestea afectează **doar poziția și dimensiunea board-ului GM** față de Whisper
# Nu modifică spațiul dintre butoane.
# ===============================
# SETĂRI BUTOANE GM FAȚĂ DE BOARD GM
# ===============================
self.gm_button_spacing_horizontal = 2
# => Spațiul între butoanele de pe același rând (orizontal)
self.gm_button_spacing_vertical = 4
# => Spațiul între rânduri de butoane (vertical)
# Observație: acestea afectează doar **butoanele GM în interiorul board-ului**,
# nu schimbă dimensiunea sau poziția board-ului față de Whisper.
# =======================================
# Creare board GM
# =======================================
self.gm_buttons_board = ui.ThinBoardGold() # creează board-ul vizual GM
self.gm_buttons_board.SetParent(self) # board-ul este copil al WhisperDialog
# Setăm dimensiune inițială (înălțime minimă, lățime adaptată la Whisper)
self.gm_buttons_board.SetSize(
self.GetWidth() - (self.gm_board_padding_left + self.gm_board_padding_right),
# => lățimea board-ului = lățimea Whisper - padding stânga/dreapta
self.gm_buttons_board_min_height
# => înălțimea minimă setată mai sus
)
# Poziționare inițială board GM
self.gm_buttons_board.SetPosition(
self.gm_board_padding_left, # => stânga board = padding stânga față de Whisper
self.GetHeight() + self.gm_buttons_distance_from_whisper + self.gm_board_padding_top
# => jos board = înălțimea Whisper + distanță față de Whisper + padding sus board
)
self.gm_buttons_board.Hide() # board-ul GM rămâne ascuns până când GM deschide fereastra
# =======================================
# Creare GM Test Buttons
# =======================================
self.__CreateGMTestButtons() # Creează butoanele de test
self.__UpdateGMBoardLayout() # Aranjează butoanele pe board
Cauta:
def Destroy(self):
self.eventMinimize = None # Șterge referința la funcția de minimize
self.eventClose = None # Șterge referința la funcția de close
self.eventAcceptTarget = None # Șterge referința la funcția de accept target
self.ClearDictionary() # Curăță toate referințele interne de UI
self.scrollBar.Destroy() # Test1 scrollBar-ul
self.titleName = None # Șterge referința la titlu
self.titleNameEdit = None # Șterge referința la input
self.closeButton = None # Șterge referința la buton close
self.scrollBar = None # Șterge referința la scrollBar
self.chatLine = None # Șterge referința la chatLine
self.sendButton = None # Șterge referința la sendButton
self.ignoreButton = None # Dezactivat, nu există
self.reportViolentWhisperButton = None # Dezactivat, nu există
self.acceptButton = None # Șterge referința la acceptButton
self.minimizeButton = None # Șterge referința la minimizeButton
self.textRenderer = None # Șterge referința la textRenderer
self.board = None # Șterge referința la board principal
self.editBar = None # Șterge referința la editBar
self.resizeButton = None # Șterge referința la resizeButton
self.gm_buttons_board = None # Șterge referința la GM board
self.gm_button_library = None # Șterge referința la biblioteca de butoane GM
def Destroy(self):
self.eventMinimize = None # Șterge referința la funcția de minimize
self.eventClose = None # Șterge referința la funcția de close
self.eventAcceptTarget = None # Șterge referința la funcția de accept target
self.ClearDictionary() # Curăță toate referințele interne de UI
self.scrollBar.Destroy() # Test1 scrollBar-ul
self.titleName = None # Șterge referința la titlu
self.titleNameEdit = None # Șterge referința la input
self.closeButton = None # Șterge referința la buton close
self.scrollBar = None # Șterge referința la scrollBar
self.chatLine = None # Șterge referința la chatLine
self.sendButton = None # Șterge referința la sendButton
self.ignoreButton = None # Dezactivat, nu există
self.reportViolentWhisperButton = None # Dezactivat, nu există
self.acceptButton = None # Șterge referința la acceptButton
self.minimizeButton = None # Șterge referința la minimizeButton
self.textRenderer = None # Șterge referința la textRenderer
self.board = None # Șterge referința la board principal
self.editBar = None # Șterge referința la editBar
self.resizeButton = None # Șterge referința la resizeButton
self.gm_buttons_board = None # Șterge referința la GM board
self.gm_button_library = None # Șterge referința la biblioteca de butoane GM
# =======================================
# Creare butoane GM Test
# =======================================
def __CreateGMTestButtons(self):
self.gm_test_buttons = [] # Listă pentru toate butoanele GM
# Lista de nume pentru butoanele GM
button_names = ["Warp", "Transfer", "Kill", "Kick",
"Test1", "Test2", "Test3:", "Test4::",
"Test5:", "Test6:", "Test7:", "Test8:"]
# Dicționar comenzi per buton
commands_per_button = {
"Warp": lambda: net.SendChatPacket("/warp " + self.targetName), # Warp target
"Transfer": lambda: net.SendChatPacket("/Transfer " + self.targetName), # Transfer target
"Kill": lambda: net.SendChatPacket("/kill " + self.targetName), # Kill target
"Kick": lambda: net.SendChatPacket("/dc " + self.targetName), # Kick target
"Test1": lambda: net.SendChatPacket("Test1 " + self.targetName), # Test1 target
"Test2": lambda: net.SendChatPacket("Test2 " + self.targetName), # Test2 target
"Test3:": lambda: net.SendChatPacket("Test3: " + self.targetName), # Test3: target
"Test4::": lambda: net.SendChatPacket("Test4:: " + self.targetName), # Test4:: target
"Test5:": lambda: net.SendChatPacket("Test5: " + self.targetName), # Test5: target
"Test6:": lambda: net.SendChatPacket("Test6: " + self.targetName), # Test6: target
"Test7:": lambda: net.SendChatPacket("Test7: " + self.targetName), # Set level target
"Test8:": lambda: net.SendChatPacket("Test8: " + self.targetName) # Set gold target
}
# Culoare butoane per nume
colors_per_button = {
"Warp": 0xccffffff, "Transfer": 0xcc1f4ad5, "Kill": 0xccf3c756, "Kick": 0xccf5273f,
"Test1": 0xccffffff, "Test2": 0xccffffff, "Test3:": 0xccffffff, "Test4::": 0xccffffff,
"Test5:": 0xccffffff, "Test6:": 0xccffffff, "Test7:": 0xccffffff, "Test8:": 0xccffffff
}
# Creare butoane efective
for name in button_names:
btn = ui.Button() # Creează un nou buton
btn.SetParent(self.gm_buttons_board) # Setează board ca parent
# Setează vizualurile pentru diferite stări
btn.SetUpVisual("d:/ymir work/ui/public/Large_Button_01.sub")
btn.SetOverVisual("d:/ymir work/ui/public/Large_Button_02.sub")
btn.SetDownVisual("d:/ymir work/ui/public/Large_Button_03.sub")
btn.SetText(name) # Setează textul butonului
btn.test_name = name # Nume test pentru debug
if name in commands_per_button:
btn.SetEvent(commands_per_button[name]) # Asociază comanda la click
btn.Show() # Afișează butonul
self.gm_test_buttons.append(btn) # Adaugă în lista GM
setattr(self, name, btn) # Creează atribut dinamic pentru fiecare buton
# Înregistrează grupul de butoane cu culori
self.gm_button_library.RegisterGroupWithColors(
"main_gm",
{name: (getattr(self, name), colors_per_button[name]) for name in button_names}
)
# =======================================
# Resize / Pickable / GM Layout
# =======================================
def ResizeWhisperDialog(self):
if not self.resizeButton or not self.board or not self.gm_buttons_board:
return
xPos, yPos = self.resizeButton.GetLocalPosition()
if xPos < 280: self.resizeButton.SetPosition(280, yPos); return
if yPos < 150: self.resizeButton.SetPosition(xPos, 150); return
self.SetWhisperDialogSize(xPos + 20, yPos + 20)
board_width = self.GetWidth() - (self.gm_board_padding_left + self.gm_board_padding_right)
self.gm_buttons_board.SetSize(board_width, self.gm_buttons_board.GetHeight())
self.__UpdateGMBoardLayout()
def __UpdatePickableArea(self):
if not chr.IsGameMaster(player.GetMainCharacterIndex()) or self.targetName in (0, "", None):
self.SetPickableAreaHeight(self.GetHeight()) # Dacă nu e GM sau target gol, folosește înălțimea normală
return
total_height = self.GetHeight() + self.gm_buttons_distance_from_whisper + self.gm_buttons_board.GetHeight() # Include board GM
self.SetPickableAreaHeight(total_height) # Aplică înălțimea totală
def SetPickableAreaHeight(self, newHeight):
self.pickable_height = newHeight # Salvează înălțimea pickable
self.SetSize(self.GetWidth(), newHeight) # Aplică dimensiunea ferestrei
def __UpdateGMBoardLayout(self):
self.__ArrangeGMButtons()
self.__UpdateGMBoardPosition()
self.__UpdatePickableArea()
def __UpdateGMBoardPosition(self):
board_x = self.gm_board_padding_left
board_y = self.GetHeight() + self.gm_buttons_distance_from_whisper
self.gm_buttons_board.SetPosition(board_x, board_y)
Acum functiile " def OpenWithTarget(self, targetName):" si " def OpenWithoutTarget(self, event):" trebuiesc refacute, dar aveti grija ca poate aveti ceva modificari, sa nu le pierdeti pe cele care deja le aveti .... ar trebui sa arate asa cu modificari :
"def OpenWithTarget(self, targetName): "
# =======================================
# DESCHIDERE WHISPER CU TARGET
# =======================================
def OpenWithTarget(self, targetName):
chat.CreateWhisper(targetName) # Crează whisper pe server pentru target
chat.SetWhisperBoxSize(targetName, self.GetWidth() - 60, self.GetHeight() - 90) # Setează dimensiune chat box
self.chatLine.SetFocus() # Focus pe linia de chat
self.titleName.SetText(targetName) # Setează titlul ferestrei
self.targetName = targetName # Salvăm intern numele targetului
self.textRenderer.SetTargetName(targetName) # TextRenderer știe ce să afișeze
self.titleNameEdit.Hide() # Ascunde inputul pentru nume
self.minimizeButton.Show() # Arată butonul minimize
self.acceptButton.Hide() # Ascunde butonul accept
self.ignoreButton.Hide()
if app.IsDevStage():
self.reportViolentWhisperButton.Show()
else:
self.reportViolentWhisperButton.Hide()
# =======================================
# GESTIONARE BUTOANE GM
# =======================================
if chr.IsGameMaster(player.GetMainCharacterIndex()): # Dacă suntem GM
self.gm_button_library.ShowGroup("main_gm") # Arată grupul de butoane GM
self.gm_buttons_board.Show() # Arată board-ul GM
else:
self.gm_buttons_board.Hide() # Ascunde board-ul GM
self.gm_button_library.HideGroup("main_gm") # Ascunde butoanele GM
self.ResizeWhisperDialog() # Ajustează dimensiunea și poziția elementelor după deschidere
# =======================================
# DESCHIDERE WHISPER FARA TARGET
# =======================================
def OpenWithoutTarget(self, event):
self.eventAcceptTarget = event # Salvăm callback pentru acceptarea targetului
self.titleName.SetText("") # Reset titlu
self.titleNameEdit.SetText("") # Golim inputul
self.titleNameEdit.SetFocus() # Focus pe input
self.targetName = 0 # Nu există target
self.titleNameEdit.Show() # Arată inputul
self.gamemasterMark.Hide() # Ascunde mark-ul GM
self.acceptButton.Show() # Arată buton accept
self.minimizeButton.Show() # Arată buton minimize
self.ignoreButton.Hide()
self.reportViolentWhisperButton.Hide()
# =======================================
# ASCUNDERE BUTOANE GM
# =======================================
self.gm_button_library.HideGroup("main_gm") # Ascunde toate butoanele GM
self.gm_buttons_board.Hide() # Ascunde board-ul GM
# =======================================
# UPDATE DIMENSIUNE + PICKABLE
# =======================================
self.ResizeWhisperDialog() # Ajustează dimensiunea dialogului
self.SetPickableAreaHeight(self.GetHeight()) # Pickable doar whisper
Asta este "uiwhisper.py" din root complet cu modificarile aduse pentru a se afisa butoanele.
*Poze:
*Link download: Descarca poze de referinta si uiwhisper.py cu noul sistem board gm


la acest mesaj și conținutul se va afișa automat.




