ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -45,7 +45,7 @@
    ## 是否无视防御
    return useSkill.GetHurtType() / 10 == 1 # 2为真伤,待扩展
def OnUseSkill(turnFight, curBatObj, useSkill, tagObjList=None, batType=ChConfig.TurnBattleType_Normal, bySkill=None):
def OnUseSkill(turnFight, curBatObj, useSkill, tagObjList=None, batType=ChConfig.TurnBattleType_Normal, bySkill=None, byBuff=None):
    '''使用技能通用入口
    @param useSkill: 使用的技能,注意并不一定是身上的技能,可能只是 SkillData 表数据
    @param bySkill: 由哪个技能额外触发的,比如附加触发的技能或被动技能均可能由某个技能触发
@@ -59,13 +59,19 @@
    if not skillID:
        return
    
    if not curBatObj.CanAction():
        return
    buffStateLimit = useSkill.GetBuffStateLimit()
    if buffStateLimit:
        limitState = curBatObj.IsInBuffStateGroup(buffStateLimit)
        if limitState:
            GameWorld.DebugLog("技能使用处于buff状态限制中! skillID=%s,buffStateLimit=%s,limitState=%s" % (skillID, buffStateLimit, limitState))
            return
    #没有指定目标,则按技能自身的目标逻辑
    if not tagObjList:
        tagAim = useSkill.GetTagAim()
        tagFriendly = useSkill.GetTagFriendly()
        tagAffect = useSkill.GetTagAffect()
        tagCount = useSkill.GetTagCount()
        tagObjList = GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount)
        tagObjList = GetSkillTags(turnFight, curBatObj, useSkill)
        rate = useSkill.GetHappenRate()
        if rate and rate != ChConfig.Def_MaxRateValue: 
            for tagObj in tagObjList[::-1]:
@@ -76,9 +82,16 @@
        # 可扩展其他目标选择,如复活技能没有死亡单位时则使用另外的效果
        return
    
    objID = curBatObj.GetID()
    oneActionUseCnt = turnFight.GetOneActionUseSkillCnt(objID)
    if oneActionUseCnt >= 20:
        GameWorld.ErrLog("单次行动累计使用技能达到上限! objID=%s,oneActionUseCnt=%s" % (objID, oneActionUseCnt), turnFight.playerID)
        return
    oneActionUseCnt = turnFight.SetOneActionUseSkillCnt(objID, oneActionUseCnt + 1)
    bySkillID = bySkill.GetSkillID() if bySkill else 0
    GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,HP:%s/%s"
                       % (curBatObj.GetID(), skillID, len(tagObjList), batType, bySkillID, curBatObj.GetHP(), curBatObj.GetMaxHP()))
    GameWorld.DebugLog("●使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,HP:%s/%s,oneActionUseCnt=%s"
                       % (objID, skillID, len(tagObjList), batType, bySkillID, curBatObj.GetHP(), curBatObj.GetMaxHP(), oneActionUseCnt))
    # 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
    
    poolMgr = ObjPool.GetPoolMgr()
@@ -86,13 +99,19 @@
    if isinstance(useSkill, IpyGameDataPY.IPY_Skill):
        usePoolSkill = True
        # 统一使用 BattleObj.PySkill
        useSkill = poolMgr.acquire(BattleObj.PySkill, useSkill)
        useSkill = poolMgr.acquire(BattleObj.PySkill, useSkill, objID)
        
    useSkill.ResetUseRec()
    useSkill.SetTagObjList(tagObjList)
    useSkill.SetBatType(batType)
    useSkill.SetBySkill(bySkill)
    useSkill.SetByBuff(byBuff)
    
    isTurnNormalSkill = SkillCommon.isTurnNormalSkill(useSkill)
    if isTurnNormalSkill:
        # 普攻追击时强制重新开始算连击
        useSkill.ComboCheckStart(batType == ChConfig.TurnBattleType_Pursue)
    curBatObj.ClearSkillTempAttr()
    tagIDList = []
    for tagObj in tagObjList:
@@ -103,7 +122,6 @@
    if useSkill.GetFuncType():
        curBatObj.SetMainTagIDList(tagIDList)
        
    objID = curBatObj.GetID()
    useTag = ""
    
    #这个技能是Buff
@@ -132,23 +150,32 @@
        turnFight.addBatPack(clientPack)
        
    # 处理反击 或 连击
    DoCombo(turnFight, curBatObj, useSkill)
    if isTurnNormalSkill:
        if not DoCombo(turnFight, curBatObj, useSkill):
            useSkill.ComboInterrupt()
    # 最后重置、回收对象
    useSkill.ResetUseRec()
    if usePoolSkill:
        poolMgr.release(useSkill)
    return True
def GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount):
def GetSkillTags(turnFight, curBatObj, useSkill):
    ## 获取技能目标
    # @return: [主目标, 目标2, ...]
    tagAim = useSkill.GetTagAim()
    tagFriendly = useSkill.GetTagFriendly()
    tagAffect = useSkill.GetTagAffect()
    tagCount = useSkill.GetTagCount()
    
    curFaction = curBatObj.GetFaction()
    
    # 自己,直接返回
    if tagAim == ChConfig.SkillTagAim_Self:
        return [curBatObj]
    tagCount += TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_AddSkillTagCnt, useSkill)
    
    sneerObj = None # 嘲讽目标
    sneerObjID, sneerObjPosNum = 0, 0
@@ -278,6 +305,11 @@
        if sneerObj in aimObjList and aimObjList.index(sneerObj) != 0:
            aimObjList.remove(sneerObj)
            aimObjList.insert(0, sneerObj)
    # 一定包含自己
    if tagFriendly == 2:
        if curBatObj not in aimObjList:
            aimObjList.append(curBatObj)
            
    if tagCount and len(aimObjList) > tagCount:
        aimObjList = aimObjList[:tagCount]
@@ -586,8 +618,7 @@
                纵排: 优先前面的单位
    '''
    
    if not SkillCommon.isTurnNormalSkill(useSkill):
        #GameWorld.DebugLog("非普攻不处理反击连击")
    if not useSkill.ComboEnable():
        return
    
    tagFriendly = useSkill.GetTagFriendly()
