From ad18dcb3014762a46929bb779b44d27262dcd3c9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 24 十一月 2021 16:52:22 +0800
Subject: [PATCH] 9341 【BT5】【主干】【后端】情缘系统(增加情缘副本;AB相互提亲优化聘礼ID取较高的)

---
 Tool/工具路径IDDispatchServer.txt                                                                                  |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py               |    2 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py                                            |   21 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py                  |   24 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py |  357 +++++++++++++++++++++++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py                                              |    6 
 ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py                                                     |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                           |   63 -----
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py                                            |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py                      |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py              |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py       |   70 ++++++
 12 files changed, 497 insertions(+), 76 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index c1c901c..c6f4d3c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -700,6 +700,8 @@
 Def_FBMapID_CrossGrasslandLing = 32040
 #跨服仙草园
 Def_FBMapID_CrossGrasslandXian = 32050
+#情缘副本
+Def_FBMapID_Love = 31300
 
 #需要刷世界BOSS的副本
 WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss, Def_FBMapID_DemonKing]
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index a316f70..a8d5e9e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -497,6 +497,12 @@
     
     # 组队副本, 有队伍的情况才验证其他队员可否进入,否则代表单人进入
     if gameMap.GetMapFBType() == ChConfig.fbtTeam:
+        if tagMapID == ChConfig.Def_FBMapID_Love:
+            onlyDoubleTeam = IpyGameDataPY.GetFuncCfg("LoveFB", 1)
+            if onlyDoubleTeam:
+                if PlayerTeam.CheckTeamOnLineCount(curPlayer.GetTeam(), includeTJG=False) != 2:
+                    PlayerControl.NotifyCode(curPlayer, "OnlyTwoMemTeamCanEnter", [tagMapID])
+                    return
         PlayerTeam.OnEnterFBTeamAsk(curPlayer, PlayerTeam.TeamFBAskType_Enter, tagMapID, tagLineID, tick)
         return
     
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py
index 96c5995..e0b6f71 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py
@@ -563,6 +563,8 @@
     PyGameData.g_marryCandyInfo[(reqPlayerID, playerID)] = candyObj
     __SortCandy()
     Sync_CandyList(None, [candyObj])
+    
+    PyGameData.g_marryReqInfo.pop(playerID, None) # 可能存在相互提亲的情况,尝试顺便把自身的提亲请求删除,因为已经无用了
     return True
 
 def __SortCandy():
@@ -863,17 +865,30 @@
             GameWorld.Log("聘礼提亲次数不足,无法提亲! bridePriceID=%s,buyCount(%s) >= canBuyMax(%s)" 
                           % (bridePriceID, buyCount, canBuyMax), playerID)
             return
-        
+                
+    curTime = int(time.time())
     if tagPlayerID in PyGameData.g_marryReqInfo:
         tagReqData = PyGameData.g_marryReqInfo[tagPlayerID]
+        tagBridePriceID = tagReqData.bridePriceID
         if playerID == tagReqData.playerIDB and not __CheckMarryReqTimeout(tagReqData):
-            GameWorld.Log("玩家提亲时,目标刚好已经先提过亲,且在有效期内,直接成亲!tagPlayerID=%s" % tagPlayerID, playerID)
+            if tagBridePriceID < bridePriceID:
+                GameWorld.Log("玩家提亲时,目标刚好已经先提过亲,且在有效期内,直接成亲!使用当前提亲玩家较高聘礼ID为准! tagPlayerID=%s,tagBridePriceID=%s < bridePriceID=%s" 
+                              % (tagPlayerID, tagBridePriceID, bridePriceID), playerID)
+                reqData = MarryReq()
+                reqData.playerIDA = playerID
+                reqData.playerIDB = tagPlayerID
+                reqData.bridePriceID = bridePriceID
+                reqData.reqTime = curTime
+                PyGameData.g_marryReqInfo[playerID] = reqData
+                if __DoMarryResponse(tagPlayer, curPlayer, playerID, 1):
+                    return
+            GameWorld.Log("玩家提亲时,目标刚好已经先提过亲,且在有效期内,直接成亲!tagPlayerID=%s,tagBridePriceID=%s,bridePriceID=%s" 
+                          % (tagPlayerID, tagBridePriceID, bridePriceID), playerID)
             if __DoMarryResponse(curPlayer, tagPlayer, tagPlayerID, 1):
                 return
         else:
             GameWorld.DebugLog("对方有提亲,但是对象不一样或已超时! tagPlayerID=%s, timeout=%s" % (tagReqData.playerIDB, __CheckMarryReqTimeout(tagReqData)), playerID)
             
