| | |
| | | import IPY_GameWorld
|
| | | import ItemControler
|
| | | import PlayerRune
|
| | | import NPCCommon
|
| | | import ChConfig
|
| | | import ChEquip
|
| | | import ChItem
|
| | |
|
| | | import random
|
| | | import math
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
| | | return
|
| | |
|
| | | showType = chestsIpyData.GetShowType() # 规定有开箱表现的默认只能开启1个
|
| | | if showType:
|
| | | useCnt = 1
|
| | | |
| | | #if showType:
|
| | | # useCnt = 1
|
| | | useCnt = min(curRoleItem.GetCount(), useCnt)
|
| | | |
| | | isBind = int(chestsIpyData.GetIsBind()) # 奖励物品是否绑定
|
| | | costItemID = chestsIpyData.GetCostItemID()
|
| | | costItemCountTotal = chestsIpyData.GetCostItemCount() * useCnt
|
| | | costGoldTotal = chestsIpyData.GetCostGold() * useCnt
|
| | | auctionItemCanSell = chestsIpyData.GetAucionItemCanSell()
|
| | | aucionItemDiffSellIDList = chestsIpyData.GetAucionItemDiffSellIDList()
|
| | |
|
| | | if costGoldTotal and not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal):
|
| | | return
|
| | |
| | | awardInfo = GetChestsAwardInfo(curPlayer, chestsItemID, useCnt, exData)
|
| | | if not awardInfo:
|
| | | return
|
| | | needSpaceDict, jobAwardItemDict, moneyType, moneyCount, notifyItemList = awardInfo
|
| | | GameWorld.DebugLog(" needSpaceDict=%s,jobAwardItemDict=%s,moneyType=%s,moneyCount=%s,notifyItemList=%s" |
| | | % (needSpaceDict, jobAwardItemDict, moneyType, moneyCount, notifyItemList))
|
| | | 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))
|
| | |
|
| | | for packType, needSpace in needSpaceDict.items():
|
| | | packSpace = ItemCommon.GetItemPackSpace(curPlayer, packType, needSpace)
|
| | |
| | | infoDict = {ChConfig.Def_Cost_Reason_SonKey:chestsItemID}
|
| | | PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, costGoldTotal, ChConfig.Def_Cost_UseItem, infoDict)
|
| | |
|
| | | saveDataDict = {"AwardItem":jobAwardItemDict}
|
| | | # 更新开启次数
|
| | | 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 jobAwardItemDict.items():
|
| | | curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isBind)
|
| | | 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
|
| | | curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem, curPlayer=curPlayer)
|
| | | if not curItem:
|
| | | GameWorld.ErrLog("宝箱创建奖励物品异常!chestsItemID=%s,useCnt=%s,itemID=%s,itemCount=%s,isBind=%s"
|
| | | % (chestsItemID, useCnt, itemID, itemCount, isBind), curPlayer.GetPlayerID())
|
| | |
| | | def GetChestsAwardInfo(curPlayer, chestsItemID, useCount, exData=0):
|
| | | '''获取宝箱开启奖励
|
| | | @return: None - 获取宝箱奖励失败
|
| | | @return: needSpaceDict, jobAwardItemDict{itemID:itemCount, ...}
|
| | | @return: needSpaceDict, jobAwardItemList [[itemID, itemCount], ...]
|
| | | '''
|
| | |
|
| | | awardIpyData = __GetChestsAwardIpyDataByLV(curPlayer, chestsItemID)
|
| | |
| | | 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():
|
| | | if not __AddChestsRandAwardItem(curPlayer, chestsItemID, useCount, awardItemDict, awardIpyData.GetRandItemList2(), awardIpyData.GetRandTimeList2()):
|
| | | if awardIpyData.GetRandItemList2() and awardIpyData.GetRandTimeList2() and randItemList2DoCount:
|
| | | if not __AddChestsRandAwardItem(curPlayer, chestsItemID, randItemList2DoCount, awardItemDict, awardIpyData.GetRandItemList2(), awardIpyData.GetRandTimeList2()):
|
| | | return
|
| | | |
| | | # 装备库
|
| | | if awardIpyData.GetPieRateDrop() or awardIpyData.GetIndepRateDrop():
|
| | | if not __AddChestsEquipItem(curPlayer, chestsItemID, useCount, awardItemDict, awardIpyData):
|
| | | return
|
| | |
|
| | | # 产出特殊物品广播
|
| | |
| | |
|
| | | needSpaceDict = {} # {packType:needSpace, ...}
|
| | | notifyItemList = []
|
| | | jobAwardItemDict = {}
|
| | | jobAwardItemList = []
|
| | | for itemID, itemCount in awardItemDict.items():
|
| | | if not itemCount:
|
| | | continue
|
| | | jobItemID = __GetChestsJobItem(chestsItemID, job, itemID, jobItemList)
|
| | | if not jobItemID:
|
| | | return
|
| | |
| | | if not itemData:
|
| | | GameWorld.ErrLog("宝箱奖励物品不存在! chestsItemID=%s,itemID=%s,jobItemID=%s" % (chestsItemID, itemID, jobItemID))
|
| | | return
|
| | | packType = ChConfig.GetItemPackType(itemData.GetType())
|
| | | packType = ChConfig.GetItemPackType(itemData)
|
| | | needSpace = int(math.ceil(itemCount / float(itemData.GetPackCount())))
|
| | | needSpaceDict[packType] = needSpaceDict.get(packType, 0) + needSpace
|
| | |
|
| | | jobAwardItemDict[jobItemID] = itemCount
|
| | | # 装备拆开给,需要同步每件装备的属性
|
| | | 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, jobAwardItemDict, awardIpyData.GetMoneyType(), awardIpyData.GetMoneyCount() * useCount, notifyItemList
|
| | | return needSpaceDict, jobAwardItemList, awardIpyData.GetMoneyType(), awardIpyData.GetMoneyCount() * useCount, notifyItemList, updOpenCount
|
| | |
|
| | | def __GetMaxRandTime(randTimeList):
|
| | | if len(randTimeList) == 1 and type(randTimeList[0]) == int:
|
| | |
| | | itemID = itemInfo[0] # 有配置物品ID,需判断该物品ID是否合法可开出等,支持配置空物品ID
|
| | | itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
|
| | | if not itemData:
|
| | | GameWorld.ErrLog("宝箱奖励物品不存在! chestsItemID=%s,itemID=%s" % (chestsItemID, itemID))
|
| | | return False
|
| | |
|
| | | # 符印判断是否已经解锁
|
| | |
| | |
|
| | | return True
|
| | |
|
| | | def __AddChestsEquipItem(curPlayer, chestsItemID, useCount, awardItemDict, awardIpyData):
|
| | | ## 获取宝箱装备库产出
|
| | | |
| | | dropEquipInfoList = []
|
| | | itemJobList = [curPlayer.GetJob()] if awardIpyData.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 掉落装备职业列表
|
| | | |
| | | # 饼图概率随机装备
|
| | | pieRateDoCnt = awardIpyData.GetPieRateDoCnt() * useCount
|
| | | pieRateDropList = awardIpyData.GetPieRateDrop() # 饼图概率掉落信息 [(概率,0),(概率,(阶,颜色)),...]
|
| | | for _ in xrange(pieRateDoCnt):
|
| | | dropInfo = GameWorld.GetResultByRandomList(pieRateDropList)
|
| | | if dropInfo:
|
| | | dropEquipInfoList.append(dropInfo)
|
| | | GameWorld.DebugLog("饼图装备掉落结果: pieRateDoCnt=%s, %s" % (pieRateDoCnt, dropEquipInfoList))
|
| | | |
| | | # 独立概率随机装备
|
| | | Def_NPCMaxDropRate = NPCCommon.Def_NPCMaxDropRate
|
| | | indepRateDict = awardIpyData.GetIndepRateDrop() # 独立概率掉落信息 {(阶,颜色):概率,...}
|
| | | for _ in xrange(useCount):
|
| | | for dropInfo, rate in indepRateDict.iteritems():
|
| | | dropRate = rate
|
| | | mustDropCount = dropRate / Def_NPCMaxDropRate
|
| | | dropRate = dropRate % Def_NPCMaxDropRate # 基础概率
|
| | | GameWorld.DebugLog(" dropInfo=%s,rate=%s,mustDropCount=%s,dropRate=%s" % (dropInfo, rate, mustDropCount, dropRate))
|
| | | curDropCount = mustDropCount
|
| | | if GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):
|
| | | curDropCount += 1
|
| | | if not curDropCount:
|
| | | continue
|
| | | |
| | | for _ in xrange(curDropCount):
|
| | | dropEquipInfoList.append(dropInfo)
|
| | | |
| | | GameWorld.DebugLog("装备库产出: dropEquipInfoList=%s" % dropEquipInfoList)
|
| | | |
| | | colorSuitRateDict = awardIpyData.GetEquipColorSuitInfo() # 装备颜色对应套装概率 {颜色:套装概率, ...}
|
| | | colorSuitPlaceKeyInfoDict = awardIpyData.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...}
|
| | | for classLV, color in dropEquipInfoList:
|
| | | isSuit = 0
|
| | | if color in colorSuitRateDict:
|
| | | suitRate = colorSuitRateDict[color]
|
| | | isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate)
|
| | | colorSuitKey = (color, isSuit)
|
| | | if colorSuitKey not in colorSuitPlaceKeyInfoDict:
|
| | | GameWorld.ErrLog("未配置颜色套装对应部位集合key! chestsItemID=%s,color=%s,isSuit=%s" % (chestsItemID, color, isSuit))
|
| | | continue
|
| | | placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey]
|
| | | jobList = itemJobList
|
| | | placeList = NPCCommon.GetEquipPlaceByPlaceKey(placeKey)
|
| | | if not placeList:
|
| | | GameWorld.ErrLog("部位集合key不存在!chestsItemID=%s,placeKey=%s" % (chestsItemID, placeKey))
|
| | | continue
|
| | | # 未指定,默认取当前解锁的最大境界装备阶
|
| | | if classLV == 0:
|
| | | classLV = ChEquip.GetPlayerMaxEquipClassLV(curPlayer)
|
| | | GameWorld.DebugLog(" 未指定装备阶,默认取玩家当前解锁的最大阶: classLV=%s" % classLV)
|
| | | |
| | | randEquipIDList = NPCCommon.__GetEquipIDList(chestsItemID, classLV, color, isSuit, placeList, itemJobList, findType="ChestsItem")
|
| | | if not randEquipIDList:
|
| | | continue
|
| | | randItemID = random.choice(randEquipIDList)
|
| | | __AddAwardItem(awardItemDict, randItemID, 1)
|
| | | GameWorld.DebugLog("开出装备: chestsItemID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,jobList=%s,randEquipIDList=%s" |
| | | % (chestsItemID, randItemID, classLV, color, isSuit, placeKey, jobList, randEquipIDList))
|
| | | |
| | | return True
|
| | |
|
| | | def __GetChestsJobItem(chestsItemID, job, itemID, jobItemList):
|
| | | ## 获取宝箱物品奖励对应的职业物品, 职业从1开始
|
| | | for jobItemIDList in jobItemList:
|
| | |
| | | # 多条产出记录的,按等级来
|
| | | lvIpyDataList = []
|
| | | for ipyData in awardIpyDataList:
|
| | | lvIpyDataList.append([ipyData.GetAwardLV(), ipyData])
|
| | | lvIpyDataList.append([ipyData.GetRealmLV(), ipyData.GetAwardLV(), ipyData])
|
| | | lvIpyDataList.sort() # 升序排序
|
| | |
|
| | | curLV = curPlayer.GetLV()
|
| | | minLV = lvIpyDataList[0][0]
|
| | | curRealmLV = curPlayer.GetOfficialRank()
|
| | | minRealmLV, minLV = lvIpyDataList[0][0], lvIpyDataList[0][1]
|
| | | if curLV < minLV:
|
| | | GameWorld.ErrLog("当前等级无法开启该宝箱!curLV=%s,minLV=%s,chestsItemID=%s" % (curLV, minLV, chestsItemID), curPlayer.GetPlayerID())
|
| | | GameWorld.ErrLog("当前等级无法开启该宝箱!curLV=%s < minLV=%s,chestsItemID=%s" % (curLV, minLV, chestsItemID), curPlayer.GetPlayerID())
|
| | | return
|
| | | if curRealmLV < minRealmLV:
|
| | | GameWorld.ErrLog("当前境界无法开启该宝箱!curRealmLV=%s < minRealmLV=%s,chestsItemID=%s" % (curRealmLV, minRealmLV, 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
|
| | | realmLV, awardLV, ipyData = lvIpyInfo
|
| | | if realmLV: # 境界优先,二选一
|
| | | if curRealmLV < realmLV:
|
| | | return lvIpyDataList[i - 1][-1]
|
| | | else:
|
| | | if curLV < awardLV:
|
| | | return lvIpyDataList[i - 1][-1]
|
| | | return awardIpyDataList[-1]
|
| | |
|