From 5fa02b1adbf1900358ab44a915cd9e841dcdf45f Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期日, 09 十月 2022 16:20:47 +0800
Subject: [PATCH] 9687 【后端】【越南】【主干】【BT7】野外根据境界动态刷怪

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                     |   52 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py                     |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                      |    2 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                          |   52 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py                |   65 ++++-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/QuestRunner.py      |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py                |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCRealmRefresh.py             |  210 +++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                   |   59 +++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                 |   25 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                   |  125 +++++++++--
 PySysDB/PySysDBPY.h                                                                                    |   21 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItem.py            |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                        |    1 
 15 files changed, 588 insertions(+), 47 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index b564235..1184158 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -496,6 +496,27 @@
 	DWORD		SuppressFightPower;	//推荐/压制战力
 };
 
+//成长型境界怪物表
+
+struct tagNPCRealmStrengthen
+{
+	DWORD		_NPCID;	//NPCID
+	BYTE		_RealmDifficulty;	//境界难度
+	DWORD		MapID;
+	DWORD		LV;	//NPC等级
+	DWORD		Exp;//基础经验
+	WORD		MaxDrapLV;//玩家最大可掉落等级
+	BYTE		EquipClassLV;	//掉落装备阶
+	DWORD		DropMoneyMin;//最小金币
+	DWORD		DropMoneyMax;//最大金币
+	WORD		LowLV;	// 推荐最低等级
+	WORD		HighestLV;	// 推荐最高等级
+	DWORD		Defense;	// 推荐防御
+	DWORD		MDef;	// 标准击杀时间/毫秒
+	DWORD		FireDef;	// 脱机挂经验计算战力
+	DWORD		SP;	// SP
+};
+
 //成长型怪物参数公式表
 
 struct tagNPCStrengthen
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 80108e3..9e0ca5d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -6550,6 +6550,58 @@
 
 
 #------------------------------------------------------
+# A2 35 选择境界难度层级 #tagCMSelectRealmDifficulty
+
+class  tagCMSelectRealmDifficulty(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("RealmDifficulty", c_ubyte),    #境界难度 = 100 + 所选境界等级,如境界13,则发113
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA2
+        self.SubCmd = 0x35
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xA2
+        self.SubCmd = 0x35
+        self.RealmDifficulty = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMSelectRealmDifficulty)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A2 35 选择境界难度层级 //tagCMSelectRealmDifficulty:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                RealmDifficulty:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.RealmDifficulty
+                                )
+        return DumpString
+
+
+m_NAtagCMSelectRealmDifficulty=tagCMSelectRealmDifficulty()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSelectRealmDifficulty.Cmd,m_NAtagCMSelectRealmDifficulty.SubCmd))] = m_NAtagCMSelectRealmDifficulty
+
+
+#------------------------------------------------------
 # A2 30 设置聊天气泡框 #tagCMSetChatBubbleBox
 
 class  tagCMSetChatBubbleBox(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index d29d140..eff6309 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3045,6 +3045,7 @@
 Def_NPC_Dict_FromRefreshValue = 'FromRefreshValue'
 #召唤地图NPC的玩家ID
 Def_NPC_Dict_SummonMapNPCPlayerID = 'SummonMapNPCPlayerID'
+Def_NPC_Dict_SummonRefreshID = 'SummonRefreshID'
 Def_NPC_Dict_PriWoodPilePlayerID = 'PriWoodPilePlayerID'
 #NPC技能已使用次数
 Def_NPC_Dict_SkillUseCnt = 'NPCSkillUseCnt_%s' # 参数skillTypeID
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 80108e3..9e0ca5d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -6550,6 +6550,58 @@
 
 
 #------------------------------------------------------
+# A2 35 选择境界难度层级 #tagCMSelectRealmDifficulty
+
+class  tagCMSelectRealmDifficulty(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("RealmDifficulty", c_ubyte),    #境界难度 = 100 + 所选境界等级,如境界13,则发113
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xA2
+        self.SubCmd = 0x35
+        return
+
+    def ReadData(self, stringData, _pos=0, _len=0):
+        self.Clear()
+        memmove(addressof(self), stringData[_pos:], self.GetLength())
+        return _pos + self.GetLength()
+
+    def Clear(self):
+        self.Cmd = 0xA2
+        self.SubCmd = 0x35
+        self.RealmDifficulty = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagCMSelectRealmDifficulty)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// A2 35 选择境界难度层级 //tagCMSelectRealmDifficulty:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                RealmDifficulty:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.RealmDifficulty
+                                )
+        return DumpString
+
+
+m_NAtagCMSelectRealmDifficulty=tagCMSelectRealmDifficulty()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMSelectRealmDifficulty.Cmd,m_NAtagCMSelectRealmDifficulty.SubCmd))] = m_NAtagCMSelectRealmDifficulty
+
+
+#------------------------------------------------------
 # A2 30 设置聊天气泡框 #tagCMSetChatBubbleBox
 
 class  tagCMSetChatBubbleBox(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/QuestRunner.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/QuestRunner.py
index 09ceb73..7438498 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/QuestRunner.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/QuestRunner.py
@@ -3848,7 +3848,8 @@
     
     effIndex = GameWorld.ToIntDef((curActionNode.GetAttribute("effIndex")), 0)
     
-    curMapItem = ChItem.AddMapDropItem(dropPos.GetPosX(), dropPos.GetPosY(), curItem, effIndex)
+    sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer)
+    curMapItem = ChItem.AddMapDropItem(dropPos.GetPosX(), dropPos.GetPosY(), curItem, effIndex, sightLevel=sightLevel)
     curMapItem.SetOwnerType(ChConfig.Def_NPCHurtTypePlayer)
     curMapItem.SetOwnerID(killPlayerID)
             
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItem.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItem.py
index 71466ed..7357f5b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItem.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MakeItem.py
@@ -23,6 +23,7 @@
 import GameWorld
 import ChConfig
 import ChItem
+import PlayerControl
 
 ## GM命令执行入口
 #  @param curPlayer 当前玩家
@@ -53,6 +54,7 @@
     doCount = 0
     dropCount = 0
     index = 0
+    sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer)
     for posX, posY in ChConfig.Def_DropItemAreaMatrix:
         doCount += 1
         resultX = dropPosX + posX
@@ -72,7 +74,7 @@
             continue
         
         # 在地上添加物品