@@ -608,7 +639,7 @@
    if not tagObj:
        return
    
    comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum)
    comboNum = useSkill.GetComboNum()
    aComboRate = atkObj.GetBatAttrValue(ChConfig.AttrID_ComboRate)
    aComboRate += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, tagObj, ChConfig.AttrID_ComboRate, useSkill)
    
@@ -620,14 +651,14 @@
        return
    GameWorld.DebugLog("● %s 【连击】 happenRate=%s,aComboRate=%s,dComboRateDef=%s,comboNum=%s" 
                       % (TurnAttack.GetObjName(atkObj), happenRate, aComboRate, dComboRateDef, comboNum))
    atkObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, comboNum + 1)
    useSkill.SetComboNum(comboNum + 1)
    
    # 连击特长
    DoHeroSpecialty(turnFight, atkObj, ChConfig.HeroSpecialty_Combo, useSkill.GetSkillID())
    
    # 连击根据技能目标配置逻辑重新选择目标
    OnUseSkill(turnFight, atkObj, useSkill, batType=ChConfig.TurnBattleType_Combo)
    return
    return True
def __getCanAtkBackSkill(useSkill, tagObj):
    ## 获取是否可反击及反击技能
@@ -708,26 +739,44 @@
        TurnAttack.SetObjKilled(turnFight, curObj)
        
    # 统计伤血,可能单个技能对同一目标造成多次伤害
    totalHurtValue = 0
    isSuperHit, isStun, isSuckHP = False, False, False
    missObjIDList = []
    missObjIDList, immuneObjIDList = [], []
    for hurtObj in useSkill.GetHurtObjList():
        hurtObjID = hurtObj.GetObjID()
        tagObj = batObjMgr.getBatObj(hurtObjID)
        if not tagObj:
            continue
        if not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery) and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
        if not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery) and not hurtObj.HaveHurtType(ChConfig.HurtType_Immune) \
            and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
            __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
        if hurtObj.HaveHurtType(ChConfig.HurtType_Normal):
            totalHurtValue += hurtObj.GetHurtHP()
        if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
            missObjIDList.append(hurtObjID)
            if hurtObjID not in missObjIDList:
                missObjIDList.append(hurtObjID)
            DoHeroSpecialty(turnFight, tagObj, ChConfig.HeroSpecialty_Miss, relatedSkillID)
        if hurtObj.HaveHurtType(ChConfig.HurtType_Immune):
            if hurtObjID not in immuneObjIDList:
                immuneObjIDList.append(hurtObjID)
        if hurtObj.HaveHurtType(ChConfig.HurtType_Parry):
            DoHeroSpecialty(turnFight, tagObj, ChConfig.HeroSpecialty_Parry, relatedSkillID)
        if hurtObj.HaveHurtType(ChConfig.HurtType_SuperHit):
            isSuperHit = True
        if hurtObj.HaveHurtType(ChConfig.HurtType_Stun):
            isStun = True
        if hurtObj.GetSuckHP() > 0:
            isSuckHP = True
    curObj.SetLastHurtValue(totalHurtValue) # 记录最后一次总伤害
    # 群攻只触发一次特长
    if isSuperHit:
        DoHeroSpecialty(turnFight, curObj, ChConfig.HeroSpecialty_SuperHit, relatedSkillID)
