From e17fcba64e93fceb1459b12cbe70663039d40314 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 11 一月 2024 18:22:45 +0800
Subject: [PATCH] 10019 【砍树】回合战斗(回合战斗buff持续时间处理及持续性buff定时触发时机处理支持;增加回合战斗死亡及复活支持;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py    |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py       |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py          |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py                              |  127 +++++---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                               |  132 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py       |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py    |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py                             |  255 +++++++++++++++---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py                            |    2 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                    |  132 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py                             |   16 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py       |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py                          |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py                    |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py             |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py          |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py    |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py                            |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py               |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py                               |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/BuffSkill.py                               |   61 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py    |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py                                       |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py       |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                      |    5 
 29 files changed, 692 insertions(+), 125 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 6965afa..60c8c3e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -47554,6 +47554,138 @@
 
 
 #------------------------------------------------------
+# B4 22 回合战斗角色死亡 #tagMCTurnFightObjDead
+
+class  tagMCTurnFightObjDead(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("ObjType", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x22
+        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 = 0xB4
+        self.SubCmd = 0x22
+        self.ObjID = 0
+        self.ObjType = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightObjDead)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 22 回合战斗角色死亡 //tagMCTurnFightObjDead:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                ObjType:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.ObjType
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightObjDead=tagMCTurnFightObjDead()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightObjDead.Cmd,m_NAtagMCTurnFightObjDead.SubCmd))] = m_NAtagMCTurnFightObjDead
+
+
+#------------------------------------------------------
+# B4 23 回合战斗角色复活 #tagMCTurnFightObjReborn
+
+class  tagMCTurnFightObjReborn(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("ObjType", c_ubyte),    
+                  ("HP", c_int),    # 复活后血量,求余亿部分
+                  ("HPEx", c_int),    # 复活后血量,整除亿部分
+                  ("RebornType", c_ubyte),    # 复活方式:1-灵宠技能复活;2-待扩展
+                  ("RebornValue1", c_int),    # 复活方式对应值1,由复活方式决定其值意义
+                  ("RebornValue2", c_int),    # 复活方式对应值2
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x23
+        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 = 0xB4
+        self.SubCmd = 0x23
+        self.ObjID = 0
+        self.ObjType = 0
+        self.HP = 0
+        self.HPEx = 0
+        self.RebornType = 0
+        self.RebornValue1 = 0
+        self.RebornValue2 = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightObjReborn)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 23 回合战斗角色复活 //tagMCTurnFightObjReborn:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                ObjType:%d,
+                                HP:%d,
+                                HPEx:%d,
+                                RebornType:%d,
+                                RebornValue1:%d,
+                                RebornValue2:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.ObjType,
+                                self.HP,
+                                self.HPEx,
+                                self.RebornType,
+                                self.RebornValue1,
+                                self.RebornValue2
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightObjReborn=tagMCTurnFightObjReborn()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightObjReborn.Cmd,m_NAtagMCTurnFightObjReborn.SubCmd))] = m_NAtagMCTurnFightObjReborn
+
+
+#------------------------------------------------------
 # B4 20 回合制战斗状态 #tagMCTurnFightState
 
 class  tagMCTurnFightState(Structure):
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 37c6264..5e7d9ce 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
@@ -62,6 +62,7 @@
 import ChNPC
 import BossHurtMng
 import NPCHurtMgr
+import TurnAttack
 
 import datetime
 import math
@@ -2285,7 +2286,7 @@
         dFinalHurtReduce = PlayerControl.GetFinalHurtReduce(defObj) # 最终固定伤害减少
         dBeHurtPer = PlayerControl.GetBeHurtPer(defObj)      # 加深受到伤害百分比
         dFightPower = PlayerControl.GetFightPower(defObj)
-        dFinalHurtReducePer = PlayerControl.GetFinalHurtReducePer(defObj)
+        dFinalHurtReducePer = GameObj.GetFinalHurtReducePer(defObj)
         dFinalHurtReducePer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(defObj, atkObj, curSkill, ChConfig.TriggerType_dFinalHurtReducePer)
         
     else:
@@ -2296,7 +2297,7 @@
         dFinalHurtReduce = 0        # 最终固定伤害减少
         dBeHurtPer = 0
         dFightPower = NPCCommon.GetSuppressFightPower(defObj)
-        dFinalHurtReducePer = 0             # 最终伤害减少百分比 默认0
+        dFinalHurtReducePer = GameObj.GetFinalHurtReducePer(defObj)
         
     #攻击字典 { 攻击类型 : '公式' }
     mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
@@ -2603,7 +2604,7 @@
     if not hurtValue:
         return
     
-    if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum):
+    if atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):
         pass
     else:
         tick = GameWorld.GetGameWorld().GetTick()
@@ -3014,6 +3015,9 @@
     if GameObj.GetHP(curObjDetel) > 0:
         return
     
+    if TurnAttack.SetKilled(curObjDetel):
+        return
+        
     #---玩家处理---
     if curObjDetel.GetGameObjType() == IPY_GameWorld.gotPlayer:
         playerControl = PlayerControl.PlayerControl(curObjDetel)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
index 02e8d34..92835f7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
@@ -24,6 +24,7 @@
 import ChNPC
 import GameObj
 import GameWorld
+import TurnAttack
 #---------------------------------------------------------------------
 Def_FB_NPCAI_SideList = []
 #---------------------------------------------------------------------
@@ -104,6 +105,8 @@
     
     #普通NPC
     if GameObj.GetHP(defender) <= 0:
+        if TurnAttack.SetKilled(defender):
+            return
         if not ChNPC.OnCheckCanDie(attacker, defender, skill, tick):
             return
         #副本
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
index e52fc10..a81ee3b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
@@ -24,6 +24,7 @@
 import PetControl
 import NPCCommon
 import SkillShell
+import TurnAttack
 import GameObj
 #---------------------------------------------------------------------
 
@@ -114,6 +115,8 @@
     
     #宠物死亡
     if GameObj.GetHP(curTagPet) <= 0:
+        if TurnAttack.SetKilled(curTagPet):
+            return
         curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
         curTagPetNPCControl.SetKilled()
     
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
index c24f3bd..81dde0a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
@@ -27,6 +27,7 @@
 import NPCCommon
 import ChNPC
 import PlayerTJG
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -115,6 +116,8 @@
         AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
         #触发被动buff
         #AttackCommon.DefenderSpringBuff(curTagPlayer, tick, BaseAttack.GetIsSuperHit())
+    elif TurnAttack.SetKilled(curTagPlayer):
+        pass
     else:
         #通知玩家
         if curTagPlayer.GetMapID() != ChConfig.Def_FBMapID_XMZZ:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
