From b60fd3b8a91432c1491f0c017fc90735dd28ebcf Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 11 一月 2019 20:34:44 +0800
Subject: [PATCH] 5722 【后端】【1.5】跨服BOSS开发(宝箱怪物刷新、跨服地图NPC个数查询支持)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_NPCCntCross.py |   60 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py          |   11 -
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                             |    2 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                           |   75 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py                    |   85 ++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py                      |   41 ++++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py                                 |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py             |   10 +
 ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py                                                   |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                         |   15 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                           |  149 ++++++++----------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py                        |    4 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                  |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py         |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                |    3 
 15 files changed, 368 insertions(+), 103 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index f0c731d..093eb59 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -22,6 +22,7 @@
 import CrossRealmPlayer
 import GameWorldBoss
 import CrossRealmPK
+import PlayerQuery
 import CrossBoss
 import ChConfig
 import GMShell
@@ -70,6 +71,9 @@
             
         elif msgType == ShareDefine.ClientServerMsg_ViewPlayerCache:
             CrossRealmPlayer.ClientServerMsg_ViewPlayerCache(serverGroupID, msgData)
+            
+        elif msgType == ShareDefine.ClientServerMsg_QueryNPCInfo:
+            PlayerQuery.ClientServerMsg_QueryNPCInfo(serverGroupID, msgData)
             
         # 需要发送到地图服务器处理的
         elif msgType in [ShareDefine.ClientServerMsg_Reborn]:
@@ -188,6 +192,9 @@
         elif msgType == ShareDefine.CrossServerMsg_DropGoodItem:
             GameWorldBoss.CrossServerMsg_DropGoodItem(msgData, tick)
             
+        elif msgType == ShareDefine.CrossServerMsg_NPCInfoRet:
+            PlayerQuery.CrossServerMsg_NPCInfoRet(msgData, tick)
+            
         # 需要发送到地图服务器处理的
         elif msgType in [ShareDefine.CrossServerMsg_RebornRet]:
             MapServer_ClientServerReceiveMsg(msgType, msgData)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 549d5d7..535acd2 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -72,6 +72,8 @@
 import CrossRealmPlayer
 import CrossRealmMsg
 import CrossRealmPK
+import ChPyNetSendPack
+import NetPackCommon
 
 import time
 import datetime
@@ -258,7 +260,7 @@
         return
     # 查询地图NPC数量
     elif queryType == ChConfig.queryType_NPCCnt:
-        __QueryMapNPCCntInfo(curPlayer, queryCallName, sendCMD)
+        __QueryMapNPCCntInfo(curPlayer, queryCallName, sendCMD, tick)
         return
     else:
         GameWorld.ErrLog('unKnow queryType = %s' % (queryType))
@@ -299,7 +301,7 @@
 #  @param queryCallName: 请求回调名
 #  @param sendCMD: 请求的命令 根据请求类型和请求命令来决定最终操作
 #  @return None
-def __QueryMapNPCCntInfo(curPlayer, queryCallName, sendCMD):
+def __QueryMapNPCCntInfo(curPlayer, queryCallName, sendCMD, tick):
     playerManager = GameWorld.GetPlayerManager()
     try:
         mapInfo = eval(sendCMD)
@@ -311,10 +313,79 @@
         return
     
     tagMapID = mapInfo[0]
+    npcIDList = mapInfo[2]
+    # 本服查询跨服地图怪物数
+    if tagMapID in ChConfig.Def_CrossMapIDList and not GameWorld.IsCrossServer():
+        __QueryCrossServerMapNPCCntInfo(curPlayer, tagMapID, npcIDList, tick)
+        return
     playerManager.MapServer_QueryPlayer(curPlayer.GetPlayerID(), ChConfig.queryType_NPCCnt, 0, tagMapID,
                 queryCallName, sendCMD, len(sendCMD), curPlayer.GetRouteServerIndex())
     return
 
