From 922b9a9139f9c86cc48b14668f05615a6ea5fd21 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 19 三月 2019 16:02:13 +0800 Subject: [PATCH] 6359 【后端】【2.0】掉落规则调整 --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 664 ++++++++++++++++++++++--------------------------------- 1 files changed, 265 insertions(+), 399 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 73327bb..164fe52 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -408,7 +408,7 @@ @param exp_rate: 击杀怪物享受的经验比例 @param mailTypeKey: 获取物品背包空间不足时发送的邮件模板key @param isMail: 是否强制发送邮件,若是则不考虑背包空间,否的话只在背包空间不足时才发送邮件 - @param extraItemList: 固定附加物品列表,如果需执行多次,则此固定产出列表需在外层处理好,内层不做多次执行处理。[[itemID, itemCount, isBind], ...] + @param extraItemList: 固定附加物品列表,如果需执行多次,则此固定产出列表需在外层处理好,内层不做多次执行处理。[[itemID, itemCount, isAuctionItem], ...] @param prizeMultiple: 奖励倍值, 对所有奖励有效,等于击杀多次NPC,多倍附加物品 ''' if not exp_rate: @@ -418,7 +418,7 @@ totalExp = 0 totalMoney = 0 itemCountDict = {} - itemBindDict = {} + auctionItemIDList = [] if prizeMultiple > 1: hadDropItemKeyList, hadDropItemPlaceList = [], [] # 已经掉落过的物品集合key列表, 已经掉落过的装备部位列表 @@ -440,11 +440,11 @@ # 掉落有概率因素,需多次执行 for dCount in xrange(1, totalCount + 1): - isKillCountDropEquipEx = dCount == 1 # 同一只NPC一次处理中多次击杀的情况,只算一次附加装备处理 - dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDropEquipEx=isKillCountDropEquipEx, curGrade=curGrade) + isKillCountDrop = dCount == 1 # 同一只NPC一次处理中多次击杀的情况,只算一次附加装备处理 + dropInfo = GetNPCDropInfo(curPlayer, mapID, npcID, isKillCountDrop=isKillCountDrop, curGrade=curGrade) if not dropInfo: continue - dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue = dropInfo + dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo totalMoney += (dropMoneyCnt * moneyValue) for itemID in dropIDList: @@ -476,12 +476,14 @@ hadDropItemKeyList.append(itemKey) itemCountDict[itemID] = itemCountDict.get(itemID, 0) + 1 - itemBindDict[itemID] = dropIDBindDict.get(itemID, 1) + if itemID in auctionIDList and itemID not in auctionItemIDList: + auctionItemIDList.append(itemID) # 固定附加物品 - for itemID, itemCount, isBind in extraItemList: + for itemID, itemCount, isAuctionItem in extraItemList: itemCountDict[itemID] = itemCountDict.get(itemID, 0) + itemCount * prizeMultiple - itemBindDict[itemID] = isBind + if isAuctionItem and itemID not in auctionItemIDList: + auctionItemIDList.append(itemID) needSpace = 0 prizeItemList = [] @@ -491,7 +493,7 @@ if not itemData: continue - isBind = itemBindDict.get(itemID, 1) + isAuctionItem = itemID in auctionItemIDList if ItemCommon.GetIsEquip(itemData): for _ in xrange(itemCount): @@ -501,9 +503,9 @@ prizeItemList.append(curItem) jsonItemList.append(ItemCommon.GetJsonItem(curItem)) else: - needSpace += int(math.ceil(itemCount / float(itemData.GetPackCount()))) - prizeItemList.append([itemID, itemCount, isBind]) - jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isBind])) + needSpace += ItemControler.GetItemNeedPackCount(IPY_GameWorld.rptItem, itemData, itemCount, isAuctionItem) + prizeItemList.append([itemID, itemCount, isAuctionItem]) + jsonItemList.append(ItemCommon.GetJsonItem([itemID, itemCount, isAuctionItem])) #成就 if not dropItemMapInfo: PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_PickUpItem, itemCount, [itemID]) @@ -516,9 +518,9 @@ dropItemList = [] for itemInfo in prizeItemList: if isinstance(itemInfo, list): - itemID, itemCount, isBind = itemInfo + itemID, itemCount, isAuctionItem = itemInfo for _ in xrange(itemCount): - dropItemList.append([itemID, 1, isBind]) + dropItemList.append([itemID, 1, isAuctionItem]) else: dropItemList.append(itemInfo) else: @@ -540,8 +542,8 @@ curItem = dropItemList[index] index += 1 if isinstance(curItem, list): - itemID, itemCount, isBind = curItem - curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, False) + itemID, itemCount, isAuctionItem = curItem + curItem = ItemControler.GetOutPutItemObj(itemID, itemCount, isAuctionItem) if not curItem: continue @@ -568,8 +570,8 @@ event = [ChConfig.ItemGive_NPCDrop, False, {"NPCID":npcID}] for prizeItem in prizeItemList: if isinstance(prizeItem, list): - itemID, itemCount, isBind = prizeItem - ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, 0, [IPY_GameWorld.rptItem], + itemID, itemCount, isAuctionItem = prizeItem + ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem], event=event) else: ItemControler.DoLogic_PutItemInPack(curPlayer, prizeItem, event=event) @@ -651,13 +653,13 @@ GameWorld.DebugLog("脱机挂杀怪掉落: npcID=%s,killCount=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s" % (npcID, killCount, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus), playerID) - dropEquipInfoList = [] # [(阶,颜色,部位集合key, 件数), ...] + dropEquipInfoList = [] # [(阶,颜色, 件数), ...] # 1.装备只算饼图概率 pieRateDoCnt = ipyDrop.GetPieRateDoCnt() if pieRateDoCnt and ipyDrop.GetPieRateDrop(): pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) pieRateDoCnt *= killCount - pieRateDropList = ipyDrop.GetPieRateDrop() # [(概率,0),(概率,(阶,颜色,部位集合key)),...] + pieRateDropList = ipyDrop.GetPieRateDrop() # [(概率,0),(概率,(阶,颜色)),...] if equipDropRatePlus: dropRateList = GameWorld.GetPlusPieList(pieRateDropList, equipDropRatePlus) GameWorld.DebugLog(" 装备配置饼图: %s,equipDropRatePlus=%s" % (pieRateDropList, equipDropRatePlus), playerID) @@ -674,50 +676,52 @@ preRate = rate if not equipInfo: continue - classLV, color, placeKey = equipInfo + classLV, color = equipInfo totalRate = curRate * pieRateDoCnt # 总概率 dropCount = totalRate / maxRate # 可掉落件数 rateEx = totalRate % maxRate # 剩余概率 if GameWorld.CanHappen(rateEx, maxRate): dropCount += 1 - GameWorld.DebugLog(" 装备掉率: curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,classLV=%s,color=%s,placeKey=%s" - % (curRate, totalRate, rateEx, dropCount, classLV, color, placeKey), playerID) + GameWorld.DebugLog(" 装备掉率: curRate=%s,totalRate=%s,rateEx=%s,dropCount=%s,classLV=%s,color=%s" + % (curRate, totalRate, rateEx, dropCount, classLV, color), playerID) if not dropCount: continue - dropEquipInfoList.append([classLV, color, placeKey, dropCount]) - GameWorld.DebugLog(" 装备掉落结果: killCount=%s,[阶,颜色,部位集合,件数]=%s" % (killCount, dropEquipInfoList), playerID) + dropEquipInfoList.append([classLV, color, dropCount]) + GameWorld.DebugLog(" 装备掉落结果: killCount=%s,[阶,颜色,件数]=%s" % (killCount, dropEquipInfoList), playerID) - placeDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1) - - # 颜色对应星级概率 + placeKeyListDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1) + colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # 装备颜色对应套装概率 {颜色:套装概率, ...} + colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...} dropEquipIDDict = {} - colorStarRateDict = ipyDrop.GetEquipStarInfo() # {颜色:[(概率, 星级),...], ...}, 没有配置的默认最低星 紫-0,橙红-1 - for classLV, color, placeKey, dropCount in dropEquipInfoList: - if placeKey not in placeDict: - GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) - continue - starCountDict = {} # {星级:件数, ...} - placeList = placeDict[placeKey] - if color in colorStarRateDict: - colorStarRateList = colorStarRateDict[color] + for classLV, color, dropCount in dropEquipInfoList: + suitCountDict = {} # {套装:件数, ...} + if color in colorSuitRateDict: + suitRate = colorSuitRateDict[color] for _ in xrange(dropCount): - star = GameWorld.GetResultByRandomList(colorStarRateList, 0) # 默认0星 - starCountDict[star] = starCountDict.get(star, 0) + 1 - elif color >= ChConfig.Def_Quality_Orange: # 橙色及以上的默认1星 - starCountDict[1] = dropCount + isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate) + suitCountDict[isSuit] = suitCountDict.get(isSuit, 0) + 1 else: - starCountDict[0] = dropCount + suitCountDict[0] = dropCount - for star, curStarDropCount in starCountDict.items(): - randEquipIDList = __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList) + for isSuit, curDropCount in suitCountDict.items(): + colorSuitKey = (color, isSuit) + if colorSuitKey not in colorSuitPlaceKeyInfoDict: + GameWorld.ErrLog("未配置颜色是否套装对应部位集合key! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit)) + continue + placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey] + if placeKey not in placeKeyListDict: + GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) + continue + placeList = placeKeyListDict[placeKey] + randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList) if not randEquipIDList: continue - for _ in xrange(curStarDropCount): + for _ in xrange(curDropCount): randItemID = random.choice(randEquipIDList) dropIDList.append(randItemID) dropEquipIDDict[randItemID] = [color, placeKey] - GameWorld.DebugLog(" 掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,star=%s,placeKey=%s,itemJobList=%s,randEquipIDList=%s" - % (npcID, randItemID, classLV, color, star, placeKey, itemJobList, randEquipIDList), playerID) + GameWorld.DebugLog(" 掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,itemJobList=%s,randEquipIDList=%s" + % (npcID, randItemID, classLV, color, isSuit, placeKey, itemJobList, randEquipIDList), playerID) # 2. 指定物品ID库 itemIDDropRateDict = ipyDrop.GetItemIDDropRate() # {物品ID:概率, ...} @@ -743,10 +747,6 @@ # 检查掉落互斥ID组 dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1)) - # 获取掉落物品绑定信息 - isGameBoss = ChConfig.IsGameBoss(npcData) - dropIDBindDict = __GetNPCDropItemBindInfo(mapID, isGameBoss, dropIDList, dropEquipIDDict) - # 掉落金币 dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt() dropMoneyRate = ipyDrop.GetDropMoneyRate() @@ -763,12 +763,18 @@ for dropID in dropIDList: dropIDCountDict[dropID] = dropIDCountDict.get(dropID, 0) + 1 + auctionIDList = [] + if ipyDrop.GetAucionItemCanSell(): + for dropID in dropIDCountDict.keys(): + if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID): + auctionIDList.append(dropID) + if dropIDCountDict: - GameWorld.DebugLog(" 最终掉落: npcID=%s,killCount=%s,dropIDCountDict=%s,dropIDBindDict=%s,dropMoney=%s" - % (npcID, killCount, dropIDCountDict, dropIDBindDict, dropMoney), playerID) - return dropIDCountDict, dropIDBindDict, dropMoney + GameWorld.DebugLog(" 最终掉落: npcID=%s,killCount=%s,dropIDCountDict=%s,auctionIDList=%s,dropMoney=%s" + % (npcID, killCount, dropIDCountDict, auctionIDList, dropMoney), playerID) + return dropIDCountDict, auctionIDList, dropMoney -def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDropEquipEx=True, curGrade=0): +def GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList=[], ipyDrop=None, isSingle=True, isKillCountDrop=True, curGrade=0): '''获取NPC掉落信息, 击杀及扫荡通用,调用该函数获得掉落信息,然后再看掉落地板上还是直接放入背包 @param dropPlayer: 用于判断调用相关用的玩家示例,该玩家并不一定是击杀者,只是按一定规则设定的掉落判断依据的玩家 如队伍,取等级最大的玩家,该玩家并不一定是击杀者 @@ -776,11 +782,11 @@ @param npcID: 掉落物品的NPCID @param ownerPlayerList: 有归属的玩家列表 @param isSingle: 是否只处理单独玩家掉落逻辑,一般都默认True,目前只有场景杀怪掉落需要考虑摸怪的情况下才为False(外层特殊处理) - @return: dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue + @return: dropIDList, auctionIDList, dropMoneyCnt, moneyValue None-没有掉落 --------------- dropIDList - 掉落的物品ID列表, 同个itemID可能在列表中有多个 [itemID, itemID, ...] - dropIDBindDict - 掉落的物品ID绑定信息 {itemID:是否绑定, ...} + auctionIDList - 掉落的拍品物品ID列表, [itemID, itemID, ...] dropMoneyCnt - 掉落金币位置数 moneyValue - 每个位置的金币数量 ''' @@ -805,21 +811,8 @@ return dropIDList = [] # 掉落的ID列表 - dropIDBindDict = {} + auctionIDList = [] dropMoneyCnt, moneyValue = 0, 0 - - # 1. 击杀次数掉落 - killCountDropIDList = [] - killCountDropInfo = ipyDrop.GetKillCountDrop() - if isSingle and killCountDropInfo: - needKillCount, isDropInItemPack, isBind, killDropItemList = killCountDropInfo - killCountDropIDList = GetKillCountDropItemList(dropPlayer, npcID, needKillCount, killDropItemList) - for kDropItemID in killCountDropIDList: - dropIDList.append(kDropItemID) # 单独玩家掉落处理的,直接加到掉落列表里,不考虑是否放入背包或掉落的情况,由使用的功能自行处理 - dropIDBindDict[kDropItemID] = isBind - #GameWorld.DebugLog("击杀次数掉落: kDropItemID=%s,needKillCount=%s,isDropInItemPack=%s,isBind=%s" - # % (kDropItemID, needKillCount, isDropInItemPack, isBind)) - itemJobList = [dropPlayer.GetJob()] if ipyDrop.GetIsDropJobSelf() else IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 掉落装备职业列表 # 通用掉率相关 @@ -830,12 +823,23 @@ doCountRate = ChConfig.Def_MaxRateValue # 归属者相关信息 - dropEquipExKillCount = 0 # 装备附加掉落综合击杀次数,取次数最少的那个,至少第一次 + tagJob = 0 + dropEquipKillCountPub = 0 # 装备附加掉落综合击杀次数,取次数最大的那个,至少第一次 + dropItemIDKillCountPub = 0 # 物品ID附加掉落综合击杀次数,取次数最大的那个,至少第一次 equipDropRatePlus = 0 # 装备掉落概率提升 equipDropDoCountPlus = 0 # 装备掉落执行次数提升 for ownerPlayer in ownerPlayerList: - ownerKillCount = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) + 1 - dropEquipExKillCount = ownerKillCount if not dropEquipExKillCount else min(dropEquipExKillCount, ownerKillCount) + killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) + equipPubKillCount = killCountValue % 100 + 1 + itemIDPubKillCount = killCountValue % 10000 / 100 + 1 + + if dropEquipKillCountPub < equipPubKillCount: + dropEquipKillCountPub = equipPubKillCount + tagJob = ownerPlayer.GetJob() + + if dropItemIDKillCountPub < itemIDPubKillCount: + dropItemIDKillCountPub = itemIDPubKillCount + equipDropRatePlus = max(equipDropRatePlus, PlayerControl.GetDropEquipPer(ownerPlayer)) equipDropDoCountPlus = max(equipDropDoCountPlus, PlayerControl.GetDropEquipDoCount(ownerPlayer)) @@ -849,185 +853,134 @@ #GameWorld.DebugLog("NPC掉落: npcID=%s,itemJobList=%s,dropRatePlusValue=%s,equipDropRatePlus=%s,equipDropDoCountPlus=%s,doCountRate=%s,doCountAdd=%s" # % (npcID, itemJobList, dropRatePlusValue, equipDropRatePlus, equipDropDoCountPlus, doCountRate, doCountAdd), playerID) - dropEquipInfoList = [] # [(阶,颜色,部位集合key), ...] - # 2. 装备库 - 饼图概率 + dropEquipInfoList = [] # [(阶,颜色), ...] + # 1. 装备库 - 饼图概率 pieRateDoCnt = ipyDrop.GetPieRateDoCnt() if pieRateDoCnt: pieRateDoCnt = __GetNPCDropDoCountChange(pieRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) dropEquipInfoList += __GetNPCPieRateEquipDrop(ipyDrop, pieRateDoCnt, equipDropRatePlus) - # 3. 装备库 - 独立概率 + # 2. 装备库 - 独立概率 indepRateDoCnt = ipyDrop.GetIndepRateDoCnt() if indepRateDoCnt: indepRateDoCnt = __GetNPCDropDoCountChange(indepRateDoCnt, doCountRate + equipDropDoCountPlus, doCountAdd) - dropEquipInfoList += __GetNPCIndepRateEquipDrop(ipyDrop, indepRateDoCnt, equipDropRatePlus, curGrade) - - #GameWorld.DebugLog("阶,颜色,部位集合key,dropEquipInfoList=%s" % (dropEquipInfoList)) - placeDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1) - # 第x次击杀,附加装备产出; 前x次击杀,附加装备产出; 归属者综合附加掉落,所有归属者都增加击杀次数; - # [次数,阶,颜色,[(概率,星级),...],部位集合key] - killCountDropEquipEx, killCountDropEquipEx2 = ipyDrop.GetKillCountDropEquipEx(), ipyDrop.GetKillCountDropEquipEx2() - isKillCountDropEquipEx = isKillCountDropEquipEx and (killCountDropEquipEx or killCountDropEquipEx2) - if isKillCountDropEquipEx and killCountDropEquipEx and dropEquipExKillCount == killCountDropEquipEx[0]: # 优先第x次击杀 - tagKillCount, tagClassLV, tagColor, tagStarRateList, tagPlaceKey = killCountDropEquipEx - elif isKillCountDropEquipEx and killCountDropEquipEx2 and dropEquipExKillCount <= killCountDropEquipEx2[0]: # 前x次击杀 - tagKillCount, tagClassLV, tagColor, tagStarRateList, tagPlaceKey = killCountDropEquipEx2 - else: - tagKillCount, tagClassLV, tagColor, tagStarRateList, tagPlaceKey = 0, 0, 0, [], 0 - maxRecordKillCount = tagKillCount # 需要记录的最大击杀次数, 超过此击杀次数后暂时不累加记录 - if tagStarRateList: - tagStar = GameWorld.GetResultByRandomList(tagStarRateList, 0) - tagStarMin = tagStarRateList[0][1] - else: - tagStar = None # 有0星的情况,所以这里默认使用None - tagStarMin = None - tagPlaceList = [] if tagPlaceKey not in placeDict else placeDict[tagPlaceKey] - tagPlace = 0 - tagJob = 0 - tagItemReplaceState = False + dropEquipInfoList += __GetNPCIndepRateEquipDrop(ipyDrop, indepRateDoCnt, equipDropRatePlus, curGrade) + #GameWorld.DebugLog("阶,颜色 key,dropEquipInfoList=%s" % (dropEquipInfoList)) - # 附加装备部位优先级分两个列表, 品质阶级都不满足的列表、品质阶级部分满足的列表 - # 部位优先级规则, 只算身上有穿的部位,没穿装备的不管 - #1)优先品质、阶数、星级都不满足,其次品质、阶数、星级部分满足 - #2)品质、阶数、星级都不满足时,按品质、阶数、星级、评分升序排序 - #3)品质、阶数、星级部分满足时,按品质、阶数、星级、评分升序排序 - #4)品质、阶数、星级都满足时,排除优先部位 - tagPlaceSortList, tagPlaceSortList2 = [], [] - for ownerPlayer in ownerPlayerList: - # 有附加目标装备需求的,统计该归属者身上需要附加给装备的部位 - playerEquip = ownerPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip) - if tagClassLV and tagColor and tagPlaceList: - for equipIndex in xrange(playerEquip.GetCount()): - if equipIndex not in tagPlaceList: - continue - curEquip = playerEquip.GetAt(equipIndex) - if curEquip.IsEmpty(): - continue - curEquipClassLV = ItemCommon.GetItemClassLV(curEquip) - curEquipColor = curEquip.GetItemColor() - curEquipStar = curEquip.GetItemQuality() - equipGS = ItemCommon.GetEquipGearScore(curEquip) - # 品质阶级都不满足 - if curEquipClassLV < tagClassLV and curEquipColor < tagColor and curEquipStar < tagStarMin: - tagPlaceSortList.append([curEquipColor, curEquipClassLV, curEquipStar, equipGS, equipIndex, ownerPlayer.GetJob()]) - # 品质阶级部分不满足 - elif curEquipClassLV < tagClassLV or curEquipColor < tagColor or curEquipStar < tagStarMin: - tagPlaceSortList2.append([curEquipColor, curEquipClassLV, curEquipStar, equipGS, equipIndex, ownerPlayer.GetJob()]) - - # 增加击杀次数 - killCount = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) + 1 - if killCount <= maxRecordKillCount: - PlayerControl.NomalDictSetProperty(ownerPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, killCount) - GameWorld.DebugLog("玩家击杀次数: npcID=%s,killCount=%s,maxRecordKillCount=%s" - % (npcID, killCount, maxRecordKillCount), ownerPlayer.GetPlayerID()) - - tagPlaceSortList.sort() # 升序排序 - tagPlaceSortList2.sort() # 升序排序 - if isKillCountDropEquipEx: - GameWorld.DebugLog("都不满足目标装备的优先级信息: npcID=%s, 数量=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, len(tagPlaceSortList), tagPlaceSortList), playerID) - GameWorld.DebugLog("部分满足目标装备的优先级信息: npcID=%s, 数量=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, len(tagPlaceSortList2), tagPlaceSortList2), playerID) - if tagPlaceSortList or tagPlaceSortList2: - isOptimalPlace = IpyGameDataPY.GetFuncCfg("DropEquipPlaceMode", 1) # 是否取最优解部位 - if isOptimalPlace: - tagPlaceSortList += tagPlaceSortList2 - if tagPlaceSortList: - tagPlace = tagPlaceSortList[0][-2] - tagJob = tagPlaceSortList[0][-1] - GameWorld.DebugLog("掉落目标部位取最优解: tagPlace=%s,tagJob=%s" % (tagPlace, tagJob), playerID) + # 3. 第x次击杀, 归属者公共附加掉落,所有归属者都增加击杀次数; + tagClassLV, tagColor, tagIsSuit, tagPlaceKey = 0, 0, 0, 0 + killCountDropEquipPub = ipyDrop.GetKillCountDropEquipPub() # 第x次击杀附加必掉装备 {次数:[阶,颜色,是否套装,部位集合key], ...} + killCountDropItemPub = ipyDrop.GetKillCountDropPub() # 击杀次数必掉(公共){击杀次数:[[物品ID, ...], [随机物品ID, ...]], ...} + maxRecordDropEquipKillCountPub = max(killCountDropEquipPub) # 需要记录的最大击杀次数, 超过此击杀次数后暂时不累加记录 + maxRecordDropItemIDKillCountPub = max(killCountDropItemPub) + #GameWorld.DebugLog("maxRecordDropEquipKillCountPub=%s,maxRecordDropItemIDKillCountPub=%s" % (maxRecordDropEquipKillCountPub, maxRecordDropItemIDKillCountPub)) + #GameWorld.DebugLog("dropEquipKillCountPub=%s,dropItemIDKillCountPub=%s" % (dropEquipKillCountPub, dropItemIDKillCountPub)) + if isKillCountDrop and killCountDropEquipPub and dropEquipKillCountPub in killCountDropEquipPub: + tagClassLV, tagColor, tagIsSuit, tagPlaceKey = killCountDropEquipPub[dropEquipKillCountPub] + if (tagClassLV, tagColor) not in dropEquipInfoList: + dropEquipInfoList.insert(0, (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob)) else: - randPlaceCountLimit = IpyGameDataPY.GetFuncCfg("DropEquipPlaceMode", 2) # 全不满足目标条件部位有几个时才优先随机 - if len(tagPlaceSortList) < randPlaceCountLimit: - tagPlaceSortList += tagPlaceSortList2 - else: - GameWorld.DebugLog("优先随机都不满足目标装备的,randPlaceCountLimit=%s" % randPlaceCountLimit, playerID) - randPlaceIndex = random.randint(0, len(tagPlaceSortList) - 1) - GameWorld.DebugLog("掉落目标部位随机, randPlaceIndex=%s, 颜色,阶,星,评分,部位,职业=%s" % (randPlaceIndex, tagPlaceSortList), playerID) - tagPlace = tagPlaceSortList[randPlaceIndex][-2] - tagJob = tagPlaceSortList[randPlaceIndex][-1] - GameWorld.DebugLog("掉落目标部位随机不满足条件的: tagPlace=%s,tagJob=%s" % (tagPlace, tagJob), playerID) + tagIndex = dropEquipInfoList.index((tagClassLV, tagColor)) + dropEquipInfoList[tagIndex] = (tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob) + GameWorld.DebugLog("第%s次击杀掉落指定目标装备信息: npcID=%s,tagClassLV=%s,tagColor=%s,tagIsSuit=%s,tagPlaceKey=%s,tagJob=%s,dropEquipInfoList=%s" + % (dropEquipKillCountPub, npcID, tagClassLV, tagColor, tagIsSuit, tagPlaceKey, tagJob, dropEquipInfoList), playerID) + elif isKillCountDrop and killCountDropItemPub and dropItemIDKillCountPub in killCountDropItemPub: + killCountItemIDList, killCountRandItemIDList = killCountDropItemPub[dropItemIDKillCountPub] + if killCountItemIDList: + dropIDList += killCountItemIDList + if killCountRandItemIDList: + klllCountRandItemID = random.choice(killCountRandItemIDList) + dropIDList.append(klllCountRandItemID) + GameWorld.DebugLog("第%s次击杀掉落指定目标物品信息: npcID=%s,killCountItemIDList=%s,killCountRandItemIDList=%s,dropIDList=%s" + % (dropItemIDKillCountPub, npcID, killCountItemIDList, killCountRandItemIDList, dropIDList), playerID) - if isKillCountDropEquipEx: - GameWorld.DebugLog("附加掉落指定目标装备信息: npcID=%s,玩家最少的击杀次数=%s,目标击杀数=%s,tagClassLV=%s,tagColor=%s,tagStar=%s,tagStarMin=%s,tagPlace=%s,tagJob=%s" - % (npcID, dropEquipExKillCount, tagKillCount, tagClassLV, tagColor, tagStar, tagStarMin, tagPlace, tagJob), playerID) - # 颜色对应星级概率 - dropEquipIDDict = {} - colorStarRateDict = ipyDrop.GetEquipStarInfo() # {颜色:[(概率, 星级),...], ...}, 没有配置的默认最低星 紫-0,橙红-1 - gradeColorStarRateDict = {} - fbGradeColorStarRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 2) # 评级影响品质星级概率 {npcID:{(颜色,星级):[D级影响概率, ..., S级影响概率], ...}, ...} - if npcID in fbGradeColorStarRateDict: - gradeColorStarRateDict = fbGradeColorStarRateDict[npcID] + for ownerPlayer in ownerPlayerList: + # 增加击杀次数 + killCountValue = ownerPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) + equipPubKillCount = killCountValue % 100 + itemIDPubKillCount = killCountValue % 10000 / 100 + isUpd = False + if equipPubKillCount < maxRecordDropEquipKillCountPub: + equipPubKillCount += 1 + isUpd = True + if itemIDPubKillCount < maxRecordDropItemIDKillCountPub: + itemIDPubKillCount += 1 + isUpd = True + + if isUpd: + itemIDPriKillCount = killCountValue / 10000 + updKillCountValue = itemIDPriKillCount * 10000 + itemIDPubKillCount * 100 + equipPubKillCount + PlayerControl.NomalDictSetProperty(ownerPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updKillCountValue) + GameWorld.DebugLog("更新玩家击杀次数值: npcID=%s,killCountValue=%s,updKillCountValue=%s" % (npcID, killCountValue, updKillCountValue), ownerPlayer.GetPlayerID()) + + gradeColorSuitRateDict = {} + fbGradeColorSuitRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 2) # 评级影响颜色套装概率 {npcID:{颜色:[D级影响概率, ..., S级影响概率], ...}, ...} + if npcID in fbGradeColorSuitRateDict: + gradeColorSuitRateDict = fbGradeColorSuitRateDict[npcID] curGrade = curGrade if curGrade else GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade) + placeKeyListDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1) colorDropCntDict = {} # 装备颜色已经掉落数 {颜色:数量, ...} - colorMaxDropCntDict = ipyDrop.GetIndepRateMaxDropCount() # {颜色:上限数量,...} - for classLV, color, placeKey in dropEquipInfoList: - - # 装备颜色对应最大掉落件数改为公共限制条件 + colorMaxDropCntDict = ipyDrop.GetEquipColorMaxDropCount() # {颜色:上限数量,...} + colorSuitRateDict = ipyDrop.GetEquipColorSuitInfo() # 装备颜色对应套装概率 {颜色:套装概率, ...} + colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...} + for dropEquipInfo in dropEquipInfoList: + classLV, color = dropEquipInfo[:2] if color in colorMaxDropCntDict: maxCount = colorMaxDropCntDict[color] dropCount = colorDropCntDict.get(color, 0) if dropCount >= maxCount: GameWorld.DebugLog("已超过该颜色装备最大掉落数,不掉!color=%s,maxCount=%s" % (color, maxCount), playerID) continue - colorDropCntDict[color] = dropCount + 1 - # 有附加目标装备时,如果常规掉落有产出同颜色的 且 还没替换过 则直接替换该装备 - if tagColor == color and tagClassLV and tagStar != None and tagPlace and not tagItemReplaceState: - tagItemReplaceState = True - randEquipIDList = __GetEquipIDList(npcID, tagClassLV, tagColor, tagPlaceList, tagStar, [tagJob], tagPlace) - if not randEquipIDList: - continue - randItemID = random.choice(randEquipIDList) - dropIDList.append(randItemID) - dropEquipIDDict[randItemID] = [tagColor, tagPlaceKey] - GameWorld.DebugLog("替换指定颜色装备: npcID=%s,itemID=%s,tagClassLV=%s,tagColor=%s,tagPlace=%s,tagStar=%s,tagJob=%s,randEquipIDList=%s" - % (npcID, randItemID, tagClassLV, tagColor, tagPlace, tagStar, tagJob, randEquipIDList), playerID) + if len(dropEquipInfo) == 5: + isSuit, placeKey, tagJob = dropEquipInfo[2:] + jobList = [tagJob] else: - if placeKey not in placeDict: - GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) + isSuit = 0 + if color in colorSuitRateDict: + suitRate = colorSuitRateDict[color] + # 评级对套装率的影响 + if color in gradeColorSuitRateDict: + suitRateEffList = gradeColorSuitRateDict[color] + suitRateEff = 10000 if (curGrade <= 0 or curGrade > len(suitRateEffList)) else suitRateEffList[curGrade - 1] + suitRate = int(suitRate * suitRateEff / 10000.0) + isSuit = GameWorld.CanHappen(suitRate, maxRate=Def_NPCMaxDropRate) + colorSuitKey = (color, isSuit) + if colorSuitKey not in colorSuitPlaceKeyInfoDict: + GameWorld.ErrLog("未配置颜色是否套装对应部位集合key! npcID=%s,color=%s,isSuit=%s" % (npcID, color, isSuit)) continue - placeList = placeDict[placeKey] - if color in colorStarRateDict: - colorStarRateList = colorStarRateDict[color] - if gradeColorStarRateDict: - colorStarRateList = __GetFBGradeColorStarRateList(color, colorStarRateList, gradeColorStarRateDict, curGrade) - star = GameWorld.GetResultByRandomList(colorStarRateList, 0) # 默认0星 - elif color >= ChConfig.Def_Quality_Orange: # 橙色及以上的默认1星 - star = 1 - else: - star = 0 - - randEquipIDList = __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList) - if not randEquipIDList: - continue - randItemID = random.choice(randEquipIDList) - dropIDList.append(randItemID) - dropEquipIDDict[randItemID] = [color, placeKey] - GameWorld.DebugLog("掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,star=%s,placeKey=%s,itemJobList=%s,randEquipIDList=%s" - % (npcID, randItemID, classLV, color, star, placeKey, itemJobList, randEquipIDList), playerID) - - # 如果没有替换指定装备,则指定装备直接当做附加赠送掉落给 - if not tagItemReplaceState and tagClassLV and tagColor and tagStar != None and tagPlace: - randEquipIDList = __GetEquipIDList(npcID, tagClassLV, tagColor, tagPlaceList, tagStar, [tagJob], tagPlace) - if randEquipIDList: - randItemID = random.choice(randEquipIDList) - dropIDList.append(randItemID) - dropEquipIDDict[randItemID] = [tagColor, tagPlaceKey] - GameWorld.DebugLog("掉落指定目标装备: npcID=%s,itemID=%s,tagClassLV=%s,tagColor=%s,tagStar=%s,tagPlace=%s,tagJob=%s,randEquipIDList=%s" - % (npcID, randItemID, tagClassLV, tagColor, tagStar, tagPlace, tagJob, randEquipIDList), playerID) + placeKey = colorSuitPlaceKeyInfoDict[colorSuitKey] + jobList = itemJobList + if placeKey not in placeKeyListDict: + GameWorld.ErrLog("部位集合key不存在!npcID=%s,placeKey=%s" % (npcID, placeKey)) + continue + placeList = placeKeyListDict[placeKey] + randEquipIDList = __GetEquipIDList(npcID, classLV, color, isSuit, placeList, jobList) + if not randEquipIDList: + continue + if color in colorMaxDropCntDict: + colorDropCntDict[color] = dropCount + 1 + randItemID = random.choice(randEquipIDList) + dropIDList.append(randItemID) + GameWorld.DebugLog("掉落装备: npcID=%s,itemID=%s,classLV=%s,color=%s,isSuit=%s,placeKey=%s,jobList=%s,randEquipIDList=%s" + % (npcID, randItemID, classLV, color, isSuit, placeKey, jobList, randEquipIDList), playerID) # 4. 指定物品ID库 dropIDList += __GetAppointDropItemIDList(dropPlayer, npcID, ipyDrop, doCountRate, doCountAdd) - # 检查掉落互斥ID组 - dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1)) - - # 获取掉落物品绑定信息 - isGameBoss = ChConfig.IsGameBoss(npcData) - dropIDBindDict = __GetNPCDropItemBindInfo(mapID, isGameBoss, dropIDList, dropEquipIDDict) - - # 5. 私有掉落固定产出,所有掉落归属者每人一份,默认绑定,不区分职业 + # 5. 私有掉落 if isSingle: + # 击杀次数掉落 + killCountDropInfo = ipyDrop.GetKillCountDropPri() + if killCountDropInfo: + needKillCount, killDropItemList = killCountDropInfo[:2] + killCountDropIDList = GetKillCountDropItemList(dropPlayer, npcID, needKillCount, killDropItemList) + for kDropItemID in killCountDropIDList: + dropIDList.append(kDropItemID) # 单独玩家掉落处理的,直接加到掉落列表里,不考虑是否放入背包或掉落的情况,由使用的功能自行处理 + #GameWorld.DebugLog("击杀次数掉落: kDropItemID=%s,needKillCount=%s" % (kDropItemID, needKillCount)) + + # 固定产出,所有掉落归属者每人一份,默认绑定,不区分职业 fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3) if npcID in fbGradePriItemIDDropDict: gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID] @@ -1040,12 +993,11 @@ priDropIDList = ipyDrop.GetPriItemIDDrop() for priDropID in priDropIDList: dropIDList.append(priDropID) - dropIDBindDict[priDropID] = 1 #GameWorld.DebugLog("私有物品掉落: priDropID=%s" % priDropID) + + # 检查掉落互斥ID组 + dropIDList = __RemoveMutexDropID(dropIDList, IpyGameDataPY.GetFuncCfg("MutexDrop", 1)) - if dropIDList: - GameWorld.DebugLog("最终掉落物品: npcID=%s,dropIDList=%s,dropIDBindDict=%s" % (npcID, dropIDList, dropIDBindDict), playerID) - # 掉落金币 dropMoneyDoCnt = ipyDrop.GetDropMoneyDoCnt() dropMoneyRate = ipyDrop.GetDropMoneyRate() @@ -1062,90 +1014,16 @@ moneyValue = __GetDropMoneyValue(dropPlayer, ipyDrop) #GameWorld.DebugLog(" 掉落金币value=%s" % (moneyValue)) - if not dropIDList and isGameBoss: + if dropIDList: + if ipyDrop.GetAucionItemCanSell(): + for dropID in dropIDList: + if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropID): + auctionIDList.append(dropID) + GameWorld.DebugLog("最终掉落物品: npcID=%s,dropIDList=%s" % (npcID, dropIDList), playerID) + GameWorld.DebugLog(" auctionIDList=%s" % (auctionIDList), playerID) + elif ChConfig.IsGameBoss(npcData): GameWorld.ErrLog("Boss没有掉落物品,NPCID=%s" % (npcID), dropPlayer.GetPlayerID()) - return dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue - -def __GetFBGradeColorStarRateList(color, colorStarRateList, gradeColorStarRateDict, curGrade): - # {(颜色,星级):[D级影响概率, ..., S级影响概率], ...} - newRateList = [] - commKey = (color, 0) # 代表都影响 - for i, rateInfo in enumerate(colorStarRateList): - rate, star = rateInfo - - if i == 0: - srcRate = rate - else: - srcRate = rate - colorStarRateList[i - 1][0] - - key = (color, star) - if not star: - newRate = srcRate - elif key in gradeColorStarRateDict: - starRateList = gradeColorStarRateDict[key] - starRate = 10000 if (curGrade <= 0 or curGrade > len(starRateList)) else starRateList[curGrade - 1] - newRate = int(srcRate * starRate / 10000.0) - elif commKey in gradeColorStarRateDict: - starRateList = gradeColorStarRateDict[commKey] - starRate = 10000 if (curGrade <= 0 or curGrade > len(starRateList)) else starRateList[curGrade - 1] - newRate = int(srcRate * starRate / 10000.0) - else: - newRate = srcRate - - if not newRateList: - newRateList.append([newRate, star]) - else: - newRateList.append([newRateList[-1][0] + newRate, star]) - - #GameWorld.DebugLog(" 副本评级影响颜色品质星级: color=%s,源=%s" % (color, colorStarRateList)) - #GameWorld.DebugLog(" curGrade=%s,gradeColorStarRateDict=%s" % (curGrade, gradeColorStarRateDict)) - #GameWorld.DebugLog(" newRateList=%s" % (newRateList)) - return newRateList - -def __GetNPCDropItemBindInfo(mapID, isGameBoss, dropIDList, dropEquipIDDict): - ## 获取NPC掉落物品绑定信息字典 - mapID = FBCommon.GetRecordMapID(mapID) - - unBindEquipPlaceKeyList = IpyGameDataPY.GetFuncCfg("EquipDropBindingRule", 3) # 非绑定部位集合key [部位集合key1, 部位集合key2, ...] - defaultMaxBindColor = IpyGameDataPY.GetFuncCfg("EquipDropBindingRule", 2) # 默认绑定最高颜色 - - bossDropBindIDList = IpyGameDataPY.GetFuncCfg("BossDropBindingRule", 1) # Boss掉落绑定的物品ID: [ID1, ID2, ...] - monsterDropNoBindIDList = IpyGameDataPY.GetFuncCfg("MonsterDropBindingRule", 1) # 小怪掉落不绑定的物品ID: [ID1, ID2, ...] - - mapDropBindDict = IpyGameDataPY.GetFuncCfg("MapDropBindRule", 1) # 地图掉落是否绑定:{MapID:是否绑定, ...} - mapDropItemNoBindDict = IpyGameDataPY.GetFuncCfg("MapDropItemNoBind", 1) # 地图掉落不绑定物品ID:{MapID:[ID1, ID2, ...],...} - mapDropItemBindDict = IpyGameDataPY.GetFuncCfg("MapDropItemBind", 1) # 地图掉落绑定物品ID:{MapID:[ID1, ID2, ...],...} - - mapDropItemIsBind = mapDropBindDict.get(mapID, None) - mapDropItemNoBindList = mapDropItemNoBindDict.get(mapID, []) - mapDropItemBindList = mapDropItemBindDict.get(mapID, []) - - dropIDBindDict = {} # 掉落物品ID绑定字典 {物品ID:是否绑定, ...} - for dropItemID in dropIDList: - if dropItemID in dropIDBindDict: - continue - - # 装备绑定规则判断 - if dropItemID in dropEquipIDDict: - color, placeKey = dropEquipIDDict[dropItemID] - isBind = placeKey not in unBindEquipPlaceKeyList and color <= defaultMaxBindColor - - # 非装备 - else: - if dropItemID in mapDropItemBindList: - isBind = True - elif dropItemID in mapDropItemNoBindList: - isBind = False - elif mapDropItemIsBind != None: - isBind = mapDropItemIsBind - elif isGameBoss: - isBind = dropItemID in bossDropBindIDList - else: - isBind = dropItemID not in monsterDropNoBindIDList - - dropIDBindDict[dropItemID] = int(isBind) - - return dropIDBindDict + return dropIDList, auctionIDList, dropMoneyCnt, moneyValue def __GetNPCDropDoCountChange(doCount, doCountRate, doCountAdd): ## 获取掉落执行次数变更结果,可能增加 或 减少 @@ -1355,10 +1233,10 @@ return dropItemIDList -def __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList, tagPlace=None): +def __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList): #存一个满足要求的所有的物品的列表 然后从当中随机选一个 - #注: 阶、颜色、星、职业、部位,这5个条件可确认唯一一件装备 - key = "%s_%s_%s" % (classLV, color, star) + #注: 阶、颜色、套装ID、职业、部位,这5个条件可确认唯一一件装备 + key = "%s_%s" % (classLV, color) if key in PyGameData.g_filterEquipDict: filterItemIDDict = PyGameData.g_filterEquipDict[key] @@ -1379,37 +1257,39 @@ continue if itemData.GetItemColor() != color: continue - #if itemData.GetEquipPlace() not in placeList: - # continue - if itemData.GetItemQuality() != star: - continue + suiteID = itemData.GetSuiteID() itemJob = itemData.GetJobLimit() / 100 itemPlace = itemData.GetEquipPlace() - filterItemIDDict[(itemJob, itemPlace)] = itemData.GetItemTypeID() + itemID = itemData.GetItemTypeID() + if itemPlace not in filterItemIDDict: + filterItemIDDict[itemPlace] = [] + placeItemList = filterItemIDDict[itemPlace] + placeItemList.append([itemJob, suiteID, itemID]) PyGameData.g_filterEquipDict[key] = filterItemIDDict - GameWorld.Log("缓存掉落装备ID: classLV_color_star=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict)) + GameWorld.Log("缓存掉落装备ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict)) itemIDList = [] - for itemJobPlace, itemID in filterItemIDDict.items(): - itemJob, itemPlace = itemJobPlace - # 有职业限制的物品才需判断是否在可掉落的职业里 - if itemJob and itemJob not in itemJobList: + for itemPlace, placeItemList in filterItemIDDict.items(): + if placeList and itemPlace not in placeList: continue - if itemPlace not in placeList: - continue - if tagPlace != None and itemPlace != tagPlace: - continue - itemIDList.append(itemID) - + for itemInfo in placeItemList: + itemJob, suiteID, itemID = itemInfo + if itemJob and itemJobList and itemJob not in itemJobList: + continue + curIsSuit = suiteID > 0 + if curIsSuit != isSuit: + continue + itemIDList.append(itemID) + if not itemIDList: - GameWorld.ErrLog("找不到可掉落的装备ID: npcID=%s,classLV=%s,color=%s,star=%s,placeList=%s,tagPlace=%s,itemJobList=%s" - % (npcID, classLV, color, star, placeList, tagPlace, itemJobList)) + GameWorld.ErrLog("找不到可掉落的装备ID: npcID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s" + % (npcID, classLV, color, isSuit, placeList, itemJobList)) return itemIDList def __GetNPCPieRateEquipDrop(ipyDrop, doCnt, equipDropPlus): ## 获取NPC饼图掉率装备掉落信息 dropEquipInfoList = [] - pieRateDropList = ipyDrop.GetPieRateDrop() # [(概率,0),(概率,(阶,颜色,部位集合key)),...] + pieRateDropList = ipyDrop.GetPieRateDrop() # 饼图概率掉落信息 [(概率,0),(概率,(阶,颜色)),...] dropRateList = pieRateDropList if not equipDropPlus else GameWorld.GetPlusPieList(pieRateDropList, equipDropPlus) #GameWorld.DebugLog("掉落饼图概率: %s, equipDropPlus=%s" % (pieRateDropList, equipDropPlus)) #GameWorld.DebugLog("实际饼图概率: %s" % (dropRateList)) @@ -1423,10 +1303,8 @@ def __GetNPCIndepRateEquipDrop(ipyDrop, doCnt, equipDropPlus, curGrade=0): ## 获取NPC独立掉率装备掉落信息 npcID = ipyDrop.GetNPCID() - indepRateDict = ipyDrop.GetIndepRateDrop() # {(阶,颜色,部位集合key):概率,...} - #colorMaxDropCntDict = ipyDrop.GetIndepRateMaxDropCount() - #GameWorld.DebugLog("独立概率装备掉落处理: indepRateDict=%s,colorMaxDropCntDict=%s,equipDropPlus=%s" - # % (indepRateDict, colorMaxDropCntDict, equipDropPlus)) + indepRateDict = ipyDrop.GetIndepRateDrop() # 独立概率掉落信息 {(阶,颜色):概率,...} + #GameWorld.DebugLog("独立概率装备掉落处理: indepRateDict=%s,equipDropPlus=%s" % (indepRateDict, equipDropPlus)) gradeColorRateDict = {} fbGradeColorRateDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 1) #{npcID:{颜色:[D级影响概率, ..., S级影响概率], ...}, ...} if npcID in fbGradeColorRateDict: @@ -1454,19 +1332,7 @@ curDropCount += 1 if not curDropCount: continue - #掉落颜色对应件数上限提到外部,修改为作为掉落装备的公共限制条件 - #======================================================================================= - # if color in colorMaxDropCntDict: - # maxCount = colorMaxDropCntDict[color] - # dropCount = colorDropCntDict.get(color, 0) - # if dropCount >= maxCount: - # #GameWorld.DebugLog(" 已超过该颜色装备最大掉落数,不掉!color=%s,maxCount=%s" % (color, maxCount)) - # continue - # maxCanDropCount = maxCount - dropCount - # curDropCount = min(curDropCount, maxCanDropCount) - # colorDropCntDict[color] = dropCount + curDropCount - # #GameWorld.DebugLog(" maxCanDropCount=%s,curDropCount=%s" % (maxCanDropCount, curDropCount)) - #======================================================================================= + for _ in xrange(curDropCount): dropEquipInfoList.append(dropInfo) #GameWorld.DebugLog("独立概率装备掉落结果: doCnt=%s, %s" % (doCnt, dropEquipInfoList)) @@ -1500,15 +1366,17 @@ def GetKillCountDropItemList(curPlayer, npcID, needKillCount, killDropItemList): ## 获取击杀次数额外掉落 - dropRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCountDrop % npcID) - killCount = dropRecord / 10 - if dropRecord % 10: - #GameWorld.DebugLog("杀掉次数已经掉落过! npcID=%s,killCount=%s,dropRecord=%s" % (npcID, killCount, dropRecord), curPlayer.GetPlayerID()) + killCountValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_NPCKillCount % npcID) + killCountPri = killCountValue / 10000 + if killCountPri >= needKillCount: + #GameWorld.DebugLog("杀掉次数已经掉落过! npcID=%s,killCountValue=%s,dropRecord=%s" % (npcID, killCountValue, dropRecord), curPlayer.GetPlayerID()) return [] - killCount += 1 + killCountPri += 1 + updRecordValue = killCountPri * 10000 + killCountValue % 10000 + jobDropInfo = [] - if killCount >= needKillCount: + if killCountPri >= needKillCount: isJobLimit = 1 #[itemID,...] for dropItemID in killDropItemList: @@ -1522,12 +1390,11 @@ #GameWorld.DebugLog("非本职业可用,不掉落! dropItemID=%s" % dropItemID) continue jobDropInfo.append(dropItemID) - recordValue = killCount * 10 + 1 - #GameWorld.DebugLog("击杀次数必掉落! npcID=%s,needKillCount=%s,jobDropInfo=%s,killDropItemList=%s,recordValue=%s" - # % (npcID, needKillCount, jobDropInfo, killDropItemList, recordValue), curPlayer.GetPlayerID()) - else: - recordValue = killCount * 10 - PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCKillCountDrop % npcID, recordValue) + GameWorld.DebugLog("击杀次数必掉落! npcID=%s,needKillCount=%s,jobDropInfo=%s,killDropItemList=%s,updRecordValue=%s" + % (npcID, needKillCount, jobDropInfo, killDropItemList, updRecordValue), curPlayer.GetPlayerID()) + + PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_NPCKillCount % npcID, updRecordValue) + GameWorld.DebugLog("更新击杀次数比掉落值: killCountValue=%s,killCountPri=%s,updRecordValue=%s" % (killCountValue, killCountPri, updRecordValue), curPlayer.GetPlayerID()) return jobDropInfo ###################################################################### #--------------------------------------------------------------------- @@ -4104,7 +3971,7 @@ def __NPCSpecialDropItem(self, dropPlayer, ownerPlayerList, ipyDrop): '''特殊掉落 (私有特殊掉落 + 击杀次数特殊掉落), 支持摸怪 @return: None - @return: [[ownerPlayer, itemID, isBind, isDropInItemPack], ...] + @return: [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...] ''' curNPC = self.__Instance npcID = curNPC.GetNPCID() @@ -4116,7 +3983,21 @@ GameWorld.DebugLog("超过最大可掉落等级,不掉落物品,特殊掉落!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV)) return specDropItemList + auctionItemCanSell = ipyDrop.GetAucionItemCanSell() + # 击杀次数掉落算摸怪 + killCountDropInfo = ipyDrop.GetKillCountDropPri() + if killCountDropInfo: + for feelPlayer in self.__FeelPlayerList: + needKillCount, killDropItemList, isDropInItemPack = killCountDropInfo + killCountDropItemList = GetKillCountDropItemList(feelPlayer, npcID, needKillCount, killDropItemList) + for dropItemID in killCountDropItemList: + isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0 + specDropItemList.append([feelPlayer, dropItemID, isAuctionItem, isDropInItemPack]) + GameWorld.DebugLog("击杀次数必掉(可摸怪): npcID=%s,dropItemID=%s,needKillCount=%s,isDropInItemPack=%s,isAuctionItem=%s" + % (npcID, dropItemID, needKillCount, isDropInItemPack, isAuctionItem), feelPlayer.GetPlayerID()) + # 私有掉落 + isDropInItemPack = False fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3) if npcID in fbGradePriItemIDDropDict: gradePriItemIDDropDict = fbGradePriItemIDDropDict[npcID] @@ -4127,25 +4008,12 @@ priDropIDList += [priItemID] * priItemCount else: priDropIDList = ipyDrop.GetPriItemIDDrop() - - # 击杀次数掉落算摸怪 - killCountDropInfo = ipyDrop.GetKillCountDrop() - if killCountDropInfo: - for feelPlayer in self.__FeelPlayerList: - needKillCount, isDropInItemPack, isBind, killDropItemList = killCountDropInfo - killCountDropItemList = GetKillCountDropItemList(feelPlayer, npcID, needKillCount, killDropItemList) - for dropItemID in killCountDropItemList: - specDropItemList.append([feelPlayer, dropItemID, isBind, isDropInItemPack]) - GameWorld.DebugLog("击杀次数必掉(可摸怪): npcID=%s,dropItemID=%s,needKillCount=%s,isDropInItemPack=%s,isBind=%s" - % (npcID, dropItemID, needKillCount, isDropInItemPack, isBind), feelPlayer.GetPlayerID()) - - # 私有掉落算归属 - for ownerPlayer in ownerPlayerList: - - for dropItemID in priDropIDList: - specDropItemList.append([ownerPlayer, dropItemID, 1, False]) # 默认绑定 + for dropItemID in priDropIDList: + isAuctionItem = 1 if auctionItemCanSell and IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", dropItemID) else 0 + for ownerPlayer in ownerPlayerList: + specDropItemList.append([ownerPlayer, dropItemID, isAuctionItem, isDropInItemPack]) # 默认绑定 #GameWorld.DebugLog("私有物品掉落: dropItemID=%s" % dropItemID, ownerPlayer.GetPlayerID()) - + return specDropItemList def __NPCDropItemByPlayers(self, dropPlayerList, mapID, ipyDrop): @@ -4156,13 +4024,13 @@ return #GameWorld.DebugLog("NPC多玩家混合掉落: dropPlayerCount=%s" % len(dropPlayerList)) - dropItemBindDict = {} + auctionItemIDList = [] dropItemList = [] for dropPlayer in dropPlayerList: dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ipyDrop=ipyDrop) if not dropInfo: continue - dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue = dropInfo + dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo moneyID = self.__GetDropMoneyModelID(moneyValue) if dropMoneyCnt: dropIDList += [moneyID] * dropMoneyCnt @@ -4171,7 +4039,7 @@ #GameWorld.DebugLog(" dropPlayerID=%s,dropIDList=%s" % (dropPlayerID, dropIDList)) for dropID in dropIDList: dropItemList.append([dropID, dropPlayerID]) - dropItemBindDict.update(dropIDBindDict) + auctionItemIDList += auctionIDList #打乱物品顺序 random.shuffle(dropItemList) @@ -4192,8 +4060,8 @@ itemID, ownerID = dropItemList[index] index += 1 itemCnt = moneyValue if itemID == moneyID else 1 - isBind = dropItemBindDict.get(itemID, 1) - curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isBind, dropPlayer) + iaAuctionItem = itemID in auctionItemIDList + curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, iaAuctionItem, dropPlayer) if not curItem: continue self.__MapCreateItem(curItem, resultX, resultY, ChConfig.Def_NPCHurtTypePlayer, ownerID) @@ -4229,17 +4097,17 @@ # dropPlayerList = GameLogic_MunekadoTrial.GetCanDropPlayerList() # return self.__NPCDropItemByPlayers(dropPlayerList, mapID, ipyDrop) - dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue = [], {}, 0, 0 + dropIDList, auctionIDList, dropMoneyCnt, moneyValue = [], [], 0, 0 dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList, ipyDrop, False) if dropInfo: - dropIDList, dropIDBindDict, dropMoneyCnt, moneyValue = dropInfo + dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo moneyID = self.__GetDropMoneyModelID(moneyValue) if moneyID and dropMoneyCnt: dropIDList += [moneyID] * dropMoneyCnt specItemSign = "SpecItem" - playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isBind, isDropInItemPack], ...] 私有特殊掉落 + 击杀次数特殊掉落 + playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...] 私有特殊掉落 + 击杀次数特殊掉落 dropIDList += [specItemSign] * len(playerSpecDropList) if len(dropIDList) > 5: @@ -4272,21 +4140,21 @@ if not playerSpecDropList: continue itemCnt = 1 - ownerPlayer, itemID, isBind, isDropInItemPack = playerSpecDropList[0] + ownerPlayer, itemID, isAuctionItem, isDropInItemPack = playerSpecDropList[0] ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, ownerPlayer.GetPlayerID() playerSpecDropList = playerSpecDropList[1:] else: ownerPlayer = dropPlayer ownerType, ownerID = hurtType, hurtID itemCnt = moneyValue if itemID == moneyID else 1 - isBind = dropIDBindDict.get(itemID, 1) - - curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isBind, dropPlayer) + isAuctionItem = itemID in auctionIDList + + curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, isAuctionItem, dropPlayer) if not curItem: continue if mapID == ChConfig.Def_FBMapID_GatherSoul:#聚魂副本特殊处理 - GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isBind) + GameLogic_GatherSoul.KillGatherSoulNPCDropAward(itemID, itemCnt, isAuctionItem) dropItemDataStr = ChItem.GetMapDropItemDataStr(curItem) self.SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr) curItem.Clear() @@ -5206,8 +5074,6 @@ def __CreateDropItem(self, curNPC, itemID, count, isAuctionItem, dropPlayer): ## 创建掉落的物品 - if IpyGameDataPY.GetIpyGameDataNotLog("AuctionItem", itemID): - isAuctionItem = True # 掉落的暂时默认都是拍品 curItem = ItemControler.GetOutPutItemObj(itemID, count, isAuctionItem, curPlayer=dropPlayer) if not curItem: return @@ -5455,8 +5321,8 @@ giveItemList = collectNPCIpyData.GetCollectAward() if giveItemList: - itemID, itemCount, isBind = giveItemList - ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, 0, [IPY_GameWorld.rptItem]) + itemID, itemCount, isAuctionItem = giveItemList + ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem]) #采集成就 PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, collectCnt, [npcID]) -- Gitblit v1.8.0