From 5b97f700fa5613e07e4e0954b983e278eae8e432 Mon Sep 17 00:00:00 2001
From: xdh <xiefantasy@qq.com>
Date: 星期一, 19 十一月 2018 09:59:37 +0800
Subject: [PATCH] 860312 防范全服限购报错

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py |  489 ++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 385 insertions(+), 104 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 59b7260..d38537a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -52,6 +52,7 @@
 import PlayerMagicWeapon
 import PlayerBossReborn
 import PlayerFairyCeremony
+import FamilyRobBoss
 import IpyGameDataPY
 import PyGameData
 import PlayerTeam
@@ -71,9 +72,10 @@
 NPCAttr_ParamDict, # 过程参数公式
 NPCAttr_AttrStrengthenList, # 等级成长属性公式
 NPCAttr_PlayerCntCoefficient, # 地图人数对应属性额外成长系数 {mapID:{"属性名":{组队进入人数:系数, ...}, ...}, ...}
+NPCAttr_NPCPlayerCntCoefficient, # NPC特殊成长人数对应属性额外成长系数 {npcID:{"属性名":{人数:系数, ...}, ...}, ...}, 优先级大于地图人数系数
 NPCAttr_DynNPCLVMap, # 动态等级的地图ID列表,默认已刷新出来的NPC等级不会再变更,下次刷出来的怪物等级变更 [地图ID, ...]
 NPCAttr_DynPCCoefficientMap, # 动态人数系数的地图ID {地图ID:是否马上刷新属性, ...}
-) = range(5)
+) = range(6)
 
 #---------------------------------------------------------------------
 ##NPC初始化->出生调用
@@ -104,6 +106,7 @@
     return curNPC.GetLV()
 
 def GetRealmLV(curNPC): return curNPC.GetMAtkMin()      # NPC表中此字段含义改成境界等级
+def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV)      # NPC表中此字段含义改成境界等级
 def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # 风防代表是否等级压制
 def GetSuppressFightPower(curNPC): return curNPC.GetThunderDef() # 雷防代表压制战力
 def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(value)
@@ -112,6 +115,7 @@
 def GetFaction(curNPC): return curNPC.GetCountry()
 def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
 def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
+def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
 def GetSkillEnhance(curNPC): return curNPC.GetWindAtk() # 风攻代表NPC 《普攻》 的技能附加伤害固定值
 def GetNPCSeries(curNPC): return curNPC.GetPoisionDef() # 毒防字段代表NPC系,按二进制位区分
 
@@ -137,11 +141,14 @@
     gameFB = GameWorld.GetGameFB()
     
     if strengthenIpyData.GetIsStrengthenByPlayerCount():
-        strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)
-        if not strengthenPlayerCnt:
-            GameWorld.ErrLog("NPC配置了按玩家人数成长类型,但是无法获取到对应的玩家人数!npcID=%s" % (npcID))
-            return
-                   
+        if FamilyRobBoss.IsHorsePetRobBoss(npcID):
+            strengthenPlayerCnt = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_HorsePetRobBossPlayerCount)
+        else:
+            strengthenPlayerCnt = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenPlayerCnt)
+            if not strengthenPlayerCnt:
+                GameWorld.ErrLog("NPC配置了按玩家人数成长类型,但是无法获取到对应的玩家人数!npcID=%s" % (npcID))
+                return
+            
     lvStrengthenType = strengthenIpyData.GetLVStrengthenType()
     # 根据世界等级
     if lvStrengthenType == 3:
@@ -153,6 +160,9 @@
     elif lvStrengthenType == 1:
         strengthenLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenAverageLV)
         
+    if strengthenIpyData.GetCmpNPCBaseLV():
+        strengthenLV = max(strengthenLV, curNPC.GetLV())
+    
     if lvStrengthenType in [1, 2] and not strengthenLV:
         GameWorld.ErrLog("NPC配置了成长等级类型,但是无法获取到对应的成长等级值!npcID=%s,lvStrengthenType=%s" % (npcID, lvStrengthenType))
         return
@@ -216,6 +226,7 @@
     paramDict = attrStrengthenInfo[NPCAttr_ParamDict] # 过程参数公式字典
     attrStrengthenList = attrStrengthenInfo[NPCAttr_AttrStrengthenList] # 属性成长公式字典
     playerCntCoefficient = attrStrengthenInfo[NPCAttr_PlayerCntCoefficient] # 人数系数
+    npcIDPlayerCntCoefficient = attrStrengthenInfo[NPCAttr_NPCPlayerCntCoefficient] # 特殊NPC人数系数
     baseMaxHP = npcData.GetHPEx() * ShareDefine.Def_PerPointValue + npcData.GetHP()
     
     if strengthenLV:
@@ -290,9 +301,14 @@
     if strengthenPlayerCnt:
         mapID = GameWorld.GetMap().GetMapID()
         dataMapID = FBCommon.GetRecordMapID(mapID)
+        formulaKey = "MapCoefficient_%s" % mapID
         playerCntAttrCoefficient = playerCntCoefficient.get(mapID, {})
         if not playerCntAttrCoefficient and dataMapID in playerCntCoefficient:
             playerCntAttrCoefficient = playerCntCoefficient[dataMapID]
+            formulaKey = "MapCoefficient_%s" % dataMapID
+        if npcID in npcIDPlayerCntCoefficient:
+            playerCntAttrCoefficient = npcIDPlayerCntCoefficient[npcID]
+            formulaKey = "NPCCoefficient_%s" % npcID
         for attrKey, coefficientDict in playerCntAttrCoefficient.items():
             if attrKey in attrDict:
                 attrValue = attrDict[attrKey]
@@ -303,7 +319,15 @@
                 if not hasattr(npcData, attrFuncName):
                     continue
                 attrValue = getattr(npcData, attrFuncName)()
