From 5b34b20562dab2b5e82b90be18285345057c12ce Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 19 八月 2025 15:52:15 +0800
Subject: [PATCH] 129 【战斗】战斗系统-服务端(优化技能表字段,增加技能及buff常用配置字段;优化被动触发及效果配置方式;技能冷却、buff持续时长计算支持;持续性buff效果结算支持;pve默认玩家先手;战锤消耗仅普攻怒技消耗;)
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5001.py | 47 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 289 ++++++++----
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py | 195 +++++--
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/AttackLogic/AttackCommon.py | 2
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py | 185 +++++--
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py | 252 +++++++++-
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py | 88 ++-
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnPassive.py | 138 +++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1001.py | 34 +
PySysDB/PySysDBPY.h | 24
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/GameSkills/SkillCommon.py | 14
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py | 55 +-
13 files changed, 986 insertions(+), 341 deletions(-)
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index cdae0ca..f6ad6a6 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -61,6 +61,7 @@
{
DWORD _SkillID; //技能ID
DWORD SkillTypeID; //技能TypeID
+ WORD SkillLV; //当前等级
WORD SkillMaxLV; //最高等级
char SkillName; //技能名
BYTE FuncType; //功能分类
@@ -71,17 +72,34 @@
BYTE TagFriendly; //敌我目标
BYTE TagAffect; //目标细分
BYTE TagCount; //目标个数
+ BYTE CalcType; //计算方式
+ WORD SkillPer; //技能万分比
+ DWORD SkillValue; //技能固定值
WORD HappenRate; //释放或添加几率
- WORD LastTime; //持续时间
- WORD CoolDownTime; //冷却时间
- WORD Priority; //优先级
DWORD EffectID1; //效果ID1
list EffectValues1; //效果值列表1
+ BYTE TriggerWay1; //触发方式
+ BYTE TriggerSrc1; //触发来源
+ list TriggerParams1; //触发参数
DWORD EffectID2; //效果ID2
list EffectValues2; //效果值列表2
+ BYTE TriggerWay2; //触发方式
+ BYTE TriggerSrc2; //触发来源
+ list TriggerParams2; //触发参数
DWORD EffectID3; //效果ID3
list EffectValues3; //效果值列表3
+ BYTE TriggerWay3; //触发方式
+ BYTE TriggerSrc3; //触发来源
+ list TriggerParams3; //触发参数
DWORD ConnSkill; //关联技能
+ WORD CoolDownTime; //技能冷却时间
+ list IgnoreStates; //无视限制列表
+ list BuffStates; //Buff状态值
+ WORD LastTime; //持续时间
+ BYTE LayerCnt; //Buff层数
+ BYTE LayerMax; //最大层数
+ DWORD BuffRepeat; //Buff叠加规则
+ DWORD DieContinue; //Buff死亡存在
list EnhanceSkillList; //触发技能ID列表
DWORD FightPower; //技能战斗力
};
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 0774adf..76ed1de 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
@@ -2235,8 +2235,6 @@
atkObj.SetDict(ChConfig.Def_PlayerKey_LastHurtNPCObjID, defObj.GetID())
else:
defObj.SetDict(ChConfig.Def_PlayerKey_LastAttackerObjID, atkObj.GetID())
-
- #TurnAttack.AddTurnObjHurtValue(atkObj, defObj, resultHurtType.HurtType, resultHurtType.RealHurtHP, resultHurtType.LostHP, curSkill)
#if resultHurtType.RealHurtHP:
# PassiveBuffEffMng.OnPassiveSkillTrigger(defObj, atkObj, None, ChConfig.TriggerType_BeHurt, tick)
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 cd9560f..f546b05 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BattleObj.py
@@ -27,6 +27,139 @@
import TurnPassive
import TurnBuff
+class PassiveEffManager():
+ ## 被动效果管理器
+
+ def __init__(self, batObj):
+ self._batObj = batObj
+ # 被影响的技能ID: 0为所有技能
+ self._AffectSkillDict = {} # 被动技能 {(触发方式, 被影响的技能ID):{技能ID:[effID, ...], ...}, ...}
+ self._AffectBuffDict = {} # 被动buff {(触发方式, 被影响的技能ID):{buffID:[effID, ...], ...}, ...}
+ return
+
+ def GetPassiveEffByTrigger(self, triggerWay, connSkill=None):
+ '''获取可触发的效果列表,技能跟buff根据触发优先级按顺序触发,优先级越高越先执行,相同时技能优先
+ 优先级之后有需要再扩展
+ @return: [["skill/buff", skillID/buffID, effIDList], ...]
+ '''
+ connSkillID = connSkill.GetSkillTypeID() if connSkill else 0
+ effList = []
+ # 技能
+ key = (triggerWay, connSkillID)
+ if key in self._AffectSkillDict:
+ effDict = self._AffectSkillDict[key]
+ for skillID, effIDList in effDict.items():
+ effList.append(["skill", skillID, effIDList])
+ if connSkillID != 0:
+ key = (triggerWay, 0)
+ effDict = self._AffectSkillDict.get(key, {})
+ for skillID, effIDList in effDict.items():
+ effList.append(["skill", skillID, effIDList])
+
+ # buff
+ key = (triggerWay, connSkillID)
+ if key in self._AffectBuffDict:
+ effDict = self._AffectBuffDict[key]
+ for buffID, effIDList in effDict.items():
+ effList.append(["buff", buffID, effIDList])
+ if connSkillID != 0:
+ key = (triggerWay, 0)
+ effDict = self._AffectBuffDict.get(key, {})
+ for buffID, effIDList in effDict.items():
+ effList.append(["buff", buffID, effIDList])
+
+ return effList
+
+ def RefreshSkillPassiveEffect(self):
+ self._AffectSkillDict = {}
+
+ skillManager = self._batObj.GetSkillManager()
+ for index in range(0, skillManager.GetSkillCount()):
+ curSkill = skillManager.GetSkillByIndex(index)
+ if not curSkill:
+ continue
+ for index in xrange(curSkill.GetEffectCount()):
+ curEffect = curSkill.GetEffect(index)
+ effectID = curEffect.GetEffectID()
+ if effectID == 0:
+ continue
+ self.AddSkillPassiveEffect(curSkill, curEffect)
+
+ return self._AffectSkillDict
+
+ def AddSkillPassiveEffect(self, curSkill, effect):
+ ## 添加技能被动效果
+ triggerWay = effect.GetTriggerWay()
+ triggerSrc = effect.GetTriggerSrc()
+ if not triggerWay or triggerSrc != 1:
+ return
+
+ skillID = curSkill.GetSkillID()
+ connSkillID = curSkill.GetConnSkill()
+ #priority = curSkill.GetPriority()
+
+ effectID = effect.GetEffectID()
+
+ key = (triggerWay, connSkillID)
+ if key not in self._AffectSkillDict:
+ self._AffectSkillDict[key] = {}
+ effDict = self._AffectSkillDict[key]
+ if skillID not in effDict:
+ effDict[skillID] = []
+ effDict[skillID].append(effectID)
+ return
+
+ def RefreshBuffPassiveEffect(self):
+ self._AffectBuffDict = {}
+ buffMgr = self._batObj.GetBuffManager()
+ for index in range(buffMgr.GetBuffCount()):
+ buff = buffMgr.GetBuffByIndex(index)
+ if not buff:
+ continue
+ skillData = buff.GetSkillData()
+ for index in xrange(skillData.GetEffectCount()):
+ curEffect = skillData.GetEffect(index)
+ effectID = curEffect.GetEffectID()
+ if effectID == 0:
+ continue
+ self.AddBuffPassiveEffect(buff, skillData, curEffect)
+
+ return self._AffectBuffDict
+
+ def AddBuffPassiveEffect(self, buff, skillData, effect):
+ '''添加Buff被动效果
+ 同个buff的技能ID如果叠加规则是独立的,那么可能同时存在多个相同技能效果的buff
+ 如果触发效果,就要触发多次,所以buff的效果以buffID为key
+ '''
+ triggerWay = effect.GetTriggerWay()
+ triggerSrc = effect.GetTriggerSrc()
+ if not triggerWay or triggerSrc != 2:
+ return
+
+ buffID = buff.GetBuffID()
+ connSkillID = skillData.GetConnSkill()
+ #priority = skillData.GetPriority()
+
+ effectID = effect.GetEffectID()
+ key = (triggerWay, connSkillID)
+ if key not in self._AffectBuffDict:
+ self._AffectBuffDict[key] = {}
+ effDict = self._AffectBuffDict[key]
+ if buffID not in effDict:
+ effDict[buffID] = []
+ effDict[buffID].append(effectID)
+ return
+
+ def DelBuffPassiveEffect(self, buffID):
+ ## 删除Buff被动效果
+ for key, effDict in self._AffectBuffDict.items():
+ if buffID not in effDict:
+ continue
+ effDict.pop(buffID)
+ if not effDict:
+ self._AffectBuffDict.pop(key)
+ return
+
class HurtObj():
## 伤血统计
@@ -54,7 +187,7 @@
return
def HaveHurtType(self, hurtType):
## 判断是否存在某种伤血类型
- return self._hurtTypes&pow(2, hurtType)
+ return self._hurtTypes & pow(2, hurtType)
def GetHurtHP(self): return self._hurtHP
def SetHurtHP(self, hurtHP): self._hurtHP = hurtHP
def GetLostHP(self): return self._lostHP
@@ -66,26 +199,40 @@
def GetBounceHP(self): return self._bounceHP
def SetBounceHP(self, bounceHP): self._bounceHP = bounceHP
-class Effect():
+class SkillEffect():
- def __init__(self, effID, values):
+ def __init__(self, effID, values, triggerWay=0, triggerSrc=0, triggerParams=None):
self._effID = effID
self._values = values
+ self._triggerWay = triggerWay
+ self._triggerSrc = triggerSrc
+ self._triggerParams = triggerParams if triggerParams else []
return
def GetEffectID(self): return self._effID
def GetEffectValue(self, index): return self._values[index] if len(self._values) > index else 0
def GetEffectValueCount(self): return len(self._values)
+ def GetTriggerWay(self): return self._triggerWay
+ def GetTriggerSrc(self): return self._triggerSrc
+ def GetTriggerParams(self, index): return self._triggerParams[index] if len(self._triggerParams) > index else 0
+EmptyEffect = SkillEffect(0, [])
+
class SklllData():
def __init__(self, ipyData):
self._ipyData = ipyData
self._effList = [] # [Effect, ...]
+ self._effDict = {} # {effID:Effect, ...}
for num in range(1, 1 + 3):
effID = getattr(ipyData, "GetEffectID%s" % num)()
values = getattr(ipyData, "GetEffectValues%s" % num)()
- self._effList.append(ObjPool.GetPoolMgr().acquire(Effect, effID, values))
+ triggerWay = getattr(ipyData, "GetTriggerWay%s" % num)()
+ triggerSrc = getattr(ipyData, "GetTriggerSrc%s" % num)()
+ triggerParams = getattr(ipyData, "GetTriggerParams%s" % num)()
+ effect = ObjPool.GetPoolMgr().acquire(SkillEffect, effID, values, triggerWay, triggerSrc, triggerParams)
+ self._effList.append(effect)
+ self._effDict[effID] = effect
return
def GetSkillID(self): return self._ipyData.GetSkillID()
@@ -101,12 +248,22 @@
def GetTagSelf(self): return self._ipyData.GetTagSelf() # 是否含自己
def GetTagAffect(self): return self._ipyData.GetTagAffect() # 目标细分
def GetTagCount(self): return self._ipyData.GetTagCount() # 目标个数
- def GetHappenRate(self): return self._ipyData.GetHappenRate() # 释放或添加几率
- def GetLastTime(self): return self._ipyData.GetLastTime() # 持续时间
- def GetCoolDownTime(self): return self._ipyData.GetCoolDownTime()
+ def GetCalcType(self): return self._ipyData.GetCalcType()
+ def GetSkillPer(self): return self._ipyData.GetSkillPer()
+ def GetSkillValue(self): return self._ipyData.GetSkillValue()
+ def GetHappenRate(self): return self._ipyData.GetHappenRate() # 触发概率
def GetEffect(self, index): return self._effList[index] if len(self._effList) > index else 0
def GetEffectCount(self): return len(self._effList)
- def GetConnSkill(self): return self._ipyData.GetConnSkill() # 关联技能
+ def GetEffectByID(self, effID): return self._effDict.get(effID, EmptyEffect)
+ def GetConnSkill(self): return self._ipyData.GetConnSkill()
+ def GetCoolDownTime(self): return self._ipyData.GetCoolDownTime()
+ def GetIgnoreStates(self): return self._ipyData.GetIgnoreStates() # 无视限制列表
+ def GetBuffStates(self): return self._ipyData.GetBuffStates()
+ def GetLastTime(self): return self._ipyData.GetLastTime() # 持续时间
+ def GetLayerCnt(self): return self._ipyData.GetLayerCnt()
+ def GetLayerMax(self): return self._ipyData.GetLayerMax()
+ def GetBuffRepeat(self): return self._ipyData.GetBuffRepeat() # Buff叠加规则
+ def GetDieContinue(self): return self._ipyData.GetDieContinue() # Buff死亡存在
def GetEnhanceSkillList(self): return self._ipyData.GetEnhanceSkillList() # 额外触发的技能ID列表
def GetFightPower(self): return self._ipyData.GetFightPower()
@@ -117,6 +274,7 @@
self._buffID = 0
self._ownerID = 0
self._layer = 0
+ self._calcTime = 0
self._remainTime = 0
self._valueList = []
return
@@ -129,16 +287,19 @@
def SetOwnerID(self, ownerID): self._ownerID = ownerID
def GetLayer(self): return self._layer
def SetLayer(self, layer): self._layer = layer
+ def GetCalcTime(self): return self._calcTime
+ def SetCalcTime(self, calcTime): self._calcTime = calcTime
def GetRemainTime(self): return self._remainTime
def SetRemainTime(self, remainTime): self._remainTime = remainTime
- def SetValueList(self, valueList): self._valueList = valueList
- def GetValue(self, index):
+ def SetBuffValueList(self, valueList): self._valueList = valueList
+ def GetBuffValue(self, index):
return self._valueList[index] if len(self._valueList) > index else 0
class BuffManager():
## 战斗对象buff管理器
- def __init__(self):
+ def __init__(self, batObj):
+ self._batObj = batObj
self._buffList = [] # [PyBuff, ...]
self._buffIDDict = {} # {buffID:PyBuff, ...}
self._skillTypeIDBuffIDs = {} # 技能TypeID对应的buff {skillTypeID:[buffID, ...], ...}
@@ -158,12 +319,8 @@
return
def GetBuffCount(self): return len(self._buffList)
- def GetBuffByIndex(self, index):
- buff = self._buffList[index]
- #if False:
- # buff = PyBuff()
- return buff
-
+ def GetBuffByIndex(self, index): return self._buffList[index]
+
def AddBuff(self, skillID):
buff = None
ipyData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
@@ -172,19 +329,18 @@
skillTypeID = ipyData.GetSkillTypeID()
self._buffID += 1
+ buffID = self._buffID
buff = ObjPool.GetPoolMgr().acquire(PyBuff, ipyData)
- buff.SetBuffID(self._buffID)
+ buff.SetBuffID(buffID)
self._buffList.append(buff)
- self._buffIDDict[self._buffID] = buff
+ self._buffIDDict[buffID] = buff
if skillTypeID not in self._skillTypeIDBuffIDs:
self._skillTypeIDBuffIDs[skillTypeID] = []
buffIDs = self._skillTypeIDBuffIDs[skillTypeID]
- if self._buffID not in buffIDs:
- buffIDs.append(self._buffID)
+ if buffID not in buffIDs:
+ buffIDs.append(buffID)
- #if False:
- # buff = PyBuff()
return buff
def DelBuff(self, buffID):
@@ -202,14 +358,7 @@
break
return
- def GetBuff(self, buffID):
- buff = None
- if buffID in self._buffIDDict:
- buff = self._buffIDDict[buffID]
- #if False:
- # buff = PyBuff()
- return buff
-
+ def GetBuff(self, buffID): return self._buffIDDict.get(buffID, None)
def FindBuffIDBySkillID(self, skillID):
## 返回该技能ID的所有buffID列表
skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
@@ -244,25 +393,34 @@
if buffID not in buffIDList:
return
buffIDList.remove(buffID)
- if not len(buffIDList):
+ if not buffIDList:
self._buffStateDict.pop(state)
GameWorld.DebugLog(" DelBuffState state=%s,buffID=%s,%s" % (state, buffID, self._buffStateDict))
return
- def IsInBuffState(self, state):
- ## 是否处于某种状态下
- return state in self._buffStateDict and len(self._buffStateDict[state]) > 0
+ def IsInBuffState(self, state): return state in self._buffStateDict ## 是否处于某种状态下
+ def GetStateBuffIDList(self, state): return self._buffStateDict.get(state, []) # 获取某种状态的所有buffID列表
+
class PySkill():
def __init__(self, ipyData):
self._skillData = ObjPool.GetPoolMgr().acquire(SklllData, ipyData)
+ self._calcTime = 0
self._remainTime = 0
self._batType = 0 # 战斗类型,普通、连击、反击、追击等
self._tagObjList = [] # 本次技能目标列表 [BatObj, ...]
self._hurtList = [] # 本次伤血列表,可能同一个对象有多个伤害,如弹射等 [HurtObj, ...]
self._bySkill = None # 由哪个技能触发的
self._isEnhanceSkill = False # 是否由主技能额外触发的(非被动触发,即主技能的EnhanceSkillList字段中的技能)
+ return
+
+ def ResetUseRec(self):
+ self._batType = 0
+ self._tagObjList = []
+ self._bySkill = None
+ self._isEnhanceSkill = False
+ self.ClearHurtObj()
return
def GetSkillID(self): return self._skillData.GetSkillID()
@@ -278,16 +436,28 @@
def GetTagSelf(self): return self._skillData.GetTagSelf() # 是否含自己
def GetTagAffect(self): return self._skillData.GetTagAffect() # 目标细分
def GetTagCount(self): return self._skillData.GetTagCount() # 目标个数
- def GetHappenRate(self): return self._skillData.GetHappenRate() # 释放或添加几率
- def GetLastTime(self): return self._skillData.GetLastTime() # 持续时间
- def GetCoolDownTime(self): return self._skillData.GetCoolDownTime()
+ def GetCalcType(self): return self._skillData.GetCalcType()
+ def GetSkillPer(self): return self._skillData.GetSkillPer()
+ def GetSkillValue(self): return self._skillData.GetSkillValue()
+ def GetHappenRate(self): return self._skillData.GetHappenRate() # 触发概率
def GetEffect(self, index): return self._skillData.GetEffect(index)
def GetEffectCount(self): return self._skillData.GetEffectCount()
- def GetConnSkill(self): return self._skillData.GetConnSkill() # 关联技能
+ def GetEffectByID(self, effID): return self._skillData.GetEffectByID()
+ def GetConnSkill(self): return self._skillData.GetConnSkill()
+ def GetCoolDownTime(self): return self._skillData.GetCoolDownTime()
+ def GetIgnoreStates(self): return self._skillData.GetIgnoreStates() # 无视限制列表
+ def GetBuffStates(self): return self._skillData.GetBuffStates()
+ def GetLastTime(self): return self._skillData.GetLastTime() # 持续时间
+ def GetLayerCnt(self): return self._skillData.GetLayerCnt()
+ def GetLayerMax(self): return self._skillData.GetLayerMax()
+ def GetBuffRepeat(self): return self._skillData.GetBuffRepeat() # Buff叠加规则
+ def GetDieContinue(self): return self._skillData.GetDieContinue() # Buff死亡存在
def GetEnhanceSkillList(self): return self._skillData.GetEnhanceSkillList() # 额外触发的技能ID列表
def GetFightPower(self): return self._skillData.GetFightPower()
## ---------------------------------- 非技能表内容 ----------------------------------
+ def GetCalcTime(self): return self._calcTime
+ def SetCalcTime(self, calcTime): self._calcTime = calcTime
def GetRemainTime(self): return self._remainTime
def SetRemainTime(self, remainTime): self._remainTime = remainTime
def GetBatType(self): return self._batType
@@ -392,7 +562,8 @@
self._skillUseCntDict = {} # 技能累计使用次数 {skillID:useCnt, ...}
self._skillTurnUseCntDict = {} # 技能单回合累计使用次数 {skillID:useCnt, ...}
self._skillMgr = ObjPool.GetPoolMgr().acquire(SkillManager)
- self._buffMgr = ObjPool.GetPoolMgr().acquire(BuffManager)
+ self._buffMgr = ObjPool.GetPoolMgr().acquire(BuffManager, self)
+ self._passiveEffMgr = ObjPool.GetPoolMgr().acquire(PassiveEffManager, self)
# 统计
self.hurtStat = 0 # 输出统计
@@ -460,6 +631,7 @@
def GetSkillManager(self): return self._skillMgr
def GetBuffManager(self):return self._buffMgr
+ def GetPassiveEffManager(self):return self._passiveEffMgr
def GetCanAttack(self):
## 可否被攻击
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 4e600cb..31df10d 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -35,6 +35,7 @@
import SkillCommon
import AttackCommon
import BattleObj
+import TurnPassive
import TurnSkill
import TurnBuff
import ObjPool
@@ -43,6 +44,7 @@
import time
import json
+TimelineSet = 10000 # 单回合最大时间轴
PosNumMax = 10 # 最大站位编号
ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
@@ -67,6 +69,8 @@
self.shapeType = 0 # 阵型
self.fightPower = 0 # 阵容总战力
self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
+ self.lingshouObjIDDict = {} # 灵兽战斗单位 {位置编号:batObjID, ...}
+ self.beautyObjIDDict = {} # 红颜战斗单位 {位置编号:batObjID, ...}
self.actionNum = ActionNumStart # 行动位置,从1开始
return
@@ -86,12 +90,16 @@
def clearLineup(self):
## 清除阵容
- if not self.posObjIDDict:
- return
batObjMgr = BattleObj.GetBatObjMgr()
for objID in self.posObjIDDict.values():
batObjMgr.delBatObj(objID)
+ for objID in self.lingshouObjIDDict.values():
+ batObjMgr.delBatObj(objID)
+ for objID in self.beautyObjIDDict.values():
+ batObjMgr.delBatObj(objID)
self.posObjIDDict = {}
+ self.lingshouObjIDDict = {}
+ self.beautyObjIDDict = {}
self.fightPower = 0
return
@@ -151,6 +159,7 @@
self.factionDict = {} # 战斗阵营 {faction:BatFaction, ...},一般是只有两个阵营,faction为1或2,每个阵营支持多个阵容
self.actionSortList = [] # 阵容行动顺序 [[faction, num], ...]
self.actionIndex = 0 # 行动顺序索引
+ self.timeline = 0 # 时间轴节点 turnNum*1000+actionIndex*100++actionNum
self.startTime = 0 # 开始时间戳,支持毫秒小数
self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
@@ -197,18 +206,35 @@
for batFaction in self.factionDict.values():
faction = batFaction.faction
for num, batLineup in batFaction.lineupDict.items():
+ isPlayer = 1 if batLineup.ownerID else 0 # 玩家阵容优先攻击
fightPower = batLineup.fightPower
sortValue = -(faction * 10 + num)
- sortList.append([fightPower, sortValue, faction, num])
+ sortList.append([isPlayer, fightPower, sortValue, faction, num])
sortList.sort(reverse=True) # 战力高的先手
self.actionIndex = 0
self.actionSortList = []
- for _, _, faction, num in sortList:
+ for _, _, _, faction, num in sortList:
self.actionSortList.append([faction, num])
- GameWorld.DebugLog("阵容战力排序[fp, sortV, f, n]: %s" % sortList)
+ GameWorld.DebugLog("阵容战力排序[isPlayer, fp, sortV, f, n]: %s" % sortList)
GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
+ return
+
+ def getTimeline(self): return self.timeline
+ def setTimeline(self, turnNum):
+ '''回合战斗的时间轴节点 ,即第几回合开始,每个回合支持9999个行动节点
+ @param turnNum: 第x回合
+ '''
+ self.timeline = turnNum * TimelineSet + 0
+ GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
+ OnTimelineChange(self)
+ return
+ def addTimeline(self):
+ ## 每切换一个行动单位可视为一个行动节点,即代表单回合战斗中的某一个时间节点
+ self.timeline += 1
+ GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
+ OnTimelineChange(self)
return
def getBatFaction(self, faction=ChConfig.Def_FactionA):
@@ -263,6 +289,7 @@
def startFight(self):
## 准备就绪,开始战斗
self.state = FightState_Start
+ self.setTimeline(1)
self.syncInit()
return
@@ -587,7 +614,7 @@
skillManager.LearnSkillByID(skillID)
batLineup.posObjIDDict[posNum] = objID
- GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s" % (objID, faction, num, posNum, skillIDList))
+ GameWorld.DebugLog("AddBatObj ID:%s,%s,skill=%s" % (objID, GetObjName(batObj), skillIDList))
batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
return
@@ -847,12 +874,15 @@
## 关卡boss是一次性处理完的,一般不可能走到这里,这边做下防范
return
- # 以下均是处理关卡小怪分段实时战斗
-
- EntryLogic(turnFight)
-
# 小怪战斗,每次消耗1个战锤
fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
+
+ if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ GameWorld.DebugLog("回合开始时战锤不足!")
+ return
+
+ # 以下均是处理关卡小怪分段实时战斗
+ EntryLogic(turnFight)
# 按阵营阵容执行顺序,逐个遍历
doCnt = 0
@@ -869,18 +899,19 @@
if turnFight.turnStart < turnNum:
GameWorld.DebugLog("执行行动: turnNum=%s, 回合开始" % (turnFight.turnNum))
turnFight.syncState(FightState_Fighting)
- if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("回合开始时战锤不足!")
- return
+ #if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ # GameWorld.DebugLog("回合开始时战锤不足!")
+ # return
turnFight.turnStart = turnNum
turnFight.actionIndex = 0
+ turnFight.addTimeline() # 每回合开始算一个时间节点
for faction, num in turnFight.actionSortList:
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
batLineup.actionNum = ActionNumStart
for objID in batLineup.posObjIDDict.values():
batObj = batObjMgr.getBatObj(objID)
- TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
+ TurnFightPerTurnBigStart(turnFight, batObj, turnNum)
if turnFight.actionIndex >= len(turnFight.actionSortList):
turnFight.actionIndex = 0
@@ -896,10 +927,6 @@
turnFight.actionIndex += 1
continue
- if faction == ChConfig.Def_FactionA:
- if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("战锤不足!")
- return
GameWorld.DebugLog("执行行动: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
# 主公
@@ -913,11 +940,13 @@
# 武将
elif batLineup.actionNum > 0:
for posNum in range(batLineup.actionNum, PosNumMax + 1):
+ turnFight.addTimeline() # 每个武将位算一个时间节点
batLineup.actionNum = posNum
if posNum not in batLineup.posObjIDDict:
continue
objID = batLineup.posObjIDDict[posNum]
batObj = batObjMgr.getBatObj(objID)
+ TurnFightHeroTurnStart(turnFight, batObj, turnNum)
if not OnObjAction(turnFight, batObj):
continue
@@ -948,21 +977,24 @@
if len(overLineupList) >= len(turnFight.actionSortList):
GameWorld.DebugLog("执行行动: turnNum=%s, 回合结束" % (turnFight.turnNum))
if turnFight.turnEnd < turnNum:
- if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("回合结束时战锤不足!")
- return
+ #if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ # GameWorld.DebugLog("回合结束时战锤不足!")
+ # return
turnFight.turnEnd = turnNum
+ turnFight.addTimeline() # 每回合结束算一个时间节点
for faction, num in turnFight.actionSortList:
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
for objID in batLineup.posObjIDDict.values():
- pass
-
+ batObj = batObjMgr.getBatObj(objID)
+ TurnFightPerTurnBigEnd(turnFight, batObj, turnNum)
+
if turnFight.checkOverByKilled():
return
if turnNum < turnFight.turnMax:
turnFight.turnNum += 1
+ turnFight.setTimeline(turnFight.turnNum) # 回合变更,直接设置新回合时间节点
else:
OnTurnAllOver(turnFight.guid)
@@ -978,10 +1010,12 @@
for turnNum in range(1, turnMax + 1):
turnFight.turnNum = turnNum
GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum)
+ turnFight.setTimeline(turnNum)
if curPlayer:
turnFight.syncState(FightState_Fighting)
# 回合开始
+ turnFight.addTimeline() # 每回合开始算一个时间节点
for faction, num in turnFight.actionSortList:
GameWorld.DebugLog("回合开始逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
batFaction = turnFight.getBatFaction(faction)
@@ -989,19 +1023,19 @@
batLineup.actionNum = 1
for objID in batLineup.posObjIDDict.values():
batObj = batObjMgr.getBatObj(objID)
- TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
+ TurnFightPerTurnBigStart(turnFight, batObj, turnNum)
# 主公
- for faction, num in turnFight.actionSortList:
- GameWorld.DebugLog("主公逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
- batFaction = turnFight.getBatFaction(faction)
- batLineup = batFaction.getBatlineup(num)
+ #for faction, num in turnFight.actionSortList:
+ # GameWorld.DebugLog("主公逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
+ # batFaction = turnFight.getBatFaction(faction)
+ # batLineup = batFaction.getBatlineup(num)
# 红颜
- for faction, num in turnFight.actionSortList:
- GameWorld.DebugLog("红颜逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
- batFaction = turnFight.getBatFaction(faction)
- batLineup = batFaction.getBatlineup(num)
+ #for faction, num in turnFight.actionSortList:
+ # GameWorld.DebugLog("红颜逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
+ # batFaction = turnFight.getBatFaction(faction)
+ # batLineup = batFaction.getBatlineup(num)
if turnFight.checkOverByKilled():
break
@@ -1015,11 +1049,13 @@
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
for posNum in range(batLineup.actionNum, PosNumMax + 1):
+ turnFight.addTimeline() # 每个武将位算一个时间节点
batLineup.actionNum = posNum + 1
if posNum not in batLineup.posObjIDDict:
continue
objID = batLineup.posObjIDDict[posNum]
batObj = batObjMgr.getBatObj(objID)
+ TurnFightHeroTurnStart(turnFight, batObj, turnNum)
if not OnObjAction(turnFight, batObj):
continue
@@ -1031,13 +1067,15 @@
turnFight.actionIndex += 1
# 回合结束
+ turnFight.addTimeline() # 每回合结束算一个时间节点
for faction, num in turnFight.actionSortList:
GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
for objID in batLineup.posObjIDDict.values():
- pass
-
+ batObj = batObjMgr.getBatObj(objID)
+ TurnFightPerTurnBigEnd(turnFight, batObj, turnNum)
+
if turnFight.checkOverByKilled():
break
@@ -1061,35 +1099,101 @@
return
GameWorld.DebugLog("执行进场逻辑...")
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for faction, num in turnFight.actionSortList:
+ batFaction = turnFight.getBatFaction(faction)
+ batLineup = batFaction.getBatlineup(num)
+ batLineup.actionNum = ActionNumStart
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_FightStart)
+
turnFight.enterLogic = True
return
-def TurnFightObjPerTurnStart(turnFight, batObj, turnNum):
- ## 回合制战斗实例 - 每回合开始时处理
+def OnTimelineChange(turnFight):
+
+ nowTimeline = turnFight.getTimeline()
+
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for batFaction in turnFight.factionDict.values():
+ for batLineup in batFaction.lineupDict.values():
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ if not batObj or batObj.GetHP() <= 0:
+ continue
+ curID = batObj.GetID()
+ skillManager = batObj.GetSkillManager()
+ for index in range(0, skillManager.GetSkillCount()):
+ curSkill = skillManager.GetSkillByIndex(index)
+ if not curSkill:
+ continue
+ remainTime = curSkill.GetRemainTime()
+ if not remainTime:
+ continue
+ calcTimeline = curSkill.GetCalcTime()
+ passTurn = __calcPassturn(calcTimeline, nowTimeline, True)
+ if passTurn <= 0:
+ continue
+ skillID = curSkill.GetSkillID()
+ updRemainTime = max(0, remainTime - passTurn)
+ curSkill.SetRemainTime(updRemainTime)
+ curSkill.SetCalcTime(nowTimeline)
+ GameWorld.DebugLog("更新技能剩余回合数: curID=%s,skillID=%s,updRemainTime=%s,calcTimeline=%s,passTurn=%s"
+ % (curID, skillID, updRemainTime, calcTimeline, passTurn))
+
+ buffMgr = batObj.GetBuffManager()
+ for index in range(buffMgr.GetBuffCount())[::-1]:
+ buff = buffMgr.GetBuffByIndex(index)
+ remainTime = buff.GetRemainTime()
+ if not remainTime:
+ # 永久buff不处理
+ continue
+ calcTimeline = buff.GetCalcTime()
+ passTurn = __calcPassturn(calcTimeline, nowTimeline, False)
+ if passTurn <= 0:
+ continue
+
+ updRemainTime = max(0, remainTime - passTurn)
+ buffID = buff.GetBuffID()
+ skillID = buff.GetSkillID()
+ GameWorld.DebugLog("更新buff剩余回合数: curID=%s,buffID=%s,skillID=%s,updRemainTime=%s,calcTimeline=%s,passTurn=%s"
+ % (curID, buffID, skillID, updRemainTime, calcTimeline, passTurn))
+ if updRemainTime > 0:
+ buff.SetRemainTime(updRemainTime)
+ buff.SetCalcTime(nowTimeline)
+ TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
+ else:
+ TurnBuff.DoBuffDel(turnFight, batObj, buff)
+
+ return
+
+def __calcPassturn(calcTimeline, nowTimeline, equalOK):
+ ## 计算已经过了的回合数
+ # @param equalOK: 时间节点相同时是否算1回合,一般技能可以算,buff不算
+ calcTurnNum = calcTimeline / TimelineSet
+ calcTimeNode = calcTimeline % TimelineSet
+ nowTurnNum = nowTimeline / TimelineSet
+ nowTimeNode = nowTimeline % TimelineSet
+ if equalOK:
+ if nowTimeNode >= calcTimeNode:
+ return max(0, nowTurnNum - calcTurnNum)
+ return max(0, nowTurnNum - calcTurnNum - 1)
+ else:
+ if nowTimeNode > calcTimeNode:
+ return max(0, nowTurnNum - calcTurnNum)
+ return max(0, nowTurnNum - calcTurnNum - 1)
+ return 0
+
+def TurnFightPerTurnBigStart(turnFight, batObj, turnNum):
+ ## 大回合开始时
if not batObj:
return
if batObj.GetHP() <= 0:
return
- curID = batObj.GetID()
- buffMgr = batObj.GetBuffManager()
- GameWorld.DebugLog("更新buff: curID=%s,buffCount=%s" % (curID, buffMgr.GetBuffCount()))
- for index in range(buffMgr.GetBuffCount())[::-1]:
- buff = buffMgr.GetBuffByIndex(index)
- curRemainTime = buff.GetRemainTime()
- if not curRemainTime:
- # 永久buff不处理
- continue
- buffID = buff.GetBuffID()
- skillID = buff.GetSkillID()
- updRemainTime = curRemainTime - 1
- GameWorld.DebugLog(" 更新buff剩余回合数: buffID=%s,skillID=%s,updRemainTime=%s" % (buffID, skillID, updRemainTime))
- if updRemainTime > 0:
- buff.SetRemainTime(updRemainTime)
- TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
- else:
- TurnBuff.DoBuffDel(turnFight, batObj, buff)
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
# SetTimeline(gameObj, turnNum, 0)
# # 重置连击、反击数
@@ -1126,6 +1230,28 @@
# __logGameObjAttr(gameObj)
return
+def TurnFightPerTurnBigEnd(turnFight, batObj, turnNum):
+ ## 大回合结束时
+ if not batObj:
+ return
+
+ if batObj.GetHP() <= 0:
+ return
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnEnd)
+ return
+
+def TurnFightHeroTurnStart(turnFight, batObj, turnNum):
+ ## 武将回合开始时
+ if not batObj:
+ return
+
+ if batObj.GetHP() <= 0:
+ return
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_HeroTurnStart)
+ return
+
def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
## 回合对象添加治疗值
# @param curObj: 获得治疗的对象
@@ -1142,12 +1268,11 @@
return
-def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, curSkill=None, isBounce=False):
+def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, skillID=0, isBounce=False):
## 回合对象添加伤害值
# @param isBounce: 是否反弹伤害
curID = curBatObj.GetID()
tagID = tagBatObj.GetID()
- skillID = curSkill.GetSkillID() if curSkill else 0
if curID != tagID:
updStatValue = curBatObj.StatHurtValue(hurtValue)
GameWorld.DebugLog(" 统计伤血: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s,isBounce=%s"
@@ -1183,11 +1308,13 @@
if not canAction:
GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
return
-
+
atk = curBatObj.GetAtk()
curXP = curBatObj.GetXP()
GameWorld.DebugLog("★回合%s %s 行动 : atk=%s,curHP=%s/%s,curXP=%s" % (turnNum, objName, atk, curHP, curBatObj.GetMaxHP(), curXP))
turnFight.syncObjAction(turnNum, objID)
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, curBatObj, ChConfig.TriggerWay_HeroActionStart)
xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
skillManager = curBatObj.GetSkillManager()
@@ -1197,8 +1324,8 @@
useSkill = skillManager.GetSkillByIndex(index)
if not useSkill:
continue
- if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
- #基础普攻不能主动释放,目前仅用于反击
+ if useSkill.GetFuncType() not in [ChConfig.Def_SkillFuncType_TurnNormaSkill, ChConfig.Def_SkillFuncType_AngerSkill]:
+ #只能主动释放普攻或怒技
continue
#被动技能无法使用
if SkillCommon.isPassiveSkill(useSkill):
@@ -1222,9 +1349,10 @@
for useInfo in useSkillList:
useSkill = useInfo[-1]
if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
- return True
+ break
- return
+ TurnPassive.OnTriggerPassiveEffect(turnFight, curBatObj, ChConfig.TriggerWay_HeroActionEnd)
+ return True
def DoAttack(curBatObj, tagBatObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
# curID = curBatObj.GetID()
@@ -1379,45 +1507,6 @@
GameWorld.DebugLog(" 可以连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)"
% (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
return True
-
-#def GetEnemyObj(curNPC, ruleType=0):
-# ## 获取一个敌对单位,针对所有敌对阵容主战单位,优先选择对位阵容单位,仅限活着的单位
-# # @param ruleType: 选择规则,默认0任意,1-最低血量;2-最高血量
-# objID = curNPC.GetID()
-# faction = GameObj.GetFaction(curNPC)
-# posInfo = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
-# num = posInfo / 100 # 阵容编号
-# posNum = posInfo % 100 # 所在阵容站位
-# turnFight = GetTurnFightMgr().getTurnFight(curNPC.GetTFGUID())
-# if not turnFight:
-# return
-#
-# tagBatFaction = turnFight.getBatFaction(Def_FactionB if faction == Def_FactionA else Def_FactionA)
-#
-# tagLineupNumList = [num] # 目标阵容选择顺序,优先对位阵容,再其他阵容
-# if num in tagBatFaction.lineupDict:
-# tagLineupNumList = [num]
-# for tagNum in tagBatFaction.lineupDict.keys():
-# if tagNum not in tagLineupNumList:
-# tagLineupNumList.append(tagNum)
-#
-# batObjMgr = BattleObj.GetBatObjMgr()
-# for tagNum in tagLineupNumList:
-# tagLineup = tagBatFaction.getBatlineup(tagNum)
-# tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
-# pNumList = tagLineup.posObjIDDict.keys()
-# pNumList.sort()
-# for pNum in pNumList:
-# if pNum > 0 and pNum not in tagPosNumList:
-# tagPosNumList.append(pNum)
-# for pNum in tagPosNumList:
-# batObj = batObjMgr.getBatObj(objID)
-# if not batObj:
-# continue
-# if batObj.GetHP( )<= 0:
-# continue
-# return batObj
-# return
def SetObjKilled(turnFight, gameObj, killer=None, useSkill=None):
objID = gameObj.GetID()
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index 9abacf7..4e35cc3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -770,8 +770,6 @@
Def_Skill_Effect_BoomSeedHurt = 804 # BUFF种子单层伤害
Def_Skill_Effect_StoreBlood = 809 # 将期间受到的伤害总值,用于最后回血,不影响伤害
Def_Skill_Effect_AttackReplace = 1009 #攻击计算,野外小怪伤害替换1010 (2018-03-07增加精英怪)
-Def_Skill_Effect_Cure = 1000 #治疗
-Def_Skill_Effect_Anger = 1001 #怒气增减偷
Def_Skill_Effect_Attack = 1010 #攻击计算
Def_Skill_Effect_LayerCnt = 1011 # BUFF层级数量 A值层数;B值:10位-是否非叠加属性,个位-层数处理方式0递增1递减;C值: 是否攻击减层
Def_Skill_Effect_MasterBuff = 1012 # 主从技能(同步buff持续时间)
@@ -952,7 +950,7 @@
#伤害类型
(
HurtType_Fail, # 失败 - 如概率没有触发 0
-HurtType_Normal, # 普通伤害 1
+HurtType_Normal, # 伤害 1
HurtTYpe_Recovery, # 回血 2
HurtType_3,
HurtType_4,
@@ -1308,11 +1306,9 @@
Def_CureTypeList = (
Def_Cure_Attack, # 攻击 0
Def_Cure_MaxHP, # 最大生命值 1
-Def_Cure_PNE, # 智力 2
-Def_Cure_PHY, # 敏捷 3
-Def_Cure_HurtValue, # 伤害值 4
-Def_Cure_TagMaxHP, # 目标最大生命值 5
-) = range(6)
+Def_Cure_HurtValue, # 伤害值 2
+Def_Cure_TagMaxHP, # 目标最大生命值 3
+) = range(4)
#回魔类型(影响公式参数)
Def_RestoreTypeList = (
@@ -3141,26 +3137,18 @@
#玩家状态定义,不能超过31个,如超过,需扩展多个key支持
BatObjStateList = (
BatObjState_Normal, # 无 0
- BatObjState_Freezed, # 定身状态 1
- BatObjState_Slow, # 减速状态 2
- BatObjState_LoseBlood, # 持续掉血状态 3
- BatObjState_Shield, # 麒麟佑身4
- BatObjState_DamBackShield, # 东皇附体5
- BatObjState_Sneer, # 嘲讽 6
- BatObjState_Stun, # 晕眩状态 7
- BatObjState_AddAtk, # 加攻状态 8
- BatObjState_WeakDef, # 减防状态 9
- BatObjState_LimitSkill, # 禁魔状态 10
- BatObjState_LimitAddHP, # 禁疗状态 11
- BatObjState_Blind, # 致盲状态 12
- BatObjState_Burn, # 灼烧 13
- BatObjState_LoseBlood2, # 职业2持续掉血状态 14
- BatObjState_LoseBlood3, # 职业3持续掉血状态 15
- BatObjState_MissSneerAtk, # 对嘲讽攻击免疫表现为miss 16
- BatObjState_BeInAir, # 浮空(做法同眩晕类) 17
- BatObjState_zqdlj, # 紫气东来金灵根技能状态 18
- BatObjState_Ice, # 寒冰状态(同减速) 19
-) = range(20)
+ BatObjState_Frozen, # 冰冻 1
+ BatObjState_Cold, # 减速/寒冷 2
+ BatObjState_Stun, # 眩晕 3
+ BatObjState_Burn, # 灼烧 4
+ BatObjState_Poison, # 中毒 5
+ BatObjState_Bleeding, # 流血 6
+ BatObjState_EasyHurt, # 易伤 7
+ BatObjState_Wudi, # 无敌 8
+ BatObjState_Sneer, # 嘲讽 9
+ BatObjState_LimitSkill, # 沉默 10
+ BatObjState_LimitAddHP, # 禁疗 11
+) = range(12)
#玩家状态定义,不能超过31个,如超过,需扩展多个key支持
Def_PlayerStateList = (
@@ -4458,6 +4446,17 @@
#-------------------------------------------------------------------------------
+# 被动触发方式
+(
+TriggerWay_FightStart, # 战斗开始时 1
+TriggerWay_BigTurnStart, # 大回合开始时 2
+TriggerWay_BigTurnEnd, # 大回合结束时 3
+TriggerWay_HeroTurnStart, # 武将回合开始时 4
+TriggerWay_HeroTurnEnd, # 武将回合开始时 5
+TriggerWay_HeroActionStart, # 武将行动前 6
+TriggerWay_HeroActionEnd, # 武将行动后 7
+) = range(1, 1 + 7)
+
(
TriggerType_BeSuperHit, # 被暴击触发技能 1
TriggerType_BuffState, # 进入4012的某个状态触发技能
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index ab67681..5fabeab 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -50236,6 +50236,7 @@
("SubCmd", c_ubyte),
("ObjID", c_int),
("RefreshType", c_ushort), # 同0418刷新类型,如血量、怒气
+ ("AttackTypes", c_int), # 飘字类型汇总,支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
("Value", c_int), # 更新值
("ValueEx", c_int), # 更新值,如果是大数值的此值为整除亿部分
("DiffType", c_ubyte), # 变化类型,0-减少;1-增加
@@ -50261,6 +50262,7 @@
self.SubCmd = 0x18
self.ObjID = 0
self.RefreshType = 0
+ self.AttackTypes = 0
self.Value = 0
self.ValueEx = 0
self.DiffType = 0
@@ -50282,6 +50284,7 @@
SubCmd:%s,
ObjID:%d,
RefreshType:%d,
+ AttackTypes:%d,
Value:%d,
ValueEx:%d,
DiffType:%d,
@@ -50295,6 +50298,7 @@
self.SubCmd,
self.ObjID,
self.RefreshType,
+ self.AttackTypes,
self.Value,
self.ValueEx,
self.DiffType,
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 833d812..65817b5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -86,6 +86,7 @@
"Skill":(
("DWORD", "SkillID", 1),
("DWORD", "SkillTypeID", 0),
+ ("WORD", "SkillLV", 0),
("WORD", "SkillMaxLV", 0),
("char", "SkillName", 0),
("BYTE", "FuncType", 0),
@@ -96,17 +97,34 @@
("BYTE", "TagFriendly", 0),
("BYTE", "TagAffect", 0),
("BYTE", "TagCount", 0),
+ ("BYTE", "CalcType", 0),
+ ("WORD", "SkillPer", 0),
+ ("DWORD", "SkillValue", 0),
("WORD", "HappenRate", 0),
- ("WORD", "LastTime", 0),
- ("WORD", "CoolDownTime", 0),
- ("WORD", "Priority", 0),
("DWORD", "EffectID1", 0),
("list", "EffectValues1", 0),
+ ("BYTE", "TriggerWay1", 0),
+ ("BYTE", "TriggerSrc1", 0),
+ ("list", "TriggerParams1", 0),
("DWORD", "EffectID2", 0),
("list", "EffectValues2", 0),
+ ("BYTE", "TriggerWay2", 0),
+ ("BYTE", "TriggerSrc2", 0),
+ ("list", "TriggerParams2", 0),
("DWORD", "EffectID3", 0),
("list", "EffectValues3", 0),
+ ("BYTE", "TriggerWay3", 0),
+ ("BYTE", "TriggerSrc3", 0),
+ ("list", "TriggerParams3", 0),
("DWORD", "ConnSkill", 0),
+ ("WORD", "CoolDownTime", 0),
+ ("list", "IgnoreStates", 0),
+ ("list", "BuffStates", 0),
+ ("WORD", "LastTime", 0),
+ ("BYTE", "LayerCnt", 0),
+ ("BYTE", "LayerMax", 0),
+ ("DWORD", "BuffRepeat", 0),
+ ("DWORD", "DieContinue", 0),
("list", "EnhanceSkillList", 0),
("DWORD", "FightPower", 0),
),
@@ -2908,29 +2926,47 @@
def GetSkillID(self): return self.attrTuple[0] # 技能ID DWORD
def GetSkillTypeID(self): return self.attrTuple[1] # 技能TypeID DWORD
- def GetSkillMaxLV(self): return self.attrTuple[2] # 最高等级 WORD
- def GetSkillName(self): return self.attrTuple[3] # 技能名 char
- def GetFuncType(self): return self.attrTuple[4] # 功能分类 BYTE
- def GetSkillType(self): return self.attrTuple[5] # 技能类型 BYTE
- def GetHurtType(self): return self.attrTuple[6] # 伤害类型 BYTE
- def GetAtkType(self): return self.attrTuple[7] # 释放方式 BYTE
- def GetTagAim(self): return self.attrTuple[8] # 瞄准位置 BYTE
- def GetTagFriendly(self): return self.attrTuple[9] # 敌我目标 BYTE
- def GetTagAffect(self): return self.attrTuple[10] # 目标细分 BYTE
- def GetTagCount(self): return self.attrTuple[11] # 目标个数 BYTE
- def GetHappenRate(self): return self.attrTuple[12] # 释放或添加几率 WORD
- def GetLastTime(self): return self.attrTuple[13] # 持续时间 WORD
- def GetCoolDownTime(self): return self.attrTuple[14] # 冷却时间 WORD
- def GetPriority(self): return self.attrTuple[15] # 优先级 WORD
- def GetEffectID1(self): return self.attrTuple[16] # 效果ID1 DWORD
- def GetEffectValues1(self): return self.attrTuple[17] # 效果值列表1 list
- def GetEffectID2(self): return self.attrTuple[18] # 效果ID2 DWORD
- def GetEffectValues2(self): return self.attrTuple[19] # 效果值列表2 list
- def GetEffectID3(self): return self.attrTuple[20] # 效果ID3 DWORD
- def GetEffectValues3(self): return self.attrTuple[21] # 效果值列表3 list
- def GetConnSkill(self): return self.attrTuple[22] # 关联技能 DWORD
- def GetEnhanceSkillList(self): return self.attrTuple[23] # 触发技能ID列表 list
- def GetFightPower(self): return self.attrTuple[24] # 技能战斗力 DWORD
+ def GetSkillLV(self): return self.attrTuple[2] # 当前等级 WORD
+ def GetSkillMaxLV(self): return self.attrTuple[3] # 最高等级 WORD
+ def GetSkillName(self): return self.attrTuple[4] # 技能名 char
+ def GetFuncType(self): return self.attrTuple[5] # 功能分类 BYTE
+ def GetSkillType(self): return self.attrTuple[6] # 技能类型 BYTE
+ def GetHurtType(self): return self.attrTuple[7] # 伤害类型 BYTE
+ def GetAtkType(self): return self.attrTuple[8] # 释放方式 BYTE
+ def GetTagAim(self): return self.attrTuple[9] # 瞄准位置 BYTE
+ def GetTagFriendly(self): return self.attrTuple[10] # 敌我目标 BYTE
+ def GetTagAffect(self): return self.attrTuple[11] # 目标细分 BYTE
+ def GetTagCount(self): return self.attrTuple[12] # 目标个数 BYTE
+ def GetCalcType(self): return self.attrTuple[13] # 计算方式 BYTE
+ def GetSkillPer(self): return self.attrTuple[14] # 技能万分比 WORD
+ def GetSkillValue(self): return self.attrTuple[15] # 技能固定值 DWORD
+ def GetHappenRate(self): return self.attrTuple[16] # 释放或添加几率 WORD
+ def GetEffectID1(self): return self.attrTuple[17] # 效果ID1 DWORD
+ def GetEffectValues1(self): return self.attrTuple[18] # 效果值列表1 list
+ def GetTriggerWay1(self): return self.attrTuple[19] # 触发方式 BYTE
+ def GetTriggerSrc1(self): return self.attrTuple[20] # 触发来源 BYTE
+ def GetTriggerParams1(self): return self.attrTuple[21] # 触发参数 list
+ def GetEffectID2(self): return self.attrTuple[22] # 效果ID2 DWORD
+ def GetEffectValues2(self): return self.attrTuple[23] # 效果值列表2 list
+ def GetTriggerWay2(self): return self.attrTuple[24] # 触发方式 BYTE
+ def GetTriggerSrc2(self): return self.attrTuple[25] # 触发来源 BYTE
+ def GetTriggerParams2(self): return self.attrTuple[26] # 触发参数 list
+ def GetEffectID3(self): return self.attrTuple[27] # 效果ID3 DWORD
+ def GetEffectValues3(self): return self.attrTuple[28] # 效果值列表3 list
+ def GetTriggerWay3(self): return self.attrTuple[29] # 触发方式 BYTE
+ def GetTriggerSrc3(self): return self.attrTuple[30] # 触发来源 BYTE
+ def GetTriggerParams3(self): return self.attrTuple[31] # 触发参数 list
+ def GetConnSkill(self): return self.attrTuple[32] # 关联技能 DWORD
+ def GetCoolDownTime(self): return self.attrTuple[33] # 技能冷却时间 WORD
+ def GetIgnoreStates(self): return self.attrTuple[34] # 无视限制列表 list
+ def GetBuffStates(self): return self.attrTuple[35] # Buff状态值 list
+ def GetLastTime(self): return self.attrTuple[36] # 持续时间 WORD
+ def GetLayerCnt(self): return self.attrTuple[37] # Buff层数 BYTE
+ def GetLayerMax(self): return self.attrTuple[38] # 最大层数 BYTE
+ def GetBuffRepeat(self): return self.attrTuple[39] # Buff叠加规则 DWORD
+ def GetDieContinue(self): return self.attrTuple[40] # Buff死亡存在 DWORD
+ def GetEnhanceSkillList(self): return self.attrTuple[41] # 触发技能ID列表 list
+ def GetFightPower(self): return self.attrTuple[42] # 技能战斗力 DWORD
# 武将表
class IPY_Hero():
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 6276416..f04ff00 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
@@ -1283,8 +1283,6 @@
AttackCommon.OnPVPDamage(attackerOwner, lostValue, curObj, "SkillLostHP")
elif curObjType == IPY_GameWorld.gotNPC:
AttackCommon.NPCAddObjInHurtList(attackerOwner, curObj, curObjHP_BeforeAttack, lostValue)
-
- #TurnAttack.AddTurnObjHurtValue(buffOwner, curObj, lostValue, lostHP, curSkill)
#统一调用攻击结束动作
if isDoAttackResult:
@@ -2075,12 +2073,12 @@
cureBaseValue = GetCureBaseValue(userObj, curSkill)
elif cureType == ChConfig.Def_Cure_MaxHP:
cureBaseValue = GameObj.GetMaxHP(userObj)
- elif cureType == ChConfig.Def_Cure_PNE:
- cureBaseValue = userObj.GetPNE()
- addPer = curSkill.GetEffect(0).GetEffectValue(2)/float(ChConfig.Def_MaxRateValue)
- addExValue = GetCureBaseValue(userObj, curSkill)*addPer
- elif cureType == ChConfig.Def_Cure_PHY:
- cureBaseValue = GameObj.GetMaxHP(userObj)
+ #elif cureType == ChConfig.Def_Cure_PNE:
+ # cureBaseValue = userObj.GetPNE()
+ # addPer = curSkill.GetEffect(0).GetEffectValue(2)/float(ChConfig.Def_MaxRateValue)
+ # addExValue = GetCureBaseValue(userObj, curSkill)*addPer
+ #elif cureType == ChConfig.Def_Cure_PHY:
+ # cureBaseValue = GameObj.GetMaxHP(userObj)
elif cureType == ChConfig.Def_Cure_HurtValue:
cureBaseValue = GameObj.GetLastHurtValue(userObj)
elif cureType == ChConfig.Def_Cure_TagMaxHP:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5001.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5001.py
new file mode 100644
index 0000000..c5e745b
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/PassiveTrigger/PassiveEff_5001.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.PassiveTrigger.PassiveEff_5001
+#
+# @todo:buff层数结算持续buff
+# @author hxp
+# @date 2025-08-19
+# @version 1.0
+#
+# 详细描述: buff层数结算持续buff
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-19 16:00"""
+#-------------------------------------------------------------------------------
+
+import TurnBuff
+
+def DoBuffEffectLogic(turnFight, batObj, curBuff, curEffect, connSkill):
+ singleLayerCnt = max(1, curEffect.GetEffectValue(0)) # 单次消耗层数/次数
+ noDel = curEffect.GetEffectValue(1) # 是否不扣除层数,默认0-扣除 1-不扣除
+ isAll = curEffect.GetEffectValue(2) # 是否结算剩余全部层数/次数,默认0结算单次
+
+ skillData = curBuff.GetSkillData()
+ nowLayerCnt = curBuff.GetLayer()
+
+ # 全部层级
+ if isAll:
+ logicCnt = nowLayerCnt / singleLayerCnt
+ updLayerCnt = 0
+ else:
+ logicCnt = 1 # 执行逻辑次数
+ updLayerCnt = nowLayerCnt - singleLayerCnt
+
+ for _ in range(logicCnt):
+ TurnBuff.DoBuffProcess(turnFight, batObj, curBuff)
+
+ # 消耗层级,有限制层级的才进行消耗
+ if not noDel and skillData.GetLayerCnt():
+ curBuff.SetLayer(max(updLayerCnt, 0))
+ if updLayerCnt <= 0:
+ TurnBuff.DoBuffDel(turnFight, batObj, curBuff)
+ else:
+ TurnBuff.SyncBuffRefresh(turnFight, batObj, curBuff)
+
+ return
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 adfc47f..27ddea2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuff.py
@@ -18,94 +18,100 @@
import ChConfig
import GameWorld
import ChPyNetSendPack
-import SkillCommon
import TurnBuffs
import ObjPool
GameWorld.ImportAll("Script\\Skill\\", "TurnBuffs")
-def OnAddBuff(turnFight, batObj, curSkill, buffOwner=None):
- skillID = curSkill.GetSkillID()
- bySkill = curSkill.GetBySkill()
+def GetAddBuffValue(attacker, defender, curSkill):
+ callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (curSkill.GetAtkType(), "CalcBuffValue"))
+ if not callFunc:
+ return []
+ return callFunc(attacker, defender, curSkill)
+
+def OnAddBuff(turnFight, batObj, buffSkill, buffOwner=None):
+ skillID = buffSkill.GetSkillID()
+ bySkill = buffSkill.GetBySkill()
relatedSkillID = bySkill.GetSkillID() if bySkill else 0
curID = batObj.GetID()
- ownerID = buffOwner.GetID() if buffOwner else curID
- GameWorld.DebugLog("OnAddBuff: curID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s" % (curID, skillID, ownerID, relatedSkillID))
- #检查是否几率触发,附加技能、被动触发的外层已检查过概率,不重复检查
- if not (curSkill.GetIsEnhanceSkill() or SkillCommon.isPassiveTriggerSkill(curSkill)):
- rate = curSkill.GetHappenRate()
- if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
- GameWorld.DebugLog(" 概率不触发buff!")
- return
-
- skillTypeID = curSkill.GetSkillTypeID()
+ if not buffOwner:
+ buffOwner = batObj
+ ownerID = buffOwner.GetID()
+ buffValueList = GetAddBuffValue(buffOwner, batObj, buffSkill)
+ GameWorld.DebugLog("OnAddBuff: curID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s,buffValueList=%s" % (curID, skillID, ownerID, relatedSkillID, buffValueList))
+
+ skillTypeID = buffSkill.GetSkillTypeID()
# 先简单做下能加上即可
buffMgr = batObj.GetBuffManager()
buffIDList = buffMgr.FindBuffIDBySkillTypeID(skillTypeID)
if buffIDList:
GameWorld.DebugLog(" 已经存在该buff: skillTypeID=%s,buffIDList=%s" % (skillTypeID, buffIDList))
+ # buff堆叠逻辑
+
return True
- buff = buffMgr.AddBuff(skillID)
- if not buff:
- GameWorld.DebugLog(" 添加buff失败! skillID=%s" % skillID)
- return False
- GameWorld.DebugLog(" AddBuffOK. buffID=%s" % buff.GetBuffID())
- buff.SetOwnerID(ownerID)
- buff.SetRemainTime(curSkill.GetLastTime())
- #buff.SetLayer()
- SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID)
-
- DoBuffAddOver(turnFight, batObj, curSkill, buff, buffOwner)
+ __AddNewBuff(turnFight, batObj, buffMgr, buffSkill, buffValueList, buffOwner)
return True
-def SyncBuffRefresh(turnFight, curBatObj, curBuff, relatedSkillID=0):
- clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffRefresh)
- clientPack.ObjID = curBatObj.GetID()
- clientPack.BuffID = curBuff.GetBuffID()
- clientPack.SkillID = curBuff.GetSkillID()
- clientPack.RelatedSkillID = relatedSkillID
- clientPack.LastTime = curBuff.GetRemainTime()
- clientPack.Layer = curBuff.GetLayer()
- clientPack.OwnerID = curBuff.GetOwnerID()
- turnFight.addBatPack(clientPack)
+def __AddNewBuff(turnFight, batObj, buffMgr, buffSkill, buffValueList, buffOwner):
+ skillID = buffSkill.GetSkillID()
+ bySkill = buffSkill.GetBySkill()
+ relatedSkillID = bySkill.GetSkillID() if bySkill else 0
+ curID = batObj.GetID()
+ ownerID = buffOwner.GetID()
+ buff = buffMgr.AddBuff(skillID)
+ if not buff:
+ GameWorld.DebugLog(" 添加buff失败! skillID=%s" % skillID, curID)
+ return False
+ buffID = buff.GetBuffID()
+ GameWorld.DebugLog(" AddBuffOK. buffID=%s,skillID=%s,ownerID=%s,relatedSkillID=%s,timeline=%s"
+ % (buffID, skillID, ownerID, relatedSkillID, turnFight.getTimeline()), curID)
+ buff.SetOwnerID(ownerID)
+ buff.SetCalcTime(turnFight.getTimeline())
+ buff.SetRemainTime(buffSkill.GetLastTime())
+ buff.SetLayer(buffSkill.GetLayerCnt())
+ buff.SetBuffValueList(buffValueList)
+ buffStates = buffSkill.GetBuffStates()
+ for buffState in buffStates:
+ buffMgr.AddBuffState(buffState, buffID)
+ isNotify = True
+ if isNotify:
+ SyncBuffRefresh(turnFight, batObj, buff, relatedSkillID)
+
+ DoBuffAddOver(turnFight, batObj, buffSkill, buff, buffOwner)
return
-def SyncBuffDel(turnFight, curBatObj, buffID, relatedSkillID=0):
- clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffDel)
- clientPack.ObjID = curBatObj.GetID()
- clientPack.BuffID = buffID
- clientPack.RelatedSkillID = relatedSkillID
- turnFight.addBatPack(clientPack)
- return
-
-def DoBuffAddOver(turnFight, batObj, curSkill, addBuff, buffOwner=None):
+def DoBuffAddOver(turnFight, batObj, buffSkill, addBuff, buffOwner):
## buff添加成功后处理
isRefreshAttr = False # 是否刷属性
- skillData = addBuff.GetSkillData()
+
+ #atkType = buffSkill.GetAtkType()
+ #if atkType:
+ # callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (atkType, "OnBuffAddOver"))
+ # if callFunc:
+ # callFunc(turnFight, batObj, buffSkill, addBuff, buffOwner)
+
+ passiveEffMgr = batObj.GetPassiveEffManager()
# buff效果加入
- for effectIndex in range(0, skillData.GetEffectCount()):
- curEffect = skillData.GetEffect(effectIndex)
+ for effectIndex in range(0, buffSkill.GetEffectCount()):
+ curEffect = buffSkill.GetEffect(effectIndex)
effectID = curEffect.GetEffectID()
if effectID == 0:
continue
- if effectID in ChConfig.AttrIDList:
+ if curEffect.GetTriggerWay():
+ if curEffect.GetTriggerSrc() == 2:
+ passiveEffMgr.AddBuffPassiveEffect(addBuff, buffSkill, curEffect)
+
+ elif effectID in ChConfig.AttrIDList:
isRefreshAttr = True
- callFunc = GameWorld.GetExecFunc(TurnBuffs, "Buff_%d.%s" % (effectID, "OnBuffAddOver"))
- if callFunc:
- GameWorld.DebugLog("OnBuffAddOver, objID=%s,buffID=%s,effectID=%s" % (batObj.GetID(), addBuff.GetBuffID(), effectID))
- callFunc(turnFight, batObj, curSkill, addBuff, curEffect, buffOwner)
-
- #被动触发的
- #triggerType = PassiveBuffEffMng.GetBuffTriggerTypeByEffectID(effectID)
- #if triggerType == -1:
- # continue
- #passiveEff = PassiveBuffEffMng.GetPassiveEffManager().InitObjPassiveEff(curObj)
- #passiveEff.AddBuffInfoByEffect(curEffect, skillID, onwerID, onwerType)
-
+ else:
+ callFunc = GameWorld.GetExecFunc(TurnBuffs, "Buff_%d.%s" % (effectID, "OnBuffAddOver"))
+ if callFunc:
+ callFunc(turnFight, batObj, buffSkill, addBuff, curEffect, buffOwner)
+
if isRefreshAttr:
RefreshBuffAttr(batObj)
@@ -113,6 +119,9 @@
def DoBuffDel(turnFight, batObj, curBuff):
## 删除buff
+
+ isRefreshAttr = False # 是否刷属性
+ haveBuffPassiveEff = False
buffMgr = batObj.GetBuffManager()
buffID = curBuff.GetBuffID()
@@ -125,20 +134,40 @@
if not effectID:
continue
- callFunc = GameWorld.GetExecFunc(TurnBuffs, "Buff_%d.%s" % (effectID, "OnBuffDel"))
-
- if callFunc:
- callFunc(turnFight, batObj, curBuff, curEffect)
+ if curEffect.GetTriggerWay():
+ if curEffect.GetTriggerSrc() == 2:
+ haveBuffPassiveEff = True
+
+ elif effectID in ChConfig.AttrIDList:
+ isRefreshAttr = True
- #passiveEff = PassiveBuffEffMng.GetPassiveEffManager().GetPassiveEff(curObj)
- #if passiveEff:
- # passiveEff.DelBuffInfo(skillData)
-
+ else:
+ callFunc = GameWorld.GetExecFunc(TurnBuffs, "Buff_%d.%s" % (effectID, "OnBuffDel"))
+ if callFunc:
+ callFunc(turnFight, batObj, curBuff, curEffect)
+
+ if haveBuffPassiveEff:
+ batObj.GetPassiveEffManager().DelBuffPassiveEffect(buffID)
+
+ buffStates = skillData.GetBuffStates()
+ for buffState in buffStates:
+ buffMgr.DelBuffState(buffState, buffID)
+
# 最后删除buff、通知
buffMgr.DelBuff(buffID)
SyncBuffDel(turnFight, batObj, buffID)
+
+ if isRefreshAttr:
+ RefreshBuffAttr(batObj)
return
+def DoBuffProcess(turnFight, batObj, curBuff):
+ skillData = curBuff.GetSkillData()
+ callFunc = GameWorld.GetExecFunc(TurnBuffs, "BuffAtkType_%d.%s" % (skillData.GetAtkType(), "DoBuffProcess"))
+ if callFunc:
+ callFunc(turnFight, batObj, curBuff)
+ return
+
def RefreshBuffAttr(batObj):
''' 刷新buff属性,如果有涉及到buff属性变更的,只能全部buff重新刷
'''
@@ -206,3 +235,23 @@
GameWorld.DebugLog(" befHP=%s/%s, aftHP=%s/%s" % (befHP, befMaxHP, aftHP, aftMaxHP))
GameWorld.DebugLog(" 最终属性 ID:%s,atk=%s,def=%s,hp=%s/%s" % (objID, batObj.GetAtk(), batObj.GetDef(), aftHP, aftMaxHP))
return
+
+def SyncBuffRefresh(turnFight, curBatObj, curBuff, relatedSkillID=0):
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffRefresh)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.BuffID = curBuff.GetBuffID()
+ clientPack.SkillID = curBuff.GetSkillID()
+ clientPack.RelatedSkillID = relatedSkillID
+ clientPack.LastTime = curBuff.GetRemainTime()
+ clientPack.Layer = curBuff.GetLayer()
+ clientPack.OwnerID = curBuff.GetOwnerID()
+ turnFight.addBatPack(clientPack)
+ return
+
+def SyncBuffDel(turnFight, curBatObj, buffID, relatedSkillID=0):
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCBuffDel)
+ clientPack.ObjID = curBatObj.GetID()
+ clientPack.BuffID = buffID
+ clientPack.RelatedSkillID = relatedSkillID
+ turnFight.addBatPack(clientPack)
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1001.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1001.py
new file mode 100644
index 0000000..5cdb4f1
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnBuffs/BuffAtkType_1001.py
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Skill.TurnBuffs.BuffAtk_1001
+#
+# @todo:buff持续攻击
+# @author hxp
+# @date 2025-08-19
+# @version 1.0
+#
+# 详细描述: buff持续攻击
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2025-08-19 16:00"""
+#-------------------------------------------------------------------------------
+
+import TurnSkill
+
+def CalcBuffValue(attacker, defender, curSkill):
+ #calcType = curSkill.GetCalcType()
+ skillPer = curSkill.GetSkillPer()
+ skillValue = curSkill.GetSkillValue()
+
+ hurtValue, hurtTypes = TurnSkill.CalcHurtHP(attacker, defender, curSkill, skillValue, skillPer, damageoftime=1)
+ return [hurtValue, hurtTypes]
+
+def DoBuffProcess(turnFight, batObj, curBuff):
+ ## 执行单次逻辑
+ hurtValue = curBuff.GetBuffValue(0) # 单次伤害
+ hurtTypes = curBuff.GetBuffValue(1)
+ TurnSkill.DoDOTAttack(turnFight, batObj, curBuff, hurtValue, hurtTypes)
+ return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnPassive.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnPassive.py
index 24321a0..c1e7a9b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnPassive.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnPassive.py
@@ -17,9 +17,143 @@
import GameWorld
import PassiveTrigger
+import ChConfig
GameWorld.ImportAll("Script\\Skill\\", "PassiveTrigger")
-
def RefreshPassive(batObj):
- return
\ No newline at end of file
+ ''' 刷新被动效果,一般可能存在于技能或buff中
+ '''
+ passiveEffMgr = batObj.GetPassiveEffManager()
+ skillEffInfo = passiveEffMgr.RefreshSkillPassiveEffect()
+ buffEffInfo = passiveEffMgr.RefreshBuffPassiveEffect()
+ skillEffInfo and GameWorld.DebugLog(" 被动技能效果: %s" % skillEffInfo)
+ buffEffInfo and GameWorld.DebugLog(" 被动Buff效果: %s" % buffEffInfo)
+ return
+
+def OnTriggerPassiveEffect(turnFight, batObj, triggerType, connSkill=None):
+ ''' 触发被动效果,可能触发技能、buff,需根据优先级触发
+ '''
+ passiveEffMgr = batObj.GetPassiveEffManager()
+ effInfoList = passiveEffMgr.GetPassiveEffByTrigger(triggerType, connSkill=connSkill)
+ if not effInfoList:
+ return
+ # [["skill/buff", skillID/buffID, effIDList], ...]
+ GameWorld.DebugLog("触发被动: triggerType=%s,objID=%s,%s" % (triggerType, batObj.GetID(), effInfoList))
+ for effInfo in effInfoList:
+ sign = effInfo[0]
+ if sign == "skill":
+ skillID, effIDList = effInfo[1:]
+ __doTriggerPassiveEffectBySkill(turnFight, batObj, skillID, effIDList, connSkill)
+
+ elif sign == "buff":
+ buffID, effIDList = effInfo[1:]
+ __doTriggerPassiveEffectByBuff(turnFight, batObj, buffID, effIDList, connSkill)
+
+ return
+
+def __doTriggerPassiveEffectBySkill(turnFight, batObj, skillID, effIDList, connSkill=None):
+ return
+
+def __doTriggerPassiveEffectByBuff(turnFight, batObj, buffID, effIDList, connSkill=None):
+ buffMgr = batObj.GetBuffManager()
+ curBuff = buffMgr.GetBuff(buffID)
+ if not curBuff:
+ return
+ skillData = curBuff.GetSkillData()
+
+ for effID in effIDList:
+ curEffect = skillData.GetEffectByID(effID)
+ if not curEffect:
+ continue
+ pyName = "PassiveEff_%s" % effID
+ callFunc = GameWorld.GetExecFunc(PassiveTrigger, "%s.%s" % (pyName, "DoBuffEffectLogic"))
+ if not callFunc:
+ continue
+ callFunc(turnFight, batObj, curBuff, curEffect, connSkill)
+
+ return
+
+def GetTriggerPassiveValue(batObj, triggerType, tagObj=None, useSkill=None):
+ ''' 获取触发被动的值,一般用于某种条件下才会产生的值,如xx情况下属性变化 或 xx情况下是否发生什么
+ @return: 触发的值,0-没有触发或本身触发的值为0;大于0-触发的具体值
+ '''
+ return 0
+# attacker = FindRealAttacker(attacker)
+# if not attacker:
+# return 0
+#
+# stopPassiveSkill = False # 被动技能不能再触发被动技能,但可以触发天赋技能
+# if useSkill and SkillCommon.isPassiveSkill(useSkill) and isStopPassiveSkill:
+# #GameWorld.DebugLog("被动技能不能再次触发被动技能")
+# #return 0
+# if not PassPassiveLimit(useSkill):
+# stopPassiveSkill = True
+#
+#
+# passiveEff = GetPassiveEffManager().GetPassiveEff(attacker)
+# if not passiveEff:
+# return 0
+# buffDict = passiveEff.GetBuffsByTriggerType(triggerType)
+# if not buffDict:
+# return 0
+#
+# # 当前战斗关系 pvp pve
+# battleRelationType = AttackCommon.GetBattleRelationType(attacker, defender)
+# if not AttackCommon.CheckBattleRelationType(attacker, defender, useSkill, battleRelationType):
+# return 0
+#
+# useSkillID = useSkill.GetSkillID() if useSkill else 0
+# #tick = GameWorld.GetGameWorld().GetTick()
+# curValue = 0
+#
+# for skillID, effectList in buffDict.items():
+# if skillID == useSkillID:
+# continue
+# curSkill = GameWorld.GetGameData().GetSkillBySkillID(skillID)
+# if not curSkill:
+# continue
+#
+# if not IsValidPassiveSkill(curSkill):
+# continue
+#
+# triggerCount = 0 # 成功触发次数
+# for effectInfo in effectList:
+# if stopPassiveSkill and curSkill.GetFuncType() != ChConfig.Def_SkillFuncType_GiftSkill:
+# # 只有天赋才可以再次被触发
+# continue
+# passiveEffect = effectInfo[0]
+# # 被动触发的技能
+# pyName = "PassiveBuff_%s"%passiveEffect.GetEffectID()
+#
+# callFunc = GameWorld.GetExecFunc(PassiveBuff, "%s.%s" % (pyName, "CheckCanHappen"))
+# if not callFunc:
+# continue
+#
+# # 条件不满足
+# if not callFunc(attacker, defender, passiveEffect, skillID, useSkill=useSkill, ownerID=effectInfo[1], ownerType=effectInfo[2]):
+# continue
+#
+# callFunc = GameWorld.GetExecFunc(PassiveBuff, "%s.%s" % (pyName, "GetValue"))
+# if callFunc is None:
+# continue
+#
+# # 如被动技能:千幻冥炎真实伤害从2变4倍
+# #curValue += GetPassiveSkillValueByTriggerType(attacker, defender, curSkill, ChConfig.TriggerType_PassiveBuffValue)
+# value = callFunc(attacker, defender, passiveEffect)
+# if triggerType in TriggerValueMaxList:
+# curValue = max(curValue, value) # 取最大值
+# elif triggerType in TriggerValueMinList:
+# if not curValue:
+# curValue = value
+# elif value > 0:
+# curValue = min(curValue, value) # 取最小值
+# else:
+# curValue += value
+#
+# triggerCount += 1
+#
+# if triggerCount:
+# OnTriggerBuffDel(attacker, curSkill, triggerCount)
+#
+# return curValue
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 b41a26b..b35f747 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Skill/TurnSkill.py
@@ -65,14 +65,19 @@
tagAffect = useSkill.GetTagAffect()
tagCount = useSkill.GetTagCount()
tagObjList = GetSkillTags(turnFight, curBatObj, tagAim, tagFriendly, tagAffect, tagCount)
-
- bySkillID = bySkill.GetSkillID() if bySkill else 0
- GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,isEnhanceSkill=%s"
- % (curBatObj.GetID(), skillID, len(tagObjList), batType, bySkillID, isEnhanceSkill))
+ rate = useSkill.GetHappenRate()
+ if rate and rate != ChConfig.Def_MaxRateValue:
+ for tagObj in tagObjList[::-1]:
+ if not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
+ tagObjList.remove(tagObj)
+
if not tagObjList:
# 可扩展其他目标选择,如复活技能没有死亡单位时则使用另外的效果
return
+ bySkillID = bySkill.GetSkillID() if bySkill else 0
+ GameWorld.DebugLog("使用技能: curID=%s,skillID=%s,tagCnt=%s,batType=%s,bySkillID=%s,isEnhanceSkill=%s"
+ % (curBatObj.GetID(), skillID, len(tagObjList), batType, bySkillID, isEnhanceSkill))
# 以下为技能可以使用的处理,之后的逻辑默认技能使用成功
poolMgr = ObjPool.GetPoolMgr()
@@ -117,10 +122,7 @@
turnFight.addBatPack(clientPack)
# 最后重置、回收对象
- useSkill.SetTagObjList([])
- useSkill.SetBySkill(None) # 需重置,防止被误回收
- useSkill.SetIsEnhanceSkill(False)
- useSkill.ClearHurtObj()
+ useSkill.ResetUseRec()
if usePoolSkill:
poolMgr.release(useSkill)
return True
@@ -311,9 +313,19 @@
if atkType == 5:
return
- # 6 怒气增减偷
+ # 怒气增
if atkType == 6:
- SkillModule_6(turnFight, curBatObj, useSkill)
+ SkillModule_6(turnFight, curBatObj, useSkill, "Increase")
+ return
+
+ # 怒气减
+ if atkType == 7:
+ SkillModule_6(turnFight, curBatObj, useSkill, "Reduce")
+ return
+
+ # 怒气偷
+ if atkType == 8:
+ SkillModule_6(turnFight, curBatObj, useSkill, "Steal")
return
return
@@ -357,7 +369,7 @@
DoAttackResult(turnFight, curBatObj, useSkill)
return
-def SkillModule_6(turnFight, curBatObj, useSkill):
+def SkillModule_6(turnFight, curBatObj, useSkill, opType):
## 怒气增减偷
curID = curBatObj.GetID()
@@ -365,24 +377,22 @@
bySkill = useSkill.GetBySkill()
relatedSkillID = bySkill.GetSkillID() if bySkill else 0
- angerPer, angerValue, calcType = 0, 0, 0
- effect = SkillCommon.GetSkillEffectByEffectID(useSkill, ChConfig.Def_Skill_Effect_Anger)
- if effect:
- angerPer = effect.GetEffectValue(0)
- angerValue = effect.GetEffectValue(1)
- calcType = effect.GetEffectValue(2)
+ #cureType = useSkill.GetCalcType()
+ skillPer = useSkill.GetSkillPer()
+ skillValue = useSkill.GetSkillValue()
+
xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
- calcValue = int(xpMax * angerPer / 10000.0 + angerValue)
+ calcValue = int(xpMax * skillPer / 10000.0 + skillValue)
attrID = ChConfig.AttrID_XP
- GameWorld.DebugLog("怒气增减偷: curID=%s,calcValue=%s,skillID=%s,angerPer=%s,angerValue=%s,calcType=%s,relatedSkillID=%s"
- % (curID, calcValue, skillID, angerPer, angerValue, calcType, relatedSkillID))
+ GameWorld.DebugLog("怒气%s: curID=%s,calcValue=%s,skillID=%s,skillPer=%s,skillValue=%s,relatedSkillID=%s"
+ % (opType, curID, calcValue, skillID, skillPer, skillValue, relatedSkillID))
curStealTotal = 0
for tagBatObj in useSkill.GetTagObjList():
tagID = tagBatObj.GetID()
# 减
- if calcType == 2:
+ if opType == "Reduce":
diffType = 0
tagXP = tagBatObj.GetXP()
diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
@@ -392,7 +402,7 @@
Sync_PropertyRefreshView(turnFight, tagBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
# 偷
- elif calcType == 3:
+ elif opType == "Steal":
diffType = 0
tagXP = tagBatObj.GetXP()
diffValue = min(tagXP, calcValue) # 取较小值,不足时剩多少减多少
@@ -419,14 +429,14 @@
diffValue = curStealTotal
updValue = curXP + diffValue
curBatObj.SetXP(updValue, False)
- GameWorld.DebugLog(" 偷总怒气: curID=%s,curStealTotal=%s,curXP=%s,updXP=%s" % (curID, curStealTotal, curXP, updValue))
+ GameWorld.DebugLog(" 加总怒气: curID=%s,curStealTotal=%s,curXP=%s,updXP=%s" % (curID, curStealTotal, curXP, updValue))
Sync_PropertyRefreshView(turnFight, curBatObj, attrID, updValue, diffValue, diffType, skillID, relatedSkillID)
DoAttackResult(turnFight, curBatObj, useSkill)
return
def DoAttackResult(turnFight, curBatObj, useSkill):
- '''执行攻击结果,技能、buff通用
+ '''执行攻击结果
@param curBatObj: 施法方或buff归属方
'''
@@ -437,7 +447,10 @@
skillID = useSkill.GetSkillID()
curBatObj.AddSkillUseCnt(skillID)
-
+ if useSkill.GetCoolDownTime():
+ useSkill.SetCalcTime(turnFight.getTimeline())
+ useSkill.SetRemainTime(useSkill.GetCoolDownTime())
+
# 需先通知伤血 - 前端按顺序优先表现技能释放内容,
isEnhanceSkill = useSkill.GetIsEnhanceSkill()
if not isEnhanceSkill or len(useSkill.GetHurtObjList()):
@@ -446,31 +459,43 @@
__doCostZhanchui(turnFight, curBatObj, useSkill)
__doSkillUserAnger(turnFight, curBatObj, useSkill)
+ DoBeAttackOver(turnFight, curBatObj, useSkill)
+
+ # 最后处理反击 或 连击
+
+ return
+
+def DoBeAttackOver(turnFight, curBatObj, useSkill):
+ '''被攻击结果
+ @param curBatObj: 施法方或buff归属方
+ '''
+
+ isTurnNormalSkill = SkillCommon.isTurnNormalSkill(useSkill)
+ isAngerSkill = SkillCommon.isAngerSkill(useSkill)
+
# 统计死亡
killObjIDList = [] # 击杀的目标ID列表
for tagObj in useSkill.GetTagObjList():
tagID = tagObj.GetID()
# 可能单个技能对同一目标造成多次伤害,所以这里遍历,如弹射等
for hurtObj in useSkill.GetHurtObjList():
- if hurtObj.GetObjID() == tagID and not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery):
+ if hurtObj.GetObjID() == tagID and not hurtObj.HaveHurtType(ChConfig.HurtTYpe_Recovery) and (isTurnNormalSkill or isAngerSkill):
__doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
if tagObj.GetHP() <= 0:
killObjIDList.append(tagID)
TurnAttack.SetObjKilled(turnFight, tagObj, curBatObj, useSkill)
- if curBatObj.GetHP() <= 0:
+ if curBatObj and curBatObj.GetHP() <= 0:
TurnAttack.SetObjKilled(turnFight, curBatObj)
# 结算副本相关的攻击结果,仅主动发起玩家阵容武将触发
curPlayer = turnFight.curPlayer
- if curPlayer and curBatObj.GetOwnerID() == curPlayer.GetPlayerID():
+ if curPlayer and curBatObj and curBatObj.GetOwnerID() == curPlayer.GetPlayerID():
FBLogic.OnPlayerLineupAttackResult(curPlayer, curBatObj, killObjIDList, useSkill, turnFight.mapID, turnFight.funcLineID)
# 额外触发技能
__doUseEnhanceSkill(turnFight, curBatObj, useSkill)
# 循环触发被动,待扩展
-
- # 最后处理反击 或 连击
return
@@ -490,12 +515,12 @@
costZhanchui = 0
batType = useSkill.GetBatType()
+ if batType != ChConfig.TurnBattleType_Normal:
+ # 暂定仅常规主动点击行为的需要扣除战锤(与前端手动战斗点击的触发点同步),被动触发的暂定不扣
+ return
+
if SkillCommon.isAngerSkill(useSkill):
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 2)
- elif batType == ChConfig.TurnBattleType_Combo:
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 3)
- elif batType == ChConfig.TurnBattleType_AtkBack:
- costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 4)
elif SkillCommon.isTurnNormalSkill(useSkill):
costZhanchui = IpyGameDataPY.GetFuncCfg("ZhanchuiCost", 1)
@@ -546,8 +571,10 @@
return
def __doUseEnhanceSkill(turnFight, curBatObj, useSkill):
+ if not curBatObj:
+ return
if useSkill.GetIsEnhanceSkill():
- GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
+ #GameWorld.DebugLog("自身为额外触发的技能不再触发额外技能! skillID=%s" % useSkill.GetSkillID())
return
enhanceSkillIDList = useSkill.GetEnhanceSkillList()
if not enhanceSkillIDList:
@@ -564,7 +591,7 @@
if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
GameWorld.DebugLog(" 额外触发技能,继承主技能目标! enhanceSkillID=%s" % enhanceSkillID)
# 额外触发的技能直接在外层检查概率,如果都没有触发则不需要再处理
- enhanceRate = enhanceSkillData.GetHappenRate()
+ enhanceRate = enhanceSkillData.GetHappenRate()
enchanceTagObjList = []
for tagObj in tagObjList:
tagID = tagObj.GetID()
@@ -605,21 +632,11 @@
atkObj = attacker
atkID = atkObj.GetID()
defID = defObj.GetID()
+ skillID = curSkill.GetSkillID()
hurtObj = curSkill.AddHurtObj(defID)
- #检查是否几率触发,附加技能、被动触发的外层已检查过概率,不重复检查
- if not (curSkill.GetIsEnhanceSkill() or SkillCommon.isPassiveTriggerSkill(curSkill)): # 额外触发的技能概率在触发时判断
- rate = curSkill.GetHappenRate()
- if rate and rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
- #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
- #放这里,兼容群攻时如果该技能是有概率的,则每个目标单独判断
- hurtObj.AddHurtType(ChConfig.HurtType_Fail)
- hurtObj.SetCurHP(defObj.GetHP())
- return hurtObj
-
- effect = SkillCommon.GetSkillEffectByEffectID(curSkill, ChConfig.Def_Skill_Effect_Attack)
- atkSkillValue = 0
- atkSkillPer = effect.GetEffectValue(0) if effect else 0
+ atkSkillPer = curSkill.GetSkillPer()
+ atkSkillValue = curSkill.GetSkillValue()
dHP = defObj.GetHP() # 防守方当前血量
dMaxHP = defObj.GetMaxHP() # 防守方最大血量
@@ -653,11 +670,11 @@
#吸血
CalcSuckBlood(atkObj, defObj, hurtObj, curSkill)
- TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, curSkill)
- return hurtObj
+ TurnAttack.AddTurnObjHurtValue(atkObj, defObj, hurtValue, lostHP, skillID)
+ return
-def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, **atkwargs):
- '''计算伤害
+def CalcHurtHP(atkObj, defObj, curSkill, atkSkillValue, atkSkillPer, **kwargs):
+ '''计算伤害,默认按攻击计算
'''
pmType = GetPMType(atkObj, curSkill)
ignoreDef = IsIgnoreDef(curSkill)
@@ -669,7 +686,7 @@
isTurnNormalSkill = SkillCommon.isTurnNormalSkill(curSkill)
isAngerSkill = SkillCommon.isAngerSkill(curSkill)
isAtkbackSkill = SkillCommon.isAtkbackSkill(curSkill)
-
+ isDot = ("damageoftime" in kwargs)
angerOverflow = 0 # 怒气溢出值
mustHit = False
@@ -690,7 +707,11 @@
hurtTypes = pow(2, ChConfig.HurtType_Normal)
+ #calcType = curSkill.GetCalcType() 目前暂时按攻击算伤害,之后可以扩展其他
+
isSuperHit = False # 是否暴击
+ if isDot:
+ isSuperHit = False
if isSuperHit:
hurtTypes |= pow(2, ChConfig.HurtType_SuperHit)
@@ -741,15 +762,13 @@
aFinalDamPer /= 10000.0
dFinalDamPerDef /= 10000.0
-
GameWorld.DebugLog("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,aAtk=%s,dDef=%s,dHP=%s,hurtTypes=%s"
% (atkID, defID, skillID, atkSkillPer, aAtk, dDef, dHP, hurtTypes))
- if "hurtFormulaKey" in atkwargs:
- aBurnValue = atkwargs.get('burnValue', 0)
- aBurnPer = atkwargs.get('burnPer', 0)
- hurtFormulaKey = atkwargs.get('hurtFormulaKey', None)
+ # 持续性伤害
+ if isDot:
hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
+ GameWorld.DebugLog(" 持续技能伤害=%s" % (hurtValue))
elif isTurnNormalSkill:
hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
GameWorld.DebugLog(" 普攻技能伤害=%s" % (hurtValue))
@@ -812,9 +831,9 @@
''' 计算治疗值
'''
cureBaseValue = 0 #治疗基础值
- effect = SkillCommon.GetSkillEffectByEffectID(curSkill, ChConfig.Def_Skill_Effect_Cure)
- skillPer = effect.GetEffectValue(0) if effect else 0
- cureType = effect.GetEffectValue(1) if effect else 0
+ cureType = curSkill.GetCalcType()
+ skillPer = curSkill.GetSkillPer()
+ #skillValue = curSkill.GetSkillValue()
#获得基础治疗值
if cureType == ChConfig.Def_Cure_Attack:
@@ -838,7 +857,7 @@
#curePer += GameObj.GetCurePer(userObj)
#if enemyObj:
# cureDefPer += GameObj.GetCureDefPer(enemyObj)
-
+
skillPer /= float(ChConfig.Def_MaxRateValue)
curePer /= float(ChConfig.Def_MaxRateValue)
cureDefPer /= float(ChConfig.Def_MaxRateValue)
@@ -854,6 +873,52 @@
GameWorld.DebugLog("计算治疗值(%s):skillID=%s,cureType=%s,baseValue=%s,skillPer=%s,curePer=%s,cureDefPer=%s,angerOverflow=%s"
% (cureHP, curSkill.GetSkillID(), cureType, baseValue, skillPer, curePer, cureDefPer, angerOverflow))
return cureHP
+
+def DoDOTAttack(turnFight, batObj, curBuff, hurtValue, hurtTypes):
+ ## 执行单次dot逻辑
+ skillID = curBuff.GetSkillID()
+ skillIpyData = IpyGameDataPY.GetIpyGameData("Skill", skillID)
+ if not skillIpyData:
+ return
+ buffID = curBuff.GetBuffID()
+ ownerID = curBuff.GetOwnerID()
+ buffOwner = BattleObj.GetBatObjMgr().getBatObj(ownerID) # 攻击方
+
+ atkObj = buffOwner
+ defObj = batObj
+
+ tagObjList = [defObj]
+ dHP = defObj.GetHP()
+ defID = defObj.GetID()
+ GameWorld.DebugLog("结算dot: defID=%s,buffID=%s,skillID=%s,ownerID=%s,hurtValue=%s,hurtTypes=%s,dHP=%s/%s"
+ % (defID, buffID, skillID, ownerID, hurtValue, hurtTypes, dHP, defObj.GetMaxHP()))
+
+ poolMgr = ObjPool.GetPoolMgr()
+ useSkill = poolMgr.acquire(BattleObj.PySkill, skillIpyData)
+ useSkill.SetTagObjList(tagObjList)
+ useSkill.ClearHurtObj()
+
+ remainHP = max(0, dHP - hurtValue) # 剩余血量
+ lostHP = dHP - remainHP # 实际掉血量
+ defObj.SetHP(remainHP)
+
+ hurtObj = useSkill.AddHurtObj(defID)
+ hurtObj.SetHurtTypes(hurtTypes)
+ hurtObj.SetHurtHP(hurtValue)
+ hurtObj.SetLostHP(lostHP)
+ hurtObj.SetCurHP(remainHP)
+
+ # dot的反弹、吸血待定
+
+ TurnAttack.AddTurnObjHurtValue(atkObj, batObj, hurtValue, lostHP, skillID)
+
+ Sync_PropertyRefreshView(turnFight, defObj, ChConfig.AttrID_HP, remainHP, hurtValue, diffType=0, skillID=skillID, hurtTypes=hurtTypes)
+
+ DoBeAttackOver(turnFight, atkObj, useSkill)
+
+ useSkill.ResetUseRec()
+ poolMgr.release(useSkill)
+ return
def Sync_UseSkill(turnFight, curBatObj, useSkill):
## 通知释放技能
@@ -881,13 +946,14 @@
turnFight.addBatPack(clientPack)
return
-def Sync_PropertyRefreshView(turnFight, curBatObj, attrID, value, diffValue, diffType=0, skillID=0, relatedSkillID=0):
+def Sync_PropertyRefreshView(turnFight, curBatObj, attrID, value, diffValue, diffType=0, skillID=0, relatedSkillID=0, hurtTypes=0):
'''通知对象属性刷新展示B418
@param attrID: 通知变化的属性ID
@param diffValue: 变化值
@param diffType: 变化类型,0-减少;1-增加
@param skillID: 使用的技能表ID,即哪个技能的效果
@param relatedSkillID: 关联的技能ID,一般是主技能ID,非主技能额外触发的为0
+ @param hurtTypes: 飘字类型汇总,支持多种类型并存,如无视防御且暴击同时被格挡,二进制或运算最终值;0-失败;1-普通;2-回血;5-格挡;6-无视防御;7-暴击;9-闪避
'''
if attrID not in ChConfig.CDBRefresh_AttrIDDict:
return
@@ -896,6 +962,7 @@
clientPack = poolMgr.acquire(ChPyNetSendPack.tagSCObjPropertyRefreshView)
clientPack.ObjID = curBatObj.GetID()
clientPack.RefreshType = refreshType
+ clientPack.AttackTypes = hurtTypes
if isBig:
clientPack.Value = value % ShareDefine.Def_PerPointValue
clientPack.ValueEx = value / ShareDefine.Def_PerPointValue
--
Gitblit v1.8.0