-    curTime = int(time.time())
     if playerID not in PyGameData.g_marryReqInfo:
         reqData = MarryReq()
         PyGameData.g_marryReqInfo[playerID] = reqData
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py
index bf88ff0..fa4bbf0 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py
@@ -1558,14 +1558,17 @@
     return (teamLV == IPY_GameServer.tmlMemberCanCall or 
              teamLV == IPY_GameServer.tmlLeader)
     
-def CheckTeamOnLineCount(curTeam):
+def CheckTeamOnLineCount(curTeam, includeTJG=True):
     ##获得队伍剩余在线人数
-    
+    if not curTeam:
+        return 0
     count = 0
     for i in xrange(curTeam.GetMemberCount()):
         curPlayer = curTeam.GetMemberPlayer(i)
         if curPlayer == None:
             continue
+        if not includeTJG and PlayerControl.GetIsTJG(curPlayer):
+            continue
         count += 1
     return count
 
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 4695ecd..db9d922 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -318,6 +318,18 @@
     
     return
 
+def GetFBEveryoneDropInfo(curNPC):
+    ## 获取副本每人掉落设置信息
+    # @return: None or [ownerPlayerList, isOnlySelfSee]
+    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
+    
+    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "GetFBEveryoneDropInfo"))
+    
+    if callFunc:
+        return callFunc(curNPC)
+    
+    return
+
 ## Npc杀死NPC,
 #  @param attacker:攻击方:NPC
 #  @param defender:被杀的NPC
@@ -2162,6 +2174,18 @@
     
     return
 
+
+## TD怪到达终点
+def OnTDNPCReachTheGoal(curNPC, tick):
+    do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
+    
+    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnTDNPCReachTheGoal"))
+    
+    if callFunc:
+        callFunc(curNPC, tick)
+        
+    return
+
 ## 刷怪通知
 #  @param refreshMark 
 #  @return None
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
index e7d21ba..86f14e1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
@@ -650,6 +650,8 @@
                 itemDict['IsAuctionItem'] = int(itemInfo[2])
         elif isinstance(itemInfo, int):
             itemDict['ItemID'] = itemInfo
+        elif isinstance(itemInfo, dict):
+            itemDict = itemInfo
         else: #物品实例
             if not ItemCommon.CheckItemCanUse(itemInfo):
                 continue
@@ -681,6 +683,47 @@
     for npcid, HPPer in npcDict.items():
         killList.append({"NPCID":npcid, "HPPer":HPPer})
     return killList