-        ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[dropType, ownerID, specOwnerIDList])
+        ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[dropType, ownerID, specOwnerIDList], sightLevel=sightLevel)
         dropCount += 1
     
     GameWorld.DebugAnswer(curPlayer, "检测坐标数:%s 掉落数: %s" % (doCount, dropCount))
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 eaceeae..b27cf92 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
@@ -50,6 +50,7 @@
 import PyGameData
 import PlayerTeam
 import GameMap
+import NPCRealmRefresh
 #---------------------------------------------------------------------
 ## 副本开启
 #  @param gameWorld IPY_GameWorld
@@ -558,6 +559,7 @@
     
     #地图自定义随机刷怪
     NPCCustomRefresh.ProcessMapRandomRefreshNPC(gameWorld, tick)
+    NPCRealmRefresh.ProcessRealmNPCRefresh(gameWorld, tick)
     return
 
 ## 通知RouteServer 消息
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 51d13ad..232fb51 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -412,6 +412,24 @@
                         ("DWORD", "SuppressFightPower", 0),
                         ),
 
+                "NPCRealmStrengthen":(
+                        ("DWORD", "NPCID", 1),
+                        ("BYTE", "RealmDifficulty", 1),
+                        ("DWORD", "MapID", 0),
+                        ("DWORD", "LV", 0),
+                        ("DWORD", "Exp", 0),
+                        ("WORD", "MaxDrapLV", 0),
+                        ("BYTE", "EquipClassLV", 0),
+                        ("DWORD", "DropMoneyMin", 0),
+                        ("DWORD", "DropMoneyMax", 0),
+                        ("WORD", "LowLV", 0),
+                        ("WORD", "HighestLV", 0),
+                        ("DWORD", "Defense", 0),
+                        ("DWORD", "MDef", 0),
+                        ("DWORD", "FireDef", 0),
+                        ("DWORD", "SP", 0),
+                        ),
+
                 "NPCStrengthen":(
                         ("DWORD", "NPCID", 1),
                         ("BYTE", "IsStrengthenByPlayerCount", 0),
@@ -2774,6 +2792,43 @@
     def GetNPCID(self): return self.NPCID # NPCID
     def GetFightPowerLackAtkLimit(self): return self.FightPowerLackAtkLimit # 战力不足限制攻击
     def GetSuppressFightPower(self): return self.SuppressFightPower # 推荐/压制战力
+
+# 成长型境界怪物表
+class IPY_NPCRealmStrengthen():
+    
+    def __init__(self):
+        self.NPCID = 0
+        self.RealmDifficulty = 0
+        self.MapID = 0
+        self.LV = 0
+        self.Exp = 0
+        self.MaxDrapLV = 0
+        self.EquipClassLV = 0
+        self.DropMoneyMin = 0
+        self.DropMoneyMax = 0
+        self.LowLV = 0
+        self.HighestLV = 0
+        self.Defense = 0
+        self.MDef = 0
+        self.FireDef = 0
+        self.SP = 0
+        return
+        
+    def GetNPCID(self): return self.NPCID # NPCID
+    def GetRealmDifficulty(self): return self.RealmDifficulty # 境界难度
+    def GetMapID(self): return self.MapID
+    def GetLV(self): return self.LV # NPC等级
+    def GetExp(self): return self.Exp # 基础经验
+    def GetMaxDrapLV(self): return self.MaxDrapLV # 玩家最大可掉落等级
+    def GetEquipClassLV(self): return self.EquipClassLV # 掉落装备阶
+    def GetDropMoneyMin(self): return self.DropMoneyMin # 最小金币
+    def GetDropMoneyMax(self): return self.DropMoneyMax # 最大金币
+    def GetLowLV(self): return self.LowLV #  推荐最低等级
+    def GetHighestLV(self): return self.HighestLV #  推荐最高等级
+    def GetDefense(self): return self.Defense #  推荐防御
+    def GetMDef(self): return self.MDef #  标准击杀时间/毫秒
+    def GetFireDef(self): return self.FireDef #  脱机挂经验计算战力
+    def GetSP(self): return self.SP #  SP
 
 # 成长型怪物参数公式表
 class IPY_NPCStrengthen():
@@ -6165,6 +6220,8 @@
         self.ipyGMAttrLen = len(self.ipyGMAttrCache)
         self.ipyNPCExCache = self.__LoadFileData("NPCEx", IPY_NPCEx)
         self.ipyNPCExLen = len(self.ipyNPCExCache)
+        self.ipyNPCRealmStrengthenCache = self.__LoadFileData("NPCRealmStrengthen", IPY_NPCRealmStrengthen)
+        self.ipyNPCRealmStrengthenLen = len(self.ipyNPCRealmStrengthenCache)
         self.ipyNPCStrengthenCache = self.__LoadFileData("NPCStrengthen", IPY_NPCStrengthen)
         self.ipyNPCStrengthenLen = len(self.ipyNPCStrengthenCache)
         self.ipyNPCTimeLostHPCache = self.__LoadFileData("NPCTimeLostHP", IPY_NPCTimeLostHP)
@@ -6733,6 +6790,8 @@
     def GetGMAttrByIndex(self, index): return self.ipyGMAttrCache[index]
     def GetNPCExCount(self): return self.ipyNPCExLen
     def GetNPCExByIndex(self, index): return self.ipyNPCExCache[index]
+    def GetNPCRealmStrengthenCount(self): return self.ipyNPCRealmStrengthenLen
+    def GetNPCRealmStrengthenByIndex(self, index): return self.ipyNPCRealmStrengthenCache[index]
     def GetNPCStrengthenCount(self): return self.ipyNPCStrengthenLen
     def GetNPCStrengthenByIndex(self, index): return self.ipyNPCStrengthenCache[index]
     def GetNPCTimeLostHPCount(self): return self.ipyNPCTimeLostHPLen
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
index 8b201c3..4cc7ead 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -1078,7 +1078,8 @@
     
     #删除物品
     #ItemManager.DeleteItem(curItem)
-    curMapItem = AddMapDropItem(dropPosX, dropPosY, curItem.GetItem())
+    sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer)
+    curMapItem = AddMapDropItem(dropPosX, dropPosY, curItem.GetItem(), sightLevel=sightLevel)
     curMapItem.SetOwnerType(ChConfig.Def_NPCHurtTypePlayer)
     curMapItem.SetOwnerID(curPlayer.GetPlayerID())    
     
