#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package GameWorldLogic.FBProcess.GameLogic_QueenRelics  
 | 
#  
 | 
# @todo:æ´»ÊÒż£  
 | 
# @author hxp  
 | 
# @date 2017-12-17  
 | 
# @version 1.0  
 | 
#  
 | 
# ÏêϸÃèÊö: æ´»ÊÒż£  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#"""Version = 2017-12-17 15:00"""  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
import IPY_GameWorld  
 | 
import GameWorldProcess  
 | 
import NPCCustomRefresh  
 | 
import PlayerControl  
 | 
import ItemControler  
 | 
import ItemCommon  
 | 
import GameWorld  
 | 
import FBCommon  
 | 
import ChConfig  
 | 
import GameMap  
 | 
import BuffSkill  
 | 
import PlayerSuccess  
 | 
import ShareDefine  
 | 
import EventShell  
 | 
import EventReport  
 | 
import ChPlayer  
 | 
import FBHelpBattle  
 | 
import IpyGameDataPY  
 | 
import PlayerWeekParty  
 | 
  
 | 
  
 | 
#½×¶Îʱ¼ä  
 | 
(  
 | 
Def_PrepareTime, # ¸±±¾×¼±¸Ê±¼ä(Ãë)  
 | 
Def_FightTime, # ½øÐÐʱ¼ä(Ãë)  
 | 
Def_LeaveTime, # Í˳öʱ¼ä(Ãë)  
 | 
) = range(3)  
 | 
  
 | 
#µ±Ç°¸±±¾µØÍ¼µÄ״̬  
 | 
(  
 | 
FB_Step_CallHelp, # ÖúÕ½ÕÙ»½  
 | 
FB_Step_Prepare, # ¸±±¾µÈ´ý  
 | 
FB_Step_Fighting, # ¸±±¾½øÐÐÖÐ  
 | 
FB_Step_Over, # ¸±±¾½áÊø  
 | 
FB_Step_Close, # ¸±±¾¹Ø±Õ  
 | 
) = range(5)  
 | 
  
 | 
FBKey_RefreshStep = 'RefreshStep' # Ë¢¹Ö½×¶ÎÊý, ´Ó1¿ªÊ¼   
 | 
FBKey_IsLastRefreshStep = 'SetGameFBDict' # ÊÇ·ñ×îºóÒ»²¨Ë¢¹Ö  
 | 
FBKey_NextLineID = 'NextLineID' # ¿ÉÒÔÌôÕ½ÏÂÒ»¹ØµÄlineID, ´óÓÚ0´ú±í¿ÉÒÔ¼ÌÐøÌôÕ½  
 | 
  
 | 
FBKey_NeedKillNPCNum = 'NeedKillNPCNum '  # ÐèÒª»÷ɱ²Å¿É¹ý¹ØµÄNPCIDÊý, ¼´±àºÅkey¸öÊý  
 | 
FBKey_NeedKillNPCID = 'NeedKillNPCID_%s'  # ÐèÒª»÷ɱ²Å¿É¹ý¹ØµÄNPCID, ²ÎÊý(±àºÅ)  
 | 
FBKey_NeedKillNPCCount = 'NeedKillNPCCount_%s'  # ÐèÒª»÷ɱ²Å¿É¹ý¹ØµÄNPCID¸öÊý, ²ÎÊý(NPCID)  
 | 
FBKey_KillNPCCount = 'KillNPCCount_%s'  # µ±Ç°½×¶ÎÒÑ»÷ɱ¹ÖÎïÊý, ²ÎÊý(NPCID)  
 | 
  
 | 
FBPKey_IsInFBOnDay = "IsInFBOnDay" # Íæ¼ÒÊÇ·ñ¸±±¾ÖйýÌì  
 | 
FBPKey_RewardLine = "RewardLine" # Íæ¼ÒÒѾ½áËãµ½µÄ½±ÀøÌìÊý, ¼Ç¼ֵʱҪ+1  
 | 
  
 | 
def OnFBPlayerOnDay(curPlayer):  
 | 
      
 | 
    mapID = FBCommon.GetRecordMapID(curPlayer.GetMapID())  
 | 
    if mapID != ChConfig.Def_FBMapID_QueenRelics:  
 | 
        return  
 | 
      
 | 
    # ÉèÖÃÔÚ¸±±¾ÖйýÌì  
 | 
    GameWorld.GetGameFB().SetPlayerGameFBDict(curPlayer.GetPlayerID(), FBPKey_IsInFBOnDay, 1)  
 | 
    GameWorld.DebugLog("ÉèÖÃæ´»ÊÌôÕ½ÖйýÌ죡", curPlayer.GetPlayerID())   
 | 
    return  
 | 
  
 | 
## ÊÇ·ñ¿É½øÈë  
 | 
#  @param curPlayer  
 | 
#  @param mapID µØÍ¼ID  
 | 
#  @param lineId ·ÖÏßID  
 | 
#  @param tick  
 | 
#  @return ÊÇ·ñ¿É½øÈë  
 | 
