local LevelPlayerManager = { PlayersArmyTable = {}, -- 起始的阵容信息列表,存的不是Entity,是data,是玩家在战斗前布阵的主将列表,顺序可能会打乱。{ [PlayerIDInRoom] = {playerInfo = {playerID, name ,campID,fighterType,elo,acid ,guildID} ,army = { heroArmyData ,heroArmyData,heroArmyData}} ,...} PlayersEntityTable = {}, -- 记录当前自己使用的实体列表,元素是Entity,不一定跟玩家布阵的主将列表一致,因为有的关卡会强制改变主将列表(比如玩家没有吕布,硬塞给玩家一个吕布)。[1][1]永远是当前上阵的Hero PvpPlayerCount = 0 ,-- 记录pvp玩法一共多少个玩家,判断是否全部在线用 SyncPlayerIDList = {}, -- 记录同步玩法创建playerArmy的顺序,用于创建entity的时候一致【一定注意:这个值是不一致的,因为收到TCP协议的时间不统一,使用时万分小心 。】 MyPlayerIDInRoom = -1, -- 我在房间中的id ,从initfuben拿到 MainEntityCampID = -1, -- 我在房间中的阵营id OnLinePlayerList = {} , -- 在线玩家的集合 {playerID ,isOnline, playerID ,isOnline, playerID ,isOnline, playerID ,isOnline} QuitRoomPlayerList = {}, -- 主动退出或者被服务器剔除房间的玩家列表 -- 同步玩法才会有数据 PlayerIDList = {}, --玩家ID列表,用列表形式保存,以防止字典可能造成的不一致。这个列表是没有按照ID从小到大排序的(因为不需要) waitingPlayerBuffInfos = {}, --战斗中途由服务器发过来的buff添加请求的buff信息 ReserveArmyDic = {} -- key:playerID ,value = { heroLineUpInfos2, heroLineUpInfos3} } local private = { IsOriginalArmy = true, -- 是否是起始阵容(被关卡元素修改过) 【只给自己主将使用】;同步玩法一定是true Player2HeroID2ArmyPosDic = {}, --在 CreatArmy时设置, armyPos指的是左中右路军这种(可能以后会改成前中后,但不影响代码功能){ [PlayerIDInRoom] = { } } DevelopEffectInfoDic = nil, -- 统计的玩家被动突破数据 { [PlayerIDInRoom] = {effec,effec,effec } , ...} PlayerBuffInfosDic = {}, --key是PlayerID,value是proto的BuffInfo结构体的数组 } local EventSystem = require('Event/EventSystem') local LuaConst = LuaConst local DEFAULT_FOUNDRY_POINT = 201 --默认情况下(没有锻铸的情况下),BuffIDs也需要生效的锻铸点ID,策划说一定是201 --初始和退出的时候调用 function LevelPlayerManager.ClearAllData() LogicUpdateManager.OnlinePlayerCount = 0 LevelPlayerManager.PlayersArmyTable = {} LevelPlayerManager.PlayersEntityTable = {} LevelPlayerManager.SyncPlayerIDList = {} LevelPlayerManager.OnLinePlayerList = {} LevelPlayerManager.QuitRoomPlayerList = {} LevelPlayerManager.PlayerIDList = {} LevelPlayerManager.buffIdList = nil LevelPlayerManager.waitingPlayerBuffInfos = {} LevelPlayerManager.ReserveArmyDic = {} LevelPlayerManager.PvpPlayerCount = 0 private.IsOriginalArmy = true private.Player2HeroID2ArmyPosDic = {} private.DevelopEffectInfoDic = nil private.PlayerBuffInfosDic = {} end function LevelPlayerManager.OnInitLevel() --这个会先于LevelFunction:InitLevel LevelPlayerManager.canSwitchHeroByCommand = true end function LevelPlayerManager.IsOriginalArmy() return private.IsOriginalArmy end function LevelPlayerManager.GetSwitchArmyData() return private.switchArmData end --[[ 获取PlayerArmy --]] function LevelPlayerManager.GetPlayerArmyByPlayerIDInRoom(playerID) local armyTable = LevelPlayerManager.PlayersArmyTable[playerID] return armyTable and armyTable.army or nil end --[[ 获取playerInfo --]] function LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if LevelPlayerManager.PlayersArmyTable[playerID] then return LevelPlayerManager.PlayersArmyTable[playerID].playerInfo end end --传入队长名字,获取这个队伍所有玩家的acid list --已经QuitRoom了的玩家的acid不会包含在内 function LevelPlayerManager.GetTeamPlayerAcidListByLeaderName(teamLeaderName) local acidList = {} local playerInfo for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe 数据查找对顺序不敏感 playerInfo = v.playerInfo if not playerInfo.isQuitted then if playerInfo.teamLeaderName == teamLeaderName then local exist = false for i,acid in ipairs(acidList) do if acid == playerInfo.acid then exist = true break end end if not exist then table.insert(acidList, playerInfo.acid) end end end end return acidList end --返回acid玩家的最新的playerInfo(一个玩家可能进出多次关卡,产生多个playerInfo,这个方法会返回最新的playerInfo) function LevelPlayerManager.GetPlayerInfoByAcid(acid) local playerInfo for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe 只会有唯一1个acid匹配、playerID值最大的项,所以可以用pairs if v.playerInfo.acid == acid then if playerInfo == nil or v.playerInfo.playerID > playerInfo.playerID then playerInfo = v.playerInfo end end end return playerInfo end --name是playerInfo里的name,是玩家的名字 function LevelPlayerManager.GetPlayerInfoByName(name) local playerInfo for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe 只会有唯一1个acid匹配,且在线(LevelPlayerManager.IsOnline)的项,所以可以用pairs if v.playerInfo.name == name then playerInfo = v.playerInfo if LevelPlayerManager.IsOnline(playerInfo.playerID) then --如果找到的这个玩家在线,就不用继续找了,直接提前break。否则还需要继续找,因为一个用户(name一致)可能进出多次同一个Level,会被分配多个playerID,对应也有多个playerInfo break end end end return playerInfo end function LevelPlayerManager.GetCampIDByPlayerIDInRoom(playerID) local campID = -1 local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if playerInfo then campID = playerInfo.campID end return campID end function LevelPlayerManager.GetTeamIDByPlayerIDInRoom(playerID) local teamId = -1 local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if playerInfo then teamId = playerInfo.teamId end return teamId end --传入的teamId是否是组队的队伍ID。 teamId有时候值可能是playerID,代表没有队伍 function LevelPlayerManager.IsTeamId(teamId) return type(teamId) == "string" end function LevelPlayerManager.IsMainPlayerTeamLeader() local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(LevelPlayerManager.MyPlayerIDInRoom) if playerInfo then return playerInfo.teamLeaderName == playerInfo.name or playerInfo.teamLeaderName == "" or playerInfo.teamLeaderName == nil else logging.error(LTAG.ERROR, "HYW : IsMainPlayerTeamLeader 查询时间过早!主玩家playerInfo为空!") return false end end function LevelPlayerManager.IsMainPlayerFirstOnlinePlayer() for i,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do if LevelPlayerManager.IsOnline(playerID) then return playerID == LevelPlayerManager.MyPlayerIDInRoom end end return false end function LevelPlayerManager.IsWarmUpRobot(entity) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(entity:GetPlayerID()) if playerInfo then return playerInfo.isWarmUpRobot end end function LevelPlayerManager.GetPlayerIDListOfTeam(teamId) if LevelPlayerManager.IsTeamId(teamId) then local result = {} for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do if v.playerInfo.teamId == teamId then table.insert(result, v.playerInfo.playerID) end end return result else --这种情况代表teamId是playerID,这个人没有组队 return {teamId} end end --获取属于teamID指定队伍的,活着的,且激活了的单位列表 function LevelPlayerManager.GetAliveAndActiveEntitiesOfTeam(teamId) local result = {} local entitiesOfPlayer = nil for playerID,v in pairs(LevelPlayerManager.PlayersArmyTable) do if v.playerInfo.teamId == teamId then entitiesOfPlayer = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitiesOfPlayer and entitiesOfPlayer[1] and entitiesOfPlayer[1]:IsAlive() and entitiesOfPlayer[1]:IsActive() then table.insert(result, entitiesOfPlayer[1]) --else --世界Boss里是正常现象,因为不同playerID的teamID可能是相同的。比如一个有队伍的玩家,进出两次,在第二次进入时playerID已经变了,但是teamID还没变。在entity被active之前,entitiesOfPlayer都为nil end end end return result end --可能返回nil function LevelPlayerManager.GetTeamLeaderByTeamId(teamId) for playerID,v in pairs(LevelPlayerManager.PlayersArmyTable) do if v.playerInfo.teamId == teamId and v.playerInfo.teamLeaderName == v.playerInfo.name then local entitiesOfPlayer = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitiesOfPlayer then return entitiesOfPlayer[1] end break end end end --[[ 获取playerID指定的玩家的所有Hero的Entity,不包含副将。可能返回nil --]] function LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) return LevelPlayerManager.PlayersEntityTable[playerID] end --[[ 获取储存了所有玩家的Entities的Dic,key是playerID,value是entity数组。entity数组不包含副将 ]]-- function LevelPlayerManager.GetHeroEntities() return LevelPlayerManager.PlayersEntityTable end function LevelPlayerManager.GetHeroEntitiesOfBornItemID(bornItemID) local list = {} for i,entity in ipairs(LogicUpdateManager.EntityList_Sync) do if entity._logicInitData.OriginBornItemID == bornItemID then table.insert(list, entity) end end return list end function LevelPlayerManager.GetPlayerActiveEntity(playerID) local entities = LevelPlayerManager.PlayersEntityTable[playerID] if entities then return entities[1] end end -- 获取名字 function LevelPlayerManager.GetPlayerName(playerID) local playArmyInfo = LevelPlayerManager.PlayersArmyTable[playerID] if playArmyInfo then return playArmyInfo.playerInfo.name else logging.warn(LTAG.WARN, "GWS : 没有找到玩家的playerArmy信息 ,playerID =" , playerID) return "" end end function LevelPlayerManager.IsSameTeam(entityA, entityB) return entityA.teamID == entityB.teamID end function LevelPlayerManager.IsSameGuild(entityA, entityB) local guildID1 = entityA._logicInitData.GuildID local guildID2 = entityB._logicInitData.GuildID return guildID1 == guildID2 and guildID1 ~= 0 and guildID1 ~= nil and guildID1 ~= "" end -- 获取玩家的某个战斗设置 function LevelPlayerManager.GetPlayerSetting(playerID ,settingEnum) if playerID > 0 then local value = nil if LevelPlayerManager.PlayersArmyTable[playerID] then value = LevelPlayerManager.PlayersArmyTable[playerID].playerInfo.setting[settingEnum] else logging.error(LTAG.ERROR, "HYW : 找不到armyTable @LevelPlayerManager.GetPlayerSetting") end if value == nil then --必须限定只等于nil。 等于false代表是设置成了false value = LuaConst.EDefaultPlayerSetting[settingEnum] end return value else logging.error(LTAG.ERROR, "HYW : 获取PlayerSetting时没有传playerID参数!!! @LevelPlayerManager.GetPlayerSetting") end end -- 设置某个玩家的设置 function LevelPlayerManager.SetPlayerSetting(playerID ,settingEnum ,value) LevelPlayerManager.PlayersArmyTable[playerID].playerInfo.setting[settingEnum] = value end function LevelPlayerManager.SetCanSwitchHeroByCommand(value) LevelPlayerManager.canSwitchHeroByCommand = value end --[[ 设置主将,主城在线(非sync玩法) ,非sync都设置了,非主城的会被重新设置一遍 ]]-- function LevelPlayerManager.SetTownHeroTable(basicHeroInfo) local playerSet = {} for i,set in ipairs(basicHeroInfo.settingInfo) do playerSet[set.settingId] = set.state end local pos, dir = LevelPlayerManager.GetMoveFromSceneInfo(basicHeroInfo.SceneInfo) LevelPlayerManager.MainEntityCampID = LuaConst.STANDALONE_PLAYER_CAMP LevelPlayerManager.MyPlayerIDInRoom = LuaConst.STANDALONE_PLAYER_PlayID -- 优化S2CRoleEnterSceneResp相关包装数据结构 LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID] = { army = { basicHeroInfo } , playerInfo = { name = basicHeroInfo.Name, setting = playerSet, Pos = pos, Dir = dir, officialPosition = basicHeroInfo.officialTitle, --势力信息,字段与BattleRoomRoleInfo命名保持一致 guildID = basicHeroInfo.guildShow.guildId, guildEmblemFrame = basicHeroInfo.guildShow.emblemFrame, guildEmblemContent = basicHeroInfo.guildShow.emblemContent, guildName = basicHeroInfo.guildShow.guildName, guildJob = basicHeroInfo.guildShow.jobTitle, guildIdentity = basicHeroInfo.guildShow.identity, serId = basicHeroInfo.serverShowId, mergeServerId = basicHeroInfo.MergeServerId, cartQuality = basicHeroInfo.cartQuality, countryId = basicHeroInfo.countryInfo.countryId, countryJobId = basicHeroInfo.countryInfo.countryJobId, basicBuff = basicHeroInfo.basicBuff, teamWarName = basicHeroInfo.teamWarName, }, townExtraHeroInfo = basicHeroInfo.basicExtraHero.heroInfo, } end function LevelPlayerManager.SetMyTownPlayerInfo(key, value) LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID].playerInfo[key] = value end function LevelPlayerManager.SetLevelBuffIdList(buffIdList) LevelPlayerManager.buffIdList = buffIdList end --buffInfo包含buffId、duration function LevelPlayerManager.SetPlayerBuffInfoList(playerID, playerbuffInfoList) private.PlayerBuffInfosDic[playerID] = playerbuffInfoList end function LevelPlayerManager.GetPlayerBuffInfoList(playerID) return private.PlayerBuffInfosDic[playerID] end --添加战斗中途由服务器发过来的buff添加请求的buff信息 --buffInfo包含buffId、duration function LevelPlayerManager.EnqueuePlayerBuff(playerBuffInfo) LevelPlayerManager.waitingPlayerBuffInfos[#LevelPlayerManager.waitingPlayerBuffInfos + 1] = playerBuffInfo end --buffInfo包含buffId、duration function LevelPlayerManager.DequeuePlayerBuff() if #LevelPlayerManager.waitingPlayerBuffInfos > 0 then return table.remove(LevelPlayerManager.waitingPlayerBuffInfos, 1) end end function LevelPlayerManager.HasWaitingPlayerBuffInfo() return #LevelPlayerManager.waitingPlayerBuffInfos > 0 end --把队长设为playerID为1的人 function LevelPlayerManager.SetTeamLeaderNameToPlayer1() local playerInfo local teamLeaderName for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do playerInfo = v.playerInfo if playerInfo.playerID == 1 then teamLeaderName = playerInfo.name break end end if teamLeaderName then for k,v in pairs(LevelPlayerManager.PlayersArmyTable) do --pairs safe 数据设置对顺序不敏感 v.playerInfo.teamLeaderName = teamLeaderName end end end --[[ 设置主将,在线关卡(非sync玩法),从roleEnterScene来 ]]-- --HeroLineUpInfos 是服务器发过来的数据,最多3个,只有非联机玩法才会走这 function LevelPlayerManager.SetNotSyncArmyTable(playerID , HeroLineUpInfos ,playerInfo, isFairLevel, stratagemDevelopEffects, robotEnemyRecommendGS, levelType) --logging.error(LTAG.ERROR, "HYW : #HeroLineUpInfos : ", #HeroLineUpInfos) LevelPlayerManager.MainEntityCampID = LuaConst.STANDALONE_PLAYER_CAMP LevelPlayerManager.MyPlayerIDInRoom = LuaConst.STANDALONE_PLAYER_PlayID local army = isFairLevel and private.CreateArmyFair(playerID,HeroLineUpInfos) or private.CreatArmy(playerID, HeroLineUpInfos, robotEnemyRecommendGS,levelType) LevelPlayerManager.PlayersArmyTable[playerID] = { playerInfo = playerInfo, army = army } private.CollectDevelopEffects(playerID) local stratagemSkill, stratagemBuffs = private.CollectStratagemSkill(stratagemDevelopEffects) playerInfo.stratagemBuffIDs = stratagemBuffs playerInfo.stratagemSkill = stratagemSkill end --设置预备军(即以后会替换现在用的 HeroLineUpInfos的数据) function LevelPlayerManager.SetPlayerReserveArmyInfo(playerID, heroLineUpInfos, heroLineUpInfos2, heroLineUpInfos3, extraInfo) --协议结构是 base.HeroFightInfo LevelPlayerManager.ReserveArmyDic[playerID] = {heroLineUpInfos1 = heroLineUpInfos, heroLineUpInfos2 = heroLineUpInfos2, heroLineUpInfos3 = heroLineUpInfos3, extraInfo = extraInfo} end function LevelPlayerManager.GetPlayerReserveArmyInfo(playerID) return LevelPlayerManager.ReserveArmyDic[playerID] end --使用预备军替换当前的战斗数据(在这个方法后,一般会调用一下 LevelFunction:CreatePlayers 即 LevelPlayerManager.SetPlayerEntityTable) function LevelPlayerManager.UseReserveArmy(playerID,useIndex) local reserveArmys = LevelPlayerManager.ReserveArmyDic[playerID] local heroLineUpInfos = reserveArmys.heroLineUpInfos1 local robotEnemyRecommendGS if useIndex == 2 then heroLineUpInfos = reserveArmys.heroLineUpInfos2 robotEnemyRecommendGS = reserveArmys.extraInfo and reserveArmys.extraInfo.recommendGS2 elseif useIndex == 3 then heroLineUpInfos = reserveArmys.heroLineUpInfos3 robotEnemyRecommendGS = reserveArmys.extraInfo and reserveArmys.extraInfo.recommendGS3 end if heroLineUpInfos == nil then logging.error(LTAG.ERROR, "[gws]: 使用预备军信息时,发现根本没数据。playerID = ", playerID , " index =",useIndex) return end local newArmy = LevelManager.IsFairLevel() and private.CreateArmyFair(playerID,heroLineUpInfos) or private.CreatArmy(playerID, heroLineUpInfos, robotEnemyRecommendGS) LevelPlayerManager.PlayersArmyTable[playerID].army = newArmy private.CollectDevelopEffects(playerID) end --[[ sync玩法 设置玩家army信息 ;所有玩家的所有出场主将的信息 , ;isFairLevel 是否是公平玩法 --]] function LevelPlayerManager.SetSyncAllPlayersArmyTable(battleRoomRoleInfoList,isFairLevel) LevelPlayerManager.BeforeStorePlayerInfo() for _,roleInfo in ipairs(battleRoomRoleInfoList) do -- roleInfo 结构是协议中的common.BattleRoomRoleInfo LevelPlayerManager.SetSyncPlayerArmyTable(roleInfo,isFairLevel) end end function LevelPlayerManager.SetSyncPlayerArmyTable(battleRoomRoleInfo,isFairLevel) local playerID = battleRoomRoleInfo.playerID --logging.error(LTAG.ERROR, "统计 initFuben 中的 playerID = ", playerID, "|campID = ", battleRoomRoleInfo.campID) if playerID == LevelPlayerManager.MyPlayerIDInRoom then LevelPlayerManager.MainEntityCampID = battleRoomRoleInfo.campID end local playerInfo = private.CreatePlayerInfoByBattleRoomRoleInfo(battleRoomRoleInfo) local heroLineUpInfos = isFairLevel and battleRoomRoleInfo.battleInfo.infoForFair or battleRoomRoleInfo.battleInfo.infoForUnFair -- 目前协议common.RoleBattleInfo中的公平不是repeated -- 储存每个玩家的多个主将信息 local army = isFairLevel and private.CreateArmyFair(playerID,heroLineUpInfos) or private.CreatArmy(playerID,heroLineUpInfos) LevelPlayerManager.PlayersArmyTable[playerID] = {playerInfo = playerInfo ,army = army} private.CollectDevelopEffects(playerID) -- 设置private.DevelopEffectInfoDic 信息 local insertPos = 1 for i, pID in ipairs(LevelPlayerManager.SyncPlayerIDList) do if playerID < pID then insertPos = i break end insertPos = i + 1 end table.insert(LevelPlayerManager.SyncPlayerIDList, insertPos, playerID) end function private.CreatePlayerInfoByBattleRoomRoleInfo(battleRoomRoleInfo) -- 这里只统计客户端目前用到的信息 ,如果需要可以加 local playerSet = {} for i,set in ipairs(battleRoomRoleInfo.settingInfo) do playerSet[set.settingId] = set.state end local stratagemSkill, stratagemBuffs = private.CollectStratagemSkill(battleRoomRoleInfo.battleInfo.stratagemDevelopEffects) local pos, dir = LevelPlayerManager.GetMoveFromSceneInfo(battleRoomRoleInfo.initPos) -- logging.error(LTAG.ERROR, "HYW : CampID : ", battleRoomRoleInfo.campID) -- logging.error(LTAG.ERROR, "HYW : TeamID : ", battleRoomRoleInfo.TeamID) -- logging.error(LTAG.ERROR, "HYW : TeamLeaderName : ", battleRoomRoleInfo.TeamLeaderName) local playerInfo = { playerID = battleRoomRoleInfo.playerID, name = battleRoomRoleInfo.Name, icon = battleRoomRoleInfo.icon,--主城头像 frameId = battleRoomRoleInfo.frameId, -- 玩家头像框ID portraitId = battleRoomRoleInfo.portraitId, -- 玩家头像ID。 campID = battleRoomRoleInfo.campID, fighterType = battleRoomRoleInfo.fighterType, elo = battleRoomRoleInfo.elo, acid = battleRoomRoleInfo.acid, wbRewardLeft = battleRoomRoleInfo.wbRewardLeft, wbEnterCount = battleRoomRoleInfo.wbEnterCount, advancedTreasureMapCount = battleRoomRoleInfo.advancedTreasureMapCount, wbId = battleRoomRoleInfo.wbId, teamLevel = battleRoomRoleInfo.teamLevel, teamId = battleRoomRoleInfo.TeamID, --如果有队伍,则这个值是一个很长的字符串。否则是空字符串。当没有队伍的时候,最终playerInfo.teamId会被设为playerID(number)。 teamLeaderName = battleRoomRoleInfo.TeamLeaderName, --注意:这个值目前只有少数玩法(目前仅世界boss和军团战)服务器才会传。 像组队副本,即便有组队,这个值也为空字符串 guildID = battleRoomRoleInfo.GuildID, guildName = battleRoomRoleInfo.GuildName,--如果有帮会,则这个值是一个很长的字符串,字符串前面是大区、小区信息,后面是一个随机的字符串。否则是空字符串。 officialPosition = battleRoomRoleInfo.officialTitle, setting = playerSet, Pos = pos, Dir = dir, serId = battleRoomRoleInfo.serId, guildJob = battleRoomRoleInfo.guildJob, guildIdentity = battleRoomRoleInfo.guildIdentity, guildEmblemContent = battleRoomRoleInfo.guildEmblemContent, guildEmblemFrame = battleRoomRoleInfo.guildEmblemFrame, realSerId = battleRoomRoleInfo.realSerId, intermediateStr = battleRoomRoleInfo.intermediateStr, assisAimAcid = battleRoomRoleInfo.assisAimAcid, isActived = false, --在LevelPlayerManager.OnPlayerActived时被设为true isQuitted = false, --在LevelPlayerManager.RecordPlayerQuitRoom时被设为true rivalPlayerList = battleRoomRoleInfo.RivalPlayerInfo, -- 仇敌列表 { ACID , IsSwornRival } -- 这个数据是不会改变的,如果战斗中有变化,则修改战斗的缓存 openRivalShoutingContent = battleRoomRoleInfo.OpenRivalShouting, -- 开启仇杀喊话 openCommonShoutingContent = battleRoomRoleInfo.OpenCommonShouting, -- 开启普杀喊话 rivalShoutingContent = battleRoomRoleInfo.RivalShoutingContent, -- 仇杀喊话 commonShoutingContent = battleRoomRoleInfo.CommonShoutingContent, -- 普杀喊话 stratagemBuffIDs = stratagemBuffs, -- 计略养成后的buff stratagemSkill = stratagemSkill, -- 计略养成后的主动技能 isWarmUpRobot = battleRoomRoleInfo.isWarmUpRobot, --是否是暖心局机器人 countryId = battleRoomRoleInfo.countryInfo.countryId,--国家(跟服务器约定死了,永远等于阵营 魏=1,蜀=2,吴=3,群=4 LuaConst.EHeroKingdomType) countryJobId = battleRoomRoleInfo.countryInfo.countryJobId, damageBefore = battleRoomRoleInfo.damageBefore, --玩家之前在房间里造成的伤害,某些玩法需要进出之后依然继承伤害 isFirstTeamDigTreasure = battleRoomRoleInfo.isFirstTeamDigTreasure, -- 组队挖宝:是否是第一次玩。(作用:控制是否自动战斗) siegeCityCanBuild = battleRoomRoleInfo.siegeCityCanBuild, --城池战是否有建造权限 roleGsSum = battleRoomRoleInfo.RoleGsSum, --玩家的总战力(包含虚战力) isGuideRobot = battleRoomRoleInfo.isGuideRobot, -- 当此玩家是机器人时,他是否是引导机器人 } if playerInfo.teamId == nil or playerInfo.teamId == "" then --如果teamId为空,则让teamId等于playerID,方便统一处理敌对关系之类的逻辑 playerInfo.teamId = playerInfo.playerID playerInfo.teamLeaderName = playerInfo.name elseif battleRoomRoleInfo.TeamID == "1" then --这种情况是世界boss引导关加的我方机器人的teamID,需要设置为跟主玩家一样的teamId,即1 playerInfo.teamId = 1 end LevelPlayerManager.SetPlayerBuffInfoList(playerInfo.playerID, battleRoomRoleInfo.battleInfo.playerBuffs) return playerInfo end --[[ 通过HeroLineUpInfos创建某人的army --]] function private.CreatArmy(playerID, heroLineUpInfos, robotEnemyRecommendGS, levelType)-- robotEnemyRecommendGS 给机器人敌人用 local army = {} if heroLineUpInfos then for i = 1, #heroLineUpInfos do local heroLineUpInfo = heroLineUpInfos[i] local heroArmyData = {} heroArmyData.HeroID = heroLineUpInfo.heroId --是CharacterID --logging.error(LTAG.ERROR, "HYW : HeroID : ", heroArmyData.HeroID) heroArmyData.AdjutantID = heroLineUpInfo.ViceHeroId heroArmyData.mainHeroLevel = heroLineUpInfo.mainHeroLevel if IsServerDataNotNil(heroLineUpInfo.mainHeroDevelopEffectsIds) then heroArmyData.mainHeroDevelopEffectsIds = {} for i, v in ipairs(heroLineUpInfo.mainHeroDevelopEffectsIds) do heroArmyData.mainHeroDevelopEffectsIds[i] = v end end if IsServerDataNotNil(heroLineUpInfo.viceHeroDevelopEffectsIds) then heroArmyData.viceHeroDevelopEffectsIds = {} for i, v in ipairs(heroLineUpInfo.viceHeroDevelopEffectsIds) do heroArmyData.viceHeroDevelopEffectsIds[i] = v end end heroArmyData.mainHeroBreakNums = heroLineUpInfo.mainHeroBreakNums heroArmyData.viceHeroBreakNums = heroLineUpInfo.viceHeroBreakNums --heroArmyData.campID = LuaConst.STANDALONE_PLAYER_CAMP heroArmyData.mainHeroMusouSkillId = heroLineUpInfo.mainHeroMusouSkillId heroArmyData.viceHeroMusouSkillId = heroLineUpInfo.viceHeroMusouSkillId heroArmyData.heroGs = heroLineUpInfo.heroGs or 0 heroArmyData.mainHeroWeaponLevels = heroLineUpInfo.mainHeroWeaponLevels heroArmyData.viceHeroWeaponLevels = heroLineUpInfo.viceHeroWeaponLevels heroArmyData.isMagicWeaponActive = heroLineUpInfo.isMagicWeaponActive heroArmyData.isViceMagicWeaponActive = heroLineUpInfo.isViceMagicWeaponActive heroArmyData.horseID = heroLineUpInfo.mainHeroHorseId heroArmyData.horseAppearanceId = heroLineUpInfo.horseAppearanceId heroArmyData.heroAppearanceId = heroLineUpInfo.heroAppearanceId heroArmyData.viceHeroAppearanceId = heroLineUpInfo.viceHeroAppearanceId heroArmyData.weaponAppearanceId = heroLineUpInfo.weaponAppearanceId heroArmyData.viceWeaponAppearanceId = heroLineUpInfo.viceWeaponAppearanceId heroArmyData.petInfo = {petId = heroLineUpInfo.petInfo.petId, stage = heroLineUpInfo.petInfo.stage, petName = heroLineUpInfo.petInfo.petName, petSkill = heroLineUpInfo.petInfo.petSkill, isLineUp = heroLineUpInfo.petInfo.isLineUp, runeSkillLevelSum = heroLineUpInfo.petInfo.runeSkillLevelSum, aptitudeSum = heroLineUpInfo.petInfo.aptitudeSum } heroArmyData.lightEffectIds = {} if heroLineUpInfo.mainLightEffectIds then for j,lightEffect in ipairs(heroLineUpInfo.mainLightEffectIds) do table.insert(heroArmyData.lightEffectIds, lightEffect) end end if IsServerDataNotNil(heroLineUpInfo.foundryLineInfo) then heroArmyData.foundryLineInfo = {} for i, v in ipairs(heroLineUpInfo.foundryLineInfo) do heroArmyData.foundryLineInfo[i] = v end end --logging.error(LTAG.ERROR, "HYW : pos : ", heroLineUpInfo.pos) --logging.error(LTAG.ERROR, "HYW : #heroLineUpInfo.mainHeroDevelopEffectsIds : ", heroLineUpInfo.mainHeroDevelopEffectsIds and #heroLineUpInfo.mainHeroDevelopEffectsIds or 0) --logging.error(LTAG.ERROR, "HYW : #heroLineUpInfo.viceHeroDevelopEffectsIds : ", heroLineUpInfo.viceHeroDevelopEffectsIds and #heroLineUpInfo.viceHeroDevelopEffectsIds or 0) heroArmyData.Attr = {} local pos = heroLineUpInfo.pos or 0 -- 左中右 军 LevelPlayerManager.SetPlayerArmyPosInfo(playerID ,heroArmyData.HeroID,pos) LevelPlayerManager.SetPlayerArmyPosInfo(playerID ,heroArmyData.AdjutantID,pos + 1) for j = 2, #heroLineUpInfo.attr.attrs do table.insert(heroArmyData.Attr, heroLineUpInfo.attr.attrs[j]) end --收集处理额外英雄信息,比如随从的。 --放在 heroArmyData.extraHeroInfo 里,元素类型是 base.HeroFightInfo 这个proto结构 heroArmyData.extraHeroInfo = IsServerDataNotNil(heroLineUpInfo.extraHeroInfo) and heroLineUpInfo.extraHeroInfo.heroInfo or nil heroArmyData.mainHeroAwaken = heroLineUpInfo.mainHeroAwaken heroArmyData.viceHeroAwaken = heroLineUpInfo.viceHeroAwaken if IsServerDataNotNil(heroLineUpInfo.weaponSoulInfo) then heroArmyData.weaponSoulInfo = {isActive = heroLineUpInfo.weaponSoulInfo.isActive, skillSceneInfo = {}} if heroLineUpInfo.weaponSoulInfo.skillSceneInfo then for _, skillInfo in ipairs(heroLineUpInfo.weaponSoulInfo.skillSceneInfo) do table.insert(heroArmyData.weaponSoulInfo.skillSceneInfo,{skillId = skillInfo.skillId, level = skillInfo.level}) end end end if IsServerDataNotNil(heroLineUpInfo.mainDyeCurPartList) then heroArmyData.mainDyeCurPartList = {} for _, val in ipairs(heroLineUpInfo.mainDyeCurPartList) do table.insert(heroArmyData.mainDyeCurPartList,val) end end if IsServerDataNotNil(heroLineUpInfo.viceDyeCurPartList) then heroArmyData.viceDyeCurPartList = {} for _, val in ipairs(heroLineUpInfo.viceDyeCurPartList) do table.insert(heroArmyData.viceDyeCurPartList,val) end end table.insert(army,heroArmyData) end end if robotEnemyRecommendGS then -- 通过推荐战力设置敌人的属性 private.ResetServerAttrByRecommendGS(army, heroLineUpInfos, robotEnemyRecommendGS) else if GameAppInfo.IsGameStreamerPackage() and levelType ~= LuaConst.LevelType.RogueLike then -- 主播pc包的特殊处理 local FormulaCalculator = require"Battle/Logic/Missile/FormulaCalculator" local recommandGs = 0 local useHeroCount = 0 local attrDic = {} for j, info in ipairs(heroLineUpInfos) do recommandGs = recommandGs + info.heroGs useHeroCount = useHeroCount + 1 if info.ViceHeroId > 0 then useHeroCount = useHeroCount + 1 end end for j, info in ipairs(heroLineUpInfos) do attrDic[j] = {} local mainAttrDic = FormulaCalculator.CalculateGameStreamerPlayerAttribute(recommandGs,useHeroCount, DataSheetManager.HeroNum:GetDataByID(info.heroId).TypeID) -- 主将属性 local viceAttrDic if info.ViceHeroId > 0 then viceAttrDic = FormulaCalculator.CalculateGameStreamerPlayerAttribute(recommandGs,useHeroCount, DataSheetManager.HeroNum:GetDataByID(info.ViceHeroId).TypeID) -- 副将属性 end for attr, val in pairs(mainAttrDic) do if viceAttrDic then army[j].Attr[LuaConst.AttrTypeId[attr]] = FP.tonumberV1(val + viceAttrDic[attr]) else army[j].Attr[LuaConst.AttrTypeId[attr]] = FP.tonumberV1(val) end end end end end return army end function private.ResetServerAttrByRecommendGS(army, heroLineUpInfos, recommandGs) local FormulaCalculator = require"Battle/Logic/Missile/FormulaCalculator" local useHeroCount = 0 for _, info in ipairs(heroLineUpInfos) do useHeroCount = useHeroCount + 1 if info.ViceHeroId > 0 then useHeroCount = useHeroCount + 1 end end for i, info in ipairs(heroLineUpInfos) do local mainAttrDic = FormulaCalculator.Calculate9v9RobotEnemyPlayerAttribute(recommandGs,useHeroCount, DataSheetManager.HeroNum:GetDataByID(info.heroId).TypeID, true) -- 主将属性 local viceAttrDic if info.ViceHeroId > 0 then viceAttrDic = FormulaCalculator.Calculate9v9RobotEnemyPlayerAttribute(recommandGs,useHeroCount, DataSheetManager.HeroNum:GetDataByID(info.ViceHeroId).TypeID, false) -- 副将属性 end for attr, val in pairs(mainAttrDic) do if viceAttrDic then army[i].Attr[LuaConst.AttrTypeId[attr]] = FP.tonumberV1(val + (viceAttrDic[attr] or FP.Const.Zero) ) else army[i].Attr[LuaConst.AttrTypeId[attr]] = FP.tonumberV1(val) end end end end private.TempFoundryMaxPoint = {} --key:LineType, value:PointID private.TempFoundryMaxPointList = {} --value:PointID --[[ 创建公平竞技的army --]] function private.CreateArmyFair(playerID, heroLineUpInfos) local army = {} for i = 1, #heroLineUpInfos do local heroLineUpInfo = heroLineUpInfos[i] local heroArmyData = {} local heroId = heroLineUpInfo.heroId local adjutantId = heroLineUpInfo.ViceHeroId heroArmyData.HeroID = heroId heroArmyData.AdjutantID = adjutantId heroArmyData.mainHeroLevel = heroLineUpInfo.mainHeroLevel heroArmyData.mainHeroBreakNums = heroLineUpInfo.mainHeroBreakNums heroArmyData.viceHeroBreakNums = heroLineUpInfo.viceHeroBreakNums heroArmyData.heroGs = heroLineUpInfo.heroGs or 0 heroArmyData.horseID = heroLineUpInfo.mainHeroHorseId heroArmyData.horseAppearanceId = heroLineUpInfo.horseAppearanceId heroArmyData.heroAppearanceId = heroLineUpInfo.heroAppearanceId heroArmyData.viceHeroAppearanceId = heroLineUpInfo.viceHeroAppearanceId heroArmyData.weaponAppearanceId = heroLineUpInfo.weaponAppearanceId heroArmyData.viceWeaponAppearanceId = heroLineUpInfo.viceWeaponAppearanceId heroArmyData.isMagicWeaponActive = heroLineUpInfo.isMagicWeaponActive heroArmyData.isViceMagicWeaponActive = heroLineUpInfo.isViceMagicWeaponActive heroArmyData.mainHeroAwaken = heroLineUpInfo.mainHeroAwaken heroArmyData.viceHeroAwaken = heroLineUpInfo.viceHeroAwaken heroArmyData.mainHeroAwakenEffectList = heroLineUpInfo.mainHeroAwakenEffectList heroArmyData.viceHeroAwakenEffectList = heroLineUpInfo.viceHeroAwakenEffectList if IsServerDataNotNil(heroLineUpInfo.mainDyeCurPartList) then heroArmyData.mainDyeCurPartList = {} for _, val in ipairs(heroLineUpInfo.mainDyeCurPartList) do table.insert(heroArmyData.mainDyeCurPartList,val) end end if IsServerDataNotNil(heroLineUpInfo.viceDyeCurPartList) then heroArmyData.viceDyeCurPartList = {} for _, val in ipairs(heroLineUpInfo.viceDyeCurPartList) do table.insert(heroArmyData.viceDyeCurPartList,val) end end local magicWeaponLevel = 15 --写死的最大等级 --主将处理 if heroId and heroId > 0 then --武将突破 heroArmyData.mainHeroDevelopEffectsIds = {} for i, v in DataSheetManager.HeroStar:GetDataByHeroID_Star(heroId) do if v.RemoveDevelopEffectID > 0 then table.removebyvalue(heroArmyData.mainHeroDevelopEffectsIds, v.RemoveDevelopEffectID) end if v.DevelopEffectID > 0 then table.insert(heroArmyData.mainHeroDevelopEffectsIds, v.DevelopEffectID) end end --武将时装 if heroArmyData.heroAppearanceId and heroArmyData.heroAppearanceId > 0 then local heroAppearanceData = DataSheetManager.HeroAppearance:GetDataByID(heroArmyData.heroAppearanceId) if heroAppearanceData and heroAppearanceData.TalentID > 0 then table.insert(heroArmyData.mainHeroDevelopEffectsIds,heroAppearanceData.TalentID) end end --武将觉醒后的天资 if heroArmyData.mainHeroAwaken then local awakenTalentList = DataSheetUtil.GetHeroAwakenTalentList(heroId) for i, v in ipairs(awakenTalentList) do table.insert(heroArmyData.mainHeroDevelopEffectsIds, v) end end --神兵突破 local mainMagicWeaponStarData = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(heroId, magicWeaponLevel) heroArmyData.mainHeroMusouSkillId = mainMagicWeaponStarData.MusouSkillID heroArmyData.mainHeroWeaponLevels = magicWeaponLevel --神兵锻铸 local foundryLineLevel = 3 --LineType不大于foundryLineLevel的只加PointID最大的,否则全部加上 local templateID = DataSheetUtil.GetForgeTemplateID(heroId, heroArmyData.weaponAppearanceId) if templateID > 0 then heroArmyData.foundryLineInfo = {} for i, v in DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(templateID) do if v.LineType <= foundryLineLevel then local maxPointID = private.TempFoundryMaxPoint[v.LineType] if not maxPointID or v.PointID > maxPointID then private.TempFoundryMaxPoint[v.LineType] = v.PointID end else table.insert(heroArmyData.foundryLineInfo, v.PointID) end end --排序,否则用pairs太危险 for i, pointID in pairs(private.TempFoundryMaxPoint) do -- pairs safe table.insert(private.TempFoundryMaxPointList, pointID) private.TempFoundryMaxPoint[i] = nil end table.sort(private.TempFoundryMaxPointList) for _, pointID in ipairs(private.TempFoundryMaxPointList) do table.insert(heroArmyData.foundryLineInfo, pointID) end table.clearArray(private.TempFoundryMaxPointList) end end --副将处理 if adjutantId and adjutantId > 0 then --武将突破 heroArmyData.viceHeroDevelopEffectsIds = {} for i, v in DataSheetManager.HeroStar:GetDataByHeroID_Star(adjutantId) do if v.RemoveDevelopEffectID > 0 then table.removebyvalue(heroArmyData.viceHeroDevelopEffectsIds, v.RemoveDevelopEffectID) end if v.DevelopEffectID > 0 then table.insert(heroArmyData.viceHeroDevelopEffectsIds, v.DevelopEffectID) end end --武将时装 if heroArmyData.viceHeroAppearanceId and heroArmyData.viceHeroAppearanceId > 0 then local viceHeroAppearanceData = DataSheetManager.HeroAppearance:GetDataByID(heroArmyData.viceHeroAppearanceId) if viceHeroAppearanceData and viceHeroAppearanceData.TalentID > 0 then table.insert(heroArmyData.viceHeroDevelopEffectsIds, viceHeroAppearanceData.TalentID) end end --武将觉醒后的天资 if heroArmyData.viceHeroAwaken then local awakenTalentList = DataSheetUtil.GetHeroAwakenTalentList(adjutantId) for i, v in ipairs(awakenTalentList) do table.insert(heroArmyData.viceHeroDevelopEffectsIds, v) end end --神兵突破 local viceMagicWeaponStarData = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(adjutantId, magicWeaponLevel) heroArmyData.viceHeroMusouSkillId = viceMagicWeaponStarData.ViceSkillID heroArmyData.viceHeroWeaponLevels = magicWeaponLevel end heroArmyData.lightEffectIds = {} if heroLineUpInfo.mainLightEffectIds then for j,lightEffect in ipairs(heroLineUpInfo.mainLightEffectIds) do table.insert(heroArmyData.lightEffectIds, lightEffect) end end heroArmyData.Attr = {} local pos = heroLineUpInfo.pos or 0 -- 左中右 军 LevelPlayerManager.SetPlayerArmyPosInfo(playerID ,heroArmyData.HeroID,pos) LevelPlayerManager.SetPlayerArmyPosInfo(playerID ,heroArmyData.AdjutantID,pos + 1) for j = 2, #heroLineUpInfo.attr.attrs do table.insert(heroArmyData.Attr, heroLineUpInfo.attr.attrs[j]) end table.insert(army,heroArmyData) end return army end --armyPos指的是左中右路军这种(可能以后会改成前中后,但不影响代码功能) function LevelPlayerManager.SetPlayerArmyPosInfo(playerID,characterID,pos) --logging.error(LTAG.ERROR, "HYW : SetPlayerArmyPosInfo : ", characterID, " pos : ", pos) if not private.Player2HeroID2ArmyPosDic[playerID] then private.Player2HeroID2ArmyPosDic[playerID] = {} end private.Player2HeroID2ArmyPosDic[playerID][characterID] = pos end --通过前中后军的索引,找到当前出场的顺序 索引 function LevelPlayerManager.GetIndexByArmyPos(playerID,armyPos) local character2PosDic = private.Player2HeroID2ArmyPosDic[playerID] local heroID = -1 for characterID, pos in pairs(character2PosDic) do if pos == armyPos then heroID = characterID break end end local armyTable = LevelPlayerManager.GetPlayerArmyByPlayerIDInRoom(playerID) for index, army in ipairs(armyTable) do if army.HeroID == heroID then return index end end --出错了,打印log local strLog = "character2PosDic [heroID]=armyPos: " for characterID, pos in pairs(character2PosDic) do strLog = strLog .. "[" .. characterID .. "] = " .. pos .. " | " end strLog = strLog .. "\n armyTable : [index]=heroID" for index, army in ipairs(armyTable) do strLog = strLog .. "[" .. index .. "] = " .. army.HeroID .. " | " end logging.error(LTAG.ERROR , "GWS: 居然没有找到",playerID,"玩家的" ,armyPos,"军索引" ,"玩家信息:" , strLog) return nil end function LevelPlayerManager.IsEntityMagicWeaponActive(heroEntity) local isMagicWeaponActive = true local isViceMagicWeaponActive = true if private.IsOriginalArmy then local heroArmyData = LevelPlayerManager.GetPlayerArmyData(heroEntity._logicInitData.PlayerIDInRoom,heroEntity) if heroArmyData and heroArmyData.mainHeroMusouSkillId then isMagicWeaponActive = (heroArmyData.mainHeroMusouSkillId > 0) isViceMagicWeaponActive = (heroArmyData.viceHeroMusouSkillId and heroArmyData.viceHeroMusouSkillId > 0) end else if private.switchArmData then for i,v in ipairs(private.switchArmData.ArmyData_Table) do if v.HeroDataID == heroEntity:GetCharacterID() then isMagicWeaponActive = v.MainHeroMusouSkillId > 0 isViceMagicWeaponActive = v.ViceHeroMusouSkillId > 0 break end end end end return isMagicWeaponActive,isViceMagicWeaponActive end --判断 entityID 对应的单位是否属于 playerID 对应的玩家 function LevelPlayerManager.IsEntityOfPlayer(entityID, playerID) local result = false local entity = LogicUpdateManager._entityDic[entityID] if entity then result = entity:GetOriginEntity():GetPlayerID() == playerID end return result end -- 获取某个characterID的位置, 主将0,2,4,副将 1,3,5 function LevelPlayerManager.GetHeroArmyPos(playerID,characterID) if private.Player2HeroID2ArmyPosDic[playerID] then return private.Player2HeroID2ArmyPosDic[playerID][characterID] or -1 end end --isByArmyData:是否是替换阵容 --entityTable:只有hero单位,没有副将单位 function LevelPlayerManager.SetPlayerEntityTable(entityTable, playerID, isByArmyData) LevelPlayerManager.PlayersEntityTable[playerID] = entityTable for i,entity in ipairs(entityTable) do entity:SetIndex(i) end local isPlayerIDExist = false for i,_playerID in ipairs(LevelPlayerManager.PlayerIDList) do if _playerID == playerID then isPlayerIDExist = true break end end if not isPlayerIDExist then table.insert(LevelPlayerManager.PlayerIDList, playerID) end local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if LevelManager.IsShowRetinue() and not LevelManager.IsOnlineTown() and LevelManager.IsNoBattleLevel() then -- 是否显示随从,如果显示一定需要加上(主城中通过basicBuff加了,故需排除下) -战斗等待区 for i,entity in ipairs(entityTable) do private.ApplyDevelopEffects(entity, playerInfo, nil, true) -- 抄写的下面代码 end else if LevelManager.IsDevelopEffectLevel() and not isByArmyData then --2022年11月17日 新增 not isByArmyData 判定,策划需求替换阵容不应用养成效果 for i,entity in ipairs(entityTable) do private.ApplyDevelopEffects(entity, playerInfo) -- 先用这个函数,有点冗余可以优化 if entity.components.adjutant.AdjutantEntity then private.ApplyDevelopEffects(entity.components.adjutant.AdjutantEntity, playerInfo) end end else if not LevelManager.IsNoBattleLevel() then -- 目前只给战斗关卡才加上锻铸的buff for i,entity in ipairs(entityTable) do LevelPlayerManager.AddDefaultFoundryBuffs(entity, DataSheetUtil.GetForgeTemplateID(entity:GetCharacterID(), entity:GetCharacterID())) end end end end if isByArmyData then --如果是替换阵容,则擦除所有觉醒flag local playerArmy = LevelPlayerManager.PlayersArmyTable[playerID] local heroArmyDataList = playerArmy.army if heroArmyDataList then for i,heroArmyData in ipairs(heroArmyDataList) do heroArmyData.mainHeroAwaken = false heroArmyData.viceHeroAwaken = false end end end -- 觉醒buff添加,old。 现在直接在 CollectDevelopEffects -- local playerArmy = LevelPlayerManager.PlayersArmyTable[playerID] -- if playerArmy then -- local heroArmyDataList = playerArmy.army -- if heroArmyDataList then -- for i,entity in ipairs(entityTable) do -- for j,heroArmyData in ipairs(heroArmyDataList) do -- if heroArmyData.HeroID == entity:GetCharacterID() then -- if heroArmyData.mainHeroAwakenEffectList then -- for k,buffId in ipairs(heroArmyData.mainHeroAwakenEffectList) do -- SystemManager.AddBuff(entity, buffId) -- end -- end -- if heroArmyData.viceHeroAwakenEffectList then -- local adjutant = entity.components.adjutant.AdjutantEntity -- if adjutant then -- for k,buffId in ipairs(heroArmyData.viceHeroAwakenEffectList) do -- SystemManager.AddBuff(adjutant, buffId) -- end -- end -- end -- break -- end -- end -- end -- end -- end --]] end function LevelPlayerManager.GetPlayerDamageBefore(playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) if playerInfo then return playerInfo.damageBefore or 0 else return 0 end end function LevelPlayerManager.GetPlayerEntityByCharacterID(playerID,characterID) local entity = nil local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entitys then for i,v in ipairs(entitys) do if v:GetCharacterID() == characterID then entity = v end end end return entity end function LevelPlayerManager.GetPlayerArmyData(playerID,heroEntity) local armyData = LevelPlayerManager.PlayersArmyTable[playerID] if not armyData then return nil end local army = armyData.army if not army then return nil end for i,heroArmyData in ipairs(army) do if heroArmyData.HeroID == heroEntity:GetCharacterID() or heroArmyData.HeroId == heroEntity:GetCharacterID() then return heroArmyData end end end -- 收集到计略技能 function private.CollectStratagemSkill(stratagemDevelopEffects) local stratagemBuffs = {} local stratagemSkill = nil for i,stratagemDevelopEffectID in ipairs(stratagemDevelopEffects) do local developEffectData = DataSheetManager.DevelopEffectData:GetDataByID(stratagemDevelopEffectID) if developEffectData.StratagemSkillID > 0 then stratagemSkill = developEffectData.StratagemSkillID end for _i,buffs in ipairs(developEffectData.BuffIDs) do table.insert(stratagemBuffs,buffs) end end return stratagemSkill, stratagemBuffs end function private.ClearDevelopEffects(playerID) if not private.DevelopEffectInfoDic then private.DevelopEffectInfoDic = {} end private.DevelopEffectInfoDic[playerID] = {} end function LevelPlayerManager.NotSyncCollectDevelopEffects(playerID) return private.CollectDevelopEffects(playerID) end --收集被动技能列表 信息 ,这个信息给所有entity创建后使用。 function private.CollectDevelopEffects(playerID) private.ClearDevelopEffects(playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) local army = LevelPlayerManager.GetPlayerArmyByPlayerIDInRoom(playerID) if not army then return end --暂时只考虑Hero,monster的被动不统计 for i,heroArmyData in ipairs(army) do if heroArmyData then --主将的 if heroArmyData.mainHeroDevelopEffectsIds or heroArmyData.mainHeroAwakenEffectList then local developEffectInfo = {} developEffectInfo.characterID = heroArmyData.HeroID --HeroID就是characterID,就是数据表的id developEffectInfo.campID = playerInfo.campID--LuaConst.STANDALONE_PLAYER_CAMP --目前暂时仅支持单机,这里所有hero的camp都是2(单机不设置camp都行,但是为了拓展先设置着) developEffectInfo.armyPos = LevelPlayerManager.GetHeroArmyPos(playerID,developEffectInfo.characterID) developEffectInfo.effectIds = {} if heroArmyData.mainHeroDevelopEffectsIds then for i,v in ipairs(heroArmyData.mainHeroDevelopEffectsIds) do table.insert(developEffectInfo.effectIds, v) end end if heroArmyData.mainHeroAwakenEffectList then for i,v in ipairs(heroArmyData.mainHeroAwakenEffectList) do table.insert(developEffectInfo.effectIds, v) end end table.insert(private.DevelopEffectInfoDic[playerID],developEffectInfo) end --logging.error(LTAG.ERROR, "HYW : MainHero character:", developEffectInfo.characterID, " #effectIds : ", #developEffectInfo.effectIds ) --副将的 if heroArmyData.viceHeroDevelopEffectsIds then local developEffectInfo = {} developEffectInfo.characterID = heroArmyData.AdjutantID --AdjutantID就是characterID,就是数据表的id developEffectInfo.campID = playerInfo.campID--LuaConst.STANDALONE_PLAYER_CAMP --目前暂时仅支持单机,这里所有hero的camp都是2(单机不设置camp都行,但是为了拓展先设置着) developEffectInfo.armyPos = LevelPlayerManager.GetHeroArmyPos(playerID,developEffectInfo.characterID) developEffectInfo.effectIds = {} if heroArmyData.viceHeroDevelopEffectsIds then for i,v in ipairs(heroArmyData.viceHeroDevelopEffectsIds) do table.insert(developEffectInfo.effectIds, v) end end if heroArmyData.viceHeroAwakenEffectList then for i,v in ipairs(heroArmyData.viceHeroAwakenEffectList) do table.insert(developEffectInfo.effectIds, v) end end table.insert(private.DevelopEffectInfoDic[playerID],developEffectInfo) --logging.error(LTAG.ERROR, "HYW : Adjutant character:", developEffectInfo.characterID, " #effectIds : ", #developEffectInfo.effectIds ) end end end end function private.IsDevelopEffectsValid(targetEntity,developEffectInfo,developEffectData) local isValid = false if developEffectData then if developEffectData.BreakEffectAim == LuaConst.EDevelopEffectAimType.SELF then --仅对自身生效 isValid = targetEntity.isHero and developEffectInfo.characterID == targetEntity:GetCharacterID() --以后如果出现多阵营可以选相同英雄的联机战斗时,这里会出问题,需要提前注意 elseif developEffectData.BreakEffectAim == LuaConst.EDevelopEffectAimType.SAME_ARMY_POS then --对同路军生效 isValid = targetEntity.isHero and private.IsSameArmyPos( targetEntity:GetPlayerID(),targetEntity:GetCharacterID(),developEffectInfo.characterID) elseif developEffectData.BreakEffectAim == LuaConst.EDevelopEffectAimType.WHOLE_ARMIES then --对全军生效 isValid = targetEntity.isHero elseif developEffectData.BreakEffectAim == LuaConst.EDevelopEffectAimType.SELF_ADJUTANT then isValid = targetEntity.isAdjuntant and developEffectInfo.characterID == targetEntity:GetCharacterID() elseif developEffectData.BreakEffectAim == LuaConst.EDevelopEffectAimType.SELF_HERO_OR_ADJUTANT then isValid = developEffectInfo.characterID == targetEntity:GetCharacterID() end end return isValid end -- 是否是同路军 ;主将0,2,4,副将 1,3,5 function private.IsSameArmyPos(playerID, characterIdA,characterIdB) local posDic = private.Player2HeroID2ArmyPosDic[playerID] local aPos = nil if posDic[characterIdA] then aPos = math.floor( posDic[characterIdA] / 2 ) end local bPos = nil if posDic[characterIdB] then bPos = math.floor( posDic[characterIdB] / 2 ) end return aPos == bPos end --返回对targetEntity可以生效的被动技能info的list --info : {developEffectData(数据表数据)、developEffectInfo} function private.GetValidateDevelopEffectInfoList(targetEntity) local validateDevelopEffectsInfos = {} if targetEntity.isRetinue then -- do nothing 随从不应用突破被动 else local playerID if targetEntity.isAdjuntant then playerID = targetEntity:GetMasterEntity():GetPlayerID() else playerID = targetEntity:GetPlayerID() end if private.IsOriginalArmy then --策划需求:被替换过的阵容,不再应用突破被动 local developEffectInfoList = private.DevelopEffectInfoDic and private.DevelopEffectInfoDic[playerID] if developEffectInfoList then for i,developEffectInfo in ipairs(developEffectInfoList) do local effectIds = developEffectInfo.effectIds local developEffectData = nil if effectIds then for j,effectId in ipairs(effectIds) do developEffectData = effectId>0 and DataSheetManager.DevelopEffectData:GetDataByID(effectId) or nil if private.IsDevelopEffectsValid(targetEntity,developEffectInfo,developEffectData) then local info = {} info.developEffectData = developEffectData info.developEffectInfo = developEffectInfo table.insert(validateDevelopEffectsInfos,info) end end end end end end end return validateDevelopEffectsInfos end --[[ 设置主将,离线-cheat 实验室【战斗策划】 ]]-- function LevelPlayerManager.SetLaboratoryHeroTable() LevelPlayerManager.BeforeStorePlayerInfo() local heroIndex = GlobalBattleData.Get_CheatHeroIndex() local heroArmyData = {} heroArmyData.HeroID = heroIndex heroArmyData.AdjutantID = heroIndex heroArmyData.mainHeroWeaponLevels = 15 -- -- 神兵突破数据(最大15级) --heroArmyData.foundryLineInfo = {106,206,306} -- 神兵锻铸数据 local mainMagicWeaponStarData = DataSheetManager.MagicWeaponStar:GetDataByMagicWeaponID_Star(heroIndex, heroArmyData.mainHeroWeaponLevels) heroArmyData.mainHeroMusouSkillId = mainMagicWeaponStarData.MusouSkillID heroArmyData.viceHeroMusouSkillId = heroArmyData.mainHeroMusouSkillId heroArmyData.horseID = 1 heroArmyData.lightEffectIds = {202003} heroArmyData.isMagicWeaponActive = true --heroArmyData.petInfo = {petId = 5, stage = 0, petName = "瞅瞅", petSkill = 0, isLineUp = true, runeSkillLevelSum = 1, aptitudeSum = 1} --heroArmyData.isViceMagicWeaponActive = true --heroArmyData.heroAppearanceId = 13 heroArmyData.weaponAppearanceId = heroIndex--1013 --天命信息 --heroArmyData.weaponSoulInfo = {isActive = true, skillSceneInfo = {{skillId = heroIndex*100+1, level = 4}, {skillId = heroIndex*100+2, level = 4}, {skillId = heroIndex*100+3, level = 4}, {skillId = heroIndex*100+4, level = 4}}} local heroArmyData2 = {} heroArmyData2.HeroID = 2 heroArmyData2.AdjutantID = 2 heroArmyData2.mainHeroMusouSkillId = 1 heroArmyData2.viceHeroMusouSkillId = 1 heroArmyData2.horseID = 1 heroArmyData2.lightEffectIds = {202003} heroArmyData2.mainHeroWeaponLevels = 2 local stratagemSkill, stratagemBuffIDs = 100, {420070001} -- 国服风林火山 ; { 420060001 } --海外风林火山 LevelPlayerManager.MainEntityCampID = LuaConst.STANDALONE_PLAYER_CAMP LevelPlayerManager.MyPlayerIDInRoom = LuaConst.STANDALONE_PLAYER_PlayID LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID] = { playerInfo = {name = "test",serId = 5,countryId = 1,stratagemSkill = stratagemSkill,stratagemBuffIDs = stratagemBuffIDs,setting = {[1] = false,[16] = true,}} ,army = {heroArmyData,heroArmyData2} } end --[[ 设置主将,离线-cheat 非实验室 ]]-- function LevelPlayerManager.SetOffLineHeroTable() LevelPlayerManager.BeforeStorePlayerInfo() local heroIndex = GlobalBattleData.Get_CheatHeroIndex() local heroArmyData = {} heroArmyData.HeroID = heroIndex heroArmyData.AdjutantID = heroIndex heroArmyData.mainHeroMusouSkillId = 1 heroArmyData.viceHeroMusouSkillId = 1 heroArmyData.horseID = 1 heroArmyData.Attr = {} local monsterValue = DataSheetManager.MonsterValueData:GetDataByGroupID_Difficulty(2,1) if monsterValue then local value = nil for i,attrName in ipairs(LuaConst.AttrIntType) do value = monsterValue[attrName] if value then table.insert(heroArmyData.Attr , value ) else table.insert(heroArmyData.Attr, 0) end end end LevelPlayerManager.MainEntityCampID = LuaConst.STANDALONE_PLAYER_CAMP LevelPlayerManager.MyPlayerIDInRoom = LuaConst.STANDALONE_PLAYER_PlayID LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID] = { playerInfo = {name = "test" ,setting = {[1] = true ,}} ,army = {heroArmyData} } end --[[ 切换主将 ]]-- function LevelPlayerManager.SwitchHero(playerID, index, isDeadSwitch, sourceType) local errorCode = 0 -- 0表示成功 ,其他表示失败 if sourceType == LuaConst.ESwitchHeroSource.SPECIAL_COMMAND and not LevelPlayerManager.canSwitchHeroByCommand then errorCode = 1 return errorCode end if index <= 1 then errorCode = 2 return errorCode end local heroEntitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if not heroEntitys then --正常情况,如果在驾驶的时候,heroEntitys为空 errorCode = 3 return errorCode end local toEntity = heroEntitys[index] if not toEntity or not toEntity:IsAlive() then errorCode = 4 return errorCode end --判断是否在CD中 if not isDeadSwitch and heroEntitys[1].components.record.SwitchTimer > 0 and sourceType ~= LuaConst.ESwitchHeroSource.FORCE_IGNORE_CD then errorCode = 5 return errorCode end --切换 local fromEntity = heroEntitys[1] if fromEntity and fromEntity:IsAlive() and (fromEntity.components.buff:HasHardControlBuff() and sourceType == LuaConst.ESwitchHeroSource.SPECIAL_COMMAND) then --当前entity存在,且isAlive为true,且身上有硬控,则禁止手动切人 errorCode = 6 return errorCode end --处理切换英雄的数据,包括设置英雄entity的index,以及armyData的顺序整理 --不同关卡类型有不同的数据处理规则 LevelManager.CurLevelFunc:HandleSwitchHeroData(heroEntitys, fromEntity, index, toEntity, playerID, private.IsOriginalArmy) SystemManager.OnSwitchHero(fromEntity, toEntity) --设置当前主将 --只有主视角才执行 if fromEntity == LogicUpdateManager._curEntity then LevelPlayerManager.SetCurEntity(toEntity ,true) -- 在SystemManager.OnSwitchHero已经做了active的逻辑 EventSystem.Dispatch(EventID.BI_LevelLow,BIManager.BIType.ChangeHeroStage,isDeadSwitch,fromEntity,toEntity) end --事件通知 EventSystem.Dispatch(EventID.Level_SwitchHero,isDeadSwitch and LuaConst.SwitchHeroType.Dead or LuaConst.SwitchHeroType.Manual, toEntity) SystemManager.AfterSwitchHero(fromEntity,toEntity) return errorCode end function LevelPlayerManager.CreatePlayers(pos,dir) LevelManager.CurLevelFunc:CreatePlayers(pos,dir) private.IsOriginalArmy = true --【只给自己主将使用】 private.switchArmData = nil --【只给自己主将使用】 end --[gws:只能给非sync玩法用] armyData是LevelBattleArmy的一行数据,代表了一套最多6个英雄的阵容(3组主副将) function LevelPlayerManager.CreatePlayers_ByArmyData(armyData,bornItemID,pos,dir, isAllHeroBattle) private.IsOriginalArmy = false private.switchArmData = armyData LevelManager.CurLevelFunc:CreatePlayers_ByArmyData(armyData,bornItemID,pos,dir, isAllHeroBattle) end --[gws:只能给非sync玩法用],切换战斗的军队前使用 function LevelPlayerManager.ClearPlayerEntity(playerID) local heroEntities = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if heroEntities then for i,v in ipairs(heroEntities) do local adjutant = v.components.adjutant.AdjutantEntity if adjutant then SystemManager.OnUnload(adjutant,true) end SystemManager.OnUnload(v,true) end end LevelPlayerManager.PlayersEntityTable[playerID] = {} for i,_playerID in ipairs(LevelPlayerManager.PlayerIDList) do if _playerID == playerID then table.remove(LevelPlayerManager.PlayerIDList, i) break end end private.Player2HeroID2ArmyPosDic[playerID] = {} end -- 只有在非同步的sync用到,切换战斗的军队 ,给自己用 function LevelPlayerManager.RecordHeroAttr(playerID) if not private.IsOriginalArmy then return end local army = LevelPlayerManager.GetPlayerArmyByPlayerIDInRoom(playerID) if not army then return end for i,v in ipairs(army) do local entity = LevelPlayerManager.PlayersEntityTable[playerID][i] if entity.components.attr:IsAlive() then v.HP = nil else v.HP = FP.Const.Zero:cloneV1() end end end --在收到关卡玩家信息时,清理数据 function LevelPlayerManager.BeforeStorePlayerInfo() LevelPlayerManager.ClearAllData() end function LevelPlayerManager.ExitLevel() --LevelPlayerManager.ClearAllData() gws 不能清理 ,否则数据都清完了 LevelPlayerManager.canSwitchHeroByCommand = true end --[[ 设置并激活当前主将,只能是关卡开始的时候使用 ]]-- function LevelPlayerManager.SetCurEntity(entity ,needNotActive ,needOnHorse) local fromEntity = LogicUpdateManager._curEntity -- 一定要放在这,下面的SystemManager.SetCurEntity会设置新entity SystemManager.SetCurEntity(entity) if not needNotActive then SystemManager.Active(entity ,needOnHorse) end --[[if LevelManager.IsDevelopEffectLevel() then private.ApplyDevelopEffects(entity) end--]] if not LevelManager.IsSyncLevel() then --非同步关卡才能走下面的方法 SystemManager.AfterSwitchHero(fromEntity,LogicUpdateManager._curEntity) end end function LevelPlayerManager.KillAllActiveHero() local entity = nil for i=#LogicUpdateManager.EntityList_Sync,1,-1 do entity = LogicUpdateManager.EntityList_Sync[i] if entity:IsHero() and entity:IsActive() then SystemManager.DeadQuit(entity) end end for i=#LogicUpdateManager.EntityList_Normal,1,-1 do entity = LogicUpdateManager.EntityList_Normal[i] if entity:IsHero() and entity:IsActive() then SystemManager.DeadQuit(entity) end end end function LevelPlayerManager.TryApplyRetinueDevelopEffects(entity) local retinueData = entity.retinueData if retinueData and retinueData.UseDevelopOfHeroID > 0 then local master = entity:GetMasterEntity() if master then local armyData = LevelPlayerManager.GetPlayerArmyData(master:GetPlayerID(), master) if armyData and armyData.extraHeroInfo then if armyData.extraHeroInfo.heroId == retinueData.UseDevelopOfHeroID then private.ApplyDevelopEffects(entity, nil, retinueData) end end end end end --如果是在主城对其他玩家进行Get,则需要传入playerID和acid才能获取到返回值。因为主城不需要锻铸、养成信息,所以在SkillBaseComponent、private.ApplyDevelopEffects里调该方法可以通过不传playerID、acid来获取空值以跳过后面的代码 function LevelPlayerManager.GetExtraHeroInfo(armyData, retinueData, playerID, acid) if LevelManager.IsOnlineTown() then if playerID == LuaConst.STANDALONE_PLAYER_PlayID then return LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID].townExtraHeroInfo else return SyncMoveManager.TownRoleList[acid] and SyncMoveManager.TownRoleList[acid].roleInfo.basicExtraHero or nil end else if armyData and armyData.extraHeroInfo and retinueData then if armyData.extraHeroInfo.heroId == retinueData.UseDevelopOfHeroID then return armyData.extraHeroInfo end end end end -- 给entity 尝试添加突破被动buff、神兵锻铸被动buff等养成获得的效果 function private.ApplyDevelopEffects(entity, playerInfo, retinueData, isOnlyRetinueDevelopEffects) -- isOnlyRetinue 只添加随从的developEffect local validateDevelopEffectsDatas = private.GetValidateDevelopEffectInfoList(entity) --logging.error(LTAG.ERROR, "HYW : #validateDevelopEffectsDatas : ", #validateDevelopEffectsDatas) --添加常规的养成被动buff(由服务器发过来的Buff列表) --2024年4月19日新增,entity可能为副将了,副将仅应用 developEffect,不应用后面的神兵锻铸等 if #validateDevelopEffectsDatas > 0 then for i,info in ipairs(validateDevelopEffectsDatas) do local developEffectData = info.developEffectData if isOnlyRetinueDevelopEffects then if developEffectData.ID == LuaConst.RetinueDevelopEffectID then local sourceEntity = LevelPlayerManager.GetPlayerEntityByCharacterID(entity._logicInitData.PlayerIDInRoom ,info.developEffectInfo.characterID) for j,buffId in ipairs(developEffectData.BuffIDs) do SystemManager.AddBuff(entity,buffId,sourceEntity,nil,nil) end return -- 如果仅仅是加貂蝉随从,则不需要下面的神兵锻铸等功能 end else local sourceEntity = LevelPlayerManager.GetPlayerEntityByCharacterID(entity._logicInitData.PlayerIDInRoom ,info.developEffectInfo.characterID) for j,buffId in ipairs(developEffectData.BuffIDs) do SystemManager.AddBuff(entity,buffId,sourceEntity,nil,nil) end end end end if isOnlyRetinueDevelopEffects then return -- 如果仅仅是加貂蝉随从,则不需要下面的神兵锻铸等功能 end if entity.isRetinue then --添加随从神兵锻铸提供的被动buff local masterEntity = entity:GetMasterEntity() if masterEntity then local armyData = LevelPlayerManager.GetPlayerArmyData(masterEntity:GetPlayerID(), masterEntity) if armyData then local extraHeroInfo = LevelPlayerManager.GetExtraHeroInfo(armyData, retinueData) if extraHeroInfo then -- extraHeroInfo.mainHeroMusouSkillId --SkillBaseComponent:TryReplaceSkillByMagicWeapon 里使用 -- extraHeroInfo.foundryLineInfo --本方法里使用 -- gws :暂定宝宝的developEffectData(mainHeroDevelopEffectsIds)仅仅应用于自己 for j,effectId in ipairs(extraHeroInfo.mainHeroDevelopEffectsIds) do local developEffectData = DataSheetManager.DevelopEffectData:GetDataByID(effectId) for j,buffId in ipairs(developEffectData.BuffIDs) do SystemManager.AddBuff(entity,buffId,entity,nil,nil) end end -- 锻铸 private.AddFoundryBuffs(entity, extraHeroInfo.heroId, extraHeroInfo.weaponAppearanceId, extraHeroInfo.foundryLineInfo) end end end elseif entity.isHero then --添加神兵锻铸提供的被动buff local heroArmyData = LevelPlayerManager.GetPlayerArmyData(entity:GetPlayerID(), entity) if heroArmyData then local templateID = DataSheetUtil.GetForgeTemplateID(heroArmyData.HeroID, heroArmyData.weaponAppearanceId) if heroArmyData.foundryLineInfo then local shouldAddDefaultFoundryPoint = true for i,lineId in ipairs(heroArmyData.foundryLineInfo) do if shouldAddDefaultFoundryPoint and lineId > 200 and lineId < 300 then --如果没有[201,299]的lineId被养成过,那么就需要添加默认的锻铸buff(策划需求) shouldAddDefaultFoundryPoint = false end local magicWeaponFoundryData = DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(templateID, lineId) if magicWeaponFoundryData and magicWeaponFoundryData.BuffIDs and #magicWeaponFoundryData.BuffIDs > 0 then for j,buffID in ipairs(magicWeaponFoundryData.BuffIDs) do SystemManager.AddBuff(entity, buffID, entity, nil, nil) end end end if shouldAddDefaultFoundryPoint then LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) end else LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) end else local templateID = DataSheetUtil.GetForgeTemplateID(entity:GetCharacterID()) LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) end -- 添加 计略的养成效果的被动buff if playerInfo and playerInfo.stratagemBuffIDs then for _i,buffId in ipairs(playerInfo.stratagemBuffIDs) do SystemManager.AddBuff(entity,buffId,entity,nil,nil) end end end end --添加神兵锻铸提供的被动buff function private.AddFoundryBuffs(entity, heroID, weaponAppearanceId, foundryLineInfo) local templateID = DataSheetUtil.GetForgeTemplateID(heroID, weaponAppearanceId) if foundryLineInfo then local shouldAddDefaultFoundryPoint = true for i,lineId in ipairs(foundryLineInfo) do if shouldAddDefaultFoundryPoint and lineId > 200 and lineId < 300 then --如果没有[201,299]的lineId被养成过,那么就需要添加默认的锻铸buff(策划需求) shouldAddDefaultFoundryPoint = false end local magicWeaponFoundryData = DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(templateID, lineId) if magicWeaponFoundryData and magicWeaponFoundryData.BuffIDs and #magicWeaponFoundryData.BuffIDs > 0 then for j,buffID in ipairs(magicWeaponFoundryData.BuffIDs) do SystemManager.AddBuff(entity, buffID, entity, nil, nil) end end end if shouldAddDefaultFoundryPoint then LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) end else LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) end end function LevelPlayerManager.AddDefaultFoundryBuffs(entity, templateID) -- 有些关卡不要这个默认锻铸 if LevelManager.IsNotDefaultFoundryLevel() then return end local defaultMagicWeaponFoundryData = DataSheetManager.MagicWeaponFoundry:GetDataByID_PointID(templateID, DEFAULT_FOUNDRY_POINT) if defaultMagicWeaponFoundryData then for j,buffID in ipairs(defaultMagicWeaponFoundryData.BuffIDs) do SystemManager.AddBuff(entity, buffID, entity, nil, nil) end else logging.error(LTAG.ERROR, "HYW : MagicWeaponFoundry表找不到默认神兵锻铸点位信息 ID : ", templateID, " pointID : ", DEFAULT_FOUNDRY_POINT) end end function LevelPlayerManager.IsAllDead(entity) -- 同步 if LevelManager.IsOneHeroLevel() then --主视角调用 if LogicUpdateManager._curEntity == entity and LogicUpdateManager._curEntity.components.attr:IsAlive() then return false,-1 end return true,-1 elseif LevelManager.IsNoBattleLevel() then--主城 return false,-1 elseif LevelManager.IsGuildWarLevel() then--军团战 return true,-1 elseif LevelManager.IsSelectOneReviveLevel() then--是否是选择一个复活的关卡 return true,-1 else local entitys = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(entity._logicInitData.PlayerIDInRoom) if entitys then for index,toEntity in ipairs(entitys) do if toEntity.components.attr:IsAlive() then return false,index end end end return true,-1 end end function LevelPlayerManager.GetMaxCountryJobLevelData(countId) local maxJobLevel = -1 local maxJobLevelData = nil local playerID -- 谁提供的 for i,_playerID in ipairs(LevelPlayerManager.PlayerIDList) do local playerInfo = LevelPlayerManager.PlayersArmyTable[_playerID].playerInfo if playerInfo.countryId == countId and (not playerInfo.isQuitted) then local countryJobData = DataSheetManager.CountryJob:GetDataByID(playerInfo.countryJobId) if countryJobData.Level > maxJobLevel then maxJobLevel = countryJobData.Level maxJobLevelData = countryJobData playerID = _playerID end end end return maxJobLevelData, playerID end -- 从 syncmove 中移过来 ;目的:校验程序的syncmove被重定向了 function LevelPlayerManager.GetMoveFromSceneInfo(sceneInfo) local pos, dir if IsServerDataNotNil(sceneInfo) then if IsServerDataNotNil(sceneInfo.Pos) then pos = FP.newV2(0,0):Rawset(sceneInfo.Pos.X, sceneInfo.Pos.Z) end if IsServerDataNotNil(sceneInfo.Dir) then dir = FP.newV2(0,0):Rawset(sceneInfo.Dir.X, sceneInfo.Dir.Z) end --logging.log(TLAG.LOG , "[gws] player posx = " , sceneInfo.Pos.X ," posz = " ,sceneInfo.Pos.Z , " dirX =" , sceneInfo.Dir.X , " dirZ =" , sceneInfo.Dir.Z ) end return pos, dir end local outOnlinePlayerList = {} function LevelPlayerManager.UpdateSyncLevelPlayerOnlineState() if not LevelManager.IsSyncLevel() then return end table.clear(outOnlinePlayerList) local errorCode = KCPTransport.GetOnlinePlayers(LogicUpdateManager._clientHandleFrame, outOnlinePlayerList) if errorCode ~= 0 then -- 返回0,表示不存在当前帧的数据 return end if #outOnlinePlayerList == 0 then --数组长度为0表示无变化 return end local isAllOffLine = outOnlinePlayerList[1] == 0 -- 数组第一个数为0,则表示都不在线 if isAllOffLine then LogicUpdateManager.OnlinePlayerCount = 0 else LogicUpdateManager.OnlinePlayerCount = #outOnlinePlayerList end if USE_LUA_STANDALONE then -- 校验程序更新记录的在线玩家列表 BattleSimulator.RecordOnlinePlayer(outOnlinePlayerList) end --更新掉线的人 local oldPlayerCount = #LevelPlayerManager.OnLinePlayerList for i =1,oldPlayerCount,2 do local playerID,lastState = LevelPlayerManager.OnLinePlayerList[i],LevelPlayerManager.OnLinePlayerList[i+1] local curState = table.containValue(outOnlinePlayerList,playerID) if lastState == true and curState == false then LevelPlayerManager.OnLinePlayerList[i+1] = false LevelManager.OnOffLine(playerID) EventSystem.Dispatch(EventID.Level_PlayerOffLine,playerID) logging.log(LTAG.LOG, "gws : OnOffLine ",playerID , "acid = ", LevelPlayerManager.PlayersArmyTable[playerID].playerInfo.acid) end end --更新上线的人 if not isAllOffLine then for i,playerID in ipairs(outOnlinePlayerList) do local find = false for i =1,oldPlayerCount,2 do if playerID == LevelPlayerManager.OnLinePlayerList[i] then find = true if LevelPlayerManager.OnLinePlayerList[i+1] == false then -- 玩家重连回来了 LevelPlayerManager.OnLinePlayerList[i+1] = true LevelManager.OnReconnect(playerID) EventSystem.Dispatch(EventID.Level_PlayerReconnected,playerID) logging.log(LTAG.LOG, "gws : OnReconnect ",playerID) end break end end if not find then table.insert(LevelPlayerManager.OnLinePlayerList,playerID) table.insert(LevelPlayerManager.OnLinePlayerList,true) LevelManager.OnPlayerFirstOnline(playerID) EventSystem.Dispatch(EventID.Level_PlayerFirstOnline,playerID) end end end end function LevelPlayerManager.IsOnline(playerID) local oldPlayerCount = #LevelPlayerManager.OnLinePlayerList for i =1,oldPlayerCount,2 do if playerID == LevelPlayerManager.OnLinePlayerList[i] then return LevelPlayerManager.OnLinePlayerList[i+1] end end return false end function LevelPlayerManager.OnPlayerActived(playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) playerInfo.isActived = true end -- 记录哪个玩家主动退出或者被服务器踢出房间 function LevelPlayerManager.RecordPlayerQuitRoom(entity) local playerID = entity:GetPlayerID() table.insert(LevelPlayerManager.QuitRoomPlayerList, playerID) local playerInfo = LevelPlayerManager.GetPlayerInfoByPlayerIDInRoom(playerID) playerInfo.isQuitted = true EventSystem.Dispatch(EventID.Level_PlayerQuit,playerID) end -- 判断所有玩家都主动退出或者被服务器踢出房间了 function LevelPlayerManager.IsAllPlayerQuitRoom() local quitRoomCount = #LevelPlayerManager.QuitRoomPlayerList if quitRoomCount == #LevelPlayerManager.SyncPlayerIDList then return true end return false end --用于怪物实验室中切将的cheat方法 function LevelPlayerManager.ChangeAvatarCheatForMonsterTest(characterID) local heroData = DataSheetManager.HeroData:GetDataByID(characterID) if not heroData then logging.error(LTAG.ERROR, "没有ID为", characterID, "的武将,请检查!!!") return end local ChangeAvatarSystem = require "Battle/Logic/Entity/System/ChangeAvatarSystem" local CharacterData = require "Battle/Logic/Entity/CharacterData" --主视角调用 local initInfo = LogicUpdateManager._curEntity._logicInitData initInfo:NotSyncResetInfo(characterID,0,false,nil,characterID,0,{201001}) ChangeAvatarSystem.ChangeAvatar(LogicUpdateManager._curEntity, characterID,nil ,true, nil, true) LevelPlayerManager.PlayersArmyTable[LuaConst.STANDALONE_PLAYER_PlayID].army[1].HeroID = characterID end -- 获取当前有效玩家的数量 function LevelPlayerManager.GetValidPlayerCount() --非同步玩法 if not LevelManager.IsSyncLevel() then return 1 end --同步玩法 local count = 0 for _,playerID in ipairs(LevelPlayerManager.SyncPlayerIDList) do local entity = LevelPlayerManager.GetPlayerActiveEntity(playerID) if entity and entity:IsValid() then count = count + 1 end end return count end return LevelPlayerManager