From 07a5b93ce90a08c7d60cecc7c61b984ca0b2ea97 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 12 十二月 2019 16:37:17 +0800
Subject: [PATCH] 8346 【恺英】【后端】协助系统(封魔坛支持协助,去除封魔坛旧版伤血统计)

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                                |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py |  459 ++++++++++++---------------------------------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py                          |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                   |    2 
 ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py                                                   |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py                           |   34 ++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py                                               |   15 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py              |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py            |    1 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py                     |   10 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py                                                 |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                                |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py                         |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                     |    2 
 14 files changed, 194 insertions(+), 370 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index 94b3cbf..56f727b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -44,7 +44,7 @@
 #import PlayerFamilyStore
 import PlayerSocial
 import PlayerFamilyParty
-import PlayerSealDemon
+#import PlayerSealDemon
 import PlayerBillboard
 import PlayerLVAward
 import PlayerDuJie
@@ -160,7 +160,7 @@
         #仙盟宴会
         PlayerFamilyParty.OnPlayerLogin(curPlayer)
         #封魔坛
-        PlayerSealDemon.OnPlayerLogin(curPlayer)
+        #PlayerSealDemon.OnPlayerLogin(curPlayer)
         #仙魔之争
         PlayerXMZZ.OnXMZZOnLogin(curPlayer)
         #等级奖励
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
index d1dba0a..80653c9 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -223,21 +223,24 @@
         GameWorld.DebugLog("非同盟玩家不能协助!")
         return
     
+    playerMapID = curPlayer.GetMapID()
     mapID = assistObj.MapID
     lineID = assistObj.LineID
-    gameMap = GameWorld.GetMap(mapID)
-    if not gameMap:
+    playerMap = GameWorld.GetMap(playerMapID)
+    if not playerMap:
         return
-    if gameMap.GetMapFBType() != ChConfig.fbtNull:
-        playerMapID = curPlayer.GetMapID()
-        playerLineID = PlayerControl.GetFBFuncLineID(curPlayer)
+    if playerMap.GetMapFBType() != ChConfig.fbtNull:
+        playerLineID = curPlayer.GetFBID()
         if playerMapID != mapID or playerLineID != lineID:
             #副本中无法协助
             PlayerControl.NotifyCode(curPlayer, "AssistFBLimit")
             return
         
     # 设定协助必须离开队伍
-    if gameMap.GetMapFBType() != ChConfig.fbtTeam:
+    tagMap = GameWorld.GetMap(mapID)
+    if not tagMap:
+        return
+    if tagMap.GetMapFBType() != ChConfig.fbtTeam:
         curTeam = curPlayer.GetTeam()
         if curTeam:
             PlayerTeam.DoPlayerLeaveTeam(curPlayer, curTeam, tick)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 450a64d..0738828 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -794,11 +794,11 @@
         PlayerTeam.MapServer_TeamMemFuncData(srcPlayerID, eval(resultName))
         return
     
-    #封魔坛结束
-    if callName == "SealDemonOver":
-        playerID, lineID, rank = eval(resultName)
-        PyDataManager.GetSealDemonRecordManager().UpdateSealDemonRecord(playerID,lineID,rank)
-        return
+#    #封魔坛结束
+#    if callName == "SealDemonOver":
+#        playerID, lineID, rank = eval(resultName)
+#        PyDataManager.GetSealDemonRecordManager().UpdateSealDemonRecord(playerID,lineID,rank)
+#        return
     
     #查询副本功能线路人数
     if callName == "FBLinePlayerCnt":
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
index 6ee43d2..17982a1 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py
@@ -225,7 +225,7 @@
 class XMZZManager(object):
        
     def __init__(self):
-        self.XMZZPlayerDict = {}     # {playerid:data, ...} PyGameDataStruct.tagDBPySealDemonRecord
+        self.XMZZPlayerDict = {}     # {playerid:data, ...} PyGameDataStruct.tagDBPyXMZZ
         self.XMZZFactionDict = {Faction_1:[0, 0], Faction_2:[0, 0]}    # {faction:[积分, 人数]}
         self.XMZZTopScore = 0 #积分王积分
         self.XMZZTopPlayerName = '' #积分王名
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index 81f8c02..a0d50ed 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -704,9 +704,9 @@
     if curObj == None:
         GameWorld.ErrLog("NPCAddObjInHurtList NoFindObj")
         return
-
-    if curTaglNPCHPBefore < hurtHP:
-        hurtHP = curTaglNPCHPBefore
+    
+    #if curTaglNPCHPBefore < hurtHP:
+    #    hurtHP = curTaglNPCHPBefore
         
     curObjType = curObj.GetGameObjType()
     if curObjType == IPY_GameWorld.gotPlayer:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 464e1a3..d27acf9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1848,7 +1848,7 @@
 Def_NoPlayerNeedProcessRefreshPointMap = [Def_FBMapID_HorsePetBoss, Def_FBMapID_SealDemon, Def_FBMapID_GodArea, Def_FBMapID_BossHome, Def_FBMapID_GatherSoul, Def_FBMapID_ZhuXianBoss, Def_FBMapID_AllFamilyBoss]
 
 # 可重复进的副本
