ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -60,9 +60,6 @@
        return
    
    objID = curBatObj.GetID()
    if not curBatObj.CanAction():
        GameWorld.DebugLog("当前状态无法使用技能! objID=%s,skillID=%s" % (objID, skillID))
        return
    
    buffStateGroups = useSkill.GetBuffStateLimit()
    if buffStateGroups:
@@ -71,6 +68,9 @@
            GameWorld.DebugLog("技能使用处于buff状态限制中! skillID=%s,buffStateGroups=%s,limitState=%s" % (skillID, buffStateGroups, limitState))
            return
        
    if CheckSkillUseCntLimit(curBatObj, useSkill):
        return
    #没有指定目标,则按技能自身的目标逻辑
    if not tagObjList:
        tagObjList = GetSkillTags(turnFight, curBatObj, useSkill)
@@ -126,19 +126,19 @@
        curBatObj.SetMainTagIDList(tagIDList)
        
    useTag = ""
    if IsNeedSyncSkill(useSkill):
        # 因为可能触发连击,所以标记需带上累计使用技能次数,确保唯一
        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:
        # 主技能额外触发的技能可不下发,前端视为仅释放一个主技能
        if batType != ChConfig.TurnBattleType_Enhance:
            # 因为可能触发连击,所以标记需带上累计使用技能次数,确保唯一
            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)
        __doUseSkill(turnFight, curBatObj, useSkill)
        
    DoAttackResult(turnFight, curBatObj, useSkill)
@@ -160,6 +160,36 @@
    if usePoolSkill:
        poolMgr.release(useSkill)
    return True
def CheckSkillUseCntLimit(batObj, useSkill):
    ## 检查技能使用次数是否受限
    # @return: 是否受限
    if not hasattr(useSkill, "GetEffectByID"):
        return
    effect = useSkill.GetEffectByID(ChConfig.SkillEff_SkillUseCntLimit)
    if not effect:
        return
    useCntLimit = effect.GetEffectValue(0) # 每场战斗最大次数,0不限
    turnUseCntLimit = effect.GetEffectValue(1) # 每大回合最大次数,0不限
    skillID = useSkill.GetSkillID()
    if useCntLimit:
        useCnt = batObj.GetSkillUseCnt(skillID)
        if useCnt >= useCntLimit:
            GameWorld.DebugLog("技能每场战斗使用次数受限! skillID=%s,useCnt=%s >= %s" % (skillID, useCnt, useCntLimit))
            return True
    if turnUseCntLimit:
        turnUseCnt = batObj.GetSkillTurnUseCnt(skillID)
        if turnUseCnt >= turnUseCntLimit:
            GameWorld.DebugLog("技能每大回合使用次数受限! skillID=%s,turnUseCnt=%s >= %s" % (skillID, turnUseCnt, turnUseCntLimit))
            return True
    return
def IsNeedSyncSkill(useSkill):
    ## 使用需要同步B427使用技能
    return useSkill.GetSkillType() in [ChConfig.Def_SkillType_Atk, ChConfig.Def_SkillType_Cure, ChConfig.Def_SkillType_CleanBuff]
def GetSkillTags(turnFight, curBatObj, useSkill):
    ## 获取技能目标
@@ -520,6 +550,9 @@
    
    atkType = useSkill.GetAtkType()
    GameWorld.DebugLog("__doUseSkill: curID=%s,skillID=%s,atkType=%s" % (curBatObj.GetID(), useSkill.GetSkillID(), atkType))
    __doHarmSelf(turnFight, curBatObj, useSkill)
    # 通用攻击
    if atkType == 1:
        SkillModule_1(turnFight, curBatObj, useSkill)
@@ -548,6 +581,36 @@
    elif atkType == 9:
        SkillModule_9(turnFight, curBatObj, useSkill)
        
    return
