From 675043eaa8d7f02469edd7f1699055796b3d203a Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 07 十二月 2023 14:27:24 +0800
Subject: [PATCH] 10019 【砍树】回合战斗(与玩家基础回合战斗)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/GameServerPyPack.ini                      |   10 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                      |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py               |   17 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChGameToMapPyPack.py               |   92 +++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ChMapToGamePyPack.py                                    |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActCollectWords.py    |    2 
 ServerPython/CoreServerGroup/GameServer/Script/ChGameToMapPyPack.py                                    |   92 +++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py       |    2 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py                               |   21 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                   |   63 ++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChMapToGamePyPack.py               |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                        |    9 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py      |   85 +++++++++++
 14 files changed, 401 insertions(+), 16 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChGameToMapPyPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChGameToMapPyPack.py
index 2f08604..a372b1f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChGameToMapPyPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChGameToMapPyPack.py
@@ -405,6 +405,98 @@
 
 
 #------------------------------------------------------
+# 03 03 玩家缓存信息同步 #tagGMPlayerCache
+
+class  tagGMPlayerCache(Structure):
+    Head = tagHead()
+    PlayerID = 0    #(DWORD PlayerID)//玩家ID
+    FindPlayerID = 0    #(DWORD FindPlayerID)//要查询的玩家ID
+    PropDataSize = 0    #(WORD PropDataSize)
+    PropData = ""    #(String PropData)//属性记录
+    PlusDataSize = 0    #(WORD PlusDataSize)
+    PlusData = ""    #(String PlusData)//扩展记录
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0x03
+        self.Head.SubCmd = 0x03
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FindPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PropDataSize,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PropData,_pos = CommFunc.ReadString(_lpData, _pos,self.PropDataSize)
+        self.PlusDataSize,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PlusData,_pos = CommFunc.ReadString(_lpData, _pos,self.PlusDataSize)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0x03
+        self.Head.SubCmd = 0x03
+        self.PlayerID = 0
+        self.FindPlayerID = 0
+        self.PropDataSize = 0
+        self.PropData = ""
+        self.PlusDataSize = 0
+        self.PlusData = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 2
+        length += len(self.PropData)
+        length += 2
+        length += len(self.PlusData)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteDWORD(data, self.FindPlayerID)
+        data = CommFunc.WriteWORD(data, self.PropDataSize)
+        data = CommFunc.WriteString(data, self.PropDataSize, self.PropData)
+        data = CommFunc.WriteWORD(data, self.PlusDataSize)
+        data = CommFunc.WriteString(data, self.PlusDataSize, self.PlusData)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                PlayerID:%d,
+                                FindPlayerID:%d,
+                                PropDataSize:%d,
+                                PropData:%s,
+                                PlusDataSize:%d,
+                                PlusData:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.PlayerID,
+                                self.FindPlayerID,
+                                self.PropDataSize,
+                                self.PropData,
+                                self.PlusDataSize,
+                                self.PlusData
+                                )
+        return DumpString
+
+
+m_NAtagGMPlayerCache=tagGMPlayerCache()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGMPlayerCache.Head.Cmd,m_NAtagGMPlayerCache.Head.SubCmd))] = m_NAtagGMPlayerCache
+
+
+#------------------------------------------------------
 #03 02 玩家领取补偿结果#tagGMRequestCompensationResult
 
 class  tagGMCompensationItem(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChMapToGamePyPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChMapToGamePyPack.py
index 53677c0..18c736d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChMapToGamePyPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChMapToGamePyPack.py
@@ -613,6 +613,7 @@
                   ("PlayerID", c_int),    #玩家ID
                   ("FindPlayerID", c_int),    #要查询的玩家ID
                   ("EquipClassLV", c_ubyte),    #大于0为查看指定境界阶装备信息,  0为查看默认信息
+                  ("CallMap", c_ubyte),    #是否需要通知地图
                   ]
 
     def __init__(self):
@@ -632,6 +633,7 @@
         self.PlayerID = 0
         self.FindPlayerID = 0
         self.EquipClassLV = 0
+        self.CallMap = 0
         return
 
     def GetLength(self):
@@ -646,14 +648,16 @@
                                 SubCmd:%s,
                                 PlayerID:%d,
                                 FindPlayerID:%d,