-Def_NoLimitEnterCntMap = [Def_FBMapID_AllFamilyBoss, Def_FBMapID_FamilyParty, Def_FBMapID_FamilyWar, Def_FBMapID_FamilyInvade, Def_FBMapID_ElderBattlefield]
+Def_NoLimitEnterCntMap = [Def_FBMapID_AllFamilyBoss, Def_FBMapID_FamilyParty, Def_FBMapID_FamilyWar, Def_FBMapID_FamilyInvade, Def_FBMapID_ElderBattlefield, Def_FBMapID_SealDemon]
 
 # 无玩家时不自动关闭的自伸缩副本
 Def_NoPlayerNotCloseAutoSizeMap = [Def_FBMapID_FamilyInvade, Def_FBMapID_FamilyBossMap, Def_FBMapID_GatherSoul]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py
index 78be798..b685cd0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py
@@ -21,6 +21,7 @@
 import ChConfig
 import NPCHurtManager
 import PlayerTeam
+import GameObj
 
 ##查看点选的NPC仇恨列表
 # @param curPlayer 玩家实例
@@ -40,7 +41,7 @@
         GameWorld.DebugAnswer(curPlayer, "objID(%s) 错误 找不到对应NPC" % objID)
         return
     
-    GameWorld.DebugAnswer(curPlayer, "---------------- %s" % (GameWorld.GetGameWorld().GetTick() % 1000))
+    GameWorld.DebugAnswer(curPlayer, "--- %s --- HP: %s / %s" % (GameWorld.GetGameWorld().GetTick() % 1000, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC)))
     GameWorld.DebugAnswer(curPlayer, "ID=%s,team=%s,family=%s" % (curPlayer.GetPlayerID(), curPlayer.GetTeamID(), curPlayer.GetFamilyID()))
     
     # 归属仙盟的,取仙盟伤血统计
@@ -48,15 +49,16 @@
         FamilyRobBoss.OnGMPrintFamilyOwnerBossHurt(curPlayer, curNPC)
         return
     
-    isPyHurtList = True
+    isPyHurtList = 1
     npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
     if not npcHurtList:
         npcHurtList = curNPC.GetPlayerHurtList()
-        isPyHurtList = False
+        isPyHurtList = 0
     if isSort:
         npcHurtList.Sort()  #sort以后伤血列表从大到小排序
         
-    GameWorld.DebugAnswer(curPlayer, "ID=%s, NPCID=%s, 伤血数=%s, isSort=%s" % (curNPC.GetID(), curNPC.GetNPCID(), npcHurtList.GetHurtCount(), isSort))
+    GameWorld.DebugAnswer(curPlayer, "ID=%s,NPCID=%s, 伤血数=%s,排序=%s,PY=%s" 
+                          % (curNPC.GetID(), curNPC.GetNPCID(), npcHurtList.GetHurtCount(), isSort, isPyHurtList))
     if isPyHurtList:
         for playerID, assistPlayerIDList in npcHurtList.GetNoAssitPlayerIDDict().items():
             GameWorld.DebugAnswer(curPlayer, "玩家:%s, 协助玩家:%s" % (playerID, assistPlayerIDList))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
index 7b7917f..b9c5d6f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
@@ -99,6 +99,7 @@
 Over_helpPlayer = 'helpPlayer' #助战玩家信息 {"玩家ID":{玩家信息key:value, ...}, ...}
 Over_ownerID = 'ownerID' #归属玩家ID
 Over_ownerName = 'ownerName' #归属玩家名
+Over_isAssist = 'isAssist' #是否协助
 
 #副本行为
 (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
index 97f6427..ff06a95 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py
@@ -18,21 +18,16 @@
 import FBCommon
 import GameWorld
 import IPY_GameWorld
-import GameWorldProcess
 import IpyGameDataPY
 import ChConfig
 import PyGameData
 import PlayerControl
 import NPCCommon
 import ItemCommon
-import ChPyNetSendPack
 import ShareDefine
 import EventShell
-import NPCCustomRefresh
 import PlayerSuccess
 import PlayerActivity
-import NetPackCommon
-import PlayerVip
 import GameObj
 import PlayerBossReborn
 import PlayerFairyCeremony
@@ -40,105 +35,58 @@
 import PlayerWeekParty
 import PlayerActLogin
 import EventReport
+import PlayerTeam
+import NPCHurtManager
+import GameWorldProcess
+import PetControl
+import AttackCommon
 
+#当前副本地图的状态
+(
+FB_Step_Open, # 副本开启
+FB_Step_Fighting, # 副本进行中
+FB_Step_Over, # 副本结束
+FB_Step_Close, # 关闭状态
+) = range(4)
 
 FBPlayerDict_EncourageLV = 'FBPlayerDict_EncourageLV'   # 鼓舞等级
-FBDict_IsOver = 'FBDict_IsOver' #是否已结算, 结算时的tick
 
 FBPlayerDict_Rank = "FBPlayerDict_Rank" # 玩家排名
 
 g_npcHurtDict = {}
 
-
-def OnFBPlayerOnLogin(curPlayer):
-    NotifyFMTDouble(curPlayer)
-    return
-
-
 ## 是否能够通过活动查询进入
-#  @param curPlayer 玩家实例
-#  @param mapID 地图ID
-#  @param lineID 线路id
-#  @param tick 时间戳
-#  @return 布尔值
 def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
-    IsDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)
-    #newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')
-    if IsDouble:# and lineID not in newbielineList:
-        enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % ChConfig.Def_FBMapID_SealDemon)
-        maxCnt = FBCommon.GetEnterFBMaxCnt(curPlayer, ChConfig.Def_FBMapID_SealDemon)
-        if enterCnt + 2 > maxCnt:
-            return False
-    # 新手副本修改为也可以重复进
-#    if lineID in newbielineList:
-#        hasEnter = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False,
-#                                               [ChConfig.Def_FBMapID_SealDemon])
-#        if hasEnter:
-#            GameWorld.DebugLog("    已进入过该新手线路 %s" % lineID)
-#            return False
     return True
 
