acestea sunt: warp / transfer / kill / kick /
Aceste obțiuni sunt doar pentru gm vizibile în pm cu un jucator
se poate extinde după bunul plac
*Poze / Video (obligatoriu):
![[Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 1 - Imagine 1 [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 1 - Imagine 1](https://i.gyazo.com/3d7c0eebcf8ecae3837f6c75f774fe0c.webp)
![[Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 1 - Imagine 1 [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 1 - Imagine 1](https://i.gyazo.com/3d7c0eebcf8ecae3837f6c75f774fe0c.webp)
Te așteptăm și pe serverul de Discord - aici ne-am strâns toată comunitatea de Metin2 din România.
Alătură-te acum!
scott.petrica5287 scrie: ↑ cum ai facut sa stea lipite acolo ?
i-am făcut un thinboard separat şi l-am pus să-şi dea update la poziţie după mărimea ferestrei în funcţia de refresh, să rămână centrat.
import ui
import net
import chat
import player
import app
import localeInfo
import ime
import chr
class WhisperButton(ui.Button):
def __init__(self):
ui.Button.__init__(self, "TOP_MOST")
def __del__(self):
ui.Button.__del__(self)
def SetToolTipText(self, text, x=0, y = 32):
ui.Button.SetToolTipText(self, text, x, y)
self.ToolTipText.Show()
def SetToolTipTextWithColor(self, text, color, x=0, y = 32):
ui.Button.SetToolTipText(self, text, x, y)
self.ToolTipText.SetPackedFontColor(color)
self.ToolTipText.Show()
def ShowToolTip(self):
if 0 != self.ToolTipText:
self.ToolTipText.Show()
def HideToolTip(self):
if 0 != self.ToolTipText:
self.ToolTipText.Show()
class WhisperDialog(ui.ScriptWindow):
class TextRenderer(ui.Window):
def SetTargetName(self, targetName):
self.targetName = targetName
def OnRender(self):
(x, y) = self.GetGlobalPosition()
chat.RenderWhisper(self.targetName, x, y)
class ResizeButton(ui.DragButton):
def __init__(self):
ui.DragButton.__init__(self)
def __del__(self):
ui.DragButton.__del__(self)
def OnMouseOverIn(self):
app.SetCursor(app.HVSIZE)
def OnMouseOverOut(self):
app.SetCursor(app.NORMAL)
def __init__(self, eventMinimize, eventClose):
print "NEW WHISPER DIALOG ----------------------------------------------------------------------------"
ui.ScriptWindow.__init__(self)
self.targetName = ""
self.eventMinimize = eventMinimize
self.eventClose = eventClose
self.eventAcceptTarget = None
def __del__(self):
print "---------------------------------------------------------------------------- DELETE WHISPER DIALOG"
ui.ScriptWindow.__del__(self)
def LoadDialog(self):
try:
pyScrLoader = ui.PythonScriptLoader()
pyScrLoader.LoadScriptFile(self, "UIScript/WhisperDialog.py")
except:
import exception
exception.Abort("WhisperDialog.LoadDialog.LoadScript")
try:
GetObject=self.GetChild
self.titleName = GetObject("titlename")
self.titleNameEdit = GetObject("titlename_edit")
self.closeButton = GetObject("closebutton")
self.scrollBar = GetObject("scrollbar")
self.chatLine = GetObject("chatline")
self.minimizeButton = GetObject("minimizebutton")
self.ignoreButton = GetObject("ignorebutton")
self.reportViolentWhisperButton = GetObject("reportviolentwhisperbutton")
self.acceptButton = GetObject("acceptbutton")
self.sendButton = GetObject("sendbutton")
self.board = GetObject("board")
self.editBar = GetObject("editbar")
self.gamemasterMark = GetObject("gamemastermark")
self.warp = GetObject("warp")
self.transfer = GetObject("transfer")
self.kill = GetObject("kill")
self.kick = GetObject("kick")
except:
import exception
exception.Abort("DialogWindow.LoadDialog.BindObject")
self.titleName.SetText("")
self.titleNameEdit.SetText("")
self.minimizeButton.SetEvent(ui.__mem_func__(self.Minimize))
self.closeButton.SetEvent(ui.__mem_func__(self.Close))
self.scrollBar.SetPos(1.0)
self.scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll))
self.chatLine.SetReturnEvent(ui.__mem_func__(self.SendWhisper))
self.chatLine.SetEscapeEvent(ui.__mem_func__(self.Minimize))
self.chatLine.SetMultiLine()
self.sendButton.SetEvent(ui.__mem_func__(self.SendWhisper))
self.titleNameEdit.SetReturnEvent(ui.__mem_func__(self.AcceptTarget))
self.titleNameEdit.SetEscapeEvent(ui.__mem_func__(self.Close))
self.warp.SetEvent(ui.__mem_func__(self.__OnWarp))
self.transfer.SetEvent(ui.__mem_func__(self.__OnTransfer))
self.kill.SetEvent(ui.__mem_func__(self.__OnKill))
self.kick.SetEvent(ui.__mem_func__(self.__OnKick))
self.ignoreButton.SetToggleDownEvent(ui.__mem_func__(self.IgnoreTarget))
self.ignoreButton.SetToggleUpEvent(ui.__mem_func__(self.IgnoreTarget))
self.reportViolentWhisperButton.SetEvent(ui.__mem_func__(self.ReportViolentWhisper))
self.acceptButton.SetEvent(ui.__mem_func__(self.AcceptTarget))
self.textRenderer = self.TextRenderer()
self.textRenderer.SetParent(self)
self.textRenderer.SetPosition(20, 28)
self.textRenderer.SetTargetName("")
self.textRenderer.Show()
self.resizeButton = self.ResizeButton()
self.resizeButton.SetParent(self)
self.resizeButton.SetSize(20, 20)
self.resizeButton.SetPosition(280, 180)
self.resizeButton.SetMoveEvent(ui.__mem_func__(self.ResizeWhisperDialog))
self.resizeButton.Show()
self.ResizeWhisperDialog()
def Destroy(self):
self.eventMinimize = None
self.eventClose = None
self.eventAcceptTarget = None
self.warp = None
self.transfer = None
self.kill = None
self.kick = None
self.ClearDictionary()
self.scrollBar.Destroy()
self.titleName = None
self.titleNameEdit = None
self.closeButton = None
self.scrollBar = None
self.chatLine = None
self.sendButton = None
self.ignoreButton = None
self.reportViolentWhisperButton = None
self.acceptButton = None
self.minimizeButton = None
self.textRenderer = None
self.board = None
self.editBar = None
self.resizeButton = None
def ResizeWhisperDialog(self):
(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)
def SetWhisperDialogSize(self, width, height):
try:
max = int((width-90)/6) * 3 - 6
self.board.SetSize(width, height)
self.scrollBar.SetPosition(width-25, 35)
self.scrollBar.SetScrollBarSize(height-100)
self.scrollBar.SetPos(1.0)
self.editBar.SetSize(width-18, 50)
self.chatLine.SetSize(width-90, 40)
self.chatLine.SetLimitWidth(width-90)
self.SetSize(width, height)
if 0 != self.targetName:
chat.SetWhisperBoxSize(self.targetName, width - 50, height - 90)
if localeInfo.IsARABIC():
self.textRenderer.SetPosition(width-20, 28)
self.scrollBar.SetPosition(width-25+self.scrollBar.GetWidth(), 35)
self.editBar.SetPosition(10 + self.editBar.GetWidth(), height-60)
self.sendButton.SetPosition(width - 80 + self.sendButton.GetWidth(), 10)
self.minimizeButton.SetPosition(width-42 + self.minimizeButton.GetWidth(), 12)
self.closeButton.SetPosition(width-24+self.closeButton.GetWidth(), 12)
self.chatLine.SetPosition(5 + self.chatLine.GetWidth(), 5)
self.board.SetPosition(self.board.GetWidth(), 0)
else:
self.textRenderer.SetPosition(20, 28)
self.scrollBar.SetPosition(width-25, 35)
self.editBar.SetPosition(10, height-60)
self.sendButton.SetPosition(width-80, 10)
self.minimizeButton.SetPosition(width-42, 12)
self.closeButton.SetPosition(width-24, 12)
self.SetChatLineMax(max)
except:
import exception
exception.Abort("WhisperDialog.SetWhisperDialogSize.BindObject")
def SetChatLineMax(self, max):
self.chatLine.SetMax(max)
from grpText import GetSplitingTextLine
text = self.chatLine.GetText()
if text:
self.chatLine.SetText(GetSplitingTextLine(text, max, 0))
def OpenWithTarget(self, targetName):
chat.CreateWhisper(targetName)
chat.SetWhisperBoxSize(targetName, self.GetWidth() - 60, self.GetHeight() - 90)
self.chatLine.SetFocus()
self.titleName.SetText(targetName)
self.targetName = targetName
self.textRenderer.SetTargetName(targetName)
self.titleNameEdit.Hide()
self.ignoreButton.Hide()
if app.IsDevStage():
self.reportViolentWhisperButton.Show()
else:
self.reportViolentWhisperButton.Hide()
self.acceptButton.Hide()
self.gamemasterMark.Hide()
self.minimizeButton.Show()
if chr.IsGameMaster(player.GetMainCharacterIndex()):
self.warp.Show()
self.transfer.Show()
self.kill.Show()
self.kick.Show()
else:
self.warp.Hide()
self.transfer.Hide()
self.kill.Hide()
self.kick.Hide()
def OpenWithoutTarget(self, event):
self.eventAcceptTarget = event
self.titleName.SetText("")
self.titleNameEdit.SetText("")
self.titleNameEdit.SetFocus()
self.targetName = 0
self.titleNameEdit.Show()
self.ignoreButton.Hide()
self.reportViolentWhisperButton.Hide()
self.acceptButton.Show()
self.minimizeButton.Hide()
self.gamemasterMark.Hide()
def SetGameMasterLook(self):
self.gamemasterMark.Show()
self.reportViolentWhisperButton.Hide()
def Minimize(self):
self.titleNameEdit.KillFocus()
self.chatLine.KillFocus()
self.Hide()
if None != self.eventMinimize:
self.eventMinimize(self.targetName)
def Close(self):
chat.ClearWhisper(self.targetName)
self.titleNameEdit.KillFocus()
self.chatLine.KillFocus()
self.Hide()
if None != self.eventClose:
self.eventClose(self.targetName)
def __OnWarp(self):
net.SendChatPacket("/warp " + self.targetName)
def __OnTransfer(self):
net.SendChatPacket("/transfer " + self.targetName)
def __OnKill(self):
net.SendChatPacket("/kill " + self.targetName)
def __OnKick(self):
net.SendChatPacket("/kick" + self.targetName)
def ReportViolentWhisper(self):
net.SendChatPacket("/reportviolentwhisper " + self.targetName)
def IgnoreTarget(self):
net.SendChatPacket("/ignore " + self.targetName)
def AcceptTarget(self):
name = self.titleNameEdit.GetText()
if len(name) <= 0:
self.Close()
return
if None != self.eventAcceptTarget:
self.titleNameEdit.KillFocus()
self.eventAcceptTarget(name)
def OnScroll(self):
chat.SetWhisperPosition(self.targetName, self.scrollBar.GetPos())
def SendWhisper(self):
text = self.chatLine.GetText()
textLength = len(text)
if textLength > 0:
if net.IsInsultIn(text):
chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CHAT_INSULT_STRING)
return
net.SendWhisperPacket(self.targetName, text)
self.chatLine.SetText("")
chat.AppendWhisper(chat.WHISPER_TYPE_CHAT, self.targetName, player.GetName() + " : " + text)
def OnTop(self):
self.chatLine.SetFocus()
def BindInterface(self, interface):
self.interface = interface
def OnMouseLeftButtonDown(self):
hyperlink = ui.GetHyperlink()
if hyperlink:
if app.IsPressed(app.DIK_LALT):
link = chat.GetLinkFromHyperlink(hyperlink)
ime.PasteString(link)
else:
self.interface.MakeHyperlinkTooltip(hyperlink)
if "__main__" == __name__:
import uiTest
class TestApp(uiTest.App):
def OnInit(self):
wnd = WhisperDialog(self.OnMax, self.OnMin)
wnd.LoadDialog()
wnd.OpenWithoutTarget(self.OnNew)
wnd.SetPosition(0, 0)
wnd.Show()
self.wnd = wnd
def OnMax(self):
pass
def OnMin(self):
pass
def OnNew(self):
pass
TestApp().MainLoop()
import uiScriptLocale
ROOT = "d:/ymir work/ui/public/"
window = {
"name" : "WhisperDialog",
"style" : ("movable", "float",),
"x" : 0,
"y" : 0,
"width" : 280,
"height" : 200,
"children" :
(
{
"name" : "board",
"type" : "thinboard",
"style" : ("attach",),
"x" : 0,
"y" : 0,
"width" : 280,
"height" : 200,
"children" :
(
## Title
{
"name" : "name_slot",
"type" : "image",
"style" : ("attach",),
"x" : 10,
"y" : 10,
"image":"d:/ymir work/ui/public/Parameter_Slot_05.sub",
"children" :
(
{
"name" : "titlename",
"type" : "text",
"x" : 3,
"y" : 3,
"text" : uiScriptLocale.WHISPER_NAME,
},
{
"name" : "titlename_edit",
"type" : "editline",
"x" : 3,
"y" : 3,
"width" : 120,
"height" : 17,
"input_limit" : PLAYER_NAME_MAX_LEN,
"text" : uiScriptLocale.WHISPER_NAME,
},
),
},
{
"name" : "gamemastermark",
"type" : "expanded_image",
"style" : ("attach",),
"x" : 206,
"y" : 6,
"x_scale" : 0.2,
"y_scale" : 0.2,
"image" : "locale/common/effect/ymirred.tga",
},
{
"name" : "warp",
"type" : "button",
"x" : 10,
"y" : 30,
"text" : "warp",
"default_image": "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
{
"name" : "transfer",
"type" : "button",
"x" : 10 + 60 * 1,
"y" : 30,
"text" : "transfer",
"default_image": "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
{
"name" : "kill",
"type" : "button",
"x" : 10 + 60 * 2,
"y" : 30,
"text" : "kill",
"default_image": "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
{
"name" : "kick",
"type" : "button",
"x" : 10 + 60 * 3,
"y" : 30,
"text" : "kick",
"default_image": "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
## Button
{
"name" : "ignorebutton",
"type" : "toggle_button",
"x" : 145,
"y" : 10,
"text" : uiScriptLocale.WHISPER_BAN,
"default_image" : "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
{
"name" : "reportviolentwhisperbutton",
"type" : "button",
"x" : 145,
"y" : 10,
"text" : uiScriptLocale.WHISPER_REPORT,
"default_image" : "d:/ymir work/ui/public/large_button_01.sub",
"over_image" : "d:/ymir work/ui/public/large_button_02.sub",
"down_image" : "d:/ymir work/ui/public/large_button_03.sub",
},
{
"name" : "acceptbutton",
"type" : "button",
"x" : 145,
"y" : 10,
"text" : uiScriptLocale.OK,
"default_image" : "d:/ymir work/ui/public/small_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/small_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/small_thin_button_03.sub",
},
{
"name" : "minimizebutton",
"type" : "button",
"x" : 280 - 41,
"y" : 12,
"tooltip_text" : uiScriptLocale.MINIMIZE,
"default_image" : "d:/ymir work/ui/public/minimize_button_01.sub",
"over_image" : "d:/ymir work/ui/public/minimize_button_02.sub",
"down_image" : "d:/ymir work/ui/public/minimize_button_03.sub",
},
{
"name" : "closebutton",
"type" : "button",
"x" : 280 - 24,
"y" : 12,
"tooltip_text" : uiScriptLocale.CLOSE,
"default_image" : "d:/ymir work/ui/public/close_button_01.sub",
"over_image" : "d:/ymir work/ui/public/close_button_02.sub",
"down_image" : "d:/ymir work/ui/public/close_button_03.sub",
},
## ScrollBar
{
"name" : "scrollbar",
"type" : "thin_scrollbar",
"x" : 280 - 25,
"y" : 35,
"size" : 280 - 160,
},
## Edit Bar
{
"name" : "editbar",
"type" : "bar",
"x" : 10,
"y" : 200 - 60,
"width" : 280 - 18,
"height" : 50,
"color" : 0x77000000,
"children" :
(
{
"name" : "chatline",
"type" : "editline",
"x" : 5,
"y" : 5,
"width" : 280 - 70,
"height" : 40,
"with_codepage" : 1,
"input_limit" : 40,
"limit_width" : 280 - 90,
"multi_line" : 1,
},
{
"name" : "sendbutton",
"type" : "button",
"x" : 280 - 80,
"y" : 10,
"text" : uiScriptLocale.WHISPER_SEND,
"default_image" : "d:/ymir work/ui/public/xlarge_thin_button_01.sub",
"over_image" : "d:/ymir work/ui/public/xlarge_thin_button_02.sub",
"down_image" : "d:/ymir work/ui/public/xlarge_thin_button_03.sub",
},
),
},
),
},
),
}
Ultima oară modificat 10 Ian 2026, 20:30 de către l3oogie, modificat de 3 ori în total.
###############################################################
# GM BOARD BUTTONS SYSTEM – VECHI
#
# Autor logică & concept:
# Vaduva Liviu Bogdan (l3oogie)
#
# Implementare tehnică:
# realizată anterior (versiune veche), fără scroll și toggle bar
#
# -------------------------------------------------------------
# DESCRIERE GENERALĂ
# -------------------------------------------------------------
#
# Acest fișier conține versiunea veche a sistemului de GM Board + butoane.
# Include:
# - Board vizual pentru butoanele GM (ThinBoardGold)
# - Butoane GM aranjate pe rânduri și centrate automat
# - Padding-uri și spacing configurabile
# - Pickable area complet funcțională, acoperind toate butoanele
#
# IMPORTANT:
# - Nu există scroll vertical sau container de clipping.
# - Nu există bara GM cu toggle.
# - Butoanele sunt afișate direct pe board, fără gestionare avansată a vizibilității.
#
# -------------------------------------------------------------
# LAYOUT DINAMIC
# -------------------------------------------------------------
#
# - Butoanele GM sunt aranjate automat pe rânduri, centrate în board.
# - Lățimea board-ului se calculează din dimensiunea ferestrei (fix sau adaptivă).
# - Dacă butoanele depășesc lățimea board-ului, acestea trec pe rândul următor.
# - Înălțimea board-ului se ajustează automat între min și max în funcție de butoane.
#
# -------------------------------------------------------------
# PICKABLE AREA
# -------------------------------------------------------------
#
# - Pickable area acoperă complet butoanele GM.
# - Se ajustează dinamic la dimensiunea board-ului și poziția butoanelor.
# - Asigură că toate click-urile sunt detectate corect pe butoanele GM.
#
# -------------------------------------------------------------
# INTEGRITATE ȘI UTILIZARE
# -------------------------------------------------------------
#
# - Codul gestionează exclusiv butoanele GM și layout-ul lor.
# - Funcționalitatea GM și permisiunile sunt gestionate server-side.
# - Poți adăuga sau elimina butoane fără să modifici logica de aranjare.
#
# -------------------------------------------------------------
# OBSERVAȚII
# -------------------------------------------------------------
#
# - Layout dinamic și pickable area completă sunt principalele caracteristici.
# - Lipsesc scroll, clipping și bara toggle (prezentă în versiunea nouă).
# - Aspectul vizual poate fi ajustat fără a afecta funcționalitatea.
#
###############################################################
import ui # Module pentru UI: ferestre, butoane, scrollbars
import net # Modul pentru trimitere comenzi către server (ex: /comanda joc gm1, /comanda joc gm1)
import chat # Modul pentru logica chat (afișarea whisper-urilor)
import player # Modul pentru informații despre jucătorul curent
import app # Funcții generale ale aplicației (cursor, timp, resize)
import localeInfo # Localizare: verifică setările limbii, RTL etc.
import ime # Input Method Editor, pentru input text complex
import chr # Module pentru verificări caractere / GM (Game Master)
# =======================================
# CLASA WHISPER BUTTON
# =======================================
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
# =======================================
# CLASA WHISPER DIALOG
# =======================================
class WhisperDialog(ui.ScriptWindow):
def IgnoreTarget(self):
net.SendChatPacket("/ignore " + self.targetName)
def ReportViolentWhisper(self):
net.SendChatPacket("/reportviolentwhisper " + self.targetName)
# =======================================
# Text Renderer intern pentru whisper
# =======================================
class TextRenderer(ui.Window):
def SetTargetName(self, targetName):
self.targetName = targetName # Setează numele destinatarului whisper-ului
def OnRender(self):
(x, y) = self.GetGlobalPosition() # Obține poziția globală a ferestrei
chat.RenderWhisper(self.targetName, x, y) # Desenează whisper-ul pe ecran
# =======================================
# Buton de resize
# =======================================
class ResizeButton(ui.DragButton):
def __init__(self):
ui.DragButton.__init__(self) # Inițializează butonul drag
def __del__(self):
ui.DragButton.__del__(self) # Destructor
def OnMouseOverIn(self):
app.SetCursor(app.HVSIZE) # Cursorul se schimbă pentru resize
def OnMouseOverOut(self):
app.SetCursor(app.NORMAL) # Cursorul revine la normal
# =======================================
# INIT FEREASTRA WHISPER
# =======================================
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
def __del__(self):
ui.ScriptWindow.__del__(self) # Destructor ScriptWindow
# =======================================
# LOAD DIALOG
# =======================================
def LoadDialog(self):
try:
pyScrLoader = ui.PythonScriptLoader() # Loader pentru scriptul UI
pyScrLoader.LoadScriptFile(self, "UIScript/WhisperDialog.py") # Încarcă scriptul
except:
import exception
exception.Abort("WhisperDialog.LoadDialog.LoadScript") # Abort dacă fișierul nu există
try:
GetObject = self.GetChild # Shortcut pentru GetChild
self.titleName = GetObject("titlename") # Titlul ferestrei
self.titleNameEdit = GetObject("titlename_edit") # Input pentru nume
self.closeButton = GetObject("closebutton") # Buton de închidere
self.scrollBar = GetObject("scrollbar") # Scroll bar
self.chatLine = GetObject("chatline") # Linie de chat
self.minimizeButton = GetObject("minimizebutton") # Buton minimize
self.sendButton = GetObject("sendbutton") # Buton trimite
self.acceptButton = GetObject("acceptbutton") # Buton accept target
self.board = GetObject("board") # Board principal
self.editBar = GetObject("editbar") # Bara editare text
self.gamemasterMark = GetObject("gamemastermark") # GM mark vizual
self.ignoreButton = GetObject("ignorebutton")
self.reportViolentWhisperButton = GetObject("reportviolentwhisperbutton")
except:
import exception
exception.Abort("DialogWindow.LoadDialog.BindObject") # Abort dacă element lipsă
# =======================================
# Ascundem elemente inițiale
# =======================================
self.gamemasterMark.Hide() # Ascunde mark GM
self.titleName.SetText("") # Curăță titlu
self.titleNameEdit.SetText("") # Curăță input
# =======================================
# Setăm evenimentele principale
# =======================================
self.minimizeButton.SetEvent(ui.__mem_func__(self.Minimize)) # Eveniment minimize
self.closeButton.SetEvent(ui.__mem_func__(self.Close)) # Eveniment close
self.scrollBar.SetPos(1.0) # Set scroll la final
self.scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll)) # Scroll event
self.chatLine.SetReturnEvent(ui.__mem_func__(self.SendWhisper)) # Enter trimite
self.chatLine.SetEscapeEvent(ui.__mem_func__(self.Minimize)) # Escape minimize
self.chatLine.SetMultiLine() # Multiline input
self.sendButton.SetEvent(ui.__mem_func__(self.SendWhisper)) # Buton trimite
self.titleNameEdit.SetReturnEvent(ui.__mem_func__(self.AcceptTarget)) # Enter accept
self.titleNameEdit.SetEscapeEvent(ui.__mem_func__(self.Close)) # Escape close
self.acceptButton.SetEvent(ui.__mem_func__(self.AcceptTarget)) # Accept target
self.ignoreButton.SetToggleDownEvent(ui.__mem_func__(self.IgnoreTarget))
self.ignoreButton.SetToggleUpEvent(ui.__mem_func__(self.IgnoreTarget))
self.reportViolentWhisperButton.SetEvent(ui.__mem_func__(self.ReportViolentWhisper))
# =======================================
# TextRenderer
# =======================================
self.textRenderer = self.TextRenderer() # Creează renderer text
self.textRenderer.SetParent(self) # Set parent
self.textRenderer.SetPosition(20, 28) # Poziție pe fereastră
self.textRenderer.SetTargetName("") # Target gol inițial
self.textRenderer.Show() # Afișează renderer
# =======================================
# Resize Button
# =======================================
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
# =======================================
# Resize Whisper Dialog
# =======================================
self.ResizeWhisperDialog() # Aplica resize inițial
# =======================================
# Destroy complet
# =======================================
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 __ArrangeGMButtons(self):
gm_buttons = self.gm_test_buttons # lista cu toate butoanele GM
# =======================================
# Padding-ul inițial al board-ului
# =======================================
padding_left = self.gm_button_padding_left # distanță minimă stânga față de board
padding_right = self.gm_button_padding_right# distanță minimă dreapta față de board
padding_top = self.gm_board_padding_top # distanță sus față de bordura board
spacing_x = self.gm_button_spacing_horizontal # spațiu între butoanele de pe același rând
spacing_y = self.gm_button_spacing_vertical # spațiu între rânduri
board_width = self.gm_buttons_board.GetWidth() # lățimea curentă a board-ului
usable_width = board_width - padding_left - padding_right # spațiul efectiv pentru butoane
rows = [] # lista de rânduri
current_row = [] # butoanele din rândul curent
current_row_width = 0 # lățimea acumulată a rândului curent
# =======================================
# Creare rânduri
# =======================================
for btn in gm_buttons:
btn_width = btn.GetWidth()
# dacă adaug butonul curent + spacing depășește usable_width => fac rând nou
next_width = current_row_width + (spacing_x if current_row else 0) + btn_width
if next_width <= usable_width:
current_row.append(btn)
current_row_width = next_width
else:
rows.append(current_row) # finalizez rândul curent
current_row = [btn] # încep rând nou
current_row_width = btn_width
if current_row:
rows.append(current_row) # adaug ultimul rând
# =======================================
# Poziționare butoane pe board
# =======================================
y = padding_top
for row in rows:
row_width = sum(btn.GetWidth() for btn in row) + spacing_x * (len(row) - 1)
# calculăm spațiul extra pentru centrare
extra_space = max(0, usable_width - row_width)
start_x = padding_left + extra_space / 2 # centrare în spațiul extra fără a tăia padding
x = start_x
row_max_height = 0 # înălțimea maximă a butoanelor din rând
for btn in row:
# aici păstrăm padding-ul minim stânga/dreapta la resize
btn.SetPosition(int(x), int(y)) # poziționează butonul
x += btn.GetWidth() + spacing_x # trece la următorul buton
row_max_height = max(row_max_height, btn.GetHeight()) # actualizează înălțimea rândului
y += row_max_height + spacing_y # trece la rândul următor
# =======================================
# Setăm înălțimea finală a board-ului GM
# =======================================
final_height = max(y - spacing_y + self.gm_board_padding_bottom, self.gm_buttons_board_min_height)
self.gm_buttons_board.SetSize(board_width, final_height)
# =======================================
# EXEMPLE MODIFICARE PADDING / SPACING
# =======================================
# 1. Mărire padding stânga/dreapta board:
# self.gm_board_padding_left = 10
# self.gm_board_padding_right = 10
# 2. Mărire spațiu între butoane pe rând:
# self.gm_button_spacing_horizontal = 8
# 3. Mărire spațiu între rânduri:
# self.gm_button_spacing_vertical = 8
# 4. Distanța board față de whisper:
# self.gm_buttons_distance_from_whisper = 5
# 5. Dimensiune minimă board:
# self.gm_buttons_board_min_height = 30
# Toate modificările se aplică **pixel cu pixel** la poziționarea și centrare butoanelor.
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)
# =======================================
# SETAREA DIMENSIUNII WHISPER
# =======================================
def SetWhisperDialogSize(self, width, height):
try:
max = int((width-90)/6) * 3 - 6 # Calculează numărul maxim de linii chat bazat pe lățime
self.board.SetSize(width, height) # Setează dimensiunea board-ului principal whisper
self.scrollBar.SetPosition(width-25, 35) # Setează poziția scroll bar-ului
self.scrollBar.SetScrollBarSize(height-100) # Setează înălțimea scroll bar-ului
self.scrollBar.SetPos(1.0) # Inițializează scroll bar-ul la poziția maximă
self.editBar.SetSize(width-18, 50) # Setează dimensiunea barei de editare
self.chatLine.SetSize(width-90, 40) # Setează dimensiunea liniei de chat
self.chatLine.SetLimitWidth(width-90) # Limitează lățimea liniei de chat
self.SetSize(width, height) # Setează dimensiunea generală a ferestrei Whisper
if 0 != self.targetName:
chat.SetWhisperBoxSize(self.targetName, width - 50, height - 90) # Update chat box pentru target
if localeInfo.IsARABIC(): # Verifică dacă limba este RTL (arabic)
self.textRenderer.SetPosition(width-20, 28) # Mută text renderer pentru RTL
self.scrollBar.SetPosition(width-25+self.scrollBar.GetWidth(), 35) # Ajustează scroll bar
self.editBar.SetPosition(10 + self.editBar.GetWidth(), height-60) # Ajustează bara de editare
self.sendButton.SetPosition(width - 80 + self.sendButton.GetWidth(), 10) # Ajustează buton send
self.minimizeButton.SetPosition(width-42 + self.minimizeButton.GetWidth(), 12) # Ajustează minimize
self.closeButton.SetPosition(width-24+self.closeButton.GetWidth(), 12) # Ajustează close
self.chatLine.SetPosition(5 + self.chatLine.GetWidth(), 5) # Ajustează linia chat
self.board.SetPosition(self.board.GetWidth(), 0) # Ajustează board
else:
self.textRenderer.SetPosition(20, 28) # Poziția normală text renderer
self.scrollBar.SetPosition(width-25, 35) # Poziția normală scroll bar
self.editBar.SetPosition(10, height-60) # Poziția normală edit bar
self.sendButton.SetPosition(width-80, 10) # Poziția normală buton send
self.minimizeButton.SetPosition(width-42, 12) # Poziția normală minimize
self.closeButton.SetPosition(width-24, 12) # Poziția normală close
self.SetChatLineMax(max) # Setează linii max chat conform calculului
except:
import exception # Import modul de gestiune erori
exception.Abort("WhisperDialog.SetWhisperDialogSize.BindObject") # Afișează eroare dacă ceva nu merge
# =======================================
# UPDATE MAX CHAT LINES
# =======================================
def SetChatLineMax(self, max):
self.chatLine.SetMax(max) # Setează numărul maxim de caractere / linie
from grpText import GetSplitingTextLine # Import funcție pentru împărțirea textului pe linii
text = self.chatLine.GetText() # Ia textul curent din chat
if text:
self.chatLine.SetText(GetSplitingTextLine(text, max, 0)) # Reformatează textul dacă e prea lung
# =======================================
# 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
# =======================================
# SET GM LOOK
# =======================================
def SetGameMasterLook(self):
self.gamemasterMark.Show() # Arată iconița GM
# =======================================
# MINIMIZE
# =======================================
def Minimize(self):
self.titleNameEdit.KillFocus() # Scoate focusul de pe input
self.chatLine.KillFocus() # Scoate focusul de pe chatLine
self.Hide() # Ascunde fereastra
if None != self.eventMinimize:
self.eventMinimize(self.targetName) # Rulează callback pentru minimize
# =======================================
# CLOSE
# =======================================
def Close(self):
chat.ClearWhisper(self.targetName) # Curăță whisper box
self.titleNameEdit.KillFocus() # Scoate focusul de pe input
self.chatLine.KillFocus() # Scoate focusul de pe chatLine
self.Hide() # Ascunde fereastra
if None != self.eventClose:
self.eventClose(self.targetName) # Rulează callback pentru close
# =======================================
# ACCEPT TARGET
# =======================================
def AcceptTarget(self):
name = self.titleNameEdit.GetText() # Ia textul introdus
if len(name) <= 0: # Dacă nu s-a introdus nimic
self.Close() # Închide fereastra
return
if None != self.eventAcceptTarget: # Dacă există callback
self.titleNameEdit.KillFocus() # Scoate focusul
self.eventAcceptTarget(name) # Rulează callback cu numele targetului
# =======================================
# SCROLL WHISPER
# =======================================
def OnScroll(self):
chat.SetWhisperPosition(self.targetName, self.scrollBar.GetPos()) # Actualizează poziția scrollului în chat
# =======================================
# TRIMITERE WHISPER
# =======================================
def SendWhisper(self):
text = self.chatLine.GetText()
if len(text) <= 0:
return
if net.IsInsultIn(text):
chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CHAT_INSULT_STRING)
return
emoji_map = {
":)": "|Eemoji/e_happy|e",
":(": "|Eemoji/e_sad|e",
":O": "|Eemoji/e_surprised|e",
":bored:": "|Eemoji/e_bored|e",
":poop:": "|Eemoji/e_cacat|e",
"B-)": "|Eemoji/e_cocalar|e",
".l.": "|Eemoji/e_cadoufa|e",
":virus:": "|Eemoji/e_coronafrt|e",
":D": "|Eemoji/e_d|e",
":P": "|Eemoji/e_p|e",
":hot:": "|Eemoji/e_estihotvtm|e",
";)": "|Eemoji/e_faccuochiufrt|e",
":facepalm:": "|Eemoji/e_facepalm|e",
":fire:": "|Eemoji/e_fire|e",
":muie:": "|Eemoji/e_fuckyou|e",
":cenzurat:": "|Eemoji/e_fututirasamatii|e",
":goodbye:": "|Eemoji/e_haipa|e",
"<3": "|Eemoji/e_inima|e",
":inlove:": "|Eemoji/e_inlove|e",
":*": "|Eemoji/e_kissyou|e",
":,(": "|Eemoji/e_lakrima|e",
":thinking:": "|Eemoji/e_magandesclamata|e",
":monkey:": "|Eemoji/e_maimuta|e",
":speriat:": "|Eemoji/e_maisperiat|e",
"=))": "|Eemoji/e_mapispatn|e",
":serios:": "|Eemoji/nicimatanutesuporta|e",
"=((": "|Eemoji/e_pling|e",
":clown:": "|Eemoji/e_pozacuatr|e",
":rip:": "|Eemoji/e_rip|e",
":rusine:": "|Eemoji/e_rusine|e",
":nebunie:": "|Eemoji/e_santnebundupatnfa|e",
":shh:": "|Eemoji/e_shh|e",
":fantoma:": "|Eemoji/e_svfantomacaspai2|e",
":vomit:": "|Eemoji/e_vomitpatn|e",
":corona:": "|Eemoji/e_anticorona|e",
":banana:": "|Eemoji/e_banana|e"
}
for key, val in emoji_map.items():
if key in text:
text = text.replace(key, val)
net.SendWhisperPacket(self.targetName, text)
self.chatLine.SetText("")
chat.AppendWhisper(chat.WHISPER_TYPE_CHAT, self.targetName, player.GetName() + " : " + text)
# =======================================
# ON TOP FOCUS
# =======================================
def OnTop(self):
self.chatLine.SetFocus() # Focus pe linia de chat
# =======================================
# BIND INTERFACE
# =======================================
def BindInterface(self, interface):
self.interface = interface # Salvează referința către interface
# =======================================
# MOUSE CLICK PE LINK
# =======================================
def OnMouseLeftButtonDown(self):
hyperlink = ui.GetHyperlink() # Ia hyperlink-ul sub cursor
if hyperlink:
if app.IsPressed(app.DIK_LALT): # Dacă ALT este apăsat
link = chat.GetLinkFromHyperlink(hyperlink) # Extrage link
ime.PasteString(link) # Lipește în input
else:
self.interface.MakeHyperlinkTooltip(hyperlink) # Arată tooltip pentru link
# =======================================
# TEST UI STANDALONE
# =======================================
if "__main__" == __name__:
import uiTest # Import modul test UI
class TestApp(uiTest.App):
def OnInit(self):
wnd = WhisperDialog(self.OnMax, self.OnMin) # Creează instanță WhisperDialog
wnd.LoadDialog() # Încarcă elementele UI
wnd.OpenWithoutTarget(self.OnNew) # Deschide fără target
wnd.SetPosition(0, 0) # Poziție colț stânga sus
wnd.Show() # Arată fereastra
self.wnd = wnd # Salvează referința pentru acces ulterior
def OnMax(self):
pass # Callback pentru maximize
def OnMin(self):
pass # Callback pentru minimize
def OnNew(self):
pass # Callback pentru creare nou target
TestApp().MainLoop() # Pornește bucla principală UI
Zeci de resurse Metin2 Premium - exclusive și 100% funcționale începând cu 15.99€!.
Vezi resursele Cumpără premium
Trebuie să fii membru pentru a răspunde
Membrii pot crea subiecte noi și pot descărca resurse Metin2 Gratuit!
Te poți înregistra sau conecta rapid utilizând contul tău de Discord, Github sau Google.
Utilizatori ce navighează pe acest forum: Andi, dedu4818, pdz0, PepsiZero, Robert Antoci și 2 vizitatori