From ad158391ff62df48198a5411e5950e578dc3c43c Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 11 四月 2019 14:42:21 +0800 Subject: [PATCH] 6459 【后端】【2.0】缥缈仙域开发单(可进入跨服妖王地图支持分区,增加竞争归属逻辑) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py | 6 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py | 2 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 184 +++++++ ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py | 15 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 8 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py | 417 ++++++++++++++++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_OpenFB.py | 69 ++ ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/EnterFB.py | 5 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py | 41 + ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py | 8 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py | 297 ----------- ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py | 16 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py | 2 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py | 7 ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py | 5 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py | 59 + ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py | 10 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 3 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 348 +++++++++++++ ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py | 2 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py | 12 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 23 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 13 23 files changed, 1,218 insertions(+), 334 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py index a4e117b..6eba4d0 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py @@ -677,16 +677,24 @@ 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 diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py index ac28fe5..c1f129a 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py @@ -15508,6 +15508,7 @@ ("Cmd", c_ubyte), ("SubCmd", c_ubyte), ("DataMapID", c_int), + ("LineID", c_ushort), ] def __init__(self): @@ -15525,6 +15526,7 @@ self.Cmd = 0xC1 self.SubCmd = 0x05 self.DataMapID = 0 + self.LineID = 0 return def GetLength(self): @@ -15537,12 +15539,14 @@ 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 diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py index 283cdf3..bdf7df7 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBoss.py @@ -55,14 +55,22 @@ ## 获取地图跨服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数据 @@ -234,18 +242,21 @@ 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) @@ -275,24 +286,38 @@ 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: diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py index 47cad59..1cfe194 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py @@ -26,6 +26,7 @@ import PlayerTalk import CrossBoss import ChConfig +import PlayerFB import GMShell import traceback @@ -89,6 +90,9 @@ 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) @@ -246,6 +250,9 @@ 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) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py index 5438e00..81b77ee 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py @@ -61,6 +61,22 @@ 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() diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py index dd9aa79..4b3114f 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py @@ -30,6 +30,12 @@ import PlayerTeam import GameWorld import ChConfig +import CrossRealmPlayer +import CrossRealmMsg +import ShareDefine +import CrossBoss + +import random #--------------------------------------------------------------------- #--------------------------------------------------------------------- @@ -70,6 +76,184 @@ 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: 请求回调名 diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py index 7672c0a..ffb1c07 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py @@ -512,6 +512,21 @@ 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) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py index bf021c6..45bed4c 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py @@ -100,3 +100,8 @@ g_crossSetPlayerAttr = {} # 跨服玩家更新玩家数据 {playerID:[[setType, setDict], ...], ...} +g_crossMapCopyMapCountDict = {} # 跨服地图动态分配虚拟线路条数信息 {mapID:copyMapCount, ...} +g_crossDynamicLineInfo = {} # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[mapID, copyMapID], ...}, ...} +g_crossDynamicLineOpeningInfo = {} # 跨服动态线路正在开启中的线路信息 {mapID:{copyMapID:{playerID:serverGroupID, ...}, ...}, ...} + + diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py index c2d09f5..063ab36 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py @@ -1194,6 +1194,7 @@ CrossServerMsg_RebornRet = "RebornRet" # 复活结果 CrossServerMsg_NPCInfoRet = "NPCInfoRet" # 跨服地图NPC信息 CrossServerMsg_CollectNPCOK = "CollectNPCOK" # 采集NPC完成 +CrossServerMsg_EnterFBRet = "EnterFBRet" # 请求进入跨服副本返回信息 # 子服发送跨服信息定义 ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功 @@ -1208,6 +1209,7 @@ ClientServerMsg_QueryNPCInfo = "QueryNPCInfo" # 查询跨服地图NPC信息 ClientServerMsg_SetPlayerAttrValue = "SetPlayerAttrValue" # 玩家属性数值更新 ClientServerMsg_CollectNPC = "CollectNPC" # 采集NPC +ClientServerMsg_EnterFB = "EnterFB" # 请求进入跨服副本 #跨服广播类型定义 CrossNotify_World = "World" diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py index 56f7b96..f637097 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py @@ -288,6 +288,8 @@ #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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py index 6352200..d4d68fa 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py @@ -1772,6 +1772,8 @@ Def_FBMapID_CrossRealmPK = 32010 #跨服蓬莱仙境 Def_FBMapID_CrossPenglai = 32020 +#跨服妖王 +Def_FBMapID_CrossDemonKing = 32030 #多仙盟Boss Def_FBMapID_AllFamilyBoss = 31260 #骑宠Boss @@ -1780,12 +1782,14 @@ 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] #副本关闭时未拾取的物品邮件发放给玩家 #这里只有需要的副本才配置,不做默认逻辑,防止某些副本实际不能给导致刷物品,如麒麟之府 @@ -1874,6 +1878,7 @@ '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],#诛仙塔 @@ -2094,7 +2099,8 @@ DropOwnerType_Faction, # 阵营 5 DropOwnerType_Special, # 特殊 6 DropOwnerType_Family, # 仙盟 7 -) = range(8) +DropOwnerType_Contend, # 争夺 8 第一个攻击的获得归属,击杀当前归属者的玩家成为新归属者 +) = range(9) #------------------------------------------------ #技能类型 @@ -3116,6 +3122,7 @@ 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" # 属性激活记录 - 强化星级 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py index ac28fe5..c1f129a 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py @@ -15508,6 +15508,7 @@ ("Cmd", c_ubyte), ("SubCmd", c_ubyte), ("DataMapID", c_int), + ("LineID", c_ushort), ] def __init__(self): @@ -15525,6 +15526,7 @@ self.Cmd = 0xC1 self.SubCmd = 0x05 self.DataMapID = 0 + self.LineID = 0 return def GetLength(self): @@ -15537,12 +15539,14 @@ 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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/EnterFB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/EnterFB.py index 511fd18..a228fff 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/EnterFB.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/EnterFB.py @@ -37,6 +37,9 @@ 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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py index 97aaa8b..a80245c 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py @@ -1229,7 +1229,11 @@ 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 #玩家 在副本中,并且副本不踢出玩家下线 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py new file mode 100644 index 0000000..f43e4a5 --- /dev/null +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossDemonKing.py @@ -0,0 +1,417 @@ +#!/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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py index 0b816e1..9143a93 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py @@ -75,6 +75,10 @@ #调用副本开启触发器 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 ## 副本关闭 @@ -167,6 +171,9 @@ #根据是否收缩型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 ##根据表中的收缩类型释放或者清空副本状态 @@ -588,6 +595,11 @@ 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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py index a928ed2..16c23cb 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AIType_186.py @@ -31,16 +31,10 @@ 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 @@ -81,7 +75,8 @@ AICommon.NormalNPCFast_Move(curNPC, tick) return - tagObj = __RefreshDropOwner(curNPC, tick) + #默认攻击归属者 + tagObj = npcControl.RefreshDropOwner(tick) if not curNPC.GetIsNeedProcess() or not tagObj: # 先回血,等回满再做其他事情 @@ -93,285 +88,6 @@ __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 ## 每次被攻击处理结果 @@ -390,7 +106,8 @@ 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()) @@ -403,7 +120,8 @@ PlayerState.SetBossStateTick(curPlayer, tick) #被击杀时强制刷新归属 - __RefreshDropOwner(curNPC, tick, 0, True) + npcControl = NPCCommon.NPCControl(curNPC) + npcControl.RefreshDropOwner(tick, 0, True) return ## NPC死亡处理 @@ -417,7 +135,8 @@ return def OnNPCSetDead(curNPC): - __DelayBossDropOwnerBuff(curNPC) + npcControl = NPCCommon.NPCControl(curNPC) + npcControl.DelayDropOwnerBuffDisappearTime() return ## npc攻击逻辑 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py index 787692c..fd34538 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py @@ -5086,6 +5086,354 @@ 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): #通知客户端假物品掉落 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py index 2493ede..cc68643 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py @@ -18,6 +18,7 @@ import ReadChConfig import GameLogic_SealDemon import GameLogic_ZhuXianBoss +import GameLogic_CrossDemonKing import PlayerControl import IPY_GameWorld import IpyGameDataPY @@ -481,24 +482,34 @@ 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) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py index 29529b2..03288e3 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py @@ -4512,10 +4512,11 @@ #{ # 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 #=============================================================================== diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py index faa901d..d122e9c 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py @@ -74,6 +74,7 @@ import PlayerMagicWeapon import GameLogic_SealDemon import GameLogic_ZhuXianBoss +import GameLogic_CrossDemonKing import PlayerTJG import PlayerVip import PlayerRefineStove @@ -1586,9 +1587,12 @@ #--------------------------------------------------------------------- -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 @@ -1613,6 +1617,21 @@ 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 diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_OpenFB.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_OpenFB.py new file mode 100644 index 0000000..85e2209 --- /dev/null +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_OpenFB.py @@ -0,0 +1,69 @@ +#!/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 + + diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py index c2d09f5..063ab36 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py @@ -1194,6 +1194,7 @@ CrossServerMsg_RebornRet = "RebornRet" # 复活结果 CrossServerMsg_NPCInfoRet = "NPCInfoRet" # 跨服地图NPC信息 CrossServerMsg_CollectNPCOK = "CollectNPCOK" # 采集NPC完成 +CrossServerMsg_EnterFBRet = "EnterFBRet" # 请求进入跨服副本返回信息 # 子服发送跨服信息定义 ClientServerMsg_ServerInitOK = "ServerInitOK" # 子服启动成功 @@ -1208,6 +1209,7 @@ ClientServerMsg_QueryNPCInfo = "QueryNPCInfo" # 查询跨服地图NPC信息 ClientServerMsg_SetPlayerAttrValue = "SetPlayerAttrValue" # 玩家属性数值更新 ClientServerMsg_CollectNPC = "CollectNPC" # 采集NPC +ClientServerMsg_EnterFB = "EnterFB" # 请求进入跨服副本 #跨服广播类型定义 CrossNotify_World = "World" -- Gitblit v1.8.0