-
-##副本玩家进入点
-# @param curPlayer 玩家实例
-# @param mapID 地图ID
-# @param lineId 分线ID
-# @param ipyEnterPosInfo 功能线路IPY配置坐标信息
-# @param tick 时间戳
-# @return posX, posY, 随机半径(可选)
+## 副本玩家进入点
 def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
     return ipyEnterPosInfo
 
-### 查询地图是否开启
-##  @param tick 时间戳
-##  @return 布尔值
+## 查询地图是否开启
 #def OnCanOpen(tick):
 #    return True
 
-##查询是否可以进入地图
-# @param ask:请求结构体(IPY_BMChangeMapAsk)
-# @param tick:时间戳
-# @return IPY_GameWorld.cme 枚举
+## 查询是否可以进入地图
 def OnChangeMapAsk(ask, tick):
     return IPY_GameWorld.cmeAccept
 
-##开启副本
-# @param tick 时间戳
-# @return 返回值无意义
-# @remarks 开启副本
+## 开启副本
 def OnOpenFB(tick):
-    mapID = GameWorld.GetMap().GetMapID()
-    if mapID == ChConfig.Def_FBMapID_SealDemonEx:
-        return
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-
-    refreshIDList = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_SealDemon, lineID)
-    if refreshIDList:
-        for refreshID in refreshIDList:
-            NPCCustomRefresh.SetNPCRefreshByID(refreshID)
-    
-    
+    FBCommon.SetFBStep(FB_Step_Fighting, tick)
     return
 
 ## 进副本
-#  @param curPlayer
-#  @param tick
-#  @return None
 def DoEnterFB(curPlayer, tick):
     playerID = curPlayer.GetPlayerID()
-    mapID = GameWorld.GetMap().GetMapID()
-    if mapID == ChConfig.Def_FBMapID_SealDemonEx:
-        lineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ReqFBFuncLine)
-        FBCommon.SetFBPropertyMark(lineID)
-    else:
-        lineID = GameWorld.GetGameWorld().GetPropertyID() - 1    
-    gameFB = GameWorld.GetGameFB()
+    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1    
     playerCnt = GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount()
     GameWorld.DebugLog("DoEnterFB...playerCnt=%s,lineID=%s" % (playerCnt, lineID), playerID)
-    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
-    if lineID < 0 or overTick:
+    gameFB = GameWorld.GetGameFB()
+    if gameFB.GetFBStep() != FB_Step_Fighting:
         PlayerControl.PlayerLeaveFB(curPlayer)
         return
+    
     hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)
     if not hadDelTicket:
         FBCommon.SetHadDelTicket(curPlayer)
@@ -147,21 +95,7 @@
             posX, posY = IpyGameDataPY.GetFuncEvalCfg('SealDemonFirstPos')
             GameWorld.ResetPlayerPos(curPlayer, posX, posY)
         EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_SealDemon, 0, ChConfig.CME_Log_Start)
-        newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')
-        if lineID not in newbielineList:
-            pass
-#            FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_SealDemon)
-#            # 每日活动
-#            PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_SealDemon)
-        else:
-            hasEnter = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [ChConfig.Def_FBMapID_SealDemon])
-            if hasEnter:
-                GameWorld.DebugLog("    已进入过该新手线路 %s" % lineID, playerID)
-                PlayerControl.PlayerLeaveFB(curPlayer)
-                return
-        UpdateHurtInfo(curPlayer, 0, True)
-     
-    
+        
     # 上鼓舞buff
     encourageLV = gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_EncourageLV)
     if encourageLV > 0:
@@ -169,213 +103,92 @@
     else:
         FBCommon.SendFBEncourageInfo(curPlayer, encourageLV)
         
-    DoFBHelp(curPlayer, tick)
     return
 
-##关闭副本
-# @param tick 时间戳
-# @return 无意义
-# @remarks 
+## 关闭副本
 def OnCloseFB(tick):
-    gameWorld = GameWorld.GetGameWorld()
-
-    gameWorld.SetPropertyID(0)
+    #GameWorld.GetGameWorld().SetPropertyID(0)
     return
 
-##玩家退出副本
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 无意义
+## 玩家退出副本
 def DoExitFB(curPlayer, tick):
