From 68c06a7abc6ad911baf81bde36e68019ecd1a11d Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 22 十二月 2025 19:06:15 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(小乔所有技能;增加触发方式53-友方造成持续伤害时;优化效果5022 5507 5509;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5022.py |    7 +-
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py                     |    8 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5507.py |   20 ++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py                    |    9 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5509.py |   36 +++++++++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py                      |   45 ++++++++++----
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                             |    3 
 7 files changed, 94 insertions(+), 34 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 e389169..061f81e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -509,7 +509,7 @@
         return
     
     def GetBuffCount(self): return len(self._buffList)
-    def GetBuffByIndex(self, index): return self._buffList[index]
+    def GetBuffByIndex(self, index): return self._buffList[index] if len(self._buffList) > index else None
     
     def AddBuff(self, skillID):
         buff = None
@@ -906,6 +906,7 @@
         self._hp = 0 # 当前生命值
         self._xp = 0 # 当前怒气值
         self._isAlive = True # 是否活着
+        self._killer = None # 被谁击杀的
         self._initAttrDict = {} # 初始化时的属性,固定不变,初始化时已经算好的属性  {attrID:value, ...}
         self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性 {attrID:+-value, ...} value可能是负值
         self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...} value可能是负值
@@ -1103,12 +1104,15 @@
     
     # 战斗属性
     def IsAlive(self): return self._isAlive # 是否活着
-    def SetDead(self):
+    def SetDead(self, killer=None):
+        self._killer = killer
         self._isAlive = False
         self._hp = 0
     def SetRevive(self, hp):
+        self._killer = None
         self._isAlive = True
         self._hp = hp
+    def GetKiller(self): return self._killer
     def GetMaxHP(self): return int(self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0))
     def SetMaxHP(self, maxHP, isNotify=False):
         maxHP = int(maxHP)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index a8e07ca..eb1b7c0 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -138,6 +138,11 @@
             deadCnt += 1
         return deadCnt
     
+    def getHeroObj(self, heroID):
+        if heroID not in self.heroObjIDDict:
+            return
+        return BattleObj.GetBatObjMgr().getBatObj(self.heroObjIDDict[heroID])
+    
 class BatFaction():
     ## 战斗阵营
     
@@ -1868,6 +1873,8 @@
     buffMgr = batObj.GetBuffManager()
     for index in range(buffMgr.GetBuffCount())[::-1]:
         buff = buffMgr.GetBuffByIndex(index)
+        if not buff: # 有出现过报错,先做下防范,理论上不太可能
+            continue
         buffID = buff.GetBuffID()
         skillID = buff.GetSkillID()
         skillData = buff.GetSkillData()
@@ -2033,7 +2040,7 @@
     killerObjID = killer.GetID() if killer else 0
     skillID = useSkill.GetSkillID() if useSkill else 0
     GameWorld.DebugLogEx("        %s 回合战斗主体被击杀: curID=%s,killerObjID=%s,skillID=%s", GetObjName(gameObj), objID, killerObjID, skillID)
-    gameObj.SetDead()
+    gameObj.SetDead(killer)
     TurnBuff.DoBuffByDead(turnFight, gameObj)
     
     clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 7ea8031..97ad37d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -4029,7 +4029,8 @@
 TriggerWay_FriendAttackOverDirectOne, # 友方使用技能后(多目标仅触发一次,包含自己) 50
 TriggerWay_FriendAttackOverDirectOneNoSelf, # 友方使用技能后(多目标仅触发一次,不含自己) 51
 TriggerWay_DOTHurt, # 造成持续伤害时 52
-) = range(1, 1 + 52)
+TriggerWay_FriendDotHurt, # 友方造成持续伤害时(多目标仅触发一次,包含自己) 53
+) = range(1, 1 + 53)
 
 # 不加载的被动触发方式,一般用于本技能固定触发逻辑用的
 TriggerWayNoLoadList = [TriggerWay_CurSkillEff, TriggerWay_CurSkillEffLst]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5022.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5022.py
index db19eb2..e196c5b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5022.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5022.py
@@ -29,6 +29,7 @@
         # 100 - 按友方某个国家武将数  参数1:国家
         if ruleType == 100:
             country = calcRule[1] if len(calcRule) > 1 else 0
+            onlyAlive = calcRule[2] if len(calcRule) > 2 else 0
             batLineup = batObj.GetBatLineup()
             countryCnt = 0
             batObjMgr = BattleObj.GetBatObjMgr()
