ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_PersonalBoss.py
@@ -2,287 +2,151 @@
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_PersonalBoss
#
# @todo:个人BOSS
# @author xdh
# @date 2017-05-05
# @todo:个人Boss、VIPBoss
# @author hxp
# @date 2019-05-23
# @version 1.0
# 详细描述: 个人BOSS
#
#---------------------------------------------------------------------
#"""Version = 2017-05-05 11:00"""
#---------------------------------------------------------------------
# 详细描述: 个人Boss、VIPBoss
# 本副本做前端自定义场景处理,后端无实际地图
#
#-------------------------------------------------------------------------------
#"""Version = 2019-05-23 17:30"""
#-------------------------------------------------------------------------------
import FBCommon
import GameWorld
import IPY_GameWorld
import NPCCustomRefresh
import IpyGameDataPY
import PlayerBossReborn
import PlayerFairyCeremony
import PlayerNewFairyCeremony
import ChConfig
import ChPlayer
import EventReport
import PlayerBossReborn
import PlayerNewFairyCeremony
import PlayerFairyCeremony
import PlayerFeastTravel
import IpyGameDataPY
import NPCCommon
import ChConfig
# 副本通用配置
(
Def_PrepareTime, # 准备时间,秒
Def_FightTime, # 战斗时间,秒
Def_ExitTime, # 退出时间, 秒
Def_RefreshBossMark, # 刷怪标识点
) = range(4)
# 副本状态
(
FB_State_Open, # 副本开启
FB_State_FightPrepare, # 战斗准备时间
FB_State_Fighting, # 战斗
FB_State_FreeTime, # 活动结束准备(胜利/失败)
FB_State_Close, # 关闭副本
) = range(5)
## 是否可进入
#  @param curPlayer
#  @param mapID 地图ID
#  @param lineId 分线ID
#  @param tick
#  @return 是否可进入
def OnEnterFBEvent(curPlayer, mapID, lineId, tick):
## 是否能够通过活动查询进入
def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
    return True
## 检查可否进行挑战
def __CheckCanChallenge(curPlayer, bossID):
    ipyData = IpyGameDataPY.GetIpyGameData('PersonalBoss', bossID)
    if not ipyData:
        return False
    needLV = ipyData.GetChanllengeLv()
    if curPlayer.GetLV() < needLV:
        GameWorld.DebugLog('    检查可否进行挑战 bossID-%s  等级不足 %s'%(bossID, needLV))
        return False
    delResult = FBCommon.DelFBEnterTicket(curPlayer, ChConfig.Def_FBMapID_PersonalBoss)
    isOK = delResult[0]
    if not isOK:
## 是否需要做进入副本通用检查条件逻辑,默认需要检查
def OnNeedCheckCanEnterFBComm(curPlayer, mapID, lineID):
    ## 进行中的不需要重复检查,防止断线重连被禁止进入
    if FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) == ChConfig.CustomMapStep_Fight:
        GameWorld.DebugLog("VIPBoss已经在进行中,本次进入不需要重新检查!")
        return False
    return True
##副本玩家进入点
# @param curPlayer 玩家实例
# @param mapID 地图ID
# @param lineId 分线ID
# @param ipyEnterPosInfo 功能线路IPY配置坐标信息
# @param tick 时间戳
# @return posX, posY, 随机半径(可选)
def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
    return ipyEnterPosInfo
## 是否可以进入
#  @param ask 请求信息
#  @param tick
#  @return 回复是否通过请求
def OnChangeMapAsk(ask, tick):
    return IPY_GameWorld.cmeAccept
## 进副本
#  @param curPlayer
#  @param tick
#  @return None
def DoEnterFB(curPlayer, tick):
    # 不做处理,有副本行为客户端发包选择挑战关卡
    return
## 副本时间到关闭
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def OnCloseFB(tick):
    return
##玩家退出副本.
# @param curPlayer 玩家实例
# @param tick 时间戳
# @return 返回值无意义
# @remarks 玩家主动离开副本.
def DoExitFB(curPlayer, tick):
    # 玩家退出默认关闭副本
    #GameWorldProcess.CloseFB(tick)
    return
##副本总逻辑计时器
# @param tick 时间戳
# @return 无意义
# @remarks 副本总逻辑计时器
def OnProcess(tick):
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep == FB_State_FightPrepare:
        __DoLogic_FightPrepare(tick)
    elif fbStep == FB_State_Fighting:
        __DoLogic_Fighting(tick)
    elif fbStep == FB_State_FreeTime:
        __DoLogic_FreeTime(tick)
    elif fbStep == FB_State_Close:
        pass
## 客户端进入自定义场景
def OnEnterCustomScene(curPlayer, mapID, lineID):
    
    return
