From 0c27822ef5e6c67782ed143a4ff03ecfbdfda1fb Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 23 五月 2022 16:52:58 +0800
Subject: [PATCH] 9415 【BT】【后端】古神战场(副本内功能完整版本)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py          |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py                                    |   24 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py                                     |  125 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py                              |   45 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py                                    |    4 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py                                          |   75 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                          |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py                             |   85 -
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py                                         |   65 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                       |   23 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                                     |   11 
 PySysDB/PySysDBPY.h                                                                                                        |    9 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                              |   24 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py                                |    3 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py                                                     |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                                         |   24 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py                    |   26 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py                     |   22 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py                       |   15 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py                                  |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py                                 |  210 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py                       |   67 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py                           |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py | 1773 ++++++++++++++++++++++++++++++++------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                                       |   16 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                                           |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py          |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                            |    2 
 28 files changed, 2,218 insertions(+), 465 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 4fafc4a..0592cf7 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -446,6 +446,15 @@
 	DWORD		IceLodeFightPower;	//冰晶矿脉扫荡战斗力
 };
 
+//特殊地图玩家属性公式表
+
+struct tagSpecMapPlayerAttrFormat
+{
+	DWORD		_DataMapID;	//数据地图ID
+	char		AttrName;	//属性名
+	char		AttrValueFormat;	//最终属性值公式(可用参数属性名)
+};
+
 //GM测试属性表
 
 struct tagGMAttr
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
index 0521929..a6dff1b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
+++ b/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
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
index 48aebe0..47443a1 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
+++ b/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))
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 2ad79cc..d7b975c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/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 = [
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index 97b8ccc..5910d59 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -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:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
index 94ad794..c24f3bd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
index 8cabede..0a5446e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
+++ b/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
     
     #私有木桩只能自己打自己的
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 5bc0ae1..6185f74 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py
index 6fe7508..cf66546 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
index 94a6d4a..29b96e0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py
index 2a3f49c..7484a3f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Pet.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 4a1a011..e9c753f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/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)
 
 #---------------------------------------------------------------------
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index db9d922..c668d83 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/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 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
index 5db11ee..830fe33 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
+++ b/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
-
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index c6d5c7e..066fd08 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py
index 5168672..1ff81a7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Map/GameMap.py
+++ b/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
\ No newline at end of file
+    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
+    
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py
new file mode 100644
index 0000000..8d77c35
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_22.py
@@ -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
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
index 5eda952..6b08c4f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/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)
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index f6781a1..b78c037 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py
index 2ab86c5..cebf17f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCompensationTube.py
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 41301f6..6764441 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4858,6 +4858,9 @@
         #护盾值刷新
         self.__RefreshMaxProDef(beforeMaxProDef)
         
+        #特殊指定属性公式
+        GameMap.SpecialMapSetAttrValueByFormat(curPlayer)
+        
         # 【到此所有功能属性都已刷新处理完毕,复制一份 功能属性的刷新结果,用于BUFF属性单独刷新】
         EffGetSet.CopyPlayerFuncAttr(curPlayer)
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
index 79a64da..f076dba 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
+++ b/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):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
index c4534d3..e027e7a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
+++ b/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
 #===============================================================================
 
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
index 2ac3136..1816ccc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
+++ b/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
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index b7da1e1..f4963bc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/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玩家伤害排行信息
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 2ad79cc..d7b975c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/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 = [
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py
index 2e5560a..5d2c846 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameBuffs/BuffProcess_1089.py
+++ b/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
 
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
index dfab201..6a5f468 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
+++ b/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:

--
Gitblit v1.8.0