hxp
2022-08-11 8a5cd920235eefda418bba0e949ba522cab72a4c
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py
@@ -23,9 +23,12 @@
import IPY_GameWorld
import ItemControler
import PlayerRune
import NPCCommon
import ChConfig
import ChEquip
import ChItem
import random
import math
#---------------------------------------------------------------------
@@ -38,14 +41,16 @@
        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
@@ -64,8 +69,8 @@
    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"
                       % (needSpaceDict, jobAwardItemList, moneyType, moneyCount, notifyItemList, updOpenCount, auctionItemCanSell))
    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)
@@ -92,7 +97,8 @@
    # 给奖励
    syncItemList = []
    for itemID, itemCount in jobAwardItemList:
        isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID) else 0
        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" 
@@ -199,6 +205,11 @@
    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
    
    # 产出特殊物品广播
    needNotifyItemList = awardIpyData.GetNeedNotifyItemList()
@@ -217,7 +228,7 @@
        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
        
@@ -249,6 +260,7 @@
            itemID = itemInfo[0] # 有配置物品ID,需判断该物品ID是否合法可开出等,支持配置空物品ID
            itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
            if not itemData:
                GameWorld.ErrLog("宝箱奖励物品不存在! chestsItemID=%s,itemID=%s" % (chestsItemID, itemID))
                return False
            
            # 符印判断是否已经解锁
@@ -291,6 +303,73 @@
            
    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:
@@ -320,19 +399,26 @@
    # 多条产出记录的,按等级来
    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]