+def __QueryCrossServerMapNPCCntInfo(curPlayer, mapID, npcIDList, tick):
+    ## 查询跨服地图NPC个数信息
+    if mapID in PyGameData.g_crossMapNPCInfo:
+        infoTick, mapNPCInfoDict = PyGameData.g_crossMapNPCInfo[mapID]
+        if tick - infoTick < 60 * 1000:
+            #GameWorld.DebugLog("直接同步本服缓存的跨服地图NPC信息")
+            SyncPlayerCrossMapNPCInfo(curPlayer, mapID, npcIDList, mapNPCInfoDict)
+            return
+        
+    # 本服缓存超时,发送跨服服务器查询
+    playerID = curPlayer.GetPlayerID()
+    CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryNPCInfo, {"PlayerID":playerID, "MapID":mapID, "NPCIDList":npcIDList})
+    return
+
+def ClientServerMsg_QueryNPCInfo(serverGroupID, msgData):
+    ## 收到子服请求查看跨服地图NPC个数信息
+    
+    mapID = msgData["MapID"]
+    zoneIpyData = CrossRealmPlayer.GetServerCrossZoneIpyData(mapID, serverGroupID)
+    if not zoneIpyData:
+        return
+    realMapID = zoneIpyData.GetMapID()
+    copyMapID = zoneIpyData.GetCopyMapID()
+    
+    sendCMD = {"ServerGroupID":serverGroupID, "CopyMapID":copyMapID}
+    sendCMD.update(msgData)
+    sendCMD = str(sendCMD)
+    GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "NPCCntCross", sendCMD, len(sendCMD))
+    return
+
+def CrossServerMsg_NPCInfoRet(msgData, tick):
+    ## 收到跨服服务器同步的地图NPC信息
+    
+    mapID = msgData["MapID"]
+    playerID = msgData["PlayerID"]
+    npcIDList = msgData["NPCIDList"]
+    mapNPCInfoDict = msgData["Result"]
+    PyGameData.g_crossMapNPCInfo[mapID] = [tick, mapNPCInfoDict]
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if curPlayer:
+        SyncPlayerCrossMapNPCInfo(curPlayer, mapID, npcIDList, mapNPCInfoDict)
+        
+    return
+
+def SyncPlayerCrossMapNPCInfo(curPlayer, mapID, npcIDList, mapNPCInfoDict):
+    ## 同步给玩家跨服地图NPC信息
+    
+    npcInfoPack = ChPyNetSendPack.tagMCNPCCntList()
+    npcInfoPack.Clear()
+    npcInfoPack.MapID = mapID
+    npcInfoPack.NPCInfoList = []
+    
+    for npcID in npcIDList:
+        npcInfo = ChPyNetSendPack.tagMCNPCCntInfo()
+        npcInfo.Clear()
+        npcInfo.NPCID = npcID
+        npcInfo.Cnt = mapNPCInfoDict.get(npcID, 0)
+        npcInfoPack.NPCInfoList.append(npcInfo)
+        
+    npcInfoPack.NPCInfoCnt = len(npcInfoPack.NPCInfoList)
+    NetPackCommon.SendFakePack(curPlayer, npcInfoPack)
+    return
+
+
 ## 获得家族属性(等级,人数)获得自己所在家族的属性
 #  @param curPlayer 请求的玩家
 #  @return 成功则返回相应的信息,家族等级和成员数量,如果不在家族中则返回None
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
index 594be37..5e91554 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -95,3 +95,6 @@
 
 g_crossPKUnNotifyOverInfo = {} # 跨服PK未同步的结算信息 {player:[overInfo], ...}
 
+g_crossMapNPCInfo = {} # 跨服地图NPC信息 {mapID:[tick, npcInfo], ...}
+
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 7dbdb73..861350f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1205,6 +1205,7 @@
 CrossServerMsg_GiveMoney = "GiveMoney"                  # 获得货币
 CrossServerMsg_DropGoodItem = "DropGoodItem"            # 掉落好物品
 CrossServerMsg_RebornRet = "RebornRet"                  # 复活结果
+CrossServerMsg_NPCInfoRet = "NPCInfoRet"                # 跨服地图NPC信息
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1215,6 +1216,7 @@
 ClientServerMsg_PKPrepareOK = "PKPrepareOK"             # 跨服PK准备完毕
 ClientServerMsg_PKBillboard = "PKBillboard"             # 跨服PK排行榜
 ClientServerMsg_Reborn = "Reborn"                       # 复活