-    global g_npcHurtDict
-    gameWorld = GameWorld.GetGameWorld()
     # 清除鼓舞buff
     FBCommon.ClearEncourageBuff(curPlayer, tick)
+    return
+
+## 玩家主动离开副本.
+def DoPlayerLeaveFB(curPlayer, tick):
+    FBCommon.SetHadDelTicket(curPlayer, 0)
+    
     #最后一人
-    if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1:
-        mapID = GameWorld.GetMap().GetMapID()
-        if mapID != ChConfig.Def_FBMapID_SealDemonEx:#单人的不管
-            lineID = gameWorld.GetPropertyID() - 1
-            PyGameData.g_sealDemonPlayerHurtDict[lineID] = {}
-            g_npcHurtDict[lineID] = {}
-            GameWorld.GetGameFB().ClearGameFBDict()
-            GameWorldProcess.CloseFB(tick)
-            return
+    if GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount() == 1:
+        GameWorldProcess.CloseFB(tick)
         
     return
 
-##玩家主动离开副本.
-# @param curPlayer 玩家实例
-# @param tick 时间戳
-# @return 返回值无意义
-def DoPlayerLeaveFB(curPlayer, tick):
-    FBCommon.SetHadDelTicket(curPlayer, 0)
-    #主动退出的去掉排行榜信息
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    playerHurtDict = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {})
-    playerHurtDict.pop(curPlayer.GetPlayerID(), 0)
-    PyGameData.g_sealDemonPlayerHurtDict[lineID] = playerHurtDict
-    return
-
-##玩家切换地图
+## 玩家切换地图
 def DoPlayerChangeMapLogic(curPlayer):
     FBCommon.SetHadDelTicket(curPlayer, 0)
     return
 
 ## 是否副本复活
-#  @param None
-#  @return 是否副本复活
 def OnPlayerReborn():
     return True
 
-
 ## 获得副本帮助信息
-#  @param curPlayer 当前玩家(被通知对象)
-#  @param tick 当前时间
-#  @return None
 def DoFBHelp(curPlayer, tick):
-    #伤害排行信息
-    hurtInfo = []
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    playerHurtList = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {}).items()
-    npcHurtList = g_npcHurtDict.get(lineID, {}).items()
-    
-    syncHurtList = (playerHurtList + npcHurtList)[:5]
-    syncHurtList.sort(key=lambda asd:asd[1][1], reverse=True)
-        
-    for i, info in enumerate(syncHurtList, 1):
-        playerName, hurt = info[1]
-        hurtDict = {}
-        hurtDict["rank"] = i
-        hurtDict["playerName"] = playerName
-        hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue
-        hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue
-        hurtInfo.append(hurtDict)
-    myRank = __GetSelfHurtRank(curPlayer)
-    if myRank and myRank > 5:
-        hurtDict = {}
-        hurtDict["rank"] = myRank
-        info = playerHurtList[myRank - 1]
-        playerName, hurt = info[1]
-        hurtDict["playerName"] = playerName
-        hurtDict["hurt"] = hurt % ChConfig.Def_PerPointValue
-        hurtDict["hurtEx"] = hurt / ChConfig.Def_PerPointValue
-        hurtInfo.append(hurtDict)
-    
-
-    fbHelpDict = {FBCommon.Help_lineID:lineID, "hurtInfo":hurtInfo}
-    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
-    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
     return
 
-def __GetSelfHurtRank(curPlayer):
-    #获取自己的排名
-    playerName = curPlayer.GetName()
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    playerHurtList = __GetSortHurtList(lineID)
-    myRank = 0
-    for i, info in enumerate(playerHurtList):
-        if playerName == info[1][0]:
-            myRank = i + 1
-            break
-    return myRank
-
 ## 副本行为
-#  @param curPlayer 玩家
-#  @param actionType 行为类型
-#  @param actionInfo 行为信息
-#  @param tick 当前时间
-#  @return None
 def DoFBAction(curPlayer, actionType, actionInfo, tick):
     if actionType == 0:
         FBCommon.FbEncourageBuff(curPlayer, FBPlayerDict_EncourageLV, actionInfo, tick)
     return
 