-                                EquipClassLV:%d
+                                EquipClassLV:%d,
+                                CallMap:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
                                 self.PlayerID,
                                 self.FindPlayerID,
-                                self.EquipClassLV
+                                self.EquipClassLV,
+                                self.CallMap
                                 )
         return DumpString
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
index 9c220f0..4c596ad 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -23,6 +23,7 @@
 import NetPackCommon
 import GameWorldArena
 import ChPyNetSendPack
+import ChGameToMapPyPack
 import PlayerFBHelpBattle
 import GameWorldSkyTower
 import CrossChampionship
@@ -238,16 +239,36 @@
 #    DWORD        PlayerID;        //玩家ID
 #    DWORD        FindPlayerID;    //要查询的玩家ID
 #    BYTE        EquipClassLV;    //大于0为查看指定境界阶装备信息,  0为查看默认信息
+#    BYTE        CallMap;        //是否需要通知地图
 #};
 def OnMGQueryPlayerCache(routeIndex, mapID, curPackData, tick):
     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)
     findPlayerID = curPackData.FindPlayerID
     equipClassLV = curPackData.EquipClassLV
+    callMap = curPackData.CallMap
     curCache = FindViewCache(findPlayerID)
     if not curCache:
         PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")
+        if callMap:
+            sendPack = ChGameToMapPyPack.tagGMPlayerCache()
+            sendPack.PlayerID = curPlayer.GetPlayerID()
+            sendPack.FindPlayerID = findPlayerID
+            sendPack.PropData = ""
+            sendPack.PropDataSize = len(sendPack.PropData)
+            sendPack.PlusData = ""
+            sendPack.PlusDataSize = len(sendPack.PlusData)
+            NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack) 
         return
     Sync_PlayerCache(curPlayer, curCache, equipClassLV)
+    if callMap:
+        sendPack = ChGameToMapPyPack.tagGMPlayerCache()
+        sendPack.PlayerID = curPlayer.GetPlayerID()
+        sendPack.FindPlayerID = findPlayerID
+        sendPack.PropData = curCache.PropData
+        sendPack.PropDataSize = len(sendPack.PropData)
+        sendPack.PlusData = curCache.PlusData
+        sendPack.PlusDataSize = len(sendPack.PlusData)
+        NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack) 
     return
 
 def Sync_PlayerCache(curPlayer, curCache, equipClassLV=0):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/GameServerPyPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/GameServerPyPack.ini
index 31a69f4..068dbfd 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/GameServerPyPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/GameServerPyPack.ini
@@ -42,6 +42,16 @@
 PacketSubCMD_1=0x02
 PacketCallFunc_1=OnGMRequestCompensationResult
 
+[PlayerViewCacheTube]
+ScriptName = Player\PlayerViewCacheTube
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0x03
+PacketSubCMD_1=0x03
+PacketCallFunc_1=OnGMPlayerCache
 
 [PlayerFriend]
 ScriptName = Player\PlayerFriend.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index 81e0310..73768b3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -477,7 +477,7 @@
 def IsPVPNPC(obj):
     if not obj:
         return False
-    return obj.GetGameObjType() == IPY_GameWorld.gotNPC and obj.GetType() in [ChConfig.ntPriWoodPilePVP]
+    return obj.GetGameObjType() == IPY_GameWorld.gotNPC and obj.GetType() in ChConfig.PVPNPCTypeList
 
 ## 获取攻击类型
 #  @param attack 攻击方对象
@@ -2259,6 +2259,7 @@
         aDamagePVP = 0      # PVP固定伤害
         aDamagePVE = 0      # PVE固定伤害
         aFinalHurt = NPCCommon.GetFinalHurt(atkObj) # 最终固定伤害
+        aOnlyFinalHurt = 0 # 额外固定伤害
         aFightPower = NPCCommon.GetSuppressFightPower(atkObj)
         
     #防守方的类型
@@ -2459,7 +2460,7 @@
             return "Robot"
         if obj.GetType() == ChConfig.ntHelpBattleRobot:
             return "HelpRobot"
-        if obj.GetType() == ChConfig.ntPriWoodPilePVP:
+        if obj.GetType() in ChConfig.PVPNPCTypeList:
             return "P"
         
     objType = obj.GetGameNPCObjType()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index 097fed2..9226dfb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -22,6 +22,7 @@
 import IpyGameDataPY
 import IPY_GameWorld
 import ChPyNetSendPack