@@ -1807,6 +1808,7 @@
     index = 0
     playerID = curPlayer.GetPlayerID()
     gameMap = GameWorld.GetMap()
+    sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer)
     for posX, posY in ChConfig.Def_DropItemAreaMatrix:
         resultX = dropPosX + posX
         resultY = dropPosY + posY
@@ -1828,7 +1830,7 @@
             continue
         
         AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID], 
-                       dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee)    
+                       dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee, sightLevel=sightLevel)    
     return
 
 ## 在地上添加物品(统一接口)
@@ -1838,7 +1840,7 @@
 #  @param effIndex 要显示的特效索引
 #  @param ownerInfo 掉落归属信息[归属类型, 归属ID, [特殊归属玩家ID列表]]
 #  @return 返回值无意义
-def AddMapDropItem(itemPosX, itemPosY, curItem, effIndex=0, ownerInfo=[], dropNPCID=0, isOnlySelfSee=False):
+def AddMapDropItem(itemPosX, itemPosY, curItem, effIndex=0, ownerInfo=[], dropNPCID=0, isOnlySelfSee=False, sightLevel=0):
     itemDataStr = GetMapDropItemDataStr(curItem, effIndex, ownerInfo, dropNPCID, isOnlySelfSee)
     
     curMapItem = GameWorld.GetMapItemManager().AddDropItem(itemPosX, itemPosY, curItem,
@@ -1848,6 +1850,9 @@
         curMapItem.SetOwnerType(ownerType)
         curMapItem.SetOwnerID(ownerID)
         
+    if sightLevel > 0:
+        curMapItem.SetSightLevel(sightLevel)
+        
     if dropNPCID:
         itemNoteDict = ItemCommon.GetItemNoteDict(curItem, curItem.GetCount())
         GameWorld.Log("AddMapDropItem mapItemID=%s,ownerType=%s,ownerID=%s,mapItemDataStr=%s,itemNoteDict=%s" 
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 a1c5c46..f2320ef 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -59,6 +59,7 @@
 import PlayerFeastTravel
 import PlayerGoldInvest
 import PlayerWeekParty
+import NPCRealmRefresh
 import NPCHurtManager
 import PlayerActLogin
 import FamilyRobBoss
@@ -187,7 +188,15 @@
         randMinLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMinLV)
         randMaxLV = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NPCStrengthenMaxLV)
         strengthenLV = random.randint(randMinLV, randMaxLV)
-        
+    # 根据境界难度
+    elif lvStrengthenType == 5:
+        realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel())
+        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+        if realmNPCIpyData:
+            strengthenLV = realmNPCIpyData.GetLV()
+        else:
+            lvStrengthenType = 0
+            
     # 木桩怪最大、平均成长等级处理,直接取归属玩家等级
     if lvStrengthenType in [1, 2] and curNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
         owner = None
@@ -599,6 +608,7 @@
     index = 0
     playerID = curPlayer.GetPlayerID()
     gameMap = GameWorld.GetMap()
+    sightLevel = PlayerControl.GetMapRealmDifficulty(curPlayer)
     for posX, posY in ChConfig.Def_DropItemAreaMatrix:
         resultX = dropPosX + posX
         resultY = dropPosY + posY
@@ -620,7 +630,7 @@
             continue
         
         ChItem.AddMapDropItem(resultX, resultY, curItem, ownerInfo=[ChConfig.Def_NPCHurtTypePlayer, playerID], 
-                              dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee)
+                              dropNPCID=npcID, isOnlySelfSee=isOnlySelfSee, sightLevel=sightLevel)
     return
 
 def DoGiveItemByVirtualDrop(curPlayer, giveItemList, npcID, dropPosX=0, dropPosY=0, isDropDisperse=True, mailTypeKey="ItemNoPickUp", extraVirtualItemList=[]):
@@ -749,6 +759,15 @@
     if not ipyDrop:
         return
     
+    realmNPCIpyData = None
+    realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)
+    realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer)
+    if mapID in realmMapIDList and realmDifficulty:
+        realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty)
+        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+        #if realmNPCIpyData:
+        #    maxDropLV = realmNPCIpyData.GetMaxDrapLV()
+            
     #脱机暂不限制最大等级掉落
     #playerLV = dropPlayer.GetLV()
     #maxDropLV = ipyDrop.GetMaxDropLV()
@@ -820,6 +839,9 @@
     colorSuitPlaceKeyInfoDict = ipyDrop.GetEquipPartKeyRateInfo() # 装备部位集合信息 {(颜色,是否套装):部位集合key, ...}
     dropEquipIDDict = {}
     for classLV, color, dropCount in dropEquipInfoList:
+        if realmNPCIpyData:
+            classLV = realmNPCIpyData.GetEquipClassLV()
+            GameWorld.DebugLog("    脱机掉落对应难度境界装备: classLV=%s" % classLV, playerID)
         suitCountDict = {} # {套装:件数, ...}
         if color in colorSuitRateDict:
             suitRate = colorSuitRateDict[color]
@@ -882,7 +904,7 @@
         dropMoneyCnt += 1
     dropMoney = 0
     if dropMoneyCnt:
-        dropMoney = __GetDropMoneyValue(dropPlayer, ipyDrop) * dropMoneyCnt
+        dropMoney = __GetDropMoneyValue(dropPlayer, ipyDrop, realmNPCIpyData) * dropMoneyCnt
         GameWorld.DebugLog("    金币掉率: dropMoneyRate=%s,moneyTotalRate=%s,dropMoneyCnt=%s,dropMoney=%s" 
                            % (dropMoneyRate, moneyTotalRate, dropMoneyCnt, dropMoney), playerID)
     dropIDCountDict = {}
@@ -937,6 +959,16 @@
     playerID = dropPlayer.GetPlayerID()
     playerLV = dropPlayer.GetLV()
     maxDropLV = ipyDrop.GetMaxDropLV()
