From ae9f73d422020a792b2615d7f094d629d81c5123 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 15 三月 2019 19:54:27 +0800
Subject: [PATCH] Merge branch 'master' of http://192.168.0.87:10010/r/SnxxServerCode

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py |  314 ++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 228 insertions(+), 86 deletions(-)

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 6d5e05c..2493ede 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
@@ -17,6 +17,7 @@
 import ShareDefine
 import ReadChConfig
 import GameLogic_SealDemon
+import GameLogic_ZhuXianBoss
 import PlayerControl
 import IPY_GameWorld
 import IpyGameDataPY
@@ -25,6 +26,7 @@
 import FBLogic
 
 import random
+import time
 #---------------------------------------------------------------------
 
 ## 所有npc刷新
@@ -90,72 +92,6 @@
         
     return
 ##------------------------------------------------------------------------------
-
-## 合服活动BOSS(勇者大陆)
-#  @param npcRefresh 刷新的npc对象
-#  @param tick 当前时间
-#  @return None
-def NPCRefresh_63(npcRefresh, tick): return __RefreshMixBoss(npcRefresh, tick)
-def NPCRefresh_64(npcRefresh, tick): return __RefreshMixBoss(npcRefresh, tick)
-def NPCRefresh_65(npcRefresh, tick): return __RefreshMixBoss(npcRefresh, tick)
-
-## 合服活动BOSS(勇者大陆)
-#  @param npcRefresh 刷新的npc对象
-#  @param tick 当前时间
-#  @return None
-def __RefreshMixBoss(npcRefresh, tick):
-    gameWorld = GameWorld.GetGameWorld()
-    isMixServer = gameWorld.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_IsMixServer)
-    mixDay = gameWorld.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_MixServerDay)
-    refreshMark = npcRefresh.GetRefreshMark()
-    
-    # 配置
-    mixBossInfo = ReadChConfig.GetEvalChConfig("MixBossInfo")
-    curBossInfo = mixBossInfo.get(refreshMark)
-    if not curBossInfo:
-        #GameWorld.DebugLog("__RefreshMixBoss() hasn't configuration refreshMark(%s)"%refreshMark)
-        return
-    npcId, mixTime, refreshTimeList = curBossInfo
-    
-    # 合服期间
-    if not isMixServer or mixDay < mixTime[0] or mixDay > mixTime[1]:
-        #GameWorld.DebugLog("__RefreshMixBoss() no mix server")
-        return
-    
-    # 一线刷新
-    lineId = GameWorld.GetGameWorld().GetLineID()
-    if lineId != 0:
-        #GameWorld.DebugLog("__RefreshMixBoss() not in 1 line(%s), now"%lineId)
-        return
-    
-    # 有怪
-    if npcRefresh.GetCount() > 0:
-        #GameWorld.DebugLog("__RefreshMixBoss() have mix server boss(%s), now"%refreshMark)
-        return
-    
-    # 刷新时间匹配
-    curTime = GameWorld.GetCurrentTime()
-    if (curTime.hour, curTime.minute) not in refreshTimeList:
-        #GameWorld.DebugLog("__RefreshMixBoss() npcId(%s) isn't refresh(%s) time(%s)"
-        #                   % (npcId, str((curTime.hour, curTime.minute)), refreshTimeList))
-        return
-    
-    # 刷新Tick 一分钟内不再刷新
-    refreshTickKey = ChConfig.Map_NPC_WorldBossLastReBornTick % npcId
-    lastRefreshTick = gameWorld.GetGameWorldDictByKey(refreshTickKey)
-    if tick - lastRefreshTick <= 60 * 1000:
-        #GameWorld.DebugLog("__RefreshMixBoss() not refresh inside minute, npcID(%s) tick(%s) lastTick(%s)"
-        #                   % (npcId, tick, lastRefreshTick))
-        return
-    gameWorld.SetGameWorldDict(refreshTickKey, tick)
-    
-    # 刷新NPC
-    npcRefresh.Refresh(npcId, ChConfig.Def_SuperBossAngryCount, 1, False)
-    # 初始化NPC
-    __InitNewBornNPC(npcRefresh, tick)
-    
-    GameWorld.DebugLog("__RefreshMixBoss() refresh mix server boss npcId(%s) success!!!" % (npcId))
-    return
 
 ## 地图M个点随机刷N只怪
 #  @param npcRefresh 刷新实例