@@ -38,11 +39,11 @@
                     continue
                 if batObj.GetCountry() != country:
                     continue
-                #if batObj.IsAlive(): # 死亡也算
-                #    continue
+                if onlyAlive and not batObj.IsAlive():
+                    continue
                 countryCnt += 1
             calcLayer = countryCnt
-            GameWorld.DebugLogEx("按友方某个国家武将数计算额外buff属性: ruleType=%s,country=%s,countryCnt=%s", ruleType, country, countryCnt)
+            GameWorld.DebugLogEx("按友方某个国家武将数计算额外buff属性: ruleType=%s,country=%s,countryCnt=%s,onlyAlive=%s", ruleType, country, countryCnt, onlyAlive)
         # 101 - 仅对指定性别有效  参数1:性别
         elif ruleType == 101:
             onlySex = calcRule[1] if len(calcRule) > 1 else 0
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5507.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5507.py
index 93d9a64..85a4eff 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5507.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5507.py
@@ -24,14 +24,20 @@
     passiveSkillID = curEffect.GetEffectValue(0) # 技能ID,为0时释放本技能
     effHeroID = curEffect.GetEffectValue(1) # 指定目标武将ID
     costHPPer = curEffect.GetEffectValue(2) # 可附加消耗自身血量百分比,配0不消耗,大于0血量不足时不释放
+    searchFrom = curEffect.GetEffectValue(3) # 目标武将ID是否从阵容中搜索
     
-    if not effHeroID or not tagObj:
+    tagHero = tagObj
+    if searchFrom:
+        batLineup = batObj.GetBatLineup()
+        tagHero = batLineup.getHeroObj(effHeroID)
+        
+    if not effHeroID or not tagHero:
         return
     
-    if tagObj.IsAlive():
+    if tagHero.IsAlive():
         return
     
-    tagHeroID = tagObj.GetHeroID()
+    tagHeroID = tagHero.GetHeroID()
     if tagHeroID != effHeroID:
         #GameWorld.DebugLogEx("5507非目标武将死亡不处理! tagHeroID=%s,effHeroID=%s", tagHeroID, effHeroID)
         return
@@ -41,11 +47,11 @@
     if not passiveSkillID:
         return
     
-    if tagObj.CheckInState(ChConfig.BatObjState_RebornLimit):
+    if tagHero.CheckInState(ChConfig.BatObjState_RebornLimit):
         GameWorld.DebugLogEx("5507目标被禁止复活不处理! tagHeroID=%s", tagHeroID)
         return
     
-    tagID = tagObj.GetID()
+    tagID = tagHero.GetID()
     if costHPPer:
         curHP = batObj.GetHP()
         maxHP = batObj.GetMaxHP()
@@ -56,8 +62,8 @@
         GameWorld.DebugLogEx("5507扣血复活指定目标! curHP=%s/%s,costHPPer=%s,costHP=%s,tagHeroID=%s,tagID=%s", curHP, maxHP, costHPPer, costHP, tagHeroID, tagID)
         batObj.SetHP(max(1, curHP - costHP), True) # 直接扣除
     else:
-        GameWorld.DebugLogEx("5507直接复活指定目标! curHP=%s/%s,costHPPer=%s,costHP=%s,tagHeroID=%s,tagID=%s", curHP, maxHP, costHPPer, costHP, tagHeroID, tagID)
+        GameWorld.DebugLogEx("5507直接复活指定目标! tagHeroID=%s,tagID=%s,searchFrom=%s", tagHeroID, tagID, searchFrom)
         
     effectID = curEffect.GetEffectID()
     effSkillID = effSkill.GetSkillID()
