hxp
2022-02-21 0c27822ef5e6c67782ed143a4ff03ecfbdfda1fb
9415 【BT】【后端】古神战场(副本内功能完整版本)
27个文件已修改
1个文件已添加
2683 ■■■■ 已修改文件
PySysDB/PySysDBPY.h 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py 1773 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py 210 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -446,6 +446,15 @@
    DWORD        IceLodeFightPower;    //冰晶矿脉扫荡战斗力
};
//特殊地图玩家属性公式表
struct tagSpecMapPlayerAttrFormat
{
    DWORD        _DataMapID;    //数据地图ID
    char        AttrName;    //属性名
    char        AttrValueFormat;    //最终属性值公式(可用参数属性名)
};
//GM测试属性表
struct tagGMAttr
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
@@ -4,12 +4,12 @@
#
##@package CrossBattlefield
#
# @todo:跨服战场
# @todo:跨服战场/古神战场
# @author hxp
# @date 2022-01-06
# @version 1.0
#
# 详细描述: 跨服战场
# 详细描述: 跨服战场/古神战场
#
#-------------------------------------------------------------------------------
#"""Version = 2022-01-06 20:30"""
@@ -180,10 +180,13 @@
    if not GameWorld.IsCrossServer():
        return
    
    enterWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 3, {}) # 周参与榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    callWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 4, {}) # 周召集榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    scoreWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 5, {}) # 周参与榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    enterWeekMoneyItemID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboardJoin", 3) # 周参与榜额外奖励货币物品ID
    enterWeekMoneyMultiDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboardJoin", 4, {}) # 周参与榜额外奖励货币名次对应倍值
    enterWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboardJoin", 2, {}) # 周参与榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    callWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 2, {}) # 周召集榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    scoreWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 3, {}) # 周积分榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    
    enterWeekMoneyMultiIntDict = {int(k):v for k, v in enterWeekMoneyMultiDict.items()}
    enterWeekOrderIntAwardDict = {int(k):v for k, v in enterWeekOrderAwardDict.items()}
    callWeekOrderIntAwardDict = {int(k):v for k, v in callWeekOrderAwardDict.items()}
    scoreWeekOrderIntAwardDict = {int(k):v for k, v in scoreWeekOrderAwardDict.items()}
@@ -209,11 +212,17 @@
                if not billboardData:
                    continue
                playerID = billboardData.ID
                cmpValue = billboardData.CmpValue
                rank = i + 1
                awardItemList = GameWorld.GetOrderValueByDict(awardDict, rank)
                paramList = [rank]
                if billboardType == ShareDefine.Def_CBT_BattlefieldWJoin and enterWeekMoneyItemID:
                    moneyBaseCount, multiValue = GameWorld.GetOrderValueByDict(enterWeekMoneyMultiIntDict, rank) # 奖励货币倍值
                    #基础保底值(不同名次可能不一样) + 名次倍率*次数
                    awardMoneyCount = int(moneyBaseCount + multiValue * cmpValue)
                    awardItemList.append([enterWeekMoneyItemID, awardMoneyCount, 0])
                PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, paramList, crossMail=True)
            billboardObj.ClearData()
            
    return
@@ -469,13 +478,8 @@
                GameWorld.DebugLog("跨服PK赛季未开启中,跨服战场系统开启广播不处理!")
                continue
            
            notifyKey = "CrossBattlefieldOpenSys"
            paramList = [notifyOpenMinute]
            country = 0
            serverGroupIDList = []
            crossNotifyList = []
            crossNotifyList.append([ShareDefine.CrossNotify_World, [country, notifyKey, paramList]])
            PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList)
            serverGroupIDList = zoneIpyData.GetServerGroupIDList()
            PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenSys", [notifyOpenMinute])
            
        return
    
@@ -503,12 +507,7 @@
        matchTickSortList = sorted(buyPlayerInfo.values(), key=operator.attrgetter("buyTime"))
        buyRec = matchTickSortList[0]
        
        notifyKey = "CrossBattlefieldOpenPlayer"
        paramList = [buyRec.playerName, notifyOpenMinute]
        country = 0
        crossNotifyList = []
        crossNotifyList.append([ShareDefine.CrossNotify_World, [country, notifyKey, paramList]])
        PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList)
        PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOpenPlayer", [buyRec.playerName, notifyOpenMinute])
        
    return
@@ -669,7 +668,7 @@
    buyPlayerInfo[playerID] = buyRec
    
    # 上榜
    billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 2) # 周召集榜上榜至少次数
    billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # 周召集榜上榜至少次数
    groupValue1, dataID, name1, name2 = zoneID, playerID, playerName, ""
    type2, value1, value2 = job, realmLV, 0
    cmpValue = buyOpenCountWeek + 1
@@ -758,9 +757,9 @@
    ## 跨服战场地图结算
    overTime = int(time.time())
    hmNum = GetCrossBattlefieldState()
    fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, superItemPlayerName, scoreKingID, scoreKingName, battlePlayerList = msgList
    GameWorld.Log("跨服战场地图同步结果: hmNum=%s,zoneID=%s,funcLineID=%s,winnerFaction=%s,superItemInfo=%s,superItemPlayerID=%s,scoreKingID=%s,battlePlayerCount=%s"
                  % (hmNum, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, scoreKingID, len(battlePlayerList)), fbPropertyID)
    fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList = msgList
    GameWorld.Log("跨服战场地图同步结果: hmNum=%s,zoneID=%s,funcLineID=%s,winnerFaction=%s,superItemInfo=%s,finalSuperItemPlayerID=%s,superItemPlayerIDList=%s,scoreKingID=%s,battlePlayerCount=%s"
                  % (hmNum, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, superItemPlayerIDList, scoreKingID, len(battlePlayerList)), fbPropertyID)
    
    winnerOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 2, {}) # 胜利方名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
    loserOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 3, {}) # 失败方名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
@@ -770,17 +769,19 @@
    winnerOrderIntAwardDict = {int(k):v for k, v in winnerOrderAwardDict.items()}
    loserOrderIntAwardDict = {int(k):v for k, v in loserOrderAwardDict.items()}
    
    billboardEnterCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # 周参与榜上榜至少次数
    billboardEnterCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboardJoin", 1) # 周参与榜上榜至少次数
    
    syncPlayerDataInfo = {}
    winnerPlayerIDList, loserPlayerIDList = [], []
    for playerInfo in battlePlayerList:
        faction, rank, playerID, job, realmLV, name, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = playerInfo
        isWinner = 0
        playerID, job, realmLV, name, \
            isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, \
            isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
            factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt \
                = playerInfo
        paramList = [rank]
        if faction == winnerFaction:
            isWinner = 1
            winnerPlayerIDList.append(playerID)
            orderAwardMailKey = "CrossBattlefieldOrderWin"
            orderAwardItemList = GameWorld.GetOrderValueByDict(winnerOrderIntAwardDict, rank)
@@ -809,10 +810,12 @@
            cmpValue = highScoreWeekTotal
            CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWScore, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue)
            
        GameWorld.Log("    战场阵营玩家: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallEnter=%s"
                      % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter), fbPropertyID)
        GameWorld.Log("    战场阵营玩家: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallOpen=%s,isCalled=%s"
                      % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallOpen, isCalled), fbPropertyID)
        
        syncPlayerDataInfo[playerID] = [highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]
        syncPlayerDataInfo[playerID] = [isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek,
                                        isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt,
                                        factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt]
        
    # 参与奖励邮件
    if winnerPlayerIDList:
@@ -822,9 +825,10 @@
    
    # 大奖获得者邮件
    superItemID, superItemCount = 0, 0
    if superItemPlayerID and superItemInfo and len(superItemInfo) == 3:
    if superItemPlayerIDList and superItemInfo and len(superItemInfo) == 3:
        superItemID, superItemCount = superItemInfo[0], superItemInfo[1]
        PlayerCompensation.SendMailByKey("CrossBattlefieldSuperAward", [superItemPlayerID], [superItemInfo], crossMail=True)
        for superItemPlayerID in superItemPlayerIDList:
            PlayerCompensation.SendMailByKey("CrossBattlefieldSuperAward", [superItemPlayerID], [superItemInfo], crossMail=True)
        
    crossZoneName = GameWorld.GetCrossZoneName()
    zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
@@ -848,7 +852,7 @@
        
    # 本分区全服:XX阵营胜利,xxx为本场积分王,xxx获得了古神大奖XXX,下个场次预计将在XX点开放。
    if battlePlayerList:
        msgParamList = [winnerFaction, scoreKingName, superItemPlayerName, superItemID, superItemCount, nextBattleTimeStr]
        msgParamList = [winnerFaction, scoreKingName, finalSuperItemPlayerName, superItemID, superItemCount, nextBattleTimeStr]
        PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOver", msgParamList)
    return
@@ -887,9 +891,8 @@
        return
    
    for playerID, playerData in syncPlayerDataInfo.items():
        highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = playerData
        if PlayerControl.GetDBPlayerAccIDByID(playerID):
            msgInfo = ["BattlefieldOver", [overTime, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]]
            msgInfo = ["BattlefieldOver", [overTime] + playerData]
            CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo)
            
    return
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
@@ -106,6 +106,8 @@
        if notifyType == ShareDefine.CrossNotify_World:
            country, msgMark, msgParamList = params
            openServerDayLimit = IpyGameDataPY.GetFuncCfg("CrossRealmCfg", 1)
            if msgMark.startswith("CrossBattlefield"):
                openServerDayLimit = IpyGameDataPY.GetFuncCfg("CrossRealmCfg", 2)
            openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
            if openServerDay < openServerDayLimit:
                GameWorld.DebugLog("开服天不足,不处理该跨服广播! openServerDay=%s < %s" % (openServerDay, openServerDayLimit))
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1800,7 +1800,27 @@
SuccType_FeastRedPack_CrossPK, # 节日红包 - 跨服PK x次  141
SuccType_FeastRedPack_FBSweep, # 节日红包 - 副本扫荡 x次  142
SuccType_PassSkyTower, #通关天星塔 143
) = range(1, 144)
SuccType_Battlefield_Join, # 古神战场 - 参与 x次  144
SuccType_Battlefield_CallOpen, # 古神战场 - 召集开启 x次  145
SuccType_Battlefield_Called, # 古神战场 - 当被召集人 x次  146
SuccType_Battlefield_WinJ, # 古神战场 - 道家获胜 x次  147
SuccType_Battlefield_WinE, # 古神战场 - 佛家获胜 x次  148
SuccType_Battlefield_KillCnt, # 古神战场 - 击败玩家 x次  149
SuccType_Battlefield_CKillCnt, # 古神战场 - 连续击败y玩家 x次  150
SuccType_Battlefield_KillBoss, # 古神战场 - 阵营击败boss x次  151
SuccType_Battlefield_KillScoreKing, # 古神战场 - 不同场次击败积分王 x次  152
SuccType_Battlefield_KillGuard, # 古神战场 - 击败守卫  x次  153
SuccType_Battlefield_Score, # 古神战场 - 累计获得个人积分 xx  154
SuccType_Battlefield_ScoreMore, # 古神战场 - 单场个人积分超过yy积分 x次  155
SuccType_Battlefield_AuraScore, # 古神战场 - 累计在积分光环中获得积分 xx  156
SuccType_Battlefield_SuperItem, # 古神战场 - 累计获得古神大奖 x次  157
SuccType_Battlefield_FactionBuff, # 古神战场 - 累计采集阵营buff x次  158
SuccType_Battlefield_PersonBuff, # 古神战场 - 累计获得个人buff x次  159
SuccType_Battlefield_Crystal, # 古神战场 - 累计采集占领资源 x次  160
SuccType_Battlefield_Wall, # 古神战场 - 累计采集积分墙 x次  161
SuccType_Battlefield_BillFirst, # 古神战场 - 任意周榜榜首 x次  162
SuccType_Battlefield_BillIn, # 古神战场 - 结算时累计上榜 x次  163
) = range(1, 164)
# 节日红包成就类型
FeastRedPackSuccessTypeList = range(SuccType_FeastRedPack_TalkWorld, SuccType_FeastRedPack_FBSweep + 1)
@@ -1836,7 +1856,7 @@
ContainSuccessTypeList = [SuccType_CompoundItemEx, SuccType_PickUpItem, SuccType_MWSkillUp]
#传进来的条件是配置条件的整数倍的成就类型
MultipleSuccessTypeList = [SuccType_ElderBattlefieldConKill]
MultipleSuccessTypeList = [SuccType_ElderBattlefieldConKill, SuccType_Battlefield_CKillCnt]
#增加进度前需要重置的成就类型
NeedResetSuccessTypeList = [
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -1034,7 +1034,7 @@
def CheckIsAvailableTag(attacker, defender):
    if defender == None or defender.GetID() == 0:
        return False
    if GameObj.GetHP(attacker) <= 0 or GameObj.GetHP(defender) <= 0 :
    if GameObj.GetHP(attacker) <= 0 or GameObj.GetHP(defender) <= 0:
        #对象已经死亡
        return False
    
@@ -1997,6 +1997,7 @@
    if tick - defObj.GetDictByKey(ChConfig.Def_PlayerKey_SomersaultTime) < 500:
        return 0, ChConfig.Def_HurtType_Miss
    
    multiValue = 1 # 伤害倍值
    summonAtkPer = 1    # 召唤继承提高基础攻击力,取表
    summonAtkObj = atkwargs.get('orgAtkObj', None) if atkwargs.get('orgAtkObj', None) else atkObj
    if summonAtkObj.GetGameObjType() == IPY_GameWorld.gotNPC and summonAtkObj.GetGameNPCObjType() == IPY_GameWorld.gnotSummon:
@@ -2262,6 +2263,7 @@
        dFinalHurtReducePer = 0             # 最终伤害减少百分比 默认0
        
    #攻击字典 { 攻击类型 : '公式' }
    mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
    hurtDist = ReadChConfig.GetEvalChConfig('CalcAttackValue')
    if suppressLV:
@@ -2284,10 +2286,12 @@
    if aRealmLV == 0 or dRealmLV == 0:
        SuppressValueRealmRate = 10000
    else:
        SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula("SuppressValueRealm", hurtDist["SuppressValueRealm"])))
        suppressRealmRateMapKey = "SuppressValueRealm_%s" % mapID
        if suppressRealmRateMapKey not in hurtDist:
            suppressRealmRateMapKey = "SuppressValueRealm"
        SuppressValueRealmRate = int(eval(FormulaControl.GetCompileFormula(suppressRealmRateMapKey, hurtDist[suppressRealmRateMapKey])))
        
    # 骑宠争夺最终伤害衰减
    # 骑宠争夺最终伤害衰减
    if defObjType == IPY_GameWorld.gotNPC and FamilyRobBoss.IsHorsePetRobBoss(defObj.GetNPCID()):
        ownerPlayer, npcObjType = GetAttackPlayer(atkObj)
            
@@ -2302,7 +2306,6 @@
    hurtFormulaKey = "%sV%s_%s" % (atkStateMark, defStateMark, atkType)
    
    suppressLVGroup = 0 # NPC压制等级组编号
    mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
    mapHurtKey = "%s_%s" % (hurtFormulaKey, mapID)
    if mapHurtKey in hurtDist:
        hurtFormulaKey = mapHurtKey
@@ -2331,10 +2334,17 @@
        hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
    hurtFormula = hurtDist[hurtFormulaKey]
    hurtValue = int(eval(FormulaControl.GetCompileFormula(hurtFormulaKey, hurtFormula)))
    if isDeadlyHit:
        hurtValue *= deadlyHitMultiValue
    if atkObjType == IPY_GameWorld.gotPlayer and defObjType == IPY_GameWorld.gotNPC and mapID == ChConfig.Def_FBMapID_CrossBattlefield:
        multiValue = FBLogic.GetFBPlayerHurtNPCMultiValue(atkObj, defObj)
    if multiValue != 1:
        hurtValue = int(hurtValue * multiValue)
    #hurtValue = min(max(hurtValue, 0), ChConfig.Def_UpperLimit_DWord)
    
    if hurtType == ChConfig.Def_HurtType_Normal and atkSkillPerYinji > 0:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
@@ -62,8 +62,13 @@
        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
    
    defenderCampType = NPCCommon.GetFaction(curNormalNPC)
    tagFaction = curTagPlayer.GetFaction()
    if tagFaction and defenderCampType:
        if tagFaction == defenderCampType:
            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
    #正义的 不攻击玩家 宠物以及玩家的召唤兽
    if defenderCampType == ChConfig.CampType_Justice:
    elif defenderCampType == ChConfig.CampType_Justice:
        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
    
    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
@@ -62,8 +62,13 @@
#  @remarks 函数详细说明.
def GetTagRelation(curPlayer, curTagNormalNPC, skill, tick):
    defenderCampType = NPCCommon.GetFaction(curTagNormalNPC)
    curFaction = curPlayer.GetFaction()
    if curFaction and defenderCampType:
        if curFaction == defenderCampType:
            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
    #不攻击正义的需要去保护的 这里有女神和守卫
    if defenderCampType == ChConfig.CampType_Justice:
    elif defenderCampType == ChConfig.CampType_Justice:
        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
    
    #私有木桩只能自己打自己的
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3057,8 +3057,6 @@
Def_NPC_Dict_SpeedPer = "SpeedPer" # 移动速度变更百分比
Def_NPC_Dict_Faction = "Faction" # 阵营
# 延迟攻击时长, 毫秒
Def_NPC_Dict_AtkDelayTick = "AtkDelayTick" # 延迟攻击时长
Def_NPC_Dict_AtkStartTick = "AtkStartTick" # 开始攻击tick
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py
@@ -30,11 +30,12 @@
    
    if not cmdList:
        GameWorld.DebugAnswer(curPlayer, "--------------------------------")
        GameWorld.DebugAnswer(curPlayer, "设置玩家击杀: CrossBattle 1 击杀数 [可选玩家ID]")
        GameWorld.DebugAnswer(curPlayer, "设置玩家积分: CrossBattle 2 总积分 [可选玩家ID]")
        GameWorld.DebugAnswer(curPlayer, "设置阵营击杀: CrossBattle 3 击杀数 [可选阵营ID]")
        GameWorld.DebugAnswer(curPlayer, "设置玩家积分: CrossBattle 1 总积分 [可选玩家ID]")
        GameWorld.DebugAnswer(curPlayer, "设置玩家击杀: CrossBattle 2 击杀数 [可选玩家ID]")
        GameWorld.DebugAnswer(curPlayer, "设置玩家贡献: CrossBattle 3 贡献度 [可选玩家ID]")
        GameWorld.DebugAnswer(curPlayer, "设置阵营积分: CrossBattle 4 总积分 [可选阵营ID]")
        GameWorld.DebugAnswer(curPlayer, "重置大奖信息: CrossBattle 5 [可选是否重新随机]")
        GameWorld.DebugAnswer(curPlayer, "重新随机大奖: CrossBattle 5")
        GameWorld.DebugAnswer(curPlayer, "复活阵营守卫: CrossBattle 6")
        GameWorld.DebugAnswer(curPlayer, "可选玩家/阵营ID没填则默认自身")
        return
    