-
-
-## 玩家对NPC造成伤害
-#  @param curPlayer 当前玩家
-#  @param curNPC 
-#  @param hurtHP 
-#  @return None
-def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
-    UpdateHurtInfo(curPlayer, hurtHP)
-    return
-#
-def UpdateHurtInfo(curPlayer, hurtHP, isAdd=False):
-    mapID = GameWorld.GetMap().GetMapID()
-    if mapID == ChConfig.Def_FBMapID_SealDemonEx:
-        return
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    
-    playerName = curPlayer.GetName() 
-    playerID = curPlayer.GetPlayerID()
-    playerHurtDict = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {})
-    if playerID not in playerHurtDict:
-        if not isAdd:
-            return
-        playerHurtDict[playerID] = [playerName, hurtHP]
-    else:
-        playerHurtDict[playerID][1] += hurtHP
-    PyGameData.g_sealDemonPlayerHurtDict[lineID] = playerHurtDict
-    return
-
-## 玩家对NPC造成伤害
-#  @param curPlayer 当前玩家
-#  @param curNPC 
-#  @param hurtHP 
-#  @return None
-def DoFB_NPC_HurtNPC(curNPC, tagNPC, hurtHP):
-    global g_npcHurtDict
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    npcID = curNPC.GetNPCID()
-    guardNPCIDList = __GetGuardNPCIDList(lineID)
-    
-    if npcID not in guardNPCIDList:
-        return
-    npcHurtDict = g_npcHurtDict.get(lineID, {})
-    if npcID not in npcHurtDict:
-        npcName = curNPC.GetName().decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
-        npcHurtDict[npcID] = [npcName, hurtHP]
-    else:
-        npcHurtDict[npcID][1] += hurtHP
-    g_npcHurtDict[lineID] = npcHurtDict
-    return
-
-def __GetGuardNPCIDList(lineID):
-    guardNPCIDList = []
-    refreshIDList = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_SealDemon, lineID)
-    if refreshIDList:
-        for refreshID in refreshIDList:
-            ipyData = IpyGameDataPY.GetIpyGameData("NPCCustomRefresh", refreshID)
-            if not ipyData:
-                continue
-            npcID = ipyData.GetRefreshNPCID()
-            guardNPCIDList.append(npcID)
-    return guardNPCIDList
-
-##---副本总逻辑计时器---
-# @param tick:时间戳
-# @return 无意义
-# @remarks 副本总逻辑计时器
+## 副本总逻辑计时器
 def OnProcess(tick):
-    gameFB = GameWorld.GetGameFB()
-    overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
-    # 结算20秒后强制关闭副本, 防止玩家不捡东西导致不结算,强关后地板上的东西会邮件发放给玩家
-    if overTick and tick - overTick >= ChConfig.Def_FBPickupItemTime:
-        GameWorld.Log("强制踢出玩家关闭副本: overTick=%s,tick=%s" % (overTick, tick))
-        FBCommon.DoLogic_FBKickAllPlayer()
-        return
-    mapID = GameWorld.GetMap().GetMapID()
-    if mapID == ChConfig.Def_FBMapID_SealDemonEx:
-        return
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
-    if lineID <0:
-        return
-
-    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
     
+    fbStep = GameWorld.GetGameFB().GetFBStep()
+    # 副本结束
+    if fbStep == FB_Step_Over:
+        __DoLogic_FB_Over(tick)
+        
     return
+
+def __DoLogic_FB_Over(tick):
+    
+    # 间隔未到
+    if tick - GameWorld.GetGameFB().GetFBStepTick() < ChConfig.Def_FBPickupItemTime:
+        return
+    
+    #副本关闭
+    GameWorldProcess.CloseFB(tick)
+    FBCommon.SetFBStep(FB_Step_Close, tick)
+    return
+
+## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
+#  @param attacker 攻击方
+#  @param defender 防守方
+#  @return bool
+def CheckCanAttackTagObjInFB(attacker, defender):
+    gameFB = GameWorld.GetGameFB()
+    if gameFB.GetFBStep() != FB_Step_Fighting:
+        return False
+    
+    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1 
+    if defender.GetGameObjType() == IPY_GameWorld.gotNPC and defender.GetNPCID() == CurFBLineBOSSID(lineID):
+        atkObjType = attacker.GetGameObjType()
+        if atkObjType == IPY_GameWorld.gotPlayer:
+            return NPCHurtManager.CheckPlayerCanAttackFBNPC(attacker, defender, ChConfig.Def_FBMapID_SealDemon, True)
+        
+        elif atkObjType == IPY_GameWorld.gotNPC:
+            if PetControl.IsPet(attacker) or attacker.GetGameNPCObjType()== IPY_GameWorld.gnotSummon:
+                ownerPlayer = AttackCommon.GetAttackPlayer(attacker)[0]
+                if not ownerPlayer:
+                    return False
+                return NPCHurtManager.CheckPlayerCanAttackFBNPC(ownerPlayer, defender, ChConfig.Def_FBMapID_SealDemon)
+            
+    return True
 
 def DoFB_Npc_KillNPC(attacker, curNPC, tick):
     __FBNPCOnKilled(curNPC, tick)
@@ -390,44 +203,52 @@
     bossID = CurFBLineBOSSID(lineID)
     if curNPC.GetNPCID() != bossID:
         return
-
-    dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()
-
-    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
-    GameWorld.DebugLog('结束 设置BOSS死亡 lineID=%s' % lineID)
-    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')
-    isNewbieLine = lineID in newbielineList
-    if not isNewbieLine:
-        playerHurtList = __GetSortHurtList(lineID)
-        if playerHurtList:
-            killerName, hurtValue = playerHurtList[0][1]
-            NPCCommon.GameServer_KillGameWorldBoss(bossID, killerName, hurtValue)
-            
-        NPCCommon.GameServe_GameWorldBossState(bossID, 0)
-        
-    __DoLogicSealDemonOver(1, tick, dropPosX, dropPosY)
-    GameWorld.GetGameFB().SetGameFBDict(FBDict_IsOver, tick)
-    return
+    FBCommon.SetFBStep(FB_Step_Over, tick)
     