def OnEnterFBEvent(curPlayer, mapID, lineId, tick):  
 | 
    if not lineId:  
 | 
        return True  
 | 
      
 | 
    preLineID = lineId - 1 # ÉÏÒ»²ã  
 | 
    mapID = FBCommon.GetRecordMapID(mapID)  
 | 
    maxGrade = len(FBCommon.GetFBLineGrade(mapID, lineId))  
 | 
    preLineGrade = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, preLineID, False, [mapID])  
 | 
    canEnter = preLineGrade >= maxGrade  
 | 
    if not canEnter:  
 | 
        GameWorld.DebugLog("ÉÏÒ»²ã·Ç×î´óÆÀ¼¶¹ý¹Ø£¬ÎÞ·¨ÌôÕ½ÏÂÒ»²ã£¡lineID=%s,preLineID=%s,preLineGrade=%s,maxGrade=%s"   
 | 
                           % (lineId, preLineID, preLineGrade, maxGrade), curPlayer.GetPlayerID())  
 | 
        return False  
 | 
      
 | 
    return True  
 | 
  
 | 
## ½øÈë´«Ë굋  
 | 
#  @param curPlayer  
 | 
#  @param mapID µØÍ¼ID  
 | 
#  @param lineId ·ÖÏßID  
 | 
#  @param tick  
 | 
#  @return ×ø±êÁбí(X,Y)  
 | 
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):  
 | 
    return ipyEnterPosInfo  
 | 
  
 | 
## ÊÇ·ñ¿ÉÒÔ½øÈë  
 | 
#  @param ask ÇëÇóÐÅÏ¢  
 | 
#  @param tick  
 | 
#  @return »Ø¸´ÊÇ·ñͨ¹ýÇëÇó  
 | 
def OnChangeMapAsk(ask, tick):  
 | 
    return IPY_GameWorld.cmeAccept  
 | 
  
 | 
## »Ø³Ç¸´»îΪ¸±±¾Öи´»î  
 | 
def OnPlayerReborn():  
 | 
    return True  
 | 
  
 | 
## ÖØÖø±±¾¸´»îÍæ¼Ò×ø±êµã  
 | 
def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    enterX, enterY = __GetQueenRelicsLinePos(mapID, lineID)  
 | 
    curPlayer.ResetPos(enterX, enterY)  
 | 
    return  
 | 
  
 | 
## ÕÙ»½ÖúÕ½Íê³É  
 | 
def OnCallHelpBattleOK(curPlayer, tick):  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    DoQueenRelicsLinePrepare(curPlayer, lineID, tick)  
 | 
    return  
 | 
  
 | 
## ½ø¸±±¾  
 | 
#  @param curPlayer  
 | 
#  @param tick  
 | 
#  @return None  
 | 
def DoEnterFB(curPlayer, tick):  
 | 
    playerID = curPlayer.GetPlayerID()  
 | 
    GameWorld.DebugLog("DoEnterFB...", playerID)  
 | 
  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
      
 | 
    if not FBCommon.GetHadDelTicket(curPlayer):  
 | 
        if not FBCommon.DelFBEnterTicket(curPlayer, GameWorld.GetGameWorld().GetMapID())[0]:  
 | 
            PlayerControl.PlayerLeaveFB(curPlayer)  
 | 
            GameWorld.ErrLog("½øÈ븱±¾¿Û³ýÃÅÆ±Ê§°Ü£¡", curPlayer.GetPlayerID())  
 | 
            return 0  
 | 
        FBCommon.SetHadDelTicket(curPlayer)  
 | 
          
 | 
    mapID = ChConfig.Def_FBMapID_QueenRelics  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    reqLineID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_ReqFBFuncLine)  
 | 
      
 | 
    fbStep = gameFB.GetFBStep()  
 | 
    if fbStep == FB_Step_CallHelp:  
 | 
        FBCommon.SetFBPropertyMark(reqLineID, curPlayer)  
 | 
        lineID = reqLineID  
 | 
        FBHelpBattle.SendGameServer_RefreshHelpBattlePlayer(curPlayer, mapID, lineID)  
 | 
        return  
 | 
      
 | 
    if reqLineID > lineID:  
 | 
        FBCommon.SetFBPropertyMark(reqLineID, curPlayer)  
 | 
        lineID = reqLineID  
 | 
        DoQueenRelicsLinePrepare(curPlayer, lineID, tick)  
 | 
    else:  
 | 
        fbLineTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
        if fbStep == FB_Step_Prepare:  
 | 
            notify_tick = fbLineTime[Def_PrepareTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
            curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)  
 | 
              
 | 
        elif fbStep == FB_Step_Fighting:  
 | 
            notify_tick = fbLineTime[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())  
 | 
            curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)  
 | 
            FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(GameWorld.GetGameWorld().GetMapID(), lineID), curPlayer)  
 | 
              
 | 
    DoFBHelp(curPlayer, tick)  
 | 
    return  
 | 
  
 | 
