8346 【恺英】【后端】协助系统(封魔坛支持协助,去除封魔坛旧版伤血统计)
14个文件已修改
496 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerXMZZ.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PrintNPCHurt.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_SealDemon.py 399 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerAssist.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
        #等级奖励
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)
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":
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 = '' #积分王名
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -705,8 +705,8 @@
        GameWorld.ErrLog("NPCAddObjInHurtList NoFindObj")
        return
    if curTaglNPCHPBefore < hurtHP:
        hurtHP = curTaglNPCHPBefore
    #if curTaglNPCHPBefore < hurtHP:
    #    hurtHP = curTaglNPCHPBefore
        
    curObjType = curObj.GetGameObjType()
    if curObjType == IPY_GameWorld.gotPlayer:
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]
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))
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' #是否协助
#副本行为
(
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()
    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,20 +95,6 @@
            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)
@@ -169,52 +103,27 @@
    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)
    #最后一人
    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
    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
    #最后一人
    if GameWorld.GetGameWorld().GetMapCopyPlayerManager().GetPlayerCount() == 1:
        GameWorldProcess.CloseFB(tick)
    return
##玩家切换地图
@@ -223,159 +132,63 @@
    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):
    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()
    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
    if gameFB.GetFBStep() != FB_Step_Fighting:
        return False
    lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
    if lineID <0:
        return
    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)
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
        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
    return True
def DoFB_Npc_KillNPC(attacker, curNPC, tick):
    __FBNPCOnKilled(curNPC, tick)
@@ -390,44 +203,52 @@
    bossID = CurFBLineBOSSID(lineID)
    if curNPC.GetNPCID() != bossID:
        return
    FBCommon.SetFBStep(FB_Step_Over, tick)
    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)
    npcHurtList = NPCHurtManager.GetPlayerHurtList(curNPC)
    if not npcHurtList:
        GameWorld.ErrLog("没有伤血列表!lineID=%s,bossID=%s" % (lineID, bossID))
    return
    
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):
    #结算
    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,14 +283,11 @@
    else:
        #prizeMultiple = 2 if rank == 1 else 1 # 第一名执行双倍掉落奖励,其他一次
        prizeMultiple = 1 # 去除第一名双倍逻辑,改为放在额外奖励产出
        isDouble = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FMTDouble)
        if isDouble:
            addCnt = 2
    equipList = []
    prizeItemDict ={}
    bossID = CurFBLineBOSSID(lineID)
    extraItemList = sealDemonIpyData.GetOwnerAwardItemEx() * addCnt if rank == 1 else []
    #for _ in xrange(addCnt):
    jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_SealDemon, {bossID:addCnt}, 
                                                                        mailTypeKey="SealDemonMail", isMail=isMail, extraItemList=extraItemList, prizeMultiple=prizeMultiple, 
                                                                        dropItemMapInfo=dropItemMapInfo,isVirtualDrop=isClientSend)
@@ -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:
        # 未过关不扣次数
@@ -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
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
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,7 +769,13 @@
                    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)
@@ -934,9 +941,11 @@
    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:
        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
@@ -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
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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1523,8 +1523,7 @@
        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)
        
    # 从副本中切图
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -38,8 +38,6 @@
g_sgzztopPlayerName = '' #上古战场积分王名字
g_sealDemonPlayerHurtDict = {} #封魔坛玩家伤害排行信息
FBEnterTimeLimiitMapID = [] # 副本开启有时间限制的副本ID,由GameServer同步得到
FBOpenTimeRecord = {} #限时副本开启时间记录