From 0c96af08f55d05ab40eae9f940467dd8eafae44c Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期二, 16 九月 2025 14:07:53 +0800 Subject: [PATCH] 129 【战斗】战斗系统-服务端(增加属性ID技能增伤65、技能减伤66;曹轶技能;被动触发增加属性支持;) --- ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py | 172 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 135 insertions(+), 37 deletions(-) diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py index 0c96bc7..2f18a62 100644 --- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py +++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py @@ -16,6 +16,7 @@ #"""Version = 2025-07-02 17:30""" #------------------------------------------------------------------------------- +import BattleObj import TurnAttack import PyGameData import ShareDefine @@ -30,7 +31,7 @@ import time class LineupHero(): - ## 阵容战斗武将,注意:同一个武将在不同阵容中可能属性不一样 + ## 阵容武将,注意:同一个武将在不同阵容中可能属性不一样 def __init__(self): self.Clear() @@ -39,10 +40,12 @@ def Clear(self): self.itemIndex = 0 self.heroID = 0 + self.skinID = 0 self.posNum = 0 self.heroBatAttrDict = {} # 武将的最终战斗属性字典, {attrID:value, ...} self.heroSkillIDList = [] # 武将拥有的技能ID列表 [skillID, ...] self.fightPower = 0 # 武将最终战力 + self.skillFightPower = 0 # 技能战力 return class Lineup(): @@ -54,6 +57,7 @@ self.olPlayer = None self.shapeType = 0 self.heroItemDict = {} # 阵容武将背包索引信息 {itemIndex:posNum, ...} + self.lineupChange = False # 是否已变更阵容标记,在刷新属性后重置标记 self.__refreshState = 0 # 刷属性标记, 0-不需要刷新了,1-需要刷新 self.__freeLineupHeroObjs = [] # 释放的空闲对象[LineupHero, ...] @@ -61,16 +65,20 @@ self.fightPower = 0 # 阵容总战力 return - def UpdLineup(self, heroItemDict, shapeType=0, refreshForce=False): + def UpdLineup(self, heroItemDict, shapeType=0, refreshForce=False, isReload=False): '''变更阵容时更新 @param heroItemDict: 武将背包索引信息 {itemIndex:posNum, ...} @param shapeType: 阵型 @param refreshForce: 是否强制刷属性 ''' + if not isReload: # 非重读阵容的视为变更 + self.lineupChange = True self.shapeType = shapeType self.heroItemDict = heroItemDict GameWorld.DebugLog("更新阵容: lineupID=%s,%s" % (self.lineupID, heroItemDict), self.playerID) self.RefreshLineupAttr(refreshForce) + if not isReload and self.olPlayer.curPlayer: + PlayerHero.Sync_Lineup(self.olPlayer.curPlayer, self.lineupID) return def FreeLineupHero(self): @@ -96,11 +104,14 @@ return lineupHero def GetLineupHeroByID(self, heroID): + lineupHero = None for posNum in self.lineupHeroDict.keys(): - lineup = self.GetLineupHero(posNum) - if lineup.heroID == heroID: - return lineup - return + lineupHero = self.GetLineupHero(posNum) + if lineupHero.heroID == heroID: + return lineupHero + if False: + lineupHero = LineupHero() + return lineupHero def GetLineupInfo(self): ## 获取阵容信息,即要用到该阵容了,如战斗或者保存缓存信息等 @@ -122,6 +133,7 @@ if not self.__refreshState: return False doRefreshLineupAttr(self.olPlayer.curPlayer, self.olPlayer, self) + self.lineupChange = False self.__refreshState = 0 return True @@ -144,10 +156,12 @@ # 主线战斗 self.mainFight = TurnAttack.MainFight(playerID) + + self._lastBatBufferInfo = [] # 最后一场战斗临时回放 ["guid", "buffer"] return def OnClear(self): - self.mainFight.clear() + self.mainFight.turnFight.exitFight() return def SetPlayer(self, curPlayer): @@ -234,6 +248,11 @@ GameWorld.DebugLog("武将物品养成更新索引: %s, 影响阵容:%s" % (itemIndexList, effLineupIDList), self.playerID) return effLineupIDList + + def GetLastBatBuffer(self): return self._lastBatBufferInfo + def SetLastBatBuffer(self, guid, batBuffer): + self._lastBatBufferInfo = [guid, batBuffer] + return class OnlineMgr(): ## 准在线玩家管理 @@ -380,8 +399,9 @@ # 获取其他绑定该阵容的功能,如红颜、灵兽等 shapeType = lineShapeTypeDict.get(lineupID, 0) - lineup.UpdLineup(heroItemDict, shapeType) + lineup.UpdLineup(heroItemDict, shapeType, isReload=True) + PlayerHero.Sync_Lineup(curPlayer) return def doCalcAllAttr(curPlayer): @@ -446,11 +466,20 @@ star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar) breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV) awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV) + skinIndex = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroSkin) + skinID = 0 + skinIDList = heroIpyData.GetSkinIDList() + if skinIndex < 0 or skinIndex >= len(skinIDList): + skinID = skinIDList[skinIndex] + elif skinIDList: + skinID = skinIDList[0] + + starMax = PlayerHero.GetHeroStarMax(heroItem) InitAddPer += qualityIpyData.GetInitAddPer() - LVAddPer += qualityIpyData.GetLVAddPer() * heroLV + LVAddPer += qualityIpyData.GetLVAddPer() * max(0, heroLV - 1) BreakLVAddPer += qualityIpyData.GetBreakLVAddPer() * breakLV - StarAddPer += qualityIpyData.GetStarAddPer() * star + StarAddPer += qualityIpyData.GetStarAddPer() * min(star, starMax) lineupHero = lineup.GetLineupHero(posNum) #if False: @@ -458,6 +487,7 @@ lineupHero.itemIndex = itemIndex lineupHero.posNum = posNum lineupHero.heroID = heroID + lineupHero.skinID = skinID lineupHero.heroBatAttrDict = {} lineupHero.heroSkillIDList = [] lineupHero.fightPower = 0 @@ -476,26 +506,11 @@ selfAttrDict[int(k)] = v heroSelfAttrInfo[heroID] = selfAttrDict - # 星级天赋 - starTalentAttrDict = {} - idCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID) - lvCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV) - for aIndex in range(min(idCount, lvCount)): - talentID = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, aIndex) - talentLV = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDLV, aIndex) - stIpyData = IpyGameDataPY.GetIpyGameData("HeroTalent", talentID) - if not stIpyData: - continue - attrID = stIpyData.GetAttrID() - attrValue = stIpyData.GetAttrValue() * talentLV - starTalentAttrDict[attrID] = starTalentAttrDict.get(attrID, 0) + attrValue - heroStarTalentInfo[heroID] = starTalentAttrDict - # 突破潜能 breakAttrDict = {} - awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroBreak", heroID) - if awakeIpyDataList: - for breakIpyData in awakeIpyDataList: + breakIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroBreak", heroID) + if breakIpyDataList: + for breakIpyData in breakIpyDataList: if breakIpyData.GetBreakLV() > breakLV: break attrIDList = breakIpyData.GetAttrIDList() @@ -510,12 +525,15 @@ heroBreakAttrInfo[heroID] = breakAttrDict # 觉醒天赋 + maxUnlockSlot = IpyGameDataPY.GetFuncCfg("HeroStarTalent", 1) # 常规天赋槽个数 awakeTalentAttrDict = {} - awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID) + awakeIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("HeroAwake", heroID) if awakeIpyDataList: for awakeIpyData in awakeIpyDataList: if awakeIpyData.GetAwakeLV() > awakeLV: break + unlockTalentSlot = awakeIpyData.GetUnlockTalentSlot() + maxUnlockSlot = max(maxUnlockSlot, unlockTalentSlot) attrIDList = awakeIpyData.GetAttrIDList() attrValueList = awakeIpyData.GetAttrValueList() for aIndex in range(min(len(attrIDList), len(attrValueList))): @@ -526,6 +544,21 @@ if skillID: lineupHero.heroSkillIDList.append(skillID) heroAwakeTalentInfo[heroID] = awakeTalentAttrDict + + # 星级天赋 + starTalentAttrDict = {} + idCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentID) + lvCount = heroItem.GetUserAttrCount(ShareDefine.Def_IudetHeroTalentIDLV) + for aIndex in range(min(idCount, lvCount, maxUnlockSlot)): # 重生导致已觉醒槽位失效时属性也无效 + talentID = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentID, aIndex) + talentLV = heroItem.GetUserAttrByIndex(ShareDefine.Def_IudetHeroTalentIDLV, aIndex) + stIpyData = IpyGameDataPY.GetIpyGameData("HeroTalent", talentID) + if not stIpyData: + continue + attrID = stIpyData.GetAttrID() + attrValue = stIpyData.GetAttrValue() * talentLV + starTalentAttrDict[attrID] = starTalentAttrDict.get(attrID, 0) + attrValue + heroStarTalentInfo[heroID] = starTalentAttrDict # 羁绊统计 for fetterID in heroIpyData.GetFetterIDList(): @@ -593,6 +626,7 @@ baseAttrFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 1) otherAttrFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 2) fightPowerFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 3) + skillFPFormula = IpyGameDataPY.GetFuncCfg("HeroAttrFormula", 4) lvAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_LV) equipAttrDict = olPlayer.GetCalcAttr(ChConfig.Def_CalcAttr_MainEquip) @@ -611,6 +645,12 @@ GameWorld.DebugLog(" 主公等级属性=%s" % lvAttrDict, playerID) GameWorld.DebugLog(" 主公装备属性=%s" % equipAttrDict, playerID) GameWorld.DebugLog(" 主公图鉴属性=%s" % bookAttrDict, playerID) + + PlayerLV = curPlayer.GetLV() + OfficialLV = curPlayer.GetOfficialRank() + GameWorld.DebugLog(" PlayerLV=%s,OfficialLV=%s" % (PlayerLV, OfficialLV), playerID) + + fpRatioIpyData = IpyGameDataPY.GetIpyGameData("FightPowerRatio", OfficialLV) lineupFightPower = 0 # 阵容总战力 InitAddPer, LVAddPer, BreakLVAddPer, StarAddPer = InitAddPer / 10000.0, LVAddPer / 10000.0, BreakLVAddPer / 10000.0, StarAddPer / 10000.0 @@ -644,8 +684,8 @@ inheritPer = 1 # 继承比例,默认100% if attrID in ChConfig.AttrInheritPerDict: attrInheritPerID = ChConfig.AttrInheritPerDict[attrID] # 继承ID - inheritPer = selfAttrDict.get(attrInheritPerID, 100) # 继承比例从武将自身属性中取 - inheritPer /= 100.0 + inheritPer = selfAttrDict.get(attrInheritPerID, 10000) # 继承比例从武将自身属性中取 + inheritPer /= 10000.0 lineupHaloValue, lineupHaloPer = lineupHaloAttrInfo.get(attrID, 0), 0 fetterValue, fetterPer = fetterAttrDict.get(attrID, 0), 0 @@ -674,23 +714,51 @@ else: attrValue = FormulaControl.Eval("otherAttrFormula", otherAttrFormula, attrParamDict) #GameWorld.DebugLog(" attrID=%s,attrValue=%s,attrParamDict=%s" % (attrID, attrValue, attrParamDict)) - lineupHero.heroBatAttrDict[attrID] = attrValue attrIpyData = IpyGameDataPY.GetIpyGameData("PlayerAttr", attrID) attrName = attrIpyData.GetParameter() if attrIpyData else "%s" % attrID + attrRatioName = "%sRatio" % attrName + ratioValue = 0 + if attrValue and hasattr(fpRatioIpyData, "Get%s" % attrRatioName): + ratioValue = getattr(fpRatioIpyData, "Get%s" % attrRatioName)() fightPowerParamDict[attrName] = attrValue + fightPowerParamDict[attrRatioName] = ratioValue if attrValue: + lineupHero.heroBatAttrDict[attrID] = attrValue logAttrDict["%s-%s" % (attrID, attrName)] = attrValue - + # 计算战力 fightPower = FormulaControl.Eval("fightPowerFormula", fightPowerFormula, fightPowerParamDict) - skillFightPower = 0 + + GameWorld.DebugLog(" heroID=%s,fightPower=%s,heroSkillIDList=%s" % (heroID, fightPower, lineupHero.heroSkillIDList), playerID) + skillTypeIDDict = {} for skillID in lineupHero.heroSkillIDList: - skillData = GameWorld.GetGameData().GetSkillBySkillID(skillID) + skillData = IpyGameDataPY.GetIpyGameData("Skill", skillID) if not skillData: continue - skillFightPower += skillData.GetFightPower() + skillTypeID = skillData.GetSkillTypeID() + if skillTypeID not in skillTypeIDDict: + skillTypeIDDict[skillTypeID] = skillData + else: + befSkillData = skillTypeIDDict[skillTypeID] + befSkillID = befSkillData.GetSkillID() + if befSkillID >= skillID: + continue + skillTypeIDDict[skillTypeID] = skillData + + skillFightPower = 0 + lineupHero.heroSkillIDList = [] + for skillData in skillTypeIDDict.values(): + skillID = skillData.GetSkillID() + lineupHero.heroSkillIDList.append(skillID) + paramDict = {"SkillPower":skillData.GetFightPower(), "PlayerLV":PlayerLV, "OfficialLV":OfficialLV} + sFightPower = FormulaControl.Eval("skillFPFormula", skillFPFormula, paramDict) + skillFightPower += sFightPower + GameWorld.DebugLog(" skillFightPower=%s,heroSkillIDList=%s" % (skillFightPower, lineupHero.heroSkillIDList), playerID) + + # 最终战力 fightPowerTotal = fightPower + skillFightPower + lineupHero.skillFightPower = skillFightPower lineupHero.fightPower = fightPowerTotal lineupFightPower += fightPowerTotal @@ -700,10 +768,40 @@ lineup.fightPower = lineupFightPower GameWorld.DebugLog(" 阵容最终战力: lineupID=%s,lineupFightPower=%s" % (lineupID, lineupFightPower), playerID) - # 更新排行榜 + # 非主线阵容不处理以下内容 if lineupID != ShareDefine.Lineup_Main: return PlayerControl.SetFightPower(curPlayer, lineupFightPower) + mainFightMgr = TurnAttack.GetMainFightMgr(curPlayer) + mainTurnFight = mainFightMgr.turnFight + # 主线战斗如果有在战斗中,实时更新 + if mainTurnFight and mainTurnFight.isInFight(): + # 如果是阵容变化的,重新开始战斗 + if lineup.lineupChange: + GameWorld.DebugLog("主阵容变化,重新开始战斗", playerID) + if mainTurnFight.mapID == ChConfig.Def_FBMapID_Main: + TurnAttack.__doMainLevelWave(curPlayer, True) + + # 否则只重新设置战斗属性 + else: + GameWorld.DebugLog("主阵容卡牌属性变更,更新战斗武将属性", playerID) + # lineup 为卡牌的阵容,仅有阵容属性相关,没有战斗对象 + # batLineup 为卡牌阵容体现到具体战斗的战斗阵容,有具体的战斗对象 + faction, num = ChConfig.Def_FactionA, 1 # 主线战斗玩家自己默认阵营A的第1个战斗阵容 + batLineup = mainTurnFight.getBatFaction(faction).getBatlineup(num) + batObjMgr = BattleObj.GetBatObjMgr() + for posNum, objID in batLineup.posObjIDDict.items(): + batObj = batObjMgr.getBatObj(objID) + if not batObj: + continue + lineupHero = lineup.GetLineupHero(posNum) + if lineupHero.heroBatAttrDict: + batObj.UpdInitBatAttr(lineupHero.heroBatAttrDict, lineupHero.heroSkillIDList) + else: + GameWorld.DebugLog("主阵容没有在战斗中,不需要处理", playerID) + + # 更新排行榜 + return -- Gitblit v1.8.0