From bd61f5e92fad5dc02f693747fde8fdb86ee01c5c Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 06 十二月 2019 20:46:52 +0800
Subject: [PATCH] 8346 【恺英】【后端】协助系统(初版,可完成协助完整流程,增加新NPC伤血管理,支持协助、支持超过20亿伤害)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py |  338 +++----------------------------------------------------
 1 files changed, 23 insertions(+), 315 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 39c9ca2..3c88207 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -53,6 +53,7 @@
 import PlayerNewFairyCeremony
 import GameLogic_CrossGrassland
 import PlayerWeekParty
+import NPCHurtManager
 import PlayerActLogin
 import FamilyRobBoss
 import IpyGameDataPY
@@ -2271,6 +2272,7 @@
     AttackCommon.ClearTeamPlayerHurtValue(curNPC)
     # 清除自定义伤血列表
     #BossHurtMng.ClearHurtValueList(curNPC)
+    NPCHurtManager.DeletePlayerHurtList(curNPC)
     if curNPC.GetType() == ChConfig.ntRobot:
         lineID = GameWorld.GetGameWorld().GetLineID()
         lineRobotJobDict = PyGameData.g_fbRobotJobDict.get(lineID, {})
@@ -2393,7 +2395,6 @@
     #  @remarks 类初始化
     def __init__(self, iNPC):
         self.__Instance = iNPC
-        self.__MaxHurtPlayer = None  # 最大伤血者,队伍取队长
         self.__LastHurtPlayer = None    # 最后一击的玩家
         self.__Killer = None # 击杀者, 由各种规则得出, 一般也是物品归属的代表, 用于广播、记录等确保与归属一致
         self.__AllKillerDict = {} # 所有击杀的玩家ID对应字典, 非队伍, 一般也是归属的拥有者
@@ -3198,231 +3199,6 @@
         npcHurtList.Clear()
         return True
     