-
-def __GetSortHurtList(lineID):
-    playerHurtDict = PyGameData.g_sealDemonPlayerHurtDict.get(lineID, {})
-    playerHurtList = sorted(playerHurtDict.iteritems(), key=lambda asd:asd[1][1], reverse=True)
-    return playerHurtList
-
-def __DoLogicSealDemonOver(isPass, tick, dropPosX, dropPosY):
-    #结算
+    dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY()
+    
+    GameWorld.DebugLog('结束设置BOSS死亡 lineID=%s' % lineID)
+    
+    NPCCommon.GameServe_GameWorldBossState(bossID, 0)
+    
+    npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
+    if not npcHurtList:
+        GameWorld.ErrLog("没有伤血列表!lineID=%s,bossID=%s" % (lineID, bossID))
+        return
+    
+    isPass = 1
     gameFB = GameWorld.GetGameFB()
     mapID = GameWorld.GetMap().GetMapID()
-    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
     leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID) * 1000
-    playerHurtList = __GetSortHurtList(lineID)
-    playerManager = GameWorld.GetPlayerManager()
-    for rank, hurtInfo in enumerate(playerHurtList, 1):
-        playerID = hurtInfo[0]
-        curPlayer = playerManager.FindPlayerByID(playerID)
+    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
+    for index in xrange(npcHurtList.GetHurtCount()):
+        hurtObj = npcHurtList.GetHurtAt(index)
+        hurtID = hurtObj.GetValueID()
+        hurtType = hurtObj.GetValueType()
         
-        if curPlayer:
+        playerIDList = []
+        if hurtType == ChConfig.Def_NPCHurtTypePlayer:
+            playerIDList = [hurtID]
+            
+        elif hurtType == ChConfig.Def_NPCHurtTypeTeam:
+            teamID = hurtID
+            mapTeamPlayerIDList = PlayerTeam.GetMapTeamPlayerIDList(teamID)
+            for teamPlayerID in mapTeamPlayerIDList:
+                if not npcHurtList.IsNoAssistPlayer(teamPlayerID):
+                    continue
+                playerIDList.append(teamPlayerID)
+        else:
+            continue
+        
+        rank = index + 1
+        if rank == 1:
+            NPCCommon.GameServer_KillGameWorldBoss(bossID, hurtObj.GetHurtName(), hurtObj.GetHurtValue())
+            
+        for playerID in playerIDList:
+            curPlayer = copyMapPlayerManager.FindPlayerByID(playerID)
+            if curPlayer == None:
+                continue
+            
             gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_Rank, rank)
             if not dropPosX or not dropPosY:
                 dropPosX, dropPosY = curPlayer.GetPosX(), curPlayer.GetPosY()
@@ -439,15 +260,7 @@
                 FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_SealDemon, lineID, isPass, overDict)
             else:
                 curPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)
-        else:
-            leaveTick = PlayerControl.GetPlayerLeaveServerTick(playerID)
-            if not leaveTick:
-                continue
-            if tick - leaveTick > ChConfig.Def_PlayerOfflineProtectTime:
-                #离线超过3分钟的不给奖励
-                continue
-            msgStr = str([playerID, lineID, rank])
-            GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'SealDemonOver', msgStr, len(msgStr))
+                
     return
 
 def GiveSealDemonAward(curPlayer, lineID, rank, isMail=False, isClientSend=False, dropItemMapInfo=[]):
@@ -470,23 +283,20 @@
     else:
         #prizeMultiple = 2 if rank == 1 else 1 # 第一名执行双倍掉落奖励,其他一次
         prizeMultiple = 1 # 去除第一名双倍逻辑,改为放在额外奖励产出
-        isDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)
-        if isDouble:
-            addCnt = 2
+        
     equipList = []
-    prizeItemDict ={}
+    prizeItemDict = {}
     bossID = CurFBLineBOSSID(lineID)
     extraItemList = sealDemonIpyData.GetOwnerAwardItemEx() * addCnt if rank == 1 else []
-    #for _ in xrange(addCnt):
-    jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt}, 
-                                                                        mailTypeKey="SealDemonMail", isMail=isMail, extraItemList=extraItemList, prizeMultiple=prizeMultiple, 
-                                                                        dropItemMapInfo=dropItemMapInfo,isVirtualDrop=isClientSend)
+    jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt},
+                                                                        mailTypeKey="SealDemonMail", isMail=isMail, extraItemList=extraItemList, prizeMultiple=prizeMultiple,
+                                                                        dropItemMapInfo=dropItemMapInfo, isVirtualDrop=isClientSend)
     for jsonItem in jsonItemList:
         if 'UserData' in jsonItem:
             equipList.append(jsonItem)
         else:
