PGRData/Script/matrix/xentity/xsupersmashbros/XSmashBMonsterManager.lua

360 lines
14 KiB
Lua
Raw Permalink Normal View History

--===========================
--超限乱斗怪物组管理器
--模块负责:吕天元
--===========================
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