+
+def OnPickUpItem(curPlayer, curItem, tick, overFunc):
+    mapItemType = curItem.GetType()
+    if mapItemType != ChConfig.Def_ItemType_Money:
+        playerID = curPlayer.GetID()
+        isEquip = ItemCommon.CheckItemIsEquip(curItem)
+        jsonItem = ItemCommon.GetJsonItem(curItem)
+        if playerID in PyGameData.g_fbPickUpItemDict:
+            if isEquip:
+                PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)
+            else:
+                isIn = False
+                for itemInfo in PyGameData.g_fbPickUpItemDict[playerID]:
+                    if itemInfo["ItemID"] == jsonItem["ItemID"] and itemInfo.get("IsBind") == jsonItem.get("IsBind"):
+                        itemInfo["Count"] = itemInfo.get("Count", 1)+ jsonItem.get("Count", 1)
+                        isIn = True
+                        break
+                if not isIn:
+                    PyGameData.g_fbPickUpItemDict[playerID].append(jsonItem)
+        else:
+            PyGameData.g_fbPickUpItemDict[playerID] = [jsonItem]
+            
+    if overFunc == None:
+        return
+    
+    playerItemCount = 0
+    mapItemManager = GameWorld.GetMapItemManager()
+    for index in xrange(mapItemManager.GetMapItemCount()):
+        mapItem = mapItemManager.GetMapItemByIndex(index)
+        if not mapItem or mapItem.IsEmpty():
+            continue
+        
+        # 还有属于自己的东西没捡不通知结束
+        if mapItem.GetOwnerID() == curPlayer.GetPlayerID():
+            playerItemCount += 1
+        
+    isItemAllPickUp = (playerItemCount <= 1)
+    if isItemAllPickUp:
+        overFunc(curPlayer, tick)
+        
+    return
 #---------------------------------------------------------------------
 def SyncDynamicBarrierState(barrierPointList, state, curPlayer=None):
     '''同步动态障碍物是否有效性
@@ -1583,6 +1626,16 @@
         return GameWorld.GetDataByDigitPlace(enterCnt, lineBit)
     return enterCnt
 
+def AddFBCntByItem(curPlayer, itemID, mapID, addCnt):
+    ## 物品增加副本次数
+    mapID = GetRecordMapID(mapID)
+    itemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID)
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID, itemAddCnt + addCnt)
+    Sync_FBPlayerFBInfoData(curPlayer, mapID)
+    PlayerControl.NotifyCode(curPlayer, 'AddActivityCount_1', [itemID, mapID, addCnt])
+    OnFBCountChangeEffectRecoverCount(curPlayer, mapID)
+    return
+
 ## 增加玩家进入副本次数
 #  @param curPlayer 玩家实例
 #  @param fbID 副本id
@@ -1894,6 +1947,11 @@
 def BuyFBEnterCount(playerIndex, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(playerIndex)
     mapID = clientData.FBID
+    if mapID == ChConfig.Def_FBMapID_Love:
+        coupleID = PlayerControl.GetCoupleID(curPlayer)
+        if not coupleID:
+            GameWorld.DebugLog("没有伴侣无法购买情缘副本次数!")
+            return
     ipyData = GetFBIpyData(mapID)
     if not ipyData:
         return
@@ -1914,12 +1972,14 @@
         return
     
     if hasBuyCnt >= canBuyCnt:
-        GameWorld.DebugLog("购买次数已经用完mapID=%s"%mapID)
+        GameWorld.DebugLog("购买次数已经用完mapID=%s,buyTimesVIPPriID=%s,hasBuyCnt=%s >= canBuyCnt=%s" % (mapID, buyTimesVIPPriID, hasBuyCnt, canBuyCnt))
         return
     costGoldDict = IpyGameDataPY.GetFuncEvalCfg('BuyFBCntCost')
     costGold = costGoldDict.get(str(mapID), '0')
     costGold = eval(costGold)
-    costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, ShareDefine.TYPE_Price_Gold_Paper_Money, costGold)
+    costMoneyTypeInfo = IpyGameDataPY.GetFuncEvalCfg('BuyFBCntCost', 2)
+    costType = costMoneyTypeInfo.get(str(mapID), ShareDefine.TYPE_Price_Gold_Paper_Money)
+    costMoneyList = PlayerControl.HaveMoneyEx(curPlayer, costType, costGold)
     #GameWorld.Log('costMoneyList=%s,costGold=%s'%(costMoneyList,costGold))
     if not costMoneyList:
         return
@@ -1933,6 +1993,12 @@
     Sync_FBPlayerFBBuyCount(curPlayer, [mapID])
     PlayerControl.NotifyCode(curPlayer, 'FBEnterTimeBuy', [mapID])
     OnFBCountChangeEffectRecoverCount(curPlayer, mapID)
+    if mapID == ChConfig.Def_FBMapID_Love:
+        coupleID = PlayerControl.GetCoupleID(curPlayer)
+        if coupleID:
+            addItemList = IpyGameDataPY.GetFuncEvalCfg("LoveFB", 3)
+            paramList = [curPlayer.GetPlayerName()]
+            PlayerControl.SendMailByKey("BuyLoveFBCntCoupleMail", [coupleID], addItemList, paramList)
     return
 
 def DoFuncOpen_RunDaily(curPlayer): return EventReport.WriteFuncCMEAcceptable(curPlayer, ShareDefine.GameFuncID_RunDaily)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py
new file mode 100644
index 0000000..4641fdb
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py
@@ -0,0 +1,357 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GameWorldLogic.FBProcess.GameLogic_Love
+#
+# @todo:情缘副本
+# @author hxp
+# @date 2021-11-24
+# @version 1.0
+#
+# 详细描述: 情缘副本
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2021-11-24 16:30"""
+#-------------------------------------------------------------------------------
+
+import FBCommon
+import NPCCommon
+import ReadChConfig
+import IPY_GameWorld
+import PlayerControl
+import GameWorldProcess
+import ItemControler
+import IpyGameDataPY
+import PyGameData
+import GameWorld
+import ChConfig
+
+(
+Def_Time_MapPrepare, # 准备时间, 秒
+Def_Time_Fight, # 战斗时间, 秒
+Def_Time_PickupItem, # 拾取物品时间, 秒
+Def_Time_Leave, # 结束时间, 秒
+) = range(4)
+
+#当前副本地图的状态
+(
+FB_Step_Open, # 地图开启
+FB_Step_MapPrepare, # 地图准备
+FB_Step_Fighting, # 战斗中
+FB_Step_PickupItem, # 拾取物品
+FB_Step_LeaveTime, # 自由退出时间
+FB_Step_Over, # 副本关闭
+) = range(6)
+
+FB_CostTime = 'FB_CostTime'   # 过关耗时
+FBPlayerDict_EnterState = "FBPlayerDict_EnterState" # 已进入的玩家,参数
+
+TDRefreshNPCFileNum = ChConfig.Def_FBMapID_Love
+
+Def_Devil_TimeType = IPY_GameWorld.tttLeaveFamilyWar
+
+def OnOpenFB(tick):
+    ##开启副本
+    return
+
+def OnCloseFB(tick):
+    ##关闭副本
+    return
+
+def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
+    onlyDoubleTeam = IpyGameDataPY.GetFuncCfg("LoveFB", 1)
+    if onlyDoubleTeam:
+        if not curPlayer.GetTeamID():
+            PlayerControl.NotifyCode(curPlayer, "OnlyTwoMemTeamCanEnter", [mapID])
+            return False
+    return True
+
+def GetPlayerResetWorldPosFBMsg(curPlayer, lineId):
+    ## 获取入场携带信息
+    return ""
+
+def OnChangeMapAsk(ask, tick):
+    ##查询是否可以进入地图
+    return IPY_GameWorld.cmeAccept
+
+def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
+    ##副本玩家进入点
+    return ipyEnterPosInfo
+
+def DoEnterFB(curPlayer, tick):
+        
+    gameFB = GameWorld.GetGameFB()
+    fbStep = gameFB.GetFBStep()
+    playerID = curPlayer.GetPlayerID()
+    
+    GameWorld.Log("DoEnterFB...", playerID)
+    hadDelTicket = FBCommon.GetHadDelTicket(curPlayer)
+    if not hadDelTicket:
+        mapID = GameWorld.GetGameWorld().GetMapID()
+        delResult = FBCommon.DelFBEnterTicket(curPlayer, mapID)
+        isOK = delResult[0]
+        #hasBind = delResult[1]
+        if not isOK:
+            PlayerControl.PlayerLeaveFB(curPlayer)
+            return
+        FBCommon.SetHadDelTicket(curPlayer)
+        FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_Love)
+        PyGameData.g_fbPickUpItemDict.pop(playerID, 0)
+        gameFB.SetPlayerGameFBDict(playerID, FBPlayerDict_EnterState, 1)
+        
+    if fbStep == FB_Step_Open:
+        FBCommon.SetFBStep(FB_Step_MapPrepare, tick)
+        
+    if fbStep <= FB_Step_MapPrepare:
+        mapID = GameWorld.GetMap().GetMapID()
+        notify_tick = FBCommon.GetFBLineStepTime(mapID)[Def_Time_MapPrepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+        curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, max(notify_tick, 0), True)
+        curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
+        
+    elif fbStep == FB_Step_Fighting:
+        mapID = GameWorld.GetMap().GetMapID()
+        notify_tick = FBCommon.GetFBLineStepTime(mapID)[Def_Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+        curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
+        FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(mapID), curPlayer)
+        
+    DoFBHelp(curPlayer, tick)
+    return
+
+def DoExitFB(curPlayer, tick):
+    ##玩家退出副本
+    return
+
+def DoPlayerLeaveFB(curPlayer, tick):
+    ##玩家主动离开副本.
+    return
+
+def DoFBHelp(curPlayer, tick):
+    wheelNum = None
+    movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % TDRefreshNPCFileNum)
+    rMarkList = movePointDict.keys()
+    gameFB = GameWorld.GetGameFB()
+    for rMark in rMarkList:
+        if wheelNum == None:
+            wheelNum = gameFB.GetGameFBDictByKey(ChConfig.Map_TDNPC_RefreshBigWheelNum % rMark) + 1
+            
+    #副本帮助(通知客户端显示)
+    fbHelpDict = {FBCommon.Help_wheel:wheelNum}
+    GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
+    FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
+    return
+
+##副本定时器
+# @param tick 时间戳
+# @return 返回值无意义
+# @remarks 副本定时器
+def OnProcess(tick):
+    
+    fbStep = GameWorld.GetGameFB().GetFBStep()
+    
+    if fbStep == FB_Step_MapPrepare:
+        __DoLogic_MapPrepare(tick)
+    elif fbStep == FB_Step_Fighting:
+        __DoLogic_MapFighting(tick)
+    elif fbStep == FB_Step_PickupItem:
+        __DoLogic_PickupItem(tick)
+    elif fbStep == FB_Step_LeaveTime:
+        __DoLogic_MapLeave(tick)
+        
+    return
+
+def __DoLogic_MapPrepare(tick):
+    mapID = GameWorld.GetMap().GetMapID()
+    timeInfo = FBCommon.GetFBLineStepTime(mapID)
+    if tick - GameWorld.GetGameFB().GetFBStepTick() < timeInfo[Def_Time_MapPrepare] * 1000:
+        return
+    
+    FBCommon.SetFBStep(FB_Step_Fighting, tick)
+    
+    movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % TDRefreshNPCFileNum)
+    rMarkList = movePointDict.keys()
+    isNotify = True
+    for rMark in rMarkList:
+        FBCommon.OpenTDNPCRefresh(rMark, TDRefreshNPCFileNum, 0, tick, isNotify)
+        if isNotify:
+            isNotify = False
+            
+    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # 强制同步一次
+    # 通知开始
+    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, timeInfo[Def_Time_Fight] * 1000)
+    return
+
+def __DoLogic_MapFighting(tick):
+    
+    mapID = GameWorld.GetMap().GetMapID()
+    timeInfo = FBCommon.GetFBLineStepTime(mapID)
+    # 间隔未到
+    if tick - GameWorld.GetGameFB().GetFBStepTick() < timeInfo[Def_Time_Fight] * 1000:
+        #FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
+        return
+    
+    __DoOver(tick)
+    return
+
+def __DoLogic_PickupItem(tick):
+    mapItemCount = GameWorld.GetMapItemManager().GetMapItemCount()
+    mapID = GameWorld.GetMap().GetMapID()
+    timeInfo = FBCommon.GetFBLineStepTime(mapID)
+    if mapItemCount and tick - GameWorld.GetGameFB().GetFBStepTick() < timeInfo[Def_Time_PickupItem] * 1000:
+        return
+    FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
+    
+    copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
+    for i in xrange(copyMapPlayerManager.GetPlayerCount()):
+        curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)
+        if curPlayer == None or curPlayer.IsEmpty():
+            continue
+        DoOverToLeave(curPlayer, tick)
+        
+    return
+
+def __DoLogic_MapLeave(tick):
+    mapID = GameWorld.GetMap().GetMapID()
+    timeInfo = FBCommon.GetFBLineStepTime(mapID)
+    if tick - GameWorld.GetGameFB().GetFBStepTick() < timeInfo[Def_Time_Leave] * 1000:
+        return
+    FBCommon.SetFBStep(FB_Step_Over, tick)
+    
+    # 时间到,踢出还在副本的玩家等...
+    FBCommon.DoLogic_FBKickAllPlayer()
+    #GameWorld.GetGameWorld().SetPropertyID(0)
+    GameWorldProcess.CloseFB(tick)
+    return
+
+def DoFBRebornNPC(curNPC, tick):
+    ##副本有NPC召出
+    fromRefreshValue = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshValue)
+    
+    if fromRefreshValue == TDRefreshNPCFileNum:
+        curNPC.SetIsNeedProcess(True)
+        FBCommon.UpdTDNPCCnt(curNPC, 1)
+        
+    return
+
+def OnTDCurWheelOver(refreshMark, tick):
+    movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % TDRefreshNPCFileNum)
+    rMarkList = movePointDict.keys()
+    isWheelRefreshOver = FBCommon.IsTDWheelRefreshOver(rMarkList) # 本大波所有点刷怪完毕
+    if isWheelRefreshOver:
+        GameWorld.DebugLog("本大波所有点刷完, 强制同步一次怪物数")
+        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # 强制同步一次
+        
+    return
+
+def OnTDNPCReachTheGoal(curNPC, tick):
+    #GameWorld.DebugLog("到达终点...")
+    curNPC.SetVisible(False)
+    NPCCommon.SetDeadEx(curNPC)
+    return
+
+def GetFBEveryoneDropInfo(curNPC):
+    ## 获取副本每人掉落设置信息
+    # @return: None or [ownerPlayerList, isOnlySelfSee]
+        
+    isOnlySelfSee = True
+    ownerPlayerList = []
+    playerManager = GameWorld.GetMapCopyPlayerManager()
+    for index in xrange(playerManager.GetPlayerCount()):
+        curPlayer = playerManager.GetPlayerByIndex(index)
+        if not curPlayer:
+            continue
+        ownerPlayerList.append(curPlayer)
+        
+    return ownerPlayerList, isOnlySelfSee
+
+#def DoFB_Npc_KillNPC(attacker, curNPC, tick):
+#    __DoOnNPCKilled(attacker, curNPC, tick)
+#    return
+#
+#def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
+#    __DoOnNPCKilled(curPlayer, curNPC, tick)
+#    return
+
+def DoFB_NPCDead(curNPC):
+    
+    fbStep = GameWorld.GetGameFB().GetFBStep()
+    if fbStep != FB_Step_Fighting:
+        return
+    
+    fromRefreshValue = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_FromRefreshValue)
+    # 入侵怪
+    if fromRefreshValue != TDRefreshNPCFileNum:
+        return
+    
+    FBCommon.UpdTDNPCCnt(curNPC, -1) # 怪物数-1
+    
+    tick = GameWorld.GetGameWorld().GetTick()
+    movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % TDRefreshNPCFileNum)
+    rMarkList = movePointDict.keys()
+    isAllRefresh = FBCommon.IsTDNPCRefreshOver(rMarkList) # 所有怪是否全部刷完
+    isAllKilled = FBCommon.IsTDNPCCurWheelAllKilled(rMarkList) # 本波怪是否全部被击杀
+    
+    if isAllRefresh and isAllKilled:
+        GameWorld.DebugLog("全部怪刷新完毕且已被杀完, 处理结束逻辑")
+        __DoOver(tick)
+        
+    elif isAllKilled:
+        GameWorld.DebugLog("本波怪全部杀完,进入下一波!")
+        for index, rMark in enumerate(rMarkList):
+            FBCommon.SetEnterTDNextWheel(rMark, tick, index == 0)
+            #if index == 0:
+            #    FBCommon.Sync_TDNextWheelTick(None, rMark, Def_Devil_TimeType, tick)
+            
+        FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # 波数切换强制同步一次
+        
+    return
+
+def __DoOver(tick):
+    # 副本结束逻辑
+    GameWorld.DebugLog("处理副本结束逻辑")
+    costTime = tick - GameWorld.GetGameFB().GetFBStepTick()
+    gameFB = GameWorld.GetGameFB()
+    gameFB.SetGameFBDict(FB_CostTime, costTime)
+    
+    FBCommon.SetFBStep(FB_Step_PickupItem, tick)
+    
+    # 清怪
+    FBCommon.ClearFBNPC()
+    FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0) # 副本结束强制同步一次
+    
+    movePointDict = ReadChConfig.GetEvalChConfig('TD_%s_Move' % TDRefreshNPCFileNum)
+    rMarkList = movePointDict.keys()
+    # 关闭所有刷怪点
+    for rMark in rMarkList:
+        FBCommon.CloseTDNPCRefresh(rMark, True)
+    return
+
+def OnPickUpItem(curPlayer, curItem, tick):
+    FBCommon.OnPickUpItem(curPlayer, curItem, tick, None)
+    return
+
+def DoOverToLeave(curPlayer, tick):
+    isPass = 1
+    playerID = curPlayer.GetPlayerID()
+    mapID = GameWorld.GetMap().GetMapID()
+    gameFB = GameWorld.GetGameFB()
+    leaveTick = FBCommon.GetFBLineStepTime(mapID)[Def_Time_Leave] * 1000
+    curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
+    
+    costTime = gameFB.GetGameFBDictByKey(FB_CostTime)
+    
+    pickupItemList = PyGameData.g_fbPickUpItemDict.get(playerID, [])
+    coupleID = PlayerControl.GetCoupleID(curPlayer)
+    coupleEnterState = gameFB.GetPlayerGameFBDictByKey(coupleID, FBPlayerDict_EnterState) if coupleID else 0
+    if coupleEnterState:
+        coupleAwardListEx = IpyGameDataPY.GetFuncEvalCfg("LoveFB", 2)
+        ItemControler.GivePlayerItemOrMail(curPlayer, coupleAwardListEx)
+        pickupItemList.extend(coupleAwardListEx)
+        
+    overDict = {FBCommon.Over_dataMapID:mapID, FBCommon.Over_isPass:isPass, FBCommon.Over_costTime:costTime, 
+                FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(pickupItemList)}
+    FBCommon.Notify_FB_Over(curPlayer, overDict)
+    GameWorld.Log("结算: coupleID=%s,coupleEnterState=%s,overDict=%s" % (coupleID, coupleEnterState, overDict), playerID)
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py
index b1adce6..7a78589 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py
@@ -17,7 +17,6 @@
 
 import ItemCommon
 import FBCommon
-import PlayerControl
 import ChConfig
 
 def BatchUseItem(curPlayer, curRoleItem, tick, useCnt, exData):
@@ -25,14 +24,7 @@
     itemTypeID = curRoleItem.GetItemTypeID()
     curEff = curRoleItem.GetEffectByIndex(0)
     mapID = curEff.GetEffectValue(0)
-    mapID = FBCommon.GetRecordMapID(mapID)
-    itemAddCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID)
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_ItemAddFbCnt % mapID, itemAddCnt+useCnt)
-    
+    FBCommon.AddFBCntByItem(curPlayer, itemTypeID, mapID, useCnt)
     ItemCommon.DelItem(curPlayer, curRoleItem, useCnt, True, ChConfig.ItemDel_AddFBCnt)
-    FBCommon.Sync_FBPlayerFBInfoData(curPlayer, mapID)
-    PlayerControl.NotifyCode(curPlayer, 'AddActivityCount_1', [itemTypeID, mapID, useCnt])
-    
-    FBCommon.OnFBCountChangeEffectRecoverCount(curPlayer, mapID)
     return True, useCnt
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
index 73b6763..23c9aa9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
@@ -31,6 +31,7 @@
 import PetControl
 import ReadChConfig
 import GameObj
+import FBLogic
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -643,7 +644,7 @@
     return
 
 
-def NPCMoveByPointList(curNPC, movePointList):
+def NPCMoveByPointList(curNPC, movePointList, tick):
     if not movePointList:
         return
     pointIndex = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_MovePointIndex)
@@ -669,5 +670,10 @@
         
         curNPC.Move(destPosX, destPosY)
         return
+    
+    # 到达终点
+    if pointIndex == (len(movePointList) - 1):
+        FBLogic.OnTDNPCReachTheGoal(curNPC, tick)
+        
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py
index 367ed38..d9bd4d0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py
@@ -115,7 +115,7 @@
             MovePointList = movePointDict[fromRefreshMark]
             
     #NpcMoveByMovePointList(curNPC, MovePointList, tick)
-    AICommon.NPCMoveByPointList(curNPC, MovePointList)
+    AICommon.NPCMoveByPointList(curNPC, MovePointList, tick)
     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 c217d01..2985ad0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -4201,58 +4201,6 @@
                 #GameWorld.DebugLog("私有物品掉落: dropItemID=%s" % dropItemID, ownerPlayer.GetPlayerID())
                 
         return specDropItemList
-
-    def __NPCDropItemByPlayers(self, dropPlayerList, mapID, ipyDrop):
-        '''NPC掉落物品, 多玩家每人一份, 混合掉落'''
-        curNPC = self.__Instance
-        npcID = curNPC.GetNPCID()
-        if not dropPlayerList:
-            return
-        
-        #GameWorld.DebugLog("NPC多玩家混合掉落: dropPlayerCount=%s" % len(dropPlayerList))
-        auctionItemIDList = []
-        dropItemList = []
-        for dropPlayer in dropPlayerList:
-            dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ipyDrop=ipyDrop)
-            if not dropInfo:
-                continue
-            dropIDList, auctionIDList, dropMoneyCnt, moneyValue = dropInfo
-            moneyID = self.__GetDropMoneyModelID(moneyValue)
-            if dropMoneyCnt:
-                dropIDList += [moneyID] * dropMoneyCnt
-                
-            dropPlayerID = dropPlayer.GetPlayerID()
-            #GameWorld.DebugLog("    dropPlayerID=%s,dropIDList=%s" % (dropPlayerID, dropIDList))
-            for dropID in dropIDList:
-                dropItemList.append([dropID, dropPlayerID])
-            auctionItemIDList += auctionIDList
-            
-        #打乱物品顺序
-        random.shuffle(dropItemList)
-        
-        gameMap = GameWorld.GetMap()
-        dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # 以NPC为中心点开始掉落
-        index = 0
-        for posX, posY in ChConfig.Def_DropItemAreaMatrix:
-            resultX = dropPosX + posX
-            resultY = dropPosY + posY
-            
-            if not gameMap.CanMove(resultX, resultY):
-                #玩家不可移动这个点
-                continue
-            
-            if index > len(dropItemList) - 1:
-                break                        
-            itemID, ownerID = dropItemList[index]
-            index += 1
-            itemCnt = moneyValue if itemID == moneyID else 1
-            iaAuctionItem = itemID in auctionItemIDList
-            curItem = self.__CreateDropItem(curNPC, itemID, itemCnt, iaAuctionItem, dropPlayer)
-            if not curItem:
-                continue
-            self.__MapCreateItem(curItem, resultX, resultY, ChConfig.Def_NPCHurtTypePlayer, ownerID)
-            
-        return
     
     ## 物品掉落
     #  @param self 类实例
@@ -4284,10 +4232,6 @@
                 curWorldLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
                 GameWorld.ErrLog("取不到NPC掉落信息!npcID=%s,curWorldLV=%s" % (npcID, curWorldLV))
             return
-        
-        #if mapID == ChConfig.Def_FBMapID_MunekadoTrial:
-        #    dropPlayerList = GameLogic_MunekadoTrial.GetCanDropPlayerList()
-        #    return self.__NPCDropItemByPlayers(dropPlayerList, mapID, ipyDrop)
         
         dropIDList, auctionIDList, dropMoneyCnt, moneyValue = [], [], 0, 0
         dropInfo = GetNPCDropInfo(dropPlayer, mapID, npcID, ownerPlayerList, ipyDrop, False)
@@ -4966,8 +4910,13 @@
             self.__KillNPCFuncEx(curPlayer, curNPC, maxHurtID, True)
         self.__ownerPlayerList = ownerPlayerList
         
+        fbOwnerInfo = FBLogic.GetFBEveryoneDropInfo(curNPC)
+        if fbOwnerInfo != None:
+            ownerPlayerList, isOnlySelfSee = fbOwnerInfo            
+            for curPlayer in ownerPlayerList:
+                self.__NPCDropItem(curPlayer, ChConfig.Def_NPCHurtTypePlayer, curPlayer.GetPlayerID(), [curPlayer], isOnlySelfSee=isOnlySelfSee)
         #调用物品掉落,boss一人一份
-        if isGameBoss and hurtType in [ChConfig.Def_NPCHurtTypePlayer, ChConfig.Def_NPCHurtTypeTeam, ChConfig.Def_NPCHurtTypeSpecial]:
+        elif isGameBoss and hurtType in [ChConfig.Def_NPCHurtTypePlayer, ChConfig.Def_NPCHurtTypeTeam, ChConfig.Def_NPCHurtTypeSpecial]:
             isOnlySelfSee = len(ownerPlayerList) > 1
             for curPlayer in ownerPlayerList:
                 self.__NPCDropItem(curPlayer, ChConfig.Def_NPCHurtTypePlayer, curPlayer.GetPlayerID(), [curPlayer], isOnlySelfSee=isOnlySelfSee)
diff --git "a/Tool/\345\267\245\345\205\267\350\267\257\345\276\204IDDispatchServer.txt" "b/Tool/\345\267\245\345\205\267\350\267\257\345\276\204IDDispatchServer.txt"
index 9c26dec..12ef4b9 100644
--- "a/Tool/\345\267\245\345\205\267\350\267\257\345\276\204IDDispatchServer.txt"
+++ "b/Tool/\345\267\245\345\205\267\350\267\257\345\276\204IDDispatchServer.txt"
@@ -1 +1,2 @@
-工具路径\MiracleCode\TCode\TeamServer\Server4\Servers\IDDispatchServer
\ No newline at end of file
+工具路径\MiracleCode\TCode\TeamServer\Server4\Servers\IDDispatchServer
+合服工具\MiracleCode\TCode\TeamServer\Server4\Tools\ServerMergeTool_IDMix
\ No newline at end of file

--
Gitblit v1.8.0