129 【战斗】战斗系统-服务端(小乔所有技能;增加触发方式53-友方造成持续伤害时;优化效果5022 5507 5509;)
| | |
| | | return
|
| | |
|
| | | def GetBuffCount(self): return len(self._buffList)
|
| | | def GetBuffByIndex(self, index): return self._buffList[index]
|
| | | def GetBuffByIndex(self, index): return self._buffList[index] if len(self._buffList) > index else None
|
| | |
|
| | | def AddBuff(self, skillID):
|
| | | buff = None
|
| | |
| | | self._hp = 0 # 当前生命值
|
| | | self._xp = 0 # 当前怒气值
|
| | | self._isAlive = True # 是否活着
|
| | | self._killer = None # 被谁击杀的
|
| | | self._initAttrDict = {} # 初始化时的属性,固定不变,初始化时已经算好的属性 {attrID:value, ...}
|
| | | self._batAttrDict = {} # 实际战斗属性,包含buff层级的实际属性 {attrID:+-value, ...} value可能是负值
|
| | | self._skillTempAttrDict = {} # 某次技能释放中临时的属性增减 {attrID:+-value, ...} value可能是负值
|
| | |
| | |
|
| | | # 战斗属性
|
| | | def IsAlive(self): return self._isAlive # 是否活着
|
| | | def SetDead(self):
|
| | | def SetDead(self, killer=None):
|
| | | self._killer = killer
|
| | | self._isAlive = False
|
| | | self._hp = 0
|
| | | def SetRevive(self, hp):
|
| | | self._killer = None
|
| | | self._isAlive = True
|
| | | self._hp = hp
|
| | | def GetKiller(self): return self._killer
|
| | | def GetMaxHP(self): return int(self._batAttrDict.get(ChConfig.AttrID_MaxHP, 0))
|
| | | def SetMaxHP(self, maxHP, isNotify=False):
|
| | | maxHP = int(maxHP)
|
| | |
| | | deadCnt += 1
|
| | | return deadCnt
|
| | |
|
| | | def getHeroObj(self, heroID):
|
| | | if heroID not in self.heroObjIDDict:
|
| | | return
|
| | | return BattleObj.GetBatObjMgr().getBatObj(self.heroObjIDDict[heroID])
|
| | | |
| | | class BatFaction():
|
| | | ## 战斗阵营
|
| | |
|
| | |
| | | buffMgr = batObj.GetBuffManager()
|
| | | for index in range(buffMgr.GetBuffCount())[::-1]:
|
| | | buff = buffMgr.GetBuffByIndex(index)
|
| | | if not buff: # 有出现过报错,先做下防范,理论上不太可能
|
| | | continue
|
| | | buffID = buff.GetBuffID()
|
| | | skillID = buff.GetSkillID()
|
| | | skillData = buff.GetSkillData()
|
| | |
| | | killerObjID = killer.GetID() if killer else 0
|
| | | skillID = useSkill.GetSkillID() if useSkill else 0
|
| | | GameWorld.DebugLogEx(" %s 回合战斗主体被击杀: curID=%s,killerObjID=%s,skillID=%s", GetObjName(gameObj), objID, killerObjID, skillID)
|
| | | gameObj.SetDead()
|
| | | gameObj.SetDead(killer)
|
| | | TurnBuff.DoBuffByDead(turnFight, gameObj)
|
| | |
|
| | | clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
|
| | |
| | | TriggerWay_FriendAttackOverDirectOne, # 友方使用技能后(多目标仅触发一次,包含自己) 50
|
| | | TriggerWay_FriendAttackOverDirectOneNoSelf, # 友方使用技能后(多目标仅触发一次,不含自己) 51
|
| | | TriggerWay_DOTHurt, # 造成持续伤害时 52
|
| | | ) = range(1, 1 + 52)
|
| | | TriggerWay_FriendDotHurt, # 友方造成持续伤害时(多目标仅触发一次,包含自己) 53
|
| | | ) = range(1, 1 + 53)
|
| | |
|
| | | # 不加载的被动触发方式,一般用于本技能固定触发逻辑用的
|
| | | TriggerWayNoLoadList = [TriggerWay_CurSkillEff, TriggerWay_CurSkillEffLst]
|
| | |
| | | # 100 - 按友方某个国家武将数 参数1:国家
|
| | | if ruleType == 100:
|
| | | country = calcRule[1] if len(calcRule) > 1 else 0
|
| | | onlyAlive = calcRule[2] if len(calcRule) > 2 else 0
|
| | | batLineup = batObj.GetBatLineup()
|
| | | countryCnt = 0
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | |
| | | continue
|
| | | if batObj.GetCountry() != country:
|
| | | continue
|
| | | #if batObj.IsAlive(): # 死亡也算
|
| | | # continue
|
| | | if onlyAlive and not batObj.IsAlive():
|
| | | continue
|
| | | countryCnt += 1
|
| | | calcLayer = countryCnt
|
| | | GameWorld.DebugLogEx("按友方某个国家武将数计算额外buff属性: ruleType=%s,country=%s,countryCnt=%s", ruleType, country, countryCnt)
|
| | | GameWorld.DebugLogEx("按友方某个国家武将数计算额外buff属性: ruleType=%s,country=%s,countryCnt=%s,onlyAlive=%s", ruleType, country, countryCnt, onlyAlive)
|
| | | # 101 - 仅对指定性别有效 参数1:性别
|
| | | elif ruleType == 101:
|
| | | onlySex = calcRule[1] if len(calcRule) > 1 else 0
|
| | |
| | | passiveSkillID = curEffect.GetEffectValue(0) # 技能ID,为0时释放本技能
|
| | | effHeroID = curEffect.GetEffectValue(1) # 指定目标武将ID
|
| | | costHPPer = curEffect.GetEffectValue(2) # 可附加消耗自身血量百分比,配0不消耗,大于0血量不足时不释放
|
| | | searchFrom = curEffect.GetEffectValue(3) # 目标武将ID是否从阵容中搜索
|
| | |
|
| | | if not effHeroID or not tagObj:
|
| | | tagHero = tagObj
|
| | | if searchFrom:
|
| | | batLineup = batObj.GetBatLineup()
|
| | | tagHero = batLineup.getHeroObj(effHeroID)
|
| | | |
| | | if not effHeroID or not tagHero:
|
| | | return
|
| | |
|
| | | if tagObj.IsAlive():
|
| | | if tagHero.IsAlive():
|
| | | return
|
| | |
|
| | | tagHeroID = tagObj.GetHeroID()
|
| | | tagHeroID = tagHero.GetHeroID()
|
| | | if tagHeroID != effHeroID:
|
| | | #GameWorld.DebugLogEx("5507非目标武将死亡不处理! tagHeroID=%s,effHeroID=%s", tagHeroID, effHeroID)
|
| | | return
|
| | |
| | | if not passiveSkillID:
|
| | | return
|
| | |
|
| | | if tagObj.CheckInState(ChConfig.BatObjState_RebornLimit):
|
| | | if tagHero.CheckInState(ChConfig.BatObjState_RebornLimit):
|
| | | GameWorld.DebugLogEx("5507目标被禁止复活不处理! tagHeroID=%s", tagHeroID)
|
| | | return
|
| | |
|
| | | tagID = tagObj.GetID()
|
| | | tagID = tagHero.GetID()
|
| | | if costHPPer:
|
| | | curHP = batObj.GetHP()
|
| | | maxHP = batObj.GetMaxHP()
|
| | |
| | | GameWorld.DebugLogEx("5507扣血复活指定目标! curHP=%s/%s,costHPPer=%s,costHP=%s,tagHeroID=%s,tagID=%s", curHP, maxHP, costHPPer, costHP, tagHeroID, tagID)
|
| | | batObj.SetHP(max(1, curHP - costHP), True) # 直接扣除
|
| | | else:
|
| | | GameWorld.DebugLogEx("5507直接复活指定目标! curHP=%s/%s,costHPPer=%s,costHP=%s,tagHeroID=%s,tagID=%s", curHP, maxHP, costHPPer, costHP, tagHeroID, tagID)
|
| | | GameWorld.DebugLogEx("5507直接复活指定目标! tagHeroID=%s,tagID=%s,searchFrom=%s", tagHeroID, tagID, searchFrom)
|
| | |
|
| | | effectID = curEffect.GetEffectID()
|
| | | effSkillID = effSkill.GetSkillID()
|
| | | return TurnSkill.OnUsePassiveSkill(turnFight, batObj, tagObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
|
| | | return TurnSkill.OnUsePassiveSkill(turnFight, batObj, tagHero, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
|
| | |
| | | byFriendObj = kwargs.pop("byFriendObj") # 直接取出,防止传递
|
| | |
|
| | | passiveSkillID = curEffect.GetEffectValue(0) # 技能ID,为0时释放本技能
|
| | | byHeorID = curEffect.GetEffectValue(1) # 仅友军武将ID时有效(验证用,不一定是技能目标)
|
| | | byFriendRule = curEffect.GetEffectValue(1) # 友军验证规则[验证方式, 验证值]
|
| | | tagRule = curEffect.GetEffectValue(2) # 指定目标 0-按技能,1-对击杀方,2-对来源友军,3-对关联对象
|
| | |
|
| | | friendHeroID = byFriendObj.GetHeroID()
|
| | | if friendHeroID != byHeorID:
|
| | | GameWorld.DebugLogEx("5509非友军触发来源不处理! friendHeroID=%s != %s", friendHeroID, byHeorID)
|
| | | return
|
| | | |
| | | if byFriendRule:
|
| | | checkType = byFriendRule[0]
|
| | | # 验证方式 1 - 按武将ID, 值-武将ID
|
| | | if checkType == 1:
|
| | | byHeorID = byFriendRule[1] if len(byFriendRule) > 1 else 0
|
| | | friendHeroID = byFriendObj.GetHeroID()
|
| | | if friendHeroID != byHeorID:
|
| | | GameWorld.DebugLogEx("5509友军武将非触发来源不处理! friendHeroID=%s != %s", friendHeroID, byHeorID)
|
| | | return
|
| | | |
| | | # 验证方式 2 - 按国家, 值-国家
|
| | | elif checkType == 2:
|
| | | byCountry = byFriendRule[1] if len(byFriendRule) > 1 else 0
|
| | | friendCountry = byFriendObj.GetCountry()
|
| | | if friendCountry != byCountry:
|
| | | GameWorld.DebugLogEx("5509友军国家非触发来源不处理! friendCountry=%s != %s", friendCountry, byCountry)
|
| | | return
|
| | | |
| | | if not passiveSkillID:
|
| | | passiveSkillID = effSkill.GetSkillID()
|
| | | if not passiveSkillID:
|
| | |
| | |
|
| | | effectID = curEffect.GetEffectID()
|
| | | effSkillID = effSkill.GetSkillID()
|
| | | return TurnSkill.OnUsePassiveSkill(turnFight, batObj, byFriendObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
|
| | | toTagObj = None
|
| | | if tagRule == 1:
|
| | | toTagObj = byFriendObj.GetKiller()
|
| | | elif tagRule == 2:
|
| | | toTagObj = byFriendObj
|
| | | elif tagRule == 3:
|
| | | toTagObj = tagObj
|
| | | |
| | | return TurnSkill.OnUsePassiveSkill(turnFight, batObj, toTagObj, passiveSkillID, connSkill, effSkillID, effectID, connBuff, **kwargs)
|
| | |
| | | skillType = useSkill.GetSkillType()
|
| | | byTriggerWay = kwargs["byTriggerWay"] if "byTriggerWay" in kwargs else 0 # 不使用参数名 triggerWay, 防止传递过程中参数混乱
|
| | | if not curBatObj.IsAlive():
|
| | | if skillType == ChConfig.Def_SkillType_Revive and useSkill.GetTagAim() == ChConfig.SkillTagAim_Self:
|
| | | GameWorld.DebugLogEx("死亡时使用复活自己的技能! skillID=%s", skillID)
|
| | | if skillType == ChConfig.Def_SkillType_Revive:
|
| | | GameWorld.DebugLogEx("死亡时使用复活技能! skillID=%s", skillID)
|
| | | else:
|
| | | if byTriggerWay in ChConfig.DeadCanTriggerWayList:
|
| | | GameWorld.DebugLogEx("死亡可触发的方式触发技能可释放! skillID=%s,byTriggerWay=%s", skillID, byTriggerWay)
|
| | |
| | | return
|
| | | harmPer = harmEff.GetEffectValue(0) # 自残百分比
|
| | | noEnoughDo = harmEff.GetEffectValue(1) # 不足时扣除方式 0-不扣;1-自杀;2-扣剩1点
|
| | | calcType = harmEff.GetEffectValue(2) # 计算方式:0-按最大血量;1-按当前血量
|
| | | curHP = curBatObj.GetHP()
|
| | | maxHP = curBatObj.GetMaxHP()
|
| | | harmHP = int(maxHP * harmPer / 100.0)
|
| | | if calcType == 1:
|
| | | harmHP = int(curHP * harmPer / 100.0)
|
| | | else:
|
| | | harmHP = int(maxHP * harmPer / 100.0)
|
| | | lostHP = harmHP
|
| | | if curHP <= harmHP:
|
| | | if noEnoughDo == 0:
|
| | |
| | |
|
| | | updHP = max(curHP - lostHP, 0)
|
| | | curBatObj.SetHP(updHP, False)
|
| | | GameWorld.DebugLogEx("使用技能时自残: curHP=%s/%s,harmPer=%s,harmHP=%s,lostHP=%s,updHP=%s,noEnoughDo=%s", |
| | | curHP, maxHP, harmPer, harmHP, lostHP, updHP, noEnoughDo)
|
| | | GameWorld.DebugLogEx("使用技能时自残: curHP=%s/%s,harmPer=%s,harmHP=%s,lostHP=%s,updHP=%s,noEnoughDo=%s,calcType=%s", |
| | | curHP, maxHP, harmPer, harmHP, lostHP, updHP, noEnoughDo, calcType)
|
| | |
|
| | | curBatObj.SetHarmSelfHP(harmHP) # 无视实际扣血量,直接更新
|
| | |
|
| | |
| | | killObjList.append(tagObj)
|
| | | TurnAttack.SetObjKilled(turnFight, tagObj, curObj, useSkill)
|
| | | useSkill.SetKillObjList(killObjList)
|
| | | # 判断自己,因为反弹、平摊伤害的原因,有可能自己干死自己
|
| | | if curObj.IsAlive() and curObj.GetHP() <= 0:
|
| | | dieObjList.append(curObj)
|
| | | TurnAttack.SetObjKilled(turnFight, curObj)
|
| | | |
| | | |
| | | # 统计伤血,可能单个技能对同一目标造成多次伤害
|
| | | totalHurtValue = 0
|
| | | isSuckHP = False
|
| | |
| | | stunObjIDList, superHitObjIDList, parryObjIDList = [], [], []
|
| | | beHurtObjIDList = [] # 受伤的对象ID列表
|
| | | reviveObjList = [] # 复活的对象列表
|
| | | bounceObjList = [] # 有反弹的对象列表
|
| | | for hurtObj in useSkill.GetHurtObjListAll():
|
| | | hurtObjID = hurtObj.GetObjID()
|
| | | tagObj = batObjMgr.getBatObj(hurtObjID)
|
| | | if not tagObj:
|
| | | continue
|
| | | |
| | | bounceHP = hurtObj.GetBounceHP()
|
| | | if bounceHP:
|
| | | if tagObj not in bounceObjList:
|
| | | bounceObjList.append(tagObj)
|
| | | |
| | | if hurtObj.HaveHurtType(ChConfig.HurtAtkType_Hurt) and not hurtObj.HaveHurtType(ChConfig.HurtAtkType_Immune) \
|
| | | and (isTurnNormalSkill or isAngerSkill) and tagObj.IsAlive():
|
| | | __doSkillHurtAnger(tagObj, hurtObj.GetLostHP(), useSkill)
|
| | |
| | | if hurtObj.GetSuckHP() > 0:
|
| | | isSuckHP = True
|
| | |
|
| | | # 判断自己死亡,因为反弹、平摊伤害的原因,有可能自己干死自己
|
| | | if curObj.IsAlive() and curObj.GetHP() <= 0:
|
| | | dieObjList.append(curObj)
|
| | | killer = bounceObjList[0] if bounceObjList else None
|
| | | TurnAttack.SetObjKilled(turnFight, curObj, killer)
|
| | | |
| | | # 记录最后一次总伤害,有伤害目标才记录
|
| | | if totalHurtValue:
|
| | | curObj.SetLastHurtValue(totalHurtValue)
|
| | |
| | | for dieObj in dieObjList:
|
| | | # 敌方单位死亡时
|
| | | if lineupObj.GetFaction() != dieObj.GetFaction():
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_EnemyDie, dieObj, connSkill=useSkill)
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_EnemyDie, dieObj, connSkill=useSkill, byKiller=curObj)
|
| | | # 己方单位死亡时
|
| | | else:
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendDie, dieObj, connSkill=useSkill, byFriendObj=dieObj)
|
| | |
| | | if isExObj:
|
| | | continue
|
| | |
|
| | | isDotHurt = False
|
| | | # 直接攻击
|
| | | if isAttackDirect:
|
| | | if not triggerOne:
|
| | |
| | | elif not isAttackDirect:
|
| | | # 受到持续伤害
|
| | | if tagID in beHurtObjIDList:
|
| | | isDotHurt = True
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, curObj, ChConfig.TriggerWay_DOTHurt, tagObj, connSkill=useSkill, connBuff=timeBuff)
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, tagObj, ChConfig.TriggerWay_BeDOTHurt, curObj, connSkill=useSkill, connBuff=timeBuff)
|
| | |
|
| | |
| | |
|
| | |
|
| | | # 敌友方
|
| | | if isAttackDirect or batType in [ChConfig.TurnBattleType_Combo, ChConfig.TurnBattleType_Pursue]:
|
| | | if isAttackDirect or batType in [ChConfig.TurnBattleType_Combo, ChConfig.TurnBattleType_Pursue] or isDotHurt:
|
| | | if not curBatLineup:
|
| | | curBatLineup = curObj.GetBatLineup()
|
| | | for lineupObjID in curBatLineup.posObjIDDict.values():
|
| | |
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendAttackOverDirectOne, tagObj, connSkill=useSkill, byFriendObj=curObj)
|
| | | if curID != lineupObj.GetID():
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendAttackOverDirectOneNoSelf, tagObj, connSkill=useSkill, byFriendObj=curObj)
|
| | | |
| | | # 持续伤害
|
| | | elif isDotHurt:
|
| | | if not triggerOne:
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendDotHurt, tagObj, connSkill=useSkill, byFriendObj=curObj)
|
| | | |
| | | # 连击
|
| | | if batType == ChConfig.TurnBattleType_Combo:
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, lineupObj, ChConfig.TriggerWay_FriendCombo, tagObj, connSkill=useSkill, byFriendObj=curObj)
|