From 1e3f8cd83080ab4f140f862b2b2a0e60282b521e Mon Sep 17 00:00:00 2001
From: xdh <xiefantasy@qq.com>
Date: 星期四, 30 八月 2018 20:11:31 +0800
Subject: [PATCH] fix:3106 【后端】新增守卫人皇参与奖励

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py |  354 ++++++++++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 264 insertions(+), 90 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 de3baf4..e5e9691 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
@@ -104,6 +105,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 +114,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系,按二进制位区分
 
@@ -822,13 +825,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 +1098,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 +1126,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 +1205,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.DebugLog("更新全服击杀次数: %s" % updNPCKilledCount)
+        # 通知GameServer记录
+        msgInfo = str([npcID, updNPCKilledCount])
+        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "GlobalKillCount", msgInfo, len(msgInfo))
+        if updNPCKilledCount in killCountDropDict:
+            isJobLimit, itemIDList, randItemIDList = killCountDropDict[updNPCKilledCount]
+            for itemID in itemIDList:
+                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.append(itemID)
+                GameWorld.DebugLog("全服击杀次数必掉物品: itemID=%s" % itemID)
+            if randItemIDList:
+                if isJobLimit:
+                    randJobItemList = []
+                    for rItemID in randItemIDList:
+                        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)
+                    randItemID = random.choice(randJobItemList)
+                else:
+                    randItemID = random.choice(randItemIDList)
+                dropItemIDList.append(randItemID)
+                GameWorld.DebugLog("全服击杀次数必掉随机物品: randItemID=%s" % randItemID)
+                
     return dropItemIDList
 
 def __GetEquipIDList(npcID, classLV, color, placeList, star, itemJobList, tagPlace=None):
@@ -1917,11 +1989,14 @@
             #因为存在boss分流,所以用gameFB字典,但是存活状态还是用GameWorld字典
             GameWorld.GetGameFB().SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % npcid, GameWorld.GetGameWorld().GetTick())
         
+            if GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_Family:
+                FamilyRobBoss.ClearFamilyOwnerBossHurt(curNPC)
+        
     
     # 清除队伍成员伤血列表
     AttackCommon.ClearTeamPlayerHurtValue(curNPC)
     # 清除自定义伤血列表
-    BossHurtMng.ClearHurtValueList(curNPC)
+    #BossHurtMng.ClearHurtValueList(curNPC)
 
     # C++设置npc死亡
     curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),
@@ -1955,6 +2030,9 @@
         self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
         self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
         self.__FeelPlayerList = [] # 所有摸怪玩家列表,处理任务及某些逻辑用
+        
+        self.__OwnerHurtType = 0
+        self.__OwnerHurtID = 0
         return
     #---------------------------------------------------------------------
     ## 移动到某一个点的附近点
@@ -2485,7 +2563,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)
 
         
@@ -2789,6 +2867,12 @@
             # 这种情况一般是玩家未加入队伍前对该NPC有伤血,加入到某个队伍后,将该伤害转移到队伍中
             return True
         
+        if hurtPlayer.GetHP() <= 0 or hurtPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
+            deadTime = hurtPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
+            if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
+                #GameWorld.DebugLog("伤血玩家死亡超过伤血保护时长,清除该伤血!playerID=%s" % hurtID)
+                return True
+            
         #GameWorld.DebugLog("正常玩家伤血保护中!playerID=%s" % hurtID)
         return False
     
@@ -2806,6 +2890,13 @@
                 if curTeamPlayer.GetCopyMapID() != copyMapID:
                     #GameWorld.DebugLog("队员不在本线路,不计!playerID=%s" % playerID)
                     continue
+                
+                if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
+                    deadTime = curTeamPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_DeadTime)
+                    if time.time() - deadTime >= IpyGameDataPY.GetFuncCfg("BossHurtValue", 1):
+                        #GameWorld.DebugLog("伤血队员死亡超过伤血保护时长,不计!playerID=%s" % playerID)
+                        continue
+                    
                 #if curTeamPlayer.GetHP() > 0 and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
                 if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
                     #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID()))
@@ -2945,7 +3036,7 @@
             #获得伤血对象
             hurtObj = npcHurtList.GetHurtAt(index)
             
-            curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, False)
+            curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, True)
             
             if curPlayer or curTeam:
                 return hurtObj
@@ -3317,6 +3408,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()):
@@ -3694,7 +3788,7 @@
         #=====================================================================================================
         
         #boss伤血排行榜击杀逻辑
-        BossHurtMng.BossOnKilled(curNPC)
+        #BossHurtMng.BossOnKilled(curNPC)
         
         #掉落需要用到摸怪,所以在处理掉落奖励之前设置
         self.__SetFeelNPCPlayerList()