## 判断可否召唤木桩怪
def OnCanSummonPriWoodPile(curPlayer, mapID, lineID, npcID, count):
    if FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) != ChConfig.CustomMapStep_Fight:
        FBCommon.SetCustomMapStep(curPlayer, mapID, lineID, ChConfig.CustomMapStep_Fight)
        EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_PersonalBoss, 0, ChConfig.CME_Log_Start)
        # 开始计时
        tick = GameWorld.GetGameWorld().GetTick()
        curPlayer.SetDict(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick, tick)
        FBCommon.UpdateCustomFBGrade(curPlayer, tick, FBCommon.GetFBLineGrade(mapID, lineID))
    return True
##战斗准备时间
# @param tick  时钟
# @return 无意义
def __DoLogic_FightPrepare(tick):
    gameFB = GameWorld.GetGameFB()
    mapID = GameWorld.GetMap().GetMapID()
    trialCfg = FBCommon.GetFBLineStepTime(mapID)
    if tick - gameFB.GetFBStepTick() < trialCfg[Def_PrepareTime] * 1000:
def OnCustomSceneProcess(curPlayer, mapID, lineID, tick):
    if FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) == ChConfig.CustomMapStep_Fight:
        FBCommon.UpdateCustomFBGrade(curPlayer, tick, FBCommon.GetFBLineGrade(mapID, lineID))
    return
## 自定义场景副本击杀NPC
def DoCustomScene_Player_KillNPC(curPlayer, curNPC, mapID, lineID):
    npcID = curNPC.GetNPCID()
    bossID = __GetPersonalBossID(lineID)
    GameWorld.DebugLog("个人boss场景击杀NPC: npcID=%s,bossID=%s" % (npcID, bossID), curPlayer.GetPlayerID())
    if npcID != bossID:
        return
    
    bossID = FBCommon.GetFBPropertyMark()
    if not bossID:
        FBCommon.DoLogic_FBKickAllPlayer()
    if FBCommon.GetCustomMapStep(curPlayer, mapID, lineID) != ChConfig.CustomMapStep_Fight:
        return
    
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, trialCfg[Def_FightTime] * 1000)
    NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineStepTime(mapID)[Def_RefreshBossMark], [bossID])
    #转入战斗
    FBCommon.SetFBStep(FB_State_Fighting, tick)
    return
## 开始副本关卡
def StartFBLevel(curPlayer, bossID, tick):
    FBCommon.SetFBPropertyMark(bossID)
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie:
        GameWorld.DebugLog("复活玩家...", curPlayer.GetPlayerID())
        ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick)
    grade = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomSceneGrade)
    costTime = GameWorld.GetGameWorld().GetTick() - curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomSceneStepTick)
    GameWorld.DebugLog("个人boss过关: grade=%s,costTime=%s" % (grade, costTime))
    isFree = False
    curfbStar = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [mapID])
    # 首次过关不扣次数
    if not curfbStar:
        isFree = True
        GameWorld.DebugLog("    首次过关!mapID=%s,lineID=%s" % (mapID, lineID), curPlayer.GetPlayerID())
    if curfbStar < grade:
        GameWorld.DebugLog("    更新评级!curfbStar=%s < grade=%s" % (curfbStar, grade), curPlayer.GetPlayerID())
        GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, grade, False, [mapID])
        FBCommon.Sync_FBPlayerFBInfoData(curPlayer, mapID) # 同步信息
    #增加进入次数
    FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_PersonalBoss)
    EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_PersonalBoss, 0, ChConfig.CME_Log_Start)
    FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_PersonalBoss, isFree=isFree)
    FBCommon.DelFBEnterTicket(curPlayer, ChConfig.Def_FBMapID_PersonalBoss)
    PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_VIPBOSS, 1)
    PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_VIPBoss, 1)
    PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_VIPBoss, 1)
    PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_VIPBoss, 1)
    
    FBCommon.ClearFBNPC()
    #gameFB = GameWorld.GetGameFB()
    mapID = GameWorld.GetMap().GetMapID()
    prepareTick = FBCommon.GetFBLineStepTime(mapID)[Def_PrepareTime] * 1000
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttAddUpTime, prepareTick)
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick)
    FBCommon.SetFBStep(FB_State_FightPrepare, tick)
    helpDict = {FBCommon.Help_npcTotal:0}
    FBCommon.Notify_FBHelp(curPlayer, helpDict)
    GameWorld.DebugLog("StartFBLevel, fbLevel=%s, helpDict=%s"
                       % (bossID, str(helpDict)), curPlayer.GetPlayerID())
    npcCountDict = {bossID:1}
    dropItemMapInfo = [0, 0]
    jsonItemList = NPCCommon.GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, dropItemMapInfo=dropItemMapInfo, curGrade=grade, isVirtualDrop=True)[0]
    FBCommon.SetCustomMapStep(curPlayer, mapID, lineID, ChConfig.CustomMapStep_Over)
    isPass = 1
    overDict = {FBCommon.Over_itemInfo:jsonItemList, FBCommon.Over_grade:grade, FBCommon.Over_costTime:costTime}
    FBCommon.NotifyFBOver(curPlayer, mapID, lineID, isPass, overDict)
    return
def __GetPersonalBossID(lineID):
    ## VIPbossID
    ipyData = IpyGameDataPY.GetIpyGameData('PersonalBoss', lineID)
    if not ipyData:
        return 0
    return ipyData.GetNPCID()
##战斗时间
# @param tick  时钟
# @return 无意义
def __DoLogic_Fighting(tick):
    gameFB = GameWorld.GetGameFB()
    mapID = GameWorld.GetMap().GetMapID()
    #判断时间结束
    if tick - gameFB.GetFBStepTick() < FBCommon.GetFBLineStepTime(mapID)[Def_FightTime] * 1000:
## 可否扫荡
def OnPlayerFBSweepAsk(curPlayer, mapID, lineID, sweepCnt, isFinish, dataEx):
    if mapID != ChConfig.Def_FBMapID_PersonalBoss:
        return
    curGrade = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [mapID])
    if curGrade < 5:
        GameWorld.DebugLog("没有S级不能扫荡! curGrade=%s" % curGrade)
        return
    
    #游戏结束
    __SetFBToFreeTime(tick)
    return
    return True
##设置副本进入离开状态
# @param tick  时钟
# @return 无意义
def __SetFBToFreeTime(tick):
    mapID = GameWorld.GetMap().GetMapID()
    FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, FBCommon.GetFBLineStepTime(mapID)[Def_ExitTime] * 1000)
    FBCommon.SetFBStep(FB_State_FreeTime, tick)
    return
##比赛结束的空闲时间
# @param tick  时钟
# @return 无意义
# @remarks 比赛结束的空闲时间
def __DoLogic_FreeTime(tick):
    mapID = GameWorld.GetMap().GetMapID()
    if tick - GameWorld.GetGameFB().GetFBStepTick() < FBCommon.GetFBLineStepTime(mapID)[Def_ExitTime] * 1000:
        return
## 扫荡结果
def OnPlayerFBSweepResult(curPlayer, mapID, lineID, sweepCnt, isFinish, dataEx):
    
    FBCommon.DoLogic_FBKickAllPlayer()
    return
## 杀怪
#  @param curPlayer
#  @param curNPC 被杀的怪
#  @param tick
#  @return None
def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
    bossID = __GetPersonalBossID(lineID)
    grade = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_Player_Dict_PlayerFBStar_MapId, lineID, False, [mapID])
    
    bossID = FBCommon.GetFBPropertyMark()
    if bossID != curNPC.GetNPCID():
        return
    helpDict = {FBCommon.Help_npcTotal:1}
    FBCommon.Notify_FBHelp(curPlayer, helpDict)
    __SetFBToFreeTime(tick)
    return
## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
#  @param attacker 攻击方
#  @param defender 防守方
#  @return bool
def CheckCanAttackTagObjInFB(attacker, defender):
    gameFB = GameWorld.GetGameFB()
    if gameFB.GetFBStep() != FB_State_Fighting:
        return False
    GameWorld.DebugLog("个人boss扫荡: lineID=%s,bossID=%s,grade=%s,sweepCnt=%s"
                       % (lineID, bossID, grade, sweepCnt), curPlayer.GetPlayerID())
    PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_VIPBOSS, sweepCnt)
    PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_VIPBoss, sweepCnt)
    PlayerNewFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_VIPBoss, sweepCnt)
    PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_VIPBoss, sweepCnt)
    npcCountDict = {bossID:sweepCnt}
    jsonItemList = NPCCommon.GiveKillNPCDropPrize(curPlayer, mapID, npcCountDict, curGrade=grade)[0]
    isPass = 1
    overDict = {FBCommon.Over_itemInfo:jsonItemList, FBCommon.Over_isSweep:1}
    FBCommon.NotifyFBOver(curPlayer, mapID, lineID, isPass, overDict)
    return True
## 是否副本复活
#  @param None
#  @return 是否副本复活
def OnPlayerReborn():
    return True
## 副本行为
#  @param curPlayer 玩家
#  @param actionType 行为类型
#  @param actionInfo 行为信息
#  @param tick 当前时间
#  @return None
def DoFBAction(curPlayer, actionType, actionInfo, tick):
    # 默认为选择关卡,由客户端决定,进场及副本选关通用此行为
    if actionInfo <= 0:
        return
    gameFB = GameWorld.GetGameFB()
    fbStep = gameFB.GetFBStep()
    if fbStep in [FB_State_FightPrepare, FB_State_Fighting]:
        GameWorld.DebugLog("准备或战斗中, 无法变更关卡!")
        return
    bossid = actionInfo
    if not __CheckCanChallenge(curPlayer, bossid):
        FBCommon.DoLogic_FBKickAllPlayer()
        return
    StartFBLevel(curPlayer, bossid, tick)
    return