@@ -741,8 +790,9 @@
    if curPlayer and curObj and curObj.GetOwnerID() == curPlayer.GetPlayerID():
        FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
        
    effIgnoreObjIDList = missObjIDList + immuneObjIDList
    # 优先触发本技能额外效果,注:仅该技能释放后该技能的额外效果视为主技能的效果,优先级最高
    __DoCurSkillEff(turnFight, curObj, useSkill, missObjIDList, isUseSkill)
    __DoCurSkillEff(turnFight, curObj, useSkill, effIgnoreObjIDList, isUseSkill)
        
    # ========== 以下触发被动 ==========
    
@@ -752,10 +802,10 @@
        tagObj = batObjMgr.getBatObj(tagObjID)
        TurnPassive.OnTriggerPassiveEffect(turnFight, buffObj, ChConfig.TriggerWay_ShieldBroken, tagObj, connSkillTypeID=buffSkillTypeID)
        
    batType = useSkill.GetBatType()
    for tagObj in useSkill.GetTagObjList():
        tagID = tagObj.GetID()
        if tagID == curID or tagID in missObjIDList:
            # 自己或对方闪避了不再触发被动
        if tagID in effIgnoreObjIDList:
            continue
        
        # 直接攻击
@@ -763,6 +813,23 @@
            TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_AttackOverDirect, tagObj, connSkill=useSkill)
            TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeAttackedDirect, curObj, connSkill=useSkill)
            
        # 使用技能后
        if isUseSkill:
            TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_UseSkillOver, tagObj, connSkill=useSkill)
        # 连击
        if batType == ChConfig.TurnBattleType_Combo:
            TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeCombo, curObj, connSkill=useSkill)
        # 追击
        elif batType == ChConfig.TurnBattleType_Pursue:
            TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BePursue, curObj, connSkill=useSkill)
    if killObjList:
        tagObj = killObjList[0]
        TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_KillOneObj, tagObj, connSkill=useSkill)
    for tagObj in killObjList:
        TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_KillTagObj, tagObj, connSkill=useSkill)
    return
def __doCostZhanchui(turnFight, curBatObj, useSkill):
@@ -851,7 +918,7 @@
    Sync_PropertyRefreshView(turnFight, gameObj, ChConfig.AttrID_XP, updXP, addXP, diffType=1, relatedSkillID=relatedSkillID)
    return
