From 49cfc84f644219fefb382215e1765a8fd81fde48 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 25 九月 2025 09:49:52 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(甘宁技能;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py |  284 +++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 217 insertions(+), 67 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
index 69bc764..12a06ea 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -45,11 +45,11 @@
     ## 是否无视防御
     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, comboLimit=False):
     '''使用技能通用入口
     @param useSkill: 使用的技能,注意并不一定是身上的技能,可能只是 SkillData 表数据
     @param bySkill: 由哪个技能额外触发的,比如附加触发的技能或被动技能均可能由某个技能触发
-    @param isEnhanceSkill: 是否附加触发的技能,即主技能拆分成多个技能,额外释放的
+    @param comboLimit: 是否强制限制连击
     @return: 是否成功
     '''
     if not useSkill:
@@ -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]:
@@ -84,7 +90,7 @@
     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,oneActionUseCnt=%s" 
+    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))
     # 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
     
@@ -99,6 +105,7 @@
     useSkill.SetTagObjList(tagObjList)
     useSkill.SetBatType(batType)
     useSkill.SetBySkill(bySkill)
+    useSkill.SetByBuff(byBuff)
     
     isTurnNormalSkill = SkillCommon.isTurnNormalSkill(useSkill)
     if isTurnNormalSkill:
@@ -144,7 +151,7 @@
         
     # 处理反击 或 连击
     if isTurnNormalSkill:
-        if not DoCombo(turnFight, curBatObj, useSkill):
+        if comboLimit or not DoCombo(turnFight, curBatObj, useSkill):
             useSkill.ComboInterrupt()
             
     # 最后重置、回收对象
@@ -153,15 +160,28 @@
         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)
+    
+    # 目标选择优先级,集火 > 魅惑 > 混乱 > 嘲讽 > 常规
+    # 集火:直接通过效果5015指定了目标,所以这里可不处理
+    # 魅惑: 敌友互换; 不打自己,只剩自己互换后是己方时不释放技能
+    # 混乱: 随机敌友; 不打自己,只剩自己随机后是己方时不释放技能
+    # 嘲讽: 目标是敌方时强制目标一定包含施法者
     
     sneerObj = None # 嘲讽目标
     sneerObjID, sneerObjPosNum = 0, 0
@@ -275,6 +295,11 @@
         aimObjList.sort(key=lambda o:(o.GetHP()), reverse=True)
         #GameWorld.DebugLog("血量最高排序: %s" % [[o.GetID(), o.GetHP(), o.GetMaxHP()] for o in aimObjList])
         
+    # 攻击力最高
+    elif tagAffect == ChConfig.SkillTagAffect_AtkHighest:
+        aimObjList.sort(key=lambda o:(o.GetAtk()), reverse=True)
+        #GameWorld.DebugLog("攻击力最高排序: %s" % [[o.GetID(), o.GetHP(), o.GetMaxHP()] for o in aimObjList])
+        
     # 未被控制优先
     elif tagAffect == ChConfig.SkillTagAffect_UncontrolledPriority:
         sneerObjFirst = False