+    
+    realmNPCIpyData = None
+    realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)
+    realmDifficulty = PlayerControl.GetRealmDifficulty(dropPlayer)
+    if mapID in realmMapIDList and realmDifficulty:
+        realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty)
+        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+        if realmNPCIpyData:
+            maxDropLV = realmNPCIpyData.GetMaxDrapLV()
+            
     if maxDropLV and playerLV > maxDropLV:
         GameWorld.DebugLog("超过最大可掉落等级,不掉落物品!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))
         return
@@ -1066,6 +1098,10 @@
     
     for dropEquipInfo in dropEquipInfoList:
         classLV, color = dropEquipInfo[:2]
+        if realmNPCIpyData:
+            classLV = realmNPCIpyData.GetEquipClassLV()
+            GameWorld.DebugLog("掉落对应难度境界装备: classLV=%s" % classLV, playerID)
+            
         if color in colorMaxDropCntDict:
             maxCount = colorMaxDropCntDict[color]
             dropCount = colorDropCntDict.get(color, 0)
@@ -1179,7 +1215,7 @@
                 
     #GameWorld.DebugLog("NPCID=%s,金币掉率: %s, 执行次数=%s, 掉落金币数=%s" % (npcID, dropMoneyRate, dropMoneyDoCnt, dropMoneyCnt))
     if dropMoneyCnt:
-        moneyValue = __GetDropMoneyValue(dropPlayer, ipyDrop)
+        moneyValue = __GetDropMoneyValue(dropPlayer, ipyDrop, realmNPCIpyData)
         #GameWorld.DebugLog("    掉落金币value=%s" % (moneyValue))
         
     if dropIDList:
@@ -1597,12 +1633,15 @@
     #GameWorld.DebugLog("独立概率装备掉落结果: doCnt=%s, %s" % (doCnt, dropEquipInfoList))
     return dropEquipInfoList
 
-def __GetDropMoneyValue(curPlayer, ipyDrop):
+def __GetDropMoneyValue(curPlayer, ipyDrop, realmNPCIpyData):
     baseMoney = FBLogic.OnGetNPCDropMoney(curPlayer)
     if baseMoney <= 0:
         # 获得掉落数量
-        baseMoney = random.randint(ipyDrop.GetDropMoneyMin(), ipyDrop.GetDropMoneyMax())
-    
+        if realmNPCIpyData:
+            baseMoney = random.randint(realmNPCIpyData.GetDropMoneyMin(), realmNPCIpyData.GetDropMoneyMax())
+        else:
+            baseMoney = random.randint(ipyDrop.GetDropMoneyMin(), ipyDrop.GetDropMoneyMax())
+            
     if baseMoney <= 0:
         return 0
     
@@ -2140,7 +2179,7 @@
 # @param aiType: AI类型
 # @return 如果召唤失败返回None 否则返回召唤的NPC的实例
 # @remarks 在地图里召唤NPC 根据NPCID 出生点 AI类型 和TICK
-def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0):
+def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0):
     curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
     if not curSummon:
         return
@@ -2159,9 +2198,17 @@
     if playerID > 0:
         curSummon.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, playerID)
         
+    if sightLevel > 0:
+        curSummon.SetSightLevel(sightLevel)
+        
+    if refreshID > 0:
+        curSummon.SetDict(ChConfig.Def_NPC_Dict_SummonRefreshID, refreshID)
+        
     if curSummon.GetType() == ChConfig.ntRobot:
         __OnFBRobotReborn(curSummon, curSummon.GetLV())
-    curSummon.Reborn(rebornX, rebornY)
+        
+    curSummon.Reborn(rebornX, rebornY, False)
+    NPCControl(curSummon).DoNPCRebornCommLogic(tick)
     
     FBLogic.DoFBRebornSummonNPC(curSummon, tick)
     #__NotifyMapPlayerSummonMapNPC(npcId, rebornX, rebornY)
@@ -2318,7 +2365,11 @@
     summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)
     if summonPlayerID > 0:
         curNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, 0)
-    
+        
+    refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC)
+    if refreshObj:
+        refreshObj.SetDead(GameWorld.GetGameWorld().GetTick())
+        
     # 暗金boss
     if ChConfig.IsGameBoss(curNPC): 
         # 通知GameServer boss状态 封魔坛在副本里单独处理
@@ -3516,7 +3567,7 @@
     def __Func_GetRandPosInRefreshArea(self):
         curNPC = self.__Instance
         #得到地图刷新点
-        posMap = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+        posMap = self.GetRefreshPoint()
         #范围校验
         if not posMap:
             GameWorld.ErrLog("__Func_GetRandPosInRefreshArea GetRefreshPosAt error: return None! npcID=%s" % curNPC.GetNPCID())
@@ -3538,6 +3589,15 @@
         return posX, poxY
 
     #---------------------------------------------------------------------
+    def GetRefreshPoint(self):
+        curNPC = self.__Instance
+        refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC)
+        if refreshObj:
+            refreshPoint = refreshObj.GetRefreshPoint()
+        else:
+            refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+        return refreshPoint
+    
     ## 是否在移动范围内
     #  @param self 类实例
     #  @return 返回值真, 在移动范围内
@@ -3545,7 +3605,7 @@
     def IsInRefreshArea(self):
         #这个NPC是否在移动范围内
         curNPC = self.__Instance
-        refreshPoint = curNPC.GetRefreshPosAt(curNPC.GetCurRefreshPointIndex())
+        refreshPoint = self.GetRefreshPoint()
         #GameWorld.Log("posX = %d posY = %d, dist = %d"%(refreshPoint.GetPosX(), refreshPoint.GetPosY(), refreshPoint.GetMoveDist()))
         if self.GetIsInRefreshPoint(curNPC.GetPosX() , curNPC.GetPosY() , refreshPoint):
             return True
@@ -4170,11 +4230,11 @@
         npcID = curNPC.GetNPCID()
         specDropItemList = []
         
-        playerLV = dropPlayer.GetLV()
-        maxDropLV = ipyDrop.GetMaxDropLV()
-        if maxDropLV and playerLV > maxDropLV:
-            GameWorld.DebugLog("超过最大可掉落等级,不掉落物品,特殊掉落!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))
-            return specDropItemList
+        #playerLV = dropPlayer.GetLV()
+        #maxDropLV = ipyDrop.GetMaxDropLV()
+        #if maxDropLV and playerLV > maxDropLV:
+        #    GameWorld.DebugLog("超过最大可掉落等级,不掉落物品,特殊掉落!npcID=%s,playerLV(%s) > maxDropLV(%s)" % (npcID, playerLV, maxDropLV))
+        #    return specDropItemList
         
         auctionItemCanSell = ipyDrop.GetAucionItemCanSell()
         # 击杀次数掉落算摸怪
@@ -4250,8 +4310,10 @@
             dropIDList += [moneyID] * dropMoneyCnt
             
         specItemSign = "SpecItem"
-        playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...]  私有特殊掉落 + 击杀次数特殊掉落
-        dropIDList += [specItemSign] * len(playerSpecDropList)
+        playerSpecDropList = []
+        if dropInfo:
+            playerSpecDropList = self.__NPCSpecialDropItem(dropPlayer, ownerPlayerList, ipyDrop) # 特殊掉落 [[ownerPlayer, itemID, isAuctionItem, isDropInItemPack], ...]  私有特殊掉落 + 击杀次数特殊掉落
+            dropIDList += [specItemSign] * len(playerSpecDropList)
         
         if len(dropIDList) > 5:
             #打乱物品顺序