@@ -45,38 +46,35 @@
    if value1 in [1, 2, 3, 4, 5, 6] and not GameWorld.IsCrossServer() or mapID != ChConfig.Def_FBMapID_CrossBattlefield:
        GameWorld.DebugAnswer(curPlayer, "该命令需在跨服战场使用CrossServer发送")
        return
    # 设置玩家击杀
    if value1 == 1:
        setCount = cmdList[1] if len(cmdList) > 1 else 1
        tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
        battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
        battleObj.killCount = setCount
        GameWorld.DebugAnswer(curPlayer, "玩家(%s)击杀数: %s" % (tagPlayerID, battleObj.killCount))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
        return
    # 设置玩家积分
    if value1 == 2:
    if value1 == 1:
        setScore = cmdList[1] if len(cmdList) > 1 else 1
        tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
        battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
        battleObj.score = setScore
        battleObj.addPlayerScore(curPlayer, setScore - battleObj.score)
        GameWorld.DebugAnswer(curPlayer, "玩家(%s)积分: %s" % (tagPlayerID, battleObj.score))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshCrossBattlefield) # 触发刷新FBHelp
        return
    
    # 设置阵营击杀
    if value1 == 3:
    # 设置玩家击杀
    if value1 == 2:
        setCount = cmdList[1] if len(cmdList) > 1 else 1
        tagFaction = cmdList[2] if len(cmdList) > 2 else 0
        if not tagFaction or tagFaction not in ShareDefine.CampTypeList:
            battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(playerID)
            tagFaction = battleObj.faction
        factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(tagFaction)
        factionObj.killCount = setCount
        GameWorld.DebugAnswer(curPlayer, "阵营(%s)击杀数: %s" % (tagFaction, factionObj.killCount))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
        tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
        battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
        battleObj.addKillCount(setCount - battleObj.killCount)
        GameWorld.DebugAnswer(curPlayer, "玩家(%s)击杀数: %s, 连杀数: %s" % (tagPlayerID, battleObj.killCount, battleObj.continueKillCount))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshCrossBattlefield) # 触发刷新FBHelp
        return
    # 设置玩家贡献度
    if value1 == 3:
        setProgress = cmdList[1] if len(cmdList) > 1 else 1
        tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
        battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
        battleObj.addSuperItemContribution(setProgress - battleObj.superItemContribution)
        GameWorld.DebugAnswer(curPlayer, "玩家(%s)贡献度: %s" % (tagPlayerID, battleObj.superItemContribution))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshCrossBattlefield) # 触发刷新FBHelp
        return
    
    # 设置阵营积分
@@ -87,32 +85,23 @@
            battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(playerID)
            tagFaction = battleObj.faction
        factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(tagFaction)
        factionObj.score = setScore
        factionObj.addFactionScore(setScore - factionObj.score)
        GameWorld.DebugAnswer(curPlayer, "阵营(%s)积分: %s" % (tagFaction, factionObj.score))
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshCrossBattlefield) # 触发刷新FBHelp
        return
    
    # 重置大奖信息
    if value1 == 5:
        isRand = cmdList[1] if len(cmdList) > 1 else 1
        worldObj = GameLogic_CrossBattlefield.GetBattleWorld()
        worldObj.superItemPlayerID = 0
        worldObj.superItemPlayerName = ""
        if isRand:
            worldObj.RandSuperTask()
        for faction in ShareDefine.CampTypeList:
            if not faction:
                continue
            factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(faction)
            factionObj.superTaskValue = 0
            factionObj.superTaskFinishCount = 0
            factionObj.setSuperTaskValueMax(worldObj)
            for battleObj in factionObj.factionPlayerDict.values():
                battleObj.superTaskValue = 0
                battleObj.superTaskFinishCount = 0
                battleObj.setSuperTaskValueMax(worldObj)
        GameWorld.DebugAnswer(curPlayer, "重置大奖信息OK!")
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
        worldObj.RandSuperTask()
        GameWorld.DebugAnswer(curPlayer, "重新随机大奖OK! %s" % worldObj.superItemInfo)
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshCrossBattlefield) # 触发刷新FBHelp
        return
    # 复活阵营守卫
    if value1 == 6:
        rebornNPCIDList = GameLogic_CrossBattlefield.rebornGurad()
        GameWorld.DebugAnswer(curPlayer, "复活阵营守卫! %s" % rebornNPCIDList)
        return
    
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
@@ -73,7 +73,12 @@
def __DoKillNPC(curPlayer, curNPC, tick):
    if not curNPC or curNPC.GetID() == 0 or GameObj.GetHP(curNPC) <= 0:
        return
    if NPCCommon.GetFaction(curNPC) == ChConfig.CampType_Justice:
    curFaction = curPlayer.GetFaction()
    npcFaction = NPCCommon.GetFaction(curNPC)
    if curFaction and npcFaction:
        if curFaction == npcFaction:
            return
    elif npcFaction == ChConfig.CampType_Justice:
        return
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:
        return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py
@@ -18,11 +18,30 @@
import ChConfig
import GameWorld
import PlayerControl
import IpyGameDataPY
import ShareDefine
import PetControl
import PlayerPet
import PetClear
import OpenFunc
#---------------------------------------------------------------------
#逻辑实现
def __Help(curPlayer, petNumNameDict):
    GameWorld.DebugAnswer(curPlayer, "------------------")
    GameWorld.DebugAnswer(curPlayer, "重置灵宠: Pet 0 [可选第几只]")
    GameWorld.DebugAnswer(curPlayer, "激活所有: Pet 99 [可选是否满阶]")
    GameWorld.DebugAnswer(curPlayer, "激活指定: Pet 第几只 阶级")
    GameWorld.DebugAnswer(curPlayer, "培养灵宠: Pet 培养类型 等阶 丹数")
    GameWorld.DebugAnswer(curPlayer, "注:重置灵宠需重登")
    petNumList = petNumNameDict.keys()
    petNameNumInfo = ""
    for i, petNum in enumerate(petNumList, 1):
        petNameNumInfo += "%s-%s;" % (petNumNameDict[petNum], petNum)
        if petNum % 3 == 0 or i == len(petNumList):
            GameWorld.DebugAnswer(curPlayer, petNameNumInfo)
            petNameNumInfo = ""
    return
## GM命令执行入口
#  @param curPlayer 当前玩家
@@ -31,29 +50,117 @@
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    
    petNumNameDict = {}
    petNPCIDNumDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetPetInfoCount()):
        ipyData = ipyDataMgr.GetPetInfoByIndex(index)
        needItemID = ipyData.GetUnLockNeedItemID()
        curItem = GameWorld.GetGameData().GetItemByTypeID(needItemID)
        if not curItem:
            continue
        itemName = curItem.GetName()
        petName = itemName.replace("灵宠:", "")
        petNum = index + 1
        petNPCID = ipyData.GetID()
        petNPCIDNumDict[petNPCID] = petNum
        petNumNameDict[petNum] = petName
    petNumList = sorted(petNumNameDict.keys())
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置所有灵宠: Pet 0")
        GameWorld.DebugAnswer(curPlayer, "设置培养灵宠: Pet 培养类型 等阶 丹数")
        __Help(curPlayer, petNumNameDict)
        return
    
    # 重置灵宠
    if msgList[0] == 0:
        if len(msgList) > 1 and msgList[1] == 1:
            PetClear.OnExec(curPlayer, [])
        clearNumList = msgList[1:] if len(msgList) > 1 else None
        clearOKList = __ClearPet(curPlayer, petNPCIDNumDict, clearNumList)
        for trainType in xrange(1, PlayerPet.GetPetTrainTypes() + 1):
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, 1)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, 0)
            
        GameWorld.DebugAnswer(curPlayer, "重置灵宠编号:%s" % sorted(clearOKList))
    # 激活所有
    elif msgList[0] == 99:
        isFullLV = msgList[1] if len(msgList) > 1 else None
        classLV = 999 if isFullLV else None
        OpenFunc.DoGMOpenFunc(curPlayer, ShareDefine.GameFuncID_Pet)
        activeOKList = []
        petNumList = petNPCIDNumDict.values()
        for i, petNum in enumerate(petNumList):
            index = msgList[0]
            refresh = i >= (len(petNumList) - 1)
            if PlayerPet.DoPetActivate(curPlayer, petNum, classLV, refresh=refresh):
                activeOKList.append(petNum)
        GameWorld.DebugAnswer(curPlayer, "激活灵宠编号:%s" % sorted(activeOKList))
    # 激活指定
    elif len(msgList) == 2:
        petNum = msgList[0]
        classLV = msgList[1]
        OpenFunc.DoGMOpenFunc(curPlayer, ShareDefine.GameFuncID_Pet)
        if PlayerPet.DoPetActivate(curPlayer, petNum, classLV):
            GameWorld.DebugAnswer(curPlayer, "激活灵宠: %s(%s), %s阶" % (petNumNameDict.get(petNum, petNum), petNum, classLV))
    # 培养灵宠
    elif len(msgList) == 3:
        trainType, trainLV, eatItemCount = msgList
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainLV % trainType, trainLV)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_PetTrainItemCount % trainType, eatItemCount)
        
    else:
        __Help(curPlayer, petNumNameDict)
        return
    
    PlayerPet.RefreshPetItemAddAttr(curPlayer, True)
    PlayerPet.OnPlayerPetLogin(curPlayer)
    return
def __ClearPet(curPlayer, petNPCIDNumDict, clearNumList=None):
    clearOKList = []
    #获得战斗的宠物
    fightPetNPCID = 0
    curPetMgr = curPlayer.GetPetMgr()
    fightPet = curPetMgr.GetFightPet()
    if fightPet != None:
        fightPetNPCID = fightPet.GetRolePet().NPCID
    fightPetNum = petNPCIDNumDict.get(fightPetNPCID)
    #---如果有出战中的宠物需要先召回---
    if not clearNumList or fightPetNum in clearNumList:
        PetControl.ReCallFightPet(curPlayer)
    #获得玩家宠物信息
    petList = []
    petListCount = curPetMgr.PetList_Cnt()
    for i in range(petListCount):
        pet = curPetMgr.PetList_At(i)
        petNPCID = pet.GetRolePet().NPCID
        petNum = petNPCIDNumDict.get(petNPCID)
        if not clearNumList or petNum in clearNumList:
            petList.append(pet)
    for pet in petList:
        curPetMgr.PetList_SetFree(pet.GetRolePet().PetID)
    # 宠物数据物品背包清除
    petPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptPet)
    for i in range(petPack.GetCount())[::-1]:
        petItem = petPack.GetAt(i)
        if not petItem or petItem.IsEmpty():
            continue
        petNPCID = petItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
        petNum = petNPCIDNumDict.get(petNPCID)
        if not clearNumList or petNum in clearNumList:
            petItem.Clear()
            clearOKList.append(petNum)
    return clearOKList
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -1465,16 +1465,16 @@
## 从列表中产生物品,[[权重, object], ....]
#  @param weightList 待选列表
def GetResultByWeightList(weightList):
def GetResultByWeightList(weightList, defValue=None):
    randList = []
    weight = 0
    for info in weightList:
        weight += info[0]
        randList.append([weight, info[1] if len(info) == 2 else info[1:]])
    if not randList:
        return
        return defValue
    rate = random.randint(1, randList[-1][0])
    return GetResultByRiseList(randList, rate)
    return GetResultByRiseList(randList, rate, defValue)
#---------------------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -1427,6 +1427,17 @@
    
    return callFunc(curPlayer)
def OnCanFBReborn(curPlayer, rebornType):
    ## 副本中额外验证是否可以复活 - 仅副本特有复活限制逻辑需要处理,其他公共复活逻辑外层处理
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnCanFBReborn"))
    if callFunc == None:
        return True
    return callFunc(curPlayer, rebornType)
## 玩家副本重生设置坐标
#  @param rebornPlace 复活位置 
#  @return None
@@ -1440,6 +1451,29 @@
        return
    
    return callFunc(curPlayer, rebornPlace, tick)
def GetFBRobotCanAtkObjTypeIDList(curNPC):
    ## 获取副本中机器人可能可攻击的实例类型ID列表
    ## @return: [[objType, objID], ...]
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "GetFBRobotCanAtkObjTypeIDList"))
    if callFunc == None:
        return []
    return callFunc(curNPC)
def GetFBRobotRandomMovePos(curNPC):
    ## 获取副本中机器人随机移动坐标点
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "GetFBRobotRandomMovePos"))
    if callFunc == None:
        return
    return callFunc(curNPC)
#---------------------------------------------------------------------
## 杀怪奖励是否给最后一个补刀的玩家
@@ -2047,6 +2081,17 @@
    
    return False
def GetFBPlayerHurtNPCMultiValue(curPlayer, curNPC):
    ## 玩家对NPC造成伤害倍值,默认1
    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "GetFBPlayerHurtNPCMultiValue"))
    if callFunc:
        return callFunc(curPlayer, curNPC)
    return 1
## 玩家对NPC造成伤害
#  @param curPlayer 当前玩家
#  @param curNPC 
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
@@ -4,12 +4,12 @@
#
##@package GameWorldLogic.FBProcess.GameLogic_CrossBattlefield
#
# @todo:跨服战场
# @todo:跨服战场/古神战场
# @author hxp
# @date 2022-01-06
# @version 1.0
#
# 详细描述: 跨服战场
# 详细描述: 跨服战场/古神战场
#
#-------------------------------------------------------------------------------
#"""Version = 2022-01-06 20:30"""
@@ -23,16 +23,23 @@
import IpyGameDataPY
import PlayerActivity
import GameWorldProcess
import NPCCustomRefresh
import PlayerControl
import ShareDefine
import SkillCommon
import SkillShell
import BuffSkill
import ChConfig
import AICommon
import GameObj
import GameMap
import ChNPC
import operator
import random
import time
import copy
import math
#当前副本地图的状态
(
@@ -49,218 +56,400 @@
Time_Leave, # 副本离开时间 2
) = range(3)
# 大奖任务类型
SuperTaskList = (
SuperTaskType_Kill, # 击杀 1
SuperTaskType_Score, # 积分 2
) = range(1, 1 + 2)
FightRefreshInterval = 5000 # 战斗阶段刷新处理间隔,毫秒
GameFBData_BattleWorld = "BattleWorld"
GameFBData_FactionInfo = "FactionInfo"
GameFBData_PlayerInfo = "PlayerInfo"
# 事件编号
AllEventNumList = (
EventNum_Aura, # 事件 - 积分光环
EventNum_Boss, # 事件 - Boss
EventNum_Wall, # 事件 - 积分墙
) = range(1, 1 + 3)
# 得分类型
(
ScoreType_Default, # 默认
ScoreType_KillPlayer, # 击杀玩家     1
ScoreType_CollectCrystal, # 占领资源建筑     2
ScoreType_CollectFactionBuff, # 采集阵营buff    3
ScoreType_GuardKillPlayer, # 守卫击杀玩家     4
ScoreType_HurtBoss, # 对boss造成伤害     5
ScoreType_Aura, # 积分光环     6
) = range(7)
## 战场公共世界管理类
class BattleWorld():
    
    def __init__(self):
        self.callOpenPlayerInfo = {} # 本场次购买召集的玩家信息 {playerID:faction, ...}
        self.superItemInfo = [] # 大奖信息 [物品ID,个数,是否拍品]
        self.superItemPlayerID = 0 # 大奖中奖者玩家ID
        self.superItemPlayerName = "" # 大奖中奖者玩家名
        self.superTaskType = 0 # 大奖任务类型
        self.crystalFactionInfo = {} # 水晶资源所属阵营信息 {npcID:所属阵营, ...}
        self.crystalAwardTick = {} # 水晶资源定时奖励tick {npcID:tick, ...}
        self.personBuffCount = 0 # 战场存在的个人buff个数
        self.personBuffCalcTick = 0 # 开始计算个人buff补充个数tick
        self.factionBuffNPCInfo = [] # 战场存在的阵营buffNPC信息,默认只能存在一个 [npcID, posX, posY]
        self.factionBuffCalcTick = 0 # 开始计算阵营buff补充个数tick
        self.factionBuffIDOrderList = [] # 阵营buff顺序刷新列表
        self.eventInfoList = [] # 本场次要刷新的事件列表 [[刷新时间秒, 事件编号], ...]
        self.eventNum = 0 # 当前进行中的事件编号
        self.eventNPCID = 0 # 当前进行中的事件NPCID
        self.eventNPCPos = [] # 当前进行中的事件NPC坐标
        self.eventStartTick = 0 # 事件开始tick
        self.eventEndTick = 0 # 事件结束时tick,某些事件有,不一定有值
        self.eventNPCHP = 0 # 事件NPC当前剩余血量
        self.lastEventEndTick = 0 # 上个事件结束tick
        self.lastWallCollOKTick = 0 # 上次积分墙采集OK时tick
        self.RandSuperTask()
        self.__randEventList()
        return
    def getWorldHelpInfo(self, tick):
        worldInfo = {"superItemInfo":self.superItemInfo, "crystalFactionInfo":self.crystalFactionInfo,
                     "factionBuffNPCInfo":self.factionBuffNPCInfo, "eventNPCID":self.eventNPCID, "eventNPCPos":self.eventNPCPos}
        if self.eventEndTick:
            worldInfo["eventEndTick"] = max(0, self.eventEndTick - tick) # 事件结束剩余时间,单位毫秒
        if self.eventNPCHP:
            worldInfo["eventNPCHP"] = self.eventNPCHP
        return {"worldInfo":worldInfo}
    
    def RandSuperTask(self):
        # 随机生成大奖任务
        fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
        superItemWeightList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper", 1)
        superItemInfo = GameWorld.GetResultByWeightList(superItemWeightList)
        self.superItemInfo = superItemInfo if superItemInfo else []
        self.superTaskType = random.choice(SuperTaskList)
        GameWorld.Log("随机战场大奖: superTaskType=%s,superItemInfo=%s" % (self.superTaskType, self.superItemInfo), fbPropertyID)
        self.superItemInfo = GameWorld.GetResultByWeightList(superItemWeightList, [])
        GameWorld.Log("随机战场大奖: superItemInfo=%s" % str(self.superItemInfo), fbPropertyID)
        return
    