-            itemID, itemCnt = jsonItem['ItemID'], jsonItem.get('Count',1)
-            prizeItemDict[itemID] = prizeItemDict.get(itemID,0)+itemCnt
+            itemID, itemCnt = jsonItem['ItemID'], jsonItem.get('Count', 1)
+            prizeItemDict[itemID] = prizeItemDict.get(itemID, 0) + itemCnt
     
     GameWorld.DebugLog("封魔坛结算奖励: lineID=%s,bossID=%s,rank=%s,totalExp=%s,totalMoney=%s,jsonItemList=%s" 
                        % (lineID, bossID, rank, totalExp, totalMoney, jsonItemList), curPlayer.GetPlayerID())
@@ -501,7 +311,6 @@
     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, addCnt, [bossID])
 
     #新手线路的更新进去记录
-    newbielineList = IpyGameDataPY.GetFuncEvalCfg('SealDemonNewbieLine')
     GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, 1, False, [ChConfig.Def_FBMapID_SealDemon])
     if isNewbieLine:
         # 未过关不扣次数
@@ -514,7 +323,7 @@
         
     # 每日活动
     PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_SealDemon, addCnt)
-    EventShell.EventRespons_FBEvent(curPlayer, "sealdemon_%s" % (lineID+1))
+    EventShell.EventRespons_FBEvent(curPlayer, "sealdemon_%s" % (lineID + 1))
     EventShell.EventRespons_FBEvent(curPlayer, "sealdemon_0")
     #任务
     if rank == 1 and lineID >= 4:
@@ -541,7 +350,7 @@
             isIn = False
             for itemInfo in PyGameData.g_fbPickUpItemDict[playerID]:
                 if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsBind") == jsonItem.get("IsBind"):
-                    itemInfo["Count"] = itemInfo.get("Count", 1)+ jsonItem.get("Count", 1)
+                    itemInfo["Count"] = itemInfo.get("Count", 1) + jsonItem.get("Count", 1)
                     isIn = True
                     break
             if not isIn:
@@ -578,7 +387,7 @@
 
 def OnClientEndFB(curPlayer, mapID, lineID, dataList):
     #客户端副本发送结束
-    GameWorld.DebugLog('封魔坛 客户端副本发送结束mapID=%s,lineID=%s,dataList=%s' % (mapID,lineID,dataList), curPlayer.GetPlayerID())
+    GameWorld.DebugLog('封魔坛 客户端副本发送结束mapID=%s,lineID=%s,dataList=%s' % (mapID, lineID, dataList), curPlayer.GetPlayerID())
     rank, hurt = dataList[:2]
     prizeItemList = GiveSealDemonAward(curPlayer, lineID, rank, False, True, [curPlayer.GetPosX(), curPlayer.GetPosY(), True])
     if rank == 1 and prizeItemList:
@@ -628,7 +437,6 @@
 def DoPlayerDead(curPlayer):
     return
 
-
 #// B1 03 设置封魔坛多倍击杀 #tagCMSetFMTDouble
 #
 #struct    tagCMSetFMTDouble
@@ -637,18 +445,5 @@
 #    BYTE        IsDouble;        //是否双倍
 #};
 def SetFMTDouble(playerIndex, clientData, tick):
-    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
-    if GameWorld.GetMap().GetMapID() == ChConfig.Def_FBMapID_SealDemon:
-        return
-    if not curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTOldDouble) and not PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_FMTDouble):
-        return
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FMTDouble, clientData.IsDouble)
-    NotifyFMTDouble(curPlayer)
     return
 
-def NotifyFMTDouble(curPlayer):
-    packData = ChPyNetSendPack.tagMCFMTDoubleState()
-    packData.IsDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)
-    packData.OldDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTOldDouble)
-    NetPackCommon.SendFakePack(curPlayer, packData)
-    return
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 3c88207..89936b0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -5147,7 +5147,8 @@
         if isDead:
             GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" 
                           % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
-        if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
+        #if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
+        if NPCHurtManager.GetPlayerHurtList(curNPC):
             maxHurtInfo = NPCHurtManager.RefreshHurtList(curNPC, tick, refreshInterval, isDead)
             if maxHurtInfo:
                 tagObj, ownerType, ownerID = maxHurtInfo
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
index 2af4573..7ceffe5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
@@ -741,6 +741,7 @@
             return
         self.__assistAwardItemID = liheItemID
         
+        fbType = GameWorld.GetMap().GetMapFBTypeByMapID(mapID)
         friendAddAssistMoneyPer = IpyGameDataPY.GetFuncCfg("AssistAward", 3)
         GameWorld.DebugLog("执行协助奖励逻辑", self.npcID, self.lineID)
         copyPlayerManager = GameWorld.GetMapCopyPlayerManager()
@@ -768,8 +769,14 @@
                     addAssistMoney += int(assistMoney * friendAddAssistMoneyPer / 100.0)
                 GameWorld.DebugLog("协助方给活跃令奖励: assistPlayerID=%s,assistMoney=%s,isFriend=%s,addAssistMoney=%s" 
                                    % (assistPlayerID, assistMoney, isFriend, addAssistMoney), self.npcID, self.lineID)