@@ -4262,6 +4324,7 @@
             GameWorld.ErrLog("Boss没有掉落: dropPlayerLV=%s,ipyWorldLV=%s,maxDropLV=%s" 
                              % (dropPlayer.GetLV(), ipyDrop.GetMaxWorldLV(), ipyDrop.GetMaxDropLV()), dropPlayer.GetPlayerID())
             
+        sightLevel = PlayerControl.GetMapRealmDifficulty(dropPlayer)
         gameMap = GameWorld.GetMap()
         dropPosX, dropPosY = curNPC.GetPosX(), curNPC.GetPosY() # 以NPC为中心点开始掉落
         index = 0
@@ -4312,7 +4375,7 @@
                     SendVirtualItemDrop(ownerPlayer, itemID, resultX, resultY, dropItemDataStr)
                     
             else:
-                self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID, isOnlySelfSee=isOnlySelfSee)
+                self.__MapCreateItem(curItem, resultX, resultY, ownerType, ownerID, isOnlySelfSee=isOnlySelfSee, sightLevel=sightLevel)
         return
     #---------------------------------------------------------------------
     ## NPC被杀死逻辑处理
@@ -4568,7 +4631,7 @@
         curNPC = self.__Instance
         
         # VIP杀怪加攻
-        PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, curNPC)
+        PlayerVip.DoAddVIPKillLVExp(lastHurtPlayer, GetNPCLV(curNPC))
         
         # SP值
         PlayerControl.AddZhenQiByKillNPC(lastHurtPlayer, curNPC.GetSP())
@@ -5109,7 +5172,14 @@
         if baseExp > 0:
             return baseExp
         
-        baseExp = curNPC.GetExp()
+        npcID = curNPC.GetNPCID()
+        realmLV = PlayerControl.GetDifficultyRealmLV(curNPC.GetSightLevel())
+        realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+        if realmNPCIpyData:
+            baseExp = realmNPCIpyData.GetExp()
+        else:
+            baseExp = curNPC.GetExp()
+            
         if baseExp == 0:
             #GameWorld.Log("杀怪经验异常,该NPC = %s,无经验"%(curNPC.GetID()))
             return 0
@@ -5143,7 +5213,7 @@
     #  @param dropType: 掉落类型
     #  @param ownerID: 归属者
     #  @return: None
-    def __MapCreateItem(self, curItem, posX, posY, dropType, ownerID, isOnlySelfSee=False):
+    def __MapCreateItem(self, curItem, posX, posY, dropType, ownerID, isOnlySelfSee=False, sightLevel=0):
         if not curItem:
             return
         
@@ -5162,7 +5232,7 @@
         # 在地上添加物品(统一接口)
         dropNPCID = 0 if not ChConfig.IsGameBoss(curNPC) else curNPCID
         specOwnerIDList = [player.GetPlayerID() for player in self.__ownerPlayerList] if dropType == ChConfig.Def_NPCHurtTypeSpecial else []
-        curMapItem = ChItem.AddMapDropItem(posX, posY, curItem, ownerInfo=[dropType, ownerID, specOwnerIDList], dropNPCID=dropNPCID, isOnlySelfSee=isOnlySelfSee)
+        curMapItem = ChItem.AddMapDropItem(posX, posY, curItem, ownerInfo=[dropType, ownerID, specOwnerIDList], dropNPCID=dropNPCID, isOnlySelfSee=isOnlySelfSee, sightLevel=sightLevel)
         
         #设置该物品生前拥有者(那个NPC掉落的)
         if curMapItem == None:
@@ -5555,7 +5625,12 @@
     npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
     if not npcData:
         return 0
-    baseExp = npcData.GetExp()
+    needRealmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer))
+    realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, needRealmLV)
+    if realmNPCIpyData:
+        baseExp = realmNPCIpyData.GetExp()
+    else:
+        baseExp = npcData.GetExp()
     if not baseExp:
         return 0
     npcLV = npcData.GetLV()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCRealmRefresh.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCRealmRefresh.py