@@ -3710,6 +3804,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)
         #===========================================================================================
@@ -4149,56 +4245,14 @@
     #  @remarks 设置对象奖励
     def __GiveObjPrize(self):
         curNPC = self.__Instance
-        objID = curNPC.GetID()
+        #objID = curNPC.GetID()
         npcID = curNPC.GetNPCID()
         self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()
         self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家
         
         self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo()
-        #isLog = self.__GetIsLog()
-        #if isLog:
-        #    GameWorld.Log("__GiveObjPrize npcID=%s,hurtType=%s,hurtID=%s,allKillPlayer=%s,curTeam=%s" 
-        #                  % (npcID, hurtType, hurtID, self.__AllKillerDict.keys(), curTeam.GetTeamID() if curTeam else None))
-            
-        # 归属队伍时,有击杀次数限制的NPC特殊处理
-        if hurtType == ChConfig.Def_NPCHurtTypeTeam and curTeam:
-            if ChConfig.IsGameBoss(curNPC) and GetDropOwnerType(curNPC) == ChConfig.DropOwnerType_MaxHurt:
-                #if isLog:
-                #    GameWorld.DebugLog("击杀boss有次数限制的NPC,队伍人数=%s" % (curTeam.GetMemberCount()))
-                memInfoList = []
-                for i in xrange(curTeam.GetMemberCount()):
-                    curTeamPlayer = curTeam.GetMember(i)
-                    if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
-                        #if isLog:
-                        #    GameWorld.DebugLog("    i=%s,队员不存在!" % i)
-                        memInfoList.append(None)
-                        continue
-                    findBuff = SkillCommon.FindBuffByID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]
-                    if not findBuff:
-                        #if isLog:
-                        #    GameWorld.DebugLog("    i=%s,找不到归属buff!" % i, curTeamPlayer.GetPlayerID())
-                        memInfoList.append([curTeamPlayer.GetPlayerID(), "Not DropOwnerBuff"])
-                        continue
-                    #同一张地图可能有多个boss,该队伍可能同时在打多个boss,且都获得归属,所以需判断归属的buff所对应的NPC实例ID
-                    if findBuff.GetOwnerType() != IPY_GameWorld.gotNPC or findBuff.GetOwnerID() != objID:
-                        #if isLog:
-                        #    GameWorld.DebugLog("    i=%s,不同归属bossBuff,不能设置归属!objID=%s,curBuffOwnerID=%s" 
-                        #                       % (i, objID, findBuff.GetOwnerID()), curTeamPlayer.GetPlayerID())
-                        #GameWorld.DebugLog("不同归属bossbuff,不能设置归属!objID=%s,curBuffOwnerID=%s" 
-                        #                   % (objID, findBuff.GetOwnerID()), curTeamPlayer.GetPlayerID())
-                        memInfoList.append([curTeamPlayer.GetPlayerID(), {"OwnerType":findBuff.GetOwnerType(), "OwnerID":findBuff.GetOwnerID()}])
-                        continue
-                    playerID = curTeamPlayer.GetPlayerID()
-                    if playerID not in self.__AllKillerDict:
-                        self.__AllKillerDict[playerID] = curTeamPlayer
-                    memInfoList.append([playerID, 1])
-                        
-                curTeam = None
-                hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0
-                
-                if not self.__AllKillerDict:
-                    GameWorld.ErrLog("归属异常队伍信息: objID=%s,npcID=%s, %s" % (objID, npcID, memInfoList))
-                    
+        self.__OwnerHurtType, self.__OwnerHurtID = hurtType, hurtID
+        
         #最后一击处理
         self.__DoLastTimeHurtLogic()
         
@@ -4228,6 +4282,10 @@
         elif curTeam != None:
             self.__KilledByTeamSetPrize(curTeam, hurtType, hurtID)
         
+        #被仙盟杀死
+        elif hurtType == ChConfig.Def_NPCHurtTypeFamily:
+            self.__KilledByFamilySetPrize(hurtType, hurtID)
+            
         else:
             GameWorld.ErrLog("NPC归属异常:npcID=%s,hurtType=%s,hurtID=%s" % (npcID, hurtType, hurtID))
             
@@ -4299,6 +4357,14 @@
     def __FindNPCKillerInfo(self):
         curNPC = self.__Instance
         npcID = curNPC.GetNPCID()
+        objID = curNPC.GetID()
+        key = (GameWorld.GetGameWorld().GetLineID(), objID, npcID)
+        if key in PyGameData.g_npcKillerInfo:
+            killerDict, killTeam, hurtType, hurtID = PyGameData.g_npcKillerInfo.pop(key)
+            teamID = killTeam.GetTeamID() if killTeam else 0
+            GameWorld.Log("NPC被击杀,归属信息: key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s" 
+                          % (key, killerDict.keys(), teamID, hurtType, hurtID))
+            return killerDict, killTeam, hurtType, hurtID
         
         hurtType = 0
         hurtID = 0
