| | |
| | | import NPCCommon
|
| | | import ShareDefine
|
| | | import PyGameData
|
| | | import IPY_GameWorld
|
| | | import ItemControler
|
| | | import SkillCommon
|
| | | import SkillShell
|
| | | import AttackCommon
|
| | | import FBLogic
|
| | | import BattleObj
|
| | | import TurnSkill
|
| | | import TurnBuff
|
| | | import ObjPool
|
| | |
|
| | | import random
|
| | | import time
|
| | |
| | | FightState_Award, # 4 结算奖励
|
| | | FightState_Over, # 5 结束状态,无特殊意义,仅代表所有处理结束了,与Start对应
|
| | | ) = range(6)
|
| | |
|
| | | Def_FactionA = 1
|
| | | Def_FactionB = 2
|
| | |
|
| | | |
| | | class BatLineup():
|
| | | ## 战斗阵容
|
| | |
|
| | | def __init__(self, faction, num, fightMgr):
|
| | | self.fightMgr = fightMgr
|
| | | def __init__(self, faction, num, turnFight):
|
| | | self.turnFight = turnFight # TurnFight
|
| | | self.faction = faction # 所属阵营
|
| | | self.num = num # 该阵容所在阵营中的编号,不同阵营可重复,多V多
|
| | | self.ownerID = 0 # 阵容所属玩家ID,可能为0,0代表非玩家阵容
|
| | | self.npcPosDict = {} # 阵容NPC {站位编号:curNPC, ...}, 站位编号小于0为非主战单位,如主公、红颜等
|
| | | self.npcObjIDDict = {} # NPC实例ID字典 {objID:curNPC, ...}
|
| | | self.shapeType = 0 # 阵型
|
| | | self.actionNum = ActionNumStart # 行动位置,从1开始
|
| | | self.lordAttrDict = {} # 主公属性
|
| | | self.npcAttrDict = {} # 阵容NPC属性 {npcID:{attrID:value, ...}, ...}
|
| | | self.fightPower = 0 # 阵容总战力
|
| | | |
| | | # 战斗统计
|
| | | self.hurtStatDict = {} # 输出统计 {objID:totalValue, ...}
|
| | | self.defStatDict = {} # 承伤统计 {objID:totalValue, ...}
|
| | | self.cureStatDict = {} # 治疗统计 {objID:totalValue, ...}
|
| | | self.posObjIDDict = {} # 站位对应战斗实体 {站位编号:batObjID, ...}, 站位编号小于0为非主战单位,如主公、红颜等
|
| | | self.actionNum = ActionNumStart # 行动位置,从1开始
|
| | | return
|
| | |
|
| | | def getGUID(self): return self.fightMgr.guid
|
| | | def getPlayerID(self): return self.fightMgr.playerID # 发起的玩家ID
|
| | | def getPlayerID(self): return self.turnFight.playerID # 发起的玩家ID
|
| | |
|
| | | def isEmpty(self): return not self.npcPosDict
|
| | | def isEmpty(self): return not self.posObjIDDict
|
| | |
|
| | | def setLineup(self, lineupInfo):
|
| | | ## 设置阵容
|
| | | # @param lineupInfo: 阵容信息
|
| | | self.clearLineup()
|
| | | self.ownerID = lineupInfo.get("PlayerID", 0) # 阵容所属的玩家ID
|
| | | self.shapeType = lineupInfo.get("Shape", 0)
|
| | | self.lordAttrDict = lineupInfo.get("LordAttrDict", {})
|
| | | self.shapeType = lineupInfo.get("ShapeType", 0)
|
| | | self.fightPower = lineupInfo.get("FightPower", 0)
|
| | | SummonLineupObjs(self, self.faction, self.num, lineupInfo, self.getPlayerID())
|
| | | return
|
| | | |
| | | def refreshFightPower(self):
|
| | | ## 刷新阵容总战力
|
| | | if self.fightPower:
|
| | | return self.fightPower
|
| | | |
| | | return self.fightPower
|
| | | |
| | | def __resetStat(self):
|
| | | ## 重置战斗统计
|
| | | self.actionNum = ActionNumStart
|
| | | self.hurtStatDict = {}
|
| | | self.defStatDict = {}
|
| | | self.cureStatDict = {}
|
| | | return
|
| | | |
| | | def __resetAttrState(self, isReborn=True):
|
| | | ## 重置属性状态
|
| | | # @param isReborn: 是否复活
|
| | | initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
|
| | | for curNPC in self.npcPosDict.values():
|
| | | if not curNPC:
|
| | | continue
|
| | | if GameObj.GetHP(curNPC) <= 0 and not isReborn:
|
| | | continue
|
| | | # 回满血,清除buff
|
| | | GameObj.SetHPFull(curNPC, False)
|
| | | # 重置怒气
|
| | | GameObj.SetXP(curNPC, initXP, False)
|
| | | # ...
|
| | | |
| | | return
|
| | |
|
| | | def resetLineup(self, isReborn=True):
|
| | | ## 重置阵容
|
| | | self.__resetAttrState(isReborn)
|
| | | self.__resetStat()
|
| | | 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.npcPosDict:
|
| | | if not self.posObjIDDict:
|
| | | return
|
| | | for curNPC in self.npcPosDict.values():
|
| | | if not curNPC:
|
| | | continue
|
| | | NPCCommon.SetDeadEx(curNPC)
|
| | | self.npcPosDict = {}
|
| | | self.npcObjIDDict = {}
|
| | | self.npcAttrDict = {}
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | for objID in self.posObjIDDict.values():
|
| | | batObjMgr.delBatObj(objID)
|
| | | self.posObjIDDict = {}
|
| | | self.fightPower = 0
|
| | | self.__resetStat()
|
| | | return
|
| | | |
| | | def statHurtValue(self, objID, hurtValue):
|
| | | ## 统计输出
|
| | | if objID not in self.npcObjIDDict:
|
| | | return
|
| | | updValue = self.hurtStatDict.get(objID, 0) + hurtValue
|
| | | self.hurtStatDict[objID] = updValue
|
| | | return updValue
|
| | | |
| | | def statDefValue(self, objID, lostHP):
|
| | | ## 统计承伤
|
| | | if objID not in self.npcObjIDDict:
|
| | | return
|
| | | updValue = self.defStatDict.get(objID, 0) + lostHP
|
| | | self.defStatDict[objID] = updValue
|
| | | return updValue
|
| | | |
| | | def statCureValue(self, objID, cureValue):
|
| | | ## 统计治疗
|
| | | if objID not in self.npcObjIDDict:
|
| | | return
|
| | | updValue = self.cureStatDict.get(objID, 0) + cureValue
|
| | | self.cureStatDict[objID] = updValue
|
| | | return updValue
|
| | |
|
| | | class BatFaction():
|
| | | ## 战斗阵营
|
| | |
|
| | | def __init__(self, faction, fightMgr):
|
| | | self.fightMgr = fightMgr
|
| | | def __init__(self, faction, turnFight):
|
| | | self.turnFight = turnFight # TurnFight
|
| | | self.faction = faction
|
| | | self.lineupDict = {} # 该阵营所有阵容信息 {编号:BatLineup, ...}
|
| | | return
|
| | |
| | | if num in self.lineupDict:
|
| | | lineup = self.lineupDict[num]
|
| | | else:
|
| | | lineup = BatLineup(self.faction, num, self.fightMgr)
|
| | | lineup = BatLineup(self.faction, num, self.turnFight)
|
| | | self.lineupDict[num] = lineup
|
| | | return lineup
|
| | |
|
| | |
| | |
|
| | | self.startTime = 0 # 开始时间戳,支持毫秒小数
|
| | | self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
|
| | | |
| | | #玩家武将行动后击杀目标
|
| | | self.playerKillObjIDList = [] # [objID, ...]
|
| | | return
|
| | |
|
| | | def setTurn(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}):
|
| | |
| | | if not lineupInfo:
|
| | | continue
|
| | | batLineup.setLineup(lineupInfo)
|
| | | batLineup.refreshFightPower()
|
| | | return
|
| | |
|
| | | def sortActionQueue(self):
|
| | |
| | | for batFaction in self.factionDict.values():
|
| | | faction = batFaction.faction
|
| | | for num, batLineup in batFaction.lineupDict.items():
|
| | | fightPower = batLineup.refreshFightPower()
|
| | | fightPower = batLineup.fightPower
|
| | | sortValue = -(faction * 10 + num)
|
| | | sortList.append([fightPower, sortValue, faction, num])
|
| | | sortList.sort(reverse=True) # 战力高的先手
|
| | |
| | | GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
|
| | | return
|
| | |
|
| | | def getBatFaction(self, faction=Def_FactionA):
|
| | | def getBatFaction(self, faction=ChConfig.Def_FactionA):
|
| | | ## 默认阵营1
|
| | | batFaction = None
|
| | | if faction in self.factionDict:
|
| | |
| | | if self.winFaction:
|
| | | return self.winFaction
|
| | |
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | for faction, batFaction in self.factionDict.items():
|
| | | allKilled = True
|
| | | for batLineup in batFaction.lineupDict.values():
|
| | | if not allKilled:
|
| | | break
|
| | | for posNum, curNPC in batLineup.npcPosDict.items():
|
| | | for posNum, objID in batLineup.posObjIDDict.items():
|
| | | if posNum <= 0:
|
| | | # 非主战位置不判断
|
| | | continue
|
| | | if GameObj.GetHP(curNPC) > 0:
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not batObj:
|
| | | continue
|
| | | if batObj.GetHP() > 0:
|
| | | allKilled = False
|
| | | break
|
| | |
|
| | | if allKilled:
|
| | | self.winFaction = Def_FactionA if faction == Def_FactionB else Def_FactionA
|
| | | self.winFaction = ChConfig.Def_FactionA if faction == ChConfig.Def_FactionB else ChConfig.Def_FactionA
|
| | | DoTurnFightOver(self.guid)
|
| | | return self.winFaction
|
| | |
|
| | |
| | | clientPack.Msg = msg
|
| | | clientPack.Len = len(clientPack.Msg)
|
| | | clientPack.FactionList = []
|
| | | |
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | for faction in self.factionDict.keys():
|
| | | batFaction = self.getBatFaction(faction)
|
| | | tfFaction = ChPyNetSendPack.tagSCTurnFightFaction()
|
| | |
| | | tfLineup.OwnerID = batLineup.ownerID
|
| | | tfLineup.ShapeType = batLineup.shapeType
|
| | | tfLineup.ObjList = []
|
| | | for posNum, curNPC in batLineup.npcPosDict.items():
|
| | | for posNum, objID in batLineup.posObjIDDict.items():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not batObj:
|
| | | continue
|
| | | tfObj = ChPyNetSendPack.tagSCTurnFightObj()
|
| | | tfObj.ObjID = curNPC.GetID()
|
| | | tfObj.NPCID = curNPC.GetNPCID()
|
| | | tfObj.HeroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | tfObj.SkinID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_SkinID)
|
| | | tfObj.HP = curNPC.GetHP()
|
| | | tfObj.HPEx = curNPC.GetHPEx()
|
| | | tfObj.MaxHP = curNPC.GetMaxHP()
|
| | | tfObj.MaxHPEx = curNPC.GetMaxHPEx()
|
| | | tfObj.LV = NPCCommon.GetNPCLV(curNPC)
|
| | | tfObj.ObjID = batObj.GetID()
|
| | | tfObj.NPCID = batObj.GetNPCID()
|
| | | tfObj.HeroID = batObj.GetHeroID()
|
| | | tfObj.SkinID = batObj.GetSkinID()
|
| | | tfObj.HP = batObj.GetHP() % ChConfig.Def_PerPointValue
|
| | | tfObj.HPEx = batObj.GetHP() / ChConfig.Def_PerPointValue
|
| | | tfObj.MaxHP = batObj.GetMaxHP() % ChConfig.Def_PerPointValue
|
| | | tfObj.MaxHPEx = batObj.GetMaxHP() / ChConfig.Def_PerPointValue
|
| | | tfObj.LV = batObj.GetLV()
|
| | | tfObj.PosNum = posNum
|
| | | tfObj.AngreXP = GameObj.GetXP(curNPC)
|
| | | tfObj.AngreXP = batObj.GetXP()
|
| | | tfLineup.ObjList.append(tfObj)
|
| | | tfLineup.ObjCnt = len(tfLineup.ObjList)
|
| | | tfFaction.LineupList.append(tfLineup)
|
| | |
| | | self.addBatPack(clientPack)
|
| | | return
|
| | |
|
| | | def syncObjAction(self, turnNum, objType, objID):
|
| | | def syncObjAction(self, turnNum, objID):
|
| | | clientPack = ChPyNetSendPack.tagMCTurnFightObjAction()
|
| | | clientPack.Clear()
|
| | | clientPack.TurnNum = turnNum
|
| | |
| | | # 有玩家的统一每个包单独发送,同样也支持战报统计
|
| | | if self.curPlayer:
|
| | | NetPackCommon.SendFakePack(self.curPlayer, clientPack)
|
| | | else:
|
| | | ObjPool.GetPoolMgr().release(clientPack)
|
| | | return
|
| | |
|
| | | class TurnFightMgr():
|
| | |
| | |
|
| | | def __init__(self):
|
| | | self.turnFightDict = {} # {guid:TurnFight, ...}
|
| | | self.npcGUIDDict = {} # npc所属的某场战斗guid {objID:guid, ...}
|
| | | return
|
| | |
|
| | | def addTurnFight(self, mapID, funcLineID=0, playerID=0):
|
| | |
| | | elif False:
|
| | | tf = TurnFight()
|
| | | return tf
|
| | | |
| | | def getNPCTurnFight(self, objID):
|
| | | ## 获取NPC所在的回合战斗,如果该npc不属于某场回合战斗则返回None
|
| | | tf = None
|
| | | if objID in self.npcGUIDDict:
|
| | | guid = self.npcGUIDDict[objID]
|
| | | if guid in self.turnFightDict:
|
| | | tf = self.turnFightDict[guid]
|
| | | if not tf and False:
|
| | | tf = TurnFight()
|
| | | return tf
|
| | | |
| | | def setNPCGUID(self, objID, guid):
|
| | | ## 设置NPC所属回合战斗guid
|
| | | self.npcGUIDDict[objID] = guid
|
| | | GameWorld.DebugLog("设置NPC所属回合战斗guid: %s,%s" % (objID, guid))
|
| | | return
|
| | | def delNPCGUID(self, objID):
|
| | | guid = self.npcGUIDDict.pop(objID, None)
|
| | | GameWorld.DebugLog("删除NPC所属回合战斗guid: %s,%s" % (objID, guid))
|
| | | return
|
| | |
|
| | | def GetTurnFightMgr():
|
| | | tfMgr = None
|
| | |
| | | ## 当前战斗是否关卡boss
|
| | | return self.turnFight.mapID == ChConfig.Def_FBMapID_MainBoss
|
| | |
|
| | | def clear(self):
|
| | | self.turnFight.clearFight()
|
| | | return
|
| | | |
| | | def GetMainFightMgr(curPlayer):
|
| | | ## 获取主线战斗管理
|
| | | olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
|
| | |
| | | % (chapterID, levelNum, nowChapterID, fixNowValue), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def GetPlayerLineupByCache(playerID, lineupID):
|
| | | def GetPlayerLineupInfoByCache(playerID, lineupID):
|
| | | ## 获取玩家阵容信息 - 根据玩家查看缓存
|
| | | return {}
|
| | | lineupInfo = {}
|
| | | return lineupInfo
|
| | |
|
| | | def GetPlayerLineup(curPlayer, lineupID):
|
| | | ## 获取玩家阵容信息
|
| | | def GetPlayerLineupInfo(curPlayer, lineupID):
|
| | | ## 获取玩家阵容信息,可用于战斗或查看缓存,因为可能取玩家的缓存进行对战,所以统一使用json格式,前端通用
|
| | | # @param lineupID: 阵容ID
|
| | | # @return: 阵容全部信息json字典,前端通用格式
|
| | |
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | lineup = PlayerOnline.GetOnlinePlayer(curPlayer).GetLineup(lineupID)
|
| | |
|
| | | # 武将
|
| | | lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType}
|
| | | heroDict = {}
|
| | | heroCount = 0
|
| | | curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
|
| | | for index in range(curPack.GetCount()):
|
| | | heroItem = curPack.GetAt(index)
|
| | | if not heroItem or heroItem.IsEmpty():
|
| | | continue
|
| | | lineupCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroLineup)
|
| | | if not lineupCount:
|
| | | continue
|
| | | posNum = 0 # վλ
|
| | | for lpIndex in range(lineupCount):
|
| | | lineupValue = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroLineup, lpIndex)
|
| | | #阵容类型*10000+阵型类型*100+位置编号
|
| | | if lineupValue / 10000 != lineupID:
|
| | | continue
|
| | | posNum = lineupValue % 100
|
| | | break
|
| | | |
| | | if not posNum:
|
| | | continue
|
| | | |
| | | heroID = heroItem.GetItemTypeID()
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | skinIDList = heroIpyData.GetSkinIDList()
|
| | | skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin)
|
| | | if skinIndex < 0 or skinIndex >= len(skinIDList):
|
| | | continue
|
| | | skinID = skinIDList[skinIndex]
|
| | | for posNum in lineup.lineupHeroDict.keys():
|
| | | hero = lineup.GetLineupHero(posNum)
|
| | | heroID = hero.heroID
|
| | | itemIndex = hero.itemIndex
|
| | | userData = ""
|
| | | heroLV = 1
|
| | | if itemIndex >= 0 and itemIndex < curPack.GetCount():
|
| | | heroItem = curPack.GetAt(itemIndex)
|
| | | if heroItem and not heroItem.IsEmpty():
|
| | | userData = heroItem.GetUserData()
|
| | | heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
|
| | | |
| | | skillIDlist = []
|
| | | skillIDlist += hero.heroSkillIDList
|
| | | heroDict[str(posNum)] = {
|
| | | "HeroID":heroID,
|
| | | "SkinID":skinID,
|
| | | "Data":heroItem.GetUserData(),
|
| | | "SkinID":hero.skinID,
|
| | | "LV":heroLV,
|
| | | "Data":userData,
|
| | | "FightPower":hero.fightPower,
|
| | | "AttrDict":{str(k):v for k, v in hero.heroBatAttrDict.items() if v > 0},
|
| | | "SkillIDList":skillIDlist,
|
| | | }
|
| | | |
| | | heroCount += 1
|
| | | if heroCount >= ShareDefine.LineupObjMax:
|
| | | break
|
| | | |
| | | if not heroDict:
|
| | | return {}
|
| | | lineupInfo.update({"Hero":heroDict})
|
| | |
|
| | | # 主公属性
|
| | | lordAttrDict = PlayerControl.GetLordAttr(curPlayer)
|
| | | |
| | | # 其他
|
| | | |
| | | lineupInfo = {"PlayerID":playerID, "LordAttrDict":lordAttrDict, "Hero":heroDict}
|
| | | return lineupInfo
|
| | |
|
| | | def GetNPCLineup(lineupID):
|
| | | def GetNPCLineupInfo(lineupID):
|
| | | ## 获取NPC阵容信息
|
| | | # @param lineupID: 阵容ID
|
| | | # @return: 阵容全部信息json字典,前端通用格式
|
| | |
| | | npcID = getattr(ipyData, "GetPosNPCID%s" % posNum)()
|
| | | if not npcID:
|
| | | continue
|
| | | npcData = NPCCommon.GetNPCDataPy(npcID)
|
| | | if not npcData:
|
| | | continue
|
| | | 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_SuperHitRate:npcData.GetSuperHitRate(), ChConfig.AttrID_SuperHitRateDef:npcData.GetSuperHitRateDef(), |
| | | ChConfig.AttrID_StunRate:npcData.GetStunRate(), ChConfig.AttrID_StunRateDef:npcData.GetStunRateDef(), |
| | | ChConfig.AttrID_ComboRate:npcData.GetComboRate(), ChConfig.AttrID_ComboRateDef:npcData.GetComboRateDef(), |
| | | ChConfig.AttrID_ParryRate:npcData.GetParryRate(), ChConfig.AttrID_ParryRateDef:npcData.GetParryRateDef(), |
| | | 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
|
| | | }
|
| | |
|
| | | heroDict[str(posNum)] = {"NPCID":npcID}
|
| | | |
| | | lineupInfo = {"Hero":heroDict}
|
| | | lineupInfo = {"NPCLineupID":lineupID, "Hero":heroDict}
|
| | | return lineupInfo
|
| | |
|
| | | def SummonLineupObjs(batLineup, faction, num, lineupInfo, playerID=0):
|
| | |
| | | @param lineupInfo: 阵容信息
|
| | | @param playerID: 发起的玩家ID,系统场次为0
|
| | | '''
|
| | | |
| | | '''关于视野层级说明 sightLevel
|
| | | 玩家发起的战斗视野层级只能用玩家ID,才能达到只通知该玩家的效果
|
| | | 但是由于同个玩家可能同时存在多场战斗,如主线战斗 + 其他战斗,所以视野层级只能用作仅通知该玩家的作用,
|
| | | 不能用于处理NPC视野来遍历伤害对象等,因为不同战场的NPC视野层级可能相同,对于同场战斗NPC的遍历处理只能用 turnFight 管理遍历
|
| | | 鉴于视野层级仅用于通知的作用,故系统场次理论上可以只用一个视野层级,但是为了减少不必要的问题,系统场次的视野层级还是尽量区分开来
|
| | | 这里暂时用时间戳的后4位来做短时间内的理论上唯一视野层级
|
| | | '''
|
| | | GameWorld.DebugLog("SummonLineupObjs faction:%s,num:%s,lineupInfo=%s" % (faction, num, lineupInfo), playerID)
|
| | | if playerID:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | | return
|
| | | posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
|
| | | sightLevel = playerID
|
| | |
|
| | | # 开发过程中可以先开启视野层级及视野,方便检查战斗相关是否有遗漏
|
| | | if curPlayer.GetSightLevel() != sightLevel:
|
| | | PlayerControl.SetPlayerSightLevel(curPlayer, sightLevel)
|
| | | sight = ChConfig.Def_PlayerSight_Default * 5
|
| | | if curPlayer.GetSight() != sight:
|
| | | PlayerControl.SetSight(curPlayer, sight)
|
| | | else:
|
| | | gameMap = GameWorld.GetMap()
|
| | | posX, posY = gameMap.GetRebornMapX(), gameMap.GetRebornMapY() # 系统战斗默认取当前地图的复活点,需要优化
|
| | | sightLevel = 2000000000 + int(time.time()) % 10000
|
| | | |
| | | GameWorld.DebugLog("sightLevel=%s,pos=(%s,%s)" % (sightLevel, posX, posY), playerID)
|
| | | |
| | | tfGUID = batLineup.turnFight.guid
|
| | | lineupPlayerID = lineupInfo.get("PlayerID", 0) # 阵容所属玩家ID
|
| | | heroDict = lineupInfo.get("Hero", {})
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | |
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | initXP = IpyGameDataPY.GetFuncCfg("AngerXP", 1)
|
| | | baseAtkSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
|
| | | tfMgr = GetTurnFightMgr()
|
| | | space = 3
|
| | | atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 3)
|
| | | for posNumKey, heroInfo in heroDict.items():
|
| | | posNum = int(posNumKey)
|
| | |
|
| | | heroID, skinID = 0, 0
|
| | | baseAtkSkillID = 0 # 基础普攻ID
|
| | | skillIDList = []
|
| | | 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)
|
| | | npcID = FighterNPCID
|
| | | lv = heroInfo.get("LV", 1)
|
| | | fightPower = heroInfo.get("FightPower", 0)
|
| | | heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
|
| | | if not heroIpyData:
|
| | | continue
|
| | | normalSkillID = heroIpyData.GetNormalSkillID()
|
| | | angerSkillID = heroIpyData.GetAngerSkillID()
|
| | | skillIDList += [normalSkillID, angerSkillID]
|
| | | atkDistType = heroIpyData.GetAtkDistType()
|
| | | objName = heroIpyData.GetName()
|
| | | else:
|
| | | npcID = heroInfo.get("NPCID", 0)
|
| | | npcDataEx = NPCCommon.GetNPCDataEx(npcID)
|
| | | npcDataEx = NPCCommon.GetNPCDataPy(npcID)
|
| | | if not npcDataEx:
|
| | | continue
|
| | | skillIDList += npcDataEx.GetSkillIDList()
|
| | | objName = npcDataEx.GetNPCName()
|
| | | atkDistType = npcDataEx.GetAtkDistType()
|
| | | lv = npcDataEx.GetLV()
|
| | |
|
| | | if not npcID:
|
| | | continue
|
| | | |
| | | npcData = GameWorld.GetGameData().FindNPCDataByID(npcID)
|
| | | if not npcData:
|
| | | continue
|
| | | curSummon = GameWorld.GetNPCManager().AddPlayerSummonNPC()
|
| | | if not curSummon:
|
| | | continue
|
| | | objID = curSummon.GetID()
|
| | | batLineup.npcPosDict[posNum] = curSummon
|
| | | batLineup.npcObjIDDict[objID] = curSummon
|
| | | tfMgr.setNPCGUID(objID, batLineup.getGUID())
|
| | | |
| | | curSummon.SetNPCTypeID(npcID)
|
| | | curSummon.SetBornTime(tick)
|
| | | curSummon.SetAIType(0)
|
| | | curSummon.SetSightLevel(sightLevel)
|
| | | curSummon.SetIsNeedProcess(False)
|
| | | curSummon.SetCanAttack(True)
|
| | | curSummon.SetVisible(True)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_TurnFightPosInfo, num * 100 + posNum)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_LineupPlayerID, lineupPlayerID)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_HeroID, heroID)
|
| | | curSummon.SetDict(ChConfig.Def_Obj_Dict_SkinID, skinID)
|
| | | GameObj.SetFaction(curSummon, faction)
|
| | | GameObj.SetXP(curSummon, initXP, False)
|
| | | batObj = batObjMgr.addBatObj()
|
| | | if not batObj:
|
| | | break
|
| | | objID = batObj.GetID()
|
| | | batObj.SetTFGUID(tfGUID)
|
| | | batObj.SetName(objName)
|
| | | batObj.SetFaction(faction)
|
| | | batObj.SetLineupPos(posNum, num)
|
| | | batObj.SetFightPower(fightPower)
|
| | | batObj.SetLV(lv)
|
| | | if npcID:
|
| | | 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:
|
| | | baseAtkSkillID = baseAtkSkillIDList[0] if len(baseAtkSkillIDList) > 0 else 0
|
| | | atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
|
| | | elif atkDistType == ChConfig.AtkDistType_Long:
|
| | | baseAtkSkillID = baseAtkSkillIDList[1] if len(baseAtkSkillIDList) > 1 else 0
|
| | | atkBackSkillID = atkBackSkillIDList[1] if len(atkBackSkillIDList) > 1 else 0
|
| | | if atkBackSkillID:
|
| | | skillIDList.append(atkBackSkillID)
|
| | | skillManager = batObj.GetSkillManager()
|
| | | skillManager.SkillReset()
|
| | | for skillID in skillIDList:
|
| | | skillManager.LearnSkillByID(skillID)
|
| | |
|
| | | skillManager = curSummon.GetSkillManager()
|
| | | #有指定的技能,重新学习
|
| | | if skillIDList:
|
| | | skillManager.ResetSkill()
|
| | | for skillID in skillIDList:
|
| | | skillManager.LVUPSkillByID(skillID)
|
| | | if baseAtkSkillID:
|
| | | skillManager.LVUPSkillByID(baseAtkSkillID)
|
| | | |
| | | rebornX = posX - space + (faction - 1) * space * 3 + ((posNum - 1) / 3 * space * 2 * (-1 if faction == 1 else 1))
|
| | | rebornY = posY + (posNum - 1) % 3 * space
|
| | | GameWorld.DebugLog("SummonNPC ID:%s,faction:%s,num=%s,posNum=%s,baseAtkSkillID=%s,%s" % (curSummon.GetID(), faction, num, posNum, baseAtkSkillID, skillIDList))
|
| | | curSummon.Reborn(rebornX, rebornY, False)
|
| | | NPCCommon.NPCControl(curSummon).DoNPCRebornCommLogic(tick)
|
| | | 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()))
|
| | |
|
| | | return
|
| | |
|
| | |
| | | teamNum = 1
|
| | | lineupID = waveLineupList[teamNum - 1] # NPC阵容ID
|
| | |
|
| | | lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
|
| | | lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
|
| | | if not lineupMainInfo:
|
| | | GameWorld.DebugLog("没有设置主阵容!", playerID)
|
| | | return
|
| | |
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | | return
|
| | |
| | |
|
| | | wave = waveMax = 1 # 关卡boss固定只有一波
|
| | |
|
| | | lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
|
| | | lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
|
| | | if not lineupMainInfo:
|
| | | GameWorld.DebugLog("没有设置主阵容!", playerID)
|
| | | return
|
| | |
| | |
|
| | | turnFight = mainFightMgr.turnFight
|
| | | turnFight.setTurn(mapID, funcLineID, turnMax, False, {"teamNum":teamNum, "teamMax":teamMax})
|
| | | turnFight.setFactionLineup(Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo}, True)
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | |
|
| | |
| | | mainFightMgr.nextTeam = False
|
| | | turnFight.resetTurn({"teamNum":teamNum})
|
| | | # 切换小队时,玩家阵容不需要处理,保留状态
|
| | | turnFight.setFactionLineup(Def_FactionB, {1:GetNPCLineup(lineupID)})
|
| | | turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID)})
|
| | | turnFight.sortActionQueue()
|
| | | turnFight.syncInit()
|
| | |
|
| | |
| | | doMax = (PosNumMax + 2) * len(turnFight.actionSortList) # 防止死循环,做最大循环次数限制 = (最大位置数 + 主公、红颜位置)*行动阵容数
|
| | | overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
|
| | |
|
| | | 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):
|
| | |
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | batLineup.actionNum = ActionNumStart
|
| | | for curNPC in batLineup.npcPosDict.values():
|
| | | TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
|
| | | for objID in batLineup.posObjIDDict.values():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
|
| | |
|
| | | if turnFight.actionIndex >= len(turnFight.actionSortList):
|
| | | turnFight.actionIndex = 0
|
| | |
| | | faction, num = turnFight.actionSortList[turnFight.actionIndex]
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | if batLineup.actionNum > max(batLineup.npcPosDict):
|
| | | if batLineup.actionNum > max(batLineup.posObjIDDict):
|
| | | if (faction, num) not in overLineupList:
|
| | | overLineupList.append((faction, num))
|
| | |
|
| | | turnFight.actionIndex += 1
|
| | | continue
|
| | |
|
| | | if faction == Def_FactionA:
|
| | | if faction == ChConfig.Def_FactionA:
|
| | | if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
|
| | | GameWorld.DebugLog("战锤不足!")
|
| | | return
|
| | |
| | | elif batLineup.actionNum > 0:
|
| | | for posNum in range(batLineup.actionNum, PosNumMax + 1):
|
| | | batLineup.actionNum = posNum
|
| | | if posNum not in batLineup.npcPosDict:
|
| | | if posNum not in batLineup.posObjIDDict:
|
| | | continue
|
| | | curNPC = batLineup.npcPosDict[posNum]
|
| | | if not curNPC or GameObj.GetHP(curNPC) <= 0:
|
| | | continue
|
| | | objType = curNPC.GetGameObjType()
|
| | | objID = curNPC.GetID()
|
| | | turnFight.syncObjAction(turnNum, objType, objID)
|
| | | |
| | | objName = GetObjName(curNPC)
|
| | | curHP = GameObj.GetHP(curNPC)
|
| | | |
| | | GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
|
| | | if not DoAttack(curNPC, None, tick):
|
| | | GameWorld.DebugLog(" 攻击失败")
|
| | | objID = batLineup.posObjIDDict[posNum]
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not OnObjAction(turnFight, batObj):
|
| | | continue
|
| | |
|
| | | if faction == Def_FactionA:
|
| | | if faction == ChConfig.Def_FactionA:
|
| | | playerHeroAtk = True
|
| | |
|
| | | break
|
| | |
|
| | | turnFight.actionIndex += 1
|
| | | batLineup.actionNum += 1
|
| | | if batLineup.actionNum > max(batLineup.npcPosDict):
|
| | | 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))
|
| | |
| | | for faction, num in turnFight.actionSortList:
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | for curNPC in batLineup.npcPosDict.values():
|
| | | for objID in batLineup.posObjIDDict.values():
|
| | | pass
|
| | |
|
| | | if turnFight.checkOverByKilled():
|
| | |
| | | curPlayer = turnFight.curPlayer
|
| | | turnMax = turnFight.turnMax
|
| | | EntryLogic(turnFight)
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | for turnNum in range(1, turnMax + 1):
|
| | | turnFight.turnNum = turnNum
|
| | | GameWorld.DebugLog("【----- 回合制战斗轮次: %s -----】" % turnNum)
|
| | |
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | batLineup.actionNum = 1
|
| | | for curNPC in batLineup.npcPosDict.values():
|
| | | TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
|
| | | for objID in batLineup.posObjIDDict.values():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | TurnFightObjPerTurnStart(turnFight, batObj, turnNum)
|
| | |
|
| | | # 主公
|
| | | for faction, num in turnFight.actionSortList:
|
| | |
| | | batLineup = batFaction.getBatlineup(num)
|
| | | for posNum in range(batLineup.actionNum, PosNumMax + 1):
|
| | | batLineup.actionNum = posNum + 1
|
| | | if posNum not in batLineup.npcPosDict:
|
| | | if posNum not in batLineup.posObjIDDict:
|
| | | continue
|
| | | curNPC = batLineup.npcPosDict[posNum]
|
| | | if not curNPC or GameObj.GetHP(curNPC) <= 0:
|
| | | continue
|
| | | objType = curNPC.GetGameObjType()
|
| | | objID = curNPC.GetID()
|
| | | turnFight.syncObjAction(turnNum, objType, objID)
|
| | | |
| | | objName = GetObjName(curNPC)
|
| | | curHP = GameObj.GetHP(curNPC)
|
| | | |
| | | GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
|
| | | if not DoAttack(curNPC, None, tick):
|
| | | objID = batLineup.posObjIDDict[posNum]
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not OnObjAction(turnFight, batObj):
|
| | | continue
|
| | |
|
| | | break
|
| | |
| | | GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
|
| | | batFaction = turnFight.getBatFaction(faction)
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | for curNPC in batLineup.npcPosDict.values():
|
| | | for objID in batLineup.posObjIDDict.values():
|
| | | pass
|
| | |
|
| | | if turnFight.checkOverByKilled():
|
| | |
| | | #funcLineID = clientData.FuncLineID
|
| | | return
|
| | |
|
| | | def GetObjName(gameObj):
|
| | | objName = gameObj.GetName()
|
| | | faction = GameObj.GetFaction(gameObj)
|
| | | posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
|
| | | heroID = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | def GetObjName(batObj):
|
| | | faction = batObj.faction
|
| | | num = batObj.lineupNum
|
| | | posNum = batObj.posNum
|
| | | heroID = batObj.heroID
|
| | | if not heroID:
|
| | | heroID = gameObj.GetNPCID()
|
| | | return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), heroID)
|
| | | heroID = 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)
|
| | |
|
| | | def EntryLogic(turnFight):
|
| | | ## 执行进场逻辑
|
| | |
| | | turnFight.enterLogic = True
|
| | | return
|
| | |
|
| | | def TurnFightObjPerTurnStart(gameObj, tagObj, turnNum, tick):
|
| | | def TurnFightObjPerTurnStart(turnFight, batObj, turnNum):
|
| | | ## 回合制战斗实例 - 每回合开始时处理
|
| | | if not gameObj:
|
| | | 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()):
|
| | | buff = buffMgr.GetBuffByIndex(index)
|
| | | curRemainTime = buff.GetRemainTime()
|
| | | if not curRemainTime:
|
| | | # 永久buff不处理
|
| | | continue
|
| | | buffID = buff.GetBuffID()
|
| | | updRemainTime = curRemainTime - 1
|
| | | GameWorld.DebugLog(" 更新buff剩余回合数: buffID=%s,updRemainTime=%s" % (buffID, updRemainTime))
|
| | | if updRemainTime > 0:
|
| | | buff.SetRemainTime(curRemainTime - 1)
|
| | | TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
|
| | | else:
|
| | | TurnBuff.SyncBuffDel(turnFight, batObj, buffID)
|
| | | |
| | | # SetTimeline(gameObj, turnNum, 0)
|
| | | # # 重置连击、反击数
|
| | | # gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
|
| | |
| | |
|
| | | def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
|
| | | ## 回合对象添加治疗值
|
| | | if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
|
| | | # @param curObj: 获得治疗的对象
|
| | | # @param srcObj: 来自谁的治疗
|
| | | # @param addValue: 治疗值
|
| | | # @param cureHP: 实际回血量
|
| | | if not srcObj:
|
| | | return
|
| | | |
| | | curFaction = GameObj.GetFaction(curObj)
|
| | | if not srcObj or curFaction != GameObj.GetFaction(srcObj):
|
| | | # 同阵营的治疗才统计
|
| | | return
|
| | | |
| | | curID = curObj.GetID()
|
| | | srcID = srcObj.GetID()
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
|
| | | if not turnFight:
|
| | | return
|
| | | |
| | | curBatFaction = turnFight.getBatFaction(curFaction)
|
| | | for num in curBatFaction.lineupDict.keys():
|
| | | batLineup = curBatFaction.getBatlineup(num)
|
| | | updStatValue = batLineup.statCureValue(srcID, cureHP)
|
| | | if updStatValue == None:
|
| | | continue
|
| | | GameWorld.DebugLog(" 统计治疗: curTD=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s" |
| | | % (curID, srcID, skillID, addValue, cureHP, updStatValue))
|
| | | break
|
| | | |
| | | updStatValue = srcObj.StatCureValue(cureHP)
|
| | | GameWorld.DebugLog(" 统计治疗: curID=%s,srcID=%s,skillID=%s,addValue=%s,cureHP=%s,updStatValue=%s" |
| | | % (curID, srcID, skillID, addValue, cureHP, updStatValue))
|
| | | |
| | | return
|
| | |
|
| | | def AddTurnObjHurtValue(curObj, tagObj, hurtType, hurtValue, lostHP, curSkill=None):
|
| | | def AddTurnObjHurtValue(curBatObj, tagBatObj, hurtValue, lostHP, curSkill=None, isBounce=False):
|
| | | ## 回合对象添加伤害值
|
| | | if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
|
| | | return
|
| | | curID = curObj.GetID()
|
| | | tagID = tagObj.GetID()
|
| | | # @param isBounce: 是否反弹伤害
|
| | | curID = curBatObj.GetID()
|
| | | tagID = tagBatObj.GetID()
|
| | | skillID = curSkill.GetSkillID() if curSkill else 0
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
|
| | | if not turnFight:
|
| | | return
|
| | | |
| | | if curID != tagID:
|
| | | curBatFaction = turnFight.getBatFaction(GameObj.GetFaction(curObj))
|
| | | for num in curBatFaction.lineupDict.keys():
|
| | | batLineup = curBatFaction.getBatlineup(num)
|
| | | updStatValue = batLineup.statHurtValue(curID, lostHP)
|
| | | if updStatValue == None:
|
| | | continue
|
| | | GameWorld.DebugLog(" 统计伤血: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,tagHP=%s" |
| | | % (curID, tagID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
|
| | | break
|
| | | 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))
|
| | |
|
| | | tagBatFaction = turnFight.getBatFaction(GameObj.GetFaction(tagObj))
|
| | | for num in tagBatFaction.lineupDict.keys():
|
| | | batLineup = tagBatFaction.getBatlineup(num)
|
| | | updStatValue = batLineup.statDefValue(tagID, lostHP)
|
| | | if updStatValue == None:
|
| | | continue
|
| | | GameWorld.DebugLog(" 统计承伤: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s" |
| | | % (tagID, curID, skillID, hurtType, hurtValue, lostHP, updStatValue, GameObj.GetHP(tagObj)))
|
| | | break
|
| | | |
| | | if tagBatObj:
|
| | | updStatValue = tagBatObj.StatDefValue(lostHP)
|
| | | 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))
|
| | | |
| | | else:
|
| | | # 如换血类技能,自残的伤害不算输出
|
| | | GameWorld.DebugLog(" 自残: curTD=%s,tagID=%s,skillID=%s,hurtType=%s,hurtValue=%s,lostHP=%s,curHP=%s" |
| | | % (curID, tagID, skillID, hurtType, hurtValue, lostHP, GameObj.GetHP(curObj)))
|
| | | |
| | | if lostHP > 0 and curID != tagID:
|
| | | addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 4)
|
| | | AddTurnFightXP(tagObj, addXP, "skillID:%s" % skillID)
|
| | | GameWorld.DebugLog(" 自残: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,curHP=%s" |
| | | % (curID, tagID, skillID, hurtValue, lostHP, curBatObj.GetHP()))
|
| | | return
|
| | |
|
| | | def AddTurnFightXP(gameObj, addXP, reason=""):
|
| | | ## 回合战斗增加XP
|
| | | if addXP <= 0 or not addXP:
|
| | | #GameWorld.DebugLog(" 没有增加XP! curID=%s" % (gameObj.GetID()))
|
| | | def OnObjAction(turnFight, curBatObj):
|
| | | ## 战斗单位行动
|
| | | if not curBatObj:
|
| | | return
|
| | | posNum = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 10
|
| | | if posNum <= 0:
|
| | | #非主战单位不加
|
| | | |
| | | curHP = curBatObj.GetHP()
|
| | | objID = curBatObj.GetID()
|
| | | if curHP <= 0:
|
| | | return
|
| | | curXP = GameObj.GetXP(gameObj)
|
| | | updXP = curXP + addXP
|
| | | GameObj.SetXP(gameObj, updXP)
|
| | | GameWorld.DebugLog(" 更新XP: curID=%s,curXP=%s,addXP=%s,updXP=%s,reason=%s" % (gameObj.GetID(), curXP, addXP, updXP, reason))
|
| | | |
| | | turnNum = turnFight.turnNum
|
| | | objName = GetObjName(curBatObj)
|
| | | |
| | | # 是否可行动状态判断
|
| | | canAction = True
|
| | | |
| | | if not canAction:
|
| | | GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
|
| | | return
|
| | | |
| | | GameWorld.DebugLog("★回合%s %s 行动 : curHP=%s" % (turnNum, objName, curHP))
|
| | | turnFight.syncObjAction(turnNum, objID)
|
| | | |
| | | curXP = curBatObj.GetXP()
|
| | | 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):
|
| | | if curXP < xpMax:
|
| | | continue
|
| | | useCnt = -1 # xp技能优先释放
|
| | | else:
|
| | | useCnt = curBatObj.GetSkillUseCnt(skillID)
|
| | | useSkillList.append([useCnt, skillID, useSkill])
|
| | | |
| | | useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
|
| | | #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
|
| | | |
| | | for useInfo in useSkillList:
|
| | | useSkill = useInfo[-1]
|
| | | if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
|
| | | return True
|
| | | |
| | | return
|
| | |
|
| | | def DoAttack(curNPC, tagNPC, tick, turnBattleType=ChConfig.TurnBattleType_Normal, useSkill=None):
|
| | | curID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | objName = GetObjName(curNPC)
|
| | | GameWorld.DebugLog(" ● %s DoAttack: curID=%s,,turnBattleType=%s" % (objName, curID, turnBattleType))
|
| | | |
| | | atkOK = False
|
| | | tagObj = tagNPC
|
| | | curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, turnBattleType)
|
| | | |
| | | if turnBattleType == ChConfig.TurnBattleType_AtkBack:
|
| | | if not tagObj:
|
| | | return
|
| | | skillManager = curNPC.GetSkillManager()
|
| | | for index in range(0, skillManager.GetSkillCount()):
|
| | | skill = skillManager.GetSkillByIndex(index)
|
| | | #已经到尾部了
|
| | | if not skill or skill.GetSkillTypeID() == 0:
|
| | | break
|
| | | if skill.GetFuncType() == ChConfig.Def_SkillFuncType_NormalAttack:
|
| | | useSkill = skill
|
| | | break
|
| | | atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
|
| | | elif turnBattleType == ChConfig.TurnBattleType_Combo:
|
| | | if not tagObj:
|
| | | return
|
| | | atkOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
|
| | | else:
|
| | | curXP = GameObj.GetXP(curNPC)
|
| | | xpMax = IpyGameDataPY.GetFuncCfg("AngerXP", 2) |
| | | skillManager = curNPC.GetSkillManager()
|
| | | useSkillList = []
|
| | | #GameWorld.DebugLog('skillCount=%s' % skillManager.GetSkillCount(), npcID)
|
| | | for index in range(0, skillManager.GetSkillCount()):
|
| | | useSkill = skillManager.GetSkillByIndex(index)
|
| | | #已经到尾部了
|
| | | if not useSkill or useSkill.GetSkillTypeID() == 0:
|
| | | break
|
| | | if useSkill.GetFuncType() in [ChConfig.Def_SkillFuncType_NormalAttack]:
|
| | | #基础普攻不能主动释放,目前仅用于反击
|
| | | continue
|
| | | #被动技能无法使用
|
| | | if SkillCommon.isPassiveSkill(useSkill):
|
| | | continue
|
| | | #还在冷却时间内无法释放
|
| | | if SkillCommon.RefreshSkillRemainTime(useSkill, tick) != 0:
|
| | | continue
|
| | | skillTypeID = useSkill.GetSkillTypeID()
|
| | | # 常规攻击优先xp
|
| | | if SkillCommon.isAngerSkill(useSkill) and turnBattleType == ChConfig.TurnBattleType_Normal:
|
| | | if curXP < xpMax:
|
| | | continue
|
| | | useCnt = -1 # xp技能优先释放
|
| | | else:
|
| | | useCnt = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_SkillUseCnt % skillTypeID) # 该技能已使用次数
|
| | | useSkillList.append([useCnt, index, skillTypeID, useSkill])
|
| | | |
| | | useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
|
| | | #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
|
| | | |
| | | for useInfo in useSkillList:
|
| | | useSkill = useInfo[-1]
|
| | | #skillID = useSkill.GetSkillID()
|
| | | atkOK, tagObj = DoNPCUseSkill(curNPC, useSkill, tick)
|
| | | if atkOK:
|
| | | break
|
| | | |
| | | curNPC.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)
|
| | | |
| | | 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)
|
| | | # |
| | | return True
|
| | |
|
| | | def CanAtkBack(atkObj, defObj):
|
| | |
| | | % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
|
| | | return True
|
| | |
|
| | | def DoNPCUseSkill(curNPC, useSkill, tick):
|
| | | '''NPC使用技能
|
| | | @return: 是否成功, tagObj
|
| | | '''
|
| | | if not useSkill or useSkill.GetSkillTypeID() == 0:
|
| | | return False, None
|
| | | |
| | | #检查是否几率触发
|
| | | rate = useSkill.GetHappenRate()
|
| | | if rate != ChConfig.Def_MaxRateValue and not GameWorld.CanHappen(rate, ChConfig.Def_MaxRateValue):
|
| | | #GameWorld.Log('检查是否几率触发 = %s失败 = %s'%(rate, useSkill.GetSkillName()))
|
| | | return False, None
|
| | | |
| | | tagObj = None
|
| | | skillTag = SkillShell.GetSkillAffectTag(useSkill)
|
| | | skillAim = SkillShell.GetSkillFireAim(useSkill)
|
| | | |
| | | # 注: 多V多的情况友好目标仅针对本阵容、敌对目标可针对任意敌对阵容
|
| | | |
| | | #---对自己释放,或者无目标技能---
|
| | | if skillTag in ChConfig.Def_ST_CanNPCUseSkill or skillAim == ChConfig.Def_UseSkillAim_None:
|
| | | #释放自身类技能
|
| | | tagObj = curNPC
|
| | | isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
|
| | | return isOK, tagObj
|
| | | |
| | | # 召唤兽对主人释放技能
|
| | | elif skillTag == ChConfig.Def_UseSkillTag_SummonMaster:
|
| | | if not NPCCommon.IsSummonNPC(curNPC):
|
| | | GameWorld.ErrLog("该NPC非召唤兽,无法获得主人释放技能")
|
| | | return False, None
|
| | | |
| | | curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotPlayer, curNPC) |
| | | if curSummonOwner == None:
|
| | | curSummonOwner = NPCCommon.GetSummonNPCOwner(IPY_GameWorld.gotNPC, curNPC)
|
| | | |
| | | if curSummonOwner == None:
|
| | | GameWorld.ErrLog("召唤兽(%s)对主人释放技能,找不到主人" % curNPC.GetNPCID())
|
| | | return False, None
|
| | | |
| | | tagObj = curSummonOwner
|
| | | |
| | | # 友好死亡目标,一般是复活技能
|
| | | elif skillTag == ChConfig.Def_UseSkillTag_FriendDeath:
|
| | | deathList = GetFriendDeathList(curNPC)
|
| | | if not deathList:
|
| | | return False, None
|
| | | tagObj = random.choice(deathList) # 随机选一个
|
| | | |
| | | # 友好目标
|
| | | elif skillTag in ChConfig.Def_ST_CanNPCUseSkillFriend:
|
| | | friendList = GetFriendObjList(curNPC)
|
| | | if not friendList:
|
| | | return False, None
|
| | | tagObj = random.choice(friendList) # 随机选一个,可扩展其他选择规则
|
| | | |
| | | # 敌方目标
|
| | | else:
|
| | | tagObj = GetEnemyObj(curNPC)
|
| | | |
| | | if not tagObj:
|
| | | return False, None
|
| | | |
| | | GameWorld.DebugLog(" 技能释放: skillID=%s,atkID=%s,def=%s,HP:%s/%s" |
| | | % (useSkill.GetSkillID(), curNPC.GetID(), GetObjName(tagObj), GameObj.GetHP(tagObj), GameObj.GetMaxHP(tagObj)))
|
| | | isOK = SkillShell.DoLogic_UseSkill(curNPC, tagObj, useSkill, tick)
|
| | | return isOK, tagObj
|
| | | #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 GetFriendDeathList(curNPC):
|
| | | ## 获取友方死亡单位,仅针对本阵容主战单位
|
| | | objID = curNPC.GetID()
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
|
| | | if not turnFight:
|
| | | return []
|
| | | batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
|
| | | num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | deathList = []
|
| | | for posNum, tagNPC in batLineup.npcPosDict.items():
|
| | | if posNum <= 0 or not tagNPC:
|
| | | continue
|
| | | if GameObj.GetHP(tagNPC) > 0:
|
| | | continue
|
| | | deathList.append(tagNPC)
|
| | | |
| | | return deathList
|
| | |
|
| | | def GetFriendObjList(curNPC):
|
| | | ## 获取友方单位,仅针对本阵容主战单位
|
| | | objID = curNPC.GetID()
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
|
| | | if not turnFight:
|
| | | return []
|
| | | batFaction = turnFight.getBatFaction(GameObj.GetFaction(curNPC))
|
| | | num = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) / 100
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | friendList = []
|
| | | for posNum, tagNPC in batLineup.npcPosDict.items():
|
| | | if posNum <= 0 or not tagNPC:
|
| | | continue
|
| | | if GameObj.GetHP(tagNPC) <= 0:
|
| | | continue
|
| | | friendList.append(tagNPC)
|
| | | return friendList
|
| | |
|
| | | 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().getNPCTurnFight(objID)
|
| | | 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)
|
| | | |
| | | for tagNum in tagLineupNumList:
|
| | | tagLineup = tagBatFaction.getBatlineup(tagNum)
|
| | | tagPosNumList = [posNum] # 优先对位位置,再其他位置按顺序遍历
|
| | | pNumList = tagLineup.npcPosDict.keys()
|
| | | pNumList.sort()
|
| | | for pNum in pNumList:
|
| | | if pNum > 0 and pNum not in tagPosNumList:
|
| | | tagPosNumList.append(pNum)
|
| | | for pNum in tagPosNumList:
|
| | | tagNPC = tagLineup.npcPosDict.get(pNum)
|
| | | if not tagNPC:
|
| | | continue
|
| | | if GameObj.GetHP(tagNPC) <= 0:
|
| | | continue
|
| | | return tagNPC
|
| | | return
|
| | |
|
| | | def SetTurnObjKilled(gameObj, killer=None):
|
| | | if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
|
| | | #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
|
| | | return
|
| | | |
| | | def SetObjKilled(turnFight, gameObj, killer=None, useSkill=None):
|
| | | objID = gameObj.GetID()
|
| | | GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), objID))
|
| | | gameObj.SetCurAction(IPY_GameWorld.laNPCDie)
|
| | | if GameObj.GetHP(gameObj) != 0:
|
| | | GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
|
| | | gameObj.SetVisible(False)
|
| | | gameObj.SetHP(0)
|
| | | killerObjID = killer.GetID() if killer else 0
|
| | | skillID = useSkill.GetSkillID() if useSkill else 0
|
| | |
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
|
| | | if not turnFight:
|
| | | return True
|
| | | clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
|
| | | clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCTurnFightObjDead)
|
| | | clientPack.ObjID = objID
|
| | | turnFight.addBatPack(clientPack)
|
| | | |
| | | # 记录主动发起的玩家阵营击杀
|
| | | curPlayer = turnFight.curPlayer
|
| | | if killer and curPlayer and killer.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
|
| | | if objID not in turnFight.playerKillObjIDList:
|
| | | turnFight.playerKillObjIDList.append(objID)
|
| | | GameWorld.DebugLog("玩家单次击杀统计: %s" % turnFight.playerKillObjIDList)
|
| | | |
| | | clientPack.KillerObjID = killerObjID
|
| | | clientPack.SkillID = skillID
|
| | | turnFight.addBatPack(clientPack) |
| | | return True
|
| | |
|
| | | def OnTurnfightAttackSuccess(curObj, tagObj, curSkill):
|
| | | ## 回合战斗攻击成功额外处理,AttackResult之前,一般处理技能相关
|
| | | if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
|
| | | return
|
| | | if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
|
| | | return
|
| | | |
| | | objID = curObj.GetID()
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
|
| | | if not turnFight:
|
| | | return
|
| | | |
| | | skillID = curSkill.GetSkillID() if curSkill else 0
|
| | | isXP = SkillCommon.isAngerSkill(curSkill)
|
| | | if isXP:
|
| | | GameObj.SetXP(curObj, 0)
|
| | | elif curSkill:
|
| | | if SkillCommon.isTurnNormalSkill(curSkill):
|
| | | addXP = IpyGameDataPY.GetFuncCfg("AngerXP", 3)
|
| | | AddTurnFightXP(curObj, addXP, "skillID:%s" % skillID)
|
| | | |
| | | curPlayer = turnFight.curPlayer
|
| | | # 仅主动发起玩家阵容触发
|
| | | if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
|
| | | FBLogic.OnPlayerLineupAttackSuccess(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
|
| | | |
| | | return
|
| | |
|
| | | def OnTurnfightAttackResult(curObj, tagObj, curSkill):
|
| | | ## 回合战斗攻击结果额外处理,AttackResult 之后,一般处理击杀结算相关
|
| | | if curObj.GetGameObjType() != IPY_GameWorld.gotNPC:
|
| | | return
|
| | | if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
|
| | | return
|
| | | |
| | | objID = curObj.GetID()
|
| | | turnFight = GetTurnFightMgr().getNPCTurnFight(objID)
|
| | | if not turnFight:
|
| | | return
|
| | | |
| | | curPlayer = turnFight.curPlayer
|
| | | # 仅主动发起玩家阵容触发
|
| | | if curPlayer and curObj.GetDictByKey(ChConfig.Def_Obj_Dict_LineupPlayerID) == curPlayer.GetPlayerID():
|
| | | FBLogic.OnPlayerLineupAttackResult(curPlayer, curObj, tagObj, curSkill, turnFight.mapID, turnFight.funcLineID)
|
| | | |
| | | turnFight.playerKillObjIDList = []
|
| | | return
|
| | |
|
| | | def OnTurnAllOver(guid):
|
| | | ## 所有回合已经全部执行完毕
|
| | |
| | |
|
| | | if turnFight.playerID:
|
| | | # 玩家发起的,未击杀对方,算玩家输
|
| | | turnFight.winFaction = Def_FactionB
|
| | | turnFight.winFaction = ChConfig.Def_FactionB
|
| | | else:
|
| | | # 系统场次,按一定规则来,这里先随机
|
| | | turnFight.winFaction = random.choice([Def_FactionA, Def_FactionB])
|
| | | turnFight.winFaction = random.choice([ChConfig.Def_FactionA, ChConfig.Def_FactionB])
|
| | |
|
| | | DoTurnFightOver(guid)
|
| | | return
|
| | |
| | | GameWorld.DebugLog("--- 战斗结束处理 --- %s, winFaction=%s, costTime=%ss" % (guid, winFaction, turnFight.costTime))
|
| | |
|
| | | # 统计明细
|
| | | batObjMgr = BattleObj.GetBatObjMgr()
|
| | | statInfo = {}
|
| | | for faction in turnFight.factionDict.keys():
|
| | | if str(faction) not in statInfo:
|
| | |
| | | facStatInfo[str(num)] = {}
|
| | | lineupStatInfo = facStatInfo[str(num)]
|
| | | batLineup = batFaction.getBatlineup(num)
|
| | | hurtStatDict = batLineup.hurtStatDict
|
| | | defStatDict = batLineup.defStatDict
|
| | | cureStatDict = batLineup.cureStatDict
|
| | | GameWorld.DebugLog("阵容明细: faction=%s,num=%s" % (faction, num))
|
| | | for posNum, curNPC in batLineup.npcPosDict.items():
|
| | | objID = curNPC.GetID()
|
| | | npcID = curNPC.GetNPCID()
|
| | | heroID = curNPC.GetDictByKey(ChConfig.Def_Obj_Dict_HeroID)
|
| | | atkHurt = hurtStatDict.get(objID, 0)
|
| | | defHurt = defStatDict.get(objID, 0)
|
| | | cureHP = cureStatDict.get(objID, 0)
|
| | | for posNum, objID in batLineup.posObjIDDict.items():
|
| | | batObj = batObjMgr.getBatObj(objID)
|
| | | if not batObj:
|
| | | continue
|
| | | objID = batObj.GetID()
|
| | | npcID = batObj.GetNPCID()
|
| | | heroID = batObj.GetHeroID()
|
| | | atkHurt = batObj.hurtStat
|
| | | defHurt = batObj.defStat
|
| | | cureHP = batObj.cureStat
|
| | | GameWorld.DebugLog(" Pos:%s ID=%s-%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s"
|
| | | % (posNum, objID, npcID, heroID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
|
| | | % (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}
|
| | |
|
| | | awardItemList = []
|
| | | playerID = turnFight.playerID
|
| | | if playerID:
|
| | | curPlayer = turnFight.curPlayer
|
| | | isWin = (winFaction == Def_FactionA)
|
| | | isWin = (winFaction == ChConfig.Def_FactionA)
|
| | | # 主线小怪
|
| | | if turnFight.mapID == ChConfig.Def_FBMapID_Main:
|
| | | OnOver_MainLevel(curPlayer, isWin, awardItemList)
|