From 65c6db4b2dfda4cd184cc5939ca6f923180c7f6d Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 18 六月 2019 17:43:21 +0800
Subject: [PATCH] 7334 【后端】【2.0】封魔坛双倍掉落规则(去除第一名双倍奖励,增加第一名额外奖励规则;宝箱增加装备筛选规则)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py                     |   71 +++++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py |   17 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                |   29 ++++++++-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                                |    8 +-
 PySysDB/PySysDBPY.h                                                                                                 |    7 ++
 5 files changed, 122 insertions(+), 10 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 0a3ab7a..881af95 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -965,6 +965,7 @@
 {
 	DWORD		_NPCID;	//ID
 	BYTE		LineID;
+	list		OwnerAwardItemEx;	//第一名额外奖励物品[[itemID,个数,是否拍品], ...]
 };
 
 //副本鼓舞表
@@ -1076,6 +1077,12 @@
 	BYTE		MoneyType;	//货币类型
 	DWORD		MoneyCount;	//货币数量
 	list		NeedNotifyItemList;	//需要广播的物品ID列表
+	BYTE		IsDropJobSelf;	//是否只掉落本职业
+	list		PieRateDrop;	//饼图概率掉落信息 [(概率,0),(概率,(阶,颜色)),...]
+	BYTE		PieRateDoCnt;	//饼图概率执行次数
+	dict		IndepRateDrop;	//独立概率掉落信息 {(阶,颜色):概率,...}
+	dict		EquipColorSuitInfo;	//装备颜色对应套装概率 {颜色:套装概率, ...}
+	dict		EquipPartKeyRateInfo;	//装备部位集合信息 {(颜色,是否套装):部位集合key, ...}
 };
 
 //VIP杀怪加攻击表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
index 4716952..648b076 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
@@ -457,6 +457,9 @@
 def GiveSealDemonAward(curPlayer, lineID, rank, isMail=False, isClientSend=False, dropItemMapInfo=[]):
     newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')
     isNewbieLine = lineID in newbielineList
+    sealDemonIpyData = GetSealDemonIpyData(lineID)
+    if not sealDemonIpyData:
+        return {}
     prizeMultiple = 1
     addCnt = 1
     if isNewbieLine:
@@ -467,16 +470,18 @@
     elif isClientSend:
         return {}
     else:
-        prizeMultiple = 2 if rank == 1 else 1 # 第一名执行双倍掉落奖励,其他一次
+        #prizeMultiple = 2 if rank == 1 else 1 # 第一名执行双倍掉落奖励,其他一次
+        prizeMultiple = 1 # 去除第一名双倍逻辑,改为放在额外奖励产出
         isDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)
         if isDouble:
             addCnt = 2
     equipList = []
     prizeItemDict ={}
     bossID = CurFBLineBOSSID(lineID)
+    extraItemList = sealDemonIpyData.GetOwnerAwardItemEx() * addCnt if rank == 1 else []
     #for _ in xrange(addCnt):
     jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt}, 
-                                                                        mailTypeKey="SealDemonMail", isMail=isMail, prizeMultiple=prizeMultiple, 
+                                                                        mailTypeKey="SealDemonMail", isMail=isMail, extraItemList=extraItemList, prizeMultiple=prizeMultiple, 
                                                                         dropItemMapInfo=dropItemMapInfo,isVirtualDrop=isClientSend)
     for jsonItem in jsonItemList:
         if 'UserData' in jsonItem:
@@ -607,6 +612,14 @@
     bossID = ipyData.GetNPCID()
     return bossID
 
