129 【战斗】战斗系统-服务端(优化技能表字段,增加技能及buff常用配置字段;优化被动触发及效果配置方式;技能冷却、buff持续时长计算支持;持续性buff效果结算支持;pve默认玩家先手;战锤消耗仅普攻怒技消耗;)
| | |
| | | {
|
| | | DWORD _SkillID; //技能ID
|
| | | DWORD SkillTypeID; //技能TypeID
|
| | | WORD SkillLV; //当前等级
|
| | | WORD SkillMaxLV; //最高等级
|
| | | char SkillName; //技能名
|
| | | BYTE FuncType; //功能分类
|
| | |
| | | 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; //技能战斗力
|
| | | };
|
| | |
| | | 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)
|
| | |
| | | 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():
|
| | | ## 伤血统计
|
| | |
|
| | |
| | | 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
|
| | |
| | | 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()
|
| | |
| | | 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()
|
| | |
|
| | |
| | | self._buffID = 0
|
| | | self._ownerID = 0
|
| | | self._layer = 0
|
| | | self._calcTime = 0
|
| | | self._remainTime = 0
|
| | | self._valueList = []
|
| | | return
|
| | |
| | | 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, ...], ...}
|
| | |
| | | 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)
|
| | |
| | | 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):
|
| | |
| | | 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)
|
| | |
| | | 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()
|
| | |
| | | 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
|
| | |
| | | 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 # 输出统计
|
| | |
| | |
|
| | | def GetSkillManager(self): return self._skillMgr
|
| | | def GetBuffManager(self):return self._buffMgr
|
| | | def GetPassiveEffManager(self):return self._passiveEffMgr
|
| | |
|
| | | def GetCanAttack(self):
|
| | | ## 可否被攻击
|
| | |
| | | import SkillCommon
|
| | | import AttackCommon
|
| | | import BattleObj
|
| | | import TurnPassive
|
| | | import TurnSkill
|
| | | import TurnBuff
|
| | | import ObjPool
|
| | |
| | | import time
|
| | | import json
|
| | |
|
| | | TimelineSet = 10000 # 单回合最大时间轴
|
| | | PosNumMax = 10 # 最大站位编号
|
| | | ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
|
| | |
|
| | |
| | | self.shapeType = 0 # 阵型
|
| | | self.fightPower = 0 # 阵容总战力
|
| | | self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
|
| | | self.lingshouObjIDDict = {} # 灵兽战斗单位 {位置编号:batObjID, ...}
|
| | | self.beautyObjIDDict = {} # 红颜战斗单位 {位置编号:batObjID, ...}
|
| | | self.actionNum = ActionNumStart # 行动位置,从1开始
|
| | | return
|
| | |
|
| | |
| | |
|
| | | 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
|
| | |
|
| | |
| | | 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 # 单场战斗总耗时,支持毫秒小数
|
| | |
| | | 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):
|
| | |
| | | def startFight(self):
|
| | | ## 准备就绪,开始战斗
|
| | | self.state = FightState_Start
|
| | | self.setTimeline(1)
|
| | | self.syncInit()
|
| | | return
|
| | |
|
| | |
| | | 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
|
| | |
| | | ## 关卡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
|
| | |
| | | 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
|
| | |
| | | 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))
|
| | |
|
| | | # 主公
|
| | |
| | | # 武将
|
| | | 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
|
| | |
|
| | |
| | | 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)
|
| | |
|
| | |
| | | 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)
|
| | |
| | | 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
|
| | |
| | | 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
|
| | |
|
| | |
| | | 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
|
| | |
|
| | |
| | | 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)
|
| | | # # 重置连击、反击数
|
| | |
| | | # __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: 获得治疗的对象
|
| | |
| | |
|
| | | 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"
|
| | |
| | | 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()
|
| | |
| | | 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):
|
| | |
| | | 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()
|
| | |
| | | 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()
|
| | |
| | | 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持续时间)
|
| | |
| | | #伤害类型
|
| | | (
|
| | | HurtType_Fail, # 失败 - 如概率没有触发 0
|
| | | HurtType_Normal, # 普通伤害 1
|
| | | HurtType_Normal, # 伤害 1
|
| | | HurtTYpe_Recovery, # 回血 2
|
| | | HurtType_3,
|
| | | HurtType_4,
|
| | |
| | | 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 = (
|
| | |
| | | #玩家状态定义,不能超过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 = (
|
| | |
| | |
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | # 被动触发方式
|
| | | (
|
| | | 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的某个状态触发技能
|
| | |
| | | ("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-增加
|
| | |
| | | self.SubCmd = 0x18
|
| | | self.ObjID = 0
|
| | | self.RefreshType = 0
|
| | | self.AttackTypes = 0
|
| | | self.Value = 0
|
| | | self.ValueEx = 0
|
| | | self.DiffType = 0
|
| | |
| | | SubCmd:%s,
|
| | | ObjID:%d,
|
| | | RefreshType:%d,
|
| | | AttackTypes:%d,
|
| | | Value:%d,
|
| | | ValueEx:%d,
|
| | | DiffType:%d,
|
| | |
| | | self.SubCmd,
|
| | | self.ObjID,
|
| | | self.RefreshType,
|
| | | self.AttackTypes,
|
| | | self.Value,
|
| | | self.ValueEx,
|
| | | self.DiffType,
|
| | |
| | | "Skill":(
|
| | | ("DWORD", "SkillID", 1),
|
| | | ("DWORD", "SkillTypeID", 0),
|
| | | ("WORD", "SkillLV", 0),
|
| | | ("WORD", "SkillMaxLV", 0),
|
| | | ("char", "SkillName", 0),
|
| | | ("BYTE", "FuncType", 0),
|
| | |
| | | ("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),
|
| | | ),
|
| | |
| | | |
| | | 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(): |
| | |
| | | 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:
|
| | |
| | | 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:
|
New file |
| | |
| | | #!/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
|
| | |
| | | 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)
|
| | |
|
| | |
| | |
|
| | | def DoBuffDel(turnFight, batObj, curBuff):
|
| | | ## 删除buff
|
| | | |
| | | isRefreshAttr = False # 是否刷属性
|
| | | haveBuffPassiveEff = False
|
| | |
|
| | | buffMgr = batObj.GetBuffManager()
|
| | | buffID = curBuff.GetBuffID()
|
| | |
| | | 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重新刷
|
| | | '''
|
| | |
| | | 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
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | |
|
| | | import GameWorld
|
| | | import PassiveTrigger
|
| | | import ChConfig
|
| | |
|
| | | GameWorld.ImportAll("Script\\Skill\\", "PassiveTrigger")
|
| | |
|
| | |
|
| | | def RefreshPassive(batObj):
|
| | | return |
| | | ''' 刷新被动效果,一般可能存在于技能或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
|
| | |
| | | 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()
|
| | |
| | | turnFight.addBatPack(clientPack)
|
| | |
|
| | | # 最后重置、回收对象
|
| | | useSkill.SetTagObjList([])
|
| | | useSkill.SetBySkill(None) # 需重置,防止被误回收
|
| | | useSkill.SetIsEnhanceSkill(False)
|
| | | useSkill.ClearHurtObj()
|
| | | useSkill.ResetUseRec()
|
| | | if usePoolSkill:
|
| | | poolMgr.release(useSkill)
|
| | | return True
|
| | |
| | | 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
|
| | |
| | | DoAttackResult(turnFight, curBatObj, useSkill)
|
| | | return
|
| | |
|
| | | def SkillModule_6(turnFight, curBatObj, useSkill):
|
| | | def SkillModule_6(turnFight, curBatObj, useSkill, opType):
|
| | | ## 怒气增减偷
|
| | |
|
| | | curID = curBatObj.GetID()
|
| | |
| | | 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) # 取较小值,不足时剩多少减多少
|
| | |
| | | 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) # 取较小值,不足时剩多少减多少
|
| | |
| | | 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归属方
|
| | | '''
|
| | |
|
| | |
| | |
|
| | | 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()):
|
| | |
| | | __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
|
| | |
|
| | |
| | |
|
| | | 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)
|
| | |
|
| | |
| | | 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:
|
| | |
| | | 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()
|
| | |
| | | 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() # 防守方最大血量
|
| | |
| | | #吸血
|
| | | 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)
|
| | |
| | | isTurnNormalSkill = SkillCommon.isTurnNormalSkill(curSkill)
|
| | | isAngerSkill = SkillCommon.isAngerSkill(curSkill)
|
| | | isAtkbackSkill = SkillCommon.isAtkbackSkill(curSkill)
|
| | | |
| | | isDot = ("damageoftime" in kwargs)
|
| | | angerOverflow = 0 # 怒气溢出值
|
| | |
|
| | | mustHit = False
|
| | |
| | |
|
| | | hurtTypes = pow(2, ChConfig.HurtType_Normal)
|
| | |
|
| | | #calcType = curSkill.GetCalcType() 目前暂时按攻击算伤害,之后可以扩展其他
|
| | | |
| | | isSuperHit = False # 是否暴击
|
| | | if isDot:
|
| | | isSuperHit = False
|
| | | if isSuperHit:
|
| | | hurtTypes |= pow(2, ChConfig.HurtType_SuperHit)
|
| | |
|
| | |
| | | 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))
|
| | |
| | | ''' 计算治疗值
|
| | | '''
|
| | | 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:
|
| | |
| | | #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)
|
| | |
| | | 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):
|
| | | ## 通知释放技能
|
| | |
| | | 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
|
| | |
| | | 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
|