local RoleAdv = {} function RoleAdv.bind(Role) local function getIdByCr(c, r) local crId = math.abs(r) + math.abs(c) * 100 if c < 0 then crId = crId + 10000 end if r < 0 then crId = crId + 20000 end return crId end local function getCrById(crId) local c = math.floor(crId % 10000 / 100) local r = crId % 100 local last = math.floor(crId / 10000) if last == 3 then c, r = -c, -r elseif last == 1 then c = -c elseif last == 2 then r = -r end return c, r end --检查 是否满足层数限制条件 local function checkIsIn(checkValue, checkType, checkRange) if not checkValue then return end if checkType == 1 then local limits = checkRange:toNumMap() for min, max in pairs(limits) do if checkValue >= min and checkValue <= max then return true end end else local limit = checkRange:toArray(true, "=") for _, _l in ipairs(limit) do if _l == checkValue then return true end end end end --关卡事件库 local function getEventLib(chapterId, level) local chapter = math.floor(chapterId / 100) % 100 local libsToType = { ["event_monsterCsv"] = {AdvEventType.Monster, AdvEventType.BOSS}, ["event_chooseCsv"] = AdvEventType.Choose, ["event_dropCsv"] = AdvEventType.Drop, ["event_buildingCsv"] = AdvEventType.Build, ["event_traderCsv"] = AdvEventType.Trader, } local eventLib = {} for lib, eventType in pairs(libsToType) do if type(eventType) == "table" then for _, temp in ipairs(eventType) do eventLib[temp] = {} end else eventLib[eventType] = {} end for id, data in pairs(csvdb[lib]) do if data.levelchapter == chapter then if checkIsIn(level, data.leveltype, data.levellimit) then if type(eventType) == "table" then eventLib[eventType[data.type]][id] = data else eventLib[eventType][id] = data end end end end end return eventLib end -- 生成地图 是否可以生成地图上层判断 function Role:randomAdvMap(chapterId, level) local chapterData = csvdb["adv_chapterCsv"][chapterId] if not chapterData then return end if level > chapterData.limitlevel then return end --随出地图 local raw_pool = chapterData.mapid:toArray(true, "=") local advInfo = self:getProperty("advInfo") local lastMapId = advInfo.mapId --非同一层不连续随出同一张类似的地图 local lastChapterId = advInfo.chapter local pool = {} for _, mapId in ipairs(raw_pool) do local temp = csvdb["mapCsv"][mapId] if temp and (lastChapterId == chapterId or lastMapId ~= mapId) then --非同一层不连续随出同一张类似的地图 if checkIsIn(level, temp.leveltype, temp.levellimit) then table.insert(pool, mapId) end end end if not next(pool) then return end local mapId = pool[math.randomInt(1, #pool)] --随出事件 local mapData = csvdb["map_" .. csvdb["mapCsv"][mapId]["path"] .. "Csv"] if not mapData then return end table.clear(advInfo) advInfo.chapter = chapterId advInfo.level = level advInfo.mapId = mapId advInfo.rooms = {} -- {[roomId] = {event = {}, open = {}, isPath = nil},} -- event 事件信息(具体信息查看randomEvent), open 是否解锁 isPath 是否是路径 --事件随机 local eventLib = getEventLib(chapterId, level) local monsterEvents = {} --处理钥匙掉落 local haveBoss = false local function randomEvent(roomId, blockId, eventType) if advInfo.rooms[roomId]["event"][blockId] then return end --已经有事件了 不覆盖 local event = {etype = eventType} local randomFunc = { [AdvEventType.In] = function() advInfo.rooms[roomId]["open"][blockId] = 1 end, [AdvEventType.Out] = function() end, [AdvEventType.BOSS] = function() if not next(eventLib[eventType]) or haveBoss then return false end haveBoss = true event.id = math.randWeight(eventLib[eventType], "showup") end, [AdvEventType.Choose] = function() if not next(eventLib[eventType]) then return false end event.id = math.randWeight(eventLib[eventType], "showup") end, [AdvEventType.Drop] = function() if not next(eventLib[eventType]) then return false end event.item = eventLib[eventType][math.randWeight(eventLib[eventType], "showup")]["range"]:randWeight(true) end, [AdvEventType.Monster] = function() if not next(eventLib[eventType]) then return false end event.id = math.randWeight(eventLib[eventType], "showup") table.insert(monsterEvents, event) end, [AdvEventType.Trader] = function() if not next(eventLib[eventType]) then return false end event.id = math.randWeight(eventLib[eventType], "showup") end, [AdvEventType.Build] = function() if not next(eventLib[eventType]) then return false end event.id = math.randWeight(eventLib[eventType], "showup") end, } if randomFunc[eventType] then if randomFunc[eventType]() ~= false then advInfo.rooms[roomId]["event"][blockId] = event end end end stagePool = {["global"] = {}} for roomId, roomName in pairs(mapData["rooms"]) do stagePool[roomId] = {} advInfo.rooms[roomId] = {event = {}, open = {}} -- 事件, open local roomData if roomName == "path" then advInfo.rooms[roomId].isPath = true roomData = mapData["path"] else roomName = roomName:gsub("/", "_") roomData = csvdb["room_" .. roomName .. "Csv"] end for blockId, stageType in pairs(roomData["blocks"]) do if AdvSpecialStage[stageType] then eventType = AdvEventType[AdvSpecialStage[stageType]] randomEvent(roomId, blockId, eventType) else stagePool["global"][stageType] = stagePool["global"][stageType] or {} stagePool[roomId][stageType] = stagePool[roomId][stageType] or {} table.insert(stagePool["global"][stageType], {room = roomId, block = blockId}) stagePool[roomId][stageType][blockId] = 1 end end end -- 全地图事件 优先级高 for stageType, events in pairs(mapData["events"]) do for _, event in ipairs(events) do local lastCount = #stagePool["global"][stageType] if lastCount <= 0 then break end if math.randomFloat(0, 1) <= (event["rate"] or 1) then local count = math.randomInt(math.min(lastCount, event["minc"]), math.min(lastCount, event["maxc"])) for i = 1, count do local idx = math.randomInt(1, lastCount) local cur = stagePool["global"][stageType][idx] randomEvent(cur["room"], cur["block"], event["event"]) table.remove(stagePool["global"][stageType], idx) lastCount = lastCount - 1 stagePool[cur["room"]][stageType][cur["block"]] = nil end end end end -- 随机单个房间的事件 for roomId, roomName in pairs(mapData["rooms"]) do local roomData if roomName == "path" then roomData = mapData["path"] else roomName = roomName:gsub("/", "_") roomData = csvdb["room_" .. roomName .. "Csv"] end for stageType, events in pairs(roomData["events"]) do local bpool = {} if stagePool[roomId][stageType] then for block, _ in pairs(stagePool[roomId][stageType]) do table.insert(bpool, block) end end for _, event in ipairs(events) do if #bpool <= 0 then break end if math.randomFloat(0, 1) <= (event["rate"] or 1) then local count = math.randomInt(math.min(#bpool, event["minc"]), math.min(#bpool, event["maxc"])) for i = 1, count do local idx = math.randomInt(1, #bpool) randomEvent(roomId, bpool[idx], event["event"]) table.remove(bpool, idx) end end end end end if not haveBoss then if not next(monsterEvents) then print("这个地图没有钥匙!!! mapId : " .. mapId) else local event = monsterEvents[math.randomInt(1, #monsterEvents)] event.item = {1, 1} --掉落钥匙 end end self:updateProperty({field = "advInfo", value = advInfo}) end end return RoleAdv