def __DoCurSkillEff(turnFight, curObj, useSkill, missObjIDList, isUseSkill):
def __DoCurSkillEff(turnFight, curObj, useSkill, effIgnoreObjIDList, isUseSkill):
    ## 执行本技能/buff释放后额外效果
    for index in xrange(useSkill.GetEffectCount()):
        curEffect = useSkill.GetEffect(index)
@@ -864,16 +931,15 @@
                continue
            
        effID = curEffect.GetEffectID()
        GameWorld.DebugLog("◆执行额外技能效果: %s, triggerWay=%s,missObjIDList=%s" % (effID, triggerWay, missObjIDList))
        GameWorld.DebugLog("◆执行额外技能效果: %s, triggerWay=%s,effIgnoreObjIDList=%s" % (effID, triggerWay, effIgnoreObjIDList))
        if effID == 5010:
            # 额外技能效果
            __doUseEnhanceSkill(turnFight, curObj, useSkill, curEffect, missObjIDList)
            __doUseEnhanceSkill(turnFight, curObj, useSkill, curEffect, effIgnoreObjIDList)
            continue
        
        for tagObj in useSkill.GetTagObjList():
            tagID = tagObj.GetID()
            GameWorld.DebugLog("    tagID=%s" % (tagID))
            if tagID in missObjIDList:
            if tagID in effIgnoreObjIDList:
                # 闪避了不触发
                continue
            
@@ -881,7 +947,7 @@
            
    return
def __doUseEnhanceSkill(turnFight, curBatObj, useSkill, curEffect, missObjIDList):
def __doUseEnhanceSkill(turnFight, curBatObj, useSkill, curEffect, effIgnoreObjIDList):
    ## 执行主技能的额外技能效果
    #if useSkill.GetBatType() == ChConfig.TurnBattleType_Enhance:
    #    #GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
@@ -906,8 +972,8 @@
            if not tagObj.IsAlive():
                GameWorld.DebugLog("    已被击杀不触发: tagID=%s" % (tagID))
                continue
            if tagID in missObjIDList:
                GameWorld.DebugLog("    闪避的不触发: tagID=%s" % (tagID))
            if tagID in effIgnoreObjIDList:
                GameWorld.DebugLog("    闪避或免疫的不触发: tagID=%s" % (tagID))
                continue
            if checkInStateList:
                if not tagObj.CheckInState(checkInStateList):
@@ -938,7 +1004,7 @@
    OnUseSkill(turnFight, curBatObj, enhanceSkillData, batType=ChConfig.TurnBattleType_Enhance, bySkill=useSkill)
    return
