local schema = require "model.schema" local logger = require "logger" local common_fun = require "model.common_fun" local module_fun = require "model.module_fun" local asset = require "model.asset" local payment = require "model.payment" local reward = require "model.reward" local stringify = require "stringify" -- local keygen = require "model.keygen" local embattle local equip -- local altar local logger_trace = logger.trace local table_insert = table.insert local math_min = math.min local MAX_NUM = 999999999999 -- 英雄最大堆叠数量 local MAX_UPGRADE = 1000 -- 最大升级数量 local module_name = "hero" local _M = schema.new(module_name, { list = { --[[ [sid] = { sid = 类型id, id = 模板id, lv = 1, equip = {穿戴的装备} } ]] }, }) local REQUEST = {} local CMD = {} local MODULE = {} local THIS = {} local tm_list = {} tm_list.hero_onekey_upgrade_star = 0 local function func_ret(fname, character, args) local f = THIS[fname] if not f then logger.error("func_ret not fname:%s !!!", fname) return {errno = STD_ERR.COMMON_SYS_ERR} end if tm_list[fname] then local now = os.time() if now - tm_list[fname] == 0 then return {errno = STD_ERR.COMMON_CLICK_TOO_FAST} -- 点击太快了 else tm_list[fname] = now end end local errno, ret = f(character, args) if errno ~= 0 then return {errno = errno} end ret = ret or {} ret.errno = 0 return ret end function MODULE.list_request_interests() return REQUEST end function MODULE.list_command_interests() return CMD end -- TODO: 解析/升级模块数据 在这里把数据初始化好 function MODULE.parse(character) local d = _M.load(character) d.list = d.list or {} end -- TODO: 侦听事件 function MODULE.monitor(character) end -- TODO: 类似泰利的 prepare 接口 function MODULE.launch(character) local d = _M.assert_get(character) local u = _M.assert_runtime(character) embattle = embattle or require "model.embattle" equip = equip or require "model.equip" -- altar = altar or require "model.altar" end -- TODO: 与客户端同步数据 function MODULE.ready(character) local d = _M.assert_get(character) end -- TODO: 玩家下线时的处理 function MODULE.saybye(character) end function MODULE.add_hero(character, id, num, collect, dispose, addition) local d = _M.assert_get(character) or {} local role_conf_list = assert(asset.RoleConfig_proto, "RoleConfig_proto") local conf = role_conf_list[id] if not conf and dispose then dispose(nil, id, num) return end if num >= 1 and num <= MAX_NUM then local add_num = num local hero_type = tostring(common_fun.get_hero_type(id)) if not d.list[hero_type] then d.list[hero_type] = { sid = hero_type, id = id, lv = 1, num = 0, } add_num = num -1; end d.list[hero_type].num = d.list[hero_type].num + add_num character.dispatch("hero_add_num", id, num) collect(GOODS_HERO, d.list[hero_type]) addition(GOODS_HERO, id, add_num) _M.persist(character) return true, add_num else if dispose then dispose(nil, id, num) end end end function MODULE.hero_check(character, sid) local d = _M.assert_get(character) return d.list[sid] and true or false end function MODULE.hero_get(character, sid) local d = _M.assert_get(character) return d.list[sid] end function MODULE.hero_get_list(character) local d = _M.assert_get(character) return d.list end function MODULE.hero_save(character) _M.persist(character) end function THIS.hero_get_data(character, args) local d = _M.assert_get(character) local ret = {} -- local altar_info = altar.get_altar_info(character) -- local altar_battle = altar.get_altar_battle_info(character) for sid, data in pairs(d.list) do -- if altar_battle[sid] then -- local temp = altar.altar_change_hero_info(altar_info, data) -- table.insert(ret, temp) -- else -- table.insert(ret, data) -- end table.insert(ret, data) end return 0, {list = ret} end local function get_max_upgrade(character, cur_lv, max_lv) local max_lv = max_lv or cur_lv + MAX_UPGRADE local level_conf_list = assert(asset.RoleLevelConfig_proto, "RoleLevelConfig_proto") local num = 0 local goods_list = {} local flag = true for lv = cur_lv+1, max_lv do local level_conf = level_conf_list[lv] if not level_conf then break end for i = 1, #level_conf.goods do local item_id = level_conf.goods[i] local item_num = level_conf.goodNum[i] if not item_id or not item_num or item_id <=0 or item_num <= 0 then break end if not goods_list[item_id] then goods_list[item_id] = module_fun.get_goods_num(character, item_id) end if goods_list[item_id] < item_num then flag = false break end goods_list[item_id] = goods_list[item_id] - item_num end if not flag then break end num = lv - cur_lv end return num end local function reset_level(lv, list) local level_conf_list = assert(asset.RoleLevelConfig_proto, "RoleLevelConfig_proto") for lv = 2, lv do local level_conf = level_conf_list[lv] if not level_conf then return STD_ERR.COMMON_SYS_ERR -- 系统异常 end for i = 1, #level_conf.goods do local item_id = level_conf.goods[i] local item_num = level_conf.goodNum[i] if item_id and item_num and item_num > 0 then table_insert(list, {id = item_id, num = item_num}) else break end end end return 0 end function THIS.hero_upgrade(character, args) local d = _M.assert_get(character) local sid = args.sid local num = args.num or 0 if not sid then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end if num < 0 or num > MAX_UPGRADE then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end -- local altar_battle = altar.get_altar_battle_info(character) -- if altar_battle[sid] then -- return STD_ERR.COMMON_PARM_ERR -- 参数异常 -- end local data = d.list[sid] local level = data.lv if not data then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local hero_conf_list = assert(asset.RoleConfig_proto, "RoleConfig_proto") local hero_conf = hero_conf_list[data.id] if not hero_conf then logger_trace("RoleConfig_proto:%d", data.id) return STD_ERR.COMMON_CONF_ERR -- 配置异常 end if num == 0 then num = get_max_upgrade(character, level) if num <= 0 then return STD_ERR.HERO_MAX_LEVEL -- 超过最大等级 end end local level_conf_list = assert(asset.RoleLevelConfig_proto, "RoleLevelConfig_proto") local pay_list = {} for i = 1, num do local conf = level_conf_list[level+i] if not conf then return STD_ERR.COMMON_CONF_ERR-- 配置异常 end for j = 1, #conf.goods do local item_id = conf.goods[j] local item_num = conf.goodNum[j] if item_id and item_num then table_insert(pay_list, {id = item_id, num = item_num}) end end end local receipt = { module="hero", brief="角色升级", context=string.format("角色id%d, 从%d升级到%d", data.id, level, level+num), notify={ flags="hero_upgrade" }, detail=pay_list } local errno = payment(character, receipt) if errno ~=0 then return errno end local cur_lv = data.lv+num local pre_lv = data.lv data.lv = data.lv+num _M.persist(character) character.dispatch("hero_upgrade", data.id, pre_lv, cur_lv) character.dispatch("hero_upgrade_info", data) return 0, {data = data} end function THIS.hero_upgrade_star(character, args) local d = _M.assert_get(character) or {} local sid = args.sid if not sid then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local data = d.list[sid] if not data then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local role_conf_list = assert(asset.RoleConfig_proto, "RoleConfig_proto") local role_conf = role_conf_list[data.id] if not role_conf then logger_trace("RoleConfig_proto:%d", data.id) return STD_ERR.COMMON_CONF_ERR -- 配置异常 end local cur_quality = role_conf.quality if not cur_quality then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end local max_quality = asset.DataConfig_proto[5].data1 if cur_quality >= max_quality then return STD_ERR.HERO_START_MAX -- 达到最大突破等级 end local conf_id = data.id + 1 role_conf = role_conf_list[conf_id] if not role_conf or role_conf.quality ~= cur_quality+1 then return STD_ERR.COMMON_CONF_ERR -- 配置异常 end if data.num < role_conf.consume then return STD_ERR.HERO_SAME_PAY_ERR end data.id = conf_id data.num = data.num - role_conf.consume _M.persist(character) return 0, {data = d.list[sid]} end function THIS.hero_onekey_upgrade_star(character, args) local d = _M.assert_get(character) return 0 end -- function THIS.hero_reset(character, args) return 0 end function THIS.hero_wear_equip(character, args) local sid = args.sid local list = args.list or {} local d = _M.assert_get(character) if not sid or not d.list[sid] then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local data = d.list[sid] -- -- 清除冗余字段 -- for i = #list , 1, -1 do -- if list[i] == "" then -- list[i] = nil -- else -- break -- end -- end if #list ~= 6 and #list ~= 0 then return STD_ERR.COMMON_PARM_ERR -- 参数异常 end local errno = equip.equip_wear(character, data, data.equip, list) if errno ~= 0 then return errno end local empty = true -- 清除冗余字段 for i = #list , 1, -1 do if list[i] ~= "" then empty = false break end end if empty then list = nil end data.equip = list _M.persist(character) return 0, {list = args.list, data = data} end -- 英雄背包数据 function REQUEST.hero_get_data(character, args) return func_ret("hero_get_data", character, args) end -- 英雄升级 function REQUEST.hero_upgrade(character, args) return func_ret("hero_upgrade", character, args) end -- 英雄升星 function REQUEST.hero_upgrade_star(character, args) return func_ret("hero_upgrade_star", character, args) end -- 一键升星 function REQUEST.hero_onekey_upgrade_star(character, args) return func_ret("hero_onekey_upgrade_star", character, args) end -- 重置 function REQUEST.hero_reset(character, args) return func_ret("hero_reset", character, args) end -- 装备穿戴 function REQUEST.hero_wear_equip(character, args) return func_ret("hero_wear_equip", character, args) end -- 英雄的特殊属性 function MODULE.get_special_attr(character) local d = _M.assert_get(character) local battle_list = embattle.get_embattle_hero_list(character) local list = {} for sid in pairs(battle_list or {}) do local data = d.list[sid] if not data then goto CONTINUE end for _, esid in ipairs(data.equip or {}) do if not esid or esid == "" then goto CONTINUE2 end local equip_info = equip.get_equip_data(character, esid) if not equip_info then goto CONTINUE2 end local equip_conf = asset.ArmorConfig_proto[equip_info.id] if equip_conf and equip_conf.entry and equip_conf.entry > 0 then local conf = asset.EntryConfig_proto[equip_conf.entry] if conf and conf.type and conf.type >= 100 then if conf.rateArr[1] and conf.rateArr[1] > 0 then list[conf.type] = (list[conf.type] or 0) + conf.rateArr[1] end end end ::CONTINUE2:: end ::CONTINUE:: end logger.test("equip get_special_attr"..stringify(list or {})) return list end return MODULE