def DoQueenRelicsLinePrepare(curPlayer, lineID, tick):  
 | 
    # ÒòΪ¸Ã¸±±¾Ö§³Ö¶à³¡¾°£¬ËùÒÔ¸±±¾°æ±¾ºÅ²»ÄÜÒÔµ¥³¡¾°ÎªÖ÷£¬ÐèÒªÒÔÍæ¼ÒΪÖ÷£¬Íæ¼Ò±¾´ÎÌôÕ½µÄ°æ±¾ºÅ´ø×Å×ß  
 | 
    GameWorld.DebugLog("¹¦ÄÜÏß¿ªÊ¼£¬½øÈë×¼±¸½×¶Î; lineID=%s" % (lineID), curPlayer.GetPlayerID())  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    gameFB.SetGameFBDict(FBKey_RefreshStep, 0)  
 | 
    gameFB.SetGameFBDict(FBKey_IsLastRefreshStep, 0)  
 | 
    gameFB.SetGameFBDict(FBKey_NextLineID, 0)  
 | 
    gameFB.SetGameFBDict(ChConfig.Def_FB_Grade, 0)  
 | 
      
 | 
    FBCommon.SetFBPropertyMark(lineID, curPlayer)  
 | 
    FBCommon.SetFBStep(FB_Step_Prepare, tick)  
 | 
    __RefreshQueenRelicsNPC(True, False, tick, curPlayer)  
 | 
    fbLineTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
    curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, fbLineTime[Def_PrepareTime] * 1000, True)  
 | 
    EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_QueenRelics, lineID, ChConfig.CME_Log_Start)  
 | 
      
 | 
    helpIpyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
    if helpIpyData:  
 | 
        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBBaseHurt, helpIpyData.GetRobotBaseHurt())  
 | 
        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBFightPower, helpIpyData.GetFightPowerMin())  
 | 
        GameWorld.DebugLog("    ¸üи±±¾ÖúÕ½»úÆ÷ÈË»ù´¡É˺¦: lineID=%s,RobotBaseHurt=%s,fbFightPower=%s"   
 | 
                           % (lineID, helpIpyData.GetRobotBaseHurt(), helpIpyData.GetFightPowerMin()))  
 | 
    return  
 | 
  
 | 
##¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ¸±±¾×ÜÂß¼¼ÆÊ±Æ÷  
 | 
def OnProcess(tick):  
 | 
      
 | 
    fbStep = GameWorld.GetGameFB().GetFBStep()  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    fbLineTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
      
 | 
    # ¸±±¾×¼±¸  
 | 
    if fbStep == FB_Step_Prepare:  
 | 
        __DoLogic_FB_Prepare(tick, fbLineTime)      
 | 
    # ¸±±¾½øÐÐÖÐ  
 | 
    elif fbStep == FB_Step_Fighting:  
 | 
        FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(GameWorld.GetGameWorld().GetMapID(), lineID))  
 | 
        __DoLogic_FB_Fighting(tick, fbLineTime)  
 | 
    # ¸±±¾½áÊø  
 | 
    elif fbStep == FB_Step_Over:  
 | 
        __DoLogic_FB_Over(tick, fbLineTime)  
 | 
          
 | 
    return  
 | 
  
 | 
## ¸±±¾×¼±¸Âß¼  
 | 
#  @param tick:ʱ¼ä´Á  
 | 
#  @return ÎÞÒâÒå  
 | 
def __DoLogic_FB_Prepare(tick, fbLineTime):  
 | 
    # ¼ä¸ôδµ½  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbLineTime[Def_PrepareTime] * 1000:  
 | 
        return  
 | 
      
 | 
    # ¸±±¾¿ªÊ¼  
 | 
    __RefreshQueenRelicsNPC(False, True, tick)  
 | 
    FBCommon.SetFBStep(FB_Step_Fighting, tick)  
 | 
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, fbLineTime[Def_FightTime] * 1000)  
 | 
    return  
 | 
  
 | 
## ¸±±¾½øÐÐÖÐ  
 | 
#  @param tick:ʱ¼ä´Á  
 | 
#  @return ÎÞÒâÒå  
 | 
def __DoLogic_FB_Fighting(tick, fbLineTime):  
 | 
    # ¼ä¸ôδµ½  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < fbLineTime[Def_FightTime] * 1000:  
 | 
        return  
 | 
      
 | 
    __DoQueenRelicsOver(False, tick)  
 | 
    return  
 | 
  
 | 
##¸±±¾¹Ø±ÕÖÐ  
 | 
# @param tick:ʱ¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ¸±±¾¹Ø±ÕÖÐ  
 | 
def __DoLogic_FB_Over(tick, fbLineTime):  
 | 
    # ¼ä¸ôδµ½  
 | 
    # ·þÎñ¶ËÇ¿ÖÆ½áÊø¸±±¾Ê±¼äÊʵ±ÑÓ³¤20Ã룬Ìṩһ¶¨µÄʱ¼ä¸ø¶ÓÎé³ÉÔ±ÇÐÏÂÒ»¹ØÓà  
 | 
    if tick - GameWorld.GetGameFB().GetFBStepTick() < (fbLineTime[Def_LeaveTime] * 1000 + 20000):  
 | 
        return  
 | 
      
 | 
    #¸±±¾¹Ø±Õ  
 | 
    GameWorldProcess.CloseFB(tick)  
 | 
    FBCommon.SetFBStep(FB_Step_Close, tick)  
 | 
    return  
 | 
  
 | 
