From efc4f490488935020d1b58a451a396ee420de9da Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 06 八月 2025 18:21:05 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(NPC、技能使用新表N.NPC表卡牌、J.技能表卡牌;重构战斗系统;优化战利品掉落;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py                       |   17 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py                             |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                              |  477 ++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                   |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py                            | 1164 +++++---------
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py                             |  578 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py |  152 -
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                |  231 +-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py                            |   14 
 PySysDB/PySysDBPY.h                                                                                                 |   92 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py                         |   26 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py                                |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py                              |  899 +++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py                             |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py              |   29 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py                                      |  498 ++++++
 /dev/null                                                                                                           |  236 --
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py                        |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py                               |   74 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py                          |   16 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py                |    4 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py                                |   51 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py                                      |    8 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py                 |   10 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                     |   86 
 25 files changed, 3,408 insertions(+), 1,274 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index dd16eba..b46fd5f 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -26,10 +26,71 @@
 	BYTE		OPLimitInAct;	//活动期间限制队伍操作
 };
 
+//NPC表
+
+struct NPC
+{
+	DWORD		_NPCID;	//NPCID
+	char		NPCName;	//名称
+	BYTE		Country;	//国家
+	BYTE		AtkDistType;	//远近类型;1-近战;2-远程
+	WORD		LV;	//等级
+	DWORD		Atk;	//攻击力
+	DWORD		Def;	//防御值
+	DWORD		MaxHP;	//最大生命值,可超过20E
+	list		SkillIDList;	//技能ID列表
+	DWORD		FinalDamPer;	//最终增伤
+	DWORD		FinalDamPerDef;	//最终减伤
+	DWORD		MissRate;	//闪避概率
+	DWORD		MissRateDef;	//抗闪避概率
+	DWORD		SuperHitRate;	//暴击概率
+	DWORD		SuperHitRateDef;	//抗暴击概率
+	DWORD		StunRate;	//击晕概率
+	DWORD		StunRateDef;	//抗击晕概率
+	DWORD		ComboRate;	//连击概率
+	DWORD		ComboRateDef;	//抗连击概率
+	DWORD		ParryRate;	//格挡概率
+	DWORD		ParryRateDef;	//抗格挡概率
+	DWORD		SuckHPPer;	//吸血比率
+	DWORD		SuckHPPerDef;	//抗吸血比率
+	dict		SpecAttrInfo;	//特殊属性信息 {"属性ID":值, ...}
+};
+
+//技能表
+struct	Skill
+{
+	DWORD		_SkillID;	//技能ID
+	DWORD		SkillTypeID;	//技能TypeID
+	WORD		SkillMaxLV;	//最高等级
+	char		SkillName;	//技能名
+	BYTE		FuncType;	//功能分类
+	BYTE		SkillType;	//技能类型
+	BYTE		HurtType;	//伤害类型
+	BYTE		AtkType;	//释放方式
+	BYTE		TagAim;		//瞄准位置
+	BYTE		TagFriendly;	//敌我目标
+	BYTE		TagAffect;	//目标细分
+	BYTE		TagCount;	//目标个数
+	WORD		HappenRate;	//释放或添加几率
+	WORD		LastTime;	//持续时间
+	WORD		CoolDownTime;	//冷却时间
+	WORD		Priority;	//优先级
+	DWORD		EffectID1;	//效果ID1
+	list		EffectValues1;	//效果值列表1
+	DWORD		EffectID2;	//效果ID2
+	list		EffectValues2;	//效果值列表2
+	DWORD		EffectID3;	//效果ID3
+	list		EffectValues3;	//效果值列表3
+	DWORD		ConnSkill;	//关联技能
+	list		EnhanceSkillList;	//触发技能ID列表
+	DWORD		FightPower;	//技能战斗力
+};
+
 //武将表
 struct	Hero
 {
 	DWORD		_HeroID;	//英雄ID
+	char		Name;	//名称
 	BYTE		Country;	// 国家
 	BYTE		Quality;	// 品质
 	BYTE		AtkDistType;	//远近类型;1-近战;2-远程
@@ -157,7 +218,6 @@
 {
 	BYTE		_ChapterID;	//章节ID
 	list		DailyBootyUpperList;	// 每日战利品掉落上限,[[物品ID,每日上限], ...]
-	list		BootyWeightList;	// 战利品掉落权重,[[权重,物品ID,掉落个数下限, 上限], ...]
 };
 
 //主线关卡表
@@ -917,36 +977,6 @@
 	float		AttrPer;	//对应等级表中的比例
 	dict		AttrSpecDict;	//特殊属性值字典 {attrKey:value, ...}
 	dict		AttrExDict;	//特殊属性值字典 {attrKey:value, ...}
-};
-
-//NPC表扩展
-
-struct tagNPCEx
-{
-	DWORD		_NPCID;	//NPCID
-	BYTE		FightPowerLackAtkLimit;	//战力不足限制攻击
-	DWORD		SuppressFightPower;	//推荐/压制战力
-	BYTE		AtkDistType;	//远近类型;1-近战;2-远程
-	DWORD		Atk;	//攻击力
-	DWORD		Def;	//防御值
-	DWORD		MaxHP;	//最大生命值,可超过20E
-	list		SkillIDList;	//技能ID列表
-	DWORD		FinalHurtPer;	//最终增伤
-	DWORD		FinalHurtReducePer;	//最终减伤
-	DWORD		MissRate;	//闪避概率
-	DWORD		MissDefRate;	//抗闪避概率
-	DWORD		SuperHitRate;	//暴击概率
-	DWORD		SuperHitRateReduce;	//抗暴击概率
-	DWORD		FaintRate;	//击晕概率
-	DWORD		FaintDefRate;	//抗击晕概率
-	DWORD		ComboRate;	//连击概率
-	DWORD		ComboDefRate;	//抗连击概率
-	DWORD		ParryRate;	//格挡概率
-	DWORD		ParryDefRate;	//抗格挡概率
-	DWORD		ParryDamPer;	//格挡减伤比率
-	DWORD		SuckHPPer;	//吸血比率
-	DWORD		SuckHPDefPer;	//抗吸血比率
-	dict		SpecAttrInfo;	//特殊属性信息 {"属性ID":值, ...}
 };
 
 //成长型境界怪物表
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 4f4bdcb..c1f70d4 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
@@ -454,7 +454,7 @@
             return heroIpyData.GetAtkDistType()
         
     npcID = curObj.GetNPCID()
-    npcDataEx = NPCCommon.GetNPCDataEx(npcID)
+    npcDataEx = NPCCommon.GetNPCDataPy(npcID)
     if npcDataEx:
         return npcDataEx.GetAtkDistType()
     
@@ -872,14 +872,14 @@
                 PlayerControl.NotifyCode(atkPlayer, sysMark)
         return False
     
-    npcDataEx = NPCCommon.GetNPCDataEx(npcID)
-    if npcDataEx and npcDataEx.GetFightPowerLackAtkLimit():
-        if npcDataEx.GetSuppressFightPower() > PlayerControl.GetFightPower(atkPlayer):
-            if isNotify:
-                PlayerControl.NotifyCode(atkPlayer, "BossFightPowerHint") 
-            #GameWorld.DebugLog("战力不足,无法攻击boss! npcID=%s,SuppressFightPower=%s > playerFightPower=%s" 
-            #                   % (npcID, npcDataEx.GetSuppressFightPower(), PlayerControl.GetFightPower(atkPlayer)))               
-            return False
+    #npcDataEx = NPCCommon.GetNPCDataPy(npcID)
+    #if npcDataEx and npcDataEx.GetFightPowerLackAtkLimit():
+    #    if npcDataEx.GetSuppressFightPower() > PlayerControl.GetFightPower(atkPlayer):
+    #        if isNotify:
+    #            PlayerControl.NotifyCode(atkPlayer, "BossFightPowerHint") 
+    #        #GameWorld.DebugLog("战力不足,无法攻击boss! npcID=%s,SuppressFightPower=%s > playerFightPower=%s" 
+    #        #                   % (npcID, npcDataEx.GetSuppressFightPower(), PlayerControl.GetFightPower(atkPlayer)))               
+    #        return False
         
     return True
 
@@ -2150,9 +2150,6 @@
         aBurnValue = atkwargs.get('burnValue', 0)
         aBurnPer = atkwargs.get('burnPer', 0)
         hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
-        #if hurtFormulaKey == "Burn":
-        #    pass
-        #else:
         hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
     elif not curSkill:
         hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
@@ -2240,7 +2237,7 @@
         else:
             defObj.SetDict(ChConfig.Def_PlayerKey_LastAttackerObjID, atkObj.GetID())
             
-    TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)
+    #TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)
     
     #if resultHurtType.RealHurtHP:
     #    PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_BeHurt, tick)
@@ -2708,8 +2705,8 @@
     if GameObj.GetHP(curObjDetel) > 0:
         return
     
-    if TurnAttack.SetTurnObjKilled(curObjDetel, atkObj):
-        return
+    #if TurnAttack.SetTurnObjKilled(curObjDetel, atkObj):
+    #    return
         
     #---玩家处理---
     if curObjDetel.GetGameObjType() == IPY_GameWorld.gotPlayer:
@@ -2787,7 +2784,7 @@
     srcID, srcType = 0, 0
     if srcObj:
         srcID, srcType = srcObj.GetID(), srcObj.GetGameObjType()
