6459 【后端】【2.0】缥缈仙域开发单(可进入跨服妖王地图支持分区,增加竞争归属逻辑)
| | |
| | | Def_FBMapID_CrossRealmPK = 32010
|
| | | #跨服蓬莱仙境
|
| | | Def_FBMapID_CrossPenglai = 32020
|
| | | #跨服妖王
|
| | | Def_FBMapID_CrossDemonKing = 32030
|
| | | #骑宠Boss
|
| | | Def_FBMapID_HorsePetBoss = 31200
|
| | |
|
| | | #需要刷世界BOSS的副本
|
| | | WorldBossFBMapIDList = [Def_FBMapID_SealDemon, Def_FBMapID_ZhuXianBoss]
|
| | | #跨服地图
|
| | | Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai]
|
| | | Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonKing]
|
| | | #跨服分区类型配置, 没配置的默认 CrossZoneComm
|
| | | Def_CrossZoneTypeName = {Def_FBMapID_CrossPenglai:"CrossZoneComm",
|
| | | Def_FBMapID_CrossDemonKing:"CrossZonePK",
|
| | | }
|
| | | #跨服分区对应地图配置表名
|
| | | Def_CrossZoneMapTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZoneMap",
|
| | | }
|
| | | #需要动态分配线路的跨服地图
|
| | | Def_CrossDynamicLineMap = [Def_FBMapID_CrossDemonKing]
|
| | |
|
| | | #同系职业枚举
|
| | | JOB_TYPY_COUNT = 5
|
| | |
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("DataMapID", c_int),
|
| | | ("LineID", c_ushort), |
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | |
| | | self.Cmd = 0xC1
|
| | | self.SubCmd = 0x05
|
| | | self.DataMapID = 0
|
| | | self.LineID = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | |
| | | DumpString = '''// C1 05 进入跨服地图 //tagCMEnterCrossServer:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | DataMapID:%d
|
| | | DataMapID:%d,
|
| | | LineID:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.DataMapID
|
| | | self.DataMapID,
|
| | | self.LineID
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
| | | ## 获取地图跨服boss所属分区
|
| | | if dataMapID not in ChConfig.Def_CrossMapIDList:
|
| | | return 0
|
| | | if dataMapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | GameWorld.ErrLog("跨服boss没有分区表!dataMapID=%s" % dataMapID)
|
| | | # 固定线路分配的
|
| | | if dataMapID in ChConfig.Def_CrossZoneMapTableName:
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID]
|
| | | zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID)
|
| | | if not zoneIpyData:
|
| | | return 0
|
| | | return zoneIpyData.GetZoneID()
|
| | | |
| | | # 动态线路分配的
|
| | | elif dataMapID in ChConfig.Def_CrossDynamicLineMap:
|
| | | zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) # {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...}
|
| | | for zoneLineInfo, mapCopyInfo in zoneLineDict.items():
|
| | | if realMapID == mapCopyInfo[0] and copyMapID == mapCopyInfo[1]:
|
| | | return zoneLineInfo[0]
|
| | | return 0
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[dataMapID]
|
| | | zoneIpyData = IpyGameDataPY.GetIpyGameData(tableName, realMapID, dataMapID, copyMapID)
|
| | | if not zoneIpyData:
|
| | | return 0
|
| | | return zoneIpyData.GetZoneID()
|
| | | return 0
|
| | |
|
| | | def __GetCrossBossRecData(zoneID, bossID):
|
| | | ## 获取跨服Boss Rec数据
|
| | |
| | |
|
| | | curTime = int(time.time())
|
| | | if not PyGameData.g_sortBOSSRefreshList:
|
| | | crossZoneName = GameWorld.GetCrossZoneName()
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for i in xrange(ipyDataMgr.GetBOSSInfoCount()):
|
| | | ipyData = ipyDataMgr.GetBOSSInfoByIndex(i)
|
| | | bossID = ipyData.GetNPCID()
|
| | | mapID = ipyData.GetMapID()
|
| | | if mapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | if mapID not in ChConfig.Def_CrossZoneTypeName:
|
| | | continue
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
|
| | | if not hasattr(ipyDataMgr, "Get%sCount" % tableName):
|
| | | zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]
|
| | | if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):
|
| | | continue
|
| | | for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()):
|
| | | zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i)
|
| | | for i in xrange(getattr(ipyDataMgr, "Get%sCount" % zoneTypeName)()):
|
| | | zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % zoneTypeName)(i)
|
| | | if zoneIpyData.GetCrossZoneName() != crossZoneName:
|
| | | continue
|
| | | zoneID = zoneIpyData.GetZoneID()
|
| | | bossRecData = __GetCrossBossRecData(zoneID, bossID)
|
| | | killedTime = GetRecKilledTime(bossRecData)
|
| | |
| | |
|
| | | return
|
| | |
|
| | | def GetCrossBossIsAliveOrCanReborn(zoneID, bossID):
|
| | | ##BOSS是否活着或者可重生
|
| | | if __GetCrossBossIsAlive(zoneID, bossID):
|
| | | return True
|
| | | bossRecData = __GetCrossBossRecData(zoneID, bossID)
|
| | | killedTime = GetRecKilledTime(bossRecData)
|
| | | refreshTime = GetRecRefreshTime(bossRecData) |
| | | curTime = int(time.time())
|
| | | rebornSecond = max(0, refreshTime - (curTime - killedTime))
|
| | | return rebornSecond == 0
|
| | |
|
| | | def OnCrossMapServerInitOK():
|
| | | __SendMapServerAliveCrossBoss()
|
| | | return
|
| | |
|
| | | def __SendMapServerAliveCrossBoss():
|
| | | ## 同步当前还活着的boss,防止地图重启后已经刷新的boss不刷新
|
| | | crossZoneName = GameWorld.GetCrossZoneName()
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for i in xrange(IpyGameDataPY.IPY_Data().GetBOSSInfoCount()):
|
| | | ipyData = IpyGameDataPY.IPY_Data().GetBOSSInfoByIndex(i)
|
| | | bossID = ipyData.GetNPCID()
|
| | | mapID = ipyData.GetMapID()
|
| | | if mapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | if mapID not in ChConfig.Def_CrossZoneTypeName:
|
| | | continue
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
|
| | | if not hasattr(ipyDataMgr, "Get%sCount" % tableName):
|
| | | zoneTypeName = ChConfig.Def_CrossZoneTypeName[mapID]
|
| | | if not hasattr(ipyDataMgr, "Get%sCount" % zoneTypeName):
|
| | | continue
|
| | | for i in xrange(getattr(ipyDataMgr, "Get%sCount" % tableName)()):
|
| | | zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % tableName)(i)
|
| | | for i in xrange(getattr(ipyDataMgr, "Get%sCount" % zoneTypeName)()):
|
| | | zoneIpyData = getattr(ipyDataMgr, "Get%sByIndex" % zoneTypeName)(i)
|
| | | if zoneIpyData.GetCrossZoneName() != crossZoneName:
|
| | | continue
|
| | | zoneID = zoneIpyData.GetZoneID()
|
| | | isAlive = __GetCrossBossIsAlive(zoneID, bossID)
|
| | | if not isAlive:
|
| | |
| | | import PlayerTalk
|
| | | import CrossBoss
|
| | | import ChConfig
|
| | | import PlayerFB
|
| | | import GMShell
|
| | |
|
| | | import traceback
|
| | |
| | |
|
| | | elif msgType == ShareDefine.ClientServerMsg_QueryNPCInfo:
|
| | | PlayerQuery.ClientServerMsg_QueryNPCInfo(serverGroupID, msgData)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_EnterFB:
|
| | | PlayerFB.ClientServerMsg_EnterFB(serverGroupID, msgData)
|
| | |
|
| | | elif msgType == ShareDefine.ClientServerMsg_SetPlayerAttrValue:
|
| | | MapServer_CrossSetPlayerAttrValue(msgData)
|
| | |
| | | elif msgType == ShareDefine.CrossServerMsg_NPCInfoRet:
|
| | | PlayerQuery.CrossServerMsg_NPCInfoRet(msgData, tick)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_EnterFBRet:
|
| | | PlayerFB.CrossServerMsg_EnterFBRet(msgData, tick)
|
| | | |
| | | # 需要发送到地图服务器处理的
|
| | | elif msgType in [ShareDefine.CrossServerMsg_RebornRet, ShareDefine.CrossServerMsg_CollectNPCOK]:
|
| | | MapServer_ClientServerReceiveMsg(msgType, msgData)
|
| | |
| | | ipyData = IpyGameDataPY.GetIpyGameDataNotLog("CrossZoneComm", crossZoneName, zoneID)
|
| | | return ipyData
|
| | |
|
| | | def GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID):
|
| | | ## 获取跨服分区
|
| | | zoneTypeName = ChConfig.Def_CrossZoneTypeName.get(mapID, "CrossZoneComm")
|
| | | crossZoneName = GameWorld.GetCrossZoneName()
|
| | | ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition(zoneTypeName, {"CrossZoneName":crossZoneName}, True)
|
| | | if not ipyDataList:
|
| | | return
|
| | | for ipyData in ipyDataList:
|
| | | serverGroupIDList = ipyData.GetServerGroupIDList()
|
| | | for serverGroupIDInfo in serverGroupIDList:
|
| | | if (isinstance(serverGroupIDInfo, tuple) and serverGroupIDInfo[0] <= serverGroupID <= serverGroupIDInfo[1]) \
|
| | | or (isinstance(serverGroupIDInfo, int) and serverGroupIDInfo == serverGroupID):
|
| | | return ipyData
|
| | | GameWorld.ErrLog("没有找到跨服玩法对应分区! mapID=%s, serverGroupID=%s, zoneTypeName=%s" % (mapID, serverGroupID, zoneTypeName))
|
| | | return
|
| | |
|
| | | def GetCrossCommZoneIpyDataByServerGroupID(serverGroupID):
|
| | | ## 获取跨服常规分区
|
| | | crossZoneName = GameWorld.GetCrossZoneName()
|
| | |
| | | import PlayerTeam
|
| | | import GameWorld
|
| | | import ChConfig
|
| | | import CrossRealmPlayer
|
| | | import CrossRealmMsg
|
| | | import ShareDefine
|
| | | import CrossBoss
|
| | |
|
| | | import random
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | return dataMapID
|
| | | return mapID
|
| | |
|
| | | def ClientServerMsg_EnterFB(serverGroupID, msgData):
|
| | | ## 收到子服请求进入动态分配的跨服副本
|
| | | playerID = msgData["PlayerID"]
|
| | | dataMapID = msgData["DataMapID"]
|
| | | funcLineID = msgData["FuncLineID"]
|
| | | |
| | | if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(dataMapID, serverGroupID)
|
| | | if not zoneIpyData:
|
| | | return
|
| | | zoneID = zoneIpyData.GetZoneID()
|
| | | bossID = msgData["BossID"]
|
| | | if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID):
|
| | | GameWorld.DebugLog("当前跨服妖王死亡状态,不可进入! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID))
|
| | | return
|
| | | |
| | | mapCopyLineInfo = __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID)
|
| | | if not mapCopyLineInfo:
|
| | | return
|
| | | mapID, copyMapID, isOpenNew = mapCopyLineInfo
|
| | | |
| | | # 如果是等待线路启动中的直接返回,等启动好后再通知可进入
|
| | | if __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID):
|
| | | return
|
| | | else:
|
| | | return
|
| | | |
| | | playerIDList = [playerID]
|
| | | retInfo = [playerIDList, dataMapID, mapID, copyMapID]
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
|
| | | return
|
| | |
|
| | | def CrossServerMsg_EnterFBRet(msgData, tick):
|
| | | ## 收到跨服服务器动态分配的跨服副本进入信息
|
| | | |
| | | playerIDList, dataMapID, mapID, copyMapID = msgData
|
| | | |
| | | if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | mapPosInfo = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 2)
|
| | | else:
|
| | | return
|
| | | posX, posY = mapPosInfo
|
| | | |
| | | for playerID in playerIDList:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | continue
|
| | | CrossRealmPlayer.SendCrossRealmReg(curPlayer, dataMapID, mapID, dataMapID, copyMapID, posX, posY)
|
| | | |
| | | return
|
| | |
|
| | | def __GetCrossDynamicLineInfo(dataMapID, funcLineID, zoneID):
|
| | | ## 获取跨服分区对应动态分配的副本地图虚拟线路信息
|
| | |
|
| | | isOpenNew = False |
| | | zoneLineKey = (zoneID, funcLineID)
|
| | | if dataMapID not in PyGameData.g_crossDynamicLineInfo:
|
| | | PyGameData.g_crossDynamicLineInfo[dataMapID] = {}
|
| | | zoneLineDict = PyGameData.g_crossDynamicLineInfo[dataMapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...} |
| | | if zoneLineKey in zoneLineDict:
|
| | | mapID, copyMapID = zoneLineDict[zoneLineKey]
|
| | | GameWorld.DebugLog("已存在该分区功能线路ID,不需要重新分配: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s" % (zoneID, funcLineID, mapID, copyMapID))
|
| | | return mapID, copyMapID, isOpenNew
|
| | | |
| | | if dataMapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | mapIDList = IpyGameDataPY.GetFuncEvalCfg("CrossDemonKingMap", 1)
|
| | | |
| | | # 其他地图待扩展
|
| | | else:
|
| | | return
|
| | | |
| | | usedMapCopyList = zoneLineDict.values() # 已经使用中的地图虚拟线路
|
| | | openMapID, openCopyMapID = 0, 0
|
| | | for mapID in mapIDList:
|
| | | maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(mapID, 0)
|
| | | for copyMapID in xrange(maxCopyMapCount):
|
| | | if [mapID, copyMapID] not in usedMapCopyList:
|
| | | openMapID, openCopyMapID = mapID, copyMapID
|
| | | break
|
| | | if openMapID:
|
| | | break
|
| | | if not openMapID:
|
| | | GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本!dataMapID=%s, funcLineID=%s, zoneID=%s, mapIDList=%s" |
| | | % (dataMapID, funcLineID, zoneID, mapIDList))
|
| | | return
|
| | | isOpenNew = True
|
| | | mapID, copyMapID = openMapID, openCopyMapID
|
| | | |
| | | zoneLineDict[zoneLineKey] = [mapID, copyMapID]
|
| | | propertyID = zoneID * 1000 + funcLineID
|
| | | GameWorld.DebugLog("不存在该分区功能线路ID,重新分配: zoneID=%s,funcLineID=%s,mapID=%s,copyMapID=%s,propertyID=%s" |
| | | % (zoneID, funcLineID, mapID, copyMapID, propertyID))
|
| | | |
| | | # 通知地图开启新的地图虚拟分线
|
| | | msgInfo = str([copyMapID, propertyID])
|
| | | GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, mapID, "OpenFB", msgInfo, len(msgInfo))
|
| | | return mapID, copyMapID, isOpenNew
|
| | |
|
| | | def __AddWaitCrossFBOpenPlayer(mapID, copyMapID, isOpenNew, playerID, serverGroupID):
|
| | | ## 添加跨服玩家进入等待动态副本虚拟线路开启队列
|
| | | |
| | | if mapID not in PyGameData.g_crossDynamicLineOpeningInfo:
|
| | | PyGameData.g_crossDynamicLineOpeningInfo[mapID] = {}
|
| | | openingMapCopyIDDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID] # 跨服动态线路正在开启中的线路信息 {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...}
|
| | | |
| | | if isOpenNew or copyMapID in openingMapCopyIDDict:
|
| | | if copyMapID not in openingMapCopyIDDict:
|
| | | openingMapCopyIDDict[copyMapID] = {}
|
| | | waitingPlayerDict = openingMapCopyIDDict[copyMapID]
|
| | | waitingPlayerDict[playerID] = serverGroupID
|
| | | GameWorld.Log("添加玩家进入等待跨服动态副本虚拟线路开启队列: mapID=%s,copyMapID=%s,isOpenNew=%s,playerID=%s,serverGroupID=%s" |
| | | % (mapID, copyMapID, isOpenNew, playerID, serverGroupID))
|
| | | GameWorld.Log(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
| | | return True
|
| | | return False
|
| | |
|
| | | def OnCrossDynamicLineOpen(mapID, copyMapID):
|
| | | ## 动态分配线路的地图虚拟线路启动成功
|
| | | |
| | | if mapID not in PyGameData.g_crossDynamicLineOpeningInfo:
|
| | | return
|
| | | openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo[mapID]
|
| | | waitingPlayerDict = openingCopyMapDict.pop(copyMapID, {})
|
| | | if not waitingPlayerDict:
|
| | | return
|
| | | |
| | | # 通知子服等待中的玩家可以进入副本
|
| | | serverPlayerIDListDict = {}
|
| | | for playerID, serverGroupID in waitingPlayerDict.items():
|
| | | if serverGroupID not in serverPlayerIDListDict:
|
| | | serverPlayerIDListDict[serverGroupID] = []
|
| | | playerIDList = serverPlayerIDListDict[serverGroupID]
|
| | | playerIDList.append(playerID)
|
| | | |
| | | dataMapID = GetRecordMapID(mapID)
|
| | | GameWorld.Log("动态分配虚拟线路启动成功,通知子服等待玩家可进入: dataMapID=%s,mapID=%s,copyMapID=%s,serverPlayerIDListDict=%s" |
| | | % (dataMapID, mapID, copyMapID, serverPlayerIDListDict))
|
| | | for serverGroupID, playerIDList in serverPlayerIDListDict.items():
|
| | | retInfo = [playerIDList, dataMapID, mapID, copyMapID]
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
|
| | | |
| | | GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
|
| | | GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
| | | return
|
| | |
|
| | | def OnCrossDynamicLineClose(mapID, copyMapID):
|
| | | ## 动态分配线路的地图虚拟线路关闭
|
| | | |
| | | dataMapID = GetRecordMapID(mapID)
|
| | | GameWorld.Log("动态分配虚拟线路关闭 dataMapID=%s,mapID=%s,copyMapID=%s" % (dataMapID, mapID, copyMapID))
|
| | | zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) |
| | | for key, mapCopyInfo in zoneLineDict.items():
|
| | | if mapCopyInfo[0] == mapID and mapCopyInfo[1] == copyMapID:
|
| | | zoneLineDict.pop(key)
|
| | | break
|
| | | |
| | | openingCopyMapDict = PyGameData.g_crossDynamicLineOpeningInfo.get(mapID, {})
|
| | | openingCopyMapDict.pop(copyMapID, {})
|
| | | |
| | | GameWorld.DebugLog(" PyGameData.g_crossDynamicLineInfo=%s" % PyGameData.g_crossDynamicLineInfo)
|
| | | GameWorld.DebugLog(" PyGameData.g_crossDynamicLineOpeningInfo=%s" % PyGameData.g_crossDynamicLineOpeningInfo)
|
| | | return
|
| | |
|
| | | def OnCrossDynamicMapReset(mapID, copyMapCount):
|
| | | ## 动态分配线路的地图重置
|
| | | |
| | | dataMapID = GetRecordMapID(mapID)
|
| | | GameWorld.Log("动态分配虚拟线路地图重置 dataMapID=%s,mapID=%s,copyMapCount=%s" % (dataMapID, mapID, copyMapCount))
|
| | | PyGameData.g_crossMapCopyMapCountDict[mapID] = copyMapCount
|
| | | |
| | | zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(dataMapID, {}) |
| | | for key, mapCopyInfo in zoneLineDict.items():
|
| | | if mapCopyInfo[0] == mapID:
|
| | | zoneLineDict.pop(key)
|
| | | |
| | | PyGameData.g_crossDynamicLineOpeningInfo.pop(mapID, None)
|
| | | return
|
| | |
|
| | | ## 请求进入副本分线
|
| | | # @param curPlayer: 请求玩家
|
| | | # @param queryCallName: 请求回调名
|
| | |
| | | PlayerControl.CrossNotify(serverGroupIDList, crossNotifyList)
|
| | | return
|
| | |
|
| | | if callName == "DynamicLineMapOpen":
|
| | | realMapID, copyMapID = eval(resultName)
|
| | | PlayerFB.OnCrossDynamicLineOpen(realMapID, copyMapID)
|
| | | return
|
| | | |
| | | if callName == "DynamicLineMapClose":
|
| | | realMapID, copyMapID = eval(resultName)
|
| | | PlayerFB.OnCrossDynamicLineClose(realMapID, copyMapID)
|
| | | return
|
| | | |
| | | if callName == "DynamicLineMapInitOK":
|
| | | realMapID, copyMapCount = eval(resultName)
|
| | | PlayerFB.OnCrossDynamicMapReset(realMapID, copyMapCount)
|
| | | return
|
| | | |
| | | if callName == "CommMapServerInitOK":
|
| | | dataMapID, lineID, realMapID, copyMapID = eval(resultName)
|
| | | PyGameData.g_commMapLineInfo[(dataMapID, lineID)] = (realMapID, copyMapID)
|
| | |
| | |
|
| | | g_crossSetPlayerAttr = {} # 跨服玩家更新玩家数据 {playerID:[[setType, setDict], ...], ...}
|
| | |
|
| | | g_crossMapCopyMapCountDict = {} # 跨服地图动态分配虚拟线路条数信息 {mapID:copyMapCount, ...}
|
| | | g_crossDynamicLineInfo = {} # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...}
|
| | | g_crossDynamicLineOpeningInfo = {} # 跨服动态线路正在开启中的线路信息 {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...}
|
| | |
|
| | |
|
| | |
| | | CrossServerMsg_RebornRet = "RebornRet" # 复活结果
|
| | | CrossServerMsg_NPCInfoRet = "NPCInfoRet" # 跨服地图NPC信息
|
| | | CrossServerMsg_CollectNPCOK = "CollectNPCOK" # 采集NPC完成
|
| | | CrossServerMsg_EnterFBRet = "EnterFBRet" # 请求进入跨服副本返回信息
|
| | |
|
| | | # 子服发送跨服信息定义
|
| | | ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功
|
| | |
| | | ClientServerMsg_QueryNPCInfo = "QueryNPCInfo" # 查询跨服地图NPC信息
|
| | | ClientServerMsg_SetPlayerAttrValue = "SetPlayerAttrValue" # 玩家属性数值更新
|
| | | ClientServerMsg_CollectNPC = "CollectNPC" # 采集NPC
|
| | | ClientServerMsg_EnterFB = "EnterFB" # 请求进入跨服副本
|
| | |
|
| | | #跨服广播类型定义
|
| | | CrossNotify_World = "World"
|
| | |
| | | #if FBLogic.DoFBOnKill_Player_ValuePrize(curPlayer, defender, tick):
|
| | | __GiveKill_Player_ValuePrize(curPlayer, defender, tick)
|
| | |
|
| | | NPCCommon.OnPlayerKillNPCPlayer(curPlayer, defender, tick)
|
| | | |
| | | #执行副本杀人逻辑
|
| | | if FBLogic.DoFBOnKill_Player(curPlayer, defender, tick):
|
| | | return
|
| | |
| | | Def_FBMapID_CrossRealmPK = 32010
|
| | | #跨服蓬莱仙境
|
| | | Def_FBMapID_CrossPenglai = 32020
|
| | | #跨服妖王
|
| | | Def_FBMapID_CrossDemonKing = 32030
|
| | | #多仙盟Boss
|
| | | Def_FBMapID_AllFamilyBoss = 31260
|
| | | #骑宠Boss
|
| | |
| | | Def_FBMapID_FairyTreasure = 31190
|
| | |
|
| | | #注册上传跨服服务器数据后直接进入跨服服务器的地图
|
| | | RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai]
|
| | | RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonKing]
|
| | | #跨服地图
|
| | | Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai]
|
| | | Def_CrossMapIDList = [Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonKing]
|
| | | #跨服分区对应地图配置表名
|
| | | Def_CrossZoneMapTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZoneMap",
|
| | | }
|
| | | #需要动态分配线路的跨服地图
|
| | | Def_CrossDynamicLineMap = [Def_FBMapID_CrossDemonKing]
|
| | |
|
| | | #副本关闭时未拾取的物品邮件发放给玩家
|
| | | #这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府
|
| | |
| | | 'SealDemon':[Def_FBMapID_SealDemon, Def_FBMapID_SealDemonEx], #封魔坛
|
| | | 'XMZZ':[Def_FBMapID_XMZZ], #仙魔之争
|
| | | 'CrossRealmPK':[Def_FBMapID_CrossRealmPK], #跨服竞技场
|
| | | 'CrossDemonKing':[Def_FBMapID_CrossDemonKing], #跨服妖王
|
| | | 'GatherSoul':[Def_FBMapID_GatherSoul],#聚魂副本
|
| | | 'ZhuXianBoss':[Def_FBMapID_ZhuXianBoss],#诛仙BOSS
|
| | | 'ZhuXianTower':[Def_FBMapID_ZhuXianTower],#诛仙塔
|
| | |
| | | DropOwnerType_Faction, # 阵营 5
|
| | | DropOwnerType_Special, # 特殊 6
|
| | | DropOwnerType_Family, # 仙盟 7
|
| | | ) = range(8)
|
| | | DropOwnerType_Contend, # 争夺 8 第一个攻击的获得归属,击杀当前归属者的玩家成为新归属者
|
| | | ) = range(9)
|
| | |
|
| | | #------------------------------------------------
|
| | | #技能类型
|
| | |
| | | Def_PlayerKey_FBCommendFightPower = "FBCommendFightPower" # 副本推荐战斗力
|
| | | Def_PlayerKey_RecordXPValue = "RecordXPValue" #临时记录XP值
|
| | | Def_PlayerKey_CollectNPCObjID = "CollectNPCObjID" #采集的NPC对象id
|
| | | Def_PlayerKey_ContendNPCObjID = "ContendNPCObjID" #竞争归属的NPC实例ID
|
| | | Def_PlayerKey_AreaRewardMultiple = "AreaRewardMultiple" #玩家所在区域福利倍值,默认1
|
| | | Def_PlayerKey_AttrActivatyNotify = "AttrActivatyNotify" # 属性激活提示类型
|
| | | Def_PlayerKey_AttrActivatyRecordStarLV = "AttrActivatyRecordStarLV" # 属性激活记录 - 强化星级
|
| | |
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("DataMapID", c_int),
|
| | | ("LineID", c_ushort), |
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | |
| | | self.Cmd = 0xC1
|
| | | self.SubCmd = 0x05
|
| | | self.DataMapID = 0
|
| | | self.LineID = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | |
| | | DumpString = '''// C1 05 进入跨服地图 //tagCMEnterCrossServer:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | DataMapID:%d
|
| | | DataMapID:%d,
|
| | | LineID:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.DataMapID
|
| | | self.DataMapID,
|
| | | self.LineID
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
| | | posY = paramList[3] if len(paramList) > 3 else 0
|
| | | if FBCommon.GetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID):
|
| | | FBCommon.SetFBPDictValue(curPlayer, ChConfig.Def_PDict_LastEnterFBTick % mapID, 0)
|
| | | PlayerControl.PlayerEnterFB(curPlayer, mapID, lineID, posX, posY)
|
| | | if mapID in ChConfig.Def_CrossMapIDList:
|
| | | PlayerControl.PlayerEnterCrossServer(curPlayer, mapID, lineID)
|
| | | else:
|
| | | PlayerControl.PlayerEnterFB(curPlayer, mapID, lineID, posX, posY)
|
| | | return
|
| | |
|
| | |
| | | def PlayerLoginInFBCheck(curPlayer, tick):
|
| | | gameMap = GameWorld.GetMap()
|
| | | #如果此地图是自动释放的, 需要检查这个玩家
|
| | | if gameMap.GetMapFBType() in [IPY_GameWorld.fbtNull, IPY_GameWorld.fbtCrossVSRoom]:
|
| | | if gameMap.GetMapFBType() in [IPY_GameWorld.fbtNull]:
|
| | | return False
|
| | | |
| | | #跨服服务器是直接注册的地图ID数据,地图肯定没有该玩家,所以不判断
|
| | | if GameWorld.IsCrossServer():
|
| | | return False
|
| | |
|
| | | #玩家 在副本中,并且副本不踢出玩家下线
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_CrossDemonKing
|
| | | #
|
| | | # @todo:跨服妖王
|
| | | # @author hxp
|
| | | # @date 2019-04-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服妖王
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-04-11 14:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import FBCommon
|
| | | import GameWorld
|
| | | import IPY_GameWorld
|
| | | import IpyGameDataPY
|
| | | import ChConfig
|
| | | import PyGameData
|
| | | import NPCCommon
|
| | | import ItemCommon
|
| | | import ShareDefine
|
| | | import PlayerSuccess
|
| | | import PlayerActLogin
|
| | |
|
| | | FBDict_StartTick = 'FBDict_StartTick%s' #开始时间
|
| | | FBDict_Speed = 'FBDict_Speed%s' #掉血速度 /s
|
| | | FBDict_RemainHP = 'FBDict_RemainHP%s' #剩余时间
|
| | | FBDict_IsOver = 'FBDict_IsOver' #是否已结算, 结算时的tick
|
| | | FBDict_IsReduceing = 'FBDict_IsReduceing%s' #是否掉血中
|
| | | FBDict_BossTotalHP = 'FBDict_BossTotalHP%s' #BOSS血量,需要的总时间
|
| | | FBDict_LastHurtTick = 'FBDict_LastHurtTick' #上次伤害时间
|
| | |
|
| | | g_heroHurtDict = {} #{playerID:hurt}
|
| | |
|
| | |
|
| | | ## 是否能够通过活动查询进入
|
| | | def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
|
| | | return True
|
| | |
|
| | | ## 查询是否可以进入地图
|
| | | def OnChangeMapAsk(ask, tick):
|
| | | return IPY_GameWorld.cmeAccept
|
| | |
|
| | | ## 开启副本
|
| | | def OnOpenFB(tick):
|
| | | lineID = GetCurFBFuncLineID()
|
| | | killTime = 60
|
| | | GameWorld.GetGameWorld().SetGameWorldDict(FBDict_BossTotalHP % lineID, killTime * 1000)
|
| | | return
|
| | |
|
| | | ## 进副本
|
| | | def DoEnterFB(curPlayer, tick):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | zoneID = GetCurFBLineZoneID()
|
| | | funcLineID = GetCurFBFuncLineID()
|
| | | GameWorld.DebugLog("DoEnterFB zoneID=%s,funcLineID=%s" % (zoneID, funcLineID), playerID)
|
| | | return
|
| | |
|
| | | ## 关闭副本
|
| | | def OnCloseFB(tick):
|
| | | # gameWorld = GameWorld.GetGameWorld()
|
| | | # lineID = gameWorld.GetPropertyID() - 1
|
| | | # gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, 0)
|
| | | # gameWorld.SetGameWorldDict(FBDict_Speed % lineID, 0)
|
| | | # gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, 0)
|
| | | # |
| | | # gameWorld.SetPropertyID(0)
|
| | | return
|
| | |
|
| | | ## 玩家退出副本
|
| | | def DoExitFB(curPlayer, tick):
|
| | | UpdateHPReduceSpeed(tick, True)
|
| | | return
|
| | |
|
| | | ##玩家主动离开副本.
|
| | | def DoPlayerLeaveFB(curPlayer, tick):
|
| | | # FBCommon.SetHadDelTicket(curPlayer, 0)
|
| | | # #主动退出的去掉排行榜信息
|
| | | # lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | # playerHurtDict = PyGameData.g_ZhuXianBossPlayerHurtDict.get(lineID, {})
|
| | | # playerHurtDict.pop(curPlayer.GetPlayerID(), 0)
|
| | | # PyGameData.g_ZhuXianBossPlayerHurtDict[lineID] = playerHurtDict
|
| | | # if not playerHurtDict: #榜上没人,停止掉血
|
| | | # StopReduceHP(lineID, tick)
|
| | | return
|
| | |
|
| | | ## 是否副本复活
|
| | | def OnPlayerReborn():
|
| | | return True
|
| | |
|
| | | ## 获得副本帮助信息
|
| | | def DoFBHelp(curPlayer, tick):
|
| | | |
| | | if GameWorld.GetGameFB().GetGameFBDictByKey(FBDict_IsOver):
|
| | | return
|
| | | |
| | | lineID = GetCurFBFuncLineID()
|
| | | curSpeed = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_Speed % lineID) |
| | | isReduceing = GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_IsReduceing % lineID) |
| | | remainHP = GetBossRemainHP(lineID, tick)
|
| | | totalHP = __GetBossTotalHP(lineID)
|
| | | hpReduceSpeed = curSpeed * 10000 / totalHP if totalHP else 0
|
| | | remainHPPer = min(1000000, remainHP * 1000000 / totalHP) if totalHP else 0
|
| | | fbHelpDict = {FBCommon.Help_lineID:lineID, 'hpReduceSpeed':hpReduceSpeed, 'remainHPPer':remainHPPer, 'isReduceing':isReduceing}
|
| | | GameWorld.DebugLog("DoFBHelp: %s" % fbHelpDict, curPlayer.GetPlayerID())
|
| | | FBCommon.Notify_FBHelp(curPlayer, fbHelpDict)
|
| | | return
|
| | |
|
| | | ## 玩家对NPC造成伤害
|
| | | def DoFB_Player_HurtNPC(curPlayer, curNPC, hurtHP):
|
| | | return
|
| | | lineID = GetCurFBFuncLineID()
|
| | | #有人上榜开始掉血
|
| | | StartReduceHP(lineID, GameWorld.GetGameWorld().GetTick())
|
| | | GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, GameWorld.GetGameWorld().GetTick())
|
| | | return
|
| | |
|
| | | ##---副本总逻辑计时器---
|
| | | # @param tick:时间戳
|
| | | # @return 无意义
|
| | | # @remarks 副本总逻辑计时器
|
| | | def OnProcess(tick):
|
| | | return
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | overTick = gameFB.GetGameFBDictByKey(FBDict_IsOver)
|
| | | # 结算20秒后强制关闭副本, 防止玩家不捡东西导致不结算,强关后地板上的东西会邮件发放给玩家
|
| | | if overTick and tick - overTick >= ChConfig.Def_FBPickupItemTime:
|
| | | GameWorld.Log("强制踢出玩家关闭副本: overTick=%s,tick=%s" % (overTick, tick))
|
| | | FBCommon.DoLogic_FBKickAllPlayer()
|
| | | return
|
| | |
|
| | | lineID = GetCurFBFuncLineID()
|
| | | if lineID < 0:
|
| | | return
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
|
| | | if not startTick or overTick:
|
| | | return
|
| | | lastHurtTick = gameFB.GetGameFBDictByKey(FBDict_LastHurtTick)
|
| | | if lastHurtTick and tick - lastHurtTick >= 2000:
|
| | | StopReduceHP(lineID, tick)
|
| | | GameWorld.GetGameFB().SetGameFBDict(FBDict_LastHurtTick, 0)
|
| | | |
| | | FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000)
|
| | | __CheckBossHP(tick)
|
| | | return
|
| | |
|
| | | def __DoLogicZhuXianBossOver(isPass, tick, dropPosX, dropPosY):
|
| | | #结算
|
| | | # gameFB = GameWorld.GetGameFB()
|
| | | # mapID = GameWorld.GetMap().GetMapID()
|
| | | # lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | # leaveTick = FBCommon.GetFBLineStepTime(mapID, lineID) * 1000
|
| | | # playerHurtList = __GetSortHurtList(lineID)
|
| | | # if not playerHurtList:
|
| | | # GameWorld.Log(' __DoLogicZhuXianBossOver, 伤害榜上没有人!!lineID=%s' % lineID)
|
| | | # return
|
| | | # firsthurtInfo = playerHurtList[0]
|
| | | # firstPlayerID = firsthurtInfo[0]
|
| | | # firstPlayerFamilyID = firsthurtInfo[1][2]
|
| | | # playerManager = GameWorld.GetMapCopyPlayerManager()#GameWorld.GetPlayerManager()
|
| | | # firstPlayer = playerManager.FindPlayerByID(firstPlayerID)
|
| | | # if firstPlayer:
|
| | | # gameFB.SetPlayerGameFBDict(firstPlayerID, FBPlayerDict_Rank, 1)
|
| | | # if not dropPosX or not dropPosY:
|
| | | # dropPosX, dropPosY = firstPlayer.GetPosX(), firstPlayer.GetPosY()
|
| | | # prizeItemList = GiveZhuXianBossAward(firstPlayer, lineID, dropItemMapInfo=[dropPosX, dropPosY, True, True])
|
| | | # if not prizeItemList:
|
| | | # # 没有掉落时直接通知结算,防止卡副本
|
| | | # firstPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
|
| | | # overDict = {FBCommon.Over_rank:1, FBCommon.Over_itemInfo:prizeItemList}
|
| | | # FBCommon.NotifyFBOver(firstPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
|
| | | # else:
|
| | | # firstPlayer.Sync_TimeTick(ChConfig.tttPickupItem, 0, ChConfig.Def_FBPickupItemTime, True)
|
| | | # else:
|
| | | # leaveServerTick = PlayerControl.GetPlayerLeaveServerTick(firstPlayerID)
|
| | | # if leaveServerTick and tick - leaveServerTick < ChConfig.Def_PlayerOfflineProtectTime:
|
| | | # #离线超过3分钟的不给奖励
|
| | | # msgStr = str([ShareDefine.Def_UniversalGameRecType_ZhuXianBossRecord, [firstPlayerID, lineID], [], 0, 0])
|
| | | # GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'AddUniversalGameRec', msgStr, len(msgStr))
|
| | | # |
| | | # helpItemList = FBCommon.GetFBLineReward(mapID, lineID)
|
| | | # if helpItemList: #同盟协助奖励
|
| | | # jsonItemList = FBCommon.GetJsonItemList(helpItemList)
|
| | | # for index in range(0 , playerManager.GetPlayerCount()):
|
| | | # curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | # curPlayerID = curPlayer.GetPlayerID()
|
| | | # if not curPlayerID:
|
| | | # continue
|
| | | # if curPlayerID == firstPlayerID:
|
| | | # continue
|
| | | # curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
|
| | | # remainCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ZhuXianBossHelpCnt)
|
| | | # if curPlayer.GetFamilyID() == firstPlayerFamilyID and remainCnt:
|
| | | # PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ZhuXianBossHelpCnt, remainCnt - 1)
|
| | | # ItemControler.GivePlayerItemOrMail(curPlayer, helpItemList, 'ZXBossHelperReward')
|
| | | # overDict = {FBCommon.Over_rank:0, FBCommon.Over_itemInfo:jsonItemList}
|
| | | # FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
|
| | | # else:
|
| | | # overDict = {FBCommon.Over_rank:0}
|
| | | # FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, 0, overDict)
|
| | | |
| | | return
|
| | |
|
| | | def GiveZhuXianBossAward(curPlayer, lineID, isMail=False, dropItemMapInfo=[]):
|
| | | ##给归属者奖励
|
| | | addCnt = 1
|
| | | equipList = []
|
| | | prizeItemDict = {}
|
| | | bossID = GetCurFBLineBOSSID(lineID)
|
| | |
|
| | | jsonItemList, totalExp, totalMoney = NPCCommon.GiveKillNPCDropPrize(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, {bossID:addCnt},
|
| | | mailTypeKey="ZXBossBelongerReward", isMail=isMail,
|
| | | dropItemMapInfo=dropItemMapInfo)
|
| | | for jsonItem in jsonItemList:
|
| | | if 'UserData' in jsonItem:
|
| | | equipList.append(jsonItem)
|
| | | else:
|
| | | itemID, itemCnt = jsonItem['ItemID'], jsonItem.get('Count', 1)
|
| | | prizeItemDict[itemID] = prizeItemDict.get(itemID, 0) + itemCnt
|
| | | |
| | | GameWorld.DebugLog("诛仙boss结算奖励: lineID=%s,bossID=%s,totalExp=%s,totalMoney=%s,jsonItemList=%s" |
| | | % (lineID, bossID, totalExp, totalMoney, jsonItemList), curPlayer.GetPlayerID())
|
| | | |
| | | prizeItemList = equipList + FBCommon.GetJsonItemList(prizeItemDict.items())
|
| | | #PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_ZhuXianBoss, addCnt)
|
| | |
|
| | | #击杀特定NPC成就
|
| | | PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, addCnt, [bossID])
|
| | | FBCommon.AddEnterFBCount(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, addCnt)
|
| | | # 每日活动
|
| | | #PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_ZhuXianBoss, addCnt)
|
| | | PlayerActLogin.AddLoginAwardActionCnt(curPlayer, ChConfig.Def_LoginAct_ZhuXianBOSS, addCnt)
|
| | | return prizeItemList
|
| | |
|
| | | def OnPickUpItem(curPlayer, curItem, tick):
|
| | | mapItemType = curItem.GetType()
|
| | | if mapItemType == ChConfig.Def_ItemType_Money:
|
| | | return
|
| | | 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]
|
| | | |
| | | 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 not isItemAllPickUp:
|
| | | return
|
| | | |
| | | isPass = 1
|
| | | lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | leaveTick = FBCommon.GetFBLineStepTime(ChConfig.Def_FBMapID_ZhuXianBoss, lineID) * 1000
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | rank = 1###gameFB.GetPlayerGameFBDictByKey(playerID, FBPlayerDict_Rank)
|
| | | |
| | | jsonItemList = PyGameData.g_fbPickUpItemDict.get(playerID, [])
|
| | | curPlayer.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTick, True)
|
| | | overDict = {FBCommon.Over_rank:rank, FBCommon.Over_itemInfo:jsonItemList}
|
| | | FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ZhuXianBoss, lineID, isPass, overDict)
|
| | | return
|
| | |
|
| | |
|
| | | def __CheckBossHP(tick):
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | isOver = gameFB.GetGameFBDictByKey(FBDict_IsOver)
|
| | | lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | |
| | | if not isOver and GetBossRemainHP(lineID, tick) == 0:
|
| | |
|
| | | bossID = GetCurFBLineBOSSID(lineID)
|
| | | curBoss = GameWorld.FindNPCByNPCID(bossID)
|
| | | dropPosX, dropPosY = 0, 0
|
| | | if curBoss:
|
| | | dropPosX, dropPosY = curBoss.GetPosX(), curBoss.GetPosY()
|
| | | |
| | | #结束 设置BOSS死亡
|
| | | FBCommon.ClearFBNPC()
|
| | | FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
|
| | | GameWorld.DebugLog('结束 设置BOSS死亡 lineID=%s' % lineID)
|
| | | ###playerHurtList = __GetSortHurtList(lineID)
|
| | | playerHurtList = []
|
| | | if playerHurtList:
|
| | | killerName, hurtValue = playerHurtList[0][1][:2]
|
| | | NPCCommon.GameServer_KillGameWorldBoss(bossID, killerName, hurtValue)
|
| | | |
| | | NPCCommon.GameServe_GameWorldBossState(bossID, 0)
|
| | | |
| | | ###__DoLogicZhuXianBossOver(1, tick, dropPosX, dropPosY)
|
| | | gameFB.SetGameFBDict(FBDict_IsOver, tick)
|
| | | return
|
| | |
|
| | | def UpdateHPReduceSpeed(tick, isExit=False):
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | playerCnt = gameWorld.GetMapCopyPlayerManager().GetPlayerCount()
|
| | | playerCnt = playerCnt - 1 if isExit else playerCnt
|
| | | if playerCnt <= 0:
|
| | | return
|
| | | lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | if lineID < 0:
|
| | | return
|
| | |
|
| | | curSpeed = int(min(1 + 0.08 * (playerCnt - 1), 1.8) * 1000)
|
| | | gameWorld.SetGameWorldDict(FBDict_Speed % lineID, curSpeed)
|
| | | if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing % lineID):
|
| | | return
|
| | | |
| | | startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
|
| | | remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)
|
| | | lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID)
|
| | | if not startTick:
|
| | | startTick = tick |
| | | lastSpeed = curSpeed
|
| | | remainHP = __GetBossTotalHP(lineID)
|
| | | remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))
|
| | | gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)
|
| | | |
| | | gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)
|
| | | GameWorld.DebugLog(' curSpeed=%s, remainHP=%s, passTime=%s, lastSpeed=%s' % (curSpeed, remainHP, tick - startTick, lastSpeed))
|
| | | FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
|
| | | return
|
| | |
|
| | | def StopReduceHP(lineID, tick):
|
| | | ##暂停BOSS血量减少
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing % lineID):
|
| | | return
|
| | | remainHP = GetBossRemainHP(lineID, tick)
|
| | | if not remainHP:
|
| | | return
|
| | | gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 0)
|
| | | gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, remainHP)
|
| | | return
|
| | |
|
| | | def StartReduceHP(lineID, tick):
|
| | | ##开始BOSS掉血
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | if gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing % lineID):
|
| | | return
|
| | | gameWorld.SetGameWorldDict(FBDict_IsReduceing % lineID, 1)
|
| | | startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
|
| | | if not startTick:
|
| | | gameWorld.SetGameWorldDict(FBDict_RemainHP % lineID, __GetBossTotalHP(lineID))
|
| | | gameWorld.SetGameWorldDict(FBDict_StartTick % lineID, tick)
|
| | | FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0)
|
| | | return
|
| | |
|
| | | def __GetBossTotalHP(lineID):return GameWorld.GetGameWorld().GetGameWorldDictByKey(FBDict_BossTotalHP % lineID)
|
| | |
|
| | | def GetBossRemainHP(lineID, tick):
|
| | | gameWorld = GameWorld.GetGameWorld()
|
| | | |
| | | startTick = gameWorld.GetGameWorldDictByKey(FBDict_StartTick % lineID)
|
| | | lastSpeed = gameWorld.GetGameWorldDictByKey(FBDict_Speed % lineID) |
| | | remainHP = gameWorld.GetGameWorldDictByKey(FBDict_RemainHP % lineID)
|
| | | if not gameWorld.GetGameWorldDictByKey(FBDict_IsReduceing % lineID):
|
| | | return remainHP
|
| | | if not startTick:
|
| | | startTick = tick
|
| | | remainHP = __GetBossTotalHP(lineID)
|
| | | else:
|
| | | remainHP = max(0, int((remainHP - (tick - startTick) / 1000.0 * lastSpeed)))
|
| | | return remainHP
|
| | |
|
| | | def GetCurFBLineBOSSID(lineID= -1):
|
| | | #该分线刷的BOSSID
|
| | | if lineID == -1:
|
| | | lineID = GameWorld.GetGameWorld().GetPropertyID() - 1
|
| | | if lineID == -1:
|
| | | return 0
|
| | | ipyData = IpyGameDataPY.GetIpyGameDataByCondition("FairyDomain", {"MapID":ChConfig.Def_FBMapID_CrossDemonKing, "LineID":lineID})
|
| | | if not ipyData:
|
| | | return 0
|
| | | bossID = ipyData.GetBossID()
|
| | | return bossID
|
| | |
|
| | | def GetCurFBFuncLineID(): return GameWorld.GetGameWorld().GetPropertyID() % 1000
|
| | | def GetCurFBLineZoneID(): return GameWorld.GetGameWorld().GetPropertyID() / 1000
|
| | |
|
| | | ##玩家死亡.
|
| | | # @param curPlayer:死亡的玩家 |
| | | # @param tick 时间戳
|
| | | # @return 返回值无意义
|
| | | # @remarks 玩家主动离开副本.
|
| | | def DoPlayerDead(curPlayer):
|
| | | return
|
| | |
|
| | | ##处理副本中杀死玩家逻辑
|
| | | def DoFBOnKill_Player(atkobj, defender, tick):
|
| | | return True
|
| | |
| | |
|
| | | #调用副本开启触发器
|
| | | FBLogic.OnOpenFB(tick)
|
| | | |
| | | if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap:
|
| | | msgInfo = str([gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapOpen", msgInfo, len(msgInfo))
|
| | | return
|
| | |
|
| | | ## 副本关闭
|
| | |
| | | #根据是否收缩型FB处理
|
| | | FreeOrClearFBByAutoSize(gameWorld)
|
| | |
|
| | | if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap:
|
| | | msgInfo = str([gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapClose", msgInfo, len(msgInfo))
|
| | | return
|
| | |
|
| | | ##根据表中的收缩类型释放或者清空副本状态
|
| | |
| | | if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:
|
| | | msgInfo = str([gameWorld.GetMapID(), gameWorld.GetLineID(), gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CommMapServerInitOK", msgInfo, len(msgInfo))
|
| | | |
| | | if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap and gameWorld.GetCopyMapID() == gameWorld.GetGameWorldCount() - 1:
|
| | | msgInfo = str([gameWorld.GetRealMapID(), gameWorld.GetGameWorldCount()])
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapInitOK", msgInfo, len(msgInfo))
|
| | | |
| | | return
|
| | |
|
| | |
|
| | |
| | | import NPCCommon
|
| | | import AICommon
|
| | | import IPY_GameWorld
|
| | | import FamilyRobBoss
|
| | | import AttackCommon
|
| | | import GameWorld
|
| | | import BaseAttack
|
| | | import PlayerState
|
| | | import SkillCommon
|
| | | import PyGameData
|
| | | import BuffSkill
|
| | | import GameObj
|
| | | import ItemCommon
|
| | |
|
| | | ## 初始化
|
| | | # @param curNPC 当前npc
|
| | |
| | | AICommon.NormalNPCFast_Move(curNPC, tick)
|
| | | return
|
| | |
|
| | | tagObj = __RefreshDropOwner(curNPC, tick)
|
| | | #默认攻击归属者
|
| | | tagObj = npcControl.RefreshDropOwner(tick)
|
| | |
|
| | | if not curNPC.GetIsNeedProcess() or not tagObj:
|
| | | # 先回血,等回满再做其他事情
|
| | |
| | | __NPCFight(curNPC, tagObj, tick)
|
| | |
|
| | | npcControl.DoHPPerLogic(ChConfig.Def_NPCHurtTypeAll, 0)
|
| | | return
|
| | |
|
| | | def __RefreshDropOwner(curNPC, tick, refreshInterval=3000, isDead=False):
|
| | | ## 刷新boss掉落归属
|
| | | # @return: 可攻击的掉落归属目标玩家
|
| | | |
| | | npcControl = NPCCommon.NPCControl(curNPC)
|
| | | tagObj = None # 即将攻击的目标, 归属最大伤血取最大伤血玩家或队伍队员,其他取最大仇恨
|
| | | ownerType, ownerID = 0, 0
|
| | | dropOwnerType = NPCCommon.GetDropOwnerType(curNPC)
|
| | | if isDead:
|
| | | GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" |
| | | % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
|
| | | if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
|
| | | maxHurtObj = npcControl.RefreshHurtList(tick, refreshInterval)
|
| | | if maxHurtObj:
|
| | | ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()
|
| | | if ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | tagObj = __GetMaxHurtTeamPlayer(curNPC, npcControl, ownerID, isDead)
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | |
| | | elif dropOwnerType == ChConfig.DropOwnerType_Family:
|
| | | ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(npcControl, curNPC, tick, refreshInterval)
|
| | | if ownerInfo:
|
| | | tagObj, ownerFamilyID = ownerInfo
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID()))
|
| | | |
| | | # 没有攻击目标,则刷新仇恨,支持主动怪
|
| | | if not tagObj:
|
| | | angryObjType, maxAngryObj = None, None
|
| | | npcControl.RefreshAngryList(tick, refreshInterval, isUpdAngry=True)
|
| | | maxAngry = npcControl.GetMaxAngryTag()
|
| | | if maxAngry:
|
| | | angryID = maxAngry.GetObjID()
|
| | | angryObjType = maxAngry.GetObjType()
|
| | | #GameWorld.DebugLog("最大仇恨目标: ID=%s, Type=%s" % (angryID, angryObjType))
|
| | | maxAngryObj = GameWorld.GetObj(angryID, angryObjType)
|
| | | |
| | | tagObj = maxAngryObj
|
| | | if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType:
|
| | | teamID = maxAngryObj.GetTeamID()
|
| | | if teamID:
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, teamID
|
| | | else:
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID))
|
| | | |
| | | __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType, ownerID, isDead)
|
| | | return tagObj
|
| | |
|
| | | def __GetMaxHurtTeamPlayer(curNPC, npcControl, teamID, isDead):
|
| | | ## 获取最大伤血队伍中攻击的目标队员
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
|
| | | if curTeam:
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | if isDead:
|
| | | GameWorld.Log("队伍成员数: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount()))
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员为空!" % i)
|
| | | continue
|
| | | if curTeamPlayer.GetHP() <= 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员血量为0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
|
| | | continue
|
| | | if not curTeamPlayer.GetVisible():
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员不可见!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
|
| | | continue
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员坐标(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID()))
|
| | | if npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | return curTeamPlayer
|
| | | else:
|
| | | GameWorld.ErrLog("找不到该队伍: teamID=%s" % teamID)
|
| | | return
|
| | |
|
| | | def __RefreshBossDropOwnerObjBuff(curNPC, npcControl, tick, ownerType=0, ownerID=0, isDead=False):
|
| | | npcID = curNPC.GetNPCID()
|
| | | dropOwnerType = NPCCommon.GetDropOwnerType(curNPC)
|
| | | if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family]:
|
| | | #GameWorld.DebugLog("不需要展示掉落归属的NPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))
|
| | | return
|
| | | |
| | | lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
|
| | | lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
|
| | | |
| | | key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
|
| | | if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID):
|
| | | GameWorld.Log("归属变更, 清除旧归属! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s" |
| | | % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID))
|
| | | __DelBossDropOwnerBuff(curNPC, lastDropOwnerType, lastDropOwnerID, tick)
|
| | | |
| | | killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0
|
| | | |
| | | # 更新归属
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID)
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType)
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))
|
| | | |
| | | # 刷新归属
|
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
|
| | | killerDict[playerID] = curPlayer
|
| | | __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC)
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | |
| | | # 因为有击杀次数限制,所以不是所有的队员都可以获得归属,所以这里设置为特殊指定玩家掉落
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0
|
| | | if isDead:
|
| | | GameWorld.Log("队伍成员数: %s" % (curTeam.GetMemberCount()))
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员不存在!" % (i))
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \
|
| | | and npcControl.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
|
| | | and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():
|
| | | __AddBossDropOwnerPlayerBuff(curTeamPlayer, tick, curNPC)
|
| | | killerDict[curTeamPlayer.GetPlayerID()] = curTeamPlayer
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员有归属权! memPlayerID=%s,背包剩余空格=%s" |
| | | % (i, curTeamPlayer.GetPlayerID(), ItemCommon.GetItemPackSpace(curTeamPlayer, IPY_GameWorld.rptItem)))
|
| | | |
| | | # 不同线、或者距离超出boss范围的队员不加归属buff
|
| | | else:
|
| | | isOk = BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | if isOk:
|
| | | GameWorld.DebugLog("删除归属队员buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID()))
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员无归属权! memPlayerID=%s,copyMapID=%s,pos(%s,%s),CheckKillNPCByCnt=%s" |
| | | % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(), |
| | | curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), |
| | | AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False)))
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | |
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(copyPlayerMgr.GetPlayerCount()):
|
| | | player = copyPlayerMgr.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | continue
|
| | | |
| | | # 归属仙盟 且 在boss区域内
|
| | | if player.GetFamilyID() == ownerID and npcControl.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint) and player.GetVisible():
|
| | | __AddBossDropOwnerPlayerBuff(player, tick, curNPC)
|
| | | |
| | | else:
|
| | | isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | if isOk:
|
| | | GameWorld.DebugLog("删除非归属仙盟成员buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID()))
|
| | | |
| | | if isDead:
|
| | | #key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
|
| | | teamID = curTeam.GetTeamID() if curTeam else 0
|
| | | if killerDict:
|
| | | PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID
|
| | | |
| | | GameWorld.Log("Boss被击杀: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s" |
| | | % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID))
|
| | | return
|
| | |
|
| | | def __AddBossDropOwnerPlayerBuff(curPlayer, tick, curNPC):
|
| | | findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]
|
| | | if not findBuff:
|
| | | SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | GameWorld.DebugLog("添加归属buff: playerID=%s" % curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def __DelBossDropOwnerBuff(curNPC, ownerType, ownerID, tick):
|
| | | |
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if not curPlayer:
|
| | | return
|
| | | GameWorld.DebugLog("删除归属玩家buff: playerID=%s" % (ownerID))
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | GameWorld.DebugLog("删除归属队伍buff: teamID=%s" % (ownerID))
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | continue
|
| | | BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | return
|
| | |
|
| | | def __DelayBossDropOwnerBuff(curNPC):
|
| | | ''' 延迟boss掉落归属buff消失时间 '''
|
| | | |
| | | ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
|
| | | ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
|
| | | |
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if not curPlayer:
|
| | | return
|
| | | __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC)
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | continue
|
| | | __SetBossDropOwnerBuffDisappearTime(curTeamPlayer, curNPC)
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(copyPlayerMgr.GetPlayerCount()):
|
| | | player = copyPlayerMgr.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | continue
|
| | | __SetBossDropOwnerBuffDisappearTime(player, curNPC)
|
| | | |
| | | return
|
| | |
|
| | | def __SetBossDropOwnerBuffDisappearTime(curPlayer, curNPC):
|
| | | |
| | | findSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_DropOwnerBuff)
|
| | | if not findSkill:
|
| | | return
|
| | | |
| | | buffType = SkillCommon.GetBuffType(findSkill)
|
| | | buffTuple = SkillCommon.GetBuffManagerByBuffType(curPlayer, buffType)
|
| | | if buffTuple == ():
|
| | | return
|
| | | |
| | | RemainTime = 10000 # 延迟10秒消失
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | |
| | | buffStateManager = buffTuple[0]
|
| | | for index in xrange(buffStateManager.GetBuffCount()):
|
| | | curBuff = buffStateManager.GetBuff(index)
|
| | | buffSkill = curBuff.GetSkill()
|
| | | |
| | | if buffSkill.GetSkillTypeID() != ChConfig.Def_SkillID_DropOwnerBuff:
|
| | | continue
|
| | | |
| | | if curNPC.GetID() != curBuff.GetOwnerID():
|
| | | #GameWorld.DebugLog("非buff归属着,不设置消失时间!", curPlayer.GetPlayerID())
|
| | | break
|
| | | |
| | | curBuff.SetCalcStartTick(tick) |
| | | curBuff.SetRemainTime(RemainTime)
|
| | | |
| | | # 通知buff刷新
|
| | | buffStateManager.Sync_RefreshBuff(index, curBuff.GetRemainTime())
|
| | | #GameWorld.DebugLog("掉落归属buff消失时间: RemainTime=%s" % (RemainTime), curPlayer.GetPlayerID())
|
| | | break
|
| | | return
|
| | |
|
| | | ## 每次被攻击处理结果
|
| | |
| | | dropOwnerType = NPCCommon.GetDropOwnerType(curNPC)
|
| | | if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt]:
|
| | | return True
|
| | | tagObj = __RefreshDropOwner(curNPC, tick, 0)
|
| | | npcControl = NPCCommon.NPCControl(curNPC)
|
| | | tagObj = npcControl.RefreshDropOwner(tick, 0)
|
| | | if not atkObj or not tagObj:
|
| | | GameObj.SetHP(curNPC, 1)
|
| | | GameWorld.ErrLog("Boss当前状态下不可以死亡!npcID=%s" % curNPC.GetNPCID())
|
| | |
| | | PlayerState.SetBossStateTick(curPlayer, tick)
|
| | |
|
| | | #被击杀时强制刷新归属
|
| | | __RefreshDropOwner(curNPC, tick, 0, True)
|
| | | npcControl = NPCCommon.NPCControl(curNPC)
|
| | | npcControl.RefreshDropOwner(tick, 0, True)
|
| | | return
|
| | |
|
| | | ## NPC死亡处理
|
| | |
| | | return
|
| | |
|
| | | def OnNPCSetDead(curNPC):
|
| | | __DelayBossDropOwnerBuff(curNPC)
|
| | | npcControl = NPCCommon.NPCControl(curNPC)
|
| | | npcControl.DelayDropOwnerBuffDisappearTime()
|
| | | return
|
| | |
|
| | | ## npc攻击逻辑
|
| | |
| | | return
|
| | | return curItem
|
| | |
|
| | | ##----------------------------------------- 归属 -----------------------------------------------
|
| | | |
| | | def RefreshDropOwner(self, tick, refreshInterval=3000, isDead=False):
|
| | | ## 刷新boss掉落归属
|
| | | # @return: 可攻击的掉落归属目标玩家
|
| | | |
| | | curNPC = self.__Instance
|
| | | tagObj = None # 即将攻击的目标, 归属最大伤血取最大伤血玩家或队伍队员,其他取最大仇恨
|
| | | ownerType, ownerID = 0, 0
|
| | | dropOwnerType = GetDropOwnerType(curNPC)
|
| | | if isDead:
|
| | | GameWorld.Log("Boss死亡: lineID=%s,objID=%s,npcID=%s,dropOwnerType=%s" |
| | | % (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), curNPC.GetNPCID(), dropOwnerType))
|
| | | if dropOwnerType == ChConfig.DropOwnerType_MaxHurt:
|
| | | maxHurtObj = self.RefreshHurtList(tick, refreshInterval)
|
| | | if maxHurtObj:
|
| | | ownerType, ownerID = maxHurtObj.GetValueType(), maxHurtObj.GetValueID()
|
| | | if ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | tagObj = self.__GetMaxHurtTeamPlayer(ownerID, isDead)
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | tagObj = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | |
| | | elif dropOwnerType == ChConfig.DropOwnerType_Family:
|
| | | ownerInfo = FamilyRobBoss.RefreshFamilyOwnerNPCHurt(curNPC, tick, refreshInterval)
|
| | | if ownerInfo:
|
| | | tagObj, ownerFamilyID = ownerInfo
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypeFamily, ownerFamilyID
|
| | | |
| | | elif dropOwnerType == ChConfig.DropOwnerType_Contend:
|
| | | tagObj = self.__RefreshContendOwner()
|
| | | if tagObj:
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, tagObj.GetPlayerID()
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("ownerType=%s, ownerID=%s, tagObjID=%s" % (ownerType, ownerID, 0 if not tagObj else tagObj.GetPlayerID()))
|
| | | |
| | | # 没有攻击目标,则刷新仇恨,支持主动怪
|
| | | if not tagObj:
|
| | | angryObjType, maxAngryObj = None, None
|
| | | self.RefreshAngryList(tick, refreshInterval, isUpdAngry=True)
|
| | | maxAngry = self.GetMaxAngryTag()
|
| | | if maxAngry:
|
| | | angryID = maxAngry.GetObjID()
|
| | | angryObjType = maxAngry.GetObjType()
|
| | | #GameWorld.DebugLog("最大仇恨目标: ID=%s, Type=%s" % (angryID, angryObjType))
|
| | | maxAngryObj = GameWorld.GetObj(angryID, angryObjType)
|
| | | |
| | | tagObj = maxAngryObj
|
| | | if angryObjType == IPY_GameWorld.gotPlayer and maxAngryObj and not ownerType:
|
| | | if dropOwnerType == ChConfig.DropOwnerType_Contend:
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()
|
| | | elif maxAngryObj.GetTeamID():
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypeTeam, maxAngryObj.GetTeamID()
|
| | | else:
|
| | | ownerType, ownerID = ChConfig.Def_NPCHurtTypePlayer, maxAngryObj.GetPlayerID()
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("angryObj, ownerType=%s, ownerID=%s" % (ownerType, ownerID))
|
| | | |
| | | self.UpdateDropOwner(tick, ownerType, ownerID, isDead)
|
| | | return tagObj
|
| | | |
| | | def __RefreshContendOwner(self):
|
| | | ## 刷新boss争夺归属者,归属移除时不做刷新新归属,默认由后面的仇恨刷新
|
| | | |
| | | curNPC = self.__Instance
|
| | | ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
|
| | | ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
|
| | | if not ownerID or ownerType != ChConfig.Def_NPCHurtTypePlayer:
|
| | | return
|
| | | |
| | | owner = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if not owner:
|
| | | return
|
| | | |
| | | if not owner.GetVisible():
|
| | | GameWorld.DebugLog("竞争归属玩家不可见,移除归属!playerID=%s" % ownerID)
|
| | | return
|
| | | |
| | | if owner.GetHP() <= 0 or owner.GetPlayerAction() == IPY_GameWorld.paDie:
|
| | | GameWorld.DebugLog("竞争归属玩家死亡,移除归属!playerID=%s" % ownerID)
|
| | | return
|
| | | |
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | if not self.GetIsInRefreshPoint(owner.GetPosX(), owner.GetPosY(), refreshPoint):
|
| | | GameWorld.DebugLog("竞争归属玩家不在boss范围里,移除归属!playerID=%s" % ownerID)
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("竞争归属玩家归属正常!playerID=%s" % ownerID)
|
| | | return owner
|
| | |
|
| | | def __GetMaxHurtTeamPlayer(self, teamID, isDead):
|
| | | ## 获取最大伤血队伍中攻击的目标队员
|
| | | |
| | | curNPC = self.__Instance
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(teamID)
|
| | | if curTeam:
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | if isDead:
|
| | | GameWorld.Log("队伍成员数: teamID=%s,memberCount=%s" % (teamID, curTeam.GetMemberCount()))
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员为空!" % i)
|
| | | continue
|
| | | if curTeamPlayer.GetHP() <= 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员血量为0!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
|
| | | continue
|
| | | if not curTeamPlayer.GetVisible():
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员不可见!, memPlayerID=%s" % (i, curTeamPlayer.GetPlayerID()))
|
| | | continue
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 队员坐标(%s, %s)! memPlayerID=%s" % (i, curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), curTeamPlayer.GetPlayerID()))
|
| | | if self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint):
|
| | | return curTeamPlayer
|
| | | else:
|
| | | GameWorld.ErrLog("找不到该队伍: teamID=%s" % teamID)
|
| | | return
|
| | | |
| | | def UpdateDropOwner(self, tick, ownerType=0, ownerID=0, isDead=False):
|
| | | |
| | | curNPC = self.__Instance
|
| | | npcID = curNPC.GetNPCID()
|
| | | dropOwnerType = GetDropOwnerType(curNPC)
|
| | | if dropOwnerType not in [ChConfig.DropOwnerType_MaxHurt, ChConfig.DropOwnerType_MaxAngry, ChConfig.DropOwnerType_Family, ChConfig.DropOwnerType_Contend]:
|
| | | #GameWorld.DebugLog("不需要展示掉落归属的NPC! npcID=%s,dropOwnerType=%s" % (npcID, dropOwnerType))
|
| | | return
|
| | | |
| | | lastDropOwnerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
|
| | | lastDropOwnerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
|
| | | |
| | | key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
|
| | | if lastDropOwnerID and (lastDropOwnerType != ownerType or lastDropOwnerID != ownerID):
|
| | | GameWorld.Log("归属变更, 清除旧归属! key=%s,ownerType=%s,ownerID=%s,lastDropOwnerType=%s,lastDropOwnerID=%s" |
| | | % (key, ownerType, ownerID, lastDropOwnerType, lastDropOwnerID))
|
| | | self.__DelDropOwnerBuff(dropOwnerType, lastDropOwnerType, lastDropOwnerID, tick)
|
| | | |
| | | killerDict, curTeam, hurtType, hurtID = {}, None, 0, 0
|
| | | |
| | | # 更新归属
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerID, ownerID)
|
| | | curNPC.SetDict(ChConfig.Def_NPC_Dict_LastDropOwnerType, ownerType)
|
| | | |
| | | if isDead:
|
| | | GameWorld.Log("Boss归属: key=%s,ownerType=%s,ownerID=%s" % (key, ownerType, ownerID))
|
| | | |
| | | # 刷新归属
|
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if curPlayer:
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypePlayer, playerID
|
| | | killerDict[playerID] = curPlayer
|
| | | self.__AddDropOwnerPlayerBuff(curPlayer, tick)
|
| | | if dropOwnerType == ChConfig.DropOwnerType_Contend:
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, curNPC.GetID())
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | |
| | | # 因为有击杀次数限制,所以不是所有的队员都可以获得归属,所以这里设置为特殊指定玩家掉落
|
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypeSpecial, 0
|
| | | if isDead:
|
| | | GameWorld.Log("队伍成员数: %s" % (curTeam.GetMemberCount()))
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员不存在!" % (i))
|
| | | continue
|
| | | |
| | | if curTeamPlayer.GetCopyMapID() == GameWorld.GetGameWorld().GetCopyMapID() \
|
| | | and self.GetIsInRefreshPoint(curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), refreshPoint) \
|
| | | and AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False) and curTeamPlayer.GetVisible():
|
| | | self.__AddDropOwnerPlayerBuff(curTeamPlayer, tick)
|
| | | killerDict[curTeamPlayer.GetPlayerID()] = curTeamPlayer
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员有归属权! memPlayerID=%s,背包剩余空格=%s" |
| | | % (i, curTeamPlayer.GetPlayerID(), ItemCommon.GetItemPackSpace(curTeamPlayer, IPY_GameWorld.rptItem)))
|
| | | |
| | | # 不同线、或者距离超出boss范围的队员不加归属buff
|
| | | else:
|
| | | isOk = BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | if isOk:
|
| | | GameWorld.DebugLog("删除归属队员buff: teamID=%s,playerID=%s" % (ownerID, curTeamPlayer.GetPlayerID()))
|
| | | if isDead:
|
| | | GameWorld.Log(" i=%s, 成员无归属权! memPlayerID=%s,copyMapID=%s,pos(%s,%s),CheckKillNPCByCnt=%s" |
| | | % (i, curTeamPlayer.GetPlayerID(), curTeamPlayer.GetCopyMapID(), |
| | | curTeamPlayer.GetPosX(), curTeamPlayer.GetPosY(), |
| | | AttackCommon.CheckKillNPCByCnt(curTeamPlayer, curNPC, False)))
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | |
| | | hurtType, hurtID = ChConfig.Def_NPCHurtTypeFamily, ownerID
|
| | | refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
|
| | | copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(copyPlayerMgr.GetPlayerCount()):
|
| | | player = copyPlayerMgr.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | continue
|
| | | |
| | | # 归属仙盟 且 在boss区域内
|
| | | if player.GetFamilyID() == ownerID and self.GetIsInRefreshPoint(player.GetPosX(), player.GetPosY(), refreshPoint) and player.GetVisible():
|
| | | self.__AddDropOwnerPlayerBuff(player, tick)
|
| | | |
| | | else:
|
| | | isOk = BuffSkill.DelBuffBySkillID(player, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | if isOk:
|
| | | GameWorld.DebugLog("删除非归属仙盟成员buff: teamID=%s,playerID=%s" % (ownerID, player.GetPlayerID()))
|
| | | |
| | | if isDead:
|
| | | #key = (GameWorld.GetGameWorld().GetLineID(), curNPC.GetID(), npcID)
|
| | | teamID = curTeam.GetTeamID() if curTeam else 0
|
| | | if killerDict:
|
| | | PyGameData.g_npcKillerInfo[key] = killerDict, curTeam, hurtType, hurtID
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | PyGameData.g_npcKillerInfo[key] = {}, None, hurtType, hurtID
|
| | | |
| | | GameWorld.Log("Boss被击杀: npcID=%s,key=%s,playerIDList=%s,teamID=%s,hurtType=%s,hurtID=%s" |
| | | % (npcID, key, killerDict.keys(), teamID, hurtType, hurtID))
|
| | | return
|
| | |
|
| | | def __AddDropOwnerPlayerBuff(self, curPlayer, tick):
|
| | | curNPC = self.__Instance
|
| | | findBuff = SkillCommon.FindBuffByID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff)[0]
|
| | | if not findBuff:
|
| | | SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | GameWorld.DebugLog("添加归属buff: playerID=%s" % curPlayer.GetPlayerID())
|
| | | return
|
| | | |
| | | def __DelDropOwnerBuff(self, dropOwnerType, ownerType, ownerID, tick):
|
| | | |
| | | curNPC = self.__Instance
|
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if not curPlayer:
|
| | | return
|
| | | GameWorld.DebugLog("删除归属玩家buff: playerID=%s" % (ownerID))
|
| | | BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | if dropOwnerType == ChConfig.DropOwnerType_Contend:
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_ContendNPCObjID, 0)
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | GameWorld.DebugLog("删除归属队伍buff: teamID=%s" % (ownerID))
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | continue
|
| | | BuffSkill.DelBuffBySkillID(curTeamPlayer, ChConfig.Def_SkillID_DropOwnerBuff, tick, buffOwner=curNPC)
|
| | | return
|
| | | |
| | | def DelayDropOwnerBuffDisappearTime(self):
|
| | | ''' 延迟掉落归属buff消失时间 '''
|
| | | |
| | | curNPC = self.__Instance
|
| | | ownerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerID)
|
| | | ownerType = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_LastDropOwnerType)
|
| | | |
| | | if ownerType == ChConfig.Def_NPCHurtTypePlayer:
|
| | | curPlayer = GameWorld.GetObj(ownerID, IPY_GameWorld.gotPlayer)
|
| | | if not curPlayer:
|
| | | return
|
| | | self.__SetDropOwnerBuffDisappearTime(curPlayer)
|
| | | |
| | | elif ownerType == ChConfig.Def_NPCHurtTypeTeam:
|
| | | curTeam = GameWorld.GetTeamManager().FindTeam(ownerID)
|
| | | if not curTeam:
|
| | | return
|
| | | for i in xrange(curTeam.GetMemberCount()):
|
| | | curTeamPlayer = curTeam.GetMember(i)
|
| | | if curTeamPlayer == None or curTeamPlayer.GetPlayerID() == 0:
|
| | | continue
|
| | | self.__SetDropOwnerBuffDisappearTime(curTeamPlayer)
|
| | | elif ownerType == ChConfig.Def_NPCHurtTypeFamily:
|
| | | copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
|
| | | for index in xrange(copyPlayerMgr.GetPlayerCount()):
|
| | | player = copyPlayerMgr.GetPlayerByIndex(index)
|
| | | if not player:
|
| | | continue
|
| | | self.__SetDropOwnerBuffDisappearTime(player)
|
| | | |
| | | return
|
| | | |
| | | def __SetDropOwnerBuffDisappearTime(self, curPlayer):
|
| | | ''' 设置掉落归属buff消失时间 '''
|
| | | |
| | | curNPC = self.__Instance
|
| | | findSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_DropOwnerBuff)
|
| | | if not findSkill:
|
| | | return
|
| | | |
| | | buffType = SkillCommon.GetBuffType(findSkill)
|
| | | buffTuple = SkillCommon.GetBuffManagerByBuffType(curPlayer, buffType)
|
| | | if buffTuple == ():
|
| | | return
|
| | | |
| | | RemainTime = 10000 # 延迟10秒消失
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | |
| | | buffStateManager = buffTuple[0]
|
| | | for index in xrange(buffStateManager.GetBuffCount()):
|
| | | curBuff = buffStateManager.GetBuff(index)
|
| | | buffSkill = curBuff.GetSkill()
|
| | | |
| | | if buffSkill.GetSkillTypeID() != ChConfig.Def_SkillID_DropOwnerBuff:
|
| | | continue
|
| | | |
| | | if curNPC.GetID() != curBuff.GetOwnerID():
|
| | | #GameWorld.DebugLog("非buff归属着,不设置消失时间!", curPlayer.GetPlayerID())
|
| | | break
|
| | | |
| | | curBuff.SetCalcStartTick(tick) |
| | | curBuff.SetRemainTime(RemainTime)
|
| | | |
| | | # 通知buff刷新
|
| | | buffStateManager.Sync_RefreshBuff(index, curBuff.GetRemainTime())
|
| | | #GameWorld.DebugLog("掉落归属buff消失时间: RemainTime=%s" % (RemainTime), curPlayer.GetPlayerID())
|
| | | break
|
| | | return
|
| | | ##--------------------------------------------- -----------------------------------------------
|
| | | |
| | | def OnPlayerKillNPCPlayer(curPlayer, defender, tick):
|
| | | ## 玩家击杀了NPC相关的玩家
|
| | | contendNPCObjID = defender.GetDictByKey(ChConfig.Def_PlayerKey_ContendNPCObjID)
|
| | | if contendNPCObjID:
|
| | | curNPC = GameWorld.FindNPCByID(contendNPCObjID)
|
| | | if not curNPC:
|
| | | return
|
| | | dropOwnerType = GetDropOwnerType(curNPC)
|
| | | if dropOwnerType != ChConfig.DropOwnerType_Contend:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("玩家击杀竞争归属者! defPlayerID=%s,contendNPCObjID=%s,npcID=%s" |
| | | % (defender.GetPlayerID(), contendNPCObjID, curNPC.GetNPCID()), playerID)
|
| | | npcControl = NPCControl(curNPC)
|
| | | npcControl.UpdateDropOwner(tick, ChConfig.Def_NPCHurtTypePlayer, playerID, False)
|
| | | |
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | def SendVirtualItemDrop(player, itemID, posX, posY, userDataStr):
|
| | | #通知客户端假物品掉落
|
| | |
| | | import ReadChConfig
|
| | | import GameLogic_SealDemon
|
| | | import GameLogic_ZhuXianBoss
|
| | | import GameLogic_CrossDemonKing
|
| | | import PlayerControl
|
| | | import IPY_GameWorld
|
| | | import IpyGameDataPY
|
| | |
| | |
|
| | | refreshMark = npcRefresh.GetRefreshMark()
|
| | | lineID = GameWorld.GetGameWorld().GetLineID()
|
| | | bossIpyData = IpyGameDataPY.GetIpyGameDataByCondition('BOSSInfo', {'RefreshMark':refreshMark, 'MapID':mapID}, isLogNone=False)
|
| | | if not bossIpyData:
|
| | | return
|
| | | |
| | | stoneNPCID = bossIpyData.GetStoneNPCID()
|
| | | bossID = bossIpyData.GetNPCID()
|
| | | if not bossID and not stoneNPCID:
|
| | | return
|
| | | |
| | | if mapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | return
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
|
| | | realMapID = GameWorld.GetGameWorld().GetRealMapID()
|
| | | copyMapID = GameWorld.GetGameWorld().GetCopyMapID()
|
| | | zoneIpyData = IpyGameDataPY.GetIpyGameDataNotLog(tableName, realMapID, mapID, copyMapID)
|
| | | if not zoneIpyData:
|
| | | |
| | | if mapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID(lineID)
|
| | | stoneNPCID = 0
|
| | | zoneID = GameLogic_CrossDemonKing.GetCurFBLineZoneID()
|
| | | |
| | | else:
|
| | | bossIpyData = IpyGameDataPY.GetIpyGameDataByCondition('BOSSInfo', {'RefreshMark':refreshMark, 'MapID':mapID}, isLogNone=False)
|
| | | if not bossIpyData:
|
| | | return
|
| | | |
| | | stoneNPCID = bossIpyData.GetStoneNPCID()
|
| | | bossID = bossIpyData.GetNPCID()
|
| | |
|
| | | if mapID not in ChConfig.Def_CrossZoneMapTableName:
|
| | | return
|
| | | tableName = ChConfig.Def_CrossZoneMapTableName[mapID]
|
| | | zoneIpyData = IpyGameDataPY.GetIpyGameDataNotLog(tableName, realMapID, mapID, copyMapID)
|
| | | if not zoneIpyData:
|
| | | return
|
| | | zoneID = zoneIpyData.GetZoneID()
|
| | | |
| | | if not zoneID:
|
| | | return
|
| | | zoneID = zoneIpyData.GetZoneID()
|
| | | if not bossID and not stoneNPCID:
|
| | | return
|
| | |
|
| | | gameFB = GameWorld.GetGameFB()
|
| | | bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID)
|
| | |
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD DataMapID;
|
| | | # WORD LineID;
|
| | | #};
|
| | | def OnEnterCrossServer(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | PlayerControl.PlayerEnterCrossServer(curPlayer, clientData.DataMapID)
|
| | | PlayerControl.PlayerEnterCrossServer(curPlayer, clientData.DataMapID, clientData.LineID)
|
| | | return
|
| | |
|
| | | #===============================================================================
|
| | |
| | | import PlayerMagicWeapon
|
| | | import GameLogic_SealDemon
|
| | | import GameLogic_ZhuXianBoss
|
| | | import GameLogic_CrossDemonKing
|
| | | import PlayerTJG
|
| | | import PlayerVip
|
| | | import PlayerRefineStove
|
| | |
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | def PlayerEnterCrossServer(curPlayer, mapID):
|
| | | def PlayerEnterCrossServer(curPlayer, mapID, lineID):
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.Log("玩家请求进入跨服地图: mapID=%s" % (mapID), playerID)
|
| | | GameWorld.Log("玩家请求进入跨服地图: mapID=%s,lineID=%s" % (mapID, lineID), playerID)
|
| | | if mapID not in ChConfig.Def_CrossMapIDList:
|
| | | return
|
| | | |
| | | if GameWorld.IsCrossServer():
|
| | | GameWorld.DebugLog("跨服服务器不允许该操作!")
|
| | | return
|
| | |
| | | NotifyCode(curPlayer, "SingleEnterPK", [mapID])
|
| | | return
|
| | |
|
| | | # 需要动态分布线路的地图,发送到跨服服务器进行分配
|
| | | if mapID in ChConfig.Def_CrossDynamicLineMap:
|
| | | extendInfo = {}
|
| | | if mapID == ChConfig.Def_FBMapID_CrossDemonKing:
|
| | | bossID = GameLogic_CrossDemonKing.GetCurFBLineBOSSID(lineID)
|
| | | if not bossID:
|
| | | return
|
| | | extendInfo["BossID"] = bossID
|
| | | |
| | | msgDict = {"PlayerID":curPlayer.GetPlayerID(), "DataMapID":mapID, "FuncLineID":lineID}
|
| | | if extendInfo:
|
| | | msgDict.update(extendInfo)
|
| | | GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_EnterFB, msgDict)
|
| | | return
|
| | | |
| | | GY_Query_CrossRealmReg.RegisterEnterCrossServer(curPlayer, mapID)
|
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.RemoteQuery.GY_Query_OpenFB
|
| | | #
|
| | | # @todo:开启副本线路
|
| | | # @author hxp
|
| | | # @date 2019-04-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 开启副本线路
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2019-04-11 14:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import IPY_GameWorld
|
| | |
|
| | |
|
| | | #逻辑实现
|
| | | ## 请求逻辑
|
| | | # @param query_Type 请求类型
|
| | | # @param query_ID 请求的玩家ID
|
| | | # @param paramList 发包命令
|
| | | # @param tick 当前时间
|
| | | # @return "True" or "False" or ""
|
| | | # @remarks 函数详细说明.
|
| | | def DoLogic(query_Type, query_ID, paramList, tick):
|
| | | copyMapID, propertyID = paramList
|
| | | |
| | | gameWorldManager = GameWorld.GetGameWorld()
|
| | | maxCopyCount = gameWorldManager.GetGameWorldCount()
|
| | | if copyMapID >= maxCopyCount:
|
| | | GameWorld.ErrLog("GY_Query_OpenFB 虚拟分线不存在! copyMapID=%s, propertyID=%s, maxCopyCount=%s" |
| | | % (copyMapID, propertyID, maxCopyCount))
|
| | | return
|
| | | |
| | | tagGameWorld = IPY_GameWorld.IPY_GameWorld(copyMapID)
|
| | | if tagGameWorld.GetOpenState() != IPY_GameWorld.fbosClosed:
|
| | | GameWorld.ErrLog("GY_Query_OpenFB 虚拟分线已经是开启状态! copyMapID=%s, propertyID=%s, GetPropertyID=%s" |
| | | % (copyMapID, propertyID, tagGameWorld.GetPropertyID()))
|
| | | return
|
| | | |
| | | if tagGameWorld.GetFBFirstOpen():
|
| | | GameWorld.ErrLog("GY_Query_OpenFB 虚拟分线已经在开启中! copyMapID=%s, propertyID=%s, GetPropertyID=%s" |
| | | % (copyMapID, propertyID, tagGameWorld.GetPropertyID()))
|
| | | return
|
| | | |
| | | GameWorld.Log("GY_Query_OpenFB copyMapID=%s, propertyID=%s" % (copyMapID, propertyID))
|
| | | tagGameWorld.SetFBFirstOpen(1) # 开启副本
|
| | | tagGameWorld.SetPropertyID(propertyID)
|
| | | return ''
|
| | |
|
| | | |
| | | #---------------------------------------------------------------------
|
| | | #执行结果
|
| | | ## 执行结果
|
| | | # @param curPlayer 发出请求的玩家
|
| | | # @param callFunName 功能名称
|
| | | # @param funResult 查询的结果
|
| | | # @param tick 当前时间
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def DoResult(curPlayer, callFunName, funResult, tick):
|
| | | return
|
| | |
|
| | |
|
| | |
| | | CrossServerMsg_RebornRet = "RebornRet" # 复活结果
|
| | | CrossServerMsg_NPCInfoRet = "NPCInfoRet" # 跨服地图NPC信息
|
| | | CrossServerMsg_CollectNPCOK = "CollectNPCOK" # 采集NPC完成
|
| | | CrossServerMsg_EnterFBRet = "EnterFBRet" # 请求进入跨服副本返回信息
|
| | |
|
| | | # 子服发送跨服信息定义
|
| | | ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功
|
| | |
| | | ClientServerMsg_QueryNPCInfo = "QueryNPCInfo" # 查询跨服地图NPC信息
|
| | | ClientServerMsg_SetPlayerAttrValue = "SetPlayerAttrValue" # 玩家属性数值更新
|
| | | ClientServerMsg_CollectNPC = "CollectNPC" # 采集NPC
|
| | | ClientServerMsg_EnterFB = "EnterFB" # 请求进入跨服副本
|
| | |
|
| | | #跨服广播类型定义
|
| | | CrossNotify_World = "World"
|