+ClientServerMsg_QueryNPCInfo = "QueryNPCInfo"           # 查询跨服地图NPC信息
 
 #角色改名结果
 (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 4707b01..a210acf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1951,6 +1951,9 @@
 Def_RMark_TimePassCnt = 'Def_RMark_TimePassCnt' #时间超过刷新个数
 Def_RMark_RefreshStep = 'Def_RMark_RefreshStep' #刷怪波数
 
+Def_RMark_RandomRefreshNPCTick = 'RandomRefreshNPCTick' # 地图自定义随机刷怪,上次检查时间
+Def_RMark_RandomRefreshNPCNumTime = 'RandomRefreshNPCNumTime_%s' # 地图自定义随机刷怪,刷怪编号上次检查时间,参数(编号)
+
 Map_FBDict_NotifyOpen = "Map_FB_NTOpen"   # 副本开启提示
 Map_FBDict_NotifyStart = "Map_FB_NTStart"   # 副本开始提示
 Map_FBDict_NotifyEnd = "Map_FBDict_NotifyEnd"   # 副本结束提示
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py
index febbcc7..5bc021f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventShell.py
@@ -288,7 +288,9 @@
         return
     
     curPlayer.SetActionObj(curNPC)
-    
+    if curNPC.GetNPCID() in ReadChConfig.GetEvalChConfig("CollectNPCLostHP"):
+        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
+        
     prepareTime = FBLogic.GetFBPrepareTime(curPlayer, curNPC)
     
     collTimeReduceRate = PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_CollTimeReduceRate)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py
index bde8871..2452d13 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/ClearCollectNPCCnt.py
@@ -40,14 +40,9 @@
         
     # 清NPCID每日采集次数
     collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
-    for npcID in collectNPCIDTimeLimit.keys():
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
-    
-    # 清NPC功能类型每日采集次数
-    collectNPCFuncTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
-    for funcType in collectNPCFuncTimeLimit.keys():
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTime % funcType, 0)
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcBuyTime % funcType, 0)
+    for npcIDTuple in collectNPCIDTimeLimit.keys():
+        for npcID in npcIDTuple:
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)
     
     NPCCommon.SyncCollNPCTime(curPlayer)
         
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 2226a1b..0b816e1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
@@ -40,6 +40,7 @@
 import ChConfig
 import PlayerControl
 import FamilyRobBoss
+import NPCCustomRefresh
 import EventShell
 import FBLogic
 import FBCommon
@@ -520,6 +521,9 @@
     
     #仙盟归属boss定时处理
     FamilyRobBoss.OnFamilyOwnerBossProcess(tick)
+    
+    #地图自定义随机刷怪
+    NPCCustomRefresh.ProcessMapRandomRefreshNPC(gameWorld, tick)
     return
 
 ## 通知RouteServer 消息
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 5334251..7229e00 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -5275,21 +5275,9 @@
     
     # 采集次数判断
     limitMaxTime, todayCollTime = 0, 0
-    npcFuncType = curNPC.GetFunctionType()
-    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
-    if npcFuncType in npcFuncCollectCntLimitDict:
-        vipLV = curPlayer.GetVIPLv()
-        limitMaxTime = eval(npcFuncCollectCntLimitDict[npcFuncType])
-        todayBuyTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % npcFuncType)
-        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % npcFuncType)
-        limitMaxTime += todayBuyTime
-        GameWorld.DebugLog("    vipLV=%s,maxTime=%s,todayTime=%s,todayBuyTime=%s" % (vipLV, limitMaxTime, todayCollTime, todayBuyTime))
-        
-    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
-    if npcID in npcIDCollectCntLimitDict:
-        limitMaxTime = npcIDCollectCntLimitDict[npcID][0]
-        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
-        GameWorld.DebugLog("    maxTime=%s,todayTime=%s" % (limitMaxTime, todayCollTime))
+    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
+    if collLimitInfo:
+        limitMaxTime, todayCollTime = collLimitInfo
         
     if limitMaxTime > 0 and todayCollTime >= limitMaxTime:
         
@@ -5338,6 +5326,19 @@
     AttackCommon.AddHurtValue(curNPC, curPlayer.GetPlayerID(), ChConfig.Def_NPCHurtTypePlayer, 1)
     return
 
+def GetCollTimeLimitInfo(curPlayer, npcID):
+    ## 获取采集次数限制信息
+    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
+    for npcIDTuple in npcIDCollectCntLimitDict.keys():
+        if npcID not in npcIDTuple:
+            continue
+        limitMaxTime = npcIDCollectCntLimitDict[npcIDTuple][0]
+        todayCollTime = 0
+        for collNPCID in npcIDTuple:
+            todayCollTime += curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % collNPCID)
+        GameWorld.DebugLog("    limitMaxTime=%s,todayCollTime=%s" % (limitMaxTime, todayCollTime))
+        return limitMaxTime, todayCollTime
+    return
 
 ## 设置玩家采集该NPC
 #  @param curPlayer:玩家实例
