From cc2207557c22a88475e28f6a05a416c0fa97e527 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 25 八月 2025 18:53:15 +0800
Subject: [PATCH] 1111 删除不需要内容;
---
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py | 1363 ++++++++++++++++++++++------------------------------------
1 files changed, 527 insertions(+), 836 deletions(-)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
index f0fb744..80b81d4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -24,23 +24,25 @@
import NetPackCommon
import PlayerControl
import GameWorld
-import GameObj
import FBCommon
import IpyGameDataPY
import PlayerOnline
import NPCCommon
import ShareDefine
import PyGameData
-import IPY_GameWorld
import ItemControler
import SkillCommon
-import SkillShell
-import BaseAttack
+import BattleObj
+import TurnPassive
+import TurnSkill
+import TurnBuff
+import ObjPool
import random
import time
import json
+TimelineSet = 10000 # 单回合最大时间轴
PosNumMax = 10 # 最大站位编号
ActionNumStart = -1 # 起始行动位置编号,一般是从1开始,如果有加主公、红颜等则扣除相应位置值,如从0或-1开始
@@ -53,129 +55,57 @@
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.lingshouObjIDDict = {} # 灵兽战斗单位 {位置编号:batObjID, ...}
+ self.beautyObjIDDict = {} # 红颜战斗单位 {位置编号:batObjID, ...}
+ 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()
return
def clearLineup(self):
## 清除阵容
- if not self.npcPosDict:
- 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)
+ for objID in self.lingshouObjIDDict.values():
+ batObjMgr.delBatObj(objID)
+ for objID in self.beautyObjIDDict.values():
+ batObjMgr.delBatObj(objID)
+ self.posObjIDDict = {}
+ self.lingshouObjIDDict = {}
+ self.beautyObjIDDict = {}
self.fightPower = 0
- 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
@@ -186,15 +116,9 @@
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
-
- def resetLineups(self):
- ## 重置所有战斗阵容
- for lineup in self.lineupDict.values():
- lineup.resetLineup()
- return
def clearLineups(self):
## 清除所有战斗阵容
@@ -219,6 +143,7 @@
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 # 是否已执行进场逻辑
@@ -232,6 +157,7 @@
self.factionDict = {} # 战斗阵营 {faction:BatFaction, ...},一般是只有两个阵营,faction为1或2,每个阵营支持多个阵容
self.actionSortList = [] # 阵容行动顺序 [[faction, num], ...]
self.actionIndex = 0 # 行动顺序索引
+ self.timeline = 0 # 时间轴节点 turnNum*1000+actionIndex*100++actionNum
self.startTime = 0 # 开始时间戳,支持毫秒小数
self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
@@ -260,23 +186,16 @@
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)
- batLineup.refreshFightPower()
return
def sortActionQueue(self):
@@ -285,21 +204,38 @@
for batFaction in self.factionDict.values():
faction = batFaction.faction
for num, batLineup in batFaction.lineupDict.items():
- fightPower = batLineup.refreshFightPower()
+ isPlayer = 1 if batLineup.ownerID else 0 # 玩家阵容优先攻击
+ fightPower = batLineup.fightPower
sortValue = -(faction * 10 + num)
- sortList.append([fightPower, sortValue, faction, num])
+ sortList.append([isPlayer, fightPower, sortValue, faction, num])
sortList.sort(reverse=True) # 战力高的先手
self.actionIndex = 0
self.actionSortList = []
- for _, _, faction, num in sortList:
+ for _, _, _, faction, num in sortList:
self.actionSortList.append([faction, num])
- GameWorld.DebugLog("阵容战力排序[fp, sortV, f, n]: %s" % sortList)
+ GameWorld.DebugLog("阵容战力排序[isPlayer, fp, sortV, f, n]: %s" % sortList)
GameWorld.DebugLog("阵容行动顺序[f, n]: %s" % self.actionSortList)
return
- def getBatFaction(self, faction=Def_FactionA):
+ def getTimeline(self): return self.timeline
+ def setTimeline(self, turnNum):
+ '''回合战斗的时间轴节点 ,即第几回合开始,每个回合支持9999个行动节点
+ @param turnNum: 第x回合
+ '''
+ self.timeline = turnNum * TimelineSet + 0
+ GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
+ OnTimelineChange(self)
+ return
+ def addTimeline(self):
+ ## 每切换一个行动单位可视为一个行动节点,即代表单回合战斗中的某一个时间节点
+ self.timeline += 1
+ GameWorld.DebugLog("时间节点更新: %s" % self.timeline)
+ OnTimelineChange(self)
+ return
+
+ def getBatFaction(self, faction=ChConfig.Def_FactionA):
## 默认阵营1
batFaction = None
if faction in self.factionDict:
@@ -316,36 +252,46 @@
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.IsAlive():
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_FactionB
DoTurnFightOver(self.guid)
return self.winFaction
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.setTimeline(1)
+ self.syncInit()
+ return
+
+ def isInFight(self): return self.state != -1
def syncInit(self):
## 初始化通知
@@ -358,6 +304,8 @@
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()
@@ -370,17 +318,22 @@
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.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)
@@ -391,6 +344,7 @@
return
def syncState(self, state, msgDict={}):
+ self.state = state
msg = json.dumps(msgDict, ensure_ascii=False)
msg = msg.replace(" ", "")
clientPack = ChPyNetSendPack.tagMCTurnFightState()
@@ -404,7 +358,7 @@
self.addBatPack(clientPack)
return
- def syncObjAction(self, turnNum, objType, objID):
+ def syncObjAction(self, turnNum, objID):
clientPack = ChPyNetSendPack.tagMCTurnFightObjAction()
clientPack.Clear()
clientPack.TurnNum = turnNum
@@ -425,6 +379,8 @@
# 有玩家的统一每个包单独发送,同样也支持战报统计
if self.curPlayer:
NetPackCommon.SendFakePack(self.curPlayer, clientPack)
+ else:
+ ObjPool.GetPoolMgr().release(clientPack)
return
class TurnFightMgr():
@@ -432,7 +388,6 @@
def __init__(self):
self.turnFightDict = {} # {guid:TurnFight, ...}
- self.npcGUIDDict = {} # npc所属的某场战斗guid {objID:guid, ...}
return
def addTurnFight(self, mapID, funcLineID=0, playerID=0):
@@ -444,7 +399,7 @@
turnFight = self.getTurnFight(guid)
if not turnFight:
return
- turnFight.clearFight()
+ turnFight.exitFight()
self.turnFightDict.pop(guid, None)
return
@@ -455,27 +410,6 @@
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
@@ -506,18 +440,6 @@
## 当前战斗是否关卡boss
return self.turnFight.mapID == ChConfig.Def_FBMapID_MainBoss
- def clear(self):
- self.turnFight.clearFight()
- return
-
- def playerLogin(self, curPlayer):
- self.turnFight.curPlayer = curPlayer
- return
-
- def playerOffline(self, curPlayer):
- self.turnFight.curPlayer = None
- return
-
def GetMainFightMgr(curPlayer):
## 获取主线战斗管理
olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
@@ -533,68 +455,50 @@
% (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
-
- npcID = heroIpyData.GetSkinNPCIDList()[0]
+ 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)] = {
- "ID":heroID,
- "Data":heroItem.GetUserData(),
- "NPCID":npcID
+ "HeroID":heroID,
+ "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字典,前端通用格式
@@ -609,10 +513,26 @@
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):
@@ -622,100 +542,79 @@
@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)
- tfMgr = GetTurnFightMgr()
- space = 3
+ atkBackSkillIDList = IpyGameDataPY.GetFuncEvalCfg("ParryCfg", 2)
for posNumKey, heroInfo in heroDict.items():
posNum = int(posNumKey)
- 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("ID", 0)
- npcID = heroInfo.get("NPCID", 0)
+ 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
- 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)
- GameObj.SetFaction(curSummon, faction)
- GameObj.SetXP(curSummon, initXP, False)
-
- skillManager = curSummon.GetSkillManager()
- #有指定的技能,重新学习
- if skillIDList:
- skillManager.ResetSkill()
- for skillID in skillIDList:
- skillManager.LVUPSkillByID(skillID)
-
- 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("Reborn ID:%s, faction:%s,posNum=%s, (%s,%s), %s" % (curSummon.GetID(), faction, posNum, rebornX, rebornY, skillIDList))
- curSummon.Reborn(rebornX, rebornY, False)
- NPCCommon.NPCControl(curSummon).DoNPCRebornCommLogic(tick)
+ 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)
+ batObj.SetAtkDistType(atkDistType)
+ if npcID:
+ batObj.SetNPCID(npcID)
+ elif lineupPlayerID:
+ batObj.SetOwnerHero(lineupPlayerID, heroID, skinID)
+
+ if atkDistType == ChConfig.AtkDistType_Short:
+ atkBackSkillID = atkBackSkillIDList[0] if len(atkBackSkillIDList) > 0 else 0
+ elif atkDistType == ChConfig.AtkDistType_Long:
+ 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)
+
+ batLineup.posObjIDDict[posNum] = objID
+ GameWorld.DebugLog("AddBatObj ID:%s,%s,skill=%s" % (objID, GetObjName(batObj), skillIDList))
+ batObj.InitBatAttr({int(k):v for k, v in attrDict.items()}, initXP)
return
@@ -746,7 +645,7 @@
if reqType == 2: # 前端主动请求开始关卡小怪的视为从休息中开始
__doMainLevelWave(curPlayer, True)
elif reqType == 3:
- __doMainBossStart(curPlayer, tick)
+ __doMainBossStart(curPlayer)
elif reqType == 4:
__doMainFight(curPlayer, tick)
else:
@@ -762,7 +661,7 @@
mainFightMgr = GetMainFightMgr(curPlayer)
turnFight = mainFightMgr.turnFight
if turnFight:
- turnFight.clearFight()
+ turnFight.exitFight()
return
def __doSetFightPoint(curPlayer, fightPoint):
@@ -824,7 +723,7 @@
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
@@ -845,13 +744,13 @@
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})
+ 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)
@@ -898,7 +797,7 @@
wave = waveMax = 1 # 关卡boss固定只有一波
- lineupMainInfo = GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
+ lineupMainInfo = GetPlayerLineupInfo(curPlayer, ShareDefine.Lineup_Main)
if not lineupMainInfo:
GameWorld.DebugLog("没有设置主阵容!", playerID)
return
@@ -919,17 +818,27 @@
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})
+ 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
@@ -948,13 +857,13 @@
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()
+ turnFight.startFight()
if mainFightMgr.isLevelBoss():
# 每次处理一小队的完整战斗,相当于一次完整战报
- __processTurnFight(turnFight.guid, tick)
+ __processTurnFight(turnFight.guid)
return
else:
__doMainLevelWave(curPlayer, False)
@@ -964,21 +873,24 @@
## 关卡boss是一次性处理完的,一般不可能走到这里,这边做下防范
return
- # 以下均是处理关卡小怪分段实时战斗
-
- EntryLogic(turnFight)
-
# 小怪战斗,每次消耗1个战锤
fightPoint = max(curPlayer.GetFightPoint(), 1) # 主线战斗消耗倍值,默认1
+
+ if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ GameWorld.DebugLog("回合开始时战锤不足!")
+ return
+
+ # 以下均是处理关卡小怪分段实时战斗
+ EntryLogic(turnFight)
# 按阵营阵容执行顺序,逐个遍历
doCnt = 0
doMax = (PosNumMax + 2) * len(turnFight.actionSortList) # 防止死循环,做最大循环次数限制 = (最大位置数 + 主公、红颜位置)*行动阵容数
overLineupList = [] # 本回合已经结束行动的阵容列表 [(faction, num), ...], 所有阵容全部结束代表本回合结束
+ batObjMgr = BattleObj.GetBatObjMgr()
turnNum = turnFight.turnNum
- unXiantaoCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCnt)
- GameWorld.DebugLog("unXiantaoCnt=%s,turnNum=%s,doMax=%s,actionIndex=%s,%s" % (unXiantaoCnt, turnNum, doMax, turnFight.actionIndex, turnFight.actionSortList))
+ 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
@@ -986,35 +898,34 @@
if turnFight.turnStart < turnNum:
GameWorld.DebugLog("执行行动: turnNum=%s, 回合开始" % (turnFight.turnNum))
turnFight.syncState(FightState_Fighting)
- if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("回合开始时战锤不足!")
- return
+ #if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ # GameWorld.DebugLog("回合开始时战锤不足!")
+ # return
turnFight.turnStart = turnNum
turnFight.actionIndex = 0
+ turnFight.addTimeline() # 每回合开始算一个时间节点
for faction, num in turnFight.actionSortList:
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
batLineup.actionNum = ActionNumStart
- for curNPC in batLineup.npcPosDict.values():
- TurnFightObjPerTurnStart(curNPC, None, turnNum, tick)
+ 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.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 not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("战锤不足!")
- return
GameWorld.DebugLog("执行行动: turnNum=%s,faction=%s,num=%s,actionNum=%s" % (turnFight.turnNum, faction, num, batLineup.actionNum))
# 主公
@@ -1028,32 +939,24 @@
# 武将
elif batLineup.actionNum > 0:
for posNum in range(batLineup.actionNum, PosNumMax + 1):
+ turnFight.addTimeline() # 每个武将位算一个时间节点
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)
+ TurnFightHeroTurnStart(turnFight, batObj, turnNum)
+ if not OnObjAction(turnFight, batObj):
continue
- if faction == Def_FactionA:
- if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint, isNotify=False):
- return
+ 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))
@@ -1061,10 +964,9 @@
if turnFight.checkOverByKilled():
break
- nowUnXiantaoCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_UnXiantaoCnt)
- if unXiantaoCnt != nowUnXiantaoCnt:
- # 玩家有消耗战锤则停止,一段段执行
- GameWorld.DebugLog("玩家有消耗战锤则停止,nowUnXiantaoCnt=%s" % (nowUnXiantaoCnt))
+ if playerHeroAtk:
+ # 玩家武将有行动则停止,一段段执行
+ GameWorld.DebugLog("玩家武将有行动则停止!")
break
if turnFight.winFaction:
@@ -1074,58 +976,65 @@
if len(overLineupList) >= len(turnFight.actionSortList):
GameWorld.DebugLog("执行行动: turnNum=%s, 回合结束" % (turnFight.turnNum))
if turnFight.turnEnd < turnNum:
- if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
- GameWorld.DebugLog("回合结束时战锤不足!")
- return
+ #if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_Xiantao, fightPoint):
+ # GameWorld.DebugLog("回合结束时战锤不足!")
+ # return
turnFight.turnEnd = turnNum
+ turnFight.addTimeline() # 每回合结束算一个时间节点
for faction, num in turnFight.actionSortList:
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
- for curNPC in batLineup.npcPosDict.values():
- pass
-
+ 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)
return
-def __processTurnFight(guid, tick):
+def __processTurnFight(guid):
## 一次性处理完一个小队的战斗
turnFight = GetTurnFightMgr().getTurnFight(guid)
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)
+ turnFight.setTimeline(turnNum)
if curPlayer:
turnFight.syncState(FightState_Fighting)
# 回合开始
+ turnFight.addTimeline() # 每回合开始算一个时间节点
for faction, num in turnFight.actionSortList:
GameWorld.DebugLog("回合开始逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
batFaction = turnFight.getBatFaction(faction)
batLineup = 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)
+ TurnFightPerTurnBigStart(turnFight, batObj, turnNum)
# 主公
- for faction, num in turnFight.actionSortList:
- GameWorld.DebugLog("主公逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
- batFaction = turnFight.getBatFaction(faction)
- batLineup = batFaction.getBatlineup(num)
+ #for faction, num in turnFight.actionSortList:
+ # GameWorld.DebugLog("主公逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
+ # batFaction = turnFight.getBatFaction(faction)
+ # batLineup = batFaction.getBatlineup(num)
# 红颜
- for faction, num in turnFight.actionSortList:
- GameWorld.DebugLog("红颜逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
- batFaction = turnFight.getBatFaction(faction)
- batLineup = batFaction.getBatlineup(num)
+ #for faction, num in turnFight.actionSortList:
+ # GameWorld.DebugLog("红颜逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
+ # batFaction = turnFight.getBatFaction(faction)
+ # batLineup = batFaction.getBatlineup(num)
if turnFight.checkOverByKilled():
break
@@ -1139,21 +1048,14 @@
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.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)
+ TurnFightHeroTurnStart(turnFight, batObj, turnNum)
+ if not OnObjAction(turnFight, batObj):
continue
break
@@ -1164,13 +1066,15 @@
turnFight.actionIndex += 1
# 回合结束
+ turnFight.addTimeline() # 每回合结束算一个时间节点
for faction, num in turnFight.actionSortList:
GameWorld.DebugLog("回合结束逻辑: turnNum=%s,faction=%s, num=%s" % (turnNum, faction, num))
batFaction = turnFight.getBatFaction(faction)
batLineup = batFaction.getBatlineup(num)
- for curNPC in batLineup.npcPosDict.values():
- pass
-
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ TurnFightPerTurnBigEnd(turnFight, batObj, turnNum)
+
if turnFight.checkOverByKilled():
break
@@ -1178,30 +1082,15 @@
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(gameObj):
- objName = gameObj.GetName()
- faction = GameObj.GetFaction(gameObj)
- posInfo = gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo)
- npcID = gameObj.GetNPCID()
- return "%s%s %s[%s-%s]" % ("A" if faction == Def_FactionA else "B", posInfo, objName, gameObj.GetID(), npcID)
+def GetObjName(batObj):
+ faction = batObj.faction
+ num = batObj.lineupNum
+ posNum = batObj.posNum
+ heroID = batObj.heroID
+ if not 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):
## 执行进场逻辑
@@ -1209,452 +1098,252 @@
return
GameWorld.DebugLog("执行进场逻辑...")
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for faction, num in turnFight.actionSortList:
+ batFaction = turnFight.getBatFaction(faction)
+ batLineup = batFaction.getBatlineup(num)
+ batLineup.actionNum = ActionNumStart
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_FightStart)
+
turnFight.enterLogic = True
return
-def TurnFightObjPerTurnStart(gameObj, tagObj, turnNum, tick):
- ## 回合制战斗实例 - 每回合开始时处理
- if not gameObj:
+def OnTimelineChange(turnFight):
+ ## 每个时间节点变化时处理
+
+ nowTimeline = turnFight.getTimeline()
+
+ batObjMgr = BattleObj.GetBatObjMgr()
+ for batFaction in turnFight.factionDict.values():
+ for batLineup in batFaction.lineupDict.values():
+ for objID in batLineup.posObjIDDict.values():
+ batObj = batObjMgr.getBatObj(objID)
+ #GameWorld.DebugLog("OnTimelineChange! objID=%s" % (objID))
+ if not batObj or not batObj.IsAlive():
+ continue
+
+ batObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
+ batObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, 0)
+ batObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, 0)
+
+ curID = batObj.GetID()
+ skillManager = batObj.GetSkillManager()
+ for index in range(0, skillManager.GetSkillCount()):
+ curSkill = skillManager.GetSkillByIndex(index)
+ if not curSkill:
+ continue
+ remainTime = curSkill.GetRemainTime()
+ if not remainTime:
+ continue
+ calcTimeline = curSkill.GetCalcTime()
+ passTurn = __calcPassturn(calcTimeline, nowTimeline, True)
+ if passTurn <= 0:
+ continue
+ skillID = curSkill.GetSkillID()
+ updRemainTime = max(0, remainTime - passTurn)
+ curSkill.SetRemainTime(updRemainTime)
+ curSkill.SetCalcTime(nowTimeline)
+ GameWorld.DebugLog("更新技能剩余回合数: curID=%s,skillID=%s,updRemainTime=%s,calcTimeline=%s,passTurn=%s"
+ % (curID, skillID, updRemainTime, calcTimeline, passTurn))
+
+ buffMgr = batObj.GetBuffManager()
+ for index in range(buffMgr.GetBuffCount())[::-1]:
+ buff = buffMgr.GetBuffByIndex(index)
+ remainTime = buff.GetRemainTime()
+ if not remainTime:
+ # 永久buff不处理
+ #GameWorld.DebugLog(" 永久buff不处理! curID=%s,index=%s,skillID=%s" % (curID, index, buff.GetSkillID()))
+ continue
+ calcTimeline = buff.GetCalcTime()
+ passTurn = __calcPassturn(calcTimeline, nowTimeline, False)
+ if passTurn <= 0:
+ #GameWorld.DebugLog(" passTurn <= 0 passTurn=%s,calcTimeline=%s,nowTimeline=%s,skillID=%s" % (passTurn, calcTimeline, nowTimeline, buff.GetSkillID()))
+ continue
+
+ updRemainTime = max(0, remainTime - passTurn)
+ buffID = buff.GetBuffID()
+ skillID = buff.GetSkillID()
+ GameWorld.DebugLog("更新buff剩余回合数: curID=%s,buffID=%s,skillID=%s,updRemainTime=%s,calcTimeline=%s,passTurn=%s"
+ % (curID, buffID, skillID, updRemainTime, calcTimeline, passTurn))
+ if updRemainTime > 0:
+ buff.SetRemainTime(updRemainTime)
+ buff.SetCalcTime(nowTimeline)
+ TurnBuff.SyncBuffRefresh(turnFight, batObj, buff)
+ else:
+ TurnBuff.DoBuffDel(turnFight, batObj, buff)
+
+ return
+
+def __calcPassturn(calcTimeline, nowTimeline, equalOK):
+ ## 计算已经过了的回合数
+ # @param equalOK: 时间节点相同时是否算1回合,一般技能可以算,buff不算
+ calcTurnNum = calcTimeline / TimelineSet
+ calcTimeNode = calcTimeline % TimelineSet
+ nowTurnNum = nowTimeline / TimelineSet
+ nowTimeNode = nowTimeline % TimelineSet
+ if equalOK:
+ if nowTimeNode >= calcTimeNode:
+ return max(0, nowTurnNum - calcTurnNum)
+ return max(0, nowTurnNum - calcTurnNum - 1)
+ else:
+ if nowTimeNode > calcTimeNode:
+ return max(0, nowTurnNum - calcTurnNum)
+ return max(0, nowTurnNum - calcTurnNum - 1)
+ return 0
+
+def TurnFightPerTurnBigStart(turnFight, batObj, turnNum):
+ ## 大回合开始时
+ if not batObj:
return
-# SetTimeline(gameObj, turnNum, 0)
-# # 重置连击、反击数
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnComboNum, 0)
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkBackNum, 0)
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnParryNum, 0)
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnMissNum, 0)
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnAtkAddXPCount, 0)
-# gameObj.SetDict(ChConfig.Def_Obj_Dict_TurnXPUseState, 0)
-# gameObj.SetDict(ChConfig.Def_PlayerKey_AttrFaintCD, 0) # 击晕CD
-#
-# objType = gameObj.GetGameObjType()
-# objID = gameObj.GetID()
-# objName = GetObjName(gameObj)
-# GameWorld.DebugLog("ObjPerTurnStart: 回合%s, %s objType-ID-HP(%s-%s-%s)" % (turnNum, objName, objType, objID, GameObj.GetHP(gameObj)))
-#
-# # 每回合开始减技能CD
-# skillManager = gameObj.GetSkillManager()
-# for i in range(skillManager.GetSkillCount()):
-# skill = skillManager.GetSkillByIndex(i)
-# remainTime = skill.GetRemainTime()
-# if not remainTime:
-# continue
-# skillID = skill.GetSkillID()
-# updRemainTime = max(0, remainTime - ChConfig.Def_PerTurnTick)
-# skill.SetRemainTime(updRemainTime)
-# GameWorld.DebugLog(" skillID=%s,remainTime=%s,updRemainTime=%s" % (skillID, remainTime, updRemainTime))
-#
-# # 刷新定时处理的buff效果
-# SkillShell.ProcessPersistBuff(gameObj, tick)
-#
-# PassiveBuffEffMng.OnPassiveSkillTrigger(gameObj, tagObj, None, ChConfig.TriggerType_TurnNum, tick)
-#
-# __logGameObjAttr(gameObj)
+ if batObj.GetHP() <= 0:
+ return
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnStart)
+ return
+
+def TurnFightPerTurnBigEnd(turnFight, batObj, turnNum):
+ ## 大回合结束时
+ if not batObj:
+ return
+
+ if batObj.GetHP() <= 0:
+ return
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_BigTurnEnd)
+ return
+
+def TurnFightHeroTurnStart(turnFight, batObj, turnNum):
+ ## 武将回合开始时
+ if not batObj:
+ return
+
+ if batObj.GetHP() <= 0:
+ return
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, batObj, ChConfig.TriggerWay_HeroTurnStart)
return
def AddTurnObjCureHP(curObj, srcObj, addValue, cureHP, skillID=0):
## 回合对象添加治疗值
- 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, skillID=0, isBounce=False):
## 回合对象添加伤害值
- if not curObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
+ # @param isBounce: 是否反弹伤害
+ if hurtValue <= 0:
return
- curID = curObj.GetID()
- tagID = tagObj.GetID()
- skillID = curSkill.GetSkillID() if curSkill else 0
- turnFight = GetTurnFightMgr().getNPCTurnFight(curID)
- if not turnFight:
- return
-
+ curID = curBatObj.GetID()
+ tagID = tagBatObj.GetID()
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(hurtValue)
+ GameWorld.DebugLog(" 统计承伤: curID=%s,tagID=%s,skillID=%s,hurtValue=%s,lostHP=%s,updStatValue=%s,curHP=%s,isBounce=%s"
+ % (tagID, curID, skillID, hurtValue, lostHP, updStatValue, tagBatObj.GetHP(), isBounce))
+
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 and curID != tagID:
- AddTurnFightXP(tagObj, __GetAddXP_Defender(tagObj, lostHP), "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 __GetAddXP_Attack(attack, curSkill):
- ## 攻击方增加的XP值根据主动普攻技能获得
- if not curSkill:
- return 0
- if not SkillCommon.isNormalAtkSkill(curSkill):
- return 0
- return IpyGameDataPY.GetFuncCfg("AngerXP", 3)
-
-def __GetAddXP_Defender(defender, lostHP):
- ## 掉血方增加的XP值根据掉血百分比获得
- if lostHP <= 0:
- return 0
- return IpyGameDataPY.GetFuncCfg("AngerXP", 4)
-
-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))
- 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)
+ turnNum = turnFight.turnNum
+ objName = GetObjName(curBatObj)
- if turnBattleType == ChConfig.TurnBattleType_AtkBack:
- if not tagObj:
- return
- atkOK = BaseAttack.Attack(curNPC, tagObj, None, 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 SkillCommon.isPassiveSkill(useSkill):
+ # 是否可行动状态判断
+ canAction = curBatObj.CanAction()
+ if not canAction:
+ GameWorld.DebugLog("★回合%s %s 当前状态不可行动!" % (turnNum, objName))
+ return
+
+ 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)
+
+ TurnPassive.OnTriggerPassiveEffect(turnFight, curBatObj, ChConfig.TriggerWay_HeroActionStart)
+
+ 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() not in [ChConfig.Def_SkillFuncType_TurnNormaSkill, ChConfig.Def_SkillFuncType_AngerSkill]:
+ #只能主动释放普攻或怒技
+ continue
+ #被动技能无法使用
+ if SkillCommon.isPassiveSkill(useSkill):
+ continue
+ #还在冷却时间内无法释放
+ if useSkill.GetRemainTime():
+ continue
+ skillID = useSkill.GetSkillID()
+ # 常规攻击优先xp
+ if SkillCommon.isAngerSkill(useSkill):
+ if curXP < xpMax:
continue
- #还在冷却时间内无法释放
- if SkillCommon.RefreshSkillRemainTime(useSkill, tick) != 0:
+ if curBatObj.IsInState(ChConfig.BatObjState_Sneer):
+ GameWorld.DebugLog("嘲讽状态下,无法主动释放怒技!") # 可被动释放怒技,如怒技追击
continue
- skillTypeID = useSkill.GetSkillTypeID()
- # 常规攻击优先xp
- if SkillCommon.isXPSkill(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)
+ useCnt = -1 # xp技能优先释放
+ else:
+ useCnt = curBatObj.GetSkillUseCnt(skillID)
+ useSkillList.append([useCnt, skillID, useSkill])
- for useInfo in useSkillList:
- useSkill = useInfo[-1]
- skillID = useSkill.GetSkillID()
- atkOK, tagObj = DoNPCUseSkill(curNPC, useSkill, tick)
- if atkOK:
- AddTurnFightXP(curNPC, __GetAddXP_Attack(curNPC, useSkill), "skillID:%s" % skillID)
- break
-
- if not atkOK:
- tagObj = GetEnemyObj(curNPC)
- if tagObj:
- GameWorld.DebugLog(' 无技能可攻击,直接使用普攻! tagID=%s(%s)' % (tagObj.GetID(), GetObjName(tagObj)), npcID)
- atkOK = BaseAttack.Attack(curNPC, tagObj, None, tick)
-
- curNPC.SetDict(ChConfig.Def_Obj_Dict_TurnBattleType, 0) # 无论攻击成功与否都重置战斗类型
+ useSkillList.sort() # 按使用次数优先升序排,使用次数低的优先判断使用
+ #GameWorld.DebugLog(' 技能使用顺序 = useSkillList%s' % str(useSkillList), npcID)
- 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)
+ for useInfo in useSkillList:
+ useSkill = useInfo[-1]
+ if TurnSkill.OnUseSkill(turnFight, curBatObj, useSkill):
+ break
+ TurnPassive.OnTriggerPassiveEffect(turnFight, curBatObj, ChConfig.TriggerWay_HeroActionEnd)
return True
-def CanAtkBack(atkObj, defObj):
- ## 可否反击
- posNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo) % 100
- if posNum <= 0:
- GameWorld.DebugLog(" 被非主战单位攻击时无法触发反击: atkID=%s,posNum=%s" % (atkObj.GetID(), posNum))
- return False
- defAtkBackRate = GameObj.GetAtkBackRate(defObj) # 防方反击率
- atkBackNum = defObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnAtkBackNum) # 已反击次数
- if atkBackNum > 10:
- # 内置最高反击数防范
- return False
- if atkBackNum > 0:
- validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 4)
- vaildPer = validPerList[atkBackNum - 1] if len(validPerList) >= atkBackNum else 0
- defAtkBackRate = int(defAtkBackRate * vaildPer / 100.0)
-
- atkAtkBackDefRate = GameObj.GetAtkBackDefRate(atkObj) # 攻方抵抗反击率
- atkBackRate = max(0, defAtkBackRate - atkAtkBackDefRate)
- if atkBackRate <= 0 or not GameWorld.CanHappen(atkBackRate):
- GameWorld.DebugLog(" 无法反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)"
- % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate))
- return False
- GameWorld.DebugLog(" 可以反击: defID=%s,atkBackNum=%s,atkBackRate=%s=(defAtkBackRate=%s - atkAtkBackDefRate=%s)"
- % (defObj.GetID(), atkBackNum, atkBackRate, defAtkBackRate, atkAtkBackDefRate))
- return True
-
-def CanCombo(atkObj, defObj):
- ## 可否连击
+def SetObjKilled(turnFight, gameObj, killer=None, useSkill=None):
+ objID = gameObj.GetID()
+ killerObjID = killer.GetID() if killer else 0
+ skillID = useSkill.GetSkillID() if useSkill else 0
+ GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s,killerObjID=%s,skillID=%s" % (GetObjName(gameObj), objID, killerObjID, skillID))
+ gameObj.SetDead()
- atkComboRate = GameObj.GetComboRate(atkObj) # 攻方连击率
- comboNum = atkObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnComboNum) # 已连击次数
- if comboNum > 10:
- # 内置最高连击数防范
- return False
- if comboNum > 0:
- validPerList = IpyGameDataPY.GetFuncEvalCfg("TurnFight", 3)
- vaildPer = validPerList[comboNum - 1] if len(validPerList) >= comboNum else 0
- atkComboRate = int(atkComboRate * vaildPer / 100.0)
-
- defComboReduce = GameObj.GetComboDefRate(defObj) # 防方抵抗连击率
- comboRate = max(0, atkComboRate - defComboReduce)
- if comboRate <= 0 or not GameWorld.CanHappen(comboRate):
- GameWorld.DebugLog(" 无法连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)"
- % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
- return False
- GameWorld.DebugLog(" 可以连击: atkID=%s,comboNum=%s,comboRate=%s=(atkComboRate=%s - defComboReduce=%s)"
- % (atkObj.GetID(), comboNum, comboRate, atkComboRate, defComboReduce))
- return True
-
-def 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 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 SetKilled(gameObj, killer=None):
- if not gameObj.GetDictByKey(ChConfig.Def_Obj_Dict_TurnFightPosInfo):
- #GameWorld.DebugLog("非回合战斗主体被击杀: curID=%s" % gameObj.GetID())
- return
-
- GameWorld.DebugLog(" %s 回合战斗主体被击杀: curID=%s" % (GetObjName(gameObj), gameObj.GetID()))
- GameObj.SetHP(gameObj, 0) # 回合制死亡仅设置为0,实例暂时不回收
- gameObj.SetVisible(False)
-
- turnFight = GetTurnFightMgr().getNPCTurnFight(gameObj.GetID())
- if turnFight:
- clientPack = ChPyNetSendPack.tagMCTurnFightObjDead()
- clientPack.ObjID = gameObj.GetID()
- turnFight.addBatPack(clientPack)
-
+ clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagMCTurnFightObjDead)
+ clientPack.ObjID = objID
+ clientPack.KillerObjID = killerObjID
+ clientPack.SkillID = skillID
+ turnFight.addBatPack(clientPack)
return True
def OnTurnAllOver(guid):
@@ -1669,10 +1358,10 @@
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
@@ -1686,9 +1375,10 @@
turnFight.costTime = time.time() - turnFight.startTime
winFaction = turnFight.winFaction
- GameWorld.DebugLog("--- 战斗结束处理 --- %s, winFaction=%s, costTime=%ss" % (guid, winFaction, turnFight.costTime))
+ GameWorld.DebugLog("--- 战斗结束处理 ---, winFaction=%s, costTime=%ss, %s" % (winFaction, turnFight.costTime, guid))
# 统计明细
+ batObjMgr = BattleObj.GetBatObjMgr()
statInfo = {}
for faction in turnFight.factionDict.keys():
if str(faction) not in statInfo:
@@ -1700,25 +1390,26 @@
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()
- atkHurt = hurtStatDict.get(objID, 0)
- defHurt = defStatDict.get(objID, 0)
- cureHP = cureStatDict.get(objID, 0)
- GameWorld.DebugLog(" Pos:%s ID=%s-%s,,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s"
- % (posNum, objID, npcID, GameObj.GetHP(curNPC), GameObj.GetMaxHP(curNPC), atkHurt, defHurt, cureHP))
- lineupStatInfo[str(posNum)] = {"ObjID":objID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
+ 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,npcID=%s,heroID=%s,HP=%s/%s, 输出=%s,承伤=%s,治疗=%s"
+ % (posNum, objID, npcID, heroID, batObj.GetHP(), batObj.GetMaxHP(), atkHurt, defHurt, cureHP))
+ lineupStatInfo[str(posNum)] = {"ObjID":objID, "HeroID":heroID, "NPCID":npcID, "AtkHurt":atkHurt, "DefHurt":defHurt, "CureHP":cureHP}
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)
--
Gitblit v1.8.0