-
Posts
402 -
Joined
-
Last visited
-
Days Won
20 -
Feedback
0%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by Ikarus_
-
-
30 minutes ago, Helia01 said:
Will this help fix the black screen in the Devil Tower?
It might be part of the solution, but it's definitely not enough to completely remove the blackscreen.
- 1
-
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:
SpoilerFirst 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:
- 242
- 3
- 4
- 1
- 1
- 2
- 3
- 62
- 9
- 71
-
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))- 1
-
Once you made gr2 to 3dsmax, it would be amazing to make the viceversa. It would be really amazing.
- 1
-
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, [])
-
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
-
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.
-
m2dev is working strangely.
-
This would solve your problem finally:
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
-
4 minutes ago, Marcos17 said:
Using the code you said to put this appears in syseer:
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
-
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)
-
34 minutes ago, Marcos17 said:
#<----------------------------------------------------------- ># # _ +----------------------------------------------+ _ # # /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
-
16 minutes ago, Marcos17 said:
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?
-
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
-
Can u paste your uiminimap.py in a pastebin?
I would like to read it- 1
-
18 minutes ago, Marcos17 said:
I looked at the class you referred to and everything seems to be correct, but the error persists =/
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- 1
-
On 1/17/2018 at 11:14 PM, .Stefan said:
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.- 1
- 1
-
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- 2
- 1
- 1
-
If you really want helps you have to show some code.
for example by picking in game/src you have to show us char.cpp char.h packet.h
and by picking from Client/UserInterface you have to show us PythonTextTail.cpp PythonTextTail.h InstanceBase.h InstanceBase.cpp Packet.hwithout reading code we don't get any way to help you
- 1
-
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. -
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
-
Added an important disclaimer at the beginning!
-
On 4/16/2021 at 8:19 PM, Ulthar said:
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 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"
Setting Drop via Mysql Tables
in Features & Metin2 Systems
Posted · Edited by Metin2 Dev
Core X - External 2 Internal
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