@@ -5422,11 +5423,11 @@
     openCnt = clientData.OpenCnt
     isAutoBuy = clientData.IsAutoBuy
     isOnlyGold = clientData.IsOnlyGold
-    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
-    if npcID not in npcIDCollectCntLimitDict:
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
+    if not collLimitInfo:
         GameWorld.DebugLog("该NPC不是自定义采集NPC箱子, 不可开启! npcID=%s" % npcID)
         return
-    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
     GameWorld.DebugLog("OnOpenCollNPCBox...npcID=%s,openCnt=%s,isAutoBuy=%s" % (npcID, openCnt, isAutoBuy))
     DoGetCollectionNPCAwardLogic(curPlayer, npcID, isAutoBuy, openCnt, mapID, isOnlyGold)
     return
@@ -5456,22 +5457,14 @@
     curNPC = GameWorld.GetGameData().FindNPCDataByID(npcID)
     if not curNPC:
         return True
-
-    # 根据NPC功能号
-    npcFuncType = curNPC.GetFunctionType()
-    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
+    
     limitMaxTime = 0 # 0表示不限制次数
     todayCollTime = 0
-    if npcFuncType in npcFuncCollectCntLimitDict:
-        vipLV = curPlayer.GetVIPLv()
-        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % npcFuncType)
-        limitMaxTime = eval(npcFuncCollectCntLimitDict[npcFuncType])
     
     # 根据NPCID
-    npcIDCollectCntLimitDict = ReadChConfig.GetEvalChConfig("CollectNPCIDTimeLimit")
-    if npcID in npcIDCollectCntLimitDict:
-        limitMaxTime = npcIDCollectCntLimitDict[npcID][0]
-        todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcIDCollTime % npcID)
+    collLimitInfo = GetCollTimeLimitInfo(curPlayer, npcID)
+    if collLimitInfo:
+        limitMaxTime, todayCollTime = collLimitInfo
         
     if limitMaxTime > 0:
         canCollectCnt = max(0, limitMaxTime - todayCollTime)
@@ -5573,20 +5566,13 @@
                                % (unCostCnt, itemGold, reduceGold), curPlayer.GetPlayerID())
         
     # 增加当日采集次数
-    if limitMaxTime > 0:
+    if collLimitInfo:
         updCollTime = todayCollTime + successCnt
-        npcFuncType = curNPC.GetFunctionType()
-        npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
-        if npcFuncType in npcFuncCollectCntLimitDict:
-            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTime % npcFuncType, updCollTime)
-            SyncCollNPCTime(curPlayer, [npcFuncType])
-                    
-        if npcID in npcIDCollectCntLimitDict:
-            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
-            SyncCollNPCTime(curPlayer, npcIDList=[npcID])
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, updCollTime)
+        SyncCollNPCTime(curPlayer, npcIDList=[npcID])
         GameWorld.DebugLog("        增加当日采集次数: todayCollTime=%s,updCollTime=%s" % (todayCollTime, updCollTime))
-        #采集成就
-        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, successCnt, [npcID])
+    #采集成就
+    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Collect, successCnt, [npcID])
     SyncCollectionItemInfo(curPlayer, addExp, addMoney, addZhenQi, giveItemInfoList, npcID)
     #DataRecordPack.DR_CollectNPCOK(curPlayer, npcID, addMoney, addExp, addZhenQi, giveItemInfoList)
     return True
@@ -5763,24 +5749,11 @@
 #  @param funcType:功能号,默认为0,即同步配表中全部
 #  @return None
 def SyncCollNPCTime(curPlayer, funcTypeList=[], npcIDList=[]):
-    if not funcTypeList:
-        npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
-        funcTypeList = npcFuncCollectCntLimitDict.keys()
-        
     if not npcIDList:
         collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
-        npcIDList = collectNPCIDTimeLimit.keys()
-    
-#    if funcTypeList:
-#        collection = ChPyNetSendPack.tagMCFuncNPCCollectionCnt()
-#        for fType in funcTypeList:
-#            todayCollTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcCollTime % fType)
-#            collection.Clear()
-#            collection.FuncType = fType
-#            collection.CollectionCnt = todayCollTime
-#            collection.BuyCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CollNpcBuyTime % fType)
-#            NetPackCommon.SendFakePack(curPlayer, collection)
-        
+        for npcIDTuple in collectNPCIDTimeLimit.keys():
+            npcIDList += list(npcIDTuple)
+            
     if npcIDList:
         npcIDCollInfo = ChPyNetSendPack.tagMCNPCIDCollectionCntInfo()
         npcIDCollInfo.Clear()