-            coefficient = GameWorld.GetDictValueByRangeKey(coefficientDict, strengthenPlayerCnt, 1)
+            # 按字典配置
+            if isinstance(coefficientDict, dict):
+                coefficient = GameWorld.GetDictValueByRangeKey(coefficientDict, strengthenPlayerCnt, 1)
+            # 按公式配置
+            elif isinstance(coefficientDict, str):
+                formulaKey = "%s_%s" % (formulaKey, attrKey)
+                coefficient = eval(FormulaControl.GetCompileFormula(formulaKey, coefficientDict))
+            else:
+                coefficient = 1
             attrDict[attrKey] = int(attrValue * coefficient)
             
     #GameWorld.DebugLog("计算NPC属性成长: npcID=%s,strengthenLV=%s,strengthenPlayerCnt=%s,baseMaxHP=%s,attrDict=%s" 
@@ -822,13 +846,28 @@
     tagPlaceSortList.sort() # 升序排序
     tagPlaceSortList2.sort() # 升序排序
     if isKillCountDropEquipEx:
-        GameWorld.DebugLog("都不满足目标装备的优先级信息: npcID=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, tagPlaceSortList), playerID)
-        GameWorld.DebugLog("部分满足目标装备的优先级信息: npcID=%s, 颜色,阶,星,评分,部位,职业=%s" % (npcID, tagPlaceSortList2), playerID)
-    tagPlaceSortList += tagPlaceSortList2
-    if tagPlaceSortList:
-        tagPlace = tagPlaceSortList[0][-2]
-        tagJob = tagPlaceSortList[0][-1]
-        
+        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)
+        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)
+            
     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)
@@ -1080,12 +1119,18 @@
             if len(jobItemList) < job:
                 GameWorld.ErrLog("职业物品集合key没有配置对应职业ID: npcID=%s,jobItemKey=%s,job=%s" % (npcID, jobItemKey, job))
                 continue
+            mustDropCount = dropRate / Def_NPCMaxDropRate
+            dropRate = dropRate % Def_NPCMaxDropRate # 基础概率
+            canDropCount = mustDropCount
             doCnt = ItemKeyMaxDropCountDict.get(jobItemKey, 1) # 默认1个
             doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)
             for _ in xrange(doCnt):
                 if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):
                     continue
-                jobItemID = jobItemList[job - 1]
+                canDropCount += 1
+                
+            jobItemID = jobItemList[job - 1]
+            for _ in xrange(canDropCount):
                 dropItemIDList.append(jobItemID)
                 #GameWorld.DebugLog("掉落自身职业指定物品ID: jobItemKey=%s,jobItemID=%s" % (jobItemKey, jobItemID))
                 
@@ -1102,11 +1147,17 @@
             # 在只掉本职业里的不处理
             if jobItemKey in ItemKeyDropRateJobDict:
                 continue
+            mustDropCount = dropRate / Def_NPCMaxDropRate
+            dropRate = dropRate % Def_NPCMaxDropRate # 基础概率
+            canDropCount = mustDropCount
             doCnt = ItemKeyMaxDropCountDict.get(jobItemKey, 1) # 默认1个
             doCnt = __GetNPCDropDoCountChange(doCnt, doCountRate, doCountAdd)
             for _ in xrange(doCnt):
                 if not GameWorld.CanHappen(dropRate, maxRate=Def_NPCMaxDropRate):
                     continue
+                canDropCount += 1
+                
+            for _ in xrange(canDropCount):
                 randJobItemID = random.choice(jobItemList)
                 dropItemIDList.append(randJobItemID)
                 #GameWorld.DebugLog("掉落随机职业指定物品ID: jobItemKey=%s,randJobItemID=%s" % (jobItemKey, randJobItemID))
@@ -1175,6 +1226,48 @@
         msgInfo = str([itemID, updKilledCnt])
         GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalDropRate", msgInfo, len(msgInfo))
          
+    # 4. 指定全服击杀次数必掉,算额外掉落
+    globalKillDropDict = IpyGameDataPY.GetFuncEvalCfg("GlobalDropCD", 2) # {NPCID:{击杀次数:[是否本职业, {物品ID:个数, ...}, [[随机物品ID,个数], ...]]}, ...}
+    if npcID in globalKillDropDict:
+        killCountDropDict = globalKillDropDict[npcID]
+        updNPCKilledCount = min(gw.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_NPCKilledCount % npcID) + 1, ShareDefine.Def_UpperLimit_DWord)
+        GameWorld.Log("更新全服击杀次数:npcID=%s, %s" % (npcID, updNPCKilledCount))
+        # 通知GameServer记录
+        msgInfo = str([npcID, updNPCKilledCount])
+        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalKillCount", msgInfo, len(msgInfo))
+        if updNPCKilledCount in killCountDropDict:
+            isJobLimit, itemIDCountDict, randItemIDCountList = killCountDropDict[updNPCKilledCount]
+            for itemID, itemCount in itemIDCountDict.items():
+                if isJobLimit:
+                    itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
+                    if not itemData:
+                        continue
+                    itemJob = itemData.GetJobLimit() / 100
+                    if itemJob and itemJob != curPlayer.GetJob():
+                        # 非本职业可用,不掉落
+                        GameWorld.DebugLog("全服击杀次数必掉,非本职业可用,不掉落! itemID=%s" % itemID)
+                        continue
+                dropItemIDList += [itemID] * itemCount
+                GameWorld.Log("全服击杀次数必掉物品: itemID=%s,itemCount=%s" % (itemID, itemCount))
+            if randItemIDCountList:
+                if isJobLimit:
+                    randJobItemList = []
+                    for rItemID, rItemCount in randItemIDCountList:
+                        itemData = GameWorld.GetGameData().GetItemByTypeID(rItemID)
+                        if not itemData:
+                            continue
+                        itemJob = itemData.GetJobLimit() / 100
+                        if itemJob and itemJob != curPlayer.GetJob():
+                            # 非本职业可用,不掉落
+                            GameWorld.DebugLog("全服击杀次数必掉随机,非本职业可用,不掉落! rItemID=%s" % rItemID)
+                            continue
+                        randJobItemList.append([rItemID, rItemCount])
+                    randItemID, randItemCount = random.choice(randJobItemList)
+                else:
+                    randItemID, randItemCount = random.choice(randItemIDCountList)
+                dropItemIDList += [randItemID] * randItemCount
+                GameWorld.Log("全服击杀次数必掉随机物品: randItemID=%s,randItemCount=%s" % (randItemID, randItemCount))
+                
     return dropItemIDList
 
 def __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList, tagPlace=None):