@@ -336,18 +272,49 @@
 def NPCRefresh_98(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
 def NPCRefresh_99(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
 def NPCRefresh_100(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_180(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_181(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_182(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_183(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_184(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_185(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_186(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_187(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_188(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_189(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_190(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_191(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_192(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_193(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_194(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_195(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_196(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_197(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_198(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_199(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
+def NPCRefresh_200(npcRefresh, tick):__DoRefreshWorldBoss(npcRefresh, tick)
 
 
 def ResetActivityBossRefreshCount():
     ## 重置活动boss刷怪个数
-    gameFB = GameWorld.GetGameFB()
-    gameNPC = GameWorld.GetNPCManager()
+    
+    # gameFb 要取活动线
+    activityLineIndex = 0 # 活动线, 默认1线
+    mapID = GameWorld.GetMap().GetMapID()
+    activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {})
+    if mapID in activityMapLineDict:
+        activityLineIndex = max(0, activityMapLineDict[mapID] - 1)
+        
+    gameWorld = IPY_GameWorld.IPY_GameWorld(activityLineIndex)
+    gameFB = gameWorld.GetGameFBByFbIndex(activityLineIndex)
+    
+    gameNPC = GameWorld.GetNPCManager() # NPC标识点的无所谓,哪条线都可以,因为都一样
     for i in xrange(gameNPC.GetCustomNPCRefreshCount()):
         npcRefresh = gameNPC.GetCustomNPCRefreshAt(i)
         refreshMark = npcRefresh.GetRefreshMark()
         if gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark):
             gameFB.SetGameFBDict(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark, 0)
-            GameWorld.DebugLog("重置活动boss刷怪点刷怪个数: refreshMark=%s" % refreshMark)
+            GameWorld.DebugLog("重置活动boss刷怪点刷怪个数: activityLineIndex=%s,refreshMark=%s" % (activityLineIndex, refreshMark))
     return
 
 ## 世界boss刷怪
@@ -358,12 +325,19 @@
     '''非分流地图boss只在一线刷
        分流地图boss每条线都刷新,其他分流线路boss在没人打的情况下同生同死
     '''
+    if GameWorld.IsCrossServer():
+        __DoRefreshWorldBossCrossServer(npcRefresh, tick)
+        return
     mapID = GameWorld.GetMap().GetMapID()
     refreshMark = npcRefresh.GetRefreshMark()
     lineID = GameWorld.GetGameWorld().GetLineID()
-    
+    relatedType, relatedID = 0, 0
+    isNeedShunt = 0
     if mapID == ChConfig.Def_FBMapID_SealDemon:
         bossID = GameLogic_SealDemon.CurFBLineBOSSID()
+        stoneNPCID = 0
+    elif mapID == ChConfig.Def_FBMapID_ZhuXianBoss:
+        bossID = GameLogic_ZhuXianBoss.CurFBLineBOSSID()
         stoneNPCID = 0
     else:
         ipyData = IpyGameDataPY.GetIpyGameDataByCondition('BOSSInfo', {'RefreshMark':refreshMark, 'MapID':mapID}, isLogNone=False)
@@ -371,14 +345,14 @@
             return
         stoneNPCID = ipyData.GetStoneNPCID()
         bossID = ipyData.GetNPCID()
+        relatedType = ipyData.GetRelatedType()
+        relatedID = ipyData.GetRelatedID()
+        isNeedShunt = ipyData.GetIsNeedShunt()
     if not bossID and not stoneNPCID:
         return
-    
     gameFB = GameWorld.GetGameFB()
     gameWorldMgr = GameWorld.GetGameWorld()
-    relatedType = ipyData.GetRelatedType()
-    relatedID = ipyData.GetRelatedID()
-    isActivityBoss = False
+    isActivityBoss = False # 是否活动boss
     # 关联日常活动
     if relatedType == 1:
         actionKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % relatedID
@@ -411,7 +385,7 @@
             rebornBossState = 0
             stoneNPCID = 0 # 活动线暂不刷墓碑
             
-    isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) and ipyData.GetIsNeedShunt()
+    isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) and isNeedShunt
     
     curNPC = None
     if npcRefresh.GetCount() > 0:
@@ -426,7 +400,7 @@
             NPCCommon.SetDeadEx(curNPC)
             
         # 非复活线 且 不需要分流的地图 且 不是封魔坛  不允许复活
-        if lineID != rebornLineID and not isNeedShunt and mapID != ChConfig.Def_FBMapID_SealDemon:
+        if lineID != rebornLineID and not isNeedShunt and mapID not in [ChConfig.Def_FBMapID_SealDemon, ChConfig.Def_FBMapID_ZhuXianBoss]:
             return
         
         if isActivityBoss and activityBossRebornCount > 0:
@@ -483,18 +457,97 @@
     '''分流boss是否需要处理
         无伤血、仇恨、没人看到他、他没看到别人
     '''
-    if curNPC.GetPlayerHurtList().GetHurtCount():
-        #GameWorld.DebugLog("分流boss有伤血,不可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
-        return True
-    
-    if curNPC.GetAttentionPlayersCount() or curNPC.GetInSightObjCount():
-        #GameWorld.DebugLog("分流boss有人看到,不可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
-        return True
-    
-    GameWorld.DebugLog("分流boss不需要处理了,可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
-    return False
+    # 策划暂时修改分流boss不同步死亡
+    return True
+#    if curNPC.GetPlayerHurtList().GetHurtCount():
+#        #GameWorld.DebugLog("分流boss有伤血,不可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
+#        return True
+#    
+#    if curNPC.GetAttentionPlayersCount() or curNPC.GetInSightObjCount():
+#        #GameWorld.DebugLog("分流boss有人看到,不可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
+#        return True
+#    
+#    GameWorld.DebugLog("分流boss不需要处理了,可以清除!npcID=%s" % curNPC.GetNPCID(), GameWorld.GetGameWorld().GetLineID())
+#    return False
 
 #===================================================================================================
+
+def __DoRefreshWorldBossCrossServer(npcRefresh, tick):
+    ## 跨服服务器刷boss
+    
+    mapID = GameWorld.GetGameWorld().GetMapID() # dataMapID
+    if mapID not in ChConfig.Def_CrossMapIDList:
+        return
+    
+    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:
+        return
+    zoneID = zoneIpyData.GetZoneID()
+    
+    gameFB = GameWorld.GetGameFB()
+    bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossRebornCross % (zoneID, bossID)
+    rebornBossState = GameWorld.GetGameWorld().GetGameWorldDictByKey(bosskey)
+    curNPC = None
+    if npcRefresh.GetCount() > 0:
+        curNPC = npcRefresh.GetAt(0)
+        
+    # 复活状态
+    if rebornBossState:
+        if curNPC:
+            if curNPC.GetNPCID() == bossID:
+                return
+            #去掉非bossNPC
+            NPCCommon.SetDeadEx(curNPC)
+            
+    # 死亡状态
+    else:
+        if curNPC:
+            if curNPC.GetNPCID() == stoneNPCID:
+                return
+            #去掉非墓碑NPC
+            NPCCommon.SetDeadEx(curNPC)
+            
+        # 延迟刷墓碑
+        bossDeadTick = gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_WorldBossDeadTick % bossID)
+        bossStoneDelayTime = IpyGameDataPY.GetFuncCfg('BossStoneDelayTime')
+        if tick - bossDeadTick <= bossStoneDelayTime:
+            return
+        gameFB.SetGameFBDict(ChConfig.Map_NPC_WorldBossDeadTick % bossID, tick)
+        
+    rebornNPCID = bossID if rebornBossState else stoneNPCID
+    if not rebornNPCID:
+        return
+    rebornTickKey = ChConfig.Map_NPC_WorldBossLastReBornTick % rebornNPCID
+    lastRebornTick = gameFB.GetGameFBDictByKey(rebornTickKey)
+    if tick - lastRebornTick <= 50 * 1000:
+        GameWorld.DebugLog("CrossBossRefresh mapID=%s,realMapID=%s,copyMapID=%s,refreshMark=%s,rebornNPCID=%s,tick=%s,lastRebornTick=%s 不重复刷新!" 
+                           % (mapID, realMapID, copyMapID, refreshMark, rebornNPCID, tick, lastRebornTick))
+        return
+    
+    npcRefresh.Refresh(rebornNPCID, ChConfig.Def_SuperBossAngryCount, 1, False)
+    #初始化NPC
+    __InitNewBornNPC(npcRefresh, tick)
+    gameFB.SetGameFBDict(rebornTickKey, tick)
+    
+    GameWorld.DebugLog("CrossBossRefresh mapID=%s,realMapID=%s,copyMapID=%s,refreshMark=%s,rebornNPCID=%s,OK!" 
+                       % (mapID, realMapID, copyMapID, refreshMark, rebornNPCID), lineID)
+    return
 
 ################################ 通用刷怪逻辑 ####################################
 def GetNPCRefreshCountList(refreshID):
@@ -784,3 +837,92 @@
 
 ################################################################################
 
+def ProcessMapRandomRefreshNPC(gameWorld, tick):
+    ''' 地图自定义随机刷怪,支持多点随机刷多种怪,标试点不可重复,支持跨服地图
+            注意:同个虚拟线路中,标试点不可重复!标试点不可重复!标试点不可重复!
+    '''
+    mapID = gameWorld.GetMapID()
+    # {mapID:{编号:[[多个NPCID], [多个标试点], 单个点最大数量, 所有点总数量, 刷怪间隔秒, 每整X小时], ...}, ...}
+    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)
+    
+    serverTime = GameWorld.GetCurrentTime()
+    curHour, curMinute = serverTime.hour, serverTime.minute
+    refreshNumList = []
+    for num, refreshInfo in mapRandRefreshNPCDict.items():
+        refreshCD = refreshInfo[4]
+        numLastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num)
+        perHours = refreshInfo[5]
+        if numLastTick and perHours:
+            if curHour % perHours != 0 or curMinute != 0:
+                continue
+            refreshCD = 65 # 1分钟内不重复刷新
+        if numLastTick and tick - numLastTick < refreshCD * 1000:
+            continue
+        gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num, tick)
+        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][:4]
+        
+        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
+

--
Gitblit v1.8.0