-    def __IsBossHurtOfflineProtect(self, refreshPoint, playerID, tick):
-        ## boss伤血是否掉线保护中
-        # 是否离线超过3分钟,下线坐标是否不在boss区域等
-        leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)
-        leavePos = PlayerControl.GetPlayerLeaveServerPos(playerID)
-        if not leaveTick or not leavePos:
-            GameWorld.DebugLog("玩家不在本地图或已长久离线!清除该伤血!playerID=%s" % playerID)
-            return False
-        
-        if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:
-            GameWorld.DebugLog("本地图离线玩家超过保护时长!清除该伤血!playerID=%s,tick=%s,leaveTick=%s" % (playerID, tick, leaveTick))
-            return False
-        
-        if not self.GetIsInRefreshPoint(leavePos[0], leavePos[1], refreshPoint):
-            GameWorld.DebugLog("本地图离线玩家不在保护区域内!playerID=%s,leavePos=%s" % (playerID, leavePos))
-            return False
-        
-        return True
-    
-    def __IsClearPlayerHurt(self, hurtPlayer, refreshPoint, hurtID, tick):
-        if hurtPlayer == None:
-            if not self.__IsBossHurtOfflineProtect(refreshPoint, hurtID, tick):
-                return True
-            
-            #GameWorld.DebugLog("本地图离线玩家伤血值保护中!playerID=%s" % (hurtID))
-            return False
-                                        
-        #if hurtPlayer.GetHP() <= 0:
-        #    GameWorld.DebugLog("伤血玩家血量为0,清除该伤血!playerID=%s" % hurtID)
-        #    return True
-        
-        curNPC = self.__Instance
-        if hurtPlayer.GetInitOK() and (not hurtPlayer.GetVisible() or hurtPlayer.GetSightLevel() != curNPC.GetSightLevel()):
-            GameWorld.DebugLog("伤血玩家不可见,清除该伤血!playerID=%s" % hurtID)
-            return True
-        
-        if not self.GetIsInRefreshPoint(hurtPlayer.GetPosX(), hurtPlayer.GetPosY(), refreshPoint):
-            GameWorld.DebugLog("伤血玩家不在boss范围里,清除该伤血!playerID=%s" % hurtID)
-            return True
-        
-        if hurtPlayer.GetTeamID():
-            # 这种情况一般是玩家未加入队伍前对该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
-    
-    def __GetTeamHurtNPCPlayerIDList(self, refreshPoint, teamID, tick):
-        
-        curNPC = self.__Instance
-        teamHurtPlayerIDList = []
-        # 如果没有在线队员在有效范围内,则进一步判断离线队员是否有伤血保护中的
-        playerMgr = GameWorld.GetPlayerManager()
-        copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
-        mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID) # 因为需要判断离线队员,所以只能用含离线的队伍缓存
-        for playerID in mapTeamPlayerIDList:
-            
-            curTeamPlayer = playerMgr.FindPlayerByID(playerID)
-            if curTeamPlayer:
-                if curTeamPlayer.GetCopyMapID() != copyMapID:
-                    #GameWorld.DebugLog("队员不在本线路,不计!playerID=%s" % playerID)
-                    continue
-                
-                if curTeamPlayer.GetInitOK() and (not curTeamPlayer.GetVisible() or curTeamPlayer.GetSightLevel() != curNPC.GetSightLevel()):
-                    #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) \
-                    and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False):
-                    #GameWorld.DebugLog("有队员在boss范围内,保留队伍伤血!teamID=%s,playerID=%s" % (teamID, curTeamPlayer.GetPlayerID()))
-                    teamHurtPlayerIDList.append(playerID)
-            else:
-                if self.__IsBossHurtOfflineProtect(refreshPoint, playerID, tick):
-                    #GameWorld.DebugLog("有队员对boss离线伤血保护中!teamID=%s,playerID=%s" % (teamID, playerID))
-                    teamHurtPlayerIDList.append(playerID)
-                    
-        if not teamHurtPlayerIDList:
-            GameWorld.DebugLog("伤血队伍没有符合条件的队员在boss区域内,清除该伤血!teamID=%s,mapTeamPlayerIDList=%s" % (teamID, mapTeamPlayerIDList))
-        return teamHurtPlayerIDList
-    
-    def RefreshHurtList(self, tick, refreshInterval=3000):
-        ## 刷新伤血列表
-        # @return: 可攻击的最大伤血数值对象 IPY_PlayerHurtValue
-        
-        curNPC = self.__Instance
-        if not curNPC.GetIsBoss() or GetDropOwnerType(curNPC) != ChConfig.DropOwnerType_MaxHurt:
-            return
-        
-        npcHurtList = curNPC.GetPlayerHurtList()
-        if tick - curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastRefreshHurtTick) < (refreshInterval):
-            if npcHurtList.GetHurtCount():
-                return self.__GetAtkObjByHurtList(npcHurtList)
-            return
-        curNPC.SetDict(ChConfig.Def_NPC_Dict_LastRefreshHurtTick, tick)
-        
-        hurtPlayerDict = {} # {playerID:teamID, ...}
-        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
-        hurtCount = npcHurtList.GetHurtCount()
-        isInHurt = 0
-        for index in xrange(hurtCount):
-            #获得伤血对象
-            hurtObj = npcHurtList.GetHurtAt(index)
-            hurtType = hurtObj.GetValueType()
-            hurtID = hurtObj.GetValueID()
-            hurtValue = hurtObj.GetHurtValue()
-            if not hurtID:
-                continue
-            
-            # Clear()只会把伤血类型及数值重置为0,不会清除该伤血数值对象
-            
-            if hurtType == ChConfig.Def_NPCHurtTypePlayer:
-                hurtPlayer = GameWorld.GetObj(hurtID, IPY_GameWorld.gotPlayer)
-                if self.__IsClearPlayerHurt(hurtPlayer, refreshPoint, hurtID, tick):
-                    hurtObj.Clear()
-                    teamID = 0 if not hurtPlayer else hurtPlayer.GetTeamID()
-                    if teamID:
-                        GameWorld.DebugLog("加入队伍,之气的伤血转移到队伍中!playerID=%s,teamID=%s" % (hurtID, teamID))
-                        AttackCommon.AddHurtValue(curNPC, teamID, ChConfig.Def_NPCHurtTypeTeam, hurtValue)
-                else:
-                    isInHurt = 1
-                    hurtPlayerDict[hurtID] = 0
-                    
-            elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
-                teamHurtPlayerIDList = self.__GetTeamHurtNPCPlayerIDList(refreshPoint, hurtID, tick)
-                if not teamHurtPlayerIDList:
-                    hurtObj.Clear()
-                else:
-                    isInHurt = 1
-                    for tPlayerID in teamHurtPlayerIDList:
-                        hurtPlayerDict[tPlayerID] = hurtID
-                        
-        mapID = GameWorld.GetMap().GetMapID()
-        if IsMapNeedBossShunt(mapID):
-            self.__UpdBossShuntInfo(mapID, hurtPlayerDict, tick)
-        
-        #GameWorld.DebugLog("RefreshHurtList, hurtCount=%s,isInHurt=%s" % (hurtCount, isInHurt))
-        npcHurtList.Sort()
-        curNPC.SetDict(ChConfig.Def_NPC_Dict_InHurtProtect, isInHurt)
-        
-        if hurtCount:
-            # 排序后的,第一个可攻击的最大伤血对象
-            return self.__GetAtkObjByHurtList(npcHurtList)
-        return
-    
-    def __UpdBossShuntInfo(self, mapID, hurtPlayerDict, tick):
-        ## 更新本地图线路boss分流信息
-        curNPC = self.__Instance
-        npcID = curNPC.GetNPCID()
-        lineID = GameWorld.GetGameWorld().GetLineID()
-        key = (mapID, lineID)
-        shuntPlayerDict = PyGameData.g_bossShuntPlayerInfo.get(key, {})
-        
-        shuntChange = False
-        for playerID, shuntInfo in shuntPlayerDict.items():
-            bossID, teamID, relatedTick = shuntInfo
-            if bossID != npcID:
-                # 不是该boss的伤害不处理
-                continue
-            
-            # 还在伤血中
-            if playerID in hurtPlayerDict:
-                newTeamID = hurtPlayerDict[playerID]
-                if newTeamID != teamID:
-                    shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
-                    shuntChange = True
-                    GameWorld.DebugLog("boss分流 -> 玩家对该boss的伤害变更队伍!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" 
-                                       % (playerID, npcID, teamID, newTeamID), lineID)
-                elif relatedTick:
-                    shuntPlayerDict[playerID] = [npcID, newTeamID, 0]
-                    shuntChange = True
-                    GameWorld.DebugLog("boss分流 -> 玩家对该boss的关联状态转为伤害状态!playerID=%s,npcID=%s,teamID=%s,newTeamID=%s" 
-                                       % (playerID, npcID, teamID, newTeamID), lineID)
-                    
-            # 不在伤血中,更新关联tick
-            elif not relatedTick:
-                shuntPlayerDict[playerID] = [npcID, teamID, tick]
-                shuntChange = True
-                GameWorld.DebugLog("boss分流 -> 玩家不在该boss伤血中,设置为关联状态!playerID=%s,npcID=%s,teamID=%s,tick=%s" 
-                                   % (playerID, npcID, teamID, tick), lineID)
-                
-        # 伤先优先级最高,可直接覆盖更新
-        for playerID, teamID in hurtPlayerDict.items():
-            if playerID not in shuntPlayerDict:
-                shuntPlayerDict[playerID] = [npcID, teamID, 0]
-                shuntChange = True
-                GameWorld.DebugLog("boss分流 -> 新增玩家对boss伤害!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
-                
-            elif shuntPlayerDict[playerID][0] != npcID:
-                shuntPlayerDict[playerID] = [npcID, teamID, 0]
-                shuntChange = True
-                GameWorld.DebugLog("boss分流 -> 伤害转移到本boss上!playerID=%s,npcID=%s,teamID=%s" % (playerID, npcID, teamID), lineID)
-                
-        if shuntChange:
-            PyGameData.g_bossShuntPlayerInfo[key] = shuntPlayerDict
-            GameServer_WorldBossShuntInfo(mapID, lineID)
-        return
-    
-    def __GetAtkObjByHurtList(self, npcHurtList):
-        '''第一个可攻击的最大伤血对象,也是实际的归属者或队伍
-        因为玩家伤血掉线、死亡有一定时间的保留机制,故最大伤血不一定是可攻击目标(归属者)
-        注意: 该规则必须与最终算归属的规则一致,不然可能导致归属错乱
-        '''
-        for index in xrange(npcHurtList.GetHurtCount()):
-            #获得伤血对象
-            hurtObj = npcHurtList.GetHurtAt(index)
-            
-            curPlayer, curTeam = self.__GetTagByHurtObj(hurtObj, True)
-            
-            if curPlayer or curTeam:
-                return hurtObj
-        return
-    
     def IsInHurtProtect(self):
         '''NPC是否伤血保护中
         因为手游比较会出现网络切换的情况,此时会可能会引起掉线重连
@@ -3457,6 +3233,8 @@
         self.ClearNPCHurtList()
         #清除所有身上buff
         self.ClearAllBuff(isClearAuraBuff)
+        curNPC = self.__Instance
+        NPCHurtManager.ClearPlayerHurtList(curNPC)
         return True
     
     #---------------------------------------------------------------------
@@ -4234,7 +4012,9 @@
         curNPC = self.__Instance
         self.__FeelPlayerList = []
         
-        npcHurtList = curNPC.GetPlayerHurtList()
+        npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
+        if not npcHurtList:
+            npcHurtList = curNPC.GetPlayerHurtList()
         #npcHurtList.Sort()  #这里不排序,只要有伤害就算
         
         eventPlayerList = []
@@ -4672,7 +4452,6 @@
         #objID = curNPC.GetID()
         npcID = curNPC.GetNPCID()
         self.__LastHurtPlayer = self.__FindLastTimeHurtObjEx()
-        self.__MaxHurtPlayer = self.__FindBossMaxHurtObj() # py自定义伤血所得到的Boss最大伤血玩家
         
         isGameBoss = ChConfig.IsGameBoss(curNPC)
         self.__AllKillerDict, curTeam, hurtType, hurtID = self.__FindNPCKillerInfo(isGameBoss)
@@ -4691,8 +4470,6 @@
             for curPlayer in self.__AllKillerDict.values():
                 if not self.__LastHurtPlayer:
                     self.__LastHurtPlayer = curPlayer
-                if not self.__MaxHurtPlayer:
-                    self.__MaxHurtPlayer = curPlayer
                 if not self.__Killer:
                     self.__Killer = curPlayer
                     
@@ -4736,12 +4513,7 @@
                 
         if OnNPCDie:
             OnNPCDie(curNPC, hurtType, hurtID)
-        
-        #执行玩家连轧逻辑
-        lastTimeHurtObj = self.__FindLastTimeHurtObj()
-        if lastTimeHurtObj[0] == None and lastTimeHurtObj[1] == None:
-            return
-         
+            
         return
     
     ## 最后一击处理
@@ -4757,35 +4529,6 @@
             return
         
         curNPC = self.__Instance
-        #npcID = curNPC.GetNPCID()
-        #mapID = GameWorld.GetMap().GetMapID()
-        #playerName = lastHurtPlayer.GetPlayerName()
-                
-        #===========================================================================================
-        # # 最后一击奖励
-        # lastTimeHurtBossAwardDict = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAward")
-        # if npcID in lastTimeHurtBossAwardDict:
-        #    giveItemList = lastTimeHurtBossAwardDict[npcID]
-        #    playerID = lastHurtPlayer.GetPlayerID()
-        #    bossAwardMailInfo = ReadChConfig.GetEvalChConfig("LastTimeHurtBossAwardMail")
-        #    title, content, getDays = bossAwardMailInfo
-        #    mailContent = content % (npcID)
-        #    PlayerControl.SendMail(title, mailContent, getDays, [playerID], giveItemList)
-        #    
-        #    # 广播
-        #    if len(giveItemList) > 0:
-        #        itemID = giveItemList[0][0] # 默认取第一个奖励物品广播
-        #        PlayerControl.WorldNotify(0, "GeRen_liubo_698214", [playerName, mapID, npcID, itemID, itemID])
-        #===========================================================================================
-            
-        #===========================================================================================
-        # # 最后一击广播
-        # LastHurtNotifyDict = ReadChConfig.GetEvalChConfig("LastHurtNotify")
-        # for npcIDTuple, notifyMark in LastHurtNotifyDict.items():
-        #    if npcID in npcIDTuple:
-        #        PlayerControl.WorldNotify(0, notifyMark, [playerName, mapID, npcID])
-        #        break
-        #===========================================================================================
         
         # VIP杀怪加攻
         PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, curNPC)
@@ -4851,14 +4594,6 @@
                     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:
-            if self.__MaxHurtPlayer:
-                maxHurtPlayerID = self.__MaxHurtPlayer.GetPlayerID()
-                if maxHurtPlayerID not in killerDict:
-                    killerDict[maxHurtPlayerID] = self.__MaxHurtPlayer
-                    #GameWorld.DebugLog("    特殊归属最大伤害玩家: playerID=%s" % maxHurtPlayerID)
-                    return killerDict, None, ChConfig.Def_NPCHurtTypePlayer, maxHurtPlayerID
                 
         # 最大仇恨
         elif dropOwnerType == ChConfig.DropOwnerType_MaxAngry:
@@ -4946,20 +4681,7 @@
         return curTag, GameWorld.GetTeamManager().FindTeam(teamID)
     
     #---------------------------------------------------------------------
-    ## 获取补刀者,包含队伍
-    #  @param self 类实例
-    #  @return 返回值 玩家或者None
-    #  @remarks 
-    def __FindLastTimeHurtObj(self):
-        curNPC = self.__Instance
-        npcHurtList = curNPC.GetPlayerHurtList()
-        if npcHurtList.GetHurtCount() <= 0:
-            return (None, None)
-        
-        maxHurtObj = npcHurtList.GetLastTimeHurtValue()
-        return self.__GetTagByHurtObj(maxHurtObj)
-
-
+    
     ## 获取补刀者(这个绝对是玩家)
     #  @param self 类实例
     #  @return 返回值 玩家或者None
@@ -4968,17 +4690,6 @@
         playerID = curNPC.GetDictByKey(ChConfig.Def_PlayerKey_LastHurt)
         
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
-        if not curPlayer:
-            return None
-        
-        return curPlayer
-    
-    def __FindBossMaxHurtObj(self):
-        # py自定义伤血所得到的Boss最大伤血玩家
-        curNPC = self.__Instance
-        maxHurtID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_BossMaxHurtID % (curNPC.GetID(), curNPC.GetNPCID()))
-        
-        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(maxHurtID)
         if not curPlayer:
             return None
         
@@ -5137,8 +4848,6 @@
         
         if not self.__LastHurtPlayer:
             self.__LastHurtPlayer = playerlist[0]
-        if not self.__MaxHurtPlayer:
-            self.__MaxHurtPlayer = playerlist[0]
         if not self.__Killer:
             self.__Killer = playerlist[0]
         maxHurtID = playerlist[0].GetPlayerID()
@@ -5217,8 +4926,6 @@
         # 赶时间,先简单处理直接取最大等级的,之后可按实际情况来
         if not self.__LastHurtPlayer:
             self.__LastHurtPlayer = dropPlayer
-        if not self.__MaxHurtPlayer:
-            self.__MaxHurtPlayer = dropPlayer
         if not self.__Killer:
             self.__Killer = dropPlayer
         maxHurtID = dropPlayer.GetPlayerID()
@@ -5441,14 +5148,10 @@
             GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" 
                           % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
         if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
-            maxHurtObj = self.RefreshHurtList(tick, refreshInterval)
-            if maxHurtObj:
-                ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()
-                if ownerType == ChConfig.Def_NPCHurtTypeTeam:
-                    tagObj = self.__GetMaxHurtTeamPlayer(ownerID, isDead)
-                elif ownerType == ChConfig.Def_NPCHurtTypePlayer:
-                    tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
-                    
+            maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead)
+            if maxHurtInfo:
+                tagObj, ownerType, ownerID = maxHurtInfo
+                
         elif dropOwnerType == ChConfig.DropOwnerType_Family:
             ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(self, curNPC, tick, refreshInterval)
             if ownerInfo:
@@ -5576,16 +5279,20 @@
         if isDead:
             GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))
             
+        hurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
         # 刷新归属
         if ownerType == ChConfig.Def_NPCHurtTypePlayer:
             curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
             if curPlayer:
                 playerID = curPlayer.GetPlayerID()
-                hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
-                killerDict[playerID] = curPlayer
-                self.__AddDropOwnerPlayerBuff(curPlayer, tick)
-                if dropOwnerType == ChConfig.DropOwnerType_Contend:
-                    curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())
+                if not hurtList or hurtList.HaveHurtValue(playerID):
+                    hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
+                    killerDict[playerID] = curPlayer
+                    self.__AddDropOwnerPlayerBuff(curPlayer, tick)
+                    if dropOwnerType == ChConfig.DropOwnerType_Contend:
+                        curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())
+                else:
+                    BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
                     
         elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
             curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
@@ -5605,6 +5312,7 @@
                     continue
                 
                 if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \
+                    and (not hurtList or hurtList.HaveHurtValue(curTeamPlayer.GetPlayerID()))\
                     and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
                     and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():
                     self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick)

--
Gitblit v1.8.0