@@ -4472,16 +4538,16 @@
     #  @param maxHurtObj 最大伤血对象
     #  @return 返回值, 伤血对象
     #  @remarks 获得伤血对象,支持抢怪
-    def __GetTagByHurtObj(self, maxHurtObj, isLog=True):
+    def __GetTagByHurtObj(self, maxHurtObj, isCheckRefreshArea=False):
         #获得死亡的NPC
         curNPC = self.__Instance
         # 伤害的obj类型元组(玩家, 队伍)
         hurtObjTuple = (None, None)
-        #isLog = self.__GetIsLog() and isLog
         if maxHurtObj == None:
             GameWorld.DebugLog("伤血对象错误,npcID=%s" % (curNPC.GetNPCID()))
             return hurtObjTuple
         
+        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
         #最大伤血类型
         maxHurtValueType = maxHurtObj.GetValueType()
         
@@ -4489,21 +4555,18 @@
             curPlayer = GameWorld.GetObj(maxHurtObj.GetValueID(), IPY_GameWorld.gotPlayer)
             
             if curPlayer == None:
-                #if isLog:
-                #    GameWorld.DebugLog("无法找到玩家,npcID=%s" % (curNPC.GetNPCID()))
                 return hurtObjTuple
             
             #支持抢怪,个人杀死,但自己死亡,不算
-            if curPlayer.GetHP() <= 0 :
-                #if isLog:
-                #    GameWorld.DebugLog("玩家已死亡!playerID=%s" % curPlayer.GetPlayerID())
+            if curPlayer.GetHP() <= 0 or curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
                 return hurtObjTuple
             
+            if isCheckRefreshArea:
+                if not self.GetIsInRefreshPoint(curPlayer.GetPosX(), curPlayer.GetPosY(), refreshPoint):
+                    return hurtObjTuple
             #如果玩家已经超出指定距离,不加经验
-            if GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),
+            elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(),
                                      curPlayer.GetPosX(), curPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
-                #if isLog:
-                #    GameWorld.DebugLog("玩家已经超出指定距离,npcPos(%s,%s),playerPos(%s,%s)" % (curNPC.GetPosX(), curNPC.GetPosY(), curPlayer.GetPosX(), curPlayer.GetPosY()))
                 return hurtObjTuple
             
             #正常返回
@@ -4515,31 +4578,36 @@
             teamID = maxHurtObj.GetValueID()
             curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
             if curTeam == None:
-                #if isLog:
-                #    GameWorld.Log("该队伍异常不存在!npcID=%s,teamID=%s" % (curNPC.GetNPCID(), teamID))
                 return hurtObjTuple
             
-            #组队成员检查
-            playerlist = PlayerControl.GetAreaTeamMember(curTeam, curNPC.GetPosX(), curNPC.GetPosY())
-            if len(playerlist) == 0 :
-                #所有队伍成员,均超过获得奖励距离,或者全部死亡
+            #遍历队伍,半径为一屏半的距离内的所有队伍/团队成员,可以获得经验
+            for i in xrange(curTeam.GetMemberCount()):
+                curTeamPlayer = curTeam.GetMember(i)
+                if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
+                    continue
+                
+                if curTeamPlayer.GetHP() <= 0 or curTeamPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
+                    continue
+                
+                if isCheckRefreshArea:
+                    if not self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
+                        continue
+                elif GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTeamPlayer.GetPosX(),
+                                       curTeamPlayer.GetPosY()) > ChConfig.Def_Team_GetExpScreenDist:
+                    continue
+                
+                hurtObjTuple = (None, curTeam)
                 return hurtObjTuple
             
-            #正常返回
-            hurtObjTuple = (None, curTeam)
             return hurtObjTuple
             
         #最大伤血对象是NPC,那么一定不给经验(玩家的召唤兽伤血算玩家)
         elif maxHurtValueType == ChConfig.Def_NPCHurtTypeNPC:
-            #if isLog:
-            #    GameWorld.DebugLog("最大伤血对象是NPC...valueID=%s" % maxHurtObj.GetValueID())
             return hurtObjTuple
         
         #异常信息,添加伤血类型错误
         else:
             pass
-            #if isLog:
-            #    GameWorld.Log("异常信息,伤血类型错误 maxHurtValueType = %s" % (maxHurtValueType))
         
         return hurtObjTuple
     
@@ -4612,7 +4680,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
@@ -4649,7 +4770,6 @@
                     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之家
@@ -5341,6 +5461,7 @@
 #  @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
     
@@ -5428,15 +5549,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()
@@ -5551,6 +5672,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