@@ -1917,11 +2010,15 @@
             #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典
             GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
         
+            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
+                FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC)
+        ChNPC.OnNPCSetDead(curNPC)
+        
     
     # 清除队伍成员伤血列表
     AttackCommon.ClearTeamPlayerHurtValue(curNPC)
     # 清除自定义伤血列表
-    BossHurtMng.ClearHurtValueList(curNPC)
+    #BossHurtMng.ClearHurtValueList(curNPC)
 
     # C++设置npc死亡
     curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),
@@ -1955,6 +2052,9 @@
         self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
         self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
         self.__FeelPlayerList = [] # 所有摸怪玩家列表,处理任务及某些逻辑用
+        
+        self.__OwnerHurtType = 0
+        self.__OwnerHurtID = 0
         return
     #---------------------------------------------------------------------
     ## 移动到某一个点的附近点
@@ -2485,7 +2585,7 @@
             self.__AddAngryValue(npcAngry, curObjID, curObjType, plusAngryValue, canPile)
         
         #激活呆滞的NPC
-        if curNPC.GetHP() > 0 and not curNPC.GetIsNeedProcess() :
+        if GameObj.GetHP(curNPC) > 0 and not curNPC.GetIsNeedProcess() :
             curNPC.SetIsNeedProcess(True)
 
         
@@ -2800,6 +2900,7 @@
     
     def __GetTeamHurtNPCPlayerIDList(self, refreshPoint, teamID, tick):
         
+        curNPC = self.__Instance
         teamHurtPlayerIDList = []
         # 如果没有在线队员在有效范围内,则进一步判断离线队员是否有伤血保护中的
         playerMgr = GameWorld.GetPlayerManager()
@@ -2820,7 +2921,8 @@
                         continue
                     
                 #if curTeamPlayer.GetHP() > 0 and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
-                if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
+                if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
+                    and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False):
                     #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID()))
                     teamHurtPlayerIDList.append(playerID)
             else:
@@ -3009,10 +3111,13 @@
         curNPC = self.__Instance
         #清除状态
         self.__ClearNPCAllState(False)
-        #初始化召唤兽
-        self.__InitNPCSummon()
-        #重置技能CD
-        self.__NormalNPCInItCD()
+        #只在重生或者满血的状态下才重置以下内容
+        if isReborn or GameObj.GetHP(curNPC) >= GameObj.GetMaxHP(curNPC):
+            #初始化召唤兽
+            self.__InitNPCSummon()
+            #重置技能CD
+            self.__NormalNPCInItCD()
+            
         #重刷属性
         self.RefreshNPCState(isReborn=isReborn)
         #通知血量, 复活的情况不通知血量,由NPC出现包通知
@@ -3330,6 +3435,9 @@
                 GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'GameWorldBossState',
                                                             '%s' % (msgList), len(str(msgList)))
                 
+                if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
+                    FamilyRobBoss.FamilyOwnerBossOnReborn(curNPC)
+                    
         # 检查是否有光环, 在重生时处理,不然可能导致有些无战斗逻辑的怪物无法套上光环buff
         skillManager = curNPC.GetSkillManager()
         for index in xrange(skillManager.GetSkillCount()):
@@ -3707,7 +3815,7 @@
         #=====================================================================================================
         
         #boss伤血排行榜击杀逻辑
-        BossHurtMng.BossOnKilled(curNPC)
+        #BossHurtMng.BossOnKilled(curNPC)
         
         #掉落需要用到摸怪,所以在处理掉落奖励之前设置
         self.__SetFeelNPCPlayerList()
@@ -3723,6 +3831,8 @@
         # 记录boss击杀信息的NPC
         bossIpyData = IpyGameDataPY.GetIpyGameDataListNotLog('BOSSInfo', npcID)
         if bossIpyData:
+            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
+                killerName = FamilyRobBoss.FamilyOwnerBossOnKilled(curNPC, self.__OwnerHurtID)
             #KillerJob = 0 if not self.__Killer else self.__Killer.GetJob()
             GameServer_KillGameWorldBoss(curNPC.GetNPCID(), killerName, 0)
         #===========================================================================================
@@ -3809,7 +3919,7 @@
                 return moneyID
         return moneyItemList[-1][1]
     