@@ -5800,18 +5773,13 @@
 #  @param curPlayer:玩家实例
 #  @return None
 def CollNPCTimeOnDay(curPlayer, funcTypeList=[]):
-    npcFuncCollectCntLimitDict = ReadChConfig.GetEvalChConfig('CollectNPCFuncTimeLimit')
-    funcTypeList = npcFuncCollectCntLimitDict.keys() if not funcTypeList else funcTypeList
-    for funcType in funcTypeList:
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcCollTime % funcType, 0)
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcBuyTime % funcType, 0)
-    
     collectNPCIDTimeLimit = ReadChConfig.GetEvalChConfig('CollectNPCIDTimeLimit')
-    for npcID, collCntInfo in collectNPCIDTimeLimit.items():
+    for npcIDTuple, collCntInfo in collectNPCIDTimeLimit.items():
         isResetOnDay = collCntInfo[1]
         if not isResetOnDay:
             continue
-        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)        
+        for npcID in npcIDTuple:
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CollNpcIDCollTime % npcID, 0)        
     
     SyncCollNPCTime(curPlayer)
     return
@@ -5899,28 +5867,43 @@
 #  @param queryNPCIDList:查询的NPCID列表
 #  @param tick
 #  @return {NPCID:cnt}
-def GetNPCCntInfo(queryNPCIDList, tick):
+def GetNPCCntInfo(queryNPCIDList, tick, copyMapID=None):
     npcCntDict = {}
 
-    if not queryNPCIDList:
-        return npcCntDict
+    #if not queryNPCIDList:
+    #    return npcCntDict
     
     gameNPCManager = GameWorld.GetNPCManager()
     GameWorld.DebugLog("GetNPCCntInfo...queryNPCIDList=%s" % (str(queryNPCIDList)))
-
-    for index in xrange(gameNPCManager.GetNPCCount()):
-        curNPC = gameNPCManager.GetNPCByIndex(index)
-        curID = curNPC.GetID()
-        if curID == 0:
-            continue
-        
-        curNPCID = curNPC.GetNPCID()
-        
-        if curNPCID not in queryNPCIDList:
-            continue
-        if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
-            continue
-        npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
+    
+    if isinstance(copyMapID, int):
+        for index in xrange(gameNPCManager.GetNPCCountByGWIndex(copyMapID)):
+            curNPC = gameNPCManager.GetNPCByIndexByGWIndex(copyMapID, index)
+            curID = curNPC.GetID()
+            if curID == 0:
+                continue
+            
+            curNPCID = curNPC.GetNPCID()
+            
+            if queryNPCIDList and curNPCID not in queryNPCIDList:
+                continue
+            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
+                continue
+            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
+    else:
+        for index in xrange(gameNPCManager.GetNPCCount()):
+            curNPC = gameNPCManager.GetNPCByIndex(index)
+            curID = curNPC.GetID()
+            if curID == 0:
+                continue
+            
+            curNPCID = curNPC.GetNPCID()
+            
+            if queryNPCIDList and curNPCID not in queryNPCIDList:
+                continue
+            if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie or not curNPC.IsAlive():
+                continue
+            npcCntDict[curNPCID] = npcCntDict.get(curNPCID, 0) + 1
                 
     GameWorld.DebugLog("    npcCntDict=%s" % (str(npcCntDict)))
     return npcCntDict
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 5a8c626..a86f294 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
@@ -17,7 +17,6 @@
 import ShareDefine
 import ReadChConfig
 import GameLogic_SealDemon
-import CrossRealmPlayer
 import PlayerControl
 import IPY_GameWorld
 import IpyGameDataPY
@@ -26,6 +25,7 @@
 import FBLogic
 
 import random
+import time
 #---------------------------------------------------------------------
 
 ## 所有npc刷新
@@ -900,3 +900,86 @@
 
 ################################################################################
 
