Jump to content

Ikarus_

Developer
  • Posts

    402
  • Joined

  • Last visited

  • Days Won

    20
  • Feedback

    0%

Posts posted by Ikarus_

  1. 5 hours ago, Jimmermania said:

    uncompatible Visual Studio version. I can't provide you the libs which would work with your version, sorry.
    If you trust it you can download the .exe directly from

    This is the hidden content, please
    .

    • Metin2 Dev 8
    • Good 2
    • Love 1
  2. This is the hidden content, please

    Metin2 Download

     

    Hi Guys,
    I m pretty sure most of you perfectly know what i m meaning for "DEVIL TOWER LAG AFTER WARP",  It's a critical FPS Drop which happen very often just after a warp in a dungeon.
    I ve found the way to definitely fix it with a few lines short change.
     

    Just to spend a few words for those who want to understand something before copying and pasting the fix here is the explanation of the bug:
     

    Spoiler

    First of all we have to understand how entities and their sync works on m2.
    The game core has a 'view list' which contains all the entities near the character and it keep this list updated by processing it every time you move your character.
    This list is continuously kept updated by sending the various changes that occur in it to the client, through packages for adding, removing or updating the characters.

    Now by looking inside CHARACTER::Show we can find this piece of code:
     

        if (bChangeTree) {
            if (GetSectree())
                GetSectree()->RemoveEntity(this);
            ViewCleanup();
        }

    CHARACTER::Show is that way of warp with no loading page, the same way which is used by the command goto while using it with coordinates.

    It checks if the player which is using the command is actually changing the sectree, in this case it perform a cleanup of the view by using CEntity::ViewCleanup.
    Now looking inside this last one:

    void CEntity::ViewCleanup() 
    {
        ENTITY_MAP::iterator it = m_map_view.begin();
    
        while (it != m_map_view.end()) {
            LPENTITY entity = it->first;
            ++it;
            entity->ViewRemove(this, false);
        }
    
        m_map_view.clear();
    }

    As you can see it is using ViewRemove by passing false as second argument, let's take a look on what it implies.

    void CEntity::ViewRemove(LPENTITY entity, bool recursive) {
        ENTITY_MAP::iterator it = m_map_view.find(entity);
    
        if (it == m_map_view.end())
            return;
    
        m_map_view.erase(it);
    
        if (!entity->m_bIsObserver)
            entity->EncodeRemovePacket(this);
    
        if (recursive)
            entity->ViewRemove(this, false);
    }

    The second argument (bool recursive) is the one which determinate if the operation of "Removing from view" the entity is to be replicated even on the caller of the function.
    In this special case of CHARACTER::Show, since ViewCleanup is passing false, it implies the EncodeRemovePacket is going to sending the remove entity packet only to the target entity but not on the caller, which can be translated into the fact that your view range is not going to be resetted after you are using CHARACTER::Show.
    Nothing so orrible till here. Yeah the server is not going to remove the entities near me while moving me out.
    But something much horrible happens client-side as consequence of this.

    CPythonCharacterManager is the class which manage entities, keep them alive or destroying them when the game core sends update packets.
    By looking inside this class we can find a check used to automatically destroy any entities which results to be really far from main character.

                int nDistance =
                    int(pkInstEach->NEW_GetDistanceFromDestInstance(*pkInstMain));
                if (nDistance > CHAR_STAGE_VIEW_BOUND + 10) {
                    __DeleteBlendOutInstance(pkInstEach);
                    m_kAliveInstMap.erase(c);
                    dwDeadInstCount++;
                }

    This check is supposed to be usefull yeah, it would help to don't waste resource to render an entity which is really far from the camera.
    But this check is co-responsible of the FPS drop which makes the dungeon experience really bad.

    Let's see what CNetworkActorManager do inside its Update call.

    void CNetworkActorManager::__OLD_Update() {
        __UpdateMainActor();
    
        CPythonCharacterManager& rkChrMgr = __GetCharacterManager();
    
        std::map<DWORD, SNetworkActorData>::iterator i;
        for (i = m_kNetActorDict.begin(); i != m_kNetActorDict.end(); ++i) {
            SNetworkActorData& rkNetActorData = i->second;
            rkNetActorData.UpdatePosition();
    
            CInstanceBase* pkInstFind =
                rkChrMgr.GetInstancePtr(rkNetActorData.m_dwVID);
            if (!pkInstFind) {
                if (__IsVisibleActor(rkNetActorData))
                    __AppendCharacterManagerActor(rkNetActorData);
            }
        }
    }

    It is iterating the whole list of entities which he knows (the entity list which keep in memory the instance datas sent by the game core) and is searching for the annexed CInstanceBase instance, in case it doesn't exists it is recreating it. 

    Yeah that's all, we have a check destroy far from camera instances, and a check recreating them, this is going to happen in every fu***ng frame. In every fu***ng game update.
     

     

     

    Here is the code:

    This is the hidden content, please

    • Metin2 Dev 242
    • kekw 3
    • Eyes 4
    • Dislove 1
    • Not Good 1
    • Think 2
    • Confused 3
    • Good 62
    • Love 9
    • Love 71
  3. 1 hour ago, CristianDragan said:

    Hi! It works fine for me, but I've got few issues when I add the part for the target system.

    item_manager.cpp: https://pastebin.com/gn7rcYjn

    item_manager.cpp: In member function 'bool ITEM_MANAGER::CreateDropItemVector(CHARACTER*, CHARACTER*, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >&)':

    item_manager.cpp:946: error: 'item' was not declared in this scope

    item_manager.cpp:955: error: 'item' was not declared in this scope

    item_manager.cpp:961: error: no matching function for call to 'MOB_DROP_MANAGER::MakeDropInfoItems(CHARACTER*&, CHARACTER*&, std::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >&)'

    mob_drop_manager.h:168: note: candidates are: void MOB_DROP_MANAGER::MakeDropInfoItems(CHARACTER*, CHARACTER*, std::vector<CItem*, std::allocator<CItem*> >&)

     

    Thanks!

    Your send target info it's a little different and it is using std::vector<std::pair<int,int> instead of std::vector<LPITEM>
    In short, searching inside bool ITEM_MANAGER::CreateDropItemVector find all the call to item = ITEM_MANAGER::instance().CreateItem(vnum, count) and subsequently vec_items.push_back(item)
    and replace it with something like : vec_items.push_back(std::make_pair(vnum, count))

    • Good 1
  4. As you can see there are some extra references, 2 more than expected. The expected result was 2 not 4. Where these references are it is not possible for me to know as I do not have all your root available to read, surely you have some AtlasWindow child that keeps its reference or something like that.
    The self.board was surely one of these, no longer now once you use SetCloseEvent with None. A test we may try is a recursive dump, it might highlight something but even if that leads to nothing, I think the things I can do without reading your code are done.

     

    	def Destroy(self):
    		import dbg
    		
    		def RecursiveDump(obj, name, tab, done_objects):
    			tabstr = '\t' * tab
    			dbg.TraceError(tabstr + ("START WITH DUMP : %s"%name))
    			try:
    				for mem, value in vars(obj).items():
    					dbg.TraceError(tabstr + ("{}.{}={}".format(name,mem,value)))
    				for mem, value in vars(obj).items():
    					if hasattr(value, '__dict__') and id(value) not in done_objects:
    						done_objects.append(id(value))
    						RecursiveDump(value, name + '.' + mem, tab+1, done_objects)
    			except Exception, e:
    				dbg.TraceError("Exception while dumping %s : %s"%(name, str(e)))
    	
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None
    		
    		RecursiveDump(self, 'AtlasWindow', 0, [])

     

  5. Using this code you can check how many references to your AtlasWindow and AtlasWindow.board are still not moved to None.

    	def Destroy(self):
    		import dbg
    		import sys
    		
    		self.board.SetCloseEvent(None)
    		
    		dbg.TraceError("AtlasWindow ref count = {}".format(sys.getrefcount(self)-1))
    		dbg.TraceError("AtlasWindow.board ref count = {}".format(sys.getrefcount(self.board)-1))		
    		
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None

     

  6. I posted the solution but when reloading this thread page i cannot see it at all. I m posting it once again.
     

    	def Destroy(self):
    		self.board.SetCloseEvent(None)
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None

     

    It could solve your bug.

  7. 4 minutes ago, Marcos17 said:

    Using the code you said to put this appears in syseer:

      Reveal hidden contents

    0320 20:55:48182 :: STARTING AtlasWindow.board DUMP
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48182 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.{} = {}
    0320 20:55:48183 :: STARTING AtlasWindow.board.titleBar DUMP
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}
    0320 20:55:48183 :: AtlasWindow.board.titleBar.{} = {}

     

     

     

     

     

     

     

     

     

     

     

     

     

    It looks the message edit wasn't applied successfully, my bad.

    So here's the code with the fix applied.
     

    	def Destroy(self):
    		import dbg
    		references = vars(self.board)
    		dbg.TraceError("STARTING AtlasWindow.board DUMP")
    		for name, value in references.items():
    			dbg.TraceError("AtlasWindow.board.{} = {}".format(name, value))
    			
    		dbg.TraceError("STARTING AtlasWindow.board.titleBar DUMP")
    		for name, value in vars(self.board.titleBar).items():
    			dbg.TraceError("AtlasWindow.board.titleBar.{} = {}".format(name, value))
    		
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None

     

  8. 22 hours ago, Ikarus_ said:

    What may not be cleaned is not necessarily AtlasWindow but its child named "board" . Let's see if you dump it what's coming out.

    	def Destroy(self):
    		import dbg
    		references = vars(self.board)
    		dbg.TraceError("STARTING AtlasWindow.board DUMP")
    		for name, value in references.items():
    			dbg.TraceError("AtlasWindow.board.{} = {}", name, value)
    			
    		dbg.TraceError("STARTING AtlasWindow.board.titleBar DUMP")
    		for name, value in vars(self.board.titleBar).items():
    			dbg.TraceError("AtlasWindow.board.titleBar.{} = {}", name, value)
    		
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None

    The test is obv identical to the previous one.

    My guess is that the close event of the "BoardWithTitleBar" isn't moved to None

    Look at this message, copy this code and make the test. The last test you made use an old Destroy which i corrected yesterday night (for this reason you need to copy again it)

  9. 34 minutes ago, Marcos17 said:
      Reveal hidden contents
    #<----------------------------------------------------------- >#
    #     _ +----------------------------------------------+ _     #
    #    /o)|     Código by Marcos Pinheiro de Lima        |(o\    #
    #   / / |                                              | \ \   #
    #  ( (_ |   Cliente Metin2 ImPaCtO - All Copryght   _  | _) )  #
    # ((\ \)+-/o)--------------------------------- ----(o\-+(/ /)) #
    # (\\\ \_/ /                                        \ \_/ ///) #
    #  \      /                                          \      /  #
    #   \____/                                            \____/   #
    #                                                              #
    #     - Código by Marcos  Lima - Cliente Metin2 ImPaCtO -      #
    #                                                              #
    #<------------------------------------------------------------>#
    import ui
    import uiScriptLocale
    import wndMgr
    import chr
    import player
    import miniMap
    import localeInfo
    import net
    import app
    import colorInfo
    import constInfo
    import background
    import time
    import snd
    import chat
    import bestproductiongame
    import background
    import time
    import re
    import os
    import serverInfo
    import uiToolTip
    import gameInfo
    import uiCommon
    import systemSetting
    import serverInfo
    
    class MapTextToolTip(ui.Window):
    	def __init__(self):
    		ui.Window.__init__(self)
    
    		textLine = ui.TextLine()
    		textLine.SetParent(self)
    		textLine.SetHorizontalAlignCenter()
    		textLine.SetOutline()
    		textLine.SetHorizontalAlignRight()
    		textLine.Show()
    		self.textLine = textLine
    
    	def __del__(self):
    		ui.Window.__del__(self)
    
    	def SetText(self, text):
    		self.textLine.SetText(text)
    
    	def SetTooltipPosition(self, PosX, PosY):
    		if localeInfo.IsARABIC():
    			w, h = self.textLine.GetTextSize()
    			self.textLine.SetPosition(PosX - w - 5, PosY)
    		else:
    			self.textLine.SetPosition(PosX - 5, PosY)
    
    	def SetTextColor(self, TextColor):
    		self.textLine.SetPackedFontColor(TextColor)
    
    	def GetTextSize(self):
    		return self.textLine.GetTextSize()
    
    class AtlasWindow(ui.ScriptWindow):
    
    	class AtlasRenderer(ui.Window):
    		def __init__(self):
    			ui.Window.__init__(self)
    			self.AddFlag("not_pick")
    
    		def OnUpdate(self):
    			miniMap.UpdateAtlas()
    
    		def OnRender(self):
    			(x, y) = self.GetGlobalPosition()
    			fx = float(x)
    			fy = float(y)
    			miniMap.RenderAtlas(fx, fy)
    
    		def HideAtlas(self):
    			miniMap.HideAtlas()
    
    		def ShowAtlas(self):
    			miniMap.ShowAtlas()
    
    	def __init__(self):
    		self.tooltipInfo = MapTextToolTip()
    		self.tooltipInfo.Hide()
    		self.infoGuildMark = ui.MarkBox()
    		self.infoGuildMark.Hide()
    		self.AtlasMainWindow = None
    		self.mapName = ""
    		self.board = 0
    
    		ui.ScriptWindow.__init__(self)
    
    	def __del__(self):
    		ui.ScriptWindow.__del__(self)
    
    	def SetMapName(self, mapName):
    		if 949==app.GetDefaultCodePage():
    			try:
    				self.board.SetTitleName(localeInfo.MINIMAP_ZONE_NAME_DICT[mapName])
    			except:
    				pass
    
    	def LoadWindow(self):
    		try:
    			pyScrLoader = ui.PythonScriptLoader()
    			pyScrLoader.LoadScriptFile(self, "UIScript/AtlasWindow.py")
    		except:
    			import exception
    			exception.Abort("AtlasWindow.LoadWindow.LoadScript")
    
    		try:
    			self.board = self.GetChild("board")
    
    		except:
    			import exception
    			exception.Abort("AtlasWindow.LoadWindow.BindObject")
    
    		self.AtlasMainWindow = self.AtlasRenderer()
    		self.board.SetCloseEvent(self.Hide)
    		self.AtlasMainWindow.SetParent(self.board)
    		self.AtlasMainWindow.SetPosition(7, 30)
    		self.tooltipInfo.SetParent(self.board)
    		self.infoGuildMark.SetParent(self.board)
    		self.SetPosition(wndMgr.GetScreenWidth() - 136 - 256 - 10, 0)
    		self.Hide()
    
    		miniMap.RegisterAtlasWindow(self)
    
    #	def Destroy(self):
    #		miniMap.UnregisterAtlasWindow()
    #		self.ClearDictionary()
    #		self.AtlasMainWindow = None
    #		self.tooltipAtlasClose = 0
    #		self.tooltipInfo = None
    #		self.infoGuildMark = None
    #		self.board = None
    
    	def Destroy(self):
    		import dbg
    		references = vars(self.board)
    		dbg.TraceError("STARTING AtlasWindow.board DUMP")
    		for name, value in references.items():
    			dbg.TraceError("AtlasWindow.board.{} = {}", name, value)
    
    		dbg.TraceError("STARTING AtlasWindow.board.titleBar DUMP")
    		for name, value in vars(self.board.titleBar).items():
    			dbg.TraceError("AtlasWindow.board.titleBar.{} = {}", name, value)
    
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None
    
    	def OnUpdate(self):
    
    		if not self.tooltipInfo:
    			return
    
    		if not self.infoGuildMark:
    			return
    
    		self.infoGuildMark.Hide()
    		self.tooltipInfo.Hide()
    
    		if FALSE == self.board.IsIn():
    			return
    
    		(mouseX, mouseY) = wndMgr.GetMousePosition()
    		(bFind, sName, iPosX, iPosY, dwTextColor, dwGuildID) = miniMap.GetAtlasInfo(mouseX, mouseY)
    
    		if FALSE == bFind:
    			return
    
    		if "empty_guild_area" == sName:
    			sName = localeInfo.GUILD_EMPTY_AREA
    
    		if localeInfo.IsARABIC() and sName[-1].isalnum():
    			self.tooltipInfo.SetText("(%s)%d, %d" % (sName, iPosX, iPosY))
    		else:
    			self.tooltipInfo.SetText("%s(%d, %d)" % (sName, iPosX, iPosY))
    
    		(x, y) = self.GetGlobalPosition()
    		self.tooltipInfo.SetTooltipPosition(mouseX - x, mouseY - y)
    		self.tooltipInfo.SetTextColor(dwTextColor)
    		self.tooltipInfo.Show()
    		self.tooltipInfo.SetTop()
    
    		if 0 != dwGuildID:
    			textWidth, textHeight = self.tooltipInfo.GetTextSize()
    			self.infoGuildMark.SetIndex(dwGuildID)
    			self.infoGuildMark.SetPosition(mouseX - x - textWidth - 18 - 5, mouseY - y)
    			self.infoGuildMark.Show()
    
    	def Hide(self):
    		if self.AtlasMainWindow:
    			self.AtlasMainWindow.HideAtlas()
    			self.AtlasMainWindow.Hide()
    		ui.ScriptWindow.Hide(self)
    
    	def Show(self):
    		if self.AtlasMainWindow:
    			(bGet, iSizeX, iSizeY) = miniMap.GetAtlasSize()
    			if bGet:
    				self.SetSize(iSizeX + 15, iSizeY + 38)
    
    				if localeInfo.IsARABIC():
    					self.board.SetPosition(iSizeX+15, 0)
    
    				self.board.SetSize(iSizeX + 15, iSizeY + 38)
    				#self.AtlasMainWindow.SetSize(iSizeX, iSizeY)
    				self.AtlasMainWindow.ShowAtlas()
    				self.AtlasMainWindow.Show()
    		ui.ScriptWindow.Show(self)
    
    	def SetCenterPositionAdjust(self, x, y):
    		self.SetPosition((wndMgr.GetScreenWidth() - self.GetWidth()) / 2 + x, (wndMgr.GetScreenHeight() - self.GetHeight()) / 2 + y)
    
    	def OnPressEscapeKey(self):
    		self.Hide()
    		return TRUE
    
    	def __RegisterMiniMapColor(type, rgb):
    		miniMap.RegisterColor(type, rgb[0], rgb[1], rgb[2])
    
    class MiniMap(ui.ScriptWindow):
    
    	CANNOT_SEE_INFO_MAP_DICT = {
    		"metin2_map_monkeydungeon" : FALSE,
    		"metin2_map_monkeydungeon_02" : FALSE,
    		"metin2_map_monkeydungeon_03" : FALSE,
    		"metin2_map_devilsCatacomb" : FALSE,
    		"metin2_map_wood_event1" : FALSE,
    		"metin2_map_n_flame_dungeon_01" : FALSE,
    		"metin2_map_n_snow_dungeon_01" : FALSE,
    	}
    
    	def __init__(self):
    		ui.ScriptWindow.__init__(self)
    
    		self.__Initialize()
    
    		miniMap.Create()
    		miniMap.SetScale(2.0)
    
    		self.AtlasWindow = AtlasWindow()
    		self.AtlasWindow.LoadWindow()
    		self.AtlasWindow.Hide()
    
    		self.tooltipMiniMapOpen = MapTextToolTip()
    		self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP)
    		self.tooltipMiniMapOpen.Show()
    		self.tooltipMiniMapClose = MapTextToolTip()
    		self.tooltipMiniMapClose.SetText(localeInfo.UI_CLOSE)
    		self.tooltipMiniMapClose.Show()
    		self.tooltipScaleUp = MapTextToolTip()
    		self.tooltipScaleUp.SetText(localeInfo.MINIMAP_INC_SCALE)
    		self.tooltipScaleUp.Show()
    		self.tooltipScaleDown = MapTextToolTip()
    		self.tooltipScaleDown.SetText(localeInfo.MINIMAP_DEC_SCALE)
    		self.tooltipScaleDown.Show()
    		self.tooltipAnimesfer = MapTextToolTip()
    		self.tooltipAnimesfer.SetText(localeInfo.ANIMESFER)
    		self.tooltipAnimesfer.Show()
    		self.tooltipCombatZone = MapTextToolTip()
    		self.tooltipCombatZone.SetText(localeInfo.COMBAT_ZONE)
    		self.tooltipCombatZone.Show()
    		self.tooltipAtlasOpen = MapTextToolTip()
    		self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP)
    		self.tooltipAtlasOpen.Show()
    		self.tooltipInfo = MapTextToolTip()
    		self.tooltipInfo.Show()
    
    		if miniMap.IsAtlas():
    			self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP)
    		else:
    			self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_CAN_NOT_SHOW_AREAMAP)
    
    		self.tooltipInfo = MapTextToolTip()
    		self.tooltipInfo.Show()
    
    		self.mapName = ""
    
    		self.isLoaded = 0
    		self.canSeeInfo = TRUE
    
    		# AUTOBAN
    		self.imprisonmentDuration = 0
    		self.imprisonmentEndTime = 0
    		self.imprisonmentEndTimeText = ""
    		# END_OF_AUTOBAN
    
    	def __del__(self):
    		miniMap.Destroy()
    		ui.ScriptWindow.__del__(self)
    
    	def __Initialize(self):
    		self.positionInfo = 0
    		self.observerCount = 0
    		if constInfo.MINIMAP_MAPNAME_ENABLE:
    			self.MapNameInfo = ""
    		if constInfo.MINIMAP_DATETIME_ENABLE:
    			self.DateTimeInfo = 0
    		self.OpenWindow = 0
    		self.CloseWindow = 0
    		self.ScaleUpButton = 0
    		self.ScaleDownButton = 0
    		self.AnimesferButton = 0
    		self.MiniMapHideButton = 0
    		self.MiniMapShowButton = 0
    		self.AtlasShowButton = 0
    
    		if (app.WJ_COMBAT_ZONE):
    			self.btnCombatZone = 0
    
    		self.tooltipMiniMapOpen = 0
    		self.tooltipMiniMapClose = 0
    		self.tooltipScaleUp = 0
    		self.tooltipScaleDown = 0
    		self.tooltipAtlasOpen = 0
    		self.tooltipInfo = None
    		self.serverInfo = None
    
    		if app.ENABLE_DEFENSE_WAVE:
    			self.MastHp = 0
    
    	def SetMapName(self, mapName):
    		self.mapName=mapName
    		self.AtlasWindow.SetMapName(mapName)
    
    		if app.TOURNAMENT_PVP_SYSTEM:
    			if player.IsTournamentMap():
    				self.canSeeInfo = FALSE
    				self.HideMiniMap()
    				ui.ScriptWindow.Hide(self)
    
    		if self.CANNOT_SEE_INFO_MAP_DICT.has_key(mapName):
    			self.canSeeInfo = FALSE
    			self.HideMiniMap()
    			self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP_CANNOT_SEE)
    		else:
    			self.canSeeInfo = TRUE
    			self.ShowMiniMap()
    			self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP)
    
    	# AUTOBAN
    	def SetImprisonmentDuration(self, duration):
    		self.imprisonmentDuration = duration
    		self.imprisonmentEndTime = app.GetGlobalTimeStamp() + duration
    
    		self.__UpdateImprisonmentDurationText()
    
    	def __UpdateImprisonmentDurationText(self):
    		restTime = max(self.imprisonmentEndTime - app.GetGlobalTimeStamp(), 0)
    
    		imprisonmentEndTimeText = localeInfo.SecondToDHM(restTime)
    		if imprisonmentEndTimeText != self.imprisonmentEndTimeText:
    			self.imprisonmentEndTimeText = imprisonmentEndTimeText
    			self.serverInfo.SetText("%s: %s" % (uiScriptLocale.AUTOBAN_QUIZ_REST_TIME, self.imprisonmentEndTimeText))
    	# END_OF_AUTOBAN
    
    	def Show(self):
    		self.__LoadWindow()
    
    		ui.ScriptWindow.Show(self)
    
    	def __LoadWindow(self):
    		if self.isLoaded == 1:
    			return
    
    		self.isLoaded = 1
    
    		try:
    			pyScrLoader = ui.PythonScriptLoader()
    			if localeInfo.IsARABIC():
    				pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "Minimap.py")
    			else:
    				pyScrLoader.LoadScriptFile(self, "UIScript/MiniMap.py")
    		except:
    			import exception
    			exception.Abort("MiniMap.LoadWindow.LoadScript")
    
    		try:
    			self.OpenWindow = self.GetChild("OpenWindow")
    			self.MiniMapWindow = self.GetChild("MiniMapWindow")
    			self.ScaleUpButton = self.GetChild("ScaleUpButton")
    			self.ScaleDownButton = self.GetChild("ScaleDownButton")
    			self.AnimesferButton = self.GetChild("AnimesferButton")
    			self.MiniMapHideButton = self.GetChild("MiniMapHideButton")
    			self.AtlasShowButton = self.GetChild("AtlasShowButton")
    			self.CloseWindow = self.GetChild("CloseWindow")
    			self.MiniMapShowButton = self.GetChild("MiniMapShowButton")
    			self.positionInfo = self.GetChild("PositionInfo")
    			self.observerCount = self.GetChild("ObserverCount")
    			self.serverInfo = self.GetChild("ServerInfo")
    			if app.ENABLE_DEFENSE_WAVE:
    				self.MastHp = self.GetChild("MastHp")
    				self.MastWindow = self.GetChild("MastWindow")
    				self.MastHp.OnMouseOverIn = ui.__mem_func__(self.MastHp.ShowToolTip)
    				self.MastHp.OnMouseOverOut = ui.__mem_func__(self.MastHp.HideToolTip)
    				self.MastHp.SetShowToolTipEvent(self.MastHp.OnMouseOverIn)
    				self.MastHp.SetHideToolTipEvent(self.MastHp.OnMouseOverOut)
    			if (app.WJ_COMBAT_ZONE):
    				self.btnCombatZone = self.GetChild("BattleButton")
    			self.wndMds = self.GetChild("Mds")
    			if constInfo.MINIMAP_MAPNAME_ENABLE:
    				self.MapNameInfo = self.GetChild("MapNameInfo")
    			if constInfo.MINIMAP_DATETIME_ENABLE:
    				self.DateTimeInfo = self.GetChild("DateTimeInfo")
    		except:
    			import exception
    			exception.Abort("MiniMap.LoadWindow.Bind")
    
    		self.GetChild("Mds").SetFontName("Tahoma:10.8")
    
    		if constInfo.MINIMAP_MAPNAME_ENABLE==0:
    			self.MapNameInfo.hide()
    
    		if constInfo.MINIMAP_POSITIONINFO_ENABLE==0:
    			self.positionInfo.Hide()
    
    		if app.ENABLE_DEFENSE_WAVE:
    			self.MastHp.SetPercentage(5000000, 5000000)
    			self.MastWindow.Hide()
    
    		self.serverInfo.SetText(net.GetServerInfo())
    		self.ScaleUpButton.SetEvent(ui.__mem_func__(self.ScaleUp))
    		self.ScaleDownButton.SetEvent(ui.__mem_func__(self.ScaleDown))
    		self.MiniMapHideButton.SetEvent(ui.__mem_func__(self.HideMiniMap))
    		self.MiniMapShowButton.SetEvent(ui.__mem_func__(self.ShowMiniMap))
    		self.wndCostume = None
    		if (app.WJ_COMBAT_ZONE):
    			self.btnCombatZone.SetEvent(ui.__mem_func__(self.OpenCombatZoneWindow))
    			self.btnCombatZone.Down()
    
    		if miniMap.IsAtlas():
    			self.AtlasShowButton.SetEvent(ui.__mem_func__(self.ShowAtlas))
    
    		(ButtonPosX, ButtonPosY) = self.MiniMapShowButton.GetGlobalPosition()
    		self.tooltipMiniMapOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.MiniMapHideButton.GetGlobalPosition()
    		self.tooltipMiniMapClose.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.ScaleUpButton.GetGlobalPosition()
    		self.tooltipScaleUp.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.ScaleDownButton.GetGlobalPosition()
    		self.tooltipScaleDown.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.AnimesferButton.GetGlobalPosition()
    		self.tooltipAnimesfer.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.btnCombatZone.GetGlobalPosition()
    		self.tooltipCombatZone.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		(ButtonPosX, ButtonPosY) = self.AtlasShowButton.GetGlobalPosition()
    		self.tooltipAtlasOpen.SetTooltipPosition(ButtonPosX, ButtonPosY)
    
    		self.ShowMiniMap()
    
    	def Destroy(self):
    		self.HideMiniMap()
    
    		self.wndMds = 0
    		self.wndMdsSlot = 0
    
    		self.AtlasWindow.Destroy()
    		self.AtlasWindow = None
    
    		self.ClearDictionary()
    
    		self.__Initialize()
    
    	def UpdateObserverCount(self, observerCount):
    		if observerCount>0:
    			self.observerCount.Show()
    		elif observerCount<=0:
    			self.observerCount.Hide()
    
    		self.observerCount.SetText(localeInfo.MINIMAP_OBSERVER_COUNT % observerCount)
    
    	if constInfo.MINIMAP_MAPNAME_ENABLE:
    		def UpdateMapName(self, MapName):
    			self.MapNameInfo.SetText("|cfff64e3f|h" + MapName)
    
    	if constInfo.MINIMAP_DATETIME_ENABLE:
    		def UpdateDateTime(self, dateTime):
    			self.DateTimeInfo.SetText("|cff00ffea|h" + dateTime)
    
    	def OnUpdate(self):
    		(x, y, z) = player.GetMainCharacterPosition()
    		miniMap.Update(x, y)
    		import constInfo
    		self.wndMds.SetText(str(constInfo.pe))
    
    		self.positionInfo.SetText("|cff00ccff(%.0f, %.0f)" % (x/100, y/100))
    
    		if self.tooltipInfo:
    			if TRUE == self.MiniMapWindow.IsIn():
    				(mouseX, mouseY) = wndMgr.GetMousePosition()
    				(bFind, sName, iPosX, iPosY, dwTextColor) = miniMap.GetInfo(mouseX, mouseY)
    				if bFind == 0:
    					self.tooltipInfo.Hide()
    				elif not self.canSeeInfo:
    					self.tooltipInfo.SetText("%s(%s)" % (sName, localeInfo.UI_POS_UNKNOWN))
    					self.tooltipInfo.SetTooltipPosition(mouseX - 5, mouseY)
    					self.tooltipInfo.SetTextColor(dwTextColor)
    					self.tooltipInfo.Show()
    				else:
    					if localeInfo.IsARABIC() and sName[-1].isalnum():
    						self.tooltipInfo.SetText("(%s)%d, %d" % (sName, iPosX, iPosY))
    					else:
    						self.tooltipInfo.SetText("%s(%d, %d)" % (sName, iPosX, iPosY))
    					self.tooltipInfo.SetTooltipPosition(mouseX - 5, mouseY)
    					self.tooltipInfo.SetTextColor(dwTextColor)
    					self.tooltipInfo.Show()
    			else:
    				self.tooltipInfo.Hide()
    
    			# AUTOBAN
    			if self.imprisonmentDuration:
    				self.__UpdateImprisonmentDurationText()
    			# END_OF_AUTOBAN
    
    		if TRUE == self.MiniMapShowButton.IsIn():
    			self.tooltipMiniMapOpen.Show()
    		else:
    			self.tooltipMiniMapOpen.Hide()
    
    		if TRUE == self.MiniMapHideButton.IsIn():
    			self.tooltipMiniMapClose.Show()
    		else:
    			self.tooltipMiniMapClose.Hide()
    
    		if TRUE == self.ScaleUpButton.IsIn():
    			self.tooltipScaleUp.Show()
    		else:
    			self.tooltipScaleUp.Hide()
    
    		if TRUE == self.ScaleDownButton.IsIn():
    			self.tooltipScaleDown.Show()
    		else:
    			self.tooltipScaleDown.Hide()
    
    		if TRUE == self.AnimesferButton.IsIn():
    			self.tooltipAnimesfer.Show()
    		else:
    			self.tooltipAnimesfer.Hide()
    
    		if TRUE == self.btnCombatZone.IsIn():
    			self.tooltipCombatZone.Show()
    		else:
    			self.tooltipCombatZone.Hide()
    
    		if TRUE == self.AtlasShowButton.IsIn():
    			self.tooltipAtlasOpen.Show()
    		else:
    			self.tooltipAtlasOpen.Hide()
    
    	def OnRender(self):
    		(x, y) = self.GetGlobalPosition()
    		fx = float(x)
    		fy = float(y)
    		miniMap.Render(fx + 4.0, fy + 5.0)
    
    	def Close(self):
    		self.HideMiniMap()
    
    	def HideMiniMap(self):
    		miniMap.Hide()
    		self.OpenWindow.Hide()
    		self.CloseWindow.Show()
    
    	def ShowMiniMap(self):
    		if not self.canSeeInfo:
    			return
    
    		miniMap.Show()
    		self.OpenWindow.Show()
    		self.CloseWindow.Hide()
    
    	def isShowMiniMap(self):
    		return miniMap.isShow()
    
    	if (app.WJ_COMBAT_ZONE):
    		def OnAskCombatZoneQuestionDialog(self):
    			import uiCommon
    			self.combatZoneLeaveQuestionDialog = uiCommon.QuestionDialog2()
    			self.combatZoneLeaveQuestionDialog.SetText1(uiScriptLocale.EXIT_BATTLE_FIELD_COLLECTED_POINTS % (player.GetCombatZonePoints()))
    			self.combatZoneLeaveQuestionDialog.SetText2(uiScriptLocale.EXIT_BATTLE_FIELD)
    			self.combatZoneLeaveQuestionDialog.SetWidth(320)
    			self.combatZoneLeaveQuestionDialog.SetAcceptEvent(lambda arg = TRUE: self.OnToggleCombatZoneQuestionDialog(arg))
    			self.combatZoneLeaveQuestionDialog.SetCancelEvent(lambda arg = FALSE: self.OnToggleCombatZoneQuestionDialog(arg))
    			self.combatZoneLeaveQuestionDialog.Open()
    
    		def OnToggleCombatZoneQuestionDialog(self, answer):
    			if not self.combatZoneLeaveQuestionDialog:
    				return
    
    			self.combatZoneLeaveQuestionDialog.Close()
    			self.combatZoneLeaveQuestionDialog = None
    
    			if not answer:
    				return
    
    			net.SendCombatZoneRequestActionPacket(net.COMBAT_ZONE_ACTION_LEAVE, net.COMBAT_ZONE_EMPTY_DATA)
    			return TRUE
    
    		def OpenCombatZoneWindow(self):
    			if app.WJ_SECURITY_SYSTEM and player.IsSecurityActivate():
    				return
    			if player.IsCombatZoneMap():
    				self.OnAskCombatZoneQuestionDialog()
    			else:
    				net.SendCombatZoneRequestActionPacket(net.COMBAT_ZONE_ACTION_OPEN_RANKING, net.COMBAT_ZONE_EMPTY_DATA)
    
    	def ScaleUp(self):
    		miniMap.ScaleUp()
    
    	def __IsSpecialMap(self):
    		Blocked_MAPS = [
    			"season1/metin2_map_oxevent",
    			"season2/metin2_map_guild_inside01",
    			"season2/metin2_map_empirewar01",
    			"season2/metin2_map_empirewar02",
    			"season2/metin2_map_empirewar03",
    			"metin2_map_dragon_timeattack_01",
    			"metin2_map_dragon_timeattack_02",
    			"metin2_map_dragon_timeattack_03",
    			"metin2_map_skipia_dungeon_boss",
    			"metin2_map_skipia_dungeon_boss2",
    			"metin2_map_devilsCatacomb",
    			"metin2_map_deviltower1",
    			"metin2_map_t1",
    			"metin2_map_t2",
    			"metin2_map_t3",
    			"metin2_map_t4",
    			"metin2_map_t5",
    			"metin2_map_wedding_01",
    			"metin2_map_ring",
    			"metin2_map_gemi",
    			"gm_guild_build",
    			"metin2_map_duel"
    		]
    
    		if str(background.GetCurrentMapName()) in Blocked_MAPS:
    			return TRUE
    
    		return FALSE
    
    	def ScaleDown(self):
    		miniMap.ScaleDown()
    
    	def ShowAtlas(self):
    		if not miniMap.IsAtlas():
    			return
    		if not self.AtlasWindow.IsShow():
    			self.AtlasWindow.Show()
    		else:
    			self.AtlasWindow.Hide()
    
    	def ToggleAtlasWindow(self):
    		if not miniMap.IsAtlas():
    			return
    		if self.AtlasWindow.IsShow():
    			self.AtlasWindow.Hide()
    		else:
    			self.AtlasWindow.Show()
    
    	if app.ENABLE_DEFENSE_WAVE:
    		def SetMastHP(self, hp):
    			self.MastHp.SetPercentage(hp, 5000000)
    			self.MastHp.SetToolTipText("HP:  %d /5000000" % hp)
    
    		def SetMastWindow(self, i):
    			if i:
    				self.MastWindow.Show()
    			else:
    				self.MastWindow.Hide()
    
    	def UpdateChannelInfo(self, channel):
    		if constInfo.SERVER_TYPE == 1:
    			srvName = serverInfo.SERVER_1
    		elif constInfo.SERVER_TYPE == 2:
    			srvName = serverInfo.SERVER_2
    		else:
    			srvName = serverInfo.SERVER_1
    		if channel == 99:
    			serverInfoStr = srvName + ' - Ortak Kanal'
    		else:
    			serverInfoStr = srvName + ' - ' + str(channel) + '. Kanal'
    		self.serverInfo.SetText(serverInfoStr)
    		net.SetServerInfo(serverInfoStr)

     

     

    I meant the code posted by me. The last Destroy

  10. 16 minutes ago, Marcos17 said:
      Hide contents

    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.{} = {}
    0320 15:56:38838 :: STARTING AtlasWindow.board.titleBar DUMP
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}
    0320 15:56:38838 :: AtlasWindow.board.titleBar.{} = {}

     

    Yesterday i update the code fixing a bug, but it looks you copied it with no fix applied. Can u copy it again? 

  11. What may not be cleaned is not necessarily AtlasWindow but its child named "board" . Let's see if you dump it what's coming out.

    	def Destroy(self):
    		import dbg
    		references = vars(self.board)
    		dbg.TraceError("STARTING AtlasWindow.board DUMP")
    		for name, value in references.items():
    			dbg.TraceError("AtlasWindow.board.{} = {}", name, value)
    			
    		dbg.TraceError("STARTING AtlasWindow.board.titleBar DUMP")
    		for name, value in vars(self.board.titleBar).items():
    			dbg.TraceError("AtlasWindow.board.titleBar.{} = {}", name, value)
    		
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None

    The test is obv identical to the previous one.

    My guess is that the close event of the "BoardWithTitleBar" isn't moved to None

  12. 18 minutes ago, Marcos17 said:

    I looked at the class you referred to and everything seems to be correct, but the error persists =/

      Reveal hidden contents
    class AtlasWindow(ui.ScriptWindow):
    
    	class AtlasRenderer(ui.Window):
    		def __init__(self):
    			ui.Window.__init__(self)
    			self.AddFlag("not_pick")
    
    		def OnUpdate(self):
    			miniMap.UpdateAtlas()
    
    		def OnRender(self):
    			(x, y) = self.GetGlobalPosition()
    			fx = float(x)
    			fy = float(y)
    			miniMap.RenderAtlas(fx, fy)
    
    		def HideAtlas(self):
    			miniMap.HideAtlas()
    
    		def ShowAtlas(self):
    			miniMap.ShowAtlas()
    
    	def __init__(self):
    		self.tooltipInfo = MapTextToolTip()
    		self.tooltipInfo.Hide()
    		self.infoGuildMark = ui.MarkBox()
    		self.infoGuildMark.Hide()
    		self.AtlasMainWindow = None
    		self.mapName = ""
    		self.board = 0
    
    		ui.ScriptWindow.__init__(self)
    
    	def __del__(self):
    		ui.ScriptWindow.__del__(self)
    
    	def SetMapName(self, mapName):
    		if 949==app.GetDefaultCodePage():
    			try:
    				self.board.SetTitleName(localeInfo.MINIMAP_ZONE_NAME_DICT[mapName])
    			except:
    				pass
    
    	def LoadWindow(self):
    		try:
    			pyScrLoader = ui.PythonScriptLoader()
    			pyScrLoader.LoadScriptFile(self, "UIScript/AtlasWindow.py")
    		except:
    			import exception
    			exception.Abort("AtlasWindow.LoadWindow.LoadScript")
    
    		try:
    			self.board = self.GetChild("board")
    
    		except:
    			import exception
    			exception.Abort("AtlasWindow.LoadWindow.BindObject")
    
    		self.AtlasMainWindow = self.AtlasRenderer()
    		self.board.SetCloseEvent(self.Hide)
    		self.AtlasMainWindow.SetParent(self.board)
    		self.AtlasMainWindow.SetPosition(7, 30)
    		self.tooltipInfo.SetParent(self.board)
    		self.infoGuildMark.SetParent(self.board)
    		self.SetPosition(wndMgr.GetScreenWidth() - 136 - 256 - 10, 0)
    		self.Hide()
    
    		miniMap.RegisterAtlasWindow(self)
    
    	def Destroy(self):
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None
    
    	def OnUpdate(self):
    
    		if not self.tooltipInfo:
    			return
    
    		if not self.infoGuildMark:
    			return
    
    		self.infoGuildMark.Hide()
    		self.tooltipInfo.Hide()
    
    		if FALSE == self.board.IsIn():
    			return
    
    		(mouseX, mouseY) = wndMgr.GetMousePosition()
    		(bFind, sName, iPosX, iPosY, dwTextColor, dwGuildID) = miniMap.GetAtlasInfo(mouseX, mouseY)
    
    		if FALSE == bFind:
    			return
    
    		if "empty_guild_area" == sName:
    			sName = localeInfo.GUILD_EMPTY_AREA
    
    		if localeInfo.IsARABIC() and sName[-1].isalnum():
    			self.tooltipInfo.SetText("(%s)%d, %d" % (sName, iPosX, iPosY))
    		else:
    			self.tooltipInfo.SetText("%s(%d, %d)" % (sName, iPosX, iPosY))
    
    		(x, y) = self.GetGlobalPosition()
    		self.tooltipInfo.SetTooltipPosition(mouseX - x, mouseY - y)
    		self.tooltipInfo.SetTextColor(dwTextColor)
    		self.tooltipInfo.Show()
    		self.tooltipInfo.SetTop()
    
    		if 0 != dwGuildID:
    			textWidth, textHeight = self.tooltipInfo.GetTextSize()
    			self.infoGuildMark.SetIndex(dwGuildID)
    			self.infoGuildMark.SetPosition(mouseX - x - textWidth - 18 - 5, mouseY - y)
    			self.infoGuildMark.Show()
    
    	def Hide(self):
    		if self.AtlasMainWindow:
    			self.AtlasMainWindow.HideAtlas()
    			self.AtlasMainWindow.Hide()
    		ui.ScriptWindow.Hide(self)
    
    	def Show(self):
    		if self.AtlasMainWindow:
    			(bGet, iSizeX, iSizeY) = miniMap.GetAtlasSize()
    			if bGet:
    				self.SetSize(iSizeX + 15, iSizeY + 38)
    
    				if localeInfo.IsARABIC():
    					self.board.SetPosition(iSizeX+15, 0)
    
    				self.board.SetSize(iSizeX + 15, iSizeY + 38)
    				#self.AtlasMainWindow.SetSize(iSizeX, iSizeY)
    				self.AtlasMainWindow.ShowAtlas()
    				self.AtlasMainWindow.Show()
    		ui.ScriptWindow.Show(self)
    
    	def SetCenterPositionAdjust(self, x, y):
    		self.SetPosition((wndMgr.GetScreenWidth() - self.GetWidth()) / 2 + x, (wndMgr.GetScreenHeight() - self.GetHeight()) / 2 + y)
    
    	def OnPressEscapeKey(self):
    		self.Hide()
    		return TRUE

     

     

    There's a easy&fast way to check if i m correct.
    Replace your def Destroy with mine posting here:
     

    	def Destroy(self):
    		miniMap.UnregisterAtlasWindow()
    		self.ClearDictionary()
    		self.AtlasMainWindow = None
    		self.tooltipAtlasClose = 0
    		self.tooltipInfo = None
    		self.infoGuildMark = None
    		self.board = None
    		
    		import dbg
    		references = vars(self)
    		dbg.TraceError("STARTING WITH DUMPING AtlasWindow")
    		for name, value in references.items():
    			dgb.TraceError("AtlasWindowReference {}={}".format(name, value))

    You need to login into game and warp your character, You will find dumping inside your syserr.txt

    Let's  hypothesize the possible scenarios:
    1. The syserr looks empty : Your Destroy function is never called: You must call it
    2. The syserr contains strings but all of them has value "None" or numbers/empty lists etc: My guess was wrong, the problem is something else.
    3. The syserr contains strings and at least one of them is a reference to an object which makes your AtlasWindow not cleaned enough.
    if you need help understanding what scenario you got you can post your syserr here

    • Love 1
  13. On 1/17/2018 at 11:14 PM, .Stefan said:

    Hey,

    i got a double Map shown after a teleport. I don't really know what it could be. Any Tips where to search ?

    c6cd581f70cf6ce743f3177a8f3a938f.png

    Memory leak.

    All references instantiated in the class must be set to None before deleting the object.
    Check your class AtlasWindow inside uiminimap.py and search for def Destroy, inside this function you have to move to None all the reference.

     

    • Metin2 Dev 1
    • Love 1
  14. On 3/14/2022 at 10:38 PM, Hik said:

    In the end i used this:

     

    int random_drop(int min, int max)
    {
        std::random_device device;
        std::mt19937 generator(device());
        std::uniform_int_distribution<int> distribution(min, max);
        return distribution(generator);
    }

     

    It works yeah, but it is really slow.

    I would suggest you something much faster.

    int number(int v1, int v2) 
    {
    	thread_local std::default_random_engine _Generator;
    	thread_local bool _Init = false;
    
    	if (!_Init)
    	{
    		_Init = true;
    		std::random_device dev;
    		_Generator.seed(dev());
    	}
    
    	std::uniform_int_distribution<int> distribution(v1, v2);
    	return distribution(_Generator);
    }

    It can totally replace the old "number" function from libthrecore (you have to remove the macro defined inside libthrecore/inlude/utils.h)
     

    Here's a small test showing how my function is faster:
    https://onlinegdb.com/27jNGeGOlx
     

    Execution time in seconds (1.000.000 function calls):

    number time : 0.0718687
    random_drop time : 17.9117

     

     

    • Good 2
    • Love 1
    • Love 1
  15. On 5/20/2021 at 7:40 AM, Suzar said:

    I do not recommend it, it causes a lot of inconvenience.

    For example?

    I used it for a long time and i can affirm that is stable, so if you got problems about this fix probably you got some change that is conflicting with it.
    If you need you can post your problems and we could search for a solution.

  16. 22 hours ago, Mafuyu said:

    for your disclaimer, should it not be enough if you check the CanWarp directly at the pc_warp function in questlua_pc? so you dont need to add the check to EVERY quest

     

    like this

     

    
    		if (!ch->CanWarp())
    		{
    			ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("CANNOT_WARP_AFTER_TRADING"));
    			lua_pushboolean(L, false);
    			return 1;
    		}

     

    I don't like it, but feel free to use it

  17. On 4/16/2021 at 8:19 PM, Ulthar said:

    EVERYONE

    Who have the same problem like me:

    in the this function:

    void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill, BOOL isSendPacket)

    Delete the #else part!

    like this:

    spacer.png

    The #else part is the original one inserted between #else and #endif to make it work as it was before apply the fix in case of for some reason you need to disable the fix.
    Honestly i don't think it make any difference since it was disabled by the fact the macro __ENABLE_SHAMAN_ATTACK_FIX__ was defined.

    In short i don't think the fact you removed the #else is the reason why now it is working for you. You can check it by adding again the removed part and test if the fix is still working.

  18. 18 hours ago, Ulthar said:

    for me its not working. Build was success, and no errors ofc.

    but my shaman attack is the same.

    can you help me @Ikarus_?

    check well the define arrives everywhere.
    try adding this at the beginning of "EterBase/Stdafx.h"

    #include "../UserInterface/Locale_inc.h"

     

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.