From de44f98f2a8a2b0c12d3482162f1e30e796d7b94 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 08 一月 2026 16:27:02 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(优化伤害计算公式参数输出;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py |  170 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 151 insertions(+), 19 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 2897f31..620c704 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -86,7 +86,7 @@
             GameWorld.DebugLogEx("技能使用处于buff状态限制中! skillID=%s,buffStateGroups=%s,limitState=%s", skillID, buffStateGroups, limitState)
             return
         
-    if CheckSkillUseCntLimit(curBatObj, useSkill):
+    if CheckSkillUseCntLimit(turnFight, curBatObj, useSkill):
         return
     
     #没有指定目标,则按技能自身的目标逻辑
@@ -185,7 +185,7 @@
     if SkillCommon.IsBuff(useSkill):
         __doAddBuff(turnFight, curBatObj, useSkill, **kwargs)
     else:
-        __doUseSkill(turnFight, curBatObj, useSkill)
+        __doUseSkill(turnFight, curBatObj, useSkill, **kwargs)
         
     DoAttackResult(turnFight, curBatObj, useSkill, **kwargs)
     
@@ -201,7 +201,7 @@
     useSkill.ResetUseRec()
     return True
 
-def CheckSkillUseCntLimit(batObj, useSkill):
+def CheckSkillUseCntLimit(turnFight, batObj, useSkill):
     ## 检查技能使用次数是否受限
     # @return: 是否受限,None-没有受限效果,False-不受限,True-受限了
     if not hasattr(useSkill, "GetEffectByID"):
@@ -214,12 +214,14 @@
     
     skillID = useSkill.GetSkillID()
     if useCntLimit:
+        useCntLimit += TurnPassive.GetTriggerEffectValue(turnFight, batObj, None, ChConfig.PassiveEff_AddSkillUseCntLimit, useSkill, LimitByTurnAll=1)
         useCnt = batObj.GetSkillUseCnt(skillID)
         if useCnt >= useCntLimit:
             GameWorld.DebugLogEx("技能每场战斗使用次数受限! skillID=%s,useCnt=%s >= %s", skillID, useCnt, useCntLimit)
             return True
         
     if turnUseCntLimit:
+        turnUseCntLimit += TurnPassive.GetTriggerEffectValue(turnFight, batObj, None, ChConfig.PassiveEff_AddSkillUseCntLimit, useSkill, LimitByTurnPer=1)
         turnUseCnt = batObj.GetSkillTurnUseCnt(skillID)
         if turnUseCnt >= turnUseCntLimit:
             GameWorld.DebugLogEx("技能每大回合使用次数受限! skillID=%s,turnUseCnt=%s >= %s", skillID, turnUseCnt, turnUseCntLimit)
@@ -426,6 +428,11 @@
         aimObjList.sort(key=lambda o:(o.GetHP()), reverse=False)
         #GameWorld.DebugLogEx("血量最低排序: %s", [[o.GetID(), o.GetHP(), o.GetMaxHP()] for o in aimObjList])
         
+    # 血量百分比最低
+    elif tagAffect == ChConfig.SkillTagAffect_HPPerLowest:
+        aimObjList.sort(key=lambda o:(o.GetHP() / float(o.GetMaxHP())), reverse=False)
+        #GameWorld.DebugLogEx("血量百分比最低排序: %s", [[o.GetID(), o.GetHP(), o.GetMaxHP(), o.GetHP() / float(o.GetMaxHP())] for o in aimObjList])
+        
     # 血量最高
     elif tagAffect == ChConfig.SkillTagAffect_HPHighest:
         aimObjList.sort(key=lambda o:(o.GetHP()), reverse=True)
@@ -586,6 +593,64 @@
         
     return aimObjList
 
+def __getSameRowObjList(tagObj):
+    ## 获取目标对应的同排对象列表,只算活着的
+    
+    posNum = tagObj.GetPosNum()
+    inRowNum = ChConfig.GetInRowNum(posNum)
+    inColNum = ChConfig.GetInColNum(posNum)
+    # 优先目标所在纵,为主目标
+    colNumList = range(1, 1 + ChConfig.TurnFightCols)
+    if inColNum in colNumList:
+        colNumList.remove(inColNum)
+        colNumList.insert(0, inColNum)
+        
+    row = inRowNum # 目标玩家所在横排
+    
+    batObjMgr = BattleObj.GetBatObjMgr()
+    batLineup = tagObj.GetBatLineup()
+    aimObjList = []
+    for col in colNumList:
+        pNum = (row - 1) * ChConfig.TurnFightCols + col
+        if pNum not in batLineup.posObjIDDict:
+            continue
+        tagObjID = batLineup.posObjIDDict[pNum]
+        tagBatObj = batObjMgr.getBatObj(tagObjID)
+        if not tagBatObj.IsAlive():
+            continue
+        aimObjList.append(tagBatObj)
+        
+    return aimObjList
+
+def __getSameColObjList(tagObj):
+    ## 获取目标对应的同列对象列表,只算活着的
+    
+    posNum = tagObj.GetPosNum()
+    inRowNum = ChConfig.GetInRowNum(posNum)
+    inColNum = ChConfig.GetInColNum(posNum)
+    
+    rowNumList = range(1, 1 + ChConfig.TurnFightRows)
+    if inRowNum in rowNumList:
+        rowNumList.remove(inRowNum)
+        rowNumList.insert(0, inRowNum)
+        
+    col = inColNum # 目标玩家所在纵排
+    
+    batObjMgr = BattleObj.GetBatObjMgr()
+    batLineup = tagObj.GetBatLineup()
+    aimObjList = []
+    for row in range(1, 1 + ChConfig.TurnFightRows):
+        pNum = (row - 1) * ChConfig.TurnFightCols + col
+        if pNum not in batLineup.posObjIDDict:
+            continue
+        tagObjID = batLineup.posObjIDDict[pNum]
+        tagBatObj = batObjMgr.getBatObj(tagObjID)
+        if not tagBatObj.IsAlive():
+            continue
+        aimObjList.append(tagBatObj)
+        
+    return aimObjList
+
 def GetRelativeObj(turnFight, curBatObj):
     '''获取对位目标,仅用于非技能目标的对位逻辑,如连击、弱疗等相对属性的判断,技能目标统一使用 GetSkillTags
     '''
@@ -679,7 +744,7 @@
         
     return
 
-def __doUseSkill(turnFight, curBatObj, useSkill):
+def __doUseSkill(turnFight, curBatObj, useSkill, **kwargs):
     
     atkType = useSkill.GetAtkType()
     GameWorld.DebugLogEx("__doUseSkill: curID=%s,skillID=%s,atkType=%s", curBatObj.GetID(), useSkill.GetSkillID(), atkType)
@@ -689,7 +754,7 @@
     
     # 通用攻击
     if atkType == 1:
-        SkillModule_1(turnFight, curBatObj, useSkill)
+        SkillModule_1(turnFight, curBatObj, useSkill, **kwargs)
     # 治疗
     if atkType == 2:
         SkillModule_2(turnFight, curBatObj, useSkill)
@@ -784,7 +849,7 @@
     Sync_PropertyRefreshView(turnFight, curBatObj, ChConfig.AttrID_HP, updHP, diffValue, diffType, skillID, relatedSkillID, hurtTypes)
     return
 
-def SkillModule_1(turnFight, curBatObj, useSkill):
+def SkillModule_1(turnFight, curBatObj, useSkill, **kwargs):
     ## 通用攻击,单攻、群攻
     
     addPer = 0
@@ -800,7 +865,10 @@
             addPer = addPerMax
         GameWorld.DebugLogEx("司马懿特殊潜能技能额外增加比例: frozenCnt=%s,addPer=%s" % (frozenCnt, addPer))
         
-    addBatDamPer = TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_AddBatDamPerByLayer, useSkill)
+    addBatDamPer = 0
+    if "addBatDamPer" in kwargs:
+        addBatDamPer += kwargs.pop("addBatDamPer", 0)
+    addBatDamPer += TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_AddBatDamPerByLayer, useSkill)
     
     # 计算伤害
     calcHurtResults = []