## 战斗实体基类
class BattleBase(object):
    BattleType_Player = "Player"
    BattleType_Faction = "Faction"
    def __init__(self, ID):
        self.fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
        self.battleType = ""
        self.ID = ID
        self.name = ""
        self.score = 0 # 积分
        self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前
        self.superTaskValue = 0 # 大奖任务当前进度
        self.superTaskValueMax = 0 # 大奖任务完成需要的进度值
        self.superTaskFinishCount = 0 # 大奖任务完成次数
        self.killCount = 0 # 击杀数
        self.continueKillCount = 0 # 连杀数
        self.beKilledCount = 0 # 被击杀数
        return
    def addScore(self, worldObj, addValue):
        self.score += addValue
        calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
        self.scoreSortTime = max(0, calcTime - int(time.time()))
        GameWorld.DebugLog("    增加积分: battleType=%s,ID=%s,addValue=%s,updScore=%s" % (self.battleType, self.ID, addValue, self.score), self.fbPropertyID)
        self.addSuperTaskValue(worldObj, SuperTaskType_Score, addValue)
        return
    def addKillCount(self, worldObj, addCount):
        self.killCount += addCount
        self.continueKillCount += addCount # 同步增加连杀
        self.addSuperTaskValue(worldObj, SuperTaskType_Kill, addCount)
        return
    def addBeKilledCount(self, addCount):
        self.beKilledCount += addCount
        self.continueKillCount = 0 # 被击杀时,连杀重置
        return
    def setSuperTaskValueMax(self, worldObj):
        if worldObj == None:
            worldObj = GetBattleWorld()
        taskType = worldObj.superTaskType
        if taskType == SuperTaskType_Kill:
            superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 1)
        elif taskType == SuperTaskType_Score:
            superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 2)
        else:
    def __randEventList(self):
        # 随机本场次事件顺序列表
        if self.eventInfoList:
            return
        
        if self.battleType == self.BattleType_Player:
            curValueMaxList = superTaskValueMaxList[0]
        elif self.battleType == self.BattleType_Faction:
            curValueMaxList = superTaskValueMaxList[1]
        else:
            return
        commEventTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldEvent", 2)
        commEventNumList = [] # 常规事件 - 不包含boss的所有事件
        commEventNumList += AllEventNumList
        commEventNumList.remove(EventNum_Boss)
        
        if not curValueMaxList:
        if len(commEventTimeList) != len(commEventNumList):
            GameWorld.ErrLog("战场常规事件刷新时间个数配置错误! commEventTimeList=%s,commEventNumList=%s"
                             % (commEventTimeList, commEventNumList))
            return
        random.shuffle(commEventNumList)
        
        if self.superTaskFinishCount >= len(curValueMaxList):
            valueMax = curValueMaxList[-1]
        else:
            valueMax = curValueMaxList[self.superTaskFinishCount]
        self.superTaskValueMax = valueMax
        GameWorld.Log("    更新大奖任务进度完成所需值! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s,superTaskValueMax=%s"
                      % (self.battleType, self.ID, taskType, self.superTaskFinishCount, self.superTaskValueMax), self.fbPropertyID)
        return
    def addSuperTaskValue(self, worldObj, taskType, addValue):
        if taskType != worldObj.superTaskType:
            #GameWorld.DebugLog("    非战场大奖任务类型,不处理! taskType=%s != superTaskType(%s)" % (taskType, worldObj.superTaskType), self.fbPropertyID)
            return
        if len(worldObj.superItemInfo) != 3:
            GameWorld.ErrLog("大奖任务物品异常,不处理! taskType=%s,superItemInfo=%s" % (taskType, worldObj.superItemInfo), self.fbPropertyID)
            return
        if worldObj.superItemPlayerID:
            GameWorld.DebugLog("    大奖已经产出,不再处理! superItemPlayerID=%s" % worldObj.superItemPlayerID, self.fbPropertyID)
            return
        for i, eventNum in enumerate(commEventNumList):
            self.eventInfoList.append([commEventTimeList[i], eventNum])
            
        if not self.superTaskValueMax:
            self.setSuperTaskValueMax(worldObj)
        if not self.superTaskValueMax:
            return
        eventBossStartTime = IpyGameDataPY.GetFuncCfg("CrossBattlefieldEvent", 3)
        isOnlyCallHaveBoss = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 5)
        
        self.superTaskValue += addValue
        if self.superTaskValue < self.superTaskValueMax:
            GameWorld.DebugLog("    更新大奖进度! battleType=%s,ID=%s,taskType=%s,addValue=%s,superTaskValue=%s < %s"
                               % (self.battleType, self.ID, taskType, addValue, self.superTaskValue, self.superTaskValueMax), self.fbPropertyID)
            return
        self.superTaskValue -= self.superTaskValueMax
        self.superTaskFinishCount += 1
        GameWorld.Log("    完成大奖任务! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s"
                      % (self.battleType, self.ID, taskType, self.superTaskFinishCount), self.fbPropertyID)
        self.setSuperTaskValueMax(worldObj)
        if isOnlyCallHaveBoss:
            zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
            hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
            hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
            callTeamInfo = hmCallTeamInfo.get(hmNum, {})
            if callTeamInfo:
                self.eventInfoList.append([eventBossStartTime, EventNum_Boss])
        else:
            self.eventInfoList.append([eventBossStartTime, EventNum_Boss])
        
        superRate = self.getSuperItemRate()
        tick = GameWorld.GetGameWorld().GetTick()
        if not GameWorld.CanHappen(superRate):
            GameWorld.Log("        大奖没有中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s"
                          % (self.battleType, self.ID, taskType, superRate), self.fbPropertyID)
            FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer)
            return
        self.eventInfoList.sort()
        
        superItemPlayerID = self.getSuperItemPlayerID()
        GameWorld.Log("        大奖中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s,superItemPlayerID=%s"
                      % (self.battleType, self.ID, taskType, superRate, superItemPlayerID), self.fbPropertyID)
        if not superItemPlayerID:
            return
        worldObj.superItemPlayerID = superItemPlayerID
        itemID, itemCount = worldObj.superItemInfo[0], worldObj.superItemInfo[1]
        battleObj = GetBattlePlayerObj(superItemPlayerID)
        worldObj.superItemPlayerName = battleObj.name
        PlayerControl.FBNotify("CrossBattlefieldSuperItemPlayer", [battleObj.faction, battleObj.name, itemID, itemCount])
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer)
        fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
        GameWorld.Log("随机战场事件刷新时间及编号列表: eventInfoList=%s" % self.eventInfoList, fbPropertyID)
        return
    
    def getSuperItemRate(self): return 0
    def getSuperItemPlayerID(self): return 0
    def setEventEnd(self, tick):
        GameWorld.Log("战场随机事件结束! eventNum=%s" % (self.eventNum), GameWorld.GetGameWorld().GetPropertyID())
        self.eventNum = 0
        self.eventNPCID = 0
        self.eventNPCPos = []
        self.eventNPCHP = 0
        self.eventEndTick = 0
        self.lastEventEndTick = tick # 上个事件结束tick
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
        return
    
## 战场阵营类
class BattleFaction(BattleBase):
class BattleFaction():
    
    def __init__(self, faction):
        super(BattleFaction, self).__init__(faction)
        self.fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
        self.faction = faction
        self.battleType = self.BattleType_Faction
        self.score = 0 # 积分
        self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前
        self.factionPlayerDict = {} # {playerID:BattlePlayer, ...}
        self.battlePlayerSortList = [] # 阵营积分排名玩家列表 [BattlePlayer, ...]
        self.scoreKingIDList = [] # 前x名积分王ID列表 [playerID, ...] ,只算在线的,所以不一定是积分排名前x名
        
        self.onlineFightPowerTotal = 0 # 在线人数总战力
        self.onlinePlayerIDList = [] # 在线玩家ID列表 [playerID, ...]
        self.setSuperTaskValueMax(None)
        self.homePlayerIDList = [] # 在营地家里的玩家ID列表 [playerID, ...]
        self.factionBuffInfo = [] # 阵营当前获得的阵营buff信息 [buff技能ID, 结束时间戳]
        self.crystalScorePlusRate = 0 # 建筑获取资源速度提升万分率
        self.crystalScorePlusEndTick = 0 # 建筑获取资源速度提升结束tick
        self.hurtBossValue = 0 # 阵营对boss的总伤害
        self.hurtBossPlayerDict = {} # 阵营玩家对boss的伤害 {playerID:hurtValue, ...}
        self.superItemProgress = 0 # 阵营大奖开奖进度魂
        self.superItemPlayerID = 0 # 阵营大奖中奖者玩家ID
        self.superItemPlayerName = "" # 阵营大奖中奖者玩家名
        self.robotObjIDList = [] # 本阵营当前机器人实例ID列表
        return
    
    def getSuperItemRate(self):
        single = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 3)
        return single * len(self.onlinePlayerIDList)
    def getSuperItemPlayerID(self):
        if not self.onlinePlayerIDList:
            return 0
        return random.choice(self.onlinePlayerIDList)
    def getFactionHelpInfo(self):
        if self.factionBuffInfo and time.time() >= self.factionBuffInfo[1]:
            self.factionBuffInfo = []
        factionInfo = {"faction":self.faction, "score":self.score, "superItemPlayerName":self.superItemPlayerName,
                       "superItemProgress":self.superItemProgress, "factionBuffInfo":self.factionBuffInfo}
        if self.hurtBossValue:
            factionInfo["hurtBossValue"] = self.hurtBossValue
        return {"factionInfo_%s" % self.faction:factionInfo}
    
    def addScore(self, worldObj, addValue):
        super(BattleFaction, self).addScore(worldObj, addValue)
    def addSuperItemProgress(self, addProgress):
        if self.superItemPlayerID:
            # 阵营大奖已开奖,不再增加阵营大奖进度,但是依然会增加个人大奖贡献
            return
        self.superItemProgress = max(0, self.superItemProgress + addProgress)
        GameWorld.DebugLog("    增加阵营大奖进度: faction=%s,addProgress=%s,superItemProgress=%s"
                           % (self.faction, addProgress, self.superItemProgress), self.fbPropertyID)
        
        battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 2)
        if self.superItemProgress < IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 2):
            return
        worldObj = GetBattleWorld()
        if not worldObj.superItemInfo:
            return
        # 本阵营大奖开奖,仅限在线玩家
        weightList = []
        for playerID, battleObj in self.factionPlayerDict.items():
            if playerID not in self.onlinePlayerIDList:
                continue
            if not battleObj.superItemContribution:
                continue
            weightList.append([battleObj.superItemContribution, playerID])
        superItemPlayerID = GameWorld.GetResultByWeightList(weightList)
        if not superItemPlayerID:
            return
        battleObj = GetBattlePlayerObj(superItemPlayerID)
        self.superItemPlayerID = superItemPlayerID
        self.superItemPlayerName = battleObj.name
        battleObj.superItemContribution = 0 # 重置贡献
        battleObj.superItemAwardCnt += 1
        itemID, itemCount = worldObj.superItemInfo[0], worldObj.superItemInfo[1]
        GameWorld.Log("阵营大奖开奖: faction=%s,weightList=%s,superItemPlayerID=%s,itemID=%s,itemCount=%s"
                      % (self.faction, weightList, superItemPlayerID, itemID, itemCount), self.fbPropertyID)
        PlayerControl.FBNotify("CrossBattlefieldSuperItemPlayer", [battleObj.faction, battleObj.name, itemID, itemCount])
        tick = GameWorld.GetGameWorld().GetTick()
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
        return
    def __checkPerScoreAddSuperItemProgress(self, befScore):
        perScoreInfo = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 4)
        if not perScoreInfo or len(perScoreInfo) != 2:
            return
        superScorePer, addProgress = perScoreInfo
        if not superScorePer or not addProgress:
            return
        befTimes = befScore / superScorePer
        aftTimes = self.score / superScorePer
        if aftTimes <= 0 or aftTimes == befTimes:
            return
        GameWorld.DebugLog("    阵营每%s积分增加在线阵营玩家大奖贡献! addProgress=%s" % (superScorePer, addProgress), self.fbPropertyID)
        for playerID, battleObj in self.factionPlayerDict.items():
            if playerID in self.onlinePlayerIDList:
                battleObj.addSuperItemContribution(addProgress)
        return
    def addFactionScore(self, addValue, isCheckVictory=True):
        ## 增加阵营积分
        # @return: 是否结算胜负,某些情况下不能在加分后直接验证是否获胜,由于某些功能可能同时增加双方阵营积分,所以需等都加完后才处理结算
        if not addValue:
            return
        befScore = self.score
        self.score = max(0, self.score + addValue)
        calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
        self.scoreSortTime = max(0, calcTime - int(time.time()))
        GameWorld.DebugLog("    增加阵营积分: faction=%s,addValue=%s,updScore=%s" % (self.faction, addValue, self.score), self.fbPropertyID)
        self.__checkPerScoreAddSuperItemProgress(befScore)
        if not isCheckVictory:
            return
        return self.checkIsVictory()
    def checkIsVictory(self):
        battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 1)
        if self.score < battleOverScore:
            return
        
        GameWorld.Log("阵营积分达到获胜积分,获胜! faction=%s,updScore=%s" % (self.faction, self.score), self.fbPropertyID)
        GameWorld.Log("阵营积分达到获胜积分,获胜! faction=%s,score=%s" % (self.faction, self.score), self.fbPropertyID)
        tick = GameWorld.GetGameWorld().GetTick()
        DoOver(self.faction, tick)
        return True
def checkBattleOver(tick):
    ## 检查结算,根据双方最终积分判断获胜方
    jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
    eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
    battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 1)
    if jFactionObj.score < battleOverScore and eFactionObj.score < battleOverScore:
        # 都未获胜
        return
    
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    winFactionObj = jFactionObj
    # 一般情况双方积分不一样,取排序后的最高分即为获胜阵营
    if jFactionObj.score != eFactionObj.score:
        sortList = [[jFactionObj.score, jFactionObj], [eFactionObj.score, eFactionObj]]
        sortList.sort(reverse=True)
        _, winFactionObj = sortList[0]
        winFaction = winFactionObj.faction
        GameWorld.Log("双方阵营积分不同,高分一方获胜! winFaction=%s,jScore=%s,eScore=%s"
                      % (winFaction, jFactionObj.score, eFactionObj.score), fbPropertyID)
    # 积分相同的情况,随机一方获胜
    else:
        winFaction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil])
        winFactionObj = GetBattleFactionObj(winFaction)
        winFactionObj.score += 100 # 随机获胜方额外增加积分
        GameWorld.Log("双方阵营积分相同,随机一方获胜! winFaction=%s,jScore=%s,eScore=%s"
                      % (winFaction, jFactionObj.score, eFactionObj.score), fbPropertyID)
    return winFactionObj.checkIsVictory()
## 战场玩家类
class BattlePlayer(BattleBase):
class BattlePlayer():
    
    def __init__(self, playerID):
        super(BattlePlayer, self).__init__(playerID)
        self.battleType = self.BattleType_Player
        self.playerID = playerID
        self.name = ""
        self.faction = 0
        self.factionObj = None
        self.accID = ""
        self.job = 1
        self.realmLV = 0
        self.fightPower = 0
        self.highScoreToday = 0 # 本日最高积分
        self.highScoreWeekTotal = 0 # 本周每日最高分累计
        self.enterCountWeek = 0 # 本周累计进入次数
        self.onlineCalcTick = 0 # 在线统计tick
        self.onlineTimes = 0 # 活动累计在线时长,毫秒
        self.setSuperTaskValueMax(None)
        self.restoreHPTick = 0 # 营地回血tick
        self.itemRebornCount = 0 # 使用特殊道具原地复活次数
        self.score = 0 # 积分
        self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前
        self.killCount = 0 # 击杀数
        self.continueKillCount = 0 # 连杀数
        self.ckillCntInfo = {} # 成就连杀数次数 {连杀数:次数, ...}
        self.killPlayerAddScoreTimes = 0 # 击杀玩家获得积分倍值
        self.killPlayerScoreAwardEndTick = 0 # 击杀玩家多倍积分福利结束tick
        self.killBossCnt = 0 # 本阵营归属击败boss
        self.killScoreKing = 0 # 本场次是否有击败积分王,单场仅计算一次
        self.killGuardCnt = 0 # 击杀守卫次数
        self.auraScore = 0 # 在光环中累计获得积分
        self.superItemAwardCnt = 0 # 获得大奖次数
        self.factionBuffCollCnt = 0 # 采集阵营buff次数
        self.personBuffCollCnt = 0 # 个人buff次数
        self.crystalCollCnt = 0 # 采集水晶资源次数
        self.wallCollCnt = 0 # 采集积分墙次数
        self.superItemContribution = 0 # 大奖进度贡献值,也是大奖获奖权重
        return
    
    def getSuperItemRate(self): return IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 2)
    def getSuperItemPlayerID(self): return self.ID
    def getFactionObj(self):
        if not self.factionObj and self.faction:
            self.factionObj = GetBattleFactionObj(self.faction)
        return self.factionObj
    def getPlayerHelpInfo(self, exInfo=None):
        helpInfo = {"score":self.score, "superItemContribution":self.superItemContribution, "itemRebornCount":self.itemRebornCount,
                    "killCount":self.killCount, "continueKillCount":self.continueKillCount}
        if exInfo:
            helpInfo.update(exInfo)
        return {"playerInfo":helpInfo}
    def addPlayerScore(self, curPlayer, addValue, scoreType=ScoreType_Default, scoreTimes=1, isCheckVictory=True):
        addValue *= scoreTimes
        befScore = self.score
        self.score = max(0, self.score + addValue)
        calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
        self.scoreSortTime = max(0, calcTime - int(time.time()))
        GameWorld.DebugLog("    增加玩家积分: playerID=%s,scoreType=%s,addValue=%s,倍值=%s,updScore=%s"
                           % (self.playerID, scoreType, addValue, scoreTimes, self.score), self.playerID)
        if scoreType == ScoreType_Aura and addValue > 0:
            self.auraScore += addValue
        if curPlayer:
            FBCommon.Notify_FBHelp(curPlayer, self.getPlayerHelpInfo({"addScore":[addValue, scoreType, scoreTimes]}))
        superScorePer = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper2", 1)
        if superScorePer:
            befTimes = befScore / superScorePer
            aftTimes = self.score / superScorePer
            if aftTimes > 0 and aftTimes != befTimes:
                addIndex = aftTimes - 1
                addProgressList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 3)
                addProgress = addProgressList[addIndex] if len(addProgressList) > addIndex else addProgressList[-1]
                GameWorld.DebugLog("    玩家每%s积分增加大奖贡献! addProgress=%s,superItemContribution=%s"
                                   % (superScorePer, addProgress, self.superItemContribution), self.playerID)
                self.addSuperItemContribution(addProgress)
        # 个人增加积分同步增加所属阵营积分
        factionObj = self.getFactionObj()
        if factionObj:
            factionObj.addFactionScore(addValue, isCheckVictory)
        return
    def addKillCount(self, addCount):
        befContKillCount = self.continueKillCount
        self.killCount = max(0, self.killCount + addCount)
        self.continueKillCount = max(0, self.continueKillCount + addCount) # 同步增加连杀
        superContKillPer = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper2", 2)
        if superContKillPer:
            befTimes = befContKillCount / superContKillPer
            aftTimes = self.continueKillCount / superContKillPer
            if aftTimes > 0 and aftTimes != befTimes:
                addIndex = aftTimes - 1
                addProgressList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 3)
                addProgress = addProgressList[addIndex] if len(addProgressList) > addIndex else addProgressList[-1]
                GameWorld.DebugLog("    玩家每%s连杀增加大奖贡献! addProgress=%s,superItemContribution=%s"
                                   % (superContKillPer, addProgress, self.superItemContribution), self.playerID)
                self.addSuperItemContribution(addProgress)
        # 连杀数成就计数
        ckillCntList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldSuccess", 1)
        for ckillCnt in ckillCntList:
            # 需整除才计数1
            if self.continueKillCount and self.continueKillCount % ckillCnt == 0:
                self.ckillCntInfo[ckillCnt] = self.ckillCntInfo.get(ckillCnt, 0) + 1
        return
    def addSuperItemContribution(self, addProgress):
        self.superItemContribution = max(0, self.superItemContribution + addProgress)
        GameWorld.DebugLog("    更新玩家大奖贡献: playerID=%s,addProgress=%s,superItemContribution=%s" % (self.playerID, addProgress, self.superItemContribution), self.playerID)
        factionObj = self.getFactionObj()
        if factionObj:
            factionObj.addSuperItemProgress(addProgress)
        return
    
def GetBattleWorld():
    worldObj = FBCommon.GetGameFBData(GameFBData_BattleWorld)
@@ -288,27 +477,80 @@
        playerObj = BattlePlayer(playerID)
        playerInfoDict[playerID] = playerObj
    return playerObj
def GetBFStepTime(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 1) # 阶段时间
def GetCrystalNPCIDList(): # 水晶资源NPCID列表
    crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {})
    return crystalNPCIDPosDict.keys()
def GetGuardNPCIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldGuard", 1) # 守卫NPCID列表
def GetPersonBuffIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 1) # 个人buffID列表
def GetFactionBuffIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 1) # 阵营buffID列表
def GetRobotNPCIDList(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldRobot", 1) # 机器人NPCID列表
def OnOpenFB(tick):
    #fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    FBCommon.SetGameFBData(GameFBData_BattleWorld, None)
    FBCommon.SetGameFBData(GameFBData_FactionInfo, {})
    FBCommon.SetGameFBData(GameFBData_PlayerInfo, {})
    
    GetBattleWorld()
    worldObj = GetBattleWorld()
    GetBattleFactionObj(ShareDefine.CampType_Justice)
    GetBattleFactionObj(ShareDefine.CampType_Evil)
    
    FBCommon.SetFBStep(FB_Step_Prepare, tick)
    zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
    hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
    hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
    callTeamInfo = hmCallTeamInfo.get(hmNum, {})
    for playerID, callTeam in callTeamInfo.items():
        worldObj.callOpenPlayerInfo[playerID] = callTeam["factionID"]
    GameWorld.Log("开启战场副本: hmNum=%s,callOpenPlayerInfo=%s" % (hmNum, worldObj.callOpenPlayerInfo), fbPropertyID)
    # 刷水晶
    crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {})
    for npcID, posInfo in crystalNPCIDPosDict.items():
        NPCCommon.SummonMapNpc(npcID, posInfo[0], posInfo[1])
    # 刷守卫
    rebornGurad()
    return
