From a9a7475c8b637b04843a5553a182a8fac9416bbb Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期三, 16 一月 2019 11:50:09 +0800 Subject: [PATCH] 5722 【后端】【1.5】跨服BOSS开发(PK击杀全服广播、仙盟广播支援支持) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py | 294 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 277 insertions(+), 17 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 92db14a..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,6 +17,7 @@ import ShareDefine import ReadChConfig import GameLogic_SealDemon +import PlayerControl import IPY_GameWorld import IpyGameDataPY import GameWorld @@ -24,6 +25,7 @@ import FBLogic import random +import time #--------------------------------------------------------------------- ## 所有npc刷新 @@ -335,7 +337,50 @@ 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 要取活动线 + 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刷怪点刷怪个数: activityLineIndex=%s,refreshMark=%s" % (activityLineIndex, refreshMark)) + return ## 世界boss刷怪 # @param npcRefresh 刷新实例 @@ -345,10 +390,14 @@ '''非分流地图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 @@ -358,14 +407,48 @@ 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() - bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID - rebornBossState = gameWorldMgr.GetGameWorldDictByKey(bosskey) - isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) + isActivityBoss = False # 是否活动boss + # 关联日常活动 + if relatedType == 1: + actionKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % relatedID + rebornBossState = 1 if gameWorldMgr.GetGameWorldDictByKey(actionKey) else 0 + isActivityBoss = True + # 关联运营活动,待扩展 + elif relatedType == 2: + pass + else: + bosskey = ShareDefine.Def_Notify_WorldKey_GameWorldBossReborn % bossID + rebornBossState = gameWorldMgr.GetGameWorldDictByKey(bosskey) + + rebornLineID = 0 + activityLineID = 0 # 活动线, 默认1线 + activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {}) + if mapID in activityMapLineDict: + activityLineID = max(0, activityMapLineDict[mapID] - 1) + + # 活动boss只在活动线路刷 + if isActivityBoss: + activityBossRebornCount = gameFB.GetGameFBDictByKey(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark) + rebornLineID = activityLineID # 活动boss只刷在活动线 + # 不是活动线 + if rebornBossState and lineID != rebornLineID: + rebornBossState = 0 + + # 非活动boss活动线不刷, 1线除外 + else: + if activityLineID and lineID == activityLineID: + rebornBossState = 0 + stoneNPCID = 0 # 活动线暂不刷墓碑 + + isNeedShunt = NPCCommon.IsMapNeedBossShunt(mapID) and isNeedShunt curNPC = None if npcRefresh.GetCount() > 0: @@ -379,8 +462,13 @@ #去掉非bossNPC NPCCommon.SetDeadEx(curNPC) - # 非一线 且 不需要分流的地图 且 不是封魔坛 不允许复活 - if lineID != 0 and not isNeedShunt and mapID != ChConfig.Def_FBMapID_SealDemon: + # 非复活线 且 不需要分流的地图 且 不是封魔坛 不允许复活 + if lineID != rebornLineID and not isNeedShunt and mapID != ChConfig.Def_FBMapID_SealDemon: + return + + if isActivityBoss and activityBossRebornCount > 0: + #GameWorld.DebugLog("活动线已经刷过不再刷活动boss: lineID=%s,rebornLineID=%s,refreshMark=%s,bossID=%s,activityBossRebornCount=%s" + # % (lineID, rebornLineID, refreshMark, bossID, activityBossRebornCount)) return # 死亡状态 @@ -391,6 +479,11 @@ return if curNPC.GetNPCID() == stoneNPCID: return + # 活动的boss + if curNPC.GetNPCID() == bossID and isActivityBoss: + GameWorld.Log("活动boss,活动结束,系统设置boss死亡!bossID=%s" % bossID) + PlayerControl.FBNotify("FairyGrabBossNoDead", [bossID]) + #去掉非墓碑NPC NPCCommon.SetDeadEx(curNPC) @@ -415,25 +508,109 @@ #初始化NPC __InitNewBornNPC(npcRefresh, tick) gameFB.SetGameFBDict(key, tick) - GameWorld.DebugLog("BossRefresh mapID=%s,refreshMark=%s,rebornNPCID=%s,isNeedShunt=%s,OK!" % (mapID, refreshMark, rebornNPCID, isNeedShunt), lineID) + + if isActivityBoss and rebornBossState: + gameFB.SetGameFBDict(ChConfig.Map_NPC_ActivityBossRebornCount % refreshMark, activityBossRebornCount + 1) + + GameWorld.DebugLog("BossRefresh mapID=%s,rebornLineID=%s,refreshMark=%s,rebornNPCID=%s,isNeedShunt=%s,OK!" + % (mapID, rebornLineID, refreshMark, rebornNPCID, isNeedShunt), lineID) return def IsShuntBossNeedProcess(curNPC): '''分流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_CrossZoneTableName: + return + tableName = ChConfig.Def_CrossZoneTableName[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): @@ -723,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 + -- Gitblit v1.8.0