BattleManager = {} local this = BattleManager local PassiveSkillLogicConfig = ConfigManager.GetConfig(ConfigName.PassiveSkillLogicConfig) local SkillLogicConfig = ConfigManager.GetConfig(ConfigName.SkillLogicConfig) local HeroConfig = ConfigManager.GetConfig(ConfigName.HeroConfig) local MonsterGroup = ConfigManager.GetConfig(ConfigName.MonsterGroup) local MonsterConfig = ConfigManager.GetConfig(ConfigName.MonsterConfig) local CombatControl = ConfigManager.GetConfig(ConfigName.CombatControl) local function pairsByKeys(t) local a = {} for n in pairs(t) do if n then a[#a+1] = n end end table.sort(a, function( op1, op2 ) local type1, type2 = type(op1), type(op2) local num1, num2 = tonumber(op1), tonumber(op2) if ( num1 ~= nil) and (num2 ~= nil) then return num1 < num2 elseif type1 ~= type2 then return type1 < type2 elseif type1 == "string" then return op1 < op2 elseif type1 == "boolean" then return op1 -- 以上处理: number, string, boolean else -- 处理剩下的: function, table, thread, userdata return tostring(op1) < tostring(op2) -- tostring后比较字符串 end end) local i = 0 return function() i = i + 1 return a[i], t[a[i]] end end function this.PrintBattleTable(tb) local indent_str = "{" local count = 0 for k,v in pairs(tb) do count = count + 1 end for k=1, #tb do local v = tb[k] if type(v) == "table" then indent_str = indent_str .. this.PrintBattleTable(v) elseif type(v) == "string" then indent_str = indent_str .. "\""..tostring(v) .. "\"" else indent_str = indent_str .. tostring(v) end if k < count then indent_str = indent_str.."," end end local index = 0 for k,v in pairsByKeys(tb) do index = index + 1 if type(k) ~= "number" then if type(v) == "table" then indent_str = string.format("%s%s=%s", indent_str, tostring(k), this.PrintBattleTable(v)) elseif type(v) == "string" then indent_str = string.format("%s%s=\"%s\"", indent_str, tostring(k), tostring(v)) else indent_str = string.format("%s%s=%s", indent_str, tostring(k), tostring(v)) end if index < count then indent_str = indent_str .. "," end end end indent_str = indent_str .. "}" return indent_str end function this.Initialize() --加载相关模块 local files = ReloadFile("Modules/Battle/Config/LuaFileConfig") LoadLuaFiles(files) end --获取技能数据(战斗用) function this.GetSkillData(skillId, pos) pos = pos or 0 if not skillId or not SkillLogicConfig[skillId] then return end local skill = {skillId} --skill = {skillId, 命中时间, 持续时间, 伤害次数, {目标id1, 效果1, 效果2, ...},{目标id2, 效果3, 效果4, ...}, ...} --效果 = {效果类型id, 效果参数1, 效果参数2, ...} local target = SkillLogicConfig[skillId].Target local effectList = SkillLogicConfig[skillId].Effect local effectArgsList = SkillLogicConfig[skillId].EffectValue local EffectCombat = CombatControl[SkillLogicConfig[skillId].SkillDisplay] local index = 1 skill[1] = skillId skill[2] = EffectCombat.KeyFrame/1000 skill[3] = EffectCombat.SkillDuration/1000 skill[4] = EffectCombat.SkillNumber for i = 1, #effectList do local effectGroup = { target[i][1] } -- 效果目标 for j = 1, #effectList[i] do local effect = { effectList[i][j] } -- 效果Id for k = 1, #effectArgsList[index] do effect[k + 1] = effectArgsList[index][k] -- 效果参数 end effectGroup[j + 1] = effect index = index + 1 end skill[i + 4] = effectGroup end return skill end function this.GetPassivityData(passivityList) local pList = {} if not passivityList then return pList end -- 遍历被动,检查是否有要覆盖的被动技能 local orderList = {} local coverList = {} for i = 1, #passivityList do local passiveId = tonumber(passivityList[i]) local cfg = PassiveSkillLogicConfig[passiveId] -- 判断技能是否在战斗中生效 if cfg and cfg.EffectiveRange == 1 then -- 判断是否有需要覆盖的被动技能 local coverId = cfg.CoverID if coverId and coverId ~= 0 then if orderList[coverId] then orderList[coverId] = nil end coverList[coverId] = 1 end -- 判断该被动技能是否已经被覆盖 if not coverList[passiveId] then -- 没有被覆盖,数据加入 local pass = {} if cfg and cfg.Type ~= 0 then pass[1] = cfg.Type for j = 1, #cfg.Value do pass[j + 1] = cfg.Value[j] end orderList[passiveId] = pass end end end end -- 构建数据 for _, passive in pairs(orderList) do table.insert(pList, passive) end return pList end --获取怪物数据(战斗用) function this.GetMonsterData(monsterId) local monsterConfig = MonsterConfig[monsterId] return { roleId = monsterConfig.MonsterId, monsterId = monsterId, --非战斗数据,仅用于显示怪物名称 professionId = monsterConfig.Profession, camp = 1, type = 1, quality = 0, skill = this.GetSkillData(monsterConfig.SkillList[1]), superSkill = this.GetSkillData(monsterConfig.SkillList[2]), element = monsterConfig.PropertyName, passivity = this.GetPassivityData(monsterConfig.PassiveSkillList), property = { monsterConfig.Level, monsterConfig.Hp, monsterConfig.Hp, monsterConfig.Attack, monsterConfig.PhysicalDefence, monsterConfig.MagicDefence, monsterConfig.Speed, monsterConfig.DamageBocusFactor, monsterConfig.DamageReduceFactor, monsterConfig.Hit, monsterConfig.Dodge, monsterConfig.CritFactor, monsterConfig.CritDamageFactor, monsterConfig.AntiCritDamageFactor, monsterConfig.TreatFacter, monsterConfig.CureFacter, monsterConfig.DifferDemonsBocusFactor, monsterConfig.DifferDemonsReduceFactor, monsterConfig.ElementDamageReduceFactor[1], monsterConfig.ElementDamageReduceFactor[2], monsterConfig.ElementDamageReduceFactor[3], monsterConfig.ElementDamageReduceFactor[4], monsterConfig.ElementDamageReduceFactor[5], monsterConfig.ElementDamageReduceFactor[6], monsterConfig.ElementDamageBonusFactor, }, ai = monsterConfig.MonsterAi, } end ---获取服务端传过来的战斗数据和随机数种子 ---参数2 isFightPlayer 0和怪物对战 1和玩家对战 function this.GetBattleServerData(msg, isFightPlayer) local fightData = { playerData = { teamSkill = {}, teamPassive = {}, firstCamp = 0, }, enemyData = { }, } isFightPlayer = isFightPlayer == 1 -- 判断是否先手 fightData.playerData.firstCamp = msg.fightData.heroFightInfos.firstCamp or 0 -- local data = msg.fightData.heroFightInfos for i = 1, #data.fightUnitList do local rid = tonumber(data.fightUnitList[i].unitId) local position = tonumber(data.fightUnitList[i].position) local star = tonumber(data.fightUnitList[i].star) local skills = string.split(data.fightUnitList[i].unitSkillIds, "#") local propertys = string.split(data.fightUnitList[i].property, "#") local role = { roleId = rid, position = position, star = star, camp = 0, type = 1, quality = 0, element = HeroConfig[rid].PropertyName, professionId = HeroConfig[rid].Profession, passivity = { }, property = { }, } if skills[1] then role.skill = this.GetSkillData(tonumber(skills[1])) end if skills[2] and skills[2] ~= "0" then role.superSkill = this.GetSkillData(tonumber(skills[2])) end if #skills > 2 then local passivityList = {} for j = 3, #skills do table.insert(passivityList, tonumber(skills[j])) end role.passivity = this.GetPassivityData(passivityList) end for j = 1, #propertys do role.property[j] = tonumber(propertys[j]) end fightData.playerData[i] = role end --Log("teamSkills:"..data.teamSkillList) local teamSkills = string.split(data.teamSkillList, "|") --异妖位置1#技能id1|异妖位置2#技能id2|.. for i = 1, #teamSkills do local s = string.split(teamSkills[i], "#") fightData.playerData.teamSkill[i] = this.GetSkillData(tonumber(s[2]), tonumber(s[1])) end --Log("data.teamPassiveList:"..data.teamPassiveList) local teamPassives = string.split(data.teamPassiveList, "|") for i = 1, #teamPassives do local s = string.split(teamPassives[i], "#") local teamPassiveList = {} for j = 1, #s do teamPassiveList[j] = tonumber(s[j]) end fightData.playerData.teamPassive[i] = this.GetPassivityData(teamPassiveList) end -- 一些战斗外数据 fightData.playerData.outData = data.specialPassive LogRed(Language[10221]..data.specialPassive) -- 敌方 -- for i = 1, #msg.fightData.monsterList do local data2 = msg.fightData.monsterList[i] fightData.enemyData[i] = { teamSkill = {}, teamPassive = {} , firstCamp = 0, } -- 判断是否先手 fightData.enemyData[i].firstCamp = data2.firstCamp or 0 -- for j = 1, #data2.fightUnitList do local skills, propertys, role if not isFightPlayer then local monsterConfig = ConfigManager.GetConfigData(ConfigName.MonsterConfig, tonumber(data2.fightUnitList[j].unitId)) local position = tonumber(data2.fightUnitList[j].position) local star = tonumber(data2.fightUnitList[j].star) skills = string.split(data2.fightUnitList[j].unitSkillIds, "#") propertys = string.split(data2.fightUnitList[j].property, "#") role = { roleId = monsterConfig.MonsterId, monsterId = tonumber(data2.fightUnitList[j].unitId), --非战斗数据,仅用于显示怪物名称 position = position, star = star, camp = 1, type = monsterConfig.Type, quality = monsterConfig.Quality, element = monsterConfig.PropertyName, ai = monsterConfig.MonsterAi, professionId = monsterConfig.Profession, passivity = { }, property = { }, } else local rid = tonumber(data2.fightUnitList[j].unitId) local position = tonumber(data2.fightUnitList[j].position) local star = tonumber(data2.fightUnitList[j].star) skills = string.split(data2.fightUnitList[j].unitSkillIds, "#") propertys = string.split(data2.fightUnitList[j].property, "#") role = { roleId = rid, position = position, star = star, camp = 1, type = 1, quality = 0, element = HeroConfig[rid].PropertyName, professionId = HeroConfig[rid].Profession, passivity = { }, property = { }, } end if skills[1] then role.skill = this.GetSkillData(tonumber(skills[1])) end if skills[2] and skills[2] ~= "0" then role.superSkill = this.GetSkillData(tonumber(skills[2])) end if #skills > 2 then local passivityList = {} for k = 3, #skills do table.insert(passivityList, tonumber(skills[k])) end role.passivity = this.GetPassivityData(passivityList) end for k = 1, #propertys do role.property[k] = tonumber(propertys[k]) end fightData.enemyData[i][j] = role end --Log("teamSkills2:"..data2.teamSkillList) local teamSkills2 = string.split(data2.teamSkillList, "|") --异妖位置1#技能id1|异妖位置2#技能id2|.. for j = 1, #teamSkills2 do local s = string.split(teamSkills2[j], "#") fightData.enemyData[i].teamSkill[j] = this.GetSkillData(tonumber(s[2]), tonumber(s[1])) end -- 一些战斗外数据 fightData.enemyData[i].outData = data2.specialPassive end local data = { fightData = fightData, fightSeed = msg.fightData.fightSeed, fightType = msg.fightData.fightType, maxRound = msg.fightData.fightMaxTime, } return data end --获取战斗数据(战斗用) function this.GetBattleData(formationId, monsterGroupId) local fightData = { playerData = { teamSkill = {}, teamPassive = {} }, enemyData = {}, } local pokemonInfos = FormationManager.formationList[formationId].teamPokemonInfos local teamHeroInfos = FormationManager.formationList[formationId].teamHeroInfos for i = 1, #pokemonInfos do Log(DiffMonsterManager.GetSinglePokemonSkillIdData(pokemonInfos[i].pokemonId)) fightData.playerData.teamSkill[i] = this.GetSkillData(DiffMonsterManager.GetSinglePokemonSkillIdData(pokemonInfos[i].pokemonId), pokemonInfos[i].position) fightData.playerData.teamPassive[i] = this.GetPassivityData(DiffMonsterManager.GetSinglePokemonPassiveSkillIdData(pokemonInfos[i].pokemonId)) end for i = 1, #teamHeroInfos do local heroData = HeroManager.GetSingleHeroData(teamHeroInfos[i].heroId) if heroData then local role = { roleId = heroData.id, camp = 0, type = 1, quality = 0, element = HeroConfig[heroData.id].PropertyName, professionId = heroData.profession, --skill = this.GetSkillData(1000112), --superSkill = nil, passivity = this.GetPassivityData(this.GetTalismanSkillData(heroData.dynamicId)), } if heroData.skillIdList[1] then Log("skillId1:" .. heroData.skillIdList[1].skillId) role.skill = this.GetSkillData(heroData.skillIdList[1].skillId) end if heroData.skillIdList[2] then Log("skillId2:" .. heroData.skillIdList[2].skillId) role.superSkill = this.GetSkillData(heroData.skillIdList[2].skillId) end local allPassiveSkillIds = HeroManager.GetHeroAllPassiveSkillIds(heroData) if allPassiveSkillIds then role.passivity = this.GetPassivityData(allPassiveSkillIds) end -- if heroData.passiveSkillList[2] then -- Log("skillIdPassive2:" .. heroData.passiveSkillList[2].skillId) -- local skillPL = this.GetPassivityData({heroData.passiveSkillList[2].skillId}) -- for i=1, #skillPL do -- table.insert(role.passivity, skillPL[i]) -- end -- end role.property = HeroManager.CalculateWarAllProVal(heroData.dynamicId) fightData.playerData[i] = role end end local Contents = MonsterGroup[monsterGroupId].Contents for i = 1, #Contents do local enemyList = { teamSkill = {}, teamPassive = {} } for j = 1, #Contents[i] do enemyList[j] = this.GetMonsterData(Contents[i][j]) end fightData.enemyData[i] = enemyList end return fightData end -- 获取我数据 function this.GetBattlePlayerData(fId) fId = fId or 1 -- 默认主线编队 local playerData = { teamSkill = {}, teamPassive = {} } -- local pokemonInfos = FormationManager.formationList[formationId].teamPokemonInfos -- for i = 1, #pokemonInfos do -- Log(DiffMonsterManager.GetSinglePokemonSkillIdData(pokemonInfos[i].pokemonId)) -- fightData.playerData.teamSkill[i] = this.GetSkillData(DiffMonsterManager.GetSinglePokemonSkillIdData(pokemonInfos[i].pokemonId), pokemonInfos[i].position) -- fightData.playerData.teamPassive[i] = this.GetPassivityData(DiffMonsterManager.GetSinglePokemonPassiveSkillIdData(pokemonInfos[i].pokemonId)) -- end local teamHeroInfos = FormationManager.formationList[fId].teamHeroInfos for i = 1, #teamHeroInfos do local teamData = teamHeroInfos[i] local heroData = HeroManager.GetSingleHeroData(teamData.heroId) if heroData then local role = { roleId = heroData.id, position = teamData.position, star = heroData.star, camp = 0, type = 1, quality = 0, element = HeroConfig[heroData.id].PropertyName, professionId = heroData.profession, } if heroData.skillIdList[1] then role.skill = this.GetSkillData(heroData.skillIdList[1].skillId) end if heroData.skillIdList[2] then role.superSkill = this.GetSkillData(heroData.skillIdList[2].skillId) end local allPassiveSkillIds = HeroManager.GetHeroAllPassiveSkillIds(heroData) if allPassiveSkillIds then role.passivity = this.GetPassivityData(allPassiveSkillIds) end role.property = HeroManager.CalculateWarAllProVal(heroData.dynamicId) -- table.insert(playerData, role) end end return playerData end -- 根据怪物组数据 function this.GetBattleEnemyData(gId) -- body local enemyData = {} local Contents = MonsterGroup[gId].Contents for i = 1, #Contents do local enemyList = { teamSkill = {}, teamPassive = {} } for j = 1, #Contents[i] do if Contents[i][j] ~= 0 then local data = this.GetMonsterData(Contents[i][j]) data.position = j table.insert(enemyList, data) end end enemyData[i] = enemyList end return enemyData end --获取单个英雄装备被动技能list --function this.GetSingHeroAllEquipSkillListData(_heroId) -- local allEquipSkillList = {} -- local curHeroData = HeroManager.GetSingleHeroData(_heroId) -- if curHeroData then -- for i = 1, #curHeroData.equipIdList do -- local curEquip = EquipManager.GetSingleEquipData(curHeroData.equipIdList[i]) -- if curEquip then -- if curEquip.skillId and curEquip.skillId > 0 then -- table.insert(allEquipSkillList, curEquip.skillId) -- end -- end -- end -- end -- return allEquipSkillList --end --获取单个英雄法宝被动技能list function this.GetTalismanSkillData(_heroId) local allTalismanSkillList = {} local curHeroData = HeroManager.GetSingleHeroData(_heroId) if curHeroData then for i = 1, #curHeroData.talismanList do local curTalisman = TalismanManager.GetSingleTalismanData(curHeroData.talismanList[i]) if curTalisman then local talismanConFig = ConfigManager.GetConfigDataByDoubleKey(ConfigName.EquipTalismana, "TalismanaId", curTalisman.backData.equipId,"Level",curTalisman.star) if talismanConFig then for j = 1, #talismanConFig.OpenSkillRules do table.insert(allTalismanSkillList, talismanConFig.OpenSkillRules[j]) end end end end end return allTalismanSkillList end -- 获取技能表现 local _CombatList = {} function this.GetSkillCombat(id) if not _CombatList[id] then local combat = CombatControl[id] if not combat then return end _CombatList[id] = { Id = combat.Id, SkillType = combat.SkillType, VerticalDrawing = combat.VerticalDrawing, KeyFrame = combat.KeyFrame, Eterm = combat.Eterm, ShockScreen = combat.ShockScreen, Bullet = combat.Bullet, BulletTime = combat.BulletTime, Hit = combat.Hit, Offset = combat.Offset, skillname = combat.skillname, BeforeBullet = combat.BeforeBullet, SkillNumber = combat.SkillNumber, SkillDuration = combat.SkillDuration, BeforeOrientation = combat.BeforeOrientation, Orientation = combat.Orientation, HitOrientation = combat.HitOrientation, BeforeEffectType = combat.BeforeEffectType , EffectType = combat.EffectType , HitEffectType = combat.HitEffectType, BeforeOffset = combat.BeforeOffset, HitOffset = combat.HitOffset, SkillNameVoice = combat.SkillNameVoice, } end return _CombatList[id] end function this.SetSkillCombat(id, combat) _CombatList[id] = combat end ----- 战斗控制相关 ------------------ -- 是否解锁二倍速 function this.IsUnlockBattleSpeed() return PrivilegeManager.GetPrivilegeOpenStatus(PRIVILEGE_TYPE.DoubleTimesFight) end -- 是否解锁跳过功能 function this.IsUnlockBattlePass() -- return false return PrivilegeManager.GetPrivilegeOpenStatus(PRIVILEGE_TYPE.SkipFight) end -- 战斗暂停控制 this.IsPlay = 0 function this.StartBattle() if this.IsPlay == 0 then this.IsPlay = 1 end end function this.IsBattlePlaying() return this.IsPlay == 1 end function this.PauseBattle() if this.IsPlay == 1 then this.IsPlay = 2 end end function this.ResumeBattle() if this.IsPlay == 2 then this.IsPlay = 1 end end function this.StopBattle() this.IsPlay = 0 end function this.IsCanOperate() return this.IsPlay ~= 0 end -- 战斗加速控制 BATTLE_TIME_SCALE_ZERO = 0 BATTLE_TIME_SCALE_ONE= 1.1 BATTLE_TIME_SCALE_TWO = 2 this.TimeScale = 0 function this.InitTimeScale() this.TimeScale = 0 local _TimeScale = PlayerPrefs.GetFloat("battleTimeScaleKey", BATTLE_TIME_SCALE_ONE) this.SetTimeScale(_TimeScale) end function this.GetTimeScale() return this.TimeScale end function this.SetTimeScale(TimeScale) -- if TimeScale < 0 or not this.IsUnlockBattleSpeed() then--or this.IsFirstBattle()then TimeScale = BATTLE_TIME_SCALE_ONE end -- if TimeScale > BATTLE_TIME_SCALE_TWO then TimeScale = BATTLE_TIME_SCALE_TWO end if this.TimeScale ~= TimeScale then this.TimeScale = TimeScale PlayerPrefs.SetFloat("battleTimeScaleKey", this.TimeScale) -- 刷新前端显示 Game.GlobalEvent:DispatchEvent(GameEvent.Battle.OnTimeScaleChanged) -- 真正生效的敌方 Time.timeScale = TimeScale -- 设置音效播放的速度 SoundManager.SetAudioSpeed(TimeScale) end end -- 获取战斗界面层级 function this.GetBattleSorting() if UIManager.IsOpen(UIName.BattlePanel) then return BattlePanel.sortingOrder end if UIManager.IsOpen(UIName.BattleTestPanel) then return BattleTestPanel.sortingOrder end end -- 获取战斗背景 local bgConfig = { [1] = "r_zhandou_changjing017", [2] = "r_zhandou_changjing016", [3] = "r_zhandou_changjing017", [1001] = "r_zhandou_changjing018", [1002] = "r_zhandou_changjing019", } function this.GetBattleBg(fightType) if fightType == BATTLE_TYPE.STORY_FIGHT then local curChapter = FightPointPassManager.GetCurChapterIndex() local index = math.floor((curChapter + 1) % 3 + 1) return bgConfig[index] elseif fightType == BATTLE_TYPE.BACK then return bgConfig[1001] elseif fightType == BATTLE_TYPE.EXECUTE_FIGHT then return bgConfig[1002] else return bgConfig[1] end end return this