def OnUsePassiveSkill(turnFight, batObj, tagObj, passiveSkill, connSkill=None, effSkillID=0, effectID=0):
def OnUsePassiveSkill(turnFight, batObj, tagObj, passiveSkill, connSkill=None, effSkillID=0, effectID=0, connBuff=None):
    '''被动触发使用技能
    @param passiveSkill: 释放的被动技能
    @param connSkill: 由什么技能引起的
@@ -964,10 +1030,10 @@
            GameWorld.DebugLog("    概率不触发: tagID=%s,happenRate=%s" % (tagID, happenRate))
            return
        passiveTagObjList = [tagObj]
        isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=ChConfig.TurnBattleType_Passive, bySkill=connSkill)
        isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=ChConfig.TurnBattleType_Passive, bySkill=connSkill, byBuff=connBuff)
    else:
        GameWorld.DebugLog("被动触发技能,重新锁定目标! effSkillID=%s,effectID=%s,passiveSkillID=%s" % (effSkillID, effectID, passiveSkillID))
        isOK = OnUseSkill(turnFight, batObj, passiveSkill, batType=ChConfig.TurnBattleType_Passive, bySkill=connSkill)
        isOK = OnUseSkill(turnFight, batObj, passiveSkill, batType=ChConfig.TurnBattleType_Passive, bySkill=connSkill, byBuff=connBuff)
        
    return isOK
@@ -994,7 +1060,7 @@
    
    else:
        hurtValue, hurtTypes = CalcHurtHP(turnFight, atkObj, defObj, curSkill, atkSkillValue, atkSkillPer)
        hurtValue, realHurtHP = CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue)
        hurtValue, realHurtHP, hurtTypes = CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue, hurtTypes)
        
        #伤害结构体
        hurtObj.SetHurtTypes(hurtTypes)
@@ -1007,7 +1073,6 @@
    hurtObj.SetLostHP(lostHP)
    hurtObj.SetCurHP(remainHP)
    defObj.SetHP(remainHP)
    atkObj.SetLastHurtValue(hurtValue)
    GameWorld.DebugLog("    伤血: atkID=%s,defID=%s,hurtValue=%s,realHurtHP=%s,lostHP=%s,%s/%s" 
                       % (atkID, defID, hurtValue, realHurtHP, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
    TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, skillID)
@@ -1026,6 +1091,7 @@
    skillID = curSkill.GetSkillID()
    pmType = GetPMType(atkObj, curSkill)
    ignoreDef = IsIgnoreDef(curSkill)
    batType = curSkill.GetBatType()
    
    changeHurtType = TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_ChangeHurtType, curSkill)
    if changeHurtType == 1:
@@ -1049,14 +1115,14 @@
        GameWorld.DebugLog("XP必命中! curXP=%s,angerOverflow=%s" % (curXP, angerOverflow))
        
    #命中公式 攻击方类型不同,公式不同
    if isTurnNormalSkill and not mustHit:
    if isTurnNormalSkill and not mustHit and not defObj.IsInControlledHard():
        aMissRateDef = atkObj.GetBatAttrValue(ChConfig.AttrID_MissRateDef) #atkObj.GetHit() # 抗闪避率 - 命中
        dMissRate = defObj.GetBatAttrValue(ChConfig.AttrID_MissRate) # 闪避率
        missNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnMissNum)
        missNum = curSkill.GetTagMissNum(defID)
        missRate = eval(IpyGameDataPY.GetFuncCompileCfg("MissCfg", 1))
        if GameWorld.CanHappen(missRate):
            GameWorld.DebugLog("闪避了! missRate=%s,dMissRate=%s,aMissRateDef=%s,missNum=%s" % (missRate, dMissRate, aMissRateDef, missNum))
            defObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, missRate + 1)
            curSkill.SetTagMissNum(defID, missRate + 1)
            return 0, pow(2, ChConfig.HurtType_Miss)
        
    hurtTypes = pow(2, ChConfig.HurtType_Normal)
@@ -1120,6 +1186,14 @@
        aPMDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_PhyDamPer) 
        dPMDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_PhyDamPerDef)
        
    aComboDamPer = 0 # 连击增伤
    if batType == ChConfig.TurnBattleType_Combo:
        aComboDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_ComboDamPer)
    aPursueDamPer = 0 # 追击增伤
    if batType == ChConfig.TurnBattleType_Pursue:
        aPursueDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_PursueDamPer)
    # 所有万分率参数统一除10000.0
    atkSkillPer /= 10000.0
    aNormalSkillPer /= 10000.0
@@ -1133,9 +1207,11 @@
    dSuperDamPerDef /= 10000.0
    aFinalDamPer /= 10000.0
    dFinalDamPerDef /= 10000.0
    aComboDamPer /= 10000.0
    aPursueDamPer /= 10000.0
    
    if calcType != ChConfig.Def_Calc_Attack:
        aAtk = GetCalcBaseValue(calcType, atkObj, defObj)
        aAtk = GetCalcBaseValue(calcType, atkObj, defObj, curSkill)
    GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s,hurtTypes=%s,aAddSkillPer=%s" 
                       % (atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, hurtTypes, aAddSkillPer))
    
@@ -1149,6 +1225,9 @@
    elif isDot:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
        GameWorld.DebugLog("    持续技能伤害=%s" % (hurtValue))
    elif calcType == ChConfig.Def_Calc_ByBuffValue:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("CalcTypeFormula", 2))
        GameWorld.DebugLog("    按最后一次buff值计算伤害=%s,calcType=%s,LastHurt=%s" % (hurtValue, calcType, aAtk))
    elif calcType != ChConfig.Def_Calc_Attack:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("CalcTypeFormula", 1))
        GameWorld.DebugLog("    非按攻击力伤害=%s,calcType=%s,aAtk=%s" % (hurtValue, calcType, aAtk))
@@ -1173,6 +1252,13 @@
        hurtValue = min(hurtValue, hurtValueMax)
        GameWorld.DebugLog("    伤害最高限制: hurtValue=%s,hurtAtkPerMax=%s,aAtk=%s" % (hurtValue, hurtAtkPerMax, aAtk))
        
    # 均摊
    hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
    if hurtShareEff:
        tagCnt = max(1, len(curSkill.GetTagObjList()))
        hurtValue = hurtValue / tagCnt
        GameWorld.DebugLog("    目标均摊伤害: hurtValue=%s,tagCnt=%s" % (hurtValue, tagCnt))
    hurtValue = max(1, int(hurtValue)) # 负值、保底防范,放最后
    return hurtValue, hurtTypes
@@ -1193,40 +1279,61 @@
    happenRate = eval(IpyGameDataPY.GetFuncCompileCfg("StunCfg", 1))
    if not GameWorld.CanHappen(happenRate):
        return False
    GameWorld.DebugLog("击晕了: happenRate=%s,aStunRate=%s,dStunRateDef=%s" % (happenRate, aStunRate, dStunRateDef))
    stunSkillID = IpyGameDataPY.GetFuncCfg("StunCfg", 2)
    TurnBuff.DoAddBuffBySkillID(turnFight, defObj, stunSkillID, atkObj, curSkill, afterLogic=True)
    return True
    if TurnBuff.DoAddBuffBySkillID(turnFight, defObj, stunSkillID, atkObj, curSkill, afterLogic=True):
        GameWorld.DebugLog("击晕了: happenRate=%s,aStunRate=%s,dStunRateDef=%s" % (happenRate, aStunRate, dStunRateDef))
        return True
    return False
def CanParry(turnFight, atkObj, defObj, curSkill):
    if defObj.IsInControlled():
        #被控制无法格挡
    if defObj.IsInControlledHard():
        #被硬控无法格挡
        return False
    
    defID = defObj.GetID()
    # 格挡印记
    buffMgr = defObj.GetBuffManager()
    parryYJBuff = buffMgr.FindBuffByState(ChConfig.BatObjState_ParryYJ)
    if parryYJBuff and parryYJBuff.GetLayer():
        GameWorld.DebugLog("格挡印记格挡了: buffID=%s,buffLayer=%s" % (parryYJBuff.GetBuffID(), parryYJBuff.GetLayer()))
        TurnBuff.DecBuffLayer(turnFight, defObj, parryYJBuff, 1, curSkill.GetSkillID())
        TurnBuff.DoBuffLayerChange(turnFight, defObj, parryYJBuff, parryYJBuff.GetLayer() - 1, curSkill)
        return True
    
    aParryRateDef = atkObj.GetBatAttrValue(ChConfig.AttrID_ParryRateDef)
    dParryRate = defObj.GetBatAttrValue(ChConfig.AttrID_ParryRate)
    parryNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnParryNum)
    parryNum = curSkill.GetTagParryNum(defID)
    happenRate = eval(IpyGameDataPY.GetFuncCompileCfg("ParryCfg", 1))
    if GameWorld.CanHappen(happenRate):
        GameWorld.DebugLog("格挡了: happenRate=%s,aParryRateDef=%s,dParryRate=%s,parryNum=%s" % (happenRate, aParryRateDef, dParryRate, parryNum))
        defObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, parryNum + 1)
        curSkill.SetTagParryNum(defID, parryNum + 1)
        return True
    return False
def CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue):
def CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue, hurtTypes=0):
    ## 计算伤害后,因各种buff和状态的影响处理
    # @return: hurtValue, realHurtHP
    # @return: hurtValue, realHurtHP, hurtTypes
    
    if hurtValue <= 0:
        return 0, 0
        return 0, 0, hurtTypes
    if defObj.CheckInState(ChConfig.BatObjState_Wudi):
        hurtTypes |= pow(2, ChConfig.HurtType_Immune) # 添加免疫
        buffMgr = defObj.GetBuffManager()
        for index in range(buffMgr.GetBuffCount()):
            buff = buffMgr.GetBuffByIndex(index)
            if not buff:
                continue
            skillData = buff.GetSkillData()
            if skillData.GetCurBuffState() != ChConfig.BatObjState_Wudi:
                continue
            # 记录免疫的积攒伤害
            buffValue = buff.GetValue1() + buff.GetValue2() * ChConfig.Def_PerPointValue
            updBuffValue = buffValue + hurtValue
            buff.SetValue1(updBuffValue % ChConfig.Def_PerPointValue)
            buff.SetValue2(updBuffValue / ChConfig.Def_PerPointValue)
            GameWorld.DebugLog("    无敌盾免疫伤害: defID=%s,buffID=%s,skillID=%s,updBuffValue=%s"
                               % (defObj.GetID(), buff.GetBuffID(), skillData.GetSkillID(), updBuffValue))
        return 0, 0, hurtTypes
    
    # 减伤盾减伤, 会改变 hurtValue
    hurtValue = max(0, hurtValue)
@@ -1268,7 +1375,7 @@
                buff.SetValue2(updShieldValue / ChConfig.Def_PerPointValue)
                curSkill.AddAfterLogic(ChConfig.AfterLogic_SyncBuff, [defObj, buff, atkObj, "ReduceShieldValue"])
                
    return hurtValue, max(0, realHurtHP)
    return hurtValue, max(0, realHurtHP), hurtTypes
def CalcBounceHP(turnFight, atkObj, defObj, hurtObj, curSkill):
    '''计算反弹反弹伤害
