From 3047503c169b6f73a383335d0953b489412ce154 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 27 十月 2025 16:44:08 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(孙坚技能;增加释放方式1005支持:根据击中的目标状态目标数额外buff属性; buff状态组限制改为支持配置数组;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py                   |   15 +++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py                 |   21 ++++++----
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                    |    4 +-
 PySysDB/PySysDBPY.h                                                                                     |    2 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py                  |    9 ++--
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py |   67 +++++++++++++++++++++++++++++++++
 6 files changed, 102 insertions(+), 16 deletions(-)

diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index 6ff7600..e8522c9 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -111,7 +111,7 @@
 	BYTE		TriggerWay3;	//触发方式
 	BYTE		TriggerSrc3;	//有效来源
 	WORD		CoolDownTime;	//技能冷却时间
-	WORD		BuffStateLimit;	//Buff状态限制组
+	list		BuffStateLimit;	//Buff状态限制组
 	BYTE		CurBuffState;	//Buff状态值
 	WORD		LastTime;	//持续时间
 	BYTE		LayerCnt;	//Buff层数
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 5437571..183349d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -543,6 +543,7 @@
         self._batType = 0 # 战斗类型,普通、连击、反击、追击等
         self._tagObjList = [] # 本次技能目标列表 [BatObj, ...]
         self._killObjList = [] # 本次技能击杀目标列表 [BatObj, ...]
+        self._effIgnoreObjIDList = [] # 额外技能效果无效的目标ID列表,一般是被闪避、免疫等
         self._hurtList = [] # 本次伤血列表,可能同一个对象有多个伤害,如弹射等 [HurtObj, ...]
         self._bySkill = None # 由哪个技能触发的
         self._byBuff = None # 由哪个buff触发的
@@ -566,6 +567,7 @@
         self._batType = 0
         self._tagObjList = []
         self._killObjList = []
+        self._effIgnoreObjIDList = []
         self._bySkill = None
         self._byBuff = None
         self._afterLogicList = []
@@ -623,6 +625,8 @@
     def SetTagObjList(self, tagObjList): self._tagObjList = tagObjList
     def GetKillObjList(self): return self._killObjList # 击杀目标列表
     def SetKillObjList(self, killObjList): self._killObjList = killObjList
+    def GetEffIgnoreObjIDList(self): return self._effIgnoreObjIDList # 额外技能效果无效的目标ID列表
+    def SetEffIgnoreObjIDList(self, effIgnoreObjIDList): self._effIgnoreObjIDList = effIgnoreObjIDList
     def GetAfterLogicList(self): return self._afterLogicList
     def AddAfterLogic(self, logicType, logicData):
         '''添加技能释放后需要处理额外逻辑
@@ -905,18 +909,19 @@
                 return True
         return False
     
-    def IsInControlled(self): return self.IsInBuffStateGroup(1) or self.IsInBuffStateGroup(2) # 是否被控制中
-    def IsInControlledHard(self): return self.IsInBuffStateGroup(1) # 是否被硬控中
-    def IsInBuffStateGroup(self, buffStateGroup):
+    def IsInControlled(self): return self.IsInBuffStateGroup([1, 2]) # 是否被控制中
+    def IsInControlledHard(self): return self.IsInBuffStateGroup([1]) # 是否被硬控中
+    def IsInBuffStateGroup(self, buffStateGroups):
         '''是否在某个状态组中
                         已定义的组: 1 - 硬控组;2 - 软控组;3 - 限制普攻组;4 - 限制怒技组;5 - 限制被动动态组
         '''
         buffStateGroupDict = IpyGameDataPY.GetFuncEvalCfg("BuffStateGroup", 1, {})
-        if buffStateGroup not in buffStateGroupDict:
-            return
-        for state in buffStateGroupDict[buffStateGroup]:
-            if self._buffMgr.IsInBuffState(state):
-                return state
+        for stateGroup in buffStateGroups:
+            if str(stateGroup) not in buffStateGroupDict:
+                continue
+            for state in buffStateGroupDict[str(stateGroup)]:
+                if self._buffMgr.IsInBuffState(state):
+                    return state
         return
     
     def CanAction(self):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index e3bc504..ee4a1ed 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -133,7 +133,7 @@
                         ("BYTE", "TriggerWay3", 0),
                         ("BYTE", "TriggerSrc3", 0),
                         ("WORD", "CoolDownTime", 0),
-                        ("WORD", "BuffStateLimit", 0),
+                        ("list", "BuffStateLimit", 0),
                         ("BYTE", "CurBuffState", 0),
                         ("WORD", "LastTime", 0),
                         ("BYTE", "LayerCnt", 0),
@@ -2544,7 +2544,7 @@
     def GetTriggerWay3(self): return self.attrTuple[28] # 触发方式 BYTE
     def GetTriggerSrc3(self): return self.attrTuple[29] # 有效来源 BYTE
     def GetCoolDownTime(self): return self.attrTuple[30] # 技能冷却时间 WORD
-    def GetBuffStateLimit(self): return self.attrTuple[31] # Buff状态限制组 WORD
+    def GetBuffStateLimit(self): return self.attrTuple[31] # Buff状态限制组 list
     def GetCurBuffState(self): return self.attrTuple[32] # Buff状态值 BYTE
     def GetLastTime(self): return self.attrTuple[33] # 持续时间 WORD
     def GetLayerCnt(self): return self.attrTuple[34] # Buff层数 BYTE
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
index f96f0fa..c20f95a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
@@ -27,10 +27,15 @@
 GameWorld.ImportAll("Script\\Skill\\", "TurnBuffs")
 
 def GetAddBuffValue(turnFight, attacker, defender, curSkill):
+    if not curSkill.GetAtkType():
+        return []
     callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (curSkill.GetAtkType(), "CalcBuffValue"))
     if not callFunc:
         return []
-    return callFunc(turnFight, attacker, defender, curSkill)
+    ret = callFunc(turnFight, attacker, defender, curSkill)
+    if ret == None:
+        return []
+    return ret
 
 def CopyBuff(turnFight, curBatObj, curBuff, tagBuff, bySkill=None, isNewAdd=False):
     '''拷贝buff数据,不含目标buffID、归属,并刷新时间
@@ -320,6 +325,8 @@
 
 def DoBuffProcess(turnFight, batObj, curBuff):
     skillData = curBuff.GetSkillData()
+    if not skillData.GetAtkType():
+        return
     callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (skillData.GetAtkType(), "DoBuffProcess"))
     if callFunc:
         callFunc(turnFight, batObj, curBuff)