def rebornGurad():
    # 复活守卫
    isOnlyCallHaveGuard = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 5)
    guardFactionList = []
    if isOnlyCallHaveGuard:
        zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
        hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
        hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
        callTeamInfo = hmCallTeamInfo.get(hmNum, {})
        for playerID, callTeam in callTeamInfo.items():
            guardFactionList.append([callTeam["factionID"], playerID])
    else:
        guardFactionList = [[ShareDefine.CampType_Justice, 0], [ShareDefine.CampType_Evil, 0]]
    rebornNPCIDList = []
    guardNPCIDList = GetGuardNPCIDList()
    guardNPCPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldGuard", 2)
    for faction, playerID in guardFactionList:
        if not faction or faction > len(guardNPCIDList) or faction > len(guardNPCPosList):
            continue
        npcID = guardNPCIDList[faction - 1]
        if GameWorld.FindNPCByNPCID(npcID):
            GameWorld.DebugLog("守卫已存在,不重复复活! npcID=%s" % npcID)
            continue
        posInfo = guardNPCPosList[faction - 1]
        NPCCommon.SummonMapNpc(npcID, posInfo[0], posInfo[1], playerID=playerID)
        rebornNPCIDList.append(npcID)
    return rebornNPCIDList
def OnCloseFB(tick):
    GameWorld.GetGameWorld().SetPropertyID(0)
    FBCommon.SetGameFBData(GameFBData_BattleWorld, None)
    FBCommon.SetGameFBData(GameFBData_FactionInfo, None)
    FBCommon.SetGameFBData(GameFBData_PlayerInfo, None)
    FBCommon.ClearFBNPC()
    return
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
@@ -334,7 +576,7 @@
##副本玩家进入点, 玩家分散在半径3格范围
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
    return random.choice(IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 1))
    return random.choice(IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 2))
def DoEnterFB(curPlayer, tick):    
    gameFB = GameWorld.GetGameFB()
@@ -367,31 +609,26 @@
    elif fbStep == FB_Step_Fighting:
        notify_tick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
        isToSafePos = not battleObj.faction
        allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
        allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick)
        
    return
##获得副本帮助信息, 用于通知阵营比分条
def DoFBHelp(curPlayer, tick):
    #gameWorld = GameWorld.GetGameWorld()
    gameWorld = GameWorld.GetGameWorld()
    playerID = curPlayer.GetPlayerID()
    lineID = gameWorld.GetLineID()
    
    worldObj = GetBattleWorld()
    battleObj = GetBattlePlayerObj(playerID)
    playerInfo = {"score":battleObj.score, "superTaskValue":battleObj.superTaskValue,
                  "superTaskValueMax":battleObj.superTaskValueMax, "superTaskFinishCount":battleObj.superTaskFinishCount}
    
    factionInfo = {}
    helpDict = {}
    helpDict.update(battleObj.getPlayerHelpInfo())
    helpDict.update(worldObj.getWorldHelpInfo(tick))
    for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
        factionObj = GetBattleFactionObj(faction)
        factionInfo[str(faction)] = {"score":factionObj.score, "superTaskValue":factionObj.superTaskValue,
                                     "superTaskValueMax":factionObj.superTaskValueMax, "superTaskFinishCount":factionObj.superTaskFinishCount}
    worldInfo = {"superTaskType":worldObj.superTaskType, "superItemPlayerName":worldObj.superItemPlayerName, "superItemInfo":worldObj.superItemInfo}
    helpDict = {"playerInfo":playerInfo, "factionInfo":factionInfo, "worldInfo":worldInfo}
        helpDict.update(factionObj.getFactionHelpInfo())
    helpDict[FBCommon.Help_robotJob] = PyGameData.g_fbRobotJobDict.get(lineID, {})
    #GameWorld.DebugLog("DoFBHelp %s" % helpDict, playerID)
    FBCommon.Notify_FBHelp(curPlayer, helpDict)
    return
@@ -439,7 +676,7 @@
    
    # 副本准备
    if fbStep == FB_Step_Prepare:
        __DoLogic_FB_Prepare(tick)
        __DoLogic_FB_Prepare(fbStep, tick)
        
    # 副本进行中
    elif fbStep == FB_Step_Fighting:
@@ -447,11 +684,11 @@
        
    # 副本结束
    elif fbStep == FB_Step_LeaveTime:
        __DoLogic_FB_Over(tick)
        __DoLogic_FB_Leave(tick)
        
    return
def __DoLogic_FB_Prepare(tick):
def __DoLogic_FB_Prepare(fbStep, tick):
    
    remaindTick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
    if remaindTick > 0:
@@ -483,11 +720,8 @@
#        playerInfoList.append({"playerID":playerID, "fightPower":fightPower, "curPlayer":None})
#    ##--------- 山寨分配测试代码 --------------
    
    # 按战力排序
    # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分
    playerInfoList.sort(key=operator.itemgetter("fightPower"), reverse=True)
    isToSafePos = True
    # 按战力从低到高升序排序
    playerInfoList.sort(key=operator.itemgetter("fightPower"))
    
    # 先分配召集队伍
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
@@ -507,7 +741,7 @@
            playerID = playerInfo["playerID"]
            fightPower = playerInfo["fightPower"]
            curPlayer = playerInfo["curPlayer"]
            allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
            allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick)
            
    for playerInfo in playerInfoList:
        playerID = playerInfo["playerID"]
@@ -515,11 +749,12 @@
        curPlayer = playerInfo["curPlayer"]
        if playerID in callPlayerIDList:
            continue
        allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
        allotPlayerFaction(playerID, fightPower, curPlayer, fbStep, tick)
        
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick):
def allotPlayerFaction(playerID, fightPower, curPlayer, allotStep, tick):
    ## 分配玩家阵营
    
    zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
@@ -536,26 +771,28 @@
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    battleObj = GetBattlePlayerObj(playerID)
    faction = battleObj.faction
    isAllot = not faction # 是否分配,无阵营时为 True
    if callFaction:
        faction = callFaction # 召集阵营为固定阵营
        
    if not faction:
        jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
        eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
        onlinePlayerTotal = len(jFactionObj.onlinePlayerIDList) + len(eFactionObj.onlinePlayerIDList)
        fbPlayerCountSet = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 3) # 副本下限人数设定
        # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分
        if onlinePlayerTotal > fbPlayerCountSet:
            faction = ShareDefine.CampType_Justice if len(jFactionObj.onlinePlayerIDList) <= len(eFactionObj.onlinePlayerIDList) else ShareDefine.CampType_Evil
        jPlayerCount = len(jFactionObj.factionPlayerDict)
        ePlayerCount = len(eFactionObj.factionPlayerDict)
        # 人数相同时随机,否则往人数少的分配
        if jPlayerCount == ePlayerCount:
            faction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil])
        elif jPlayerCount < ePlayerCount:
            faction = ShareDefine.CampType_Justice
        else:
            faction = ShareDefine.CampType_Justice if jFactionObj.onlineFightPowerTotal <= eFactionObj.onlineFightPowerTotal else ShareDefine.CampType_Evil
            faction = ShareDefine.CampType_Evil
            
    battleObj.faction = faction
    battleObj.onlineCalcTick = tick
    
    factionObj = GetBattleFactionObj(faction)
    battleObj.factionObj = factionObj
    
    if playerID not in factionObj.factionPlayerDict:
        factionObj.factionPlayerDict[playerID] = battleObj
@@ -565,38 +802,120 @@
    if playerID not in factionObj.onlinePlayerIDList:
        factionObj.onlinePlayerIDList.append(playerID)
        
    GameWorld.Log("    分配阵营: callFaction=%s,faction=%s,playerID=%s,fightPower=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,isToSafePos=%s"
                  % (callFaction, faction, playerID, fightPower, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, isToSafePos), fbPropertyID)
    GameWorld.Log("    分配阵营: allotStep=%s,callFaction=%s,faction=%s,playerID=%s,fightPower=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,isAllot=%s"
                  % (allotStep, callFaction, faction, playerID, fightPower, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, isAllot), fbPropertyID)
    
    # 分配阶段是准备阶段的
    if allotStep == FB_Step_Prepare:
        initScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 2)
        battleObj.addPlayerScore(curPlayer, initScore)
    if curPlayer:
        curPlayer.SetFaction(faction)
        if isToSafePos:
            __RandFactionSafeArea(curPlayer)
        if isAllot:
            __RandFactionRebornArea(curPlayer)
            
    return
## 重置副本复活玩家坐标点
def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):
    __RandFactionSafeArea(curPlayer)
def OnCanFBReborn(curPlayer, rebornType):
    playerID = curPlayer.GetPlayerID()
    if rebornType == ChConfig.rebornType_Health:
        GameWorld.ErrLog("不允许消耗货币原地健康复活! ", playerID)
        return False
    if rebornType == ChConfig.rebornType_UseItem:
        battleObj = GetBattlePlayerObj(playerID)
        if battleObj.itemRebornCount >= IpyGameDataPY.GetFuncCfg("CrossBattlefieldReborn", 2):
            PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldItemRebornLimit")
            return False
    return True
## 玩家复活后处理
def OnPlayerRebornOver(curPlayer, rebornType):
    playerID = curPlayer.GetPlayerID()
    battleObj = GetBattlePlayerObj(playerID)
    if rebornType == ChConfig.rebornType_UseItem:
        battleObj.itemRebornCount += 1
        GameWorld.DebugLog("更新使用道具复活次数! itemRebornCount=%s, 且不中断连杀=%s"
                           % (battleObj.itemRebornCount, battleObj.continueKillCount), playerID)
    else:
        GameWorld.DebugLog("非原地复活,中断连杀!  %s" % battleObj.continueKillCount, playerID)
        battleObj.continueKillCount = 0 # 非原地复活的中断连杀数
    return
def __RandFactionSafeArea(curPlayer):
    faction = curPlayer.GetFaction()
    factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 2)
    if faction and faction <= len(factionSafeAreaRandPosList):
        safePosX, safePosY, radius = random.choice(factionSafeAreaRandPosList[faction - 1])
        posPoint = GameMap.GetEmptyPlaceInArea(safePosX, safePosY, radius)
        posX, posY = posPoint.GetPosX(), posPoint.GetPosY()
def OnPlayerReborn():
    ## 是否副本复活
    return True
## 重置副本复活玩家坐标点
def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):
    __RandFactionRebornArea(curPlayer)
    return
def __RandFactionRebornArea(curPlayer):
    ## 随机阵营复活点: 营地 + 已占领的资源点  随机
    faction = curPlayer.GetFaction()
    posInfo = getRandFactionRebornPos(faction)
    if posInfo:
        posX, posY = posInfo
    else:
        posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
    curPlayer.ResetPos(posX, posY)
    return
def getRandFactionRebornPos(faction):
    rebornPosList = []
    factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3)
    if faction and faction <= len(factionSafeAreaRandPosList):
        safePosX, safePosY, _ = factionSafeAreaRandPosList[faction - 1]
        rebornPosList.append([safePosX, safePosY, 3])
    crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {})
    worldObj = GetBattleWorld()
    for npcID, ownerFaction in worldObj.crystalFactionInfo.items():
        if ownerFaction != faction:
            continue
        if npcID not in crystalNPCIDPosDict:
            continue
        posInfo = crystalNPCIDPosDict[npcID]
        rebornPosList.append([posInfo[0], posInfo[1], 3])
    if not rebornPosList:
        return
    randPosX, randPosY, radius = random.choice(rebornPosList)
    posPoint = GameMap.GetEmptyPlaceInArea(randPosX, randPosY, radius)
    return posPoint.GetPosX(), posPoint.GetPosY()
def GetFBRobotRandomMovePos(curNPC):
    ## 获取副本中机器人随机移动坐标点
    randPosList = []
    crystalNPCIDPosDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldCrystal", 1, {})
    for posX, posY in crystalNPCIDPosDict.values():
        randPosList.append([posX, posY])
    factionBuffPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 2)
    for posList in factionBuffPosList:
        for posX, posY in posList:
            randPosList.append([posX, posY])
    return random.choice(randPosList)
def __DoLogic_FB_Fighting(tick):
    
    remaindTick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
    passTick = tick - GameWorld.GetGameFB().GetFBStepTick()
    remaindTick = GetBFStepTime()[Time_Fight] * 1000 - passTick
    if remaindTick > 0:
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000, refreshFactionPlayer)
        passSeconds = passTick / 1000
        __refreshFactionHome(tick)
        __RefreshPersonBuff(tick, passSeconds)
        __RefreshFactionBuff(tick, passSeconds)
        __RefreshBattlefieldEvent(tick, passSeconds)
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, FightRefreshInterval, refreshCrossBattlefield)
        return
    
    jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
@@ -611,111 +930,531 @@
    DoOver(winnerFaction, tick)
    return
def __DoLogic_FB_Over(tick):
def __refreshFactionHome(tick):
    # 刷新阵营营地相关,如回血等
    restoreHPPerBySecond = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 4) # 每秒回血百分比
    factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3) # 营地坐标
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
        factionObj = GetBattleFactionObj(faction)
        if not factionObj.homePlayerIDList:
            continue
        for playerID in factionObj.homePlayerIDList[::-1]:
            curPlayer = copyMapMgr.FindPlayerByID(playerID)
            if not curPlayer:
                continue
            batObj = GetBattlePlayerObj(playerID)
            safePosX, safePosY, safeRadius = factionSafeAreaRandPosList[faction - 1]
            if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) > safeRadius:
                factionObj.homePlayerIDList.remove(playerID)
                batObj.restoreHPTick = 0
                continue
            # 营地回血
            restoreSeconds = (tick - batObj.restoreHPTick) / 1000.0 if batObj.restoreHPTick else 1 # 首次保底1秒
            if restoreSeconds < 1:
                continue
            maxHP = GameObj.GetMaxHP(curPlayer)
            if GameObj.GetHP(curPlayer) < maxHP:
                restoreHP = int(maxHP * restoreHPPerBySecond / 100.0 * round(restoreSeconds, 1))
                #GameWorld.DebugLog("restoreHPPerBySecond=%s,restoreSeconds=%s,maxHP=%s,restoreHP=%s"
                #                   % (restoreHPPerBySecond, restoreSeconds, maxHP, restoreHP), playerID)
                SkillCommon.SkillAddHP(curPlayer, 0, restoreHP)
            batObj.restoreHPTick = tick
    return
def __RefreshPersonBuff(tick, passSeconds):
    ## 刷新个人buff
    startRefreshSeconds, refreshCD = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 3)
    if passSeconds < startRefreshSeconds:
        return
    buffCountMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldPersonBuff", 4)
    worldObj = GetBattleWorld()
    if worldObj.personBuffCount >= buffCountMax:
        return
    if (tick - worldObj.personBuffCalcTick) < (refreshCD * 1000):
        return
    buffIDList = GetPersonBuffIDList()
    if not buffIDList:
        return
    posList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPersonBuff", 2)
    posInfo = __GetRandPos(posList)
    if not posInfo:
        return
    randBuffNPCID = random.choice(buffIDList)
    if not NPCCommon.SummonMapNpc(randBuffNPCID, posInfo[0], posInfo[1]):
        return
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    worldObj.personBuffCount = worldObj.personBuffCount + 1
    if worldObj.personBuffCount >= buffCountMax:
        worldObj.personBuffCalcTick = 0
    else:
        worldObj.personBuffCalcTick = tick
    GameWorld.DebugLog("刷新个人buff: randBuffNPCID=%s,personBuffCount=%s" % (randBuffNPCID, worldObj.personBuffCount), fbPropertyID)
    return
def __RefreshFactionBuff(tick, passSeconds):
    ## 刷新阵营buff
    startRefreshSeconds, refreshCD = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 3)
    if passSeconds < startRefreshSeconds:
        return
    worldObj = GetBattleWorld()
    if worldObj.factionBuffNPCInfo:
        return
    if (tick - worldObj.factionBuffCalcTick) < (refreshCD * 1000):
        return
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    if not worldObj.factionBuffIDOrderList:
        buffIDList = GetFactionBuffIDList()
        if not buffIDList:
            return
        worldObj.factionBuffIDOrderList = copy.deepcopy(buffIDList)
        random.shuffle(worldObj.factionBuffIDOrderList) # 每轮重新打乱顺序
        GameWorld.DebugLog("战场阵营buff顺序列表: %s" % worldObj.factionBuffIDOrderList, fbPropertyID)
    if not worldObj.factionBuffIDOrderList:
        return
    jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
    eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
    # 使用对方阵营的积分作为本阵营权重, 分数越低的阵营随机到靠近自己阵营的位置的权重越高,权重至少10
    nearFactionWeightList = [[max(10, jFactionObj.score), ShareDefine.CampType_Evil],
                             [max(10, eFactionObj.score), ShareDefine.CampType_Justice]]
    nearFaction = GameWorld.GetResultByWeightList(nearFactionWeightList, ShareDefine.CampType_Evil)
    allPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFactionBuff", 2)
    if nearFaction > len(allPosList):
        return
    posList = allPosList[nearFaction - 1]
    posInfo = __GetRandPos(posList)
    if not posInfo:
        return
    posX, posY = posInfo[0], posInfo[1]
    randBuffNPCID = worldObj.factionBuffIDOrderList.pop(0)
    if not NPCCommon.SummonMapNpc(randBuffNPCID, posX, posY):
        return
    worldObj.factionBuffNPCInfo = [randBuffNPCID, posX, posY]
    GameWorld.DebugLog("刷新阵营buff: randBuffNPCID=%s,nearFaction=%s,nearFactionWeightList=%s"
                       % (randBuffNPCID, nearFaction, nearFactionWeightList), fbPropertyID)
    PlayerControl.FBNotify("CrossBattlefieldBuff_%s" % randBuffNPCID, [randBuffNPCID])
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def __GetRandPos(posList):
    if not posList:
        return
    random.shuffle(posList)
    gameMap = GameWorld.GetMap()
    for posX, posY in posList:
        if gameMap.CanMove(posX, posY) != True:
            continue
        #检查有没有玩家在这一点上
        mapObj = gameMap.GetPosObj(posX, posY)
        if not mapObj:
            continue
        if mapObj.GetObjCount() != 0:
            #有玩家在此点上
            #GameWorld.DebugLog("有实例在此坐标上: posX=%s, posY=%s, GetObjCount=%s"
            #                   % (posX, posY, mapObj.GetObjCount()), GameWorld.GetGameWorld().GetPropertyID())
            continue
        return posX, posY
    return