@@ -1839,6 +1907,10 @@
             GameWorld.DebugLogEx("有击杀目标时该技能无效! enhanceSkillID=%s", enhanceSkillID)
             return
         
+    if checkHeroSex:
+        if TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_IgnoreSex, connSkillTypeID=enhanceSkillData.GetSkillTypeID(), connSkillID=enhanceSkillID):
+            checkHeroSex = 0
+            
     # 继承主技能目标
     if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
         GameWorld.DebugLogEx("继承主技能目标! enhanceSkillID=%s", enhanceSkillID)
@@ -1969,6 +2041,20 @@
         GameWorld.DebugLogEx("被动触发技能,针对来源友军! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s,byFriendID=%s", 
                              effSkillID, effectID, passiveSkillID, bySkillID, byFriendObj.GetID())
         isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
+    # 继承主技能目标同横排 11
+    elif tagAim == ChConfig.SkillTagAim_MainSkillRow:
+        if not tagObj:
+            return
+        GameWorld.DebugLogEx("被动触发技能,针对目标同排对象! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
+        passiveTagObjList = __getSameRowObjList(tagObj)
+        isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
+    # 继承主技能目标同纵排 12
+    elif tagAim == ChConfig.SkillTagAim_MainSkillCol:
+        if not tagObj:
+            return
+        GameWorld.DebugLogEx("被动触发技能,针对目标同纵对象! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
+        passiveTagObjList = __getSameColObjList(tagObj)
+        isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
     else:
         GameWorld.DebugLogEx("被动触发技能,重新锁定目标! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
         isOK = OnUseSkill(turnFight, batObj, passiveSkill, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
@@ -2040,7 +2126,6 @@
         aSuperDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_SuperDamPer, curSkill)
         
         dSuperDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_SuperDamPerDef)
-        GameWorld.DebugLogEx("aSuperDamPer=%s,dSuperDamPerDef=%s", aSuperDamPer, dSuperDamPerDef)
         
     if isParry:
         hurtTypes |= pow(2, ChConfig.HurtAtkType_Parry)
@@ -2068,6 +2153,32 @@
     aFinalDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddFinalDamPer, curSkill)
     aFinalDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_FinalDamPer, curSkill)
     
