| | |
| | | WORD OldPrice; //礼包原价
|
| | | };
|
| | |
|
| | | //拍卖物品表
|
| | |
|
| | | struct tagAuctionItem
|
| | | {
|
| | | DWORD _AuctionItemID;
|
| | | };
|
| | |
|
| | | //VIP特权表
|
| | |
|
| | | struct tagVipPrivilege
|
| | |
| | | BYTE CanBreakCollect; //被攻击是否打断采集
|
| | | };
|
| | |
|
| | | //宝箱怪表
|
| | |
|
| | | struct tagTreasureNPC
|
| | | {
|
| | | DWORD _NPCID; //宝箱怪NPCID
|
| | | dict AttackCountDropWeightInfo; //攻击次数对应掉落权重饼图 {次数:[[权重, [物品ID,个数,是否拍品]], ...], ...}
|
| | | list AttackDropWeightList; //常规攻击权重饼图 [[权重, [物品ID,个数,是否拍品]], ...]
|
| | | list AttackDropWeightListEx; //额外掉落权重饼图库,每次攻击都会掉落 [[权重, [物品ID,个数,是否拍品]], ...]
|
| | | BYTE DropCountEx; //额外库执行次数
|
| | | BYTE AlchemyDiffLV; //过滤炼丹等级差,0-不过滤,>0过滤大于自身炼丹等级X级的物品
|
| | | char NotDropNotify; //没有掉落时提示信息
|
| | | };
|
| | |
|
| | | //宝箱表开启
|
| | |
|
| | | struct Chests
|
| | |
| | | DWORD _ChestsItemID; //宝箱物品ID
|
| | | DWORD CostItemID; //消耗物品ID
|
| | | BYTE CostItemCount; //消耗物品个数
|
| | | WORD CostGold; //消耗仙玉
|
| | | BYTE ShowType; //前端表现类型0-无表现, >0有表现需同步结果,具体类型前端自定义
|
| | | BYTE IsBind; //开出物品是否绑定
|
| | | BYTE AucionItemCanSell; //开出拍品可否上架集市
|
| | | list AucionItemDiffSellIDList; //可否上架差异拍品ID列表,即可上架代表不可上架的拍品ID列表,不可上架代表可上架的拍品ID列表
|
| | | BYTE CostMoneyType; //开启消耗货币类型
|
| | | WORD CostMoneyValue; //消耗货币
|
| | | };
|
| | |
|
| | | //宝箱表产出表
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A8 10 通知获得物品 #tagMCNotifyUseItemGetItem
|
| | |
|
| | | class tagMCNotifyUseItemGetItem(Structure):
|
| | | Head = tagHead()
|
| | | UseItemID = 0 #(DWORD UseItemID)// 使用的物品ID
|
| | | UseCount = 0 #(WORD UseCount)// 使用物品个数
|
| | | GetItemLen = 0 #(WORD GetItemLen)
|
| | | GetItemData = "" #(String GetItemData)// 获得物品信息 [[itemID,itemCount,isBind], [或itemID,itemCount,isBind,isAppoint], {或物品信息字典}, ...] |
| | | MoneyType = 0 #(BYTE MoneyType)// 获得货币类型
|
| | | MoneyCount = 0 #(DWORD MoneyCount)// 获得货币数量
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA8
|
| | | self.Head.SubCmd = 0x10
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.UseItemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.UseCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.GetItemLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.GetItemData,_pos = CommFunc.ReadString(_lpData, _pos,self.GetItemLen)
|
| | | self.MoneyType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.MoneyCount,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA8
|
| | | self.Head.SubCmd = 0x10
|
| | | self.UseItemID = 0
|
| | | self.UseCount = 0
|
| | | self.GetItemLen = 0
|
| | | self.GetItemData = ""
|
| | | self.MoneyType = 0
|
| | | self.MoneyCount = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 4
|
| | | length += 2
|
| | | length += 2
|
| | | length += len(self.GetItemData)
|
| | | length += 1
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteDWORD(data, self.UseItemID)
|
| | | data = CommFunc.WriteWORD(data, self.UseCount)
|
| | | data = CommFunc.WriteWORD(data, self.GetItemLen)
|
| | | data = CommFunc.WriteString(data, self.GetItemLen, self.GetItemData)
|
| | | data = CommFunc.WriteBYTE(data, self.MoneyType)
|
| | | data = CommFunc.WriteDWORD(data, self.MoneyCount)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | UseItemID:%d,
|
| | | UseCount:%d,
|
| | | GetItemLen:%d,
|
| | | GetItemData:%s,
|
| | | MoneyType:%d,
|
| | | MoneyCount:%d
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.UseItemID,
|
| | | self.UseCount,
|
| | | self.GetItemLen,
|
| | | self.GetItemData,
|
| | | self.MoneyType,
|
| | | self.MoneyCount
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCNotifyUseItemGetItem=tagMCNotifyUseItemGetItem()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCNotifyUseItemGetItem.Head.Cmd,m_NAtagMCNotifyUseItemGetItem.Head.SubCmd))] = m_NAtagMCNotifyUseItemGetItem
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A8 17 宠物培养信息 #tagMCPetTrainInfo
|
| | |
|
| | | class tagMCPetTrainInfo(Structure):
|
| | |
| | | curSingleItem.Clear()
|
| | | return
|
| | |
|
| | | ItemControler.NotifyGiveAwardInfo(curPlayer, {newItemID:itemCount}, "Compound")
|
| | | return userData
|
| | |
|
| | | #// A3 13 物品拆解 #tagCMItemDecompound
|
| | |
| | | ("WORD", "OldPrice", 0),
|
| | | ),
|
| | |
|
| | | "AuctionItem":(
|
| | | ("DWORD", "AuctionItemID", 1),
|
| | | ),
|
| | |
|
| | | "VipPrivilege":(
|
| | | ("DWORD", "VIPPriID", 1),
|
| | | ("DWORD", "VIP0", 0),
|
| | |
| | | ("BYTE", "CanBreakCollect", 0),
|
| | | ),
|
| | |
|
| | | "TreasureNPC":(
|
| | | ("DWORD", "NPCID", 1),
|
| | | ("dict", "AttackCountDropWeightInfo", 0),
|
| | | ("list", "AttackDropWeightList", 0),
|
| | | ("list", "AttackDropWeightListEx", 0),
|
| | | ("BYTE", "DropCountEx", 0),
|
| | | ("BYTE", "AlchemyDiffLV", 0),
|
| | | ("char", "NotDropNotify", 0),
|
| | | ),
|
| | |
|
| | | "Chests":(
|
| | | ("DWORD", "ChestsItemID", 1),
|
| | | ("DWORD", "CostItemID", 0),
|
| | | ("BYTE", "CostItemCount", 0),
|
| | | ("WORD", "CostGold", 0),
|
| | | ("BYTE", "ShowType", 0),
|
| | | ("BYTE", "IsBind", 0),
|
| | | ("BYTE", "AucionItemCanSell", 0),
|
| | | ("list", "AucionItemDiffSellIDList", 0),
|
| | | ("BYTE", "CostMoneyType", 0),
|
| | | ("WORD", "CostMoneyValue", 0),
|
| | | ),
|
| | |
|
| | | "ChestsAward":(
|
| | |
| | | def GetPrice(self): return self.attrTuple[2] # 礼包现价 WORD
|
| | | def GetOldPrice(self): return self.attrTuple[3] # 礼包原价 WORD |
| | | |
| | | # 拍卖物品表 |
| | | class IPY_AuctionItem(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetAuctionItemID(self): return self.attrTuple[0] # DWORD |
| | | |
| | | # VIP特权表 |
| | | class IPY_VipPrivilege(): |
| | | |
| | |
| | | def GetNotifyCollectResult(self): return self.attrTuple[10] # 是否通知采集结果 BYTE
|
| | | def GetCanBreakCollect(self): return self.attrTuple[11] # 被攻击是否打断采集 BYTE |
| | | |
| | | # 宝箱怪表 |
| | | class IPY_TreasureNPC(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetNPCID(self): return self.attrTuple[0] # 宝箱怪NPCID DWORD
|
| | | def GetAttackCountDropWeightInfo(self): return self.attrTuple[1] # 攻击次数对应掉落权重饼图 {次数:[[权重, [物品ID,个数,是否拍品]], ...], ...} dict
|
| | | def GetAttackDropWeightList(self): return self.attrTuple[2] # 常规攻击权重饼图 [[权重, [物品ID,个数,是否拍品]], ...] list
|
| | | def GetAttackDropWeightListEx(self): return self.attrTuple[3] # 额外掉落权重饼图库,每次攻击都会掉落 [[权重, [物品ID,个数,是否拍品]], ...] list
|
| | | def GetDropCountEx(self): return self.attrTuple[4] # 额外库执行次数 BYTE
|
| | | def GetAlchemyDiffLV(self): return self.attrTuple[5] # 过滤炼丹等级差,0-不过滤,>0过滤大于自身炼丹等级X级的物品 BYTE
|
| | | def GetNotDropNotify(self): return self.attrTuple[6] # 没有掉落时提示信息 char |
| | | |
| | | # 宝箱表开启 |
| | | class IPY_Chests(): |
| | | |
| | |
| | | def GetChestsItemID(self): return self.attrTuple[0] # 宝箱物品ID DWORD
|
| | | def GetCostItemID(self): return self.attrTuple[1] # 消耗物品ID DWORD
|
| | | def GetCostItemCount(self): return self.attrTuple[2] # 消耗物品个数 BYTE
|
| | | def GetCostGold(self): return self.attrTuple[3] # 消耗仙玉 WORD
|
| | | def GetShowType(self): return self.attrTuple[4] # 前端表现类型0-无表现, >0有表现需同步结果,具体类型前端自定义 BYTE
|
| | | def GetIsBind(self): return self.attrTuple[5] # 开出物品是否绑定 BYTE
|
| | | def GetAucionItemCanSell(self): return self.attrTuple[6] # 开出拍品可否上架集市 BYTE
|
| | | def GetAucionItemDiffSellIDList(self): return self.attrTuple[7] # 可否上架差异拍品ID列表,即可上架代表不可上架的拍品ID列表,不可上架代表可上架的拍品ID列表 list |
| | | def GetCostMoneyType(self): return self.attrTuple[3] # 开启消耗货币类型 BYTE
|
| | | def GetCostMoneyValue(self): return self.attrTuple[4] # 消耗货币 WORD |
| | | |
| | | # 宝箱表产出表 |
| | | class IPY_ChestsAward(): |
| | |
| | | self.__LoadFileData("TreasureUp", onlyCheck)
|
| | | self.__LoadFileData("SignIn", onlyCheck)
|
| | | self.__LoadFileData("VIPAward", onlyCheck)
|
| | | self.__LoadFileData("AuctionItem", onlyCheck)
|
| | | self.__LoadFileData("VipPrivilege", onlyCheck)
|
| | | self.__LoadFileData("Store", onlyCheck)
|
| | | self.__LoadFileData("ActSpringSale", onlyCheck)
|
| | |
| | | self.__LoadFileData("RuneCompound", onlyCheck)
|
| | | self.__LoadFileData("ResourcesBack", onlyCheck)
|
| | | self.__LoadFileData("CollectNPC", onlyCheck)
|
| | | self.__LoadFileData("TreasureNPC", onlyCheck)
|
| | | self.__LoadFileData("Chests", onlyCheck)
|
| | | self.__LoadFileData("ChestsAward", onlyCheck)
|
| | | self.__LoadFileData("VIPKillNPC", onlyCheck)
|
| | |
| | | self.CheckLoadData("VIPAward") |
| | | return self.ipyVIPAwardCache[index]
|
| | | |
| | | def GetAuctionItemCount(self): |
| | | self.CheckLoadData("AuctionItem") |
| | | return self.ipyAuctionItemLen
|
| | | def GetAuctionItemByIndex(self, index): |
| | | self.CheckLoadData("AuctionItem") |
| | | return self.ipyAuctionItemCache[index]
|
| | | |
| | | def GetVipPrivilegeCount(self): |
| | | self.CheckLoadData("VipPrivilege") |
| | | return self.ipyVipPrivilegeLen
|
| | |
| | | def GetCollectNPCByIndex(self, index): |
| | | self.CheckLoadData("CollectNPC") |
| | | return self.ipyCollectNPCCache[index]
|
| | | |
| | | def GetTreasureNPCCount(self): |
| | | self.CheckLoadData("TreasureNPC") |
| | | return self.ipyTreasureNPCLen
|
| | | def GetTreasureNPCByIndex(self, index): |
| | | self.CheckLoadData("TreasureNPC") |
| | | return self.ipyTreasureNPCCache[index]
|
| | | |
| | | def GetChestsCount(self): |
| | | self.CheckLoadData("Chests") |
| | |
| | |
|
| | | return
|
| | |
|
| | | def SendUseItemGetItemResult(curPlayer, useItemID, useCount, getItemInfo, moneyType=0, moneyCount=0):
|
| | | # 通知客户端使用物品结果包
|
| | | # @param getItemInfo: [{"ItemID":物品ID, "Count":个数, "IsBind":是否绑定, "IsSuite":是否套装化, "UserData":"自定义属性字符串"}, ...]
|
| | | |
| | | getItemInfo = json.dumps(getItemInfo, ensure_ascii=False)
|
| | | getItemInfo = getItemInfo.replace(" ", "")
|
| | | getItemPack = ChPyNetSendPack.tagMCNotifyUseItemGetItem()
|
| | | getItemPack.Clear()
|
| | | getItemPack.UseItemID = useItemID
|
| | | getItemPack.UseCount = useCount
|
| | | getItemPack.GetItemData = str(getItemInfo)
|
| | | getItemPack.GetItemLen = len(getItemPack.GetItemData)
|
| | | getItemPack.MoneyType = moneyType
|
| | | getItemPack.MoneyCount = moneyCount
|
| | | NetPackCommon.SendFakePack(curPlayer, getItemPack)
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | ## 准备结束
|
| | |
| | | return False
|
| | |
|
| | | if isAuctionItem:
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
|
| | | ipyData = None #IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
|
| | | if not ipyData:
|
| | | GameWorld.ErrLog("非拍卖物品,默认转为非拍品! itemID=%s,itemCount=%s,isAuctionItem=%s"
|
| | | % (itemID, itemCount, isAuctionItem), curPlayer.GetPlayerID())
|
| | |
| | | return
|
| | | curSingleItem.SetRemainHour(outTimeServerDay)
|
| | |
|
| | | if isAuctionItem:
|
| | | if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID):
|
| | | ItemControler.SetIsAuctionItem(curSingleItem, isAuctionItem)
|
| | | else:
|
| | | GameWorld.DebugLog("拍卖物品表不存在该ID!创建拍品失败,默认转为非拍品!itemID=%s" % itemID)
|
| | | #if isAuctionItem:
|
| | | # if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID):
|
| | | # ItemControler.SetIsAuctionItem(curSingleItem, isAuctionItem)
|
| | | # else:
|
| | | # GameWorld.DebugLog("拍卖物品表不存在该ID!创建拍品失败,默认转为非拍品!itemID=%s" % itemID)
|
| | |
|
| | | ItemControler.SetItemCount(curSingleItem, itemCount)
|
| | |
|
| | |
| | | if not chestsIpyData:
|
| | | return
|
| | |
|
| | | showType = chestsIpyData.GetShowType() # 规定有开箱表现的默认只能开启1个
|
| | | #if showType:
|
| | | # useCnt = 1
|
| | | useCnt = min(curRoleItem.GetCount(), useCnt)
|
| | |
|
| | | isBind = int(chestsIpyData.GetIsBind()) # 奖励物品是否绑定
|
| | | isBind = 0 # 奖励物品是否绑定
|
| | | costItemID = chestsIpyData.GetCostItemID()
|
| | | costItemCountTotal = chestsIpyData.GetCostItemCount() * useCnt
|
| | | costGoldTotal = chestsIpyData.GetCostGold() * useCnt
|
| | | auctionItemCanSell = chestsIpyData.GetAucionItemCanSell()
|
| | | aucionItemDiffSellIDList = chestsIpyData.GetAucionItemDiffSellIDList()
|
| | | costMoneyType = chestsIpyData.GetCostMoneyType()
|
| | | costGoldTotal = chestsIpyData.GetCostMoneyValue() * useCnt
|
| | |
|
| | | if costGoldTotal and not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal):
|
| | | if costGoldTotal and costMoneyType and not PlayerControl.HaveMoney(curPlayer, costMoneyType, costGoldTotal):
|
| | | return
|
| | |
|
| | | if costItemID:
|
| | |
| | | if not awardInfo:
|
| | | return
|
| | | needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount = awardInfo
|
| | | GameWorld.DebugLog(" needSpaceDict=%s,jobAwardItemList=%s,moneyType=%s,moneyCount=%s,notifyItemList=%s,updOpenCount=%s,auctionItemCanSell=%s,aucionItemDiffSellIDList=%s" |
| | | % (needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount, auctionItemCanSell, aucionItemDiffSellIDList))
|
| | | GameWorld.DebugLog(" needSpaceDict=%s,jobAwardItemList=%s,moneyType=%s,moneyCount=%s,notifyItemList=%s,updOpenCount=%s" |
| | | % (needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount))
|
| | |
|
| | | for packType, needSpace in needSpaceDict.items():
|
| | | packSpace = ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace)
|
| | |
| | | # 扣除消耗
|
| | | if costItemID:
|
| | | ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCountTotal, "Chests")
|
| | | if costGoldTotal:
|
| | | if costMoneyType and costGoldTotal:
|
| | | infoDict = {ChConfig.Def_Cost_Reason_SonKey:chestsItemID}
|
| | | PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal, ChConfig.Def_Cost_UseItem, infoDict)
|
| | | PlayerControl.PayMoney(curPlayer, costMoneyType, costGoldTotal, ChConfig.Def_Cost_UseItem, infoDict)
|
| | |
|
| | | # 更新开启次数
|
| | | if updOpenCount:
|
| | |
| | | # 给奖励
|
| | | syncItemList = []
|
| | | for itemID, itemCount in jobAwardItemList:
|
| | | canSell = (not auctionItemCanSell) if itemID in aucionItemDiffSellIDList else auctionItemCanSell
|
| | | isAuctionItem = 1 if canSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID) else 0
|
| | | |
| | | userDataList = []
|
| | | giveOKCount = ItemControler.DoGiveItemLoop(curPlayer, itemID, itemCount, isAuctionItem, |
| | | giveOKCount = ItemControler.DoGiveItemLoop(curPlayer, itemID, itemCount, isBind, |
| | | event=[ChConfig.ItemGive_Chests, False, {"UseItemID":chestsItemID}],
|
| | | jsonItemList=syncItemList, userDataList=userDataList)
|
| | | if giveOKCount < itemCount:
|
| | |
| | | if not PlayerControl.GiveMoney(curPlayer, moneyType, moneyCount, ChConfig.Def_GiveMoney_UseItem, addDataDict, False):
|
| | | moneyType, moneyCount = 0, 0
|
| | |
|
| | | # ֪ͨ
|
| | | if showType and syncItemList:
|
| | | ChItem.SendUseItemGetItemResult(curPlayer, chestsItemID, useCnt, syncItemList, moneyType, moneyCount)
|
| | | ItemControler.NotifyGiveAwardInfo(curPlayer, jobAwardItemList, "Chests", moneyInfo={moneyType, moneyCount})
|
| | | return True, useCnt
|
| | |
|
| | |
|