| | |
| | | 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):
|
| | |
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not batObj:
|
| | | continue
|
| | | if batObj.GetHP() > 0:
|
| | | if batObj.IsAlive():
|
| | | allKilled = False
|
| | | break
|
| | |
|
| | | if allKilled:
|
| | | self.winFaction = ChConfig.Def_FactionA if faction == ChConfig.Def_FactionB else ChConfig.Def_FactionA
|
| | | self.winFaction = ChConfig.Def_FactionA if faction == ChConfig.Def_FactionB else ChConfig.Def_FactionB
|
| | | DoTurnFightOver(self.guid)
|
| | | return self.winFaction
|
| | |
|
| | |
| | | def startFight(self):
|
| | | ## 准备就绪,开始战斗
|
| | | self.state = FightState_Start
|
| | | self.setTimeline(1)
|
| | | self.syncInit()
|
| | | return
|
| | |
|
| | |
| | |
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
|
| | | atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
|
| | | atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 2)
|
| | | for posNumKey, heroInfo in heroDict.items():
|
| | | posNum = int(posNumKey)
|
| | |
|
| | |
| | | batObj.SetLineupPos(posNum, num)
|
| | | batObj.SetFightPower(fightPower)
|
| | | batObj.SetLV(lv)
|
| | | batObj.SetAtkDistType(atkDistType)
|
| | | if npcID:
|
| | | batObj.SetNPCID(npcID)
|
| | | elif lineupPlayerID:
|
| | |
| | | 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)
|
| | | #GameWorld.DebugLog("OnTimelineChange! objID=%s" % (objID))
|
| | | if not batObj or not batObj.IsAlive():
|
| | | continue
|
| | | |
| | | batObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
|
| | | batObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, 0)
|
| | | batObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, 0)
|
| | | |
| | | 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不处理
|
| | | #GameWorld.DebugLog(" 永久buff不处理! curID=%s,index=%s,skillID=%s" % (curID, index, buff.GetSkillID()))
|
| | | continue
|
| | | calcTimeline = buff.GetCalcTime()
|
| | | passTurn = __calcPassturn(calcTimeline, nowTimeline, False)
|
| | | if passTurn <= 0:
|
| | | #GameWorld.DebugLog(" passTurn <= 0 passTurn=%s,calcTimeline=%s,nowTimeline=%s,skillID=%s" % (passTurn, calcTimeline, nowTimeline, buff.GetSkillID()))
|
| | | 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)
|
| | | |
| | | # SetTimeline(gameObj, turnNum, 0)
|
| | | # # 重置连击、反击数
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 0)
|
| | | # gameObj.SetDict(ChConfig.Def_PlayerKey_AttrFaintCD, 0) # 击晕CD
|
| | | # |
| | | # objType = gameObj.GetGameObjType()
|
| | | # objID = gameObj.GetID()
|
| | | # objName = GetObjName(gameObj)
|
| | | # GameWorld.DebugLog("ObjPerTurnStart: 回合%s, %s objType-ID-HP(%s-%s-%s)" % (turnNum, objName, objType, objID, GameObj.GetHP(gameObj)))
|
| | | # |
| | | # # 每回合开始减技能CD
|
| | | # skillManager = gameObj.GetSkillManager()
|
| | | # for i in range(skillManager.GetSkillCount()):
|
| | | # skill = skillManager.GetSkillByIndex(i)
|
| | | # remainTime = skill.GetRemainTime()
|
| | | # if not remainTime:
|
| | | # continue
|
| | | # skillID = skill.GetSkillID()
|
| | | # updRemainTime = max(0, remainTime - ChConfig.Def_PerTurnTick)
|
| | | # skill.SetRemainTime(updRemainTime)
|
| | | # GameWorld.DebugLog(" skillID=%s,remainTime=%s,updRemainTime=%s" % (skillID, remainTime, updRemainTime))
|
| | | # |
| | | # # 刷新定时处理的buff效果
|
| | | # SkillShell.ProcessPersistBuff(gameObj, tick)
|
| | | # |
| | | # PassiveBuffEffMng.OnPassiveSkillTrigger(gameObj, tagObj, None, ChConfig.TriggerType_TurnNum, tick)
|
| | | # |
| | | # __logGameObjAttr(gameObj)
|
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
|
| | | 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):
|
| | |
| | |
|
| | | return
|
| | |
|
| | | def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, curSkill=None, isBounce=False):
|
| | | def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, skillID=0, isBounce=False):
|
| | | ## 回合对象添加伤害值
|
| | | # @param isBounce: 是否反弹伤害
|
| | | if hurtValue <= 0:
|
| | | return
|
| | | 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"
|
| | | % (curID, tagID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
|
| | |
|
| | | if tagBatObj:
|
| | | updStatValue = tagBatObj.StatDefValue(lostHP)
|
| | | updStatValue = tagBatObj.StatDefValue(hurtValue)
|
| | | GameWorld.DebugLog(" 统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,isBounce=%s"
|
| | | % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
|
| | |
|
| | |
| | | objName = GetObjName(curBatObj)
|
| | |
|
| | | # 是否可行动状态判断
|
| | | canAction = True
|
| | | |
| | | canAction = curBatObj.CanAction()
|
| | | if not canAction:
|
| | | GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
|
| | | return
|
| | |
| | | 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()
|
| | | useSkillList = []
|
| | |
| | | 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):
|
| | |
| | | if SkillCommon.isAngerSkill(useSkill):
|
| | | if curXP < xpMax:
|
| | | continue
|
| | | if curBatObj.IsInState(ChConfig.BatObjState_Sneer):
|
| | | GameWorld.DebugLog("嘲讽状态下,无法主动释放怒技!") # 可被动释放怒技,如怒技追击
|
| | | continue
|
| | | useCnt = -1 # xp技能优先释放
|
| | | else:
|
| | | useCnt = curBatObj.GetSkillUseCnt(skillID)
|
| | |
| | | for useInfo in useSkillList:
|
| | | useSkill = useInfo[-1]
|
| | | if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
|
| | | return True
|
| | | break
|
| | |
|
| | | return
|
| | |
|
| | | def DoAttack(curBatObj, tagBatObj, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
|
| | | # curID = curBatObj.GetID()
|
| | | # npcID = curBatObj.GetNPCID()
|
| | | # objName = GetObjName(curBatObj)
|
| | | # GameWorld.DebugLog(" ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
|
| | | # |
| | | # atkOK = False
|
| | | # curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
|
| | | # |
| | | # if turnBattleType == ChConfig.TurnBattleType_AtkBack:
|
| | | # if not tagBatObj:
|
| | | # return
|
| | | # skillManager = curBatObj.GetSkillManager()
|
| | | # for index in range(0, skillManager.GetSkillCount()):
|
| | | # skill = skillManager.GetSkillByIndex(index)
|
| | | # if not skill:
|
| | | # continue
|
| | | # if skill.GetFuncType() == ChConfig.Def_SkillFuncType_AtkbackSkill:
|
| | | # useSkill = skill
|
| | | # break
|
| | | # atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
|
| | | # elif turnBattleType == ChConfig.TurnBattleType_Combo:
|
| | | # if not tagBatObj:
|
| | | # return
|
| | | # atkOK = SkillShell.DoLogic_UseSkill(curBatObj, tagBatObj, useSkill, tick)
|
| | | # else:
|
| | | # curXP = GameObj.GetXP(curBatObj)
|
| | | # xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) |
| | | # skillManager = curBatObj.GetSkillManager()
|
| | | # useSkillList = []
|
| | | # #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
|
| | | # for index in range(0, skillManager.GetSkillCount()):
|
| | | # useSkill = skillManager.GetSkillByIndex(index)
|
| | | # if not useSkill:
|
| | | # continue
|
| | | # if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_AtkbackSkill]:
|
| | | # #基础普攻不能主动释放,目前仅用于反击
|
| | | # continue
|
| | | # #被动技能无法使用
|
| | | # if SkillCommon.isPassiveSkill(useSkill):
|
| | | # continue
|
| | | # #还在冷却时间内无法释放
|
| | | # if useSkill.GetRemainTime():
|
| | | # continue
|
| | | # skillID = useSkill.GetSkillID()
|
| | | # # 常规攻击优先xp
|
| | | # if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
|
| | | # if curXP < xpMax:
|
| | | # continue
|
| | | # useCnt = -1 # xp技能优先释放
|
| | | # else:
|
| | | # useCnt = curBatObj.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillID) # 该技能已使用次数
|
| | | # useSkillList.append([useCnt, index, skillID, useSkill])
|
| | | # |
| | | # useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
|
| | | # #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
|
| | | # |
| | | # for useInfo in useSkillList:
|
| | | # useSkill = useInfo[-1]
|
| | | # #skillID = useSkill.GetSkillID()
|
| | | # atkOK, tagBatObj = OnUseSkill(curBatObj, useSkill, tick)
|
| | | # if atkOK:
|
| | | # break
|
| | | # |
| | | # curBatObj.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
|
| | | # |
| | | # tagID = 0
|
| | | # tagHP = 0
|
| | | # if tagObj:
|
| | | # tagID = tagObj.GetID()
|
| | | # tagHP = GameObj.GetHP(tagObj)
|
| | | # GameWorld.DebugLog(' atkOK=%s,tagID=%s,tagHP=%s' % (atkOK, tagID, tagHP), npcID)
|
| | | # if not atkOK:
|
| | | # return
|
| | | # |
| | | # if not tagObj:
|
| | | # return
|
| | | # |
| | | # if GameObj.GetFaction(curNPC) == GameObj.GetFaction(tagObj):
|
| | | # # 同阵营直接返回,不处理连击、反击
|
| | | # return True
|
| | | # |
| | | # curHP = GameObj.GetHP(curNPC)
|
| | | # tagHP = GameObj.GetHP(tagObj)
|
| | | # tagID = tagObj.GetID()
|
| | | # GameWorld.DebugLog(" curID-HP=(%s-%s),tagID-HP=(%s-%s)" % (curID, curHP, tagID, tagHP))
|
| | | # if tagHP <= 0 or curHP <= 0:
|
| | | # return True
|
| | | # |
| | | # # 反击,反击可打断连击,所以优先判断
|
| | | # if CanAtkBack(curNPC, tagObj):
|
| | | # DoAttack(tagObj, curNPC, tick, ChConfig.TurnBattleType_AtkBack)
|
| | | # return True
|
| | | # |
| | | # # 连击
|
| | | # if CanCombo(curNPC, tagObj):
|
| | | # DoAttack(curNPC, tagObj, tick, ChConfig.TurnBattleType_Combo, useSkill)
|
| | | # |
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, curBatObj, ChConfig.TriggerWay_HeroActionEnd)
|
| | | return True
|
| | |
|
| | | def CanAtkBack(atkObj, defObj):
|
| | | ## 可否反击
|
| | | posNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 100
|
| | | if posNum <= 0:
|
| | | GameWorld.DebugLog(" 被非主战单位攻击时无法触发反击: atkID=%s,posNum=%s" % (atkObj.GetID(), posNum))
|
| | | return False
|
| | | atkDistType = AttackCommon.GetAtkDistType(defObj)
|
| | | if atkDistType == ChConfig.AtkDistType_Long:
|
| | | if not IpyGameDataPY.GetFuncCfg("ParryCfg", 2):
|
| | | GameWorld.DebugLog(" 远程单位不可反击: defID=%s" % (defObj.GetID()))
|
| | | return False
|
| | | defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率
|
| | | atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数
|
| | | if atkBackNum > 10:
|
| | | # 内置最高反击数防范
|
| | | return False
|
| | | if atkBackNum > 0:
|
| | | validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 4)
|
| | | vaildPer = validPerList[atkBackNum - 1] if len(validPerList) >= atkBackNum else 0
|
| | | defAtkBackRate = int(defAtkBackRate * vaildPer / 100.0)
|
| | | |
| | | atkAtkBackDefRate = GameObj.GetAtkBackDefRate(atkObj) # 攻方抵抗反击率
|
| | | atkBackRate = max(0, defAtkBackRate - atkAtkBackDefRate)
|
| | | if atkBackRate <= 0 or not GameWorld.CanHappen(atkBackRate):
|
| | | GameWorld.DebugLog(" 无法反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)" |
| | | % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate))
|
| | | return False
|
| | | GameWorld.DebugLog(" 可以反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)" |
| | | % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate))
|
| | | return True
|
| | |
|
| | | def CanCombo(atkObj, defObj):
|
| | | ## 可否连击
|
| | | |
| | | atkComboRate = GameObj.GetComboRate(atkObj) # 攻方连击率
|
| | | comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum) # 已连击次数
|
| | | if comboNum > 10:
|
| | | # 内置最高连击数防范
|
| | | return False
|
| | | if comboNum > 0:
|
| | | validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 3)
|
| | | vaildPer = validPerList[comboNum - 1] if len(validPerList) >= comboNum else 0
|
| | | atkComboRate = int(atkComboRate * vaildPer / 100.0)
|
| | | |
| | | defComboReduce = GameObj.GetComboDefRate(defObj) # 防方抵抗连击率
|
| | | comboRate = max(0, atkComboRate - defComboReduce)
|
| | | if comboRate <= 0 or not GameWorld.CanHappen(comboRate):
|
| | | GameWorld.DebugLog(" 无法连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)" |
| | | % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
|
| | | return False
|
| | | 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()
|
| | | GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), objID))
|
| | | gameObj.SetHP(0)
|
| | | killerObjID = killer.GetID() if killer else 0
|
| | | skillID = useSkill.GetSkillID() if useSkill else 0
|
| | | GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s,killerObjID=%s,skillID=%s" % (GetObjName(gameObj), objID, killerObjID, skillID))
|
| | | gameObj.SetDead()
|
| | |
|
| | | clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCTurnFightObjDead)
|
| | | clientPack.ObjID = objID
|
| | |
| | |
|
| | | turnFight.costTime = time.time() - turnFight.startTime
|
| | | winFaction = turnFight.winFaction
|
| | | GameWorld.DebugLog("--- 战斗结束处理 --- %s, winFaction=%s, costTime=%ss" % (guid, winFaction, turnFight.costTime))
|
| | | GameWorld.DebugLog("--- 战斗结束处理 ---, winFaction=%s, costTime=%ss, %s" % (winFaction, turnFight.costTime, guid))
|
| | |
|
| | | # 统计明细
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | |
| | | atkHurt = batObj.hurtStat
|
| | | defHurt = batObj.defStat
|
| | | cureHP = batObj.cureStat
|
| | | GameWorld.DebugLog(" Pos:%s ID=%s-%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s" |
| | | GameWorld.DebugLog(" Pos:%s ID=%s,npcID=%s,heroID=%s,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s" |
| | | % (posNum, objID, npcID, heroID, batObj.GetHP(), batObj.GetMaxHP(), atkHurt, defHurt, cureHP))
|
| | | lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
|
| | |
|