index c8c1aee..24bb3b2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
@@ -24,6 +24,7 @@
 import IPY_GameWorld
 import GameWorld
 import SkillShell
+import TurnAttack
 import GameObj
 #---------------------------------------------------------------------
 
@@ -132,6 +133,8 @@
     
     #召唤兽死亡
     if GameObj.GetHP(curTagSummonNPC) <= 0:
+        if TurnAttack.SetKilled(curTagSummonNPC):
+            return
         curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummonNPC)
         #召唤兽死亡
         curTagSummonNPCControl.SetKilled()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
index f47b37a..c51a06f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
@@ -29,6 +29,7 @@
 import SkillShell
 import ChNPC
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -110,6 +111,9 @@
         #执行击杀NPC逻辑
         curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
         
+        if TurnAttack.SetKilled(curTagNPC):
+            return
+        
         if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
             return
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
index d02b0c4..8f35f83 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
@@ -26,6 +26,7 @@
 import PetControl
 import SkillShell
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -126,6 +127,8 @@
     
     #宠物死亡
     if GameObj.GetHP(curTagPet) <= 0:
+        if TurnAttack.SetKilled(curTagPet):
+            return
         curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
         curTagPetNPCControl.SetKilled()
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
index c5f5266..5a5ea6d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
@@ -33,6 +33,7 @@
 import PetControl
 import SkillShell
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -149,6 +150,9 @@
         
         return
     
+    if TurnAttack.SetKilled(curTagPlayer):
+        return
+    
     if curPlayer != None:
         #执行玩家击杀玩家逻辑
         AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
index 86bcd47..45531eb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
@@ -26,6 +26,7 @@
 import PetControl
 import SkillShell
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -133,6 +134,8 @@
     
     #防守方召唤兽死亡
     if GameObj.GetHP(curTagSummon) <= 0:
+        if TurnAttack.SetKilled(curTagSummon):
+            return
         curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
         #召唤兽死亡
         curTagSummonNPCControl.SetKilled()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
index 0a5446e..85f948c 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
@@ -32,6 +32,7 @@
 import SkillShell
 import ChNPC
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -122,6 +123,8 @@
         return
     
     if GameObj.GetHP(curTagNormalNPC) <= 0:
+        if TurnAttack.SetKilled(curTagNormalNPC):
+            return
         if not ChNPC.OnCheckCanDie(curPlayer, curTagNormalNPC, skill, tick):
             return
         #执行击杀NPC逻辑
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
index 13d8df5..2bacd86 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
@@ -29,6 +29,7 @@
 import SkillCommon
 import PetControl
 import SkillShell
+import TurnAttack
 import GameObj
 #---------------------------------------------------------------------
 
@@ -138,6 +139,8 @@
     
     #宠物死亡
     if GameObj.GetHP(curTagPet) <= 0:
+        if TurnAttack.SetKilled(curTagPet):
+            return
         curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
         curTagPetNPCControl.SetKilled()
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
index 4c6d6a8..72b36e7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
@@ -31,6 +31,7 @@
 import FBLogic
 import GameObj
 import ChNPC
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -144,6 +145,8 @@
     
     #召唤兽死亡
     if GameObj.GetHP(curTagSummon) <=  0:
+        if TurnAttack.SetKilled(curTagSummon):
+            return
         NPCCommon.OnPlayerAttackNPCDie(curTagSummon, curPlayer, skill)
         FBLogic.DoFB_Player_KillNPC(curPlayer , curTagSummon , tick)
         #获得控制器
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
index 403c638..dc598c5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
@@ -33,6 +33,7 @@
 import SkillShell
 import ChNPC
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -143,6 +144,9 @@
     #玩家击杀NPC副本触发器
     curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
     
+    if TurnAttack.SetKilled(curTagNPC):
+        return
+    
     if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
         return
     
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
index 7c34c5a..9da9bbf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
@@ -26,6 +26,7 @@
 import PlayerControl
 import PetControl
 import SkillShell
+import TurnAttack
 import GameObj
 #---------------------------------------------------------------------
 
@@ -137,6 +138,8 @@
     
     #宠物死亡
     if GameObj.GetHP(curTagPet) <= 0:
+        if TurnAttack.SetKilled(curTagPet):
+            return
         curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
         curTagPetNPCControl.SetKilled()
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
index 2bdd44b..24c5c77 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
@@ -33,6 +33,7 @@
 import SkillShell
 import ChNPC
 import GameObj
+import TurnAttack
 #---------------------------------------------------------------------
 
 #---------------------------------------------------------------------
@@ -151,7 +152,10 @@
             AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
         
         return
-        
+    
+    if TurnAttack.SetKilled(curTagPlayer):
+        return
+    
     if curPlayer != None:
         #执行玩家击杀玩家逻辑
         AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
index f54d8b0..b657117 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
@@ -30,6 +30,7 @@
 import GameWorld
 import PlayerControl
 import SkillShell
+import TurnAttack
 import GameObj
 #---------------------------------------------------------------------
 
@@ -155,6 +156,8 @@
     
     #防守方召唤兽死亡
     if GameObj.GetHP(curTagSummon) <= 0:
+        if TurnAttack.SetKilled(curTagSummon):
+            return
         curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
         #召唤兽死亡
         curTagSummonNPCControl.SetKilled()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
index 3ab6448..f3a4525 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
@@ -272,12 +272,13 @@
 def Attack(attacker, defender, useSkill, tick, skillPercent=10000, skillEnhance=0, attackTime=1, isEnhanceSkill=False):
     global g_skillHurtList
     
-    if attacker.GetGameObjType() == IPY_GameWorld.gotNPC:
-        #Npc在防一次攻击限制, 防止眩晕时能进行普攻
-        if not OperControlManager.IsObjCanDoAction(attacker,
-                                                   ChConfig.Def_Obj_ActState_ServerSkill,
-                                                   ChConfig.Def_Action_Attack_Bit):
-            return  False
+    #if attacker.GetGameObjType() == IPY_GameWorld.gotNPC:
+    #    #Npc在防一次攻击限制, 防止眩晕时能进行普攻
+    #玩家也需要判断普攻
+    if not OperControlManager.IsObjCanDoAction(attacker,
+                                               ChConfig.Def_Obj_ActState_ServerSkill,
+                                               ChConfig.Def_Action_Attack_Bit):
+        return  False
 
     #判断攻击对象是否为敌人
     if not GetCanAttack(attacker, defender, useSkill, tick):
