PGRData/Script/matrix/xentity/xsupersmashbros/XSmashBRoleManager.lua
2024-09-01 22:49:41 +02:00

436 lines
No EOL
16 KiB
Lua
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--===========================
--超限乱斗玩家角色管理器
--模块负责:吕天元
--===========================
local XSmashBRoleManager = {}
local Roles
local RoleDicById
local EggRobotList = {} --记录所有的彩蛋机器人 key = robotId , value = role
local RoleScript = require("XEntity/XSuperSmashBros/XSmashBRole") --超限乱斗角色数据
local XSmashBAssistanceMonster = require("XEntity/XSuperSmashBros/XSmashBAssistanceMonster")
local XRobot = require("XEntity/XRobot/XRobot")
local IsAscendOrder = true
local SortFunctionDic = {
[XRoomCharFilterTipsConfigs.EnumSortTag.Level] = function(roleA, roleB)
if IsAscendOrder then
return roleA:GetLevel() > roleB:GetLevel()
else
return roleA:GetLevel() < roleB:GetLevel()
end
end,
[XRoomCharFilterTipsConfigs.EnumSortTag.Quality] = function(roleA, roleB)
if IsAscendOrder then
return roleA:GetQuality() > roleB:GetQuality()
else
return roleA:GetQuality() < roleB:GetQuality()
end
end,
[XRoomCharFilterTipsConfigs.EnumSortTag.Ability] = function(roleA, roleB)
if IsAscendOrder then
return roleA:GetAbility() > roleB:GetAbility()
else
return roleA:GetAbility() < roleB:GetAbility()
end
end,
}
--=============
--初始化管理器
--=============
function XSmashBRoleManager.Init()
Roles = {}
RoleDicById = {}
XSmashBRoleManager.RegisterEvents()
end
--=============
--刷新后台推送活动数据
--=============
function XSmashBRoleManager.RefreshNotifyRoleData(data)
--TODO
end
--=============
--根据角色Id获取角色对象
--@param
--roleId : 角色Id,若是用户角色则传入CharacterId机器人传入RobotId
--=============
function XSmashBRoleManager.GetRoleById(roleId)
if XTool.IsTableEmpty(Roles) then
XSmashBRoleManager.GenerateRoleData()
end
return RoleDicById[roleId]
end
--=============
--注册事件
--=============
function XSmashBRoleManager.RegisterEvents()
--玩家角色增加时,增加成员
XEventManager.AddEventListener(XEventId.EVENT_CHARACTER_ADD_SYNC, XSmashBRoleManager.OnCharacterAdd)
end
--=============
--玩家角色增加时
--=============
function XSmashBRoleManager.OnCharacterAdd(character)
if character == nil then return end
if RoleDicById[character.Id] then return end
-- 防止错误判断Roles新增角色时先调用一遍初始化
if XTool.IsTableEmpty(Roles) then
XSmashBRoleManager.GenerateRoleData()
end
XSmashBRoleManager.AddNewRole(character)
end
--=============
--收集角色信息并添加
--=============
function XSmashBRoleManager.GenerateRoleData()
local characters = XDataCenter.CharacterManager.GetOwnCharacterList()
-- 拥有角色
for _, character in ipairs(characters) do
XSmashBRoleManager.AddNewRole(character)
end
-- 超限乱斗机器人
for _, robotCfg in ipairs(XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.SystemCharaConfig)) do
XSmashBRoleManager.AddNewRole(XRobot.New(robotCfg.RobotId))
end
-- 超限乱斗彩蛋机器人
for robot_id, v in pairs(XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.EggRobot)) do
XSmashBRoleManager.AddNewRole(XRobot.New(robot_id))
local eggRole = XSmashBRoleManager.GetRoleById(robot_id)
eggRole:SetSuperSmashEggRobot(v)
EggRobotList[robot_id] = eggRole
end
-- 怪物 3.0加入支援设定,以及可选支援怪物
local allAssistantConfig = XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.Assistance)
for i, assistantConfig in pairs(allAssistantConfig) do
if assistantConfig.AssistType == XSuperSmashBrosConfig.AssistType.Monster then
local role = XSmashBAssistanceMonster.New(assistantConfig)
XSmashBRoleManager.AddNewAssistanceMonster(role)
end
--支援表的机器人,不加入,防止与普通角色选择列表不一致
--if assistantConfig.AssistType == XSuperSmashBrosConfig.AssistType.Robot then
-- XSmashBRoleManager.AddNewRole(XRobot.New(assistantConfig.AssistId))
--end
end
end
--=============
--增加新角色
--@params :
-- roleData : XCharacter | XRobot
--=============
function XSmashBRoleManager.AddNewRole(roleData)
-- 如果已经存在,直接不处理
if RoleDicById[roleData.Id] then return end
local role = RoleScript.New(roleData)
table.insert(Roles, role)
RoleDicById[role:GetId()] = role
end
--=============
--增加新支援怪物
--@params :
-- roleData : XCharacter | XRobot
--=============
---@param role XSmashBAssistanceMonster
function XSmashBRoleManager.AddNewAssistanceMonster(role)
-- 如果已经存在,直接不处理
if RoleDicById[role:GetId()] then return end
table.insert(Roles, role)
RoleDicById[role:GetId()] = role
end
--=============
--获取所有角色列表
--=============
function XSmashBRoleManager.GetRoleList()
if XTool.IsTableEmpty(Roles) then
XSmashBRoleManager.GenerateRoleData()
end
return Roles
end
--=============
--获取所有彩蛋角色列表
--=============
function XSmashBRoleManager.GetEggRoleList()
if XTool.IsTableEmpty(EggRobotList) then
XSmashBRoleManager.GenerateRoleData()
end
return EggRobotList
end
--=============
-- 解锁重置可播放彩蛋动画,且解锁菜单机器人绑定和展示和核心 每次退出模式(包括胜利退出和放弃退出)并进入ready界面时重置 cxldV2
--=============
function XSmashBRoleManager.ResetEggRobotOpen()
-- 循环彩蛋角色列表
for robotId, char in pairs(EggRobotList) do
char:SetCloseEgg()
char:SetCore(nil) -- 解除核心
XSaveTool.SaveData(string.format("%d%dSuperSmashEggAnim", XPlayer.Id, char:GetId()), 0)
end
end
--==============
--根据角色类型获取所有角色列表
--@param:
--charaType:角色类型(构造体,授格者…)
--==============
function XSmashBRoleManager.GetRoleListByCharaType(charaType)
if XTool.IsTableEmpty(Roles) then
XSmashBRoleManager.GenerateRoleData()
end
if charaType == nil then
return Roles
end
local result = {}
for _, role in ipairs(Roles) do
if role:GetCharacterType() == charaType then
table.insert(result, role)
end
end
return result
end
--==============
--排序角色列表(筛选排列界面的配套方法)
--@param:
--roles:要排列的角色列表
--sortTagType:排序标签类型
--isAscendOrder:true为升序 false为降序
--==============
---@param roles XSmashBCharacter[]
function XSmashBRoleManager.SortRoles(roles, sortTagType, isAscendOrder)
if isAscendOrder == nil then isAscendOrder = true end
IsAscendOrder = isAscendOrder
if not sortTagType or (sortTagType == XRoomCharFilterTipsConfigs.EnumSortTag.Default) then
sortTagType = XRoomCharFilterTipsConfigs.EnumSortTag.Ability
end
local characterRoles = {}
local characterIdDic = {}
local robotRoles = {}
for _, role in ipairs(roles) do
if not role:IsNoCareer() then
if role:GetIsRobot() then
table.insert(robotRoles, role)
else
table.insert(characterRoles, role)
characterIdDic[role:GetId()] = role
end
end
end
table.sort(characterRoles, SortFunctionDic[sortTagType])
table.sort(robotRoles, SortFunctionDic[sortTagType])
return appendArray(characterRoles, robotRoles)
end
--==============
--获取设置真实队伍角色队伍数据
--@param:
--modeId:设置真实队伍的模式Id
--charaIdList:我方选择角色队伍Id列表(包含空位,随机位)
--==============
function XSmashBRoleManager.GetSetTeamRoleTeam(modeId, charaIdList)
local teamData = XDataCenter.SuperSmashBrosManager.GetDefaultTeamInfoByModeId(modeId)
local finalCharaIdList = XSmashBRoleManager.SelectRandomRole(teamData.RoleIds, modeId) --finalCharaIdList 随机后的最终id
local colorList = {}
for i, color in pairs(teamData.Color) do
colorList[i] = color
end
local resultTeam = {}
local resultColor = {}
local captainPos = teamData.CaptainPos
local firstFightPos = teamData.FirstFightPos
--检查队长位
--若设置的队长位是空位置则强制将其设置到第一个有角色Id的位置
if not finalCharaIdList[captainPos] or (finalCharaIdList[captainPos] == 0) then
for pos, finalCharaId in pairs(finalCharaIdList) do
if finalCharaId > 0 then
captainPos = pos
break
end
end
end
--检查首战位
--若设置的首战位是空位置则将其设置到第一个有角色Id的位置
if not finalCharaIdList[firstFightPos] or (finalCharaIdList[firstFightPos] == 0) then
for pos, finalCharaId in pairs(finalCharaIdList) do
if finalCharaId > 0 then
firstFightPos = pos
break
end
end
end
local captainColor = teamData.Color[captainPos]
local resultCaptainPos = 1
for index, finalCharaId in pairs(finalCharaIdList) do
if finalCharaId > 0 then
local roleId = teamData.RoleIds[index]
local isMonster = false
if roleId and roleId > 0 then
local role = XDataCenter.SuperSmashBrosManager.GetRoleById(roleId)
if role:IsNoCareer() then
isMonster = true
end
end
local isAssistance = teamData.Assistance[index]
table.insert(resultTeam, {
Id = finalCharaId,
IsRobot = not isMonster and XEntityHelper.GetIsRobot(finalCharaId),
IsRandom = teamData.RoleIds[index] == XSuperSmashBrosConfig.PosState.Random or teamData.RoleIds[index] == XSuperSmashBrosConfig.PosState.OnlyRandom,
GridIndex = index,
IsAssist = isAssistance,
})
table.insert(resultColor, (colorList[index] == 0 and 1) or colorList[index])
if captainColor == colorList[index] then resultCaptainPos = (captainColor == 0 and 1) or captainColor end
end
end
firstFightPos = resultCaptainPos --首战位统一和队长位相同
return resultTeam, resultColor, resultCaptainPos, firstFightPos
end
--==============
--选择随机角色
--@param:
--charaIdList:我方角色队伍Id列表(包含空位,随机位)
--modeId:进行随机的模式Id
--==============
function XSmashBRoleManager.SelectRandomRole(charaIdList, modeId)
local mode = XDataCenter.SuperSmashBrosManager.GetModeByModeType(modeId)
local isTeamBattle = mode:GetRoleBattleNum() > 1 --出战人数多于1人时就为组队制
--提取已选中角色的Id字典与获得队伍角色类型限制
local charaIdDic = {}
local charaType
for _, charaId in pairs(charaIdList) do
if charaId > 0 then
charaIdDic[charaId] = true
--组队模式要检查队内角色类型必须统一
if isTeamBattle and (not charaType) then
local role = XSmashBRoleManager.GetRoleById(charaId)
charaType = role:GetCharacterType()
end
end
end
--从所有角色池中构建符合队伍的随机角色池
local randomPool = {}
for _, role in pairs(Roles) do
if charaIdDic[role:GetId()] then --已经在队伍中的角色排除
goto nextRole
end
if role:GetIsRobot() then --试玩角色排除
goto nextRole
end
if role:IsNoCareer() then
goto nextRole
end
-- cxldV2 授格者已经可以混队
-- if isTeamBattle and charaType and (role:GetCharacterType() ~= charaType) then --组队模式下不和已在队伍中的角色统一类型的排除
-- goto nextRole
-- end
table.insert(randomPool, role)
:: nextRole ::
end
-- 开始随机
local resultList = {}
for index, charaId in pairs(charaIdList) do
if charaId == XSuperSmashBrosConfig.PosState.Random or
charaId == XSuperSmashBrosConfig.PosState.OnlyRandom then
local result = 0
-- :: randomAgain ::
local roleNum = #randomPool
if roleNum > 0 then
local random = math.random(1, roleNum)
local randomId = randomPool[random]:GetId()
-- cxldV2 授格者已经可以混队
-- local randomCharaType = randomPool[random]:GetCharacterType()
-- if not charaType then
-- charaType = randomCharaType
-- elseif randomCharaType ~= charaType then
-- table.remove(randomPool, random)
-- goto randomAgain
-- end
table.remove(randomPool, random)
result = randomId
end
resultList[index] = result
elseif charaId > 0 then
resultList[index] = charaId
else
resultList[index] = 0
end
end
return resultList
end
function XSmashBRoleManager.SetBattleRoleLeftHp(battleTeam, characterProgress, characterHpResultList)
for index, charaId in pairs(battleTeam or {}) do
local role = XSmashBRoleManager.GetRoleById(charaId)
if role then
--这里先把所有被淘汰(出场索引在现起始出战索引之前)的角色Hp设置为0
--其他都初始化为满血,在后面再根据数据设置剩余血量
if index < characterProgress then
role:SetHpLeft(0)
else
role:SetHpLeft(100)
end
end
end
for _, charaInfo in pairs(characterHpResultList or {}) do
local role = XSmashBRoleManager.GetRoleById(charaInfo.CharacterId)
if role then
role:SetHpLeft(charaInfo.HpPercent)
role:SetSpLeft(charaInfo.Energy)
end
end
end
function XSmashBRoleManager.GetAssistantRoleList()
local result = {}
-- 怪物 3.0加入支援设定,以及可选怪物
local allAssistantConfig = XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.Assistance)
for i, assistantConfig in pairs(allAssistantConfig) do
if assistantConfig.AssistType == XSuperSmashBrosConfig.AssistType.Monster then
result[#result + 1] = XSmashBRoleManager.GetRoleById(assistantConfig.AssistId)
end
end
-- 自己的角色
for i, assistantConfig in pairs(allAssistantConfig) do
if assistantConfig.AssistType == XSuperSmashBrosConfig.AssistType.Character then
result[#result + 1] = XSmashBRoleManager.GetRoleById(assistantConfig.AssistId)
end
end
-- 机器人
for i, assistantConfig in pairs(allAssistantConfig) do
if assistantConfig.AssistType == XSuperSmashBrosConfig.AssistType.Robot then
result[#result + 1] = XSmashBRoleManager.GetRoleById(assistantConfig.AssistId)
end
end
-- 为了迎合指引将特定id放到第一位
for i = 1, #result do
local role = result[i]
if role:GetId() == 81900 then
table.remove(result, i)
table.insert(result, 1, role)
break
end
end
-- 角色
--local characters = XDataCenter.CharacterManager.GetOwnCharacterList()
--for i, character in pairs(characters) do
-- local characterId = character:GetId()
-- local assistantConfig = XSuperSmashBrosConfig.GetCfgByIdKey(XSuperSmashBrosConfig.TableKey.Assistance, characterId, true)
-- if assistantConfig then
-- local robot = XDataCenter.SuperSmashBrosManager.GetRoleById(characterId)
-- result[#result + 1] = robot
-- end
--end
-- 机器人
--for _, robotCfg in ipairs(XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.SystemCharaConfig)) do
-- local robotId = robotCfg.RobotId
-- local characterId = XRobotManager.GetCharacterId(robotId)
-- local assistantConfig = XSuperSmashBrosConfig.GetCfgByIdKey(XSuperSmashBrosConfig.TableKey.Assistance, characterId, true)
-- if assistantConfig then
-- local robot = XDataCenter.SuperSmashBrosManager.GetRoleById(robotId)
-- result[#result + 1] = robot
-- end
--end
return result
end
return XSmashBRoleManager