+    #招架  - 无视攻击方最终增伤百分比
+    dZhaojia = defObj.GetBatAttrValue(ChConfig.AttrID_Zhaojia)
+    aZhaojiaDef = atkObj.GetBatAttrValue(ChConfig.AttrID_ZhaojiaDef)
+    if dZhaojia > aZhaojiaDef:
+        perMoreValue, perReduce = IpyGameDataPY.GetFuncEvalCfg("ZhaojiaCfg", 1) # 每高与对方抗贯穿x值无视y%最终减伤
+        reducePer = (dZhaojia - aZhaojiaDef) / float(perMoreValue) * perReduce
+        reduceMin, reduceMax = IpyGameDataPY.GetFuncEvalCfg("ZhaojiaCfg", 2) # 最小无视百分比|最大无视百分比
+        if reducePer >= reduceMin and GameWorld.CanHappen(IpyGameDataPY.GetFuncCfg("ZhaojiaCfg", 3)):
+            reducePer = min(reducePer, reduceMax)
+            hurtTypes |= pow(2, ChConfig.HurtAtkType_Zhaojia)
+            aFinalDamPer = int(aFinalDamPer * (100 - reducePer) / 100.0) # 按百分比减少
+            GameWorld.DebugLogEx("dZhaojia=%s,aZhaojiaDef=%s,reducePer=%s,aFinalDamPer=%s", dZhaojia, aZhaojiaDef, reducePer, aFinalDamPer)
+            
+    #贯穿  - 无视防守方最终减伤百分比
+    aGuanchuan = atkObj.GetBatAttrValue(ChConfig.AttrID_Guanchuan)
+    dGuanchuanDef = defObj.GetBatAttrValue(ChConfig.AttrID_GuanchuanDef)
+    if aGuanchuan > dGuanchuanDef:
+        perMoreValue, perReduce = IpyGameDataPY.GetFuncEvalCfg("GuanchuanCfg", 1) # 每高与对方抗贯穿x值无视y%最终减伤
+        reducePer = (aGuanchuan - dGuanchuanDef) / float(perMoreValue) * perReduce
+        reduceMin, reduceMax = IpyGameDataPY.GetFuncEvalCfg("GuanchuanCfg", 2) # 最小无视百分比|最大无视百分比
+        if reducePer >= reduceMin and GameWorld.CanHappen(IpyGameDataPY.GetFuncCfg("GuanchuanCfg", 3)):
+            reducePer = min(reducePer, reduceMax)
+            hurtTypes |= pow(2, ChConfig.HurtAtkType_Guanchuan)
+            dFinalDamPerDef = int(dFinalDamPerDef * (100 - reducePer) / 100.0) # 按百分比减少
+            GameWorld.DebugLogEx("aGuanchuan=%s,dGuanchuanDef=%s,reducePer=%s,dFinalDamPerDef=%s", aGuanchuan, dGuanchuanDef, reducePer, dFinalDamPerDef)   
+            
     aNormalSkillPer, dNormalSkillPerDef = 0, 0
     if isTurnNormalSkill:
         aNormalSkillPer = atkObj.GetBatAttrValue(ChConfig.AttrID_NormalSkillPer) # 普技增伤