+def ProcessMapRandomRefreshNPC(gameWorld, tick):
+    ''' 地图自定义随机刷怪,支持多点随机刷多种怪,标试点不可重复,支持跨服地图
+            注意:同个虚拟线路中,标试点不可重复!标试点不可重复!标试点不可重复!
+    '''
+    mapID = gameWorld.GetMapID()
+    # {mapID:{编号:[[多个NPCID], [多个标试点], 单个点最大数量, 所有点总数量, 刷怪间隔秒], ...}, ...}
+    randRefreshNPCDict = IpyGameDataPY.GetFuncEvalCfg("RandomRefreshNPC", 1, {})
+    if mapID not in randRefreshNPCDict:
+        return
+    mapRandRefreshNPCDict = randRefreshNPCDict[mapID]
+    
+    #copyMapID = gameWorld.GetCopyMapID()
+    
+    gameFB = GameWorld.GetGameFB()
+    lastCheckTick = gameFB.GetGameFBDictByKey(ChConfig.Def_RMark_RandomRefreshNPCTick)
+    if lastCheckTick and tick - lastCheckTick < 1000:
+        return
+    gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCTick, tick)
+    
+    curTime = int(time.time())
+    refreshNumList = []
+    for num, refreshInfo in mapRandRefreshNPCDict.items():
+        refreshCD = refreshInfo[-1]
+        numLastTime = gameFB.GetGameFBDictByKey(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num)
+        if numLastTime and curTime - numLastTime < refreshCD:
+            continue
+        gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num, curTime)
+        refreshNumList.append(num)
+        
+    if not refreshNumList:
+        #GameWorld.DebugLog("没有需要刷怪的", copyMapID)
+        return
+    npcCountDict = {}  # 标识点对应NPC数量
+    rMarkNPCRefreshDict = {} # 标试点对应标试点实例 {标试点:IPY_CustomNPCRefresh, ...}
+    gameNPC = GameWorld.GetNPCManager()
+    for i in xrange(gameNPC.GetCustomNPCRefreshCount()):
+        npcRefresh = gameNPC.GetCustomNPCRefreshAt(i)
+        npcCount = npcRefresh.GetCount()
+        #if not npcCount: # 因为要记录刷怪点实例,所以0的不屏蔽
+        #    continue
+        rMark = npcRefresh.GetRefreshMark()
+        npcCountDict[rMark] = npcCountDict.get(rMark, 0) + npcCount
+        rMarkNPCRefreshDict[rMark] = npcRefresh
+        
+    #GameWorld.DebugLog("npcCountDict=%s" % npcCountDict, copyMapID)
+    for num in refreshNumList:
+        npcIDList, markList, maxCount, totalMaxCount = mapRandRefreshNPCDict[num][:-1]
+        
+        curTotalCount = 0
+        for rMark in markList:
+            curTotalCount += npcCountDict.get(rMark, 0)
+            
+        refreshCount = totalMaxCount - curTotalCount
+        
+        #GameWorld.DebugLog("    num=%s,markList=%s,curTotalCount=%s,totalMaxCount=%s,refreshCount=%s" 
+        #                   % (num, markList, curTotalCount, totalMaxCount, refreshCount), copyMapID)
+        if refreshCount <= 0:
+            continue
+        
+        random.shuffle(markList) # 随机打乱顺序
+        #GameWorld.DebugLog("    markList=%s" % markList, copyMapID)
+        for rMark in markList:
+            if rMark not in rMarkNPCRefreshDict:
+                #GameWorld.DebugLog("        标试点不存在: rMark=%s" % rMark, copyMapID)
+                continue
+            if refreshCount <= 0:
+                #GameWorld.DebugLog("        不需要刷怪了: rMark=%s" % rMark, copyMapID)
+                break
+            curCount = npcCountDict.get(rMark, 0)
+            if curCount >= maxCount:
+                #GameWorld.DebugLog("        该点已经达到单点最大数: rMark=%s" % rMark, copyMapID)
+                continue
+            needRefreshCount = min(refreshCount, maxCount - curCount)
+            refreshCount -= needRefreshCount
+            npcID = npcIDList[0] if len(npcIDList) == 1 else random.choice(npcIDList)
+            
+            #GameWorld.DebugLog("        刷怪: rMark=%s,needRefreshCount=%s,还需=%s" % (rMark, needRefreshCount, refreshCount), copyMapID)
+            npcRefresh = rMarkNPCRefreshDict[rMark]
+            npcRefresh.Refresh(npcID, ChConfig.Def_NormalNPCAngryCount, needRefreshCount, False)
+            __InitNewBornNPC(npcRefresh , tick)
+            
+    return
+
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 d7dd489..9ec0e31 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -5457,10 +5457,17 @@
     return
 
 