-                PlayerControl.GiveMoney(assistPlayer, ShareDefine.TYPE_Price_XianyuanCoin, addAssistMoney) # 给活跃令无视发布方是否在线
-                
+                PlayerControl.GiveMoney(assistPlayer, ShareDefine.TYPE_Price_FamilyActivity, addAssistMoney) # 给活跃令无视发布方是否在线
+                if fbType == IPY_GameWorld.fbtNull:
+                    PlayerControl.NotifyCode(assistPlayer, "AssistSuccess")
+                else:
+                    overDict = {FBCommon.Over_isAssist:1, FBCommon.Over_money:FBCommon.GetJsonMoneyList({ShareDefine.TYPE_Price_FamilyActivity:addAssistMoney}),
+                                FBCommon.Over_itemInfo:[]}
+                    FBCommon.NotifyFBOver(assistPlayer, mapID, PlayerControl.GetFBFuncLineID(assistPlayer), 1, overDict)
+                    
                 if noAssistPlayer:
                     todayGiftCount = assistPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GetThanksGiftCount % liheItemID)
                     assistAwardPlayerDict[assistPlayerID] = {"PlayerName":assistPlayer.GetPlayerName(), "Job":assistPlayer.GetJob(), 
@@ -934,10 +941,12 @@
     if key not in PyGameData.g_npcHurtDict:
         ## 只统计最大伤血归属的boss
         npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
-        if not npcData:
+        if not npcData or not ChConfig.IsGameBoss(npcData):
             return defendHurtList
-        if not npcData.GetIsBoss() or NPCCommon.GetDropOwnerType(npcData) != ChConfig.DropOwnerType_MaxHurt:
-            return defendHurtList
+        if NPCCommon.GetDropOwnerType(npcData) != ChConfig.DropOwnerType_MaxHurt:
+            mapID = GameWorld.GetMap().GetMapID()
+            if mapID not in [ChConfig.Def_FBMapID_SealDemon]:
+                return defendHurtList
         defendHurtList = PlayerHurtList(lineID, objID, npcID)
         PyGameData.g_npcHurtDict[key] = defendHurtList
     defendHurtList = PyGameData.g_npcHurtDict[key]
@@ -997,3 +1006,18 @@
         return False
     return defendHurtList.IsAssistPlayer(playerID)
 
+def CheckPlayerCanAttackFBNPC(curPlayer, curNPC, mapID, isNotify=False):
+    ## 检查玩家可否攻击有副本次数的NPC
+    enterCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_EnterFbCntDay % mapID)
+    if enterCnt < FBCommon.GetEnterFBMaxCnt(curPlayer, mapID):
+        return True
+    
+    # 没有次数的,如果是助战玩家也可攻击
+    if IsAssistPlayer(curPlayer.GetPlayerID(), curNPC):
+        return True
+    
+    if isNotify:
+        PlayerControl.NotifyCode(curPlayer, "AttackFBBossLimit")
+        
+    return False
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py
index fae0769..169a3ae 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py
@@ -54,8 +54,11 @@
         return
     
     curNPC = GameWorld.FindNPCByNPCID(npcID)
-    if not curNPC or curNPC.GetID() != objID:
-        GameWorld.DebugLog("协助NPC不存在无法协助!", playerID)
+    if not curNPC:
+        GameWorld.DebugLog("协助NPC不存在无法协助!npcID=%s" % npcID, playerID)
+        return
+    if curNPC.GetID() != objID:
+        GameWorld.DebugLog("协助NPC实例ID不一致无法协助!npcID=%s,curNPC.GetID()=%s,sendObjID=%s" % (npcID, curNPC.GetID(), objID), playerID)
         return
     
     ipyData = IpyGameDataPY.GetIpyGameDataNotLog('BOSSInfo', npcID)
@@ -73,9 +76,7 @@
         return
     
     mapID = curPlayer.GetMapID()
-    lineID = 0
-    if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull: # 副本型boss,如封魔坛
-        lineID = PlayerControl.GetFBFuncLineID(curPlayer)
+    lineID = GameWorld.GetGameWorld().GetLineID()
     queryData = [mapID, lineID, npcID, objID]
     QueryGameServer_PlayerAssist(playerID, "RequestAssistBoss", queryData)
     return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index f7d7a80..490a212 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1523,9 +1523,8 @@
         NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FromFBLineID, lineID)
         GameWorld.DebugLog("进入副本时,最后一次离开的可返回的副本ID更新!mapID=%s,lineID=%s,Pos(%s,%s)" % (mapID, lineID, posX, posY))
         
-    # 离开地图,暂时只处理离开中立、组队副本
-    if curPlayer.GetMapID() in IpyGameDataPY.GetFuncEvalCfg("MapLine", 4) or GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtTeam:
-        NPCHurtManager.OnPlayerLeaveMap(curPlayer)
+    # 离开地图
+    NPCHurtManager.OnPlayerLeaveMap(curPlayer)
         
     # 从副本中切图
     if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 3edcfd4..3eaa6a6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -38,8 +38,6 @@
 
 g_sgzztopPlayerName = '' #上古战场积分王名字
 
-g_sealDemonPlayerHurtDict = {} #封魔坛玩家伤害排行信息
-
 FBEnterTimeLimiitMapID = [] # 副本开启有时间限制的副本ID,由GameServer同步得到
 
 FBOpenTimeRecord = {} #限时副本开启时间记录

--
Gitblit v1.8.0