def __RefreshQueenRelicsNPC(isNextStep, isRefreshNow, tick, notifyPlayer=None):  
 | 
    ## Ë¢Ð½׶εĹÖÎï  
 | 
      
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    refreshNPCCfg = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
    # [{µÚÒ»²¨Ë¢¹Ö¹æÔòID:¹ý¹ØÊÇ·ñÐèÒª»÷ɱ, ...}, {µÚ¶þ²¨Ë¢¹Ö¹æÔòID:¹ý¹ØÊÇ·ñÐèÒª»÷ɱ, ...}, ...]  
 | 
    if not refreshNPCCfg:  
 | 
        GameWorld.ErrLog("ûÓÐÅäÖÃË¢¹ÖÐÅÏ¢!lineID=%s" % lineID)  
 | 
        return  
 | 
      
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    step = gameFB.GetGameFBDictByKey(FBKey_RefreshStep)  
 | 
    if isNextStep:  
 | 
        step += 1  
 | 
    maxStep = len(refreshNPCCfg)  
 | 
    if step > maxStep:  
 | 
        GameWorld.DebugLog("³¬¹ý×î´óË¢¹Ö½×¶Î!step=%s,maxStep=%s" % (step, maxStep))  
 | 
        return  
 | 
    refreshIDDict = refreshNPCCfg[step - 1]  
 | 
      
 | 
    needKillNPCDict = {}  
 | 
    for refreshID, needKill in refreshIDDict.items():  
 | 
        if not needKill:  
 | 
            continue  
 | 
        npcCountList = NPCCustomRefresh.GetNPCRefreshCountList(refreshID)  
 | 
        if not npcCountList:  
 | 
            return  
 | 
        for npcID, count in npcCountList:  
 | 
            needKillNPCDict[npcID] = needKillNPCDict.get(npcID, 0) + count  
 | 
              
 | 
    if not needKillNPCDict:  
 | 
        GameWorld.ErrLog("ûÓÐÐèÒª»÷ɱ²Å¿É¹ý¹ØµÄNPCÅäÖÃ!lineID=%s,step=%s" % (lineID, step))  
 | 
        return  
 | 
      
 | 
    isLastStep = int(step == maxStep)  
 | 
    gameFB.SetGameFBDict(FBKey_RefreshStep, step)  
 | 
    gameFB.SetGameFBDict(FBKey_IsLastRefreshStep, isLastStep)  
 | 
      
 | 
    # ¸üÐÂÉèÖùý¹ØÐèÒª»÷ɱµÄNPCÐÅÏ¢  
 | 
    needKillNPCIDList = needKillNPCDict.keys()  
 | 
    needKillNum = len(needKillNPCIDList)  
 | 
    gameFB.SetGameFBDict(FBKey_NeedKillNPCNum, needKillNum)  
 | 
    for i, npcID in enumerate(needKillNPCIDList):  
 | 
        gameFB.SetGameFBDict(FBKey_NeedKillNPCID % i, npcID)  
 | 
        gameFB.SetGameFBDict(FBKey_NeedKillNPCCount % npcID, needKillNPCDict[npcID])  
 | 
          
 | 
    if isNextStep:  
 | 
        GameWorld.DebugLog("Ë¢¹Ö×¼±¸: step=%s,isLastStep=%s,refreshIDDict=%s,needKillNPCDict=%s"   
 | 
                           % (step, isLastStep, refreshIDDict, needKillNPCDict))  
 | 
          
 | 
    # Ë¢¹Ö  
 | 
    if isRefreshNow:  
 | 
        GameWorld.DebugLog("ˢйÖÎï: step=%s,isLastStep=%s,refreshIDDict=%s,needKillNPCDict=%s"   
 | 
                           % (step, isLastStep, refreshIDDict, needKillNPCDict))  
 | 
        for refreshID in refreshIDDict.keys():  
 | 
            NPCCustomRefresh.SetNPCRefreshByID(refreshID)  
 | 
          
 | 
    if notifyPlayer:  
 | 
        DoFBHelp(notifyPlayer, tick)  
 | 
        return  
 | 
          
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for i in range(playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(i)  
 | 
        if not curPlayer:  
 | 
            continue  
 | 
        DoFBHelp(curPlayer, tick)  
 | 
          
 | 
    return  
 | 
  
 | 
## ¸±±¾Ê±¼äµ½¹Ø±Õ  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷.  
 | 
def OnCloseFB(tick):  
 | 
    return  
 | 
  
 | 
##Íæ¼ÒÍ˳ö¸±±¾.  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoExitFB(curPlayer, tick):  
 | 
    return  
 | 
  
 | 
##Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
def DoPlayerLeaveFB(curPlayer, tick):  
 | 
    # É¾³ýµ¥²ãÓÐЧµÄbuff, ÊÈѪµ¤  
 | 
    BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_QueenRelicsItemBuff, tick)  
 | 
  
 | 
    return  
 | 
  
 | 
##¸±±¾°ïÖúÐÅÏ¢  
 | 
# @param curPlayer Íæ¼ÒʵÀý  
 | 
# @param tick Ê±¼ä´Á  
 | 
# @return ÎÞÒâÒå  
 | 
# @remarks ÓÃÓÚ֪ͨÕóÓª±È·ÖÌõ  
 | 