def __doHarmSelf(turnFight, curBatObj, useSkill):
    harmEff = useSkill.GetEffectByID(ChConfig.SkillEff_UseSkillHarmSelf)
    if not harmEff:
        return
    harmPer = harmEff.GetEffectValue(0) # 自残百分比
    noEnoughDo = harmEff.GetEffectValue(1) # 不足时扣除方式 0-不扣;1-自杀;2-扣剩1点
    curHP = curBatObj.GetHP()
    maxHP = curBatObj.GetMaxHP()
    harmHP = int(maxHP * harmPer / 100.0)
    lostHP = harmHP
    if curHP <= harmHP:
        if noEnoughDo == 0:
            lostHP = 0
        elif noEnoughDo == 2:
            lostHP -= 1
    updHP = max(curHP - lostHP, 0)
    curBatObj.SetHP(updHP, False)
    GameWorld.DebugLog("使用技能时自残: curHP=%s/%s,harmPer=%s,harmHP=%s,lostHP=%s,updHP=%s,noEnoughDo=%s"
                       % (curHP, maxHP, harmPer, harmHP, lostHP, updHP, noEnoughDo))
    curBatObj.SetHarmSelfHP(harmHP) # 无视实际扣血量,直接更新
    # 单独通知前端表现
    hurtTypes = pow(2, ChConfig.HurtType_HarmSelf)
    diffType, diffValue = 0, lostHP
    skillID = relatedSkillID = useSkill.GetSkillID()
    Sync_PropertyRefreshView(turnFight, curBatObj, ChConfig.AttrID_HP, updHP, diffValue, diffType, skillID, relatedSkillID, hurtTypes)
    return
def SkillModule_1(turnFight, curBatObj, useSkill):
@@ -778,11 +841,10 @@
    skillID = useSkill.GetSkillID()
    curBatObj.AddSkillUseCnt(skillID)
    if useSkill.GetCoolDownTime():
        useSkill.SetCalcTime(turnFight.getTimeline())
        useSkill.SetRemainTime(useSkill.GetCoolDownTime())
        
    # 需先技能使用 - 前端按顺序优先表现技能释放内容,前端需要动作或有伤血则通知
    if useSkill.GetSkillMotionName() or len(useSkill.GetHurtObjList()) or useSkill.GetSkillType() in [ChConfig.Def_SkillType_CleanBuff]:
    if IsNeedSyncSkill(useSkill):
        Sync_UseSkill(turnFight, curBatObj, useSkill)
        
    __doCostZhanchui(turnFight, curBatObj, useSkill)
@@ -943,7 +1005,8 @@
    # 统计伤血,可能单个技能对同一目标造成多次伤害
    totalHurtValue = 0
    isSuperHit, isStun, isSuckHP = False, False, False
    missObjIDList, immuneObjIDList = [], []
    missObjIDList, immuneObjIDList = [], [] # 闪避、免疫对象ID列表
    beHurtObjIDList = [] # 受伤的对象ID列表
    for hurtObj in useSkill.GetHurtObjList():
        hurtObjID = hurtObj.GetObjID()
        tagObj = batObjMgr.getBatObj(hurtObjID)
@@ -955,7 +1018,10 @@
            
        if hurtObj.HaveHurtType(ChConfig.HurtType_Normal):
            totalHurtValue += hurtObj.GetHurtHP()
            if hurtObj.GetLostHP() > 0: # 有掉血的
                if hurtObjID not in beHurtObjIDList:
                    beHurtObjIDList.append(hurtObjID)
        if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
            if hurtObjID not in missObjIDList:
                missObjIDList.append(hurtObjID)
@@ -1021,6 +1087,10 @@
        if tagID in effIgnoreObjIDList:
            continue
        
        # 掉血时
        if tagID in beHurtObjIDList:
            TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeHurt, curObj, connSkill=useSkill)
        # 直接攻击
        if isAttackDirect:
            if not triggerOne:
@@ -1181,6 +1251,14 @@
    if not enhanceSkillData:
        return
    
    killObjList = useSkill.GetKillObjList()
    if killObjList:
        invalidSkillID = TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_SkillInvalid, useSkill,
                                                           triggerWay=ChConfig.TriggerWay_KillOneObj)
        if invalidSkillID and invalidSkillID == enhanceSkillID:
            GameWorld.DebugLog("有击杀目标时该技能无效! enhanceSkillID=%s" % enhanceSkillID)
            return
    # 继承主技能目标
    if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
        GameWorld.DebugLog("继承主技能目标! enhanceSkillID=%s" % enhanceSkillID)