+def GetSealDemonIpyData(lineID= -1):
+    #该分线刷的BOSSID
+    if lineID == -1:
+        lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
+    if lineID == -1:
+        return
+    return IpyGameDataPY.GetIpyGameDataByCondition('SealDemon', {'LineID':lineID})
+
 ##玩家死亡.
 # @param curPlayer:死亡的玩家 
 # @param tick 时间戳
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e63df06..df473b5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -778,6 +778,7 @@
                 "SealDemon":(
                         ("DWORD", "NPCID", 1),
                         ("BYTE", "LineID", 0),
+                        ("list", "OwnerAwardItemEx", 0),
                         ),
 
                 "FbEncourage":(
@@ -865,6 +866,12 @@
                         ("BYTE", "MoneyType", 0),
                         ("DWORD", "MoneyCount", 0),
                         ("list", "NeedNotifyItemList", 0),
+                        ("BYTE", "IsDropJobSelf", 0),
+                        ("list", "PieRateDrop", 0),
+                        ("BYTE", "PieRateDoCnt", 0),
+                        ("dict", "IndepRateDrop", 0),
+                        ("dict", "EquipColorSuitInfo", 0),
+                        ("dict", "EquipPartKeyRateInfo", 0),
                         ),
 
                 "VIPKillNPC":(
@@ -3029,11 +3036,13 @@
     
     def __init__(self):
         self.NPCID = 0
-        self.LineID = 0
+        self.LineID = 0
+        self.OwnerAwardItemEx = []
         return
         
     def GetNPCID(self): return self.NPCID # ID
-    def GetLineID(self): return self.LineID
+    def GetLineID(self): return self.LineID
+    def GetOwnerAwardItemEx(self): return self.OwnerAwardItemEx # 第一名额外奖励物品[[itemID,个数,是否拍品], ...]
 
 # 副本鼓舞表
 class IPY_FbEncourage():
@@ -3200,7 +3209,13 @@
         self.JobItemList = []
         self.MoneyType = 0
         self.MoneyCount = 0
-        self.NeedNotifyItemList = []
+        self.NeedNotifyItemList = []
+        self.IsDropJobSelf = 0
+        self.PieRateDrop = []
+        self.PieRateDoCnt = 0
+        self.IndepRateDrop = {}
+        self.EquipColorSuitInfo = {}
+        self.EquipPartKeyRateInfo = {}
         return
         
     def GetChestsItemID(self): return self.ChestsItemID # 宝箱物品ID
@@ -3215,7 +3230,13 @@
     def GetJobItemList(self): return self.JobItemList # 职业物品列表
     def GetMoneyType(self): return self.MoneyType # 货币类型
     def GetMoneyCount(self): return self.MoneyCount # 货币数量
-    def GetNeedNotifyItemList(self): return self.NeedNotifyItemList # 需要广播的物品ID列表
+    def GetNeedNotifyItemList(self): return self.NeedNotifyItemList # 需要广播的物品ID列表
+    def GetIsDropJobSelf(self): return self.IsDropJobSelf # 是否只掉落本职业
+    def GetPieRateDrop(self): return self.PieRateDrop # 饼图概率掉落信息 [(概率,0),(概率,(阶,颜色)),...]
+    def GetPieRateDoCnt(self): return self.PieRateDoCnt # 饼图概率执行次数
+    def GetIndepRateDrop(self): return self.IndepRateDrop # 独立概率掉落信息 {(阶,颜色):概率,...}
+    def GetEquipColorSuitInfo(self): return self.EquipColorSuitInfo # 装备颜色对应套装概率 {颜色:套装概率, ...}
+    def GetEquipPartKeyRateInfo(self): return self.EquipPartKeyRateInfo # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...}
 
 # VIP杀怪加攻击表
 class IPY_VIPKillNPC():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py
index 8d37733..aa034f3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_Chests.py
@@ -23,9 +23,11 @@
 import IPY_GameWorld
 import ItemControler
 import PlayerRune
+import NPCCommon
 import ChConfig
 import ChItem
 
+import random
 import math
 #---------------------------------------------------------------------
 
@@ -199,6 +201,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()
@@ -249,6 +256,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 +299,69 @@
             
     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)
+    
+    placeKeyListDict = IpyGameDataPY.GetFuncCfg("EquipDropPartSets", 1)
+    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
+        if placeKey not in placeKeyListDict:
+            GameWorld.ErrLog("部位集合key不存在!chestsItemID=%s,placeKey=%s" % (chestsItemID, placeKey))
+            continue
+        placeList = placeKeyListDict[placeKey]
+        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:
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 a35eba0..c7a3e33 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -1371,7 +1371,7 @@
                 
     return dropItemIDList
 
-def __GetEquipIDList(npcID, classLV, color, isSuit, placeList, itemJobList):
+def __GetEquipIDList(findID, classLV, color, isSuit, placeList, itemJobList, findType="NPC"):
     #存一个满足要求的所有的物品的列表 然后从当中随机选一个
     #注: 阶、颜色、套装ID、职业、部位,这5个条件可确认唯一一件装备
     key = "%s_%s" % (classLV, color)
@@ -1404,7 +1404,7 @@
                     placeItemList = filterItemIDDict[itemPlace]
                     placeItemList.append([itemJob, suiteID, itemID])
         PyGameData.g_filterEquipDict[key] = filterItemIDDict
-        GameWorld.Log("缓存掉落装备ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict))
+        GameWorld.Log("缓存产出装备ID: classLV_color=%s, %s, %s" % (key, filterItemIDDict, PyGameData.g_filterEquipDict))
         
     itemIDList = []
     for itemPlace, placeItemList in filterItemIDDict.items():
@@ -1420,8 +1420,8 @@
             itemIDList.append(itemID)
             
     if not itemIDList:
-        GameWorld.ErrLog("找不到可掉落的装备ID: npcID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s" 
-                         % (npcID, classLV, color, isSuit, placeList, itemJobList))
+        GameWorld.ErrLog("找不到可产出的装备ID: %sID=%s,classLV=%s,color=%s,isSuit=%s,placeList=%s,itemJobList=%s" 
+                         % (findType, findID, classLV, color, isSuit, placeList, itemJobList))
     return itemIDList
 
 def __GetNPCPieRateEquipDrop(ipyDrop, doCnt, equipDropPlus):

--
Gitblit v1.8.0