From a075f7841fb2d0a3b32bf10c8bc2df5bf02d6acb Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期日, 14 十二月 2025 14:24:28 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(贾诩所有技能;5022效果支持配置buff额外属性计算方式;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py |  591 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 470 insertions(+), 121 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
index e49c8f3..f2a0f36 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -23,7 +23,6 @@
 import ChNetSendPack
 import ShareDefine
 import ChConfig
-import ObjPool
 import TurnPassive
 import TurnBuff
 
@@ -32,18 +31,75 @@
     
     def __init__(self, batObj):
         self._batObj = batObj
-        # 被影响的技能ID: 0为所有技能
+        self._objID = batObj.GetID() if batObj else 0
+        
+        # 技能
         self._AffectSkillDict = {} # 被动技能 {(触发方式, 有效来源):{技能ID:[effID, ...], ...}, ...}
+        self._affectSkillEnhanceDict = {} # 未学习的额外子技能被动效果 {skillID:{(触发方式, 有效来源):[effID, ...], ...}, ...}
+        self._skillTriggerWayList = [] # 技能有的触发方式 [触发方式, ...] ,优化效率用,减少多余逻辑
+        
+        # buff
         self._AffectBuffDict = {} # 被动buff {(触发方式, 有效来源):{buffID:[effID, ...], ...}, ...}
+        self._buffSkillIDDict = {} # {buffID:skillID, ...}
+        self._buffTriggerWayList = [] # buff有的触发方式 [触发方式, ...] ,优化效率用,减少多余逻辑
         return
     
-    def GetPassiveEffByTrigger(self, triggerWay, connSkillTypeID=0):
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        self._batObj = None
+        return
+    
+    def GetPassiveEffByTrigger(self, triggerWay, connSkill=None, connSkillTypeID=0, connBuff=None):
         '''获取可触发的效果列表,技能跟buff根据触发优先级按顺序触发,优先级越高越先执行,相同时技能优先
                         优先级之后有需要再扩展
-        @return: [["skill/buff", skillID/buffID, effIDList], ...]
+        @return: [["skill/buff", skillID, buffID, effIDList], ...]
         '''
         effList = []
         
+        # 额外子技能的一般是未学习的技能,直接加载自身的被动效果
+        if connSkill and not isinstance(connSkill, IpyGameDataPY.IPY_Skill) and self._objID == connSkill.GetObjID() \
+            and connSkill.GetBatType() == ChConfig.TurnBattleType_Enhance:
+            skillID = connSkill.GetSkillID()
+            if skillID not in self._affectSkillEnhanceDict:
+                effDict = {}
+                for index in xrange(connSkill.GetEffectCount()):
+                    effect = connSkill.GetEffect(index)
+                    effectID = effect.GetEffectID()
+                    if effectID == 0:
+                        continue
+                    tWay = effect.GetTriggerWay()
+                    tSrc = effect.GetTriggerSrc()
+                    if not tWay:
+                        continue
+                    if tWay in ChConfig.TriggerWayNoLoadList:
+                        continue
+                    if tSrc != ChConfig.TriggerSrc_SkillSelf:
+                        # 非对象身上已学的技能时,仅添加本技能有效的
+                        continue
+                    if tWay == ChConfig.TriggerWay_CalcEffValue:
+                        tWay = "%s_%s" % (tWay, effectID)
+                        
+                    key = (tWay, tSrc)
+                    if key not in effDict:
+                        effDict[key] = {}
+                    effList = effDict[key]
+                    if effectID not in effList:
+                        effList.append(effList)
+                self._affectSkillEnhanceDict[skillID] = effDict
+                
+            effDict = self._affectSkillEnhanceDict[skillID]
+            if triggerWay in effDict:
+                effList.append(["skill", skillID, 0, effDict[triggerWay]])
+                
+        if triggerWay not in self._skillTriggerWayList and triggerWay not in self._buffTriggerWayList:
+            return effList
+        
+        if not connSkillTypeID:
+            if connSkill:
+                connSkillTypeID = connSkill.GetSkillTypeID()
+            elif connBuff:
+                connSkillTypeID = connBuff.GetSkillTypeID()
+                
         # 优先取关联技能的
         if connSkillTypeID and connSkillTypeID not in [ChConfig.TriggerSrc_Skill, ChConfig.TriggerSrc_Buff, ChConfig.TriggerSrc_SkillSelf, ChConfig.TriggerSrc_BuffSelf]:
             # 技能
@@ -51,31 +107,36 @@
             if key in self._AffectSkillDict:
                 effDict = self._AffectSkillDict[key]
                 for skillID, effIDList in effDict.items():
-                    effList.append(["skill", skillID, effIDList])
+                    effList.append(["skill", skillID, 0, effIDList])
                     
             # buff
             key = (triggerWay, connSkillTypeID)
             if key in self._AffectBuffDict:
                 effDict = self._AffectBuffDict[key]
                 for buffID, effIDList in effDict.items():
-                    effList.append(["buff", buffID, effIDList])
+                    skillID = self._buffSkillIDDict[buffID] if buffID in self._buffSkillIDDict else 0
+                    effList.append(["buff", skillID, buffID, effIDList])
                     
         # 所有技能有效的
         key = (triggerWay, ChConfig.TriggerSrc_Skill)
-        effDict = self._AffectSkillDict.get(key, {})
-        for skillID, effIDList in effDict.items():
-            effList.append(["skill", skillID, effIDList])
+        if key in self._AffectSkillDict:
+            effDict = self._AffectSkillDict[key]
+            for skillID, effIDList in effDict.items():
+                effList.append(["skill", skillID, 0, effIDList])
             
         # 所有buff有效的
         key = (triggerWay, ChConfig.TriggerSrc_Buff)
-        effDict = self._AffectBuffDict.get(key, {})
-        for buffID, effIDList in effDict.items():
-            effList.append(["buff", buffID, effIDList])
+        if key in self._AffectBuffDict:
+            effDict = self._AffectBuffDict[key]
+            for buffID, effIDList in effDict.items():
+                skillID = self._buffSkillIDDict[buffID] if buffID in self._buffSkillIDDict else 0
+                effList.append(["buff", skillID, buffID, effIDList])
             
         return effList
     
     def RefreshSkillPassiveEffect(self):
         self._AffectSkillDict = {}
+        self._skillTriggerWayList = []
         
         skillManager = self._batObj.GetSkillManager()
         for index in range(0, skillManager.GetSkillCount()):
@@ -97,9 +158,9 @@
         triggerSrc = effect.GetTriggerSrc()
         if not triggerWay:
             return
-        if triggerWay == ChConfig.TriggerWay_CurSkillEff:
+        if triggerWay in ChConfig.TriggerWayNoLoadList:
             return
-        if triggerSrc in [ChConfig.TriggerSrc_Buff, ChConfig.TriggerSrc_BuffSelf]:
+        if effect.GetTriggerBuffEnable():
             # buff有效的不加进来
             return
         
@@ -119,10 +180,14 @@
         if skillID not in effDict:
             effDict[skillID] = []
         effDict[skillID].append(effectID)
+        if triggerWay not in self._skillTriggerWayList:
+            self._skillTriggerWayList.append(triggerWay)
         return
         
     def RefreshBuffPassiveEffect(self):
         self._AffectBuffDict = {}
+        self._buffTriggerWayList = []
+        
         buffMgr = self._batObj.GetBuffManager()
         for index in range(buffMgr.GetBuffCount()):
             buff = buffMgr.GetBuffByIndex(index)
@@ -147,10 +212,10 @@
         triggerSrc = effect.GetTriggerSrc()
         if not triggerWay:
             return
-        if triggerWay == ChConfig.TriggerWay_CurSkillEff:
+        if triggerWay in ChConfig.TriggerWayNoLoadList:
             return
-        if triggerSrc in [ChConfig.TriggerSrc_Skill, ChConfig.TriggerSrc_SkillSelf]:
-            # 技能有效的不加进来
+        if not effect.GetTriggerBuffEnable():
+            # 非buff有效的不加进来
             return
         
         buffID = buff.GetBuffID()
@@ -171,6 +236,9 @@
         effIDList = effDict[buffID]
         if effectID not in effIDList:
             effIDList.append(effectID)
+        self._buffSkillIDDict[buffID] = skillData.GetSkillID()
+        if triggerWay not in self._buffTriggerWayList:
+            self._buffTriggerWayList.append(triggerWay)
         return
     
     def DelBuffPassiveEffect(self, buffID):
@@ -178,9 +246,19 @@
         for key, effDict in self._AffectBuffDict.items():
             if buffID not in effDict:
                 continue
+            self._buffSkillIDDict.pop(buffID, 0)
             effDict.pop(buffID)
             if not effDict:
                 self._AffectBuffDict.pop(key)
+                # 检查移除存在的触发方式
+                triggerWay = key[0]
+                hasTrigger = False
+                for k in self._AffectBuffDict.keys():
+                    if triggerWay == k[0]:
+                        hasTrigger = True
+                        break
+                if not hasTrigger and triggerWay in self._buffTriggerWayList:
+                    self._buffTriggerWayList.remove(triggerWay)
         return
     
 class HurtObj():
@@ -190,15 +268,19 @@
         self.Clear()
         return
     
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        return
+    
     def Clear(self):
         self._objID = 0
         self._hurtTypes = 0 # 本次伤血类型,如闪避、暴击、格挡等,通过二进制或运算得到最终值,支持多种同时出现,如暴击的同时被格挡
         self._hurtHP = 0 # 公式最终计算的伤害值,一般用于飘血
-        self._realHurtHP = 0 # 真实伤血值,被承伤盾抵扣后的可伤血的值
         self._lostHP = 0 # 实际掉血值
         self._curHP = 0 # 更新血量
         self._suckHP = 0 # 吸血量
         self._bounceHP = 0 # 反弹血量
+        self._hurtListEx = [] # 额外伤血列表,一般后端单技能执行多次伤害逻辑时有用,如弹射的平摊伤害 [HurtObj, ...]
         return
     
     def GetObjID(self): return self._objID
@@ -208,14 +290,12 @@
     def AddHurtType(self, hurtType):
         ## 添加伤血类型,单次伤害支持多种类型同时出现
         self._hurtTypes |= pow(2, hurtType)
-        return
+        return self._hurtTypes
     def HaveHurtType(self, hurtType):
         ## 判断是否存在某种伤血类型
         return self._hurtTypes & pow(2, hurtType) 
     def GetHurtHP(self): return self._hurtHP
     def SetHurtHP(self, hurtHP): self._hurtHP = hurtHP
-    def GetRealHurtHP(self): return self._realHurtHP
-    def SetRealHurtHP(self, realHurtHP): self._realHurtHP = realHurtHP
     def GetLostHP(self): return self._lostHP
     def SetLostHP(self, lostHP): self._lostHP = lostHP
     def GetCurHP(self): return self._curHP
@@ -224,15 +304,29 @@
     def SetSuckHP(self, suckHP): self._suckHP = suckHP
     def GetBounceHP(self): return self._bounceHP
     def SetBounceHP(self, bounceHP): self._bounceHP = bounceHP
+    def ClearHurtObjEx(self):
+        self._hurtListEx = []
+        return
+    def AddHurtObjEx(self, tagID):
+        hurtObj = HurtObj()
+        hurtObj.SetObjID(tagID)
+        self._hurtListEx.append(hurtObj)
+        return hurtObj
+    def GetHurtObjListEx(self): return self._hurtListEx # 某个伤害的额外伤害列表
     
 class SkillEffect():
     
-    def __init__(self, effID, values, triggerWay=0, triggerSrc=0):
+    def __init__(self, effID, values, triggerWay=0, triggerSrcs=[]):
+        # @param triggerSrcs: 触发参数 [触发来源, buff时是否有效默认无效]
         self._effID = effID
         self._values = values
         self._triggerWay = triggerWay
-        self._triggerSrc = triggerSrc
-        #self._triggerParams = triggerParams if triggerParams else []
+        self._triggerSrc = triggerSrcs[0] if len(triggerSrcs) > 0 else 0
+        self._triggerBuffEnable = triggerSrcs[1] if len(triggerSrcs) > 1 else 0
+        return
+    
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
         return
     
     def GetEffectID(self): return self._effID
@@ -241,14 +335,19 @@
     def GetEffectValues(self): return self._values # 直接返回整个效果values
     def GetTriggerWay(self): return self._triggerWay
     def GetTriggerSrc(self): return self._triggerSrc
-    #def GetTriggerParams(self, index): return self._triggerParams[index] if len(self._triggerParams) > index else 0
+    def GetTriggerBuffEnable(self):
+        if self.GetTriggerSrc() in [ChConfig.TriggerSrc_Buff, ChConfig.TriggerSrc_BuffSelf]:
+            return True
+        if self._triggerBuffEnable:
+            return True
+        return False
     
-EmptyEffect = SkillEffect(0, [])
-
 class SklllData():
     
     def __init__(self, ipyData):
         self._ipyData = ipyData
+        self._skillID = self._ipyData.GetSkillID()
+        self._skillTypeID = self._ipyData.GetSkillTypeID()
         self._effList = [] # [Effect, ...]
         self._effDict = {} # {(effID, triggerWay):Effect, ...} ,确保唯一,同个技能可能配置相同的效果ID
         for num in range(1, 1 + 3):
@@ -256,15 +355,20 @@
             values = getattr(ipyData, "GetEffectValues%s" % num)()
             triggerWay = getattr(ipyData, "GetTriggerWay%s" % num)()
             triggerSrc = getattr(ipyData, "GetTriggerSrc%s" % num)()
-            #triggerParams = getattr(ipyData, "GetTriggerParams%s" % num)()
-            effect = ObjPool.GetPoolMgr().acquire(SkillEffect, effID, values, triggerWay, triggerSrc)
+            effect = SkillEffect(effID, values, triggerWay, triggerSrc)
             self._effList.append(effect)
             self._effDict[(effID, triggerWay)] = effect
         return
     
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        return
+    
+    def GetObjID(self): return 0 # 减少判断 hasattr 用
+    def GetBatType(self): return -1 # 减少判断 hasattr 用
     def GetIpyData(self): return self._ipyData
-    def GetSkillID(self): return self._ipyData.GetSkillID()
-    def GetSkillTypeID(self): return self._ipyData.GetSkillTypeID()
+    def GetSkillID(self): return self._skillID
+    def GetSkillTypeID(self): return  self._skillTypeID
     def GetSkillLV(self): return self._ipyData.GetSkillLV()
     def GetSkillMaxLV(self): return self._ipyData.GetSkillMaxLV()
     def GetSkillName(self): return self._ipyData.GetSkillName()
@@ -280,46 +384,69 @@
     def GetCalcType(self): return self._ipyData.GetCalcType()
     def GetSkillPer(self): return self._ipyData.GetSkillPer()
     def GetSkillValue(self): return self._ipyData.GetSkillValue()
+    def GetHurtAtkPerMax(self): return self._ipyData.GetHurtAtkPerMax()
     def GetHappenRate(self): return self._ipyData.GetHappenRate() # 触发概率
-    def GetEffect(self, index): return self._effList[index] if len(self._effList) > index else 0
+    def GetEffect(self, index): return self._effList[index]# if len(self._effList) > index else 0
     def GetEffectCount(self): return len(self._effList)
-    def GetEffectByID(self, effID, triggerWay=0): return self._effDict.get((effID, triggerWay), EmptyEffect)
+    def GetEffectByID(self, effID, triggerWay=0):
+        if (effID, triggerWay) in self._effDict:
+            return self._effDict[(effID, triggerWay)]
     def GetConnSkill(self): return self._ipyData.GetConnSkill()
+    def GetCoolDownInit(self): return self._ipyData.GetCoolDownInit()
     def GetCoolDownTime(self): return self._ipyData.GetCoolDownTime()
-    def GetIgnoreStates(self): return self._ipyData.GetIgnoreStates() # 无视限制列表
+    def GetBuffStateLimit(self): return self._ipyData.GetBuffStateLimit()
     def GetCurBuffState(self): return self._ipyData.GetCurBuffState()
     def GetLastTime(self): return self._ipyData.GetLastTime() # 持续时间
+    def GetLastTimeType(self): return self._ipyData.GetLastTimeType() # 持续时间规则
     def GetLayerCnt(self): return self._ipyData.GetLayerCnt()
     def GetLayerMax(self): return self._ipyData.GetLayerMax()
     def GetBuffRepeat(self): return self._ipyData.GetBuffRepeat() # Buff叠加规则
-    def GetDieContinue(self): return self._ipyData.GetDieContinue() # Buff死亡存在
+    def GetDispersedLimit(self): return self._ipyData.GetDispersedLimit() or self._ipyData.GetSkillType() == ChConfig.Def_SkillType_Halo # 驱散限制
+    def GetBuffRetain(self): return self._ipyData.GetBuffRetain()
     def GetFightPower(self): return self._ipyData.GetFightPower()
-    def GetSkillMotionName(self): return self._ipyData.GetSkillMotionName()
     
 class PyBuff():
     
     def __init__(self, ipyData):
-        self._skillData = ObjPool.GetPoolMgr().acquire(SklllData, ipyData)
+        self._skillData = SklllData(ipyData)
+        self._skillID = self._skillData.GetSkillID()
+        self._skillTypeID = self._skillData.GetSkillTypeID()
+        self._addTiming = 0 # 添加该buff时间点,0-自身回合前;1-自身回合后
+        self._refreshState = 0 # 添加buff后是否刷新过剩余回合,未刷新过的需要先设置为已刷新,防止添加后马上被扣除1回合的时长
         self._buffID = 0
         self._ownerID = 0
         self._layer = 0
-        self._calcTime = 0
         self._remainTime = 0
         self._value1 = 0 # 值需要通知前端,开发时注意20亿问题
         self._value2 = 0
         self._value3 = 0
+        self._isCopy = 0 # 是否复制的buff
+        self._effExDict = {} # 效果ID额外数值 {(effID, calcType):value, ...} # 计算方式取决于本buff技能中属性效果ID的配置
+        self._haloObjIDList = [] # 光环有效目标ID列表 [objID, ...],ownerID为自己时即为光源,包含光源
+        return
+    
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
         return
     
     def GetSkillData(self): return self._skillData
-    def GetSkillID(self): return self._skillData.GetSkillID()
+    def GetSkillID(self): return self._skillID
+    def GetSkillTypeID(self): return self._skillTypeID
+    def GetCurBuffState(self): return self._skillData.GetCurBuffState()
+    def GetDispersedLimit(self): return self._skillData.GetDispersedLimit()
+    def GetBuffRetain(self): return self._skillData.GetBuffRetain()
+    def GetAddTiming(self): return self._addTiming
+    def SetAddTiming(self, addTiming):
+        self._addTiming = addTiming
+        self._refreshState = 0 # 更新添加时机时需标记为未刷新
+    def GetRefreshState(self): return self._refreshState
+    def SetRefreshState(self, refreshState): self._refreshState = refreshState
     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 GetCalcTime(self): return self._calcTime
-    def SetCalcTime(self, calcTime): self._calcTime = calcTime
     def GetRemainTime(self): return self._remainTime
     def SetRemainTime(self, remainTime): self._remainTime = remainTime
     def SetBuffValueList(self, valueList):
@@ -336,6 +463,16 @@
     def SetValue2(self, value): self._value2 = value
     def GetValue3(self): return self._value3
     def SetValue3(self, value): self._value3 = value
+    def GetIsCopy(self): return self._isCopy
+    def SetIsCopy(self, isCopy): self._isCopy = isCopy
+    def ResetEffectValueEx(self): self._effExDict = {}
+    def AddEffectValueEx(self, effID, valueEx, calcType=1): self._effExDict[(effID, calcType)] = self._effExDict.get((effID, calcType), 0) + valueEx
+    def GetEffectExDict(self): return self._effExDict
+    def GetHaloObjIDList(self): return self._haloObjIDList
+    def SetHaloObjIDList(self, haloObjIDList): self._haloObjIDList = haloObjIDList
+    def AddHaloObjID(self, objID):
+        if objID not in self._haloObjIDList:
+            self._haloObjIDList.append(objID)
     
 class BuffManager():
     ## 战斗对象buff管理器
@@ -350,10 +487,12 @@
         # 该项目设定同一个对象可能同时存在多个相同skillID的buff,独立算CD
         return
     
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        self._batObj = None
+        return
+    
     def ClearBuff(self):
-        poolMgr = ObjPool.GetPoolMgr()
-        for buff in self._buffList:
-            poolMgr.release(buff)
         self._buffList = []
         self._buffIDDict = {}
         self._skillTypeIDBuffIDs = {}
@@ -373,12 +512,12 @@
         self._buffID += 1
         
         buffID = self._buffID
-        buff = ObjPool.GetPoolMgr().acquire(PyBuff, ipyData)
+        buff = PyBuff(ipyData)
         buff.SetBuffID(buffID)
         
         self._buffList.append(buff)
         self._buffIDDict[buffID] = buff
-        #GameWorld.DebugLog("ObjBuff:%s, AddBuff buffID=%s, %s, %s, %s, %s, %s" % (self._batObj.GetID(), buffID, buff, len(self._buffList), len(self._buffIDDict), self._buffList, self._buffIDDict))
+        #GameWorld.DebugLogEx("ObjBuff:%s, AddBuff buffID=%s, %s, %s, %s, %s, %s", self._batObj.GetID(), buffID, buff, len(self._buffList), len(self._buffIDDict), self._buffList, self._buffIDDict)
         if skillTypeID not in self._skillTypeIDBuffIDs:
             self._skillTypeIDBuffIDs[skillTypeID] = []
         buffIDs = self._skillTypeIDBuffIDs[skillTypeID]
@@ -389,9 +528,9 @@
     
     def DelBuff(self, buffID, release=True):
         if buffID not in self._buffIDDict:
-            #GameWorld.DebugLog("ObjBuff:%s, DelBuff not in self._buffIDDict, buffID=%s, %s" % (self._batObj.GetID(), buffID, self._buffIDDict.keys()))
+            #GameWorld.DebugLogEx("ObjBuff:%s, DelBuff not in self._buffIDDict, buffID=%s, %s", self._batObj.GetID(), buffID, self._buffIDDict.keys())
             return
-        #GameWorld.DebugLog("ObjBuff:%s, DelBuff %s, buffID=%s, dict:%s, len:%s, list:%s" % (self._batObj.GetID(), release, buffID, self._buffIDDict, len(self._buffList), self._buffList))
+        #GameWorld.DebugLogEx("ObjBuff:%s, DelBuff %s, buffID=%s, dict:%s, len:%s, list:%s", self._batObj.GetID(), release, buffID, self._buffIDDict, len(self._buffList), self._buffList)
         buff = self._buffIDDict.pop(buffID)
         if buff in self._buffList:
             self._buffList.remove(buff)
@@ -401,7 +540,7 @@
                 if lBuff.GetBuffID() == buffID:
                     self._buffList.remove(lBuff)
                     GameWorld.ErrLog("删除buff异常不在列表里! buffID=%s,lBuff=%s,buff=%s" % (buffID, lBuff, buff))
-        #GameWorld.DebugLog("    ObjBuff:%s, buffID=%s, dict:%s, len:%s, dictKeys:%s, list:%s" % (self._batObj.GetID(), buffID, len(self._buffIDDict), len(self._buffList), self._buffIDDict.keys(), self._buffList))
+        #GameWorld.DebugLogEx("    ObjBuff:%s, buffID=%s, dict:%s, len:%s, dictKeys:%s, list:%s", self._batObj.GetID(), buffID, len(self._buffIDDict), len(self._buffList), self._buffIDDict.keys(), self._buffList)
         for skillTypeID, buffIDList in self._skillTypeIDBuffIDs.items():
             if buffID not in buffIDList:
                 continue
@@ -409,11 +548,11 @@
             if not buffIDList:
                 self._skillTypeIDBuffIDs.pop(skillTypeID)
             break
-        if release:
-            ObjPool.GetPoolMgr().release(buff)
         return
     
-    def GetBuff(self, buffID): return self._buffIDDict.get(buffID, None)
+    def GetBuff(self, buffID):
+        if buffID in self._buffIDDict:
+            return self._buffIDDict[buffID]
     def FindBuffListBySkillID(self, skillID):
         ## 返回该技能ID的所有buff列表
         skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
@@ -430,13 +569,37 @@
                 continue
             buffs.append(self._buffIDDict[buffID])
         return buffs
+    def FindBuffBySkillID(self, skillID, ownerID=0):
+        ## 查找某个技能ID的buff
+        # @param ownerID: 可指定查找指定来源的buff
+        buffList = self.FindBuffListBySkillID(skillID)
+        if not ownerID:
+            return buffList[0] if buffList else None
+        for buff in buffList:
+            if buff.GetOwnerID() == ownerID:
+                return buff
+        return
     def FindBuffByState(self, state):
         ## 查找某种buff状态的buff
-        buffIDList = self._buffStateDict.get(state, [])
+        if state not in self._buffStateDict:
+            return
+        buffIDList = self._buffStateDict[state]
         if not buffIDList:
             return
         buffID = buffIDList[0]
-        return self._buffIDDict.get(buffID, None)
+        if buffID in self._buffIDDict:
+            return self._buffIDDict[buffID]
+    def FindBuffListByState(self, state):
+        ## 查找某种buff状态的buff列表
+        if state not in self._buffStateDict:
+            return []
+        buffIDList = self._buffStateDict[state]
+        buffs = []
+        for buffID in buffIDList:
+            if buffID not in self._buffIDDict:
+                continue
+            buffs.append(self._buffIDDict[buffID])
+        return buffs
     
     def AddBuffState(self, state, buffID):
         ## 添加buff影响的状态,ChConfig.BatObjStateList
@@ -445,7 +608,7 @@
         buffIDList = self._buffStateDict[state]
         if buffID not in buffIDList:
             buffIDList.append(buffID)
-        GameWorld.DebugLog("    AddBuffState state=%s,buffID=%s,%s" % (state, buffID, self._buffStateDict))
+        GameWorld.DebugLogEx("    AddBuffState state=%s,buffID=%s,%s", state, buffID, self._buffStateDict)
         return
     
     def DelBuffState(self, state, buffID):
@@ -457,35 +620,65 @@
         buffIDList.remove(buffID)
         if not buffIDList:
             self._buffStateDict.pop(state)
-        GameWorld.DebugLog("    DelBuffState state=%s,buffID=%s,%s" % (state, buffID, self._buffStateDict))
+        GameWorld.DebugLogEx("    DelBuffState state=%s,buffID=%s,%s", state, buffID, self._buffStateDict)
         return
     
     def IsInBuffState(self, state): return state in self._buffStateDict ## 是否处于某种状态下
-    def GetStateBuffIDList(self, state): return self._buffStateDict.get(state, []) # 获取某种状态的所有buffID列表
+    def GetStateBuffIDList(self, state): # 获取某种状态的所有buffID列表
+        if state in self._buffStateDict:
+            return self._buffStateDict[state]
+        return []
     
 class PySkill():
     
-    def __init__(self, ipyData):
-        self._skillData = ObjPool.GetPoolMgr().acquire(SklllData, ipyData)
-        self._calcTime = 0
+    def __init__(self, ipyData, objID):
+        self._objID = objID # 该技能谁的
+        self._skillData = SklllData(ipyData)
+        self._skillID = self._skillData.GetSkillID()
+        self._skillTypeID = self._skillData.GetSkillTypeID()
         self._remainTime = 0
         self._batType = 0 # 战斗类型,普通、连击、反击、追击等
-        self._tagObjList = [] # 本次技能目标列表 [BatObj, ...]
-        self._hurtList = [] # 本次伤血列表,可能同一个对象有多个伤害,如弹射等 [HurtObj, ...]
+        self._tagObjList = [] # 本次技能主要目标列表 [BatObj, ...]
+        self._tagObjListEx = [] # 本次技能额外目标列表,平摊伤害、溅射等 [BatObj, ...]
+        self._killObjList = [] # 本次技能击杀目标列表 [BatObj, ...]
+        self._effIgnoreObjIDList = [] # 额外技能效果无效的目标ID列表,一般是被闪避、免疫等
+        self._hurtList = [] # 主要伤血列表,可能同一个对象有多个伤害,如弹射等 [HurtObj, ...]
+        self._hurtListEx = [] # 额外伤血列表,如平摊、溅射 [HurtObj, ...]
         self._bySkill = None # 由哪个技能触发的
+        self._byBuff = None # 由哪个buff触发的
         self._afterLogicList = [] # 技能释放后需要处理逻辑 [[logicType, logicParams], ...]
+        self._energy = 0 # 技能能量,一般用于累计能量达到某种条件后做逻辑
+        
+        # 连击相关
+        self._comboState = 0 # 连击状态 0-未重置,1-初始化连击相关可连击,2-连击已中断
+        self._comboNum = 0 # 连击次数
+        self._missTagIDDict = {} # 单次连续连击中对方已闪避次数 {tagID:missNum, ...}
+        self._parryTagIDDict = {} # 单次连续连击中对方已格挡次数 {tagID:parryNum, ...}
+        return
+    
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        self.ResetUseRec()
         return
     
     def ResetUseRec(self):
+        ## 重置技能使用记录
+        ## 注:有用到对象池相关对象的一定要重置,不然再回收技能对象时会连同该技能下的所有用到的对象池对象一并回收,导致后续使用对象错误
         self._batType = 0
         self._tagObjList = []
+        self._tagObjListEx = []
+        self._killObjList = []
+        self._effIgnoreObjIDList = []
         self._bySkill = None
+        self._byBuff = None
         self._afterLogicList = []
         self.ClearHurtObj()
         return
     
-    def GetSkillID(self): return self._skillData.GetSkillID()
-    def GetSkillTypeID(self): return self._skillData.GetSkillTypeID()
+    def GetObjID(self): return self._objID
+    def GetSkillData(self): return self._skillData
+    def GetSkillID(self): return self._skillID
+    def GetSkillTypeID(self): return self._skillTypeID
     def GetSkillLV(self): return self._skillData.GetSkillLV()
     def GetSkillMaxLV(self): return self._skillData.GetSkillMaxLV()
     def GetSkillName(self): return self._skillData.GetSkillName()
@@ -501,33 +694,44 @@
     def GetCalcType(self): return self._skillData.GetCalcType()
     def GetSkillPer(self): return self._skillData.GetSkillPer()
     def GetSkillValue(self): return self._skillData.GetSkillValue()
+    def GetHurtAtkPerMax(self): return self._skillData.GetHurtAtkPerMax()
     def GetHappenRate(self): return self._skillData.GetHappenRate() # 触发概率
     def GetEffect(self, index): return self._skillData.GetEffect(index)
     def GetEffectCount(self): return self._skillData.GetEffectCount()
     def GetEffectByID(self, effID, triggerWay=0): return self._skillData.GetEffectByID(effID, triggerWay)
     def GetConnSkill(self): return self._skillData.GetConnSkill()
+    def GetCoolDownInit(self): return self._skillData.GetCoolDownInit()
     def GetCoolDownTime(self): return self._skillData.GetCoolDownTime()
-    def GetIgnoreStates(self): return self._skillData.GetIgnoreStates() # 无视限制列表
+    def GetBuffStateLimit(self): return self._skillData.GetBuffStateLimit()
     def GetCurBuffState(self): return self._skillData.GetCurBuffState()
     def GetLastTime(self): return self._skillData.GetLastTime() # 持续时间
+    def GetLastTimeType(self): return self._skillData.GetLastTimeType() # 持续时间规则
     def GetLayerCnt(self): return self._skillData.GetLayerCnt()
     def GetLayerMax(self): return self._skillData.GetLayerMax()
     def GetBuffRepeat(self): return self._skillData.GetBuffRepeat() # Buff叠加规则
-    def GetDieContinue(self): return self._skillData.GetDieContinue() # Buff死亡存在
+    def GetDispersedLimit(self): return self._skillData.GetDispersedLimit() # 驱散限制
+    def GetBuffRetain(self): return self._ipyData.GetBuffRetain()
     def GetFightPower(self): return self._skillData.GetFightPower()
-    def GetSkillMotionName(self): return self._skillData.GetSkillMotionName()
     
     ## ---------------------------------- 非技能表内容 ----------------------------------
-    def GetCalcTime(self): return self._calcTime
-    def SetCalcTime(self, calcTime): self._calcTime = calcTime
     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 GetBySkill(self): return self._bySkill
     def SetBySkill(self, bySkill): self._bySkill = bySkill
-    def GetTagObjList(self): return self._tagObjList # 技能目标列表
+    def GetByBuff(self): return self._byBuff
+    def SetByBuff(self, byBuff): self._byBuff = byBuff
+    def GetTagObjList(self): return self._tagObjList # 技能主要目标列表
     def SetTagObjList(self, tagObjList): self._tagObjList = tagObjList
+    def GetTagObjListEx(self): return self._tagObjListEx # 技能额外目标列表
+    def AddTagObjEx(self, tagObj):
+        if tagObj not in self._tagObjList and tagObj not in self._tagObjListEx:
+            self._tagObjListEx.append(tagObj)
+    def GetKillObjList(self): return self._killObjList # 击杀目标列表
+    def SetKillObjList(self, killObjList): self._killObjList = killObjList
+    def GetEffIgnoreObjIDList(self): return self._effIgnoreObjIDList # 额外技能效果无效的目标ID列表
+    def SetEffIgnoreObjIDList(self, effIgnoreObjIDList): self._effIgnoreObjIDList = effIgnoreObjIDList
     def GetAfterLogicList(self): return self._afterLogicList
     def AddAfterLogic(self, logicType, logicData):
         '''添加技能释放后需要处理额外逻辑
@@ -538,39 +742,89 @@
         return
     def ClearHurtObj(self):
         ## 清空伤血统计
-        poolMgr = ObjPool.GetPoolMgr()
         for hurtObj in self._hurtList:
-            poolMgr.release(hurtObj)
+            hurtObj.ClearHurtObjEx()
         self._hurtList = []
+        
+        for hurtObjEx in self._hurtListEx:
+            hurtObjEx.ClearHurtObjEx()
+        self._hurtListEx = []
         return
-    def AddHurtObj(self, tagID):
+    def AddHurtObj(self, tagID, isEx=False):
         ## 添加某个伤血
-        hurtObj = ObjPool.GetPoolMgr().acquire(HurtObj)
+        # @param isEx: 是否额外伤血
+        hurtObj = HurtObj()
         hurtObj.SetObjID(tagID)
-        self._hurtList.append(hurtObj)
+        if isEx:
+            self._hurtListEx.append(hurtObj)
+        else:
+            self._hurtList.append(hurtObj)
         return hurtObj
-    def GetHurtObjList(self): return self._hurtList
+    def GetHurtObjList(self): return self._hurtList # 技能主要伤血列表
+    def GetHurtObjListEx(self): return self._hurtListEx # 技能额外伤血列表
+    def GetHurtObjListAll(self): return self._hurtList + self._hurtListEx # 技能所有伤血列表
+    
+    def __commboClear(self):
+        ## 连击相关清空
+        self._comboState = 0
+        self._comboNum = 0
+        self._missTagIDDict = {}
+        self._parryTagIDDict = {}
+        return
+    
+    def ComboCheckStart(self, force=False):
+        ## 检查并设置开始连击相关,一般是开始使用技能时调用
+        if not force:
+            if self._comboState == 1:
+                #GameWorld.DebugLogEx("连击进行中,不重置")
+                return
+        self.__commboClear()
+        self._comboState = 1 # 设置已初始化连击相关
+        #GameWorld.DebugLogEx("连击重置")
+        return
+    
+    def ComboEnable(self): return self._comboState == 1 ## 可否执行连击相关
+    
+    def ComboInterrupt(self):
+        ## 连击中断,概率不再触发连击时需要设置中断
+        self._comboState = 2
+        return
+    
+    def GetComboNum(self): return self._comboNum # 已连击次数
+    def SetComboNum(self, comboNum): self._comboNum = comboNum
+    def GetTagMissNum(self, tagID): return self._missTagIDDict.get(tagID, 0)
+    def SetTagMissNum(self, tagID, missNum): self._missTagIDDict[tagID] = missNum
+    def GetTagParryNum(self, tagID): return self._parryTagIDDict.get(tagID, 0)
+    def SetTagParryNum(self, tagID, parryNum): self._parryTagIDDict[tagID] = parryNum
+    
+    def GetEnergy(self): return self._energy # 累计能量
+    def SetEnergy(self, energy): self._energy = energy
     
 class SkillManager():
     ## 战斗对象技能管理器
     
-    def __init__(self):
+    def __init__(self, batObj):
+        self._batObj = batObj
         self._skillList = [] # 技能列表 [PySkill, ...]
         self._skillDict = {} # {skillID:PySkill, ...}
         return
     
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
+        self._batObj = None
+        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): return self._skillList[index]
-    def GetSkillIDList(self): return self._skillDict.keys()
-    def FindSkillByID(self, skillID): return self._skillDict.get(skillID, None)
+    def GetSkillIDList(self): return sorted(self._skillDict.keys())
+    def FindSkillByID(self, skillID):
+        if skillID in self._skillDict:
+            return self._skillDict[skillID]
     def FindSkillByTypeID(self, skillTypeID):
         skill = None
         for s in self._skillList:
@@ -593,7 +847,7 @@
             self.__deleteSkill(curSkill)
             
         # 学新技能
-        curSkill = ObjPool.GetPoolMgr().acquire(PySkill, ipyData)
+        curSkill = PySkill(ipyData, self._batObj.GetID())
         self._skillDict[skillID] = curSkill
         self._skillList.append(curSkill)
         return curSkill
@@ -603,7 +857,6 @@
         self._skillDict.pop(skillID, None)
         if curSkill in self._skillList:
             self._skillList.remove(curSkill)
-        ObjPool.GetPoolMgr().release(curSkill)
         return
     
 class BatObj():
@@ -621,7 +874,9 @@
         self.atkDistType = 0
         self.specialty = 0 # 特长
         self.sex = 0
+        self.job = 0
         self.lv = 1
+        self._star = 0
         self.fightPower = 0
         self.faction = 0 # 所属阵营,一般只有双方阵营, 1 或 2,发起方默认1
         self.lineupNum = 1 # 阵容位置编号,一般多V多时有用,通常默认1
@@ -630,19 +885,31 @@
         self._xp = 0 # 当前怒气值
         self._isAlive = True # 是否活着
         self._initAttrDict = {} # 初始化时的属性,固定不变,初始化时已经算好的属性  {attrID:value, ...}
-        self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性
-        self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...}
+        self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性 {attrID:+-value, ...} value可能是负值
+        self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...} value可能是负值
         self._kvDict = {} # 自定义kv字典
+        self._bigTurnAtkbackCnt = 0 # 大回合累计反击次数
+        self._incrementValue = 0 # 自增值,每场战斗重置,用于确保唯一的场景,如 Skill tag 标签
+        self._skillHappenFailCntDict = {} # 技能累计概率触发次数,使用成功后重置 {skillID:failCnt, ...}
         self._skillUseCntDict = {} # 技能累计使用次数 {skillID:useCnt, ...}
         self._skillTurnUseCntDict = {} # 技能单回合累计使用次数 {skillID:useCnt, ...}
-        self._skillMgr = ObjPool.GetPoolMgr().acquire(SkillManager)
-        self._buffMgr = ObjPool.GetPoolMgr().acquire(BuffManager, self)
-        self._passiveEffMgr = ObjPool.GetPoolMgr().acquire(PassiveEffManager, self)
+        self._skillMgr = SkillManager(self)
+        self._buffMgr = BuffManager(self)
+        self._passiveEffMgr = PassiveEffManager(self)
+        self._lastHurtValue = 0
+        self._harmSelfHP = 0 # 自残值
+        self._mainTagIDList = [] # 主技能目标ID列表,一般用于技能拆分成多个技能效果时,子技能可能会用到主技能的对象做逻辑
+        self._timing = 0 # 当前武将时间节点: 0-回合前;1-回合后
+        self._angerOverflow = 0 # 怒气技能怒气溢出值,子技能也生效,因为主技能释放后怒气会被扣除,所以这里做个记录
         
         # 统计
         self.hurtStat = 0 # 输出统计
         self.defStat = 0 # 承伤统计
         self.cureStat = 0 # 治疗统计
+        return
+    
+    def onRelease(self):
+        ## 回收前处理,主要处理一些其他不需要释放的对象池对象,防止被连同误回收
         return
     
     def InitBatAttr(self, initAttrDict, initXP=0):
@@ -653,37 +920,55 @@
         self._initAttrDict = initAttrDict
         self._batAttrDict = {}
         self._batAttrDict.update(initAttrDict)
+        self.__onUpdBatAttr()
         self._skillTempAttrDict = {}
-        self._xp = initXP
-        self._hp = initAttrDict.get(ChConfig.AttrID_MaxHP, 1)
-        TurnBuff.RefreshBuffAttr(self)
+        self.SetXP(initXP, False)
+        self.SetHPFull(False)
+        TurnBuff.RefreshBuffAttr(self, isInit=True)
         TurnPassive.RefreshPassive(self)
         return
     
-    def TurnReset(self):
-        ## 回合重置
-        self._skillTurnUseCntDict = {}
-        
-    def UpdInitBatAttr(self, initAttrDict, skillIDList):
+    def UpdInitBatAttr(self, initAttrDict, skillIDList=None):
         ## 更新战斗属性,一般只有主阵容需要更新,战斗中养成、装备变化等引起的主阵容属性变更时需要实时更新
         self._initAttrDict = initAttrDict
         learnNewSkill = False
-        for skillID in skillIDList:
-            if self._skillMgr.LearnSkillByID(skillID):
-                learnNewSkill = True
+        if skillIDList:
+            for skillID in skillIDList:
+                if self._skillMgr.LearnSkillByID(skillID):
+                    learnNewSkill = True
         TurnBuff.RefreshBuffAttr(self)
         if learnNewSkill: # 有学新技能时重刷技能被动
             self._passiveEffMgr.RefreshSkillPassiveEffect()
         return
     
+    def GMSetBatAttr(self, attrID, attrValue):
+        ## GM设置战斗属性
+        self._initAttrDict[attrID] = attrValue # 需要同步设置初始化属性,防止刷属性后被重置
+        if attrID == ChConfig.AttrID_HP:
+            self.SetHP(attrValue, True)
+            if attrValue > self.GetMaxHP():
+                self._initAttrDict[ChConfig.AttrID_MaxHP] = attrValue
+                self.SetMaxHP(attrValue, True)
+        elif attrID == ChConfig.AttrID_XP:
+            self.SetXP(attrValue, True)
+        else:
+            self.SetBatAttrValue(attrID, attrValue)
+        return
+    
     def ResetBattleEffect(self):
+        ## 重置战斗属性,一般刷属性前调用
         self._batAttrDict = {}
         self._batAttrDict.update(self._initAttrDict)
+        self.__onUpdBatAttr()
         return self._batAttrDict
     
     def GetTFGUID(self): return self.tfGUID # 所属的某场战斗
     def SetTFGUID(self, tfGUID): self.tfGUID = tfGUID
     def GetTurnFight(self): return TurnAttack.GetTurnFightMgr().getTurnFight(self.tfGUID)
+    def GetBatLineup(self):
+        turnFight = self.GetTurnFight()
+        batFaction = turnFight.getBatFaction(self.faction)
+        return batFaction.getBatlineup(self.lineupNum)
     def GetOwnerID(self): return self.ownerID # 如果是玩家战斗单位,则该值非0,为所属玩家ID
     def SetOwnerID(self, ownerID): self.ownerID = ownerID
     def GetID(self): return self.objID
@@ -697,6 +982,8 @@
     def SetSpecialty(self, specialty): self.specialty = specialty
     def GetSex(self): return self.sex
     def SetSex(self, sex): self.sex = sex
+    def GetJob(self): return self.job
+    def SetJob(self, job): self.job = job
     def GetNPCID(self): return self.npcID # 如果是NPC战斗单位,则该值非0
     def SetNPCID(self, npcID): self.npcID = npcID # 设置所属的NPCID
     def GetHeroID(self): return self.heroID
@@ -718,6 +1005,8 @@
     def SetFightPower(self, fightPower): self.fightPower = fightPower
     def GetLV(self): return self.lv
     def SetLV(self, lv): self.lv = lv
+    def GetStar(self): return self._star
+    def SetStar(self, star): self._star = star
     def GetDictByKey(self, key): return self._kvDict.get(key, 0)
     def SetDict(self, key, value): self._kvDict[key] = value
     
@@ -744,22 +1033,27 @@
             if self._buffMgr.IsInBuffState(state):
                 return True
         return False
-    def IsInState(self, state):
-        ## 是否处于指定状态下
-        return self._buffMgr.IsInBuffState(state)
     
-    def IsInControlled(self):
-        ## 是否被控制中
-        for state in ChConfig.InControlledStateList:
-            if self.IsInState(state):
-                return True
-        return False
+    def IsInControlled(self): return self.IsInBuffStateGroup([1, 2]) # 是否被控制中
+    def IsInControlledHard(self): return self.IsInBuffStateGroup([1]) # 是否被硬控中
+    def IsInBuffStateGroup(self, buffStateGroups):
+        '''是否在某个状态组中
+                        已定义的组: 1 - 硬控组;2 - 软控组;3 - 限制普攻组;4 - 限制怒技组;5 - 限制被动动态组
+        '''
+        buffStateGroupDict = IpyGameDataPY.GetFuncEvalCfg("BuffStateGroup", 1, {})
+        for stateGroup in buffStateGroups:
+            if str(stateGroup) not in buffStateGroupDict:
+                continue
+            for state in buffStateGroupDict[str(stateGroup)]:
+                if self._buffMgr.IsInBuffState(state):
+                    return state
+        return
     
     def CanAction(self):
         ## 是否可以行动
         if not self.IsAlive():
             return False
-        if self.IsInControlled():
+        if self.IsInControlledHard():
             return False
         return True
     
@@ -783,14 +1077,19 @@
     def SetDead(self):
         self._isAlive = False
         self._hp = 0
-    def GetMaxHP(self): return self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0)
+    def SetRevive(self, hp):
+        self._isAlive = True
+        self._hp = hp
+    def GetMaxHP(self): return int(self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0))
     def SetMaxHP(self, maxHP, isNotify=False):
+        maxHP = int(maxHP)
         self._batAttrDict[ChConfig.AttrID_MaxHP] = maxHP
         if isNotify:
             NotifyObjInfoRefresh(self, ChConfig.AttrID_MaxHP, maxHP)
         return
     def GetHP(self): return self._hp
     def SetHP(self, hp, isNotify=False):
+        hp = int(hp)
         self._hp = hp
         if isNotify:
             NotifyObjInfoRefresh(self, ChConfig.AttrID_HP, hp)
@@ -798,6 +1097,7 @@
     def SetHPFull(self, isNotify=True): self.SetHP(self.GetMaxHP(), isNotify)
     def GetXP(self): return self._xp
     def SetXP(self, xp, isNotify=True):
+        xp = int(xp)
         self._xp = xp
         if isNotify:
             NotifyObjInfoRefresh(self, ChConfig.AttrID_XP, xp)
@@ -805,26 +1105,75 @@
     def GetAtk(self): return self.GetBatAttrValue(ChConfig.AttrID_Atk)
     def GetDef(self): return self.GetBatAttrValue(ChConfig.AttrID_Def)
     
+    def GetBatAttrDict(self): return self._batAttrDict
     def GetBatAttrValue(self, attrID, includeTemp=True):
         #ChConfig.AttrID_HP ChConfig.AttrID_XP
         value = self._batAttrDict.get(attrID, 0)
         if includeTemp and attrID in self._skillTempAttrDict:
             value += self._skillTempAttrDict[attrID] # 支持正负值
-            value = max(1, value)
+            #value = max(1, value)
         return value
-    def SetBatAttrValue(self, attrID, value): self._batAttrDict[attrID] = value
+    def SetBatAttrValue(self, attrID, value):
+        self._batAttrDict[attrID] = value
+        self.__onUpdBatAttr()
+        return
+    def __onUpdBatAttr(self):
+        for attrID in [ChConfig.AttrID_MaxHP]:
+            self._batAttrDict[attrID] = int(self._batAttrDict.get(attrID, 0))
+        return
     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 GetSkillHappenFailCnt(self, skillID): return self._skillHappenFailCntDict.get(skillID, 0) # 技能概率触发失败累计次数
+    def IsSkillCanHappen(self, skillID, happenRate):
+        if happenRate and not GameWorld.CanHappen(happenRate, ChConfig.Def_MaxRateValue):
+            self._skillHappenFailCntDict[skillID] = self._skillHappenFailCntDict.get(skillID, 0) + 1
+            return False
+        self._skillHappenFailCntDict.pop(skillID, 0)
+        return True
+    
+    def GetSkillUseCnt(self, skillID): return self._skillUseCntDict.get(skillID, 0) # 单场战斗累计使用次数
+    def GetSkillTurnUseCnt(self, skillID): return self._skillTurnUseCntDict.get(skillID, 0) # 单回合累计使用次数
+    def ResetSkillUseCnt(self):
+        ## 每场战斗开始时重置
+        self._skillHappenFailCntDict = {}
+        self._skillUseCntDict = {}
+        self._skillTurnUseCntDict = {}
+        self._incrementValue = 0
     def AddSkillUseCnt(self, skillID):
         self._skillUseCntDict[skillID] = self._skillUseCntDict.get(skillID, 0) + 1
         self._skillTurnUseCntDict[skillID] = self._skillTurnUseCntDict.get(skillID, 0) + 1
         
+    def GetBigTurnAtkbackCnt(self): return self._bigTurnAtkbackCnt
+    def AddBigTurnAtkbackCnt(self):  self._bigTurnAtkbackCnt += 1
+    
+    def ResetBigTurn(self):
+        ## 每大回合重置
+        self._bigTurnAtkbackCnt = 0
+        self._skillTurnUseCntDict = {}
+    
+    def GetIncrementValue(self):
+        self._incrementValue += 1
+        return self._incrementValue
+    
+    def GetLastHurtValue(self): return self._lastHurtValue
+    def SetLastHurtValue(self, lastHurtValue): self._lastHurtValue = lastHurtValue
+    
+    def GetHarmSelfHP(self): return self._harmSelfHP
+    def SetHarmSelfHP(self, harmSelfHP): self._harmSelfHP = harmSelfHP
+    
+    def GetAngerOverflow(self): return self._angerOverflow
+    def SetAngerOverflow(self, angerOverflow): self._angerOverflow = angerOverflow
+    
+    def GetMainTagIDList(self): return self._mainTagIDList
+    def SetMainTagIDList(self, mainTagIDList): self._mainTagIDList = mainTagIDList
+    
+    def GetTiming(self): return self._timing # 时间节点 0-回合前;1-回合后
+    def SetTiming(self, timing): self._timing = timing
+    
     def StatHurtValue(self, hurtValue):
         ## 统计输出
         self.hurtStat += hurtValue
@@ -834,6 +1183,7 @@
         ## 统计承伤
         self.defStat += lostHP
         return self.defStat
+    def GetStatDefValue(self): return self.defStat # 获取累计总承伤
     
     def StatCureValue(self, cureValue):
         ## 统计治疗
@@ -871,10 +1221,10 @@
         newObjID = self.__getNewObjID()
         if not newObjID:
             return newBatObj
-        newBatObj = ObjPool.GetPoolMgr().acquire(BatObj)
+        newBatObj = BatObj()
         newBatObj.objID = newObjID
         self.batObjDict[newObjID] = newBatObj
-        GameWorld.DebugLog("添加战斗单位: objID=%s" % (newObjID))
+        GameWorld.DebugLogEx("添加战斗单位: objID=%s", newObjID)
         if False:
             newBatObj = BatObj(None, 0)
         return newBatObj
@@ -894,7 +1244,7 @@
         if not batObj:
             return
         objID = batObj.objID
-        GameWorld.DebugLog("回收战斗单位: objID=%s" % (objID))
+        GameWorld.DebugLogEx("回收战斗单位: objID=%s", objID)
         #前端确认不需要通知消失
         #turnFight = batObj.GetTurnFight()
         #if turnFight:
@@ -905,7 +1255,6 @@
         #    turnFight.addBatPack(clientPack)
         
         # 最后回收对象
-        ObjPool.GetPoolMgr().release(batObj)
         if objID not in self._freeIDList: # 回收ID,重复利用
             self._freeIDList.append(objID)
         return
@@ -918,7 +1267,7 @@
     return batObjMgr
 
 def OnMinute():
-    GameWorld.Log("战斗单位数量: %s" % len(GetBatObjMgr().batObjDict))
+    #GameWorld.Log("战斗单位数量: %s" % len(GetBatObjMgr().batObjDict))
     return
 
 def NotifyObjInfoRefresh(batObj, attrID, value):
@@ -929,7 +1278,7 @@
     turnFight = TurnAttack.GetTurnFightMgr().getTurnFight(batObj.GetTFGUID())
     if not turnFight:
         return
-    clientPack = ObjPool.GetPoolMgr().acquire(ChNetSendPack.tagObjInfoRefresh)
+    clientPack = ChNetSendPack.tagObjInfoRefresh()
     clientPack.ObjID = batObj.GetID()
     clientPack.RefreshType = refreshType
     if isBig:

--
Gitblit v1.8.0