-    return TurnSkill.OnUsePassiveSkill(turnFight, batObj, tagObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
+    return TurnSkill.OnUsePassiveSkill(turnFight, batObj, tagHero, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5509.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5509.py
index 7dac9f2..3a733e1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5509.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5509.py
@@ -24,13 +24,27 @@
     byFriendObj = kwargs.pop("byFriendObj") # 直接取出,防止传递
     
     passiveSkillID = curEffect.GetEffectValue(0) # 技能ID,为0时释放本技能
-    byHeorID = curEffect.GetEffectValue(1) # 仅友军武将ID时有效(验证用,不一定是技能目标)
+    byFriendRule = curEffect.GetEffectValue(1) # 友军验证规则[验证方式, 验证值]
+    tagRule = curEffect.GetEffectValue(2) # 指定目标 0-按技能,1-对击杀方,2-对来源友军,3-对关联对象
     
-    friendHeroID = byFriendObj.GetHeroID()
-    if friendHeroID != byHeorID:
-        GameWorld.DebugLogEx("5509非友军触发来源不处理! friendHeroID=%s != %s", friendHeroID, byHeorID)
-        return
-    
+    if byFriendRule:
+        checkType = byFriendRule[0]
+        # 验证方式 1 - 按武将ID, 值-武将ID
+        if checkType == 1:
+            byHeorID = byFriendRule[1] if len(byFriendRule) > 1 else 0
+            friendHeroID = byFriendObj.GetHeroID()
+            if friendHeroID != byHeorID:
+                GameWorld.DebugLogEx("5509友军武将非触发来源不处理! friendHeroID=%s != %s", friendHeroID, byHeorID)
+                return
+            
+        # 验证方式 2 - 按国家, 值-国家
+        elif checkType == 2:
+            byCountry = byFriendRule[1] if len(byFriendRule) > 1 else 0
+            friendCountry = byFriendObj.GetCountry()
+            if friendCountry != byCountry:
+                GameWorld.DebugLogEx("5509友军国家非触发来源不处理! friendCountry=%s != %s", friendCountry, byCountry)
+                return
+            
     if not passiveSkillID:
         passiveSkillID = effSkill.GetSkillID()
     if not passiveSkillID:
@@ -38,4 +52,12 @@
     
     effectID = curEffect.GetEffectID()
     effSkillID = effSkill.GetSkillID()
-    return TurnSkill.OnUsePassiveSkill(turnFight, batObj, byFriendObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
+    toTagObj = None
+    if tagRule == 1:
+        toTagObj = byFriendObj.GetKiller()
+    elif tagRule == 2:
+        toTagObj = byFriendObj
+    elif tagRule == 3:
+        toTagObj = tagObj
+        
+    return TurnSkill.OnUsePassiveSkill(turnFight, batObj, toTagObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
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 3474507..ed4d6c5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -62,8 +62,8 @@
     skillType = useSkill.GetSkillType()
     byTriggerWay = kwargs["byTriggerWay"] if "byTriggerWay" in kwargs else 0 # 不使用参数名 triggerWay, 防止传递过程中参数混乱
     if not curBatObj.IsAlive():
-        if skillType == ChConfig.Def_SkillType_Revive and useSkill.GetTagAim() == ChConfig.SkillTagAim_Self:
-            GameWorld.DebugLogEx("死亡时使用复活自己的技能! skillID=%s", skillID)
+        if skillType == ChConfig.Def_SkillType_Revive:
+            GameWorld.DebugLogEx("死亡时使用复活技能! skillID=%s", skillID)
         else:
             if byTriggerWay in ChConfig.DeadCanTriggerWayList:
                 GameWorld.DebugLogEx("死亡可触发的方式触发技能可释放! skillID=%s,byTriggerWay=%s", skillID, byTriggerWay)
@@ -756,9 +756,13 @@
         return
     harmPer = harmEff.GetEffectValue(0) # 自残百分比
     noEnoughDo = harmEff.GetEffectValue(1) # 不足时扣除方式 0-不扣;1-自杀;2-扣剩1点
+    calcType = harmEff.GetEffectValue(2) # 计算方式:0-按最大血量;1-按当前血量
     curHP = curBatObj.GetHP()
     maxHP = curBatObj.GetMaxHP()
-    harmHP = int(maxHP * harmPer / 100.0)
+    if calcType == 1:
+        harmHP = int(curHP * harmPer / 100.0)
+    else:
+        harmHP = int(maxHP * harmPer / 100.0)
     lostHP = harmHP
     if curHP <= harmHP:
         if noEnoughDo == 0:
@@ -768,8 +772,8 @@
             
     updHP = max(curHP - lostHP, 0)
     curBatObj.SetHP(updHP, False)
-    GameWorld.DebugLogEx("使用技能时自残: curHP=%s/%s,harmPer=%s,harmHP=%s,lostHP=%s,updHP=%s,noEnoughDo=%s", 
-                         curHP, maxHP, harmPer, harmHP, lostHP, updHP, noEnoughDo)
+    GameWorld.DebugLogEx("使用技能时自残: curHP=%s/%s,harmPer=%s,harmHP=%s,lostHP=%s,updHP=%s,noEnoughDo=%s,calcType=%s", 
+                         curHP, maxHP, harmPer, harmHP, lostHP, updHP, noEnoughDo, calcType)
     
     curBatObj.SetHarmSelfHP(harmHP) # 无视实际扣血量,直接更新
     
@@ -1355,11 +1359,7 @@
                 killObjList.append(tagObj)
             TurnAttack.SetObjKilled(turnFight, tagObj, curObj, useSkill)
     useSkill.SetKillObjList(killObjList)
-    # 判断自己,因为反弹、平摊伤害的原因,有可能自己干死自己
-    if curObj.IsAlive() and curObj.GetHP() <= 0:
-        dieObjList.append(curObj)
-        TurnAttack.SetObjKilled(turnFight, curObj)
-        
+    
     # 统计伤血,可能单个技能对同一目标造成多次伤害
     totalHurtValue = 0
     isSuckHP = False
@@ -1367,11 +1367,18 @@
     stunObjIDList, superHitObjIDList, parryObjIDList = [], [], []
     beHurtObjIDList = [] # 受伤的对象ID列表
     reviveObjList = [] # 复活的对象列表
+    bounceObjList = [] # 有反弹的对象列表
     for hurtObj in useSkill.GetHurtObjListAll():
         hurtObjID = hurtObj.GetObjID()
         tagObj = batObjMgr.getBatObj(hurtObjID)
         if not tagObj:
             continue
+        
+        bounceHP = hurtObj.GetBounceHP()
+        if bounceHP:
+            if tagObj not in bounceObjList:
+                bounceObjList.append(tagObj)
+                
         if hurtObj.HaveHurtType(ChConfig.HurtAtkType_Hurt) and not hurtObj.HaveHurtType(ChConfig.HurtAtkType_Immune) \
             and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
             __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
@@ -1411,6 +1418,12 @@
         if hurtObj.GetSuckHP() > 0:
             isSuckHP = True
             
+    # 判断自己死亡,因为反弹、平摊伤害的原因,有可能自己干死自己
+    if curObj.IsAlive() and curObj.GetHP() <= 0:
+        dieObjList.append(curObj)
+        killer = bounceObjList[0] if bounceObjList else None
+        TurnAttack.SetObjKilled(turnFight, curObj, killer)
+        
     # 记录最后一次总伤害,有伤害目标才记录
     if totalHurtValue:
         curObj.SetLastHurtValue(totalHurtValue)
@@ -1466,7 +1479,7 @@
                     for dieObj in dieObjList:
                         # 敌方单位死亡时
                         if lineupObj.GetFaction() != dieObj.GetFaction():
-                            TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_EnemyDie, dieObj, connSkill=useSkill)
+                            TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_EnemyDie, dieObj, connSkill=useSkill, byKiller=curObj)
                         # 己方单位死亡时
                         else:
                             TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendDie, dieObj, connSkill=useSkill, byFriendObj=dieObj)
@@ -1509,6 +1522,7 @@
         if isExObj:
             continue
         
+        isDotHurt = False
         # 直接攻击
         if isAttackDirect:
             if not triggerOne:
@@ -1519,6 +1533,7 @@
         elif not isAttackDirect:
             # 受到持续伤害
             if tagID in beHurtObjIDList:
+                isDotHurt = True
                 TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_DOTHurt, tagObj, connSkill=useSkill, connBuff=timeBuff)
                 TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeDOTHurt, curObj, connSkill=useSkill, connBuff=timeBuff)
                 
@@ -1558,7 +1573,7 @@
             
             
         # 敌友方
-        if isAttackDirect or batType in [ChConfig.TurnBattleType_Combo, ChConfig.TurnBattleType_Pursue]:
+        if isAttackDirect or batType in [ChConfig.TurnBattleType_Combo, ChConfig.TurnBattleType_Pursue] or isDotHurt:
             if not curBatLineup:
                 curBatLineup = curObj.GetBatLineup()
             for lineupObjID in curBatLineup.posObjIDDict.values():
@@ -1572,7 +1587,11 @@
                         TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendAttackOverDirectOne, tagObj, connSkill=useSkill, byFriendObj=curObj)
                         if curID != lineupObj.GetID():
                             TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendAttackOverDirectOneNoSelf, tagObj, connSkill=useSkill, byFriendObj=curObj)
-                            
+                # 持续伤害
+                elif isDotHurt:
+                    if not triggerOne:
+                        TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendDotHurt, tagObj, connSkill=useSkill, byFriendObj=curObj)
+                        
                 # 连击
                 if batType == ChConfig.TurnBattleType_Combo:
                     TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendCombo, tagObj, connSkill=useSkill, byFriendObj=curObj)

--
Gitblit v1.8.0