@@ -1742,8 +1743,7 @@
             GameWorld.DebugLog("击晕CD中! rate=%s,剩余tick=%s" % (rate, remainTick), attacker.GetID())
             return
         attacker.SetDict(ChConfig.Def_PlayerKey_AttrFaintCD, tick)
-        GameWorld.DebugLog("触发击晕! rate=%s,tagID=%s" % (rate, defender.GetID()), attacker.GetID())
-        
+    GameWorld.DebugLog("可触发击晕! rate=%s,tagID=%s" % (rate, defender.GetID()), attacker.GetID())
     SkillCommon.AddBuffBySkillType(defender, ChConfig.Def_SkillID_AtkerFaint, tick)
     return
 
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 1a11598..4b650a9 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -30,6 +30,7 @@
 import GameWorld
 import GameObj
 import PetControl
+import SkillShell
 
 (
 FightState_Start,
@@ -38,6 +39,10 @@
 FightState_Fail,
 FightState_Over,
 ) = range(5)
+
+(
+RebornType_PetSkill,
+) = range(1, 1 + 1)
 
 def GetObjName(gameObj):
     objName = gameObj.GetName()
@@ -121,10 +126,14 @@
     factionListB = fightPetObjListB + [tagObj]
     atkFactionList = [factionListA, factionListB]
     
+    # 设置战斗主体
+    curPlayer.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRole, 1)
+    tagObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightMainRole, 1)
+    
     # 战斗前初始化,可能会改变攻速,所以先初始化
     for faction, factionObjList in enumerate(atkFactionList, 1):
         for gameObj in factionObjList:
-            TurnFightObjStartInit(gameObj, faction, tick)
+            TurnFightObjStartInit(playerID, gameObj, faction, tick)
             
     #一个回合攻击顺序,为了后续逻辑统一,都是先确定好顺序
     sortType = 2 # 攻击顺序排序方式
@@ -150,13 +159,29 @@
         for gameObj in fightObjList:
             TurnFightObjPerTurnStart(gameObj, turnNum, tick)
             
+        isWin = CheckIswin(curPlayer, tagObj)
+        if isWin != None:
+            break
+        
         # 回合战斗: 轮流依次攻击
-        for gameObj in fightObjList:
-            if not gameObj or GameObj.GetHP(gameObj) <= 0:
+        for actionNum, gameObj in enumerate(fightObjList, 1):
+            if not gameObj:
+                # 没有对象可视为没有该节点
                 continue
-            faction = GameObj.GetFaction(gameObj)
+            
+            for obj in fightObjList:
+                TurnFightObjPerTurnActionnum(turnNum, actionNum, obj, tick)
+                                                
             objType = gameObj.GetGameObjType()
             objID = gameObj.GetID()
+            SyncTurnFightObjAction(curPlayer, turnNum, objType, objID)
+            
+            if GameObj.GetHP(gameObj) <= 0:
+                # 复活时机在自己行动节点
+                if not DoReborn(gameObj):
+                    continue
+                    
+            faction = GameObj.GetFaction(gameObj)
             objName = GetObjName(gameObj)
             curHP = GameObj.GetHP(gameObj)
             
@@ -165,28 +190,16 @@
             tagObjID = tagGameObj.GetID()
             tagHP = GameObj.GetHP(tagGameObj)
             
-            GameWorld.DebugLog("    ★回合%s %s 行动 : objType-ID-HP(%s-%s-%s), tagType-ID-HP(%s-%s-%s)" 
-                               % (turnNum, objName, objType, objID, curHP, tagObjType, tagObjID, tagHP))
-            SyncTurnFightObjAction(curPlayer, turnNum, objType, objID)
+            GameWorld.DebugLog("    ★回合%s.%s %s 行动 : objType-ID-HP(%s-%s-%s),curAtk=%s, tagType-ID-HP(%s-%s-%s)" 
+                               % (turnNum, actionNum, objName, objType, objID, curHP, gameObj.GetMaxAtk(), tagObjType, tagObjID, tagHP))
             
-            DoAttack(gameObj, tagGameObj, tick)
-            
-            playerDead = GameObj.GetHP(curPlayer) <= 0
-            tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0)
-            if not playerDead and not tagObjDead:
+            if not DoAttack(gameObj, tagGameObj, tick):
                 continue
             
-            if playerDead and tagObjDead:
-                isWin = False # 平局算失败
-                GameWorld.DebugLog("        双方被击杀,平局算失败: isWin=%s" % isWin)
-            elif playerDead:
-                isWin = False
-                GameWorld.DebugLog("        玩家被击杀,失败: isWin=%s" % isWin)
-            elif tagObjDead:
-                isWin = True # 胜利
-                GameWorld.DebugLog("        对手被击杀,胜利: isWin=%s" % isWin)
-            break
-        
+            isWin = CheckIswin(curPlayer, tagObj)
+            if isWin != None:
+                break
+            
         if isWin != None:
             break
         
@@ -200,11 +213,154 @@
                        % (mapID, funcLineID, tagPlayerID, isWin, overState), playerID)
     return
 