@@ -291,6 +316,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]
@@ -680,7 +710,7 @@
     @param isUseSkill: 是否是直接使用技能的攻击结果,否则视为持续性的
     '''
     
-    curID = curObj.GetID()
+    #curID = curObj.GetID()
     isTurnNormalSkill = SkillCommon.isTurnNormalSkill(useSkill)
     isAngerSkill = SkillCommon.isAngerSkill(useSkill)
     
@@ -716,30 +746,49 @@
         if tagObj.IsAlive() and tagObj.GetHP() <= 0 and tagObj.GetFaction() != curObj.GetFaction():
             killObjList.append(tagObj)
             TurnAttack.SetObjKilled(turnFight, tagObj, curObj, useSkill)
+    useSkill.SetKillObjList(killObjList)
     if curObj.IsAlive() and curObj.GetHP() <= 0:
         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)
@@ -753,9 +802,10 @@
     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)
+    
     # ========== 以下触发被动 ==========
     
     # 破盾时
@@ -764,22 +814,43 @@
         tagObj = batObjMgr.getBatObj(tagObjID)
         TurnPassive.OnTriggerPassiveEffect(turnFight, buffObj, ChConfig.TriggerWay_ShieldBroken, tagObj, connSkillTypeID=buffSkillTypeID)
         
+    # 有击杀时
+    for index, tagObj in enumerate(killObjList):
+        if index == 0:
+            TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_KillOneObj, tagObj, connSkill=useSkill)
+        TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_KillTagObj, tagObj, connSkill=useSkill)
+        
+    triggerOne = False
+    batType = useSkill.GetBatType()
+    isAttackDirect = (isUseSkill and not SkillCommon.IsBuff(useSkill) and useSkill.GetSkillType() in [ChConfig.Def_SkillType_Atk])
     for tagObj in useSkill.GetTagObjList():
         tagID = tagObj.GetID()
-        if tagID == curID or tagID in missObjIDList:
-            # 自己或对方闪避了不再触发被动
+        if tagID in effIgnoreObjIDList:
             continue
         
         # 直接攻击
-        if isUseSkill and not SkillCommon.IsBuff(useSkill) and useSkill.GetSkillType() in [ChConfig.Def_SkillType_Atk]:
+        if isAttackDirect:
+            if not triggerOne:
+                TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_AttackOverDirectOne, tagObj, connSkill=useSkill)
             TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_AttackOverDirect, tagObj, connSkill=useSkill)
             TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeAttackedDirect, curObj, connSkill=useSkill)
+        else:
+            TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeAnyEffect, 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)
+        # 使用技能后
+        if isUseSkill:
+            if not triggerOne:
+                TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_UseSkillOverOne, tagObj, connSkill=useSkill)
+            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)
+            
+        triggerOne = True # 设置已经触发过一次
         
     return
 
@@ -869,7 +940,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)
@@ -882,15 +953,15 @@
                 continue
             
         effID = curEffect.GetEffectID()
-        GameWorld.DebugLog("◆执行额外技能效果: %s, triggerWay=%s,missObjIDList=%s" % (effID, triggerWay, missObjIDList))
+        GameWorld.DebugLog("●执行额外技能效果: skillID=%s,effID=%s, triggerWay=%s,effIgnoreObjIDList=%s" % (useSkill.GetSkillID(), 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()
-            if tagID in missObjIDList:
+            if tagID in effIgnoreObjIDList:
                 # 闪避了不触发
                 continue
             
@@ -898,14 +969,15 @@
             
     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())
     #    return
     enhanceSkillID = curEffect.GetEffectValue(0)
     checkInStateList = curEffect.GetEffectValue(1)
-    GameWorld.DebugLog("额外触发的技能: enhanceSkillID=%s,checkInStateList=%s" % (enhanceSkillID, checkInStateList))
+    checkHeroJob = curEffect.GetEffectValue(2)
+    GameWorld.DebugLog("额外触发的技能: enhanceSkillID=%s,checkInStateList=%s,checkHeroJob=%s" % (enhanceSkillID, checkInStateList, checkHeroJob))
     tagObjList = useSkill.GetTagObjList()
     
     enhanceSkillData = IpyGameDataPY.GetIpyGameData("Skill", enhanceSkillID)
@@ -923,13 +995,16 @@
             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):
                     GameWorld.DebugLog("    不在状态下不触发: tagID=%s not in state:%s" % (tagID, checkInStateList))
                     continue
+            if checkHeroJob and checkHeroJob != tagObj.GetJob():
+                GameWorld.DebugLog("    非目标职业不触发: tagID=%s,job=%s != %s" % (tagID, tagObj.GetJob(), checkHeroJob))
+                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
@@ -943,19 +1018,26 @@
     
     # 只执行一次,防止群攻时额外触发多次
     GameWorld.DebugLog("重新锁定目标! enhanceSkillID=%s" % enhanceSkillID)
-    if checkInStateList:
-        inState = False
+    if checkInStateList or checkHeroJob:
+        inState, haveJob = False, False
         for tagObj in tagObjList:
-            if tagObj.CheckInState(checkInStateList):
+            tagID = tagObj.GetID()
+            if tagID in effIgnoreObjIDList:
+                continue
+            if not inState and tagObj.CheckInState(checkInStateList):
                 inState = True
-                break
-        if not inState:
-            GameWorld.DebugLog("    没有目标在状态下不触发: tagObj not in state:%s" % str(checkInStateList))
+            if not haveJob and checkHeroJob and checkHeroJob == tagObj.GetJob():
+                haveJob = True
+        if checkInStateList and not inState:
+            GameWorld.DebugLog("    没有命中目标在状态下不触发: tagObj not in state:%s" % str(checkInStateList))
+            return
+        if checkHeroJob and not haveJob:
+            GameWorld.DebugLog("    没有命中目标为目标职业不触发: checkHeroJob=%s" % checkHeroJob)
             return
     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: 由什么技能引起的
@@ -965,12 +1047,21 @@
     '''
     if not passiveSkill:
         return