def DoFBHelp(curPlayer, tick):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    step = gameFB.GetGameFBDictByKey(FBKey_RefreshStep)  
 | 
    grade = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_Grade)  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
      
 | 
    npcDict = {}  
 | 
    needNum = gameFB.GetGameFBDictByKey(FBKey_NeedKillNPCNum)  
 | 
    for i in xrange(needNum):  
 | 
        npcID = gameFB.GetGameFBDictByKey(FBKey_NeedKillNPCID % i)  
 | 
        killCount = gameFB.GetGameFBDictByKey(FBKey_KillNPCCount % npcID)  
 | 
        npcDict[npcID] = killCount  
 | 
          
 | 
    fbHelpDict = {FBCommon.Help_lineID:lineID, FBCommon.Help_grade:grade,  
 | 
                  FBCommon.Help_npc:FBCommon.GetJsonNPCKillList(npcDict)}  
 | 
    if step:  
 | 
        fbHelpDict[FBCommon.Help_step] = step  
 | 
          
 | 
    FBCommon.NotifyFBHelp(curPlayer, lineID, fbHelpDict)  
 | 
    return  
 | 
  
 | 
def DoFB_Npc_KillNPC(attacker, curNPC, tick):  
 | 
    __FBNPCOnKilled(curNPC, tick)  
 | 
    return  
 | 
  
 | 
##Íæ¼ÒɱËÀNPC  
 | 
# @param curPlayer:Íæ¼ÒʵÀý  
 | 
# @param curNPC:µ±Ç°±»É±ËÀµÄNPC  
 | 
# @param tick:ʱ¼ä´Á  
 | 
# @return ·µ»ØÖµÎÞÒâÒå  
 | 
# @remarks Íæ¼ÒÖ÷¶¯À뿪¸±±¾.  
 | 
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):  
 | 
    __FBNPCOnKilled(curNPC, tick)  
 | 
    return  
 | 
  
 | 
def __FBNPCOnKilled(curNPC, tick):  
 | 
    curNPCID = curNPC.GetNPCID()  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    killNPCCount = gameFB.GetGameFBDictByKey(FBKey_KillNPCCount % curNPCID) + 1  
 | 
    gameFB.SetGameFBDict(FBKey_KillNPCCount % curNPCID, killNPCCount)  
 | 
      
 | 
    # ÅжÏÐèÒª»÷ɱ²Å¿É¹ý¹ØµÄNPCÊÇ·ñ¶¼ÒÑ»÷ɱ  
 | 
    isNeedKillNPCID = False  
 | 
    isAllKill = True  
 | 
    needNum = gameFB.GetGameFBDictByKey(FBKey_NeedKillNPCNum)  
 | 
    for i in xrange(needNum):  
 | 
        npcID = gameFB.GetGameFBDictByKey(FBKey_NeedKillNPCID % i)  
 | 
        if curNPCID == npcID:  
 | 
            isNeedKillNPCID = True  
 | 
              
 | 
        if isAllKill:  
 | 
            needKillCount = gameFB.GetGameFBDictByKey(FBKey_NeedKillNPCCount % npcID)  
 | 
            killCount = gameFB.GetGameFBDictByKey(FBKey_KillNPCCount % npcID)  
 | 
            if killCount < needKillCount:  
 | 
                isAllKill = False  
 | 
                  
 | 
    if not isAllKill:  
 | 
        if isNeedKillNPCID:  
 | 
            playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
            for index in xrange(playerManager.GetPlayerCount()):  
 | 
                player = playerManager.GetPlayerByIndex(index)  
 | 
                if player:  
 | 
                    DoFBHelp(player, tick)  
 | 
        return  
 | 
      
 | 
    if gameFB.GetGameFBDictByKey(FBKey_IsLastRefreshStep):  
 | 
        if isNeedKillNPCID:  
 | 
            GameWorld.DebugLog("ËùÓйÖÎïÒÑ»÷ɱ£¡¹ý¹Ø£¡")  
 | 
            __DoQueenRelicsOver(True, tick)  
 | 
    else:  
 | 
        __RefreshQueenRelicsNPC(True, True, tick)  
 | 
    return  
 | 
  
 | 
## ¼ì²éÊÇ·ñ¿É¹¥»÷£¬ Ö÷Åж¨²»¿É¹¥»÷µÄÇé¿ö£¬ÆäËûÂß¼ÓÉÍâ²ã¾ö¶¨  
 | 
#  @param attacker ¹¥»÷·½  
 | 
#  @param defender ·ÀÊØ·½  
 | 
#  @return bool  
 | 
def CheckCanAttackTagObjInFB(attacker, defender):  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    if gameFB.GetFBStep() != FB_Step_Fighting:  
 | 
        return False  
 | 
    return True  
 | 
  
 | 
