10 mesaje
Avatar utilizator
Ene
  • Mesaje: 158
  • Reacții: 3816
  • Mesaje utile: 0
  • Status: (^.^)
  • Regat: Shinsoo
  • [ID Discord]
  • Contact:

    Medalii

    *Descriere: ce sunt aceste modificări ei bine oferă posibilitatea de-a executa anumite comenzi direct din pm de către un admin
    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
    *Link download:

    Conținut: Ascuns
    Reacționează ❤️ la acest mesaj și conținutul se va afișa automat.

    Conținut: Ascuns
    Reacționează ❤️ la acest mesaj și conținutul se va afișa automat.

    Nou Cum descarc de pe TeraBox?

    Afișează detalii Ascunde detalii
    • Este asemănător cu Mega.nz
    • Instalați-vă clientul lor de Download de aici
    • Faceți-vă un cont (vă puteți loga cu Facebook / Google / etc)
    • Nou Dacă nu vreți să descărcați clientul de Download, folosiți acest site
    • Gata! Acum puteți descărca resursele rapid & simplu.

    De ce folosim TeraBox?

    • Este gratuit
    • Primești 1TB de spațiu gratuit la orice cont creat!
    • Este ușor de folosit și varianta premium este foarte ieftină
    • Fișierele nu sunt șterse niciodată
    TeraBox logo

    See full signature

    📢 Resurse Metin2 Premium!

    Zeci de resurse Metin2 Premium - exclusive și 100% funcționale începând cu 15.99€!.

    Vezi resursele Cumpără premium
    Premium
    Premium
    Anunț
    Utilizator interzis Utilizator interzis
  • Mesaje: 13
  • Reacții: 4
  • Mesaje utile: 0
  • Server: nu joc
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    Avatar utilizator
    Utilizator interzis
    Utilizator interzis

    Mesaj de scott. »

    e bună ideea.
  • Mesaje: 45
  • Reacții: 86
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Regat: Chunjo
  • Medalii

    cum ai facut sa stea lipite acolo ?
    Administrator Administrator
  • Mesaje: 3543
  • Reacții: 59227
  • Mesaje utile: 37
  • Status: Pe aici.. 🤠
  • Server: Saga2 - Soon
  • Regat: Jinno
  • [ID Discord]
  • Contact:
    Avatar utilizator
    Administrator
    Administrator

    Mesaj de [HF]White »

    petrica5287 scrie: cum ai facut sa stea lipite acolo ?
    scott.
    Te asteptam si pe serverul de Discord :p - aici ne-am strans toata comunitatea de Metin2 din Romania.
    Link: https://discord.gg/jWxeDSf7HP

    Suntem aproape 2000 membri! - Avem chat activ zilnic, support, cereri, resurse. :D :ymcowboy:




    See full signature
    Utilizator interzis Utilizator interzis
  • Mesaje: 13
  • Reacții: 4
  • Mesaje utile: 0
  • Server: nu joc
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    Avatar utilizator
    Utilizator interzis
    Utilizator interzis

    Mesaj de scott. »

    [HF]White scrie:
    petrica5287 scrie: cum ai facut sa stea lipite acolo ?
    scott.
    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.
    l-am scos, că dacă îl mai aveam îl puneam aici.
  • Mesaje: 45
  • Reacții: 86
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Regat: Chunjo
  • Medalii

    scott. ms de info ,oricum nu stiu sa fac ce ai zis tu acolo :)) le las asa sus cum is ele
  • Mesaje: 7
  • Reacții: 7
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Server: Testam si invatam :D
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    Mesaj de l3oogie »

    Imi zice cineva de ce inchide clientul la login cont daca il pun( varianta de sus nici nu deschide clientul ) ? versiune ulthar v2 tmp4 base, il iau si pun impachetez frumos dar apoi daca intru in client il inchide la login.... nu ma pricep, am cautat si cu ai-ul , am urmarit liniile sa vad daca lipseste cuvant, are spatiu sau ceva gresit la o linie .... nu reusesc sa ii dau de cap ....
    Code:
    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()
    
    

    Code:
    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",
    						},
    					),
    				},
    			),
    		},
    	),
    }
    
    

    Rezolvat! merci oricum .
  • Mesaje: 7
  • Reacții: 7
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Server: Testam si invatam :D
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    Mesaj de l3oogie »

    Update :
    Am sa postez separat noul sistem ui pentru gm board buttons facut de mine cu mai multe butoane usor de integrat direct in uiwhisper fara whisperdialog plus, aveti mai multe logici de functionare ale lui, sub whisper se afla si are resize update la board si butoane dupa whisper, are reincadrare butoane pe randuri in functie de resize , are o o latime maxima pentru butoane dupa care, daca cumva depaseste el trece pe urmatorul rand iar la resize whisper daca se calculeaza si da dimensiunea pe axa latimii buna scade cu un rand si trece in rand cu celelalte , altfel o sa apara sub pe randuri , totul este in functie de whisper adica, daca butoanele ajung sa depaseasca acea latime a gm board buttons care e setat dupa o dimensiunea a whisper ului ele trec in rand sub el , aveti padding stanga dreapta, aveti padding sus jos, atat la butoane fata de whisper cat si la board fata de whisper si plus aveti padding intre butoane adica distante , si padding intre randuri ! , am facut zona pickable dar aici am intalnit un bug vizual mic rezolvat astfel , prin chemarea resize whisper in target el da refresh si recalculeaza totul apoi nu mai e bug ul deci nu afecteaza cu nimic , nu sunt expert sa fac codul intr un fisier ui separat ca altfel il faceam, nu stiu sintaxe, si nu stiu multe functii deja definite in ui sistemul metin :))) sper ca o sa va fi e de folos, am sa postez separat acest mic sistem ui facut in uiwhisper doar!
    Il puteti cauta in forum dupa numele de "GM Board Buttons – sistem UI integrat în Whisper (layout dinamic + resize)"

    Doar ca eu nu stiu sa fac imagini frumoase care sa fie afisate cum are .scott pe butoane sau acea culoare pe text buton :))))
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 8 - Imagine 1
    Fişiere ataşate:
    [img]./download/file.php?mode=view&amp;id=6189[/img]
    [img]./download/file.php?mode=view&id=6189[/img]
  • Mesaje: 129
  • Reacții: 441
  • Mesaje utile: 0
  • Status: Incerc sa fac si eu un server!
  • Server: Ro/Eu TigerGhost
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    nu reusesc nici sa fac butoanele functionale am reusit sa separ thinbord-urile l-am facut sa stea central si lipit jos da nu reusesc nici cum sa pun buaonele acolo si sa le fac functionale de 10 ore me chinui cu el
  • Mesaje: 7
  • Reacții: 7
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Server: Testam si invatam :D
  • Regat: Jinno
  • [ID Discord]
  • Contact:

    Medalii

    Mesaj de l3oogie »

    Iti dau o versiune mai noua la ce am facut dar nu ultima, cauta si tu referintele din cod la ce nu are whisper ul normal si le introduci exact cum sunt in ordinea lor din asta si in ala al tau , ok? daca vezi ca ceva dispare din ce ai avut il stergi dar vezi sa nu stergi functii sau clase noi pe care poti sa le ai daca ai whisper deja modificat, nu stau sa pun acum fiecare linie unde vine si ce e nou in el ca maine muncesc si sunt si obosit :
    ATENTIE!!! NU FOLOSESTI REFERINTE IN WHISPERDIALOG.PY DELOC !!! ACOLO NU MAI CREEZI BUTOANE LE STERGI, EU AM CREAT BUTOANELE SI TOT CE TINE DE BOARD SI RESIZE SI REINCADRARI PE RANDURI ETC, DOAR PE WHISPER FARA SA MAI MA ENERVEZ CA TREBUIE SA FAC SI DINCOLO, POTI CREA BUTOANE CATE DORESTI, DAR SUNT SIMPLE NU FAC DECAT COMMAND PE CONSOLA JOC LA CHAT ATAT !! IA AI UL SI INVATA SA TE JOCI CU ELE CUM SI EU AM FACUT :))! Spor :D!
    Code:
    ###############################################################
    #  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
    
    
    
    Poze:
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 1
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 2
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 3

    Eu am ajuns la varianta asta pana acum, unde am pus scroll, am setat minim si maxim pe height la board gm buttons, sa faca si minimize/maximize cu tooltip etc...(Inca invat):
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 4
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 5
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 6
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 7
    [Py] Optiuni Staff in PM (Kick / Teleport / Kill / etc) - Mesaj 10 - Imagine 8
    Fişiere ataşate:
    [img]./download/file.php?mode=view&amp;id=6539[/img]
    [img]./download/file.php?mode=view&id=6539[/img]

    🔥 Hai pe Discord! - Chat activ și support direct

    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!
    Suntem aproape: 
    Robot Discord
    Roboțelu'
    Anunț
    Scrie răspuns

    Creează-ți un cont sau autentifică-te pentru a participa la discuție

    Trebuie să fii membru pentru a răspunde

    Creează-ți un cont

    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.

    Înregistrare

    Autentifică-te

    Înapoi la “Sisteme Metin2”

    Informații

    Utilizatori ce navighează pe acest forum: pdz0, PepsiZero, Robert Antoci, salexandru9982 și 2 vizitatori

    Discord ID copiat: