129 【战斗】战斗系统-服务端(孙坚技能;增加释放方式1005支持:根据击中的目标状态目标数额外buff属性; buff状态组限制改为支持配置数组;)
5个文件已修改
1个文件已添加
118 ■■■■ 已修改文件
PySysDB/PySysDBPY.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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层数
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):
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
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()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1005.py
New file
@@ -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
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)