def __RefreshBattlefieldEvent(tick, passSeconds):
    ## 刷新战场随机事件
    worldObj = GetBattleWorld()
    if worldObj.eventStartTick > worldObj.lastEventEndTick:
        #GameWorld.DebugLog("当前事件进行中未结束!")
        if worldObj.eventNum == EventNum_Aura:
            if tick <= worldObj.eventEndTick:
                return
            auraNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1)
            auraNPC = GameWorld.FindNPCByNPCID(auraNPCID)
            if auraNPC:
                NPCCommon.SetDeadEx(auraNPC)
            worldObj.setEventEnd(tick)
        return
    if not worldObj.eventInfoList:
        return
    nextEventTime, nextEventNum = worldObj.eventInfoList[0] # 默认取第一个就行,副本开始时已随机好
    if passSeconds < nextEventTime:
        # 事件时间未到
        return
    eventRefresCD = IpyGameDataPY.GetFuncCfg("CrossBattlefieldEvent", 4) * 1000
    if worldObj.lastEventEndTick and eventRefresCD and (tick - worldObj.lastEventEndTick) < eventRefresCD:
        GameWorld.DebugLog("事件刷新CD中!")
        return
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
    eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
    nearFaction = 0
    if nextEventNum == EventNum_Boss:
        callFactioList = worldObj.callOpenPlayerInfo.values()
        callFactioList = worldObj.callOpenPlayerInfo.values()
        if len(callFactioList) == 1:
            nearFaction = callFactioList[0]
            GameWorld.Log("战场boss事件,仅一方召集,固定刷新在靠近该阵营的位置: nearFaction=%s, callOpenPlayerInfo=%s"
                          % (nearFaction, worldObj.callOpenPlayerInfo), fbPropertyID)
        else:
            GameWorld.Log("战场boss事件,走常规逻辑判断靠近阵营位置! callOpenPlayerInfo=%s" % worldObj.callOpenPlayerInfo, fbPropertyID)
    # 使用对方阵营的积分作为本阵营权重, 分数越低的阵营随机到靠近自己阵营的位置的权重越高,权重至少10
    if nearFaction:
        # 已经决定了事件靠近的阵营,不用再处理
        pass
    elif jFactionObj.score < eFactionObj.score:
        nearFaction = ShareDefine.CampType_Justice
    elif jFactionObj.score > eFactionObj.score:
        nearFaction = ShareDefine.CampType_Evil
    else:
        nearFaction = random.choice([ShareDefine.CampType_Justice, ShareDefine.CampType_Evil])
    if nextEventNum == EventNum_Aura:
        refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1)
    elif nextEventNum == EventNum_Boss:
        refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1)
    elif nextEventNum == EventNum_Wall:
        refreshNPCID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1)
    else:
        return
    refreshMark = 0
    if refreshNPCID:
        eventRefreshMarkList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldEvent", 1)
        if nearFaction > len(eventRefreshMarkList):
            return
        refreshMark = eventRefreshMarkList[nearFaction - 1]
    worldObj.eventInfoList.pop(0)
    eventNum = nextEventNum
    GameWorld.Log("开始战场事件: eventNum=%s,refreshNPCID=%s,nearFaction=%s,refreshMark=%s"
                  % (eventNum, refreshNPCID, nearFaction, refreshMark), fbPropertyID)
    worldObj.eventNum = eventNum
    worldObj.eventNPCID = refreshNPCID
    worldObj.eventStartTick = tick
    if eventNum == EventNum_Aura:
        worldObj.eventEndTick = tick + IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 2) * 1000
    else:
        worldObj.eventEndTick = 0
    if refreshNPCID and refreshMark:
        NPCCustomRefresh.SetNPCRefresh(refreshMark, [refreshNPCID])
    # 帮助信息放在NPC刷出来后通知,因为需要坐标信息
    return
def DoFBRebornNPC(curNPC, tick):
    ##副本有NPC召出
    npcID = curNPC.GetNPCID()
    worldObj = GetBattleWorld()
    if npcID == worldObj.eventNPCID:
        fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
        eventNum = worldObj.eventNum
        worldObj.eventNPCHP = GameObj.GetHP(curNPC)
        worldObj.eventNPCPos = [curNPC.GetPosX(), curNPC.GetPosY()]
        GameWorld.Log("战场事件NPC刷新: eventNum=%s,npcID=%s,eventNPCPos=%s,eventNPCHP=%s"
                      % (worldObj.eventNum, npcID, worldObj.eventNPCPos, worldObj.eventNPCHP), fbPropertyID)
        if eventNum == EventNum_Aura:
            PlayerControl.FBNotify("CrossBattlefieldEventAura", [npcID])
        elif eventNum == EventNum_Boss:
            factionScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 3)
            PlayerControl.FBNotify("CrossBattlefieldEventBoss", [npcID, factionScore])
        elif eventNum == EventNum_Wall:
            wallScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 3)
            PlayerControl.FBNotify("CrossBattlefieldEventWall", [npcID, wallScore, worldObj.eventNPCHP])
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def DoBeAttackOver(attacker, defender, curSkill, tick):
    atkObjType = attacker.GetGameObjType()
    defObjType = defender.GetGameObjType()
    if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotPlayer:
        curNPC, curPlayer = attacker, defender
        npcID = curNPC.GetNPCID()
        if npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreAura", 1):
            __DoAuraNPCAddPlayerScore(curNPC, curPlayer)
    return
def __DoAuraNPCAddPlayerScore(curNPC, curPlayer):
    ## 积分光环给玩家增加积分
    #npcID = curNPC.GetNPCID()
    playerID = curPlayer.GetPlayerID()
    auraScoreRange = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreAura", 3)
    if len(auraScoreRange) != 2:
        return
    addValue = random.randint(auraScoreRange[0], auraScoreRange[1])
    #GameWorld.DebugLog("积分光环给玩家加积分: addValue=%s,auraScoreRange=%s" % (addValue, auraScoreRange), playerID)
    battleObj = GetBattlePlayerObj(playerID)
    battleObj.addPlayerScore(curPlayer, addValue, ScoreType_Aura)
    return
def __DoLogic_FB_Leave(tick):
    remaindTick = GetBFStepTime()[Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
    if remaindTick > 0:
        return
    
    FBCommon.DoLogic_FBKickAllPlayer()
    GameWorldProcess.CloseFB(tick)
    FBCommon.SetFBStep(FB_Step_Over, tick)
    return
##处理副本中杀死玩家逻辑
def DoFBOnKill_Player(curPlayer, defender, tick):
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = defender.GetPlayerID()
    faction = curPlayer.GetFaction()
    tagFaction = defender.GetFaction()
    curBattleObj = GetBattlePlayerObj(playerID)
    tagBattleObj = GetBattlePlayerObj(tagPlayerID)
    if not faction or not tagFaction:
        GameWorld.ErrLog("击杀玩家没有阵营! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s"
                         % (playerID, faction, tagPlayerID, tagFaction), playerID)
        return
    worldObj = GetBattleWorld()
    curFactionObj = GetBattleFactionObj(faction)
    tagFactionObj = GetBattleFactionObj(tagFaction)
    GameWorld.DebugLog("击杀玩家! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s"
                       % (playerID, faction, tagPlayerID, tagFaction), playerID)
    # 1. 处理玩家
    killPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldKill", 1)
    addPlayerScore = 0
    addPlayerScore += killPlayerScore
    #addPlayerScore += ... # 其他加分
    curBattleObj.addScore(worldObj, addPlayerScore)
    curBattleObj.addKillCount(worldObj, 1)
    tagBattleObj.addBeKilledCount(1)
    # 2. 处理阵营
    addFactionScore = 0
    addFactionScore += addPlayerScore # 阵营积分同步增加玩家得分
    # 击杀积分王,阵营积分额外增加
    for index, kingID in enumerate(tagFactionObj.scoreKingIDList):
        if kingID == tagPlayerID:
            killScoreKingScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 3)
            if index < len(killScoreKingScoreList):
                kingScore = killScoreKingScoreList[index]
                addFactionScore += kingScore
                GameWorld.DebugLog("    对方是积分王,阵营额外获得积分:  index=%s,kingScore=%s" % (index, kingScore), playerID)
            killScoreKingNotifyList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 4)
            if index < len(killScoreKingNotifyList):
                msgMark = killScoreKingNotifyList[index]
                defMapID = defender.GetMapID()
                defPosX = defender.GetPosX()
                defPosY = defender.GetPosY()
                PlayerControl.FBNotify(msgMark, [faction, curPlayer.GetPlayerName(), tagFaction, defender.GetPlayerName(), defMapID, defPosX, defPosY])
            break
    #addFactionScore += ... # 其他加分
    curFactionObj.addScore(worldObj, addFactionScore)
    curFactionObj.addKillCount(worldObj, 1)
    tagFactionObj.addBeKilledCount(1)
    onBattleObjKillOtherBattleObj(curPlayer, defender, tick)
    return True
def refreshFactionPlayer(tick):
    ## 刷新阵营玩家相关
def onBattleObjKillOtherBattleObj(atkObj, defObj, tick):
    ## 战斗实例 击杀 其他阵营战斗实例,战斗实例包含(真实玩家、战斗机器人)
    if not atkObj or not defObj:
        return
    
    atkID = atkObj.GetID()
    defID = defObj.GetID()
    atkObjType = atkObj.GetGameObjType()
    defObjType = defObj.GetGameObjType()
    if atkObjType == defObjType and atkID == defID:
        return
    if atkObjType == IPY_GameWorld.gotPlayer:
        atkName = atkObj.GetName()
        atkFaction = atkObj.GetFaction()
    elif atkObjType == IPY_GameWorld.gotNPC:
        atkFaction = NPCCommon.GetFaction(atkObj)
        atkName = atkObj.GetName()
        atkName = atkName.decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
    else:
        return
    if defObjType == IPY_GameWorld.gotPlayer:
        defFaction = defObj.GetFaction()
    elif defObjType == IPY_GameWorld.gotNPC:
        defFaction = NPCCommon.GetFaction(defObj)
    else:
        return
    if not atkFaction or not defFaction or atkFaction == defFaction:
        return
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    baseKillScore = 0 # 基础击杀分
    fbFightSeconds = (tick - GameWorld.GetGameFB().GetFBStepTick()) / 1000
    killPlayerScoreTimeList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreBase", 3)
    for fbFightTimes, killScore in killPlayerScoreTimeList:
        if fbFightSeconds <= (fbFightTimes * 60):
            baseKillScore = killScore
            GameWorld.DebugLog("基础击杀分: baseKillScore=%s, %s分钟内" % (baseKillScore, fbFightTimes), fbPropertyID)
            break
    worldObj = GetBattleWorld()
    # 1. 处理玩家个人积分
    if atkObjType == IPY_GameWorld.gotPlayer:
        playerID = atkID
        playerScore = 0
        playerScore += baseKillScore
        GameWorld.DebugLog("玩家击杀对手! playerID=%s,atkFaction=%s,defObjType=%s,defID=%s"
                           % (playerID, atkFaction, defObjType, defID), fbPropertyID)
        if playerID in worldObj.callOpenPlayerInfo:
            callPlayerKillScoreEx = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreBase", 4)
            playerScore += callPlayerKillScoreEx
            GameWorld.DebugLog("    召集人额外击杀分: callPlayerKillScoreEx=%s" % callPlayerKillScoreEx, fbPropertyID)
        atkBattleObj = GetBattlePlayerObj(playerID)
        scoreTimes = 1 # 积分倍值
        if atkBattleObj.killPlayerAddScoreTimes and tick <= atkBattleObj.killPlayerScoreAwardEndTick:
            scoreTimes = atkBattleObj.killPlayerAddScoreTimes
        else:
            atkBattleObj.killPlayerAddScoreTimes = 0
            atkBattleObj.killPlayerScoreAwardEndTick = 0
        atkBattleObj.addKillCount(1)
        atkBattleObj.addPlayerScore(atkObj, playerScore, ScoreType_KillPlayer, scoreTimes)
    else:
        GameWorld.DebugLog("机器人击杀对手! atkID=%s,atkFaction=%s,defObjType=%s,defID=%s"
                           % (atkID, atkFaction, defObjType, defID), fbPropertyID)
        # 机器人不计算个人积分
    # 2. 处理阵营积分
    factionScore = 0
    atkFactionObj = GetBattleFactionObj(atkFaction)
    defFactionObj = GetBattleFactionObj(defFaction)
    if atkObjType == IPY_GameWorld.gotNPC:
        factionScore += baseKillScore # 机器人没有个人分,所以击杀基础分直接算到阵营上
    # 击杀积分王,阵营积分额外增加
    if defObjType == IPY_GameWorld.gotPlayer:
        for index, kingID in enumerate(defFactionObj.scoreKingIDList):
            if kingID == defID:
                killScoreKingScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 3)
                kingScore = killScoreKingScoreList[index] if index < len(killScoreKingScoreList) else 0
                factionScore += kingScore
                GameWorld.DebugLog("    对方是积分王,阵营额外获得积分:  index=%s,kingScore=%s" % (index, kingScore), fbPropertyID)
                killScoreKingNotifyList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 4)
                if index < len(killScoreKingNotifyList):
                    msgMark = killScoreKingNotifyList[index]
                    defMapID = GameWorld.GetMap().GetMapID()
                    defPosX = defObj.GetPosX()
                    defPosY = defObj.GetPosY()
                    PlayerControl.FBNotify(msgMark, [atkFaction, atkName, defFaction, defObj.GetPlayerName(), kingScore, defMapID, defPosX, defPosY])
                # 玩家击败积分王
                if atkObjType == IPY_GameWorld.gotPlayer and index == 0:
                    atkBattleObj.killScoreKing = 1
                break
    else:
        pass
    #factionScore += ... # 其他加分
    atkFactionObj.addFactionScore(factionScore)
    return
def DoFB_NPCDead(curNPC):
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetFBStep() != FB_Step_Fighting:
        return
    faction = NPCCommon.GetFaction(curNPC)
    if not faction:
        return
    if curNPC.GetType() == ChConfig.ntRobot:
        objID = curNPC.GetID()
        factionObj = GetBattleFactionObj(faction)
        if objID in factionObj.robotObjIDList:
            factionObj.robotObjIDList.remove(objID)
            GameWorld.DebugLog("机器人被击杀,阵营机器人ID移除: faction=%s,objID=%s,robotObjIDList=%s"
                               % (faction, objID, factionObj.robotObjIDList), GameWorld.GetGameWorld().GetPropertyID())
    return
def refreshCrossBattlefield(tick, checkVictory=True):
    ## 刷新战场相关
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    # 定时占领资源积分奖励
    awardScorePerSecond = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCrystal", 3)
    worldObj = GetBattleWorld()
    for npcID, ownerFaction in worldObj.crystalFactionInfo.items():
        lastAwardTick = worldObj.crystalAwardTick.get(npcID, tick)
        awardSeconds = (tick - lastAwardTick) / 1000.0
        awardFactionScore = int(awardScorePerSecond * round(awardSeconds))
        worldObj.crystalAwardTick[npcID] = tick
        if awardFactionScore <= 0:
            continue
        factionObj = GetBattleFactionObj(ownerFaction)
        if factionObj.crystalScorePlusRate and tick <= factionObj.crystalScorePlusEndTick:
            awardFactionScore = int(awardFactionScore * (1 + int(factionObj.crystalScorePlusRate / 10000.0)))
        else:
            factionObj.crystalScorePlusRate = 0
            factionObj.crystalScorePlusEndTick = 0
        GameWorld.DebugLog("定时资源积分: npcID=%s,ownerFaction=%s,awardSeconds=%s,awardFactionScore=%s"
                           % (npcID, ownerFaction, awardSeconds, awardFactionScore), fbPropertyID)
        factionObj.addFactionScore(awardFactionScore, False)
    # 参与玩家处理
    scoreKingScoreMin = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreKing", 1)
    scoreKingBuffIDList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 2)
    scoreKingCount = len(scoreKingBuffIDList)
    
    factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 3) # 营地坐标
    robotNPCIDList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldRobot", 1)
    battleObjBaseCount = IpyGameDataPY.GetFuncCfg("CrossBattlefieldRobot", 2) # 阵营保底战斗人员数,在线+机器人
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    copyPlayerCount = copyMapMgr.GetPlayerCount()
    for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
        factionObj = GetBattleFactionObj(faction)
        
        # 机器人,有真实玩家时才处理刷出机器人
        if copyPlayerCount and len(factionObj.onlinePlayerIDList) + len(factionObj.robotObjIDList) < battleObjBaseCount and faction <= len(robotNPCIDList):
            robotNPCID = robotNPCIDList[faction - 1]
            posInfo = getRandFactionRebornPos(faction)
            if posInfo:
                robotNPC = NPCCommon.SummonMapNpc(robotNPCID, posInfo[0], posInfo[1])
                if robotNPC:
                    robotNPC.SetIsNeedProcess(True)
                    robotID = robotNPC.GetID()
                    if robotID not in factionObj.robotObjIDList:
                        factionObj.robotObjIDList.append(robotID)
                        GameWorld.DebugLog("新增阵营机器人: faction=%s,robotNPCID=%s,robotID=%s,posInfo=%s,robotObjIDList=%s"
                                           % (faction, robotNPCID, robotID, posInfo, factionObj.robotObjIDList), fbPropertyID)
        befKingIDList = factionObj.scoreKingIDList
        
        factionObj.battlePlayerSortList = factionObj.factionPlayerDict.values()
        factionObj.battlePlayerSortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True)
        
        safePosX, safePosY, safeRadius = factionSafeAreaRandPosList[faction - 1]
        aftKingIDList = []
        aftKingObjList = []
        for batObj in factionObj.battlePlayerSortList:
            playerID = batObj.ID
            playerID = batObj.playerID
            curPlayer = copyMapMgr.FindPlayerByID(playerID)
            if not curPlayer:
                continue
            
            # 累计参与战斗时长
            if batObj.onlineCalcTick:
                batObj.onlineTimes += max(0, tick - batObj.onlineCalcTick)
                batObj.onlineCalcTick = tick
                
            if batObj.score < scoreKingScoreMin:
                continue
            if len(aftKingIDList) < scoreKingCount:
            # 回营地
            if GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), safePosX, safePosY) <= safeRadius:
                if playerID not in factionObj.homePlayerIDList:
                    factionObj.homePlayerIDList.append(playerID)
            # 有资格的积分王列表
            if batObj.score >= scoreKingScoreMin and len(aftKingIDList) < scoreKingCount:
                aftKingIDList.append(playerID)
                aftKingObjList.append([curPlayer, batObj])
                
        if befKingIDList == aftKingIDList:
            #GameWorld.DebugLog("    阵营积分王不变: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList))
            #GameWorld.DebugLog("    阵营积分王不变: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList), fbPropertyID)
            continue
        
        GameWorld.DebugLog("    阵营积分王变更: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList))
        GameWorld.DebugLog("    阵营积分王变更: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList), fbPropertyID)
        
        # 更新buff
        for index, objInfo in enumerate(aftKingObjList):
@@ -728,27 +1467,34 @@
            if playerID in befKingIDList:
                befIndex = befKingIDList.index(playerID)
                if index == befIndex:
                    GameWorld.DebugLog("        积分王名次不变,不需要变更buff! index=%s" % index, playerID)
                    GameWorld.DebugLog("        积分王名次不变,不需要变更buff! index=%s,playerID=%s" % (index, playerID), fbPropertyID)
                    continue
                delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0
                if delBuffID:
                    GameWorld.DebugLog("        积分王名次变更! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID)
                    GameWorld.DebugLog("        积分王名次变更! 删除旧buff! befIndex=%s,delBuffID=%s,playerID=%s" % (befIndex, delBuffID, playerID), fbPropertyID)
                    BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick)
                    
            if addBuffID:
                GameWorld.DebugLog("        积分王名次变更! 添加新buff! index=%s,addBuffID=%s" % (index, addBuffID), playerID)
                GameWorld.DebugLog("        积分王名次变更! 添加新buff! index=%s,addBuffID=%s,playerID=%s" % (index, addBuffID, playerID), fbPropertyID)
                SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, addBuffID, tick)
                
        for befIndex, playerID in enumerate(befKingIDList):
            if playerID in aftKingIDList:
                continue
            curPlayer = copyMapMgr.FindPlayerByID(playerID)
            if not curPlayer:
                continue
            delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0
            if delBuffID:
                GameWorld.DebugLog("        积分王被挤掉! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID)
                GameWorld.DebugLog("        积分王被挤掉! 删除旧buff! befIndex=%s,delBuffID=%s,playerID=%s" % (befIndex, delBuffID, playerID), fbPropertyID)
                BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick)
                
        factionObj.scoreKingIDList = aftKingIDList
    if not checkVictory:
        return
    checkBattleOver(tick)
    return
def DoOver(winnerFaction, tick):
@@ -757,7 +1503,8 @@
    funcLineID = FBCommon.GetCrossDynamicLineMapFuncLineID()
    GameWorld.Log("跨服战场结算! zoneID=%s,funcLineID=%s,winnerFaction=%s" % (zoneID, funcLineID, winnerFaction), fbPropertyID)
    
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer) # 结算前强刷一次
    refreshCrossBattlefield(tick, False) # 结算前强刷一次
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
    
    #awardOnlineTimes = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAward", 1) # 结算奖励需参与活动时长,秒钟
    
