| | |
| | | import time
|
| | | import json
|
| | |
|
| | | FighterNPCID = 100 # 战斗NPCID,仅后端用,除怪物外,所有玩家武将均使用该NPCID
|
| | | PosNumMax = 10 # 最大站位编号
|
| | | ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
|
| | |
|
| | |
| | | SummonLineupObjs(self, self.faction, self.num, lineupInfo, self.getPlayerID())
|
| | | return
|
| | |
|
| | | def resetLineup(self, isReborn=True):
|
| | | ## 重置阵容
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | for objID in self.posObjIDDict.values():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not batObj:
|
| | | continue
|
| | | batObj.ResetBatObj(isReborn)
|
| | | return
|
| | | |
| | | def clearLineup(self):
|
| | | ## 清除阵容
|
| | | if not self.posObjIDDict:
|
| | |
| | | self.lineupDict[num] = lineup
|
| | | return lineup
|
| | |
|
| | | def resetLineups(self):
|
| | | ## 重置所有战斗阵容
|
| | | for lineup in self.lineupDict.values():
|
| | | lineup.resetLineup()
|
| | | return
|
| | | |
| | | def clearLineups(self):
|
| | | ## 清除所有战斗阵容
|
| | | for lineup in self.lineupDict.values():
|
| | |
| | | self.curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) if playerID else None
|
| | | self.mapID = mapID
|
| | | self.funcLineID = funcLineID
|
| | | self.state = -1 # -1 代表未战斗
|
| | | self.turnNum = 1 # 当前第x回合,默认第1回合开始
|
| | | self.turnMax = 15 # 最大回合数
|
| | | self.enterLogic = False # 是否已执行进场逻辑
|
| | |
| | | self.costTime = 0
|
| | | return
|
| | |
|
| | | def setFactionLineup(self, faction, lineupDict, onlyReset=False):
|
| | | def setFactionLineup(self, faction, lineupDict):
|
| | | ## 设置阵营阵容
|
| | | # @param lineupDict: {阵容编号:阵容信息, ...} 每个阵营支持多个阵容,即支持多V多
|
| | | # @param onlyReset: 是否仅重置,一般用于玩家的阵容,重复利用阵容实例,
|
| | | batFaction = self.getBatFaction(faction)
|
| | | if onlyReset:
|
| | | batFaction.resetLineups()
|
| | | else:
|
| | | batFaction.clearLineups()
|
| | | batFaction.clearLineups()
|
| | | for num, lineupInfo in lineupDict.items():
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | if onlyReset and not batLineup.isEmpty():
|
| | | continue
|
| | | if not lineupInfo:
|
| | | continue
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | batLineup.setLineup(lineupInfo)
|
| | | return
|
| | |
|
| | |
| | |
|
| | | return 0
|
| | |
|
| | | def clearBatFaction(self, faction):
|
| | | batFaction = self.getBatFaction(faction)
|
| | | batFaction.clearLineups()
|
| | | return
|
| | | |
| | | def clearFight(self):
|
| | | def exitFight(self):
|
| | | ## 退出战斗
|
| | | self.syncState(FightState_Over)
|
| | | for batFaction in self.factionDict.values():
|
| | | batFaction.clearLineups()
|
| | | self.state = -1
|
| | | return
|
| | | |
| | | def startFight(self):
|
| | | ## 准备就绪,开始战斗
|
| | | self.state = FightState_Start
|
| | | self.syncInit()
|
| | | return
|
| | | |
| | | def isInFight(self): return self.state != -1
|
| | |
|
| | | def syncInit(self):
|
| | | ## 初始化通知
|
| | |
| | | return
|
| | |
|
| | | def syncState(self, state, msgDict={}):
|
| | | self.state = state
|
| | | msg = json.dumps(msgDict, ensure_ascii=False)
|
| | | msg = msg.replace(" ", "")
|
| | | clientPack = ChPyNetSendPack.tagMCTurnFightState()
|
| | |
| | | turnFight = self.getTurnFight(guid)
|
| | | if not turnFight:
|
| | | return
|
| | | turnFight.clearFight()
|
| | | turnFight.exitFight()
|
| | | self.turnFightDict.pop(guid, None)
|
| | | return
|
| | |
|
| | |
| | | batObj.SetNPCID(npcID)
|
| | | elif lineupPlayerID:
|
| | | batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
|
| | | batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
|
| | | |
| | | |
| | | 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,faction:%s,num=%s,posNum=%s,skill=%s,atk=%s,def=%s,hp=%s" |
| | | % (objID, faction, num, posNum, skillIDList, batObj.GetAtk(), batObj.GetDef(), batObj.GetHP()))
|
| | | GameWorld.DebugLog("AddBatObj ID:%s,faction:%s,num=%s,posNum=%s,skill=%s" % (objID, faction, num, posNum, skillIDList))
|
| | | batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
|
| | |
|
| | | return
|
| | |
|
| | |
| | | if reqType == 2: # 前端主动请求开始关卡小怪的视为从休息中开始
|
| | | __doMainLevelWave(curPlayer, True)
|
| | | elif reqType == 3:
|
| | | __doMainBossStart(curPlayer, tick)
|
| | | __doMainBossStart(curPlayer)
|
| | | elif reqType == 4:
|
| | | __doMainFight(curPlayer, tick)
|
| | | else:
|
| | |
| | | mainFightMgr = GetMainFightMgr(curPlayer)
|
| | | turnFight = mainFightMgr.turnFight
|
| | | if turnFight:
|
| | | turnFight.clearFight()
|
| | | turnFight.exitFight()
|
| | | return
|
| | |
|
| | | def __doSetFightPoint(curPlayer, fightPoint):
|
| | |
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | | turnFight.startFight()
|
| | | return
|
| | |
|
| | | def __doMainBossStart(curPlayer, tick):
|
| | | def __doMainBossStart(curPlayer):
|
| | | ## 开始挑战关卡boss
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | chapterID, levelNum, wave = PlayerControl.GetMainLevelPassInfo(curPlayer)
|
| | |
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | | turnFight.startFight()
|
| | |
|
| | | # 挑战boss无中间过程,每次执行直接挑战一队结果
|
| | | __processTurnFight(turnFight.guid, tick)
|
| | | __processTurnFight(turnFight.guid)
|
| | | return
|
| | |
|
| | | def __doMainFight(curPlayer, tick):
|
| | | ## 主线执行战斗
|
| | | |
| | | # 限制请求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)
|
| | | |
| | | mainFightMgr = GetMainFightMgr(curPlayer)
|
| | | turnFight = mainFightMgr.turnFight
|
| | |
|
| | |
| | | # 切换小队时,玩家阵容不需要处理,保留状态
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | | turnFight.startFight()
|
| | |
|
| | | if mainFightMgr.isLevelBoss():
|
| | | # 每次处理一小队的完整战斗,相当于一次完整战报
|
| | | __processTurnFight(turnFight.guid, tick)
|
| | | __processTurnFight(turnFight.guid)
|
| | | return
|
| | | else:
|
| | | __doMainLevelWave(curPlayer, False)
|
| | |
| | |
|
| | | return
|
| | |
|
| | | def __processTurnFight(guid, tick):
|
| | | def __processTurnFight(guid):
|
| | | ## 一次性处理完一个小队的战斗
|
| | | turnFight = GetTurnFightMgr().getTurnFight(guid)
|
| | | curPlayer = turnFight.curPlayer
|
| | |
| | | OnTurnAllOver(turnFight.guid)
|
| | | return
|
| | |
|
| | | #// B4 10 回合制战斗 #tagCMTurnFight
|
| | | #
|
| | | #struct tagCMTurnFight
|
| | | #{
|
| | | # tagHead Head;
|
| | | # DWORD MapID; // 自定义地图ID,可用于绑定战斗地图场景功能(如主线关卡、主线boss、爬塔、竞技场等)
|
| | | # DWORD FuncLineID; // MapID对应的扩展值,如具体某个关卡等
|
| | | # BYTE TagType; // 目标类型,0-NPC阵容,1-玩家
|
| | | # DWORD TagID; // 目标类型对应的ID,如阵容ID或玩家ID
|
| | | # BYTE ValueCount;
|
| | | # DWORD ValueList[ValueCount]; // 附加值列表,可选,具体含义由MapID决定
|
| | | #};
|
| | | def OnTurnFight(index, clientData, tick):
|
| | | #curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | #mapID = clientData.MapID
|
| | | #funcLineID = clientData.FuncLineID
|
| | | return
|
| | |
|
| | | def GetObjName(batObj):
|
| | | faction = batObj.faction
|
| | | num = batObj.lineupNum
|
| | |
| | | curID = batObj.GetID()
|
| | | buffMgr = batObj.GetBuffManager()
|
| | | GameWorld.DebugLog("更新buff: curID=%s,buffCount=%s" % (curID, buffMgr.GetBuffCount()))
|
| | | for index in range(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,updRemainTime=%s" % (buffID, updRemainTime))
|
| | | GameWorld.DebugLog(" 更新buff剩余回合数: buffID=%s,skillID=%s,updRemainTime=%s" % (buffID, skillID, updRemainTime))
|
| | | if updRemainTime > 0:
|
| | | buff.SetRemainTime(curRemainTime - 1)
|
| | | buff.SetRemainTime(updRemainTime)
|
| | | TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
|
| | | else:
|
| | | TurnBuff.SyncBuffDel(turnFight, batObj, buffID)
|
| | | TurnBuff.DoBuffDel(turnFight, batObj, buff)
|
| | |
|
| | | # SetTimeline(gameObj, turnNum, 0)
|
| | | # # 重置连击、反击数
|
| | |
| | | GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
|
| | | return
|
| | |
|
| | | GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
|
| | | 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)
|
| | |
|
| | | curXP = curBatObj.GetXP()
|
| | | xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2)
|
| | | skillManager = curBatObj.GetSkillManager()
|
| | | useSkillList = []
|