-
-## 地图NPC数量查询封包 A2 27 查询地图NPC数量信息 #tagCMQueryNPCCntInfo
-#  @param curPlayer
-#  @return None
+#// A2 27 查询地图NPC数量信息 #tagCMQueryNPCCntInfo
+#
+#struct tagCMQueryNPCCntInfo
+#{
+#    tagHead        Head;
+#    DWORD        MapID; // 目标地图ID
+#    WORD        LineID; // 线路ID
+#    BYTE        IsNoTimeLimit;//是否没有查询时间限制,默认有限制
+#    BYTE        NPCIDListLen;
+#    char        NPCIDList[NPCIDListLen]; // 需要查询的NPCID列表
+#};
 def OnQueryMapNPCCntInfo(index, clientData, tick):
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
     if not curPlayer:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py
index c005eb0..a7b24d9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerMissionCollect.py
@@ -18,7 +18,7 @@
 # @change: "2010-11-22 12:15" Alee 采集限制
 # @change: "2014-04-14 12:00" hxp 增加自定义采集NPC
 #---------------------------------------------------------------------
-"""Version = 2014-04-14 12:00"""
+#"""Version = 2014-04-14 12:00"""
 #---------------------------------------------------------------------
 #导入
 import GameWorld
@@ -31,6 +31,8 @@
 import NPCCommon
 import FBLogic
 import AttackCommon
+import ReadChConfig
+import PlayerState
 import GameObj
 #---------------------------------------------------------------------
 '''Version = 2010-09-16 09:55'''
@@ -94,6 +96,8 @@
     
     #先设置对象,任务可采集得到对象NPC
     curPlayer.SetActionObj(curNPC)
+    if curNPC.GetNPCID() in ReadChConfig.GetEvalChConfig("CollectNPCLostHP"):
+        curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
     
     # 自定义的采集NPC
     if NPCCommon.DoCollectNPCBegin(curPlayer, curNPC):
@@ -130,7 +134,7 @@
 #  @param curPlayer
 #  @return None
 #  @remarks 函数详细说明.
-def EndMissionCollect(curPlayer):
+def EndMissionCollect(curPlayer, tick):
     #任务采集类NPC
     curNPC = GetActionNPCbyType(curPlayer, IPY_GameWorld.ntMissionCollect)
     if not curNPC:
@@ -142,6 +146,8 @@
     if not ChNPC.OnCollectEnd(curPlayer, curNPC):
         return
     
+    PlayerState.DoCollectingLostHP(curPlayer, npcID, tick, True)
+    
     # 自定义的采集NPC
     if NPCCommon.DoCollectNPCOK(curPlayer, npcID):
         EventShell.EventRespons_MisCollectSuccess(curPlayer, curNPC) # 先直接写这边触发一下,自定义采集的不再处理后面的代码
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
index 8ae4d09..fc75233 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -535,7 +535,7 @@
     if tick - curPlayer.GetPlayerActionTick() < curPlayer.GetPrepareTime():
         #时间间隔没有到
         if prepareState in [IPY_GameWorld.pstCollecting, IPY_GameWorld.pstMissionCollecting]:
-            FBLogic.OnCollecting(curPlayer, tick)
+            OnCollecting(curPlayer, tick)
         
         return
     
@@ -561,7 +561,7 @@
     
     elif prepareState == IPY_GameWorld.pstMissionCollecting:
         #任务采集
-        PlayerMissionCollect.EndMissionCollect(curPlayer)
+        PlayerMissionCollect.EndMissionCollect(curPlayer, tick)
 
     elif prepareState == ShareDefine.Def_PstProduce:
         #生产采集(进入生产采集状态,不再重置玩家状态)
@@ -583,6 +583,39 @@
     #重置玩家状态
     curPlayer.SetPrepareState(0)    # 成功
     PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)