def __DoQueenRelicsOver(isPass, tick):  
 | 
    # Õ½¶·³¬Ê±  
 | 
    if GameWorld.GetGameFB().GetFBStep() == FB_Step_Over:  
 | 
        GameWorld.DebugLog("ÒѾ½áËã¹ý£¡²»Öظ´½áËã!")  
 | 
        return  
 | 
    costTime = tick - GameWorld.GetGameFB().GetFBStepTick()  
 | 
    NPCCustomRefresh.CloseFBCustomRefresh(tick) # ÏȹرÕÔÙÇå¹Ö  
 | 
      
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    lineID = FBCommon.GetFBPropertyMark()  
 | 
    dataMapID = FBCommon.GetRecordMapID(mapID)  
 | 
    FBCommon.UpdateFBGrade(tick, FBCommon.GetFBLineGrade(mapID, lineID)) # ½áËãÇ°Ç¿ÖÆË¢ÐÂÒ»´ÎÆÀ¼¶  
 | 
    grade = GameWorld.GetGameFB().GetGameFBDictByKey(ChConfig.Def_FB_Grade)  
 | 
      
 | 
    FBCommon.SetFBStep(FB_Step_Over, tick) # Ðè·ÅÔÚÆÀ¼¶Ë¢ÐºóÉèÖà  
 | 
      
 | 
    fbLineTime = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_QueenRelics, lineID)  
 | 
    rewardRateList = FBCommon.GetFBGradeRewardRateList(mapID)  
 | 
    maxGrade = len(rewardRateList)  
 | 
      
 | 
    nextLineID = 0  
 | 
    # ×î¸ßÆÀ¼¶¹ý¹Ø£¬¿ÉÌôÕ½ÏÂÒ»¹Ø  
 | 
    if isPass and grade >= maxGrade:  
 | 
        nextLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID + 1, False)  
 | 
        nextLineID = 0 if not nextLineIpyData else (lineID + 1) # ÕÒ²»µ½ÏëÏÂÒ»²ãÊý¾Ý´ú±íͨ¹Ø  
 | 
          
 | 
      
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    gameFB.SetGameFBDict(FBKey_NextLineID, nextLineID)  
 | 
    GameWorld.DebugLog("¿ªÊ¼¹ý¹Ø½áËã: lineID=%s,grade=%s,isPass=%s,nextLineID=%s" % (lineID, grade, isPass, nextLineID))  
 | 
      
 | 
    playerManager = GameWorld.GetMapCopyPlayerManager()  
 | 
    for index in xrange(playerManager.GetPlayerCount()):  
 | 
        curPlayer = playerManager.GetPlayerByIndex(index)  
 | 
        if not curPlayer:  
 | 
            continue  
 | 
        DoFBHelp(curPlayer, tick)  
 | 
          
 | 
        playerID = curPlayer.GetPlayerID()  
 | 
        rewardLine = gameFB.GetPlayerGameFBDictByKey(playerID, FBPKey_RewardLine)  
 | 
        needSyncFBData = False  
 | 
        overDict = {}  
 | 
        if isPass:  
 | 
            overDict = {FBCommon.Over_costTime:costTime, FBCommon.Over_grade:grade}  
 | 
            rewardRet = __GivePlayerQueenRelicsReward(curPlayer, dataMapID, rewardLine - 1, lineID, grade, maxGrade, rewardRateList)  
 | 
            if rewardRet:  
 | 
                needSyncFBData, startRewardLineID, totalSP, rewardItemList = rewardRet  
 | 
                overDict.update({FBCommon.Over_sp:totalSP, FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(rewardItemList),   
 | 
                                 "startRewardLineID":startRewardLineID})  
 | 
            if lineID+1 > curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBHistoryMaxLine % dataMapID):  
 | 
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FBHistoryMaxLine % dataMapID, lineID+1)  
 | 
            #³É¾Í  
 | 
            if grade >= maxGrade:  
 | 
                PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_QueenRelics, 1, [lineID+1])  
 | 
              
 | 
            EventShell.EventRespons_PassQueenRelecs(curPlayer, lineID, grade)  
 | 
            #ÈÎÎñ  
 | 
            EventShell.EventRespons_FBEvent(curPlayer, "queenrelics_pass")  
 | 
          
 | 
        # ¼Ç¼½áËãµ½µÄÏß·²ã£¬¼Ç¼ֵ+1  
 | 
        updRewardLine = lineID + 1  
 | 
        gameFB.SetPlayerGameFBDict(playerID, FBPKey_RewardLine, updRewardLine)  
 | 
          
 | 
        if isPass and not rewardLine:  
 | 
            isInFBOnDay = gameFB.GetPlayerGameFBDictByKey(playerID, FBPKey_IsInFBOnDay)  
 | 
            if not isInFBOnDay:  
 | 
                GameWorld.DebugLog("Ê״νáËã½±Àø£¬Ôö¼ÓÌôÕ½´ÎÊý£¡", playerID)  
 | 
                needSyncFBData = True  
 | 
                FBCommon.AddEnterFBCount(curPlayer, dataMapID)  
 | 
                addXianyuanCoin, reason = FBHelpBattle.DoFBAddXianyuanCoin(curPlayer, mapID, lineID)  
 | 
                overDict[FBCommon.Over_xianyuanCoin] = [addXianyuanCoin, reason]  
 | 
            else:  
 | 
                GameWorld.DebugLog("¸±±¾ÖйýÌ죬²»Ôö¼ÓÌôÕ½´ÎÊý£¡", playerID)  
 | 
            PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_QueenRelicsEx, 1)  
 | 
            PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_QueenRelices, 1)  
 | 
        # ²»¿ÉÔÙÌôÕ½ÏÂÒ»¹ØÁË  
 | 
        if not nextLineID:  
 | 
            curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, fbLineTime[Def_LeaveTime] * 1000, True)  
 | 
        else:  
 | 
            curPlayer.Sync_TimeTick(IPY_GameWorld.tttFBAddTime, 0, fbLineTime[Def_LeaveTime] * 1000, True)  
 | 
            GameWorld.DebugLog("    ¿É½øÈëÏÂÒ»¹Ø: updRewardLine=%s,nextLineID=%s" % (updRewardLine, nextLineID), playerID)  
 | 
              
 | 
        if needSyncFBData:  
 | 
            FBCommon.Sync_FBPlayerFBInfoData(curPlayer, dataMapID) # Í¬²½ÐÅÏ¢  
 | 
              
 | 
        FBCommon.NotifyFBOver(curPlayer, dataMapID, lineID, isPass, overDict)  
 | 
    return  
 | 
  
 | 