@@ -2130,7 +2241,6 @@
     if turnFight.isPVP() > 0:
         aPVPDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_PVPDamPer)
         dPVPDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_PVPDamPerDef)
-        GameWorld.DebugLogEx("PVP aPVPDamPer=%s,dPVPDamPerDef=%s", aPVPDamPer, dPVPDamPerDef)
         
     # 所有万分率参数统一除10000.0
     atkSkillPer /= 10000.0
@@ -2159,10 +2269,21 @@
     
     if calcType != ChConfig.Def_Calc_Attack:
         aAtk = GetCalcBaseValue(calcType, atkObj, defObj, curSkill)
-    GameWorld.DebugLogEx("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aBatDamPer=%s,aFinalDamPer=%s", 
-                         atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aBatDamPer, aFinalDamPer)
-    #GameWorld.DebugLogEx("aCountry=%s,dCountry=%s,aCountryDamPer=%s,dCountryDamPerDef=%s", aCountry, dCountry, aCountryDamPer, dCountryDamPerDef)
-    
+    GameWorld.DebugLogEx("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aBatDamPer=%s,dBatDamPerDef=%s,aFinalDamPer=%s,dFinalDamPerDef=%s", 
+                         atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aBatDamPer, dBatDamPerDef, aFinalDamPer, dFinalDamPerDef)
+    if isSuperHit:
+        GameWorld.DebugLogEx("    暴击 aSuperDamPer=%s,dSuperDamPerDef=%s", aSuperDamPer, dSuperDamPerDef)
+    if aPMDamPer or dPMDamPerDef:
+        GameWorld.DebugLogEx("    物法 aPMDamPer=%s,dPMDamPerDef=%s,pmType=%s", aPMDamPer, dPMDamPerDef, pmType)
+    if aComboDamPer or dComboDamPerDef:
+        GameWorld.DebugLogEx("    连击 aComboDamPer=%s,dComboDamPerDef=%s", aComboDamPer, dComboDamPerDef)
+    if aPursueDamPer or dPursueDamPerDef:
+        GameWorld.DebugLogEx("    追击 aPursueDamPer=%s,dPursueDamPerDef=%s", aPursueDamPer, dPursueDamPerDef)
+    if aPVPDamPer or dPVPDamPerDef:
+        GameWorld.DebugLogEx("    PVP aPVPDamPer=%s,dPVPDamPerDef=%s", aPVPDamPer, dPVPDamPerDef)
+    if aCountryDamPer or dCountryDamPerDef:
+        GameWorld.DebugLogEx("    国家 aCountry=%s,dCountry=%s,aCountryDamPer=%s,dCountryDamPerDef=%s", aCountry, dCountry, aCountryDamPer, dCountryDamPerDef)
+        
     if isTurnNormalSkill:
         hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
         GameWorld.DebugLogEx("    普攻技能伤害=%s,aNormalSkillPer=%s,dNormalSkillPerDef=%s", hurtValue, aNormalSkillPer, dNormalSkillPerDef)