@@ -1281,8 +1388,9 @@
        return
    
    GameWorld.DebugLog("    反弹伤害=%s,%s/%s" % (bounceHP, atkObj.GetHP(), atkObj.GetMaxHP()))
    bounceHP, realBounceHP = CalcHurtHPWithBuff(turnFight, defObj, atkObj, curSkill, bounceHP)
    bounceHP, realBounceHP, _ = CalcHurtHPWithBuff(turnFight, defObj, atkObj, curSkill, bounceHP)
    if bounceHP <= 0:
        GameWorld.DebugLog("        bounceHP=%s" % (bounceHP))
        return
    hurtObj.SetBounceHP(bounceHP)
    
@@ -1328,9 +1436,22 @@
    skillPer = curSkill.GetSkillPer()
    #skillValue = curSkill.GetSkillValue()
    
    cureBaseValue = GetCalcBaseValue(cureType, userObj, tagObj)
    skillPer += TurnPassive.GetTriggerEffectValue(turnFight, userObj, tagObj, ChConfig.PassiveEff_AddSkillPer, curSkill)
    cureHP = __calcCureHP(turnFight, userObj, tagObj, curSkill, cureType, skillPer, largeNum)
    cureWayExEff = curSkill.GetEffectByID(ChConfig.SkillEff_CureWayEx)
    if cureWayExEff:
        cureType = cureWayExEff.GetEffectValue(0)
        skillPer = cureWayExEff.GetEffectValue(1)
        GameWorld.DebugLog("额外计算治疗方式: cureType=%s,skillPer=%s" % (cureType, skillPer))
        cureHPEx = __calcCureHP(turnFight, userObj, tagObj, curSkill, cureType, skillPer, largeNum)
        cureHP += cureHPEx
    return max(1, int(cureHP)) # 保底1点
def __calcCureHP(turnFight, userObj, tagObj, curSkill, cureType, skillPer, largeNum=False):
    cureBaseValue = GetCalcBaseValue(cureType, userObj, tagObj, curSkill)
    
    # 回合制
    curePer = 0 # 治疗加成
@@ -1359,8 +1480,9 @@
                       % (cureHP, curSkill.GetSkillID(), cureType, baseValue, skillPer, curePer, cureDefPer, angerOverflow))
    return cureHP
def GetCalcBaseValue(calcType, curObj, tagObj):
def GetCalcBaseValue(calcType, curObj, tagObj, curSkill):
    ##获得基础计算值
    baseValue = 0
    if calcType == ChConfig.Def_Calc_Attack:
        baseValue = curObj.GetAtk()
    elif calcType == ChConfig.Def_Calc_MaxHP:
@@ -1369,6 +1491,11 @@
        baseValue = curObj.GetLastHurtValue()
    elif calcType == ChConfig.Def_Calc_TagMaxHP:
        baseValue = 0 if not tagObj else tagObj.GetMaxHP()
    elif calcType == ChConfig.Def_Calc_ByBuffValue:
        byBuff = curSkill.GetByBuff()
        if byBuff:
            baseValue = byBuff.GetValue1() + byBuff.GetValue2() * ChConfig.Def_PerPointValue
            GameWorld.DebugLog("根据buff值: %s" % baseValue)
    return baseValue
def DoDOTAttack(turnFight, batObj, curBuff, hurtValue, hurtTypes):
@@ -1391,7 +1518,7 @@
    tagObjList = [defObj]
    
    poolMgr = ObjPool.GetPoolMgr()
    useSkill = poolMgr.acquire(BattleObj.PySkill, skillIpyData)
    useSkill = poolMgr.acquire(BattleObj.PySkill, skillIpyData, atkID)
    useSkill.SetTagObjList(tagObjList)
    useSkill.ClearHurtObj()
    hurtObj = useSkill.AddHurtObj(defID)
@@ -1399,14 +1526,13 @@
    dHP = defObj.GetHP()
    GameWorld.DebugLog("结算dot: atkID=%s,defID=%s,buffID=%s,skillID=%s,ownerID=%s,hurtValue=%s,hurtTypes=%s,dHP=%s" 
                       % (atkID, defID, buffID, skillID, ownerID, hurtValue, hurtTypes, dHP))
    hurtValue, realHurtHP = CalcHurtHPWithBuff(turnFight, atkObj, defObj, useSkill, hurtValue)
    hurtValue, realHurtHP, hurtTypes = CalcHurtHPWithBuff(turnFight, atkObj, defObj, useSkill, hurtValue, hurtTypes)
    
    # dot的反弹、吸血待定
    
    remainHP = max(0, dHP - realHurtHP) # 剩余血量
    lostHP = dHP - remainHP # 实际掉血量
    defObj.SetHP(remainHP)
    atkObj.SetLastHurtValue(hurtValue)
    GameWorld.DebugLog("    hurtValue=%s,realHurtHP=%s,lostHP=%s,%s/%s" % (hurtValue, realHurtHP, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
    
    hurtObj.SetHurtTypes(hurtTypes)
@@ -1447,6 +1573,15 @@
        hurt.SuckHP = min(hurtObj.GetSuckHP(), ChConfig.Def_UpperLimit_DWord)
        hurt.BounceHP = min(hurtObj.GetBounceHP(), ChConfig.Def_UpperLimit_DWord)
        clientPack.HurtList.append(hurt)
    if not clientPack.HurtList:
        for tagObj in useSkill.GetTagObjList():
            tagID = tagObj.GetID()
            hurt = poolMgr.acquire(ChPyNetSendPack.tagSCUseSkillHurt)
            hurt.ObjID = tagID
            hurt.CurHP = tagObj.GetHP() % ChConfig.Def_PerPointValue
            hurt.CurHPEx = tagObj.GetHP() / ChConfig.Def_PerPointValue
            clientPack.HurtList.append(hurt)
    clientPack.HurtCount = len(clientPack.HurtList)
    turnFight.addBatPack(clientPack)
    return