def __GivePlayerQueenRelicsReward(curPlayer, dataMapID, rewardLineID, curLineID, passGrade, maxGrade, rewardRateList):  
 | 
    ## ¸øÍæ¼Ò¹ý¹Ø½±Àø  
 | 
      
 | 
    totalSP = 0  
 | 
    totalItemCountDict = {}  
 | 
      
 | 
    # Ò»°ãÊDz»¿ÉÄÜ£¬ÕâÀï×ö¸öÀíÂÛÊýÖµ·À·¶  
 | 
    if rewardLineID >= curLineID:  
 | 
        GameWorld.ErrLog("Íæ¼ÒÖØ¸´½áËãæ´»Ê¹ý¹Ø½±Àø£¡rewardLineID=%s >= curLineID=%s" % (rewardLineID, curLineID), curPlayer.GetPlayerID())  
 | 
        return  
 | 
      
 | 
    startRewardLineID = rewardLineID + 1  
 | 
    needSyncFBData = False  
 | 
    # Í³¼Æ½±Àø£¬±¾¹Ø¿¨Ö®Ç°µÄ¶¼¸ø×î¸ß¼¶½±Àø, µ±Ç°²ãÒÔ±¾´ÎÆÀ¼¶Îª×¼  
 | 
    for giveLineID in xrange(startRewardLineID, curLineID + 1):  
 | 
          
 | 
        rewardGrade = maxGrade if giveLineID < curLineID else passGrade  
 | 
        curGrade = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, giveLineID, False, [dataMapID])  
 | 
        if curGrade < rewardGrade:  
 | 
            GameWorld.DebugLog("    ¸üйý¹ØÆÀ¼¶: dataMapID=%s,giveLineID=%s,curGrade=%s,rewardGrade=%s"   
 | 
                               % (dataMapID, giveLineID, curGrade, rewardGrade), curPlayer.GetPlayerID())  
 | 
            GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, giveLineID, rewardGrade, False, [dataMapID])  
 | 
            needSyncFBData = True  
 | 
              
 | 
        lineReward = FBCommon.GetFBLineReward(dataMapID, giveLineID)  
 | 
        rewardSP = lineReward[0]  
 | 
        rewardItemList = lineReward[1:]  
 | 
        rewardRateIndex = 0 if rewardGrade >= maxGrade else maxGrade - rewardGrade  
 | 
        if rewardRateIndex < 0 or rewardRateIndex >= len(rewardRateList):  
 | 
            GameWorld.ErrLog("    ÆÀ¼¶¶ÔÓ¦½±Àø±ÈÀýË÷ÒýÒì³£: giveLineID=%s,rewardGrade=%s,rewardRateList=%s,maxGrade=%s,rewardRateIndex=%s"   
 | 
                             % (giveLineID, rewardGrade, rewardRateList, maxGrade, rewardRateIndex), curPlayer.GetPlayerID())  
 | 
            continue  
 | 
        rewardRate = rewardRateList[rewardRateIndex]  
 | 
          
 | 
        if rewardRate < 100:  
 | 
            addSP = int(round(rewardSP * rewardRate / 100.0))  
 | 
            giveItemList = []  
 | 
            for itemID, itemCount in rewardItemList:  
 | 
                rewardCount = max(1, int(round(itemCount * rewardRate / 100.0))) # È·±£ÖÁÉÙ1¸ö  
 | 
                giveItemList.append([itemID, rewardCount])  
 | 
        else:  
 | 
            addSP = rewardSP  
 | 
            giveItemList = rewardItemList  
 | 
              
 | 
        GameWorld.DebugLog("    ¸ø¹Ø¿¨½±Àø: giveLineID=%s,rewardGrade=%s,rewardRateList=%s,rewardRate=%s,addSP=%s,giveItemList=%s"   
 | 
                           % (giveLineID, rewardGrade, rewardRateList, rewardRate, addSP, giveItemList), curPlayer.GetPlayerID())  
 | 
          
 | 
        totalSP += addSP  
 | 
        for itemID, itemCount in giveItemList:  
 | 
            totalItemCountDict[itemID] = totalItemCountDict.get(itemID, 0) + itemCount  
 | 
      
 | 
    # ¸ø½±Àø  
 | 
    PlayerControl.PlayerAddZhenQi(curPlayer, totalSP, eventName="QueenRelics")  
 | 
      
 | 
    rewardItemList = []  
 | 
    for itemID, itemCount in totalItemCountDict.items():  
 | 
        rewardItemList.append([itemID, itemCount, 1])  
 | 
          
 | 
    needSpace = len(rewardItemList)  
 | 
    emptySpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)  
 | 
    if emptySpace < needSpace:  
 | 
        PlayerControl.SendMailByKey("QueenRelicsMail", [curPlayer.GetPlayerID()], rewardItemList)  
 | 
    else:  
 | 
        for itemID, itemCount, isBind in rewardItemList:  
 | 
            ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isBind, [IPY_GameWorld.rptItem], event=["QueenRelics", False, {}])  
 | 
              
 | 
    GameWorld.DebugLog("    ×ܽ±Àø£ºtotalSP=%s,rewardItemList=%s" % (totalSP, rewardItemList), curPlayer.GetPlayerID())  
 | 
    return needSyncFBData, startRewardLineID, totalSP, rewardItemList  
 | 
  
 | 
  
 | 