+import PlayerViewCacheTube
 import NetPackCommon
 import PlayerControl
 import SkillCommon
@@ -57,8 +58,20 @@
         
     SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Start)
     
+    if tagPlayerID:
+        PlayerViewCacheTube.GetPlayerPropDataCall(curPlayer, tagPlayerID, DoTrunFightVSPlayer, [mapID, funcLineID])
+        return
+    
     DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick)
     
+    SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Over)
+    return
+
+def DoTrunFightVSPlayer(curPlayer, tagPlayerID, callData, PropDict):
+    mapID, funcLineID = callData
+    if PropDict:
+        tick = GameWorld.GetGameWorld().GetTick()
+        DoTrunFight(curPlayer, mapID, funcLineID, tagPlayerID, tick)
     SyncTurnFightState(curPlayer, mapID, funcLineID, tagPlayerID, FightState_Over)
     return
 
@@ -66,8 +79,8 @@
     playerID = curPlayer.GetPlayerID()
     tagObj = None
     if tagPlayerID:
-        pass
-    
+        npcID = ChConfig.Def_NPCID_PVP
+        tagObj = NPCCommon.SummonMapNpc(npcID, curPlayer.GetPosX(), curPlayer.GetPosY(), sightLevel=playerID, pvpPlayerID=tagPlayerID)
     else:
         ipyData = IpyGameDataPY.GetIpyGameData("FBTurn", mapID, funcLineID)
         if not ipyData:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 57a7fdd..4ad6a4e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3070,6 +3070,7 @@
 Def_NPC_Dict_SummonMapNPCPlayerID = 'SummonMapNPCPlayerID'
 Def_NPC_Dict_SummonRefreshID = 'SummonRefreshID'
 Def_NPC_Dict_PriWoodPilePlayerID = 'PriWoodPilePlayerID'
+Def_NPC_Dict_PVPPlayerID = 'PVPPlayerID'
 #NPC技能已使用次数
 Def_NPC_Dict_SkillUseCnt = 'NPCSkillUseCnt_%s' # 参数skillTypeID
 #不死的boss
@@ -5635,9 +5636,15 @@
 ntMonsterTime, #按时间掉血的怪物 22 废弃,以是否有配置在时间掉血怪物表为准
 ntPriWoodPilePVE, #专属私有木桩 - PVE 23
 ntPriWoodPilePVP, #专属私有木桩 - PVP 24
+ntPVP, # PVP玩家战斗镜像,有相互PK逻辑,不同于木桩(木桩仅被打) 25
 ntMax
-) = range(26)
+) = range(27)
 
+#视为PVP的NPC类型
+PVPNPCTypeList = [ntPriWoodPilePVP, ntPVP]
+
+#写死的NPCID
+Def_NPCID_PVP = 50000
 
 (Def_SkillFuncType_Common, #0为通用技能
 Def_SkillFuncType_FbSkill, #1为法宝功能获得的主动技能
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChGameToMapPyPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChGameToMapPyPack.py
index 2f08604..a372b1f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChGameToMapPyPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChGameToMapPyPack.py
@@ -405,6 +405,98 @@
 
 
 #------------------------------------------------------
+# 03 03 玩家缓存信息同步 #tagGMPlayerCache
+
+class  tagGMPlayerCache(Structure):
+    Head = tagHead()
+    PlayerID = 0    #(DWORD PlayerID)//玩家ID
+    FindPlayerID = 0    #(DWORD FindPlayerID)//要查询的玩家ID
+    PropDataSize = 0    #(WORD PropDataSize)
+    PropData = ""    #(String PropData)//属性记录
+    PlusDataSize = 0    #(WORD PlusDataSize)
+    PlusData = ""    #(String PlusData)//扩展记录
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0x03
+        self.Head.SubCmd = 0x03
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.FindPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PropDataSize,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PropData,_pos = CommFunc.ReadString(_lpData, _pos,self.PropDataSize)
+        self.PlusDataSize,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.PlusData,_pos = CommFunc.ReadString(_lpData, _pos,self.PlusDataSize)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0x03
+        self.Head.SubCmd = 0x03
+        self.PlayerID = 0
+        self.FindPlayerID = 0
+        self.PropDataSize = 0
+        self.PropData = ""
+        self.PlusDataSize = 0
+        self.PlusData = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 4
+        length += 2
+        length += len(self.PropData)
+        length += 2
+        length += len(self.PlusData)
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.PlayerID)
+        data = CommFunc.WriteDWORD(data, self.FindPlayerID)
+        data = CommFunc.WriteWORD(data, self.PropDataSize)
+        data = CommFunc.WriteString(data, self.PropDataSize, self.PropData)
+        data = CommFunc.WriteWORD(data, self.PlusDataSize)
+        data = CommFunc.WriteString(data, self.PlusDataSize, self.PlusData)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                PlayerID:%d,
+                                FindPlayerID:%d,
+                                PropDataSize:%d,
+                                PropData:%s,
+                                PlusDataSize:%d,
+                                PlusData:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.PlayerID,
+                                self.FindPlayerID,
+                                self.PropDataSize,
+                                self.PropData,
+                                self.PlusDataSize,
+                                self.PlusData
+                                )
+        return DumpString
+
+
+m_NAtagGMPlayerCache=tagGMPlayerCache()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGMPlayerCache.Head.Cmd,m_NAtagGMPlayerCache.Head.SubCmd))] = m_NAtagGMPlayerCache
+
+
+#------------------------------------------------------
 #03 02 玩家领取补偿结果#tagGMRequestCompensationResult
 
 class  tagGMCompensationItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChMapToGamePyPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChMapToGamePyPack.py
