---@class PrivilegeMonthData ---@field PrivilegeTypeData table ---@class PrivilegeTypeData ---@field id number ---@field start_time number ---@field durationtime number 持续时长 单位小时 PrivilegeMonth = {} local this = {} this.PRIVILEGE_DATA_KEY = "T$_PLAYER_MONTH_PRIVILEGE_DATA_KEY" this.PRIVILEGE_OVER_TIME_DATA_KEY = "T$_PLAYER_MONTH_PRIVILEGE_OVER_TIME_DATA_KEY" this.change_type = { bag = 1, warehouse = 2, } PrivilegeCardType = { MONTH_CARD = 1, PRIVILEGE_CARD = 2, } PrivilegeMonth.PrivilegeType = { WILD_LINE = "1", -- 野外线路 QUICK_SHOP = "2", -- 随身商店 MONSTER_HOOK_PROTECTION = "3", -- 小怪挂机保护 BACKPACK_SPACE_INCREASE = "4", -- 背包空间增加 WAREHOUSE_INCREASE = "5", -- 特权仓库增加 AUTO_BUY_MEDICINE = "6", -- 自动买药 SWITCHING_POINT_SCHEME = "7", -- 切换加点方案 MASTER_TALENT_FREE_SWITCHING = "8", -- 大师天赋免费切换 FALLING_RATE_UP = "9", -- 掉落提升 EXP_ADD_RATE = "10", -- 经验提升 RECYCLING_INCOME_UP = "11", -- 回收收益提升 PATROL_AFK = "12", -- 巡逻挂机 REMOTE_WAREHOUSE = "13", -- 远程仓库 TRADE_LINE_UP_COUNT_INCREASE = "14", -- 交易行寄售货架数量增加 AUTO_PICKUP = "15", -- 自动拾取 AUTO_RECOVERY = "16", -- 自动回收 COMBO_NUM = "17", -- 连击试炼每日次数增加 TRADE_SALE = "18", -- 交易行寄售功能开启 COMBO_SWEEP_IS_OPEN = "19", -- 连击副本扫荡功能开启 } PrivilegeMonth.PrivilegeConfigMapping = { [PrivilegeMonth.PrivilegeType.EXP_ADD_RATE] = "experienceup", [PrivilegeMonth.PrivilegeType.FALLING_RATE_UP] = "dropsup", --[PrivilegeMonth.PrivilegeType.BACKPACK_SPACE_INCREASE] = "backpackup", --[PrivilegeMonth.PrivilegeType.WAREHOUSE_INCREASE] = "depotup", [PrivilegeMonth.PrivilegeType.RECYCLING_INCOME_UP] = "reclaimup", [PrivilegeMonth.PrivilegeType.TRADE_LINE_UP_COUNT_INCREASE] = "tradingghelvesup", [PrivilegeMonth.PrivilegeType.COMBO_NUM] = "combonum", } function PrivilegeMonth.jump(actor) -- RoleAttr.getPrivilegeAttrPointProgramme(actor) end function PrivilegeMonth.monthCardExchangePrivilege(actor, p_type) -- 暂不启用批量购买, count为1 this.monthCardExchangePrivilege(actor, p_type, 1) end function PrivilegeMonth.hasPrivilegeType(actor, p_type) return this.hasPrivilegeType(actor, p_type) end function PrivilegeMonth.hasAnyPrivilege(actor) return this.hasAnyPrivilege(actor) end ---是否开启了特权 ---@param privilegeType number 特权类型,PrivilegeMonth.PrivilegeType ---@return boolean, number true:已开启特权; false:未开启特权, 特权对应数值 function PrivilegeMonth.hasPrivilege(actor, privilegeType) return this.hasPrivilege(actor, privilegeType) end function PrivilegeMonth.login(actor) this.loginCheckPrivilegeMonth(actor) this.sendPrivilegeBubbleData(actor) local is_open, rate = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.EXP_ADD_RATE) if is_open then ExpBonus.changeBonus(actor, BonusType.PRIVILEGE_EXP_BONUS, rate, 0, 0) else ExpBonus.changeBonus(actor, BonusType.PRIVILEGE_EXP_BONUS, 0, 0, 0) end end function PrivilegeMonth.sendHasPrivilege(actor, p_type) local ret = this.hasPrivilegeType(actor, p_type) sendluamsg(actor, LuaMessageIdToClient.RES_CHECK_MONTH_PRIVILEGE_IS_OPEN, ret) end function PrivilegeMonth.sendPrivilegeData(actor) local data = this.getPrivilegeData(actor) this.debug("send_privilege_data", data) sendluamsg(actor, LuaMessageIdToClient.RES_GET_MONTH_PRIVILEGE_DATA, data) end -- -------------------------------------------------------------------------- -- ---@return PrivilegeMonthData function this.getPrivilegeData(actor) return getplaydef(actor, this.PRIVILEGE_DATA_KEY) end function this.setPrivilegeData(actor, data) setplaydef(actor, this.PRIVILEGE_DATA_KEY, data) end function this.hasPrivilegeType(actor, p_type) local data = this.getPrivilegeData(actor) if table.isEmpty(data) then return false end ---@type PrivilegeTypeData local type_data = data[p_type] if table.isEmpty(type_data) then return false end if type_data.start_time < 1 then return false end if type_data.durationtime == -1 then return true else local now = getbaseinfo("now") local end_mills = type_data.start_time + type_data.durationtime * 60 * 60 * 1000 return end_mills > tonumber(now) end end function this.hasAnyPrivilege(actor) local data = this.getPrivilegeData(actor) if table.isEmpty(data) then return false end for p_type, _ in pairs(data) do local tableValue = ConfigDataManager.getTable("cfg_privilege", "id", p_type) return not table.isNullOrEmpty(tableValue) end return false end function this.hasPrivilege(actor, privilegeType) local privilegeData = this.getPrivilegeData(actor) if table.isEmpty(privilegeData) then return false, 0 end local total = 0 local isFound = false for id, _ in pairs(privilegeData) do local privilegeListStr = ConfigDataManager.getTableValue("cfg_privilege", "privilegellist1", "id", id) local privilegeList = string.split(privilegeListStr, "#") if not table.isEmpty(privilegeList) and table.contains(privilegeList, privilegeType) then isFound = true local countKey = PrivilegeMonth.PrivilegeConfigMapping[privilegeType] or "" local countValueStr = ConfigDataManager.getTableValue("cfg_privilege", countKey, "id", id) local countValue = 0 if string.contains(countValueStr, "#") then countValue = tonumber(string.split(countValueStr, "#")[2]) else countValue = tonumber(countValueStr) end if countValue then if privilegeType == PrivilegeMonth.PrivilegeType.EXP_ADD_RATE then total = total > countValue and total or countValue else total = total + countValue end end end end return isFound, total end function this.monthCardExchangePrivilege(actor, p_type, count) this.debug("兑换月卡特权类型:", p_type) local config_arr = ConfigDataManager.getTable("cfg_privilege", "id", p_type) if table.isEmpty(config_arr) then this.debug("未获取到配置信息", "p_type:", p_type) return end local config = config_arr[1] this.debug("config:", config) count = math.min(count, tonumber(config.maxcount)) local cost_price = tonumber(config.price) * count -- 扣除月卡天数 local is_suc = MonthCard.deletemonthcardtime(actor, cost_price) if not is_suc then this.debug("扣除月卡天数失败!无法继续开通特权") return end this.jprint("开始兑换月卡特权") local is_activation -- 获取特权数据 local data = this.getPrivilegeData(actor) if table.isEmpty(data) then data = {} is_activation = true elseif this.hasPrivilegeType(actor, p_type) then is_activation = false end ---@type PrivilegeTypeData local type_data = data[p_type] if table.isEmpty(type_data) then type_data = {} type_data.id = p_type type_data.start_time = 0 type_data.durationtime = 0 is_activation = true else is_activation = false end local now = tonumber(getbaseinfo("now")) if type_data.start_time == 0 then type_data.start_time = now end local durationtime = tonumber(config.time) * 24 * count type_data.durationtime = type_data.durationtime + durationtime data[p_type] = type_data this.setPrivilegeData(actor, data) this.debug("激活成功, 特权数据:", data) PrivilegeMonth.sendPrivilegeData(actor) -- 定时清理玩家特权 local delay_mills = type_data.durationtime * 60 * 60 * 1000 this.delayClosePrivilege(actor, delay_mills, p_type) -- 开启特权功能 if is_activation then this.monthPrivilegeActivation(actor, p_type) end end function this.delayClosePrivilege(actor, delay_mills, p_type) this.jprint("---- " .. tostring(delay_mills / 1000) .. "秒后清理玩家特权 ----") intervalcalldelay(actor, delay_mills, 1000, 1, "timeoutmonthprivilegeclear", p_type) end function timeoutmonthprivilegeclear(actor, p_type) this.debug("---- 开始清理特权 ----", "p_type:", p_type) local rid = actor:toString() this.jprint("rid: " .. tostring(rid)) local is_has = this.hasPrivilegeType(actor, p_type) if is_has then this.jprint("玩家特权未到期,不处理清理逻辑") return end local data = this.getPrivilegeData(actor) data[p_type] = nil this.setPrivilegeData(actor, data) this.setPrivilegeBubbleTime(actor, p_type, getbaseinfo("now")) this.monthPrivilegeClose(actor, p_type) -- 移除加成 local is_open, rate = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.EXP_ADD_RATE) if not is_open then RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.PRIVILEGE_EXP_BOOST) ExpBonus.changeBonus(actor, BonusType.PRIVILEGE_EXP_BONUS, 0, 0, 0) else -- 加成信息变化修改 if data then if is_open then RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.PRIVILEGE_EXP_BOOST) RoleAttr.addAndSaveRoleAttr(actor, RoleAttrKey.PRIVILEGE_EXP_BOOST, { [this.getExpBoostAttrId(p_type)] = rate }) ExpBonus.changeBonus(actor, BonusType.PRIVILEGE_EXP_BONUS, rate, 0, 0) end end end this.debug("---- 清理特权完成 ----") sendluamsg(actor, LuaMessageIdToClient.RES_MONTH_PRIVILEGE_TIME_OUT, p_type) end function this.loginCheckPrivilegeMonth(actor) -- 登录时检查特权是否过期 未则开启定时任务 local data = this.getPrivilegeData(actor) if table.isEmpty(data) then return end for k, v in pairs(data) do if v.start_time < 1 then goto continue end local now = getbaseinfo("now") local end_mills = v.start_time + v.durationtime * 60 * 60 * 1000 local delay_mills = end_mills - tonumber(now) this.debug("玩家特权结束时间: ", end_mills, "now:", now, "delay_mills:", delay_mills) delay_mills = math.max(delay_mills, 1000) this.delayClosePrivilege(actor, delay_mills, k) :: continue :: end end function this.monthPrivilegeActivation(actor, p_type) this.addFallRate(actor, p_type) this.changeCapacity(actor, this.change_type.bag, true, p_type) this.changeCapacity(actor, this.change_type.warehouse, true, p_type) this.changeComboCount(actor, true, p_type) end function this.monthPrivilegeClose(actor, p_type) local is_has = PrivilegeMonth.hasPrivilegeType(actor, p_type) if not is_has then this.closeAutoBuyMedicine(actor) this.clearFallRate(actor, p_type) this.changeCapacity(actor, this.change_type.bag, false, p_type) this.changeCapacity(actor, this.change_type.warehouse, false, p_type) this.changeComboCount(actor, false, p_type) end end function this.closeAutoBuyMedicine(actor) local autoBuyPotion = getplaydef(actor, "T$autoBuyPotion") or {} local isOn = autoBuyPotion["on"] or 0 if isOn == 0 then return end AutoBuyPotionScript.openOrCloseAutoBuyPotion(actor) end function this.addFallRate(actor, p_type) local attr_str = ConfigDataManager.getTableValue("cfg_privilege", "dropsup", "id", p_type) if attr_str and attr_str ~= "" then local drop_tbl = string.split(attr_str, "#") this.debug("drop_tbl:", drop_tbl, "attr_str", attr_str) local attr_map = {} attr_map[tonumber(drop_tbl[1])] = tonumber(drop_tbl[2]) RoleAttr.addAndSaveRoleAttr(actor, RoleAttrKey.PRIVILEGE_MONTH_DROP_RATE, attr_map) end end function this.clearFallRate(actor, p_type) local attr_str = ConfigDataManager.getTableValue("cfg_privilege", "dropsup", "id", p_type) if attr_str and attr_str ~= "" then local drop_tbl = string.split(attr_str, "#") this.debug("drop_tbl:", drop_tbl, "attr_str", attr_str) local attr_map = {} attr_map[tonumber(drop_tbl[1])] = tonumber(drop_tbl[2]) RoleAttr.reduceAndSaveRoleAttr(actor, RoleAttrKey.PRIVILEGE_MONTH_DROP_RATE, attr_map) end end function this.changeCapacity(actor, capacity_type, is_add, p_type) local is_open, _ = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.BACKPACK_SPACE_INCREASE) if not is_open and is_add then this.debug("特权未开启,无法扩容") return end -- 定义内置函数, 执行全局函数 local function handleCapacityChange(action, pages, grids) if pages then for _, page in pairs(pages) do action(actor, page) end else action(actor, grids) end end local action, pages, grids if capacity_type == this.change_type.bag then grids = ConfigDataManager.getTableValue("cfg_privilege", "backpackup", "id", p_type) this.debug("----grids-----", grids, p_type) action = is_add and unlockbaggridcount or lockbaggridcount elseif capacity_type == this.change_type.warehouse then local config = ConfigDataManager.getById("cfg_privilege", p_type) if table.isEmpty(config) then return end pages = string.split(config.depotup, "#") action = is_add and unlockstoregridcount or lockstoregridcount end if grids and grids ~= "" then handleCapacityChange(action, pages, grids) end end --- 改变连击副本次数 --- @param actor table 玩家对象 --- @param isAdd boolean 是否增加 --- @param p_type number 特权类型 function this.changeComboCount(actor, isAdd, p_type) local comboNum = ConfigDataManager.getTableValue("cfg_privilege", "comboNum", "id", p_type) if comboNum and comboNum ~= "" then if isAdd then addleftcountofactivity(actor, DuplicateType.COMBO_TEST, comboNum) ComboTest.setComboTestAddCount(actor) else local comboCount = getleftcountofactivity(actor, DuplicateType.COMBO_TEST) if comboCount and comboCount > 0 then comboNum = comboCount - comboNum > 0 and comboCount - comboNum or comboCount reduceactivitytimes(actor, DuplicateType.COMBO_TEST, comboNum) ComboTest.setComboTestAddCount(actor) end end end end ---- 特权过期气泡 function this.sendPrivilegeBubbleData(actor) local data = this.getPrivilegeBubbleData(actor) if table.isEmpty(data) then return end sendluamsg(actor, LuaMessageIdToClient.RES_PRIVILEGE_MONTH_BUBBLE_DATA, data) end function this.getPrivilegeBubbleData(actor) return getplaydef(actor, this.PRIVILEGE_OVER_TIME_DATA_KEY) end function this.setPrivilegeBubbleTime(actor, p_type, time) local data = this.getPrivilegeBubbleData(actor) if table.isEmpty(data) then data = {} end data[p_type] = time setplaydef(actor, this.PRIVILEGE_OVER_TIME_DATA_KEY, data) end ---------------------------- 日志打印 ----------------------------- this.log_open = false function this.debug(...) if not this.log_open then return end gameDebug.print(...) end function this.jprint(param) if not this.log_open then return end if param == nil then param = "error! 输出内容为空. nil" end jprint(param) end function this.loginfo(actor, param) if not this.log_open then return end if param == nil then param = "error! 日志输出内容为空. nil" end jprint(param) info(actor, param) end this.gm_open = true function l_privilege_month_add_bag_count(actor, p_type) if not this.gm_open then return end this.changeCapacity(actor, this.change_type.bag, true, p_type) end function l_privilege_month_close_bag_count(actor, p_type) if not this.gm_open then return end this.changeCapacity(actor, this.change_type.bag, false, p_type) end function this.checkIsNew(data, mintType) local tableValuesByMinType = ConfigDataManager.getTable("cfg_privilege", "mintype", mintType) for _, v in pairs(tableValuesByMinType) do local id = tonumber(v["id"]) if data[id] then return true end end return false end --- 使用特权卡 ---@param actor table 角色对象 ---@param itemConfigId number 道具配置ID ---@param count number 使用数量 function PrivilegeMonth.usePrivilegeCard(actor, itemConfigId, count) local tableValues = ConfigDataManager.getTable("cfg_privilege", "type", PrivilegeCardType.PRIVILEGE_CARD) local p_type = 0 local p_minType = 0; local config = {} for _, v in pairs(tableValues) do if tonumber(v.item) == tonumber(itemConfigId) then p_type = tonumber(v.id) p_minType = tonumber(v.mintype) config = v break end end if p_type > 0 then local is_activation -- 获取特权数据 local data = this.getPrivilegeData(actor) if table.isEmpty(data) then data = {} is_activation = true elseif this.hasPrivilegeType(actor, p_type) then is_activation = false end local is_new = false -- 判断之前是否有使用同类型的特权卡 --if p_type == PrivilegeCardId.SILVER1 or p_type == PrivilegeCardId.SILVER2 or p_type == PrivilegeCardId.SILVER3 or p_type == PrivilegeCardId.SILVER4 then -- is_new = data[PrivilegeCardId.SILVER1] or data[PrivilegeCardId.SILVER2] or data[PrivilegeCardId.SILVER3] or data[PrivilegeCardId.SILVER4] -- p_type = PrivilegeCardId.SILVER1 --end -- --if p_type == PrivilegeCardId.GOLD1 or p_type == PrivilegeCardId.GOLD2 then -- is_new = data[PrivilegeCardId.GOLD1] or data[PrivilegeCardId.GOLD2] -- p_type = PrivilegeCardId.GOLD1 --end -- --if p_type == PrivilegeCardId.DIAMOND1 or p_type == PrivilegeCardId.DIAMOND2 then -- is_new = data[PrivilegeCardId.DIAMOND1] or data[PrivilegeCardId.DIAMOND2] -- p_type = PrivilegeCardId.DIAMOND1 --end if p_minType == PrivilegeCardMinType.SILVER then p_type = PrivilegeCardId.SILVER1 elseif p_minType == PrivilegeCardMinType.GOLD then p_type = PrivilegeCardId.GOLD1 elseif p_minType == PrivilegeCardMinType.DIAMOND then p_type = PrivilegeCardId.DIAMOND1 elseif p_minType == PrivilegeCardMinType.RECOVERY then local id = ConfigDataManager.getTableValue("cfg_privilege", "id", "mintype", p_minType) if string.isNullOrEmpty(id) then error("该类型特权卡暂时未实现", p_type, p_minType) return end p_type = tonumber(id) else error("特权卡minType类型错误", p_type, p_minType) return end is_new = this.checkIsNew(data, p_minType) jprint("特权卡信息", p_type, p_minType, is_new) ---@type PrivilegeTypeData local type_data = data[p_type] if table.isEmpty(type_data) then type_data = {} type_data.id = p_type type_data.start_time = 0 type_data.durationtime = 0 is_activation = true else is_activation = false end local now = tonumber(getbaseinfo("now")) if type_data.start_time == 0 then type_data.start_time = now end local configTime = config.time if configTime and configTime ~= "" then configTime = configTime / 60 / 24 local durationtime = configTime * 24 * count type_data.durationtime = type_data.durationtime + durationtime -- 定时清理玩家特权 local delay_mills = type_data.durationtime * 60 * 60 * 1000 this.delayClosePrivilege(actor, delay_mills, p_type) else type_data.durationtime = -1 end data[p_type] = type_data this.setPrivilegeData(actor, data) this.debug("激活成功, 特权数据:", data) PrivilegeMonth.sendPrivilegeData(actor) -- 开启特权功能 if is_activation then this.monthPrivilegeActivation(actor, p_type) -- 如果之前没有使用此特权卡则增加特权BOSS挑战次数 local type if p_type == PrivilegeCardId.SILVER1 then type = PrivilegeBossCountType.SILVER_CARD elseif p_type == PrivilegeCardId.GOLD1 then type = PrivilegeBossCountType.GOLD_CARD elseif p_type == PrivilegeCardId.DIAMOND1 then type = PrivilegeBossCountType.DIAMOND_CARD end PrivilegeBoss.addCount(actor, type) --白银特权任务 TaskHandler.TriggerTaskGoal(actor, TaskTargetType.ACTIVATE_SILVER_PRIVILEGE) end if not is_new then sendluamsg(actor, LuaMessageIdToClient.RES_PRIVILEGE_CARD_ACTIVATION, p_type) -- 发送经验加成信息 local is_open, rate = PrivilegeMonth.hasPrivilege(actor, PrivilegeMonth.PrivilegeType.EXP_ADD_RATE) if is_open then local attrId = this.getExpBoostAttrId(p_type) local attrMap = { [attrId] = rate } RoleAttr.clearRoleAttrAndDB(actor, RoleAttrKey.PRIVILEGE_EXP_BOOST) RoleAttr.addAndSaveRoleAttr(actor, RoleAttrKey.PRIVILEGE_EXP_BOOST, attrMap) ExpBonus.changeBonus(actor, BonusType.PRIVILEGE_EXP_BONUS, rate, 0, 0) end end end end ---是否激活白银特权 function PrivilegeMonth.hasSilverPrivilege(actor) if PrivilegeMonth.hasPrivilegeType(actor, PrivilegeCardId.SILVER1) or PrivilegeMonth.hasPrivilegeType(actor, PrivilegeCardId.SILVER2) or PrivilegeMonth.hasPrivilegeType(actor, PrivilegeCardId.SILVER3) or PrivilegeMonth.hasPrivilegeType(actor, PrivilegeCardId.SILVER4) then return true; end return false; end function this.getExpBoostAttrId(p_type) local countKey = PrivilegeMonth.PrivilegeConfigMapping[PrivilegeMonth.PrivilegeType.EXP_ADD_RATE] local countValueStr = ConfigDataManager.getTableValue("cfg_privilege", countKey, "id", p_type) local split = string.split(countValueStr, "#") --return tonumber(split[1]) return 325012 end