@@ -766,28 +1513,28 @@
    leaveTime = GetBFStepTime()[Time_Leave] * 1000
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    
    superItemPlayerID = worldObj.superItemPlayerID
    superItemPlayerName = worldObj.superItemPlayerName
    # 没人中奖则随机给其中一位在线的玩家
    if not superItemPlayerID:
        onlinePlayerIDList = []
        for index in xrange(copyMapMgr.GetPlayerCount()):
            curPlayer = copyMapMgr.GetPlayerByIndex(index)
            playerID = curPlayer.GetPlayerID()
            if not playerID:
                continue
            onlinePlayerIDList.append(playerID)
        if onlinePlayerIDList:
            superItemPlayerID = random.choice(onlinePlayerIDList)
            superPlayerObj = GetBattlePlayerObj(superItemPlayerID)
            superItemPlayerName = superPlayerObj.name
            worldObj.superItemPlayerID = superItemPlayerID
            worldObj.superItemPlayerName = superItemPlayerName
            GameWorld.Log("没人中大奖,则随机其中一位在线玩家! superItemPlayerID=%s,onlinePlayerIDList=%s"
                          % (superItemPlayerID, onlinePlayerIDList), fbPropertyID)
    GameWorld.Log("大奖获奖信息: superItemInfo=%s,superItemPlayerID=%s" % (worldObj.superItemInfo, superItemPlayerID), fbPropertyID)
    superItemPlayerIDList = []
    superWeight = []
    for index in xrange(copyMapMgr.GetPlayerCount()):
        curPlayer = copyMapMgr.GetPlayerByIndex(index)
        playerID = curPlayer.GetPlayerID()
        if not playerID:
            continue
        battleObj = GetBattlePlayerObj(playerID)
        if not battleObj.superItemContribution:
            continue
        superWeight.append([battleObj.superItemContribution, playerID])
    # 这是最终结算额外再开一次的大奖,仅限结算时在线的所有玩家
    finalSuperItemPlayerName = ""
    finalSuperItemPlayerID = GameWorld.GetResultByWeightList(superWeight, 0)
    GameWorld.Log("最终结算额外随机大奖在线玩家! superItemInfo=%s,finalSuperItemPlayerID=%s,superWeight=%s"
                  % (worldObj.superItemInfo, finalSuperItemPlayerID, superWeight), fbPropertyID)
    if finalSuperItemPlayerID:
        superPlayerObj = GetBattlePlayerObj(finalSuperItemPlayerID)
        superPlayerObj.superItemAwardCnt += 1
        finalSuperItemPlayerName = superPlayerObj.name
        superItemPlayerIDList.append(finalSuperItemPlayerID)
    hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
    hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
    callTeamInfo = hmCallTeamInfo.get(hmNum, {})
@@ -800,10 +1547,13 @@
    for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
        factionObj = GetBattleFactionObj(faction)
        factionScore = factionObj.score
        isWinner = (faction == winnerFaction)
        isWinner = 1 if faction == winnerFaction else 0
        scoreKingIDList = factionObj.scoreKingIDList
        GameWorld.Log("结算阵营! faction=%s,factionScore=%s,isWinner=%s,playerCount=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,scoreKingIDList=%s"
                      % (faction, factionScore, isWinner, len(factionObj.battlePlayerSortList), factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, scoreKingIDList), fbPropertyID)
        factionSuperItemPlayerID = factionObj.superItemPlayerID
        GameWorld.Log("结算阵营! faction=%s,factionScore=%s,isWinner=%s,playerCount=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,scoreKingIDList=%s,factionSuperItemPlayerID=%s"
                      % (faction, factionScore, isWinner, len(factionObj.battlePlayerSortList), factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, scoreKingIDList, factionSuperItemPlayerID), fbPropertyID)
        if factionSuperItemPlayerID:
            superItemPlayerIDList.append(factionSuperItemPlayerID)
        if isWinner and scoreKingIDList:
            scoreKingID = scoreKingIDList[0]
            scoreKingObj = GetBattlePlayerObj(scoreKingID)
@@ -813,9 +1563,9 @@
        for battleObj in factionObj.battlePlayerSortList[:20]:
            rankPlayerList.append({"Name":battleObj.name, "Job":battleObj.job, "Score":battleObj.score})
            
        overDict = {"rankPlayerList":rankPlayerList, "faction":faction, "superItemPlayerName":superItemPlayerName, "scoreKingName":scoreKingName}
        overDict = {"rankPlayerList":rankPlayerList, "faction":faction, "superItemPlayerName":finalSuperItemPlayerName, "scoreKingName":scoreKingName}
        for rank, battleObj in enumerate(factionObj.battlePlayerSortList, 1):
            playerID = battleObj.ID
            playerID = battleObj.playerID
            score = battleObj.score
            job = battleObj.job
            realmLV = battleObj.realmLV
@@ -824,6 +1574,7 @@
            highScoreWeekTotal = battleObj.highScoreWeekTotal
            enterCountWeek = battleObj.enterCountWeek
            onlineTimes = battleObj.onlineTimes / 1000
            GameWorld.Log("     rank=%s,playerID=%s,score=%s,fightPower=%s,onlineTimes=%s,accID=%s" 
                          % (rank, playerID, score, battleObj.fightPower, onlineTimes, battleObj.accID), fbPropertyID)
            
@@ -832,8 +1583,18 @@
            #    GameWorld.Log("    活动时长不足,不给奖励! faction=%s,playerID=%s,isWinner=%s" % (faction, playerID, isWinner), fbPropertyID)
            #    continue
            
            isCallEnter = 1 if playerID in allCallPlayerIDList else 0 # 是否召集进入的
            playerInfo = [faction, rank, playerID, job, realmLV, name, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]
            isCallOpen = 1 if playerID in worldObj.callOpenPlayerInfo else 0 # 是否召集进入的
            isCalled = 1 if (playerID in allCallPlayerIDList and not isCallOpen) else 0 # 是否被召集的
            killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
                factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt = \
                battleObj.killCount, battleObj.ckillCntInfo, battleObj.killBossCnt, battleObj.killScoreKing, battleObj.killGuardCnt, \
                battleObj.auraScore, battleObj.superItemAwardCnt, battleObj.factionBuffCollCnt, battleObj.personBuffCollCnt, \
                battleObj.crystalCollCnt, battleObj.wallCollCnt
            playerInfo = [playerID, job, realmLV, name,
                          isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek,
                          isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt,
                          factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt]
            battlePlayerList.append(playerInfo)
            
            player = copyMapMgr.FindPlayerByID(playerID)
@@ -849,28 +1610,391 @@
            
    # 同步GameServer 比赛结果
    superItemInfo = worldObj.superItemInfo
    msgInfo = str([fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, superItemPlayerName, scoreKingID, scoreKingName, battlePlayerList])
    msgInfo = str([fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, finalSuperItemPlayerID, finalSuperItemPlayerName, superItemPlayerIDList, scoreKingID, scoreKingName, battlePlayerList])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossBattlefieldOver", msgInfo, len(msgInfo))
    
    FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
    return
## 执行副本杀怪逻辑
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
    #curNPC.SetDict(ChConfig.Def_NPC_Dict_Faction, 0)
##是否可以夺旗
def OnCanCollect(curPlayer, curNPC, tick):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    # 非战斗阶段不可采集
    if fbStep != FB_Step_Fighting:
        PlayerControl.NotifyCode(curPlayer, "NotFightStepCanNotCollect")
        return False
    npcID = curNPC.GetNPCID()
    GameWorld.DebugLog("OnCanCollect npcID=%s" % npcID, curPlayer.GetPlayerID())
    if npcID in GetCrystalNPCIDList():
        # 已获得战旗的战盟不可采集
        worldObj = GetBattleWorld()
        ownerFaction = worldObj.crystalFactionInfo.get(npcID)
        faction = curPlayer.GetFaction()
        if ownerFaction == faction:
            PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldCollectOwnerLimit")
            return False
    # 积分墙
    elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1):
        worldObj = GetBattleWorld()
        collectCD = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 2) * 1000
        passTick = tick - worldObj.lastWallCollOKTick
        #GameWorld.DebugLog("lastWallCollOKTick=%s,tick=%s,passTick=%s,collectCD=%s" % (worldObj.lastWallCollOKTick, tick, passTick, collectCD))
        if passTick <= collectCD:
            waitSeconds = int(math.ceil((collectCD - passTick) / 1000.0))
            PlayerControl.NotifyCode(curPlayer, "CrossBattlefieldWallTimeLimit", [waitSeconds])
            return False
    return True
##玩家收集成功(塔, 旗)
def OnCollectOK(curPlayer, npcID, tick):
    GameWorld.DebugLog("OnCollectOK npcID=%s" % npcID, curPlayer.GetPlayerID())
    tagObj = curPlayer.GetActionObj()
    if not tagObj:
        return
    if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:
        return
    curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())
    AICommon.ClearPlayerPreparing(curNPC, curPlayer)
    npcID = curNPC.GetNPCID()
    # 水晶
    if npcID in GetCrystalNPCIDList():
        __OnCollectOK_Crystal(curPlayer, curNPC, tick)
    # 个人buff
    elif npcID in GetPersonBuffIDList():
        __OnCollectOK_PersonBuff(curPlayer, curNPC, tick)
    # 阵营buff
    elif npcID in GetFactionBuffIDList():
        __OnCollectOK_FactionBuff(curPlayer, curNPC, tick)
    # 积分墙
    elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 1):
        __OnCollectOK_EventWall(curPlayer, curNPC, tick)
    return
def __OnCollectOK_Crystal(curPlayer, curNPC, tick):
    ## 采集水晶资源建筑
    objID = curNPC.GetID()
    npcID = curNPC.GetNPCID()
    playerID = curPlayer.GetPlayerID()
    battleObj = GetBattlePlayerObj(playerID)
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    if not battleObj:
        return
    faction = battleObj.faction
    worldObj = GetBattleWorld()
    lastOwnerFaction = worldObj.crystalFactionInfo.get(npcID)
    if lastOwnerFaction == faction:
        return
    # 更新归属信息
    worldObj.crystalFactionInfo[npcID] = faction
    worldObj.crystalAwardTick[npcID] = tick
    battleObj.crystalCollCnt += 1
    GameWorld.Log("玩家占领水晶: objID=%s,npcID=%s,lastOwnerFaction=%s,playerID=%s,faction=%s"
                  % (objID, npcID, lastOwnerFaction, playerID, faction), fbPropertyID)
    addScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCrystal", 2)
    battleObj.addPlayerScore(curPlayer, addScore, ScoreType_CollectCrystal)
    # 占领广播给自己阵营、对方阵营 不同内容
    PlayerControl.FBFactionNotify(curPlayer.GetFaction(), "CrossBattlefieldOccupiedSelf", [battleObj.name],
                                  "CrossBattlefieldOccupiedOther", [battleObj.name])
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def __OnCollectOK_PersonBuff(curPlayer, curNPC, tick):
    npcID = curNPC.GetNPCID()
    worldObj = GetBattleWorld()
    if worldObj.personBuffCount > 0:
        worldObj.personBuffCount = worldObj.personBuffCount - 1
    if not worldObj.personBuffCalcTick:
        worldObj.personBuffCalcTick = tick
    # 增加buff效果
    addSkill = curNPC.GetSkillManager().GetSkillByIndex(0)
    addSkillID = addSkill.GetSkillID() if addSkill else 0
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("采集个人buff: npcID=%s,addSkillID=%s,personBuffCount=%s"
                       % (npcID, addSkillID, worldObj.personBuffCount), playerID)
    battleObj = GetBattlePlayerObj(playerID)
    battleObj.personBuffCollCnt += 1
    if addSkill:
        SkillShell.__DoLogic_AddBuff(curPlayer, curPlayer, addSkill, False, tick, addForce=True)
    # 攻击翻x倍                            30908107
    # 击杀玩家积分翻x倍        30908108
    # 无敌                                        30908109
    if npcID == 30908108:
        buffSkill = GameWorld.GetGameData().GetSkillBySkillID(addSkillID)
        if buffSkill:
            buffTime = buffSkill.GetLastTime()
            battleObj.killPlayerAddScoreTimes = buffSkill.GetEffect(0).GetEffectValue(0)
            battleObj.killPlayerScoreAwardEndTick = tick + buffTime
            GameWorld.DebugLog("获得击杀玩家多倍积分福利: killPlayerAddScoreTimes=%s,buffTime=%s"
                               % (battleObj.killPlayerAddScoreTimes, buffTime), playerID)
    NPCCommon.SetDeadEx(curNPC)
    return
def __OnCollectOK_FactionBuff(curPlayer, curNPC, tick):
    npcID = curNPC.GetNPCID()
    worldObj = GetBattleWorld()
    if worldObj.factionBuffNPCInfo and npcID == worldObj.factionBuffNPCInfo[0]:
        worldObj.factionBuffNPCInfo = []
    worldObj.factionBuffCalcTick = tick
    # 增加buff效果
    addSkill = curNPC.GetSkillManager().GetSkillByIndex(0)
    addSkillID = addSkill.GetSkillID() if addSkill else 0
    if not addSkillID:
        return
    buffSkill = GameWorld.GetGameData().GetSkillBySkillID(addSkillID)
    if not buffSkill:
        return
    playerID = curPlayer.GetPlayerID()
    addScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFactionBuff", 4)
    battleObj = GetBattlePlayerObj(playerID)
    battleObj.factionBuffCollCnt += 1
    battleObj.addPlayerScore(curPlayer, addScore, ScoreType_CollectFactionBuff)
    faction = battleObj.faction
    tagFaction = ShareDefine.CampType_Justice if faction == ShareDefine.CampType_Evil else ShareDefine.CampType_Evil
    # 黑夜降临: 敌对玩家每x秒掉血y%,持续xx秒                        30908110
    # 天道威压: 敌对玩家攻击降低x%,持续xx秒                           30908111
    # 普度众生: 我方建筑获取资源速度提升x%,持续xx秒       30908112
    # 洞天福地: 我方玩家每x秒回血y%,持续xx秒                        30908113
    gainBuffFaction = faction # 获得buff的阵营
    if npcID in [30908110, 30908111]:
        gainBuffFaction = tagFaction
    GameWorld.DebugLog("采集阵营buff: npcID=%s,addSkillID=%s,faction=%s,tagFaction=%s,gainBuffFaction=%s"
                       % (npcID, addSkillID, faction, tagFaction, gainBuffFaction), playerID)
    paramList = [faction, battleObj.name, npcID, gainBuffFaction]
    PlayerControl.FBNotify("CrossBattlefieldBuffOK_%s" % npcID, paramList)
    gainBuffFactionObj = GetBattleFactionObj(gainBuffFaction)
    doAddFactionPlayerBuff(curPlayer, gainBuffFactionObj, buffSkill, tick)
    buffTime = buffSkill.GetLastTime()
    endTime = int(time.time()) + int(buffTime / 1000)
    gainBuffFactionObj.factionBuffInfo = [addSkillID, endTime]
    if npcID == 30908112:
        gainBuffFactionObj.crystalScorePlusRate = buffSkill.GetEffect(0).GetEffectValue(0)
        gainBuffFactionObj.crystalScorePlusEndTick = tick + buffTime
    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    NPCCommon.SetDeadEx(curNPC)
    return
def doAddFactionPlayerBuff(curPlayer, factionObj, buffSkill, tick):
    ## 给某个阵营在线玩家添加buff
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    for playerID in factionObj.onlinePlayerIDList:
        player = copyMapMgr.FindPlayerByID(playerID)
        if not player:
            continue
        SkillShell.__DoLogic_AddBuff(curPlayer, player, buffSkill, False, tick, addForce=True)
    return
def __OnCollectOK_EventWall(curPlayer, curNPC, tick):
    ## 采集积分墙
    npcID = curNPC.GetNPCID()
    ChNPC.OnCollectEnd(curPlayer, curNPC)
    worldObj = GetBattleWorld()
    worldObj.lastWallCollOKTick = tick
    worldObj.eventNPCHP = GameObj.GetHP(curNPC)
    playerID = curPlayer.GetPlayerID()
    faction = curPlayer.GetFaction()
    battleObj = GetBattlePlayerObj(playerID)
    battleObj.wallCollCnt += 1
    factionObj = GetBattleFactionObj(faction)
    addValue = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreWall", 3)
    GameWorld.Log("玩家采集积分墙: npcID=%s,faction=%s,eventNPCHP=%s,tick=%s" % (npcID, faction, worldObj.eventNPCHP, tick), playerID)
    factionObj.addFactionScore(addValue)
    PlayerControl.FBNotify("CrossBattlefieldWallCollectOK", [faction, curPlayer.GetPlayerName(), npcID, addValue])
    if worldObj.eventNPCHP <= 0:
        worldObj.setEventEnd(tick)
    else:
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def DoFBOnNPCKill_Player(curNPC, curPlayer, tick):
    ## 执行副本NPC击杀玩家
    npcID = curNPC.GetNPCID()
    npcFaction = NPCCommon.GetFaction(curNPC)
    if npcFaction:
        __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick)
        if npcID in GetGuardNPCIDList():
            __OnGuardKillOtherPlayer(curNPC, curPlayer, tick)
        elif npcID in GetRobotNPCIDList():
            onBattleObjKillOtherBattleObj(curNPC, curPlayer, tick)
    else:
        __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick)
        pass
    return
def __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick):
    ## 玩家击杀其他阵营机器人玩家
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
    ## 执行副本杀怪逻辑
    npcID = curNPC.GetNPCID()
    npcFaction = NPCCommon.GetFaction(curNPC)
    GameWorld.DebugLog("DoFB_Player_KillNPC %s kill %s" % (curPlayer.GetID(), npcID))
    if npcFaction:
        if npcID in GetGuardNPCIDList():
            __OnPlayerKillOtherFactionGurad(curPlayer, curNPC, tick)
        elif npcID in GetRobotNPCIDList():
            onBattleObjKillOtherBattleObj(curPlayer, curNPC, tick)
    # boss
    elif npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1):
        __OnPlayerKillEventBoss(curPlayer, curNPC, tick)
    return
def __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick):
    ## 玩家击杀中立怪物
def DoFB_Npc_KillNPC(attacker, curNPC, tick):
    if attacker.GetType() == ChConfig.ntRobot and curNPC.GetType() == ChConfig.ntRobot:
        onBattleObjKillOtherBattleObj(attacker, curNPC, tick)
    return
def __OnPlayerKillOtherFactionGurad(curPlayer, curNPC, tick):
    ## 玩家击杀其他阵营守卫
    playerID = curPlayer.GetPlayerID()
    guardFaction = NPCCommon.GetFaction(curNPC)
    tagFaction = curPlayer.GetFaction()
    if guardFaction == tagFaction:
        return
    battleObj = GetBattlePlayerObj(playerID)
    battleObj.killGuardCnt += 1
    PlayerControl.FBFactionNotify(curPlayer.GetFaction(), "CrossBattlefieldKillGuardSelf", [battleObj.name],
                                  "CrossBattlefieldKillGuardOther", [battleObj.name])
    factionObj = GetBattleFactionObj(battleObj.faction)
    killGuardScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 3)
    factionObj.addFactionScore(killGuardScore)
    return