-def TurnFightObjStartInit(gameObj, faction, tick):
+def CheckIswin(curPlayer, tagObj):
+    ## 检查是否结束
+    # @return: None-未结束;True-获胜;False-失败
+    playerDead = GameObj.GetHP(curPlayer) <= 0 and GetRebornTypeInfo(curPlayer) == None
+    tagObjDead = (not tagObj or GameObj.GetHP(tagObj) <= 0) and GetRebornTypeInfo(tagObj) == None
+    
+    if not playerDead and not tagObjDead:
+        return
+    
+    isWin = None
+    if playerDead and tagObjDead:
+        isWin = False # 平局算失败
+        GameWorld.DebugLog("        双方被击杀,平局算失败: isWin=%s" % isWin)
+    elif playerDead:
+        isWin = False
+        GameWorld.DebugLog("        玩家被击杀,失败: isWin=%s" % isWin)
+    elif tagObjDead:
+        isWin = True # 胜利
+        GameWorld.DebugLog("        对手被击杀,胜利: isWin=%s" % isWin)
+        
+    return isWin
+
+def SetKilled(gameObj, killer=None):
+    if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole):
+        #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
+        return
+    
+    GameWorld.DebugLog("        %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), gameObj.GetID()))
+    GameObj.SetHP(gameObj, 0)
+    
+    playerID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightID)
+    if not playerID:
+        return
+    curPlayer = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(playerID)
+    if not curPlayer:
+        return
+    
+    # 通知前端
+    clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
+    clientPack.ObjID = gameObj.GetID()
+    clientPack.ObjType = gameObj.GetGameObjType()
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return True
+
+def GetRebornTypeInfo(gameObj):
+    ''' 获取可复活的方式信息
+    @return: None-代表不可复活
+    '''
+    if not gameObj:
+        return
+    
+    if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole):
+        # 仅主体可复活
+        return
+    
+    rebornCountMax = 1
+    curRebornCount = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnRebornCount)
+    if curRebornCount >= rebornCountMax:
+        GameWorld.DebugLog("%s 已经超过复活次数,不能再复活! curID=%s,curRebornCount=%s" % (GetObjName(gameObj), gameObj.GetID(), curRebornCount))
+        return
+    
+    # 检查是否有灵宠复活技能
+    for index in range(gameObj.GetSummonCount()):
+        curSummonNPC = gameObj.GetSummonNPCAt(index)
+        if not curSummonNPC:
+            continue
+        if not PetControl.IsPetNPC(curSummonNPC):
+            continue
+        skillManager = curSummonNPC.GetSkillManager()
+        for skillIndex in range(skillManager.GetSkillCount()):
+            skill = skillManager.GetSkillByIndex(skillIndex)
+            if skill.GetSkillType() != ChConfig.Def_SkillType_Revive:
+                continue
+            if not skill.GetRemainTime():
+                return RebornType_PetSkill, curSummonNPC, skill
+            
+    # 检查其他功能复活,待扩展...
+    
+    #GameWorld.DebugLog("    没有可以复活的方式!")
+    return
+
+def DoReborn(gameObj, hpPer=ChConfig.Def_MaxRateValue):
+    ## 执行复活
+    rebornTypeInfo = GetRebornTypeInfo(gameObj)
+    if rebornTypeInfo == None:
+        return
+    
+    objName = GetObjName(gameObj)
+    objID = gameObj.GetID()
+    objType = gameObj.GetGameObjType()
+    
+    rebornType = rebornTypeInfo[0]
+    rebornValue1, rebornValue2 = 0, 0
+    if rebornType == RebornType_PetSkill:
+        petNPC, skill = rebornTypeInfo[1:]
+        skill.SetRemainTime(skill.GetCoolDownTime())
+        hpPer = skill.GetEffect(0).GetEffectValue(0)
+        rebornValue1 = petNPC.GetID()
+        rebornValue2 = skill.GetSkillID()
+        
+    rebornCount = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnRebornCount) + 1
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnRebornCount, rebornCount)
+    setHP = int(GameObj.GetMaxHP(gameObj) * hpPer / float(ChConfig.Def_MaxRateValue))
+    GameObj.SetHP(gameObj, setHP)
+    
+    if objType == IPY_GameWorld.gotPlayer:
+        gameObj.ChangeAction(IPY_GameWorld.paNull)
+    else:
+        gameObj.ChangeAction(IPY_GameWorld.laNPCNull)
+        
+    curHP = GameObj.GetHP(gameObj)
+    GameWorld.DebugLog("复活 %s: rebornType=%s,objID=%s,hpPer=%s,curHP=%s,rebornCount=%s" % (objName, rebornType, objID, hpPer, curHP, rebornCount))
+    
+    playerID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightID)
+    if not playerID:
+        return
+    curPlayer = GameWorld.GetMapCopyPlayerManager().FindPlayerByID(playerID)
+    if not curPlayer:
+        return
+    
+    # 通知前端
+    clientPack = ChPyNetSendPack.tagMCTurnFightObjReborn()
+    clientPack.ObjID = gameObj.GetID()
+    clientPack.ObjType = gameObj.GetGameObjType()
+    clientPack.HP = curHP % ChConfig.Def_PerPointValue
+    clientPack.HPEx = curHP / ChConfig.Def_PerPointValue
+    clientPack.RebornType = rebornType
+    clientPack.RebornValue1 = rebornValue1
+    clientPack.RebornValue2 = rebornValue2
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return True
+
+def SetTimeline(gameObj, turnNum, actionNum):
+    '''设置回合制战斗所在时间节点
+    @param turnNum: 第几回合,如果在回合制战斗中,则回合数一定大于0,
+    @param actionNum: 第几个行动节点,每回合的行动节点会重置,也就是说行动节点0可视为每回合的起始节点,1位第一个行动目标节点,以此类推
+    '''
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightTimeline, turnNum * 100 + actionNum)
+    return
+
+def TurnFightObjStartInit(playerID, gameObj, faction, tick):
     ## 回合制战斗实例初始化
     if not gameObj:
         return
-    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 1)
+    isMainRole = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightMainRole)
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightID, playerID)
+    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnRebornCount, 0)
+    SetTimeline(gameObj, 1, 0)
     GameObj.SetFaction(gameObj, faction)
     GameObj.SetHPFull(gameObj)
     gameObj.RefreshView()
@@ -214,9 +370,9 @@
     objName = GetObjName(gameObj)
     fightPlaceNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_FightPetPlaceNum)
     
-    GameWorld.DebugLog("【 %s 初始化 %s 】 objID=%s,npcID=%s,atkSpeed=%s,HP=%s,Atk=%s,Def=%s" 
-                       % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID, 
-                          GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj), gameObj.GetMaxAtk(), gameObj.GetDef()))
+    GameWorld.DebugLog("【 %s 初始化 %s 】 objID=%s,npcID=%s,atkSpeed=%s,HP=%s,Atk=%s,Def=%s,isMainRole=%s" 
+                       % (objName, BaseAttack.GetObjAttackName(gameObj), gameObj.GetID(), npcID,
+                          GameObj.GetAtkSpeed(gameObj), GameObj.GetHP(gameObj), gameObj.GetMaxAtk(), gameObj.GetDef(), isMainRole))
     GameWorld.DebugLog("    闪避(%s,%s),暴击(%s,%s),击晕(%s,%s),连击(%s,%s),反击(%s,%s),吸血(%s,%s)" 
                        % (GameObj.GetMissRate(gameObj), GameObj.GetMissDefRate(gameObj),
                           GameObj.GetSuperHitRate(gameObj), GameObj.GetSuperHitRateReduce(gameObj),
@@ -242,9 +398,10 @@
                 continue
             skillIDList.append(curSkill.GetSkillID())
             if fightPlaceNum:
-                # 灵宠技能开始时直接进入CD
-                curSkill.SetLastUseTick(tick)
-                curSkill.SetRemainTime(curSkill.GetCoolDownTime())
+                if curSkill.GetSkillType() != ChConfig.Def_SkillType_Revive:
+                    # 灵宠技能开始时直接进入CD
+                    curSkill.SetLastUseTick(tick)
+                    curSkill.SetRemainTime(curSkill.GetCoolDownTime())
         GameWorld.DebugLog("    NPC技能: npcID=%s,skillIDList=%s" % (npcID, skillIDList))
         
     return
@@ -254,7 +411,7 @@
     if not gameObj:
         return
     
-    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, turnNum)
+    SetTimeline(gameObj, turnNum, 0)
     # 重置连击、反击数
     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0)
