I understand now. The server side (game source) sends the shop items in a specific format, but the shop edit mode is using a different one, so it doesn’t read the list correctly.
I added another item just to see what happens, and yes — when I enter edit mode, the item appears and then instantly disappears because the data is not properly synchronized.
Ok, I understand this part now, but how should I rewrite it so that edit mode can correctly read the existing shop items from the server using the same format? I’m still a beginner and this already goes a bit beyond my current level.
Also, how should edit mode correctly add new items to an already existing shop (without overwriting the current ones), making sure the price, count, sockets, attributes, and all related data are saved and synchronized properly with the server?
Cod: Selectaţi tot
class ShopEditWindow(ui.ScriptWindow):
def __init__(self):
ui.ScriptWindow.__init__(self)
self.items={}
self.Edit={}
self.pop=None
self.id=0
self.lastUpdate=0
self.priceInputBoard=None
self.__Load()
self.tooltipItem = uiToolTip.ItemToolTip()
self.tooltipItem.Hide()
def __del__(self):
ui.ScriptWindow.__del__(self)
self.Close()
def __Load_LoadScript(self, fileName):
try:
pyScriptLoader = ui.PythonScriptLoader()
pyScriptLoader.LoadScriptFile(self, fileName)
except:
import exception
exception.Abort("ShopEditWindow.__Load_LoadScript")
def __Load_BindObject(self):
try:
self.titleBar = self.GetChild("TitleBar")
self.titleName = self.GetChild("TitleName")
self.ItemSlot = self.GetChild("ItemSlot")
try:
for key in ["BuyButton","SellButton","MiddleTab1","MiddleTab2","MiddleTab2","SmallTab1","SmallTab2","SmallTab3"]:
self.GetChild(key).Hide()
except Exception:
pass
self.CloseButton = self.GetChild("CloseButton")
except:
import exception
exception.Abort("StoneDialog.__Load_BindObject")
self.CloseButton.SetText(uiScriptLocale.SHOP_EDIT_SHOP_CANCEL)
self.CloseButton.SetEvent(ui.__mem_func__(self.Close))
self.titleName.SetText(uiScriptLocale.SHOP_EDIT_SHOP_WINDOW)
self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close))
self.ItemSlot.SAFE_SetButtonEvent("LEFT", "EMPTY", self.OnSelectEmptySlot)
self.ItemSlot.SAFE_SetButtonEvent("LEFT", "EXIST", self.OnSelectItemSlot)
self.ItemSlot.SAFE_SetButtonEvent("RIGHT", "EXIST", self.UnselectItemSlot)
self.ItemSlot.SetOverInItemEvent(ui.__mem_func__(self.OverInItem))
self.ItemSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem))
self.Edit["Board"] = ui.BoardWithTitleBar()
self.Edit["Board"].SetSize(150, 100)
self.Edit["Board"].AddFlag("movable")
self.Edit["Board"].SetPosition(0,0)
self.Edit["Board"].SetTitleName(uiScriptLocale.SHOP_SELECT)
self.Edit["Board"].SetCloseEvent(self.CloseEdit)
self.Edit["Board"].Show()
self.Edit["ChangePrice"] = ui.Button()
self.Edit["ChangePrice"].SetParent(self.Edit["Board"])
self.Edit["ChangePrice"].SetPosition(30,35)
self.Edit["ChangePrice"].SetUpVisual('d:/ymir work/ui/public/Large_button_01.sub')
self.Edit["ChangePrice"].SetOverVisual('d:/ymir work/ui/public/Large_button_02.sub')
self.Edit["ChangePrice"].SetDownVisual('d:/ymir work/ui/public/Large_button_03.sub')
self.Edit["ChangePrice"].SetText(uiScriptLocale.SHOP_CHANGE_PRICE)
self.Edit["ChangePrice"].Show()
self.Edit["Remove"] = ui.Button()
self.Edit["Remove"].SetParent(self.Edit["Board"])
self.Edit["Remove"].SetPosition(30,65)
self.Edit["Remove"].SetUpVisual('d:/ymir work/ui/public/Large_button_01.sub')
self.Edit["Remove"].SetOverVisual('d:/ymir work/ui/public/Large_button_02.sub')
self.Edit["Remove"].SetDownVisual('d:/ymir work/ui/public/Large_button_03.sub')
self.Edit["Remove"].SetText(uiScriptLocale.SHOP_REMOVE_ITEM)
self.Edit["Remove"].Show()
def __Load(self):
self.__Load_LoadScript("UIScript/ShopDialog.py")
self.__Load_BindObject()
def CloseEdit(self):
self.Edit["Board"].Hide()
def Show(self,id):
if self.IsShow():
self.Close()
else:
ui.ScriptWindow.Show(self)
net.SendChatPacket("/update_shop_item edit_start|"+id)
net.SendChatPacket("/refresh_shop_items "+id)
self.id=id
self.Refresh()
def OnPressEscapeKey(self):
self.Close()
return TRUE
def __OnClosePopupDialog(self):
if self.pop != None:
if self.pop.IsShow():
self.pop.Hide()
self.pop = None
def __GetRealIndex(self, i):
return shop.SHOP_SLOT_COUNT + i
def Close(self):
if None != self.tooltipItem:
self.tooltipItem.HideToolTip()
self.CancelInputPrice()
self.__OnClosePopupDialog()
self.Edit["Board"].Hide()
self.Hide()
return TRUE
def Clear(self):
self.items={}
self.CancelInputPrice()
self.__OnClosePopupDialog()
self.Edit["Board"].Hide()
self.Refresh()
def GetItemCount(self,slot):
try:
return int(self.items[int(slot)]["count"])
except KeyError:
return 0
def GetItemID(self,slot):
try:
return int(self.items[int(slot)]["vnum"])
except KeyError:
return 0
def AddItem(self,slot,data):
self.items[int(slot)]=data
self.Refresh()
def Refresh(self):
self.CancelInputPrice()
self.__OnClosePopupDialog()
self.Edit["Board"].Hide()
setItemID=self.ItemSlot.SetItemSlot
for i in xrange(shop.SHOP_SLOT_COUNT):
vnum=self.GetItemID(i)
itemCount = self.GetItemCount(i)
setItemID(i, vnum, itemCount)
wndMgr.RefreshSlot(self.ItemSlot.GetWindowHandle())
self.ItemSlot.RefreshSlot()
def __ShowToolTip(self, slot):
if self.tooltipItem:
self.tooltipItem.ClearToolTip()
if int(slot) in self.items.keys():
it=self.items[int(slot)]
if it.get("sourceSlot",-1)!=-1:
self.tooltipItem.SetEditPrivateShopItem(int(it["sourceWindow"]),int(it["sourceSlot"]),it["price"])
else:
self.tooltipItem.AppendSellingPrice(it["price"])
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
self.tooltipItem.AppendSellingCheque2(it["cheque"])
self.tooltipItem.AddItemData(int(it["vnum"]),it["sockets"],it["attrs"])
else:
self.tooltipItem.HideToolTip()
def OverInItem(self, slotIndex):
#slotIndex = self.__GetRealIndex(slotIndex)
self.ItemSlot.SetUsableItem(FALSE)
self.__ShowToolTip(slotIndex)
def OverOutItem(self):
self.ItemSlot.SetUsableItem(FALSE)
if self.tooltipItem:
self.tooltipItem.HideToolTip()
def OnSelectEmptySlot(self, selectedSlotPos):
isAttached = mouseModule.mouseController.isAttached()
if isAttached:
attachedSlotType = mouseModule.mouseController.GetAttachedType()
attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber()
mouseModule.mouseController.DeattachObject()
if player.SLOT_TYPE_INVENTORY != attachedSlotType and player.SLOT_TYPE_DRAGON_SOUL_INVENTORY != attachedSlotType:
return
attachedInvenType = player.SlotTypeToInvenType(attachedSlotType)
count = player.GetItemCount(attachedInvenType, attachedSlotPos)
itemVNum = player.GetItemIndex(attachedInvenType, attachedSlotPos)
item.SelectItem(itemVNum)
if item.IsAntiFlag(item.ANTIFLAG_GIVE) or item.IsAntiFlag(item.ANTIFLAG_MYSHOP):
chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.PRIVATE_SHOP_CANNOT_SELL_ITEM)
return
priceInputBoard = uiCommon.MoneyInputDialog()
priceInputBoard.SetTitle(localeInfo.PRIVATE_SHOP_INPUT_PRICE_DIALOG_TITLE)
priceInputBoard.SetAcceptEvent(ui.__mem_func__(self.AcceptInputPrice))
priceInputBoard.SetCancelEvent(ui.__mem_func__(self.CancelInputPrice))
priceInputBoard.SetMaxLength(16)
priceInputBoard.Open()
#self.ItemSlot.ActivateSlot(int(selectedSlotPos))
self.priceInputBoard = priceInputBoard
self.priceInputBoard.itemVNum = itemVNum
self.priceInputBoard.sourceWindowType = attachedInvenType
self.priceInputBoard.sourceSlotPos = attachedSlotPos
self.priceInputBoard.targetSlotPos = selectedSlotPos
def UnselectItemSlot(self,selectedSlotPos):
self.Edit["Board"].Hide()
#self.ItemSlot.DeactivateSlot(int(selectedSlotPos))
self.CancelInputPrice()
self.__OnClosePopupDialog()
def OnSelectItemSlot(self, selectedSlotPos):
isAttached = mouseModule.mouseController.isAttached()
#selectedSlotPos = self.__GetRealIndex(selectedSlotPos)
if isAttached:
snd.PlaySound("sound/ui/loginfail.wav")
#self.ItemSlot.DeactivateSlot(int(selectedSlotPos))
mouseModule.mouseController.DeattachObject()
self.Edit["Board"].Hide()
else:
if not int(selectedSlotPos) in self.items.keys():
self.Edit["Board"].Hide()
return
snd.PlaySound("sound/ui/drop.wav")
#self.ItemSlot.ActivateSlot(selectedSlotPos)
self.EditItem(selectedSlotPos)
def AcceptInputPrice(self):
if not self.priceInputBoard:
return True
text = self.priceInputBoard.GetText()
if not text:
return True
if not text.isdigit():
return True
if int(text) <= 0:
return True
attachedInvenType = self.priceInputBoard.sourceWindowType
sourceSlotPos = self.priceInputBoard.sourceSlotPos
targetSlotPos = self.priceInputBoard.targetSlotPos
price = int(self.priceInputBoard.GetText())
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
cheque = int(self.priceInputBoard.GetTextCheque())
count = player.GetItemCount(attachedInvenType, sourceSlotPos)
vnum = player.GetItemIndex(attachedInvenType, sourceSlotPos)
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
self.items[int(targetSlotPos)]={
"vnum":int(vnum),
"count":int(count),
"price":int(price),
"cheque":int(cheque),
"sourceSlot":sourceSlotPos,
"sourceWindow":attachedInvenType
}
else:
self.items[int(targetSlotPos)]={
"vnum":int(vnum),
"count":int(count),
"price":int(price),
"sourceSlot":sourceSlotPos,
"sourceWindow":attachedInvenType
}
snd.PlaySound("sound/ui/pick.wav")
#self.ItemSlot.DeactivateSlot(targetSlotPos)
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
net.SendChatPacket("/update_shop_item add|%d|%d|%d|%d|%s|%s"%(int(self.id),int(targetSlotPos),int(sourceSlotPos),int(attachedInvenType),str(price), str(cheque)))
else:
net.SendChatPacket("/update_shop_item add|%d|%d|%d|%d|%s"%(int(self.id),int(targetSlotPos),int(sourceSlotPos),int(attachedInvenType),str(price)))
self.Refresh()
#####
self.priceInputBoard = None
return True
def CancelInputPrice(self):
self.priceInputBoard = None
return True
def EditItem(self,slot):
self.Edit["ChangePrice"].SetEvent(ui.__mem_func__(self.EditPrice),int(slot))
self.Edit["Remove"].SetEvent(ui.__mem_func__(self.RemoveItem),int(slot))
(w,h)=(170,328)
(x,y)=self.GetLocalPosition()
self.Edit["Board"].SetPosition((x-w),(y+(h/2)))
self.Edit["Board"].Show()
def EditPrice(self,slot):
self.priceInputBoard = uiCommon.MoneyInputDialog()
self.priceInputBoard.SetTitle(localeInfo.PRIVATE_SHOP_INPUT_PRICE_DIALOG_TITLE)
self.priceInputBoard.SetAcceptEvent(ui.__mem_func__(self.AcceptEditPrice))
self.priceInputBoard.SetCancelEvent(ui.__mem_func__(self.CancelInputPrice))
self.priceInputBoard.SetMaxLength(16)
self.priceInputBoard.Open()
self.priceInputBoard.targetSlotPos = int(slot)
def RemoveItem(self,slot):
self.pop = uiCommon.QuestionDialog()
self.pop.SetText(uiScriptLocale.SHOP_REMOVE_ITEM_QUEST)
self.pop.SetAcceptEvent(lambda arg1=str(slot): self.AcceptRemoveItem(arg1))
self.pop.SetCancelEvent(ui.__mem_func__(self.__OnClosePopupDialog))
self.pop.Open()
def AcceptRemoveItem(self,slot):
if int(slot) in self.items.keys():
snd.PlaySound("sound/ui/drop.wav")
net.SendChatPacket("/update_shop_item remove|"+str(self.id)+"|"+str(self.items[int(slot)]["id"]))
#self.ItemSlot.DeactivateSlot(int(slot))
del self.items[int(slot)]
self.Refresh()
self.__OnClosePopupDialog()
def AcceptEditPrice(self):
if not self.priceInputBoard:
return True
text = self.priceInputBoard.GetText()
if not text:
return True
if not text.isdigit():
return True
if int(text) <= 0:
return True
targetSlotPos = self.priceInputBoard.targetSlotPos
price = int(self.priceInputBoard.GetText())
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
cheque = int(self.priceInputBoard.GetTextCheque())
#self.ItemSlot.DeactivateSlot(int(targetSlotPos))
self.items[int(targetSlotPos)]["price"]=price
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
self.items[int(targetSlotPos)]["cheque"]=cheque
snd.PlaySound("sound/ui/drop.wav")
if app.ENABLE_OFFLINE_SHOP_USE_CHEQUE:
net.SendChatPacket("/update_shop_item price|"+str(self.id)+"|"+str(self.items[int(targetSlotPos)]["id"])+"|"+str(price)+"|"+str(cheque))
else:
net.SendChatPacket("/update_shop_item price|"+str(self.id)+"|"+str(self.items[int(targetSlotPos)]["id"])+"|"+str(price))
self.Refresh()
self.priceInputBoard = None
return True
def OnUpdate(self):
if self.IsShow() and self.lastUpdate < app.GetGlobalTime():
self.lastUpdate=app.GetGlobalTime()+1000
if int(self.id)>0:
net.SendChatPacket("/update_shop_item edit_tick|"+self.id)