SanctuaryBoss = {} SanctuaryBoss.__index = SanctuaryBoss local this = {} local function __serverType() return 2 end local function __bossType() return 5 end local function __globalKey() return "R$_SanctuaryBossGlobalKey" end function SanctuaryBoss.getDbKey() return __globalKey() end function SanctuaryBoss.get() local data = getsysvar(__globalKey(), 1) return setmetatable(data or {}, SanctuaryBoss) end function SanctuaryBoss:save() setsysvar(__globalKey(), self, 1) -- 同步数据到所有主机 local hosts = gethosts() for _, host in ipairs(hosts) do setsysvar(host, __globalKey(), self) end end function SanctuaryBoss.combine() -- 发起合服是清理缓存 this.clearCache() end function SanctuaryBoss.initBossState() this.initBossState() end function SanctuaryBoss.getMonsterCount(map_id, line, monster_id, state) return this.getMonsterCount(map_id, line, monster_id, state) end function SanctuaryBoss.monsterDie(actor) local success, ret = xpcall(this.monsterStateChange, debug.traceback, actor) gameDebug.assertTrue(success, "圣域BOSS怪物死亡同步数据异常! error", ret) end function SanctuaryBoss.monsterRelive(actor) local success, ret = xpcall(this.monsterStateChange, debug.traceback, actor) gameDebug.assertTrue(success, "圣域BOSS怪物复活同步数据异常! error", ret) end --- 请求进入圣域地图 function SanctuaryBoss.enterMap(actor, msgData) this.enterMap(actor, msgData) end function this.enterMap(actor, move_id) this.assertT(string.tonumber(move_id) > 0, "参数错误", move_id) local map_id = getbaseinfo(actor, "mapid") this.assertT(string.tonumber(map_id) == CrossMap.CROSS_MAP_ID, "必须通过跨服主城进入地图", map_id, CrossMap.CROSS_MAP_ID) -- 执行传送 MapMoveTransfer.mapMove(actor, move_id) end function this.initBossState() if not this.is_cross() then return end -- 清理缓存 this.clearCache() local config_list = ConfigDataManager.getTable("cfg_BOSS_challenge", "monsterType", __bossType()) this.assertT(table.notEmpty(config_list), "cfg_BOSS_challenge配置错误", __bossType()) -- 开始缓存数据 local data = SanctuaryBoss.get() for _, config in ipairs(config_list) do local map_data = config.mapid for _, v in pairs(string.split(map_data, "|")) do local mapInfo = string.split(v, "#") local map_cfg_id = mapInfo[1] local line = mapInfo[2] local map_id = gamemap.getMapKey(map_cfg_id, line) if table.isEmpty(data.map[map_id]) then local map = {} local info_list = mapbossinfo(map_id) for _, v in pairs(info_list) do map[v.id] = v end data.map[map_id] = map end end end data:save() this.debug("---------- finish init boss state cache. ----------") end function this.clearCache() local data = SanctuaryBoss.get() data.map = {} data:save() end function this.getMonsterCount(map_id, line, monster_id, state) local data = SanctuaryBoss.get() local key = gamemap.getMapKey(map_id, line) local map_data = data.map[key] this.assertT(table.notEmpty(map_data)) local count = 0 for _, info in pairs(map_data) do local is_dead = info.isdead and 0 or 1 if tonumber(state) ~= is_dead then goto continue end if tonumber(info.cfgid) ~= tonumber(monster_id) then goto continue end count = count + 1 ::continue:: end return count end function this.monsterStateChange(actor) if not this.is_cross() then return end local map_id = getbaseinfo(actor, "unimapid") local data = SanctuaryBoss.get() if table.isEmpty(data.map) then return end local cache_info = data.map[map_id] or {} local mon_info = getmonsterinfo(actor) if table.isEmpty(mon_info) then return end cache_info[mon_info.id] = mon_info data:save() end function this.is_cross() local server_type = getbaseinfo("servertype") return tonumber(server_type) == __serverType() end -- ----------------------------------------------------------------- -- this.log_open = false function this.debug(...) if not this.log_open then return end gameDebug.print(...) end function this.assertT(condition, ...) gameDebug.assertTrue(condition, ...) end