@@ -277,14 +434,23 @@
         skill.SetRemainTime(updRemainTime)
         GameWorld.DebugLog("    skillID=%s,remainTime=%s,updRemainTime=%s" % (skillID, remainTime, updRemainTime))
         
+    # 刷新定时处理的buff效果
+    SkillShell.ProcessPersistBuff(gameObj, tick)
+    return
+
+def TurnFightObjPerTurnActionnum(turnNum, actionNum, gameObj, tick):
+    ## 回合制战斗实例 - 每个行动节点处理
+    if not gameObj:
+        return
+    
+    SetTimeline(gameObj, turnNum, actionNum)
+    
+    objType = gameObj.GetGameObjType()
     if objType == IPY_GameWorld.gotPlayer:
+        #刷新玩家Buff时长
         gameObj.SetTickByType(ChConfig.TYPE_Player_Tick_Buff, 0)
-        gameObj.SetPersistBuffTick(0)
-        
-        #刷新玩家Buff
         reFlashBuff = PlayerState.ProcessRefreshBuffState(gameObj, tick)
-        #刷新玩家场景buff效果
-        PlayerState.ProcessPlayerBuffEffect(gameObj, tick)
+        #SkillShell.ProcessPersistBuff(gameObj, tick) # 定时处理的在每个时间节点有需要再开启,目前默认回合开始处理
         
         attrBuffResult, actBuffResult = PlayerState.ProcessRefreshActionBuffState(gameObj, tick)
         playerControl = PlayerControl.PlayerControl(gameObj)
@@ -311,7 +477,7 @@
     ## 回合制战斗实例结束重置
     if not gameObj:
         return
-    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnFightNum, 0)
+    SetTimeline(gameObj, 0, 0)
     gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0)
     GameObj.SetFaction(gameObj, 0)
     
@@ -324,6 +490,9 @@
     return
 
 def RecycleObj(gameObj):
+    ## 释放回合制战斗对象
+    
+    #灵宠跟召唤兽由主人回收时触发回收,不然会导致报错
     npcObjType = gameObj.GetGameNPCObjType()
     if npcObjType == IPY_GameWorld.gnotPet:
         #GameWorld.DebugLog("RecycleObj 灵宠不回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
@@ -333,9 +502,7 @@
         if curOwner and curOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
             #GameWorld.DebugLog("RecycleObj 召唤兽主人是NPC不回收 objID=%s,npcObjType=%s,%s,ownerID=%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID(), curOwner.GetID()))
             return
-    if GameObj.GetHP(gameObj) <= 0:
-        #GameWorld.DebugLog("RecycleObj 已死亡,不用重复回收 objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
-        return
+        
     #GameWorld.DebugLog("RecycleObj: objID=%s,npcObjType=%s,%s" % (gameObj.GetID(), npcObjType, gameObj.GetNPCID()))
     NPCCommon.SetDeadEx(gameObj)
     return
@@ -370,18 +537,18 @@
     tagHP = GameObj.GetHP(tagObj)
     GameWorld.DebugLog("            curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
     if tagHP <= 0 or curHP <= 0:
-        return
+        return True
     
     # 反击,反击可打断连击,所以优先判断
     if CanAtkBack(curObj, tagObj):
         DoAttack(tagObj, curObj, tick)
-        return
+        return True
     
     # 连击
     if CanCombo(curObj, tagObj):
         DoAttack(curObj, tagObj, tick)
         
-    return
+    return True
 
 def CanAtkBack(atkObj, defObj):
     ## 可否反击
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 86897ae..fd4728f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3067,7 +3067,10 @@
 
 #---Obj字典-------
 Def_Obj_Dict_Faction = 'Faction' # 所属阵营
-Def_Obj_Dict_TurnFightNum = 'TurnFightNum' # 回合制战斗当前轮次
+Def_Obj_Dict_TurnFightID = 'TurnFightID' # 回合制战斗所属玩家ID
+Def_Obj_Dict_TurnFightTimeline = 'TurnFightTimeline' # 回合制战斗时间线: 回合数*100+行动编号节点
+Def_Obj_Dict_TurnFightMainRole = 'TurnFightMainRole' # 是否回合制战斗主体,最终胜负由主体存活状态决定
+Def_Obj_Dict_TurnRebornCount = 'TurnRebornCount' # 回合战斗已复活次数
 Def_Obj_Dict_TurnComboNum = 'TurnComboNum' # 本回合已累计连击次数
 Def_Obj_Dict_TurnAtkBackNum = 'TurnAtkBackNum' # 本回合已累计反击次数
 Def_Obj_Dict_TurnBattleType = 'TurnBattleType' # 本次攻击战斗类型:TurnBattleType_xxx
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 6965afa..60c8c3e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -47554,6 +47554,138 @@
 
 
 #------------------------------------------------------
+# B4 22 回合战斗角色死亡 #tagMCTurnFightObjDead
+
+class  tagMCTurnFightObjDead(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("ObjType", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x22
+        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 = 0xB4
+        self.SubCmd = 0x22
+        self.ObjID = 0
+        self.ObjType = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightObjDead)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 22 回合战斗角色死亡 //tagMCTurnFightObjDead:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                ObjType:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.ObjType
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightObjDead=tagMCTurnFightObjDead()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightObjDead.Cmd,m_NAtagMCTurnFightObjDead.SubCmd))] = m_NAtagMCTurnFightObjDead
+
+
+#------------------------------------------------------
+# B4 23 回合战斗角色复活 #tagMCTurnFightObjReborn
+
+class  tagMCTurnFightObjReborn(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("ObjType", c_ubyte),    
+                  ("HP", c_int),    # 复活后血量,求余亿部分
+                  ("HPEx", c_int),    # 复活后血量,整除亿部分
+                  ("RebornType", c_ubyte),    # 复活方式:1-灵宠技能复活;2-待扩展
+                  ("RebornValue1", c_int),    # 复活方式对应值1,由复活方式决定其值意义
+                  ("RebornValue2", c_int),    # 复活方式对应值2
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x23
+        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 = 0xB4
+        self.SubCmd = 0x23
+        self.ObjID = 0
+        self.ObjType = 0
+        self.HP = 0
+        self.HPEx = 0
+        self.RebornType = 0
+        self.RebornValue1 = 0
+        self.RebornValue2 = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCTurnFightObjReborn)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 23 回合战斗角色复活 //tagMCTurnFightObjReborn:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                ObjType:%d,
+                                HP:%d,
+                                HPEx:%d,
+                                RebornType:%d,
+                                RebornValue1:%d,
+                                RebornValue2:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.ObjType,
+                                self.HP,
+                                self.HPEx,
+                                self.RebornType,
+                                self.RebornValue1,
+                                self.RebornValue2
+                                )
+        return DumpString
+
+
+m_NAtagMCTurnFightObjReborn=tagMCTurnFightObjReborn()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTurnFightObjReborn.Cmd,m_NAtagMCTurnFightObjReborn.SubCmd))] = m_NAtagMCTurnFightObjReborn
+
+
+#------------------------------------------------------
 # B4 20 回合制战斗状态 #tagMCTurnFightState
 
 class  tagMCTurnFightState(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
index 2f87806..ae67f97 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
@@ -179,6 +179,14 @@
     gameObj.SetDict(ChConfig.Def_PlayerKey_BloodShiledHurtEx, value / ShareDefine.Def_PerPointValue)
     return
 
+def GetFinalHurtReducePer(gameObj): return gameObj.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtReducePer)
+def SetFinalHurtReducePer(gameObj, value):
+    ## 最终伤害减免百分比
+    gameObj.SetDict(ChConfig.Def_PlayerKey_FinalHurtReducePer, value)
+    if gameObj.GetGameObjType() == IPY_GameWorld.gotPlayer:
+        PlayerControl.SendPropertyRefresh(gameObj, ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, value)
+    return
+
 def GetFaction(gameObj):
     faction = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_Faction)
     if faction:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
