PsionicModel = PsionicModel or BaseClass(BaseVo, true) local PsionicModel = PsionicModel local GetFighting = GetFighting local stringtotable = stringtotable function PsionicModel:__init() PsionicModel.Instance = self self:Reset() end function PsionicModel:Reset() self.psionic_lv = 0 -- 圣物等级 self.psionic_exp = 0 -- 圣物经验值 self.ps_slot_data = {} -- 圣物槽位信息 self.psionic_bag_data = nil -- 圣物装备背包 self.psionic_equip_data = nil -- 圣物装备栏 self.psionic_dig_data = {} -- 圣物抽奖面板信息 self.psionic_skill_vo_list = {} -- 圣物技能主动技能vo列表 -- 红点缓存 self.psionic_red_cache = {} -- 圣物红点缓存 self.ps_main_effect_red = false -- 圣物圣环红点按钮缓存 self.ps_resolve_btn_red = false -- 圣物分解提示红点 self.psionic_equip_slot_red = {} -- 圣物系统可装备槽位红点 self.psionic_power_higher_bagitem = {} -- 圣物背包中属性更高的装备列表,格式 = {goods_id = goods_id, ...} self.psionic_power_higest_bagitem = {} -- 圣物背包中战斗力最高的装备列表,格式 = {slot = goods_id, ...} self.psionic_advance_slot_red = {} --圣物装备进阶左侧装备红点 self.psionic_break_equip_red = {} -- 圣物装备突破红点缓存 self.psionic_break_slot_red = {} -- 圣物突破页签槽位红点 self.psionic_wash_slot_red = {} -- 圣物装备洗练槽位红点 self.psionic_wash_break_slot_red = {} -- 圣物装备洗练槽位的突破红点 self.psionic_skill_slot_red = {} -- 圣物技能觉醒槽位红点 self.psionic_datadig_pooltype_red = {} -- 圣物数据挖掘池子红点缓存(分别缓存了单抽券,十连券和免费红点) self.psionic_exchange_sort_red = {} -- 圣物兑换商店栏位红点 格式 = [sort] = true/false -- 兑换商店 self.psionic_exchange_shop_cfg = {} -- 圣物兑换商店商品配置 -- toggle快速购买确认 self._hide_double_check_advance_flag = false -- 本次登录是否直接付费自动购买进阶材料 self._hide_double_check_break_flag = false -- 本次登录是否直接付费自动购买突破材料 self._dont_check_psionic_draw_tip = {} -- 不打开寻宝二次确认标志 self.ps_left_free_wash_times = 0--剩余免费洗练次数 -- 新版圣物增加 self.ps_stage_title_data = nil -- 圣物系统等级头衔配置 self.ps_equip_cfg = {} -- 动态增加的圣物阶段配置 self.ps_wash_cfg = {} -- 动态增加圣物洗练配置 self.ps_stage_max_level = {} -- 动态获得阶段的最高等级 self.ps_skill_awake_cfg = {} -- 动态获得觉醒的等级配置 self.psionic_show_goods_fly = true -- 是否展示道具飞入表现 -- 新版圣物红点缓存 self._ps_equip_power_list = {} -- 圣物装备战力缓存 ([slot]{[goods_id] = 基础属性+成长属性*槽位等级, slot_lv = slot_lv}),槽位等级变动时清空 self:InitExchangeShopCfg() self.ps_effect_show_status = nil -- 圣物魂环展示标志cookie{当前装备, 历史最高解锁, {[阶段数] = 是否有红点}} -- 进化装备缓存 self._break_type_id_cache = {} self._block_skill_upgrade_click = false -- 延迟弹出觉醒成功界面之前,禁止发起觉醒协议 end function PsionicModel:getInstance() if self.Instance == nil then self.Instance = PsionicModel.New() end return self.Instance end ----------------- -- 配置初始化相关 ----------------- -- 通过服务端发过来的道具信息获取道具配置 function PsionicModel:GetPsionicEquipGradeCfg(type_id) if not type_id then return nil end type_id = tonumber(type_id) if not self.ps_equip_cfg[type_id] then local equip_cfg = Config.Nucleonequip[type_id] if not equip_cfg then return nil end local tb = { cost = stringtotable(equip_cfg.cost), attrs = stringtotable(equip_cfg.attrs), resolve = stringtotable(equip_cfg.resolve), id = equip_cfg.id, next = equip_cfg.next, star = equip_cfg.star, } self.ps_equip_cfg[type_id] = tb end return self.ps_equip_cfg[type_id] end function PsionicModel:InitExchangeShopCfg( ) self.psionic_exchange_shop_cfg = {} for k, v in pairs(Config.Nucleonexchange) do self.psionic_exchange_shop_cfg[#self.psionic_exchange_shop_cfg+1] = v end local sort_func = function ( a, b ) return a.sort < b.sort end table.sort(self.psionic_exchange_shop_cfg, sort_func) end function PsionicModel:GetExchangeShopCfg( ) return self.psionic_exchange_shop_cfg end -- 获取圣物洗练配置 function PsionicModel:GetPsionicWashCfg(slot, grade, no_need_mapping) -- 一般调用这个接口的都是用goods_vo的subtype,装备是从4开始,需要减3做映射 -- 多一个字段用来控制映射处理 if no_need_mapping then slot = slot and slot or 1 else slot = slot and slot - 3 or 1 end grade = grade or 1 local key = slot .. "@" .. grade if not self.ps_wash_cfg[key] then local cfg = Config.Nucleonrecast[key] local tb = {} tb.cost = stringtotable(cfg.cost) tb.attrs = stringtotable(cfg.attrs) tb.maxs = SortAttrList(stringtotable(cfg.maxs)) tb.adds = stringtotable(cfg.adds) self.ps_wash_cfg[key] = tb end return self.ps_wash_cfg[key] end -- 根据阶段数,获取阶段的最高等级 function PsionicModel:GetPsionicSlotStageMaxLevel(grade) grade = grade or 1 if not self.ps_stage_max_level[grade] then local max = 999 for k, v in pairs(Config.Nucleonlv) do if v.grade == grade and Config.Nucleonlv[v.next].grade ~= grade then max = v.lv break end end self.ps_stage_max_level[grade] = max end -- 获取最高阶段数,并每次都默认返回 if not self.ps_stage_max_level["max"] then local max_grade = 0 for k, v in pairs(Config.Nucleonlv) do if Config.Nucleonlv[v.next].grade ~= v.grade and max_grade < v.grade then max_grade = v.grade end end self.ps_stage_max_level["max"] = max_grade end return self.ps_stage_max_level[grade], self.ps_stage_max_level["max"] end -- 获取圣物等级头衔数据 function PsionicModel:GetPsionicStageTitleData( ) if not self.ps_stage_title_data then self.ps_stage_title_data = {} for k, v in pairs(Config.Nucleontitle) do local tb = DeepCopy(v) tb.attrs = stringtotable(tb.attrs) tb.cost = stringtotable(tb.cost) table.insert(self.ps_stage_title_data, tb) end local sort_func = function ( a, b ) return a.lv < b.lv end table.sort(self.ps_stage_title_data, sort_func) end return self.ps_stage_title_data end -- 根据对应的位置获取圣物觉醒配置 function PsionicModel:GetPsionicAwakeCfg(pos, section) if not pos then return nil end section = section or 0 -- 未传入觉醒等级给默认0级配置 pos = pos - 3 -- 配置等级要与参数等级做一个减3映射 local key = pos .. "@" .. section if not self.ps_skill_awake_cfg[key] then local tb = DeepCopy(Config.Nucleonsection[key]) tb.cost = stringtotable(tb.cost) tb.attrs = stringtotable(tb.attrs) tb.skill = stringtotable(tb.skill) tb.sec_skill = stringtotable(tb.sec_skill) self.ps_skill_awake_cfg[key] = tb end return self.ps_skill_awake_cfg[key] end -- 获取圣物觉醒技能解锁和技能配置 function PsionicModel:GetPsionicAwakeUnlockCfg(pos) if not pos then return nil end pos = pos - 3 -- 这边的配置需要减3映射 return Config.Nucleonhole[pos] or nil end -- 获取圣物抽奖奖池概率信息 function PsionicModel:GetPsionicDrawPoolPecData(pool_type) if not self.ps_draw_poolpec_data then self.ps_draw_poolpec_data = {} self.ps_draw_poolpec_data[PsionicConst.DrawPoolType.Normal] = {} self.ps_draw_poolpec_data[PsionicConst.DrawPoolType.Deep] = {} -- 筛选出两个不同奖池的配置 local pt1, pt2, temp_tb = {}, {} for k, v in pairs(Config.Nucleonpoolawards) do temp_tb = DeepCopy(v) temp_tb.awards = stringtotable(v.awards) if temp_tb.pool == PsionicConst.DrawPoolType.Normal then pt1[#pt1+1] = temp_tb elseif temp_tb.pool == PsionicConst.DrawPoolType.Deep then pt2[#pt2+1] = temp_tb end end local function sort_rewards_by_color(tb, target_list) local total_weight = 0 for k, v in ipairs(tb) do -- 总权值 total_weight = total_weight + v.weight -- 不同品质总权值 target_list.color_weight = target_list.color_weight or {} target_list.color_weight[v.color] = (target_list.color_weight[v.color] or 0) + v.weight -- 这里用的不是顺序表,在使用的时候请用自然数递减的方式推算颜色获取数据 target_list.data = target_list.data or {} target_list.data[v.color] = target_list.data[v.color] or {} table.insert(target_list.data[v.color], v) end target_list.total_weight = total_weight -- 根据商品sort排序 local sort_func = function ( a, b ) return a.sort < b.sort end for k, v in pairs(target_list.data) do table.sort(v, sort_func) end end -- sort_rewards_by_color sort_rewards_by_color(pt1, self.ps_draw_poolpec_data[PsionicConst.DrawPoolType.Normal]) sort_rewards_by_color(pt2, self.ps_draw_poolpec_data[PsionicConst.DrawPoolType.Deep]) end return self.ps_draw_poolpec_data[pool_type] end ----------------- -- 协议相关 ----------------- -- 圣物数据 13900 function PsionicModel:SetPsionicMainData(vo) if not vo then return end self.psionic_lv = vo.lv self.psionic_exp = vo.exp -- 缓存槽位信息 self.ps_slot_data = {} for k, v in pairs(vo.holes) do self.ps_slot_data[v.pos] = v -- 如果没有战斗力缓存,或者缓存的槽位等级与当前不相等,则清空当前槽位的战斗力缓存并重新初始化 if not self._ps_equip_power_list[v.pos] or not self._ps_equip_power_list[v.pos].slot_lv or self._ps_equip_power_list[v.pos].slot_lv ~= v.lv then self._ps_equip_power_list[v.pos] = {} self._ps_equip_power_list[v.pos].slot_lv = v.lv self._ps_equip_power_list[v.pos].goods_list = {} end -- 加载vo self:UpdatePsionicSkillVo(v) end end function PsionicModel:GetPsionicLv( ) return self.psionic_lv, self.psionic_exp end -- 获取圣物槽位数据 function PsionicModel:GetPsionicSlotData(slot) if slot then return self.ps_slot_data[slot] else return self.ps_slot_data end end -- 圣物充能结果推送,更新圣物等级和经验值 13901 13902 function PsionicModel:UpdatePsionicMainLv(vo) self.psionic_lv = vo.lv self.psionic_exp = vo.exp end -- 圣物槽位升级 13905 function PsionicModel:UpdatePsionicSlotLv(vo) if vo and self.ps_slot_data[vo.pos] then self.ps_slot_data[vo.pos].lv = vo.lv self.ps_slot_data[vo.pos].exp = vo.exp -- 如果没有战斗力缓存,或者缓存的槽位等级与当前不相等,则清空当前槽位的战斗力缓存并重新初始化 if not self._ps_equip_power_list[vo.pos] or not self._ps_equip_power_list[vo.pos].slot_lv or self._ps_equip_power_list[vo.pos].slot_lv ~= vo.lv then self._ps_equip_power_list[vo.pos] = {} self._ps_equip_power_list[vo.pos].slot_lv = vo.lv self._ps_equip_power_list[vo.pos].goods_list = {} end end end -- 圣物槽位突破 13906 function PsionicModel:UpdatePsionicSlotGrade(vo) if vo and self.ps_slot_data[vo.pos] then self.ps_slot_data[vo.pos].grade = vo.grade self.ps_slot_data[vo.pos].lv = vo.lv self.ps_slot_data[vo.pos].exp = vo.exp -- 如果没有战斗力缓存,或者缓存的槽位等级与当前不相等,则清空当前槽位的战斗力缓存并重新初始化 if not self._ps_equip_power_list[vo.pos] or not self._ps_equip_power_list[vo.pos].slot_lv or self._ps_equip_power_list[vo.pos].slot_lv ~= vo.lv then self._ps_equip_power_list[vo.pos] = {} self._ps_equip_power_list[vo.pos].slot_lv = vo.lv self._ps_equip_power_list[vo.pos].goods_list = {} end end end -- 获取背包相关的数据 -- 获取圣物背包中的装备 15010 function PsionicModel:SetPsionicBagData( ) self.psionic_bag_data = GoodsModel:getInstance():GetPsionicBagList() self:Fire(PsionicConst.UPDATE_PISIONIC_BAG_ARMOR) end -- sort_flag:true 品质降序 false 品质升序 function PsionicModel:GetPsionicBagData(sort_flag) if not self.psionic_bag_data then return {} end local tb = {} for k, v in pairs(self.psionic_bag_data) do tb[#tb+1] = v end -- 没有排序需求,就直接扔出来 if sort_flag == nil then return tb else local sort_func = function ( a, b ) if a.color ~= b.color then -- 根据排序类型决定排序规则 if sort_flag then return a.color > b.color else return a.color < b.color end else -- 颜色相同,现根据星数再根据装备id最后再根据战斗力(战斗力这块数与旧逻辑,有可能不用了) if a.subtype ~= b.subtype then return a.subtype < b.subtype else if a.star ~= b.star then return a.star > b.star else return a.type_id < b.type_id end end end end table.sort(tb, sort_func) return tb end end -- 更新槽位觉醒信息 13908 function PsionicModel:UpdatePsionicSectionLv(vo) if vo and self.ps_slot_data[vo.pos] then self.ps_slot_data[vo.pos].sec_lv = vo.section end end -- 圣物槽位洗练数据更新 13909 function PsionicModel:UpdatePsionicSlotWashData(vo) if vo and self.ps_slot_data[vo.pos] then self.ps_slot_data[vo.pos].attrs = vo.attrs end end -- 圣物抽奖面板信息 13910 function PsionicModel:SetPsionicDigData(vo) if not vo then return end for k, v in pairs(vo.pools) do self.psionic_dig_data[v.pool] = v end end function PsionicModel:GetPsionicDigData(pool_type) if pool_type then return self.psionic_dig_data[pool_type] end return self.psionic_dig_data end -- 更新圣物数据挖掘信息 13910 function PsionicModel:UpdatePsionicDigData(vo) if not vo or not self.psionic_dig_data then return end -- 更新剩余次数 self.psionic_dig_data[vo.pool].remain = vo.remain self.psionic_dig_data[vo.pool].rtime = vo.rtime self.psionic_dig_data[vo.pool].isfirst = vo.isfirst end -- 更新玩家的圣物等级 function PsionicModel:UpdatePsionicSkillData(vo) if vo and self.ps_slot_data[vo.pos] then self.ps_slot_data[vo.pos].skill_id = vo.skill_id self.ps_slot_data[vo.pos].skill_lv = vo.skill_lv -- 加载vo self:UpdatePsionicSkillVo(self.ps_slot_data[vo.pos]) end end -- 更新圣物技能主动技vo function PsionicModel:UpdatePsionicSkillVo(slot_data) if not slot_data then return end local skill_cfg = ConfigItemMgr.Instance:GetSkillItem(slot_data.skill_id) if skill_cfg and skill_cfg.type == 1 then -- 主动技能才需要加载skillvo self.psionic_skill_vo_list[slot_data.pos] = self.psionic_skill_vo_list[slot_data.pos] or SkillVo.New(slot_data.skill_id) self.psionic_skill_vo_list[slot_data.pos].level = slot_data.skill_lv self:Fire(PsionicConst.UPDATE_PSIONIC_SKILL_VO, slot_data.pos) end end function PsionicModel:GetPsionicSkillVo(slot) if slot then return self.psionic_skill_vo_list[slot] else return self.psionic_skill_vo_list end end ---------------- -- 红点表现相关 -- ---------------- -- 更新圣物系统全部红点 function PsionicModel:CheckPsionicAllRed( ) self.psionic_red_cache[PsionicConst.TabId.PArmor] = self:CheckPsionicArmorTabRed() self.psionic_red_cache[PsionicConst.TabId.PAdvance] = self:CheckPsionicAdvanceTabRed() self.psionic_red_cache[PsionicConst.TabId.PBreak] = self:CheckPsionicBreakTabRed() self.psionic_red_cache[PsionicConst.TabId.PWash] = self:CheckPsionicWashTabRed() self.psionic_red_cache[PsionicConst.TabId.PSkill] = self:CheckPsionicSkillTabRed() self.psionic_red_cache[PsionicConst.TabId.PDataDig] = self:CheckPsionicDataDigTabRed() self.psionic_red_cache[PsionicConst.TabId.PExchange] = self:CheckPsionicExchangeRed() self:Fire(PsionicConst.UPDATE_RED_BY_TABID) self:CheckPsionicMainIconRed() end -- 获取界面tab的缓存红点 function PsionicModel:GetPsionicRedDotCache( tab_id ) return not tab_id and self.psionic_red_cache or self.psionic_red_cache[tab_id] end -- 通过界面类型缓存红点 function PsionicModel:CheckPsionicRedByTabID(tab_id, is_all, ...) local other_args = {...} local function get_slot() local slot = other_args[1] or false local goods_id = other_args[2] or false if not slot and goods_id then -- 没有传入slot但传入了对应的装备id,则获取这件装备的id对应的装备槽位 slot = self:GetPsionicEquipSlotByGoodsId(goods_id) end return slot end local bool = false if tab_id == PsionicConst.TabId.PArmor then -- 圣物背包相关 local slot = get_slot() bool = self:CheckPsionicArmorTabRed(slot) elseif tab_id == PsionicConst.TabId.PAdvance then -- 圣物进阶相关 local slot = get_slot() bool = self:CheckPsionicAdvanceTabRed(slot) elseif tab_id == PsionicConst.TabId.PBreak then -- 圣物突破相关 local slot = get_slot() bool = self:CheckPsionicBreakTabRed(slot) elseif tab_id == PsionicConst.TabId.PWash then -- 圣物洗练相关 local slot = other_args[1] or false bool = self:CheckPsionicWashTabRed(slot) elseif tab_id == PsionicConst.TabId.PSkill then -- 圣物觉醒(技能)相关 local slot = get_slot() bool = self:CheckPsionicSkillTabRed(slot) elseif tab_id == PsionicConst.TabId.PDataDig then -- 圣物数据挖掘相关 local pool_type = other_args[1] or false bool = self:CheckPsionicDataDigTabRed(pool_type) elseif tab_id == PsionicConst.TabId.PExchange then -- 圣物兑换商店 bool = self:CheckPsionicExchangeRed() end self.psionic_red_cache[tab_id] = bool self:Fire(PsionicConst.UPDATE_RED_BY_TABID, tab_id, bool) if is_all then self:CheckPsionicMainIconRed() end return bool end function PsionicModel:CheckPsionicMainIconRed( ) local bool = false for k, v in pairs(self.psionic_red_cache) do if v == true then bool = true break end end GlobalEventSystem:Fire(EventName.SHOW_FUNCTION_RED_POINT, 139, bool) --通知自己功能按钮红点 end -- 当圣物背包发生变动时调用 function PsionicModel:OnPsionicEquipChange() local function refresh_psionic_bag_red() self:CheckPsionicRedByTabID(PsionicConst.TabId.PArmor) self:CheckPsionicRedByTabID(PsionicConst.TabId.PAdvance) self:CheckPsionicRedByTabID(PsionicConst.TabId.PBreak) self:CheckPsionicRedByTabID(PsionicConst.TabId.PWash, true) -- 最后再全局刷新按钮红点 end TimeManager.GetInstance():StartTime("PsionicModelEquipRed_1", 0.5, refresh_psionic_bag_red) end -- 当头衔/进阶/突破/觉醒/兑换材料变动时调用 function PsionicModel:OnPsionicGoodsChange( ) self:CheckPsionicRedByTabID(PsionicConst.TabId.PAdvance) self:CheckPsionicRedByTabID(PsionicConst.TabId.PWash) self:CheckPsionicRedByTabID(PsionicConst.TabId.PSkill) self:CheckPsionicRedByTabID(PsionicConst.TabId.PExchange, true) -- 最后再全局刷新按钮红点 -- self:Fire(PsionicConst.UPDATE_PSIONIC_ADVANCE_GOODSNUM) end function PsionicModel:OnPsionicDrawGoodsChange( ) local function refresh_psionic_draw_goods() self:CheckPsionicRedByTabID(PsionicConst.TabId.PDataDig, true) end TimeManager.GetInstance():StartTime("PsionicModelDrawGoodsUpdate", 0.5, refresh_psionic_draw_goods) end -- 检查圣物装备界面红点 function PsionicModel:CheckPsionicArmorTabRed(slot) -- 这个红点比较麻烦,需要先判断身上的装备穿齐了没,然后还要判断身上的装备战斗力是否比背包中的低 local goods_model = GoodsModel:getInstance() local equip_data local bag_list_by_slot local bool = false local function check_slot_equip_red(slot) -- 初始化最高战斗力装备数据 self.psionic_power_higest_bagitem[slot] = nil local temp_bool = false equip_data = goods_model:GetPsionicEquipBySlot(slot) bag_list_by_slot = goods_model:GetPsionicBagItemBySlot(slot) if equip_data then -- 判断是否有装备的战斗力超过了当前的装备 local cur_power = self:GetPsionicEquipTotalPower(equip_data) local temp_power = 0 local heightest_power = 0 for k2, bag_equip_vo in ipairs(bag_list_by_slot) do temp_power = self:GetPsionicEquipTotalPower(bag_equip_vo) if temp_power > cur_power then self.psionic_power_higher_bagitem[bag_equip_vo.goods_id] = bag_equip_vo.goods_id -- 替换装备战斗力提升的标识 temp_bool = true -- 缓存下最高战斗力的圣物 if heightest_power < temp_power then heightest_power = temp_power self.psionic_power_higest_bagitem[slot] = bag_equip_vo.goods_id end else self.psionic_power_higher_bagitem[bag_equip_vo.goods_id] = nil end end else -- 当前装备没有穿戴,而背包对应栏位有装备,则需要提示红点 temp_bool = not IsTableEmpty(bag_list_by_slot) end self.psionic_equip_slot_red[slot] = temp_bool bool = bool or temp_bool end if slot then check_slot_equip_red(slot) if not bool then -- 当前的槽位已经消除了红点,则需要判断一下其他槽位的情况 for k, v in pairs(self.psionic_equip_slot_red) do bool = bool or v end end else for i = 4, 7 do check_slot_equip_red(i) end end -- 检测圣环红点 self.ps_main_effect_red = false -- 获取实时的装备状态 local cur_stage = self:GetPsionicEffectStage() local effect_status = self:GetPsionicEffectShowStatus() for k, v in pairs(effect_status[3]) do if k ~= 0 and k <= cur_stage then self.ps_main_effect_red = self.ps_main_effect_red or v end end bool = bool or self.ps_main_effect_red -- 检查分解红点 -- 获取背包列表 self.psionic_bag_data = self.psionic_bag_data or {} local blue_equip_num = 0 for k, v in pairs(self.psionic_bag_data) do if v.color <= 2 then -- 蓝色装备 blue_equip_num = blue_equip_num + 1 end if blue_equip_num >= 10 then break end end self.ps_resolve_btn_red = blue_equip_num >= 10 bool = bool or self.ps_resolve_btn_red return bool end -- 获取圣物装备左侧装备位置红点缓存 function PsionicModel:GetPsionicEquipSlotRed(slot) if slot then return self.psionic_equip_slot_red[slot] or false else return self.psionic_equip_slot_red end end function PsionicModel:CheckPsionicEffectBtnRed( ) -- 检测圣环红点 self.ps_main_effect_red = false local effect_status = self:GetPsionicEffectShowStatus() for k, v in pairs(effect_status[3]) do if k ~= 0 then self.ps_main_effect_red = self.ps_main_effect_red or v end end end -- 获取圣环红点 function PsionicModel:GetPsionicEffectBtnRed( ) return self.ps_main_effect_red end -- 获取圣物分解红点 function PsionicModel:GetPsionicResolveBtnRed( ) return self.ps_resolve_btn_red end -- 判断这件装备是否替换后能提升战斗力 function PsionicModel:IsPsionicEquipPowerUpOrNot(goods_id) return self.psionic_power_higher_bagitem[goods_id] and true or false end -- 2020年7月23日新增 对于背包界面的未穿戴装备和可替换装备栏位追加逻辑引导穿戴和替换 -- 获取到目标栏位战力最高的圣物装备 greater:是否要追加判断战斗力大于身上穿戴的,否则就单纯返回背包中战力最高的一件 function PsionicModel:GetTopPowerUpEquipInBag(slot, greater) if not slot then return nil end local goods_model = GoodsModel:getInstance() local equip_data = goods_model:GetPsionicEquipBySlot(slot) if equip_data then -- 存在战力比自己身上的高的装备,就挑最好的返回 if self.psionic_power_higest_bagitem[slot] then -- 需要判断战力超过身上的,就判断有没有带红点就好了,没红点就没有必要替换 if greater and not self:GetPsionicEquipSlotRed(slot) then return nil end return goods_model:GetPsionicBagGoodsByID(self.psionic_power_higest_bagitem[slot]) else return nil end else -- 身上没有穿戴的话就比较麻烦,由于装备槽位红点对这种情况的战斗力做了优化导致没有缓存,这里要首次点击要算一次战斗力 local bag_list_by_slot = goods_model:GetPsionicBagItemBySlot(slot) local temp_power, heightest_power, heightest_equip_vo = 0, 0, nil local role_lv = RoleManager.Instance.mainRoleInfo.level for k2, bag_equip_vo in ipairs(bag_list_by_slot) do temp_power = self:GetPsionicEquipTotalPower(bag_equip_vo) -- 逐个判断最高战力的装备 if heightest_power < temp_power then heightest_power = temp_power heightest_equip_vo = bag_equip_vo end end return heightest_equip_vo end return nil end -- 获取装备进阶页签红点 (slot:当更换了某个位置的装备之后,有则需要重新计算这个位置的红点) function PsionicModel:CheckPsionicAdvanceTabRed(slot) local bool = false local goods_model = GoodsModel:getInstance() local equip_data, slot_data, cur_exp_cfg, next_exp_cfg, advance_cost_cfg local function check_advance_slot_red(slot) equip_data = goods_model:GetPsionicEquipBySlot(slot) local temp_bool = false if equip_data then slot_data = self:GetPsionicSlotData(slot) cur_exp_cfg = Config.Nucleonlv[slot_data.lv] if cur_exp_cfg.next ~= 0 then -- 还能升级 -- 追加判断是否是处于突破时,等待突破的期间没有红点 next_exp_cfg = Config.Nucleonlv[cur_exp_cfg.next] if next_exp_cfg.grade ~= cur_exp_cfg.grade and slot_data.exp == cur_exp_cfg.exp then temp_bool = false else advance_cost_cfg = stringtotable(cur_exp_cfg.cost)[1] -- 当存在所需材料时就有红点 temp_bool = goods_model:GetTypeGoodsNum(advance_cost_cfg[2]) > 0 end end end self.psionic_advance_slot_red[slot] = temp_bool bool = bool or temp_bool end if slot then check_advance_slot_red(slot) end if not bool then -- 主要针对圣物进阶之后,本装备已经没有红点,但是其他装备的红点是由背包材料决定,这里需要判断其他槽位 for i = 4, 7 do if not slot or slot ~= i then check_advance_slot_red(i) end end end return bool end function PsionicModel:GetPsionicAdvanceRed(slot) if slot then return self.psionic_advance_slot_red[slot] else return self.psionic_advance_slot_red end end -- 获取突破红点 -- 2021年6月30日追加 提前缓存好当前背包中所有的可突破的装备id,并调整红点提示规则 function PsionicModel:CheckPsionicBreakTabRed(slot) local bool = false local goods_model = GoodsModel:getInstance() local cost_cfg local function check_equip_break_red(equip_data, equip_slot) local break_red = false if equip_data then if equip_data.next ~= 0 then -- 加载材料装备和基础材料的消耗配置 cost_cfg = equip_data.cost or {} if not IsTableEmpty(cost_cfg) then for k, v in ipairs(cost_cfg) do local typeId, lock = goods_model:GetMappingTypeId(v[1], v[2]) local have_num = goods_model:GetPsionicBagGoodsNumByTypeID(typeId, equip_data.goods_id) break_red = have_num >= v[3] end end end self.psionic_break_equip_red[equip_data.goods_id] = break_red end self.psionic_break_slot_red[equip_slot] = break_red or self.psionic_break_slot_red[equip_slot] bool = bool or break_red end -- 获取背包列表 self.psionic_bag_data = self.psionic_bag_data or {} local cur_equip_data if slot then -- 需要清除一次槽位红点 self.psionic_break_slot_red[slot] = false -- 当前穿戴 cur_equip_data = goods_model:GetPsionicEquipBySlot(slot) check_equip_break_red(cur_equip_data, slot) -- 背包内装备的突破红点 for k, v in pairs(self.psionic_bag_data) do if v.subtype == slot then check_equip_break_red(v, v.subtype) end end end if not bool then -- 没有更新到红点,就再刷新其他页签 for i = 4, 7 do if not slot or slot ~= i then -- 清除一次槽位红点再开始计算 self.psionic_break_slot_red[i] = false -- 当前穿戴 cur_equip_data = goods_model:GetPsionicEquipBySlot(i) check_equip_break_red(cur_equip_data, i) end end -- 背包内装备的突破红点 for k, v in pairs(self.psionic_bag_data) do if not slot or slot ~= v.subtype then check_equip_break_red(v, v.subtype) end end end return bool end -- 获取圣物系统突破页签槽位红点 function PsionicModel:GetPsionicBreakSlotRed(slot) if slot then return self.psionic_break_slot_red[slot] or false else return self.psionic_break_slot_red[slot] end end function PsionicModel:GetPsionicBreakEquipRed(goods_id) if goods_id then return self.psionic_break_equip_red[goods_id] or false else return self.psionic_break_equip_red end end -- 获取洗练红点 function PsionicModel:CheckPsionicWashTabRed(slot) local bool = false local goods_model = GoodsModel:getInstance() local equip_data, slot_data, wash_cfg, cost_data, lv_data local function check_wash_slot_red(slot) local wash_red = false local break_red = false equip_data = goods_model:GetPsionicEquipBySlot(slot) if equip_data then local all_attr_max = true slot_data = self:GetPsionicSlotData(slot) wash_cfg = self:GetPsionicWashCfg(equip_data.subtype, slot_data.grade) lv_data = Config.Nucleonlv[slot_data.lv] local stage_max_lv, max_stage = self:GetPsionicSlotStageMaxLevel(slot_data.grade) cost_data = wash_cfg.cost[1] -- 突破红点 local slot_can_break = stage_max_lv <= slot_data.lv and slot_data.exp >= lv_data.exp -- 当前槽位已达到阶段满级满经验 -- 整合协议属性 local attr_id_list = {} for k, v in pairs(slot_data.attrs) do attr_id_list[v.attr_id] = v.attr_value end for k, v in pairs(wash_cfg.maxs) do -- 如果有一条属性没有拉满,那就把这个标识设为false,而为true时有材料也不给红点 local cur_val = attr_id_list[v[1]] or 0 all_attr_max = all_attr_max and tonumber(v[2]) <= cur_val -- 槽位突破红点(需判断有没有达到最终阶段且当前阶段等级升满了) break_red = slot_can_break and max_stage > slot_data.grade and (break_red or v[2] <= cur_val) end -- 满足单次洗练的材料就有红点 wash_red = not all_attr_max and goods_model:GetTypeGoodsNum(cost_data[2]) >= cost_data[3] or false --宠物生活技能多一次免费洗练的机会 如果词条满了不能再洗练,那免费洗练也不给 if not all_attr_max then local left_free_wash_times = self:GetPsionicFreeWashTimes() wash_red = wash_red or left_free_wash_times > 0 end end self.psionic_wash_slot_red[slot] = wash_red self.psionic_wash_break_slot_red[slot] = break_red -- bool = bool or wash_red -- 突破的红点需要去进阶那边操作,就不要强制到页签上面去 bool = bool or wash_red or break_red end if slot then check_wash_slot_red(slot) end if not bool then for i = 4, 7 do if not slot or slot ~= i then check_wash_slot_red(i) end end end return bool end -- 获取圣物洗练界面洗练按钮红点缓存 function PsionicModel:GetPsionicWashSlotRed(slot) if slot then return self.psionic_wash_slot_red[slot] or false else return self.psionic_wash_slot_red end end -- 获取圣物洗练界面突破按钮红点缓存 function PsionicModel:GetPsionicWashSlotBreakRed(slot) if slot then return self.psionic_wash_break_slot_red[slot] or false else return self.psionic_wash_break_slot_red end end -- 检查技能页签红点 function PsionicModel:CheckPsionicSkillTabRed(slot) local bool = false local slot_awake_lv, skill_slot_cfg, slot_data local goods_model = GoodsModel:getInstance() local function check_skill_red_by_slot(slot) self.psionic_skill_slot_red[slot] = false -- 清除缓存 slot_data = self:GetPsionicSlotData(slot) if slot_data and slot_data.skill_lv > 0 then -- 判断是否已经激活了圣物技能 slot_awake_lv = slot_data.sec_lv -- 觉醒等级 skill_slot_cfg = self:GetPsionicAwakeCfg(slot, slot_awake_lv) if skill_slot_cfg and skill_slot_cfg.next ~= 0 then -- 不满级才有红点 local cost = skill_slot_cfg.cost[1] local need_num = cost[3] local have_num = goods_model:GetTypeGoodsNum(cost[2]) self.psionic_skill_slot_red[slot] = have_num >= need_num bool = bool or self.psionic_skill_slot_red[slot] end end end if slot then check_skill_red_by_slot(slot) end if not bool then for i = 4, 7 do if not slot or i ~= slot then check_skill_red_by_slot(i) end end end return bool end function PsionicModel:GetPsionicSkillSlotRedCache(slot) if slot then return self.psionic_skill_slot_red[slot] else return self.psionic_skill_slot_red end end -- 检查数据挖掘界面红点 function PsionicModel:CheckPsionicDataDigTabRed(pool_type) local bool = false -- 寻宝是否开放 local draw_open = GetModuleIsOpen(139, 7) local function check_datadig_by_pooltype(pool_type) local pool_data, cfg_data local temp_bool self.psionic_datadig_pooltype_red[pool_type] = self.psionic_datadig_pooltype_red[pool_type] or {} pool_data = self:GetPsionicDigData(pool_type) cfg_data = Config.Nucleonpool[pool_type] self:ClearFreePoolTimerByType(pool_type) if draw_open and pool_data and cfg_data then self.psionic_datadig_pooltype_red[pool_type].free_red = false if pool_data.isfirst == 0 then -- 终生首次 temp_bool = true self.psionic_datadig_pooltype_red[pool_type].free_red = true else if pool_data.remain > 0 then local function free_pull_timer() if pool_data.rtime <= TimeUtil:getServerTime() then -- 已经过了冷却时间 temp_bool = true self.psionic_datadig_pooltype_red[pool_type].free_red = temp_bool self.psionic_red_cache[PsionicConst.TabId.PDataDig] = temp_bool self:Fire(PsionicConst.UPDATE_RED_BY_TABID, PsionicConst.TabId.PDataDig, temp_bool) self:Fire(PsionicConst.UPDATE_DATADIG_RED_BY_TYPE, pool_type) GlobalEventSystem:Fire(EventName.SHOW_FUNCTION_RED_POINT, 139, temp_bool) --通知自己功能按钮红点 self:ClearFreePoolTimerByType(pool_type) end end self["free_pull_timer"..pool_type] = GlobalTimerQuest:AddPeriodQuest(free_pull_timer, 1, -1) free_pull_timer() end local single_pull_num = GoodsModel:getInstance():GetTypeGoodsNum(cfg_data.one) local ten_pull_num = GoodsModel:getInstance():GetTypeGoodsNum(cfg_data.ten) self.psionic_datadig_pooltype_red[pool_type].single_red = single_pull_num >= 6 and single_pull_num < 9 -- 单抽券超过6张少于9张给单抽红点 self.psionic_datadig_pooltype_red[pool_type].ten_red = ten_pull_num > 0 or single_pull_num >= 9 -- 存在十连或者9张以上单抽给十连抽的红点 temp_bool = temp_bool or self.psionic_datadig_pooltype_red[pool_type].single_red or self.psionic_datadig_pooltype_red[pool_type].ten_red end if temp_bool then self:ClearFreePoolTimerByType(pool_type) end bool = bool or temp_bool -- 数据挖掘这边单独起一个刷新事件 self:Fire(PsionicConst.UPDATE_DATADIG_RED_BY_TYPE, pool_type) end end if pool_type then check_datadig_by_pooltype(pool_type) end if not bool then -- 没有页签红点的情况下,更新另一个池子的红点 if pool_type then check_datadig_by_pooltype(pool_type == PsionicConst.DrawPoolType.Normal and PsionicConst.DrawPoolType.Deep or PsionicConst.DrawPoolType.Normal) else check_datadig_by_pooltype(PsionicConst.DrawPoolType.Normal) check_datadig_by_pooltype(PsionicConst.DrawPoolType.Deep) end end return bool end function PsionicModel:GetPsionicDataDigPoolRedCache(pool_type) if pool_type then return self.psionic_datadig_pooltype_red[pool_type] else return self.psionic_datadig_pooltype_red end end function PsionicModel:ClearFreePoolTimerByType(pool_type) if self["free_pull_timer" .. pool_type] then GlobalTimerQuest:CancelQuest(self["free_pull_timer" .. pool_type]) self["free_pull_timer" .. pool_type] = nil end end -- 替换完某件装备后,保险起见要删除这件装备在红点中的缓存 function PsionicModel:ClearTargetEquipRedCache(goods_id) self.psionic_power_higher_bagitem[goods_id] = nil end -- 检查圣物兑换商店红点 function PsionicModel:CheckPsionicExchangeRed( ) local bool = false local goods_model = GoodsModel:getInstance() local cost, have_num, is_enough for k, v in ipairs(self.psionic_exchange_shop_cfg) do cost = stringtotable(v.cost)[1] have_num = goods_model:GetTypeGoodsNum(cost[2]) is_enough = have_num >= cost[3] bool = bool or is_enough self.psionic_exchange_sort_red[v.sort] = is_enough end return bool end function PsionicModel:GetPsionicExchangeRed(sort) if sort then return self.psionic_exchange_sort_red[sort] or false else for k, v in pairs(self.psionic_exchange_sort_red) do if v == true then return true end end return false end end ---------------- -- 数据处理相关 -- ---------------- -- 计算圣物装备的总战斗力 function PsionicModel:GetPsionicEquipTotalPower(goods_vo) if goods_vo then local slot = goods_vo.subtype if self._ps_equip_power_list[slot].goods_list[goods_vo.goods_id] then -- 存在战斗力缓存,则返回缓存即可 return self._ps_equip_power_list[slot].goods_list[goods_vo.goods_id] else local slot_lv = self._ps_equip_power_list[slot].slot_lv -- 整合数据,根据槽位等级叠加属性,计算战力并返回 local attr_list = {} for k, v in pairs(goods_vo.cfg_attrs) do attr_list[#attr_list+1] = { [1] = v[1], [2] = v[2] + v[3] * slot_lv } end local power = GetFighting(attr_list) self._ps_equip_power_list[slot].goods_list[goods_vo.goods_id] = power return power end end return 0 end -- 通过两个等级的属性数据获得一个数据链表 function PsionicModel:GetPsionicLevelAttrList(cfg_cur, cfg_next) local temp_tb = {} cfg_cur = cfg_cur or {} cfg_next = cfg_next or {} for k, v in ipairs(cfg_next) do temp_tb[v[1]] = temp_tb[v[1]] or {type = v[1], sort_id = k} temp_tb[v[1]].next_val = v[2] end for k, v in ipairs(cfg_cur) do temp_tb[v[1]] = temp_tb[v[1]] or {type = v[1], sort_id = k} temp_tb[v[1]].cur_val = v[2] end local tb = {} for k, v in pairs(temp_tb) do tb[v.sort_id] = v end return tb end -- 计算目标圣物装备上随机属性的战力列表并按需求排序 -- sort_type:排序类型 0降序 1升序 function PsionicModel:GetPsionicEquipAttrPowerBySortType(attr_list, sort_type) local power_list = {} local temp_power = 0 if attr_list then for k, v in pairs(attr_list) do temp_power = GetFighting({{[1] = v[3], [2] = v[4]}}) power_list[#power_list+1] = {power = temp_power, type = v[3]} end end local sort_func_list = { [0] = function ( a, b ) return a.power > b.power end, [1] = function ( a, b ) return a.power < b.power end, } local sort_func = sort_func_list[sort_type] table.sort(power_list, sort_func) return power_list end -- 根据属性的颜色品质,星级和条目获取属性配置 function PsionicModel:GetRefactorAttrCfg(color, star, code) if not color or not star or not code then return nil end local key = color .. "@" .. star .. "@" .. code local cfg = Config.Nucleonrule[key] return cfg end -- 获取目标圣物装备对应的槽位信息 function PsionicModel:GetPsionicEquipSlotByGoodsId(goods_id) local slot = nil if goods_id then local goods_vo = GoodsModel:getInstance():GetPsionicEquipGoodsByID(goods_id) or GoodsModel:getInstance():GetPsionicBagGoodsByID(goods_id) if goods_vo then slot = goods_vo.subtype end end return slot end -- 根据目标装备数据,获得该装备列表能解锁的圣环阶段 -- 返回值:解锁阶段,装备颜色列表 function PsionicModel:GetPsionicEffectStage(equip_data) local color_list = { [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, } if not equip_data then -- 不传的话就默认拿玩家自己的装备数据 equip_data = {} for i = 4, 7 do slot_data = GoodsModel:getInstance():GetPsionicEquipBySlot(i) if slot_data then table.insert(equip_data, slot_data) for j = 2, 6 do if slot_data.color >= j then color_list[j] = color_list[j] + 1 else break end end end end end local lowest_color, activated local state if TableSize(equip_data) < 4 then -- 装备没有带齐,那就不给光环效果或者给个1级的展示效果 state = 0 end if not state then -- 穿戴装备齐全了,就找出最低品质的装备来决定展示的特效 for k, v in pairs(equip_data) do lowest_color = lowest_color and (lowest_color > v.color and v.color or lowest_color) or v.color end if lowest_color < 3 then -- 最低品质圣物低于紫色品质 state = 0 elseif lowest_color == 3 then -- 展示紫色品质圣物特效 state = 1 elseif lowest_color == 4 then -- 展示橙色品质圣物特效 state = 2 elseif lowest_color >= 5 then -- 展示红色品质圣物特效 state = 3 end end return state, color_list end function PsionicModel:CheckPsionicEffectStage( ) if self.ps_effect_show_status == nil then return end local cur_equip_state = self:GetPsionicEffectStage() -- 当前圣物装备品质下的可激活阶段数 local cur_state = self.ps_effect_show_status[1] or 0 -- 当前佩戴的圣环阶段数 local top_state = self.ps_effect_show_status[2] or 0 -- 历史激活的圣环最高阶段数缓存 if cur_state > cur_equip_state then -- 当前的装备圣环阶段数达不到当前穿戴的圣环阶段数,则需要强制设置为0脱下圣环 self:SavePsionicEffectShowStatus(0) end if top_state < cur_equip_state then -- 当前装备的圣环阶段能超过了缓存的最高阶段数,则赋予红点,且修改缓存中最高的解锁阶段数缓存 self.ps_effect_show_status[2] = cur_equip_state for i = top_state + 1, cur_equip_state do self:SavePsionicEffectStatusRed(i, true, i == cur_equip_state) end end end -- 获得该模型需要的圣物光环资源名 function PsionicModel:GetPsionicEffectStageByid(res_id) return "effect_hunhuan_00" .. res_id end -- 获取当前是否在大世界显示玩家圣环效果 function PsionicModel:GetPsionicEffectShowStatus( ) if self.ps_effect_show_status == nil then self.ps_effect_show_status = CookieWrapper.Instance:GetCookie(CookieLevelType.Account, CookieKey.PSIONIC_EFFECT_SHOW_STATUS) or {0, 0, {}} -- 兼容旧缓存 if type(self.ps_effect_show_status) == "boolean" then self.ps_effect_show_status = {0, 0, {}} end if type(self.ps_effect_show_status) == "number" then self.ps_effect_show_status = {self.ps_effect_show_status, self.ps_effect_show_status, {}} end -- end return self.ps_effect_show_status end -- status 目标使用的阶段数 cur_equip_state 当前激活的最高阶段数(默认不传,只有在装备变动的时候会更新) function PsionicModel:SavePsionicEffectShowStatus(status, cur_equip_state) if self.ps_effect_show_status then cur_equip_state = cur_equip_state or self.ps_effect_show_status[2] if status ~= self.ps_effect_show_status[1] then self.ps_effect_show_status[1] = status if self.ps_effect_show_status[2] < cur_equip_state then self.ps_effect_show_status[2] = status end CookieWrapper.Instance:SaveCookie(CookieLevelType.Account, CookieTimeType.TYPE_ALWAYS, CookieKey.PSIONIC_EFFECT_SHOW_STATUS, self.ps_effect_show_status) CookieWrapper.Instance:WriteAll() end -- 更新场景的魂环 self:Fire(PsionicConst.UPDATE_PSIONIC_EFFECT) end end -- status 目标使用的阶段数 function PsionicModel:SavePsionicEffectStatusRed(status, bool, save_cookie) if self.ps_effect_show_status then status = status or 0 bool = bool and true or false self.ps_effect_show_status[3] = self.ps_effect_show_status[3] or {} -- 检查默认,默认没有红点 self.ps_effect_show_status[3][status] = self.ps_effect_show_status[3][status] or false if bool ~= self.ps_effect_show_status[3] then self.ps_effect_show_status[3][status] = bool if save_cookie then CookieWrapper.Instance:SaveCookie(CookieLevelType.Account, CookieTimeType.TYPE_ALWAYS, CookieKey.PSIONIC_EFFECT_SHOW_STATUS, self.ps_effect_show_status) CookieWrapper.Instance:WriteAll() end end self:CheckPsionicRedByTabID(PsionicConst.TabId.PArmor, true) end end --剩余免费洗练次数 function PsionicModel:UpdatePsionicFreeWashTimes(vo) self.ps_left_free_wash_times = vo.free_times end function PsionicModel:GetPsionicFreeWashTimes( ) return self.ps_left_free_wash_times end -- 圣物系统道具飞入限制 function PsionicModel:SetPsionicShowFlyGoods(show) self.psionic_show_goods_fly = show end function PsionicModel:GetPsionicShowFlyGoods( ) return self.psionic_show_goods_fly end --打开技能激活展示界面 function PsionicModel:OpenSkillActiveShowView(skill_id) if skill_id then local skill_cfg = ConfigItemMgr.Instance:GetSkillItem(skill_id) if skill_cfg then local desc = "" if skill_cfg.lvs and skill_cfg.lvs[1] then desc = skill_cfg.lvs[1].desc end local show_vos = {{ type = 2, is_out_res=true, outside_res = GameResPath.GetSkillIcon(skill_id), saying = desc or "", ignore_fly=true, id=skill_id, show_time=15, is_angry = true, skill_id = skill_id, res_name = GameResPath.GetSkillIcon(skill_id), name = skill_cfg.name, ignore_auto_task = true, }} local view = NewFuncOpenView.New() view:Open(show_vos) end end end