c1_lua/lua/app/userdata/chapter/chapter_data.lua
2025-09-26 15:41:46 +08:00

587 lines
14 KiB
Lua

local ChapterData = class("ChapterData", BaseData)
ChapterData.MIN_CHAPTER_ID = 1
local MIN_CHAPTER_ID = ChapterData.MIN_CHAPTER_ID
local CHAPTER_PAGE = 5
function ChapterData:ctor()
self.data.chapterId = MIN_CHAPTER_ID
self.data.maxChapterId = 0
self.data.isDirty = false
end
function ChapterData:clear()
self.data.chapterId = MIN_CHAPTER_ID
self.data.maxChapterId = 0
self.trailHeroId = nil
self.trailChapterId = nil
self.trailAtkInfo = nil
self.boxCanGetState = nil
self.canGetBoxInfo = nil
end
function ChapterData:init(data, notChangeChapterId)
if not data then
return
end
local cfg = self:getChapterCfg()[data.max_chapter_id]
if not cfg then
local maxChapterId = 0
for id, info in pairs(self:getChapterCfg()) do
if maxChapterId < id then
maxChapterId = id
end
end
data.max_chapter_id = maxChapterId
data.max_wave = self:getChapterCfgMaxWave(data.max_chapter_id)
end
self.maxWave = data.max_wave or 0
if self.maxWave >= self:getChapterCfgMaxWave(data.max_chapter_id) then
self.data.maxChapterId = data.max_chapter_id
else
self.data.maxChapterId = data.max_chapter_id - 1
end
if not notChangeChapterId then
self.data.chapterId = data.max_chapter_id
end
self.data.chapterInfo = data.chapter_info or {}
self.boxCanGetState = nil
self.canGetBoxInfo = {}
end
function ChapterData:getIsFirstChapter(chapterId)
return chapterId == MIN_CHAPTER_ID
end
function ChapterData:getIsFinalChapter(chapterId)
local chapterInfo = self:getChapterCfg()[chapterId]
if chapterInfo == nil then
return false
end
local chapterId = chapterInfo.next_chapter
if chapterId == nil then
return true
end
return false
end
function ChapterData:setDirty()
self.data.isDirty = not self.data.isDirty
end
function ChapterData:getChapterId()
return self.data.chapterId
end
function ChapterData:setChapterId(chapterId)
self.data.chapterId = chapterId
end
function ChapterData:getNextChapter(chapterId)
local chapterInfo = self:getChapterCfg()[chapterId]
if chapterInfo == nil then
return 1
end
if chapterInfo.next_chapter == nil then
return chapterId
end
return chapterInfo.next_chapter
end
function ChapterData:getNewChapterId()
return self:getNextChapter(self:getMaxChapterId())
end
function ChapterData:isFinalChapter(chapterId)
local chapterInfo = self:getChapterCfg()[chapterId]
if chapterInfo == nil then
return true
end
return chapterInfo.next_chapter == nil
end
function ChapterData:goNextChapter()
local chapterId = self:getNextChapter(self.data.chapterId)
if self.data.chapterId == chapterId then
return false
else
self.data.chapterId = chapterId
end
return true
end
function ChapterData:goLastChapter()
local chapterInfo = self:getChapterCfg()[self.data.chapterId]
if chapterInfo == nil then
return false
end
local chapterId = chapterInfo.before_chapter
if chapterId == nil then
return false
end
self.data.chapterId = chapterId
return true
end
function ChapterData:getChapterCfg()
if self.chapterCfg == nil then
self.chapterCfg = ConfigManager:getConfig("chapter")
end
return self.chapterCfg
end
function ChapterData:getChapterBoxCount(chapterId)
chapterId = chapterId or self:getChapterId()
local cfg = self:getChapterCfg()[chapterId]
if cfg and cfg.box_num then
return #cfg.box_num
end
return 1
end
function ChapterData:getChapterBoxNum(chapterId, index)
chapterId = chapterId or self:getChapterId()
local cfg = self:getChapterCfg()[chapterId]
if cfg and cfg.box_num then
return cfg.box_num[index] or 1
end
return 1
end
function ChapterData:clearChapterBoxState()
self.boxCanGetState = nil
end
function ChapterData:getChapterBoxCanGet()
if self.boxCanGetState == nil then
self:calcChapterBoxCanGet()
end
return self.boxCanGetState or false
end
function ChapterData:calcChapterBoxCanGet()
local maxChapterId = self:getNextChapter(self.data.maxChapterId)
for chapterId = 1, maxChapterId do
for ii = 1, 3 do
local canGet = self:boxCanGet(chapterId, ii)
if canGet then
self.boxCanGetState = true
return
end
end
end
self.boxCanGetState = false
end
function ChapterData:getChapterBoxCanGetInfo()
self.canGetBoxInfo = {}
local maxChapterId = self:getNextChapter(self.data.maxChapterId)
for chapterId = 1, maxChapterId do
local boxes = {}
for i = 1, 3 do
local canGet = self:boxCanGet(chapterId, i)
if canGet then
table.insert(boxes, i)
end
end
if #boxes > 0 then
table.insert(self.canGetBoxInfo, {id = chapterId, boxes = boxes})
end
end
return self.canGetBoxInfo
end
function ChapterData:getChapterBoxRewardGot(chapterId, index)
chapterId = chapterId or self:getChapterId()
local info = self.data.chapterInfo[chapterId]
if not info or not info.index then
return false
end
for _, idx in ipairs(info.index) do
if idx == index then
return true
end
end
return false
end
function ChapterData:boxCanGet(chapterId, index)
if self:getChapterBoxRewardGot(chapterId, index) then
return false
end
local needWave = DataManager.ChapterData:getChapterBoxNum(chapterId, index)
local curMaxWave = DataManager.ChapterData:getChapterMaxWave(chapterId)
return needWave <= curMaxWave
end
function ChapterData:getChapterBoxRewardList(chapterId)
local list = {}
local cfg = self:getChapterCfg()[chapterId]
if cfg then
for i = 1, 3 do
table.insert(list, cfg["box_reward_" .. i])
end
end
return list
end
function ChapterData:getChapterMaxWave(chapterId)
chapterId = chapterId or self:getChapterId()
if chapterId <= self.data.maxChapterId then
return self:getChapterCfgMaxWave(chapterId)
elseif chapterId == self:getNextChapter(self.data.maxChapterId) then
return self.maxWave
else
return 0
end
end
function ChapterData:getChapterCfgMaxWave(chapterId)
if not self.chapterCfgMaxWaveMap then
self.chapterCfgMaxWaveMap = {}
end
if not self.chapterCfgMaxWaveMap[chapterId] then
local chapterInfo = self:getChapterCfg()[chapterId]
if not chapterInfo then
self.chapterCfgMaxWaveMap[chapterId] = 1
else
self.chapterCfgMaxWaveMap[chapterId] = #chapterInfo.monster
end
end
return self.chapterCfgMaxWaveMap[chapterId]
end
function ChapterData:getChapterFightCount(chapterId)
chapterId = chapterId or self:getChapterId()
if self.data.chapterInfo[chapterId] then
return self.data.chapterInfo[chapterId].total_count or 0
end
return 0
end
function ChapterData:getFightCost()
return GFunc.getConstReward("chapter_cost")
end
function ChapterData:getMaxChapterId()
return self.data.maxChapterId
end
-- 得到有奖励的最小章节,如果没有,就是当前章节
function ChapterData:getIsHaveRewardsMinId()
local chapterBefore = MIN_CHAPTER_ID
local chapterCfg = self:getChapterCfg()
local chapterInfo = chapterCfg[chapterBefore]
while true do
if self:getIsHaveRewards(chapterBefore) then
break
end
if chapterBefore == self.data.maxChapterId then
chapterBefore = self:getNextChapter(self.data.maxChapterId)
break
end
chapterBefore = chapterInfo.next_chapter
if chapterBefore == nil then
break
end
chapterInfo = chapterCfg[chapterBefore]
if chapterInfo == nil then
break
end
end
if not chapterBefore then
chapterBefore = self:getNextChapter(self.data.maxChapterId)
end
return chapterBefore
end
-- 此章节是否有可领但是未领取的奖励
function ChapterData:getIsHaveRewards(chapterId)
if chapterId > self.data.maxChapterId + 1 then
return false
end
local info = self.data.chapterInfo[chapterId]
if not info or not info.index then
return false
end
local count = self:getChapterBoxCount(chapterId)
if info.index and #info.index == count then -- 数量一致说明都领完了
return false
elseif chapterId < self.data.maxChapterId then
return true
end
local curMaxWave = self:getChapterMaxWave(chapterId)
for i = 1, count do
local needWave = self:getChapterBoxNum(chapterId, i)
local rewardGot = self:getChapterBoxRewardGot(chapterId, i)
if needWave <= curMaxWave and not rewardGot then -- 有可以领但是没有领的奖励
return true
end
end
return false
end
function ChapterData:getChapterPassed(chapterId)
chapterId = chapterId or self:getChapterId()
if chapterId <= self.data.maxChapterId then
return true
else
return self.maxWave >= self:getChapterCfgMaxWave(chapterId)
end
end
function ChapterData:openBox()
local maxChapterId = self:getNextChapter(self.data.maxChapterId)
for chapterId = 1, maxChapterId do
self.data.chapterInfo[chapterId] = self.data.chapterInfo[chapterId] or {total_count = 0, index = {}, mystery_box_idx = {}}
for i = 1, 3 do
local canGet = self:boxCanGet(chapterId, i)
if canGet then
self.data.chapterInfo[chapterId].index[i] = i
end
end
end
self.boxCanGetState = nil
self:setDirty()
end
function ChapterData:fightChapter(chapterId, maxChapterId, maxWave, mysteryBoxIdx)
if not self.data.chapterInfo[chapterId] then
self.data.chapterInfo[chapterId] = {
total_count = 0,
index = {},
mystery_box_idx = {}
}
end
self.data.chapterInfo[chapterId].total_count = (self.data.chapterInfo[chapterId].total_count or 0) + 1
if maxChapterId <= self.data.maxChapterId then
return
end
self.data.chapterId = maxChapterId
self.maxWave = maxWave
if self.maxWave >= self:getChapterCfgMaxWave(maxChapterId) then
self.data.maxChapterId = maxChapterId
else
self.data.maxChapterId = maxChapterId - 1
end
for _, idx in ipairs(mysteryBoxIdx) do
if not self:getChapterMysteryBoxIsGot(chapterId, idx) then
table.insert(self.data.chapterInfo[chapterId].mystery_box_idx, idx)
end
end
self:setDirty()
end
function ChapterData:getChapterMysteryBoxReward(chapterId)
local cfg = self:getChapterCfg()[chapterId]
if not cfg then
return
end
return cfg.mystery_box_reward
end
function ChapterData:getChapterMysteryBoxRewardCount(chapterId)
local cfg = self:getChapterCfg()[chapterId]
if not cfg then
return 0
end
if cfg.mystery_box_reward then
return #cfg.mystery_box_reward
else
return 0
end
end
function ChapterData:getChapterMysteryBoxIsGot(chapterId, index)
if not self.data.chapterInfo[chapterId] then
return false
end
if not self.data.chapterInfo[chapterId].mystery_box_idx then
return false
end
for _, idx in ipairs(self.data.chapterInfo[chapterId].mystery_box_idx) do
if idx == index then
return true
end
end
return false
end
function ChapterData:getGoldDrop()
local info = self:getChapterCfg()[self:getMaxChapterId()]
if info == nil then
return 0
end
return info.idle_gold
end
function ChapterData:getExpDrop()
local info = self:getChapterCfg()[self:getMaxChapterId()]
if info == nil then
return 0
end
return info.idle_exp
end
function ChapterData:getChapterMysteryBoxGotCount(chapterId)
if not self.data.chapterInfo[chapterId] then
return 0
end
if not self.data.chapterInfo[chapterId].mystery_box_idx then
return 0
end
return #self.data.chapterInfo[chapterId].mystery_box_idx
end
function ChapterData:getNeedShowTouchCancelTips()
if not self.linkTouchCancelCount then
self.linkTouchCancelCount = LocalData:getLinkTouchCancelCount()
self.linkTouchCancelHideCount = GFunc.getConstIntValue("canle_link_hide")
end
if self.linkTouchCancelCount >= self.linkTouchCancelHideCount then
return false
end
if not self.showTouchCancelChapter then
self.showTouchCancelChapter = GFunc.getConstIntValue("cancle_link_show")
end
return self:getChapterPassed(self.showTouchCancelChapter)
end
function ChapterData:addLinkTouchCancelCount()
self:getNeedShowTouchCancelTips()
local newCount = self.linkTouchCancelHideCount + 1
if self.linkTouchCancelCount < self.linkTouchCancelHideCount and newCount >= self.linkTouchCancelHideCount then
LocalData:setLinkTouchCancelCount(newCount)
end
self.linkTouchCancelCount = newCount
end
function ChapterData:cacheTrailHeroIdAndChapterId(heroId, chapterId)
if self.markTrailHeroTag == nil then
self.markTrailHeroTag = LocalData:GetMarktrailHero() == 1
end
if self.markTrailHeroTag then
self.trailHeroId = nil
self.trailChapterId = nil
return
end
local heroEntity = DataManager.HeroData:getHeroById(heroId)
if not heroEntity or heroEntity:isActived() then -- 不存在或者已经激活
self.trailHeroId = nil
self.trailChapterId = nil
return
end
self.trailHeroId = heroId
self.trailChapterId = chapterId
end
function ChapterData:MarkTrailHero()
self.markTrailHeroTag = true
LocalData:MarkTrailHero()
end
function ChapterData:getCacheTrialHeroIdAndChapterId()
local heroEntity = DataManager.HeroData:getHeroById(self.trailHeroId)
if not heroEntity or heroEntity:isActived() then -- 不存在或者已经激活
self.trailHeroId = nil
self.trailChapterId = nil
end
return self.trailHeroId, self.trailChapterId
end
function ChapterData:cacheTrailAtkInfo(atkInfo)
self.trailAtkInfo = atkInfo
end
function ChapterData:getCacheTrailAtkInfo()
return self.trailAtkInfo
end
--@region 主线章节
function ChapterData:getChapterList(chapterPage)
if self.chapterCfgList == nil then
self.chapterCfgList = {}
local cfg = self:getChapterCfg()
for i, v in ipairs(cfg) do
v.chapterId = i
self.chapterCfgList[v.chapter] = self.chapterCfgList[v.chapter] or {}
table.insert(self.chapterCfgList[v.chapter], v)
end
end
if chapterPage then
return self.chapterCfgList[chapterPage]
end
return self.chapterCfgList
end
function ChapterData:getChapterCfgByPageAndStage(chapterPage, stage)
local cfg = self:getChapterList(chapterPage)
if not cfg[stage] then
return
end
return cfg[stage].chapterId
end
function ChapterData:getChapterPage(chapterId)
local info = self:getChapterCfg()[chapterId]
if info == nil then
return 1
end
return info.chapter
end
function ChapterData:getChapterStage(chapterId)
local info = self:getChapterCfg()[chapterId]
if info == nil then
return 1
end
return info.stage
end
-- 返回x-x格式的章节关卡名称
function ChapterData:getChapterNameXYMode(chapterId)
local chapterCfg = self:getChapterCfg()[chapterId]
if chapterCfg then
return string.format("%s-%s",chapterCfg.chapter_id, chapterCfg.stage_num)
end
return chapterId
end
--@endregion
--@region 红点
function ChapterData:showRedPoint(chapterId)
chapterId = chapterId or self:getChapterId()
local list = self:getChapterBoxRewardList(chapterId)
for i = 1, #list do
if self:boxCanGet(chapterId, i) then
return true
end
end
return false
end
--@endregion
return ChapterData