index 90d0128..25098df 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCAI/AICommon.py
@@ -306,7 +306,7 @@
         return False
 
     #CD时间
-    if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum):
+    if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):
         if useSkill.GetRemainTime():
             #GameWorld.Log('技能回合CD中 = %s, %s'%(useSkill.GetSkillName(), useSkill.GetRemainTime()))
             return False
@@ -452,7 +452,7 @@
 def DoAutoUseSkill(curNPC, curTag, tagDist, tick):
     #攻击僵持中
     if tick - curNPC.GetAttackTick() < curNPC.GetAtkInterval():
-        if not (PetControl.IsPet(curNPC) or curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum)):
+        if not (PetControl.IsPet(curNPC) or curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)):
             #GameWorld.Log('攻击僵持中')
             return False
     
@@ -482,6 +482,10 @@
         if not useSkill or useSkill.GetSkillTypeID() == 0:
             break
         
+        if useSkill.GetSkillType() == ChConfig.Def_SkillType_Revive:
+            #复活技能单独处理
+            continue
+        
         if useSkillIDOnDie and useSkillIDOnDie == useSkill.GetSkillID():
             #GameWorld.DebugLog("死亡释放的技能仅在死亡时才能释放!useSkillIDOnDie=%s" % useSkillIDOnDie)
             continue
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
index 1c37662..55f7719 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCHurtManager.py
@@ -726,7 +726,7 @@
     def __GetIsInRefreshPoint(self, curPosX, curPosY, refreshPoint):
         if not refreshPoint:
             curNPC = self.curNPC
-            if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum):
+            if curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):
                 return True
             if self.logDetail:
                 GameWorld.Log("        not refreshPoint=%s" % refreshPoint, self.npcID, self.lineID)
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 9d80ec4..813b00e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -6923,12 +6923,6 @@
     curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtPer, value)
     SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtPer, value)
     
-## 最终伤害减免百分比
-def GetFinalHurtReducePer(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurtReducePer)
-def SetFinalHurtReducePer(curPlayer, value):
-    curPlayer.SetDict(ChConfig.Def_PlayerKey_FinalHurtReducePer, value)
-    SendPropertyRefresh(curPlayer, ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, value)
-    
 ## 最终固定伤害增加
 def GetFinalHurt(curPlayer): return curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_FinalHurt)
 def SetFinalHurt(curPlayer, value):
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 70622e1..4cf25cc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
@@ -215,7 +215,7 @@
     curPlayerPropDict["FinalHurt"] = PlayerControl.GetFinalHurt(curPlayer) # 最终固定伤害增加
     curPlayerPropDict["FinalHurtReduce"] = PlayerControl.GetFinalHurtReduce(curPlayer) # 最终固定伤害减少
     curPlayerPropDict["FinalHurtPer"] = PlayerControl.GetFinalHurtPer(curPlayer) # 最终伤害百分比
-    curPlayerPropDict["FinalHurtReducePer"] = PlayerControl.GetFinalHurtReducePer(curPlayer) # 最终伤害减少百分比
+    curPlayerPropDict["FinalHurtReducePer"] = GameObj.GetFinalHurtReducePer(curPlayer) # 最终伤害减少百分比
     curPlayerPropDict["OnlyFinalHurt"] = PlayerControl.GetOnlyFinalHurt(curPlayer) # 额外输出伤害
     curPlayerPropDict["DamChanceDef"] = PlayerControl.GetDamChanceDef(curPlayer) # 20%的概率抵御伤害比率
     curPlayerPropDict["NPCHurtAddPer"] = PlayerControl.GetNPCHurtAddPer(curPlayer) # 对怪物伤害加成
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/BuffSkill.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/BuffSkill.py
index 560665d..d6d7cb4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/BuffSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/BuffSkill.py
@@ -351,6 +351,11 @@
         # 继承上一个buff的循环记录
         addBuff.SetProcessInterval(updProcessInterval)
         
+    turnFightTimeline = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)
+    if turnFightTimeline:
+        addBuff.SetCalcStartTick(turnFightTimeline)
+        #GameWorld.DebugLog("        SetCalcStartTick:%s, skillID=%s,objID=%s" % (turnFightTimeline, skillID, curObj.GetID()))
+        
     #设置buff属性
     __SetBuffValue(addBuff , plusValueList , buffOwner)
     
@@ -402,7 +407,7 @@
         PYSync_RefreshBuff(curObj, addBuff, SkillCommon.GetBuffType(curSkill), notifyAll=False, owner = buffOwner, errSkillID=skillID)
         
     #添加BUFF后的特殊处理
-    DoAddBuffOver(curObj, curSkill, addBuff, buffOwner, tick)
+    DoAddBuffOver(curObj, buffState, curSkill, addBuff, buffOwner, tick)
 
     #检查是否属于刷新BUFF
     #===========================================================================