def __OnGuardKillOtherPlayer(curNPC, tagPlayer, tick):
    ## 守卫击杀玩家
    npcID = curNPC.GetNPCID()
    guardFaction = NPCCommon.GetFaction(curNPC)
    tagFaction = tagPlayer.GetFaction()
    tagPlayerID = tagPlayer.GetPlayerID()
    ownerPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)
    if not ownerPlayerID or guardFaction == tagFaction:
        return
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    ownerPlayer = copyMapMgr.FindPlayerByID(ownerPlayerID)
    guardKillPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldGuard", 4)
    GameWorld.DebugLog("守卫击杀玩家: npcID=%s,guardFaction=%s,ownerPlayerID=%s,tagPlayerID=%s"
                       % (npcID, guardFaction, ownerPlayerID, tagPlayerID), fbPropertyID)
    battleObj = GetBattlePlayerObj(ownerPlayerID)
    battleObj.addKillCount(1)
    battleObj.addPlayerScore(ownerPlayer, guardKillPlayerScore, ScoreType_GuardKillPlayer)
    return
def __OnPlayerKillEventBoss(curPlayer, curNPC, tick):
    ## 玩家击杀事件Boss
    npcID = curNPC.GetNPCID()
    killerPlayerID = curPlayer.GetPlayerID()
    killerFaction = curPlayer.GetFaction()
    fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
    jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
    eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
    GameWorld.Log("击杀天道之眼Boss: npcID=%s,killerPlayerID=%s,killerFaction=%s"
                  % (npcID, killerPlayerID, killerFaction), fbPropertyID)
    GameWorld.Log("    faction=%s,hurtBossValue=%s" % (jFactionObj.faction, jFactionObj.hurtBossValue), fbPropertyID)
    GameWorld.Log("    faction=%s,hurtBossValue=%s" % (eFactionObj.faction, eFactionObj.hurtBossValue), fbPropertyID)
    ownerFaction = None
    if jFactionObj.hurtBossValue > eFactionObj.hurtBossValue:
        ownerFaction = jFactionObj
    elif jFactionObj.hurtBossValue < eFactionObj.hurtBossValue:
        ownerFaction = eFactionObj
    else:
        # 伤害相同时,归属最后一击玩家所属阵营
        ownerFaction = jFactionObj if killerFaction == jFactionObj.faction else eFactionObj
        ownerFaction.hurtBossValue += 100 # 随机归属方额外增加伤害
        GameWorld.Log("    伤害相同,归属最后一击玩家阵营! ", fbPropertyID)
    GameWorld.Log("    Boss归属阵营: faction=%s" % ownerFaction.faction, fbPropertyID)
    ownerFactionScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 3)
    ownerFaction.addFactionScore(ownerFactionScore, False)
    hurtPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 2)
    for factionObj in [jFactionObj, eFactionObj]:
        for playerID in factionObj.hurtBossPlayerDict.keys():
            battleObj = GetBattlePlayerObj(playerID)
            if factionObj.faction == ownerFaction.faction:
                battleObj.killBossCnt += 1
            battleObj.addPlayerScore(curPlayer, hurtPlayerScore, ScoreType_HurtBoss, isCheckVictory=False)
    PlayerControl.FBNotify("CrossBattlefieldBossKilled", [npcID, ownerFaction.faction, ownerFactionScore, hurtPlayerScore])
    worldObj = GetBattleWorld()
    worldObj.setEventEnd(tick)
    if not checkBattleOver(tick):
        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshCrossBattlefield)
    return
def GetFBPlayerHurtNPCMultiValue(curPlayer, curNPC):
    ## 玩家对NPC造成伤害倍值,默认1
    npcID = curNPC.GetNPCID()
    playerID = curPlayer.GetPlayerID()
    worldObj = GetBattleWorld()
    # 召集开启的玩家  对 Boss的伤害倍值
    if playerID in worldObj.callOpenPlayerInfo and npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1):
        return IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 4)
    return 1
def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
    ## 玩家对NPC造成伤害
    npcID = curNPC.GetNPCID()
    playerID = curPlayer.GetPlayerID()
    # Boss
    if npcID == IpyGameDataPY.GetFuncCfg("CrossBattlefieldBoss", 1):
        worldObj = GetBattleWorld()
        worldObj.eventNPCHP = GameObj.GetHP(curNPC)
        faction = curPlayer.GetFaction()
        factionObj = GetBattleFactionObj(faction)
        # 累加伤害
        factionObj.hurtBossValue = factionObj.hurtBossValue + hurtHP
        factionObj.hurtBossPlayerDict[playerID] = factionObj.hurtBossPlayerDict.get(playerID, 0) + hurtHP
        GameWorld.DebugLog("玩家攻击boss: faction=%s,hurtHP=%s,factionHurtBossValue=%s,playerHurtBossValue=%s,npcHP=%s"
                           % (faction, hurtHP, factionObj.hurtBossValue, factionObj.hurtBossPlayerDict[playerID], GameObj.GetHP(curNPC)), playerID)
    return
## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
@@ -878,13 +2002,40 @@
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetFBStep() != FB_Step_Fighting:
        return False
    atkObjType = attacker.GetGameObjType()
    defObjType = defender.GetGameObjType()
    if atkObjType == IPY_GameWorld.gotNPC and defObjType == IPY_GameWorld.gotNPC:
        if NPCCommon.GetFaction(attacker) == NPCCommon.GetFaction(defender):
            return False
        if attacker.GetType() == ChConfig.ntRobot and defender.GetType() == ChConfig.ntRobot:
            #GameWorld.DebugLog("本副本机器人NPC可以互相攻击: atkNPCID=%s(%s),defNPCID=%s(%s)" % (attacker.GetNPCID(), attacker.GetName(), defender.GetNPCID(), defender.GetName()))
            return True
        #GameWorld.DebugLog("本副本NPC不能互相攻击: atkNPCID=%s(%s),defNPCID=%s(%s)" % (attacker.GetNPCID(), attacker.GetName(), defender.GetNPCID(), defender.GetName()))
        return False
    return True
def GetFBRobotCanAtkObjTypeIDList(curNPC):
    ## 获取副本中机器人可能可攻击的实例类型ID列表
    ## @return: [[objType, objID], ...]
    faction = NPCCommon.GetFaction(curNPC)
    if not faction:
        return []
    defFaction = ShareDefine.CampType_Justice if faction == ShareDefine.CampType_Evil else ShareDefine.CampType_Evil
    objTypeIDList = []
    defFactionObj = GetBattleFactionObj(defFaction)
    for playerID in defFactionObj.onlinePlayerIDList:
        objTypeIDList.append([IPY_GameWorld.gotPlayer, playerID])
    for robotID in defFactionObj.robotObjIDList:
        objTypeIDList.append([IPY_GameWorld.gotNPC, robotID])
    random.shuffle(objTypeIDList) # 打乱顺序
    return objTypeIDList
## 玩家攻击玩家是否有惩罚
def DoFBAttackHasPunish(atkPlayer, defPlayer):
    return False
## 是否副本复活
def OnPlayerReborn():
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -374,6 +374,12 @@
                        ("DWORD", "IceLodeFightPower", 0),
                        ),
                "SpecMapPlayerAttrFormat":(
                        ("DWORD", "DataMapID", 1),
                        ("char", "AttrName", 0),
                        ("char", "AttrValueFormat", 0),
                        ),
                "GMAttr":(
                        ("DWORD", "GMAttrID", 1),
                        ("BYTE", "IsValid", 0),
@@ -2669,6 +2675,19 @@
    def GetAttackEff(self): return self.AttackEff # 挂机效率
    def GetReFightPower(self): return self.ReFightPower # 战斗力
    def GetIceLodeFightPower(self): return self.IceLodeFightPower # 冰晶矿脉扫荡战斗力
# 特殊地图玩家属性公式表
class IPY_SpecMapPlayerAttrFormat():
    def __init__(self):
        self.DataMapID = 0
        self.AttrName = ""
        self.AttrValueFormat = ""
        return
    def GetDataMapID(self): return self.DataMapID # 数据地图ID
    def GetAttrName(self): return self.AttrName # 属性名
    def GetAttrValueFormat(self): return self.AttrValueFormat # 最终属性值公式(可用参数属性名)
# GM测试属性表
class IPY_GMAttr():
@@ -6080,6 +6099,8 @@
        self.ipyHorseSkinPlusLen = len(self.ipyHorseSkinPlusCache)
        self.ipyPlayerLVCache = self.__LoadFileData("PlayerLV", IPY_PlayerLV)
        self.ipyPlayerLVLen = len(self.ipyPlayerLVCache)
        self.ipySpecMapPlayerAttrFormatCache = self.__LoadFileData("SpecMapPlayerAttrFormat", IPY_SpecMapPlayerAttrFormat)
        self.ipySpecMapPlayerAttrFormatLen = len(self.ipySpecMapPlayerAttrFormatCache)
        self.ipyGMAttrCache = self.__LoadFileData("GMAttr", IPY_GMAttr)
        self.ipyGMAttrLen = len(self.ipyGMAttrCache)
        self.ipyNPCExCache = self.__LoadFileData("NPCEx", IPY_NPCEx)
@@ -6644,6 +6665,8 @@
    def GetHorseSkinPlusByIndex(self, index): return self.ipyHorseSkinPlusCache[index]
    def GetPlayerLVCount(self): return self.ipyPlayerLVLen
    def GetPlayerLVByIndex(self, index): return self.ipyPlayerLVCache[index]
    def GetSpecMapPlayerAttrFormatCount(self): return self.ipySpecMapPlayerAttrFormatLen
    def GetSpecMapPlayerAttrFormatByIndex(self, index): return self.ipySpecMapPlayerAttrFormatCache[index]
    def GetGMAttrCount(self): return self.ipyGMAttrLen
    def GetGMAttrByIndex(self, index): return self.ipyGMAttrCache[index]
    def GetNPCExCount(self): return self.ipyNPCExLen
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py
@@ -21,13 +21,16 @@
# @change: "2012-05-22 11:00" jiang 增加函数GetAreaTypeByMapPos()获取某一点所在的区域类型
# @change: "2015-09-23 14:30" hxp 增加函数GetEmptyPlaceInAreaEx获取某点指定范围区域内的随机点
#---------------------------------------------------------------------
"""Version = 2015-09-23 14:30"""
#"""Version = 2015-09-23 14:30"""
#---------------------------------------------------------------------
import GameWorld
import random
import ChConfig
import AttackCommon
import IPY_GameWorld
import FormulaControl
import IpyGameDataPY
import GameObj
#---------------------------------------------------------------------
#########################################################
#Python的pos定义
@@ -302,4 +305,62 @@
        effectID = curPosObj.GetEffectID(index)
        if effectID == findEffectID:
            return True
    return False
    return False
def SpecialMapSetAttrValueByFormat(curPlayer):
    import FBCommon
    import PlayerControl
    dataMapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("SpecMapPlayerAttrFormat", dataMapID)
    if not ipyDataList:
        return
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("特殊地图设置属性: dataMapID=%s" % dataMapID, playerID)
    for ipyData in ipyDataList:
        attrName = ipyData.GetAttrName()
        attrValueFormat = ipyData.GetAttrValueFormat()
        attrOwner = ""
        # GameObj 的 Get、Set函数
        getFuncName = "Get%s" % attrName
        setFuncName = "Set%s" % attrName
        if hasattr(GameObj, getFuncName) and hasattr(GameObj, setFuncName):
            getFunc = getattr(GameObj, getFuncName)
            setFunc = getattr(GameObj, setFuncName)
            value = getFunc(curPlayer)
            attrOwner = "GameObj"
        # PlayerControl 的 Get、Set函数
        elif hasattr(PlayerControl, getFuncName) and hasattr(PlayerControl, setFuncName):
            getFunc = getattr(PlayerControl, getFuncName)
            setFunc = getattr(PlayerControl, setFuncName)
            value = getFunc(curPlayer)
            attrOwner = "PlayerControl"
        # curPlayer 的 Get、Set函数
        elif hasattr(curPlayer, getFuncName) and hasattr(curPlayer, setFuncName):
            getFunc = getattr(curPlayer, getFuncName)
            setFunc = getattr(curPlayer, setFuncName)
            value = getFunc()
            attrOwner = "curPlayer"
        else:
            GameWorld.ErrLog("特殊地图设置属性异常,不存在该属性! dataMapID=%s,attrName=%s" % (dataMapID, attrName), playerID)
            continue
        if attrValueFormat.isdigit():
            setValue = int(attrValueFormat)
        else:
            setValue = eval(FormulaControl.GetCompileFormula("SpecMapAttr_%s_%s" % (dataMapID, attrName), attrValueFormat))
        if attrOwner == "curPlayer":
            setFunc(setValue)
        else:
            setFunc(curPlayer, setValue)
        GameWorld.DebugLog("    attrName=%s,value=%s,setValue=%s,%s" % (attrName, value, setValue, attrOwner), playerID)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py
New file
@@ -0,0 +1,210 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package NPCAI.AIType_22
#
# @todo:副本活动机器人
# @author hxp
# @date 2022-02-21
# @version 1.0
#
# 详细描述: 副本活动机器人,默认自动寻找可攻击的目标,没有可攻击目标时,随机移动
#
#-------------------------------------------------------------------------------
#"""Version = 2022-02-21 20:00"""
#-------------------------------------------------------------------------------
import ChConfig
import AICommon
import NPCCommon
import BaseAttack
import IPY_GameWorld
import AttackCommon
import GameWorld
import GameObj
import GameMap
import FBLogic
import random
#---------------------------------------------------------------------
Key_TagObjType = "TagObjType"
Key_TagObjID = "TagObjID"
#---------------------------------------------------------------------
## 初始化
#  @param curNPC 当前npc
#  @return None
#  @remarks 函数详细说明.
def DoInit(curNPC):
    curNPC.GetNPCAngry().Init(ChConfig.Def_SuperFBBossAngryCount)
    return
def OnNPCReborn(curNPC):
    curNPC.SetIsNeedProcess(True)
    return
## 执行AI
#  @param curNPC 当前npc
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def ProcessAI(curNPC, tick):
    npcControl = NPCCommon.NPCControl(curNPC)
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
        return
    #刷新自己的buff
    npcControl.RefreshBuffState(tick)
    if GameObj.GetHP(curNPC) == 0:
        # BUFF刷新中可能会导致NPC死亡
        return
    #刷新自己仇恨度列表
    npcControl.RefreshAngryList(tick)
    curNPCAngry = npcControl.GetMaxAngryTag()
    tagObjType, tagObjID = 0, 0
    if curNPCAngry:
        tagObjType = curNPCAngry.GetObjType()
        tagObjID = curNPCAngry.GetObjID()
    else:
        tagObj = getRandAtkObj(curNPC, tick)
        if tagObj:
            tagObjType = tagObj.GetGameObjType()
            tagObjID = tagObj.GetID()
    curNPC.SetDict(Key_TagObjType, tagObjType)
    curNPC.SetDict(Key_TagObjID, tagObjID)
    if tagObjType and tagObjID:
        robotFight(curNPC, tagObjID, tagObjType, tick)
    else:
        randomMove(curNPC, tick)
    return
def randomMove(curNPC, tick):
    ## 随机移动
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:
        return
    randPos = FBLogic.GetFBRobotRandomMovePos(curNPC)
    if randPos:
        tagPosX, tagPosY = randPos
    else:
        tagPos = GameMap.GetEmptyPlaceInArea(curNPC.GetPosX(), curNPC.GetPosY(), 10)
        tagPosX, tagPosY = tagPos.GetPosX(), tagPos.GetPosY()
    #GameWorld.DebugLog("机器人随机移动到目标点: objID=%s,npcID=%s,tagPosX=%s,tagPosY=%s"
    #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagPosX, tagPosY), GameWorld.GetGameWorld().GetPropertyID())
    curNPC.Move(tagPosX, tagPosY)
    return
def getRandAtkObj(curNPC, tick):
    ## 获取地图中一个可攻击的随机目标玩家
    tagObjType = curNPC.GetDictByKey(Key_TagObjType)
    tagObjID = curNPC.GetDictByKey(Key_TagObjID)
    if tagObjType and tagObjID:
        tagObj = GameWorld.GetObj(tagObjID, tagObjType)
        if tagObj and not AttackCommon.GetIsDead(tagObj) and GameObj.GetHP(tagObj) > 0 and checkCanAtkTag(curNPC, tagObj, tick):
            return tagObj
        #GameWorld.DebugLog("机器人追踪指定目标无效了: objID=%s,npcID=%s,tagObjType=%s,tagObjID=%s,canAtk=%s"
        #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagObjType, tagObjID, checkCanAtkTag(curNPC, tagObj, tick)),
        #                   GameWorld.GetGameWorld().GetPropertyID())
    # 如果副本已有特殊指定
    canAtkObjTypeIDList = FBLogic.GetFBRobotCanAtkObjTypeIDList(curNPC)
    #GameWorld.DebugLog("机器人副本指定可追踪目标: objID=%s,npcID=%s,canAtkObjTypeIDList=%s"
    #                   % (curNPC.GetID(), curNPC.GetNPCID(), canAtkObjTypeIDList),
    #                   GameWorld.GetGameWorld().GetPropertyID())
    for objType, objID in canAtkObjTypeIDList:
        tagObj = GameWorld.GetObj(objID, objType)
        if not tagObj:
            continue
        if checkCanAtkTag(curNPC, tagObj, tick):
            return tagObj
    # 没有的话随机遍历副本中在线玩家
    copyMapMgr = GameWorld.GetMapCopyPlayerManager()
    randIndexList = range(copyMapMgr.GetPlayerCount())
    random.shuffle(randIndexList)
    for index in randIndexList:
        tagPlayer = copyMapMgr.GetPlayerByIndex(index)
        if not tagPlayer:
            continue
        if checkCanAtkTag(curNPC, tagPlayer, tick):
            return tagPlayer
    # 及NPC...待扩展
    return
def checkCanAtkTag(curNPC, tagObj, tick):
    if not AttackCommon.CheckCanAttackTag(curNPC, tagObj):
        return
    relation = BaseAttack.GetTagRelation(curNPC, tagObj, None, tick)[0]
    if relation != ChConfig.Type_Relation_Enemy:
        return
    return True
def robotFight(curNPC, tagID, tagType, tick):
    curTag = GameWorld.GetObj(tagID, tagType)
    if curTag == None or GameObj.GetHP(curTag) <= 0:
        return
    tagDist = GameWorld.GetDist(curNPC.GetPosX(), curNPC.GetPosY(), curTag.GetPosX(), curTag.GetPosY())
    if tagDist > curNPC.GetAtkDist():
        moveToTag(curNPC, curTag)
        return
    npcControl = NPCCommon.NPCControl(curNPC)
    if curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:
        curNPC.StopMove()
        if npcControl.FixTagPos(curTag.GetPosX(), curTag.GetPosY()):
            #修正这个NPC的站立位置
            return
    NPCCommon.SetNPCInBattleState(curNPC)
    #---优先释放技能---
    if AICommon.DoAutoUseSkill(curNPC, curTag, tagDist, tick):
        return
    #---释放普通攻击---
    if tick - curNPC.GetAttackTick() >= curNPC.GetAtkInterval():
        BaseAttack.Attack(curNPC, curTag, None, tick)
    return
def moveToTag(curNPC, tagObj):
    tagPosX, tagPosY = tagObj.GetPosX(), tagObj.GetPosY()
    destDist = GameWorld.GetDist(curNPC.GetDestPosX(), curNPC.GetDestPosY(), tagObj.GetPosX(), tagObj.GetPosY())
    if destDist <= curNPC.GetAtkDist() and curNPC.GetCurAction() == IPY_GameWorld.laNPCMove:
        # 目标在移动的攻击范围内,不改变目标点
        #GameWorld.DebugLog("机器人追踪指定目标在移动的攻击范围内,不改变目标点: objID=%s,npcID=%s,tagID=%s,tagPosX=(%s,%s),destPos=(%s,%s)"
        #                   % (objID, npcID, tagID, tagPosX, tagPosY, curNPC.GetDestPosX(), curNPC.GetDestPosY()), propertyID)
        return
    movePos = GameMap.GetEmptyPlaceInArea(tagPosX, tagPosY, 3)
    movePosX, movePosY = movePos.GetPosX(), movePos.GetPosY()
    curNPC.Move(movePosX, movePosY)
    #GameWorld.DebugLog("机器人追踪指定目标: objID=%s,npcID=%s,tagID=%s,tagPosX=(%s,%s),movePos=(%s,%s)"
    #                   % (curNPC.GetID(), curNPC.GetNPCID(), tagObj.GetID(), tagPosX, tagPosY, movePosX, movePosY),
    #                   GameWorld.GetGameWorld().GetPropertyID())
    return
### NPC死亡
##  @param curNPC 当前npc
##  @param hurtType 伤害者的obj类型
##  @param hurtID 伤害者的objID
##  @return None
#def OnDie(curNPC, hurtType, hurtID):
#    AICommon.DoNPCUseSkillOnDie(curNPC)
#    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -135,9 +135,7 @@
def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord))
def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力
def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型
def GetFaction(curNPC):
    faction = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_Faction)
    return faction if faction else curNPC.GetCountry()