-    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(curObj.GetID())
+    turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(curObj.GetTFGUID())
     if turnFight:
         clientPack = ChNetSendPack.tagObjPropertyRefreshView()
         clientPack.ObjID = curObj.GetID()
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
deleted file mode 100644
index 08f7962..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_NormalNPC.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_NormalNPC.py
-# 普通NPC攻击普通NPC
-#
-# @author adaws
-# @date 2010-11-17 19:00
-# @version 1.3
-#
-# @change: "2010-11-18 13:50" chenxuewei Npc杀死NPC时通知副本
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import FBLogic
-import SkillShell
-import ChNPC
-import GameObj
-import GameWorld
-import TurnAttack
-#---------------------------------------------------------------------
-Def_FB_NPCAI_SideList = []
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param attacker 攻击方:普通NPC
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 函数详细说明.
-def GetCanAttack(attacker, defender, skill, tick):
-    return AttackCommon.CheckNPCCanAttackTag(attacker, defender, skill)
-
-
-## 获得关系
-#  @param attacker 攻击方:普通NPC
-#  @param defender 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 函数详细说明.
-def GetTagRelation(attacker, defender, skill, tick):
-    # 优先级高于其他
-    atkLimit = ChNPC.GetNPCAttackTagLimit(attacker, defender)
-    if atkLimit:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    attackerCampType = GameObj.GetFaction(attacker)
-    defenderCampType = GameObj.GetFaction(defender)
-    
-    #不同阵营是敌人
-    if attackerCampType != defenderCampType:
-        return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-    
-    #机器人可以打机器人
-    if attacker.GetType() == ChConfig.ntRobot and defender.GetType() == ChConfig.ntRobot:
-        return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-    
-    return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-
-## 攻击
-#  @param attacker 攻击方:普通NPC
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 函数详细说明.
-def DoAttack(attacker, defender, skill, skillValue, skillPercent, skillHurtList, tick):
-    #计算反弹,添加伤血 
-    hurtType = AttackCommon.GetHurtHP(attacker, defender, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    FBLogic.DoFB_NPC_HurtNPC(attacker, defender, hurtHP)
-    
-    npcControl = NPCCommon.NPCControl(defender)
-    npcControl.AddObjDetelToAngryList_ByAttack(attacker, hurtHP, skill)
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(defender, skillHurtList, hurtType.HurtType, hurtHP)
-    #ChNPC.OnUndeathBossHurt(defender, hurtHP)
-    return hurtType
-
-## 处理攻击后的结果
-#  @param attacker 攻击方:普通NPC
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 函数详细说明.
-def AttackResult(attacker, defender, skill, tick):
-    
-    if ChNPC.OnUndeathBossAttacked(defender):
-        return
-    
-    #普通NPC
-    if GameObj.GetHP(defender) <= 0:
-        if TurnAttack.SetTurnObjKilled(defender, attacker):
-            return
-        if not ChNPC.OnCheckCanDie(attacker, defender, skill, tick):
-            return
-        #副本
-        FBLogic.DoFB_Npc_KillNPC(attacker, defender, tick)
-            
-        npcControl = NPCCommon.NPCControl(defender)
-        npcControl.SetKilled()
-    
-    return True
-
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
deleted file mode 100644
index e52fc10..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Pet.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_Pet
-# @todo: 普通NPC攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.3
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-#------------------------------------------------------------------------------ 
-"""Version = 2012-02-10 20:20"""
-#---------------------------------------------------------------------
-import PlayerControl
-import AttackCommon
-import ChConfig
-import ChEquip
-import BaseAttack
-import PetControl
-import NPCCommon
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPet 防守方:玩家宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击
-def GetCanAttack(curNormalNPC, curTagPet, skill, tick):
-    return False
-    #===========================================================================
-    # if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagPet, skill):
-    #    return False
-    # 
-    # return True
-    #===========================================================================
-
-#---------------------------------------------------------------------
-## 获得关系
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPet 防守方:玩家宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagPet, skill, tick):
-    return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-    defenderCampType = NPCCommon.GetFaction(curNormalNPC)
-    #正义的 不攻击玩家 宠物以及玩家的召唤兽
-    if defenderCampType == ChConfig.CampType_Justice:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-#---------------------------------------------------------------------
-## 攻击
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPet 防守方:玩家宠物
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curNormalNPC, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-    #计算反弹,添加伤血
-    curNPCBeHP = GameObj.GetHP(curNormalNPC)
-    hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagPet, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    
-    #添加仇恨
-    petControl = NPCCommon.NPCControl(curTagPet)
-    petControl.AddObjDetelToAngryList_ByAttack(curNormalNPC, hurtHP, skill)
-    
-    #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
-    lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curTagPlayer != None:
-        if lastHP > 0:
-            #添加伤血列表
-            AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP)
-        
-        #给这个玩家的其他召唤兽增加仇恨(打主人优先->这里只添加1点仇恨)
-        AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, 1)
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-#---------------------------------------------------------------------
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPet 防守方:玩家宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curNormalNPC, curTagPet, skill, tick):
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-    
-    #宠物死亡
-    if GameObj.GetHP(curTagPet) <= 0:
-        curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
-        curTagPetNPCControl.SetKilled()
-    
-    return True
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
deleted file mode 100644
index 678d07c..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_Player.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_Player
-# 普通NPC攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.4
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-06-25 11:00" Alee 修改系统提示
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2016-07-04 17:00" hxp 玩家被NPC击杀提示信息前置(防止先处理死亡逻辑后有些地方可能会清怪,导致NPCID找不到)
-#------------------------------------------------------------------------------------------------------------ 
-#"""Version = 2016-07-04 17:00"""
-#---------------------------------------------------------------------
-import PlayerControl
-import AttackCommon
-import ChConfig
-import FBLogic
-import GameObj
-import NPCCommon
-import ChNPC
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 函数详细说明.
-def GetCanAttack(curNormalNPC, curTagPlayer, skill, tick):
-    if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagPlayer, skill):
-        return False
-    
-    return True
-
-## 获得关系
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagPlayer, skill, tick):
-    # 优先级高于其他
-    atkLimit = ChNPC.GetNPCAttackTagLimit(curNormalNPC, curTagPlayer)
-    if atkLimit:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    defenderCampType = NPCCommon.GetFaction(curNormalNPC)
-    tagFaction = curTagPlayer.GetFaction()
-    if tagFaction and defenderCampType:
-        if tagFaction == defenderCampType:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    #正义的 不攻击玩家 宠物以及玩家的召唤兽
-    elif defenderCampType == ChConfig.CampType_Justice:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 函数详细说明.
-def DoAttack(curNormalNPC, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-    #计算反弹,添加伤血
-    curNPCBeHP = GameObj.GetHP(curNormalNPC)
-    hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagPlayer, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
-    lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
-    if lastHP > 0 :
-        #添加伤血列表
-        AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP, True)
-    #给这个玩家的召唤兽增加仇恨
-    AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, hurtHP)
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 函数详细说明.
-def AttackResult(curNormalNPC, curTagPlayer, skill, tick):
-
-    #玩家活着
-    if GameObj.GetHP(curTagPlayer) > 0:
-        #被攻击玩家进入战斗状态
-        AttackCommon.OnNPCHitPlayer(curNormalNPC, curTagPlayer, tick)
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-    else:
-        #通知玩家
-        if curTagPlayer.GetMapID() != ChConfig.Def_FBMapID_XMZZ:
-            if curNormalNPC.GetType() == ChConfig.ntRobot:
-                PlayerControl.NotifyCode(curTagPlayer, 'RobotKill_1', [curNormalNPC.GetID(), curNormalNPC.GetNPCID()])
-            else:
-                PlayerControl.NotifyCode(curTagPlayer, 'GeRen_chenxin_279029', [curNormalNPC.GetNPCID()])
-        #玩家已经死亡
-        playerControl = PlayerControl.PlayerControl(curTagPlayer)
-        playerControl.SetDead()
-        FBLogic.DoFBOnNPCKill_Player(curNormalNPC, curTagPlayer, tick)
-    return True
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
deleted file mode 100644
index 194814d..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/NormalNPC_Attack_SummonNPC.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package NormalNPC_Attack_SummonNPC
-# 普通NPC攻击召唤NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2010-11-18 11:00" adaws NPC阵容判定错修改
-# @change: "2011-05-05 17:30" Alee 攻击关系判断
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-#------------------------------------------------------------------------------ 
-"""Version = 2012-02-10 20:20"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import SkillShell
-import TurnAttack
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 函数详细说明.
-def GetCanAttack(curNormalNPC, curTagSummon, skill, tick):
-    if not AttackCommon.CheckNPCCanAttackTag(curNormalNPC, curTagSummon, skill):
-        return False
-    
-    return True
-
-## 获得关系
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 函数详细说明.
-def GetTagRelation(curNormalNPC, curTagSummon, skill, tick):
-    #1.不攻击精灵
-    if curTagSummon.GetType() == IPY_GameWorld.ntFairy:
-        return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-    
-    #判断阵营
-    attackerCampType = GameObj.GetFaction(curNormalNPC)
-    defenderCampType = GameObj.GetFaction(curTagSummon)
-    
-    if attackerCampType != defenderCampType:
-        return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-    
-    #2.不攻击阵营相同(不包括二者都为中立)
-    if not (attackerCampType == ChConfig.CampType_Neutral and defenderCampType == ChConfig.CampType_Neutral): 
-        if attackerCampType == defenderCampType:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        
-    #召唤兽的主人
-    curSummonOwner =  NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)    
-    if curSummonOwner == None:
-        curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curTagSummon)
-    
-    if curSummonOwner != None:
-        if GameWorld.IsSameObj(curSummonOwner, curNormalNPC) :
-            #3.不攻击自己的召唤兽
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-        #4.不攻击NPC召唤兽
-        if curSummonOwner.GetGameObjType() == IPY_GameWorld.gotNPC:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-            
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 函数详细说明.
-def DoAttack(curNormalNPC, curTagSummonNPC, skill, skillValue, skillPercent, skillHurtList, tick):
-    #计算反弹,添加伤血
-    curNPCBeHP = GameObj.GetHP(curNormalNPC)
-    hurtType = AttackCommon.GetHurtHP(curNormalNPC, curTagSummonNPC, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    
-    #添加仇恨
-    summonControl = NPCCommon.NPCControl(curTagSummonNPC)
-    summonControl.AddObjDetelToAngryList_ByAttack(curNormalNPC, hurtHP, skill)
-    
-    #判断NPC是否伤血,如果伤血,说明反弹伤害,要加伤血列表
-    lastHP = curNPCBeHP - GameObj.GetHP(curNormalNPC)
-    
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
-    
-    if curTagPlayer != None :
-        if lastHP > 0 :
-            #添加伤血列表
-            AttackCommon.NPCAddObjInHurtList(curTagPlayer, curNormalNPC, curNPCBeHP, lastHP)
-        
-        #给这个玩家的其他召唤兽增加仇恨(打主人优先->这里只添加1点仇恨)
-        AttackCommon.SummonAddAngryByOwner(curNormalNPC, curTagPlayer, 1)
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagSummonNPC, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:普通NPC
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 函数详细说明.
-def AttackResult(curNormalNPC, curTagSummonNPC, skill, tick):
-    #获取召唤兽的主人
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0 :
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-    
-    #召唤兽死亡
-    if GameObj.GetHP(curTagSummonNPC) <= 0:
-        if TurnAttack.SetTurnObjKilled(curTagSummonNPC, curNormalNPC):
-            return
-        curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummonNPC)
-        #召唤兽死亡
-        curTagSummonNPCControl.SetKilled()
-    
-    return True
-
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
deleted file mode 100644
index f47b37a..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_NormalNPC.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_NormalNPC
-# 宠物攻击普通NPC
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.7
-#
-# @change: "2010-07-01 17:20" chenxuewei 修复bug:宠物攻击NPC的仇恨值只加在宠物身上,不添加在其主人身上。
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-13 14:51" panwei 宠物攻击也给玩家添加一份仇恨
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import FBLogic
-import PetControl
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curPet 攻击方:宠物
-#  @param curTagNormalNPC 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPet, curTagNormalNPC, skill, tick):
-    
-    if not AttackCommon.CheckNPCCanAttackTag(curPet, curTagNormalNPC, skill):
-        return False
-     
-    return True
-
-
-## 获得关系
-#  @param curPet 攻击方:宠物
-#  @param curTagNormalNPC 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPet, curTagNormalNPC, skill, tick):
-    defenderCampType = NPCCommon.GetFaction(curTagNormalNPC)
-    #不攻击正义的需要去保护的 这里有女神和守卫
-    if defenderCampType == ChConfig.CampType_Justice:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPet, curTagNPC, skill, skillValue, skillPercent, skillHurtList, tick):
-    curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNPC)
-    hurtType = AttackCommon.GetHurtHP(curPet, curTagNPC, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-
-    npcControl = NPCCommon.NPCControl(curTagNPC)
-    curPetOwner = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    #无法查找主人,添加自己
-    if curPetOwner:
-        AttackCommon.NPCAddObjInHurtList(curPetOwner, curTagNPC, curTagNPCHPBeforeAtk, hurtHP)
-        npcControl.AddObjDetelToAngryList_ByAttack(curPetOwner, hurtHP, skill)
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagNPC, skillHurtList, hurtType.HurtType, hurtHP)
-    #ChNPC.OnUndeathBossHurt(curTagNPC, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagNPC, skill, tick):
-    
-    if ChNPC.OnUndeathBossAttacked(curTagNPC):
-        return
-    
-    #NPC死亡
-    if GameObj.GetHP(curTagNPC) <= 0:
-        #执行击杀NPC逻辑
-        curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-        
-        if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
-            return
-        
-        if curPlayer != None:
-            NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
-            FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
-            
-        curTagNormalNPCControl = NPCCommon.NPCControl(curTagNPC)
-        curTagNormalNPCControl.SetKilled()
-    else:
-        ChNPC.OnNPCAttacked(curPet, curTagNPC, skill, tick)
-        
-    
-    return True
-
-    
\ No newline at end of file
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
deleted file mode 100644
index d02b0c4..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Pet.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_Pet
-# 宠物攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-25 13:00" jiang 攻击宠物玩家红名
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import GameWorld
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curPet 攻击方:宠物
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPet, curTagPet, skill, tick):
-    return False
-    #return AttackCommon.CheckNPCCanAttackTag(curPet, curTagPet, skill)
-
-## 获得关系
-#  @param curPet 攻击方:宠物
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPet, curTagPet, skill, tick):
-    
-    return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-    
-    curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人 
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curPlayer != None  and curTagPlayer != None:
-        #同一玩家不互相攻击
-        if GameWorld.IsSameObj(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        
-        #检查攻击模式
-        if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-        
-        #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-        
-        return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-    
-    #不同类型的,可以直接攻击
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-#  @param curPet 攻击方:宠物
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPet, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-    hurtType = AttackCommon.GetHurtHP(curPet, curTagPet, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #添加仇恨
-    curTagPetControl = NPCCommon.NPCControl(curTagPet)
-    curTagPetControl.AddObjDetelToAngryList_ByAttack(curPet, hurtHP, skill)
-    
-    #---攻击方为召唤兽,给主人加仇恨---
-    curPetOwner = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    if curPetOwner != None:
-        curTagPetControl.AddObjToAngryList(curPetOwner, 1)
-        
-        curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-        if curTagPlayer != None:
-            AttackCommon.OnPVPDamage(curPetOwner, hurtHP, curTagPlayer, "Pet v Pet")
-
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
-    
-    return hurtType
-
-## 处理攻击后的结果
-#  @param curPet 攻击方:宠物
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagPet, skill, tick):
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #宠物死亡
-    if GameObj.GetHP(curTagPet) <= 0:
-        curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
-        curTagPetNPCControl.SetKilled()
-        
-        if curPlayer != None and curTagPlayer != None:
-            AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
-    
-    return True
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
deleted file mode 100644
index ae825f3..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_Player.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_Player
-# @todo: 宠物攻击玩家
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 2.0
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2011-02-12 17:30" Alee 注释攻击类型相关
-# @change: "2011-10-26 14:20" chengaobao 增加逻辑:乘骑状态被攻击,自动下马
-# @change: "2011-10-27 17:20" chengaobao 将乘骑状态被攻击,自动下马逻辑移到BaseAttack中
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-10-19 14:30" jiang 添加具体的伤害,用于副本计算
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2015-06-03 14:00" hxp 处理击杀逻辑后再SetDead,防止清除临时黄名后PK惩罚关系判断错误
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import PlayerControl
-import AttackCommon
-import SkillCommon
-import ChConfig
-import GameWorld
-import ChEquip
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击
-def GetCanAttack(curPet, curTagPlayer, skill, tick):
-    return AttackCommon.CheckNPCCanAttackTag(curPet, curTagPlayer, skill)
-
-## 获得关系
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPet, curTagPlayer, skill, tick):
-    
-    curPetOwner = PetControl.GetPetOwner(curPet)  # 宠物主人
-    if curPetOwner == None:
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    #宠物不能攻击自己的主人
-    if GameWorld.IsSameObj(curPetOwner, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    #判断主人的攻击模式,判断是否可以攻击这个玩家
-    if not AttackCommon.CheckPlayerAttackMode_Player(curPetOwner, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-    
-    #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-    
-    return AttackCommon.GetPlayersRelation(curPetOwner, curTagPlayer)
-
-
-## 攻击
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPet, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-    curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
-    hurtType = AttackCommon.GetHurtHP(curPet, curTagPlayer, skill, skillValue, skillPercent, tick)
-    #伤血
-    hurtHP = hurtType.HurtHP
-    
-    curAttackPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    #2个玩家的召唤兽互相PK,需要判断防守方玩家的是否可以攻击进攻方
-    if curAttackPlayer != None:
-        #if AttackCommon.CheckPlayerAttackMode_Player(curTagPlayer, curAttackPlayer):
-        #    AttackCommon.SummonAddAngryByOwner(curPet, curTagPlayer, hurtHP)
-            
-        #AttackCommon.NPCAddObjInHurtList(curAttackPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
-        
-        AttackCommon.OnPVPDamage(curAttackPlayer, hurtHP, curTagPlayer, "Pet v Player")
-        
-    #直接攻击
-    #else:
-    #    AttackCommon.SummonAddAngryByOwner(curPet, curTagPlayer, hurtHP)
-    
-    #添加伤血列表
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)    
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curPet 攻击方:宠物
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagPlayer, skill, tick):
-
-    #防守方血量
-    curTagPlayerHP = GameObj.GetHP(curTagPlayer)
-    
-    #是否同国籍
-    #获得攻击方拥有者
-    curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    #被攻击提示,避免频繁提示
-    #===========================================================================
-    # if not curTagPlayer.GetBattleState():
-    #    PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-    # 
-    # if curPlayer != None and not curPlayer.GetBattleState():
-    #    PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-    #===========================================================================
-    
-    #玩家是否死亡
-    if curTagPlayerHP > 0:
-        #被攻击者也进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-        
-        return
-    
-    if curPlayer != None:
-        #执行玩家击杀玩家逻辑
-        AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-        
-        #刷新NPC的仇恨列表,删除死亡对象
-        #npcControl = NPCCommon.NPCControl(curPet)
-        #npcControl.RefreshAngryList(tick)
-        
-    #玩家已经死亡
-    tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
-    tagPlayerControl.SetDead()
-    
-    return True
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
deleted file mode 100644
index 86bcd47..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Pet_Attack_SummonNPC.py
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Pet_Attack_SummonNPC
-# @todo: 宠物攻击召唤兽
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.4
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import SkillCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curPet 攻击方:宠物
-#  @param curTagSummon 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPet, curTagSummon, skill, tick):
-    return AttackCommon.CheckNPCCanAttackTag(curPet, curTagSummon, skill)
-
-## 获得关系
-#  @param curPet 攻击方:宠物
-#  @param curTagSummon 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPet, curTagSummon, skill, tick):
-    
-    curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    if curPlayer == None:
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    
-    if curTagPlayer == None:
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    if curPlayer != None and curTagPlayer != None:
-        #同一玩家不互相攻击
-        if GameWorld.IsSameObj(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        
-        #检查攻击模式
-        if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-        
-        #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-        
-        return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-    
-    #不同类型的,可以直接攻击
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-#  @param curPet 攻击方:宠物
-#  @param curTagSummon 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPet, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
-    hurtType = AttackCommon.GetHurtHP(curPet, curTagSummon, skill, skillValue, skillPercent, tick)
-    
-    hurtHP = hurtType.HurtHP
-    #添加仇恨
-    summonControl = NPCCommon.NPCControl(curTagSummon)
-    #summonControl.AddObjDetelToAngryList_ByAttack(curPet, hurtHP, skill)
-
-    #---攻击方为召唤兽,给主人加仇恨---
-    curPetOwner = PetControl.GetPetOwner(curPet)  # 宠物主人
-    
-    if curPetOwner != None:
-        summonControl.AddObjToAngryList(curPetOwner, 1)
-        
-        curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-        if curTagPlayer != None:
-            AttackCommon.OnPVPDamage(curPetOwner, hurtHP, curTagPlayer, "Pet v Summon")
-
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curPet 攻击方:宠物
-#  @param curTagSummon 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPet, curTagSummon, skill, tick):
-    
-    #获取防守方召唤兽的主人
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    #攻击的是玩家的召唤兽
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        #获取召唤兽的主人
-        curPlayer = PetControl.GetPetOwner(curPet)  # 宠物主人
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #防守方召唤兽死亡
-    if GameObj.GetHP(curTagSummon) <= 0:
-        curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
-        #召唤兽死亡
-        curTagSummonNPCControl.SetKilled()
-    
-    return True
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
deleted file mode 100644
index 0a5446e..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_NormalNPC.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_NormalNPC
-# 玩家攻击普通NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.8
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-17 19:00" adaws 加入NPC阵容判定
-# @change: "2011-07-15 18:00" zhangd 添加NPC被玩家打死后触发逻辑
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2015-03-05 21:30" hxp 伤血类型检查触发被动技能
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import ChConfig
-import AttackCommon
-import GameWorld
-import FBLogic
-import ChEquip
-import IPY_GameWorld
-import SkillCommon
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 函数详细说明.
-def GetCanAttack(curPlayer, curTagNormalNPC, skill, tick):
-    #通用判断
-    if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagNormalNPC):
-        return False
-    
-    if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagNormalNPC, skill):
-        return False
-    
-    return True
-
-## 获得关系
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 函数详细说明.
-def GetTagRelation(curPlayer, curTagNormalNPC, skill, tick):
-    defenderCampType = NPCCommon.GetFaction(curTagNormalNPC)
-    curFaction = curPlayer.GetFaction()
-    if curFaction and defenderCampType:
-        if curFaction == defenderCampType:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    #不攻击正义的需要去保护的 这里有女神和守卫
-    elif defenderCampType == ChConfig.CampType_Justice:
-        return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-    
-    #私有木桩只能自己打自己的
-    if curTagNormalNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
-        summonPlayerID = curTagNormalNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
-        if curPlayer.GetPlayerID() != summonPlayerID:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-## 攻击
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 函数详细说明.
-def DoAttack(curPlayer, curTagNormalNPC, skill, skillValue, skillPercent, skillHurtList, tick):
-
-    curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNormalNPC)
-    hurtType = AttackCommon.GetHurtHP(curPlayer, curTagNormalNPC, skill, skillValue, skillPercent, tick)
-    
-    #伤血量
-    hurtHP = hurtType.HurtHP
-    #给这个普通小怪增加仇恨
-    npcControl = NPCCommon.NPCControl(curTagNormalNPC)
-    npcControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-    
-    #添加伤血列表
-    AttackCommon.NPCAddObjInHurtList(curPlayer, curTagNormalNPC, curTagNPCHPBeforeAtk, hurtHP)
-    #给这个玩家的所有召唤兽增加仇恨
-    AttackCommon.SummonAddAngryByOwner(curTagNormalNPC, curPlayer, hurtHP)
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagNormalNPC, skillHurtList, hurtType.HurtType, hurtHP)
-
-    return hurtType
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 函数详细说明.
-def AttackResult(curPlayer, curTagNormalNPC, skill, tick):
-    if ChNPC.OnUndeathBossAttacked(curTagNormalNPC):
-        return
-    
-    if GameObj.GetHP(curTagNormalNPC) <= 0:
-        if not ChNPC.OnCheckCanDie(curPlayer, curTagNormalNPC, skill, tick):
-            return
-        #执行击杀NPC逻辑
-        NPCCommon.OnPlayerAttackNPCDie(curTagNormalNPC, curPlayer, skill)
-        FBLogic.DoFB_Player_KillNPC(curPlayer , curTagNormalNPC , tick)
-        #NPC死亡
-        curTagNormalNPCControl = NPCCommon.NPCControl(curTagNormalNPC)
-        curTagNormalNPCControl.SetKilled()
-    else:
-        ChNPC.OnNPCAttacked(curPlayer, curTagNormalNPC, skill, tick)
-        
-        
-    return True
-
-
-
-
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
deleted file mode 100644
index 13d8df5..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Pet.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_Pet
-# 玩家攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.6
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-13 18:00" jiang 攻击宠物玩家红名
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import GameWorld
-import AttackCommon
-import IPY_GameWorld
-import PlayerControl
-import ChConfig
-import ChEquip
-import SkillCommon
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curPlayer 攻击方:玩家
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPlayer, curTagPet, skill, tick):
-    return False
-    #===========================================================================
-    # #通用判断
-    # if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagPet):
-    #    return False 
-    # 
-    # #判断距离
-    # if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagPet, skill):
-    #    return False
-    # 
-    # return True
-    #===========================================================================
-
-## 获得关系
-#  @param curPlayer 攻击方:玩家
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPlayer, curTagPet, skill, tick):
-    return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curTagPlayer == None:
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    #自己的宠物,不能攻击
-    if GameWorld.IsSameObj(curPlayer, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    #别人的宠物,判定玩家的攻击模式
-    if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-    
-    #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-    
-    return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-#  @param curPlayer 攻击方:玩家
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPlayer, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-    
-    #攻击前血量
-    curTagPetHP = GameObj.GetHP(curTagPet)
-    #攻击成功
-    hurtType = AttackCommon.GetHurtHP(curPlayer, curTagPet, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #给召唤兽添加仇恨
-    petControl = NPCCommon.NPCControl(curTagPet)
-    petControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-    
-    #添加伤血列表
-    AttackCommon.NPCAddObjInHurtList(curPlayer, curTagPet, curTagPetHP, hurtHP)
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    if curTagPlayer != None:
-        AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Pet")
-    
-    #给自己的其他召唤兽添加仇恨
-    AttackCommon.SummonAddAngryByOwner(curTagPet, curPlayer, hurtHP)
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curPlayer 攻击方:玩家
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagPet, skill, tick):
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curTagPlayer != None:
-        
-        if GameObj.GetHP(curTagPlayer) > 0:
-            #进入战斗状态
-            AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-            
-        AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #宠物死亡
-    if GameObj.GetHP(curTagPet) <= 0:
-        curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
-        curTagPetNPCControl.SetKilled()
-        
-        if curPlayer != None and curTagPlayer != None:
-            AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
-    return True
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py
deleted file mode 100644
index eb1e2ee..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_Player.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_Player
-# 玩家攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.7
-#
-# 修改时间 修改人 修改内容
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2014-09-25 11:30" hxp 增加最终伤害衰减控制
-# @change: "2015-03-07 07:30" hxp 最终伤害影响控制, 伤血类型检查触发被动技能; 淬毒
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import PlayerControl
-import GameWorld
-import AttackCommon
-import ChConfig
-import BaseAttack
-import ChEquip
-import IPY_GameWorld
-import SkillShell
-import SkillCommon
-import PassiveBuffEffMng
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPlayer, curTagPlayer, skill, tick):
-    #通用判断
-    if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagPlayer):
-        return False
-
-    #判断距离
-    if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagPlayer, skill):
-        return False
-
-    return True
-
-## 获得关系
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:玩家C
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPlayer, curTagPlayer, skill, tick):
-    #最高优先级, 选定的目标是自己, 返回朋友
-    if GameWorld.IsSameObj(curPlayer, curTagPlayer) :
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    #攻击模式, 如果不可攻击, 返回朋友
-    if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-    
-    #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-    
-    return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPlayer, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-    
-    curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
-    
-    #玩家攻击玩家
-    hurtType = AttackCommon.GetHurtHP(curPlayer, curTagPlayer, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    
-    #给双方的玩家召唤兽添加仇恨
-    #攻击者添加
-    AttackCommon.SummonAddAngryByOwner(curTagPlayer, curPlayer, hurtHP)
-    #防御者添加
-    AttackCommon.SummonAddAngryByOwner(curPlayer, curTagPlayer, hurtHP)
-    
-    #添加伤血列表
-    #AttackCommon.NPCAddObjInHurtList(curPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
-    AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Player")
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
-    
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagPlayer, skill, tick):
-    #防守方玩家血量
-    curTagPlayerHP = GameObj.GetHP(curTagPlayer)
-    
-    #被攻击提示,避免频繁提示
-    if not curTagPlayer.GetBattleState() or not curPlayer.GetBattleState():
-        PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-    
-    #玩家活着
-    if curTagPlayerHP > 0:
-        #被攻击的玩家也进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-         
-    else:
-        AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-        
-        #玩家已经死亡
-        tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
-        tagPlayerControl.SetDead()
-        
-        if skill != None:
-            SkillCommon.CheckAddPoisonAtkBuff(skill.GetSkillTypeID(), curPlayer, curTagPlayer, tick)
-        
-    return True
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
deleted file mode 100644
index 4c6d6a8..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/Player_Attack_SummonNPC.py
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package Player_Attack_SummonNPC
-# 玩家攻击召唤NPC
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.9
-#
-# 修改时间 修改人 修改内容
-# @change: "2010-05-12 18:30" zhengyang 添加注释
-# @change: "2010-05-28 15:50" chenxuewei 应策划刘鸿生需求:增加剑圣项目的PK规则
-# @change: "2010-06-02 10:50" chenxuewei 玩家可以攻击目标的情况下,获得玩家间的关系统一在AttackCommon处理
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2011-07-15 18:00" zhangd 添加NPC被玩家打死后触发逻辑
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2015-04-11 15:30" hxp 增加最终伤害逻辑
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import GameWorld
-import AttackCommon
-import IPY_GameWorld
-import ChConfig
-import FBLogic
-import GameObj
-import ChNPC
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curPlayer, curTagSummonNPC, skill, tick):
-    #通用判断
-    if not AttackCommon.CheckPlayerCanAttackTag(curPlayer, curTagSummonNPC):
-        return False 
-    
-    #判断距离
-    if not AttackCommon.CheckPlayerAttackDist(curPlayer, curTagSummonNPC, skill):
-        return False
-    
-    return True
-
-## 获得关系
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curPlayer, curTagSummonNPC, skill, tick):
-    #获取召唤兽的主人
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummonNPC)
-    
-    if curTagPlayer == None :
-        #怪物的召唤兽,不考虑攻击模式问题
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    #私有木桩只能自己打自己的
-    if curTagSummonNPC.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
-        summonPlayerID = curTagSummonNPC.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
-        if curPlayer.GetPlayerID() != summonPlayerID:
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    #自己的召唤兽,不能攻击
-    if GameWorld.IsSameObj(curPlayer, curTagPlayer) :
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    #别人的召唤兽,判定玩家的攻击模式
-    if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-    
-    #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-    
-    return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-
-
-## 攻击
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curPlayer, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
-    
-    #攻击前血量
-    curTagSummonBeHP = GameObj.GetHP(curTagSummon)
-    #攻击成功
-    hurtType = AttackCommon.GetHurtHP(curPlayer, curTagSummon, skill, skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #给召唤兽添加仇恨
-    summonControl = NPCCommon.NPCControl(curTagSummon)
-    summonControl.AddObjDetelToAngryList_ByAttack(curPlayer, hurtHP, skill)
-    
-    #添加伤血列表
-    AttackCommon.NPCAddObjInHurtList(curPlayer, curTagSummon, curTagSummonBeHP, hurtHP)
-    
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    if curTagPlayer != None:
-        AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Player v Summon")
-    
-    #给自己的其他召唤兽添加仇恨
-    AttackCommon.SummonAddAngryByOwner(curTagSummon, curPlayer, hurtHP)
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:玩家
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curPlayer, curTagSummon, skill, tick):
-    #获取召唤兽的主人
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    #如果是玩家的召唤兽逻辑处理(NPC的召唤兽不考虑)
-    if curTagPlayer != None :
-        
-        if GameObj.GetHP(curTagPlayer) > 0:
-            #进入战斗状态
-            AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-            
-        AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #召唤兽死亡
-    if GameObj.GetHP(curTagSummon) <=  0:
-        NPCCommon.OnPlayerAttackNPCDie(curTagSummon, curPlayer, skill)
-        FBLogic.DoFB_Player_KillNPC(curPlayer , curTagSummon , tick)
-        #获得控制器
-        curTagNormalNPCControl = NPCCommon.NPCControl(curTagSummon)
-        curTagNormalNPCControl.SetKilled()
-    else:
-        ChNPC.OnNPCAttacked(curPlayer, curTagSummon, skill, tick)
-        
-    return True
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
deleted file mode 100644
index e964c30..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_NormalNPC.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_NormalNPC
-# @todo: 召唤兽攻击普通NPC
-#
-# @author: panwei
-# @date 2010-09-06
-# @version 2.1
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-11-18 11:00" adaws NPC阵容判定错修改
-# @change: "2010-11-18 13:50" chenxuewei Npc杀死NPC时通知副本
-# @change: "2011-04-15 14:00" chenxuewei 修复bug9922:守护囚车,范围技能(玩家召回隐形NPC放群攻技能)可攻击己方囚车、守卫
-# @change: "2011-05-11 13:45" Alee 召唤兽是陷阱则把仇恨给主人
-# @change: "2011-05-12 14:00" Alee 陷阱改为灵仇恨全转移给主人
-# @change: "2011-05-12 17:00" chenxuewei AttackResult召唤兽有没主人都只要通知副本一次即可,避免重复通知
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2013-01-03 17:00" wdb 去除npc攻击造成的伤血记录
-# @change: "2013-11-08 18:00" hxp 增加NPC被攻击逻辑入口
-# @change: "2016-09-28 21:00" hxp 不死boss逻辑支持
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-09-28 21:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import IPY_GameWorld
-import AttackCommon
-import ChConfig
-import GameWorld
-import FBLogic
-import SkillShell
-import ChNPC
-import GameObj
-import TurnAttack
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 布尔值
-#  @remarks 函数详细说明.
-def GetCanAttack(curSummonNPC, curTagNormalNPC, skill, tick):
-    
-    return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagNormalNPC, skill)
-
-#---------------------------------------------------------------------
-## 获得关系
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 关系列表 如:[ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None]
-#  @remarks 获得关系列表
-def GetTagRelation(curSummonNPC, curTagNormalNPC, skill, tick):
-    
-    #防守方阵营
-    defenderCampType = GameObj.GetFaction(curTagNormalNPC)
-    
-    #玩家的召唤兽才能攻击普通NPC
-    npcOwner_Player = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-
-    if npcOwner_Player != None:
-        
-        #不攻击正义的需要去保护的 这里有女神和守卫
-        if defenderCampType == ChConfig.CampType_Justice:
-            return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-        
-        return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-    
-    #攻击方阵营
-    attackerCampType = GameObj.GetFaction(curSummonNPC)
-    if attackerCampType != defenderCampType:
-        return ChConfig.Type_Relation_Enemy, ChConfig.Def_PASysMessage_None
-    return ChConfig.Type_Relation_Friend, ChConfig.Def_PASysMessage_None
-#---------------------------------------------------------------------
-## 攻击
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击逻辑
-def DoAttack(curSummonNPC, curTagNPC, skill, skillValue, skillPercent, skillHurtList, tick):
-    curTagNPCHPBeforeAtk = GameObj.GetHP(curTagNPC)
-    hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagNPC, skill,
-                                      skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #---被攻击的NPC添加仇恨---
-    curTagNPCControl = NPCCommon.NPCControl(curTagNPC)
-    curTagNPCControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-    
-    #---被攻击的NPC添加伤血---
-    
-    #攻击方为召唤兽,添加到主人伤血中
-    summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-
-    #2013-1-3,去除npc攻击造成的伤血记录
-    if summonOwner != None:
-
-        # 召唤兽主人为玩家,伤血
-        if summonOwner.GetGameObjType() == IPY_GameWorld.gotPlayer:
-            AttackCommon.NPCAddObjInHurtList(summonOwner, curTagNPC, curTagNPCHPBeforeAtk, hurtHP)
-        
-        addAngry = hurtHP
-        if skill != None:
-            addAngry += skill.GetSkillAngry()
-        
-        #也添加一份主人的仇恨(暴风雪这类的不可攻击召唤技能, 要NPC攻击主人)
-        curTagNPCControl.AddObjToAngryList(summonOwner, addAngry)
-    
-    #---构建伤血列表---
-    
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagNPC, skillHurtList, hurtType.HurtType, hurtHP)
-    #ChNPC.OnUndeathBossHurt(curTagNPC, hurtHP)
-    return hurtType
-#---------------------------------------------------------------------
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:普通NPC
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 无意义
-#  @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagNPC, skill, tick):
-    
-    if ChNPC.OnUndeathBossAttacked(curTagNPC):
-        return
-    
-    #---NPC还活着---
-    if GameObj.GetHP(curTagNPC) > 0:
-        ChNPC.OnNPCAttacked(curSummonNPC, curTagNPC, skill, tick)
-        return
-
-    #---NPC被击杀---
-    if TurnAttack.SetTurnObjKilled(curTagNPC, curSummonNPC):
-        return
-    
-    #玩家击杀NPC副本触发器
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    
-    if not ChNPC.OnCheckCanDie(curPlayer, curTagNPC, skill, tick):
-        return
-    
-    #2011-05-12 chenxuewei 有没主人都只要通知一次即可,避免重复通知
-    if curPlayer != None:
-        NPCCommon.OnPlayerAttackNPCDie(curTagNPC, curPlayer, skill)
-        FBLogic.DoFB_Player_KillNPC(curPlayer, curTagNPC, tick)
-    else:
-        #副本
-        FBLogic.DoFB_Npc_KillNPC(curSummonNPC, curTagNPC, tick)
-        
-    #调用统一击杀逻辑
-    curTagNPCControl = NPCCommon.NPCControl(curTagNPC)
-    curTagNPCControl.SetKilled()
-    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
deleted file mode 100644
index 7c34c5a..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Pet.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_Pet
-# 召唤兽攻击宠物
-#
-# @author chenxuewei
-# @date 2010-06-26
-# @version 1.5
-#
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2012-06-13 18:00" jiang 攻击宠物玩家红名
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PlayerControl
-import PetControl
-import SkillShell
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curSummonNPC 攻击方:召唤兽
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curSummonNPC, curTagPet, skill, tick):
-    return False
-    #return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagPet, skill)
-
-## 获得关系
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagPet, skill, tick):
-    return ChConfig.Type_Relation_None , ChConfig.Def_PASysMessage_None
-    
-    #获得召唤兽的主人
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC) 
-    
-    if curPlayer == None:
-        #该召唤兽的主人非玩家,则可攻击宠物
-#        curSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC,curSummonNPC)
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    if curTagPlayer != None:
-        #同一玩家不互相攻击
-        if GameWorld.IsSameObj(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        
-        #检查攻击模式
-        if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-        
-        #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-        
-        return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-    
-    #不同类型的,可以直接攻击
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-#  @param curSummonNPC 攻击方:召唤兽
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curSummonNPC, curTagPet, skill, skillValue, skillPercent, skillHurtList, tick):
-    
-    hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagPet, skill, 
-                                      skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #添加仇恨
-    petControl = NPCCommon.NPCControl(curTagPet)
-    petControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-    
-    #---攻击方为召唤兽,给主人加仇恨---
-    summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-    
-    if summonOwner != None:
-        petControl.AddObjToAngryList(summonOwner, 1)
-        
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC) 
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    if curPlayer != None and curTagPlayer != None:
-        AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Summon v Pet")
-        
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPet, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-## 处理攻击后的结果
-#  @param curSummonNPC 攻击方:召唤兽
-#  @param curTagPet 防守方:宠物
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagPet, skill, tick):
-    
-    curTagPlayer = PetControl.GetPetOwner(curTagPet)  # 宠物主人
-    
-    #获取召唤兽的主人
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #宠物死亡
-    if GameObj.GetHP(curTagPet) <= 0:
-        curTagPetNPCControl = NPCCommon.NPCControl(curTagPet)
-        curTagPetNPCControl.SetKilled()
-        
-        if curPlayer != None and curTagPlayer != None:
-            AttackCommon.AddPKValue(curPlayer, curTagPlayer, tick)
-    
-    return True
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
deleted file mode 100644
index e3e790f..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_Player.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_Player
-# 召唤兽攻击玩家
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.7
-#
-# 修改时间 修改人 修改内容
-# @change: "2013-03-25 10:00" wdb 去装备使用不扣耐久
-# @change: "2013-09-27 19:30" Alee 恢复耐久
-# @change: "2013-11-05 21:00" Alee PK提示
-# @change: "2014-03-08 17:20" hxp 修复召唤兽击杀红/黄名玩家时,召唤兽主人红名问题
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-# @change: "2016-11-24 19:30" hxp 支持特殊副本攻击结果判断死亡规则
-# @change: "2016-11-26 19:00" hxp 陷阱AI增加可攻击主人逻辑
-#------------------------------------------------------------------------------ 
-#"""Version = 2016-11-26 19:00"""
-#------------------------------------------------------------------------------ 
-import FBLogic
-import NPCCommon
-import PlayerControl
-import IPY_GameWorld
-import AttackCommon
-import ChConfig
-import GameWorld
-import BaseAttack
-import ChEquip
-import SkillShell
-import ChNPC
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击
-def GetCanAttack(curSummonNPC, curTagPlayer, skill, tick):
-    return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagPlayer, skill)
-
-## 获得关系
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagPlayer, skill, tick):
-    #召唤兽的主人(玩家)
-    summonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    if summonOwner == None :
-        #NPC的召唤兽不考虑
-        return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-    
-    #人物的召唤兽,不能攻击自己的主人
-    if GameWorld.IsSameObj(summonOwner, curTagPlayer) :
-        #return ChNPC.OnGetOwnerRelation(curSummonNPC, curTagPlayer)
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    #判断主人的攻击模式,判断是否可以攻击这个玩家
-    if not AttackCommon.CheckPlayerAttackMode_Player(summonOwner, curTagPlayer):
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-    
-    #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-    
-    return AttackCommon.GetPlayersRelation(summonOwner, curTagPlayer)
-
-
-## 攻击
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curSummonNPC, curTagPlayer, skill, skillValue, skillPercent, skillHurtList, tick):
-    
-    curTagPlayerHPBeforeAtk = GameObj.GetHP(curTagPlayer)
-    
-    hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagPlayer, skill, 
-                                      skillValue, skillPercent, tick)
-    #伤血
-    hurtHP = hurtType.HurtHP
-    
-    curAttackPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    #2个玩家的召唤兽互相PK,需要判断防守方玩家的是否可以攻击进攻方
-    if curAttackPlayer != None:
-        if AttackCommon.CheckPlayerAttackMode_Player(curTagPlayer, curAttackPlayer):
-            AttackCommon.SummonAddAngryByOwner(curSummonNPC, curTagPlayer, hurtHP)
-        
-        #AttackCommon.NPCAddObjInHurtList(curAttackPlayer, curTagPlayer, curTagPlayerHPBeforeAtk, hurtHP)
-        
-        AttackCommon.OnPVPDamage(curAttackPlayer, hurtHP, curTagPlayer, "Summon v Player")
-        
-    #直接攻击
-    else:
-        AttackCommon.SummonAddAngryByOwner(curSummonNPC, curTagPlayer, hurtHP)
-        
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagPlayer, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:玩家
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagPlayer, skill, tick):
-    #防守方血量
-    curTagPlayerHP = GameObj.GetHP(curTagPlayer)
-    curTagPlayerFBHP = FBLogic.OnGetFBCurHP(curTagPlayer)
-    
-    #是否同国籍
-    #获得攻击方拥有者
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    
-    #被攻击提示,避免频繁提示
-    #===========================================================================
-    # if not curTagPlayer.GetBattleState():
-    #    PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-    # 
-    # if curPlayer != None and not curPlayer.GetBattleState():
-    #    PlayerControl.NotifyCode(curTagPlayer, "PK_admin_0")
-    #===========================================================================
-    
-    #玩家是否死亡
-    if curTagPlayerHP > 0 and curTagPlayerFBHP > 0:
-        #被攻击者也进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-        
-        return
-        
-    if curPlayer != None:
-        #执行玩家击杀玩家逻辑
-        AttackCommon.OnPlayerKillPlayer(curPlayer, curTagPlayer, tick)
-        
-        #刷新NPC的仇恨列表,删除死亡对象
-        npcControl = NPCCommon.NPCControl(curSummonNPC)
-        npcControl.RefreshAngryList(tick)
-    
-    #玩家已经死亡
-    tagPlayerControl = PlayerControl.PlayerControl(curTagPlayer)
-    tagPlayerControl.SetDead()
-    return True
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
deleted file mode 100644
index b298f0b..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/SummonNPC_Attack_SummonNPC.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#---------------------------------------------------------------------
-#
-#---------------------------------------------------------------------
-##@package SummonNPC_Attack_SummonNPC
-# 召唤兽攻击召唤兽
-#
-# @author eggxp
-# @date 2010-4-20
-# @version 1.9
-#
-# 修改时间 修改人 修改内容
-# @change: "2010-05-12 18:30" zhengyang 添加注释
-# @change: "2010-05-28 15:50" chenxuewei 应策划刘鸿生需求:增加剑圣项目的PK规则
-# @change: "2010-06-02 10:50" chenxuewei 玩家可以攻击目标的情况下,获得玩家间的关系统一在AttackCommon处理
-# @change: "2010-06-07 13:30" Alee 召唤兽攻击给主人加仇恨
-# @change: "2010-06-07 17:30" Alee 调用已有的管理器
-# @change: "2010-09-06 17:30" panwei GetBattleType函数修改, 新增参数:攻击方
-# @change: "2010-09-27 17:55" panwei 取消GM不可攻击限制
-# @change: "2012-02-10 20:20" Alee 添加技能必发生状态
-# @change: "2016-02-26 17:00" hxp 增加PVP伤害统计
-#------------------------------------------------------------------------------ 
-"""Version = 2016-02-26 17:00"""
-#---------------------------------------------------------------------
-import NPCCommon
-import AttackCommon
-import ChConfig
-import IPY_GameWorld
-import GameWorld
-import PlayerControl
-import SkillShell
-import TurnAttack
-import GameObj
-#---------------------------------------------------------------------
-
-#---------------------------------------------------------------------
-
-## 是否可以攻击 
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True or False
-#  @remarks 是否可以攻击 
-def GetCanAttack(curSummonNPC, curTagSummon, skill, tick):
-    return AttackCommon.CheckNPCCanAttackTag(curSummonNPC, curTagSummon, skill)
-
-## 获得关系
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return 如:ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-#  @remarks 获得关系
-def GetTagRelation(curSummonNPC, curTagSummon, skill, tick):
-    #变量初始化
-    curSummonOwner_NPC = None
-    curTagSummonOwner_NPC = None
-    
-    #获得2个召唤兽的主人
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC) 
-    
-    if curPlayer == None :
-        curSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curSummonNPC)
-    
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    
-    if curTagPlayer == None :
-        curTagSummonOwner_NPC = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curTagSummon)
-    
-    if curSummonOwner_NPC != None and curTagSummonOwner_NPC != None :
-        #NPC的召唤兽不互相攻击
-        return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-    
-    if curPlayer != None and curTagPlayer != None :
-        #私有木桩只能自己打自己的
-        if curTagSummon.GetType() in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
-            summonPlayerID = curTagSummon.GetDictByKey(ChConfig.Def_NPC_Dict_PriWoodPilePlayerID)
-            if curPlayer.GetPlayerID() != summonPlayerID:
-                return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-            return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-        
-        #同一玩家不互相攻击
-        if GameWorld.IsSameObj(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_None
-        
-        
-        #检查攻击模式
-        if not AttackCommon.CheckPlayerAttackMode_Player(curPlayer, curTagPlayer):
-            return ChConfig.Type_Relation_Friend , ChConfig.Def_PASysMessage_AttackMode
-        
-        #------------------------以下逻辑,都是玩家可以攻击目标的情况下
-        
-        return AttackCommon.GetPlayersRelation(curPlayer, curTagPlayer)
-    
-    #不同类型的,可以直接攻击
-    return ChConfig.Type_Relation_Enemy , ChConfig.Def_PASysMessage_None
-
-
-## 攻击
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param skillValue 技能增强
-#  @param skillPercent 技能增强百分比
-#  @param skillHurtList 技能伤血列表(C++接口)
-#  @param tick 当前时间
-#  @return hurtType : HurtType 伤害结构体类 
-#  @remarks 攻击
-def DoAttack(curSummonNPC, curTagSummon, skill, skillValue, skillPercent, skillHurtList, tick):
-    hurtType = AttackCommon.GetHurtHP(curSummonNPC, curTagSummon, skill, 
-                                      skillValue, skillPercent, tick)
-    hurtHP = hurtType.HurtHP
-    #添加仇恨
-    summonControl = NPCCommon.NPCControl(curTagSummon)
-    summonControl.AddObjDetelToAngryList_ByAttack(curSummonNPC, hurtHP, skill)
-    
-    #---攻击方为召唤兽,给主人加仇恨---
-    summonOwner = NPCCommon.GetSummonOwnerDetel(curSummonNPC)
-    
-    if summonOwner != None:
-        summonControl.AddObjToAngryList(summonOwner, 1)
-
-    curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    if curPlayer != None and curTagPlayer != None:
-        AttackCommon.OnPVPDamage(curPlayer, hurtHP, curTagPlayer, "Summon v Summon")
-        
-        
-    #添加技能伤害通知列表,(用于攻击结束,统一通知客户端)
-    AttackCommon.AddHurt(curTagSummon, skillHurtList, hurtType.HurtType, hurtHP)
-    return hurtType
-
-
-## 处理攻击后的结果
-#  @param curNormalNPC 攻击方:召唤兽
-#  @param curTagPlayer 防守方:召唤兽
-#  @param skill 技能(无->None)
-#  @param tick 当前时间
-#  @return True
-#  @remarks 处理攻击后的结果
-def AttackResult(curSummonNPC, curTagSummon, skill, tick):
-    #获取防守方召唤兽的主人
-    curTagPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curTagSummon)
-    #攻击的是玩家的召唤兽
-    if curTagPlayer != None and GameObj.GetHP(curTagPlayer) > 0:
-        #进入战斗状态
-        AttackCommon.SetPlayerBattleState(curTagPlayer, tick)
-        #获取召唤兽的主人
-        curPlayer = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curSummonNPC)
-        
-        #是否在特殊的副本中
-        if curPlayer != None:
-            AttackCommon.OnPlayerHitPlayer(curPlayer, curTagPlayer, tick)
-    
-    #防守方召唤兽死亡
-    if GameObj.GetHP(curTagSummon) <= 0:
-        if TurnAttack.SetTurnObjKilled(curTagSummon, curSummonNPC):
-            return
-        curTagSummonNPCControl = NPCCommon.NPCControl(curTagSummon)
-        #召唤兽死亡
-        curTagSummonNPCControl.SetKilled()
-    
-    return True
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 c5ef889..da07209 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
@@ -340,7 +340,7 @@
         
     DoLogic_AttackResult(attacker, defender, useSkill, tick)
     
-    TurnAttack.OnTurnfightAttackResult(attacker, defender, useSkill)
+    #TurnAttack.OnTurnfightAttackResult(attacker, defender, useSkill)
     return True
 
 #---------------------------------------------------------------------
@@ -666,7 +666,7 @@
     
     OnHurtTypeTriggerPassiveSkill(attacker, defender, curSkill, tick)
     DoLogic_AttackResult(attacker, defender, curSkill, tick)
-    TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+    #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
     return True
 
 
@@ -878,7 +878,7 @@
 
         DoLogic_AttackResult(attacker, defObj, curSkill, tick)
         
-    TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+    #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
     return
 
 ## 执行群攻攻击
@@ -1882,7 +1882,7 @@
     #通知客户端攻击结果
     __Sync_AttackResult(curNPC, target, curSkill)
     
-    TurnAttack.OnTurnfightAttackSuccess(curNPC, target, curSkill)
+    #TurnAttack.OnTurnfightAttackSuccess(curNPC, target, curSkill)
     
     #技能使用成功
     if curSkill:
@@ -2671,7 +2671,7 @@
 
         DoLogic_AttackResult(attacker, defObj, curSkill, tick)
         
-    TurnAttack.OnTurnfightAttackResult(attacker, None, curSkill)
+    #TurnAttack.OnTurnfightAttackResult(attacker, None, curSkill)
     return True
     
     
@@ -2781,7 +2781,7 @@
     sendPack.ValueEx = curHurt.GetHurtHPEx()
     sendPack.RemainHP = curHurt.GetCurHP()
     sendPack.RemainHPEx = curHurt.GetCurHPEx()
-    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(attacker.GetID())
+    turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(attacker.GetTFGUID())
     if turnFight:
         turnFight.addBatPack(sendPack)
         return
@@ -2797,7 +2797,7 @@
     # m_LastBattleTick = GetGameWorldManager()->GetTick();
     #===========================================================================
     
-    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(attacker.GetID())
+    turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(attacker.GetTFGUID())
     if turnFight:
         sendPack = ChNetSendPack.tagUseSkillAttack()
         sendPack.ObjID = attacker.GetID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
new file mode 100644
index 0000000..2b7da00
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -0,0 +1,578 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package BattleObj
+#
+# @todo:战斗对象
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: py自定义的战斗对象,可以是玩家、NPC通用的,废弃原c++的Player及NPC,完全由py自行处理
+# MMO项目可以curPlayer绑定一个战斗对象,curPlayer仅做为玩家的数据对象,战斗相关统一使用战斗对象
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import TurnAttack
+import IpyGameDataPY
+import ChNetSendPack
+import ShareDefine
+import ChConfig
+import ObjPool
+
+class HurtObj():
+    ## 伤血统计
+    
+    def __init__(self):
+        self.Clear()
+        return
+    
+    def Clear(self):
+        self._objID = 0
+        self._hurtTypes = 0 # 本次伤血类型,如闪避、暴击、格挡等,通过二进制或运算得到最终值,支持多种同时出现,如暴击的同时被格挡
+        self._hurtHP = 0 # 伤血值
+        self._lostHP = 0 # 实际掉血值
+        self._curHP = 0 # 更新血量
+        self._suckHP = 0 # 吸血量
+        self._bounceHP = 0 # 反弹血量
+        return
+    
+    def GetObjID(self): return self._objID
+    def SetObjID(self, objID): self._objID = objID
+    def GetHurtTypes(self): return self._hurtTypes
+    def SetHurtTypes(self, hurtTypes): self._hurtTypes = hurtTypes
+    def AddHurtType(self, hurtType):
+        ## 添加伤血类型,单次伤害支持多种类型同时出现
+        self._hurtTypes |= pow(2, hurtType)
+        return
+    def HaveHurtType(self, hurtType):
+        ## 判断是否存在某种伤血类型
+        return self._hurtTypes&pow(2, hurtType) 
+    def GetHurtHP(self): return self._hurtHP
+    def SetHurtHP(self, hurtHP): self._hurtHP = hurtHP
+    def GetLostHP(self): return self._lostHP
+    def SetLostHP(self, lostHP): self._lostHP = lostHP
+    def GetCurHP(self): return self._curHP
+    def SetCurHP(self, curHP): self._curHP = curHP
+    def GetSuckHP(self): return self._suckHP
+    def SetSuckHP(self, suckHP): self._suckHP = suckHP
+    def GetBounceHP(self): return self._bounceHP
+    def SetBounceHP(self, bounceHP): self._bounceHP = bounceHP
+    
+class PyBuff():
+    
+    def __init__(self, skillData):
+        self._skillData = skillData
+        self._buffID = 0
+        self._ownerID = 0
+        self._layer = 0
+        self._remainTime = 0
+        self._valueList = []
+        return
+    
+    def GetSkillData(self): return self._skillData
+    def GetSkillID(self): return self._skillData.GetSkillID()
+    def GetBuffID(self): return self._buffID
+    def SetBuffID(self, buffID): self._buffID = buffID
+    def GetOwnerID(self): return self._ownerID
+    def SetOwnerID(self, ownerID): self._ownerID = ownerID
+    def GetLayer(self): return self._layer
+    def SetLayer(self, layer): self._layer = layer
+    def GetRemainTime(self): return self._remainTime
+    def SetRemainTime(self, remainTime): self._remainTime = remainTime
+    def SetValueList(self, valueList): self._valueList = valueList
+    def GetValue(self, index):
+        return self._valueList[index] if len(self._valueList) > index else 0
+
+class BuffManager():
+    ## 战斗对象buff管理器
+    
+    def __init__(self):
+        self._buffList = [] # [PyBuff, ...]
+        self._buffIDDict = {} # {buffID:PyBuff, ...}
+        self._skillTypeIDBuffIDs = {} # 技能TypeID对应的buff {skillTypeID:[buffID, ...], ...}
+        self._buffID = 0 # 该对象的唯一buffID,递增,不同对象buffID可重复,buffID非skillID,不同buffID的skillID可能一样
+        # 该项目设定同一个对象可能同时存在多个相同skillID的buff,独立算CD
+        return
+    
+    def ClearBuff(self):
+        poolMgr = ObjPool.GetPoolMgr()
+        for buff in self._buffList:
+            poolMgr.release(buff)
+        self._buffList = []
+        self._buffIDDict = {}
+        self._skillTypeIDBuffIDs = {}
+        self._buffID = 0
+        return
+    
+    def GetBuffCount(self): return len(self._buffList)
+    def GetBuffByIndex(self, index):
+        buff = self._buffList[index]
+        #if False:
+        #    buff = PyBuff()
+        return buff
+        
+    def AddBuff(self, skillID):
+        buff = None
+        skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+        if not skillData:
+            return buff
+        skillTypeID = skillData.GetSkillTypeID()
+        self._buffID += 1
+        
+        buff = ObjPool.GetPoolMgr().acquire(PyBuff, skillData)
+        buff.SetBuffID(self._buffID)
+        
+        self._buffList.append(buff)
+        self._buffIDDict[self._buffID] = buff
+        if skillTypeID not in self._skillTypeIDBuffIDs:
+            self._skillTypeIDBuffIDs[skillTypeID] = []
+        buffIDs = self._skillTypeIDBuffIDs[skillTypeID]
+        if self._buffID not in buffIDs:
+            buffIDs.append(self._buffID)
+            
+        #if False:
+        #    buff = PyBuff()
+        return buff
+    
+    def GetBuff(self, buffID):
+        buff = None
+        if buffID in self._buffIDDict:
+            buff = self._buffIDDict[buffID]
+        #if False:
+        #    buff = PyBuff()
+        return buff
+    
+    def FindBuffIDBySkillID(self, skillID):
+        ## 返回该技能ID的所有buffID列表
+        skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+        if not skillData:
+            return []
+        return self.FindBuffIDBySkillTypeID(skillData.GetSkillTypeID())
+    def FindBuffIDBySkillTypeID(self, skillTypeID):
+        ## 返回该技能TypeID的所有buffID列表
+        if skillTypeID not in self._skillTypeIDBuffIDs:
+            return []
+        buffs = []
+        for buffID in self._skillTypeIDBuffIDs[skillTypeID]:
+            if buffID not in self._buffIDDict:
+                continue
+            buffs.append(self._buffIDDict[buffID])
+        return buffs
+    
+class PySkill():
+    
+    def __init__(self, skillData):
+        self._skillData = skillData
+        self._remainTime = 0
+        self._batType = 0 # 战斗类型,普通、连击、反击、追击等
+        self._enhanceBySkill = None # 由哪个主技能触发的
+        self._tagObjList = [] # 本次技能目标列表 [BatObj, ...]
+        self._hurtList = [] # 本次伤血列表 [HurtObj, ...]
+        return
+    
+    def SetSkillData(self, skillData): self._skillData = skillData
+    def GetSkillID(self): return self._skillData.GetSkillID()
+    def GetSkillTypeID(self): return self._skillData.GetSkillTypeID()
+    def GetSkillMaxLV(self): return self._skillData.GetSkillMaxLV()
+    def GetSkillName(self): return self._skillData.GetSkillName()
+    def GetFuncType(self): return self._skillData.GetFuncType()
+    def GetSkillType(self): return self._skillData.GetSkillType()
+    def GetHurtType(self): return self._skillData.GetHurtType()
+    def GetAtkType(self): return self._skillData.GetAtkType()
+    def GetTagAim(self): return self._skillData.GetTagAim() # 瞄准位置
+    def GetTagFriendly(self): return self._skillData.GetTagFriendly() # 敌我目标
+    def GetTagSelf(self): return self._skillData.GetTagSelf() # 是否含自己
+    def GetTagAffect(self): return self._skillData.GetTagAffect() # 目标细分
+    def GetTagCount(self): return self._skillData.GetTagCount() # 目标个数
+    def GetHappenRate(self): return self._skillData.GetHappenRate() # 释放或添加几率
+    def GetLastTime(self): return self._skillData.GetLastTime() # 持续时间
+    def GetCoolDownTime(self): return self._skillData.GetCoolDownTime()
+    def FindEffectID(self, effID):
+        ## 查找是否有某个效果ID
+        # @return: 大于0该ID所在的效果ID编号; 0-不存在该效果ID
+        for idNum in range(1, 1 + 3):
+            if self.GetEffectID(idNum) == effID:
+                return idNum
+        return 0
+    def GetEffectID(self, idNum):
+        ## 获取效果ID
+        # @param idNum: 效果ID编号,从1开始
+        if idNum == 1:
+            return self._skillData.GetEffectID1()
+        if idNum == 2:
+            return self._skillData.GetEffectID2()
+        if idNum == 3:
+            return self._skillData.GetEffectID3()
+        return 0
+    def GetEffectValue(self, idNum, index):
+        ## 获取效果对应值
+        # @param idNum: 效果ID编号,从1开始
+        # @param index: 值索引,从0开始代表第1个值
+        if idNum <= 0:
+            return 0
+        if idNum == 1:
+            values = self._skillData.GetEffectValues1()
+        elif idNum == 2:
+            values = self._skillData.GetEffectValues2()
+        elif idNum == 3:
+            values = self._skillData.GetEffectValues3()
+        else:
+            return 0
+        return values[index] if len(values) > index else 0
+    def GetConnSkill(self): return self._skillData.GetConnSkill() # 关联技能
+    def GetEnhanceSkillList(self): return self._skillData.GetEnhanceSkillList() # 额外触发的技能ID列表
+    def GetFightPower(self): return self._skillData.GetFightPower()
+    
+    ## ---------------------------------- 非技能表内容 ----------------------------------
+    def GetRemainTime(self): return self._remainTime
+    def SetRemainTime(self, remainTime): self._remainTime = remainTime
+    def GetBatType(self): return self._batType
+    def SetBatType(self, batType): self._batType = batType
+    def GetEnhanceBySkill(self): return self._enhanceBySkill
+    def SetEnhanceBySkill(self, enhanceBySkill): self._enhanceBySkill = enhanceBySkill
+    def GetTagObjList(self): return self._tagObjList # 技能目标列表
+    def SetTagObjList(self, tagObjList): self._tagObjList = tagObjList
+    def ClearHurtObj(self):
+        ## 清空伤血统计
+        poolMgr = ObjPool.GetPoolMgr()
+        for hurtObj in self._hurtList:
+            poolMgr.release(hurtObj)
+        self._hurtList = []
+        return
+    def AddHurtObj(self, tagID):
+        ## 添加某个伤血
+        hurtObj = ObjPool.GetPoolMgr().acquire(HurtObj)
+        hurtObj.SetObjID(tagID)
+        self._hurtList.append(hurtObj)
+        return hurtObj
+    def GetHurtObjList(self): return self._hurtList
+    def GetHurtObj(self, tagID):
+        ## 获取某个伤血,如果目标没有在伤血列表里则返回None
+        for hurtObj in self._hurtList:
+            if hurtObj.GetObjID() == tagID:
+                return hurtObj
+        return
+    
+class SkillManager():
+    ## 战斗对象技能管理器
+    
+    def __init__(self):
+        self._skillList = [] # 技能列表 [PySkill, ...]
+        self._skillDict = {} # {skillID:PySkill, ...}
+        return
+    
+    def SkillReset(self):
+        poolMgr = ObjPool.GetPoolMgr()
+        for skill in self._skillList:
+            poolMgr.release(skill)
+        self._skillList = []
+        self._skillDict = {}
+        return
+    
+    def GetSkillCount(self): return len(self._skillList)
+    def GetSkillByIndex(self, index):
+        skill = self._skillList[index]
+        #if False:
+        #    skill = PySkill()
+        return skill
+    def FindSkillByID(self, skillID):
+        skill = self._skillDict.get(skillID, None)
+        #if False:
+        #    skill = PySkill()
+        return skill
+    def FindSkillByTypeID(self, skillTypeID):
+        skill = None
+        for s in self._skillList:
+            if s.GetSkillTypeID() == skillTypeID:
+                skill = s
+                break
+        #if False:
+        #    skill = PySkill()
+        return skill
+    
+    def LearnSkillByID(self, skillID):
+        skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+        if not skillData:
+            return
+        if skillID in self._skillDict:
+            return
+        skillTypeID = skillData.GetSkillTypeID()
+        curSkill = self.FindSkillByTypeID(skillTypeID)
+        if curSkill:
+            if curSkill.GetSkillID() >= skillID:
+                return
+            # 升级技能
+            curSkill.SetSkillData(skillData)
+        else:
+            # 学新技能
+            curSkill = ObjPool.GetPoolMgr().acquire(PySkill, skillData)
+            self._skillDict[skillID] = curSkill
+            self._skillList.append(curSkill)
+        return curSkill
+    
+class BatObj():
+    ## 战斗实体对象数据,目前与某个NPCObj绑定
+    
+    def __init__(self):
+        self.tfGUID = "" # 所属的某场回合战斗的guid
+        self.objID = 0
+        self.objName = ""
+        self.npcID = 0
+        self.ownerID = 0 # 所属玩家ID,可能为0,0代表非玩家的战斗实体
+        self.heroID = 0
+        self.skinID = 0
+        self.lv = 1
+        self.fightPower = 0
+        self.faction = 0 # 所属阵营,一般只有双方阵营, 1 或 2,发起方默认1
+        self.lineupNum = 1 # 阵容位置编号,一般多V多时有用,通常默认1
+        self.posNum = 0 # 所在阵容站位
+        self._initAttrDict = {} # 初始化时的属性,固定不变,初始化时已经算好的属性  {attrID:value, ...}
+        self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性
+        self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...}
+        self._kvDict = {} # 自定义kv字典
+        self._skillUseCntDict = {} # 技能累计使用次数 {skillID:useCnt, ...}
+        self._skillTurnUseCntDict = {} # 技能单回合累计使用次数 {skillID:useCnt, ...}
+        self._skillMgr = ObjPool.GetPoolMgr().acquire(SkillManager)
+        self._buffMgr = ObjPool.GetPoolMgr().acquire(BuffManager)
+        
+        # 统计
+        self.hurtStat = 0 # 输出统计
+        self.defStat = 0 # 承伤统计
+        self.cureStat = 0 # 治疗统计
+        return
+    
+    def InitBatAttr(self, initAttrDict, initXP=0):
+        ## 初始化战斗属性
+        self._initAttrDict = initAttrDict
+        self._batAttrDict = {}
+        self._batAttrDict.update(initAttrDict)
+        self._batAttrDict[ChConfig.AttrID_XP] = initXP
+        self._batAttrDict[ChConfig.AttrID_HP] = initAttrDict.get(ChConfig.AttrID_MaxHP, 1)
+        self._skillTempAttrDict = {}
+        return
+    def GetTFGUID(self): return self.tfGUID # 所属的某场战斗
+    def SetTFGUID(self, tfGUID): self.tfGUID = tfGUID
+    def GetTurnFight(self): return TurnAttack.GetTurnFightMgr().getTurnFight(self.tfGUID)
+    def GetID(self): return self.objID
+    def GetName(self): return self.objName
+    def SetName(self, name): self.objName = name
+    def GetNPCID(self): return self.npcID # 如果是NPC战斗单位,则该值非0
+    def SetNPCID(self, npcID): self.npcID = npcID # 设置所属的NPCID
+    def GetOwnerID(self): return self.ownerID # 如果是玩家战斗单位,则该值非0,为所属玩家ID
+    def GetHeroID(self): return self.heroID # 仅玩家有值,某个武将ID
+    def GetSkinID(self): return self.heroID # 仅玩家有值,武将皮肤
+    def SetOwnerHero(self, ownerID, heroID, skinID): # 设置所属的玩家及武将
+        self.ownerID = ownerID
+        self.heroID = heroID
+        self.skinID = skinID
+    def SetLineupPos(self, posNum, lineupNum=1):
+        ## 设置阵容所在位置
+        # @param posNum: 在本阵容中的站位
+        # @param lineupNum: 本阵容在本阵营中的站位,一般多V多时有用,默认1
+        self.posNum = posNum
+        self.lineupNum = lineupNum
+    def GetLineupNum(self): return self.lineupNum
+    def GetPosNum(self): return self.posNum
+    def GetFaction(self): return self.faction
+    def SetFaction(self, faction): self.faction = faction
+    def GetFightPower(self): return self.fightPower
+    def SetFightPower(self, fightPower): self.fightPower = fightPower
+    def GetLV(self): return self.lv
+    def SetLV(self, lv): self.lv = lv
+    def GetDictByKey(self, key): return self._kvDict.get(key, 0)
+    def SetDict(self, key, value): self._kvDict[key] = value
+    
+    def GetSkillManager(self): return self._skillMgr
+    def GetBuffManager(self):return self._buffMgr
+    
+    def GetCanAttack(self):
+        ## 可否被攻击
+        # 无敌buff
+        #if 无敌:
+        #    return False
+        return True
+    
+    # 战斗属性
+    def GetMaxHP(self): return self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0)
+    def SetMaxHP(self, maxHP): self._batAttrDict[ChConfig.AttrID_MaxHP] = maxHP
+    def GetHP(self): return self._batAttrDict.get(ChConfig.AttrID_HP, 0)
+    def SetHP(self, hp, isNotify=False):
+        self._batAttrDict[ChConfig.AttrID_HP] = hp
+        if isNotify:
+            NotifyObjInfoRefresh(self, ChConfig.AttrID_HP, hp)
+        return
+    def SetHPFull(self, isNotify=True): self.SetHP(self.GetMaxHP())
+    def GetXP(self): return self._batAttrDict.get(ChConfig.AttrID_XP, 0)
+    def SetXP(self, xp, isNotify=True):
+        self._batAttrDict[ChConfig.AttrID_XP] = xp
+        if isNotify:
+            NotifyObjInfoRefresh(self, ChConfig.AttrID_XP, xp)
+        return
+    def GetAtk(self): return self.GetAttrValue(ChConfig.AttrID_Atk)
+    def GetDef(self): return self.GetAttrValue(ChConfig.AttrID_Def)
+    
+    def GetAttrValue(self, attrID):
+        value = self._batAttrDict.get(attrID, 0)
+        if attrID in self._skillTempAttrDict:
+            value += self._skillTempAttrDict[attrID] # 支持正负值
+            value = max(1, value)
+        return value
+    def AddSkillTempAttr(self, attrID, value):
+        ## 增加技能临时属性,支持正负值
+        # @param value: 正值-加属性;负值-减属性
+        self._skillTempAttrDict[attrID] = self._skillTempAttrDict.get(attrID, 0) + value
+    def ClearSkillTempAttr(self): self._skillTempAttrDict = {}
+    
+    def GetSkillUseCnt(self, skillID): return self._skillUseCntDict.get(skillID, 0)
+    def GetSkillTurnUseCnt(self, skillID): return self._skillTurnUseCntDict.get(skillID, 0)
+    def AddSkillUseCnt(self, skillID):
+        self._skillUseCntDict[skillID] = self._skillUseCntDict.get(skillID, 0) + 1
+        self._skillTurnUseCntDict[skillID] = self._skillTurnUseCntDict.get(skillID, 0) + 1
+        
+    def StatHurtValue(self, hurtValue):
+        ## 统计输出
+        self.hurtStat += hurtValue
+        return self.hurtStat
+    
+    def StatDefValue(self, lostHP):
+        ## 统计承伤
+        self.defStat += lostHP
+        return self.defStat
+    
+    def StatCureValue(self, cureValue):
+        ## 统计治疗
+        self.cureStat += cureValue
+        return self.cureStat
+    
+    def TurnReset(self):
+        ## 回合重置
+        self._skillTurnUseCntDict = {}
+        
+    def ResetBatObj(self, isReborn=True):
+        ## 重置战斗相关
+        # @param isReborn: 死亡的是否复活
+        
+        # 重置统计
+        self.hurtStat = 0
+        self.defStat = 0
+        self.cureStat = 0
+        
+        if self.GetHP() <= 0 and not isReborn:
+            return
+        
+        # 清除buff
+        
+        # 回满血
+        self.SetHPFull()
+        
+        # 重置怒气
+        initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
+        self.SetXP(initXP)
+        return
+    
+    
+class BattleObjMgr():
+    ## 战斗对象管理器
+    
+    def __init__(self):
+        self._newID = 0 # 管理创建新的实例ID
+        self._freeIDList = []
+        self.batObjDict = {} # 战斗单位 {objID:BatObj, ...}
+        return
+    
+    def __getNewObjID(self):
+        while self._freeIDList:
+            objID = self._freeIDList.pop(0)
+            if objID not in self.batObjDict:
+                return objID
+            
+        maxID = 100000
+        if self._newID >= maxID:
+            self._newID = 0
+        while self._newID < maxID:
+            self._newID += 1
+            if self._newID not in self.batObjDict:
+                return self._newID
+        GameWorld.ErrLog("__getNewObjID error.")
+        return 0
+    
+    def addBatObj(self):
+        ## 添加战斗单位
+        newBatObj = None
+        newObjID = self.__getNewObjID()
+        if not newObjID:
+            return newBatObj
+        newBatObj = ObjPool.GetPoolMgr().acquire(BatObj)
+        newBatObj.objID = newObjID
+        self.batObjDict[newObjID] = newBatObj
+        GameWorld.DebugLog("添加战斗单位: objID=%s" % (newObjID))
+        if False:
+            newBatObj = BatObj(None, 0)
+        return newBatObj
+    
+    def getBatObj(self, objID):
+        batObj = None
+        if objID in self.batObjDict:
+            batObj = self.batObjDict[objID]
+        elif False:
+            batObj = BatObj(None, 0)
+        return batObj
+    
+    def delBatObj(self, objID):
+        if objID not in self.batObjDict:
+            return
+        batObj = self.batObjDict.pop(objID)
+        if not batObj:
+            return
+        objID = batObj.objID
+        GameWorld.DebugLog("回收战斗单位: objID=%s" % (objID))
+        turnFight = batObj.GetTurnFight()
+        if turnFight:
+            # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分
+            clientPack = ChNetSendPack.tagNPCDisappear()
+            clientPack.NPCID = [objID]
+            clientPack.Count = len(clientPack.NPCID)
+            turnFight.addBatPack(clientPack)
+            
+        # 最后回收对象
+        ObjPool.GetPoolMgr().release(batObj)
+        if objID not in self._freeIDList: # 回收ID,重复利用
+            self._freeIDList.append(objID)
+        return
+    
+def GetBatObjMgr():
+    batObjMgr = PyGameData.g_batObjMgr
+    if not batObjMgr:
+        batObjMgr = BattleObjMgr()
+        PyGameData.g_batObjMgr = batObjMgr
+    return batObjMgr
+
+def OnMinute():
+    GameWorld.Log("战斗单位数量: %s" % len(GetBatObjMgr().batObjDict))
+    return
+
+def NotifyObjInfoRefresh(batObj, attrID, value):
+    ##0418通知对象属性刷新
+    if attrID not in ChConfig.CDBRefresh_AttrIDDict:
+        return
+    refreshType, isBig = ChConfig.CDBRefresh_AttrIDDict[attrID]
+    turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(batObj.GetTFGUID())
+    if not turnFight:
+        return
+    clientPack = ObjPool.GetPoolMgr().acquire(ChNetSendPack.tagObjInfoRefresh)
+    clientPack.ObjID = batObj.GetID()
+    clientPack.RefreshType = refreshType
+    if isBig:
+        clientPack.Value = value % ShareDefine.Def_PerPointValue
+        clientPack.ValueEx = value / ShareDefine.Def_PerPointValue
+    else:
+        clientPack.Value = value
+        clientPack.ValueEx = 0
+    turnFight.addBatPack(clientPack)
+    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 e1e95ad..1bc7528 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -31,12 +31,13 @@
 import NPCCommon
 import ShareDefine
 import PyGameData
-import IPY_GameWorld
 import ItemControler
 import SkillCommon
-import SkillShell
 import AttackCommon
-import FBLogic
+import BattleObj
+import TurnSkill
+import TurnBuff
+import ObjPool
 
 import random
 import time
@@ -55,129 +56,61 @@
 FightState_Award, # 4 结算奖励
 FightState_Over, # 5 结束状态,无特殊意义,仅代表所有处理结束了,与Start对应
 ) = range(6)
-
-Def_FactionA = 1
-Def_FactionB = 2
-
+    
 class BatLineup():
     ## 战斗阵容
     
-    def __init__(self, faction, num, fightMgr):
-        self.fightMgr = fightMgr
+    def __init__(self, faction, num, turnFight):
+        self.turnFight = turnFight # TurnFight
         self.faction = faction # 所属阵营
         self.num = num # 该阵容所在阵营中的编号,不同阵营可重复,多V多
         self.ownerID = 0 # 阵容所属玩家ID,可能为0,0代表非玩家阵容
-        self.npcPosDict = {} # 阵容NPC {站位编号:curNPC, ...}, 站位编号小于0为非主战单位,如主公、红颜等
-        self.npcObjIDDict = {} # NPC实例ID字典 {objID:curNPC, ...}
         self.shapeType = 0 # 阵型
-        self.actionNum = ActionNumStart # 行动位置,从1开始
-        self.lordAttrDict = {} # 主公属性
-        self.npcAttrDict = {} # 阵容NPC属性 {npcID:{attrID:value, ...}, ...}
         self.fightPower = 0 # 阵容总战力
-        
-        # 战斗统计
-        self.hurtStatDict = {} # 输出统计 {objID:totalValue, ...}
-        self.defStatDict = {} # 承伤统计 {objID:totalValue, ...}
-        self.cureStatDict = {} # 治疗统计 {objID:totalValue, ...}
+        self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
+        self.actionNum = ActionNumStart # 行动位置,从1开始
         return
     
-    def getGUID(self): return self.fightMgr.guid
-    def getPlayerID(self): return self.fightMgr.playerID # 发起的玩家ID
+    def getPlayerID(self): return self.turnFight.playerID # 发起的玩家ID
     
-    def isEmpty(self): return not self.npcPosDict
+    def isEmpty(self): return not self.posObjIDDict
     
     def setLineup(self, lineupInfo):
         ## 设置阵容
         # @param lineupInfo: 阵容信息
         self.clearLineup()
         self.ownerID = lineupInfo.get("PlayerID", 0) # 阵容所属的玩家ID
-        self.shapeType = lineupInfo.get("Shape", 0)
-        self.lordAttrDict = lineupInfo.get("LordAttrDict", {})
+        self.shapeType = lineupInfo.get("ShapeType", 0)
+        self.fightPower = lineupInfo.get("FightPower", 0)
         SummonLineupObjs(self, self.faction, self.num, lineupInfo, self.getPlayerID())
-        return
-    
-    def refreshFightPower(self):
-        ## 刷新阵容总战力
-        if self.fightPower:
-            return self.fightPower
-        
-        return self.fightPower
-    
-    def __resetStat(self):
-        ## 重置战斗统计
-        self.actionNum = ActionNumStart
-        self.hurtStatDict = {}
-        self.defStatDict = {}
-        self.cureStatDict = {}
-        return
-    
-    def __resetAttrState(self, isReborn=True):
-        ## 重置属性状态
-        # @param isReborn: 是否复活
-        initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
-        for curNPC in self.npcPosDict.values():
-            if not curNPC:
-                continue
-            if GameObj.GetHP(curNPC) <= 0 and not isReborn:
-                continue
-            # 回满血,清除buff
-            GameObj.SetHPFull(curNPC, False)
-            # 重置怒气
-            GameObj.SetXP(curNPC, initXP, False)
-            # ...
-            
         return
     
     def resetLineup(self, isReborn=True):
         ## 重置阵容
-        self.__resetAttrState(isReborn)
-        self.__resetStat()
+        batObjMgr = BattleObj.GetBatObjMgr()
+        for objID in self.posObjIDDict.values():
+            batObj = batObjMgr.getBatObj(objID)
+            if not batObj:
+                continue
+            batObj.ResetBatObj(isReborn)
         return
     
     def clearLineup(self):
         ## 清除阵容
-        if not self.npcPosDict:
+        if not self.posObjIDDict:
             return
-        for curNPC in self.npcPosDict.values():
-            if not curNPC:
-                continue
-            NPCCommon.SetDeadEx(curNPC)
-        self.npcPosDict = {}
-        self.npcObjIDDict = {}
-        self.npcAttrDict = {}
+        batObjMgr = BattleObj.GetBatObjMgr()
+        for objID in self.posObjIDDict.values():
+            batObjMgr.delBatObj(objID)
+        self.posObjIDDict = {}
         self.fightPower = 0
-        self.__resetStat()
         return
-    
-    def statHurtValue(self, objID, hurtValue):
-        ## 统计输出
-        if objID not in self.npcObjIDDict:
-            return
-        updValue = self.hurtStatDict.get(objID, 0) + hurtValue
-        self.hurtStatDict[objID] = updValue
-        return updValue
-    
-    def statDefValue(self, objID, lostHP):
-        ## 统计承伤
-        if objID not in self.npcObjIDDict:
-            return
-        updValue = self.defStatDict.get(objID, 0) + lostHP
-        self.defStatDict[objID] = updValue
-        return updValue
-    
-    def statCureValue(self, objID, cureValue):
-        ## 统计治疗
-        if objID not in self.npcObjIDDict:
-            return
-        updValue = self.cureStatDict.get(objID, 0) + cureValue
-        self.cureStatDict[objID] = updValue
-        return updValue
     
 class BatFaction():
     ## 战斗阵营
     
-    def __init__(self, faction, fightMgr):
-        self.fightMgr = fightMgr
+    def __init__(self, faction, turnFight):
+        self.turnFight = turnFight # TurnFight
         self.faction = faction
         self.lineupDict = {} # 该阵营所有阵容信息 {编号:BatLineup, ...}
         return
@@ -188,7 +121,7 @@
         if num in self.lineupDict:
             lineup = self.lineupDict[num]
         else:
-            lineup = BatLineup(self.faction, num, self.fightMgr)
+            lineup = BatLineup(self.faction, num, self.turnFight)
             self.lineupDict[num] = lineup
         return lineup
     
@@ -237,9 +170,6 @@
         
         self.startTime = 0 # 开始时间戳,支持毫秒小数
         self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
-        
-        #玩家武将行动后击杀目标
-        self.playerKillObjIDList = [] # [objID, ...]
         return
     
     def setTurn(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}):
@@ -281,7 +211,6 @@
             if not lineupInfo:
                 continue
             batLineup.setLineup(lineupInfo)
-            batLineup.refreshFightPower()
         return
     
     def sortActionQueue(self):
@@ -290,7 +219,7 @@
         for batFaction in self.factionDict.values():
             faction = batFaction.faction
             for num, batLineup in batFaction.lineupDict.items():
-                fightPower = batLineup.refreshFightPower()
+                fightPower = batLineup.fightPower
                 sortValue = -(faction * 10 + num)
                 sortList.append([fightPower, sortValue, faction, num])
         sortList.sort(reverse=True) # 战力高的先手
@@ -304,7 +233,7 @@
         GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
         return
     
-    def getBatFaction(self, faction=Def_FactionA):
+    def getBatFaction(self, faction=ChConfig.Def_FactionA):
         ## 默认阵营1
         batFaction = None
         if faction in self.factionDict:
@@ -321,21 +250,25 @@
         if self.winFaction:
             return self.winFaction
         
+        batObjMgr = BattleObj.GetBatObjMgr()
         for faction, batFaction in self.factionDict.items():
             allKilled = True
             for batLineup in batFaction.lineupDict.values():
                 if not allKilled:
                     break
-                for posNum, curNPC in batLineup.npcPosDict.items():
+                for posNum, objID in batLineup.posObjIDDict.items():
                     if posNum <= 0:
                         # 非主战位置不判断
                         continue
-                    if GameObj.GetHP(curNPC) > 0:
+                    batObj = batObjMgr.getBatObj(objID)
+                    if not batObj:
+                        continue
+                    if batObj.GetHP() > 0:
                         allKilled = False
                         break
                     
             if allKilled:
-                self.winFaction = Def_FactionA if faction == Def_FactionB else Def_FactionA
+                self.winFaction = ChConfig.Def_FactionA if faction == ChConfig.Def_FactionB else ChConfig.Def_FactionA
                 DoTurnFightOver(self.guid)
                 return self.winFaction
             
@@ -363,6 +296,8 @@
         clientPack.Msg = msg
         clientPack.Len = len(clientPack.Msg)
         clientPack.FactionList = []
+        
+        batObjMgr = BattleObj.GetBatObjMgr()
         for faction in self.factionDict.keys():
             batFaction = self.getBatFaction(faction)
             tfFaction = ChPyNetSendPack.tagSCTurnFightFaction()
@@ -375,19 +310,22 @@
                 tfLineup.OwnerID = batLineup.ownerID
                 tfLineup.ShapeType = batLineup.shapeType
                 tfLineup.ObjList = []
-                for posNum, curNPC in batLineup.npcPosDict.items():
+                for posNum, objID in batLineup.posObjIDDict.items():
+                    batObj = batObjMgr.getBatObj(objID)
+                    if not batObj:
+                        continue
                     tfObj = ChPyNetSendPack.tagSCTurnFightObj()
-                    tfObj.ObjID = curNPC.GetID()
-                    tfObj.NPCID = curNPC.GetNPCID()
-                    tfObj.HeroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
-                    tfObj.SkinID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_SkinID)
-                    tfObj.HP = curNPC.GetHP()
-                    tfObj.HPEx = curNPC.GetHPEx()
-                    tfObj.MaxHP = curNPC.GetMaxHP()
-                    tfObj.MaxHPEx = curNPC.GetMaxHPEx()
-                    tfObj.LV = NPCCommon.GetNPCLV(curNPC)
+                    tfObj.ObjID = batObj.GetID()
+                    tfObj.NPCID = batObj.GetNPCID()
+                    tfObj.HeroID = batObj.GetHeroID()
+                    tfObj.SkinID = batObj.GetSkinID()
+                    tfObj.HP = batObj.GetHP() % ChConfig.Def_PerPointValue
+                    tfObj.HPEx = batObj.GetHP() / ChConfig.Def_PerPointValue
+                    tfObj.MaxHP = batObj.GetMaxHP() % ChConfig.Def_PerPointValue
+                    tfObj.MaxHPEx = batObj.GetMaxHP() / ChConfig.Def_PerPointValue
+                    tfObj.LV = batObj.GetLV()
                     tfObj.PosNum = posNum
-                    tfObj.AngreXP = GameObj.GetXP(curNPC)
+                    tfObj.AngreXP = batObj.GetXP()
                     tfLineup.ObjList.append(tfObj)
                 tfLineup.ObjCnt = len(tfLineup.ObjList)
                 tfFaction.LineupList.append(tfLineup)
@@ -411,7 +349,7 @@
         self.addBatPack(clientPack)
         return
     
-    def syncObjAction(self, turnNum, objType, objID):
+    def syncObjAction(self, turnNum, objID):
         clientPack = ChPyNetSendPack.tagMCTurnFightObjAction()
         clientPack.Clear()
         clientPack.TurnNum = turnNum
@@ -432,6 +370,8 @@
         # 有玩家的统一每个包单独发送,同样也支持战报统计
         if self.curPlayer:
             NetPackCommon.SendFakePack(self.curPlayer, clientPack)
+        else:
+            ObjPool.GetPoolMgr().release(clientPack)
         return
     
 class TurnFightMgr():
@@ -439,7 +379,6 @@
     
     def __init__(self):
         self.turnFightDict = {} # {guid:TurnFight, ...}
-        self.npcGUIDDict = {} # npc所属的某场战斗guid {objID:guid, ...}
         return
     
     def addTurnFight(self, mapID, funcLineID=0, playerID=0):
@@ -462,27 +401,6 @@
         elif False:
             tf = TurnFight()
         return tf
-    
-    def getNPCTurnFight(self, objID):
-        ## 获取NPC所在的回合战斗,如果该npc不属于某场回合战斗则返回None
-        tf = None
-        if objID in self.npcGUIDDict:
-            guid = self.npcGUIDDict[objID]
-            if guid in self.turnFightDict:
-                tf = self.turnFightDict[guid]
-        if not tf and False:
-            tf = TurnFight()
-        return tf
-    
-    def setNPCGUID(self, objID, guid):
-        ## 设置NPC所属回合战斗guid
-        self.npcGUIDDict[objID] = guid
-        GameWorld.DebugLog("设置NPC所属回合战斗guid: %s,%s" % (objID, guid))
-        return
-    def delNPCGUID(self, objID):
-        guid = self.npcGUIDDict.pop(objID, None)
-        GameWorld.DebugLog("删除NPC所属回合战斗guid: %s,%s" % (objID, guid))
-        return
     
 def GetTurnFightMgr():
     tfMgr = None
@@ -513,10 +431,6 @@
         ## 当前战斗是否关卡boss
         return self.turnFight.mapID == ChConfig.Def_FBMapID_MainBoss
     
-    def clear(self):
-        self.turnFight.clearFight()
-        return
-    
 def GetMainFightMgr(curPlayer):
     ## 获取主线战斗管理
     olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
@@ -532,71 +446,50 @@
                           % (chapterID, levelNum, nowChapterID, fixNowValue), curPlayer.GetPlayerID())
     return
 
-def GetPlayerLineupByCache(playerID, lineupID):
+def GetPlayerLineupInfoByCache(playerID, lineupID):
     ## 获取玩家阵容信息 - 根据玩家查看缓存
-    return {}
+    lineupInfo = {}
+    return lineupInfo
 
-def GetPlayerLineup(curPlayer, lineupID):
-    ## 获取玩家阵容信息
+def GetPlayerLineupInfo(curPlayer, lineupID):
+    ## 获取玩家阵容信息,可用于战斗或查看缓存,因为可能取玩家的缓存进行对战,所以统一使用json格式,前端通用
     # @param lineupID: 阵容ID
     # @return: 阵容全部信息json字典,前端通用格式
     
     playerID = curPlayer.GetPlayerID()
+    lineup = PlayerOnline.GetOnlinePlayer(curPlayer).GetLineup(lineupID)
     
-    # 武将
+    lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType}
     heroDict = {}
-    heroCount = 0
     curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
-    for index in range(curPack.GetCount()):
-        heroItem = curPack.GetAt(index)
-        if not heroItem or heroItem.IsEmpty():
-            continue
-        lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
-        if not lineupCount:
-            continue
-        posNum = 0 # 站位
-        for lpIndex in range(lineupCount):
-            lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
-            #阵容类型*10000+阵型类型*100+位置编号
-            if lineupValue / 10000 != lineupID:
-                continue
-            posNum = lineupValue % 100
-            break
-        
-        if not posNum:
-            continue
-        
-        heroID = heroItem.GetItemTypeID()
-        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
-        if not heroIpyData:
-            continue
-        skinIDList = heroIpyData.GetSkinIDList()
-        skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
-        if skinIndex < 0 or skinIndex >= len(skinIDList):
-            continue
-        skinID = skinIDList[skinIndex]
+    for posNum in lineup.lineupHeroDict.keys():
+        hero = lineup.GetLineupHero(posNum)
+        heroID = hero.heroID
+        itemIndex = hero.itemIndex
+        userData = ""
+        heroLV = 1
+        if itemIndex >= 0 and itemIndex < curPack.GetCount():
+            heroItem = curPack.GetAt(itemIndex)
+            if heroItem and not heroItem.IsEmpty():
+                userData = heroItem.GetUserData()
+                heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+                
+        skillIDlist = []
+        skillIDlist += hero.heroSkillIDList
         heroDict[str(posNum)] = {
                                  "HeroID":heroID,
-                                 "SkinID":skinID,
-                                 "Data":heroItem.GetUserData(),
+                                 "SkinID":hero.skinID,
+                                 "LV":heroLV,
+                                 "Data":userData,
+                                 "FightPower":hero.fightPower,
+                                 "AttrDict":{str(k):v for k, v in hero.heroBatAttrDict.items() if v > 0},
+                                 "SkillIDList":skillIDlist,
                                  }
-        
-        heroCount += 1
-        if heroCount >= ShareDefine.LineupObjMax:
-            break
-        
-    if not heroDict:
-        return {}
+    lineupInfo.update({"Hero":heroDict})
     
-    # 主公属性
-    lordAttrDict = PlayerControl.GetLordAttr(curPlayer)
-    
-    # 其他
-    
-    lineupInfo = {"PlayerID":playerID, "LordAttrDict":lordAttrDict, "Hero":heroDict}
     return lineupInfo
 
-def GetNPCLineup(lineupID):
+def GetNPCLineupInfo(lineupID):
     ## 获取NPC阵容信息
     # @param lineupID: 阵容ID
     # @return: 阵容全部信息json字典,前端通用格式
@@ -611,10 +504,26 @@
         npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
         if not npcID:
             continue
+        npcData = NPCCommon.GetNPCDataPy(npcID)
+        if not npcData:
+            continue
+        batAttrDict = {ChConfig.AttrID_Atk:npcData.GetAtk(), ChConfig.AttrID_Def:npcData.GetDef(), ChConfig.AttrID_MaxHP:npcData.GetMaxHP(), 
+                       ChConfig.AttrID_FinalDamPer:npcData.GetFinalDamPer(), ChConfig.AttrID_FinalDamPerDef:npcData.GetFinalDamPerDef(), 
+                       ChConfig.AttrID_MissRate:npcData.GetMissRate(), ChConfig.AttrID_MissRateDef:npcData.GetMissRateDef(), 
+                       ChConfig.AttrID_SuperHitRate:npcData.GetSuperHitRate(), ChConfig.AttrID_SuperHitRateDef:npcData.GetSuperHitRateDef(), 
+                       ChConfig.AttrID_StunRate:npcData.GetStunRate(), ChConfig.AttrID_StunRateDef:npcData.GetStunRateDef(), 
+                       ChConfig.AttrID_ComboRate:npcData.GetComboRate(), ChConfig.AttrID_ComboRateDef:npcData.GetComboRateDef(), 
+                       ChConfig.AttrID_ParryRate:npcData.GetParryRate(), ChConfig.AttrID_ParryRateDef:npcData.GetParryRateDef(), 
+                       ChConfig.AttrID_SuckHPPer:npcData.GetSuckHPPer(), ChConfig.AttrID_SuckHPPerDef:npcData.GetSuckHPPerDef(), 
+                       }
+        batAttrDict.update(npcData.GetSpecAttrInfo())
+        skillIDList = [] + npcData.GetSkillIDList()
+        heroDict[str(posNum)] = {"NPCID":npcID, 
+                                 "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0},
+                                 "SkillIDList":skillIDList
+                                 }
         
-        heroDict[str(posNum)] = {"NPCID":npcID}
-        
-    lineupInfo = {"Hero":heroDict}
+    lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict}
     return lineupInfo
 
 def SummonLineupObjs(batLineup, faction, num, lineupInfo, playerID=0):
@@ -624,115 +533,79 @@
     @param lineupInfo: 阵容信息
     @param playerID: 发起的玩家ID,系统场次为0
     '''
-    
-    '''关于视野层级说明 sightLevel
-        玩家发起的战斗视野层级只能用玩家ID,才能达到只通知该玩家的效果
-        但是由于同个玩家可能同时存在多场战斗,如主线战斗 + 其他战斗,所以视野层级只能用作仅通知该玩家的作用,
-        不能用于处理NPC视野来遍历伤害对象等,因为不同战场的NPC视野层级可能相同,对于同场战斗NPC的遍历处理只能用 turnFight 管理遍历
-        鉴于视野层级仅用于通知的作用,故系统场次理论上可以只用一个视野层级,但是为了减少不必要的问题,系统场次的视野层级还是尽量区分开来
-        这里暂时用时间戳的后4位来做短时间内的理论上唯一视野层级
-    '''
     GameWorld.DebugLog("SummonLineupObjs faction:%s,num:%s,lineupInfo=%s" % (faction, num, lineupInfo), playerID)
     if playerID:
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
         if not curPlayer:
             return
-        posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
-        sightLevel = playerID
         
-        # 开发过程中可以先开启视野层级及视野,方便检查战斗相关是否有遗漏
-        if curPlayer.GetSightLevel() != sightLevel:
-            PlayerControl.SetPlayerSightLevel(curPlayer, sightLevel)
-        sight = ChConfig.Def_PlayerSight_Default * 5
-        if curPlayer.GetSight() != sight:
-            PlayerControl.SetSight(curPlayer, sight)
-    else:
-        gameMap = GameWorld.GetMap()
-        posX, posY = gameMap.GetRebornMapX(), gameMap.GetRebornMapY() # 系统战斗默认取当前地图的复活点,需要优化
-        sightLevel = 2000000000 + int(time.time()) % 10000
-        
-    GameWorld.DebugLog("sightLevel=%s,pos=(%s,%s)" % (sightLevel, posX, posY), playerID)
-    
+    tfGUID = batLineup.turnFight.guid
     lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
     heroDict = lineupInfo.get("Hero", {})
-    tick = GameWorld.GetGameWorld().GetTick()
     
+    batObjMgr = BattleObj.GetBatObjMgr()
     initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
-    baseAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
-    tfMgr = GetTurnFightMgr()
-    space = 3
+    atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
     for posNumKey, heroInfo in heroDict.items():
         posNum = int(posNumKey)
         
-        heroID, skinID = 0, 0
-        baseAtkSkillID = 0 # 基础普攻ID
-        skillIDList = []
+        npcID, heroID, skinID = 0, 0, 0
+        atkBackSkillID = 0 # 反击技能ID
+        fightPower = 0
+        skillIDList = [] # 战斗对象可能改变属性或技能,重新创建,防止误修改来源值
+        attrDict = {}
+        skillIDList += heroInfo.get("SkillIDList", [])
+        attrDict.update(heroInfo.get("AttrDict", {}))
+        objName = ""
         if lineupPlayerID:
             heroID = heroInfo.get("HeroID", 0)
             skinID = heroInfo.get("SkinID", 0)
-            npcID = FighterNPCID
+            lv = heroInfo.get("LV", 1)
+            fightPower = heroInfo.get("FightPower", 0)
             heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
             if not heroIpyData:
                 continue
-            normalSkillID = heroIpyData.GetNormalSkillID()
-            angerSkillID = heroIpyData.GetAngerSkillID()
-            skillIDList += [normalSkillID, angerSkillID]
             atkDistType = heroIpyData.GetAtkDistType()
+            objName = heroIpyData.GetName()
         else:
             npcID = heroInfo.get("NPCID", 0)
-            npcDataEx = NPCCommon.GetNPCDataEx(npcID)
+            npcDataEx = NPCCommon.GetNPCDataPy(npcID)
             if not npcDataEx:
                 continue
-            skillIDList += npcDataEx.GetSkillIDList()
+            objName = npcDataEx.GetNPCName()
             atkDistType = npcDataEx.GetAtkDistType()
+            lv = npcDataEx.GetLV()
             
-        if not npcID:
-            continue
-        
-        npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
-        if not npcData:
-            continue
-        curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
-        if not curSummon:
-            continue
-        objID = curSummon.GetID()
-        batLineup.npcPosDict[posNum] = curSummon
-        batLineup.npcObjIDDict[objID] = curSummon
-        tfMgr.setNPCGUID(objID, batLineup.getGUID())
-        
-        curSummon.SetNPCTypeID(npcID)
-        curSummon.SetBornTime(tick)
-        curSummon.SetAIType(0)
-        curSummon.SetSightLevel(sightLevel)
-        curSummon.SetIsNeedProcess(False)
-        curSummon.SetCanAttack(True)
-        curSummon.SetVisible(True)
-        curSummon.SetDict(ChConfig.Def_Obj_Dict_TurnFightPosInfo, num * 100 + posNum)
-        curSummon.SetDict(ChConfig.Def_Obj_Dict_LineupPlayerID, lineupPlayerID)
-        curSummon.SetDict(ChConfig.Def_Obj_Dict_HeroID, heroID)
-        curSummon.SetDict(ChConfig.Def_Obj_Dict_SkinID, skinID)
-        GameObj.SetFaction(curSummon, faction)
-        GameObj.SetXP(curSummon, initXP, False)
+        batObj = batObjMgr.addBatObj()
+        if not batObj:
+            break
+        objID = batObj.GetID()
+        batObj.SetTFGUID(tfGUID)
+        batObj.SetName(objName)
+        batObj.SetFaction(faction)
+        batObj.SetLineupPos(posNum, num)
+        batObj.SetFightPower(fightPower)
+        batObj.SetLV(lv)
+        if npcID:
+            batObj.SetNPCID(npcID)
+        elif lineupPlayerID:
+            batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
+        batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
         
         if atkDistType == ChConfig.AtkDistType_Short:
-            baseAtkSkillID = baseAtkSkillIDList[0] if len(baseAtkSkillIDList) > 0 else 0
+            atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
         elif atkDistType == ChConfig.AtkDistType_Long:
-            baseAtkSkillID = baseAtkSkillIDList[1] if len(baseAtkSkillIDList) > 1 else 0
+            atkBackSkillID = atkBackSkillIDList[1] if len(atkBackSkillIDList) > 1 else 0
+        if atkBackSkillID:
+            skillIDList.append(atkBackSkillID)
+        skillManager = batObj.GetSkillManager()
+        skillManager.SkillReset()
+        for skillID in skillIDList:
+            skillManager.LearnSkillByID(skillID)
             
-        skillManager = curSummon.GetSkillManager()
-        #有指定的技能,重新学习
-        if skillIDList:
-            skillManager.ResetSkill()
-            for skillID in skillIDList:
-                skillManager.LVUPSkillByID(skillID)
-        if baseAtkSkillID:
-            skillManager.LVUPSkillByID(baseAtkSkillID)
-            
-        rebornX = posX - space + (faction - 1) * space * 3 + ((posNum - 1) / 3 * space * 2 * (-1 if faction == 1 else 1))
-        rebornY = posY + (posNum - 1) % 3 * space
-        GameWorld.DebugLog("SummonNPC ID:%s,faction:%s,num=%s,posNum=%s,baseAtkSkillID=%s,%s" % (curSummon.GetID(), faction, num, posNum, baseAtkSkillID, skillIDList))
-        curSummon.Reborn(rebornX, rebornY, False)
-        NPCCommon.NPCControl(curSummon).DoNPCRebornCommLogic(tick)
+        batLineup.posObjIDDict[posNum] = objID
+        GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s,atk=%s,def=%s,hp=%s" 
+                           % (objID, faction, num, posNum, skillIDList, batObj.GetAtk(), batObj.GetDef(), batObj.GetHP()))
         
     return
 
@@ -841,7 +714,7 @@
     teamNum = 1
     lineupID = waveLineupList[teamNum - 1] # NPC阵容ID
     
-    lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
+    lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
     if not lineupMainInfo:
         GameWorld.DebugLog("没有设置主阵容!", playerID)
         return
@@ -862,8 +735,8 @@
     
     turnFight = mainFightMgr.turnFight
     turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
-    turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
-    turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+    turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
     turnFight.sortActionQueue()
     turnFight.syncInit()
     return
@@ -915,7 +788,7 @@
     
     wave = waveMax = 1 # 关卡boss固定只有一波
     
-    lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
+    lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
     if not lineupMainInfo:
         GameWorld.DebugLog("没有设置主阵容!", playerID)
         return
@@ -936,8 +809,8 @@
     
     turnFight = mainFightMgr.turnFight
     turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
-    turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
-    turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
+    turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
     turnFight.sortActionQueue()
     turnFight.syncInit()
     
@@ -965,7 +838,7 @@
             mainFightMgr.nextTeam = False
             turnFight.resetTurn({"teamNum":teamNum})
             # 切换小队时,玩家阵容不需要处理,保留状态
-            turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
+            turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
             turnFight.sortActionQueue()
             turnFight.syncInit()
             
@@ -993,6 +866,7 @@
     doMax = (PosNumMax + 2) * len(turnFight.actionSortList) # 防止死循环,做最大循环次数限制 = (最大位置数 + 主公、红颜位置)*行动阵容数
     overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
     
+    batObjMgr = BattleObj.GetBatObjMgr()
     turnNum = turnFight.turnNum
     GameWorld.DebugLog("turnNum=%s,doMax=%s,actionIndex=%s,%s" % (turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
     while doCnt < doMax and len(overLineupList) < len(turnFight.actionSortList):
@@ -1011,8 +885,9 @@
                 batFaction = turnFight.getBatFaction(faction)
                 batLineup = batFaction.getBatlineup(num)
                 batLineup.actionNum = ActionNumStart
-                for curNPC in batLineup.npcPosDict.values():
-                    TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
+                for objID in batLineup.posObjIDDict.values():
+                    batObj = batObjMgr.getBatObj(objID)
+                    TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
                     
         if turnFight.actionIndex >= len(turnFight.actionSortList):
             turnFight.actionIndex = 0
@@ -1021,14 +896,14 @@
         faction, num = turnFight.actionSortList[turnFight.actionIndex]
         batFaction = turnFight.getBatFaction(faction)
         batLineup = batFaction.getBatlineup(num)
-        if batLineup.actionNum > max(batLineup.npcPosDict):
+        if batLineup.actionNum > max(batLineup.posObjIDDict):
             if (faction, num) not in overLineupList:
                 overLineupList.append((faction, num))
                 
             turnFight.actionIndex += 1
             continue
         
-        if faction == Def_FactionA:
+        if faction == ChConfig.Def_FactionA:
             if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
                 GameWorld.DebugLog("战锤不足!")
                 return
@@ -1046,31 +921,21 @@
         elif batLineup.actionNum > 0:
             for posNum in range(batLineup.actionNum, PosNumMax + 1):
                 batLineup.actionNum = posNum
-                if posNum not in batLineup.npcPosDict:
+                if posNum not in batLineup.posObjIDDict:
                     continue
-                curNPC = batLineup.npcPosDict[posNum]
-                if not curNPC or GameObj.GetHP(curNPC) <= 0:
-                    continue
-                objType = curNPC.GetGameObjType()
-                objID = curNPC.GetID()
-                turnFight.syncObjAction(turnNum, objType, objID)
-                
-                objName = GetObjName(curNPC)
-                curHP = GameObj.GetHP(curNPC)
-                
-                GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
-                if not DoAttack(curNPC, None, tick):
-                    GameWorld.DebugLog("        攻击失败")
+                objID = batLineup.posObjIDDict[posNum]
+                batObj = batObjMgr.getBatObj(objID)
+                if not OnObjAction(turnFight, batObj):
                     continue
                 
-                if faction == Def_FactionA:
+                if faction == ChConfig.Def_FactionA:
                     playerHeroAtk = True
                     
                 break
             
         turnFight.actionIndex += 1
         batLineup.actionNum += 1
-        if batLineup.actionNum > max(batLineup.npcPosDict):
+        if batLineup.actionNum > max(batLineup.posObjIDDict):
             GameWorld.DebugLog("该阵容本回合已经全部行动完了: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
             if (faction, num) not in overLineupList:
                 overLineupList.append((faction, num))
@@ -1097,7 +962,7 @@
             for faction, num in turnFight.actionSortList:
                 batFaction = turnFight.getBatFaction(faction)
                 batLineup = batFaction.getBatlineup(num)
-                for curNPC in batLineup.npcPosDict.values():
+                for objID in batLineup.posObjIDDict.values():
                     pass
                 
             if turnFight.checkOverByKilled():
@@ -1116,6 +981,7 @@
     curPlayer = turnFight.curPlayer
     turnMax = turnFight.turnMax
     EntryLogic(turnFight)
+    batObjMgr = BattleObj.GetBatObjMgr()
     for turnNum in range(1, turnMax + 1):
         turnFight.turnNum = turnNum
         GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum)
@@ -1128,8 +994,9 @@
             batFaction = turnFight.getBatFaction(faction)
             batLineup = batFaction.getBatlineup(num)
             batLineup.actionNum = 1
-            for curNPC in batLineup.npcPosDict.values():
-                TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
+            for objID in batLineup.posObjIDDict.values():
+                batObj = batObjMgr.getBatObj(objID)
+                TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
                 
         # 主公
         for faction, num in turnFight.actionSortList:
@@ -1156,20 +1023,11 @@
             batLineup = batFaction.getBatlineup(num)
             for posNum in range(batLineup.actionNum, PosNumMax + 1):
                 batLineup.actionNum = posNum + 1
-                if posNum not in batLineup.npcPosDict:
+                if posNum not in batLineup.posObjIDDict:
                     continue
-                curNPC = batLineup.npcPosDict[posNum]
-                if not curNPC or GameObj.GetHP(curNPC) <= 0:
-                    continue
-                objType = curNPC.GetGameObjType()
-                objID = curNPC.GetID()
-                turnFight.syncObjAction(turnNum, objType, objID)
-                
-                objName = GetObjName(curNPC)
-                curHP = GameObj.GetHP(curNPC)
-                
-                GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
-                if not DoAttack(curNPC, None, tick):
+                objID = batLineup.posObjIDDict[posNum]
+                batObj = batObjMgr.getBatObj(objID)
+                if not OnObjAction(turnFight, batObj):
                     continue
                 
                 break
@@ -1184,7 +1042,7 @@
             GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
             batFaction = turnFight.getBatFaction(faction)
             batLineup = batFaction.getBatlineup(num)
-            for curNPC in batLineup.npcPosDict.values():
+            for objID in batLineup.posObjIDDict.values():
                 pass
             
         if turnFight.checkOverByKilled():
@@ -1212,14 +1070,15 @@
     #funcLineID = clientData.FuncLineID
     return
 
-def GetObjName(gameObj):
-    objName = gameObj.GetName()
-    faction = GameObj.GetFaction(gameObj)
-    posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
-    heroID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
+def GetObjName(batObj):
+    faction = batObj.faction
+    num = batObj.lineupNum
+    posNum = batObj.posNum
+    heroID = batObj.heroID
     if not heroID:
-        heroID = gameObj.GetNPCID()
-    return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), heroID)
+        heroID = batObj.npcID
+    objName = GameWorld.CodeToGbk(batObj.GetName())
+    return "%s%s-%s [%s-%s] %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), heroID, objName)
 
 def EntryLogic(turnFight):
     ## 执行进场逻辑
@@ -1230,11 +1089,32 @@
     turnFight.enterLogic = True
     return
 
-def TurnFightObjPerTurnStart(gameObj, tagObj, turnNum, tick):
+def TurnFightObjPerTurnStart(turnFight, batObj, turnNum):
     ## 回合制战斗实例 - 每回合开始时处理
-    if not gameObj:
+    if not batObj:
         return
     
+    if batObj.GetHP() <= 0:
+        return
+    
+    curID = batObj.GetID()
+    buffMgr = batObj.GetBuffManager()
+    GameWorld.DebugLog("更新buff: curID=%s,buffCount=%s" % (curID, buffMgr.GetBuffCount()))
+    for index in range(buffMgr.GetBuffCount()):
+        buff = buffMgr.GetBuffByIndex(index)
+        curRemainTime = buff.GetRemainTime()
+        if not curRemainTime:
+            # 永久buff不处理
+            continue
+        buffID = buff.GetBuffID()
+        updRemainTime = curRemainTime - 1
+        GameWorld.DebugLog("    更新buff剩余回合数: buffID=%s,updRemainTime=%s" % (buffID, updRemainTime))
+        if updRemainTime > 0:
+            buff.SetRemainTime(curRemainTime - 1)
+            TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
+        else:
+            TurnBuff.SyncBuffDel(turnFight, batObj, buffID)
+            
 #    SetTimeline(gameObj, turnNum, 0)
 #    # 重置连击、反击数
 #    gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
@@ -1272,190 +1152,201 @@
 
 def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
     ## 回合对象添加治疗值
-    if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+    # @param curObj: 获得治疗的对象
+    # @param srcObj: 来自谁的治疗
+    # @param addValue: 治疗值
+    # @param cureHP: 实际回血量
+    if not srcObj:
         return
-    
-    curFaction = GameObj.GetFaction(curObj)
-    if not srcObj or curFaction != GameObj.GetFaction(srcObj):
-        # 同阵营的治疗才统计
-        return
-    
     curID = curObj.GetID()
     srcID = srcObj.GetID()
-    turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
-    if not turnFight:
-        return
-    
-    curBatFaction = turnFight.getBatFaction(curFaction)
-    for num in curBatFaction.lineupDict.keys():
-        batLineup = curBatFaction.getBatlineup(num)
-        updStatValue = batLineup.statCureValue(srcID, cureHP)
-        if updStatValue == None:
-            continue
-        GameWorld.DebugLog("        统计治疗: curTD=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s" 
-                       % (curID, srcID, skillID, addValue, cureHP, updStatValue))
-        break
-    
+    updStatValue = srcObj.StatCureValue(cureHP)
+    GameWorld.DebugLog("        统计治疗: curID=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s" 
+                   % (curID, srcID, skillID, addValue, cureHP, updStatValue))
+        
     return
 
-def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, lostHP, curSkill=None):
+def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, curSkill=None, isBounce=False):
     ## 回合对象添加伤害值
-    if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
-        return
-    curID = curObj.GetID()
-    tagID = tagObj.GetID()
+    # @param isBounce: 是否反弹伤害
+    curID = curBatObj.GetID()
+    tagID = tagBatObj.GetID()
     skillID = curSkill.GetSkillID() if curSkill else 0
-    turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
-    if not turnFight:
-        return
-    
     if curID != tagID:
-        curBatFaction = turnFight.getBatFaction(GameObj.GetFaction(curObj))
-        for num in curBatFaction.lineupDict.keys():
-            batLineup = curBatFaction.getBatlineup(num)
-            updStatValue = batLineup.statHurtValue(curID, lostHP)
-            if updStatValue == None:
-                continue
-            GameWorld.DebugLog("        统计伤血: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s" 
-                           % (curID, tagID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
-            break
+        updStatValue = curBatObj.StatHurtValue(hurtValue)
+        GameWorld.DebugLog("        统计伤血: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s,isBounce=%s" 
+                       % (curID, tagID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
         
-        tagBatFaction = turnFight.getBatFaction(GameObj.GetFaction(tagObj))
-        for num in tagBatFaction.lineupDict.keys():
-            batLineup = tagBatFaction.getBatlineup(num)
-            updStatValue = batLineup.statDefValue(tagID, lostHP)
-            if updStatValue == None:
-                continue
-            GameWorld.DebugLog("        统计承伤: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s" 
-                           % (tagID, curID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
-            break
-        
+        if tagBatObj:
+            updStatValue = tagBatObj.StatDefValue(lostHP)
+            GameWorld.DebugLog("        统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,isBounce=%s" 
+                           % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
+            
     else:
         # 如换血类技能,自残的伤害不算输出
-        GameWorld.DebugLog("        自残: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,curHP=%s" 
-                           % (curID, tagID, skillID, hurtType, hurtValue, lostHP, GameObj.GetHP(curObj)))
-        
-    if lostHP > 0 and curID != tagID:
-        addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
-        AddTurnFightXP(tagObj, addXP, "skillID:%s" % skillID)
+        GameWorld.DebugLog("        自残: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,curHP=%s" 
+                           % (curID, tagID, skillID, hurtValue, lostHP, curBatObj.GetHP()))
     return
 
-def AddTurnFightXP(gameObj, addXP, reason=""):
-    ## 回合战斗增加XP
-    if addXP <= 0 or not addXP:
-        #GameWorld.DebugLog("        没有增加XP! curID=%s" % (gameObj.GetID()))
+def OnObjAction(turnFight, curBatObj):
+    ## 战斗单位行动
+    if not curBatObj:
         return
-    posNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 10
-    if posNum <= 0:
-        #非主战单位不加
+    
+    curHP = curBatObj.GetHP()
+    objID = curBatObj.GetID()
+    if curHP <= 0:
         return
-    curXP = GameObj.GetXP(gameObj)
-    updXP = curXP + addXP
-    GameObj.SetXP(gameObj, updXP)
-    GameWorld.DebugLog("        更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
+    
+    turnNum = turnFight.turnNum
+    objName = GetObjName(curBatObj)
+    
+    # 是否可行动状态判断
+    canAction = True
+    
+    if not canAction:
+        GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
+        return
+    
+    GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
+    turnFight.syncObjAction(turnNum, objID)
+    
+    curXP = curBatObj.GetXP()
+    xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) 
+    skillManager = curBatObj.GetSkillManager()
+    useSkillList = []
+    #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
+    for index in range(0, skillManager.GetSkillCount()):
+        useSkill = skillManager.GetSkillByIndex(index)
+        if not useSkill:
+            continue
+        if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
+            #基础普攻不能主动释放,目前仅用于反击
+            continue
+        #被动技能无法使用
+        if SkillCommon.isPassiveSkill(useSkill):
+            continue
+        #还在冷却时间内无法释放
+        if useSkill.GetRemainTime():
+            continue
+        skillID = useSkill.GetSkillID()
+        # 常规攻击优先xp
+        if SkillCommon.isAngerSkill(useSkill):
+            if curXP < xpMax:
+                continue
+            useCnt = -1 # xp技能优先释放
+        else:
+            useCnt = curBatObj.GetSkillUseCnt(skillID)
+        useSkillList.append([useCnt, skillID, useSkill])
+        
+    useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
+    #GameWorld.DebugLog('    技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
+    
+    for useInfo in useSkillList:
+        useSkill = useInfo[-1]
+        if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
+            return True
+        
     return
 
-def DoAttack(curNPC, tagNPC, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
-    curID = curNPC.GetID()
-    npcID = curNPC.GetNPCID()
-    objName = GetObjName(curNPC)
-    GameWorld.DebugLog("    ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
-    
-    atkOK = False
-    tagObj = tagNPC
-    curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
-    
-    if turnBattleType == ChConfig.TurnBattleType_AtkBack:
-        if not tagObj:
-            return
-        skillManager = curNPC.GetSkillManager()
-        for index in range(0, skillManager.GetSkillCount()):
-            skill = skillManager.GetSkillByIndex(index)
-            #已经到尾部了
-            if not skill or skill.GetSkillTypeID() == 0:
-                break
-            if skill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
-                useSkill = skill
-                break
-        atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
-    elif turnBattleType == ChConfig.TurnBattleType_Combo:
-        if not tagObj:
-            return
-        atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
-    else:
-        curXP = GameObj.GetXP(curNPC)
-        xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) 
-        skillManager = curNPC.GetSkillManager()
-        useSkillList = []
-        #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
-        for index in range(0, skillManager.GetSkillCount()):
-            useSkill = skillManager.GetSkillByIndex(index)
-            #已经到尾部了
-            if not useSkill or useSkill.GetSkillTypeID() == 0:
-                break
-            if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_NormalAttack]:
-                #基础普攻不能主动释放,目前仅用于反击
-                continue
-            #被动技能无法使用
-            if SkillCommon.isPassiveSkill(useSkill):
-                continue
-            #还在冷却时间内无法释放
-            if SkillCommon.RefreshSkillRemainTime(useSkill, tick) != 0:
-                continue
-            skillTypeID = useSkill.GetSkillTypeID()
-            # 常规攻击优先xp
-            if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
-                if curXP < xpMax:
-                    continue
-                useCnt = -1 # xp技能优先释放
-            else:
-                useCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillTypeID) # 该技能已使用次数
-            useSkillList.append([useCnt, index, skillTypeID, useSkill])
-            
-        useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
-        #GameWorld.DebugLog('    技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
-        
-        for useInfo in useSkillList:
-            useSkill = useInfo[-1]
-            #skillID = useSkill.GetSkillID()
-            atkOK, tagObj = DoNPCUseSkill(curNPC, useSkill, tick)
-            if atkOK:
-                break
-            
-    curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
-    
-    tagID = 0
-    tagHP = 0
-    if tagObj:
-        tagID = tagObj.GetID()
-        tagHP = GameObj.GetHP(tagObj)
-    GameWorld.DebugLog('        atkOK=%s,tagID=%s,tagHP=%s' % (atkOK, tagID, tagHP), npcID)
-    if not atkOK:
-        return
-    
-    if not tagObj:
-        return
-    
-    if GameObj.GetFaction(curNPC) == GameObj.GetFaction(tagObj):
-        # 同阵营直接返回,不处理连击、反击
-        return True
-    
-    curHP = GameObj.GetHP(curNPC)
-    tagHP = GameObj.GetHP(tagObj)
-    tagID = tagObj.GetID()
-    GameWorld.DebugLog("            curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
-    if tagHP <= 0 or curHP <= 0:
-        return True
-    
-    # 反击,反击可打断连击,所以优先判断
-    if CanAtkBack(curNPC, tagObj):
-        DoAttack(tagObj, curNPC, tick, ChConfig.TurnBattleType_AtkBack)
-        return True
-    
-    # 连击
-    if CanCombo(curNPC, tagObj):
-        DoAttack(curNPC, tagObj, tick, ChConfig.TurnBattleType_Combo, useSkill)
-        
+def DoAttack(curBatObj, tagBatObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
+#    curID = curBatObj.GetID()
+#    npcID = curBatObj.GetNPCID()
+#    objName = GetObjName(curBatObj)
+#    GameWorld.DebugLog("    ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
+#    
+#    atkOK = False
+#    curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
+#    
+#    if turnBattleType == ChConfig.TurnBattleType_AtkBack:
+#        if not tagBatObj:
+#            return
+#        skillManager = curBatObj.GetSkillManager()
+#        for index in range(0, skillManager.GetSkillCount()):
+#            skill = skillManager.GetSkillByIndex(index)
+#            if not skill:
+#                continue
+#            if skill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill:
+#                useSkill = skill
+#                break
+#        atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
+#    elif turnBattleType == ChConfig.TurnBattleType_Combo:
+#        if not tagBatObj:
+#            return
+#        atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
+#    else:
+#        curXP = GameObj.GetXP(curBatObj)
+#        xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) 
+#        skillManager = curBatObj.GetSkillManager()
+#        useSkillList = []
+#        #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
+#        for index in range(0, skillManager.GetSkillCount()):
+#            useSkill = skillManager.GetSkillByIndex(index)
+#            if not useSkill:
+#                continue
+#            if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
+#                #基础普攻不能主动释放,目前仅用于反击
+#                continue
+#            #被动技能无法使用
+#            if SkillCommon.isPassiveSkill(useSkill):
+#                continue
+#            #还在冷却时间内无法释放
+#            if useSkill.GetRemainTime():
+#                continue
+#            skillID = useSkill.GetSkillID()
+#            # 常规攻击优先xp
+#            if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
+#                if curXP < xpMax:
+#                    continue
+#                useCnt = -1 # xp技能优先释放
+#            else:
+#                useCnt = curBatObj.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillID) # 该技能已使用次数
+#            useSkillList.append([useCnt, index, skillID, useSkill])
+#            
+#        useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
+#        #GameWorld.DebugLog('    技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
+#        
+#        for useInfo in useSkillList:
+#            useSkill = useInfo[-1]
+#            #skillID = useSkill.GetSkillID()
+#            atkOK, tagBatObj = OnUseSkill(curBatObj, useSkill, tick)
+#            if atkOK:
+#                break
+#            
+#    curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
+#    
+#    tagID = 0
+#    tagHP = 0
+#    if tagObj:
+#        tagID = tagObj.GetID()
+#        tagHP = GameObj.GetHP(tagObj)
+#    GameWorld.DebugLog('        atkOK=%s,tagID=%s,tagHP=%s' % (atkOK, tagID, tagHP), npcID)
+#    if not atkOK:
+#        return
+#    
+#    if not tagObj:
+#        return
+#    
+#    if GameObj.GetFaction(curNPC) == GameObj.GetFaction(tagObj):
+#        # 同阵营直接返回,不处理连击、反击
+#        return True
+#    
+#    curHP = GameObj.GetHP(curNPC)
+#    tagHP = GameObj.GetHP(tagObj)
+#    tagID = tagObj.GetID()
+#    GameWorld.DebugLog("            curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
+#    if tagHP <= 0 or curHP <= 0:
+#        return True
+#    
+#    # 反击,反击可打断连击,所以优先判断
+#    if CanAtkBack(curNPC, tagObj):
+#        DoAttack(tagObj, curNPC, tick, ChConfig.TurnBattleType_AtkBack)
+#        return True
+#    
+#    # 连击
+#    if CanCombo(curNPC, tagObj):
+#        DoAttack(curNPC, tagObj, tick, ChConfig.TurnBattleType_Combo, useSkill)
+#        
     return True
 
 def CanAtkBack(atkObj, defObj):
@@ -1512,224 +1403,58 @@
                        % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
     return True
 
-def DoNPCUseSkill(curNPC, useSkill, tick):
-    '''NPC使用技能
-    @return: 是否成功, tagObj
-    '''
-    if not useSkill or useSkill.GetSkillTypeID() == 0:
-        return False, None
-    
-    #检查是否几率触发
-    rate = useSkill.GetHappenRate()
-    if rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
-        #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
-        return False, None
-    
-    tagObj = None
-    skillTag = SkillShell.GetSkillAffectTag(useSkill)
-    skillAim = SkillShell.GetSkillFireAim(useSkill)
-    
-    # 注: 多V多的情况友好目标仅针对本阵容、敌对目标可针对任意敌对阵容
-    
-    #---对自己释放,或者无目标技能---
-    if skillTag in ChConfig.Def_ST_CanNPCUseSkill or skillAim == ChConfig.Def_UseSkillAim_None:
-        #释放自身类技能
-        tagObj = curNPC
-        isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
-        return isOK, tagObj
-    
-    # 召唤兽对主人释放技能
-    elif skillTag == ChConfig.Def_UseSkillTag_SummonMaster:
-        if not NPCCommon.IsSummonNPC(curNPC):
-            GameWorld.ErrLog("该NPC非召唤兽,无法获得主人释放技能")
-            return False, None
-        
-        curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC)    
-        if curSummonOwner == None:
-            curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)
-            
-        if curSummonOwner == None:
-            GameWorld.ErrLog("召唤兽(%s)对主人释放技能,找不到主人" % curNPC.GetNPCID())
-            return False, None
-        
-        tagObj = curSummonOwner
-        
-    # 友好死亡目标,一般是复活技能
-    elif skillTag == ChConfig.Def_UseSkillTag_FriendDeath:
-        deathList = GetFriendDeathList(curNPC)
-        if not deathList:
-            return False, None
-        tagObj = random.choice(deathList) # 随机选一个
-        
-    # 友好目标
-    elif skillTag in ChConfig.Def_ST_CanNPCUseSkillFriend:
-        friendList = GetFriendObjList(curNPC)
-        if not friendList:
-            return False, None
-        tagObj = random.choice(friendList) # 随机选一个,可扩展其他选择规则
-        
-    # 敌方目标
-    else:
-        tagObj = GetEnemyObj(curNPC)
-        
-    if not tagObj:
-        return False, None
-    
-    GameWorld.DebugLog("    技能释放: skillID=%s,atkID=%s,def=%s,HP:%s/%s" 
-                       % (useSkill.GetSkillID(), curNPC.GetID(), GetObjName(tagObj), GameObj.GetHP(tagObj), GameObj.GetMaxHP(tagObj)))
-    isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
-    return isOK, tagObj
+#def GetEnemyObj(curNPC, ruleType=0):
+#    ## 获取一个敌对单位,针对所有敌对阵容主战单位,优先选择对位阵容单位,仅限活着的单位
+#    # @param ruleType: 选择规则,默认0任意,1-最低血量;2-最高血量
+#    objID = curNPC.GetID()
+#    faction = GameObj.GetFaction(curNPC)
+#    posInfo = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
+#    num = posInfo / 100 # 阵容编号
+#    posNum = posInfo % 100 # 所在阵容站位
+#    turnFight = GetTurnFightMgr().getTurnFight(curNPC.GetTFGUID())
+#    if not turnFight:
+#        return
+#    
+#    tagBatFaction = turnFight.getBatFaction(Def_FactionB if faction == Def_FactionA else Def_FactionA)
+#    
+#    tagLineupNumList = [num] # 目标阵容选择顺序,优先对位阵容,再其他阵容
+#    if num in tagBatFaction.lineupDict:
+#        tagLineupNumList = [num]
+#    for tagNum in tagBatFaction.lineupDict.keys():
+#        if tagNum not in tagLineupNumList:
+#            tagLineupNumList.append(tagNum)
+#            
+#    batObjMgr = BattleObj.GetBatObjMgr()
+#    for tagNum in tagLineupNumList:
+#        tagLineup = tagBatFaction.getBatlineup(tagNum)
+#        tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
+#        pNumList = tagLineup.posObjIDDict.keys()
+#        pNumList.sort()
+#        for pNum in pNumList:
+#            if pNum > 0 and pNum not in tagPosNumList:
+#                tagPosNumList.append(pNum)
+#        for pNum in tagPosNumList:
+#            batObj = batObjMgr.getBatObj(objID)
+#            if not batObj:
+#                continue
+#            if batObj.GetHP( )<= 0:
+#                continue
+#            return batObj
+#    return
 
-def GetFriendDeathList(curNPC):
-    ## 获取友方死亡单位,仅针对本阵容主战单位
-    objID = curNPC.GetID()
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return []
-    batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
-    num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
-    batLineup = batFaction.getBatlineup(num)
-    deathList = []
-    for posNum, tagNPC in batLineup.npcPosDict.items():
-        if posNum <= 0 or not tagNPC:
-            continue
-        if GameObj.GetHP(tagNPC) > 0:
-            continue
-        deathList.append(tagNPC)
-        
-    return deathList
-
-def GetFriendObjList(curNPC):
-    ## 获取友方单位,仅针对本阵容主战单位
-    objID = curNPC.GetID()
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return []
-    batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
-    num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
-    batLineup = batFaction.getBatlineup(num)
-    friendList = []
-    for posNum, tagNPC in batLineup.npcPosDict.items():
-        if posNum <= 0 or not tagNPC:
-            continue
-        if GameObj.GetHP(tagNPC) <= 0:
-            continue
-        friendList.append(tagNPC)
-    return friendList
-
-def GetEnemyObj(curNPC, ruleType=0):
-    ## 获取一个敌对单位,针对所有敌对阵容主战单位,优先选择对位阵容单位,仅限活着的单位
-    # @param ruleType: 选择规则,默认0任意,1-最低血量;2-最高血量
-    objID = curNPC.GetID()
-    faction = GameObj.GetFaction(curNPC)
-    posInfo = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
-    num = posInfo / 100 # 阵容编号
-    posNum = posInfo % 100 # 所在阵容站位
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return
-    
-    tagBatFaction = turnFight.getBatFaction(Def_FactionB if faction == Def_FactionA else Def_FactionA)
-    
-    tagLineupNumList = [num] # 目标阵容选择顺序,优先对位阵容,再其他阵容
-    if num in tagBatFaction.lineupDict:
-        tagLineupNumList = [num]
-    for tagNum in tagBatFaction.lineupDict.keys():
-        if tagNum not in tagLineupNumList:
-            tagLineupNumList.append(tagNum)
-            
-    for tagNum in tagLineupNumList:
-        tagLineup = tagBatFaction.getBatlineup(tagNum)
-        tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
-        pNumList = tagLineup.npcPosDict.keys()
-        pNumList.sort()
-        for pNum in pNumList:
-            if pNum > 0 and pNum not in tagPosNumList:
-                tagPosNumList.append(pNum)
-        for pNum in tagPosNumList:
-            tagNPC = tagLineup.npcPosDict.get(pNum)
-            if not tagNPC:
-                continue
-            if GameObj.GetHP(tagNPC) <= 0:
-                continue
-            return tagNPC
-    return
-
-def SetTurnObjKilled(gameObj, killer=None):
-    if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
-        #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
-        return
-    
+def SetObjKilled(turnFight, gameObj, killer=None, useSkill=None):
     objID = gameObj.GetID()
     GameWorld.DebugLog("        %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), objID))
-    gameObj.SetCurAction(IPY_GameWorld.laNPCDie)
-    if GameObj.GetHP(gameObj) != 0:
-        GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
-    gameObj.SetVisible(False)
+    gameObj.SetHP(0)
+    killerObjID = killer.GetID() if killer else 0
+    skillID = useSkill.GetSkillID() if useSkill else 0
     
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return True
-    clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
+    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCTurnFightObjDead)
     clientPack.ObjID = objID
-    turnFight.addBatPack(clientPack)
-    
-    # 记录主动发起的玩家阵营击杀
-    curPlayer = turnFight.curPlayer
-    if killer and curPlayer and killer.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
-        if objID not in turnFight.playerKillObjIDList:
-            turnFight.playerKillObjIDList.append(objID)
-        GameWorld.DebugLog("玩家单次击杀统计: %s" % turnFight.playerKillObjIDList)
-        
+    clientPack.KillerObjID = killerObjID
+    clientPack.SkillID = skillID
+    turnFight.addBatPack(clientPack)        
     return True
-
-def OnTurnfightAttackSuccess(curObj, tagObj, curSkill):
-    ## 回合战斗攻击成功额外处理,AttackResult之前,一般处理技能相关
-    if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
-        return
-    if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
-        return
-    
-    objID = curObj.GetID()
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return
-    
-    skillID = curSkill.GetSkillID() if curSkill else 0
-    isXP = SkillCommon.isAngerSkill(curSkill)
-    if isXP:
-        GameObj.SetXP(curObj, 0)
-    elif curSkill:
-        if SkillCommon.isTurnNormalSkill(curSkill):
-            addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
-            AddTurnFightXP(curObj, addXP, "skillID:%s" % skillID)
-            
-    curPlayer = turnFight.curPlayer
-    # 仅主动发起玩家阵容触发
-    if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
-        FBLogic.OnPlayerLineupAttackSuccess(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
-        
-    return
-
-def OnTurnfightAttackResult(curObj, tagObj, curSkill):
-    ## 回合战斗攻击结果额外处理,AttackResult 之后,一般处理击杀结算相关
-    if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
-        return
-    if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
-        return
-    
-    objID = curObj.GetID()
-    turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
-    if not turnFight:
-        return
-    
-    curPlayer = turnFight.curPlayer
-    # 仅主动发起玩家阵容触发
-    if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
-        FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
-        
-    turnFight.playerKillObjIDList = []
-    return
 
 def OnTurnAllOver(guid):
     ## 所有回合已经全部执行完毕
@@ -1743,10 +1468,10 @@
     
     if turnFight.playerID:
         # 玩家发起的,未击杀对方,算玩家输
-        turnFight.winFaction = Def_FactionB
+        turnFight.winFaction = ChConfig.Def_FactionB
     else:
         # 系统场次,按一定规则来,这里先随机
-        turnFight.winFaction = random.choice([Def_FactionA, Def_FactionB])
+        turnFight.winFaction = random.choice([ChConfig.Def_FactionA, ChConfig.Def_FactionB])
         
     DoTurnFightOver(guid)
     return
@@ -1763,6 +1488,7 @@
     GameWorld.DebugLog("--- 战斗结束处理 --- %s, winFaction=%s, costTime=%ss" % (guid, winFaction, turnFight.costTime))
     
     # 统计明细
+    batObjMgr = BattleObj.GetBatObjMgr()
     statInfo = {}
     for faction in turnFight.factionDict.keys():
         if str(faction) not in statInfo:
@@ -1774,26 +1500,26 @@
                 facStatInfo[str(num)] = {}
             lineupStatInfo = facStatInfo[str(num)]
             batLineup = batFaction.getBatlineup(num)
-            hurtStatDict = batLineup.hurtStatDict
-            defStatDict = batLineup.defStatDict
-            cureStatDict = batLineup.cureStatDict
             GameWorld.DebugLog("阵容明细: faction=%s,num=%s" % (faction, num))
-            for posNum, curNPC in batLineup.npcPosDict.items():
-                objID = curNPC.GetID()
-                npcID = curNPC.GetNPCID()
-                heroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
-                atkHurt = hurtStatDict.get(objID, 0)
-                defHurt = defStatDict.get(objID, 0)
-                cureHP = cureStatDict.get(objID, 0)
+            for posNum, objID in batLineup.posObjIDDict.items():
+                batObj = batObjMgr.getBatObj(objID)
+                if not batObj:
+                    continue
+                objID = batObj.GetID()
+                npcID = batObj.GetNPCID()
+                heroID = batObj.GetHeroID()
+                atkHurt = batObj.hurtStat
+                defHurt = batObj.defStat
+                cureHP = batObj.cureStat
                 GameWorld.DebugLog("    Pos:%s ID=%s-%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s" 
-                                   % (posNum, objID, npcID, heroID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
+                                   % (posNum, objID, npcID, heroID, batObj.GetHP(), batObj.GetMaxHP(), atkHurt, defHurt, cureHP))
                 lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
                 
     awardItemList = []
     playerID = turnFight.playerID
     if playerID:
         curPlayer = turnFight.curPlayer
-        isWin = (winFaction == Def_FactionA)
+        isWin = (winFaction == ChConfig.Def_FactionA)
         # 主线小怪
         if turnFight.mapID == ChConfig.Def_FBMapID_Main:
             OnOver_MainLevel(curPlayer, isWin, awardItemList)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index c0cbe0f..71f3b86 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -184,8 +184,6 @@
                }
 
 # 属性ID对应0418刷新类型 {属性ID:[刷新同步类型, 是否支持超20亿的大数值], ...}
-# 卡牌项目玩家/主公属性仅为中间层属性,并非最终属性,最终属性体现在卡牌上,暂定全部前端自己算
-# 所以仅配置战斗场景需要同步的属性即可
 CDBRefresh_AttrIDDict = {
                          AttrID_MaxHP:[IPY_PlayerDefine.CDBPlayerRefresh_MaxHP, 1],
                          AttrID_HP:[IPY_PlayerDefine.CDBPlayerRefresh_HP, 1],
@@ -772,6 +770,8 @@
 Def_Skill_Effect_BoomSeedHurt = 804 # BUFF种子单层伤害
 Def_Skill_Effect_StoreBlood = 809 # 将期间受到的伤害总值,用于最后回血,不影响伤害
 Def_Skill_Effect_AttackReplace = 1009  #攻击计算,野外小怪伤害替换1010 (2018-03-07增加精英怪)
+Def_Skill_Effect_Cure = 1000  #治疗
+Def_Skill_Effect_Anger = 1001  #怒气增减偷
 Def_Skill_Effect_Attack = 1010  #攻击计算
 Def_Skill_Effect_LayerCnt = 1011 # BUFF层级数量 A值层数;B值:10位-是否非叠加属性,个位-层数处理方式0递增1递减;C值: 是否攻击减层
 Def_Skill_Effect_MasterBuff = 1012 # 主从技能(同步buff持续时间)
@@ -951,6 +951,20 @@
 
 #伤害类型
 (
+HurtType_Fail,              # 失败 - 如概率没有触发 0
+HurtType_Normal,            # 普通伤害 1
+HurtTYpe_Recovery,          # 回血 2
+HurtType_3,
+HurtType_4,
+HurtType_Parry,             # 格挡 5
+HurtType_IgnoreDef,         # 无视防御 6
+HurtType_SuperHit,          # 暴击 7
+HurtType_8,
+HurtType_Miss,              # 闪避 9
+) = range(10)
+
+#伤害类型
+(
 Def_HurtType_Normal,         # 普通伤害 1
 Def_HurtTYpe_Recovery,       # 回复 2
 Def_HurtType_BounceHurt,     # 反弹伤害 3
@@ -969,7 +983,7 @@
 Def_HurtType_ThumpHit,     # 重击 16
 Def_HurtType_Yinji,     # 印记 17
 Def_HurtType_Burn,     # 灼烧 18
-) = range(1, 19)
+) = range(1001, 1001 + 18)
 #Def_HurtType_SuckBlood,      # 吸血 
 
 (
@@ -1319,6 +1333,24 @@
 Def_Skill_HappenState_LuckyHit = 0x0004  # 必会心一击
 Def_Skill_HappenState_ThumpHit = 0x0008  # 必重击
 
+# 技能目标 - 瞄准范围
+(
+SkillTagAim_All, # 全部 0
+SkillTagAim_Relative, # 对位位置 1
+SkillTagAim_FrontRow, # 前排  2
+SkillTagAim_BackRow, # 后排  3
+SkillTagAim_Vertical, # 竖排/纵排 4
+SkillTagAim_Self, # 自己 5
+SkillTagAim_MainSkill, # 继承主技能目标 6
+) = range(7)
+
+# 技能目标 - 细分
+(
+SkillTagAffect_None, # 无  0
+SkillTagAffect_HPLowest, # 血量最低 1
+SkillTagAffect_HPHighest, # 血量最高 2
+SkillTagAffect_Death, # 死亡单位 3
+) = range(4)
 
 #技能施法目标
 Def_UseSkillAim_Type = 3
@@ -1827,10 +1859,9 @@
 Def_NstNull, Def_NstMoving, Def_NstDead, Def_NstAttack = range(4)
 
 #-------------------------------#副本相关#------------------------
-# 主线小怪
-Def_FBMapID_Main = 1
-# 主线Boss
-Def_FBMapID_MainBoss = 2
+
+Def_FBMapID_Main = 1 # 主线小怪
+Def_FBMapID_MainBoss = 2 # 主线Boss
 
 #创角新手村地图ID列表
 Def_CreatRoleMapIDList = [10000]
@@ -2278,6 +2309,10 @@
 DropOwnerType_Contend, # 争夺 8 第一个攻击的获得归属,击杀当前归属者的玩家成为新归属者
 DropOwnerType_RankHurtPlayer, # 个人伤血排行奖励归属 9 根据玩家个人伤血排行给奖励,伤血不重置
 ) = range(10)
+
+#阵营
+Def_FactionA = 1
+Def_FactionB = 2
 
 #------------------------------------------------
 #技能类型
@@ -3022,7 +3057,8 @@
 TurnBattleType_Normal, # 常规攻击
 TurnBattleType_Combo, # 连击
 TurnBattleType_AtkBack, # 反击
-) = range(3)
+TurnBattleType_Pursue , # 追击
+) = range(4)
 
 Def_PerTurnTick = 1000 # 每回合等同于常规tick时长
 
@@ -4295,7 +4331,8 @@
 
 #主线
 Def_PDict_UnXiantaoCntExp = "UnXiantaoCntExp" # 累计未结算经验的战锤数
-Def_PDict_UnXiantaoCntEquip = "UnXiantaoCntEquip" # 累计未结算掉落的战锤数
+Def_PDict_UnXiantaoCntEquip = "UnXiantaoCntEquip" # 累计未结算装备掉落的战锤数
+Def_PDict_UnXiantaoCntBooty = "UnXiantaoCntBooty_%s" # 累计未结算战利品掉落的战锤数,参数(itemID)
 Def_PDict_BootyDropToday = "BootyDropToday_%s" # 今日已累计掉落战利品数量,参数(itemID)
 
 #-------------------------------------------------------------------------------
@@ -5103,6 +5140,16 @@
 ) = range(27)
 
 
+# 回合卡牌
+(
+Def_SkillFuncType_Common, #0为通用技能
+Def_SkillFuncType_TurnNormaSkill,  #1 普攻技能
+Def_SkillFuncType_AngerSkill,  #2 怒气技能
+Def_SkillFuncType_PotentialSkill,  #3 潜能技能
+Def_SkillFuncType_AtkbackSkill,  #4 反击技能
+) = range(5)
+
+# MMO项目 - 先保留,重新定义从1000开始,后续可陆续删除
 (Def_SkillFuncType_Common, #0为通用技能
 Def_SkillFuncType_FbSkill, #1为法宝功能获得的主动技能
 Def_SkillFuncType_FbPassiveSkill, #2为法宝功能获得的被动技能
@@ -5126,8 +5173,7 @@
 Def_SkillFuncType_ShentongSkill,     #20 神通技能
 Def_SkillFuncType_ElfSkill,     #21 精怪技能
 Def_SkillFuncType_GatherTheSoul,     #22 聚魂技能
-Def_SkillFuncType_TurnNormaSkill,  #23 回合普攻技能
-) = range(24)
+) = range(1000, 1000 + 23)
 
 # 受技能效果完全影响的怪, 对应 Def_BattleRelationType_CommNoBoss
 Def_SkillAttack_NPCIsBoss = [ Def_NPCType_Ogre_Normal     ,  #平凡小怪 0    # c++ 定义为普通NPC视野刷新
@@ -5154,24 +5200,6 @@
 ExpRateLimitType_Recover, # 资源找回
 ExpRateLimitType_Sweep, # 扫荡
 ) = range(2)
-
-# 技能功能类对应战斗力模块
-Def_SkillFuncType_MFPType={
-                           Def_SkillFuncType_FbSkill:ShareDefine.Def_MFPType_MagicWeapon1,
-                           Def_SkillFuncType_FbPassiveSkill:ShareDefine.Def_MFPType_MagicWeapon2,
-                           Def_SkillFuncType_FbSPSkill:ShareDefine.Def_MFPType_MagicWeapon1,
-                           Def_SkillFuncType_GiftSkill:ShareDefine.Def_MFPType_Role,
-                           
-                           Def_SkillFuncType_HorseSkill:ShareDefine.Def_MFPType_Horse,
-                           Def_SkillFuncType_PetSkill:ShareDefine.Def_MFPType_Pet,
-                           Def_SkillFuncType_PetOwnerSkill:ShareDefine.Def_MFPType_Pet,
-                           Def_SkillFuncType_GWSkill:ShareDefine.Def_MFPType_Prestige,
-                           Def_SkillFuncType_SuiteSkill:ShareDefine.Def_MFPType_Equip,
-                           Def_SkillFuncType_TitleSkill:ShareDefine.Def_MFPType_Dienstgrad,
-                           Def_SkillFuncType_LianTiSkill:ShareDefine.Def_MFPType_LianTi,
-                           Def_SkillFuncType_ShentongSkill:ShareDefine.Def_MFPType_Shentong,
-                           }
-
 
 # 投资理财类型,和前端对应,从7开始
 InvestTypeList = (
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index c44e72b..8c1dd37 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -49840,6 +49840,142 @@
 
 
 #------------------------------------------------------
+# B4 29 Buff消失 #tagSCBuffDel
+
+class  tagSCBuffDel(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("BuffID", c_int),    
+                  ("RelatedSkillID", c_int),    # 关联的技能ID,一般是主技能ID或由于某个技能释放引起的buff变更
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x29
+        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 = 0x29
+        self.ObjID = 0
+        self.BuffID = 0
+        self.RelatedSkillID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCBuffDel)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 29 Buff消失 //tagSCBuffDel:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                BuffID:%d,
+                                RelatedSkillID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.BuffID,
+                                self.RelatedSkillID
+                                )
+        return DumpString
+
+
+m_NAtagSCBuffDel=tagSCBuffDel()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCBuffDel.Cmd,m_NAtagSCBuffDel.SubCmd))] = m_NAtagSCBuffDel
+
+
+#------------------------------------------------------
+# B4 28 Buff刷新 #tagSCBuffRefresh
+
+class  tagSCBuffRefresh(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    # 谁身上的buff
+                  ("BuffID", c_int),    # buffID,某个obj上的唯一buffID,不同的buffID可能skillID相同
+                  ("SkillID", c_int),    # 该buff对应技能表ID
+                  ("RelatedSkillID", c_int),    # 关联的技能ID,一般是主技能ID或由于某个技能释放引起的buff变更
+                  ("LastTime", c_int),    # 剩余时长毫秒/回合数
+                  ("Layer", c_ushort),    # 层数,不需要默认0
+                  ("OwnerID", c_int),    # buff来源者,即施法方
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x28
+        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 = 0x28
+        self.ObjID = 0
+        self.BuffID = 0
+        self.SkillID = 0
+        self.RelatedSkillID = 0
+        self.LastTime = 0
+        self.Layer = 0
+        self.OwnerID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCBuffRefresh)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 28 Buff刷新 //tagSCBuffRefresh:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                BuffID:%d,
+                                SkillID:%d,
+                                RelatedSkillID:%d,
+                                LastTime:%d,
+                                Layer:%d,
+                                OwnerID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.BuffID,
+                                self.SkillID,
+                                self.RelatedSkillID,
+                                self.LastTime,
+                                self.Layer,
+                                self.OwnerID
+                                )
+        return DumpString
+
+
+m_NAtagSCBuffRefresh=tagSCBuffRefresh()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCBuffRefresh.Cmd,m_NAtagSCBuffRefresh.SubCmd))] = m_NAtagSCBuffRefresh
+
+
+#------------------------------------------------------
 # B4 12 删除恶意攻击玩家 #tagMCDelMaliciousAtkPlayer
 
 class  tagMCDelMaliciousAtkPlayer(Structure):
@@ -50032,6 +50168,90 @@
 
 m_NAtagMCNPCSkillWarn=tagMCNPCSkillWarn()
 ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCNPCSkillWarn.Head.Cmd,m_NAtagMCNPCSkillWarn.Head.SubCmd))] = m_NAtagMCNPCSkillWarn
+
+
+#------------------------------------------------------
+# B4 18 对象属性刷新展示 #tagSCObjPropertyRefreshView
+
+class  tagSCObjPropertyRefreshView(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("Cmd", c_ubyte),
+                  ("SubCmd", c_ubyte),
+                  ("ObjID", c_int),    
+                  ("RefreshType", c_ushort),    # 同0418刷新类型,如血量、怒气
+                  ("Value", c_int),    # 更新值
+                  ("ValueEx", c_int),    # 更新值,如果是大数值的此值为整除亿部分
+                  ("DiffType", c_ubyte),    # 变化类型,0-减少;1-增加
+                  ("DiffValue", c_int),    # 变化值
+                  ("DiffValueEx", c_int),    # 变化值,如果是大数值的此值为整除亿部分
+                  ("SkillID", c_int),    # 使用的技能表ID
+                  ("RelatedSkillID", c_int),    # 关联的技能ID,一般是主技能ID,非主技能额外触发的为0
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        self.Cmd = 0xB4
+        self.SubCmd = 0x18
+        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 = 0x18
+        self.ObjID = 0
+        self.RefreshType = 0
+        self.Value = 0
+        self.ValueEx = 0
+        self.DiffType = 0
+        self.DiffValue = 0
+        self.DiffValueEx = 0
+        self.SkillID = 0
+        self.RelatedSkillID = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCObjPropertyRefreshView)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 18 对象属性刷新展示 //tagSCObjPropertyRefreshView:
+                                Cmd:%s,
+                                SubCmd:%s,
+                                ObjID:%d,
+                                RefreshType:%d,
+                                Value:%d,
+                                ValueEx:%d,
+                                DiffType:%d,
+                                DiffValue:%d,
+                                DiffValueEx:%d,
+                                SkillID:%d,
+                                RelatedSkillID:%d
+                                '''\
+                                %(
+                                self.Cmd,
+                                self.SubCmd,
+                                self.ObjID,
+                                self.RefreshType,
+                                self.Value,
+                                self.ValueEx,
+                                self.DiffType,
+                                self.DiffValue,
+                                self.DiffValueEx,
+                                self.SkillID,
+                                self.RelatedSkillID
+                                )
+        return DumpString
+
+
+m_NAtagSCObjPropertyRefreshView=tagSCObjPropertyRefreshView()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCObjPropertyRefreshView.Cmd,m_NAtagSCObjPropertyRefreshView.SubCmd))] = m_NAtagSCObjPropertyRefreshView
 
 
 #------------------------------------------------------
@@ -51241,6 +51461,8 @@
                   ("Cmd", c_ubyte),
                   ("SubCmd", c_ubyte),
                   ("ObjID", c_int),    
+                  ("KillerObjID", c_int),    # 被谁击杀的,可能为0	
+                  ("SkillID", c_int),    # 被什么技能击杀,可能为0	
                   ]
 
     def __init__(self):
@@ -51258,6 +51480,8 @@
         self.Cmd = 0xB4
         self.SubCmd = 0x22
         self.ObjID = 0
+        self.KillerObjID = 0
+        self.SkillID = 0
         return
 
     def GetLength(self):
@@ -51270,12 +51494,16 @@
         DumpString = '''// B4 22 回合战斗对象死亡 //tagMCTurnFightObjDead:
                                 Cmd:%s,
                                 SubCmd:%s,
-                                ObjID:%d
+                                ObjID:%d,
+                                KillerObjID:%d,
+                                SkillID:%d
                                 '''\
                                 %(
                                 self.Cmd,
                                 self.SubCmd,
-                                self.ObjID
+                                self.ObjID,
+                                self.KillerObjID,
+                                self.SkillID
                                 )
         return DumpString
 
@@ -51569,6 +51797,251 @@
 
 
 #------------------------------------------------------
+# B4 26 回合战斗标签 #tagSCTurnFightTag
+
+class  tagSCTurnFightTag(Structure):
+    Head = tagHead()
+    Len = 0    #(BYTE Len)
+    Tag = ""    #(String Tag)// 标签,释放技能的标签格式: Skill_objID_skillID,其他标签格式可再扩展
+    Sign = 0    #(BYTE Sign)// 0-标签头;1-标签尾;
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB4
+        self.Head.SubCmd = 0x26
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.Len,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.Tag,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
+        self.Sign,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB4
+        self.Head.SubCmd = 0x26
+        self.Len = 0
+        self.Tag = ""
+        self.Sign = 0
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 1
+        length += len(self.Tag)
+        length += 1
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.Len)
+        data = CommFunc.WriteString(data, self.Len, self.Tag)
+        data = CommFunc.WriteBYTE(data, self.Sign)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                Len:%d,
+                                Tag:%s,
+                                Sign:%d
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.Len,
+                                self.Tag,
+                                self.Sign
+                                )
+        return DumpString
+
+
+m_NAtagSCTurnFightTag=tagSCTurnFightTag()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCTurnFightTag.Head.Cmd,m_NAtagSCTurnFightTag.Head.SubCmd))] = m_NAtagSCTurnFightTag
+
+
+#------------------------------------------------------
+# B4 27 使用技能 #tagSCUseSkill
+
+class  tagSCUseSkillHurt(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("ObjID", c_int),    
+                  ("AttackTypes", c_int),    # 飘血类型汇总,支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
+                  ("HurtHP", c_int),    # 飘血值,求余亿部分
+                  ("HurtHPEx", c_int),    # 飘血值,整除亿部分
+                  ("CurHP", c_int),    # 更新剩余血量,求余亿部分
+                  ("CurHPEx", c_int),    # 更新剩余血量,整除亿部分
+                  ("SuckHP", c_int),    # 本次伤害转化的吸血量
+                  ("BounceHP", c_int),    # 本次伤害反弹的伤害量
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.ObjID = 0
+        self.AttackTypes = 0
+        self.HurtHP = 0
+        self.HurtHPEx = 0
+        self.CurHP = 0
+        self.CurHPEx = 0
+        self.SuckHP = 0
+        self.BounceHP = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagSCUseSkillHurt)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// B4 27 使用技能 //tagSCUseSkill:
+                                ObjID:%d,
+                                AttackTypes:%d,
+                                HurtHP:%d,
+                                HurtHPEx:%d,
+                                CurHP:%d,
+                                CurHPEx:%d,
+                                SuckHP:%d,
+                                BounceHP:%d
+                                '''\
+                                %(
+                                self.ObjID,
+                                self.AttackTypes,
+                                self.HurtHP,
+                                self.HurtHPEx,
+                                self.CurHP,
+                                self.CurHPEx,
+                                self.SuckHP,
+                                self.BounceHP
+                                )
+        return DumpString
+
+
+class  tagSCUseSkill(Structure):
+    Head = tagHead()
+    ObjID = 0    #(DWORD ObjID)
+    PMType = 0    #(BYTE PMType)// 物法类型 0或1-物理;2-法术
+    BattleType = 0    #(BYTE BattleType)// 战斗类型 0-常规;1-连击;2-反击;3-追击
+    CurHP = 0    #(DWORD CurHP)// 释放技能后剩余血量,吸血、反弹可能引起变化,求余亿部分
+    CurHPEx = 0    #(DWORD CurHPEx)// 释放技能后剩余血量,吸血、反弹可能引起变化,整除亿部分
+    SkillID = 0    #(DWORD SkillID)
+    HurtCount = 0    #(BYTE HurtCount)//伤害数目
+    HurtList = list()    #(vector<tagSCUseSkillHurt> HurtList)//size = HurtCount
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xB4
+        self.Head.SubCmd = 0x27
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.ObjID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.PMType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.BattleType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.CurHP,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.CurHPEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.SkillID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+        self.HurtCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.HurtCount):
+            temHurtList = tagSCUseSkillHurt()
+            _pos = temHurtList.ReadData(_lpData, _pos)
+            self.HurtList.append(temHurtList)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xB4
+        self.Head.SubCmd = 0x27
+        self.ObjID = 0
+        self.PMType = 0
+        self.BattleType = 0
+        self.CurHP = 0
+        self.CurHPEx = 0
+        self.SkillID = 0
+        self.HurtCount = 0
+        self.HurtList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 4
+        length += 1
+        length += 1
+        length += 4
+        length += 4
+        length += 4
+        length += 1
+        for i in range(self.HurtCount):
+            length += self.HurtList[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteDWORD(data, self.ObjID)
+        data = CommFunc.WriteBYTE(data, self.PMType)
+        data = CommFunc.WriteBYTE(data, self.BattleType)
+        data = CommFunc.WriteDWORD(data, self.CurHP)
+        data = CommFunc.WriteDWORD(data, self.CurHPEx)
+        data = CommFunc.WriteDWORD(data, self.SkillID)
+        data = CommFunc.WriteBYTE(data, self.HurtCount)
+        for i in range(self.HurtCount):
+            data = CommFunc.WriteString(data, self.HurtList[i].GetLength(), self.HurtList[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                ObjID:%d,
+                                PMType:%d,
+                                BattleType:%d,
+                                CurHP:%d,
+                                CurHPEx:%d,
+                                SkillID:%d,
+                                HurtCount:%d,
+                                HurtList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.ObjID,
+                                self.PMType,
+                                self.BattleType,
+                                self.CurHP,
+                                self.CurHPEx,
+                                self.SkillID,
+                                self.HurtCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagSCUseSkill=tagSCUseSkill()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCUseSkill.Head.Cmd,m_NAtagSCUseSkill.Head.SubCmd))] = m_NAtagSCUseSkill
+
+
+#------------------------------------------------------
 # B5 04 拍卖行新上架拍品 #tagGCAddAuctionItemInfo
 
 class  tagGCAddAuctionItem(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
index 95f6e59..40f4d30 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Hero.py
@@ -157,8 +157,10 @@
 def __oneKeyLineup(curPlayer, msgList):
     ## 阵容上阵: Hero f 阵容ID [武将ID ...]
     lineupID = msgList[1] if len(msgList) > 1 else 0
-    heroIDList = list(set(msgList[2:])) # 去重,单阵容武将ID不能重复
-    
+    heroIDList = []
+    for heroID in msgList[2:]: # 去重,单阵容武将ID不能重复
+        if heroID not in heroIDList:
+            heroIDList.append(heroID)
     if lineupID not in ShareDefine.LineupList:
         GameWorld.DebugAnswer(curPlayer, "不存在该阵容: %s" % lineupID)
         return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
index 8a608cc..1446e64 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/MainLevel.py
@@ -25,7 +25,7 @@
     if not gmList:
         GameWorld.DebugAnswer(curPlayer, "重置主线: MainLevel 0")
         GameWorld.DebugAnswer(curPlayer, "设置主线: MainLevel 章节 关卡 波")
-        GameWorld.DebugAnswer(curPlayer, "测试掉落: MainLevel d 击杀数")
+        GameWorld.DebugAnswer(curPlayer, "测试掉落: MainLevel d 战锤数")
         GameWorld.DebugAnswer(curPlayer, "重置战利: MainLevel b 0")
         GameWorld.DebugAnswer(curPlayer, "设置战利: MainLevel b 战利品ID 已掉落个数")
         return
@@ -33,8 +33,8 @@
     value = gmList[0]
     
     if value == "d":
-        killCnt = gmList[1] if len(gmList) > 1 else 1
-        GameLogic_MainLevel.GMTestKillDrop(curPlayer, killCnt)
+        unXiantao = gmList[1] if len(gmList) > 1 else 1
+        GameLogic_MainLevel.GMTestKillDrop(curPlayer, unXiantao)
         return
     
     if value == "b":
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
index 2f512de..f3dd9cc 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameObj.py
@@ -533,9 +533,9 @@
     else:
         sendPack.Value = value
         sendPack.ValueEx = 0
-    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(gameObj.GetID())
-    if turnFight:
-        turnFight.addBatPack(sendPack)
-        return
+    #turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(gameObj.GetTFGUID())
+    #if turnFight:
+    #    turnFight.addBatPack(sendPack)
+    #    return
     gameObj.NotifyAll(sendPack.GetBuffer(), sendPack.GetLength())
     return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
index f1661c3..41dd4bf 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBLogic.py
@@ -2409,25 +2409,14 @@
     
     return callFunc(curPlayer, mapID, funcLineID, tagType, tagID, valueList)
 
-def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
-    ## 回合战斗主动发起的玩家阵容释放技能成功
-    do_FBLogic_ID = __GetFBLogic_MapID(mapID)
-    
-    callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnPlayerLineupAttackSuccess"))
-    
-    if callFunc:
-        callFunc(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID)
-        
-    return
-
-def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
-    ## 回合战斗主动发起的玩家阵容攻击结果额外处理
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+    ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
     do_FBLogic_ID = __GetFBLogic_MapID(mapID)
     
     callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnPlayerLineupAttackResult"))
     
     if callFunc:
-        callFunc(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID)
+        callFunc(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID)
         
     return
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
index 72f075a..6cb2c29 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -18,17 +18,16 @@
 import ChConfig
 import GameWorld
 import ShareDefine
-import SkillCommon
 import IpyGameDataPY
 import PlayerControl
 import ChPyNetSendPack
 import ItemControler
 import IPY_GameWorld
 import NetPackCommon
-import TurnAttack
 import ItemCommon
 import NPCCommon
 import ChEquip
+import ObjPool
 
 import random
 
@@ -43,6 +42,7 @@
 def ResetBootyDropToday(curPlayer):
     bootyItemIDList = GetBootyItemIDList()
     for itemID in bootyItemIDList:
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, 0)
         if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID):
             PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_BootyDropToday % itemID, 0)
     SyncDropBootyInfo(curPlayer)
@@ -64,63 +64,21 @@
     ipyData = ipyDataMgr.GetMainChapterByIndex(chapterCount - 1)
     return [booty[0] for booty in ipyData.GetDailyBootyUpperList()]
 
-def OnPlayerLineupAttackSuccess(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
-    ## 回合战斗主动发起的玩家阵容释放技能成功
+def OnPlayerLineupAttackResult(curPlayer, atkObj, killObjIDList, useSkill, mapID, funcLineID):
+    ## 回合战斗主动发起的玩家阵容攻击结果额外处理 ,一般处理副本相关的掉落、奖励等
     
     if mapID == ChConfig.Def_FBMapID_Main:
-        __doCostZhanchui(curPlayer, atkObj, curSkill)
+        __doKillAward(curPlayer, atkObj, killObjIDList)
         
     return
 
-def __doCostZhanchui(curPlayer, atkObj, curSkill):
-    ## 扣除战锤消耗
-    costZhanchui = 0
-    isXP = SkillCommon.isAngerSkill(curSkill)
-    turnBattleType = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnBattleType)
-    if isXP:
-        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
-    elif turnBattleType == ChConfig.TurnBattleType_Combo:
-        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
-    elif turnBattleType == ChConfig.TurnBattleType_AtkBack:
-        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
-    elif SkillCommon.isTurnNormalSkill(curSkill):
-        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
-        
-    if costZhanchui <= 0:
-        return
-    
-    fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
-    costZhanchuiTotal = costZhanchui * fightPoint
-    if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
-        # 不足时,有多少扣多少
-        nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
-        PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
-        
-    return
-
-def OnPlayerLineupAttackResult(curPlayer, atkObj, defObj, curSkill, mapID, funcLineID):
-    
-    if mapID == ChConfig.Def_FBMapID_Main:
-        __doKillAward(curPlayer, atkObj, mapID, funcLineID)
-        
-    return
-
-def __doKillAward(curPlayer, atkObj, mapID, funcLineID):
+def __doKillAward(curPlayer, atkObj, killObjIDList):
     ## 计算击杀奖励
-    turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(atkObj.GetID())
-    if not turnFight:
+    if not killObjIDList:
+        GameWorld.DebugLog("没有击杀不需要处理!")
         return
-    
-    unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
-    if not turnFight.playerKillObjIDList:
-        unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
-        GameWorld.DebugLog("没有击杀不需要处理! unXiantaoCntExp=%s,unXiantaoCntEquip=%s" % (unXiantaoCntExp, unXiantaoCntEquip))
-        return
-    killCnt = len(turnFight.playerKillObjIDList)
-    # 直接重置,防止异常时重复结算
-    turnFight.playerKillObjIDList = []
-    
     # 结算经验
+    unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
     if unXiantaoCntExp:
         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, 0)
         perExp = IpyGameDataPY.GetFuncCfg("Mainline", 1) # 每个战锤增加经验
@@ -128,60 +86,68 @@
         GameWorld.DebugLog("增加经验: totalExp=%s,unXiantaoCntExp=%s" % (totalExp, unXiantaoCntExp))
         PlayerControl.PlayerControl(curPlayer).AddExp(totalExp, ShareDefine.Def_ViewExpType_KillNPC)
         
-    __doMainDrop(curPlayer, killCnt)
+    __doMainDrop(curPlayer)
     return
 
-def __doMainDrop(curPlayer, killCnt):
+def __doMainDrop(curPlayer):
     # 装备掉落
     __doDropEquip(curPlayer)
     
     playerID = curPlayer.GetPlayerID()
-    DailyBootyUpperList, BootyWeightList = [], []
+    DailyBootyUpperList = []
     chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
     chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
     if chapterIpyData:
         DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
-        BootyWeightList = chapterIpyData.GetBootyWeightList()
-        
-    bootyDropUpperDict = {k:v for k, v in DailyBootyUpperList}    
-    GameWorld.DebugLog("可掉落战利品上限: chapterID=%s,%s,killCnt=%s" % (chapterID, bootyDropUpperDict, killCnt), playerID)
+           
+    GameWorld.DebugLog("可掉落战利品上限: chapterID=%s, %s" % (chapterID, DailyBootyUpperList), playerID)
     
     # 其他战利品掉落
-    for _ in range(killCnt):
-        dropInfo = GameWorld.GetResultByWeightList(BootyWeightList)
-        if not dropInfo:
-            continue
-        itemID = dropInfo[0]
-        if not itemID:
-            GameWorld.DebugLog("本次不掉落战利品!", playerID)
-            continue
-        if itemID not in bootyDropUpperDict:
-            GameWorld.DebugLog("该战利品未解锁! itemID=%s" % itemID, playerID)
+    bootyDropNeedDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 1, {})
+    bootyDropCntDict = IpyGameDataPY.GetFuncEvalCfg("MainBootyDrop", 2, {})
+    for itemID, dropUpper in DailyBootyUpperList:
+        if dropUpper <= 0:
             continue
         todyDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
-        dropUpper = bootyDropUpperDict.get(itemID, 0)
         if todyDropCnt >= dropUpper:
             GameWorld.DebugLog("战利品已达今日掉落上限! itemID=%s,todyDropCnt=%s >= %s" % (itemID, todyDropCnt, dropUpper), playerID)
             continue
+        if itemID not in bootyDropNeedDict or itemID not in bootyDropCntDict:
+            continue
+        dropOneNeed = bootyDropNeedDict[itemID]
+        unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID)
+        dropBootyCnt = unXiantaoCntBooty / dropOneNeed
+        if dropBootyCnt <= 0:
+            continue
         
-        dropMin = dropInfo[1] if len(dropInfo) > 1 else 1
-        dropMax = dropInfo[2] if len(dropInfo) > 2 else 1
+        dropCntRange = bootyDropCntDict[itemID]
+        if not isinstance(dropCntRange, (list, tuple)) or len(dropCntRange) != 2:
+            continue
+        dropMin = dropCntRange[0]
+        dropMax = dropCntRange[1]
         
-        if dropMin == dropMax:
-            dropCnt = dropMin
-        else:
-            dropCnt = random.randint(dropMin, dropMax)
-        dropCnt = min(dropCnt, dropUpper - todyDropCnt)
+        dropCntTotal = 0
+        for _ in range(dropBootyCnt):
+            if dropMin == dropMax:
+                dropCnt = dropMin
+            else:
+                dropCnt = random.randint(dropMin, dropMax)
+            dropCntTotal += dropCnt
+        dropCntTotal = min(dropCntTotal, dropUpper - todyDropCnt)
+        if dropCntTotal <= 0:
+            continue
         
-        GameWorld.DebugLog("掉落战利品! itemID=%s,dropCnt=%s" % (itemID, dropCnt), playerID)
-        curItem = ItemControler.GetOutPutItemObj(itemID, dropCnt, False, curPlayer=curPlayer)
+        GameWorld.DebugLog("掉落战利品! itemID=%s,unXiantaoCntBooty=%s,次数=%s,dropCntTotal=%s" % (itemID, unXiantaoCntBooty, dropBootyCnt, dropCntTotal), playerID)
+        curItem = ItemControler.GetOutPutItemObj(itemID, dropCntTotal, False, curPlayer=curPlayer)
         if curItem == None:
             continue
         curItem.SetIsBind(1) # 为1时代表是掉落
         if not ItemControler.DoLogic_PutItemInPack(curPlayer, curItem, packIndexList=[IPY_GameWorld.rptIdentify]):
             continue
-        SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCnt)
-                
+        unXiantaoCntBooty = unXiantaoCntBooty % dropOneNeed
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
+        SetBootyDropToday(curPlayer, itemID, todyDropCnt + dropCntTotal)
+        
     return
 
 def __doDropEquip(curPlayer):
@@ -243,14 +209,23 @@
         
     return
 
-def GMTestKillDrop(curPlayer, killCnt):
+def GMTestKillDrop(curPlayer, unXiantao):
     ## GM测试掉落
-    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + killCnt
+    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip) + unXiantao
     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip)
-    __doMainDrop(curPlayer, killCnt)
-    
-    unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
-    GameWorld.DebugAnswer(curPlayer, "剩余未结算装备掉落战锤数:%s" % unXiantaoCntEquip)
+    GameWorld.DebugAnswer(curPlayer, "未结算装备战锤数: %s" % unXiantaoCntEquip)
+    chapterID = PlayerControl.GetMainLevelNowInfo(curPlayer)[0]
+    chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
+    if chapterIpyData:
+        DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
+        for itemID, upperCnt in DailyBootyUpperList:
+            if upperCnt <= 0:
+                continue
+            unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID) + unXiantao
+            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty)
+            GameWorld.DebugAnswer(curPlayer, "未结算战利品(%s)战锤数: %s" % (itemID, unXiantaoCntBooty))
+            
+    __doMainDrop(curPlayer)
     return
 
 #// B4 15 主线掉落物品操作 #tagCSMainDropItemOP
@@ -406,10 +381,11 @@
         syncItemIDList = GetBootyItemIDList()
     else:
         syncItemIDList = [itemID]
-    clientPack = ChPyNetSendPack.tagSCDropBootyInfo()
+    poolMgr = ObjPool.GetPoolMgr()
+    clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCDropBootyInfo)
     clientPack.DropBootyList = []
     for itemID in syncItemIDList:
-        dropBooty = ChPyNetSendPack.tagSCDropBooty()
+        dropBooty = poolMgr.acquire(ChPyNetSendPack.tagSCDropBooty)
         dropBooty.ItemID = itemID
         dropBooty.TodayDropCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID)
         clientPack.DropBootyList.append(dropBooty)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
index 0b2a0a9..697275e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
@@ -26,6 +26,8 @@
 import ShareDefine
 import PlayerTeam
 import PyGameData
+import BattleObj
+import ObjPool
 
 import datetime
 import time
@@ -265,6 +267,8 @@
     #GameWorldActionControl.Dispose_DailyActionState()
     #GameWorldActionControl.Dispose_FBStateTime()
     PlayerOnline.OnMinute()
+    BattleObj.OnMinute()
+    ObjPool.OnMinute()
     
     PlayerTeam.OnCheckTeamPlayerDisconnectTimeout(tick)
     __CheckIpyDataRecycle(curTime)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e39ca0d..dff0eec 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -56,8 +56,64 @@
                         ("BYTE", "OPLimitInAct", 0),
                         ),
 
+                "NPC":(
+                        ("DWORD", "NPCID", 1),
+                        ("char", "NPCName", 0),
+                        ("BYTE", "Country", 0),
+                        ("BYTE", "AtkDistType", 0),
+                        ("WORD", "LV", 0),
+                        ("DWORD", "Atk", 0),
+                        ("DWORD", "Def", 0),
+                        ("DWORD", "MaxHP", 0),
+                        ("list", "SkillIDList", 0),
+                        ("DWORD", "FinalDamPer", 0),
+                        ("DWORD", "FinalDamPerDef", 0),
+                        ("DWORD", "MissRate", 0),
+                        ("DWORD", "MissRateDef", 0),
+                        ("DWORD", "SuperHitRate", 0),
+                        ("DWORD", "SuperHitRateDef", 0),
+                        ("DWORD", "StunRate", 0),
+                        ("DWORD", "StunRateDef", 0),
+                        ("DWORD", "ComboRate", 0),
+                        ("DWORD", "ComboRateDef", 0),
+                        ("DWORD", "ParryRate", 0),
+                        ("DWORD", "ParryRateDef", 0),
+                        ("DWORD", "SuckHPPer", 0),
+                        ("DWORD", "SuckHPPerDef", 0),
+                        ("dict", "SpecAttrInfo", 0),
+                        ),
+
+                "Skill":(
+                        ("DWORD", "SkillID", 1),
+                        ("DWORD", "SkillTypeID", 0),
+                        ("WORD", "SkillMaxLV", 0),
+                        ("char", "SkillName", 0),
+                        ("BYTE", "FuncType", 0),
+                        ("BYTE", "SkillType", 0),
+                        ("BYTE", "HurtType", 0),
+                        ("BYTE", "AtkType", 0),
+                        ("BYTE", "TagAim", 0),
+                        ("BYTE", "TagFriendly", 0),
+                        ("BYTE", "TagAffect", 0),
+                        ("BYTE", "TagCount", 0),
+                        ("WORD", "HappenRate", 0),
+                        ("WORD", "LastTime", 0),
+                        ("WORD", "CoolDownTime", 0),
+                        ("WORD", "Priority", 0),
+                        ("DWORD", "EffectID1", 0),
+                        ("list", "EffectValues1", 0),
+                        ("DWORD", "EffectID2", 0),
+                        ("list", "EffectValues2", 0),
+                        ("DWORD", "EffectID3", 0),
+                        ("list", "EffectValues3", 0),
+                        ("DWORD", "ConnSkill", 0),
+                        ("list", "EnhanceSkillList", 0),
+                        ("DWORD", "FightPower", 0),
+                        ),
+
                 "Hero":(
                         ("DWORD", "HeroID", 1),
+                        ("char", "Name", 0),
                         ("BYTE", "Country", 0),
                         ("BYTE", "Quality", 0),
                         ("BYTE", "AtkDistType", 0),
@@ -161,7 +217,6 @@
                 "MainChapter":(
                         ("BYTE", "ChapterID", 1),
                         ("list", "DailyBootyUpperList", 0),
-                        ("list", "BootyWeightList", 0),
                         ),
 
                 "MainLevel":(
@@ -730,33 +785,6 @@
                         ("float", "AttrPer", 0),
                         ("dict", "AttrSpecDict", 0),
                         ("dict", "AttrExDict", 0),
-                        ),
-
-                "NPCEx":(
-                        ("DWORD", "NPCID", 1),
-                        ("BYTE", "FightPowerLackAtkLimit", 0),
-                        ("DWORD", "SuppressFightPower", 0),
-                        ("BYTE", "AtkDistType", 0),
-                        ("DWORD", "Atk", 0),
-                        ("DWORD", "Def", 0),
-                        ("DWORD", "MaxHP", 0),
-                        ("list", "SkillIDList", 0),
-                        ("DWORD", "FinalHurtPer", 0),
-                        ("DWORD", "FinalHurtReducePer", 0),
-                        ("DWORD", "MissRate", 0),
-                        ("DWORD", "MissDefRate", 0),
-                        ("DWORD", "SuperHitRate", 0),
-                        ("DWORD", "SuperHitRateReduce", 0),
-                        ("DWORD", "FaintRate", 0),
-                        ("DWORD", "FaintDefRate", 0),
-                        ("DWORD", "ComboRate", 0),
-                        ("DWORD", "ComboDefRate", 0),
-                        ("DWORD", "ParryRate", 0),
-                        ("DWORD", "ParryDefRate", 0),
-                        ("DWORD", "ParryDamPer", 0),
-                        ("DWORD", "SuckHPPer", 0),
-                        ("DWORD", "SuckHPDefPer", 0),
-                        ("dict", "SpecAttrInfo", 0),
                         ),
 
                 "NPCRealmStrengthen":(
@@ -2840,6 +2868,71 @@
     def GetSortReverse(self): return self.attrTuple[6] # 是否倒序 BYTE
     def GetOPLimitInAct(self): return self.attrTuple[7] # 活动期间限制队伍操作 BYTE
 
+# NPC表
+class IPY_NPC():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetNPCID(self): return self.attrTuple[0] # NPCID DWORD
+    def GetNPCName(self): return self.attrTuple[1] # 名称 char
+    def GetCountry(self): return self.attrTuple[2] # 国家 BYTE
+    def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
+    def GetLV(self): return self.attrTuple[4] # 等级 WORD
+    def GetAtk(self): return self.attrTuple[5] # 攻击力 DWORD
+    def GetDef(self): return self.attrTuple[6] # 防御值 DWORD
+    def GetMaxHP(self): return self.attrTuple[7] # 最大生命值,可超过20E DWORD
+    def GetSkillIDList(self): return self.attrTuple[8] # 技能ID列表 list
+    def GetFinalDamPer(self): return self.attrTuple[9] # 最终增伤 DWORD
+    def GetFinalDamPerDef(self): return self.attrTuple[10] # 最终减伤 DWORD
+    def GetMissRate(self): return self.attrTuple[11] # 闪避概率 DWORD
+    def GetMissRateDef(self): return self.attrTuple[12] # 抗闪避概率 DWORD
+    def GetSuperHitRate(self): return self.attrTuple[13] # 暴击概率 DWORD
+    def GetSuperHitRateDef(self): return self.attrTuple[14] # 抗暴击概率 DWORD
+    def GetStunRate(self): return self.attrTuple[15] # 击晕概率 DWORD
+    def GetStunRateDef(self): return self.attrTuple[16] # 抗击晕概率 DWORD
+    def GetComboRate(self): return self.attrTuple[17] # 连击概率 DWORD
+    def GetComboRateDef(self): return self.attrTuple[18] # 抗连击概率 DWORD
+    def GetParryRate(self): return self.attrTuple[19] # 格挡概率 DWORD
+    def GetParryRateDef(self): return self.attrTuple[20] # 抗格挡概率 DWORD
+    def GetSuckHPPer(self): return self.attrTuple[21] # 吸血比率 DWORD
+    def GetSuckHPPerDef(self): return self.attrTuple[22] # 抗吸血比率 DWORD
+    def GetSpecAttrInfo(self): return self.attrTuple[23] # 特殊属性信息 {"属性ID":值, ...} dict
+
+# 技能表
+class IPY_Skill():
+    
+    def __init__(self):
+        self.attrTuple = None
+        return
+        
+    def GetSkillID(self): return self.attrTuple[0] # 技能ID DWORD
+    def GetSkillTypeID(self): return self.attrTuple[1] # 技能TypeID DWORD
+    def GetSkillMaxLV(self): return self.attrTuple[2] # 最高等级 WORD
+    def GetSkillName(self): return self.attrTuple[3] # 技能名 char
+    def GetFuncType(self): return self.attrTuple[4] # 功能分类 BYTE
+    def GetSkillType(self): return self.attrTuple[5] # 技能类型 BYTE
+    def GetHurtType(self): return self.attrTuple[6] # 伤害类型 BYTE
+    def GetAtkType(self): return self.attrTuple[7] # 释放方式 BYTE
+    def GetTagAim(self): return self.attrTuple[8] # 瞄准位置 BYTE
+    def GetTagFriendly(self): return self.attrTuple[9] # 敌我目标 BYTE
+    def GetTagAffect(self): return self.attrTuple[10] # 目标细分 BYTE
+    def GetTagCount(self): return self.attrTuple[11] # 目标个数 BYTE
+    def GetHappenRate(self): return self.attrTuple[12] # 释放或添加几率 WORD
+    def GetLastTime(self): return self.attrTuple[13] # 持续时间 WORD
+    def GetCoolDownTime(self): return self.attrTuple[14] # 冷却时间 WORD
+    def GetPriority(self): return self.attrTuple[15] # 优先级 WORD
+    def GetEffectID1(self): return self.attrTuple[16] # 效果ID1 DWORD
+    def GetEffectValues1(self): return self.attrTuple[17] # 效果值列表1 list
+    def GetEffectID2(self): return self.attrTuple[18] # 效果ID2 DWORD
+    def GetEffectValues2(self): return self.attrTuple[19] # 效果值列表2 list
+    def GetEffectID3(self): return self.attrTuple[20] # 效果ID3 DWORD
+    def GetEffectValues3(self): return self.attrTuple[21] # 效果值列表3 list
+    def GetConnSkill(self): return self.attrTuple[22] # 关联技能 DWORD
+    def GetEnhanceSkillList(self): return self.attrTuple[23] # 触发技能ID列表 list
+    def GetFightPower(self): return self.attrTuple[24] # 技能战斗力 DWORD
+
 # 武将表
 class IPY_Hero():
     
@@ -2848,17 +2941,18 @@
         return
         
     def GetHeroID(self): return self.attrTuple[0] # 英雄ID DWORD
-    def GetCountry(self): return self.attrTuple[1] #  国家 BYTE
-    def GetQuality(self): return self.attrTuple[2] #  品质 BYTE
-    def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
-    def GetSkinIDList(self): return self.attrTuple[4] #  皮肤ID列表 list
-    def GetNormalSkillID(self): return self.attrTuple[5] # 普攻技能ID DWORD
-    def GetAngerSkillID(self): return self.attrTuple[6] # 怒气技能ID DWORD
-    def GetAtkInheritPer(self): return self.attrTuple[7] # 攻击继承 WORD
-    def GetDefInheritPer(self): return self.attrTuple[8] # 防御继承 WORD
-    def GetHPInheritPer(self): return self.attrTuple[9] # 生命继承 WORD
-    def GetBatAttrDict(self): return self.attrTuple[10] # 其他战斗属性字典 {"属性ID":值, ...} dict
-    def GetFetterIDList(self): return self.attrTuple[11] # 羁绊ID列表 list
+    def GetName(self): return self.attrTuple[1] # 名称 char
+    def GetCountry(self): return self.attrTuple[2] #  国家 BYTE
+    def GetQuality(self): return self.attrTuple[3] #  品质 BYTE
+    def GetAtkDistType(self): return self.attrTuple[4] # 远近类型;1-近战;2-远程 BYTE
+    def GetSkinIDList(self): return self.attrTuple[5] #  皮肤ID列表 list
+    def GetNormalSkillID(self): return self.attrTuple[6] # 普攻技能ID DWORD
+    def GetAngerSkillID(self): return self.attrTuple[7] # 怒气技能ID DWORD
+    def GetAtkInheritPer(self): return self.attrTuple[8] # 攻击继承 WORD
+    def GetDefInheritPer(self): return self.attrTuple[9] # 防御继承 WORD
+    def GetHPInheritPer(self): return self.attrTuple[10] # 生命继承 WORD
+    def GetBatAttrDict(self): return self.attrTuple[11] # 其他战斗属性字典 {"属性ID":值, ...} dict
+    def GetFetterIDList(self): return self.attrTuple[12] # 羁绊ID列表 list
 
 # 武将星级天赋表
 class IPY_HeroTalent():
@@ -3010,8 +3104,7 @@
         return
         
     def GetChapterID(self): return self.attrTuple[0] # 章节ID BYTE
-    def GetDailyBootyUpperList(self): return self.attrTuple[1] #  每日战利品掉落上限,[[物品ID,每日上限], ...] list
-    def GetBootyWeightList(self): return self.attrTuple[2] #  战利品掉落权重,[[权重,物品ID,掉落个数下限, 上限], ...] list
+    def GetDailyBootyUpperList(self): return self.attrTuple[1] #  每日战利品掉落上限,[[物品ID,每日上限], ...] list
 
 # 主线关卡表
 class IPY_MainLevel():
@@ -3890,38 +3983,6 @@
     def GetAttrPer(self): return self.attrTuple[5] # 对应等级表中的比例 float
     def GetAttrSpecDict(self): return self.attrTuple[6] # 特殊属性值字典 {attrKey:value, ...} dict
     def GetAttrExDict(self): return self.attrTuple[7] # 特殊属性值字典 {attrKey:value, ...} dict
-
-# NPC表扩展
-class IPY_NPCEx():
-    
-    def __init__(self):
-        self.attrTuple = None
-        return
-        
-    def GetNPCID(self): return self.attrTuple[0] # NPCID DWORD
-    def GetFightPowerLackAtkLimit(self): return self.attrTuple[1] # 战力不足限制攻击 BYTE
-    def GetSuppressFightPower(self): return self.attrTuple[2] # 推荐/压制战力 DWORD
-    def GetAtkDistType(self): return self.attrTuple[3] # 远近类型;1-近战;2-远程 BYTE
-    def GetAtk(self): return self.attrTuple[4] # 攻击力 DWORD
-    def GetDef(self): return self.attrTuple[5] # 防御值 DWORD
-    def GetMaxHP(self): return self.attrTuple[6] # 最大生命值,可超过20E DWORD
-    def GetSkillIDList(self): return self.attrTuple[7] # 技能ID列表 list
-    def GetFinalHurtPer(self): return self.attrTuple[8] # 最终增伤 DWORD
-    def GetFinalHurtReducePer(self): return self.attrTuple[9] # 最终减伤 DWORD
-    def GetMissRate(self): return self.attrTuple[10] # 闪避概率 DWORD
-    def GetMissDefRate(self): return self.attrTuple[11] # 抗闪避概率 DWORD
-    def GetSuperHitRate(self): return self.attrTuple[12] # 暴击概率 DWORD
-    def GetSuperHitRateReduce(self): return self.attrTuple[13] # 抗暴击概率 DWORD
-    def GetFaintRate(self): return self.attrTuple[14] # 击晕概率 DWORD
-    def GetFaintDefRate(self): return self.attrTuple[15] # 抗击晕概率 DWORD
-    def GetComboRate(self): return self.attrTuple[16] # 连击概率 DWORD
-    def GetComboDefRate(self): return self.attrTuple[17] # 抗连击概率 DWORD
-    def GetParryRate(self): return self.attrTuple[18] # 格挡概率 DWORD
-    def GetParryDefRate(self): return self.attrTuple[19] # 抗格挡概率 DWORD
-    def GetParryDamPer(self): return self.attrTuple[20] # 格挡减伤比率 DWORD
-    def GetSuckHPPer(self): return self.attrTuple[21] # 吸血比率 DWORD
-    def GetSuckHPDefPer(self): return self.attrTuple[22] # 抗吸血比率 DWORD
-    def GetSpecAttrInfo(self): return self.attrTuple[23] # 特殊属性信息 {"属性ID":值, ...} dict
 
 # 成长型境界怪物表
 class IPY_NPCRealmStrengthen():
@@ -7084,6 +7145,8 @@
         self.__LoadFileData("DirtyList", onlyCheck)
         self.__LoadFileData("DirtyName", onlyCheck)
         self.__LoadFileData("FuncTeamSet", onlyCheck)
+        self.__LoadFileData("NPC", onlyCheck)
+        self.__LoadFileData("Skill", onlyCheck)
         self.__LoadFileData("Hero", onlyCheck)
         self.__LoadFileData("HeroTalent", onlyCheck)
         self.__LoadFileData("HeroBreak", onlyCheck)
@@ -7159,7 +7222,6 @@
         self.__LoadFileData("PlayerLV", onlyCheck)
         self.__LoadFileData("SpecMapPlayerAttrFormat", onlyCheck)
         self.__LoadFileData("GMAttr", onlyCheck)
-        self.__LoadFileData("NPCEx", onlyCheck)
         self.__LoadFileData("NPCRealmStrengthen", onlyCheck)
         self.__LoadFileData("NPCStrengthen", onlyCheck)
         self.__LoadFileData("NPCTimeLostHP", onlyCheck)
@@ -7603,6 +7665,20 @@
     def GetFuncTeamSetByIndex(self, index):
         self.CheckLoadData("FuncTeamSet")
         return self.ipyFuncTeamSetCache[index]
+
+    def GetNPCCount(self):
+        self.CheckLoadData("NPC")
+        return self.ipyNPCLen
+    def GetNPCByIndex(self, index):
+        self.CheckLoadData("NPC")
+        return self.ipyNPCCache[index]
+
+    def GetSkillCount(self):
+        self.CheckLoadData("Skill")
+        return self.ipySkillLen
+    def GetSkillByIndex(self, index):
+        self.CheckLoadData("Skill")
+        return self.ipySkillCache[index]
 
     def GetHeroCount(self):
         self.CheckLoadData("Hero")
@@ -8128,13 +8204,6 @@
     def GetGMAttrByIndex(self, index):
         self.CheckLoadData("GMAttr")
         return self.ipyGMAttrCache[index]
-
-    def GetNPCExCount(self):
-        self.CheckLoadData("NPCEx")
-        return self.ipyNPCExLen
-    def GetNPCExByIndex(self, index):
-        self.CheckLoadData("NPCEx")
-        return self.ipyNPCExCache[index]
 
     def GetNPCRealmStrengthenCount(self):
         self.CheckLoadData("NPCRealmStrengthen")
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 9080305..a6a329f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -129,12 +129,12 @@
             return realmNPCIpyData.GetLV()
     return curNPC.GetLV()
 
-def GetNPCDataEx(npcID):
-    ## 获取NPC扩展数据表,可热更
-    npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPCEx", npcID)
+def GetNPCDataPy(npcID):
+    ## 获取NPC数据表,py自定义的表,可热更
+    npcDataEx = IpyGameDataPY.GetIpyGameDataNotLog("NPC", npcID)
     if not npcDataEx:
         if False: # 不可能成立的条件,只为了 . 出代码提示
-            npcDataEx = IpyGameDataPY.IPY_NPCEx()
+            npcDataEx = IpyGameDataPY.IPY_NPC()
         return npcDataEx
     return npcDataEx
 
@@ -142,11 +142,9 @@
 def SetRealmLV(curNPC, realmLV): return curNPC.SetMAtkMin(realmLV)      # NPC表中此字段含义改成境界等级
 def GetIsLVSuppress(curNPC): return curNPC.GetWindDef() # 风防代表是否等级压制
 def GetFightPowerLackAtkLimit(curNPC): # 战力不足限制攻击,默认不限制
-    npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
-    return npcDataEx.GetFightPowerLackAtkLimit() if npcDataEx else 0
-def GetSuppressFightPower(curNPC):
-    npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
-    return npcDataEx.GetSuppressFightPower() if npcDataEx else curNPC.GetThunderDef() # 雷防代表压制战力
+    return 0
+def GetSuppressFightPower(curNPC): # 压制战力
+    return 0
 def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord))
 def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力
 def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型
@@ -1124,19 +1122,18 @@
             
     # C++设置npc死亡
     notifyClient = True
-    tfMgr = TurnAttack.GetTurnFightMgr()
-    turnFight = tfMgr.getNPCTurnFight(objID)
-    if turnFight:
-        notifyClient = False # 回合制战斗的由py自己通知
-        # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分
-        clientPack = ChNetSendPack.tagNPCDisappear()
-        clientPack.NPCID = [objID]
-        clientPack.Count = len(clientPack.NPCID)
-        turnFight.addBatPack(clientPack)
+    #tfMgr = TurnAttack.GetTurnFightMgr()
+    #turnFight = tfMgr.getNPCTurnFight(objID)
+    #if turnFight:
+    #    notifyClient = False # 回合制战斗的由py自己通知
+    #    # //04 07 NPC消失#tagNPCDisappear 此处通知消失,与回合制死亡区分
+    #    clientPack = ChNetSendPack.tagNPCDisappear()
+    #    clientPack.NPCID = [objID]
+    #    clientPack.Count = len(clientPack.NPCID)
+    #    turnFight.addBatPack(clientPack)
     curNPC.SetDead(curNPC.GetDictByKey(ChConfig.Def_NPCDead_Reason),
                    curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerType),
                    curNPC.GetDictByKey(ChConfig.Def_NPCDead_KillerID), notifyClient)
-    tfMgr.delNPCGUID(objID)
     return
 
 def GameServer_KillGameWorldBoss(bossID, killPlayerName, hurtValue, isNotify=True, killerIDList=[]):
@@ -2444,13 +2441,13 @@
     
     def __notifyAppear(self):
         ## //04 06 NPC出现#tagNPCAppear,可能也有 04 08 玩家召唤NPC出现#tagPlayerSummonNPCAppear,卡牌先简化,只使用0406
-        curNPC = self.__Instance
-        objID = curNPC.GetID()
-        turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(objID)
-        if not turnFight:
-            # 非回合制怪保留原通知
-            curNPC.NotifyAppear()
-            return
+        #curNPC = self.__Instance
+        #objID = curNPC.GetID()
+        #turnFight = TurnAttack.GetTurnFightMgr().getNPCTurnFight(objID)
+        #if not turnFight:
+        #    # 非回合制怪保留原通知
+        #    curNPC.NotifyAppear()
+        #    return
         
         # 回合制怪不通知,统一由 // B4 24 回合战斗初始化 #tagSCTurnFightInit
         return
@@ -2583,7 +2580,7 @@
                                  ChConfig.AttrID_MaxHP:3000000000,
                                  })
         else:
-            npcDataEx = GetNPCDataEx(curNPC.GetNPCID())
+            npcDataEx = GetNPCDataPy(curNPC.GetNPCID())
             if not npcDataEx:
                 return
             heroAttrDict.update({
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
index 5ce5b67..a9b3f02 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -31,6 +31,7 @@
 import traceback
 import ChGameToMapPyPack
 from PyMongoDB.DBCommon import CommonDefine
+import ObjPool
 #-------------------------------------------------------------------------------
 #---全局变量---
 
@@ -227,6 +228,8 @@
         Log("SendFakePack: clientPack Len = %s > %s"%(clientPack.GetLength(), len(innerPackData)))
     #curPlayer.SendFakePack(innerPackData, len(innerPackData))
     curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength())
+    ObjPool.GetPoolMgr().release(clientPack)
+    return
     
 def SendFackPackOnline(clientPack, parseFunc=None, *args):
     ## 发送给全服在线玩家
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py
new file mode 100644
index 0000000..062659f
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ObjPool.py
@@ -0,0 +1,498 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package ObjPool
+#
+# @todo:对象池管理
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 对象池管理,建议对频繁创建的类使用对象池,如封包相关、战斗相关
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import collections
+import types
+#import sys
+#import ctypes
+
+class RecursiveObjectPoolManager(object):
+    
+    def __init__(self):
+        self._pools = {}  # 存储各类的对象池 {class: pool}
+        # 使用对象ID作为键的映射:{id(obj): obj_class}
+        self._obj_id_to_pool = {}
+        self._releasing = set()  # 正在释放的对象ID集合
+        
+    def create_pool(self, obj_class, max_size=10):
+        """为指定类创建对象池
+        :param obj_class: 要管理的对象类
+        :param max_size: 对象池最大容量
+        """
+        if obj_class in self._pools:
+            GameWorld.Log("Pool for %s already exists" % obj_class.__name__)
+            return
+        GameWorld.Log("create_pool %s, max_size=%s" % ( obj_class.__name__, max_size))
+        
+        self._pools[obj_class] = {
+            'max_size': max_size,
+            'free_list': [],      # 空闲对象列表
+            'active_list': [],    # 使用中对象列表
+            'created_count': 0    # 已创建对象计数
+        }
+        return self
+    
+    def acquire(self, obj_class, *args, **kwargs):
+        """获取对象并记录其所属池"""
+        if obj_class not in self._pools:
+            # 如果池不存在,自动创建大小为0的无限制池
+            self.create_pool(obj_class, 0)
+        
+        pool = self._pools[obj_class]
+        
+        if pool['free_list']:
+            # 复用空闲对象
+            obj = pool['free_list'].pop()
+            # 重新初始化对象
+            obj.__init__(*args, **kwargs)
+        else:
+            # 创建新对象
+            if pool['max_size'] <= 0 or pool['created_count'] < pool['max_size']:
+                obj = obj_class(*args, **kwargs)
+                pool['created_count'] += 1
+                # 记录对象到池的映射
+                obj_id = id(obj)
+                self._obj_id_to_pool[obj_id] = obj_class
+            else:
+                GameWorld.ErrLog("%s pool exhausted" % obj_class.__name__)
+                return None  # 返回None表示获取失败
+    
+        pool['active_list'].append(obj)
+        return obj
+    
+    def release(self, obj):
+        """释放对象并递归释放其嵌套对象池对象"""
+        obj_id = id(obj)
+        
+        # 检查是否正在递归释放中
+        if obj_id in self._releasing:
+            return
+        
+        # 只处理对象池管理的对象
+        if obj_id not in self._obj_id_to_pool:
+            return
+        
+        # 标记为正在释放
+        self._releasing.add(obj_id)
+        visited = set([obj_id])  # 初始化已访问集合
+        
+        try:
+            # 1. 递归释放嵌套对象池对象
+            self._recursive_release(obj, visited)
+            # 2. 释放当前对象
+            self._return_to_pool(obj)
+        finally:
+            # 移除释放标记
+            self._releasing.discard(obj_id)
+    
+    def _recursive_release(self, obj, visited):
+        """递归释放嵌套对象池对象(深度优先)"""
+        # 获取对象的所有引用(不包含基础类型)
+        for ref in self._get_references(obj):
+            try:
+                ref_id = id(ref)
+            except TypeError:
+                # 如果对象不可哈希,跳过
+                continue
+                
+            if ref_id in visited:
+                continue
+            visited.add(ref_id)
+            
+            # 只处理对象池管理的对象
+            if ref_id in self._obj_id_to_pool:
+                # 先递归释放嵌套对象
+                self._recursive_release(ref, visited)
+                # 再释放当前引用对象
+                self._return_to_pool(ref)
+            else:
+                # 对于非对象池管理的对象,继续递归查找其中的对象池对象
+                self._recursive_release(ref, visited)
+    
+    def _get_references(self, obj):
+        """安全获取对象的所有直接引用,支持复杂数据结构"""
+        refs = []
+        obj_type = type(obj)
+        
+        # 处理自定义对象的属性
+        try:
+            # 首先尝试__dict__属性
+            if hasattr(obj, '__dict__'):
+                for attr in dir(obj):
+                    if attr.startswith('__'):
+                        continue
+                    
+                    try:
+                        attr_value = getattr(obj, attr)
+                    except Exception:
+                        continue
+                    
+                    # 过滤基础类型
+                    if not self._is_basic_type(attr_value):
+                        refs.append(attr_value)
+        except Exception:
+            pass
+        
+        # 处理常见容器类型
+        if obj_type in (list, tuple, set, collections.deque):
+            for item in obj:
+                if not self._is_basic_type(item):
+                    refs.append(item)
+        elif obj_type is dict:
+            for key, value in obj.iteritems():
+                if not self._is_basic_type(key):
+                    refs.append(key)
+                if not self._is_basic_type(value):
+                    refs.append(value)
+        
+        # 处理特殊属性(如__slots__定义的对象)
+        try:
+            if hasattr(obj, '__slots__'):
+                for slot_name in obj.__slots__:
+                    if hasattr(obj, slot_name):
+                        slot_value = getattr(obj, slot_name)
+                        if not self._is_basic_type(slot_value):
+                            refs.append(slot_value)
+        except Exception:
+            pass
+        
+        return refs
+    
+    def _is_basic_type(self, value):
+        """判断值是否为基本类型,不需要递归处理"""
+        if value is None:
+            return True
+        if isinstance(value, (int, long, float, bool, str, unicode)):
+            return True
+        if isinstance(value, (types.FunctionType, types.MethodType, types.ModuleType)):
+            return True
+        if isinstance(value, (types.BuiltinFunctionType, type)):
+            return True
+        return False
+    
+    def _return_to_pool(self, obj):
+        """将对象归还到其所属池"""
+        obj_id = id(obj)
+        
+        # 获取对象所属类
+        if obj_id not in self._obj_id_to_pool:
+            return  # 如果不在池中,忽略
+        
+        obj_class = self._obj_id_to_pool[obj_id]
+        
+        if obj_class not in self._pools:
+            return  # 如果池不存在,忽略
+        
+        pool = self._pools[obj_class]
+        
+        # 确保对象在活跃列表中
+        if obj in pool['active_list']:
+            # 从活跃列表移除
+            try:
+                pool['active_list'].remove(obj)
+            except ValueError:
+                # 如果对象不在列表中,忽略
+                return
+                
+            # 执行对象清理方法
+            #if hasattr(obj, 'cleanup'):
+            #    try:
+            #        obj.cleanup()
+            #    except Exception:
+            #        pass
+                    
+            # 添加到空闲列表
+            pool['free_list'].append(obj)
+        else:
+            # 如果在空闲列表中,跳过
+            pass
+        
+    def destroy_pool(self, obj_class):
+        """销毁指定类的对象池"""
+        if obj_class not in self._pools:
+            return
+        
+        pool = self._pools[obj_class]
+        
+        # 清理所有对象
+        for obj in list(pool['free_list'] + pool['active_list']):
+            # 清理对象属性
+            #if hasattr(obj, 'cleanup'):
+            #    try:
+            #        obj.cleanup()
+            #    except Exception:
+            #        pass
+            
+            # 从映射中移除
+            obj_id = id(obj)
+            if obj_id in self._obj_id_to_pool:
+                del self._obj_id_to_pool[obj_id]
+        
+        del self._pools[obj_class]
+        
+    def pool_status(self):
+        """输出所有对象池的状态信息"""
+        statusList = []
+        max_name_len = 0
+        max_created_len = 0
+        max_free_len = 0
+        max_active_len = 0
+        
+        # 收集状态并计算最大长度
+        for obj_class, pool in self._pools.items():
+            # 获取类名
+            class_name = getattr(obj_class, '__name__', str(obj_class))
+            created = pool['created_count']
+            free = len(pool['free_list'])
+            active = len(pool['active_list'])
+            
+            statusList.append({
+                'obj_class': class_name,
+                'created': created,
+                'free': free,
+                'active': active
+            })
+            
+            # 计算最大长度
+            max_name_len = max(max_name_len, len(class_name))
+            max_created_len = max(max_created_len, len(str(created)))
+            max_free_len = max(max_free_len, len(str(free)))
+            max_active_len = max(max_active_len, len(str(active)))
+        
+        # 添加表头长度
+        max_name_len = max(max_name_len, 8)  # "对象池名称"的长度
+        max_created_len = max(max_created_len, 4)  # "总数"的长度
+        max_free_len = max(max_free_len, 4)  # "空闲"的长度
+        max_active_len = max(max_active_len, 4)  # "活跃"的长度
+        
+        # 按活跃对象数量排序
+        statusList.sort(key=lambda s: (s['created'], s['active']), reverse=True)
+        
+        # 创建格式字符串
+        header_format = "| {:<{name_width}} | {:>{created_width}} | {:>{free_width}} | {:>{active_width}} |"
+        row_format = "| {:<{name_width}} | {:>{created_width}} | {:>{free_width}} | {:>{active_width}} |"
+        
+        # 输出表头
+        GameWorld.Log("----- 对象池状态 -----")
+        GameWorld.Log(header_format.format(
+            "对象池名称", "总数", "空闲", "活跃",
+            name_width=max_name_len,
+            created_width=max_created_len,
+            free_width=max_free_len,
+            active_width=max_active_len
+        ))
+        
+        # 输出分隔线
+        separator = "+-{}-+-{}-+-{}-+-{}-+".format(
+            "-" * max_name_len,
+            "-" * max_created_len,
+            "-" * max_free_len,
+            "-" * max_active_len
+        )
+        GameWorld.Log(separator)
+        
+        # 输出数据行
+        for s in statusList:
+            GameWorld.Log(row_format.format(
+                s['obj_class'], s['created'], s['free'], s['active'],
+                name_width=max_name_len,
+                created_width=max_created_len,
+                free_width=max_free_len,
+                active_width=max_active_len
+            ))
+        
+        return
+    
+def GetPoolMgr():
+    """获取指定类创建对象池"""
+    poolMgr = PyGameData.g_objPoolMgr
+    if not poolMgr:
+        poolMgr = RecursiveObjectPoolManager()
+        PyGameData.g_objPoolMgr = poolMgr
+    return poolMgr
+
+def OnMinute():
+    """每分钟执行,输出对象池状态"""
+    GetPoolMgr().pool_status()
+    return
+
+## 使用示例
+#if __name__ == "__main__":
+#    
+#    # 定义一个嵌套的Structure类
+#    class SubStructure(ctypes.Structure):
+#        _fields_ = [("z", ctypes.c_int)]
+#        
+#        def __init__(self, name):
+#            self.name = name
+#            print "初始化SubStructure: name=%s" % (self.name)
+#            return
+#        
+#        def cleanup(self):
+#            """清理方法"""
+#            print "清理SubStructure: name=%s" % (self.name)
+#            self.name = None
+#    
+#    # 定义一个继承自Structure的类
+#    class MyStructure(ctypes.Structure):
+#        _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int)]
+#        
+#        def __init__(self, name):
+#            self.name = name
+#            # 嵌套的Structure对象
+#            self.sub = GetPoolMgr().acquire(SubStructure, "%s_sub" % name)
+#            print "初始化MyStructure: name=%s" % (self.name)
+#            return
+#        
+#        def cleanup(self):
+#            """清理方法"""
+#            print "清理MyStructure: name=%s" % (self.name)
+#            self.name = None
+#            # 不需要手动释放sub,递归释放会处理
+#            self.sub = None
+#    
+#    class ClassE():
+#        
+#        def __init__(self, name):
+#            self.name = name
+#            print "初始化对象 ClassE: name=%s" % (self.name)
+#            self.ed1 = GetPoolMgr().acquire(ClassD, "%s_ed_1" % name)
+#            return
+#        
+#    class ClassD():
+#        
+#        def __init__(self, name):
+#            self.name = name
+#            print "初始化对象 ClassD: name=%s" % (self.name)
+#            return
+#        
+#        def cleanup(self):
+#            """清理方法"""
+#            print "清理ClassD: name=%s" % (self.name)
+#            self.name = None
+#        
+#    class ClassC():
+#        
+#        def __init__(self, name, bb):
+#            self.name = name
+#            print "初始化对象 ClassC: name=%s" % (self.name)
+#            self.bb = bb
+#            self.cd1 = GetPoolMgr().acquire(ClassD, "%s_cd_1" % name)
+#            self.cd2 = GetPoolMgr().acquire(ClassD, "%s_cd_2" % name)
+#            return
+#    
+#    class ClassB():
+#        
+#        def __init__(self, name):
+#            self.name = name
+#            print "初始化对象 ClassB: name=%s" % (self.name)
+#            bc1 = GetPoolMgr().acquire(ClassC, "%s_c_1" % name, self)
+#            bc2 = GetPoolMgr().acquire(ClassC, "%s_c_2" % name, self)
+#            self.cList = [bc1, bc2]
+#            self.dDict = {1:GetPoolMgr().acquire(ClassD, "%s_d_1" % name), GetPoolMgr().acquire(ClassD, "%s_d_2" % name):2, "bc1":bc1, "bc2":bc2}
+#            return
+#            
+#        def do(self, doStr):
+#            print "ClassB.do name=%s, %s" % (self.name, doStr)
+#            return
+#        
+#    class ClassA():
+#        
+#        def __init__(self, objID, name):
+#            self.objID = objID
+#            self.name = name
+#            self.b = GetPoolMgr().acquire(ClassB, "%s_b" % name)
+#            self.e = ClassE("%s_e" % name)
+#            self.struct = GetPoolMgr().acquire(MyStructure, "%s_struct" % name)  # Structure对象
+#            self.dDict = {1:GetPoolMgr().acquire(ClassD, "%s_d_1" % name), GetPoolMgr().acquire(ClassD, "%s_d_2" % name):2}
+#            print "初始化对象 ClassA: objID=%s,name=%s" % (self.objID, self.name)
+#            
+#        def do(self, doStr):
+#            print "ClassA.do objID=%s,name=%s, %s" % (self.objID, self.name, doStr)
+#            return
+#        
+#        def cleanup(self):
+#            """清理方法"""
+#            print "清理ClassA: objID=%s,name=%s" % (self.objID, self.name)
+#            self.b = None
+#            self.e = None
+#            self.struct = None
+#            self.dDict = None
+#            self.name = None
+#            self.objID = None
+#
+#    
+#    # 创建对象池管理器
+#    poolMgr = GetPoolMgr()
+#    
+#    # 为所有类创建对象池,max_size=0 表示无限制
+#    poolMgr.create_pool(ClassA, max_size=0)
+#    poolMgr.create_pool(ClassB, max_size=0)
+#    poolMgr.create_pool(ClassC, max_size=0)
+#    poolMgr.create_pool(ClassD, max_size=0)
+#    poolMgr.create_pool(MyStructure, max_size=0)
+#    poolMgr.create_pool(SubStructure, max_size=0)  # 嵌套的Structure类
+#    
+#    # 创建测试对象
+#    a1 = poolMgr.acquire(ClassA, 1000, "hanmeimei")
+#    if a1 is None:
+#        GameWorld.ErrLog("Failed to acquire ClassA instance for hanmeimei")
+#    else:
+#        a1.do("hello 1ilei")
+#    
+#    a2 = poolMgr.acquire(ClassA, 1001, "lilei")
+#    if a2 is None:
+#        GameWorld.ErrLog("Failed to acquire ClassA instance for lilei")
+#    else:
+#        a2.do("hello hanmeimei")
+#    
+#    # 输出状态
+#    print("\n释放前状态")
+#    poolMgr.pool_status()
+#    
+#    # 释放对象
+#    if a1:
+#        poolMgr.release(a1)
+#    if a2:
+#        poolMgr.release(a2)
+#    
+#    # 输出状态
+#    print("\n释放后状态")
+#    poolMgr.pool_status()
+#    
+#    # 再次获取应复用对象
+#    a3 = poolMgr.acquire(ClassA, 1002, "lihua")
+#    if a3 is None:
+#        GameWorld.ErrLog("Failed to acquire ClassA instance for lihua")
+#    else:
+#        a3.do("fuck you")
+#    
+#    # 输出状态
+#    print("\n再次获取后状态")
+#    poolMgr.pool_status()
+#    
+#    # 清理
+#    if a3:
+#        poolMgr.release(a3)
+#    poolMgr.destroy_pool(ClassA)
+#    poolMgr.destroy_pool(ClassB)
+#    poolMgr.destroy_pool(ClassC)
+#    poolMgr.destroy_pool(ClassD)
+#    poolMgr.destroy_pool(MyStructure)
+#    poolMgr.destroy_pool(SubStructure)
\ No newline at end of file
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 b35b8c3..3ee73aa 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -578,7 +578,7 @@
 #  @return 返回值无意义
 def ClearPyPlayerAction(curPlayer):
     #清除py自定义状态
-    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PyPlayerAction, 0)      
+    NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PyPlayerAction, 0)      
     return
 
 #---------------------------------------------------------------------
@@ -2837,10 +2837,25 @@
     #轮回殿
     PlayerActLunhuidian.AddLunhuidianValue(curPlayer, PlayerActLunhuidian.AwardType_PayMoney, type_Price, price)
     if type_Price == ShareDefine.TYPE_Price_Xiantao:
+        # 累加未结算战锤 - 经验
         unXiantaoCntExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntExp)
         NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntExp, unXiantaoCntExp + price)
+        # 累加未结算战锤 - 装备
         unXiantaoCntEquip = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntEquip)
         NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntEquip, unXiantaoCntEquip + price)
+        # 累加未结算战锤 - 战利品
+        chapterID = GetMainLevelNowInfo(curPlayer)[0]
+        chapterIpyData = IpyGameDataPY.GetIpyGameData("MainChapter", chapterID)
+        if chapterIpyData:
+            DailyBootyUpperList = chapterIpyData.GetDailyBootyUpperList()
+            for itemID, upperCnt in DailyBootyUpperList:
+                if upperCnt <= 0:
+                    continue
+                if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_BootyDropToday % itemID) >= upperCnt:
+                    continue
+                unXiantaoCntBooty = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCntBooty % itemID)
+                NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_UnXiantaoCntBooty % itemID, unXiantaoCntBooty + price)
+                
         PlayerPrestigeSys.AddRealmTaskValue(curPlayer, PlayerPrestigeSys.RealmTaskType_UseXiantao, price)
     unitPrice = price if quantity == 1 else int(math.ceil(price * 1.0 / quantity)) # 单价
     #reason_name = "Unknown" if not costType else costType
@@ -3476,7 +3491,8 @@
         
         # 杀怪
         if expViewType == ShareDefine.Def_ViewExpType_KillNPC:
-            exp_rate = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)
+            #exp_rate = curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_TotalExpRate)
+            exp_rate = 10000
         elif expViewType in [ShareDefine.Def_ViewExpType_GameEvent, ShareDefine.Def_ViewExpType_Sit]:
             exp_rate = curPlayer.GetGameEventExpRate()
             #exp_rate += GetFamilySitExpPer(curPlayer)
@@ -4965,12 +4981,6 @@
     insidePerAttrDict = {}
     customAttrDict = {}
     return attrList, insidePerAttrDict, customAttrDict
-
-def GetLordAttr(curPlayer):
-    ## 获取主公属性汇总
-    lordAttrDict = {"Atk":curPlayer.GetMaxAtk(), "Def":curPlayer.GetDef(), "MaxHP":GameObj.GetMaxHP(curPlayer), 
-                    "Hit":curPlayer.GetHit(), "Miss":curPlayer.GetMiss()}
-    return lordAttrDict
 
 #-------------------------------------------------------------------------------
 ## 设置玩家字典值, 存库
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
index e51d59f..cbe7cb0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -30,7 +30,7 @@
 import time
 
 class LineupHero():
-    ## 阵容战斗武将,注意:同一个武将在不同阵容中可能属性不一样
+    ## 阵容武将,注意:同一个武将在不同阵容中可能属性不一样
     
     def __init__(self):
         self.Clear()
@@ -39,6 +39,7 @@
     def Clear(self):
         self.itemIndex = 0
         self.heroID = 0
+        self.skinID = 0
         self.posNum = 0
         self.heroBatAttrDict = {} # 武将的最终战斗属性字典, {attrID:value, ...}
         self.heroSkillIDList = [] # 武将拥有的技能ID列表 [skillID, ...]
@@ -153,7 +154,7 @@
         return
     
     def OnClear(self):
-        self.mainFight.clear()
+        self.mainFight.turnFight.clearFight()
         return
     
     def SetPlayer(self, curPlayer):
@@ -453,7 +454,15 @@
         star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
         breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
         awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+        skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
         
+        skinID = 0
+        skinIDList = heroIpyData.GetSkinIDList()
+        if skinIndex < 0 or skinIndex >= len(skinIDList):
+            skinID = skinIDList[skinIndex]
+        elif skinIDList:
+            skinID = skinIDList[0]
+            
         InitAddPer += qualityIpyData.GetInitAddPer()
         LVAddPer += qualityIpyData.GetLVAddPer() * heroLV
         BreakLVAddPer += qualityIpyData.GetBreakLVAddPer() * breakLV
@@ -465,6 +474,7 @@
         lineupHero.itemIndex = itemIndex
         lineupHero.posNum = posNum
         lineupHero.heroID = heroID
+        lineupHero.skinID = skinID
         lineupHero.heroBatAttrDict = {}
         lineupHero.heroSkillIDList = []
         lineupHero.fightPower = 0
@@ -695,7 +705,7 @@
         GameWorld.DebugLog("    fightPower=%s,heroSkillIDList=%s" % (fightPower, lineupHero.heroSkillIDList))
         skillTypeIDDict = {}
         for skillID in lineupHero.heroSkillIDList:
-            skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID)
+            skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
             if not skillData:
                 continue
             skillTypeID = skillData.GetSkillTypeID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index e22d418..862a17a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -24,6 +24,9 @@
 g_serverClosing = 0 # 是否关服中 0-非关服中;1-关服中;2-关服结束
 g_closeSaveDataOK = False # 关服数据入库是否成功
 
+g_objPoolMgr = None # 对象池管理器
+g_batObjMgr = None # 战斗对象管理
+
 g_pyGameDataManager = None
 
 g_dbPlayerIDMap = {} # 本服DBPlayer玩家表ID映射关系 {playerID:accID, ...}
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
index a835c35..6276416 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -1284,13 +1284,13 @@
         elif curObjType == IPY_GameWorld.gotNPC:
             AttackCommon.NPCAddObjInHurtList(attackerOwner, curObj, curObjHP_BeforeAttack, lostValue)
             
-    TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, hurtType, lostValue, lostHP, curSkill)
+    #TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, lostValue, lostHP, curSkill)
     
     #统一调用攻击结束动作
     if isDoAttackResult:
         BaseAttack.DoLogic_AttackResult(buffOwner, curObj, None, tick)
         
-    TurnAttack.OnTurnfightAttackResult(buffOwner, curObj, curSkill)
+    #TurnAttack.OnTurnfightAttackResult(buffOwner, curObj, curSkill)
     return lostHP
 
 ## 检查增加淬毒buff
@@ -1852,12 +1852,16 @@
 
 def isAngerSkill(curSkill):
     ## 是否怒气技能
-    return curSkill and curSkill.GetXP() > 0
+    return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AngerSkill
 
 def isTurnNormalSkill(curSkill):
     ## 是否回合普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
     return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaSkill
 
+def isAtkbackSkill(curSkill):
+    ## 是否反击技能
+    return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill
+
 ## 检查技能是否为被动技能, 用于控制不可释放技能
 def isPassiveSkill(curSkill):
     return curSkill.GetSkillType() in [ChConfig.Def_SkillType_Passive,
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py
deleted file mode 100644
index 39225ed..0000000
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PySkillManager.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/python
-# -*- coding: GBK -*-
-#
-#
-##@package PySkillManager
-# @todo: 用于战斗模块所需接口,学习技能等其他所用接口可不开放
-#        支持临时改变数据以便战斗计算等其他效果
-# @author: Alee
-# @date: 2013-10-31 14:45
-# @version 1.1
-#
-# 修改时间 修改人 修改内容
-# @change: "2016-11-16 15:30" hxp 增加减少buff持续时间
-#
-#---------------------------------------------------------------------
-#"""Version = 2016-11-16 15:30"""
-#---------------------------------------------------------------------
-#导入
-
-# python 模拟技能效果结构
-class PySkillEffect():
-
-    def __init__(self, effObj):
-        self.effectID = effObj.GetEffectID()
-        
-        self.effectValueList = []
-        for i in xrange(effObj.GetEffectValueCount()):
-            self.effectValueList.append(effObj.GetEffectValue(i))
-
-        return
-
-    def Clear(self):
-        self.effectID = 0
-        self.effectValueList = []
-
-    def GetEffectID(self):
-        return self.effectID
-    
-    def GetEffectValue(self, index):
-        return self.effectValueList[index]
-    
-    def GetEffectValueCount(self):
-        return len(self.effectValueList)
-    
-    def SetEffectValue(self, index, value):
-        self.effectValueList[index] = value
-    
-    def AddEffectValue(self, index, value):
-        self.effectValueList[index] += value
-
-
-# python 模拟技能结构
-class PySkillData():
-    
-    def __init__(self):
-        return
-    
-    def CopySkillData(self, skillData):
-        self.Clear()
-        
-        self.effObjList = []
-        for i in xrange(skillData.GetEffectCount()):
-            self.effObjList.append(PySkillEffect(skillData.GetEffect(i)))
-        
-        self.skillID = skillData.GetSkillID()
-        self.skillName = skillData.GetSkillName()
-        self.skillTypeID = skillData.GetSkillTypeID()
-        self.skillLV = skillData.GetSkillLV()
-        self.skillMaxLV = skillData.GetSkillMaxLV()
-        self.useType = skillData.GetUseType()
-        
-        self.funcType = skillData.GetFuncType()
-        
-        self.castTime = skillData.GetCastTime()
-        self.skillType = skillData.GetSkillType()
-        self.continueUse = skillData.GetContinueUse()
-        self.atkType = skillData.GetAtkType()
-        self.atkRadius = skillData.GetAtkRadius()
-        self.tag = skillData.GetTag()
-        self.atkDist = skillData.GetAtkDist()
-        self.coolDownTime = skillData.GetCoolDownTime()
-        self.mp = skillData.GetMP()
-        self.hp = skillData.GetHP()
-        self.xp = skillData.GetXP()
-        self.useItemID = skillData.GetUseItemID()
-        self.useItemCnt = skillData.GetUseItemCount()
-        self.skillAngry = skillData.GetSkillAngry()
-        self.skillEnhance1 = skillData.GetSkillEnhance1()
-        self.skillEnhance2 = skillData.GetSkillEnhance2()
-        self.happenRate = skillData.GetHappenRate()
-        self.lastTime = skillData.GetLastTime()
-        self.canRepeatTime = skillData.GetCanRepeatTime()
-        self.commonCD = skillData.GetCommonCD()
-        self.hurtType = skillData.GetHurtType()
-        self.stiffTime = skillData.GetStiffTime()
-        self.clientActionLimit = skillData.GetClientActionLimit()
-        self.serverActionLimit = skillData.GetServerActionLimit()
-        self.clientSkillSeriesLimit = skillData.GetClientSkillSeriesLimit()
-        self.serverSkillSeriesLimit = skillData.GetServerSkillSeriesLimit()
-        self.skillOfSeries = skillData.GetSkillOfSeries()
-        self.exAttr1 = skillData.GetExAttr1()
-        self.exAttr2 = skillData.GetExAttr2()
-        self.exAttr3 = skillData.GetExAttr3()
-        self.exAttr4 = skillData.GetExAttr4()
-        self.exAttr5 = skillData.GetExAttr5()
-        
-        #非同步属性
-        self.buffValueEffDict = {}
-        return
-    
-    
-    def Clear(self):
-        self.effObjList = []
-        self.skillID = 0
-        self.skillName = 0
-        self.skillTypeID = 0
-        self.skillLV = 0
-        self.skillMaxLV = 0
-        self.useType = 0
-        self.weaponTypeList = []
-        self.castTime = 0
-        self.skillType = 0
-        self.continueUse = 0
-        self.atkType = 0
-        self.atkRadius = 0
-        self.tag = 0
-        self.atkDist = 0
-        self.coolDownTime = 0
-        self.mp = 0
-        self.hp = 0
-        self.xp = 0
-        self.useItemID = 0
-        self.useItemCnt = 0
-        self.skillAngry = 0
-        self.skillEnhance1 = 0
-        self.skillEnhance2 = 0
-        self.happenRate = 0
-        self.lastTime = 0
-        self.canRepeatTime = 0
-        self.commonCD = 0
-        self.hurtType = 0
-        self.stiffTime = 0
-        self.clientActionLimit = 0
-        self.serverActionLimit = 0
-        self.clientSkillSeriesLimit = 0
-        self.serverSkillSeriesLimit = 0
-        self.skillOfSeries = 0
-        self.exAttr1 = 0
-        self.exAttr2 = 0
-        self.exAttr3 = 0
-        self.exAttr4 = 0
-        self.exAttr5 = 0
-        
-        #非同步属性
-        self.buffValueEffDict = {}
-        self.buffValue = {}
-        return
-    
-    def GetEffect(self, index): return self.effObjList[index]
-    def GetEffectCount(self): return len(self.effObjList)
-    def GetSkillID(self): return self.skillID
-    def GetSkillName(self): return self.skillID
-    def GetSkillTypeID(self): return self.skillTypeID
-    def GetSkillLV(self): return self.skillLV
-    def GetSkillMaxLV(self): return self.skillMaxLV
-    def GetUseType(self): return self.useType
-    def GetFuncType(self, index): return self.funcType
-    def GetCastTime(self): return self.castTime
-    def GetSkillType(self): return self.skillType
-    def GetContinueUse(self): return self.continueUse
-    def GetAtkType(self): return self.atkType
-    def GetAtkRadius(self): return self.atkRadius
-    def GetTag(self): return self.tag
-    def GetAtkDist(self): return self.atkDist
-    def GetCoolDownTime(self): return self.coolDownTime
-    def GetMP(self): return self.mp
-    def GetHP(self): return self.hp
-    def GetXP(self): return self.xp
-    def GetUseItemID(self): return self.useItemID
-    def GetUseItemCount(self): return self.useItemCnt
-    def GetSkillAngry(self): return self.skillAngry
-    def GetSkillEnhance1(self): return self.skillEnhance1
-    def GetSkillEnhance2(self): return self.skillEnhance2
-    def GetHappenRate(self): return self.happenRate
-    def GetLastTime(self): return self.lastTime
-    def GetCanRepeatTime(self): return self.canRepeatTime
-    def GetCommonCD(self): return self.commonCD
-    def GetHurtType(self): return self.hurtType
-    def GetStiffTime(self): return self.stiffTime
-    def GetClientActionLimit(self): return self.clientActionLimit
-    def GetServerActionLimit(self): return self.serverActionLimit
-    def GetClientSkillSeriesLimit(self): return self.clientSkillSeriesLimit
-    def GetServerSkillSeriesLimit(self): return self.serverSkillSeriesLimit
-    def GetSkillOfSeries(self): return self.skillOfSeries
-    def GetExAttr1(self): return self.exAttr1
-    def GetExAttr2(self): return self.exAttr2
-    def GetExAttr3(self): return self.exAttr3
-    def GetExAttr4(self): return self.exAttr4
-    def GetExAttr5(self): return self.exAttr5
-    
-    #非同步接口--------------------------------------------------------------------
-    
-    def ReduceCoolDownTime(self, value):
-        self.coolDownTime -= value
-        
-    def AddHappenRate(self, value):
-        self.happenRate += value
-        
-    def AddLastTime(self, value):
-        self.lastTime += value
-    
-    def DecLastTime(self, value):
-        self.lastTime = max(0, self.lastTime - value)
-        
-    # BUFF类型的buffvalue处理
-    def GetBuffValueByEffectID(self, effectID):
-        return self.buffValueEffDict.get(effectID, 0)
-
-    def AddBuffValueEff(self, effectID, value):
-        self.buffValueEffDict[effectID] = value + self.buffValueEffDict.get(effectID, 0)
-    
-    # BUFF类型的buffvalue处理
-    def GetBuffValueEx(self, index):
-        return self.buffValue.get(index, 0)
-
-    def AddBuffValueEx(self, index, value):
-        self.buffValue[index] = value + self.buffValueEffDict.get(index, 0)
-        
-    def GetBuffValueDict(self):
-        return self.buffValue
-#-------------------------------------------------------------------------------    
-    
-#全局,适用于单线程,慎用
-Py_SkillData = PySkillData()    # 主动释放的技能
-Py_SkillDataTrigger = PySkillData()    # 触发技能
-
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 3452d8a..fd10975 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/SkillShell.py
@@ -3494,7 +3494,7 @@
 
         #调用攻击惩罚逻辑
         BaseAttack.DoLogic_AttackResult(attacker, defender, None, tick)
-        TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
+        #TurnAttack.OnTurnfightAttackResult(attacker, defender, curSkill)
         
     return
 #---------------------------------------------------------------------
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
new file mode 100644
index 0000000..7d4a172
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnBuff
+#
+# @todo:回合战斗buff
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 回合战斗buff
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import ChPyNetSendPack
+import ObjPool
+
+def OnAddBuff(turnFight, batObj, curSkill, buffOwner=None):
+    skillID = curSkill.GetSkillID()
+    enhanceBySkill = curSkill.GetEnhanceBySkill()
+    relatedSkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+    curID = batObj.GetID()
+    ownerID = buffOwner.GetID() if buffOwner else curID
+    GameWorld.DebugLog("OnAddBuff: curID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s" % (curID, skillID, ownerID, relatedSkillID))
+    #检查是否几率触发
+    if not enhanceBySkill:
+        rate = curSkill.GetHappenRate()
+        if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
+            GameWorld.DebugLog("    概率不触发buff!")
+            return
+        
+    skillTypeID = curSkill.GetSkillTypeID()
+    # 先简单做下能加上即可
+    buffMgr = batObj.GetBuffManager()
+    buffIDList = buffMgr.FindBuffIDBySkillTypeID(skillTypeID)
+    if buffIDList:
+        GameWorld.DebugLog("    已经存在该buff: skillTypeID=%s,buffIDList=%s" % (skillTypeID, buffIDList))
+        return True
+    
+    buff = buffMgr.AddBuff(skillID)
+    if not buff:
+        GameWorld.DebugLog("    添加buff失败! skillID=%s" % skillID)
+        return False
+    GameWorld.DebugLog("    AddBuffOK. buffID=%s" % buff.GetBuffID())
+    buff.SetOwnerID(ownerID)
+    buff.SetRemainTime(curSkill.GetLastTime())
+    #buff.SetLayer()
+    SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID)
+    return True
+
+def SyncBuffRefresh(turnFight, curBatObj, curBuff, relatedSkillID=0):
+    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffRefresh)
+    clientPack.ObjID = curBatObj.GetID()
+    clientPack.BuffID = curBuff.GetBuffID()
+    clientPack.SkillID = curBuff.GetSkillID()
+    clientPack.RelatedSkillID = relatedSkillID
+    clientPack.LastTime = curBuff.GetRemainTime()
+    clientPack.Layer = curBuff.GetLayer()
+    clientPack.OwnerID = curBuff.GetOwnerID()
+    turnFight.addBatPack(clientPack)
+    return
+
+def SyncBuffDel(turnFight, curBatObj, buffID, relatedSkillID=0):
+    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffDel)
+    clientPack.ObjID = curBatObj.GetID()
+    clientPack.BuffID = buffID
+    clientPack.RelatedSkillID = relatedSkillID
+    turnFight.addBatPack(clientPack)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
new file mode 100644
index 0000000..7cbef56
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -0,0 +1,899 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnSkill
+#
+# @todo:回合战斗技能
+# @author hxp
+# @date 2025-08-06
+# @version 1.0
+#
+# 详细描述: 回合战斗技能
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-06 18:30"""
+#-------------------------------------------------------------------------------
+
+import ChConfig
+import GameWorld
+import BattleObj
+import SkillCommon
+import IpyGameDataPY
+import IPY_GameWorld
+import ChPyNetSendPack
+import PlayerControl
+import ShareDefine
+import TurnAttack
+import TurnBuff
+import ObjPool
+import FBLogic
+
+import random
+
+def GetPMType(batObj, useSkill):
+    ## 获取物法伤害类型
+    # GetHurtType 个位数用法改成 pvp pve标识,十位数-物攻法攻 IPY_GameWorld.ghtPhy = 1
+    #---技能攻击, 读表获取攻击类型---
+    ght = useSkill.GetHurtType() % 10
+    if ght == IPY_GameWorld.ghtMag: # 做配置兼容用,优先验证法伤,否则默认物伤
+        return IPY_GameWorld.ghtMag
+    return IPY_GameWorld.ghtPhy
+
+def IsIgnoreDef(useSkill):
+    ## 是否无视防御
+    return useSkill.GetHurtType() / 10 == 1 # 2为真伤,待扩展
+
+def OnUseSkill(turnFight, curBatObj, useSkill, tagObjList=None, batType=ChConfig.TurnBattleType_Normal, enhanceBySkill=None):
+    '''使用技能通用入口
+    @param useSkill: 使用的技能,注意并不一定是身上的技能,可能只是 SkillData 表数据
+    @param enhanceBySkill: 由哪个主技能额外触发的
+    @return: 是否成功
+    '''
+    if not useSkill:
+        return
+    
+    skillID = useSkill.GetSkillID()
+    if not skillID:
+        return
+    
+    #没有指定目标,则按技能自身的目标逻辑
+    if not tagObjList:
+        tagAim = useSkill.GetTagAim()
+        tagFriendly = useSkill.GetTagFriendly()
+        tagAffect = useSkill.GetTagAffect()
+        tagCount = useSkill.GetTagCount()
+        tagObjList = GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount)
+        
+    enhanceBySkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+    GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,enhanceBySkill=%s" 
+                       % (curBatObj.GetID(), skillID, len(tagObjList), batType, enhanceBySkillID))
+    if not tagObjList:
+        # 可扩展其他目标选择,如复活技能没有死亡单位时则使用另外的效果
+        return
+    
+    # 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
+    
+    poolMgr = ObjPool.GetPoolMgr()
+    usePoolSkill = False
+    if isinstance(useSkill, IpyGameDataPY.IPY_Skill):
+        usePoolSkill = True
+        # 统一使用 BattleObj.PySkill
+        useSkill = poolMgr.acquire(BattleObj.PySkill, useSkill)
+        
+    useSkill.SetTagObjList(tagObjList)
+    useSkill.SetBatType(batType)
+    useSkill.SetEnhanceBySkill(enhanceBySkill)
+    useSkill.ClearHurtObj()
+    
+    curBatObj.ClearSkillTempAttr()
+    for tagObj in tagObjList:
+        tagObj.ClearSkillTempAttr()
+        
+    objID = curBatObj.GetID()
+    useTag = ""
+    if not enhanceBySkill:
+        # 因为可能触发连击,所以标记需带上累计使用技能次数,确保唯一
+        useTag = "Skill_%s_%s_%s" % (objID, skillID, curBatObj.GetSkillUseCnt(skillID) + 1)
+        clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCTurnFightTag)
+        clientPack.Tag = useTag
+        clientPack.Len = len(clientPack.Tag)
+        clientPack.Sign = 0
+        turnFight.addBatPack(clientPack)
+        
+    #这个技能是Buff
+    if SkillCommon.IsBuff(useSkill):
+        __doAddBuff(turnFight, curBatObj, useSkill)
+    else:
+        __doUseSkill(turnFight, curBatObj, useSkill)
+        
+    if useTag:
+        clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCTurnFightTag)
+        clientPack.Tag = useTag
+        clientPack.Len = len(clientPack.Tag)
+        clientPack.Sign = 1
+        turnFight.addBatPack(clientPack)
+        
+    # 最后重置、清空回收对象池
+    useSkill.SetTagObjList([])
+    useSkill.SetEnhanceBySkill(None) # 需重置,防止主技能被误回收
+    useSkill.ClearHurtObj()
+    if usePoolSkill:
+        poolMgr.release(useSkill)
+    return True
+
+def GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount):
+    ## 获取技能目标    
+    curFaction = curBatObj.GetFaction()
+    
+    # 自己,直接返回
+    if tagAim == ChConfig.SkillTagAim_Self:
+        return [curBatObj]
+    
+    if tagFriendly:
+        tagFaction = curFaction
+    else:
+        tagFaction = ChConfig.Def_FactionB if curFaction == ChConfig.Def_FactionA else ChConfig.Def_FactionA
+        
+    batObjMgr = BattleObj.GetBatObjMgr()
+    lineupNum = curBatObj.GetLineupNum()
+    posNum = curBatObj.GetPosNum()
+    
+    batFaction = turnFight.getBatFaction(tagFaction)
+    if tagFaction == curFaction:
+        lineupNumList = [lineupNum] # 友方暂时仅限制自己阵容
+    else:
+        lineupNumList = [lineupNum] # 敌方优先对位阵容,再其他阵容
+        for tagNum in batFaction.lineupDict.keys():
+            if tagNum not in lineupNumList:
+                lineupNumList.append(tagNum)
+                
+    aimObjList = [] # 先筛选出范围目标
+    for num in lineupNumList:
+        batLineup = batFaction.getBatlineup(num)
+        
+        # 对位
+        if tagAim == ChConfig.SkillTagAim_Relative:
+            posNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
+            pNumList = batLineup.posObjIDDict.keys()
+            pNumList.sort()
+            for pNum in pNumList:
+                if pNum > 0 and pNum not in posNumList:
+                    posNumList.append(pNum)
+            for pNum in posNumList:
+                if pNum not in batLineup.posObjIDDict:
+                    continue
+                tagObjID = batLineup.posObjIDDict[pNum]
+                tagBatObj = batObjMgr.getBatObj(tagObjID)
+                if not __skillTagFilter(tagBatObj, tagAffect):
+                    continue
+                aimObjList.append(tagBatObj) # 对位的默认只选1个
+                break
+            
+        # 前排
+        elif tagAim == ChConfig.SkillTagAim_FrontRow:
+            # 优先前排,如果没有则后排亦是前排
+            for pNumList in [[1, 2, 3], [4, 5, 6]]:
+                hasObj = False
+                for pNum in pNumList:
+                    if pNum not in batLineup.posObjIDDict:
+                        continue
+                    tagObjID = batLineup.posObjIDDict[pNum]
+                    tagBatObj = batObjMgr.getBatObj(tagObjID)
+                    if not __skillTagFilter(tagBatObj, tagAffect):
+                        continue
+                    hasObj = True
+                    aimObjList.append(tagBatObj)
+                if hasObj:
+                    break
+                
+        # 后排
+        elif tagAim == ChConfig.SkillTagAim_BackRow:
+            # 优先后排,如果没有则前排亦是后排
+            for pNumList in [[4, 5, 6], [1, 2, 3]]:
+                hasObj = False
+                for pNum in pNumList:
+                    if pNum not in batLineup.posObjIDDict:
+                        continue
+                    tagObjID = batLineup.posObjIDDict[pNum]
+                    tagBatObj = batObjMgr.getBatObj(tagObjID)
+                    if not __skillTagFilter(tagBatObj, tagAffect):
+                        continue
+                    hasObj = True
+                    aimObjList.append(tagBatObj)
+                if hasObj:
+                    break
+                
+        # 竖排/纵排
+        elif tagAim == ChConfig.SkillTagAim_Vertical:
+            verticalNumList = [[1, 4], [2, 5], [3, 6]]
+            for pNumList in verticalNumList:
+                # 优先对位排
+                if posNum in pNumList:
+                    verticalNumList.remove(pNumList)
+                    verticalNumList.insert(0, pNumList)
+                    break
+            for pNumList in verticalNumList:
+                hasObj = False
+                for pNum in pNumList:
+                    if pNum not in batLineup.posObjIDDict:
+                        continue
+                    tagObjID = batLineup.posObjIDDict[pNum]
+                    tagBatObj = batObjMgr.getBatObj(tagObjID)
+                    if not __skillTagFilter(tagBatObj, tagAffect):
+                        continue
+                    hasObj = True
+                    aimObjList.append(tagBatObj)
+                if hasObj:
+                    break
+                
+        # 其他,默认全部
+        else:
+            pNumList = batLineup.posObjIDDict.keys()
+            for pNum in pNumList:
+                if pNum <= 0:
+                    continue
+                tagObjID = batLineup.posObjIDDict[pNum]
+                tagBatObj = batObjMgr.getBatObj(tagObjID)
+                if not __skillTagFilter(tagBatObj, tagAffect):
+                    continue
+                aimObjList.append(tagBatObj)
+                
+    # 目标细分
+    # 血量最低
+    if tagAffect == ChConfig.SkillTagAffect_HPLowest:
+        aimObjList.sort(key=lambda o:(o.GetHP()), reverse=False)
+        aimObjList = aimObjList[:tagCount]
+    
+    # 血量最高
+    elif tagAffect == ChConfig.SkillTagAffect_HPHighest:
+        aimObjList.sort(key=lambda o:(o.GetHP()), reverse=True)
+        aimObjList = aimObjList[:tagCount]
+        
+    else:
+        # 范围目标超过个数,则随机取
+        if tagCount and len(aimObjList) > tagCount:
+            random.shuffle(aimObjList)
+            aimObjList = aimObjList[:tagCount]
+            
+    return aimObjList
+
+def __skillTagFilter(tagBatObj, tagAffect):
+    ## 技能目标过滤器
+    # @return: 是否允许添加该单位
+    if not tagBatObj:
+        return False
+    if tagAffect != ChConfig.SkillTagAffect_Death and tagBatObj.GetHP() <= 0:
+        return False
+    if tagAffect == ChConfig.SkillTagAffect_Death and tagBatObj.GetHP() > 0:
+        return False
+    if not tagBatObj.GetCanAttack():
+        return False
+    return True
+
+def __doAddBuff(turnFight, curBatObj, useSkill):
+    #执行添加buff
+    
+    for tagBatObj in useSkill.GetTagObjList():
+        TurnBuff.OnAddBuff(turnFight, tagBatObj, useSkill, buffOwner=curBatObj)
+        
+    DoAttackResult(turnFight, curBatObj, useSkill)
+    return
+
+def __doUseSkill(turnFight, curBatObj, useSkill):
+    
+    atkType = useSkill.GetAtkType()
+    GameWorld.DebugLog("__doUseSkill: curID=%s,skillID=%s,atkType=%s" % (curBatObj.GetID(), useSkill.GetSkillID(), atkType))
+    # 通用攻击
+    if atkType == 1:
+        SkillModule_1(turnFight, curBatObj, useSkill)
+        return
+    
+    # 治疗
+    if atkType == 2:
+        SkillModule_2(turnFight, curBatObj, useSkill)
+        return
+    
+    # 复活
+    if atkType == 3:
+        return
+    
+    # 多次攻击(锁目标多次伤害,非前端的多段飘血)
+    if atkType == 4:
+        return
+    
+    # 弹射(多次攻击,切换目标)
+    if atkType == 5:
+        return
+    
+    # 6 怒气增减偷
+    if atkType == 6:
+        SkillModule_6(turnFight, curBatObj, useSkill)
+        return
+    
+    return
+
+def SkillModule_1(turnFight, curBatObj, useSkill):
+    ## 通用攻击,单攻、群攻
+    
+    #执行攻击结果
+    for tagBatObj in useSkill.GetTagObjList():
+        __doSkillHurtHP(curBatObj, tagBatObj, useSkill)
+        
+    DoAttackResult(turnFight, curBatObj, useSkill)
+    return
+
+def SkillModule_2(turnFight, curBatObj, useSkill):
+    ## 治疗
+    
+    skillID = useSkill.GetSkillID()
+    for tagBatObj in useSkill.GetTagObjList():
+        cureHP = CalcCureHP(curBatObj, tagBatObj, useSkill, largeNum=True)
+        if cureHP <= 0:
+            continue
+        
+        dHP = tagBatObj.GetHP()
+        dMapHP = tagBatObj.GetMaxHP()
+        
+        remainHP = min(dHP + cureHP, dMapHP)
+        realCureHP = max(remainHP - dHP, 0)
+        tagBatObj.SetHP(remainHP)
+        
+        dID = tagBatObj.GetID()
+        hurtObj = useSkill.AddHurtObj(dID)
+        hurtObj.AddHurtType(ChConfig.HurtTYpe_Recovery)
+        hurtObj.SetHurtHP(cureHP)
+        hurtObj.SetLostHP(realCureHP)
+        hurtObj.SetCurHP(tagBatObj.GetHP())
+        GameWorld.DebugLog("    治疗: dID=%s,cureHP=%s,realCureHP=%s,%s/%s" % (dID, cureHP, realCureHP, tagBatObj.GetHP(), dMapHP))
+        
+        TurnAttack.AddTurnObjCureHP(tagBatObj, curBatObj, cureHP, realCureHP, skillID)
+        
+    DoAttackResult(turnFight, curBatObj, useSkill)
+    return
+
+def SkillModule_6(turnFight, curBatObj, useSkill):
+    ## 怒气增减偷
+    
+    curID = curBatObj.GetID()
+    skillID = useSkill.GetSkillID()
+    enhanceBySkill = useSkill.GetEnhanceBySkill()
+    relatedSkillID = enhanceBySkill.GetSkillID() if enhanceBySkill else 0
+    
+    effIDNum = useSkill.FindEffectID(ChConfig.Def_Skill_Effect_Anger)
+    angerPer = useSkill.GetEffectValue(effIDNum, 0) # 最大值的百分比,万分率
+    angerValue = useSkill.GetEffectValue(effIDNum, 1) # 固定值
+    calcType = useSkill.GetEffectValue(effIDNum, 2) # 计算方式(1增 2减 3偷)
+    xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
+    calcValue = int(xpMax * angerPer / 10000.0 + angerValue)
+    attrID = ChConfig.AttrID_XP
+    
+    GameWorld.DebugLog("怒气增减偷: curID=%s,calcValue=%s,skillID=%s,angerPer=%s,angerValue=%s,calcType=%s,relatedSkillID=%s" 
+                       % (curID, calcValue, skillID, angerPer, angerValue, calcType, relatedSkillID))
+    curStealTotal = 0
+    for tagBatObj in useSkill.GetTagObjList():
+        
+        tagID = tagBatObj.GetID()
+        # 减
+        if calcType == 2:
+            diffType = 0
+            tagXP = tagBatObj.GetXP()
+            diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
+            updValue = tagXP - diffValue
+            tagBatObj.SetXP(updValue, False)
+            GameWorld.DebugLog("    减怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+            Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+            
+        # 偷
+        elif calcType == 3:
+            diffType = 0
+            tagXP = tagBatObj.GetXP()
+            diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
+            updValue = tagXP - diffValue
+            tagBatObj.SetXP(updValue, False)
+            GameWorld.DebugLog("    偷怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+            Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+            
+            curStealTotal += diffValue
+            
+        # 其他默认加
+        else:
+            diffType = 1
+            tagXP = tagBatObj.GetXP()
+            diffValue = calcValue
+            updValue = tagXP + diffValue
+            tagBatObj.SetXP(updValue, False)
+            GameWorld.DebugLog("    加怒气: tagID=%s,diffValue=%s,tagXP=%s,updXP=%s" % (tagID, diffValue, tagXP, updValue))
+            Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+            
+    if curStealTotal > 0:
+        diffType = 1
+        curXP = curBatObj.GetXP()
+        diffValue = curStealTotal
+        updValue = curXP + diffValue
+        curBatObj.SetXP(updValue, False)
+        GameWorld.DebugLog("    偷总怒气: curID=%s,curStealTotal=%s,curXP=%s,updXP=%s" % (curID, curStealTotal, curXP, updValue))
+        Sync_PropertyRefreshView(turnFight, curBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
+        
+    DoAttackResult(turnFight, curBatObj, useSkill)
+    return
+
+def DoAttackResult(turnFight, curBatObj, useSkill):
+    '''执行攻击结果,技能、buff通用
+    @param curBatObj: 施法方或buff归属方
+    '''
+    
+    if curBatObj:
+        # 反弹、吸血 的原因,需要统一处理后结算,可能导致HP为负值,修正为0
+        if curBatObj.GetHP() < 0:
+            curBatObj.SetHP(0)
+            
+    skillID = useSkill.GetSkillID()
+    curBatObj.AddSkillUseCnt(skillID)
+    
+    # 需先通知伤血 - 前端按顺序优先表现主技能内容,
+    enhanceBySkill = useSkill.GetEnhanceBySkill()
+    if not enhanceBySkill:
+        Sync_UseSkill(turnFight, curBatObj, useSkill)
+        __doCostZhanchui(turnFight, curBatObj, useSkill)
+        __doSkillUserAnger(turnFight, curBatObj, useSkill)
+        
+    # 统计死亡
+    killObjIDList = [] # 击杀的目标ID列表
+    for tagObj in useSkill.GetTagObjList():
+        tagID = tagObj.GetID()
+        hurtObj = useSkill.GetHurtObj(tagID)
+        if hurtObj and not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery):
+            __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
+        if tagObj.GetHP() <= 0:
+            killObjIDList.append(tagID)
+            TurnAttack.SetObjKilled(turnFight, tagObj, curBatObj, useSkill)
+    if curBatObj.GetHP() <= 0:
+        TurnAttack.SetObjKilled(turnFight, curBatObj)
+        
+    # 结算副本相关的攻击结果,仅主动发起玩家阵容武将触发
+    curPlayer = turnFight.curPlayer
+    if curPlayer and curBatObj.GetOwnerID() == curPlayer.GetPlayerID():
+        FBLogic.OnPlayerLineupAttackResult(curPlayer, curBatObj, killObjIDList, useSkill, turnFight.mapID, turnFight.funcLineID)
+        
+    # 额外触发技能
+    __doUseEnhanceSkill(turnFight, curBatObj, useSkill)
+    
+    # 循环触发被动,待扩展
+    
+    # 最后处理反击 或 连击
+    
+    return
+
+def __doCostZhanchui(turnFight, curBatObj, useSkill):
+
+    turnFight.mapID
+    if turnFight.mapID != ChConfig.Def_FBMapID_Main:
+        ## 仅主线战斗需要
+        return
+    
+    curPlayer = turnFight.curPlayer
+    if not curPlayer:
+        return
+    # 仅主动发起玩家阵容武将释放技能需要消耗
+    if curBatObj.GetOwnerID() != curPlayer.GetPlayerID():
+        return
+    
+    costZhanchui = 0
+    batType = useSkill.GetBatType()
+    if SkillCommon.isAngerSkill(useSkill):
+        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
+    elif batType == ChConfig.TurnBattleType_Combo:
+        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
+    elif batType == ChConfig.TurnBattleType_AtkBack:
+        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
+    elif SkillCommon.isTurnNormalSkill(useSkill):
+        costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
+        
+    if costZhanchui <= 0:
+        return
+    
+    fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
+    costZhanchuiTotal = costZhanchui * fightPoint
+    if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, costZhanchuiTotal, isNotify=False):
+        # 不足时,有多少扣多少
+        nowMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao)
+        PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, min(nowMoney, costZhanchuiTotal), isNotify=False)
+        
+    return
+
+def __doSkillUserAnger(turnFight, curBatObj, useSkill):
+    ## 技能释放者怒气相关
+    if SkillCommon.isAngerSkill(useSkill):
+        curBatObj.SetXP(0)
+    elif SkillCommon.isTurnNormalSkill(useSkill):
+        addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
+        AddTurnFightXP(curBatObj, addXP, "skillID:%s" % useSkill.GetSkillID())
+    return
+
+def __doSkillHurtAnger(batObj, lostHP, useSkill):
+    ## 结算受伤者怒气
+    if lostHP <= 0:
+        return
+    addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
+    if addXP <= 0:
+        return
+    AddTurnFightXP(batObj, addXP, "skillID:%s" % useSkill.GetSkillID())
+    return
+
+def AddTurnFightXP(gameObj, addXP, reason=""):
+    ## 回合战斗增加XP
+    if addXP <= 0 or not addXP:
+        #GameWorld.DebugLog("        没有增加XP! curID=%s" % (gameObj.GetID()))
+        return
+    posNum = gameObj.GetPosNum()
+    if posNum <= 0:
+        #非主战单位不加
+        return
+    curXP = gameObj.GetXP()
+    updXP = curXP + addXP
+    gameObj.SetXP(updXP)
+    GameWorld.DebugLog("        更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
+    return
+
+def __doUseEnhanceSkill(turnFight, curBatObj, useSkill):
+    if useSkill.GetEnhanceBySkill():
+        GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
+        return
+    enhanceSkillIDList = useSkill.GetEnhanceSkillList()
+    if not enhanceSkillIDList:
+        return
+    GameWorld.DebugLog("额外触发的技能! skillID=%s,enhanceSkillIDList=%s" % (useSkill.GetSkillID(), enhanceSkillIDList))
+    # 根据触发技能的特点决定是触发一次还是 触发多次
+    # 群体BUFF的请参考 IsPlayerUseSkill 客户端决定对象,一样可以实现同样效果
+    tagObjList = useSkill.GetTagObjList()
+    for enhanceSkillID in enhanceSkillIDList:
+        enhanceSkillData = IpyGameDataPY.GetIpyGameData("Skill", enhanceSkillID)
+        if not enhanceSkillData:
+            continue
+        # 继承主技能目标
+        if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
+            GameWorld.DebugLog("    额外触发技能,继承主技能目标! enhanceSkillID=%s" % enhanceSkillID)
+            # 额外触发的技能直接在外层检查概率,如果都没有触发则不需要再处理
+            enhanceRate = enhanceSkillData.GetHappenRate()            
+            enchanceTagObjList = []
+            for tagObj in tagObjList:
+                tagID = tagObj.GetID()
+                if tagObj.GetHP() <= 0:
+                    GameWorld.DebugLog("    已被击杀不触发: tagID=%s" % (tagID))
+                    continue
+                hurtObj = useSkill.GetHurtObj(tagID)
+                if not hurtObj:
+                    GameWorld.DebugLog("    没有伤血不触发: tagID=%s" % (tagID))
+                    continue
+                if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
+                    GameWorld.DebugLog("    闪避的对象不再触发技能: tagID=%s,enhanceSkillID=%s" % (tagID, enhanceSkillID))
+                    continue
+                if enhanceRate and enhanceRate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(enhanceRate, ChConfig.Def_MaxRateValue):
+                    GameWorld.DebugLog("    概率不触发: tagID=%s,enhanceRate=%s" % (tagID, enhanceRate))
+                    continue
+                
+                enchanceTagObjList.append(tagObj)
+                
+            if enchanceTagObjList:
+                OnUseSkill(turnFight, curBatObj, enhanceSkillData, enchanceTagObjList, enhanceBySkill=useSkill)
+                
+            continue
+        
+        GameWorld.DebugLog("    额外触发技能,重新锁定目标! enhanceSkillID=%s" % enhanceSkillID)
+        OnUseSkill(turnFight, curBatObj, enhanceSkillData, enhanceBySkill=useSkill)
+        
+    return
+
+def __doSkillHurtHP(attacker, defObj, curSkill):
+    ## 执行技能伤血,只计算伤血,其他逻辑等技能同步后再处理
+    # @return: None - 没有执行成功,即忽略该目标
+    
+    atkObj = attacker
+    atkID = atkObj.GetID()
+    defID = defObj.GetID()
+    hurtObj = curSkill.AddHurtObj(defID)
+    
+    #检查是否几率触发
+    if not curSkill.GetEnhanceBySkill(): # 额外触发的技能概率在触发时判断
+        rate = curSkill.GetHappenRate()
+        if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
+            #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
+            #放这里,兼容群攻时如果该技能是有概率的,则每个目标单独判断
+            hurtObj.AddHurtType(ChConfig.HurtType_Fail)
+            hurtObj.SetCurHP(defObj.GetHP())
+            return hurtObj
+        
+    atkEffIDNum = curSkill.FindEffectID(ChConfig.Def_Skill_Effect_Attack)
+    atkSkillValue = 0
+    atkSkillPer = curSkill.GetEffectValue(atkEffIDNum, 0)
+    
+    dHP = defObj.GetHP()                # 防守方当前血量
+    dMaxHP = defObj.GetMaxHP()          # 防守方最大血量
+    
+    zhansha = False # 斩杀特殊处理
+    # 斩杀
+    if zhansha:
+        pass
+    
+    else:
+        hurtValue, hurtTypes = CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer)
+        
+        # 各种减伤 吸收盾处理
+        #hurtValue = CalcHurtHPWithBuff(atkObj, defObj, hurtValue, curSkill, tick)
+        
+        #伤害结构体
+        hurtObj.SetHurtTypes(hurtTypes)
+        hurtObj.SetHurtHP(hurtValue)
+        remainHP = min(dMaxHP, max(0, dHP - hurtValue)) # 剩余血量
+        
+    remainHP = int(remainHP)    #防范
+    lostHP = dHP - remainHP # 实际掉血量
+    hurtObj.SetLostHP(lostHP)
+    hurtObj.SetCurHP(remainHP)
+    defObj.SetHP(remainHP)
+    GameWorld.DebugLog("    伤血: atkID=%s,defID=%s,hurtValue=%s,lostHP=%s,%s/%s" % (atkID, defID, hurtValue, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
+    
+    #反弹伤害
+    CalcBounceHP(atkObj, defObj, hurtObj, curSkill)
+    
+    #吸血
+    CalcSuckBlood(atkObj, defObj, hurtObj, curSkill)
+    
+    TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, curSkill)
+    return hurtObj
+
+def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, **atkwargs):
+    '''计算伤害
+    '''
+    pmType = GetPMType(atkObj, curSkill)
+    ignoreDef = IsIgnoreDef(curSkill)
+    
+    atkID = atkObj.GetID()
+    defID = defObj.GetID()
+    
+    skillID = curSkill.GetSkillID()
+    isTurnNormalSkill = SkillCommon.isTurnNormalSkill(curSkill)
+    isAngerSkill = SkillCommon.isAngerSkill(curSkill)
+    isAtkbackSkill = SkillCommon.isAtkbackSkill(curSkill)
+    
+    angerOverflow = 0 # 怒气溢出值
+    
+    mustHit = False
+    if isAngerSkill:
+        mustHit = True
+        GameWorld.DebugLog("        XP必命中")
+        angerOverflow = max(atkObj.GetXP() - IpyGameDataPY.GetFuncCfg("AngerXP", 2), 0)
+        
+    #命中公式 攻击方类型不同,公式不同
+    if not mustHit:
+        aMissRateDef = atkObj.GetAttrValue(ChConfig.AttrID_MissRateDef) #atkObj.GetHit() # 抗闪避率 - 命中
+        dMissRate = defObj.GetAttrValue(ChConfig.AttrID_MissRate) # 闪避率
+        missNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnMissNum)
+        missRate = eval(IpyGameDataPY.GetFuncCompileCfg("MissCfg", 1))
+        if GameWorld.CanHappen(missRate):
+            return 0, pow(2, ChConfig.HurtType_Miss)
+        
+    hurtTypes = pow(2, ChConfig.HurtType_Normal)
+    
+    isSuperHit = False # 是否暴击
+    if isSuperHit:
+        hurtTypes |= pow(2, ChConfig.HurtType_SuperHit)
+        
+    isParry = False # 是否格挡
+    if isParry:
+        hurtTypes |= pow(2, ChConfig.HurtType_Parry)
+        
+    if ignoreDef:
+        hurtTypes |= pow(2, ChConfig.HurtType_IgnoreDef)
+        
+    #参与运算的数值
+    rand = random.random()                #种子数 0~1
+    
+    aAtk = atkObj.GetAttrValue(ChConfig.AttrID_Atk) # 攻击方最大攻击
+    
+    dHP = defObj.GetHP()
+    dDef = 0 if ignoreDef else defObj.GetAttrValue(ChConfig.AttrID_Def) # 防守方防御力
+    
+    aFinalDamPer = atkObj.GetAttrValue(ChConfig.AttrID_FinalDamPer) # 最终加成
+    dFinalDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_FinalDamPerDef) # 最终减伤
+    
+    aNormalSkillPer, dNormalSkillPerDef = 0, 0
+    if isTurnNormalSkill:
+        aNormalSkillPer = atkObj.GetAttrValue(ChConfig.AttrID_NormalSkillPer) # 普技增伤
+        dNormalSkillPerDef = defObj.GetAttrValue(ChConfig.AttrID_NormalSkillPerDef) # 普技减伤
+        
+    aAngerSkillPer, dAngerSkillPerDef = 0, 0
+    if isAngerSkill:
+        aAngerSkillPer = atkObj.GetAttrValue(ChConfig.AttrID_AngerSkillPer) # 普技增伤
+        dAngerSkillPerDef = defObj.GetAttrValue(ChConfig.AttrID_AngerSkillPerDef) # 普技减伤
+        
+    # 物法增减伤
+    if pmType == IPY_GameWorld.ghtMag: # 法伤
+        aPMDamPer = atkObj.GetAttrValue(ChConfig.AttrID_MagDamPer)
+        dPMDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_MagDamPerDef)
+    else: # 物伤
+        aPMDamPer = atkObj.GetAttrValue(ChConfig.AttrID_PhyDamPer) 
+        dPMDamPerDef = defObj.GetAttrValue(ChConfig.AttrID_PhyDamPerDef)
+        
+    # 所有万分率参数统一除10000.0
+    atkSkillPer /= 10000.0
+    aNormalSkillPer /= 10000.0
+    dNormalSkillPerDef /= 10000.0
+    aAngerSkillPer /= 10000.0
+    dAngerSkillPerDef /= 10000.0
+    aPMDamPer /= 10000.0
+    dPMDamPerDef /= 10000.0
+    aFinalDamPer /= 10000.0
+    dFinalDamPerDef /= 10000.0
+    
+    
+    GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,aAtk=%s,dDef=%s,dHP=%s,hurtTypes=%s" 
+                       % (atkID, defID, skillID, atkSkillPer, aAtk, dDef, dHP, hurtTypes))
+    
+    if "hurtFormulaKey" in atkwargs:
+        aBurnValue = atkwargs.get('burnValue', 0)
+        aBurnPer = atkwargs.get('burnPer', 0)
+        hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
+        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
+    elif isTurnNormalSkill:
+        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
+        GameWorld.DebugLog("    普攻技能伤害=%s" % (hurtValue))
+    elif isAngerSkill:
+        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 2))
+        GameWorld.DebugLog("    怒气技能伤害=%s" % (hurtValue))
+    elif isAtkbackSkill:
+        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
+        GameWorld.DebugLog("    反击伤害=%s" % (hurtValue))
+    else:
+        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 4))
+        GameWorld.DebugLog("    其他伤害=%s" % (hurtValue))
+        
+    hurtValue = max(1, int(hurtValue)) # 负值、保底防范
+    
+    return hurtValue, hurtTypes
+
+def CalcBounceHP(atkObj, defObj, hurtObj, curSkill):
+    '''计算反弹反弹伤害
+    '''
+    if not atkObj.GetCanAttack():
+        return
+    
+    bounceHP = int(hurtObj.GetHurtHP() * random.uniform(0.1, 0.2))
+    
+    if bounceHP <= 0:
+        return
+    
+    remainHP = atkObj.GetHP() - bounceHP # 反弹允许弹到负值,如果最终吸血没有吸到正值则算死亡
+    hurtObj.SetBounceHP(bounceHP)
+    atkObj.SetHP(remainHP)
+    GameWorld.DebugLog("    反弹伤害=%s,remainHP=%s" % (bounceHP, remainHP))
+    
+    TurnAttack.AddTurnObjHurtValue(defObj, atkObj, bounceHP, bounceHP, isBounce=True)
+    return
+
+def CalcSuckBlood(atkObj, defObj, hurtObj, curSkill):
+    '''计算吸血
+    '''
+    
+    suckHP = int(hurtObj.GetHurtHP() * random.uniform(0.1, 0.2))
+    
+    if suckHP <= 0:
+        return
+    
+    curHP = atkObj.GetHP()
+    maxHP = atkObj.GetMaxHP()
+    remainHP = min(curHP + suckHP, maxHP)
+    cureHP = remainHP - curHP # 实际治疗量
+    
+    hurtObj.SetSuckHP(suckHP)
+    atkObj.SetHP(remainHP)
+    GameWorld.DebugLog("    吸血=%s,remainHP=%s/%s" % (suckHP, remainHP, maxHP))
+    
+    # 吸血暂定算治疗
+    TurnAttack.AddTurnObjCureHP(atkObj, atkObj, suckHP, cureHP)
+    return
+
+def CalcCureHP(userObj, tagObj, curSkill, largeNum=False):
+    ''' 计算治疗值
+    '''
+    cureBaseValue = 0     #治疗基础值
+    effIDNum = curSkill.FindEffectID(ChConfig.Def_Skill_Effect_Cure)
+    skillPer = curSkill.GetEffectValue(effIDNum, 0)
+    cureType = curSkill.GetEffectValue(effIDNum, 1)
+    
+    #获得基础治疗值
+    if cureType == ChConfig.Def_Cure_Attack:
+        cureBaseValue = userObj.GetAtk()
+    elif cureType == ChConfig.Def_Cure_MaxHP:
+        cureBaseValue = userObj.GetMaxHP()
+    #elif cureType == ChConfig.Def_Cure_HurtValue:
+    #    cureBaseValue = GameObj.GetLastHurtValue(userObj)
+    elif cureType == ChConfig.Def_Cure_TagMaxHP:
+        cureBaseValue = 0 if not tagObj else tagObj.GetMaxHP()
+        
+    #skillPer += PassiveBuffEffMng.GetPassiveSkillValueByTriggerType(userObj, None, curSkill, ChConfig.TriggerType_AddHP)
+    
+    # 回合制
+    curePer = 0 # 治疗加成
+    cureDefPer = 0 # 敌方的弱化治疗
+    angerOverflow = 0 # 怒气溢出值
+    if SkillCommon.isAngerSkill(curSkill):
+        angerOverflow = max(userObj.GetXP() - IpyGameDataPY.GetFuncCfg("AngerXP", 2), 0)
+        #enemyObj = TurnAttack.GetEnemyObj(userObj)
+        #curePer += GameObj.GetCurePer(userObj)
+        #if enemyObj:
+        #    cureDefPer += GameObj.GetCureDefPer(enemyObj)
+                
+    skillPer /= float(ChConfig.Def_MaxRateValue)
+    curePer /= float(ChConfig.Def_MaxRateValue)
+    cureDefPer /= float(ChConfig.Def_MaxRateValue)
+    
+    baseValue = max(0, cureBaseValue) # 防止基值被弱化为负值,在恢复比例也是负值的情况下负负得正导致可以恢复血量
+    
+    #公式计算治疗值 
+    cureHP = eval(IpyGameDataPY.GetFuncCompileCfg("CureFormula", 1))
+    if not largeNum:
+        cureHP = min(cureHP, ChConfig.Def_UpperLimit_DWord)
+    cureHP = max(1, int(cureHP)) # 保底1点
+    
+    GameWorld.DebugLog("计算治疗值(%s):skillID=%s,cureType=%s,baseValue=%s,skillPer=%s,curePer=%s,cureDefPer=%s,angerOverflow=%s" 
+                       % (cureHP, curSkill.GetSkillID(), cureType, baseValue, skillPer, curePer, cureDefPer, angerOverflow))
+    return cureHP
+
+def Sync_UseSkill(turnFight, curBatObj, useSkill):
+    ## 通知释放技能
+    poolMgr = ObjPool.GetPoolMgr()
+    clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCUseSkill)
+    clientPack.ObjID = curBatObj.GetID()
+    clientPack.PMType = GetPMType(curBatObj, useSkill)
+    clientPack.BattleType = useSkill.GetBatType()
+    clientPack.CurHP = curBatObj.GetHP() % ChConfig.Def_PerPointValue
+    clientPack.CurHPEx = curBatObj.GetHP() / ChConfig.Def_PerPointValue
+    clientPack.SkillID = useSkill.GetSkillID()
+    clientPack.HurtList = []
+    for hurtObj in useSkill.GetHurtObjList():
+        hurt = poolMgr.acquire(ChPyNetSendPack.tagSCUseSkillHurt)
+        hurt.ObjID = hurtObj.GetObjID()
+        hurt.AttackTypes = hurtObj.GetHurtTypes()
+        hurt.HurtHP = hurtObj.GetHurtHP() % ChConfig.Def_PerPointValue
+        hurt.HurtHPEx = hurtObj.GetHurtHP() / ChConfig.Def_PerPointValue
+        hurt.CurHP = hurtObj.GetCurHP() % ChConfig.Def_PerPointValue
+        hurt.CurHPEx = hurtObj.GetCurHP() / ChConfig.Def_PerPointValue
+        hurt.SuckHP = min(hurtObj.GetSuckHP(), ChConfig.Def_UpperLimit_DWord)
+        hurt.BounceHP = min(hurtObj.GetBounceHP(), ChConfig.Def_UpperLimit_DWord)
+        clientPack.HurtList.append(hurt)
+    clientPack.HurtCount = len(clientPack.HurtList)
+    turnFight.addBatPack(clientPack)
+    return
+
+def Sync_PropertyRefreshView(turnFight, curBatObj, attrID, value, diffValue, diffType=0, skillID=0, relatedSkillID=0):
+    '''通知对象属性刷新展示B418
+    @param attrID: 通知变化的属性ID
+    @param diffValue: 变化值
+    @param diffType: 变化类型,0-减少;1-增加
+    @param skillID: 使用的技能表ID,即哪个技能的效果
+    @param relatedSkillID: 关联的技能ID,一般是主技能ID,非主技能额外触发的为0
+    '''
+    if attrID not in ChConfig.CDBRefresh_AttrIDDict:
+        return
+    refreshType, isBig = ChConfig.CDBRefresh_AttrIDDict[attrID]
+    poolMgr = ObjPool.GetPoolMgr()
+    clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCObjPropertyRefreshView)
+    clientPack.ObjID = curBatObj.GetID()
+    clientPack.RefreshType = refreshType
+    if isBig:
+        clientPack.Value = value % ShareDefine.Def_PerPointValue
+        clientPack.ValueEx = value / ShareDefine.Def_PerPointValue
+        clientPack.DiffValue = diffValue % ShareDefine.Def_PerPointValue
+        clientPack.DiffValueEx = diffValue / ShareDefine.Def_PerPointValue
+    else:
+        clientPack.Value = value
+        clientPack.ValueEx = 0
+        clientPack.DiffValue = diffValue
+        clientPack.DiffValueEx = 0
+    clientPack.DiffType = diffType
+    clientPack.SkillID = skillID
+    clientPack.RelatedSkillID = relatedSkillID
+    turnFight.addBatPack(clientPack)
+    return

--
Gitblit v1.8.0