From 9b67e4335f655af8c8aef8aa1e7d41e509c50b76 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 12 九月 2025 17:38:35 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(反击改为使用普攻,去除通用反击技能设定;武将特长支持;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py | 3 +
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 4 +
PySysDB/PySysDBPY.h | 1
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 11 +----
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py | 4 --
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py | 55 ++++++++++++++++++++++-----
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py | 22 -----------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 17 ++++++--
8 files changed, 67 insertions(+), 50 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index a59137e..c86794f 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -143,6 +143,7 @@
dict BatAttrDict; //其他战斗属性字典 {"属性ID":值, ...}
list FetterIDList; //羁绊ID列表
BYTE RecruitBySelf; // 招募需要本体
+ BYTE Specialty; // 武将特长
};
//武将星级天赋表
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
index ce0b1a0..f1d7758 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py
+++ b/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 当前玩家(被攻击了)
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 b0984f2..483b08e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/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
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 18ffeee..ee92f50 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/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:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 356ab3b..ad78879 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/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, # 资源找回
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index a7b8e5e..ac11826 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/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":(
@@ -2736,7 +2737,8 @@
def GetHPInheritPer(self): return self.attrTuple[11] # 生命继承 WORD
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 GetRecruitBySelf(self): return self.attrTuple[14] # 招募需要本体 BYTE
+ def GetSpecialty(self): return self.attrTuple[15] # 武将特长 BYTE
# 武将星级天赋表
class IPY_HeroTalent():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
index 5560b0a..93f395e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py
+++ b/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,
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 a763895..c670c0e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/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,7 +715,23 @@
__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
if curPlayer and curObj and curObj.GetOwnerID() == curPlayer.GetPlayerID():
@@ -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))
--
Gitblit v1.8.0