| | |
| | | GameWorld.DebugLogEx("技能使用处于buff状态限制中! skillID=%s,buffStateGroups=%s,limitState=%s", skillID, buffStateGroups, limitState)
|
| | | return
|
| | |
|
| | | if CheckSkillUseCntLimit(curBatObj, useSkill):
|
| | | if CheckSkillUseCntLimit(turnFight, curBatObj, useSkill):
|
| | | return
|
| | |
|
| | | #没有指定目标,则按技能自身的目标逻辑
|
| | |
| | | if SkillCommon.IsBuff(useSkill):
|
| | | __doAddBuff(turnFight, curBatObj, useSkill, **kwargs)
|
| | | else:
|
| | | __doUseSkill(turnFight, curBatObj, useSkill)
|
| | | __doUseSkill(turnFight, curBatObj, useSkill, **kwargs)
|
| | |
|
| | | DoAttackResult(turnFight, curBatObj, useSkill, **kwargs)
|
| | |
|
| | |
| | | useSkill.ResetUseRec()
|
| | | return True
|
| | |
|
| | | def CheckSkillUseCntLimit(batObj, useSkill):
|
| | | def CheckSkillUseCntLimit(turnFight, batObj, useSkill):
|
| | | ## 检查技能使用次数是否受限
|
| | | # @return: 是否受限,None-没有受限效果,False-不受限,True-受限了
|
| | | if not hasattr(useSkill, "GetEffectByID"):
|
| | |
| | |
|
| | | skillID = useSkill.GetSkillID()
|
| | | if useCntLimit:
|
| | | useCntLimit += TurnPassive.GetTriggerEffectValue(turnFight, batObj, None, ChConfig.PassiveEff_AddSkillUseCntLimit, useSkill, LimitByTurnAll=1)
|
| | | useCnt = batObj.GetSkillUseCnt(skillID)
|
| | | if useCnt >= useCntLimit:
|
| | | GameWorld.DebugLogEx("技能每场战斗使用次数受限! skillID=%s,useCnt=%s >= %s", skillID, useCnt, useCntLimit)
|
| | | return True
|
| | |
|
| | | if turnUseCntLimit:
|
| | | turnUseCntLimit += TurnPassive.GetTriggerEffectValue(turnFight, batObj, None, ChConfig.PassiveEff_AddSkillUseCntLimit, useSkill, LimitByTurnPer=1)
|
| | | turnUseCnt = batObj.GetSkillTurnUseCnt(skillID)
|
| | | if turnUseCnt >= turnUseCntLimit:
|
| | | GameWorld.DebugLogEx("技能每大回合使用次数受限! skillID=%s,turnUseCnt=%s >= %s", skillID, turnUseCnt, turnUseCntLimit)
|
| | |
| | | aimObjList.sort(key=lambda o:(o.GetHP()), reverse=False)
|
| | | #GameWorld.DebugLogEx("血量最低排序: %s", [[o.GetID(), o.GetHP(), o.GetMaxHP()] for o in aimObjList])
|
| | |
|
| | | # 血量百分比最低
|
| | | elif tagAffect == ChConfig.SkillTagAffect_HPPerLowest:
|
| | | aimObjList.sort(key=lambda o:(o.GetHP() / float(o.GetMaxHP())), reverse=False)
|
| | | #GameWorld.DebugLogEx("血量百分比最低排序: %s", [[o.GetID(), o.GetHP(), o.GetMaxHP(), o.GetHP() / float(o.GetMaxHP())] for o in aimObjList])
|
| | | |
| | | # 血量最高
|
| | | elif tagAffect == ChConfig.SkillTagAffect_HPHighest:
|
| | | aimObjList.sort(key=lambda o:(o.GetHP()), reverse=True)
|
| | |
| | |
|
| | | return aimObjList
|
| | |
|
| | | def __getSameRowObjList(tagObj):
|
| | | ## 获取目标对应的同排对象列表,只算活着的
|
| | | |
| | | posNum = tagObj.GetPosNum()
|
| | | inRowNum = ChConfig.GetInRowNum(posNum)
|
| | | inColNum = ChConfig.GetInColNum(posNum)
|
| | | # 优先目标所在纵,为主目标
|
| | | colNumList = range(1, 1 + ChConfig.TurnFightCols)
|
| | | if inColNum in colNumList:
|
| | | colNumList.remove(inColNum)
|
| | | colNumList.insert(0, inColNum)
|
| | | |
| | | row = inRowNum # 目标玩家所在横排
|
| | | |
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | batLineup = tagObj.GetBatLineup()
|
| | | aimObjList = []
|
| | | for col in colNumList:
|
| | | pNum = (row - 1) * ChConfig.TurnFightCols + col
|
| | | if pNum not in batLineup.posObjIDDict:
|
| | | continue
|
| | | tagObjID = batLineup.posObjIDDict[pNum]
|
| | | tagBatObj = batObjMgr.getBatObj(tagObjID)
|
| | | if not tagBatObj.IsAlive():
|
| | | continue
|
| | | aimObjList.append(tagBatObj)
|
| | | |
| | | return aimObjList
|
| | |
|
| | | def __getSameColObjList(tagObj):
|
| | | ## 获取目标对应的同列对象列表,只算活着的
|
| | | |
| | | posNum = tagObj.GetPosNum()
|
| | | inRowNum = ChConfig.GetInRowNum(posNum)
|
| | | inColNum = ChConfig.GetInColNum(posNum)
|
| | | |
| | | rowNumList = range(1, 1 + ChConfig.TurnFightRows)
|
| | | if inRowNum in rowNumList:
|
| | | rowNumList.remove(inRowNum)
|
| | | rowNumList.insert(0, inRowNum)
|
| | | |
| | | col = inColNum # 目标玩家所在纵排
|
| | | |
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | batLineup = tagObj.GetBatLineup()
|
| | | aimObjList = []
|
| | | for row in range(1, 1 + ChConfig.TurnFightRows):
|
| | | pNum = (row - 1) * ChConfig.TurnFightCols + col
|
| | | if pNum not in batLineup.posObjIDDict:
|
| | | continue
|
| | | tagObjID = batLineup.posObjIDDict[pNum]
|
| | | tagBatObj = batObjMgr.getBatObj(tagObjID)
|
| | | if not tagBatObj.IsAlive():
|
| | | continue
|
| | | aimObjList.append(tagBatObj)
|
| | | |
| | | return aimObjList
|
| | |
|
| | | def GetRelativeObj(turnFight, curBatObj):
|
| | | '''获取对位目标,仅用于非技能目标的对位逻辑,如连击、弱疗等相对属性的判断,技能目标统一使用 GetSkillTags
|
| | | '''
|
| | |
| | |
|
| | | return
|
| | |
|
| | | def __doUseSkill(turnFight, curBatObj, useSkill):
|
| | | def __doUseSkill(turnFight, curBatObj, useSkill, **kwargs):
|
| | |
|
| | | atkType = useSkill.GetAtkType()
|
| | | GameWorld.DebugLogEx("__doUseSkill: curID=%s,skillID=%s,atkType=%s", curBatObj.GetID(), useSkill.GetSkillID(), atkType)
|
| | |
| | |
|
| | | # 通用攻击
|
| | | if atkType == 1:
|
| | | SkillModule_1(turnFight, curBatObj, useSkill)
|
| | | SkillModule_1(turnFight, curBatObj, useSkill, **kwargs)
|
| | | # 治疗
|
| | | if atkType == 2:
|
| | | SkillModule_2(turnFight, curBatObj, useSkill)
|
| | |
| | | Sync_PropertyRefreshView(turnFight, curBatObj, ChConfig.AttrID_HP, updHP, diffValue, diffType, skillID, relatedSkillID, hurtTypes)
|
| | | return
|
| | |
|
| | | def SkillModule_1(turnFight, curBatObj, useSkill):
|
| | | def SkillModule_1(turnFight, curBatObj, useSkill, **kwargs):
|
| | | ## 通用攻击,单攻、群攻
|
| | |
|
| | | addPer = 0
|
| | |
| | | addPer = addPerMax
|
| | | GameWorld.DebugLogEx("司马懿特殊潜能技能额外增加比例: frozenCnt=%s,addPer=%s" % (frozenCnt, addPer))
|
| | |
|
| | | addBatDamPer = TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_AddBatDamPerByLayer, useSkill)
|
| | | addBatDamPer = 0
|
| | | if "addBatDamPer" in kwargs:
|
| | | addBatDamPer += kwargs.pop("addBatDamPer", 0)
|
| | | addBatDamPer += TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_AddBatDamPerByLayer, useSkill)
|
| | |
|
| | | # 计算伤害
|
| | | calcHurtResults = []
|
| | |
| | | GameWorld.DebugLogEx("有击杀目标时该技能无效! enhanceSkillID=%s", enhanceSkillID)
|
| | | return
|
| | |
|
| | | if checkHeroSex:
|
| | | if TurnPassive.GetTriggerEffectValue(turnFight, curBatObj, None, ChConfig.PassiveEff_IgnoreSex, connSkillTypeID=enhanceSkillData.GetSkillTypeID(), connSkillID=enhanceSkillID):
|
| | | checkHeroSex = 0
|
| | | |
| | | # 继承主技能目标
|
| | | if enhanceSkillData.GetTagAim() == ChConfig.SkillTagAim_MainSkill:
|
| | | GameWorld.DebugLogEx("继承主技能目标! enhanceSkillID=%s", enhanceSkillID)
|
| | |
| | | GameWorld.DebugLogEx("被动触发技能,针对来源友军! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s,byFriendID=%s",
|
| | | effSkillID, effectID, passiveSkillID, bySkillID, byFriendObj.GetID())
|
| | | isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
|
| | | # 继承主技能目标同横排 11
|
| | | elif tagAim == ChConfig.SkillTagAim_MainSkillRow:
|
| | | if not tagObj:
|
| | | return
|
| | | GameWorld.DebugLogEx("被动触发技能,针对目标同排对象! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
|
| | | passiveTagObjList = __getSameRowObjList(tagObj)
|
| | | isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
|
| | | # 继承主技能目标同纵排 12
|
| | | elif tagAim == ChConfig.SkillTagAim_MainSkillCol:
|
| | | if not tagObj:
|
| | | return
|
| | | GameWorld.DebugLogEx("被动触发技能,针对目标同纵对象! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
|
| | | passiveTagObjList = __getSameColObjList(tagObj)
|
| | | isOK = OnUseSkill(turnFight, batObj, passiveSkill, passiveTagObjList, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
|
| | | else:
|
| | | GameWorld.DebugLogEx("被动触发技能,重新锁定目标! effSkillID=%s,effectID=%s,passiveSkillID=%s,bySkillID=%s", effSkillID, effectID, passiveSkillID, bySkillID)
|
| | | isOK = OnUseSkill(turnFight, batObj, passiveSkill, batType=batType, bySkill=connSkill, byBuff=connBuff, **kwargs)
|
| | |
| | | aSuperDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_SuperDamPer, curSkill)
|
| | |
|
| | | dSuperDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_SuperDamPerDef)
|
| | | GameWorld.DebugLogEx("aSuperDamPer=%s,dSuperDamPerDef=%s", aSuperDamPer, dSuperDamPerDef)
|
| | |
|
| | | if isParry:
|
| | | hurtTypes |= pow(2, ChConfig.HurtAtkType_Parry)
|
| | |
| | | aFinalDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_AddFinalDamPer, curSkill)
|
| | | aFinalDamPer += TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.AttrID_FinalDamPer, curSkill)
|
| | |
|
| | | #招架 - 无视攻击方最终增伤百分比
|
| | | dZhaojia = defObj.GetBatAttrValue(ChConfig.AttrID_Zhaojia)
|
| | | aZhaojiaDef = atkObj.GetBatAttrValue(ChConfig.AttrID_ZhaojiaDef)
|
| | | if dZhaojia > aZhaojiaDef:
|
| | | perMoreValue, perReduce = IpyGameDataPY.GetFuncEvalCfg("ZhaojiaCfg", 1) # 每高与对方抗贯穿x值无视y%最终减伤
|
| | | reducePer = (dZhaojia - aZhaojiaDef) / float(perMoreValue) * perReduce
|
| | | reduceMin, reduceMax = IpyGameDataPY.GetFuncEvalCfg("ZhaojiaCfg", 2) # 最小无视百分比|最大无视百分比
|
| | | if reducePer >= reduceMin and GameWorld.CanHappen(IpyGameDataPY.GetFuncCfg("ZhaojiaCfg", 3)):
|
| | | reducePer = min(reducePer, reduceMax)
|
| | | hurtTypes |= pow(2, ChConfig.HurtAtkType_Zhaojia)
|
| | | aFinalDamPer = int(aFinalDamPer * (100 - reducePer) / 100.0) # 按百分比减少
|
| | | GameWorld.DebugLogEx("dZhaojia=%s,aZhaojiaDef=%s,reducePer=%s,aFinalDamPer=%s", dZhaojia, aZhaojiaDef, reducePer, aFinalDamPer)
|
| | | |
| | | #贯穿 - 无视防守方最终减伤百分比
|
| | | aGuanchuan = atkObj.GetBatAttrValue(ChConfig.AttrID_Guanchuan)
|
| | | dGuanchuanDef = defObj.GetBatAttrValue(ChConfig.AttrID_GuanchuanDef)
|
| | | if aGuanchuan > dGuanchuanDef:
|
| | | perMoreValue, perReduce = IpyGameDataPY.GetFuncEvalCfg("GuanchuanCfg", 1) # 每高与对方抗贯穿x值无视y%最终减伤
|
| | | reducePer = (aGuanchuan - dGuanchuanDef) / float(perMoreValue) * perReduce
|
| | | reduceMin, reduceMax = IpyGameDataPY.GetFuncEvalCfg("GuanchuanCfg", 2) # 最小无视百分比|最大无视百分比
|
| | | if reducePer >= reduceMin and GameWorld.CanHappen(IpyGameDataPY.GetFuncCfg("GuanchuanCfg", 3)):
|
| | | reducePer = min(reducePer, reduceMax)
|
| | | hurtTypes |= pow(2, ChConfig.HurtAtkType_Guanchuan)
|
| | | dFinalDamPerDef = int(dFinalDamPerDef * (100 - reducePer) / 100.0) # 按百分比减少
|
| | | GameWorld.DebugLogEx("aGuanchuan=%s,dGuanchuanDef=%s,reducePer=%s,dFinalDamPerDef=%s", aGuanchuan, dGuanchuanDef, reducePer, dFinalDamPerDef) |
| | | |
| | | aNormalSkillPer, dNormalSkillPerDef = 0, 0
|
| | | if isTurnNormalSkill:
|
| | | aNormalSkillPer = atkObj.GetBatAttrValue(ChConfig.AttrID_NormalSkillPer) # 普技增伤
|
| | |
| | | if turnFight.isPVP() > 0:
|
| | | aPVPDamPer = atkObj.GetBatAttrValue(ChConfig.AttrID_PVPDamPer)
|
| | | dPVPDamPerDef = defObj.GetBatAttrValue(ChConfig.AttrID_PVPDamPerDef)
|
| | | GameWorld.DebugLogEx("PVP aPVPDamPer=%s,dPVPDamPerDef=%s", aPVPDamPer, dPVPDamPerDef)
|
| | |
|
| | | # 所有万分率参数统一除10000.0
|
| | | atkSkillPer /= 10000.0
|
| | |
| | |
|
| | | if calcType != ChConfig.Def_Calc_Attack:
|
| | | aAtk = GetCalcBaseValue(calcType, atkObj, defObj, curSkill)
|
| | | GameWorld.DebugLogEx("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aBatDamPer=%s,aFinalDamPer=%s", |
| | | atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aBatDamPer, aFinalDamPer)
|
| | | #GameWorld.DebugLogEx("aCountry=%s,dCountry=%s,aCountryDamPer=%s,dCountryDamPerDef=%s", aCountry, dCountry, aCountryDamPer, dCountryDamPerDef)
|
| | | |
| | | GameWorld.DebugLogEx("伤血计算: atkID=%s,defID=%s,skillID=%s,atkSkillPer=%s,calcType=%s,aAtk=%s,dDef=%s,dHP=%s/%s,hurtTypes=%s,aBatDamPer=%s,dBatDamPerDef=%s,aFinalDamPer=%s,dFinalDamPerDef=%s", |
| | | atkID, defID, skillID, atkSkillPer, calcType, aAtk, dDef, dHP, dMaxHP, hurtTypes, aBatDamPer, dBatDamPerDef, aFinalDamPer, dFinalDamPerDef)
|
| | | if isSuperHit:
|
| | | GameWorld.DebugLogEx(" 暴击 aSuperDamPer=%s,dSuperDamPerDef=%s", aSuperDamPer, dSuperDamPerDef)
|
| | | if aPMDamPer or dPMDamPerDef:
|
| | | GameWorld.DebugLogEx(" 物法 aPMDamPer=%s,dPMDamPerDef=%s,pmType=%s", aPMDamPer, dPMDamPerDef, pmType)
|
| | | if aComboDamPer or dComboDamPerDef:
|
| | | GameWorld.DebugLogEx(" 连击 aComboDamPer=%s,dComboDamPerDef=%s", aComboDamPer, dComboDamPerDef)
|
| | | if aPursueDamPer or dPursueDamPerDef:
|
| | | GameWorld.DebugLogEx(" 追击 aPursueDamPer=%s,dPursueDamPerDef=%s", aPursueDamPer, dPursueDamPerDef)
|
| | | if aPVPDamPer or dPVPDamPerDef:
|
| | | GameWorld.DebugLogEx(" PVP aPVPDamPer=%s,dPVPDamPerDef=%s", aPVPDamPer, dPVPDamPerDef)
|
| | | if aCountryDamPer or dCountryDamPerDef:
|
| | | GameWorld.DebugLogEx(" 国家 aCountry=%s,dCountry=%s,aCountryDamPer=%s,dCountryDamPerDef=%s", aCountry, dCountry, aCountryDamPer, dCountryDamPerDef)
|
| | | |
| | | if isTurnNormalSkill:
|
| | | hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("HurtFormula", 1))
|
| | | GameWorld.DebugLogEx(" 普攻技能伤害=%s,aNormalSkillPer=%s,dNormalSkillPerDef=%s", hurtValue, aNormalSkillPer, dNormalSkillPerDef)
|
| | |
| | | GameWorld.DebugLogEx(" 怒气技能伤害=%s,aAngerSkillPer=%s,dAngerSkillPerDef=%s", hurtValue, aAngerSkillPer, dAngerSkillPerDef)
|
| | | elif isDot:
|
| | | hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("DOTFormula", 1))
|
| | | GameWorld.DebugLogEx(" 持续技能伤害=%s" % (hurtValue))
|
| | | GameWorld.DebugLogEx(" 持续技能伤害=%s,aDOTPer=%s,dDOTPerDef=%s", hurtValue, aDOTPer, dDOTPerDef)
|
| | | elif calcType == ChConfig.Def_Calc_ByBuffValue:
|
| | | hurtValue = eval(IpyGameDataPY.GetFuncCompileCfg("CalcTypeFormula", 2))
|
| | | GameWorld.DebugLogEx(" 按最后一次buff值计算伤害=%s,calcType=%s,LastHurt=%s", hurtValue, calcType, aAtk)
|
| | |
| | | GameWorld.DebugLogEx(" 伤害最高限制: hurtValue=%s,hurtAtkPerMax=%s,aAtk=%s", hurtValue, hurtAtkPerMax, aAtk)
|
| | |
|
| | | # 均摊
|
| | | hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
|
| | | if hurtShareEff:
|
| | | if HaveShareEff(atkObj, curSkill):
|
| | | tagCnt = max(1, len(curSkill.GetTagObjList()))
|
| | | hurtValue = hurtValue / tagCnt
|
| | | GameWorld.DebugLogEx(" 目标均摊伤害: hurtValue=%s,tagCnt=%s", hurtValue, tagCnt)
|
| | |
|
| | | hurtValue = max(1, int(hurtValue)) # 负值、保底防范,放最后
|
| | | return hurtValue, hurtTypes
|
| | |
|
| | | def HaveShareEff(atkObj, curSkill):
|
| | | ## 玩家技能是否有分摊效果: 均摊伤害/治疗/承伤盾值
|
| | | hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
|
| | | if not hurtShareEff:
|
| | | return False
|
| | | needLearnSkillID = hurtShareEff.GetEffectValue(0)
|
| | | if needLearnSkillID:
|
| | | if not atkObj.GetSkillManager().FindSkillByID(needLearnSkillID):
|
| | | GameWorld.DebugLogEx("所需技能未学习,分摊效果不生效! skillID=%s,needLearnSkillID=%s", curSkill.GetSkillID(), needLearnSkillID)
|
| | | return False
|
| | | return True
|
| | |
|
| | | def GetAddSkillPer(turnFight, atkObj, defObj, curSkill):
|
| | | ## 获取额外增加的技能万分比
|
| | |
| | |
|
| | | def CanSuperHit(turnFight, atkObj, defObj, curSkill):
|
| | | if TurnPassive.GetTriggerEffectValue(turnFight, atkObj, defObj, ChConfig.PassiveEff_MustSuperHit, curSkill):
|
| | | GameWorld.DebugLogEx("目标血量低于百分x时必定暴击: defID=%s,hp:%s/%s", defObj.GetID(), defObj.GetHP(), defObj.GetMaxHP())
|
| | | return True
|
| | |
|
| | | aSuperHitRate = atkObj.GetBatAttrValue(ChConfig.AttrID_SuperHitRate)
|
| | |
| | | buffMgr = defObj.GetBuffManager()
|
| | | for buff in buffMgr.FindBuffListByState(ChConfig.BatObjState_DamBackShield):
|
| | | damBackPer += buff.GetValue1()
|
| | | connSkillTypeID = buff.GetSkillTypeID()
|
| | | damBackPer += TurnPassive.GetTriggerEffectValue(turnFight, defObj, atkObj, ChConfig.PassiveEff_AddDamBackPerByBuffLayer, connSkillTypeID=connSkillTypeID)
|
| | |
|
| | | if damBackPer <= 0:
|
| | | return
|
| | |
| | | cureHP = int(cureHP * multiValue)
|
| | | GameWorld.DebugLogEx(" 治疗倍值: cureHP=%s,multiValue=%s", cureHP, multiValue)
|
| | |
|
| | | hurtShareEff = curSkill.GetEffectByID(ChConfig.SkillEff_HurtShare)
|
| | | if hurtShareEff:
|
| | | if HaveShareEff(userObj, curSkill):
|
| | | tagCnt = max(1, len(curSkill.GetTagObjList()))
|
| | | cureHP = cureHP / tagCnt
|
| | | GameWorld.DebugLogEx(" 目标均摊治疗: cureHP=%s,tagCnt=%s", cureHP, tagCnt)
|