@@ -419,7 +424,7 @@
 # @param addBuff 玩家身上的BUFF实例
 # @param tick 时间戳
 # @return None 
-def DoAddBuffOver(curObj, curSkill, addBuff, buffOwner, tick):
+def DoAddBuffOver(curObj, buffState, curSkill, addBuff, buffOwner, tick):
     #触发被动技能
     if buffOwner:
         PassiveBuffEffMng.OnPassiveSkillTrigger(buffOwner, curObj, curSkill, ChConfig.TriggerType_AddBuffOver, tick)
@@ -451,6 +456,10 @@
         
         callFunc(curObj, addBuff, curEffect, tick, buffOwner)
     
+    # 回合制下,持续型处理buff添加后立即处理一次
+    if isLstSkill and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline):
+        SkillShell.ProcessSinglePersistBuff(curObj, buffState, addBuff, tick, True)
+        
     return
 
 
@@ -565,7 +574,7 @@
 
     buffState.Sync_RefreshBuff(buffIndex, curBuff.GetRemainTime())
     
-    DoAddBuffOver(curObj, curBuff.GetSkill(), curBuff, buffOwner, GameWorld.GetGameWorld().GetTick())  
+    DoAddBuffOver(curObj, buffState, curBuff.GetSkill(), curBuff, buffOwner, GameWorld.GetGameWorld().GetTick())  
     return
 
 #---------------------------------------------------------------------
@@ -655,7 +664,8 @@
     
     index = 0
     isPlayerTJG = (curObj.GetGameObjType() == IPY_GameWorld.gotPlayer and PlayerTJG.GetIsTJG(curObj))
-    turnNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum) # 回合编号,大于0同时也代表回合制中
+    turnFightTimeline = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)
+    turnNum, actionNum = turnFightTimeline / 100, turnFightTimeline % 100
     
     skillIDListInDelBuff = []   # buff消失中需要处理添加buff,外层处理避免错乱
     
@@ -678,17 +688,42 @@
             #GameWorld.DebugLog("脱机挂状态下不刷新buff时间: skillTypeID=%s" % curSkill.GetSkillTypeID())
             continue
         
-        remainTime = curBuffRemainTime - ( tick - curBuff.GetCalcStartTick() )
+        # buff回合时长计算
         if turnNum > 0:
-            remainTime -= ChConfig.Def_PerTurnTick
-            GameWorld.DebugLog("    刷新buff时间: objID=%s,skillID=%s,remainTime=%s,turnNum=%s" % (curObj.GetID(), curSkill.GetSkillID(), remainTime, turnNum))
+            #回合制下持续性类型buff由process时机处理 ProcessSinglePersistBuff
+            if curSkill.GetSkillType() in ChConfig.Def_LstBuff_List:
+                index += 1
+                continue
+            calcTick = curBuff.GetCalcStartTick()
+            calcTurnNum, calcActionNum = calcTick / 100, calcTick % 100
+            passTurnNum = turnNum - calcTurnNum # 经过的回合数
+            if passTurnNum > 0:
+                if actionNum < calcActionNum:
+                    passTurnNum -= 1 # 还未到该buff的计算节点,可视为本回合未到,需-1
+                    
+            remainTime = curBuffRemainTime
+            if passTurnNum > 0: # 最小单位1回合,有满1回合才减时长
+                remainTime = curBuffRemainTime - ChConfig.Def_PerTurnTick * passTurnNum
+                GameWorld.DebugLog("    刷新回合buff时间: objID=%s,skillID=%s,remainTime=%s,calcTick=%s,timeline=%s,passTurnNum=%s" 
+                                   % (curObj.GetID(), curSkill.GetSkillID(), remainTime, calcTick, turnFightTimeline, passTurnNum))
+                curBuff.SetCalcStartTick(turnFightTimeline)
+                curBuff.SetRemainTime(remainTime)
+                
+            #还有剩余时间
+            if remainTime > 0:
+                index += 1
+                continue
             
-        #还有剩余时间
-        if remainTime > 0:
-            curBuff.SetCalcStartTick( tick ) 
-            curBuff.SetRemainTime( remainTime )
-            index += 1
-            continue
+        # buff常规时长计算
+        else:
+            remainTime = curBuffRemainTime - ( tick - curBuff.GetCalcStartTick() )
+                
+            #还有剩余时间
+            if remainTime > 0:
+                curBuff.SetCalcStartTick( tick ) 
+                curBuff.SetRemainTime( remainTime )
+                index += 1
+                continue
         #-------------------无剩余时间了
         curBuff.SetRemainTime(0)
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py
index a825d98..4c05949 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/EffGetSet.py
@@ -168,7 +168,7 @@
    [lambda curObj:PlayerControl.GetNormalHurtPer(curObj), lambda curObj, value:PlayerControl.SetNormalHurtPer(curObj, value), ShareDefine.CDBPlayerRefresh_NormalHurtPer, 1, 0],  # 属性普通攻击加成
    [lambda curObj:PlayerControl.GetFabaoHurt(curObj), lambda curObj, value:PlayerControl.SetFabaoHurt(curObj, value), ShareDefine.CDBPlayerRefresh_FabaoHurt, 1, 0],  # 属性法宝技能增伤
    [lambda curObj:PlayerControl.GetFabaoHurtPer(curObj), lambda curObj, value:PlayerControl.SetFabaoHurtPer(curObj, value), ShareDefine.CDBPlayerRefresh_FabaoHurtPer, 1, 0],  # 属性法宝技能加成
-   [lambda curObj:PlayerControl.GetFinalHurtReducePer(curObj), lambda curObj, value:PlayerControl.SetFinalHurtReducePer(curObj, value), ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, 1, 0],      # 最终伤害减少百分比
+   [lambda curObj:GameObj.GetFinalHurtReducePer(curObj), lambda curObj, value:GameObj.SetFinalHurtReducePer(curObj, value), ShareDefine.CDBPlayerRefresh_FinalHurtReducePer, 1, 0],      # 最终伤害减少百分比
    [lambda curObj:PlayerControl.GetLostYinjiTime(curObj), lambda curObj, value:PlayerControl.SetLostYinjiTime(curObj, value), ShareDefine.CDBPlayerRefresh_YinjiTime, 1, 0],    # 每X秒自动消失一个印记 毫秒
    [lambda curObj:PlayerControl.GetTheFBSkillsCD(curObj), lambda curObj, value:PlayerControl.SetTheFBSkillsCD(curObj, value), 0, 0, 0],    # 减少指定技能组CD XX%
    [lambda curObj:PlayerControl.GetBurnValue(curObj), lambda curObj, value:PlayerControl.SetBurnValue(curObj, value), 0, 0, 0],    # 灼烧固定伤害
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
index 6bad0d9..58321d4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
@@ -2423,53 +2423,79 @@
     if not buffStateCount:
         return
     
