// The 5-page bag (PORT; 40250 has 2 pages of 45 cells), run by PythonBoot::RunMainScript as module // mt_inventory. GameType.h's c_Inventory_Page_Count = 5 matches the 203 server patch // (tools/server/inventory-5-pages), which moves every cell after the bag from 90 to 225. The 40250 scripts // stay unchanged; this module patches what they hard-code for 2 pages: // - InventoryWindow.py: EQUIPMENT_START_INDEX = 90 is remapped to player.EQUIPMENT_SLOT_START, and the two // large page tabs become five small ones (the equipment tabs' image) across the 5x32 grid; // - uiInventory.InventoryWindow: five tab events, SetInventoryPage's `inventoryTab[1-page]`, and the // auto-potion highlight in RefreshBagSlotWindow, which only subtracts one page; // - uiselectitem.SelectItemWindow.RefreshSlot: scans INVENTORY_PAGE_SIZE*2 cells. static const char c_szInventoryPagesScript[] = R"PY(# -*- coding: utf-8 -*- import constInfo import player import ui import uiInventory import uiselectitem import item OLD_EQUIPMENT_START = 90 OLD_EQUIPMENT_END = OLD_EQUIPMENT_START + 32 PAGE_COUNT = player.INVENTORY_PAGE_COUNT PAGE_TEXTS = ("I", "II", "III", "IV", "V") SMALL_TAB = "d:/ymir work/ui/game/windows/tab_button_small_%02d.sub" TAB_X = 8 TAB_W = 32 def _Children(node): return node.get("children", ()) def _Find(node, name): if node.get("name") == name: return node for child in _Children(node): found = _Find(child, name) if found: return found return None def _PageTab(page, x, y, tooltip): tab = { "name" : "Inventory_Tab_%02d" % (page + 1), "type" : "radio_button", "x" : x, "y" : y, "default_image" : SMALL_TAB % 1, "over_image" : SMALL_TAB % 2, "down_image" : SMALL_TAB % 3, "children" : ( { "name" : "Inventory_Tab_%02d_Print" % (page + 1), "type" : "text", "x" : 0, "y" : 0, "all_align" : "center", "text" : PAGE_TEXTS[page], }, ), } if tooltip: tab["tooltip_text"] = tooltip return tab def _PatchInventoryWindow(window): delta = player.EQUIPMENT_SLOT_START - OLD_EQUIPMENT_START equip = _Find(window, "EquipmentSlot") if equip and delta: slots = [] for slot in equip["slot"]: if OLD_EQUIPMENT_START <= slot["index"] < OLD_EQUIPMENT_END: slot = dict(slot) slot["index"] += delta slots.append(slot) equip["slot"] = tuple(slots) board = _Find(window, "board") first = _Find(window, "Inventory_Tab_01") if not board or not first: return tooltips = [first.get("tooltip_text")] second = _Find(window, "Inventory_Tab_02") tooltips.append(second.get("tooltip_text") if second else None) children = [] for child in board["children"]: name = child.get("name", "") if name.startswith("Inventory_Tab_"): if name == "Inventory_Tab_01": for page in xrange(PAGE_COUNT): tip = tooltips[page] if page < len(tooltips) else None children.append(_PageTab(page, TAB_X + TAB_W * page, first["y"], tip)) continue children.append(child) board["children"] = tuple(children) def _InstallScriptPatch(): execfile = ui.execfile def ExecFile(fileName, dict): execfile(fileName, dict) if fileName.replace("\\", "/").split("/")[-1].lower() == "inventorywindow.py" and "window" in dict: _PatchInventoryWindow(dict["window"]) ui.execfile = ExecFile def _InstallInventoryWindow(): cls = uiInventory.InventoryWindow load = cls._InventoryWindow__LoadWindow refresh = cls.RefreshBagSlotWindow def LoadWindow(self): loaded = self.isLoaded load(self) if loaded: return try: self.inventoryTab = [self.GetChild("Inventory_Tab_%02d" % (page + 1)) for page in xrange(PAGE_COUNT)] for page in xrange(PAGE_COUNT): self.inventoryTab[page].SetEvent(lambda arg=page: self.SetInventoryPage(arg)) self.inventoryTab[0].Down() except: import dbg dbg.TraceError("mt_inventory: cannot bind the page tabs") def SetInventoryPage(self, page): self.inventoryPageIndex = page for i in xrange(len(self.inventoryTab)): if i != page: self.inventoryTab[i].SetUp() self.RefreshBagSlotWindow() def RefreshBagSlotWindow(self): refresh(self) page = getattr(self, "inventoryPageIndex", 0) if page < 2: return # 40250 turns a cell into a slot by subtracting one page, so pages 3-5 highlight nothing. for i in xrange(player.INVENTORY_PAGE_SIZE): slotNumber = page * player.INVENTORY_PAGE_SIZE + i if not player.GetItemCount(slotNumber): continue if not constInfo.IS_AUTO_POTION(player.GetItemIndex(slotNumber)): continue if player.GetItemMetinSocket(slotNumber, 0): self.wndItem.ActivateSlot(i) else: self.wndItem.DeactivateSlot(i) self.wndItem.RefreshSlot() cls._InventoryWindow__LoadWindow = LoadWindow cls.SetInventoryPage = SetInventoryPage cls.RefreshBagSlotWindow = RefreshBagSlotWindow def _InstallSelectItem(): # SelectItemWindow.RefreshSlot with the cell loop over every page instead of INVENTORY_PAGE_SIZE*2. def RefreshSlot(self): slotPos = 0 self.inventorySlotPosDict = {} getItemVNum=player.GetItemIndex getItemCount=player.GetItemCount setItemVNum=self.itemSlot.SetItemSlot for i in xrange(player.INVENTORY_PAGE_SIZE*PAGE_COUNT): slotNumber = i itemVNum = getItemVNum(slotNumber) if 0 == itemVNum: continue if not item.IsMetin(itemVNum): continue itemGrade = player.GetItemGrade(slotNumber) if itemGrade > 2: continue self.inventorySlotPosDict[slotPos] = i slotPos += 1 if slotPos > 54: break itemCount = len(self.inventorySlotPosDict) if itemCount < 15: self.SetTableSize(3) else: lineCount = 3 lineCount += (itemCount - 15) / 5 if itemCount % 5: lineCount += 1 self.SetTableSize(lineCount) for selectWndPos, inventoryPos in self.inventorySlotPosDict.items(): itemVNum = getItemVNum(inventoryPos) itemCount = getItemCount(inventoryPos) if itemCount <= 1: itemCount = 0 setItemVNum(selectWndPos, itemVNum, itemCount) self.itemSlot.RefreshSlot() uiselectitem.SelectItemWindow.RefreshSlot = RefreshSlot def __Install(): if PAGE_COUNT <= 2: return for install in (_InstallScriptPatch, _InstallInventoryWindow, _InstallSelectItem): try: install() except: import dbg dbg.TraceError("mt_inventory: %s failed" % install.__name__) __Install() )PY";