From cc207773cbedb51c20300a87c62529ace416b086 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 19 九月 2025 19:23:35 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(无敌支持,免疫伤害、dot、控制;小怪技能;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py | 93 ++++++++++++++---------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py | 5 -
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py | 86 +++++++++++++++------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 4
5 files changed, 123 insertions(+), 67 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 433c306..2297e4b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -819,14 +819,11 @@
if self._buffMgr.IsInBuffState(state):
return True
return False
- def IsInState(self, state):
- ## 是否处于指定状态下
- return self._buffMgr.IsInBuffState(state)
def IsInControlled(self):
## 是否被控制中
for state in ChConfig.InControlledStateList:
- if self.IsInState(state):
+ if self._buffMgr.IsInBuffState(state):
return True
return False
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 0f0b02b..111c080 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -1562,7 +1562,7 @@
if SkillCommon.isAngerSkill(useSkill):
if curXP < xpMax:
continue
- if curBatObj.IsInState(ChConfig.BatObjState_Sneer):
+ if curBatObj.CheckInState(ChConfig.BatObjState_Sneer):
GameWorld.DebugLog("嘲讽状态下,无法主动释放怒技!") # 可被动释放怒技,如怒技追击
continue
useCnt = -1 # xp技能优先释放
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 8832fed..bd99e5a 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -968,7 +968,7 @@
HurtType_Normal, # 伤害 1
HurtTYpe_Recovery, # 回血 2
HurtType_3,
-HurtType_4,
+HurtType_Immune, # 免疫 4
HurtType_Parry, # 格挡 5
HurtType_IgnoreDef, # 无视防御/真实伤害 6
HurtType_SuperHit, # 暴击 7
@@ -3142,7 +3142,7 @@
BatObjState_Poison, # 中毒 5
BatObjState_Bleeding, # 流血 6
BatObjState_EasyHurt, # 易伤 7
- BatObjState_Wudi, # 无敌 8
+ BatObjState_Wudi, # 无敌( 受任意伤害、控制类、dot效果,全部飘“免疫”) 8
BatObjState_Sneer, # 嘲讽 9
BatObjState_LimitSkill, # 沉默 10
BatObjState_LimitAddHP, # 禁疗 11
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 e8240c1..b77b72f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
@@ -44,10 +44,10 @@
useSkill = poolMgr.acquire(BattleObj.PySkill, skillIpyData, ownerID)
useSkill.SetTagObjList(tagObjList)
- OnAddBuff(turnFight, batObj, useSkill, buffOwner, bySkill, afterLogic)
+ isOK = OnAddBuff(turnFight, batObj, useSkill, buffOwner, bySkill, afterLogic)
poolMgr.release(useSkill)
- return
+ return isOK
def OnAddBuff(turnFight, batObj, buffSkill, buffOwner=None, bySkill=None, afterLogic=False):
skillID = buffSkill.GetSkillID()
@@ -57,6 +57,14 @@
if not buffOwner:
buffOwner = batObj
ownerID = buffOwner.GetID()
+
+ #无敌免疫持续减益buff、控制类buff
+ if buffSkill.GetSkillType() in [ChConfig.Def_SkillType_LstDepBuff, ChConfig.Def_SkillType_Action] \
+ and batObj.CheckInState(ChConfig.BatObjState_Wudi):
+ GameWorld.DebugLog("无敌状态下免疫该buff: curID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s"
+ % (curID, skillID, ownerID, relatedSkillID))
+ return False
+
buffValueList = GetAddBuffValue(turnFight, buffOwner, batObj, buffSkill)
GameWorld.DebugLog("OnAddBuff: curID=%s,skillID=%s,atkType=%s,buffValueList=%s,ownerID=%s,relatedSkillID=%s"
% (curID, skillID, buffSkill.GetAtkType(), buffValueList, ownerID, relatedSkillID))
@@ -81,7 +89,23 @@
buffMgr = batObj.GetBuffManager()
if buffRepeat == 4: # 4 独立:回合、效果独立计算
- pass # 不处理,直接跳过添加新buff
+ maxLayerCnt = buffSkill.GetLayerMax()
+ # 如果有限制最大层数,达到上限时如果有新的层数进来,就替换掉持续时间最短的,只算相同来源
+ if maxLayerCnt:
+ buffList = buffMgr.FindBuffListBySkillTypeID(skillTypeID)
+ if len(buffList) >= maxLayerCnt:
+ delBuff = None
+ for buff in buffList:
+ if not buff:
+ continue
+ if buff.GetOwnerID() != ownerID:
+ continue
+ if not delBuff or delBuff.GetRemainTime() < buff.GetRemainTime():
+ delBuff = buff
+ if delBuff:
+ GameWorld.DebugLog("删除独立层级多余buff: buffID=%s,ownerID=%s,remainTime=%s" % (delBuff.GetBuffID(), ownerID, delBuff.GetRemainTime()))
+ DoBuffDel(turnFight, batObj, delBuff, bySkill, afterLogic, buffOwner)
+
elif buffRepeat == 5: # 5 唯一,强制覆盖不同来源同状态buff,如嘲讽状态
buffState = buffSkill.GetCurBuffState()
for index in range(buffMgr.GetBuffCount())[::-1]:
@@ -93,40 +117,37 @@
DoBuffDel(turnFight, batObj, buff, bySkill, afterLogic, buffOwner)
else:
buffList = buffMgr.FindBuffListBySkillTypeID(skillTypeID)
- if buffList:
- for buff in buffList:
- if not buff:
- continue
- if buff.GetOwnerID() != ownerID:
- continue
- buffID = buff.GetBuffID()
- nowLayerCnt = buff.GetLayer()
- GameWorld.DebugLog(" 已经存在该buff: buffID=%s,skillTypeID=%s,ownerID=%s,buffRepeat=%s" % (buffID, skillTypeID, ownerID, buffRepeat))
-
- updLayerCnt = addLayerCnt
- if buffRepeat == 3: # 叠加层级
- maxLayerCnt = buffSkill.GetLayerMax()
- updLayerCnt = nowLayerCnt + addLayerCnt
- if maxLayerCnt and updLayerCnt > maxLayerCnt:
- updLayerCnt = maxLayerCnt
- GameWorld.DebugLog(" 叠加层级: nowLayerCnt=%s,addLayerCnt=%s,updLayerCnt=%s" % (nowLayerCnt, addLayerCnt, updLayerCnt))
- else:
- GameWorld.DebugLog(" 默认覆盖")
-
- # 重置回合、CD、值等
- buff.SetCalcTime(turnFight.getTimeline())
- buff.SetRemainTime(buffSkill.GetLastTime())
- buff.SetLayer(updLayerCnt)
- buff.SetBuffValueList(buffValueList)
- if afterLogic and bySkill:
- bySkill.AddAfterLogic(ChConfig.AfterLogic_AddBuff, [batObj, buff, buffOwner])
- else:
- SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID, isNewAdd=True)
-
- if nowLayerCnt != updLayerCnt:
- RefreshBuffEffect(turnFight, batObj, buff, False)
- break
+ for buff in buffList:
+ if not buff:
+ continue
+ if buff.GetOwnerID() != ownerID:
+ continue
+ buffID = buff.GetBuffID()
+ nowLayerCnt = buff.GetLayer()
+ GameWorld.DebugLog(" 已经存在该buff: buffID=%s,skillTypeID=%s,ownerID=%s,buffRepeat=%s" % (buffID, skillTypeID, ownerID, buffRepeat))
+ updLayerCnt = addLayerCnt
+ if buffRepeat == 3: # 叠加层级
+ maxLayerCnt = buffSkill.GetLayerMax()
+ updLayerCnt = nowLayerCnt + addLayerCnt
+ if maxLayerCnt and updLayerCnt > maxLayerCnt:
+ updLayerCnt = maxLayerCnt
+ GameWorld.DebugLog(" 叠加层级: nowLayerCnt=%s,addLayerCnt=%s,updLayerCnt=%s" % (nowLayerCnt, addLayerCnt, updLayerCnt))
+ else:
+ GameWorld.DebugLog(" 默认覆盖")
+
+ # 重置回合、CD、值等
+ buff.SetCalcTime(turnFight.getTimeline())
+ buff.SetRemainTime(buffSkill.GetLastTime())
+ buff.SetLayer(updLayerCnt)
+ buff.SetBuffValueList(buffValueList)
+ if afterLogic and bySkill:
+ bySkill.AddAfterLogic(ChConfig.AfterLogic_AddBuff, [batObj, buff, buffOwner])
+ else:
+ SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID, isNewAdd=True)
+
+ if nowLayerCnt != updLayerCnt:
+ RefreshBuffEffect(turnFight, batObj, buff, False)
return True
__addNewBuff(turnFight, batObj, buffMgr, buffSkill, buffValueList, buffOwner, bySkill, afterLogic, setLayerCnt=addLayerCnt)
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 f22dcf8..3d2c457 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -720,26 +720,44 @@
TurnAttack.SetObjKilled(turnFight, curObj)
# 统计伤血,可能单个技能对同一目标造成多次伤害
+ totalHurtValue = 0
isSuperHit, isStun, isSuckHP = False, False, False
- missObjIDList = []
+ missObjIDList, immuneObjIDList = [], []
for hurtObj in useSkill.GetHurtObjList():
hurtObjID = hurtObj.GetObjID()
tagObj = batObjMgr.getBatObj(hurtObjID)
if not tagObj:
continue
- if not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery) and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
+ if not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery) and not hurtObj.HaveHurtType(ChConfig.HurtType_Immune) \
+ and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
__doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
+
+ if hurtObj.HaveHurtType(ChConfig.HurtType_Normal):
+ totalHurtValue += hurtObj.GetHurtHP()
+
if hurtObj.HaveHurtType(ChConfig.HurtType_Miss):
- missObjIDList.append(hurtObjID)
+ if hurtObjID not in missObjIDList:
+ missObjIDList.append(hurtObjID)
DoHeroSpecialty(turnFight, tagObj, ChConfig.HeroSpecialty_Miss, relatedSkillID)
+
+ if hurtObj.HaveHurtType(ChConfig.HurtType_Immune):
+ if hurtObjID not in immuneObjIDList:
+ immuneObjIDList.append(hurtObjID)
+
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
+
+ curObj.SetLastHurtValue(totalHurtValue) # 记录最后一次总伤害
+
# 群攻只触发一次特长
if isSuperHit:
DoHeroSpecialty(turnFight, curObj, ChConfig.HeroSpecialty_SuperHit, relatedSkillID)
@@ -753,8 +771,9 @@
if curPlayer and curObj and curObj.GetOwnerID() == curPlayer.GetPlayerID():
FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, killObjList, useSkill, turnFight.mapID, turnFight.funcLineID)
+ effIgnoreObjIDList = missObjIDList + immuneObjIDList
# 优先触发本技能额外效果,注:仅该技能释放后该技能的额外效果视为主技能的效果,优先级最高
- __DoCurSkillEff(turnFight, curObj, useSkill, missObjIDList, isUseSkill)
+ __DoCurSkillEff(turnFight, curObj, useSkill, effIgnoreObjIDList, isUseSkill)
# ========== 以下触发被动 ==========
@@ -766,7 +785,7 @@
for tagObj in useSkill.GetTagObjList():
tagID = tagObj.GetID()
- if tagID in missObjIDList:
+ if tagID in effIgnoreObjIDList:
continue
# 直接攻击
@@ -872,7 +891,7 @@
Sync_PropertyRefreshView(turnFight, gameObj, ChConfig.AttrID_XP, updXP, addXP, diffType=1, relatedSkillID=relatedSkillID)
return
-def __DoCurSkillEff(turnFight, curObj, useSkill, missObjIDList, isUseSkill):
+def __DoCurSkillEff(turnFight, curObj, useSkill, effIgnoreObjIDList, isUseSkill):
## 执行本技能/buff释放后额外效果
for index in xrange(useSkill.GetEffectCount()):
curEffect = useSkill.GetEffect(index)
@@ -885,15 +904,15 @@
continue
effID = curEffect.GetEffectID()
- GameWorld.DebugLog("◆执行额外技能效果: %s, triggerWay=%s,missObjIDList=%s" % (effID, triggerWay, missObjIDList))
+ GameWorld.DebugLog("◆执行额外技能效果: %s, triggerWay=%s,effIgnoreObjIDList=%s" % (effID, triggerWay, effIgnoreObjIDList))
if effID == 5010:
# 额外技能效果
- __doUseEnhanceSkill(turnFight, curObj, useSkill, curEffect, missObjIDList)
+ __doUseEnhanceSkill(turnFight, curObj, useSkill, curEffect, effIgnoreObjIDList)
continue
for tagObj in useSkill.GetTagObjList():
tagID = tagObj.GetID()
- if tagID in missObjIDList:
+ if tagID in effIgnoreObjIDList:
# 闪避了不触发
continue
@@ -901,7 +920,7 @@
return
-def __doUseEnhanceSkill(turnFight, curBatObj, useSkill, curEffect, missObjIDList):
+def __doUseEnhanceSkill(turnFight, curBatObj, useSkill, curEffect, effIgnoreObjIDList):
## 执行主技能的额外技能效果
#if useSkill.GetBatType() == ChConfig.TurnBattleType_Enhance:
# #GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
@@ -926,8 +945,8 @@
if not tagObj.IsAlive():
GameWorld.DebugLog(" 已被击杀不触发: tagID=%s" % (tagID))
continue
- if tagID in missObjIDList:
- GameWorld.DebugLog(" 闪避的不触发: tagID=%s" % (tagID))
+ if tagID in effIgnoreObjIDList:
+ GameWorld.DebugLog(" 闪避或免疫的不触发: tagID=%s" % (tagID))
continue
if checkInStateList:
if not tagObj.CheckInState(checkInStateList):
@@ -1014,7 +1033,7 @@
else:
hurtValue, hurtTypes = CalcHurtHP(turnFight, atkObj, defObj, curSkill, atkSkillValue, atkSkillPer)
- hurtValue, realHurtHP = CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue)
+ hurtValue, realHurtHP, hurtTypes = CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue, hurtTypes)
#伤害结构体
hurtObj.SetHurtTypes(hurtTypes)
@@ -1027,7 +1046,6 @@
hurtObj.SetLostHP(lostHP)
hurtObj.SetCurHP(remainHP)
defObj.SetHP(remainHP)
- atkObj.SetLastHurtValue(hurtValue)
GameWorld.DebugLog(" 伤血: atkID=%s,defID=%s,hurtValue=%s,realHurtHP=%s,lostHP=%s,%s/%s"
% (atkID, defID, hurtValue, realHurtHP, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, skillID)
@@ -1224,10 +1242,11 @@
happenRate = eval(IpyGameDataPY.GetFuncCompileCfg("StunCfg", 1))
if not GameWorld.CanHappen(happenRate):
return False
- GameWorld.DebugLog("击晕了: happenRate=%s,aStunRate=%s,dStunRateDef=%s" % (happenRate, aStunRate, dStunRateDef))
stunSkillID = IpyGameDataPY.GetFuncCfg("StunCfg", 2)
- TurnBuff.DoAddBuffBySkillID(turnFight, defObj, stunSkillID, atkObj, curSkill, afterLogic=True)
- return True
+ if TurnBuff.DoAddBuffBySkillID(turnFight, defObj, stunSkillID, atkObj, curSkill, afterLogic=True):
+ GameWorld.DebugLog("击晕了: happenRate=%s,aStunRate=%s,dStunRateDef=%s" % (happenRate, aStunRate, dStunRateDef))
+ return True
+ return False
def CanParry(turnFight, atkObj, defObj, curSkill):
if defObj.IsInControlled():
@@ -1253,12 +1272,31 @@
return True
return False
-def CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue):
+def CalcHurtHPWithBuff(turnFight, atkObj, defObj, curSkill, hurtValue, hurtTypes=0):
## 计算伤害后,因各种buff和状态的影响处理
- # @return: hurtValue, realHurtHP
+ # @return: hurtValue, realHurtHP, hurtTypes
if hurtValue <= 0:
- return 0, 0
+ return 0, 0, hurtTypes
+
+ if defObj.CheckInState(ChConfig.BatObjState_Wudi):
+ hurtTypes |= pow(2, ChConfig.HurtType_Immune) # 添加免疫
+ buffMgr = defObj.GetBuffManager()
+ for index in range(buffMgr.GetBuffCount()):
+ buff = buffMgr.GetBuffByIndex(index)
+ if not buff:
+ continue
+ skillData = buff.GetSkillData()
+ if skillData.GetCurBuffState() != ChConfig.BatObjState_Wudi:
+ continue
+ # 记录免疫的积攒伤害
+ buffValue = buff.GetValue1() + buff.GetValue2() * ChConfig.Def_PerPointValue
+ updBuffValue = buffValue + hurtValue
+ buff.SetValue1(updBuffValue % ChConfig.Def_PerPointValue)
+ buff.SetValue2(updBuffValue / ChConfig.Def_PerPointValue)
+ GameWorld.DebugLog(" 无敌盾免疫伤害: defID=%s,buffID=%s,skillID=%s,updBuffValue=%s"
+ % (defObj.GetID(), buff.GetBuffID(), skillData.GetSkillID(), updBuffValue))
+ return 0, 0, hurtTypes
# 减伤盾减伤, 会改变 hurtValue
hurtValue = max(0, hurtValue)
@@ -1300,7 +1338,7 @@
buff.SetValue2(updShieldValue / ChConfig.Def_PerPointValue)
curSkill.AddAfterLogic(ChConfig.AfterLogic_SyncBuff, [defObj, buff, atkObj, "ReduceShieldValue"])
- return hurtValue, max(0, realHurtHP)
+ return hurtValue, max(0, realHurtHP), hurtTypes
def CalcBounceHP(turnFight, atkObj, defObj, hurtObj, curSkill):
'''计算反弹反弹伤害
@@ -1313,8 +1351,9 @@
return
GameWorld.DebugLog(" 反弹伤害=%s,%s/%s" % (bounceHP, atkObj.GetHP(), atkObj.GetMaxHP()))
- bounceHP, realBounceHP = CalcHurtHPWithBuff(turnFight, defObj, atkObj, curSkill, bounceHP)
+ bounceHP, realBounceHP, _ = CalcHurtHPWithBuff(turnFight, defObj, atkObj, curSkill, bounceHP)
if bounceHP <= 0:
+ GameWorld.DebugLog(" bounceHP=%s" % (bounceHP))
return
hurtObj.SetBounceHP(bounceHP)
@@ -1431,14 +1470,13 @@
dHP = defObj.GetHP()
GameWorld.DebugLog("结算dot: atkID=%s,defID=%s,buffID=%s,skillID=%s,ownerID=%s,hurtValue=%s,hurtTypes=%s,dHP=%s"
% (atkID, defID, buffID, skillID, ownerID, hurtValue, hurtTypes, dHP))
- hurtValue, realHurtHP = CalcHurtHPWithBuff(turnFight, atkObj, defObj, useSkill, hurtValue)
+ hurtValue, realHurtHP, hurtTypes = CalcHurtHPWithBuff(turnFight, atkObj, defObj, useSkill, hurtValue, hurtTypes)
# dot的反弹、吸血待定
remainHP = max(0, dHP - realHurtHP) # 剩余血量
lostHP = dHP - remainHP # 实际掉血量
defObj.SetHP(remainHP)
- atkObj.SetLastHurtValue(hurtValue)
GameWorld.DebugLog(" hurtValue=%s,realHurtHP=%s,lostHP=%s,%s/%s" % (hurtValue, realHurtHP, lostHP, defObj.GetHP(), defObj.GetMaxHP()))
hurtObj.SetHurtTypes(hurtTypes)
--
Gitblit v1.8.0