new file mode 100644
index 0000000..7073fd2
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCRealmRefresh.py
@@ -0,0 +1,210 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package NPCRealmRefresh
+#
+# @todo:境界NPC刷怪
+# @author hxp
+# @date 2022-08-23
+# @version 1.0
+#
+# 详细描述: tagNPCRefresh.txt py读取该表刷怪规则
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-08-23 19:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import IpyGameDataPY
+import PlayerControl
+import NPCCommon
+import ChConfig
+
+import os
+
+class IPY_ChRefreshPos():
+    
+    def __init__(self):
+        self.posX = 0
+        self.posY = 0
+        self.area = 0
+        self.moveDist = 0
+        return
+    
+    def GetRandPosX(self): return self.posX
+    def GetRandPosY(self): return self.posY
+    def GetPosX(self): return self.posX
+    def GetPosY(self): return self.posY
+    def GetArea(self): return self.area
+    def GetMoveDist(self): return self.moveDist
+    
+class tagNPCRefresh():
+    
+    def __init__(self, RefreshID):
+        self.RefreshID = RefreshID
+        self.NPCID = 0
+        self.RefreshPoint = IPY_ChRefreshPos()
+        self.RefreshTotal = 0
+        self.RefreshCount = 0
+        self.RefreshTime = 0
+        self.RebornState = 0 # 是否复活状态
+        self.DeadTick = 0 # 上次死亡tick
+        return
+    
+    def GetRefreshID(self): return self.RefreshID
+    def GetNPCID(self): return self.NPCID
+    def GetRefreshPoint(self): return self.RefreshPoint
+    def GetRefreshTotal(self): return self.RefreshTotal
+    def GetRefreshCount(self): return self.RefreshCount
+    def GetRefreshTime(self): return self.RefreshTime
+    def GetRebornState(self): return self.RebornState
+    def GetDeadTick(self): return self.DeadTick
+    def SetReborn(self):
+        self.RebornState = 1
+        return
+    def SetDead(self, tick):
+        self.RebornState = 0
+        self.DeadTick = tick
+        return
+    
+def GetTagNPCRefresh(curNPC):
+    realmDiff = curNPC.GetSightLevel()
+    refreshID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonRefreshID)
+    
+    obj = None
+    if realmDiff in PyGameData.g_realmDiffNPCRefresh:
+        mapNPCRefresh = PyGameData.g_realmDiffNPCRefresh[realmDiff]
+        if refreshID in mapNPCRefresh:
+            obj = mapNPCRefresh[refreshID]
+    else:
+        if False:
+            obj = tagNPCRefresh(refreshID) # 这两行代码无用,只是为了方便 . 出代码提示
+            
+    return obj
+
+def GetMapRealmNPCRefresh(realm):
+    ''' 加载本地图  tagNPCRefresh.txt 刷怪规则
+    '''
+    
+    if realm in PyGameData.g_realmDiffNPCRefresh:
+        return PyGameData.g_realmDiffNPCRefresh[realm]
+    
+    filePath = os.path.join(ChConfig.GetDBPath(), "SysDB", "tagNPCRefresh.txt")
+    if not os.path.isfile(filePath):
+        GameWorld.ErrLog("can not find file = %s" % filePath)
+        raise Exception("can not find file = %s" % filePath)
+        
+    mapNPCRefresh = {}
+    curMapID = GameWorld.GetMap().GetMapID()
+    fileObj = open(filePath, 'rb')
+    content = fileObj.read()
+    fileObj.close()
+    infoList = content.split('\r\n')
+    for line in xrange(len(infoList)):
+        if line == 0:
+            continue
+        if not infoList[line]:
+            continue
+        rowList = infoList[line].split('\t')
+        if len(rowList) != 17:
+            continue
+        try:
+            MapID = int(rowList[2])
+            if curMapID != MapID:
+                continue
+            RefreshID = int(rowList[0])
+            NPCID = int(rowList[1])
+            if not NPCID:
+                continue
+            RefreshPos = eval(rowList[4])
+            RefreshTotal = int(rowList[5])
+            RefreshCount = int(rowList[6])
+            RefreshTime = int(rowList[8])
+            if not (type(RefreshPos) in [list, tuple] and len(RefreshPos) == 4 and isinstance(RefreshPos[0], int)):
+                GameWorld.ErrLog("tagNPCRefresh.txt line(%s) not processed." % (line + 1))
+                continue
+            refreshObj = tagNPCRefresh(RefreshID)
+            refreshObj.NPCID = NPCID
+            refreshObj.RefreshPoint.posX = RefreshPos[0]
+            refreshObj.RefreshPoint.posY = RefreshPos[1]
+            refreshObj.RefreshPoint.area = RefreshPos[2]
+            refreshObj.RefreshPoint.moveDist = RefreshPos[3]
+            refreshObj.RefreshTotal = RefreshTotal
+            refreshObj.RefreshCount = RefreshCount
+            refreshObj.RefreshTime = RefreshTime
+            mapNPCRefresh[RefreshID] = refreshObj
+        except:
+            GameWorld.ErrLog("tagNPCRefresh.txt line(%s) error." % (line + 1))
+            continue
+        
+    PyGameData.g_realmDiffNPCRefresh[realm] = mapNPCRefresh
+    GameWorld.Log("LoadMapRealmNPCRefresh mapID=%s,realm=%s,refreshIDList=%s" % (curMapID, realm, mapNPCRefresh.keys()))
+    return mapNPCRefresh
+
+def ProcessRealmNPCRefresh(gameWorld, tick):
+    mapID = gameWorld.GetMapID()
+    mapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)
+    if mapID not in mapIDList:
+        return
+    
+    playerDict = {}
+    copyPlayerMgr = GameWorld.GetMapCopyPlayerManager()
+    for realmDiff, playerIDList in PyGameData.g_realmDiffPlayerDict.items():
+        if not playerIDList:
+            continue
+        
+        mapNPCRefresh = GetMapRealmNPCRefresh(realmDiff)
+        if not mapNPCRefresh:
+            continue
+        
+        for refreshID, refreshObj in mapNPCRefresh.items():
+            if not refreshObj:
+                continue
+            if refreshObj.GetRebornState():
+                continue
+            
+            DeadTick = refreshObj.GetDeadTick()
+            RefreshTime = refreshObj.GetRefreshTime()
+            if DeadTick and RefreshTime:
+                if (tick - DeadTick) < RefreshTime:
+                    continue
+                
+            NPCID = refreshObj.GetNPCID()
+            npcData = GameWorld.GetGameData().FindNPCDataByID(NPCID)
+            if not npcData:
+                continue
+            
+            refreshPoint = refreshObj.GetRefreshPoint()
+            posX, posY = refreshPoint.GetPosX(), refreshPoint.GetPosY()
+            canRefresh = False
+            # 判断玩家是否可视
+            for playerID in playerIDList:
+                if playerID in playerDict:
+                    player = playerDict[playerID]
+                else:
+                    player = copyPlayerMgr.FindPlayerByID(playerID)                  
+                if not player:
+                    continue
+                playerDict[playerID] = player
+                playerRealm = PlayerControl.GetRealmDifficulty(player)
+                if playerRealm != realmDiff:
+                    continue
+                sight = player.GetSight()
+                playerPosX, playerPosY = player.GetPosX(), player.GetPosY()
+                if GameWorld.GetDist(posX, posY, playerPosX, playerPosY) <= sight:
+                    canRefresh = True
+                    break
+                
+            if not canRefresh:
+                continue
+            
+            if NPCCommon.SummonMapNpc(NPCID, posX, posY, npcData.GetAIType(), sightLevel=realmDiff, refreshID=refreshID):
+                refreshObj.SetReborn()
+                #GameWorld.DebugLog("ProcessNPCRefresh realmDiff=%s,NPCID=%s,posX=%s,posY=%s" % (realmDiff, NPCID, posX, posY), refreshID)
+                continue
+            
+    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 77ed195..cf80f03 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -1215,6 +1215,12 @@
     if not GameWorld.IsCrossServer() and (PlayerControl.GetCrossMapID(curPlayer) or PlayerControl.GetCustomMapID(curPlayer)):
         GameWorld.DebugLog("===登录本服地图时,处于跨服或自定义场景状态,不刷新视野!", curPlayer.GetPlayerID())
         PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
