9341 【BT5】【主干】【后端】情缘系统(增加情缘副本;AB相互提亲优化聘礼ID取较高的)

# Conflicts:
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
11个文件已修改
1个文件已添加
573 ■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerLove.py 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerTeam.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddFBCnt.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/FBDefenseCommon.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/工具路径IDDispatchServer.txt 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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]
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
    
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
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
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
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)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Love.py
New file
@@ -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
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
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
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
## å¥³ç¥žå‰¯æœ¬çš„æ™®é€šæ£€æŸ¥
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)
Tool/¹¤¾ß·¾¶IDDispatchServer.txt
@@ -1 +1,2 @@
工具路径\MiracleCode\TCode\TeamServer\Server4\Servers\IDDispatchServer
工具路径\MiracleCode\TCode\TeamServer\Server4\Servers\IDDispatchServer
合服工具\MiracleCode\TCode\TeamServer\Server4\Tools\ServerMergeTool_IDMix