+    return
+
+def OnCollecting(curPlayer, tick):
+    ## 采集中逻辑
+    tagObj = curPlayer.GetActionObj()
+    if not tagObj:
+        return
+    if tagObj.GetGameObjType() != IPY_GameWorld.gotNPC:
+        return
+    curNPC = GameWorld.GetNPCManager().GetNPCByIndex(tagObj.GetIndex())
+    DoCollectingLostHP(curPlayer, curNPC.GetNPCID(), tick, False)
+    FBLogic.OnCollecting(curPlayer, tick)
+    return
+
+def DoCollectingLostHP(curPlayer, npcID, tick, isEnd):
+    ## 执行采集掉血
+    CollectNPCLostHPCfg = ReadChConfig.GetEvalChConfig("CollectNPCLostHP")
+    if npcID not in CollectNPCLostHPCfg:
+        return
+    lostSecond, lostHPPer = CollectNPCLostHPCfg[npcID]
+    lastTick = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_CollectLostHPTick)
+    lostTime = (tick - lastTick) / (lostSecond * 1000.0) # 掉血次数
+    if isEnd:
+        lostTime = int(round(lostTime)) # 采集完的时候四舍五入
+    else:
+        lostTime = int(lostTime)
+    if lostTime < 1:
+        return
+    
+    curPlayer.SetDict(ChConfig.Def_PlayerKey_CollectLostHPTick, tick)
+    lostValue = int(GameObj.GetMaxHP(curPlayer) * lostHPPer / 100.0) * lostTime
+    skillTypeID, buffOwner = 0, None
+    SkillCommon.SkillLostHP(curPlayer, skillTypeID, buffOwner, lostValue, tick)
     return
 
 
@@ -623,6 +656,8 @@
     
     if not curNPC:
         return
+    
+    DoCollectingLostHP(curPlayer, curNPC.GetNPCID(), tick, True)
     
     result = FBLogic.OnCanCollect(curPlayer, curNPC, tick)
     
@@ -1504,6 +1539,8 @@
     
 def ProcessAreaExp(curPlayer, tick):
     ##给场景经验
+    if GameWorld.IsCrossServer():
+        return
     crossMapID = PlayerControl.GetCrossMapID(curPlayer)
     mapID = crossMapID if crossMapID else GameWorld.GetMap().GetMapID()
     neutralMapExpAwardDict = IpyGameDataPY.GetFuncEvalCfg('NeutralMapExpAward', 1, {})
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_NPCCntCross.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_NPCCntCross.py
new file mode 100644
index 0000000..326eaec
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_NPCCntCross.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_NPCCntCross
+#
+# @todo:查询跨服地图NPC数量信息
+# @author hxp
+# @date 2019-01-11
+# @version 1.0
+#
+# 详细描述: 查询跨服地图NPC数量信息
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2019-01-11 20:30"""
+#-------------------------------------------------------------------------------
+
+import NPCCommon
+import GameWorld
+import ShareDefine
+
+#---------------------------------------------------------------------
+#全局变量
+#---------------------------------------------------------------------
+
+
+#---------------------------------------------------------------------
+#逻辑实现
+## 请求逻辑
+#  @param query_Type 请求类型
+#  @param query_ID 请求的玩家ID
+#  @param packCMDList 发包命令 [ ]
+#  @param tick 当前时间
+#  @return "True" or "False" or ""
+#  @remarks 函数详细说明.
+def DoLogic(query_Type, query_ID, packCMDInfo, tick):
+    GameWorld.DebugLog("GY_Query_NPCCntCross %s" % (packCMDInfo))
+    
+    serverGroupID = packCMDInfo["ServerGroupID"]
+    copyMapID = packCMDInfo["CopyMapID"]
+    
+    npcCntDict = NPCCommon.GetNPCCntInfo([], tick, copyMapID) # 跨服的一次查全部,都是遍历一遍,不过滤npcID
+    retMsg = {"Result":npcCntDict}
+    retMsg.update(packCMDInfo)
+    GameWorld.SendMsgToClientServer(ShareDefine.CrossServerMsg_NPCInfoRet, retMsg, [serverGroupID])
+    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 7dbdb73..861350f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1205,6 +1205,7 @@
 CrossServerMsg_GiveMoney = "GiveMoney"                  # 获得货币
 CrossServerMsg_DropGoodItem = "DropGoodItem"            # 掉落好物品
 CrossServerMsg_RebornRet = "RebornRet"                  # 复活结果
+CrossServerMsg_NPCInfoRet = "NPCInfoRet"                # 跨服地图NPC信息
 
 # 子服发送跨服信息定义
 ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
@@ -1215,6 +1216,7 @@
 ClientServerMsg_PKPrepareOK = "PKPrepareOK"             # 跨服PK准备完毕
 ClientServerMsg_PKBillboard = "PKBillboard"             # 跨服PK排行榜
 ClientServerMsg_Reborn = "Reborn"                       # 复活
+ClientServerMsg_QueryNPCInfo = "QueryNPCInfo"           # 查询跨服地图NPC信息
 
 #角色改名结果
 (

--
Gitblit v1.8.0