PySysDB/PySysDBPY.h
@@ -969,6 +969,20 @@ char MoneyCount; //单次消耗金钱数量 }; //地图标试点NPC刷新 struct tagMapRefreshNPC { DWORD _MapID; //地图ID BYTE RefreshNum; //刷怪规则编号 list NPCIDList; //NPCID列表 list RefreshMarkList; //标试点列表 BYTE PointMaxCount; //单个点最大存在怪物数 BYTE TotalMaxCount; //所有点总怪物数 BYTE RefreshSeconds; //刷怪间隔秒 BYTE RefreshPerMinutes; //每整X分刷怪 }; //符印合成表 struct tagRuneCompound ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py
@@ -14,3 +14,72 @@ #------------------------------------------------------------------------------- #"""Version = 2019-04-15 16:30""" #------------------------------------------------------------------------------- import GameWorld import GameWorldProcess import NPCCustomRefresh import PyGameData def OnEnterFBEvent(curPlayer, mapID, lineID, tick): return True ## 开启副本 def OnOpenFB(tick): gameWorld = GameWorld.GetGameWorld() realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID() key = (realMapID, copyMapID) if key in PyGameData.g_crossFuncLineDataCache: refreshNPCInfo = PyGameData.g_crossFuncLineDataCache[key] GameWorld.DebugLog("副本开启根据保存的虚拟线路标试点刷怪信息刷怪: realMapID=%s,copyMapID=%s,refreshNPCInfo=%s" % (realMapID, copyMapID, refreshNPCInfo)) NPCCustomRefresh.OnFBOpenSetRandomRefreshNPCInfo(refreshNPCInfo, tick) return def GetCurFBFuncLineID(): ## 获取本线路功能线路ID return GameWorld.GetGameWorld().GetPropertyID() % 10000 / 10 def GetCurFBLineZoneID(): ## 获取本线路所属跨服分区 return GameWorld.GetGameWorld().GetPropertyID() / 10000 ## 进副本 def DoEnterFB(curPlayer, tick): playerID = curPlayer.GetPlayerID() zoneID = GetCurFBLineZoneID() funcLineID = GetCurFBFuncLineID() GameWorld.Log("DoEnterFB zoneID=%s,funcLineID=%s" % (zoneID, funcLineID), playerID) return ## 副本总逻辑计时器 def OnProcess(tick): #gameFB = GameWorld.GetGameFB() return ## 关闭副本 def OnCloseFB(tick): gameWorld = GameWorld.GetGameWorld() refreshNPCInfo = NPCCustomRefresh.GetCopyMapRandomRefreshNPCInfo() if refreshNPCInfo: realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID() key = (realMapID, copyMapID) PyGameData.g_crossFuncLineDataCache[key] = refreshNPCInfo GameWorld.DebugLog("缓存虚拟线路标试点刷怪信息: realMapID=%s,copyMapID=%s,refreshNPCInfo=%s" % (realMapID, copyMapID, refreshNPCInfo)) GameWorld.GetGameWorld().SetPropertyID(0) return ## 玩家退出副本 def DoExitFB(curPlayer, tick): return ##玩家主动离开副本. def DoPlayerLeaveFB(curPlayer, tick): gameWorld = GameWorld.GetGameWorld() #最后一人退出副本则关闭地图 if gameWorld.GetMapCopyPlayerManager().GetPlayerCount() == 1: GameWorldProcess.CloseFB(tick) return ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -783,6 +783,17 @@ ("char", "MoneyCount", 0), ), "MapRefreshNPC":( ("DWORD", "MapID", 1), ("BYTE", "RefreshNum", 0), ("list", "NPCIDList", 0), ("list", "RefreshMarkList", 0), ("BYTE", "PointMaxCount", 0), ("BYTE", "TotalMaxCount", 0), ("BYTE", "RefreshSeconds", 0), ("BYTE", "RefreshPerMinutes", 0), ), "RuneCompound":( ("DWORD", "TagItemID", 1), ("list", "NeedItem", 0), @@ -2986,6 +2997,29 @@ def GetInspireMaxLV(self): return self.InspireMaxLV # 鼓舞等级限制 def GetMoneyCount(self): return self.MoneyCount # 单次消耗金钱数量 # 地图标试点NPC刷新 class IPY_MapRefreshNPC(): def __init__(self): self.MapID = 0 self.RefreshNum = 0 self.NPCIDList = [] self.RefreshMarkList = [] self.PointMaxCount = 0 self.TotalMaxCount = 0 self.RefreshSeconds = 0 self.RefreshPerMinutes = 0 return def GetMapID(self): return self.MapID # 地图ID def GetRefreshNum(self): return self.RefreshNum # 刷怪规则编号 def GetNPCIDList(self): return self.NPCIDList # NPCID列表 def GetRefreshMarkList(self): return self.RefreshMarkList # 标试点列表 def GetPointMaxCount(self): return self.PointMaxCount # 单个点最大存在怪物数 def GetTotalMaxCount(self): return self.TotalMaxCount # 所有点总怪物数 def GetRefreshSeconds(self): return self.RefreshSeconds # 刷怪间隔秒 def GetRefreshPerMinutes(self): return self.RefreshPerMinutes # 每整X分刷怪 # 符印合成表 class IPY_RuneCompound(): @@ -4484,6 +4518,8 @@ self.ipySealDemonLen = len(self.ipySealDemonCache) self.ipyFbEncourageCache = self.__LoadFileData("FbEncourage", IPY_FbEncourage) self.ipyFbEncourageLen = len(self.ipyFbEncourageCache) self.ipyMapRefreshNPCCache = self.__LoadFileData("MapRefreshNPC", IPY_MapRefreshNPC) self.ipyMapRefreshNPCLen = len(self.ipyMapRefreshNPCCache) self.ipyRuneCompoundCache = self.__LoadFileData("RuneCompound", IPY_RuneCompound) self.ipyRuneCompoundLen = len(self.ipyRuneCompoundCache) self.ipyResourcesBackCache = self.__LoadFileData("ResourcesBack", IPY_ResourcesBack) @@ -4938,6 +4974,8 @@ def GetSealDemonByIndex(self, index): return self.ipySealDemonCache[index] def GetFbEncourageCount(self): return self.ipyFbEncourageLen def GetFbEncourageByIndex(self, index): return self.ipyFbEncourageCache[index] def GetMapRefreshNPCCount(self): return self.ipyMapRefreshNPCLen def GetMapRefreshNPCByIndex(self, index): return self.ipyMapRefreshNPCCache[index] def GetRuneCompoundCount(self): return self.ipyRuneCompoundLen def GetRuneCompoundByIndex(self, index): return self.ipyRuneCompoundCache[index] def GetResourcesBackCount(self): return self.ipyResourcesBackLen ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
@@ -855,12 +855,13 @@ ''' 地图自定义随机刷怪,支持多点随机刷多种怪,标试点不可重复,支持跨服地图 注意:同个虚拟线路中,标试点不可重复!标试点不可重复!标试点不可重复! ''' mapID = gameWorld.GetMapID() # {mapID:{编号:[[多个NPCID], [多个标试点], 单个点最大数量, 所有点总数量, 刷怪间隔秒, 每整X小时], ...}, ...} randRefreshNPCDict = IpyGameDataPY.GetFuncEvalCfg("RandomRefreshNPC", 1, {}) if mapID not in randRefreshNPCDict: if gameWorld.GetOpenState() != IPY_GameWorld.fbosOpen: #已经关闭了 return mapRandRefreshNPCDict = randRefreshNPCDict[mapID] mapID = gameWorld.GetMapID() refreshIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("MapRefreshNPC", mapID) if not refreshIpyDataList: return #copyMapID = gameWorld.GetCopyMapID() @@ -872,21 +873,26 @@ serverTime = GameWorld.GetCurrentTime() curHour, curMinute = serverTime.hour, serverTime.minute refreshNumList = [] for num, refreshInfo in mapRandRefreshNPCDict.items(): refreshCD = refreshInfo[4] minuteTotal = curHour * 60 + curMinute needRefreshIpyDataList = [] for ipyData in refreshIpyDataList: num = ipyData.GetRefreshNum() numLastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num) perHours = refreshInfo[5] if numLastTick and perHours: if curHour % perHours != 0 or curMinute != 0: if numLastTick: perMinutes = ipyData.GetRefreshPerMinutes() if perMinutes: if minuteTotal % perMinutes != 0: continue refreshCD = 60 # 1分钟内不重复刷新 else: refreshCD = ipyData.GetRefreshSeconds() if tick - numLastTick < refreshCD * 1000: continue refreshCD = 65 # 1分钟内不重复刷新 if numLastTick and tick - numLastTick < refreshCD * 1000: continue gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num, tick) refreshNumList.append(num) needRefreshIpyDataList.append(ipyData) if not refreshNumList: if not needRefreshIpyDataList: #GameWorld.DebugLog("没有需要刷怪的", copyMapID) return npcCountDict = {} # 标识点对应NPC数量 @@ -901,9 +907,12 @@ 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] #GameWorld.DebugLog("标试点怪物数: minuteTotal=%s,npcCountDict=%s" % (minuteTotal, npcCountDict), copyMapID) for ipyData in needRefreshIpyDataList: npcIDList = ipyData.GetNPCIDList() markList = ipyData.GetRefreshMarkList() maxCount = ipyData.GetPointMaxCount() totalMaxCount = ipyData.GetTotalMaxCount() curTotalCount = 0 for rMark in markList: @@ -911,13 +920,16 @@ refreshCount = totalMaxCount - curTotalCount #GameWorld.DebugLog(" num=%s,markList=%s,curTotalCount=%s,totalMaxCount=%s,refreshCount=%s" # % (num, markList, curTotalCount, totalMaxCount, refreshCount), copyMapID) #GameWorld.DebugLog(" npcIDList=%s,markList=%s,curTotalCount=%s,totalMaxCount=%s,refreshCount=%s" # % (npcIDList, markList, curTotalCount, totalMaxCount, refreshCount), copyMapID) if refreshCount <= 0: continue random.shuffle(markList) # 随机打乱顺序 #GameWorld.DebugLog(" markList=%s" % markList, copyMapID) isNeedRandom = len(markList) != totalMaxCount if isNeedRandom: markList = list(markList) random.shuffle(markList) # 随机打乱顺序,如果需要随机的话就用多个不同的标试点 #GameWorld.DebugLog(" markList=%s" % str(markList), copyMapID) for rMark in markList: if rMark not in rMarkNPCRefreshDict: #GameWorld.DebugLog(" 标试点不存在: rMark=%s" % rMark, copyMapID) @@ -940,3 +952,57 @@ return def GetCopyMapRandomRefreshNPCInfo(): ## 获取当前虚拟线路随机刷怪点NPC信息 gameWorld = GameWorld.GetGameWorld() mapID = gameWorld.GetMapID() refreshIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("MapRefreshNPC", mapID) if not refreshIpyDataList: return lastRefreshTickDict = {} gameFB = GameWorld.GetGameFB() for ipyData in refreshIpyDataList: num = ipyData.GetRefreshNum() lastRefreshTickDict[num] = gameFB.GetGameFBDictByKey(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num) markNPCDict = {} # 标识点对应NPC数量 gameNPC = GameWorld.GetNPCManager() for i in xrange(gameNPC.GetCustomNPCRefreshCount()): npcRefresh = gameNPC.GetCustomNPCRefreshAt(i) npcCount = npcRefresh.GetCount() if not npcCount: continue rMark = npcRefresh.GetRefreshMark() npcIDCountDict = {} for j in xrange(npcCount): curNPC = npcRefresh.GetAt(j) npcID = curNPC.GetNPCID() npcIDCountDict[npcID] = npcIDCountDict.get(npcID, 0) + 1 markNPCDict[rMark] = npcIDCountDict return lastRefreshTickDict, markNPCDict def OnFBOpenSetRandomRefreshNPCInfo(refreshNPCInfo, tick): ## 副本虚拟线路启动时,根据保存的标试点刷怪信息设置刷怪 lastRefreshTickDict, markNPCDict = refreshNPCInfo gameFB = GameWorld.GetGameFB() gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCTick, tick) for num, setTick in lastRefreshTickDict.items(): gameFB.SetGameFBDict(ChConfig.Def_RMark_RandomRefreshNPCNumTime % num, setTick) gameNPC = GameWorld.GetNPCManager() for i in xrange(gameNPC.GetCustomNPCRefreshCount()): npcRefresh = gameNPC.GetCustomNPCRefreshAt(i) rMark = npcRefresh.GetRefreshMark() if rMark not in markNPCDict: continue npcIDCountDict = markNPCDict[rMark] for npcID, count in npcIDCountDict.items(): GameWorld.DebugLog(" 副本启动刷怪: rMark=%s,npcID=%s,count=%s" % (rMark, npcID, count)) npcRefresh.Refresh(npcID, ChConfig.Def_NormalNPCAngryCount, count, False) __InitNewBornNPC(npcRefresh , tick) return ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -1617,6 +1617,16 @@ NotifyCode(curPlayer, "SingleEnterPK", [mapID]) return fbIpyData = FBCommon.GetFBIpyData(mapID) if fbIpyData: fbLineIpyData = FBCommon.GetFBLineIpyData(mapID, lineID, False) if not fbLineIpyData: GameWorld.DebugLog("副本表找不到副本对应功能线路!mapID=%s,lineID=%s" % (mapID, lineID)) return ret = FBCommon.CheckCanEnterFBComm(curPlayer, mapID, lineID, fbIpyData, fbLineIpyData) if ret != ShareDefine.EntFBAskRet_OK: return tick = GameWorld.GetGameWorld().GetTick() for mapIDList in ChConfig.Def_FB_MapID.values(): if mapID not in mapIDList: