129 【战斗】战斗系统-服务端(反击改为使用普攻,去除通用反击技能设定;武将特长支持;)
8个文件已修改
113 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -143,6 +143,7 @@
    dict        BatAttrDict;    //其他战斗属性字典 {"属性ID":值, ...}
    list        FetterIDList;    //羁绊ID列表
    BYTE        RecruitBySelf;    // 招募需要本体
    BYTE        Specialty;    // 武将特长
};
//武将星级天赋表
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
@@ -433,28 +433,6 @@
    #NPC读表取
    return attack.GetHurtType()
def GetAtkDistType(curObj):
    ## 获取是近战还是远程,默认近战
    if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
        return ChConfig.AtkDistType_Short
    playerID = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID)
    if not playerID:
        return ChConfig.AtkDistType_Short
    heroID = curObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
    if heroID:
        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
        if heroIpyData:
            return heroIpyData.GetAtkDistType()
    npcID = curObj.GetNPCID()
    npcDataEx = NPCCommon.GetNPCDataPy(npcID)
    if npcDataEx:
        return npcDataEx.GetAtkDistType()
    return ChConfig.AtkDistType_Short
#--------------------------------------------------------------------------
## 设置玩家进入战斗状态
#  @param defender 当前玩家(被攻击了)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -599,6 +599,7 @@
        self.skinID = 0
        self.country = 0
        self.atkDistType = 0
        self.specialty = 0 # 特长
        self.sex = 0
        self.lv = 1
        self.fightPower = 0
@@ -668,6 +669,8 @@
    def SetCountry(self, country): self.country = country
    def GetAtkDistType(self): return self.atkDistType
    def SetAtkDistType(self, atkDistType): self.atkDistType = atkDistType
    def GetSpecialty(self): return self.specialty
    def SetSpecialty(self, specialty): self.specialty = specialty
    def GetSex(self): return self.sex
    def SetSex(self, sex): self.sex = sex
    def GetNPCID(self): return self.npcID # 如果是NPC战斗单位,则该值非0
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -728,11 +728,9 @@
    
    batObjMgr = BattleObj.GetBatObjMgr()
    initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
    atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 2)
    for posNumKey, heroInfo in heroDict.items():
        posNum = int(posNumKey)
        
        atkBackSkillID = 0 # 反击技能ID
        fightPower = 0
        skillIDList = [] # 战斗对象可能改变属性或技能,重新创建,防止误修改来源值
        attrDict = {}
@@ -744,6 +742,7 @@
        lv = heroInfo.get("LV", 1)
        heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None
        if heroIpyData:
            specialty = heroIpyData.GetSpecialty()
            atkDistType = heroIpyData.GetAtkDistType()
            objName = heroIpyData.GetName()
            country = heroIpyData.GetCountry()
@@ -759,6 +758,7 @@
            if not npcDataEx:
                continue
            if not heroIpyData:
                specialty = 0
                atkDistType = npcDataEx.GetAtkDistType()
                objName = npcDataEx.GetNPCName()
                country = npcDataEx.GetCountry()
@@ -779,16 +779,11 @@
        batObj.SetFightPower(fightPower)
        batObj.SetLV(lv)
        batObj.SetAtkDistType(atkDistType)
        batObj.SetSpecialty(specialty)
        batObj.SetCountry(country)
        batObj.SetSex(sex)
        batObj.SetHero(heroID, skinID)
        
        if atkDistType == ChConfig.AtkDistType_Short:
            atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
        elif atkDistType == ChConfig.AtkDistType_Long:
            atkBackSkillID = atkBackSkillIDList[1] if len(atkBackSkillIDList) > 1 else 0
        if atkBackSkillID:
            skillIDList.append(atkBackSkillID)
        skillManager = batObj.GetSkillManager()
        skillManager.SkillReset()
        for skillID in skillIDList:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -960,9 +960,9 @@
HurtType_3,
HurtType_4,
HurtType_Parry,             # 格挡 5
HurtType_IgnoreDef,         # 无视防御 6
HurtType_IgnoreDef,         # 无视防御/真实伤害 6
HurtType_SuperHit,          # 暴击 7
HurtType_8,
HurtType_Stun,              # 击晕 8 仅算概率触发的击晕,技能额外击晕效果的不算
HurtType_Miss,              # 闪避 9
) = range(10)
@@ -4979,8 +4979,7 @@
Def_SkillFuncType_TurnNormaSkill,  #1 普攻技能
Def_SkillFuncType_AngerSkill,  #2 怒气技能
Def_SkillFuncType_PotentialSkill,  #3 潜能技能
Def_SkillFuncType_AtkbackSkill,  #4 反击技能
) = range(5)
) = range(4)
# MMO项目 - 先保留,重新定义从1000开始,后续可陆续删除
(Def_SkillFuncType_Common, #0为通用技能
@@ -5028,6 +5027,16 @@
AtkDistType_Long, # 远程
) = range(1, 1 + 2)
# 武将特长
HeroSpecialtyList = (
HeroSpecialty_Stun,         # 击晕 1
HeroSpecialty_SuperHit,     # 暴击 2
HeroSpecialty_Combo,        # 连击 3
HeroSpecialty_Miss,         # 闪避 4
HeroSpecialty_Parry,        # 格挡 5
HeroSpecialty_SuckHP,       # 吸血 6
) = range(1, 1 + 6)
# 经验倍率限制类型
(
ExpRateLimitType_Recover, # 资源找回
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -163,6 +163,7 @@
                        ("dict", "BatAttrDict", 0),
                        ("list", "FetterIDList", 0),
                        ("BYTE", "RecruitBySelf", 0),
                        ("BYTE", "Specialty", 0),
                        ),
                "HeroTalent":(
@@ -2737,6 +2738,7 @@
    def GetBatAttrDict(self): return self.attrTuple[12] # 其他战斗属性字典 {"属性ID":值, ...} dict
    def GetFetterIDList(self): return self.attrTuple[13] # 羁绊ID列表 list
    def GetRecruitBySelf(self): return self.attrTuple[14] #  招募需要本体 BYTE
    def GetSpecialty(self): return self.attrTuple[15] #  武将特长 BYTE
# 武将星级天赋表
class IPY_HeroTalent():
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
@@ -1860,10 +1860,6 @@
    ## 是否回合普攻技能,区别与无技能的普通A一下,该普攻同样可以有各种技能效果,只是他属于普攻
    return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaSkill
def isAtkbackSkill(curSkill):
    ## 是否反击技能
    return curSkill and curSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill
## 检查技能是否为被动技能, 用于控制不可释放技能
def isPassiveSkill(curSkill):
    return curSkill.GetSkillType() in [ChConfig.Def_SkillType_Passive,
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -605,6 +605,7 @@
    if CanCombo(curBatObj, tagObj):
        # 连击根据技能目标配置逻辑重新选择目标
        GameWorld.DebugLog("● %s 【连击】" % TurnAttack.GetObjName(curBatObj))
        DoHeroSpecialty(turnFight, curBatObj, ChConfig.HeroSpecialty_Combo, useSkill.GetSkillID())
        OnUseSkill(turnFight, curBatObj, useSkill, batType=ChConfig.TurnBattleType_Combo)
        
    return
@@ -615,8 +616,9 @@
        return
    
    tagID = tagObj.GetID()
    if tagObj.GetAtkDistType() != ChConfig.AtkDistType_Short:
        GameWorld.DebugLog("非近战不可反击! tagID=%s" % tagID)
    canAtkbackDictTypeList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 2)
    if tagObj.GetAtkDistType() not in canAtkbackDictTypeList:
        GameWorld.DebugLog("该远近类型武将不可反击! tagID=%s,AtkDistType=%s not in %s" % (tagID, tagObj.GetAtkDistType(), canAtkbackDictTypeList))
        return
    
    canAtkBack = False
@@ -636,7 +638,7 @@
        useSkill = skillManager.GetSkillByIndex(index)
        if not useSkill:
            continue
        if useSkill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill:
        if useSkill.GetFuncType() == ChConfig.Def_SkillFuncType_TurnNormaSkill: # 使用普攻反击
            GameWorld.DebugLog("可以反击! tagID=%s" % tagID)
            return useSkill
    return
@@ -702,6 +704,7 @@
        TurnAttack.SetObjKilled(turnFight, curObj)
        
    # 统计伤血,可能单个技能对同一目标造成多次伤害
    isSuperHit, isStun, isSuckHP = False, False, False
    missObjIDList = []
    for hurtObj in useSkill.GetHurtObjList():
        hurtObjID = hurtObj.GetObjID()
@@ -712,6 +715,22 @@
            __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
        if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
            missObjIDList.append(hurtObjID)
            DoHeroSpecialty(turnFight, tagObj, ChConfig.HeroSpecialty_Miss, relatedSkillID)
        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
    # 群攻只触发一次特长
    if isSuperHit:
        DoHeroSpecialty(turnFight, curObj, ChConfig.HeroSpecialty_SuperHit, relatedSkillID)
    if isStun:
        DoHeroSpecialty(turnFight, curObj, ChConfig.HeroSpecialty_Stun, relatedSkillID)
    if isSuckHP:
        DoHeroSpecialty(turnFight, curObj, ChConfig.HeroSpecialty_SuckHP, relatedSkillID)
            
    # 结算副本相关的攻击结果,仅主动发起玩家阵容武将触发
    curPlayer = turnFight.curPlayer
@@ -784,7 +803,7 @@
    ## 技能释放者怒气相关
    if SkillCommon.isAngerSkill(useSkill):
        curBatObj.SetXP(0)
    elif SkillCommon.isTurnNormalSkill(useSkill):
    elif SkillCommon.isTurnNormalSkill(useSkill) and useSkill.GetBatType() == ChConfig.TurnBattleType_Normal:
        addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
        AddTurnFightXP(curBatObj, addXP, "skillID:%s" % useSkill.GetSkillID())
    return
@@ -812,6 +831,21 @@
    updXP = curXP + addXP
    gameObj.SetXP(updXP)
    GameWorld.DebugLog("        更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
    return
def DoHeroSpecialty(turnFight, gameObj, specialty, relatedSkillID=0):
    ## 执行武将特长
    if gameObj.GetSpecialty() != specialty:
        return
    specialtyAddXPDict = IpyGameDataPY.GetFuncEvalCfg("AngerXP", 5, {})
    if str(specialty) not in specialtyAddXPDict:
        return
    addXP = specialtyAddXPDict[str(specialty)]
    curXP = gameObj.GetXP()
    updXP = curXP + addXP
    gameObj.SetXP(updXP, False)
    GameWorld.DebugLog("        特长加XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,特性=%s" % (gameObj.GetID(), curXP, addXP, updXP, specialty))
    Sync_PropertyRefreshView(turnFight, gameObj, ChConfig.AttrID_XP, updXP, addXP, diffType=1, relatedSkillID=relatedSkillID)
    return
def __DoCurSkillEff(turnFight, curObj, useSkill, missObjIDList):
@@ -999,7 +1033,6 @@
    skillID = curSkill.GetSkillID()
    isTurnNormalSkill = SkillCommon.isTurnNormalSkill(curSkill)
    isAngerSkill = SkillCommon.isAngerSkill(curSkill)
    isAtkbackSkill = SkillCommon.isAtkbackSkill(curSkill)
    isDot = ("damageoftime" in kwargs)
    angerOverflow = 0 # 怒气溢出值
    
@@ -1028,12 +1061,12 @@
    
    #calcType = curSkill.GetCalcType() 目前暂时按攻击算伤害,之后可以扩展其他
    
    isSuperHit, isParry = False, False
    isSuperHit, isParry, isStun = False, False, False
    aSuperDamPer, dSuperDamPerDef = 0, 0
    if not isDot:
        isSuperHit = CanSuperHit(atkObj, defObj) # 是否暴击
        isParry = (isTurnNormalSkill and CanParry(atkObj, defObj)) # 是否格挡,仅针对普攻
        CanStun(turnFight, atkObj, defObj, curSkill) # 是否击晕
        isStun = CanStun(turnFight, atkObj, defObj, curSkill) # 是否击晕
        
    if isSuperHit:
        hurtTypes |= pow(2, ChConfig.HurtType_SuperHit)
@@ -1045,6 +1078,9 @@
        
    if ignoreDef:
        hurtTypes |= pow(2, ChConfig.HurtType_IgnoreDef)
    if isStun:
        hurtTypes |= pow(2, ChConfig.HurtType_Stun)
        
    #参与运算的数值
    #rand = random.random()                #种子数 0~1
@@ -1101,9 +1137,6 @@
    elif isAngerSkill:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 2))
        GameWorld.DebugLog("    怒气技能伤害=%s" % (hurtValue))
    elif isAtkbackSkill:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 3))
        GameWorld.DebugLog("    反击伤害=%s" % (hurtValue))
    else:
        hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 4))
        GameWorld.DebugLog("    其他伤害=%s" % (hurtValue))