From 3ed128401680ce3755dee186f48c7fb965f7aca8 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期四, 18 九月 2025 10:11:12 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(诸葛果技能;追击支持;优化连击追击;程序内置限制单武将单次行动中每个对象累计使用技能次数20次;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5012.py | 39 +++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py | 39 +++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 14 +++-
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py | 42 +++++++++-----
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 3 -
6 files changed, 116 insertions(+), 23 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 59773b3..6203538 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -502,6 +502,12 @@
self._hurtList = [] # 本次伤血列表,可能同一个对象有多个伤害,如弹射等 [HurtObj, ...]
self._bySkill = None # 由哪个技能触发的
self._afterLogicList = [] # 技能释放后需要处理逻辑 [[logicType, logicParams], ...]
+
+ # 连击相关
+ self._comboState = 0 # 连击状态 0-未重置,1-初始化连击相关可连击,2-连击已中断
+ self._comboNum = 0 # 连击次数
+ self._missTagIDDict = {} # 单次连续连击中对方已闪避次数 {tagID:missNum, ...}
+ self._parryTagIDDict = {} # 单次连续连击中对方已格挡次数 {tagID:parryNum, ...}
return
def ResetUseRec(self):
@@ -580,6 +586,39 @@
return hurtObj
def GetHurtObjList(self): return self._hurtList
+ def __commboClear(self):
+ ## 连击相关清空
+ self._comboState = 0
+ self._comboNum = 0
+ self._missTagIDDict = {}
+ self._parryTagIDDict = {}
+ return
+
+ def ComboCheckStart(self, force=False):
+ ## 检查并设置开始连击相关,一般是开始使用技能时调用
+ if not force:
+ if self._comboState == 1:
+ #GameWorld.DebugLog("连击进行中,不重置")
+ return
+ self.__commboClear()
+ self._comboState = 1 # 设置已初始化连击相关
+ #GameWorld.DebugLog("连击重置")
+ return
+
+ def ComboEnable(self): return self._comboState == 1 ## 可否执行连击相关
+
+ def ComboInterrupt(self):
+ ## 连击中断,概率不再触发连击时需要设置中断
+ self._comboState = 2
+ return
+
+ def GetComboNum(self): return self._comboNum # 已连击次数
+ def SetComboNum(self, comboNum): self._comboNum = comboNum
+ def GetTagMissNum(self, tagID): return self._missTagIDDict.get(tagID, 0)
+ def SetTagMissNum(self, tagID, missNum): self._missTagIDDict[tagID] = missNum
+ def GetTagParryNum(self, tagID): return self._parryTagIDDict.get(tagID, 0)
+ def SetTagParryNum(self, tagID, parryNum): self._parryTagIDDict[tagID] = parryNum
+
class SkillManager():
## 战斗对象技能管理器
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 e5a4564..2c03cc5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -162,6 +162,7 @@
self.timeline = 0 # 时间轴节点 turnNum*1000+actionIndex*100++actionNum
self.startTime = 0 # 开始时间戳,支持毫秒小数
self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
+ self._oneActionUseSkillCntDict = {} # 某对象行动开始后所有对象累计使用技能次数,用于单对象单次行动中限制每个对象的最高触发技能次数 {objID:useCnt, ...}
# pve 多小队 - 一般只有PVE用到
self.lineupIndex = 0 # 当前小队索引
@@ -427,6 +428,12 @@
else:
ObjPool.GetPoolMgr().release(clientPack)
return
+
+ def ResetOneActionUseSkillCnt(self): self._oneActionUseSkillCntDict = {}
+ def GetOneActionUseSkillCnt(self, objID): return self._oneActionUseSkillCntDict.get(objID, 0)
+ def SetOneActionUseSkillCnt(self, objID, useCnt):
+ self._oneActionUseSkillCntDict[objID] = useCnt
+ return useCnt
class TurnFightMgr():
## 回合战斗管理器
@@ -1340,6 +1347,7 @@
batLineup.actionNum = ActionNumStart
for objID in batLineup.posObjIDDict.values():
batObj = batObjMgr.getBatObj(objID)
+ turnFight.ResetOneActionUseSkillCnt()
TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_FightStart)
turnFight.enterLogic = True
@@ -1358,10 +1366,6 @@
#GameWorld.DebugLog("OnTimelineChange! objID=%s" % (objID))
if not batObj or not batObj.IsAlive():
continue
-
- batObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
- batObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, 0)
- batObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, 0)
curID = batObj.GetID()
skillManager = batObj.GetSkillManager()
@@ -1440,6 +1444,7 @@
if batObj.GetHP() <= 0:
return
+ turnFight.ResetOneActionUseSkillCnt()
TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
return
@@ -1463,6 +1468,7 @@
return
GameWorld.DebugLog("---[武将回合开始时] : curID=%s,curHP=%s/%s" % (batObj.GetID(), batObj.GetHP(), batObj.GetMaxHP()))
+ turnFight.ResetOneActionUseSkillCnt()
TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_HeroTurnStart)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 8d63b64..9487696 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -3063,9 +3063,6 @@
Def_Obj_Dict_SkinID = 'SkinID' # 该战斗NPC所绑定的武将皮肤ID,一般仅玩家阵容有
Def_Obj_Dict_TurnFightPosInfo = 'TurnFightPosInfo' # 回合制站位: 阵营编号*100+阵型站位,阵型站位为0时代表非主战单位
Def_Obj_Dict_TurnFightTimeline = 'TurnFightTimeline' # 回合制战斗时间线: 回合数*100+行动编号节点
-Def_Obj_Dict_TurnComboNum = 'TurnComboNum' # 单次累计连击次数
-Def_Obj_Dict_TurnAtkBackNum = 'TurnAtkBackNum' # 单次累计反击次数
-Def_Obj_Dict_TurnParryNum = 'TurnParryNum' # 单次累计格挡次数
Def_Obj_Dict_TurnMissNum = 'TurnMissNum' # 单次累计闪避次数
Def_Obj_Dict_TurnBattleType = 'TurnBattleType' # 本次攻击战斗类型:TurnBattleType_xxx
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index adc5d47..05ffe43 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -509,7 +509,7 @@
def CanHappen(rate, maxRate=ShareDefine.Def_MaxRateValue):
if rate <= 0:
return 0
- if random.randint(0, maxRate -1) < rate:
+ if rate >= maxRate or random.randint(0, maxRate -1) < rate:
return 1
return 0
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5012.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5012.py
new file mode 100644
index 0000000..4285c9e
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5012.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.PassiveTrigger.PassiveEff_5012
+#
+# @todo:概率进行追击
+# @author hxp
+# @date 2025-09-18
+# @version 1.0
+#
+# 详细描述: 概率进行追击
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-09-18 10:30"""
+#-------------------------------------------------------------------------------
+
+import TurnSkill
+import IpyGameDataPY
+import GameWorld
+import ChConfig
+
+def DoSkillEffectLogic(turnFight, batObj, tagObj, effSkill, curEffect, connSkill):
+ rate = curEffect.GetEffectValue(0)
+ if not GameWorld.CanHappen(rate):
+ #GameWorld.DebugLog("概率进行追击不触发!")
+ return
+ skillID = curEffect.GetEffectValue(1) # 技能ID,为0时释放本技能
+ if not skillID:
+ passiveSkill = effSkill
+ else:
+ passiveSkill = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+ if not passiveSkill:
+ return
+ return TurnSkill.OnUseSkill(turnFight, batObj, passiveSkill, batType=ChConfig.TurnBattleType_Pursue, bySkill=connSkill)
+
+def DoBuffEffectLogic(turnFight, batObj, tagObj, effBuff, curEffect, connSkill):
+ effSkill = effBuff.GetSkillData().GetIpyData()
+ return DoSkillEffectLogic(turnFight, batObj, tagObj, effSkill, curEffect, connSkill)
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 c571d8c..d52db40 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -76,9 +76,16 @@
# 可扩展其他目标选择,如复活技能没有死亡单位时则使用另外的效果
return
+ objID = curBatObj.GetID()
+ oneActionUseCnt = turnFight.GetOneActionUseSkillCnt(objID)
+ if oneActionUseCnt >= 20:
+ GameWorld.ErrLog("单次行动累计使用技能达到上限! objID=%s,oneActionUseCnt=%s" % (objID, oneActionUseCnt), turnFight.playerID)
+ return
+ oneActionUseCnt = turnFight.SetOneActionUseSkillCnt(objID, oneActionUseCnt + 1)
+
bySkillID = bySkill.GetSkillID() if bySkill else 0
- GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,HP:%s/%s"
- % (curBatObj.GetID(), skillID, len(tagObjList), batType, bySkillID, curBatObj.GetHP(), curBatObj.GetMaxHP()))
+ GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,HP:%s/%s,oneActionUseCnt=%s"
+ % (objID, skillID, len(tagObjList), batType, bySkillID, curBatObj.GetHP(), curBatObj.GetMaxHP(), oneActionUseCnt))
# 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
poolMgr = ObjPool.GetPoolMgr()
@@ -93,6 +100,11 @@
useSkill.SetBatType(batType)
useSkill.SetBySkill(bySkill)
+ isTurnNormalSkill = SkillCommon.isTurnNormalSkill(useSkill)
+ if isTurnNormalSkill:
+ # 普攻追击时强制重新开始算连击
+ useSkill.ComboCheckStart(batType == ChConfig.TurnBattleType_Pursue)
+
curBatObj.ClearSkillTempAttr()
tagIDList = []
for tagObj in tagObjList:
@@ -103,7 +115,6 @@
if useSkill.GetFuncType():
curBatObj.SetMainTagIDList(tagIDList)
- objID = curBatObj.GetID()
useTag = ""
#这个技能是Buff
@@ -132,8 +143,10 @@
turnFight.addBatPack(clientPack)
# 处理反击 或 连击
- DoCombo(turnFight, curBatObj, useSkill)
-
+ if isTurnNormalSkill:
+ if not DoCombo(turnFight, curBatObj, useSkill):
+ useSkill.ComboInterrupt()
+
# 最后重置、回收对象
useSkill.ResetUseRec()
if usePoolSkill:
@@ -586,8 +599,7 @@
纵排: 优先前面的单位
'''
- if not SkillCommon.isTurnNormalSkill(useSkill):
- #GameWorld.DebugLog("非普攻不处理反击连击")
+ if not useSkill.ComboEnable():
return
tagFriendly = useSkill.GetTagFriendly()
@@ -608,7 +620,7 @@
if not tagObj:
return
- comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum)
+ comboNum = useSkill.GetComboNum()
aComboRate = atkObj.GetBatAttrValue(ChConfig.AttrID_ComboRate)
aComboRate += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, tagObj, ChConfig.AttrID_ComboRate, useSkill)
@@ -620,14 +632,14 @@
return
GameWorld.DebugLog("● %s 【连击】 happenRate=%s,aComboRate=%s,dComboRateDef=%s,comboNum=%s"
% (TurnAttack.GetObjName(atkObj), happenRate, aComboRate, dComboRateDef, comboNum))
- atkObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, comboNum + 1)
+ useSkill.SetComboNum(comboNum + 1)
# 连击特长
DoHeroSpecialty(turnFight, atkObj, ChConfig.HeroSpecialty_Combo, useSkill.GetSkillID())
# 连击根据技能目标配置逻辑重新选择目标
OnUseSkill(turnFight, atkObj, useSkill, batType=ChConfig.TurnBattleType_Combo)
- return
+ return True
def __getCanAtkBackSkill(useSkill, tagObj):
## 获取是否可反击及反击技能
@@ -872,7 +884,6 @@
for tagObj in useSkill.GetTagObjList():
tagID = tagObj.GetID()
- GameWorld.DebugLog(" tagID=%s" % (tagID))
if tagID in missObjIDList:
# 闪避了不触发
continue
@@ -1052,11 +1063,11 @@
if isTurnNormalSkill and not mustHit:
aMissRateDef = atkObj.GetBatAttrValue(ChConfig.AttrID_MissRateDef) #atkObj.GetHit() # 抗闪避率 - 命中
dMissRate = defObj.GetBatAttrValue(ChConfig.AttrID_MissRate) # 闪避率
- missNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnMissNum)
+ missNum = curSkill.GetTagMissNum(defID)
missRate = eval(IpyGameDataPY.GetFuncCompileCfg("MissCfg", 1))
if GameWorld.CanHappen(missRate):
GameWorld.DebugLog("闪避了! missRate=%s,dMissRate=%s,aMissRateDef=%s,missNum=%s" % (missRate, dMissRate, aMissRateDef, missNum))
- defObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, missRate + 1)
+ curSkill.SetTagMissNum(defID, missRate + 1)
return 0, pow(2, ChConfig.HurtType_Miss)
hurtTypes = pow(2, ChConfig.HurtType_Normal)
@@ -1203,6 +1214,7 @@
#被控制无法格挡
return False
+ defID = defObj.GetID()
# 格挡印记
buffMgr = defObj.GetBuffManager()
parryYJBuff = buffMgr.FindBuffByState(ChConfig.BatObjState_ParryYJ)
@@ -1213,11 +1225,11 @@
aParryRateDef = atkObj.GetBatAttrValue(ChConfig.AttrID_ParryRateDef)
dParryRate = defObj.GetBatAttrValue(ChConfig.AttrID_ParryRate)
- parryNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnParryNum)
+ parryNum = curSkill.GetTagParryNum(defID)
happenRate = eval(IpyGameDataPY.GetFuncCompileCfg("ParryCfg", 1))
if GameWorld.CanHappen(happenRate):
GameWorld.DebugLog("格挡了: happenRate=%s,aParryRateDef=%s,dParryRate=%s,parryNum=%s" % (happenRate, aParryRateDef, dParryRate, parryNum))
- defObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, parryNum + 1)
+ curSkill.SetTagParryNum(defID, parryNum + 1)
return True
return False
--
Gitblit v1.8.0