| | |
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChConfig
|
| | | import PlayerTask
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import PlayerControl
|
| | |
| | | self.turnNum = 1 # 当前第x回合,默认第1回合开始
|
| | | self.turnMax = 15 # 最大回合数
|
| | | self.enterLogic = False # 是否已执行进场逻辑
|
| | | self.turnStart = 0 # 已执行回合开始值,如第1回合开始已执行则为1,第2回合为2
|
| | | self.turnEnd = 0 # 已执行回合结束值,如第1回合结束已执行则为1,第2回合为2
|
| | | self.winFaction = 0 # 本场战斗结束标记,获胜阵营,为0时代表未结束,所有小队打完或失败才有结果,0-未结束,>0-获胜的阵营
|
| | | self.batBuffer = "" # 战报buffer,战报暂时只保留最后一个小队的
|
| | | self.isNeedReport = isNeedReport # 是否需要战报
|
| | |
| | |
|
| | | self.factionDict = {} # 战斗阵营 {faction:BatFaction, ...},一般是只有两个阵营,faction为1或2,每个阵营支持多个阵容
|
| | | self.actionSortList = [] # 阵容行动顺序 [[faction, num], ...]
|
| | | self.actionIndex = 0 # 行动顺序索引
|
| | | self.actionIndex = 0 # 行动顺序索引 |
| | | self.timeline = 0 # 时间轴节点 turnNum*1000+actionIndex*100++actionNum
|
| | | |
| | | self.startTime = 0 # 开始时间戳,支持毫秒小数
|
| | | self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
|
| | | return
|
| | |
| | | ## 一般用于玩家发起的战斗,在需要保留玩家阵容属性及状态的情况下,重置回合进入下一场战斗
|
| | | self.turnNum = 1
|
| | | self.enterLogic = False
|
| | | self.turnStart = 0
|
| | | self.turnEnd = 0
|
| | | self.winFaction = 0
|
| | | self.batBuffer = "" # 战报buffer
|
| | | self.msgDict.update(msgDict)
|
| | | self.timeline = 0
|
| | | self.startTime = time.time()
|
| | | self.costTime = 0
|
| | | return
|
| | |
| | | GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
|
| | | return
|
| | |
|
| | | def getTurnNumStartTimelin(self, turnNum): return turnNum * TimelineSet + 0 # 每回合的时间节点起点
|
| | | def getTimeline(self): return self.timeline
|
| | | def setTimeline(self, turnNum):
|
| | | def setTimeline(self, timeline, isEmpty=False):
|
| | | '''回合战斗的时间轴节点 ,即第几回合开始,每个回合支持9999个行动节点
|
| | | @param turnNum: 第x回合
|
| | | '''
|
| | | self.timeline = turnNum * TimelineSet + 0
|
| | | self.timeline = timeline
|
| | | GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
|
| | | if isEmpty:
|
| | | # 空位置的节点可直接跳过
|
| | | return timeline
|
| | | |
| | | OnTimelineChange(self)
|
| | | return
|
| | | def addTimeline(self):
|
| | | ## 每切换一个行动单位可视为一个行动节点,即代表单回合战斗中的某一个时间节点
|
| | | self.timeline += 1
|
| | | GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
|
| | | OnTimelineChange(self)
|
| | | return
|
| | | return timeline
|
| | |
|
| | | def getBatFaction(self, faction=ChConfig.Def_FactionA):
|
| | | ## 默认阵营1
|
| | |
| | | def startFight(self):
|
| | | ## 准备就绪,开始战斗
|
| | | self.state = FightState_Start
|
| | | self.setTimeline(1)
|
| | | self.turnNum = 1
|
| | | self.timeline = self.getTurnNumStartTimelin(self.turnNum)
|
| | | self.syncInit()
|
| | | return
|
| | |
|
| | |
| | | self.teamMax = 1 # 当前波最大小队,某场战斗可能包含多个小队,所有小队混流击杀完才算过了本波
|
| | | self.nextTeam = False # 下次前端请求战斗是否是下一小队,否则都是重新刷新当前进度怪
|
| | | self.waveLineupList = [] # 小队列表
|
| | | self.strongerLV = 0
|
| | | self.difficulty = 0
|
| | | self.turnFight = GetTurnFightMgr().addTurnFight(ChConfig.Def_FBMapID_Main, 0, playerID)
|
| | | return
|
| | |
|
| | |
| | |
|
| | | return lineupInfo
|
| | |
|
| | | def GetNPCLineupInfo(lineupID):
|
| | | def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0):
|
| | | ## 获取NPC阵容信息
|
| | | # @param lineupID: 阵容ID
|
| | | # @param npcLV: 成长NPC等级
|
| | | # @param difficulty: 成长NPC难度系数
|
| | | # @return: 阵容全部信息json字典,前端通用格式
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("NPCLineup", lineupID)
|
| | | if not ipyData:
|
| | |
| | | npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
|
| | | if not npcID:
|
| | | continue
|
| | | npcData = NPCCommon.GetNPCDataPy(npcID)
|
| | | if not npcData:
|
| | | battleDict = GetNPCBattleDict(ipyData, npcID, strongerLV, difficulty)
|
| | | if not battleDict:
|
| | | continue
|
| | | heroDict[str(posNum)] = battleDict
|
| | | |
| | | lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict}
|
| | | return lineupInfo
|
| | |
|
| | | def GetNPCBattleDict(lineupIpyData, npcID, strongerLV=0, difficulty=0):
|
| | | ## 获取NPC战斗相关字典,支持成长NPC
|
| | | # @param strongerLV: 成长等级
|
| | | # @param difficulty: 难度系数
|
| | | npcData = NPCCommon.GetNPCDataPy(npcID)
|
| | | if not npcData:
|
| | | return
|
| | | heroID = npcData.GetRelatedHeroID()
|
| | | npcLV = npcData.GetLV()
|
| | | |
| | | lvIpyData = None
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None
|
| | | npcStronger = IpyGameDataPY.GetIpyGameDataNotLog("NPCStronger", npcID)
|
| | | if npcStronger and strongerLV:
|
| | | lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", strongerLV)
|
| | | if lvIpyData:
|
| | | npcLV = strongerLV
|
| | | if not lvIpyData:
|
| | | lvIpyData = IpyGameDataPY.GetIpyGameData("PlayerLV", npcLV)
|
| | | |
| | | if heroIpyData and lvIpyData:
|
| | | skinIDList = heroIpyData.GetSkinIDList()
|
| | | skinID = skinIDList[0] if skinIDList else 0
|
| | | skillIDList = GetNPCHeroSkillIDList(heroID, heroIpyData, lvIpyData.GetReHeroBreakLV(), lvIpyData.GetReHeroAwakeLV())
|
| | | else:
|
| | | heroID = 0
|
| | | skinID = 0
|
| | | skillIDList = [] + npcData.GetSkillIDList()
|
| | | |
| | | # boss额外随机技能
|
| | | bossID = lineupIpyData.GetBossID()
|
| | | if npcID == bossID:
|
| | | skillIDExList = lineupIpyData.GetSkillIDExList()
|
| | | if skillIDExList:
|
| | | randSkillIDExList = [] + list(skillIDExList)
|
| | | skillExCnt = lineupIpyData.GetSkillExCnt()
|
| | | if skillExCnt > 0 and len(randSkillIDExList) > skillExCnt:
|
| | | random.shuffle(randSkillIDExList)
|
| | | randSkillIDExList = randSkillIDExList[:skillExCnt]
|
| | | skillIDList += randSkillIDExList
|
| | | GameWorld.DebugLog("阵容boss技能: %s, 随机附加技能: %s" % (skillIDList, randSkillIDExList))
|
| | | |
| | | # 成长怪属性
|
| | | batAttrDict = GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty)
|
| | | if not batAttrDict:
|
| | | batAttrDict = {ChConfig.AttrID_Atk:npcData.GetAtk(), ChConfig.AttrID_Def:npcData.GetDef(), ChConfig.AttrID_MaxHP:npcData.GetMaxHP(),
|
| | | ChConfig.AttrID_FinalDamPer:npcData.GetFinalDamPer(), ChConfig.AttrID_FinalDamPerDef:npcData.GetFinalDamPerDef(),
|
| | | ChConfig.AttrID_MissRate:npcData.GetMissRate(), ChConfig.AttrID_MissRateDef:npcData.GetMissRateDef(),
|
| | |
| | | ChConfig.AttrID_SuckHPPer:npcData.GetSuckHPPer(), ChConfig.AttrID_SuckHPPerDef:npcData.GetSuckHPPerDef(),
|
| | | }
|
| | | batAttrDict.update(npcData.GetSpecAttrInfo())
|
| | | skillIDList = [] + npcData.GetSkillIDList()
|
| | | heroDict[str(posNum)] = {"NPCID":npcID, |
| | | "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0},
|
| | | "SkillIDList":skillIDList
|
| | | }
|
| | |
|
| | | lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict}
|
| | | return lineupInfo
|
| | | battleDict = {"NPCID":npcID,
|
| | | "HeroID":heroID,
|
| | | "SkinID":skinID,
|
| | | "LV":npcLV,
|
| | | "AttrDict":{str(k):v for k, v in batAttrDict.items() if v > 0},
|
| | | "SkillIDList":skillIDList,
|
| | | }
|
| | | |
| | | GameWorld.DebugLog("GetNPCBattleDict npcID=%s,strongerLV=%s,difficulty=%s,%s" % (npcID, strongerLV, difficulty, battleDict))
|
| | | return battleDict
|
| | |
|
| | | def GetNPCHeroSkillIDList(heroID, heroIpyData, breakLV, awakeLV):
|
| | | ## 获取NPC对应武将的技能ID列表
|
| | | normalSkillID = heroIpyData.GetNormalSkillID()
|
| | | angerSkillID = heroIpyData.GetAngerSkillID()
|
| | | skillIDList = [normalSkillID, angerSkillID]
|
| | | |
| | | breakIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroBreak", heroID)
|
| | | if breakIpyDataList:
|
| | | for breakIpyData in breakIpyDataList:
|
| | | if breakIpyData.GetBreakLV() > breakLV:
|
| | | break
|
| | | skillID = breakIpyData.GetSkillID()
|
| | | if skillID:
|
| | | skillIDList.append(skillID)
|
| | | |
| | | awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID)
|
| | | if awakeIpyDataList:
|
| | | for awakeIpyData in awakeIpyDataList:
|
| | | if awakeIpyData.GetAwakeLV() > awakeLV:
|
| | | break
|
| | | skillID = awakeIpyData.GetSkillID()
|
| | | if skillID:
|
| | | skillIDList.append(skillID)
|
| | | |
| | | return skillIDList
|
| | |
|
| | | def GetNPCStrongerAttrDict(npcID, lvIpyData, npcStronger, difficulty):
|
| | | ## 获取NPC成长属性
|
| | | # @param strongerLV: 成长等级
|
| | | # @param difficulty: 难度系数
|
| | | |
| | | batAttrDict = {}
|
| | | if not lvIpyData or not npcStronger or not difficulty:
|
| | | return batAttrDict
|
| | | lv = lvIpyData.GetLV()
|
| | | for attrID in ChConfig.CalcBattleAttrIDList:
|
| | | attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID)
|
| | | if not attrIpyData:
|
| | | continue
|
| | | attrName = attrIpyData.GetParameter()
|
| | | if not hasattr(lvIpyData, "GetRe%s" % attrName):
|
| | | continue
|
| | | reValue = getattr(lvIpyData, "GetRe%s" % attrName)() # 基础参考值
|
| | | ratio = getattr(npcStronger, "Get%sRatio" % attrName)() if hasattr(npcStronger, "Get%sRatio" % attrName) else 1 # 属性系数
|
| | | attrValue = int(reValue * ratio * difficulty)
|
| | | batAttrDict[attrID] = attrValue
|
| | | #GameWorld.DebugLog(" attrID=%s,attrValue=%s,reValue=%s,ratio=%s,difficulty=%s" % (attrID, attrValue, reValue, ratio, difficulty))
|
| | | |
| | | GameWorld.DebugLog("NPC成长属性: npcID=%s,lv=%s,difficulty=%s,%s" % (npcID, lv, difficulty, batAttrDict))
|
| | | return batAttrDict
|
| | |
|
| | | def SummonLineupObjs(batLineup, faction, num, lineupInfo, playerID=0):
|
| | | '''召唤阵容战斗实例
|
| | |
| | | for posNumKey, heroInfo in heroDict.items():
|
| | | posNum = int(posNumKey)
|
| | |
|
| | | npcID, heroID, skinID = 0, 0, 0
|
| | | atkBackSkillID = 0 # 反击技能ID
|
| | | fightPower = 0
|
| | | skillIDList = [] # 战斗对象可能改变属性或技能,重新创建,防止误修改来源值
|
| | | attrDict = {}
|
| | | skillIDList += heroInfo.get("SkillIDList", [])
|
| | | attrDict.update(heroInfo.get("AttrDict", {}))
|
| | | objName = ""
|
| | | if lineupPlayerID:
|
| | | heroID = heroInfo.get("HeroID", 0)
|
| | | skinID = heroInfo.get("SkinID", 0)
|
| | | lv = heroInfo.get("LV", 1)
|
| | | fightPower = heroInfo.get("FightPower", 0)
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | npcID = heroInfo.get("NPCID", 0)
|
| | | heroID = heroInfo.get("HeroID", 0)
|
| | | skinID = heroInfo.get("SkinID", 0)
|
| | | lv = heroInfo.get("LV", 1)
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID) if heroID else None
|
| | | if heroIpyData:
|
| | | atkDistType = heroIpyData.GetAtkDistType()
|
| | | objName = heroIpyData.GetName()
|
| | | country = heroIpyData.GetCountry()
|
| | | sex = heroIpyData.GetSex()
|
| | | |
| | | if lineupPlayerID:
|
| | | fightPower = heroInfo.get("FightPower", 0)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | |
| | | else:
|
| | | npcID = heroInfo.get("NPCID", 0)
|
| | | npcDataEx = NPCCommon.GetNPCDataPy(npcID)
|
| | | if not npcDataEx:
|
| | | continue
|
| | | objName = npcDataEx.GetNPCName()
|
| | | atkDistType = npcDataEx.GetAtkDistType()
|
| | | lv = npcDataEx.GetLV()
|
| | | |
| | | if not heroIpyData:
|
| | | atkDistType = npcDataEx.GetAtkDistType()
|
| | | objName = npcDataEx.GetNPCName()
|
| | | country = npcDataEx.GetCountry()
|
| | | sex = npcDataEx.GetSex()
|
| | | |
| | | batObj = batObjMgr.addBatObj()
|
| | | if not batObj:
|
| | | break
|
| | | objID = batObj.GetID()
|
| | | if npcID:
|
| | | batObj.SetNPCID(npcID)
|
| | | elif lineupPlayerID:
|
| | | batObj.SetOwnerID(lineupPlayerID)
|
| | | batObj.SetTFGUID(tfGUID)
|
| | | batObj.SetName(objName)
|
| | | batObj.SetFaction(faction)
|
| | |
| | | batObj.SetFightPower(fightPower)
|
| | | batObj.SetLV(lv)
|
| | | batObj.SetAtkDistType(atkDistType)
|
| | | if npcID:
|
| | | batObj.SetNPCID(npcID)
|
| | | elif lineupPlayerID:
|
| | | batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
|
| | | |
| | | batObj.SetCountry(country)
|
| | | batObj.SetSex(sex)
|
| | | batObj.SetHero(heroID, skinID)
|
| | | |
| | | if atkDistType == ChConfig.AtkDistType_Short:
|
| | | atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
|
| | | elif atkDistType == ChConfig.AtkDistType_Long:
|
| | |
| | | skillManager.LearnSkillByID(skillID)
|
| | |
|
| | | batLineup.posObjIDDict[posNum] = objID
|
| | | GameWorld.DebugLog("AddBatObj ID:%s,%s,skill=%s" % (objID, GetObjName(batObj), skillIDList))
|
| | | GameWorld.DebugLog("AddBatObj %s,skill=%s" % (GetObjName(batObj), skillManager.GetSkillIDList()))
|
| | | batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
|
| | |
|
| | | return
|
| | |
| | | __doSetFightPoint(curPlayer, reqValue)
|
| | | return
|
| | |
|
| | | GameWorld.DebugLog("主线战斗请求: reqType=%s" % reqType, curPlayer.GetPlayerID())
|
| | | clientPack = ChPyNetSendPack.tagSCTurnFightReportSign()
|
| | | clientPack.Sign = 0
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack) # 标记开始
|
| | |
| | | GameWorld.DebugLog("没有设置主阵容!", playerID)
|
| | | return
|
| | |
|
| | | strongerLV = levelIpyData.GetNPCLV()
|
| | | difficulty = levelIpyData.GetDifficulty()
|
| | | mainFightMgr = GetMainFightMgr(curPlayer)
|
| | | mainFightMgr.nextTeam = False
|
| | | mainFightMgr.chapterID = chapterID
|
| | |
| | | mainFightMgr.waveLineupList = waveLineupList
|
| | | mainFightMgr.teamNum = teamNum
|
| | | mainFightMgr.teamMax = teamMax
|
| | | mainFightMgr.strongerLV = strongerLV
|
| | | mainFightMgr.difficulty = difficulty
|
| | | turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 2)
|
| | | mapID, funcLineID = ChConfig.Def_FBMapID_Main, PlayerControl.ComMainLevelValue(chapterID, levelNum, wave)
|
| | | GameWorld.DebugLog("设置起始关卡波: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s" |
| | | % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID), playerID)
|
| | | GameWorld.DebugLog("设置起始关卡波: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s,strongerLV=%s,difficulty=%s" |
| | | % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID, strongerLV, difficulty), playerID)
|
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.startFight()
|
| | | |
| | | __doMainFight(curPlayer)
|
| | | return
|
| | |
|
| | | def __doMainBossStart(curPlayer):
|
| | |
| | | if not lineupMainInfo:
|
| | | GameWorld.DebugLog("没有设置主阵容!", playerID)
|
| | | return
|
| | | |
| | | |
| | | strongerLV = levelIpyData.GetNPCLV()
|
| | | difficulty = levelIpyData.GetDifficulty()
|
| | | mainFightMgr = GetMainFightMgr(curPlayer)
|
| | | mainFightMgr.nextTeam = False
|
| | | mainFightMgr.chapterID = chapterID
|
| | |
| | | mainFightMgr.waveLineupList = waveLineupList
|
| | | mainFightMgr.teamNum = teamNum
|
| | | mainFightMgr.teamMax = teamMax
|
| | | mainFightMgr.strongerLV = strongerLV
|
| | | mainFightMgr.difficulty = difficulty
|
| | | turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 3)
|
| | | mapID, funcLineID = ChConfig.Def_FBMapID_MainBoss, PlayerControl.ComMainLevelValue(chapterID, levelNum, wave)
|
| | | GameWorld.DebugLog("设置关卡boss: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s" |
| | | % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID), playerID)
|
| | | GameWorld.DebugLog("设置关卡boss: 关卡%s-%s,波=%s/%s,teamMax=%s,mapID=%s,funcLineID=%s,lineupID=%s,strongerLV=%s,difficulty=%s" |
| | | % (chapterID, levelNum, wave, waveMax, teamMax, mapID, funcLineID, lineupID, strongerLV, difficulty), playerID)
|
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.startFight()
|
| | |
|
| | |
| | | __processTurnFight(turnFight.guid)
|
| | | return
|
| | |
|
| | | def __doMainFight(curPlayer, tick):
|
| | | ## 主线执行战斗
|
| | | def __doMainFight(curPlayer, tick=0):
|
| | | '''执行主线战斗,单场战斗断电式战斗,以前端玩家手动点击节点做为断点处
|
| | | 每场战斗的初始化、结束默认断点,由前端决定自动继续或者点击继续
|
| | | '''
|
| | |
|
| | | # 限制请求CD
|
| | | #if not GameWorld.GetGameWorld().GetDebugLevel():
|
| | | key = "MainFightReqTick"
|
| | | lastTick = curPlayer.GetDictByKey(key)
|
| | | if lastTick and tick - lastTick <= 1000:
|
| | | GameWorld.DebugLog("主线战斗请求CD中")
|
| | | return
|
| | | curPlayer.SetDict(key, tick)
|
| | | |
| | | if tick:
|
| | | key = "MainFightReqTick"
|
| | | lastTick = curPlayer.GetDictByKey(key)
|
| | | if lastTick and tick - lastTick <= 1000:
|
| | | GameWorld.DebugLog("主线战斗请求CD中")
|
| | | return
|
| | | curPlayer.SetDict(key, tick)
|
| | | |
| | | mainFightMgr = GetMainFightMgr(curPlayer)
|
| | | turnFight = mainFightMgr.turnFight
|
| | |
|
| | |
| | | mainFightMgr.nextTeam = False
|
| | | turnFight.resetTurn({"teamNum":teamNum})
|
| | | # 切换小队时,玩家阵容不需要处理,保留状态
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, mainFightMgr.strongerLV, mainFightMgr.difficulty)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.startFight()
|
| | |
|
| | |
| | | # 每次处理一小队的完整战斗,相当于一次完整战报
|
| | | __processTurnFight(turnFight.guid)
|
| | | return
|
| | | else:
|
| | | __doMainFight(curPlayer)
|
| | | else:
|
| | | __doMainLevelWave(curPlayer, False)
|
| | | return
|
| | |
| | |
|
| | | # 小怪战斗,每次消耗1个战锤
|
| | | fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
|
| | | |
| | | if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
|
| | | GameWorld.DebugLog("回合开始时战锤不足!")
|
| | | return
|
| | |
|
| | | # 以下均是处理关卡小怪分段实时战斗
|
| | | EntryLogic(turnFight)
|
| | | isEntry = EntryLogic(turnFight)
|
| | |
|
| | | # 按阵营阵容执行顺序,逐个遍历
|
| | | doCnt = 0
|
| | | doMax = (PosNumMax + 2) * len(turnFight.actionSortList) # 防止死循环,做最大循环次数限制 = (最大位置数 + 主公、红颜位置)*行动阵容数
|
| | | overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
|
| | | # 是否开始检查断点,预判可断的点,方便前端点击体验,点下去就是玩家放的某个行动
|
| | | # 初始开始进场后,默认开始断点
|
| | | checkBreakpoint = True if isEntry else False
|
| | |
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | turnNum = turnFight.turnNum
|
| | | GameWorld.DebugLog("turnNum=%s,doMax=%s,actionIndex=%s,%s" % (turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
|
| | | while doCnt < doMax and len(overLineupList) < len(turnFight.actionSortList):
|
| | | doCnt += 1
|
| | | turnNum = turnFight.turnNum
|
| | | # 执行回合开始逻辑
|
| | | 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
|
| | | turnFight.turnStart = turnNum
|
| | | turnFight.actionIndex = 0
|
| | | turnFight.addTimeline() # 每回合开始算一个时间节点
|
| | | turnMax = turnFight.turnMax
|
| | | for turnNum in range(turnNum, turnMax + 1):
|
| | | turnTimeline = turnFight.getTurnNumStartTimelin(turnNum) # 本回合起始时间节点
|
| | | curTimeline = turnFight.getTimeline()
|
| | | |
| | | # 回合开始
|
| | | turnTimeline += 1 # 每回合开始算一个时间节点
|
| | | if curTimeline < turnTimeline:
|
| | | curTimeline = turnFight.setTimeline(turnTimeline)
|
| | | GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】 curTimeline=%s" % (turnNum, curTimeline))
|
| | | turnFight.turnNum = turnNum
|
| | | if curPlayer:
|
| | | turnFight.syncState(FightState_Fighting)
|
| | | |
| | | 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)
|
| | | batLineup.actionNum = ActionNumStart
|
| | | batLineup.actionNum = 1
|
| | | for objID in batLineup.posObjIDDict.values():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | TurnFightPerTurnBigStart(turnFight, batObj, turnNum)
|
| | |
|
| | | if turnFight.actionIndex >= len(turnFight.actionSortList):
|
| | | turnFight.actionIndex = 0
|
| | | |
| | | playerHeroAtk = False # 玩家阵容行动标记
|
| | | faction, num = turnFight.actionSortList[turnFight.actionIndex]
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | if batLineup.actionNum > max(batLineup.posObjIDDict):
|
| | | if (faction, num) not in overLineupList:
|
| | | overLineupList.append((faction, num))
|
| | | |
| | | turnFight.actionIndex += 1
|
| | | continue
|
| | | |
| | | GameWorld.DebugLog("执行行动: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
|
| | | |
| | | # 主公
|
| | | if batLineup.actionNum == -1:
|
| | | pass
|
| | | |
| | | # 红颜
|
| | | elif batLineup.actionNum == 0:
|
| | | pass
|
| | | # 灵兽
|
| | | |
| | | if turnFight.checkOverByKilled():
|
| | | break
|
| | |
|
| | | # 武将
|
| | | elif batLineup.actionNum > 0:
|
| | | doMax = PosNumMax * len(turnFight.actionSortList)
|
| | | doCnt = 0
|
| | | while doCnt < doMax and turnFight.actionIndex < len(turnFight.actionSortList):
|
| | | doCnt += 1
|
| | | faction, num = turnFight.actionSortList[turnFight.actionIndex]
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | for posNum in range(batLineup.actionNum, PosNumMax + 1):
|
| | | turnFight.addTimeline() # 每个武将位算一个时间节点
|
| | | batLineup.actionNum = posNum
|
| | | if posNum not in batLineup.posObjIDDict:
|
| | | turnTimeline += 1 # 每个武将位算一个时间节点
|
| | | if turnTimeline <= curTimeline:
|
| | | # 该时间节点已经处理过了
|
| | | GameWorld.DebugLog("该时间节点已经处理过了! turnTimeline=%s <= %s" % (turnTimeline, curTimeline))
|
| | | continue
|
| | | |
| | | if posNum not in batLineup.posObjIDDict:
|
| | | batLineup.actionNum = posNum + 1
|
| | | curTimeline = turnFight.setTimeline(turnTimeline, True)
|
| | | continue
|
| | | |
| | | objID = batLineup.posObjIDDict[posNum]
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | |
| | | # 玩家自己阵营,预判可否行动
|
| | | if checkBreakpoint and faction == ChConfig.Def_FactionA and batObj:
|
| | | if batObj.CanAction():
|
| | | GameWorld.DebugLog("玩家武将已经行动过了,且有下一个可行动的武将,断点: curTimeline=%s,nextPosNum=%s" % (curTimeline, posNum))
|
| | | return
|
| | | |
| | | batLineup.actionNum = posNum + 1
|
| | | curTimeline = turnFight.setTimeline(turnTimeline)
|
| | | TurnFightHeroTurnStart(turnFight, batObj, turnNum)
|
| | | if not OnObjAction(turnFight, batObj):
|
| | | continue
|
| | |
|
| | | if faction == ChConfig.Def_FactionA:
|
| | | playerHeroAtk = True
|
| | | if not checkBreakpoint and faction == ChConfig.Def_FactionA:
|
| | | checkBreakpoint = True
|
| | |
|
| | | break
|
| | | |
| | | turnFight.actionIndex += 1
|
| | | batLineup.actionNum += 1
|
| | | if batLineup.actionNum > max(batLineup.posObjIDDict):
|
| | | GameWorld.DebugLog("该阵容本回合已经全部行动完了: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
|
| | | if (faction, num) not in overLineupList:
|
| | | overLineupList.append((faction, num))
|
| | | if turnFight.actionIndex >= len(turnFight.actionSortList) - 1:
|
| | | turnFight.actionIndex = 0
|
| | | else:
|
| | | turnFight.actionIndex += 1
|
| | |
|
| | | if turnFight.checkOverByKilled():
|
| | | break
|
| | | |
| | | if playerHeroAtk:
|
| | | # 玩家武将有行动则停止,一段段执行
|
| | | GameWorld.DebugLog("玩家武将有行动则停止!")
|
| | | break
|
| | | |
| | | if turnFight.winFaction:
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("turnNum=%s,doCnt=%s,overLineupList=%s" % (turnNum, doCnt, overLineupList))
|
| | | 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
|
| | | turnFight.turnEnd = turnNum
|
| | | turnFight.addTimeline() # 每回合结束算一个时间节点
|
| | | # 回合结束
|
| | | turnTimeline += 1 # 每回合结束算一个时间节点
|
| | | if curTimeline < turnTimeline:
|
| | | curTimeline = turnFight.setTimeline(turnTimeline)
|
| | | 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():
|
| | | 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)
|
| | | |
| | | if turnFight.checkOverByKilled():
|
| | | break
|
| | | |
| | | if not turnFight.winFaction:
|
| | | OnTurnAllOver(turnFight.guid)
|
| | | |
| | | return
|
| | |
|
| | | def __processTurnFight(guid):
|
| | |
| | | for turnNum in range(1, turnMax + 1):
|
| | | turnFight.turnNum = turnNum
|
| | | GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum)
|
| | | turnFight.setTimeline(turnNum)
|
| | | curTimeline = turnFight.getTurnNumStartTimelin(turnNum) # 本回合起始时间节点
|
| | | curTimeline = turnFight.setTimeline(curTimeline + 1)
|
| | | 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)
|
| | |
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | 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)
|
| | | # 灵兽
|
| | |
|
| | | 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:
|
| | | curTimeline = turnFight.setTimeline(curTimeline + 1, True)
|
| | | continue
|
| | | curTimeline = turnFight.setTimeline(curTimeline + 1) # 每个武将位算一个时间节点
|
| | | objID = batLineup.posObjIDDict[posNum]
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | TurnFightHeroTurnStart(turnFight, batObj, turnNum)
|
| | |
| | | turnFight.actionIndex += 1
|
| | |
|
| | | # 回合结束
|
| | | turnFight.addTimeline() # 每回合结束算一个时间节点
|
| | | curTimeline = turnFight.setTimeline(curTimeline + 1) # 每回合结束算一个时间节点
|
| | | for faction, num in turnFight.actionSortList:
|
| | | GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | |
| | | num = batObj.lineupNum
|
| | | posNum = batObj.posNum
|
| | | heroID = batObj.heroID
|
| | | if not heroID:
|
| | | heroID = batObj.npcID
|
| | | npcID = batObj.npcID
|
| | | objName = GameWorld.CodeToGbk(batObj.GetName())
|
| | | return "%s%s-%s [%s-%s] %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), heroID, objName)
|
| | | if heroID:
|
| | | objName += " Hero:%s" % heroID
|
| | | if npcID:
|
| | | objName += " NPC:%s" % npcID |
| | | return "%s%s-P%s ID:%s %s" % ("A" if faction == ChConfig.Def_FactionA else "B", num, posNum, batObj.GetID(), objName)
|
| | |
|
| | | def EntryLogic(turnFight):
|
| | | ## 执行进场逻辑
|
| | |
| | | TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_FightStart)
|
| | |
|
| | | turnFight.enterLogic = True
|
| | | return
|
| | | return True
|
| | |
|
| | | def OnTimelineChange(turnFight):
|
| | | ## 每个时间节点变化时处理
|
| | |
| | | return
|
| | |
|
| | | def TurnFightHeroTurnStart(turnFight, batObj, turnNum):
|
| | | ## 武将回合开始时
|
| | | ## 武将回合开始时,不能行动也要触发
|
| | | if not batObj:
|
| | | return
|
| | |
|
| | |
| | | clientPack.ObjID = objID
|
| | | clientPack.KillerObjID = killerObjID
|
| | | clientPack.SkillID = skillID
|
| | | turnFight.addBatPack(clientPack) |
| | | turnFight.addBatPack(clientPack)
|
| | | |
| | | curPlayer = turnFight.curPlayer
|
| | | # 暂时只算主线小怪
|
| | | if curPlayer and turnFight.mapID == ChConfig.Def_FBMapID_Main and gameObj.GetFaction() != ChConfig.Def_FactionA:
|
| | | PlayerTask.AddTaskValue(curPlayer, ChConfig.TaskType_KillNPC, 1) |
| | | return True
|
| | |
|
| | | def OnTurnAllOver(guid):
|