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