index 53677c0..18c736d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChMapToGamePyPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChMapToGamePyPack.py
@@ -613,6 +613,7 @@
                   ("PlayerID", c_int),    #玩家ID
                   ("FindPlayerID", c_int),    #要查询的玩家ID
                   ("EquipClassLV", c_ubyte),    #大于0为查看指定境界阶装备信息,  0为查看默认信息
+                  ("CallMap", c_ubyte),    #是否需要通知地图
                   ]
 
     def __init__(self):
@@ -632,6 +633,7 @@
         self.PlayerID = 0
         self.FindPlayerID = 0
         self.EquipClassLV = 0
+        self.CallMap = 0
         return
 
     def GetLength(self):
@@ -646,14 +648,16 @@
                                 SubCmd:%s,
                                 PlayerID:%d,
                                 FindPlayerID:%d,
-                                EquipClassLV:%d
+                                EquipClassLV:%d,
+                                CallMap:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
                                 self.PlayerID,
                                 self.FindPlayerID,
-                                self.EquipClassLV
+                                self.EquipClassLV,
+                                self.CallMap
                                 )
         return DumpString
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
index 9422613..d5063a6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/KillScreenNPC.py
@@ -82,7 +82,7 @@
         return
     if curNPC.GetCurAction() == IPY_GameWorld.laNPCDie:
         return
-    if curNPC.GetType() not in [IPY_GameWorld.ntMonster, ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
+    if curNPC.GetType() not in [IPY_GameWorld.ntMonster, ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP, ChConfig.ntPVP]:
         return
     if not curNPC.GetVisible():
         return
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 8542c3c..42d8693 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -55,6 +55,7 @@
 import PlayerNewFairyCeremony
 import GameLogic_CrossGrassland
 import PlayerActGarbageSorting
+import PlayerViewCacheTube
 import PlayerActBossTrial
 import PlayerTongTianLing
 import CrossPlayerData
@@ -2267,7 +2268,7 @@
 # @param aiType: AI类型
 # @return 如果召唤失败返回None 否则返回召唤的NPC的实例
 # @remarks 在地图里召唤NPC 根据NPCID 出生点 AI类型 和TICK
-def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0):
+def SummonMapNpc(npcId, rebornX, rebornY, aiType=0, lastTime=0, playerID=0, sightLevel=0, refreshID=0, pvpPlayerID=0):
     curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
     if not curSummon:
         return
@@ -2294,6 +2295,9 @@
         
     if curSummon.GetType() == ChConfig.ntRobot:
         __OnFBRobotReborn(curSummon, curSummon.GetLV())
+        
+    if curSummon.GetType() == ChConfig.ntPVP and pvpPlayerID:
+        curSummon.SetDict(ChConfig.Def_NPC_Dict_PVPPlayerID, pvpPlayerID)
         
     curSummon.Reborn(rebornX, rebornY, False)
     NPCControl(curSummon).DoNPCRebornCommLogic(tick)