-    turnNum = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightNum) # 回合编号,大于0同时也代表回合制中
-    
-    #buff持续效果
-    for i in range(0, buffStateCount):
+    #buff持续效果,回合下可能删除buff,倒序遍历
+    for i in range(0, buffStateCount)[::-1]:
         curBuff = buffState.GetBuff(i)
+        ProcessSinglePersistBuff(curObj, buffState, curBuff, tick)
         
-        if not curBuff:
-            #在以下处理过程中, 对方有可能死亡, 如果死亡, 会清空buff, 导致这里取得None
-            #所以一定要continue 
-            continue
-        
-        curBuffSkill = curBuff.GetSkill()
-        
-        if not __BuffCanProcess(curObj, curBuffSkill):
-            continue
-
-        processBuffTick = GetProcessBuffTick(curBuffSkill, curObj)
-        
-        #---验证触发间隔TICK---
-        if turnNum > 0:
-            GameWorld.DebugLog("    buffProcess: objID=%s,skillID=%s,turnNum=%s" % (curObj.GetID(), curBuffSkill.GetSkillID(), turnNum))
-        else:
-            if tick - curBuff.GetProcessInterval() <= processBuffTick:
-                continue
-        curBuff.SetProcessInterval(tick)
-        
-        
-        #得到当前buff
-        for effIndex in range(0, curBuffSkill.GetEffectCount()):
-            #得到当前效果
-            curEffect = curBuffSkill.GetEffect(effIndex)
-            curEffectID = curEffect.GetEffectID()
-            
-            if not curEffectID:
-                continue
-            
-            processStr = "BuffProcess_%d.%s"%(curEffectID, "ProcessBuff")
-            
-            callBuffProcessFunc = GameWorld.GetExecFunc(GameBuffs, processStr)
-            
-            if not callBuffProcessFunc:
-                continue
-            
-            callBuffProcessFunc(curObj, curBuff, curEffect, processBuffTick, tick)
-    
     #执行ProcessBuff中设定的玩家字典
     __DoProcessBuff_PlayerKey(curObj, tick)
+    return
+
+def ProcessSinglePersistBuff(curObj, buffState, curBuff, tick, turnForce=False):
+    '''处理单个持续性buff,可能会删除buff,调用时如果是循环遍历,需注意遍历顺序,防止buff删除后索引错乱
+    @param turnForce: 回合下强制立刻执行
+    '''
+    if not curBuff:
+        return
+    curBuffSkill = curBuff.GetSkill()
+    
+    if not __BuffCanProcess(curObj, curBuffSkill):
+        return
+    
+    processBuffTick = GetProcessBuffTick(curBuffSkill, curObj)
+    
+    isDel = False
+    remainTime = None
+    timeLine = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightTimeline)
+    #---验证触发间隔TICK---
+    if timeLine > 0:
+        turnNum, actionNum = timeLine / 100, timeLine % 100
+        if not turnForce and actionNum != 0:
+            # 持续型buff暂仅支持回合开始时处理
+            return
+        remainTime = curBuff.GetRemainTime() - ChConfig.Def_PerTurnTick # 每处理一次固定算一回合
+        if remainTime <= 0:
+            isDel = True
+        GameWorld.DebugLog("    回合buffProcess: objID=%s,skillID=%s,remainTime=%s,turnNum=%s" % (curObj.GetID(), curBuffSkill.GetSkillID(), remainTime, turnNum))
+    else:
+        if tick - curBuff.GetProcessInterval() <= processBuffTick:
+            return
+    curBuff.SetProcessInterval(tick)
+    
+    #得到当前buff
+    for effIndex in range(0, curBuffSkill.GetEffectCount()):
+        #得到当前效果
+        curEffect = curBuffSkill.GetEffect(effIndex)
+        curEffectID = curEffect.GetEffectID()
+        
+        if not curEffectID:
+            continue
+        
+        processStr = "BuffProcess_%d.%s"%(curEffectID, "ProcessBuff")
+        
+        callBuffProcessFunc = GameWorld.GetExecFunc(GameBuffs, processStr)
+        
+        if not callBuffProcessFunc:
+            continue
+        
+        callBuffProcessFunc(curObj, curBuff, curEffect, processBuffTick, tick)
+        
+    # 剩余时间需效果处理后再设置
+    if remainTime != None:
+        curBuff.SetRemainTime(remainTime)
+        
+    if not isDel:
+        return
+    
+    GameWorld.DebugLog("    buffProcess后删除buff: objID=%s,skillID=%s,turnNum=%s" % (curObj.GetID(), curBuffSkill.GetSkillID(), turnNum))
+    skillID = curBuffSkill.GetSkillID()
+    skillTypeID = curBuffSkill.GetSkillTypeID()
+    ownerID, ownerType = curBuff.GetOwnerID(), curBuff.GetOwnerType()
+    BuffSkill.DoBuffDisApper(curObj, curBuff, tick)
+    buffState.DeleteBuffByTypeID(skillTypeID)
+    SkillShell.ClearBuffEffectBySkillID(curObj, skillID, ownerID, ownerType)
+    return
 
 #---------------------------------------------------------------------
 ##执行ProcessBuff中设定的玩家字典
@@ -3410,10 +3436,23 @@
 def CheeckTrigSkillandTag(attacker, exSkill, defender, tick):
     #再次验证附加技能是否对目标可用
     if attacker.GetGameObjType() != IPY_GameWorld.gotPlayer:
+        skillTag = GetSkillAffectTag(exSkill)
         #该技能是对自己使用的 防守者应该改为攻击者
-        if GetSkillAffectTag(exSkill) in [ChConfig.Def_UseSkillTag_Self,
+        if skillTag in [ChConfig.Def_UseSkillTag_Self,
                                           ChConfig.Def_UseSkillTag_SelfAndFriend]:
             return True, attacker
+        
+        # 召唤兽对主人释放技能
+        if skillTag == ChConfig.Def_UseSkillTag_SummonMaster:
+            if not NPCCommon.IsSummonNPC(attacker):
+                return False, None
+            curSummonOwner =  NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, attacker)    
+            if curSummonOwner == None:
+                curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, attacker)
+            if curSummonOwner == None:
+                return False, None
+            return True, curSummonOwner
+        
         return True, defender
     
     #该技能是对自己使用的 防守者应该改为攻击者

--
Gitblit v1.8.0