360 lines
No EOL
14 KiB
Lua
360 lines
No EOL
14 KiB
Lua
--===========================
|
||
--超限乱斗怪物组管理器
|
||
--模块负责:吕天元
|
||
--===========================
|
||
local XSmashBMonsterManager = {}
|
||
local MonsterGroups
|
||
local MonsterGroupDicById
|
||
local Monsters
|
||
local MonsterDicById
|
||
local MonsterScript = require("XEntity/XSuperSmashBros/XSmashBMonster")
|
||
local IsAscendOrder
|
||
--=================
|
||
--筛选方法(筛选界面配套)
|
||
--=================
|
||
local SortFunctionDic = {
|
||
[XRoomCharFilterTipsConfigs.EnumSortTag.Ability] = function(monsterA, monsterB)
|
||
if IsAscendOrder then
|
||
return monsterA:GetAbility() > monsterB:GetAbility()
|
||
else
|
||
return monsterA:GetAbility() < monsterB:GetAbility()
|
||
end
|
||
end,
|
||
[XRoomCharFilterTipsConfigs.EnumSortTag.SSBMonster] = function(monsterA, monsterB)
|
||
if IsAscendOrder then
|
||
return monsterA:GetMonsterType() > monsterB:GetMonsterType()
|
||
else
|
||
return monsterA:GetMonsterType() < monsterB:GetMonsterType()
|
||
end
|
||
end,
|
||
[XRoomCharFilterTipsConfigs.EnumSortTag.SSBMonsterDefault] = function(monsterA, monsterB)
|
||
if IsAscendOrder then
|
||
return monsterA:GetMonsterType() >= monsterB:GetMonsterType() and monsterA:GetAbility() > monsterB:GetAbility()
|
||
else
|
||
return monsterA:GetMonsterType() <= monsterB:GetMonsterType() and monsterA:GetAbility() < monsterB:GetAbility()
|
||
end
|
||
end
|
||
}
|
||
--=============
|
||
--初始化管理器
|
||
--=============
|
||
function XSmashBMonsterManager.Init(activityId)
|
||
MonsterGroups = nil
|
||
MonsterGroupDicById = nil
|
||
Monsters = nil
|
||
MonsterDicById = nil
|
||
end
|
||
--=============
|
||
--刷新后台推送活动数据
|
||
--=============
|
||
function XSmashBMonsterManager.RefreshNotifyMonsterData(data)
|
||
|
||
end
|
||
--=============
|
||
--刷新怪物组胜利次数数据
|
||
--=============
|
||
function XSmashBMonsterManager.RefreshMonsterGroupWinCount(winCountList)
|
||
for _, monsterGroupWinCount in pairs(winCountList or {}) do
|
||
local monsterGroup = XSmashBMonsterManager.GetMonsterGroupById(monsterGroupWinCount.Id)
|
||
if monsterGroup then
|
||
monsterGroup:SetWinCount(monsterGroupWinCount.WinCount)
|
||
end
|
||
end
|
||
end
|
||
--=============
|
||
--根据怪物Id获取怪物对象
|
||
--@param
|
||
--monsterId : 怪物Id SuperSmashBrosMonster Id
|
||
--=============
|
||
function XSmashBMonsterManager.GetMonsterById(monsterId)
|
||
if not Monsters then
|
||
XSmashBMonsterManager.CreateMonsters()
|
||
end
|
||
return MonsterDicById[monsterId]
|
||
end
|
||
--=============
|
||
--创建所有怪物对象
|
||
--=============
|
||
function XSmashBMonsterManager.CreateMonsters()
|
||
Monsters = {}
|
||
MonsterDicById = {}
|
||
local allMonsters = XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.MonsterConfig)
|
||
local script = require("XEntity/XSuperSmashBros/XSmashBMonster")
|
||
for id, monsterCfg in pairs(allMonsters) do
|
||
local monster = script.New(monsterCfg)
|
||
table.insert(Monsters, monster)
|
||
MonsterDicById[id] = monster
|
||
end
|
||
end
|
||
--=============
|
||
--根据怪物组Id获取怪物组对象
|
||
--@param
|
||
--monsterId : 怪物Id SuperSmashBrosMonster Id
|
||
--=============
|
||
function XSmashBMonsterManager.GetMonsterGroupById(monsterGroupId)
|
||
if not MonsterGroups then
|
||
XSmashBMonsterManager.CreateMonsterGroups()
|
||
end
|
||
return MonsterGroupDicById[monsterGroupId]
|
||
end
|
||
--=============
|
||
--创建所有怪物对象
|
||
--=============
|
||
function XSmashBMonsterManager.CreateMonsterGroups()
|
||
MonsterGroups = {}
|
||
MonsterGroupDicById = {}
|
||
local allMonsterGroups = XSuperSmashBrosConfig.GetAllConfigs(XSuperSmashBrosConfig.TableKey.MonsterGroupConfig)
|
||
local script = require("XEntity/XSuperSmashBros/XSmashBMonsterGroup")
|
||
for id, monsterGroupCfg in pairs(allMonsterGroups) do
|
||
local monsterGroup = script.New(monsterGroupCfg)
|
||
table.insert(MonsterGroups, monsterGroup)
|
||
MonsterGroupDicById[id] = monsterGroup
|
||
end
|
||
end
|
||
--=============
|
||
--根据模式Id获取已首通的怪物组数量
|
||
--@param
|
||
--modeId : 模式Id SuperSmashBrosMode Id
|
||
--=============
|
||
function XSmashBMonsterManager.GetPassMonstersNumByModeId(modeId)
|
||
local monsterList = XSmashBMonsterManager.GetMonsterGroupListByModeId(modeId)
|
||
local result = 0
|
||
for _, monsterGroup in pairs(monsterList) do
|
||
if monsterGroup:CheckIsClear() then
|
||
result = result + 1
|
||
end
|
||
end
|
||
return result
|
||
end
|
||
--=============
|
||
--根据怪物Id列表获取怪物对象组
|
||
--=============
|
||
function XSmashBMonsterManager.GetMonstersByIdList(idList)
|
||
local result = {}
|
||
for _, id in pairs(idList or {}) do
|
||
local monster = XSmashBMonsterManager.GetMonsterById(id)
|
||
if monster then
|
||
table.insert(result, monster)
|
||
end
|
||
end
|
||
return result
|
||
end
|
||
--=============
|
||
--根据模式Id获取所有怪物组
|
||
--@param
|
||
--modeId : 模式Id SuperSmashBrosMode Id
|
||
--=============
|
||
function XSmashBMonsterManager.GetMonsterGroupListByModeId(modeId)
|
||
local mode = XDataCenter.SuperSmashBrosManager.GetModeByModeType(modeId)
|
||
local allGroups = XSuperSmashBrosConfig.GetCfgByIdKey(XSuperSmashBrosConfig.TableKey.Group2MonsterGroupDic, mode:GetMonsterLibraryId(), true)
|
||
local result = {}
|
||
for _, group in pairs(allGroups) do
|
||
local temp = XSmashBMonsterManager.GetMonsterGroupById(group.Id)
|
||
if temp then
|
||
table.insert(result, temp)
|
||
end
|
||
end
|
||
table.sort(result, function(monsterGroupA, monsterGroupB)
|
||
return monsterGroupA:GetId() < monsterGroupB:GetId()
|
||
end)
|
||
return result
|
||
end
|
||
--=============
|
||
--根据Id列表获取所有怪物组列表
|
||
--@param
|
||
--monsterGourpIdList : MonsterGroup Id列表
|
||
--=============
|
||
function XSmashBMonsterManager.GetMonsterGroupListByIdList(monsterGourpIdList)
|
||
local result = {}
|
||
for _, id in pairs(monsterGourpIdList or {}) do
|
||
local monsterGroup = MonsterGroupDicById[id or 0]
|
||
if monsterGroup then
|
||
table.insert(result, monsterGroup)
|
||
end
|
||
end
|
||
return result
|
||
end
|
||
--=============
|
||
--怪物列表排序(排序筛选界面用)
|
||
--@param
|
||
--monsters : 要排序MonsterGroup列表
|
||
--sortTagType :检索标签类型
|
||
--isAscendOrder : true 升序 false 降序
|
||
--=============
|
||
function XSmashBMonsterManager.SortMonsters(monsters, 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 clearMonsters = {}
|
||
local isFirstFightMonsters = {}
|
||
for key, monster in pairs(monsters) do
|
||
if monster:CheckIsClear() then
|
||
table.insert(clearMonsters, monster)
|
||
else
|
||
table.insert(isFirstFightMonsters, monster)
|
||
end
|
||
end
|
||
table.sort(clearMonsters, SortFunctionDic[sortTagType])
|
||
table.sort(isFirstFightMonsters, SortFunctionDic[sortTagType])
|
||
|
||
return appendArray(isFirstFightMonsters, clearMonsters)
|
||
end
|
||
--=============
|
||
--进入模式处理,选择随机怪兽
|
||
--@param
|
||
--monsterIdList : 选择的怪兽Id列表
|
||
--stageId : 选择的地图Id,用于筛选掉不符合地图的怪兽
|
||
--modeId : 选择的模式Id
|
||
--=============
|
||
function XSmashBMonsterManager.SelectRandomMonster(monsterIdList, stageId, modeId)
|
||
if not MonsterGroups then
|
||
XSmashBMonsterManager.CreateMonsterGroups()
|
||
end
|
||
local monsterGroup = XSmashBMonsterManager.GetMonsterGroupListByModeId(modeId)
|
||
local mode = XDataCenter.SuperSmashBrosManager.GetModeByModeType(modeId)
|
||
|
||
local monsterNum = #monsterGroup --总的怪物组数目
|
||
local monsterIdDic = {} --队伍中已经被选择的怪物组Id字典
|
||
local bossLimit = mode:GetBossLimit()
|
||
local bossNum = 0 --统计已选定的怪物组中的首领级怪物组数目
|
||
for _, monsterId in pairs(monsterIdList) do
|
||
if monsterId > 0 then
|
||
monsterIdDic[monsterId] = true --已经选择了的怪物组放入字典中
|
||
local monster = XSmashBMonsterManager.GetMonsterGroupById(monsterId)
|
||
local isBoss = monster:GetMonsterType() == XSuperSmashBrosConfig.MonsterType.Boss
|
||
bossNum = bossNum + (isBoss and 1 or 0)
|
||
end
|
||
end
|
||
local isSelectBoss = bossNum < bossLimit --是否需要选择首领级怪物
|
||
--分开首战,非首战怪物组
|
||
local firstBattleMonsterDic = {} --首战怪物组
|
||
local clearBattleMonsterDic = {} --非首战怪物组
|
||
for _, monster in pairs(monsterGroup) do
|
||
if monsterIdDic[monster:GetId()] then
|
||
goto continue
|
||
end
|
||
local isStageLimit = monster:CheckLimitStage(stageId) --检查怪物组是否受地图限制出战
|
||
if isStageLimit then
|
||
goto continue
|
||
end
|
||
local isBoss = monster:GetMonsterType() == XSuperSmashBrosConfig.MonsterType.Boss
|
||
if not isSelectBoss and isBoss then
|
||
goto continue
|
||
end
|
||
local isFirst = not monster:CheckIsClear()
|
||
if isFirst then
|
||
table.insert(firstBattleMonsterDic, monster)
|
||
else
|
||
table.insert(clearBattleMonsterDic, monster)
|
||
end
|
||
:: continue ::
|
||
end
|
||
|
||
local resultList = {}
|
||
for index, monsterId in pairs(monsterIdList) do
|
||
--按以下流程随机
|
||
--1.检测是不是随机位
|
||
--1-1.是随机位
|
||
--1-1-1.先检查首战怪物组中有没成员,有的话从中随机,随机一个数字
|
||
--1-1-1-1.检查是否超过最多选择的首领级怪物组数目
|
||
--1-1-1-2.超过而且随机的是首领的话从首战怪物组字典删去该项,重新到步骤1-1
|
||
--1-1-1-3.不超过而且是首领的话把选中首领怪物组的数目+1
|
||
--1-1-1-4.随机成功,记录在队伍Id字典和结果Id中,之后从首战怪物组字典删去该项
|
||
--1-1-1-5.给随机位赋值结果Id
|
||
--1-1-2.检查复刷怪物组中有没成员,具体内部步骤同1-1-1-X首战怪物组
|
||
--1-1-3.若首战怪物组和复刷怪物组中皆没有成员,给随机位赋值0(空位)
|
||
if monsterId == XSuperSmashBrosConfig.PosState.Random or
|
||
monsterId == XSuperSmashBrosConfig.PosState.OnlyRandom then
|
||
local result = 0
|
||
isSelectBoss = bossNum < bossLimit --是否需要选择首领级怪物
|
||
:: GroupRandom ::
|
||
if #firstBattleMonsterDic > 0 then
|
||
local random = math.random(1, #firstBattleMonsterDic)
|
||
local isBoss = firstBattleMonsterDic[random]:GetMonsterType() == XSuperSmashBrosConfig.MonsterType.Boss
|
||
if not isSelectBoss and isBoss then
|
||
table.remove(firstBattleMonsterDic, random)
|
||
goto GroupRandom
|
||
elseif isBoss then
|
||
bossNum = bossNum + 1
|
||
end
|
||
local randomId = firstBattleMonsterDic[random]:GetId()
|
||
monsterIdDic[randomId] = true
|
||
table.remove(firstBattleMonsterDic, random)
|
||
result = randomId
|
||
elseif #clearBattleMonsterDic > 0 then
|
||
local random = math.random(1, #clearBattleMonsterDic)
|
||
local isBoss = clearBattleMonsterDic[random]:GetMonsterType() == XSuperSmashBrosConfig.MonsterType.Boss
|
||
if not isSelectBoss and isBoss then
|
||
table.remove(clearBattleMonsterDic, random)
|
||
goto GroupRandom
|
||
elseif isBoss then
|
||
bossNum = bossNum + 1
|
||
end
|
||
local randomId = clearBattleMonsterDic[random]:GetId()
|
||
monsterIdDic[randomId] = true
|
||
table.remove(clearBattleMonsterDic, random)
|
||
result = randomId
|
||
else
|
||
result = 0
|
||
end
|
||
resultList[index] = result
|
||
elseif monsterId > 0 then
|
||
resultList[index] = monsterId
|
||
else
|
||
resultList[index] = 0
|
||
end
|
||
end
|
||
return resultList
|
||
end
|
||
--===================
|
||
--设置出战怪物组剩余生命值
|
||
--@params:
|
||
--enemyTeam : 怪物组Id列表
|
||
--monsterProgress :
|
||
--===================
|
||
function XSmashBMonsterManager.SetMonsterTeamLeftHp(enemyTeam, monsterProgress, monsterHpResultList, monsterBattleNum)
|
||
for index, enemyId in pairs(enemyTeam or {}) do
|
||
local monsterGroup = XSmashBMonsterManager.GetMonsterGroupById(enemyId)
|
||
if monsterGroup and index < monsterProgress then
|
||
monsterGroup:SetHpLeft(0)
|
||
elseif monsterGroup and monsterHpResultList and index < (monsterProgress + monsterBattleNum) then
|
||
--这里剩余怪物同一ID的怪物状态刷新不能记录哪个怪兽属于哪个组
|
||
--这种情况会发生计算错误,需要策划配置时回避
|
||
local total = 0 --怪兽组总血量
|
||
local left = 0 --怪兽组总剩余血量
|
||
local monsterIds = {}
|
||
for _, monsterId in pairs(monsterGroup:GetMonsterIdList()) do
|
||
local monster = XSmashBMonsterManager.GetMonsterById(monsterId)
|
||
if monster then
|
||
monsterIds[monster:GetMonsterId()] = true
|
||
end
|
||
end
|
||
for _, info in pairs(monsterHpResultList or {}) do
|
||
if monsterIds[info.NpcId] and info.AttrTable[1] then
|
||
total = total + info.AttrTable[1].MaxValue
|
||
left = left + info.AttrTable[1].Value
|
||
end
|
||
end
|
||
monsterGroup:SetHpLeft((total == 0 and 100) or (left / total * 100))
|
||
else
|
||
monsterGroup:SetHpLeft(100)
|
||
end
|
||
end
|
||
end
|
||
--===================
|
||
--根据怪物组Id列表重置怪物组剩余生命值
|
||
--===================
|
||
function XSmashBMonsterManager.ResetMonsterGroupHpLeftByIdList(idList)
|
||
for _, monsterGroupId in pairs(idList or {}) do
|
||
if monsterGroupId > 0 then
|
||
local monsterGroup = XSmashBMonsterManager.GetMonsterGroupById(monsterGroupId)
|
||
if monsterGroup then
|
||
monsterGroup:SetHpLeft(100)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
return XSmashBMonsterManager |