-    isOK = False
+    bySkillID = 0
+    if connSkill:
+        bySkillID = connSkill.GetSkillID()
+    elif connBuff:
+        bySkillID = connBuff.GetSkillID()
     passiveSkillID = passiveSkill.GetSkillID()
+    if passiveSkillID == bySkillID:
+        #GameWorld.DebugLog("###被动触发技能不触发自身,防止死循环! effSkillID=%s,effectID=%s,passiveSkillID=%s" % (effSkillID, effectID, passiveSkillID))
+        return
+    
+    isOK = False
     # 继承主技能目标
     if passiveSkill.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
         happenRate = passiveSkill.GetHappenRate()
-        GameWorld.DebugLog("被动触发技能,继承主技能目标! effSkillID=%s,effectID=%s,passiveSkillID=%s,happenRate=%s" % (effSkillID, effectID, passiveSkillID, happenRate))
+        GameWorld.DebugLog("被动触发技能,继承主技能目标! effSkillID=%s,effectID=%s,passiveSkillID=%s,happenRate=%s,bySkillID=%s" % (effSkillID, effectID, passiveSkillID, happenRate, bySkillID))
         if not tagObj:
             return
         tagID = tagObj.GetID()
@@ -981,10 +1072,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)
+        GameWorld.DebugLog("被动触发技能,重新锁定目标! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s" % (effSkillID, effectID, passiveSkillID, bySkillID))
+        isOK = OnUseSkill(turnFight, batObj, passiveSkill, batType=ChConfig.TurnBattleType_Passive, bySkill=connSkill, byBuff=connBuff)
         
     return isOK
 
@@ -1011,7 +1102,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)
@@ -1024,7 +1115,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)
@@ -1067,7 +1157,7 @@
         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 = curSkill.GetTagMissNum(defID)
@@ -1109,13 +1199,18 @@
     
     aAtk = atkObj.GetAtk() # 攻击方最大攻击
     
-    dHP = defObj.GetHP()
+    dHP, dMaxHP = defObj.GetHP(), defObj.GetMaxHP()
     dDef = 0 if ignoreDef else defObj.GetDef() # 防守方防御力
     
     atkSkillPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddSkillPer, curSkill)
+    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)
     
     aFinalDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_FinalDamPer) # 最终加成
     dFinalDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_FinalDamPerDef) # 最终减伤
+    
+    aFinalDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddFinalDamPer, curSkill)
     
     aNormalSkillPer, dNormalSkillPerDef = 0, 0
     if isTurnNormalSkill:
@@ -1163,9 +1258,9 @@
     aPursueDamPer /= 10000.0
     
     if calcType != ChConfig.Def_Calc_Attack:
-        aAtk = GetCalcBaseValue(calcType, atkObj, defObj)
-    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))
+        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))
     
     # 持续性伤害
     if isTurnNormalSkill:
@@ -1177,6 +1272,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))
@@ -1201,10 +1299,21 @@
         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
 
 def CanSuperHit(turnFight, atkObj, defObj, curSkill):
+    if TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_MustSuperHit, curSkill):
+        GameWorld.DebugLog("目标血量低于百分x时必定暴击: defID=%s,hp:%s/%s" % (defObj.GetID(), defObj.GetHP(), defObj.GetMaxHP()))
+        return True
+    
     aSuperHitRate = atkObj.GetBatAttrValue(ChConfig.AttrID_SuperHitRate)
     aSuperHitRate += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_SuperHitRate, curSkill)
     dSuperHitRateDef = defObj.GetBatAttrValue(ChConfig.AttrID_SuperHitRateDef)
@@ -1221,14 +1330,15 @@
     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()
@@ -1237,7 +1347,7 @@
     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)
@@ -1250,12 +1360,31 @@
         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)
@@ -1297,7 +1426,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):
     '''计算反弹反弹伤害
@@ -1310,8 +1439,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)
     
@@ -1357,9 +1487,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 # 治疗加成
@@ -1388,8 +1531,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:
@@ -1398,6 +1542,13 @@
         baseValue = curObj.GetLastHurtValue()
     elif calcType == ChConfig.Def_Calc_TagMaxHP:
         baseValue = 0 if not tagObj else tagObj.GetMaxHP()
+    elif calcType == ChConfig.Def_Calc_TagLostHP:
+        baseValue = 0 if not tagObj else max(0, tagObj.GetMaxHP() - tagObj.GetHP())
+    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):
@@ -1428,14 +1579,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)

--
Gitblit v1.8.0