From f3f55bc0b986102ca0bd70063cafa11c04756fe1 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 16 四月 2019 10:14:55 +0800
Subject: [PATCH] 6459 【后端】【2.0】缥缈仙域开发单(地图刷怪逻辑修改,草园刷怪支持配置,支持开关线路保存刷怪信息)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 38 +++++++
PySysDB/PySysDBPY.h | 14 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py | 69 +++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py | 112 +++++++++++++++++----
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 10 ++
5 files changed, 220 insertions(+), 23 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 763aa91..89f6a1a 100644
--- a/PySysDB/PySysDBPY.h
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py
index d9fc0c7..0b2d18e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossGrassland.py
+++ b/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
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index db11233..e9efd34 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/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
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 d4c95eb..d1cbeb0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCustomRefresh.py
+++ b/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
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 a939d53..9948798 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/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:
--
Gitblit v1.8.0