@@ -1392,6 +1470,7 @@
        hurtTypes |= pow(2, ChConfig.HurtType_Parry)
        
    if ignoreDef:
        GameWorld.DebugLog("无视防御/真实伤害!")
        hurtTypes |= pow(2, ChConfig.HurtType_IgnoreDef)
        
    if isStun:
@@ -1419,9 +1498,11 @@
        
    aAngerSkillPer, dAngerSkillPerDef = 0, 0
    if isAngerSkill:
        aAngerSkillPer = atkObj.GetBatAttrValue(ChConfig.AttrID_AngerSkillPer) # 普技增伤
        dAngerSkillPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_AngerSkillPerDef) # 普技减伤
        aAngerSkillPer = atkObj.GetBatAttrValue(ChConfig.AttrID_AngerSkillPer) # 怒技增伤
        aAngerSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddAngerSkillPerByXP, curSkill)
        dAngerSkillPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_AngerSkillPerDef) # 怒技减伤
    aAddSkillPer = 0 # 技能增伤
    aAddSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_SkillPer, curSkill)
    
@@ -1459,16 +1540,16 @@
    
    if calcType != ChConfig.Def_Calc_Attack:
        aAtk = GetCalcBaseValue(calcType, atkObj, defObj, curSkill)
    GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aAddSkillPer=%s"
                       % (atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aAddSkillPer))
    GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aAddSkillPer=%s,aFinalDamPer=%s"
                       % (atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aAddSkillPer, aFinalDamPer))
    
    # 持续性伤害
    if isTurnNormalSkill:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
        GameWorld.DebugLog("    普攻技能伤害=%s" % (hurtValue))
        GameWorld.DebugLog("    普攻技能伤害=%s,aNormalSkillPer=%s,dNormalSkillPerDef=%s" % (hurtValue, aNormalSkillPer, dNormalSkillPerDef))
    elif isAngerSkill:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 2))
        GameWorld.DebugLog("    怒气技能伤害=%s" % (hurtValue))
        GameWorld.DebugLog("    怒气技能伤害=%s,aAngerSkillPer=%s,dAngerSkillPerDef=%s" % (hurtValue, aAngerSkillPer, dAngerSkillPerDef))
    elif isDot:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
        GameWorld.DebugLog("    持续技能伤害=%s" % (hurtValue))
@@ -1516,6 +1597,7 @@
    atkSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddSkillPerByHP, curSkill)
    atkSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddSkillPerByJob, curSkill)
    atkSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddSkillPerByBuffLayer, curSkill)
    atkSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddSkillPerByDeadTeammate, curSkill)
    return atkSkillPer
def CanSuperHit(turnFight, atkObj, defObj, curSkill):
@@ -1618,11 +1700,12 @@
            if shieldHurtValue <= 0:
                break
            buffID = buff.GetBuffID()
            buffSkillID = buff.GetSkillID()
            if shieldHurtValue < buffValue:
                decShieldValue = shieldHurtValue
            else:
                decShieldValue = buffValue
            GameWorld.DebugLog("    承伤盾抵扣: buffID=%s,buffValue=%s,剩余盾伤=%s,扣除盾值=%s" % (buffID, buffValue, shieldHurtValue, decShieldValue))
            GameWorld.DebugLog("    承伤盾抵扣: buffID=%s,skillID=%s,buffValue=%s,剩余盾伤=%s,扣除盾值=%s" % (buffID, buffSkillID, buffValue, shieldHurtValue, decShieldValue))
            shieldHurtValue -= decShieldValue # 承伤值
            if decShieldValue >= buffValue:
                GameWorld.DebugLog("        删除盾: buffID=%s,剩余盾伤=%s" % (buffID, shieldHurtValue))
@@ -1810,6 +1893,10 @@
        if byBuff:
            baseValue = byBuff.GetValue1() + byBuff.GetValue2() * ChConfig.Def_PerPointValue
            GameWorld.DebugLog("根据buff值: %s" % baseValue)
    elif calcType == ChConfig.Def_Calc_HarmSelfHP:
        baseValue = curObj.GetHarmSelfHP()
        GameWorld.DebugLog("根据自残值: %s" % baseValue)
    return baseValue
def DoDOTAttack(turnFight, batObj, curBuff, hurtValue, hurtTypes, **kwargs):