New file |
| | |
| | | #!/usr/bin/python |
| | | # -*- coding: GBK -*- |
| | | #------------------------------------------------------------------------------- |
| | | # |
| | | ##@package GameWorldLogic.FBProcess.GameLogic_RealmTower |
| | | # |
| | | # @todo:境界塔 |
| | | # @author hxp |
| | | # @date 2023-10-25 |
| | | # @version 1.0 |
| | | # |
| | | # 详细描述: 境界塔 |
| | | # |
| | | #------------------------------------------------------------------------------- |
| | | #"""Version = 2023-10-25 01:30""" |
| | | #------------------------------------------------------------------------------- |
| | | |
| | | import FBCommon |
| | | import GameWorld |
| | | import IPY_GameWorld |
| | | import PlayerControl |
| | | import NetPackCommon |
| | | import NPCCustomRefresh |
| | | import GameWorldProcess |
| | | import ChPyNetSendPack |
| | | import ItemControler |
| | | import IpyGameDataPY |
| | | import ChConfig |
| | | import ChPlayer |
| | | import GameObj |
| | | |
| | | FBDict_Floor = 'FBDict_Floor' # 副本关卡 |
| | | |
| | | # 副本通用配置 |
| | | ( |
| | | Def_PrepareTime, # 每关准备时间,秒 |
| | | Def_FightTime, # 每关战斗时间,秒 |
| | | Def_ExitTime, # 退出时间, 秒 |
| | | ) = range(3) |
| | | |
| | | # 副本状态 |
| | | ( |
| | | FB_State_Open, # 副本开启 |
| | | FB_State_FightPrepare, # 战斗准备时间 |
| | | FB_State_Fighting, # 战斗 |
| | | FB_State_FreeTime, # 活动结束准备(胜利/失败) |
| | | FB_State_Close, # 关闭副本 |
| | | ) = range(5) |
| | | |
| | | def __GetFBTimelCfg(): return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_RealmTower) |
| | | |
| | | def GetTowerIpyData(floor): return IpyGameDataPY.GetIpyGameData("RealmTower", floor) |
| | | |
| | | def OnFBPlayerOnLogin(curPlayer): |
| | | SyncRealmTowerInfo(curPlayer) |
| | | return |
| | | |
| | | def SyncRealmTowerInfo(curPlayer): |
| | | clientPack = ChPyNetSendPack.tagMCRealmTowerInfo() |
| | | clientPack.Clear() |
| | | clientPack.Floor = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor) |
| | | NetPackCommon.SendFakePack(curPlayer, clientPack) |
| | | return |
| | | |
| | | def OnEnterFBEvent(curPlayer, mapID, lineId, tick): |
| | | nextFloorID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor) + 1 |
| | | return __CheckCanChallenge(curPlayer, nextFloorID) |
| | | |
| | | ## 检查可否进行挑战 |
| | | def __CheckCanChallenge(curPlayer, floorID): |
| | | playerID = curPlayer.GetPlayerID() |
| | | ipyData = GetTowerIpyData(floorID) |
| | | if not ipyData: |
| | | GameWorld.ErrLog("境界塔层不存在: floorID=%s" % floorID, playerID) |
| | | return False |
| | | |
| | | curFloorID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealmTowerFloor) |
| | | if floorID <= curFloorID: |
| | | GameWorld.DebugLog("该境界塔层已过关: floorID=%s" % floorID, playerID) |
| | | return False |
| | | |
| | | if floorID > curFloorID + 1: |
| | | GameWorld.DebugLog("上一层未过关: floorID=%s > curFloorID=%s+1" % (floorID, curFloorID), playerID) |
| | | return False |
| | | |
| | | if curPlayer.GetOfficialRank() < ipyData.GetNeedRealmLV(): |
| | | GameWorld.DebugLog("该境界塔层所需境界不足: floorID=%s,NeedRealmLV=%s" % (floorID, ipyData.GetNeedRealmLV()), playerID) |
| | | return False |
| | | |
| | | return True |
| | | |
| | | def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick): |
| | | return ipyEnterPosInfo |
| | | |
| | | def OnChangeMapAsk(ask, tick): |
| | | return IPY_GameWorld.cmeAccept |
| | | |
| | | def DoEnterFB(curPlayer, tick): |
| | | gameFB = GameWorld.GetGameFB() |
| | | fbStep = gameFB.GetFBStep() |
| | | |
| | | if fbStep == FB_State_FightPrepare: |
| | | notify_tick = __GetFBTimelCfg()[Def_PrepareTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) |
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True) |
| | | |
| | | elif fbStep == FB_State_Fighting: |
| | | notify_tick = __GetFBTimelCfg()[Def_FightTime] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick()) |
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True) |
| | | |
| | | elif fbStep > FB_State_Fighting: |
| | | PlayerControl.PlayerLeaveFB(curPlayer) |
| | | return |
| | | |
| | | # 不做处理,有副本行为客户端发包选择挑战关卡 |
| | | return |
| | | |
| | | def OnCloseFB(tick): |
| | | return |
| | | |
| | | def DoExitFB(curPlayer, tick): |
| | | # 玩家退出默认关闭副本 |
| | | GameWorldProcess.CloseFB(tick) |
| | | return |
| | | |
| | | 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 |
| | | |
| | | return |
| | | |
| | | ## 获取BossID |
| | | def __GetRealmTowerBossID(): |
| | | gameFB = GameWorld.GetGameFB() |
| | | floorID = gameFB.GetGameFBDictByKey(FBDict_Floor) |
| | | ipyData = GetTowerIpyData(floorID) |
| | | if not ipyData: |
| | | GameWorld.ErrLog("__GetRealmTowerBossID() can not find %s in RealmTowerNPC.txt" % floorID) |
| | | return 0 |
| | | return ipyData.GetBossID() |
| | | |
| | | ##战斗准备时间 |
| | | # @param tick 时钟 |
| | | # @return 无意义 |
| | | def __DoLogic_FightPrepare(tick): |
| | | gameFB = GameWorld.GetGameFB() |
| | | |
| | | trialCfg = __GetFBTimelCfg() |
| | | if tick - gameFB.GetFBStepTick() < trialCfg[Def_PrepareTime] * 1000: |
| | | return |
| | | |
| | | bossID = __GetRealmTowerBossID() |
| | | if not bossID: |
| | | FBCommon.DoLogic_FBKickAllPlayer() |
| | | return |
| | | |
| | | FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, trialCfg[Def_FightTime] * 1000) |
| | | |
| | | NPCCustomRefresh.SetNPCRefresh(FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_RealmTower, 0), [bossID]) |
| | | |
| | | #转入战斗 |
| | | FBCommon.SetFBStep(FB_State_Fighting, tick) |
| | | return |
| | | |
| | | ## 开始副本关卡 |
| | | def StartfloorID(curPlayer, floorID, tick): |
| | | if curPlayer.GetPlayerAction() == IPY_GameWorld.paDie: |
| | | GameWorld.DebugLog("复活玩家...", curPlayer.GetPlayerID()) |
| | | ChPlayer.PlayerRebornByType(curPlayer, ChConfig.rebornType_City, tick) |
| | | GameObj.SetHPFull(curPlayer) |
| | | FBCommon.ClearFBNPC() |
| | | |
| | | gameFB = GameWorld.GetGameFB() |
| | | gameFB.SetGameFBDict(FBDict_Floor, floorID) |
| | | |
| | | prepareTick = __GetFBTimelCfg()[Def_PrepareTime] * 1000 |
| | | |
| | | FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttWaitStart, prepareTick) |
| | | FBCommon.SetFBStep(FB_State_FightPrepare, tick) |
| | | helpDict = {FBCommon.Help_wheel:floorID} |
| | | FBCommon.Notify_FBHelp(curPlayer, helpDict) |
| | | GameWorld.DebugLog("StartfloorID, floorID=%s, helpDict=%s" % (floorID, str(helpDict)), curPlayer.GetPlayerID()) |
| | | return |
| | | |
| | | def __DoLogic_Fighting(tick): |
| | | gameFB = GameWorld.GetGameFB() |
| | | |
| | | #判断时间结束 |
| | | if tick - gameFB.GetFBStepTick() < __GetFBTimelCfg()[Def_FightTime] * 1000: |
| | | return |
| | | |
| | | floorID = gameFB.GetGameFBDictByKey(FBDict_Floor) |
| | | playerManager = GameWorld.GetMapCopyPlayerManager() |
| | | for index in xrange(playerManager.GetPlayerCount()): |
| | | curPlayer = playerManager.GetPlayerByIndex(index) |
| | | if not curPlayer: |
| | | continue |
| | | __SendRealmTowerOverInfo(curPlayer, floorID, False) |
| | | |
| | | #游戏结束 |
| | | __SetFBToFreeTime(tick) |
| | | return |
| | | |
| | | def __SetFBToFreeTime(tick): |
| | | FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttLeaveMap, __GetFBTimelCfg()[Def_ExitTime] * 1000) |
| | | FBCommon.SetFBStep(FB_State_FreeTime, tick) |
| | | return |
| | | |
| | | def __DoLogic_FreeTime(tick): |
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < __GetFBTimelCfg()[Def_ExitTime] * 1000: |
| | | return |
| | | |
| | | return |
| | | |
| | | def DoFB_Player_KillNPC(curPlayer, curNPC, tick): |
| | | gameFB = GameWorld.GetGameFB() |
| | | if gameFB.GetFBStep() != FB_State_Fighting: |
| | | return |
| | | |
| | | bossID = __GetRealmTowerBossID() |
| | | if bossID != curNPC.GetNPCID(): |
| | | return |
| | | |
| | | floorID = gameFB.GetGameFBDictByKey(FBDict_Floor) |
| | | |
| | | # 过关全服广播 |
| | | ipyData = GetTowerIpyData(floorID) |
| | | if not ipyData: |
| | | return |
| | | |
| | | #更新关卡 |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RealmTowerFloor, floorID) |
| | | GameWorld.DebugLog('更新境界塔已通关数 %s' % floorID) |
| | | |
| | | # 给过关奖励 |
| | | giveItemList = ipyData.GetRewardItemList() |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, giveItemList, None, ["RealmTower", False, {}]) |
| | | prizeDict = {FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(giveItemList)} |
| | | |
| | | # 过关时间 |
| | | costTime = tick - GameWorld.GetGameFB().GetFBStepTick() |
| | | prizeDict[FBCommon.Over_costTime] = costTime |
| | | __SendRealmTowerOverInfo(curPlayer, floorID, True, prizeDict) |
| | | |
| | | SyncRealmTowerInfo(curPlayer) |
| | | |
| | | __SetFBToFreeTime(tick) |
| | | return |
| | | |
| | | ## 发送挑战结果信息 |
| | | def __SendRealmTowerOverInfo(curPlayer, floorID, isPass, overDict={}): |
| | | overDict[FBCommon.Over_dataMapID] = ChConfig.Def_FBMapID_RealmTower |
| | | overDict[FBCommon.Over_wheel] = floorID |
| | | overDict[FBCommon.Over_isPass] = int(isPass) |
| | | GameWorld.DebugLog("__SendRealmTowerOverInfo overDict=%s" % (str(overDict)), curPlayer.GetPlayerID()) |
| | | FBCommon.Notify_FB_Over(curPlayer, overDict) |
| | | return |
| | | |
| | | ## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定 |
| | | # @param attacker 攻击方 |
| | | # @param defender 防守方 |
| | | # @return bool |
| | | def CheckCanAttackTagObjInFB(attacker, defender): |
| | | gameFB = GameWorld.GetGameFB() |
| | | if gameFB.GetFBStep() != FB_State_Fighting: |
| | | return False |
| | | return True |
| | | |
| | | ##玩家死亡 |
| | | def DoPlayerDead(curPlayer): |
| | | gameFB = GameWorld.GetGameFB() |
| | | floorID = gameFB.GetGameFBDictByKey(FBDict_Floor) |
| | | __SendRealmTowerOverInfo(curPlayer, floorID, False) |
| | | tick = GameWorld.GetGameWorld().GetTick() |
| | | #游戏结束 |
| | | __SetFBToFreeTime(tick) |
| | | return |
| | | |
| | | ## 是否副本复活 |
| | | def OnPlayerReborn(): |
| | | return True |
| | | |
| | | ## 副本行为 |
| | | 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 |
| | | |
| | | floorID = actionInfo |
| | | if not __CheckCanChallenge(curPlayer, floorID): |
| | | FBCommon.DoLogic_FBKickAllPlayer() |
| | | return |
| | | |
| | | StartfloorID(curPlayer, floorID, tick) |
| | | return |