def GetFaction(curNPC): return curNPC.GetCountry()
def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
@@ -2167,7 +2165,10 @@
    
    if playerID > 0:
        curSummon.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, playerID)
    if curSummon.GetType() == ChConfig.ntRobot:
        __OnFBRobotReborn(curSummon, curSummon.GetLV())
    FBLogic.DoFBRebornSummonNPC(curSummon, tick)
    __NotifyMapPlayerSummonMapNPC(npcId, rebornX, rebornY)
    return curSummon
@@ -3521,6 +3522,9 @@
        #得到地图刷新点
        posMap = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
        #范围校验
        if not posMap:
            GameWorld.ErrLog("__Func_GetRandPosInRefreshArea GetRefreshPosAt error: return None! npcID=%s" % curNPC.GetNPCID())
            return
        posMapX = posMap.GetPosX()
        posMapY = posMap.GetPosY()
        
@@ -5654,8 +5658,8 @@
    collTimeReduceRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_CollTimeReduceRate)
    if collTimeReduceRate:
        prepareTime = max(1000, int(prepareTime * (ShareDefine.Def_MaxRateValue - collTimeReduceRate) / float(ShareDefine.Def_MaxRateValue)))
    PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, IPY_GameWorld.pstMissionCollecting, prepareID=curNPC.GetID())
    prepareType = IPY_GameWorld.pstCollecting if curNPC.GetType() == IPY_GameWorld.ntCollection else IPY_GameWorld.pstMissionCollecting
    PlayerControl.Sync_PrepareBegin(curPlayer, prepareTime, prepareType, prepareID=curNPC.GetID())
    if collectNPCIpyData.GetLostHPPer():
        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -4308,11 +4308,16 @@
        if not __RebornCost(curPlayer, rebornType, False):
            return
        
    # 副本额外验证
    if not FBLogic.OnCanFBReborn(curPlayer, rebornType):
        return
    return True
def __RebornCost(curPlayer, rebornType, isDoCost):
    ## 扣除复活消耗
    # @param isDoCost: 是否执行消耗
    crossMapID = PlayerControl.GetCrossMapID(curPlayer)
    playerID = curPlayer.GetPlayerID()
    if rebornType == ChConfig.rebornType_Health:
        rebornCfg = IpyGameDataPY.GetFuncEvalCfg('RebornArguments', 1)
@@ -4328,7 +4333,11 @@
                    return
                
    elif rebornType == ChConfig.rebornType_UseItem:
        rebornItem = ItemCommon.FindItemInPackByEffectEx(curPlayer, ChConfig.Def_Effect_Reborn)
        if crossMapID == ChConfig.Def_FBMapID_CrossBattlefield:
            rebornItemID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldReborn", 1)
            rebornItem = ItemCommon.FindItemInPackByItemID(curPlayer, rebornItemID, IPY_GameWorld.rptItem)
        else:
            rebornItem = ItemCommon.FindItemInPackByEffectEx(curPlayer, ChConfig.Def_Effect_Reborn)
        if not rebornItem:
            GameWorld.ErrLog("复活道具不足,无法原地复活! ", playerID)                
            return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py
@@ -30,6 +30,7 @@
import ChConfig
import PlayerControl
import IpyGameDataPY
import PlayerSuccess
import EventShell
import time
@@ -195,6 +196,20 @@
    sendMCPack.Result = 1
    NetPackCommon.SendFakePack(curPlayer, sendMCPack)
    
    #<MailTemplate>模板编号</MailTemplate>[%s,%s]
    lSign, rSign = "<MailTemplate>", "</MailTemplate>"
    if lSign in content and rSign in content:
        mailKey = content[content.index(lSign) + len(lSign):content.index(rSign)]
        try:
            mailParamList = eval(content[content.index(rSign) + len(rSign):])
        except:
            mailParamList = []
        if mailKey in ["CrossBattlefieldEnterOrderWeek", "CrossBattlefieldCallOrderWeek", "CrossBattlefieldScoreOrderWeek"]:
            GameWorld.DebugLog("古神战场周榜邮件处理成就: mailKey=%s,mailParamList=%s" % (mailKey, mailParamList), curPlayer.GetPlayerID())
            if mailParamList and mailParamList[0] == 1:
                PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_BillFirst, 1)
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_BillIn, 1)
    #===========================================================================
    # #领取补偿事件记录
    # Text = curPackData.Text
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4858,6 +4858,9 @@
        #护盾值刷新
        self.__RefreshMaxProDef(beforeMaxProDef)
        
        #特殊指定属性公式
        GameMap.SpecialMapSetAttrValueByFormat(curPlayer)
        # 【到此所有功能属性都已刷新处理完毕,复制一份 功能属性的刷新结果,用于BUFF属性单独刷新】
        EffGetSet.CopyPlayerFuncAttr(curPlayer)
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
@@ -4,12 +4,12 @@
#
##@package Player.PlayerCrossBattlefield
#
# @todo:跨服战场
# @todo:跨服战场/古神战场
# @author hxp
# @date 2022-01-06
# @version 1.0
#
# 详细描述: 跨服战场
# 详细描述: 跨服战场/古神战场
#
#-------------------------------------------------------------------------------
#"""Version = 2022-01-06 20:30"""
@@ -27,6 +27,7 @@
import NetPackCommon
import ItemControler
import PlayerActivity
import PlayerSuccess
def DoPlayerLogin(curPlayer):
@@ -192,27 +193,37 @@
    # 固定礼包
    buyAwardItemList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBuyOpen", 3)
    ItemControler.GivePlayerItemOrMail(curPlayer, buyAwardItemList)
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_CallOpen, 1)
    return
def __DoBattlefieldOver(curPlayer, dataMsg):
    
    playerID = curPlayer.GetPlayerID()
    overTime, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = dataMsg
    overTime, \
        isWinner, faction, rank, score, highScoreToday, highScoreWeekTotal, enterCountWeek, \
        isCallOpen, isCalled, killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt, \
        factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt = dataMsg
    isToday = GameWorld.CheckTimeIsSameServerDayEx(overTime)
    isSameWeek = GameWorld.CheckTimeIsSameWeek(overTime)
    GameWorld.Log("跨服战场结算玩家结果: highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallEnter=%s,overTime=%s,isToday=%s,isSameWeek=%s"
                  % (highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter, GameWorld.ChangeTimeNumToStr(overTime), isToday, isSameWeek), playerID)
    GameWorld.Log("跨服战场结算玩家结果: highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,overTime=%s,isToday=%s,isSameWeek=%s"
                  % (highScoreToday, highScoreWeekTotal, enterCountWeek, GameWorld.ChangeTimeNumToStr(overTime), isToday, isSameWeek), playerID)
    GameWorld.Log("    isWinner=%s,faction=%s,rank=%s,score=%s,isCallOpen=%s,isCalled=%s" % (isWinner, faction, rank, score, isCallOpen, isCalled), playerID)
    GameWorld.Log("    killCnt=%s,ckillCntInfo=%s,killBossCnt=%s,killScoreKing=%s,killGuardCnt=%s,auraScore=%s,superItemAwardCnt=%s"
                  % (killCnt, ckillCntInfo, killBossCnt, killScoreKing, killGuardCnt, auraScore, superItemAwardCnt), playerID)
    GameWorld.Log("    factionBuffCollCnt=%s,personBuffCollCnt=%s,crystalCollCnt=%s,wallCollCnt=%s"
                  % (factionBuffCollCnt, personBuffCollCnt, crystalCollCnt, wallCollCnt), playerID)
    
    if isToday:
        addCnt = 1
        # 非召集进入的需要增加日常次数
        if not isCallEnter:
            PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossBattlefield, addCnt)
        # 召集进入由于是免费进入,不许要增加日常次数,直接增加日常活跃
        else:
        # 召集进入由于是免费进入,不需要增加日常次数,直接增加日常活跃
        if isCallOpen or isCalled:
            activityNum = PlayerActivity.GetActivityNum(PlayerActivity.RelatedType_1, ShareDefine.DailyActionID_CrossBattlefield)
            PlayerActivity.AddActivityFinishCnt(curPlayer, activityNum, None, addCnt)
        # 非召集兑入进入的需要增加日常次数
        else:
            PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossBattlefield, addCnt)
            
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreToday, highScoreToday)
        SyncCrossBattlefieldPlayerInfo(curPlayer)
@@ -221,6 +232,40 @@
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_EnterCountWeek, enterCountWeek)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreTotalWeek, highScoreWeekTotal)
        
    # 成就
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Join, 1)
    if isCalled:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Called, 1)
    if isWinner:
        if faction == ShareDefine.CampType_Justice:
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_WinJ, 1)
        elif faction == ShareDefine.CampType_Evil:
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_WinE, 1)
    if killCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_KillCnt, killCnt)
    for ckillCnt, addCnt in ckillCntInfo.items():
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_CKillCnt, addCnt, [ckillCnt])
    if killBossCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_KillBoss, killBossCnt)
    if killScoreKing > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_KillScoreKing, killScoreKing)
    if killGuardCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_KillGuard, killGuardCnt)
    if score > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Score, score)
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_ScoreMore, 1, [score])
    if auraScore > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_AuraScore, auraScore)
    if superItemAwardCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_SuperItem, superItemAwardCnt)
    if factionBuffCollCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_FactionBuff, factionBuffCollCnt)
    if personBuffCollCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_PersonBuff, personBuffCollCnt)
    if crystalCollCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Crystal, crystalCollCnt)
    if wallCollCnt > 0:
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Battlefield_Wall, wallCollCnt)
    return
def SyncCrossBattlefieldPlayerInfo(curPlayer):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -527,15 +527,18 @@
    return True
def DoPetActivate(curPlayer, index, classlv):
def DoPetActivate(curPlayer, index, classlv=None, refresh=True):
    ##直接激活 外部调用GM测试用
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    petInfoCount = ipyDataMgr.GetPetInfoCount()
    if petInfoCount <= 0 or index > petInfoCount:
        GameWorld.ErrLog("激活宠物超过宠物表数据数: index=%s,petInfoCount=%s" % (index, petInfoCount))
        return
    petNPCID = ipyDataMgr.GetPetInfoByIndex(index - 1).GetID()
    quality = ipyDataMgr.GetPetInfoByIndex(index - 1).GetQuality()
    petIpyData = ipyDataMgr.GetPetInfoByIndex(index - 1)
    petNPCID = petIpyData.GetID()
    quality = petIpyData.GetQuality()
    maxClassLV = petIpyData.GetMaxRank()
    petPackIndex = ShareDefine.rptPet
    petPack = curPlayer.GetItemManager().GetPack(petPackIndex)
    for i in range(petPack.GetCount()):
@@ -544,12 +547,15 @@
            continue
        petItemNPCID = packItem.GetUserAttr(ShareDefine.Def_IudetPet_NPCID)
        if petItemNPCID == petNPCID:
            packItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, max(0, classlv - 1))
            if classlv:
                packItem.SetUserAttr(ShareDefine.Def_IudetPet_ClassLV, max(0, min(classlv, maxClassLV) - 1))
            packItem.SetUserAttr(ShareDefine.Def_IudetPet_QualityLV, quality) # 宠物品质
            GameWorld.DebugLog("已经拥有该宠物! i=%s,petItemNPCID=%s,petNPCID=%s" % (i, petItemNPCID, petNPCID))
            return
            return True
    if classlv == None:
        classlv = 1
    classlv = min(classlv, maxClassLV)
    newPetItem = GetNewPetDataItem(curPlayer, petNPCID, classlv)
    if not newPetItem:
        return
@@ -557,10 +563,12 @@
    
    if not ItemControler.PlayerItemControler(curPlayer).PutInItem(petPackIndex, newPetItem):
        return
    if not refresh:
        return True
    petItemIndex = GetPetDataItemIndexByNPCID(curPlayer, petNPCID)
    DoChangePetState(curPlayer, petItemIndex, ShareDefine.Def_PetState_Fight)
    RefreshPetItemAddAttr(curPlayer, True)
    return
    return True
#===============================================================================
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -663,6 +663,10 @@
    if not result:
        return
    
    collectNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CollectNPC", curNPC.GetNPCID())
    if collectNPCIpyData:
        DoCollectingLostHP(curPlayer, collectNPCIpyData, tick, True)
    FBLogic.OnCollectOK(curPlayer, curNPC.GetNPCID(), tick)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -101,7 +101,7 @@
g_crossPlayerItemsChangeInfo = {} #跨服玩家物品变化信息 {playerID:{"背包类型-物品位":itemMD5, ...}, ...}
g_crossPlayerSkillsChangeInfo = {} #跨服玩家技能变化信息 {playerID:[技能ID], ...}
g_crossBattlefieldCallTeamInfo = {} # 跨服战场召集队伍信息 {zoneID:{hmNum:{playerID:[召集队伍玩家ID列表], ...}, ...}, ...}
g_crossBattlefieldCallTeamInfo = {} # 跨服战场召集队伍信息 {zoneID:{hmNum:{playerID:{"callPlayerIDList":[召集队伍玩家ID列表], "factionID":阵营ID}, ...}, ...}, ...}
g_ZhuXianBossPlayerHurtDict = {} #诛仙BOSS玩家伤害排行信息
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1800,7 +1800,27 @@
SuccType_FeastRedPack_CrossPK, # 节日红包 - 跨服PK x次  141
SuccType_FeastRedPack_FBSweep, # 节日红包 - 副本扫荡 x次  142
SuccType_PassSkyTower, #通关天星塔 143
) = range(1, 144)
SuccType_Battlefield_Join, # 古神战场 - 参与 x次  144
SuccType_Battlefield_CallOpen, # 古神战场 - 召集开启 x次  145
SuccType_Battlefield_Called, # 古神战场 - 当被召集人 x次  146
SuccType_Battlefield_WinJ, # 古神战场 - 道家获胜 x次  147
SuccType_Battlefield_WinE, # 古神战场 - 佛家获胜 x次  148
SuccType_Battlefield_KillCnt, # 古神战场 - 击败玩家 x次  149
SuccType_Battlefield_CKillCnt, # 古神战场 - 连续击败y玩家 x次  150
SuccType_Battlefield_KillBoss, # 古神战场 - 阵营击败boss x次  151
SuccType_Battlefield_KillScoreKing, # 古神战场 - 不同场次击败积分王 x次  152
SuccType_Battlefield_KillGuard, # 古神战场 - 击败守卫  x次  153
SuccType_Battlefield_Score, # 古神战场 - 累计获得个人积分 xx  154
SuccType_Battlefield_ScoreMore, # 古神战场 - 单场个人积分超过yy积分 x次  155
SuccType_Battlefield_AuraScore, # 古神战场 - 累计在积分光环中获得积分 xx  156
SuccType_Battlefield_SuperItem, # 古神战场 - 累计获得古神大奖 x次  157
SuccType_Battlefield_FactionBuff, # 古神战场 - 累计采集阵营buff x次  158
SuccType_Battlefield_PersonBuff, # 古神战场 - 累计获得个人buff x次  159
SuccType_Battlefield_Crystal, # 古神战场 - 累计采集占领资源 x次  160
SuccType_Battlefield_Wall, # 古神战场 - 累计采集积分墙 x次  161
SuccType_Battlefield_BillFirst, # 古神战场 - 任意周榜榜首 x次  162
SuccType_Battlefield_BillIn, # 古神战场 - 结算时累计上榜 x次  163
) = range(1, 164)
# 节日红包成就类型
FeastRedPackSuccessTypeList = range(SuccType_FeastRedPack_TalkWorld, SuccType_FeastRedPack_FBSweep + 1)
@@ -1836,7 +1856,7 @@
ContainSuccessTypeList = [SuccType_CompoundItemEx, SuccType_PickUpItem, SuccType_MWSkillUp]
#传进来的条件是配置条件的整数倍的成就类型
MultipleSuccessTypeList = [SuccType_ElderBattlefieldConKill]
MultipleSuccessTypeList = [SuccType_ElderBattlefieldConKill, SuccType_Battlefield_CKillCnt]
#增加进度前需要重置的成就类型
NeedResetSuccessTypeList = [
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py
@@ -50,18 +50,20 @@
def OnPassiveSkillByHurtCount(defender, curBuff, curEffect, buffOwner):
    if not buffOwner:
        return
    if buffOwner.GetGameObjType() != IPY_GameWorld.gotPlayer:
        return
    # 执行次数。 当汲灵对目标造成3次伤害时,可降低目标20%的防御
    curBuff.SetValue1(curBuff.GetValue1() + 1)
    tick = GameWorld.GetGameWorld().GetTick()
    defender.SetDict(ChConfig.Def_PlayerKey_BuffHurtCnt, curBuff.GetValue1())
    PassiveBuffEffMng.OnPassiveSkillTrigger(buffOwner, defender, curBuff.GetSkill(), ChConfig.TriggerType_BuffHurtCnt, tick)
    defender.SetDict(ChConfig.Def_PlayerKey_BuffHurtCnt, 0)
    try:
        if not buffOwner:
            return
        if buffOwner.GetGameObjType() != IPY_GameWorld.gotPlayer:
            return
        # 执行次数。 当汲灵对目标造成3次伤害时,可降低目标20%的防御
        curBuff.SetValue1(curBuff.GetValue1() + 1)
        tick = GameWorld.GetGameWorld().GetTick()
        defender.SetDict(ChConfig.Def_PlayerKey_BuffHurtCnt, curBuff.GetValue1())
        PassiveBuffEffMng.OnPassiveSkillTrigger(buffOwner, defender, curBuff.GetSkill(), ChConfig.TriggerType_BuffHurtCnt, tick)
        defender.SetDict(ChConfig.Def_PlayerKey_BuffHurtCnt, 0)
    except:
        GameWorld.ErrLog("OnPassiveSkillByHurtCount error!!!")
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
@@ -3547,7 +3547,7 @@
# @param tagRoundPosY 对地面区域攻击坐标Y
# @return 返回值真, 释放成功
# @remarks 自定义函数, 释放Buff技能
def __DoLogic_AddBuff(attacker, defender, curSkill, isEnhanceSkill, tick,  tagRoundPosX = 0, tagRoundPosY = 0):
def __DoLogic_AddBuff(attacker, defender, curSkill, isEnhanceSkill, tick,  tagRoundPosX = 0, tagRoundPosY = 0, addForce=False):
    skillTypeID = curSkill.GetSkillTypeID()
    skillBuffType = SkillCommon.GetBuffType(curSkill)
    
@@ -3581,7 +3581,7 @@
    else:  
        #---添加的Buff值---, 仅支持放在效果1的buff
        addBuffValueList = GetAddBuffValue(attacker, curSkill, defender)
        result = BuffSkill.DoAddBuff(defender, skillBuffType, curSkill, tick, addBuffValueList, attacker)
        result = BuffSkill.DoAddBuff(defender, skillBuffType, curSkill, tick, addBuffValueList, attacker, addForce=addForce)
        
        # result为0 是抵消的不需要对buff处理
        if result is not 0: