#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package UseItem.Item_Chests # # @todo:±¦Ïä # @author hxp # @date 2018-02-05 # @version 1.0 # # ÏêϸÃèÊö: Ipy±¦Ïä±íÎïÆ· # #------------------------------------------------------------------------------- #"""Version = 2018-02-05 15:00""" #------------------------------------------------------------------------------- #µ¼Èë import GameWorld import ItemCommon import PlayerControl import IpyGameDataPY import IPY_GameWorld import ItemControler import PlayerRune import ChConfig import ChItem import math #--------------------------------------------------------------------- def BatchUseItem(curPlayer, curRoleItem, tick, useCnt, exData): ##ÅúÁ¿Ê¹ÓÃÎïÆ· chestsItemID = curRoleItem.GetItemTypeID() chestsIpyData = IpyGameDataPY.GetIpyGameDataNotLog("Chests", chestsItemID) if not chestsIpyData: return showType = chestsIpyData.GetShowType() # ¹æ¶¨ÓпªÏä±íÏÖµÄĬÈÏÖ»ÄÜ¿ªÆô1¸ö if showType: useCnt = 1 isBind = int(chestsIpyData.GetIsBind()) # ½±ÀøÎïÆ·ÊÇ·ñ°ó¶¨ costItemID = chestsIpyData.GetCostItemID() costItemCountTotal = chestsIpyData.GetCostItemCount() * useCnt costGoldTotal = chestsIpyData.GetCostGold() * useCnt if costGoldTotal and not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal): return if costItemID: costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID) if bindCnt + unBindCnt < costItemCountTotal: GameWorld.DebugLog("ËùÐèÏûºÄµÀ¾ß²»×㣬ÎÞ·¨´ò¿ª±¦Ïä!chestsItemID=%s,costItemID=%s,costItemCountTotal=%s,bindCnt=%s,unBindCnt=%s" % (chestsItemID, costItemID, costItemCountTotal, bindCnt, unBindCnt)) return GameWorld.DebugLog("UseChests: chestsItemID=%s,useCnt=%s,isBind=%s,costItemID=%s*%s,costGoldTotal=%s" % (chestsItemID, useCnt, isBind, costItemID, costItemCountTotal, costGoldTotal)) # ²ú³öÔ¤´¦Àí awardInfo = GetChestsAwardInfo(curPlayer, chestsItemID, useCnt, exData) 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" % (needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount)) for packType, needSpace in needSpaceDict.items(): packSpace = ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace) if packSpace < needSpace: #PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [packType]) PlayerControl.NotifyCode(curPlayer, "OpenBoxItem", [packType, chestsItemID, needSpace - packSpace]) return # ¿Û³ýÏûºÄ if costItemID: ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, costItemCountTotal, "Chests") if costGoldTotal: infoDict = {ChConfig.Def_Cost_Reason_SonKey:chestsItemID} PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal, ChConfig.Def_Cost_UseItem, infoDict) # ¸üпªÆô´ÎÊý if updOpenCount: PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ChestsOpenCount % chestsItemID, updOpenCount) GameWorld.DebugLog(" ¸üб¦Ï俪Æô´ÎÊý: %s" % updOpenCount) saveDataDict = {"AwardItem":jobAwardItemList} ItemCommon.DelItem(curPlayer, curRoleItem, useCnt, True, ChConfig.ItemDel_Chests, saveDataDict) # ¸ø½±Àø syncItemList = [] for itemID, itemCount in jobAwardItemList: curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isBind) if not curItem: GameWorld.ErrLog("±¦Ïä´´½¨½±ÀøÎïÆ·Òì³£!chestsItemID=%s,useCnt=%s,itemID=%s,itemCount=%s,isBind=%s" % (chestsItemID, useCnt, itemID, itemCount, isBind), curPlayer.GetPlayerID()) continue if showType: syncItemList.append(ItemCommon.GetJsonItem(curItem)) # ±ØÐëÔÚ¸øÎïÆ·Ö®Ç°ÏÈget userData = curItem.GetUserData() isOK = ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, event=[ChConfig.ItemGive_Chests, False, {"UseItemID":chestsItemID}]) if isOK and itemID in notifyItemList: PlayerControl.WorldNotify(0, "ChooseMessage", [curPlayer.GetPlayerName(), chestsItemID, itemID, isBind, itemCount, userData]) # »õ±Ò if moneyType: addDataDict = {ChConfig.Def_Give_Reason_SonKey:chestsItemID} if not PlayerControl.GiveMoney(curPlayer, moneyType, moneyCount, ChConfig.Def_GiveMoney_UseItem, addDataDict, False): moneyType, moneyCount = 0, 0 # ֪ͨ if syncItemList: ChItem.SendUseItemGetItemResult(curPlayer, chestsItemID, useCnt, syncItemList, moneyType, moneyCount) return True, useCnt def GetChestsAwardInfo(curPlayer, chestsItemID, useCount, exData=0): '''»ñÈ¡±¦Ï俪Æô½±Àø @return: None - »ñÈ¡±¦Ïä½±ÀøÊ§°Ü @return: needSpaceDict, jobAwardItemList [[itemID, itemCount], ...] ''' awardIpyData = __GetChestsAwardIpyDataByLV(curPlayer, chestsItemID) if not awardIpyData: return awardItemDict = {} job = curPlayer.GetJob() jobItemList = awardIpyData.GetJobItemList() # Ñ¡ÔñÎïÆ· if awardIpyData.GetSelectItemDict(): if not exData: GameWorld.ErrLog("Ñ¡ÔñµÄÎïÆ·´íÎó, ÐèÒªÖ¸¶¨Ò»¸öÑ¡ÔñÎïÆ·ID!chestsItemID=%s,selectItemID=%s" % (chestsItemID, exData)) return selectItemID = exData isSelectOK = False for cfgItemID, itemCount in awardIpyData.GetSelectItemDict().items(): # Ö§³Ö°´Ö°ÒµÑ¡Ôñ£¬Ç°¶ËÎÞÂÛ·¢Ö°Òµ¶ÔÓ¦ÎïÆ·ID»òÕßÅäÖõÄÎïÆ·ID¾ù¿É»ñµÃ jobItemID = __GetChestsJobItem(chestsItemID, job, cfgItemID, jobItemList) if not jobItemID: return if selectItemID == cfgItemID or selectItemID == jobItemID: __AddAwardItem(awardItemDict, jobItemID, itemCount * useCount) isSelectOK = True break if not isSelectOK: GameWorld.ErrLog("Ñ¡ÔñµÄÎïÆ·´íÎó, ¸Ã±¦ÏäûÓиÃÎïÆ·!chestsItemID=%s,selectItemID=%s" % (chestsItemID, selectItemID)) return # ¹Ì¶¨²ú³öÎïÆ· if awardIpyData.GetFixedItemDict(): for itemID, itemCount in awardIpyData.GetFixedItemDict().items(): __AddAwardItem(awardItemDict, itemID, itemCount * useCount) # Ëæ»úÎïÆ·¿â1 if awardIpyData.GetRandItemList1() and awardIpyData.GetRandTimeList1(): if not __AddChestsRandAwardItem(curPlayer, chestsItemID, useCount, awardItemDict, awardIpyData.GetRandItemList1(), awardIpyData.GetRandTimeList1()): return # ¸ù¾Ý±¦Ï俪Æô´ÎÊýÌØÊâ²ú³ö updOpenCount = 0 randItemList2DoCount = useCount randItemByUseCountDict = awardIpyData.GetRandItemByUseCount() if randItemByUseCountDict: maxOpenCount = max(randItemByUseCountDict) hisOpenCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ChestsOpenCount % chestsItemID) if hisOpenCount < maxOpenCount: updOpenCount = min(hisOpenCount + useCount, maxOpenCount) for specUseCount, randItemList in randItemByUseCountDict.items(): if not (hisOpenCount < specUseCount <= updOpenCount): GameWorld.DebugLog(" ²»Âú×ãÌØÊâ´ÎÊý²ú³ö: hisOpenCount=%s,specUseCount=%s,updOpenCount=%s" % (hisOpenCount, specUseCount, updOpenCount)) continue randItemList2DoCount -= 1 randItemInfo = GameWorld.GetResultByRandomList(randItemList) GameWorld.DebugLog(" ¸ù¾Ý¿ªÆô´ÎÊýÌØÊâ²ú³ö: specUseCount=%s, %s, randItemList2DoCount=%s" % (specUseCount, randItemInfo, randItemList2DoCount)) if not randItemInfo: continue if len(randItemInfo) != 2: GameWorld.ErrLog("±¦Ï俪Æô´ÎÊýÌØÊâ²ú³öËæ»ú¿âÅäÖôíÎó!chestsItemID=%s" % chestsItemID) return itemID, itemCount = randItemInfo if not itemID: continue __AddAwardItem(awardItemDict, itemID, itemCount) if randItemList2DoCount != useCount: GameWorld.DebugLog(" Ëæ»úÎïÆ·¿â2Ö´ÐдÎÊý: %s" % (randItemList2DoCount)) # Ëæ»úÎïÆ·¿â2 if awardIpyData.GetRandItemList2() and awardIpyData.GetRandTimeList2() and randItemList2DoCount: if not __AddChestsRandAwardItem(curPlayer, chestsItemID, randItemList2DoCount, awardItemDict, awardIpyData.GetRandItemList2(), awardIpyData.GetRandTimeList2()): return # ²ú³öÌØÊâÎïÆ·¹ã²¥ needNotifyItemList = awardIpyData.GetNeedNotifyItemList() needSpaceDict = {} # {packType:needSpace, ...} notifyItemList = [] jobAwardItemList = [] for itemID, itemCount in awardItemDict.items(): jobItemID = __GetChestsJobItem(chestsItemID, job, itemID, jobItemList) if not jobItemID: return itemData = GameWorld.GetGameData().GetItemByTypeID(jobItemID) if not itemData: GameWorld.ErrLog("±¦Ïä½±ÀøÎïÆ·²»´æÔÚ! chestsItemID=%s,itemID=%s,jobItemID=%s" % (chestsItemID, itemID, jobItemID)) return packType = ChConfig.GetItemPackType(itemData.GetType()) needSpace = int(math.ceil(itemCount / float(itemData.GetPackCount()))) needSpaceDict[packType] = needSpaceDict.get(packType, 0) + needSpace # ×°±¸²ð¿ª¸ø£¬ÐèҪͬ²½Ã¿¼þ×°±¸µÄÊôÐÔ if ItemCommon.GetIsEquip(itemData): jobAwardItemList.extend([[jobItemID, 1]] * itemCount) else: jobAwardItemList.append([jobItemID, itemCount]) if itemID in needNotifyItemList or jobItemID in needNotifyItemList: notifyItemList.append(jobItemID) return needSpaceDict, jobAwardItemList, awardIpyData.GetMoneyType(), awardIpyData.GetMoneyCount() * useCount, notifyItemList, updOpenCount def __GetMaxRandTime(randTimeList): if len(randTimeList) == 1 and type(randTimeList[0]) == int: return randTimeList[0] return randTimeList[-1][1] def __AddChestsRandAwardItem(curPlayer, chestsItemID, useCount, awardItemDict, randItemList, randTimeList): # ¹ýÂËδ½âËøµÄÎïÆ· resetRandItemList = [] # ÖØÉè¿É²ú³öµÄÎïÆ·±ýͼ¸ÅÂÊÁбí for i, rateItemInfo in enumerate(randItemList): if type(rateItemInfo) not in [list, tuple] or len(rateItemInfo) != 2: GameWorld.ErrLog("±¦ÏäËæ»úÎïÆ·¿â±ýͼ¸ñʽ´íÎó!chestsItemID=%s,randItemList=%s" % (chestsItemID, randItemList)) return False rate, itemInfo = rateItemInfo if itemInfo and itemInfo[0]: itemID = itemInfo[0] # ÓÐÅäÖÃÎïÆ·ID£¬ÐèÅжϸÃÎïÆ·IDÊÇ·ñºÏ·¨¿É¿ª³öµÈ£¬Ö§³ÖÅäÖÿÕÎïÆ·ID itemData = GameWorld.GetGameData().GetItemByTypeID(itemID) if not itemData: return False # ·ûÓ¡ÅжÏÊÇ·ñÒѾ­½âËø if itemData.GetType() == ChConfig.Def_ItemType_Rune: if not PlayerRune.GetIsOpenByRuneID(curPlayer, itemID): GameWorld.DebugLog("´Ë·ûӡδ½âËøÎÞ·¨¿ª³ö! chestsItemID=%s,itemID=%s" % (chestsItemID, itemID)) continue curRate = rate if i == 0 else (rate - randItemList[i - 1][0]) preRate = 0 if not resetRandItemList else resetRandItemList[-1][0] resetRandItemList.append([preRate + curRate, itemInfo]) # ÖØÉè±ýͼ¸ÅÂÊÁбí for _ in xrange(useCount): if len(randTimeList) == 1 and type(randTimeList[0]) == int: randTimes = randTimeList[0] else: randTimes = GameWorld.GetResultByRandomList(randTimeList) if randTimes == None: GameWorld.ErrLog("±¦ÏäËæ»ú´ÎÊýÅäÖôíÎó!chestsItemID=%s" % chestsItemID) return False if not randTimes: continue for _ in xrange(randTimes): randItemInfo = GameWorld.GetResultByRandomList(resetRandItemList) if not randItemInfo: #GameWorld.DebugLog("±¦ÏäËæ»ú¿âËæ»ú³öÎïÆ·0£¬randItemInfo=%s" % randItemInfo) continue if len(randItemInfo) != 2: GameWorld.ErrLog("±¦ÏäËæ»ú¿âÅäÖôíÎó!chestsItemID=%s" % chestsItemID) return False itemID, itemCount = randItemInfo if not itemID: #GameWorld.DebugLog("±¦ÏäËæ»ú¿âËæ»ú³öÎïÆ·itemID=0£¬randItemInfo=%s" % randItemInfo) continue __AddAwardItem(awardItemDict, itemID, itemCount) return True def __GetChestsJobItem(chestsItemID, job, itemID, jobItemList): ## »ñÈ¡±¦ÏäÎïÆ·½±Àø¶ÔÓ¦µÄÖ°ÒµÎïÆ·£¬ Ö°Òµ´Ó1¿ªÊ¼ for jobItemIDList in jobItemList: if type(jobItemIDList) not in [list, tuple]: GameWorld.ErrLog("±¦ÏäÖ°ÒµÎïÆ·×é¸ñʽ´íÎó!chestsItemID=%s,jobItemList=%s" % (chestsItemID, jobItemList)) return 0 if itemID in jobItemIDList: if job <= 0 or job > len(jobItemIDList): GameWorld.ErrLog("±¦ÏäÖ°ÒµÎïÆ·ÅäÖôíÎó,ûÓиÃÖ°Òµ¶ÔÓ¦ÎïÆ·ID!chestsItemID=%s,job=%s,itemID=%s" % (chestsItemID, job, itemID)) return 0 return jobItemIDList[job - 1] return itemID def __AddAwardItem(awardItemDict, itemID, itemCount): awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount return def __GetChestsAwardIpyDataByLV(curPlayer, chestsItemID): ## »ñÈ¡±¦Ï俪Æô½±Àø awardIpyDataList = IpyGameDataPY.GetIpyGameDataList("ChestsAward", chestsItemID) if not awardIpyDataList: return if len(awardIpyDataList) == 1: return awardIpyDataList[0] # ¶àÌõ²ú³ö¼Ç¼µÄ£¬°´µÈ¼¶À´ lvIpyDataList = [] for ipyData in awardIpyDataList: lvIpyDataList.append([ipyData.GetAwardLV(), ipyData]) lvIpyDataList.sort() # ÉýÐòÅÅÐò curLV = curPlayer.GetLV() minLV = lvIpyDataList[0][0] if curLV < minLV: GameWorld.ErrLog("µ±Ç°µÈ¼¶ÎÞ·¨¿ªÆô¸Ã±¦Ïä!curLV=%s,minLV=%s,chestsItemID=%s" % (curLV, minLV, chestsItemID), curPlayer.GetPlayerID()) return for i, lvIpyInfo in enumerate(lvIpyDataList[1:], 1): awardLV, ipyData = lvIpyInfo if curLV < awardLV: awardLV, ipyData = lvIpyDataList[i - 1] return ipyData return awardIpyDataList[-1]