+    elif not GameWorld.IsCrossServer():
+        realmDifficulty = PlayerControl.GetMapRealmDifficulty(curPlayer)
+        if realmDifficulty:
+            GameWorld.DebugLog("===登录本服地图时,处于境界难度地图,自动设置难度! realmDifficulty=%s" % realmDifficulty, curPlayer.GetPlayerID())
+            PlayerControl.SetRealmDifficulty(curPlayer, realmDifficulty)
+            
     PlayerState.ChangePlayerSigh(curPlayer, tick)
     
     if GameWorld.IsCrossServer():
@@ -1573,6 +1579,12 @@
         if not GameWorld.IsCrossServer() and (PlayerControl.GetCrossMapID(curPlayer) or curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene)):
             GameWorld.DebugLog("===本服LoadMapOK时玩家处于跨服或自定义场景状态,不设置可见!", curPlayer.GetPlayerID())
             PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
+        elif not GameWorld.IsCrossServer():
+            realmDifficulty = PlayerControl.GetMapRealmDifficulty(curPlayer)
+            if realmDifficulty:
+                GameWorld.DebugLog("===本服LoadMapOK时玩家处于境界难度地图,自动设置难度!realmDifficulty=%s" % realmDifficulty, curPlayer.GetPlayerID())
+                PlayerControl.SetRealmDifficulty(curPlayer, realmDifficulty)
+                
         curPlayer.RefreshView()
         curPlayer.SetVisible(True)
         
@@ -6164,3 +6176,16 @@
         GameObj.SetHP(curPlayer, updHP)
         
     return
+
+#// A2 35 选择境界难度层级 #tagCMSelectRealmDifficulty
+#
+#struct    tagCMSelectRealmDifficulty
+#{
+#    tagHead        Head;
+#    BYTE        RealmDifficulty;    //境界难度 = 100 + 所选境界等级,如境界13,则发113
+#};
+def OnSelectRealmDifficulty(index, clientData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    PlayerControl.SetRealmDifficulty(curPlayer, clientData.RealmDifficulty)
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
index 89d3dbb..65abdbd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
@@ -299,7 +299,7 @@
     SetTJGTime(curPlayer, min(GetTJGTime(curPlayer) + addTime, maxTime))
     return
 
-def CalcTJGExp(curPlayer, times, npcData):
+def CalcTJGExp(curPlayer, times, npcData, realmNPCIpyData):
     lvIpyData = PlayerControl.GetPlayerLVIpyData(curPlayer.GetLV())
     if not lvIpyData:
         return 0
@@ -327,9 +327,19 @@
     aReFightPower = lvIpyData.GetReFightPower() # 等级表对应的战力
     aNPCHurtAddPer = PlayerControl.GetNPCHurtAddPer(curPlayer) #PVE 伤害加成万分率
     
-    npcExp = npcData.GetExp()
-    npcMaxHP = GameObj.GetHP(npcData)
-    npcCommendFightPower = NPCCommon.GetCommendFightPower(npcData)
+    npcID = npcData.GetNPCID()
+    if realmNPCIpyData:
+        attrDict = NPCCommon.GetNPCStrengthenAttrDict(npcID, realmNPCIpyData.GetLV())
+        npcExp = realmNPCIpyData.GetExp()
+        npcMaxHP = attrDict.get("MaxHP", GameObj.GetHP(npcData))
+        npcCommendFightPower = realmNPCIpyData.GetFireDef()
+        GameWorld.DebugLog("CalcTJGExp realmNPC npcID=%s,npcExp=%s,npcMaxHP=%s,npcCommendFightPower=%s" % (npcID, npcExp, npcMaxHP, npcCommendFightPower))
+    else:
+        npcExp = npcData.GetExp()
+        npcMaxHP = GameObj.GetHP(npcData)
+        npcCommendFightPower = NPCCommon.GetCommendFightPower(npcData)
+        GameWorld.DebugLog("CalcTJGExp npcID=%s,npcExp=%s,npcMaxHP=%s,npcCommendFightPower=%s" % (npcID, npcExp, npcMaxHP, npcCommendFightPower))
+        
     petSkillLV = 1
     petSkillPer = 10000
     
@@ -365,7 +375,7 @@
         aNPCHurtAddPer:%s, aFinalHurtPer:%s, 
         aIceAtk:%s, aDamagePVE:%s, aSkillAtkRate:%s, petMinAtk:%s, petMaxAtk:%s, petDamPer:%s, atkSpeed:%s,
         aIgnoreDefRate:%s, aLuckyHit:%s, aLuckyHitRate:%s, aBleedDamage:%s, aFinalHurt:%s, npcExp:%s, npcMaxHP:%s, npcCommendFightPower:%s,
-        petSkillLV:%s, petSkillPer:%s, skill:%s, petSkill:%s"""%(curPlayer.GetID(), curPlayer.GetLV(), times, npcData.GetNPCID(),
+        petSkillLV:%s, petSkillPer:%s, skill:%s, petSkill:%s"""%(curPlayer.GetID(), curPlayer.GetLV(), times, npcID,
             reExp, attackEff, aMinAtk, aMaxAtk, aSuperHitRate, aSuperHit, aNPCHurtAddPer, aFinalHurtPer,
             aIceAtk, aDamagePVE, aSkillAtkRate, petMinAtk, petMaxAtk, petDamPer,
             atkSpeed, aIgnoreDefRate, aLuckyHit, aLuckyHitRate, aBleedDamage, aFinalHurt, npcExp, npcMaxHP, npcCommendFightPower, petSkillLV,
@@ -418,8 +428,21 @@
     if not npcData:
         return finalAddExp
     
+    realmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer))
+    realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+    if realmNPCIpyData:
+        mDef = realmNPCIpyData.GetMDef()
+        npcLV = realmNPCIpyData.GetLV()
+        sp = realmNPCIpyData.GetSP()
+        GameWorld.DebugLog("OnTJGKillNPCByTimes npcID=%s,npcLV=%s,mDef=%s,sp=%s,realmLV=%s" % (npcID, npcLV, mDef, sp, realmLV))
+    else:
+        mDef = npcData.GetMDef()
+        npcLV = npcData.GetLV()
+        sp = npcData.GetSP()
+        GameWorld.DebugLog("OnTJGKillNPCByTimes npcID=%s,npcLV=%s,mDef=%s,sp=%s" % (npcID, npcLV, mDef, sp))
+        
     # 1. 经验
