| | |
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_FamilyBoss
|
| | | #
|
| | | # @todo:战盟boss副本
|
| | | # @author xdh
|
| | | # @date 2018-02-08
|
| | | # @todo:战盟boss副本/仙盟试炼
|
| | | # @author hxp
|
| | | # @date 2023-09-29
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 战盟boss副本
|
| | | # 详细描述: 战盟boss副本/仙盟试炼
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | #"""Version = 2018-02-08 17:20"""
|
| | | #---------------------------------------------------------------------
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2023-09-29 02:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import FBCommon
|
| | | import GameWorldProcess
|
| | | import GameWorld
|
| | | import IPY_GameWorld
|
| | | import PlayerControl
|
| | | import GameWorld
|
| | | import PlayerTongTianLing
|
| | | import NPCCustomRefresh
|
| | | import ChPyNetSendPack
|
| | | import ItemControler
|
| | | import NetPackCommon
|
| | | import IpyGameDataPY
|
| | | import PlayerFamily
|
| | | import ShareDefine
|
| | | import EventReport
|
| | | import SkillCommon
|
| | | import PyGameData
|
| | | import BuffSkill
|
| | | import ChConfig
|
| | |
|
| | | import math
|
| | |
|
| | | #当前副本地图的状态
|
| | | (
|
| | | FB_Step_Open, # 地图开启
|
| | | FB_Step_MapPrepare, # 地图准备
|
| | | FB_Step_Fighting, # 战斗中
|
| | | FB_Step_LeaveTime, # 自由时间(还可进入)
|
| | | FB_Step_LeaveTime1, # 自由时间(不可进入)
|
| | | FB_Step_LeaveTime, # 自由时间
|
| | | FB_Step_Over, # 副本关闭
|
| | | ) = range(6)
|
| | | ) = range(5)
|
| | |
|
| | | #---战盟副本---
|
| | | FamilyBossFB_Star = 'FamilyBossFB_Star' #评级
|
| | | Map_FamilyBossFB_FamilyID = "FamilyBossFB_FamilyID" # 对应的家族id
|
| | |
|
| | | (
|
| | | Def_Time_MapPrepare, # 准备时间, 秒
|
| | | Def_Time_Fight, # 持续时间, 秒
|
| | | Def_Time_Leave, # 结束时间, 秒
|
| | | Def_StarTime, # 星级对应耗时配置, 秒
|
| | | ) = range(4)
|
| | |
|
| | | def GetFamilyBossFBTimeCfg():return FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_FamilyBossMap, 0)
|
| | |
|
| | | def GameServerOpenFamilyBoss(familyID, openCount):
|
| | | if familyID in PyGameData.g_familyBossOpenCountDict:
|
| | | curOpenCount = PyGameData.g_familyBossOpenCountDict[familyID]
|
| | | if curOpenCount == openCount:
|
| | | return
|
| | | PyGameData.g_familyBossOpenCountDict[familyID] = openCount
|
| | | if familyID in PyGameData.g_familyBossPlayer:
|
| | | PyGameData.g_familyBossPlayer.pop(familyID)
|
| | | GameWorld.DebugLog("开启仙盟Boss: familyID=%s,openCount=%s" % (familyID, openCount))
|
| | | return
|
| | |
|
| | | def AddFamilyBossPlayer(curPlayer):
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | if familyID not in PyGameData.g_familyBossOpenCountDict:
|
| | | return
|
| | | openCount = PyGameData.g_familyBossOpenCountDict[familyID]
|
| | | familyPlayerList = PyGameData.g_familyBossPlayer.get(familyID, [])
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID in familyPlayerList:
|
| | | return
|
| | | familyPlayerList.append(playerID)
|
| | | PyGameData.g_familyBossPlayer[familyID] = familyPlayerList
|
| | | GameWorld.DebugLog("仙盟参与玩家: %s" % PyGameData.g_familyBossPlayer)
|
| | | EventReport.WriteEvent_FB(curPlayer, ChConfig.Def_FBMapID_FamilyBossMap, openCount, ChConfig.CME_Log_Start)
|
| | | PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_FamilyBoss, 1)
|
| | | return
|
| | |
|
| | |
|
| | |
|
| | | ##开启副本
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 开启副本
|
| | | def OnOpenFB(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, 0)
|
| | | gameFB.SetGameFBDict(FamilyBossFB_Star, 0)
|
| | | return
|
| | |
|
| | |
|
| | | ##关闭副本
|
| | | # @param tick 时间戳
|
| | | # @return 无意义
|
| | | # @remarks |
| | | def OnCloseFB(tick):
|
| | | #副本踢出玩家
|
| | | # 通知GameServer副本结束
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
|
| | | # msgStr = str([familyID, 0])
|
| | | # GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
|
| | | class BattlePlayer():
|
| | |
|
| | | if familyID in PyGameData.g_familyBossOpenCountDict:
|
| | | PyGameData.g_familyBossOpenCountDict.pop(familyID)
|
| | | GameWorld.DebugLog("移除仙盟开启boss数:%s" % PyGameData.g_familyBossOpenCountDict)
|
| | | if familyID in PyGameData.g_familyBossPlayer:
|
| | | PyGameData.g_familyBossPlayer.pop(familyID)
|
| | | GameWorld.DebugLog("移除仙盟参与玩家:%s" % PyGameData.g_familyBossPlayer)
|
| | | def __init__(self, playerID):
|
| | | self.playerID = playerID
|
| | | self.hurtValue = 0 # 当前累计伤害
|
| | | self.hurtValueLast = 0 # 上次同步结算时伤害
|
| | | self.fightTickTotal = 0 # 累计战斗tick
|
| | | self.statsTick = 0 # 统计tick
|
| | | return
|
| | | |
| | | def onEnter(self, curPlayer, tick):
|
| | | hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
|
| | | hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
|
| | | self.hurtValue = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
|
| | | self.hurtValueLast = self.hurtValue
|
| | | self.fightTickTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds) * 1000
|
| | | self.statsTick = tick
|
| | | return
|
| | | |
| | | def OnFBPlayerOnLogin(curPlayer):
|
| | | SyncFamilyBossPlayerInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def OnFBPlayerOnDay(curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
|
| | | hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
|
| | | hurtValueTotal = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
|
| | | |
| | | rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
|
| | | #仙盟伤血奖励GameServer处理补发
|
| | | |
| | | #GameWorld.DebugLog("仙盟boss伤血过天. hurtValueTotal=%s,rewardRecord=%s" % (hurtValueTotal, rewardRecord), playerID)
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetFamilyBossHurtAwardCount()):
|
| | | ipyData = ipyDataMgr.GetFamilyBossHurtAwardByIndex(index)
|
| | | if ipyData.GetAwardType() != 1:
|
| | | continue
|
| | | needHurtTotal = ipyData.GetNeedHurtTotal()
|
| | | if hurtValueTotal < needHurtTotal:
|
| | | #GameWorld.DebugLog(" 伤血不足,不补发该奖励! needHurtTotal=%s" % needHurtTotal, playerID)
|
| | | continue
|
| | | recordIndex = ipyData.GetRecordIndex()
|
| | | if rewardRecord & pow(2, recordIndex):
|
| | | #GameWorld.DebugLog(" 该个人奖励已领奖! recordIndex=%s,rewardRecord=%s" % (recordIndex, rewardRecord), playerID)
|
| | | continue
|
| | |
|
| | | paramList = [needHurtTotal]
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | PlayerControl.SendMailByKey("FamilyBossHurtAward", [playerID], awardItemList, paramList)
|
| | | #GameWorld.DebugLog(" 邮件补发伤血奖励! recordIndex=%s" % recordIndex, playerID)
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValue, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValuePoint, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossFightSeconds, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAward, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAwardFamily, 0)
|
| | | SyncFamilyBossPlayerInfo(curPlayer) |
| | | return
|
| | |
|
| | | def GetBattlePlayer(playerID):
|
| | | if playerID in PyGameData.g_familyBossHurtPlayerDict:
|
| | | batPlayer = PyGameData.g_familyBossHurtPlayerDict[playerID]
|
| | | else:
|
| | | batPlayer = BattlePlayer(playerID)
|
| | | PyGameData.g_familyBossHurtPlayerDict[playerID] = batPlayer
|
| | | return batPlayer
|
| | |
|
| | | def OnOpenFB(tick):
|
| | | return
|
| | |
|
| | | def OnCloseFB(tick):
|
| | | GameWorld.GetGameWorld().SetPropertyID(0)
|
| | | FBCommon.DoLogic_FBKickAllPlayer()
|
| | | return
|
| | |
|
| | |
|
| | | ## 是否能够通过活动查询进入
|
| | | # @param curPlayer 玩家实例
|
| | | # @param mapID 地图ID
|
| | | # @param lineID 线路id
|
| | | # @param tick 时间戳
|
| | | # @return 布尔值
|
| | | def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
|
| | | return __CheckEnter(curPlayer, mapID)
|
| | |
|
| | |
|
| | | ##进入副本检查
|
| | | # @param curPlayer 玩家实例
|
| | | # @param mapID 地图ID
|
| | | # @param lineID 线路id
|
| | | # @return None
|
| | | def __CheckEnter(curPlayer, mapID):
|
| | | |
| | | # 是否有战盟
|
| | | if curPlayer.GetFamilyID() <= 0:
|
| | | GameWorld.DebugLog("没有战盟,不能进入战盟boss副本!")
|
| | | GameWorld.DebugLog("没有战盟,不能进入战盟boss副本!", curPlayer.GetPlayerID())
|
| | | return False
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | fightSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds) # 已战斗时长
|
| | | fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
|
| | | if fightSeconds >= fightSecondsMax:
|
| | | GameWorld.DebugLog("已经达到仙盟boss战斗时长上限,无法进入. fightSeconds=%s" % fightSeconds, playerID)
|
| | | 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 TChangeMapError
|
| | | # @remarks 验证家族是否在今天的家族战表
|
| | | def OnChangeMapAsk(ask, tick):
|
| | | return IPY_GameWorld.cmeAccept
|
| | |
|
| | |
|
| | | ##玩家进入副本
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 无意义
|
| | | # @remarks 玩家进入副本
|
| | | def DoEnterFB(curPlayer, tick):
|
| | | mapID = GameWorld.GetGameWorld().GetMapID()
|
| | | |
| | | if not __CheckEnter(curPlayer, mapID):
|
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | fbStep = gameFB.GetFBStep()
|
| | |
|
| | | if fbStep == FB_Step_Open:
|
| | | FBCommon.SetFBStep(FB_Step_MapPrepare, tick)
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | gameFB.SetGameFBDict(Map_FamilyBossFB_FamilyID, familyID)
|
| | | msgStr = str([familyID, 1])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
|
| | | familyBossFBCfg = GetFamilyBossFBTimeCfg() |
| | | fbStep = gameFB.GetFBStep()
|
| | | if fbStep == FB_Step_MapPrepare:
|
| | | #初始化并通知等待倒计时
|
| | | __EnterFBInPrepare(curPlayer, familyBossFBCfg[Def_Time_MapPrepare] * 1000, gameFB, tick)
|
| | | |
| | | elif fbStep == FB_Step_Fighting:
|
| | | #通知进入时间
|
| | | notifyTick = max(familyBossFBCfg[Def_Time_Fight] * 1000 - (tick - gameFB.GetFBStepTick()), 0)
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, notifyTick, True)
|
| | | __UpdFamilyBossFBStar(tick, True, curPlayer)
|
| | | elif fbStep == FB_Step_LeaveTime:
|
| | | notifyTick = max(familyBossFBCfg[Def_Time_Leave] * 1000 - (tick - gameFB.GetFBStepTick()), 0)
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, notifyTick, True)
|
| | | DoFBHelp(curPlayer, tick)
|
| | | batPlayer = GetBattlePlayer(playerID)
|
| | | batPlayer.onEnter(curPlayer, tick)
|
| | | GameWorld.DebugLog("DoEnterFB: fbStep=%s,fightTickTotal=%s,hurtValue=%s" % (fbStep, batPlayer.fightTickTotal, batPlayer.hurtValue), playerID)
|
| | |
|
| | | AddFamilyBossPlayer(curPlayer)
|
| | | fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
|
| | | remainTick = fightSecondsMax * 1000 - batPlayer.fightTickTotal
|
| | | if remainTick <= 0:
|
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | return
|
| | | |
| | | if fbStep != FB_Step_Fighting:
|
| | | __SetFBToFight(tick)
|
| | | |
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, remainTick, True)\
|
| | | |
| | | statsFBMemberHurt(tick, 1)
|
| | | return
|
| | |
|
| | | def __SetFBToFight(tick):
|
| | | FBCommon.SetFBStep(FB_Step_Fighting, tick)
|
| | | refreshMark, bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
|
| | | if not GameWorld.FindNPCByNPCID(bossID):
|
| | | NPCCustomRefresh.SetNPCRefresh(refreshMark, [bossID])
|
| | | return
|
| | |
|
| | | ##副本定时器
|
| | | # @param tick 时间戳
|
| | |
| | | def OnProcess(tick):
|
| | | fbStep = GameWorld.GetGameFB().GetFBStep()
|
| | |
|
| | | if fbStep == FB_Step_MapPrepare:
|
| | | __DoLogic_MapPrepare(tick)
|
| | | elif fbStep == FB_Step_Fighting:
|
| | | if fbStep == FB_Step_Fighting:
|
| | | __DoLogic_MapFighting(tick)
|
| | | elif fbStep == FB_Step_LeaveTime:
|
| | | __DoLogic_MapLeave(tick)
|
| | | elif fbStep == FB_Step_LeaveTime1:
|
| | | __DoLogic_MapLeave(tick)
|
| | | return
|
| | |
|
| | |
|
| | | ## 更新当前副本星级
|
| | | def __UpdFamilyBossFBStar(tick, isForce=False, curPlayer=None):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
|
| | | if curStar == 1:
|
| | | return curStar
|
| | | |
| | | useSecond = int(math.ceil((tick - gameFB.GetFBStepTick()) / 1000.0))
|
| | | familyBossFBCfg = GetFamilyBossFBTimeCfg()
|
| | | starTimeList = familyBossFBCfg[Def_StarTime]
|
| | | diffSecond = 0
|
| | | updStar = 1 # 默认至少1星
|
| | | for star, starTime in enumerate(starTimeList, 2):
|
| | | if useSecond <= starTime:
|
| | | updStar = star
|
| | | diffSecond = starTime-useSecond
|
| | | |
| | | if curStar == updStar and not isForce:
|
| | | return curStar
|
| | |
|
| | | gameFB.SetGameFBDict(FamilyBossFB_Star, updStar)
|
| | | |
| | | GameWorld.DebugLog("__UpdFamilyBossFBStar useSecond=%s,curStar=%s,updStar=%s, diffSecond=%s" |
| | | % (useSecond, curStar, updStar, diffSecond))
|
| | | |
| | | if curPlayer:
|
| | | DoFBHelp(curPlayer, tick)
|
| | | if updStar != 1:
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
|
| | | else:
|
| | | playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if not curPlayer:
|
| | | continue
|
| | | DoFBHelp(curPlayer, tick)
|
| | | if updStar != 1:
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttFlagTake, 0, diffSecond * 1000, True)
|
| | | |
| | | |
| | | return updStar
|
| | |
|
| | |
|
| | | def __EnterFBInPrepare(curPlayer, downTime, gameFB, tick, notifyEff=False):
|
| | | #通知准备倒计时
|
| | | notifyTick = max(downTime - (tick - gameFB.GetFBStepTick()), 0)
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, notifyTick, True)
|
| | | |
| | | if notifyEff:
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttAddUpTime, 0, notifyTick, True)
|
| | | return
|
| | |
|
| | |
|
| | | def __DoLogic_MapPrepare(tick):
|
| | | invadeCfg = GetFamilyBossFBTimeCfg()
|
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() < invadeCfg[Def_Time_MapPrepare] * 1000:
|
| | | return
|
| | | __OnFamilyBossFBStart(tick)
|
| | | return
|
| | |
|
| | |
|
| | | def __DoLogic_MapFighting(tick):
|
| | | invadeCfg = GetFamilyBossFBTimeCfg()
|
| | | |
| | | if tick - GameWorld.GetGameFB().GetFBStepTick() >= invadeCfg[Def_Time_Fight] * 1000:
|
| | | __DoFamilyBossFBOver(tick, False)
|
| | | return
|
| | | __UpdFamilyBossFBStar(tick)
|
| | | return
|
| | |
|
| | | def __DoLogic_MapLeave(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | invadeCfg = GetFamilyBossFBTimeCfg()
|
| | | remianTime = invadeCfg[Def_Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
|
| | | if remianTime > 0:
|
| | | fbStep = gameFB.GetFBStep()
|
| | | if remianTime < 5000 and fbStep == FB_Step_LeaveTime:
|
| | | gameFB.SetFBStep(FB_Step_LeaveTime1)
|
| | | familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
|
| | | msgStr = str([familyID, 0])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
|
| | | lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)
|
| | | if tick - lastTick < 5000:
|
| | | return
|
| | | |
| | | # 时间到,踢出还在副本的玩家等...
|
| | | GameWorldProcess.CloseFB(tick)
|
| | | FBCommon.SetFBStep(FB_Step_Over, tick)
|
| | | FBCommon.DoLogic_FBKickAllPlayer()
|
| | | gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)
|
| | | statsFBMemberHurt(tick)
|
| | | return
|
| | |
|
| | | def __OnFamilyBossFBStart(tick):
|
| | | FBCommon.SetFBStep(FB_Step_Fighting, tick)
|
| | | refreshMark, bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
|
| | | NPCCustomRefresh.SetNPCRefresh(refreshMark, [bossID])
|
| | |
|
| | | # 战盟频道通知开始
|
| | | familyBossFBCfg = GetFamilyBossFBTimeCfg()
|
| | | FBCommon.Sync_Player_TimeTick(IPY_GameWorld.tttTowerTake, familyBossFBCfg[Def_Time_Fight] * 1000) |
| | | def statsFBMemberHurt(tick, statsType=0, exitPlayerID=0):
|
| | | ## 统计副本仙盟成员伤害
|
| | | # statsType 0-常规;1-玩家进入;2-玩家退出
|
| | |
|
| | | __UpdFamilyBossFBStar(tick)
|
| | | return
|
| | |
|
| | |
|
| | | def __DoFamilyBossFBOver(tick, isKill):
|
| | | # 副本结束逻辑
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | if gameFB.GetFBStep() == FB_Step_LeaveTime:
|
| | | return
|
| | | GameWorld.DebugLog("处理仙盟BOSS副本结束逻辑")
|
| | | invadeCfg = GetFamilyBossFBTimeCfg()
|
| | | FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
|
| | |
|
| | | familyID = gameFB.GetGameFBDictByKey(Map_FamilyBossFB_FamilyID)
|
| | | msgStr = str([familyID, 2])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'FamilyBossFBState', msgStr, len(msgStr))
|
| | | fightMemCount = 0
|
| | | familyID = GameWorld.GetGameWorld().GetPropertyID()
|
| | | playerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if not curPlayer:
|
| | | continue
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID != exitPlayerID:
|
| | | fightMemCount += 1
|
| | | |
| | | needMemCount, skillTypeID = IpyGameDataPY.GetFuncEvalCfg("FamilyBossFB", 2)
|
| | |
|
| | | grade = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
|
| | | GameWorld.Log("仙盟BOSS副本结算: familyID=%s, grade=%s" % (familyID, grade), familyID)
|
| | | leaveTick = invadeCfg[Def_Time_Leave] * 1000
|
| | | copyMapPlayerManager = GameWorld.GetMapCopyPlayerManager()
|
| | | playerCount = copyMapPlayerManager.GetPlayerCount()
|
| | | for i in xrange(playerCount):
|
| | | |
| | | curPlayer = copyMapPlayerManager.GetPlayerByIndex(i)
|
| | | |
| | | if curPlayer == None or curPlayer.IsEmpty():
|
| | | fightSecondsMax = IpyGameDataPY.GetFuncCfg("FamilyBossFB", 1)
|
| | | addFamilyHurt = 0
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if not curPlayer:
|
| | | continue
|
| | |
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
|
| | | if isKill:
|
| | | PlayerFamily.AddFamilyActivity(curPlayer, ShareDefine.FamilyActive_BOSS)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | batPlayer = GetBattlePlayer(playerID)
|
| | | |
| | | hurtValue = batPlayer.hurtValue
|
| | | addHurtValue = max(0, hurtValue - batPlayer.hurtValueLast)
|
| | | batPlayer.hurtValueLast = hurtValue
|
| | |
|
| | | if isKill:
|
| | | doCountRate = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 1))
|
| | | doCountAdd = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyBOSSDropRule", 2))
|
| | | FBCommon.SetNPCDropDoCountRate(gameFB, doCountRate, doCountAdd)
|
| | | passTick = tick - batPlayer.statsTick
|
| | | if passTick > 0:
|
| | | batPlayer.fightTickTotal += passTick
|
| | | batPlayer.statsTick = tick
|
| | | |
| | | fightSeconds = batPlayer.fightTickTotal / 1000
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValue, hurtValue % ChConfig.Def_PerPointValue)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtValuePoint, hurtValue / ChConfig.Def_PerPointValue)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossFightSeconds, fightSeconds)
|
| | | |
| | | addFamilyHurt += addHurtValue
|
| | | #GameWorld.DebugLog("仙盟玩家伤血统计: fightSeconds=%s,hurtValue=%s,addHurtValue=%s, %s" % (fightSeconds, hurtValue, addHurtValue, addFamilyHurt), playerID)
|
| | | |
| | | # 帮助信息
|
| | | helpDict = {"hurtValue":hurtValue, "fightSeconds":fightSeconds, "fightMemCount":fightMemCount}
|
| | | FBCommon.Notify_FBHelp(curPlayer, helpDict)
|
| | | |
| | | if playerID == exitPlayerID:
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
|
| | | SyncFamilyBossPlayerInfo(curPlayer)
|
| | | elif fightSeconds >= fightSecondsMax:
|
| | | GameWorld.DebugLog(" 没有战斗时长了,踢出副本", playerID)
|
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | else:
|
| | | # 处理buff
|
| | | __parseFightBuff(curPlayer, fightMemCount, needMemCount, skillTypeID, tick)
|
| | | |
| | | SendGameServer("FBMemberHurt", [statsType, familyID, fightMemCount, addFamilyHurt])
|
| | | return
|
| | |
|
| | | def __parseFightBuff(curPlayer, fightMemCount, needMemCount, skillTypeID, tick):
|
| | | if fightMemCount < needMemCount:
|
| | | #GameWorld.DebugLog(" 人数不足战斗buff", curPlayer.GetPlayerID())
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
|
| | | return
|
| | | skillLV = fightMemCount - needMemCount + 1 |
| | | findBuff = SkillCommon.FindBuffByID(curPlayer, skillTypeID)[0]
|
| | | if findBuff and findBuff.GetSkill().GetSkillLV() == skillLV:
|
| | | #GameWorld.DebugLog(" 战斗buff等级不变.skillTypeID=%s,skillLV=%s" % (skillTypeID, skillLV), curPlayer.GetPlayerID())
|
| | | return
|
| | | #GameWorld.DebugLog(" 战斗buff等级改变.skillTypeID=%s,skillLV=%s" % (skillTypeID, skillLV), curPlayer.GetPlayerID())
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, skillTypeID, tick)
|
| | | SkillCommon.AddBuffBySkillType(curPlayer, skillTypeID, tick, skillLV)
|
| | | return
|
| | |
|
| | | def OnEnterFamily(curPlayer):
|
| | | #进入仙盟时补同步领奖状态到GameServer
|
| | | SendGameServer_FamilyHurtAwardStateFamily(curPlayer)
|
| | | return
|
| | |
|
| | | def SendGameServer_FamilyHurtAwardStateFamily(curPlayer):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | hurtAwardStateFamily = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
|
| | | SendGameServer("FamilyHurtAwardStateFamily", [familyID, playerID, hurtAwardStateFamily])
|
| | | return
|
| | |
|
| | | ##玩家退出副本
|
| | | def DoExitFB(curPlayer, tick):
|
| | | statsFBMemberHurt(tick, 2, curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | ##玩家主动离开副本.
|
| | | def DoPlayerLeaveFB(curPlayer, tick):
|
| | | return
|
| | |
|
| | | ## 玩家对NPC造成伤害
|
| | | def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
|
| | | familyID = curPlayer.GetFamilyID()
|
| | | if not familyID:
|
| | | return
|
| | | bossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)[1]
|
| | | if bossID != curNPC.GetNPCID():
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | batPlayer = GetBattlePlayer(playerID)
|
| | | batPlayer.hurtValue += hurtHP
|
| | | #GameWorld.DebugLog("增加伤血: familyID=%s,hurtHP=%s, %s" % (familyID, hurtHP, batPlayer.hurtValue), playerID)
|
| | | return
|
| | |
|
| | | ## 是否副本复活
|
| | | # @param None
|
| | | # @return 是否副本复活
|
| | | def OnPlayerReborn():
|
| | | return True
|
| | |
|
| | | ## 重置副本复活玩家坐标点
|
| | | # @param None
|
| | | # @return 无意义
|
| | | def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):
|
| | | ipyEnterPosInfo = FBCommon.GetFBLineEnterPosInfo(ChConfig.Def_FBMapID_FamilyBossMap, 0)
|
| | | posX, posY = ipyEnterPosInfo[:2]
|
| | | curPlayer.ResetPos(posX, posY)
|
| | | return
|
| | |
|
| | | ##玩家退出家族处理
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | def OnLeaveFamily(curPlayer, tick):
|
| | | #GameWorld.DebugLog("OnLeaveFamily...")
|
| | | #curPlayerID = curPlayer.GetPlayerID()
|
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | return
|
| | |
|
| | | ##获得副本帮助信息
|
| | | # @param curPlayer 玩家实例
|
| | | # @param tick 时间戳
|
| | | # @return 无意义
|
| | | # @remarks 用于通知阵营比分条
|
| | | def DoFBHelp(curPlayer, tick):
|
| | | helpDict = {}
|
| | | |
| | | gameFB = GameWorld.GetGameFB()
|
| | | curStar = gameFB.GetGameFBDictByKey(FamilyBossFB_Star)
|
| | | helpDict[FBCommon.Help_grade] = curStar
|
| | | FBCommon.Notify_FBHelp(curPlayer, helpDict)
|
| | | return
|
| | |
|
| | |
|
| | | ## 执行副本杀怪逻辑
|
| | | # @param curPlayer 杀怪的人
|
| | | # @param curNPC 被杀的怪
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
|
| | | |
| | | bossID = curNPC.GetNPCID()
|
| | | refreshMark, refreshBossID = FBCommon.GetFBLineRefreshNPC(ChConfig.Def_FBMapID_FamilyBossMap, 0)
|
| | |
|
| | | if bossID != refreshBossID:
|
| | | return
|
| | | GameWorld.DebugLog('仙盟BOSS已被击杀!')
|
| | | |
| | | # # 全服广播
|
| | | # PlayerControl.WorldNotify(0, "jiazu_liubo_202580", [curPlayer.GetFamilyName(), mapID, bossID])
|
| | | __DoFamilyBossFBOver(tick, True)
|
| | | return
|
| | |
|
| | | ## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
|
| | | # @param attacker 攻击方
|
| | | # @param defender 防守方
|
| | | # @return bool
|
| | | def CheckCanAttackTagObjInFB(attacker, defender):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | if gameFB.GetFBStep() != FB_Step_Fighting:
|
| | |
| | | return True
|
| | |
|
| | |
|
| | | def GetFamilyBossHurtAward(curPlayer, awardType, awardIndex):
|
| | | ## awardType 1-个人;2-仙盟
|
| | | |
| | | awardIndex = GameWorld.ToIntDef(awardIndex)
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("FamilyBossHurtAward", awardType, awardIndex)
|
| | | if not ipyData:
|
| | | return
|
| | | needHurtTotal = ipyData.GetNeedHurtTotal()
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | |
| | | familyID = curPlayer.GetFamilyID()
|
| | | if awardType == 2:
|
| | | if not familyID:
|
| | | return
|
| | | rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
|
| | | if rewardRecord & pow(2, awardIndex):
|
| | | GameWorld.DebugLog("仙盟boss伤血仙盟奖励已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
|
| | | return
|
| | | SendGameServer("FamilyHurtAwardReq", [familyID, awardType, awardIndex, needHurtTotal, awardItemList], playerID)
|
| | | return
|
| | | |
| | | hurtValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
|
| | | hurtValuePoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
|
| | | hurtValueTotal = hurtValuePoint * ChConfig.Def_PerPointValue + hurtValue
|
| | | |
| | | if hurtValueTotal < needHurtTotal:
|
| | | GameWorld.DebugLog("仙盟boss伤血个人奖励伤血不足不能领取: awardIndex=%s,hurtValueTotal=%s < %s" % (awardIndex, hurtValueTotal, needHurtTotal), playerID)
|
| | | return
|
| | | |
| | | rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
|
| | | if rewardRecord & pow(2, awardIndex):
|
| | | GameWorld.DebugLog("仙盟boss伤血个人奖励已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
|
| | | return
|
| | | updRewardRecord = rewardRecord | pow(2, awardIndex)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAward, updRewardRecord)
|
| | | |
| | | GameWorld.DebugLog("仙盟boss伤血仙盟奖励发放: familyID=%s,awardType=%s,awardIndex=%s,updRewardRecord=%s,awardItemList=%s" |
| | | % (familyID, awardType, awardIndex, updRewardRecord, awardItemList), playerID)
|
| | | |
| | | event = ["FamilyBossHurtAward", False, {"awardType":awardType, "awardIndex":awardIndex}]
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, None, event)
|
| | | |
| | | SyncFamilyBossPlayerInfo(curPlayer)
|
| | | return
|
| | |
|
| | | def SendGameServer(msgType, msgData, playerID=0):
|
| | | msgInfo = str([msgType, msgData])
|
| | | GameWorld.DebugLog("仙盟boss试炼同步GameServer: msgType=%s,%s" % (msgType, msgData), playerID)
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, "FamilyBoss", msgInfo, len(msgInfo))
|
| | | return
|
| | |
|
| | | def GameServer_FamilyBossInfo(curPlayer, resultList):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | msgType, msgData = resultList[:2]
|
| | | |
| | | GameWorld.Log("仙盟Boss试炼GameServer返回: %s" % str(resultList), playerID)
|
| | | if msgType == "FamilyHurtAwardReq":
|
| | | familyID, awardType, awardIndex, needHurtTotal, awardItemList = msgData
|
| | | hurtValueTotal = resultList[2]
|
| | | if hurtValueTotal < needHurtTotal:
|
| | | GameWorld.DebugLog("仙盟boss伤血仙盟奖励伤血不足不能领取: awardIndex=%s,hurtValueTotal=%s < %s" % (awardIndex, hurtValueTotal, needHurtTotal), playerID)
|
| | | return
|
| | | |
| | | rewardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
|
| | | if rewardRecord & pow(2, awardIndex):
|
| | | GameWorld.DebugLog("仙盟boss伤血仙盟奖励返回时已领奖!awardIndex=%s,rewardRecord=%s" % (awardIndex, rewardRecord), playerID)
|
| | | return
|
| | | updRewardRecord = rewardRecord | pow(2, awardIndex)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FamilyBossHurtAwardFamily, updRewardRecord)
|
| | | |
| | | GameWorld.DebugLog("仙盟boss伤血仙盟奖励发放: familyID=%s,awardType=%s,awardIndex=%s,updRewardRecord=%s,awardItemList=%s" |
| | | % (familyID, awardType, awardIndex, updRewardRecord, awardItemList), playerID)
|
| | | |
| | | event = ["FamilyBossHurtAward", False, {"awardType":awardType, "awardIndex":awardIndex}]
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, None, event)
|
| | | |
| | | SendGameServer_FamilyHurtAwardStateFamily(curPlayer)
|
| | | SyncFamilyBossPlayerInfo(curPlayer)
|
| | | |
| | | return
|
| | |
|
| | | def SyncFamilyBossPlayerInfo(curPlayer):
|
| | | clientPack = ChPyNetSendPack.tagMCFamilyBosFBPlayerInfo()
|
| | | clientPack.Clear()
|
| | | clientPack.HurtTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValue)
|
| | | clientPack.HurtTotalPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtValuePoint)
|
| | | clientPack.FightSeconds = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossFightSeconds)
|
| | | clientPack.HurtAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAward)
|
| | | clientPack.HurtAwardStateFamily = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FamilyBossHurtAwardFamily)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|