@@ -2171,7 +2292,7 @@
         GameWorld.DebugLogEx("    怒气技能伤害=%s,aAngerSkillPer=%s,dAngerSkillPerDef=%s", hurtValue, aAngerSkillPer, dAngerSkillPerDef)
     elif isDot:
         hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
-        GameWorld.DebugLogEx("    持续技能伤害=%s" % (hurtValue))
+        GameWorld.DebugLogEx("    持续技能伤害=%s,aDOTPer=%s,dDOTPerDef=%s", hurtValue, aDOTPer, dDOTPerDef)
     elif calcType == ChConfig.Def_Calc_ByBuffValue:
         hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("CalcTypeFormula", 2))
         GameWorld.DebugLogEx("    按最后一次buff值计算伤害=%s,calcType=%s,LastHurt=%s", hurtValue, calcType, aAtk)
@@ -2201,14 +2322,25 @@
         GameWorld.DebugLogEx("    伤害最高限制: hurtValue=%s,hurtAtkPerMax=%s,aAtk=%s", hurtValue, hurtAtkPerMax, aAtk)
         
     # 均摊
-    hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
-    if hurtShareEff:
+    if HaveShareEff(atkObj, curSkill):
         tagCnt = max(1, len(curSkill.GetTagObjList()))
         hurtValue = hurtValue / tagCnt
         GameWorld.DebugLogEx("    目标均摊伤害: hurtValue=%s,tagCnt=%s", hurtValue, tagCnt)
         
     hurtValue = max(1, int(hurtValue)) # 负值、保底防范,放最后
     return hurtValue, hurtTypes
+
+def HaveShareEff(atkObj, curSkill):
+    ## 玩家技能是否有分摊效果: 均摊伤害/治疗/承伤盾值
+    hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
+    if not hurtShareEff:
+        return False
+    needLearnSkillID = hurtShareEff.GetEffectValue(0)
+    if needLearnSkillID:
+        if not atkObj.GetSkillManager().FindSkillByID(needLearnSkillID):
+            GameWorld.DebugLogEx("所需技能未学习,分摊效果不生效! skillID=%s,needLearnSkillID=%s", curSkill.GetSkillID(), needLearnSkillID)
+            return False
+    return True
 
 def GetAddSkillPer(turnFight, atkObj, defObj, curSkill):
     ## 获取额外增加的技能万分比
@@ -2223,7 +2355,6 @@
 
 def CanSuperHit(turnFight, atkObj, defObj, curSkill):
     if TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_MustSuperHit, curSkill):
-        GameWorld.DebugLogEx("目标血量低于百分x时必定暴击: defID=%s,hp:%s/%s", defObj.GetID(), defObj.GetHP(), defObj.GetMaxHP())
         return True
     
     aSuperHitRate = atkObj.GetBatAttrValue(ChConfig.AttrID_SuperHitRate)
@@ -2708,6 +2839,8 @@
     buffMgr = defObj.GetBuffManager()
     for buff in buffMgr.FindBuffListByState(ChConfig.BatObjState_DamBackShield):
         damBackPer += buff.GetValue1()
+        connSkillTypeID = buff.GetSkillTypeID()
+        damBackPer += TurnPassive.GetTriggerEffectValue(turnFight, defObj, atkObj, ChConfig.PassiveEff_AddDamBackPerByBuffLayer, connSkillTypeID=connSkillTypeID)
         
     if damBackPer <= 0:
         return
@@ -2827,8 +2960,7 @@
         cureHP = int(cureHP * multiValue)
         GameWorld.DebugLogEx("    治疗倍值: cureHP=%s,multiValue=%s", cureHP, multiValue)
         
-    hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
-    if hurtShareEff:
+    if HaveShareEff(userObj, curSkill):
         tagCnt = max(1, len(curSkill.GetTagObjList()))
         cureHP = cureHP / tagCnt
         GameWorld.DebugLogEx("    目标均摊治疗: cureHP=%s,tagCnt=%s", cureHP, tagCnt)

--
Gitblit v1.8.0