-    exp = CalcTJGExp(curPlayer, times, npcData)
+    exp = CalcTJGExp(curPlayer, times, npcData, realmNPCIpyData)
     playerControl = PlayerControl.PlayerControl(curPlayer)
     if exp > 0:
         finalAddExp = playerControl.AddExp(exp, ShareDefine.Def_ViewExpType_KillNPC)
@@ -430,10 +453,10 @@
 
     
     # GetMDef 用于 NPC被击杀时间效率 毫秒
-    if npcData.GetMDef() == 0:
+    if mDef == 0:
         return finalAddExp
     
-    killCnt = times*1000/npcData.GetMDef()
+    killCnt = times*1000/mDef
     if not killCnt:
         return finalAddExp
     
@@ -442,18 +465,18 @@
     # 2.物品
     OnTJGDropItems(curPlayer, npcID, killCnt)
     #任务道具
-    OnTJGDropTaskItems(curPlayer, npcData.GetLV(), killCnt)
+    OnTJGDropTaskItems(curPlayer, npcLV, killCnt)
     # VIP杀怪加攻
-    PlayerVip.DoAddVIPKillLVExp(curPlayer, npcData, killCnt)
+    PlayerVip.DoAddVIPKillLVExp(curPlayer, npcLV, killCnt)
     
     # SP值
-    PlayerControl.AddZhenQiByKillNPC(curPlayer, npcData.GetSP(), killCnt)
+    PlayerControl.AddZhenQiByKillNPC(curPlayer, sp, killCnt)
     
     # 击杀特定NPC成就
     PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_KillSpecificNPC, killCnt, [npcID])
     # 日常活动
     if not curPlayer.NomalDictGetProperty(ChConfig.Def_PDictType_TJGOnDayEx):
-        if npcData.GetLV()>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
+        if npcLV>=curPlayer.GetLV() - IpyGameDataPY.GetFuncCfg('DailyQuestKillMonster'):
             PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_KillNPC, killCnt)
     # 击杀任务怪, 杀怪日常已经没有了,暂时屏蔽
     #for _ in xrange(killCnt):
@@ -775,8 +798,11 @@
     if not npcData:
         return
     
+    realmLV = PlayerControl.GetDifficultyRealmLV(PlayerControl.GetRealmDifficulty(curPlayer))
+    realmNPCIpyData = IpyGameDataPY.GetIpyGameDataNotLog("NPCRealmStrengthen", npcID, realmLV)
+    
     # 1. 经验 
-    exp = CalcTJGExp(curPlayer, times, npcData)
+    exp = CalcTJGExp(curPlayer, times, npcData, realmNPCIpyData)
     expRate = PlayerControl.GetLimitExpRate(curPlayer, ChConfig.ExpRateLimitType_Recover)
     exp = int(exp * expRate / float(ChConfig.Def_MaxRateValue))
     # 通知脱机挂被杀是的时间 和 被杀后的脱机挂时间可获得的经验
@@ -984,14 +1010,23 @@
 
         maxMapID = mapID
         
+    GameWorld.DebugLog("FindTJGNPC maxMapID=%s" % maxMapID)
     if not maxMapID:
         return 0
     
     # ---找到挂机等级点---
     lv = curPlayer.GetLV()
     myPoint = None
-    mapList = IpyGameDataPY.GetIpyGameDataByCondition("MapEventPoint", {"MapID":maxMapID}, True)
-
+    
+    # 注: NPCRealmStrengthen MapEventPoint 这两张配置表需要确保相关共用字段命名一样
+    realmMapIDList = IpyGameDataPY.GetFuncEvalCfg("RealmDifficulty", 1)
+    realmDifficulty = PlayerControl.GetRealmDifficulty(curPlayer)
+    if maxMapID in realmMapIDList and realmDifficulty:
+        realmLV = PlayerControl.GetDifficultyRealmLV(realmDifficulty)
+        mapList = IpyGameDataPY.GetIpyGameDataByCondition("NPCRealmStrengthen", {"MapID":maxMapID, "RealmDifficulty":realmLV}, True)
+    else:
+        mapList = IpyGameDataPY.GetIpyGameDataByCondition("MapEventPoint", {"MapID":maxMapID}, True)
+        
     mapEffList = []  # 有效挂机点,同地图中存在不需要挂机的NPC点
     for mapInfo in mapList:
         if mapInfo.GetLowLV() == 0:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py
index d098736..1bd8fb9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py
@@ -538,7 +538,7 @@
     GameWorld.DebugLog("VIP杀怪等级信息同步开关, isOn=%s" % isOn, curPlayer.GetPlayerID())
     return
 
-def DoAddVIPKillLVExp(curPlayer, curNPC, killCount=1):
+def DoAddVIPKillLVExp(curPlayer, npcLV, killCount=1):
     ''' 击杀NPC增加VIP杀怪等级经验,只算击杀的,队员击杀无效
     '''
     
@@ -549,7 +549,6 @@
     if not mwID or not PlayerMagicWeapon.GetIsActiveMagicWeapon(curPlayer, mwID):
         return
     
-    npcLV = NPCCommon.GetNPCLV(curNPC)
     addExp = eval(IpyGameDataPY.GetFuncCompileCfg("VIPAddAtkEXP", 1))
     addExp *= killCount
     if not addExp:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index b883fa3..c53fa23 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -15,6 +15,8 @@
 #"""Version = 2017-09-05 21:30"""
 #-------------------------------------------------------------------------------
 g_mapIDTxtInfo = {} # MapID.txt 加载的信息
+g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
+g_realmDiffNPCRefresh = {} # {realm:{refreshID:tagNPCRefresh, ...}}
 
 g_commMapLinePlayerCountDict = {} # 常规地图分线人数 {mapID:{lineID:人数, ...}}
 g_needRefreshMapServerState = True # 常规地图分线人数是否有变更需要通知

--
Gitblit v1.8.0