## ¸±±¾ÐÐΪ  
 | 
#  @param curPlayer Íæ¼Ò  
 | 
#  @param actionType ÐÐΪÀàÐÍ  
 | 
#  @param actionInfo ÐÐΪÐÅÏ¢  
 | 
#  @param tick µ±Ç°Ê±¼ä  
 | 
#  @return None  
 | 
def DoFBAction(curPlayer, actionType, actionInfo, tick):  
 | 
    if actionType != FBCommon.Def_FbActionChangeLine:  
 | 
        return  
 | 
    toLineID = actionInfo  
 | 
    curLineID = FBCommon.GetFBPropertyMark()  
 | 
    GameWorld.DebugLog("DoFBAction actionType=%s, toLineID=%s, curLineID=%s" % (actionType, actionInfo, curLineID), curPlayer.GetPlayerID())  
 | 
    mapID = GameWorld.GetMap().GetMapID()  
 | 
    if curLineID == toLineID:  
 | 
        toPosX, toPosY = __GetQueenRelicsLinePos(mapID, toLineID)  
 | 
        PlayerControl.PlayerResetWorldPosFBLineID(curPlayer, mapID, toPosX, toPosY, toLineID)  
 | 
        GameWorld.DebugLog("ÒѾÊǵ±Ç°¹¦ÄÜÏß·, Çл»µ½¸Ã¹¦ÄÜÏßÂ·×ø±ê: toPosX=%s,toPosY=%s,toLineID=%s"   
 | 
                           % (toPosX, toPosY, toLineID), curPlayer.GetPlayerID())  
 | 
        return  
 | 
      
 | 
    fbStep = GameWorld.GetGameFB().GetFBStep()  
 | 
    if fbStep != FB_Step_Over:  
 | 
        GameWorld.DebugLog("·Ç½áÊø×´Ì¬!fbStep=%s" % fbStep)  
 | 
        return  
 | 
    if toLineID != curLineID + 1:  
 | 
        GameWorld.DebugLog("Ö»ÄܽøÈëÏÂÒ»¹Ø, curLineID=%s,toLineID=%s" % (curLineID, toLineID))  
 | 
        return  
 | 
    gameFB = GameWorld.GetGameFB()  
 | 
    grade = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_Grade)  
 | 
    maxGrade = len(FBCommon.GetFBLineGrade(mapID, curLineID))  
 | 
    if grade < maxGrade:  
 | 
        GameWorld.DebugLog("·Ç×î´óÆÀ¼¶¹ý¹Ø£¬ÎÞ·¨ÌôÕ½ÏÂÒ»²ã£¡curLineID=%s,grade=%s,maxGrade=%s"   
 | 
                           % (curLineID, grade, maxGrade), curPlayer.GetPlayerID())  
 | 
        return  
 | 
    toLineIpyData = FBCommon.GetFBLineIpyData(mapID, toLineID, False)  
 | 
    if not toLineIpyData:  
 | 
        GameWorld.ErrLog("ûÓÐÄ¿±ê¹¦ÄÜÏß·£¡toLineID=%s" % toLineID)  
 | 
        return  
 | 
      
 | 
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:  
 | 
        GameWorld.Log("½øÈëÏÂÒ»²ãÊ±Íæ¼ÒÊÇËÀÍö״̬£¬Ïȸ´»î!", curPlayer.GetPlayerID())  
 | 
        ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_System, tick)  
 | 
          
 | 
    toPosX, toPosY = __GetQueenRelicsLinePos(mapID, toLineID, toLineIpyData)  
 | 
    PlayerControl.PlayerResetWorldPosFBLineID(curPlayer, mapID, toPosX, toPosY, toLineID)  
 | 
      
 | 
    # É¾³ýµ¥²ãÓÐЧµÄbuff, ÊÈѪµ¤  
 | 
    if BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_QueenRelicsItemBuff, tick):  
 | 
        playerControl = PlayerControl.PlayerControl(curPlayer)  
 | 
        playerControl.RefreshPlayerAttrByBuff()  
 | 
    return  
 | 
  
 | 
def __GetQueenRelicsLinePos(mapID, lineID, toLineIpyData=None):  
 | 
    posInfo = FBCommon.GetFBLineEnterPosInfo(mapID, lineID, toLineIpyData)  
 | 
    enterX, enterY, dist = posInfo  
 | 
    posPoint = GameMap.GetEmptyPlaceInArea(enterX, enterY, dist)  
 | 
    return posPoint.GetPosX(), posPoint.GetPosY()  
 | 
  
 | 
  
 |