-    def __NPCSpecialDropItem(self, ownerPlayerList, ipyDrop):
+    def __NPCSpecialDropItem(self, dropPlayer, ownerPlayerList, ipyDrop):
         '''特殊掉落 (私有特殊掉落 + 击杀次数特殊掉落), 支持摸怪
         @return: None
         @return: [[ownerPlayer, itemID, isBind, isDropInItemPack], ...]
@@ -3817,6 +3927,12 @@
         curNPC = self.__Instance
         npcID = curNPC.GetNPCID()
         specDropItemList = []
+        
+        playerLV = dropPlayer.GetLV()
+        maxDropLV = ipyDrop.GetMaxDropLV()
+        if maxDropLV and playerLV > maxDropLV:
+            GameWorld.DebugLog("超过最大可掉落等级,不掉落物品,特殊掉落!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))
+            return specDropItemList
         
         # 私有掉落
         fbGradePriItemIDDropDict = IpyGameDataPY.GetFuncEvalCfg("FBGradeEquipDropRate", 3)
@@ -3915,10 +4031,16 @@
         npcID = curNPC.GetNPCID()
         mapID = GameWorld.GetMap().GetMapID()
         mapID = FBCommon.GetRecordMapID(mapID)
+        isGameBoss = ChConfig.IsGameBoss(curNPC)
+        if isGameBoss:
+            GameWorld.Log("NPC开始掉落: npcID=%s,dropPlayerID=%s" % (npcID, dropPlayer.GetPlayerID()), dropPlayer.GetPlayerID())
         if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
             return
         ipyDrop = GetNPCDropIpyData(npcID)
         if not ipyDrop:
+            if isGameBoss:
+                curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+                GameWorld.ErrLog("取不到NPC掉落信息!npcID=%s,curWorldLV=%s" % (npcID, curWorldLV))
             return
         
         #if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
@@ -3935,13 +4057,17 @@
             dropIDList += [moneyID] * dropMoneyCnt
             
         specItemSign = "SpecItem"
-        playerSpecDropList = self.__NPCSpecialDropItem(ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isBind, isDropInItemPack], ...]  私有特殊掉落 + 击杀次数特殊掉落
+        playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isBind, isDropInItemPack], ...]  私有特殊掉落 + 击杀次数特殊掉落
         dropIDList += [specItemSign] * len(playerSpecDropList)
         
         if len(dropIDList) > 5:
             #打乱物品顺序
             random.shuffle(playerSpecDropList)
             random.shuffle(dropIDList)
+            
+        if not dropIDList and isGameBoss:
+            GameWorld.ErrLog("Boss没有掉落: dropPlayerLV=%s,ipyWorldLV=%s,maxDropLV=%s" 
+                             % (dropPlayer.GetLV(), ipyDrop.GetMaxWorldLV(), ipyDrop.GetMaxDropLV()), dropPlayer.GetPlayerID())
             
         gameMap = GameWorld.GetMap()
         dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # 以NPC为中心点开始掉落
@@ -4167,8 +4293,12 @@
         self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()
         self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家
         
-        self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo()
-                    
+        isGameBoss = ChConfig.IsGameBoss(curNPC)
+        self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss)
+        self.__OwnerHurtType, self.__OwnerHurtID = hurtType, hurtID
+        if isGameBoss:
+            GameWorld.Log("__GiveObjPrize npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
+        
         #最后一击处理
         self.__DoLastTimeHurtLogic()
         
@@ -4198,9 +4328,19 @@
         elif curTeam != None:
             self.__KilledByTeamSetPrize(curTeam, hurtType, hurtID)
         
-        else:
-            GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
+        #被仙盟杀死
+        elif hurtType == ChConfig.Def_NPCHurtTypeFamily:
+            self.__KilledByFamilySetPrize(hurtType, hurtID)
             
+        elif isGameBoss:
+            GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
+        
+        if isGameBoss:
+            dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "mapID":GameWorld.GetMap().GetMapID(),
+                        "lineID":GameWorld.GetGameWorld().GetLineID(), "teamID":curTeam.GetTeamID() if curTeam else 0,
+                            "killerID":self.__AllKillerDict.keys(), "hurtType":hurtType,"hurtID":hurtID}
+            DataRecordPack.SendEventPack("KillBossRecord", dataDict)
+                
         if OnNPCDie:
             OnNPCDie(curNPC, hurtType, hurtID)
         
@@ -4266,7 +4406,7 @@
     ## NPC死亡, 分享经验逻辑
     #  @param self 类实例
     #  @return 返回击杀玩家信息元组, (玩家列表实例,队伍实例,归属类型,归属ID)
-    def __FindNPCKillerInfo(self):
+    def __FindNPCKillerInfo(self, isGameBoss):
         curNPC = self.__Instance
         npcID = curNPC.GetNPCID()
         objID = curNPC.GetID()
@@ -4285,36 +4425,39 @@
         
         #isLog = self.__GetIsLog()
         dropOwnerType = GetDropOwnerType(curNPC)
-        #GameWorld.DebugLog("NPC击杀者信息...npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))
-        
+        if isGameBoss:
+            GameWorld.Log("NPC被击杀, key=%s,dropOwnerType=%s" % (key, dropOwnerType))
+            
         # 最大伤血 - 伤血可能被重置
         if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
             npcHurtList = curNPC.GetPlayerHurtList()
             npcHurtList.Sort()
-            #if isLog:
-            #    GameWorld.DebugLog("NPC被击杀,npcID=%s,dropOwnerType=%s,hurtCount=%s" % (npcID, dropOwnerType, npcHurtList.GetHurtCount()))
+            if isGameBoss:
+                GameWorld.Log("hurtCount=%s" % (npcHurtList.GetHurtCount()))
             for i in xrange(npcHurtList.GetHurtCount()):
                 #获得最大伤血对象
                 maxHurtObj = npcHurtList.GetHurtAt(i)
-                #if isLog:
-                #    GameWorld.DebugLog("    i=%s,hurtValueType=%s,valueID=%s" % (i, maxHurtObj.GetValueType(), maxHurtObj.GetValueID()))
-                curPlayer, curTeam = self.__GetTagByHurtObj(maxHurtObj)
+                if isGameBoss:
+                    GameWorld.Log("hurtIndex=%s,hurtValueType=%s,valueID=%s" % (i, maxHurtObj.GetValueType(), maxHurtObj.GetValueID()))
+                curPlayer, curTeam = self.__GetTagByHurtObj(maxHurtObj, isLog=isGameBoss)
                 #当前伤血对象超出指定范围或已经死亡
                 if curPlayer == None and curTeam == None:
-                    #if isLog:
-                    #    GameWorld.DebugLog("        当前伤血对象超出指定范围或已经死亡")
+                    if isGameBoss:
+                        GameWorld.Log("    当前伤血对象超出指定范围或已经死亡")
                     continue
                 
                 if curPlayer:
                     playerID = curPlayer.GetPlayerID()
                     if playerID not in killerDict:
                         killerDict[playerID] = curPlayer
-                    GameWorld.Log("    归属最大伤血玩家: npcID=%s,dropOwnerType=%s,playerID=%s" % (npcID, dropOwnerType, playerID))
+                    if isGameBoss:
+                        GameWorld.Log("    归属最大伤血玩家: npcID=%s,dropOwnerType=%s,playerID=%s" % (npcID, dropOwnerType, playerID))
                     return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, playerID
                 
                 if curTeam:
                     killTeam = curTeam
-                    GameWorld.Log("    归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))
+                    if isGameBoss:
+                        GameWorld.Log("    归属最大伤血队伍: npcID=%s,dropOwnerType=%s,teamID=%s" % (npcID, dropOwnerType, curTeam.GetTeamID()))
                     return killerDict, curTeam, ChConfig.Def_NPCHurtTypeTeam, curTeam.GetTeamID()
         # 最大伤血玩家 - 伤血不会被重置
         elif dropOwnerType == ChConfig.DropOwnerType_MaxHurtPlayer:
@@ -4344,8 +4487,8 @@
         if self.__LastHurtPlayer:
             lastHurtPlayerID = self.__LastHurtPlayer.GetPlayerID()
             teamID = self.__LastHurtPlayer.GetTeamID()
-            #if isLog:
-            #    GameWorld.DebugLog("    归属最后一击,npcID=%s,lastHurtPlayerID=%s,teamID=%s" % (npcID, lastHurtPlayerID, teamID))
+            if isGameBoss:
+                GameWorld.Log("    归属最后一击,npcID=%s,lastHurtPlayerID=%s,teamID=%s" % (npcID, lastHurtPlayerID, teamID))
             if teamID:
                 killTeam = GameWorld.GetTeamManager().FindTeam(teamID)
             if not killTeam and lastHurtPlayerID not in killerDict:
@@ -4353,9 +4496,8 @@
                 
         if dropOwnerType == ChConfig.DropOwnerType_All:
             hurtType = ChConfig.Def_NPCHurtTypeAll
-            #if isLog:
-            #    GameWorld.DebugLog("    无归属...npcID=%s" % npcID)
-            #GameWorld.DebugLog("    无归属...")
+            if isGameBoss:
+                GameWorld.Log("    无归属...npcID=%s" % npcID)
             
         elif dropOwnerType == ChConfig.DropOwnerType_Faction:
             #阵营归属
@@ -4363,23 +4505,22 @@
             if protectFaction > 0:
                 hurtType = ChConfig.Def_NPCHurtTypeFaction
                 hurtID = protectFaction
-                #GameWorld.DebugLog("    阵营归属...factionID=%s" % protectFaction)
+                if isGameBoss:
+                    GameWorld.Log("    阵营归属...factionID=%s" % protectFaction)
                 
         if hurtType == 0:
             #归属队伍
             if killTeam:
                 hurtType = ChConfig.Def_NPCHurtTypeTeam
                 hurtID = killTeam.GetTeamID()
-                #if isLog:
-                #    GameWorld.DebugLog("    归属默认队伍, npcID=%s,teamID=%s" % (npcID, hurtID))
-                #GameWorld.DebugLog("    归属默认队伍, teamID=%s" % hurtID)
+                if isGameBoss:
+                    GameWorld.Log("    归属默认队伍, npcID=%s,teamID=%s" % (npcID, hurtID))
             #伤血归属玩家
             elif killerDict:
                 hurtType = ChConfig.Def_NPCHurtTypePlayer
                 hurtID = killerDict.keys()[0]
-                #if isLog:
-                #    GameWorld.DebugLog("    归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID))
-                #GameWorld.DebugLog("    归属默认玩家, playerID=%s" % hurtID)
+                if isGameBoss:
+                    GameWorld.Log("    归属默认玩家, npcID=%s,playerID=%s" % (npcID, hurtID))
                 
         return killerDict, killTeam, hurtType, hurtID
     
@@ -4450,9 +4591,10 @@
     #  @param maxHurtObj 最大伤血对象
     #  @return 返回值, 伤血对象
     #  @remarks 获得伤血对象,支持抢怪
-    def __GetTagByHurtObj(self, maxHurtObj, isCheckRefreshArea=False):
+    def __GetTagByHurtObj(self, maxHurtObj, isCheckRefreshArea=False, isLog=False):
         #获得死亡的NPC
         curNPC = self.__Instance
+        npcID = curNPC.GetNPCID()
         # 伤害的obj类型元组(玩家, 队伍)
         hurtObjTuple = (None, None)
         if maxHurtObj == None:
@@ -4467,18 +4609,28 @@
             curPlayer = GameWorld.GetObj(maxHurtObj.GetValueID(), IPY_GameWorld.gotPlayer)
             
             if curPlayer == None:
+                if isLog:
+                    GameWorld.Log("找不到该目标伤血玩家: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))
                 return hurtObjTuple
             
             #支持抢怪,个人杀死,但自己死亡,不算
             if curPlayer.GetHP() <= 0 or curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
+                if isLog:
+                    GameWorld.Log("该目标伤血玩家已死亡: npcID=%s,playerID=%s" % (npcID, maxHurtObj.GetValueID()))
                 return hurtObjTuple
             
             if isCheckRefreshArea:
                 if not self.GetIsInRefreshPoint(curPlayer.GetPosX(), curPlayer.GetPosY(), refreshPoint):
+                    if isLog:
+                        GameWorld.Log("该目标伤血玩家不在NPC区域内: npcID=%s,playerID=%s,pos(%s,%s)" 
+                                      % (npcID, maxHurtObj.GetValueID(), curPlayer.GetPosX(), curPlayer.GetPosY()))
                     return hurtObjTuple
             #如果玩家已经超出指定距离,不加经验
             elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),
                                      curPlayer.GetPosX(), curPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
+                if isLog:
+                    GameWorld.Log("该目标伤血玩家超出指定距离: npcID=%s,playerID=%s,npcPos(%s,%s),playerPos(%s,%s)" 
+                                  % (npcID, maxHurtObj.GetValueID(), curNPC.GetPosX(), curNPC.GetPosY(), curPlayer.GetPosX(), curPlayer.GetPosY()))
                 return hurtObjTuple
             
             #正常返回
@@ -4489,23 +4641,39 @@
             #获得当前队伍
             teamID = maxHurtObj.GetValueID()
             curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
+            if isLog:
+                GameWorld.Log("目标伤血队伍: npcID=%s,teamID=%s" % (npcID, teamID))
             if curTeam == None:
+                if isLog:
+                    GameWorld.Log("找不到目标队伍, teamID=%s" % (teamID))
                 return hurtObjTuple
             
+            if isLog:
+                GameWorld.Log("队伍成员数: GetMemberCount=%s" % (curTeam.GetMemberCount()))                
             #遍历队伍,半径为一屏半的距离内的所有队伍/团队成员,可以获得经验
             for i in xrange(curTeam.GetMemberCount()):
                 curTeamPlayer = curTeam.GetMember(i)
                 if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+                    if isLog:
+                        GameWorld.Log("    i=%s, 无该队员!" % (i))
                     continue
                 
                 if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
+                    if isLog:
+                        GameWorld.Log("    i=%s, 队员已死亡!memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
                     continue
                 
                 if isCheckRefreshArea:
                     if not self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
+                        if isLog:
+                            GameWorld.Log("    i=%s, 队员不在NPC区域内!memPlayerID=%s,pos(%s,%s)" 
+                                          % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))
                         continue
                 elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(),
                                        curTeamPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
+                    if isLog:
+                        GameWorld.Log("    i=%s, 队员超出指定距离!memPlayerID=%s,npcPos(%s,%s),playerPos(%s,%s)" 
+                                      % (i, curTeamPlayer.GetPlayerID(), curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY()))
                     continue
                 
                 hurtObjTuple = (None, curTeam)
@@ -4592,7 +4760,60 @@
         self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
         #GameWorld.Log("队伍杀死怪物奖励,逻辑成功结束")
         return
-
+    
+    def __KilledByFamilySetPrize(self, hurtType, hurtID):
+        ## 仙盟杀死NPC奖励逻辑
+        curNPC = self.__Instance
+        
+        maxLV = 0
+        dropPlayer = None
+        ownerPlayerList = []
+        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+        copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
+        for index in xrange(copyPlayerMgr.GetPlayerCount()):
+            player = copyPlayerMgr.GetPlayerByIndex(index)
+            if not player:
+                continue
+            
+            if player.GetFamilyID() != hurtID or not self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint):
+                continue
+            
+            curPlayerLV = player.GetLV()
+            if maxLV < curPlayerLV:
+                maxLV = curPlayerLV
+                dropPlayer = player
+            ownerPlayerList.append(player)
+            
+        if not ownerPlayerList:
+            GameWorld.Log("奖励归属仙盟,但是不存在可获得该奖励的成员!npcID=%s,hurtType=%s,hurtID=%s" 
+                          % (curNPC.GetNPCID(), hurtType, hurtID))
+            
+        # 因为仙盟归属boss归属伤血第一的仙盟,仙盟伤血有保护,可能存在伤血第一仙盟在boss死亡的时候都不在
+        # 此时掉落计算玩家算最后一击玩家,归属还是算伤血第一仙盟的
+        if not dropPlayer:
+            dropPlayer = self.__LastHurtPlayer
+            
+        if not dropPlayer:
+            GameWorld.ErrLog("奖励归属仙盟,找不到掉落玩家!npcID=%s,hurtType=%s,hurtID=%s" 
+                             % (curNPC.GetNPCID(), hurtType, hurtID))
+            return
+        
+        # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来
+        if not self.__LastHurtPlayer:
+            self.__LastHurtPlayer = dropPlayer
+        if not self.__MaxHurtPlayer:
+            self.__MaxHurtPlayer = dropPlayer
+        if not self.__Killer:
+            self.__Killer = dropPlayer
+        maxHurtID = dropPlayer.GetPlayerID()
+        
+        for curPlayer in ownerPlayerList:
+            self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, False)
+            
+        #调用物品掉落
+        self.__NPCDropItem(dropPlayer, hurtType, hurtID, ownerPlayerList)
+        return
+    
     ## 队伍或自己击杀NPC扩展功能
     #  @param curPlayer
     #  @return None
@@ -4601,7 +4822,7 @@
         npcID = curNPC.GetNPCID()
         defObjType = curNPC.GetGameObjType() 
         mapFBType = GameWorld.GetMap().GetMapFBType()
-        mapID = GameWorld.GetMap().GetMapID()
+        mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
         playerID = curPlayer.GetPlayerID()
         
         # 如果是NPC
@@ -4609,7 +4830,10 @@
             #掉落归属
             if mapFBType != IPY_GameWorld.fbtNull:
                 FBLogic.DoFB_DropOwner(curPlayer , curNPC)
-            
+            else:
+                if curNPC.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
+                    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC)
+                
             killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
             limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
             if limitIndex != None:
@@ -4623,24 +4847,23 @@
                 dataDict = {"objID":curNPC.GetID(), "bossID":npcID, "touchCnt":newCnt,
                             "AccID":curPlayer.GetAccID(), "PlayerID":curPlayer.GetPlayerID()}
                 DataRecordPack.SendEventPack("AddKillBossCnt", dataDict, curPlayer)
-                
                 if limitIndex == 0:
                     # 世界BOSS击杀成就
                     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillWorldBoss, 1)
                     # 每日活动
                     PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_WorldBOSS)
-                    PlayerMagicWeapon.SetMWPrivilegeData(curPlayer, ChConfig.MWPrivilege_KillBossAddAttr, 1, True)
                     PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_WorldBOSS, 1)
                     PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_WorldBoss, 1)
-                elif limitIndex == 1: #BOSS之家
-                    # BOSS之家BOSS击杀成就
-                    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
-                    # 每日活动
-                    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
-                    PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
-                    PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
-            #击杀特定NPC成就
-            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])
+            if ChConfig.IsGameBoss(curNPC) and mapID == ChConfig.Def_FBMapID_BossHome:
+                #BOSS之家
+                # BOSS之家BOSS击杀成就
+                PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillBossHomeBoss, 1)
+                # 每日活动
+                PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_BOSSHome)
+                PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_BOSSHome, 1)
+                PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_BossHome, 1)
+            
+            
         return
         
     #---------------------------------------------------------------------
@@ -4662,10 +4885,10 @@
         #不是普通NPC    
         elif npcObjType != IPY_GameWorld.gnotNormal:
             return
-        
+        npcID = curNPC.GetNPCID()
         #GameWorld.DebugLog("__MissionOnKillNPC isFeel=%s" % (isFeel), curPlayer.GetPlayerID())
         killBossCntLimitDict = IpyGameDataPY.GetFuncCfg('KillBossCntLimit', 1)
-        limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, curNPC.GetNPCID())
+        limitIndex = GameWorld.GetDictValueByKey(killBossCntLimitDict, npcID)
         isWorldBoos = limitIndex == 0
         if isFeel:
             #击杀NPC触发摸怪任务事件
@@ -4677,13 +4900,14 @@
             EventShell.EventRespons_OnKillById(curPlayer, curNPC)
             if isWorldBoos:
                 EventShell.EventRespons_KillWorldBoss(curPlayer)
-            
+        #击杀特定NPC成就
+        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, 1, [npcID])
         return
         
     def __GetIsLog(self):
         ## 测试查错日志,临时用
         ## 相关bug: 仙界秘境无经验、boss无掉落
-        return False
+        return ChConfig.IsGameBoss(self.__Instance)
         #return GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_BZZD or ChConfig.IsGameBoss(self.__Instance)
 
     #---------------------------------------------------------------------
@@ -4847,7 +5071,7 @@
     return max(value / pow(10, nlen), 1)
 
 
-Def_CollNPCCfg_Len = 9
+Def_CollNPCCfg_Len = 10
 (
 Def_CollNPCCfg_CanTogether, # 是否允许同时采集
 Def_CollNPCCfg_SysMsgMark, # 不可同时采集提示
@@ -4858,6 +5082,7 @@
 Def_CollNPCCfg_ZhenQi, # 获得的真气/魔魂
 Def_CollNPCCfg_GiveItemModeID, # 获得的物品信息模板编号
 Def_CollNPCCfg_NotCostItemNotify, # 消耗品不足提示
+Def_CollNPCCfg_LimitSysMsgMark, #采集上限提示
 ) = range(Def_CollNPCCfg_Len)
 
 
@@ -4932,7 +5157,8 @@
         GameWorld.DebugLog("    maxTime=%s,todayTime=%s" % (limitMaxTime, todayCollTime))
         
     if limitMaxTime > 0 and todayCollTime >= limitMaxTime:
-        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_807125")
+        
+        PlayerControl.NotifyCode(curPlayer, collectNPCInfo[Def_CollNPCCfg_LimitSysMsgMark], [limitMaxTime])
         return True
     
     # 采集消耗
@@ -4972,7 +5198,7 @@
 
     PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, \
                                     prepareID=curNPC.GetID())
-    
+    FBLogic.OnBeginCollect(curPlayer, curNPC)
     ##添加这个NPC的伤血列表,用于判断可否同时采集,改为字典判断
     AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)
     return
@@ -5224,7 +5450,8 @@
             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
             SyncCollNPCTime(curPlayer, npcIDList=[npcID])
         GameWorld.DebugLog("        增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
-        
+        #采集成就
+        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, successCnt, [npcID])
     SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
     #DataRecordPack.DR_CollectNPCOK(curPlayer, npcID, addMoney, addExp, addZhenQi, giveItemInfoList)
     return True
@@ -5283,44 +5510,45 @@
     GameWorld.DebugLog("    最终可得到物品giveItemInfoList=%s" % giveItemInfoList)
     
     syncItemInfoList = [] # 同步的采集到的物品信息列表
-    for itemType, itemID, itemCnt, isBind in giveItemInfoList:
+    for itemID, itemCnt, isBind in giveItemInfoList:
         if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
             break
         
         isBind = setBind or isBind
-        if itemType == 0:
-            getItemObj = ItemControler.GetOutPutItemObj(itemID)
-        elif itemType == 1:
-            itemDictData = ItemControler.GetAppointItemDictData(itemID, isBind)
-            getItemObj = ItemControler.GetItemByData(itemDictData)
-        elif itemType == 2:
-            quality = ItemCommon.GetRandEquipQualityByTable(itemID, "CollectEquipRandQuality")
-            if quality == 0:
-                isBroadcast = False
-                getItemObj = ItemCommon.RandNormalEquip(curPlayer, itemID, isBind, "CollectNormalEquip")
-            else:
-                getItemObj, isBroadcast = ItemCommon.RandGreateEquip(curPlayer, itemID, isBind, "CollectGreateEquip", quality)
-            if getItemObj == None:
-                continue
-            
-            itemID = getItemObj.GetItemTypeID()
+        
+        getItemObj = ItemControler.GetOutPutItemObj(itemID)
+#        elif itemType == 1:
+#            itemDictData = ItemControler.GetAppointItemDictData(itemID, isBind)
+#            getItemObj = ItemControler.GetItemByData(itemDictData)
+#        elif itemType == 2:
+#            quality = ItemCommon.GetRandEquipQualityByTable(itemID, "CollectEquipRandQuality")
+#            if quality == 0:
+#                isBroadcast = False
+#                getItemObj = ItemCommon.RandNormalEquip(curPlayer, itemID, isBind, "CollectNormalEquip")
+#            else:
+#                getItemObj, isBroadcast = ItemCommon.RandGreateEquip(curPlayer, itemID, isBind, "CollectGreateEquip", quality)
+#            if getItemObj == None:
+#                continue
+#            
+#            itemID = getItemObj.GetItemTypeID()
         userData = getItemObj.GetUserData()
         getItemObj.SetCount(itemCnt)
         getItemObj.SetIsBind(isBind)
         ItemCommon.NotifyItemDropByKill(curPlayer, getItemObj, npcID)
             
-        SendGameServerGoodItemRecord(mapID, npcID, curPlayer.GetPlayerName(), curPlayer.GetPlayerID(), itemID)
+        #SendGameServerGoodItemRecord(mapID, npcID, curPlayer.GetPlayerName(), curPlayer.GetPlayerID(), itemID)
         #可以放入背包
         if not ItemControler.DoLogic_PutItemInPack(curPlayer, getItemObj, True, True,
                                                    event=["CollectNPC", False, {"npcID":npcID}]):
             break
-        syncItemInfoList.append([itemType, itemID, itemCnt, isBind, userData])
+        syncItemInfoList.append([itemID, itemCnt, isBind, userData])
     return syncItemInfoList
 
 ## 采集结果同步
 #  @param None
 #  @param None
 def SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, syncItemInfoList, collectNPCID=0):
+    return #暂不同步
     if addExp <= 0 and addMoney <= 0 and addZhenQi <= 0 and not syncItemInfoList:
         return
     
@@ -5408,15 +5636,15 @@
         collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
         npcIDList = collectNPCIDTimeLimit.keys()
     
-    if funcTypeList:
-        collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
-        for fType in funcTypeList:
-            todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
-            collection.Clear()
-            collection.FuncType = fType
-            collection.CollectionCnt = todayCollTime
-            collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
-            NetPackCommon.SendFakePack(curPlayer, collection)
+#    if funcTypeList:
+#        collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
+#        for fType in funcTypeList:
+#            todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
+#            collection.Clear()
+#            collection.FuncType = fType
+#            collection.CollectionCnt = todayCollTime
+#            collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
+#            NetPackCommon.SendFakePack(curPlayer, collection)
         
     if npcIDList:
         npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()
@@ -5531,6 +5759,59 @@
     NetPackCommon.SendFakePack(curPlayer, npcInfoPack)
     return
 
+
+## 获取本地图NPC数量
+#  @param queryNPCIDList:查询的NPCID列表
+#  @param tick
+#  @return {NPCID:cnt}
+def GetNPCCntInfo(queryNPCIDList, tick):
+    npcCntDict = {}
+
+    if not queryNPCIDList:
+        return npcCntDict
+    
+    gameNPCManager = GameWorld.GetNPCManager()
+    GameWorld.DebugLog("GetNPCCntInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))
+
+    for index in xrange(gameNPCManager.GetNPCCount()):
+        curNPC = gameNPCManager.GetNPCByIndex(index)
+        curID = curNPC.GetID()
+        if curID == 0:
+            continue
+        
+        curNPCID = curNPC.GetNPCID()
+        
+        if curNPCID not in queryNPCIDList:
+            continue
+        if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
+            continue
+        npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
+                
+    GameWorld.DebugLog("    npcCntDict=%s" % (str(npcCntDict)))
+    return npcCntDict
+
+## 同步地图NPC数量信息
+#  @param curPlayer:采集玩家实例
+#  @param mapID:
+#  @param npcInfoDict:
+#  @return None
+def SyncNPCCntInfo(curPlayer, mapID, npcCntDict):
+    npcInfoPack = ChPyNetSendPack.tagMCNPCCntList()
+    npcInfoPack.Clear()
+    npcInfoPack.MapID = mapID
+    npcInfoPack.NPCInfoList = []
+
+    for npcid, npcCnt in npcCntDict.items():
+        npcInfo = ChPyNetSendPack.tagMCNPCCntInfo()
+        npcInfo.Clear()
+        npcInfo.NPCID = npcid
+        npcInfo.Cnt = npcCnt
+        npcInfoPack.NPCInfoList.append(npcInfo)
+        
+    npcInfoPack.NPCInfoCnt = len(npcInfoPack.NPCInfoList)
+    NetPackCommon.SendFakePack(curPlayer, npcInfoPack)
+    return
+
 def SendGameServerGoodItemRecord(mapID, npcID, playerName, playerID, itemID, equipInfo=[]):
     # @param equipInfo: [equipPlace, itemClassLV, itemColor, itemQuality, itemUserData]
 #    GameWorld.DebugLog("检查物品是否发送GameServer: mapID=%s, npcID=%s, playerName=%s, itemID=%s" 

--
Gitblit v1.8.0