@@ -345,6 +352,12 @@
         buff = buffMgr.GetBuffByIndex(index)
         layer = max(1, buff.GetLayer())
         skillData = buff.GetSkillData()
+        atkType = skillData.GetAtkType()
+        if atkType:
+            callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (atkType, "CalcBuffAttrEx"))
+            if callFunc:
+                callFunc(batObj, buff, skillData, layer, buffAttrDict)
+                
         for eIndex in range(skillData.GetEffectCount()):
             effect = skillData.GetEffect(eIndex)
             effID = effect.GetEffectID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py
new file mode 100644
index 0000000..f15fd29
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnBuffs.BuffAtkType_1005
+#
+# @todo:额外属性
+# @author hxp
+# @date 2025-10-27
+# @version 1.0
+#
+# 详细描述: 额外属性,效果1值配置:[击中x状态]|增加属性ID|每击中1个增加属性值
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-10-27 17:00"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+
+def CalcBuffValue(turnFight, attacker, defender, curSkill):
+    bySkill = curSkill.GetBySkill()
+    if not bySkill:
+        return
+    
+    effect = curSkill.GetEffect(0)
+    checkInStateList = effect.GetEffectValue(0)
+    attrIDEx = effect.GetEffectValue(1)
+    attrValueEx = effect.GetEffectValue(2)
+    #GameWorld.DebugLog("BuffAtkType_1005 检查额外属性: checkInStateList=%s,attrIDEx=%s,attrValueEx=%s" % (checkInStateList, attrIDEx, attrValueEx))
+    if not checkInStateList or not attrIDEx or not attrValueEx:
+        return
+    
+    hitCnt = 0
+    effIgnoreObjIDList = bySkill.GetEffIgnoreObjIDList()
+    tagObjList = bySkill.GetTagObjList()
+    for tagObj in tagObjList:
+        tagID = tagObj.GetID()
+        if tagID in effIgnoreObjIDList:
+            #GameWorld.DebugLog("    闪避或免疫的目标: tagID=%s" % (tagID))
+            continue
+        if not tagObj.CheckInState(checkInStateList):
+            #GameWorld.DebugLog("    不在状态下的目标: tagID=%s not in state:%s" % (tagID, checkInStateList))
+            continue
+        hitCnt += 1
+        #GameWorld.DebugLog("    hitCnt=%s,tagID=%s" % (hitCnt, tagID))
+        
+    if hitCnt <= 0:
+        return
+    
+    return [hitCnt]
+
+def CalcBuffAttrEx(batObj, buff, skillData, layer, buffAttrDict):
+    ## 计算buff额外属性
+    hitCnt = buff.GetValue1()
+    effect = skillData.GetEffect(0)
+    attrID = effect.GetEffectValue(1)
+    attrValue = effect.GetEffectValue(2) * hitCnt * layer
+    if not attrID or not attrValue:
+        return
+    calcType = effect.GetEffectValue(3)
+    if calcType == 2: # 减少,其他默认增加
+        attrValue = -attrValue
+    buffAttrDict[attrID] = buffAttrDict.get(attrID, 0) + attrValue
+    GameWorld.DebugLog("    buff额外属性: skillID=%s,hitCnt=%s,attrID=%s,attrValue=%s" % (skillData.GetSkillID(), hitCnt, attrID, attrValue))
+    return
+
+
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 3b23e4c..af1e1e4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -62,11 +62,11 @@
     if not curBatObj.CanAction():
         return
     
-    buffStateLimit = useSkill.GetBuffStateLimit()
-    if buffStateLimit:
-        limitState = curBatObj.IsInBuffStateGroup(buffStateLimit)
+    buffStateGroups = useSkill.GetBuffStateLimit()
+    if buffStateGroups:
+        limitState = curBatObj.IsInBuffStateGroup(buffStateGroups)
         if limitState:
-            GameWorld.DebugLog("技能使用处于buff状态限制中! skillID=%s,buffStateLimit=%s,limitState=%s" % (skillID, buffStateLimit, limitState))
+            GameWorld.DebugLog("技能使用处于buff状态限制中! skillID=%s,buffStateGroups=%s,limitState=%s" % (skillID, buffStateGroups, limitState))
             return
         
     #没有指定目标,则按技能自身的目标逻辑
@@ -879,6 +879,7 @@
         FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
         
     effIgnoreObjIDList = missObjIDList + immuneObjIDList
+    useSkill.SetEffIgnoreObjIDList(effIgnoreObjIDList)
     # 优先触发本技能额外效果,注:仅该技能释放后该技能的额外效果视为主技能的效果,优先级最高
     __DoCurSkillEff(turnFight, curObj, useSkill, effIgnoreObjIDList, isUseSkill)
     

--
Gitblit v1.8.0