@@ -2453,6 +2457,9 @@
     summonPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID)
     if summonPlayerID > 0:
         curNPC.SetDict(ChConfig.Def_NPC_Dict_SummonMapNPCPlayerID, 0)
+        
+    if curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PVPPlayerID):
+        curNPC.SetDict(ChConfig.Def_NPC_Dict_PVPPlayerID, 0)
         
     refreshObj = NPCRealmRefresh.GetTagNPCRefresh(curNPC)
     if refreshObj:
@@ -4054,8 +4061,12 @@
             PetControl.RefurbishPetAttr(curNPC, canSyncClient)
             return
         
-        DoNPCAttrStrengthen(curNPC, isReborn)
-
+        pvpPlayerID = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PVPPlayerID)
+        if pvpPlayerID:
+            self.SetPVPNPCPlayerAttr(pvpPlayerID)
+        else:
+            DoNPCAttrStrengthen(curNPC, isReborn)
+            
         #计算buf对战斗属性的改变
         allAttrList = SkillShell.CalcBuffer_NPCBattleEffect(curNPC)
         
@@ -4067,6 +4078,52 @@
             
         return
     
+    def SetPVPNPCPlayerAttr(self, pvpPlayerID):
+        PropDict = PlayerViewCacheTube.GetPlayerPropData(pvpPlayerID)
+        if not PropDict:
+            return
+        curNPC = self.__Instance
+        curNPC.SetCurLV(PropDict["LV"], False)
+        curNPC.SetMinAtk(PropDict["MinAtk"])
+        curNPC.SetMaxAtk(PropDict["MaxAtk"])
+        curNPC.SetDef(PropDict["Def"])
+        GameObj.SetMaxHP(curNPC, PropDict["MaxHP"])
+        curNPC.SetHit(PropDict["Hit"])
+        curNPC.SetMiss(PropDict["Miss"])
+        
+#        curPlayerPropDict["SkillAtkRate"] = curPlayer.GetSkillAtkRate() # 技能攻击比例加成
+#        curPlayerPropDict["SkillAtkRateReduce"] = PlayerControl.GetSkillAtkRateReduce(curPlayer) # 技能攻击比例减少
+#        curPlayerPropDict["LuckyHitRate"] = curPlayer.GetLuckyHitRate() # 会心一击几率
+#        curPlayerPropDict["LuckyHitVal"] = curPlayer.GetLuckyHitVal() # 会心一击伤害固定值
+#        curPlayerPropDict["LuckyHitRateReduce"] = PlayerControl.GetLuckyHitRateReduce(curPlayer) # 会心一击概率抗性
+#        curPlayerPropDict["LuckyHitReduce"] = PlayerControl.GetLuckyHitReduce(curPlayer) # 会心一击伤害减免固定值
+#        curPlayerPropDict["SuperHitRate"] = curPlayer.GetSuperHitRate() # 暴击概率
+#        curPlayerPropDict["SuperHit"] = curPlayer.GetSuperHit() # 暴击伤害固定值
+#        curPlayerPropDict["SuperHitRateReduce"] = PlayerControl.GetSuperHitRateReduce(curPlayer) # 暴击概率抗性
+#        curPlayerPropDict["SuperHitReduce"] = PlayerControl.GetSuperHitReduce(curPlayer) # 暴击伤害抗性固定值
+#        curPlayerPropDict["IceAtk"] = curPlayer.GetIceAtk() # 真实伤害            固定值
+#        curPlayerPropDict["IceDef"] = curPlayer.GetIceDef() # 真实伤害防御        固定值
+#        curPlayerPropDict["IgnoreDefRate"] = curPlayer.GetIgnoreDefRate() # 无视防御几率
+#        curPlayerPropDict["IgnoreDefRateReduce"] = PlayerControl.GetIgnoreDefRateReduce(curPlayer) # 无视防御概率抗性
+#        curPlayerPropDict["IgnoreDefReducePer"] = PlayerControl.GetIgnoreDefReducePer(curPlayer) # 无视防御伤害减免
+#        curPlayerPropDict["DamagePVE"] = PlayerControl.GetDamagePVE(curPlayer) # 伤害输出计算固定值PVE
+#        curPlayerPropDict["DamagePerPVP"] = PlayerControl.GetDamagePerPVP(curPlayer) # 伤害输出计算百分比PVP
+#        curPlayerPropDict["DamagePerPVPReduce"] = PlayerControl.GetDamagePerPVPReduce(curPlayer) # 伤害输出计算百分比PVP减少
+#        curPlayerPropDict["DamagePVP"] = PlayerControl.GetDamagePVP(curPlayer) # PVP固定伤害
+#        curPlayerPropDict["DamagePVPReduce"] = PlayerControl.GetDamagePVPReduce(curPlayer) # PVP固定减伤
+#        curPlayerPropDict["FinalHurt"] = PlayerControl.GetFinalHurt(curPlayer) # 最终固定伤害增加
+#        curPlayerPropDict["FinalHurtReduce"] = PlayerControl.GetFinalHurtReduce(curPlayer) # 最终固定伤害减少
+#        curPlayerPropDict["FinalHurtPer"] = PlayerControl.GetFinalHurtPer(curPlayer) # 最终伤害百分比
+#        curPlayerPropDict["FinalHurtReducePer"] = PlayerControl.GetFinalHurtReducePer(curPlayer) # 最终伤害减少百分比
+#        curPlayerPropDict["OnlyFinalHurt"] = PlayerControl.GetOnlyFinalHurt(curPlayer) # 额外输出伤害
+#        curPlayerPropDict["DamChanceDef"] = PlayerControl.GetDamChanceDef(curPlayer) # 20%的概率抵御伤害比率
+#        curPlayerPropDict["NPCHurtAddPer"] = PlayerControl.GetNPCHurtAddPer(curPlayer) # 对怪物伤害加成
+#        curPlayerPropDict["AtkBackHPPer"] = PlayerControl.GetAtkBackHPPer(curPlayer) # 攻击回复血量固定值
+#        curPlayerPropDict["PVPAtkBackHP"] = PlayerControl.GetPVPAtkBackHP(curPlayer) # PVP攻击回血
+#        curPlayerPropDict["FaintRate"] = PlayerControl.GetFaintRate(curPlayer) # 触发击晕
+#        curPlayerPropDict["FaintDefRate"] = PlayerControl.GetFaintDefRate(curPlayer) # 击晕抵抗
+        return
+    
     def SetHelpBattleRobotRebornAttr(self, fightPower):
         '''助战机器人只设置血量属性
                         血量算法,(助战玩家=助战机器人):每个副本配置伤害*(助战玩家战力/副本规定战力)*系数值  系数值暂定为50
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActCollectWords.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActCollectWords.py
index 1dde262..3781b58 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActCollectWords.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActCollectWords.py
@@ -100,7 +100,7 @@
 def OnKillNPCDrop(curPlayer, curNPC):
     ## 击杀NPC掉字逻辑
     
-    if curNPC.GetType() in [ChConfig.ntPriWoodPilePVP]:
+    if curNPC.GetType() in ChConfig.PVPNPCTypeList:
         return
     
     for actInfo in PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_CollectWords, {}).values():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
index f847acb..34ebc36 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -160,8 +160,7 @@
              
     return json.dumps(classItemDataDict, ensure_ascii=False).replace(" ", "")
 
-def GetPlayerPropPlusCache(curPlayer):
-    #玩家属性缓存
+def UpdPlayerPropPlusCache(curPlayer):
     curPlayerPropDict = {}
     curPlayerPropDict["AccID"] = curPlayer.GetAccID()
     curPlayerPropDict["LV"] = curPlayer.GetLV()
@@ -277,6 +276,19 @@
     #魂石、丹药使用个数
     curPlayerPlusDict["Fruit"] = PlayerAttrFruit.GetAttrFruitEatCntDict(curPlayer)
     
+    PyGameData.g_playerViewCache[curPlayer.GePlayerID()] = {"PropData":curPlayerPropDict, "PlusData":curPlayerPlusDict}
+    return
+
+def GetPlayerPropPlusCache(curPlayer):
+    #玩家属性缓存
+    UpdPlayerPropPlusCache(curPlayer)
+    return GetPlayerPropPlusCacheByID(curPlayer.GePlayerID())
+
+def GetPlayerPropPlusCacheByID(playerID):
+    #玩家属性缓存
+    viewCache = PyGameData.g_playerViewCache.get(playerID, {})
+    curPlayerPropDict = viewCache.get("PropData", {})
+    curPlayerPlusDict = viewCache.get("PlusData", {})
     PropData = json.dumps(curPlayerPropDict, ensure_ascii=False).replace(" ", "")
     PlusData = json.dumps(curPlayerPlusDict, ensure_ascii=False).replace(" ", "")
     return PropData, PlusData
@@ -411,3 +423,72 @@
     NetPackCommon.SendPyPackToGameServer(sendPack)  
     return
 
+def GetPlayerPropData(findPlayerID):
+    ## 获取玩家战斗属性数据  UpdPlayerPropPlusCache
+    viewCache = PyGameData.g_playerViewCache.get(findPlayerID, {})
+    return viewCache.get("PropData", {})
+
+def GetPlayerPropDataCall(curPlayer, findPlayerID, callFunc, callData=None, syncClient=True):
+    ## 获取玩家战斗属性数据 - 支持callback,因为地图可能暂时没有离线玩家缓存数据
+    
+    playerID = curPlayer.GetPlayerID()
+    dataDict = GetPlayerPropData(findPlayerID)
+    if dataDict:
+        if syncClient:
+            Sync_PlayerCache(curPlayer, findPlayerID)
+        callFunc(curPlayer, findPlayerID, callData, dataDict)
+        return dataDict
+    PyGameData.g_viewCacheCallback[playerID] = [callFunc, callData]
+    
+    #发送到GameServer去查询
+    sendPack = ChMapToGamePyPack.tagMGQueryPlayerCache()
+    sendPack.PlayerID = playerID
+    sendPack.FindPlayerID = findPlayerID
+    sendPack.EquipClassLV = 0
+    sendPack.CallMap = 1
+    NetPackCommon.SendPyPackToGameServer(sendPack)  
+    return
+
+def Sync_PlayerCache(curPlayer, tagPlayerID):
+    #回包客户端
+    PropData, PlusData = GetPlayerPropPlusCacheByID(tagPlayerID)
+    if not PropData:
+        return
+    sendPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()
+    sendPack.PlayerID = tagPlayerID
+    sendPack.PropData = PropData
+    sendPack.PropDataSize = len(sendPack.PropData)
+    sendPack.PlusData = PlusData
+    sendPack.PlusDataSize = len(sendPack.PlusData)
+    NetPackCommon.SendFakePack(curPlayer, sendPack)
+    return
+
+#// 03 03 玩家缓存信息同步 #tagGMPlayerCache
+def OnGMPlayerCache(curPackData, tick):
+    playerID = curPackData.PlayerID
+    findPlayerID = curPackData.FindPlayerID
+    PropData = curPackData.PropData
+    PlusData = curPackData.PlusData
+    
+    #GameWorld.DebugLog("玩家缓存信息同步到地图: playerID=%s,findPlayerID=%s" % (playerID, findPlayerID), playerID)
+    #GameWorld.DebugLog("    PropData=%s" % PropData, playerID)
+    #GameWorld.DebugLog("    PlusData=%s" % PlusData, playerID)
+    
+    curPlayerPropDict = {}
+    if PropData and PlusData:
+        curPlayerPropDict = eval(PropData)
+        curPlayerPlusDict = eval(PlusData)
+        PyGameData.g_playerViewCache[findPlayerID] = {"PropData":curPlayerPropDict, "PlusData":curPlayerPlusDict}
+        
+    if not playerID:
+        return
+    callback = PyGameData.g_viewCacheCallback.pop(playerID, None)
+    if not callback:
+        return
+    callFunc, callData = callback
+    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+    if not curPlayer:
+        return
+    callFunc(curPlayer, findPlayerID, callData, curPlayerPropDict)
+    return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index a481010..943c466 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -22,6 +22,9 @@
 g_needRefreshMapServerState = True # 常规地图分线人数是否有变更需要通知
 g_mapLastProcess_Minute = -1 # 地图上次处理的分钟
 
+g_playerViewCache = {} # {playerID:{k:v, ...}, ...} # 查看玩家数据缓存
+g_viewCacheCallback = {} # {playerID:any, ...} # 玩家数据缓存回调
+
 InitPyItem = False # 是否加载过物品表所需要的Py数据, 每张地图只在启动时执行一次
 DailyUseCountLimitItemIDList = [] # 每日有使用个数限制的物品ID列表
 EquipItemSkillIDList = [] # 装备技能ID列表

--
Gitblit v1.8.0