Commit 43babcff6fcbfd9940df4a5a1faa71f1686d092d
1 parent
836228c9
优化冒险结构 增加夹层功能
Showing
9 changed files
with
931 additions
and
697 deletions
Show diff stats
src/GlobalVar.lua
| ... | ... | @@ -87,6 +87,7 @@ AdvEventType = { |
| 87 | 87 | Build = 5, --建筑物 |
| 88 | 88 | Trap = 6, --陷阱 |
| 89 | 89 | Click = 7, --点击生效 |
| 90 | + Layer = 8, --切换层的点 | |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | 93 | AdvBackEventType = { |
| ... | ... | @@ -106,7 +107,8 @@ AdvBackEventType = { |
| 106 | 107 | TurnEnd = 14, -- 回合结束 |
| 107 | 108 | Miss = 15, -- miss |
| 108 | 109 | BattleBegin = 16, -- 战斗开始 |
| 109 | - Trap = 17, | |
| 110 | + Trap = 17, --陷阱 | |
| 111 | + Layer = 18, --切换层 | |
| 110 | 112 | } |
| 111 | 113 | |
| 112 | 114 | AdvScoreType = { | ... | ... |
src/adv/Adv.lua
| 1 | 1 | local Passive = require "adv.AdvPassive" |
| 2 | 2 | |
| 3 | --- 工具函数--第一象限 < 10000 < 第二象限 < 20000 < 第四象限 < 30000 < 第三象限 | |
| 4 | -local function getIdByCr(c, r) | |
| 5 | - local crId = math.abs(r) + math.abs(c) * 100 -- row + column * 100 | |
| 6 | - if c < 0 then | |
| 7 | - crId = crId + 10000 | |
| 8 | - end | |
| 9 | - if r < 0 then | |
| 10 | - crId = crId + 20000 | |
| 11 | - end | |
| 12 | - return crId | |
| 13 | -end | |
| 3 | +local AdvCommon = require "adv.AdvCommon" | |
| 4 | +local AdvMap = require "adv.AdvMap" | |
| 14 | 5 | |
| 15 | -local function getCrById(crId) | |
| 16 | - local c = math.floor(crId % 10000 / 100) | |
| 17 | - local r = crId % 100 | |
| 18 | - local last = math.floor(crId / 10000) | |
| 19 | - if last == 3 then | |
| 20 | - c, r = -c, -r | |
| 21 | - elseif last == 1 then | |
| 22 | - c = -c | |
| 23 | - elseif last == 2 then | |
| 24 | - r = -r | |
| 25 | - end | |
| 26 | - return c, r | |
| 6 | +local Adv = class("Adv") | |
| 7 | +function Adv:ctor(owner) | |
| 8 | + assert(owner, "Adv instance must have owner(role)") | |
| 9 | + self.owner = owner | |
| 10 | + self.maps = {} | |
| 11 | + self.battle = nil | |
| 12 | + self.backEvents = {} --发给客户端的事件组 | |
| 13 | + self:initByInfo(self.owner:getProperty("advInfo")) | |
| 27 | 14 | end |
| 28 | 15 | |
| 29 | ------------------------------随机地图----------------------------- | |
| 30 | ---检查 是否满足层数限制条件 -- if checktype == 1 then check value in range a=b else check value in array a=b=c | |
| 31 | -local function checkIsIn(checkValue, checkType, checkRange) | |
| 32 | - if not checkValue then return end | |
| 33 | - if checkType == 1 then | |
| 34 | - local limits = checkRange:toNumMap() | |
| 35 | - for min, max in pairs(limits) do | |
| 36 | - if checkValue >= min and checkValue <= max then | |
| 37 | - return true | |
| 38 | - end | |
| 39 | - end | |
| 40 | - else | |
| 41 | - local limit = checkRange:toArray(true, "=") | |
| 42 | - for _, _l in ipairs(limit) do | |
| 43 | - if _l == checkValue then | |
| 44 | - return true | |
| 45 | - end | |
| 46 | - end | |
| 16 | +--初始化adv 信息 | |
| 17 | +function Adv:initByInfo(advInfo) | |
| 18 | + if not next(advInfo) then return end --还没有 开始新地图 | |
| 19 | + | |
| 20 | + self.chapterId = advInfo.chapterId | |
| 21 | + self.level = advInfo.level or 1 | |
| 22 | + self.score = advInfo.score or {} | |
| 23 | + self.lastEnemyId = advInfo.lastEId or 1 | |
| 24 | + self.mapStack = advInfo.mstack or {} | |
| 25 | + self.maps = {} | |
| 26 | + for id, map in ipairs(advInfo.maps or {}) do | |
| 27 | + self.maps[id] = AdvMap.new(self, id, map) | |
| 47 | 28 | end |
| 29 | + | |
| 30 | + self:initBattle() | |
| 48 | 31 | end |
| 49 | 32 | |
| 50 | ---关卡事件库 | |
| 51 | -local function getEventLib(chapterId, level, needEventType) -- needEventType 需要的事件 | |
| 52 | - local chapter = math.floor(chapterId / 100) % 100 | |
| 33 | +-- 随机新的地图 | |
| 34 | +function Adv:initByChapter(chapterId, level, isToNext, notNotify) | |
| 35 | + if self.chapterId and chapterId ~= self.chapterId then return end --新的关卡 或者 去到下一层 | |
| 36 | + self.chapterId = chapterId | |
| 37 | + self.level = level or 1 | |
| 38 | + self.score = self.score or {} | |
| 39 | + self.lastEnemyId = 1 | |
| 40 | + self.mapStack = {1} -- 最后一个为当前的地图 | |
| 53 | 41 | |
| 54 | - local libsToType = { | |
| 55 | - ["event_monsterCsv"] = {AdvEventType.Monster, AdvEventType.BOSS, AdvEventType.Monster}, | |
| 56 | - ["event_chooseCsv"] = AdvEventType.Choose, | |
| 57 | - ["event_dropCsv"] = AdvEventType.Drop, | |
| 58 | - ["event_buildingCsv"] = AdvEventType.Build, | |
| 59 | - ["event_traderCsv"] = AdvEventType.Trader, | |
| 60 | - ["event_trapCsv"] = AdvEventType.Trap, | |
| 61 | - ["event_clickCsv"] = AdvEventType.Click, | |
| 42 | + -- 随机出地图 | |
| 43 | + local mapId = self:randomMapId(chapterId, level) | |
| 44 | + self.maps = {} | |
| 45 | + self.maps[1] = AdvMap.new(self, 1, mapId) | |
| 62 | 46 | |
| 63 | - } | |
| 64 | - local eventLib = {} | |
| 65 | - for lib, eventType in pairs(libsToType) do | |
| 66 | - -- init eventLib | |
| 67 | - if type(eventType) == "table" then | |
| 68 | - for _, temp in ipairs(eventType) do | |
| 69 | - eventLib[temp] = {} | |
| 70 | - end | |
| 71 | - else | |
| 72 | - eventLib[eventType] = {} | |
| 73 | - end | |
| 74 | - -- needEventType 只获取这个事件类型 | |
| 75 | - if not needEventType or eventLib[needEventType] then | |
| 76 | - for id, data in pairs(csvdb[lib]) do | |
| 77 | - if data.levelchapter == chapter then | |
| 78 | - if checkIsIn(level, data.leveltype, data.levellimit) then | |
| 79 | - if type(eventType) == "table" then | |
| 80 | - eventLib[eventType[data.type]][data.BlockEventType] = eventLib[eventType[data.type]][data.BlockEventType] or {} | |
| 81 | - eventLib[eventType[data.type]][data.BlockEventType][id] = {showup = data.showup, limit = data.limit} | |
| 82 | - else | |
| 83 | - eventLib[eventType][data.BlockEventType] = eventLib[eventType][data.BlockEventType] or {} | |
| 84 | - eventLib[eventType][data.BlockEventType][id] = {showup = data.showup, limit = data.limit} | |
| 85 | - end | |
| 86 | - end | |
| 87 | - end | |
| 88 | - end | |
| 89 | - if needEventType then | |
| 90 | - break | |
| 91 | - end | |
| 92 | - end | |
| 47 | + if isToNext then | |
| 48 | + self:scoreChange(AdvScoreType.Level) --增加层级加分 | |
| 93 | 49 | end |
| 94 | - return eventLib | |
| 95 | -end | |
| 96 | 50 | |
| 97 | --- 生成地图 是否可以生成地图上层判断 | |
| 98 | -local function randomAdvMap(role, chapterId, level, notNotify) | |
| 99 | - local chapterData = csvdb["adv_chapterCsv"][chapterId] | |
| 100 | - if not chapterData then | |
| 101 | - error("chapterId " .. chapterId .. " dont exist!") | |
| 102 | - return | |
| 103 | - end | |
| 104 | - if level > chapterData.limitlevel then | |
| 105 | - error("level overflow!") | |
| 106 | - return | |
| 51 | + self:initBattle() | |
| 52 | + | |
| 53 | + if not notNotify then | |
| 54 | + self:saveDB(notNotify) | |
| 107 | 55 | end |
| 108 | - --随出地图 | |
| 109 | - local raw_pool = chapterData.mapid:toArray(true, "=") | |
| 110 | - local advInfo = role:getProperty("advInfo") | |
| 56 | +end | |
| 111 | 57 | |
| 112 | - local lastMapId = advInfo.mapId --非同一层不连续随出同一张类似的地图 | |
| 113 | - local lastChapterId = advInfo.chapter | |
| 114 | - local lastScore = advInfo.score or {} -- 分数 | |
| 58 | +function Adv:clear() | |
| 59 | + self.chapterId = nil | |
| 60 | + self.level = nil | |
| 61 | + self.score = {} | |
| 62 | + self.lastEnemyId = 1 | |
| 63 | + self.mapStack = {} | |
| 64 | + self.maps = {} | |
| 65 | + self.battle = nil | |
| 66 | +end | |
| 115 | 67 | |
| 116 | - local pool = {} | |
| 117 | - for _, mapId in ipairs(raw_pool) do | |
| 118 | - local temp = csvdb["mapCsv"][mapId] | |
| 119 | - if temp and (lastChapterId == chapterId or lastMapId ~= mapId) then --非同一层不连续随出同一张类似的地图 | |
| 120 | - if checkIsIn(level, temp.leveltype, temp.levellimit) then | |
| 121 | - table.insert(pool, mapId) | |
| 122 | - end | |
| 123 | - end | |
| 124 | - end | |
| 125 | - if not next(pool) then | |
| 126 | - error("mapIds is empty!") | |
| 127 | - return | |
| 128 | - end | |
| 129 | - local mapId = pool[math.randomInt(1, #pool)] | |
| 130 | - --随出事件 | |
| 131 | - local mapData = csvdb["map_" .. csvdb["mapCsv"][mapId]["path"] .. "Csv"] | |
| 132 | - if not mapData then | |
| 133 | - error("mapId " .. mapId .. " dont exist!") | |
| 134 | - return | |
| 135 | - end | |
| 68 | +function Adv:saveDB(notNotify) | |
| 69 | + local advInfo, advTeam = {}, self.owner:getProperty("advTeam") | |
| 70 | + if self.chapterId then | |
| 136 | 71 | |
| 137 | - table.clear(advInfo) | |
| 138 | - advInfo.chapter = chapterId | |
| 139 | - advInfo.level = level | |
| 140 | - advInfo.mapId = mapId | |
| 141 | - advInfo.score = lastScore | |
| 142 | - advInfo.enemyId = 1 --怪递增的索引 | |
| 143 | - advInfo.rooms = {} -- {[roomId] = {event = {}, open = {}},} -- event 事件信息(具体信息查看randomEvent), open 是否解锁 | |
| 144 | - --事件随机 | |
| 145 | - local eventLib = getEventLib(chapterId, level) -- 同时记录出现次数 | |
| 146 | - local monsterEvents = {} --处理钥匙掉落 | |
| 147 | - local haveBoss = false | |
| 148 | - | |
| 149 | - local function randomEvent(roomId, blockId, eventType) | |
| 150 | - if advInfo.rooms[roomId]["event"][blockId] then return end --已经有事件了 不覆盖 | |
| 151 | - local etype, especial = eventType, 0 | |
| 152 | - if eventType > 100 then -- 特殊事件(固定) | |
| 153 | - etype = math.floor(eventType / 100) | |
| 154 | - especial = eventType % 100 | |
| 155 | - end | |
| 156 | - | |
| 157 | - local event = {etype = etype} | |
| 158 | - local randomFunc = {} | |
| 159 | - | |
| 160 | - local function randomCommon() | |
| 161 | - if not eventLib[etype] or not next(eventLib[etype]) or not eventLib[etype][especial] or not next(eventLib[etype][especial]) then return false end | |
| 162 | - event.id = math.randWeight(eventLib[etype][especial], "showup") | |
| 163 | - if not event.id then return false end | |
| 164 | - if eventLib[etype][especial][event.id].limit > 1 then | |
| 165 | - eventLib[etype][especial][event.id].limit = eventLib[etype][especial][event.id].limit - 1 | |
| 166 | - elseif eventLib[etype][especial][event.id].limit == 1 then | |
| 167 | - eventLib[etype][especial][event.id] = nil | |
| 168 | - end | |
| 169 | - end | |
| 72 | + advInfo.chapterId = self.chapterId | |
| 73 | + advInfo.level = self.level | |
| 74 | + advInfo.score = self.score | |
| 75 | + advInfo.lastEId = self.lastEnemyId | |
| 76 | + advInfo.mstack = self.mapStack | |
| 77 | + advInfo.maps = {} | |
| 170 | 78 | |
| 171 | - --入口 | |
| 172 | - randomFunc[AdvEventType.In] = function()end | |
| 173 | - --出口 | |
| 174 | - randomFunc[AdvEventType.Out] = function() end | |
| 175 | - --boss | |
| 176 | - randomFunc[AdvEventType.BOSS] = function() | |
| 177 | - if haveBoss then return false end | |
| 178 | - if randomCommon() == false then | |
| 179 | - return false | |
| 180 | - end | |
| 181 | - haveBoss = true | |
| 182 | - end | |
| 183 | - --怪物 | |
| 184 | - randomFunc[AdvEventType.Monster] = function() | |
| 185 | - if randomCommon() == false then | |
| 186 | - return false | |
| 187 | - end | |
| 188 | - table.insert(monsterEvents, event) | |
| 189 | - end | |
| 79 | + self.battle:saveDB() | |
| 190 | 80 | |
| 191 | - --选择点 | |
| 192 | - randomFunc[AdvEventType.Choose] = randomCommon | |
| 193 | - --掉落点 | |
| 194 | - randomFunc[AdvEventType.Drop] = randomCommon | |
| 195 | - --交易所 | |
| 196 | - randomFunc[AdvEventType.Trader] = randomCommon | |
| 197 | - --建筑 | |
| 198 | - randomFunc[AdvEventType.Build] = randomCommon | |
| 199 | - --陷阱 | |
| 200 | - randomFunc[AdvEventType.Trap] = randomCommon | |
| 201 | - --点击生效 | |
| 202 | - randomFunc[AdvEventType.Click] = randomCommon | |
| 203 | - | |
| 204 | - | |
| 205 | - if randomFunc[etype] then | |
| 206 | - if randomFunc[etype]() ~= false then | |
| 207 | - advInfo.rooms[roomId]["event"][blockId] = event | |
| 208 | - end | |
| 81 | + for id , map in ipairs(self.maps) do | |
| 82 | + advInfo.maps[id] = map:getDB() | |
| 209 | 83 | end |
| 210 | - end | |
| 211 | - local stagePool = {["global"] = {}} | |
| 212 | - for roomId, roomName in pairs(mapData["rooms"]) do | |
| 213 | - stagePool[roomId] = {} | |
| 214 | - advInfo.rooms[roomId] = {event = {}, open = {}} -- 事件, open open == 1 房间内地块全部开放 | |
| 215 | - local roomData | |
| 216 | - if roomName == "path" then | |
| 217 | - roomData = mapData["path"] | |
| 218 | - else | |
| 219 | - roomName = roomName:gsub("/", "_") | |
| 220 | - roomData = csvdb["room_" .. roomName .. "Csv"] | |
| 221 | - end | |
| 222 | - for blockId, stageType in pairs(roomData["blocks"]) do | |
| 223 | - if AdvSpecialStage[stageType] then | |
| 224 | - local eventType = AdvEventType[AdvSpecialStage[stageType]] -- 地块固定类型 | |
| 225 | - randomEvent(roomId, blockId, eventType) | |
| 226 | - else | |
| 227 | - stagePool["global"][stageType] = stagePool["global"][stageType] or {} | |
| 228 | - stagePool[roomId][stageType] = stagePool[roomId][stageType] or {} | |
| 229 | - table.insert(stagePool["global"][stageType], {room = roomId, block = blockId}) | |
| 230 | - stagePool[roomId][stageType][blockId] = 1 | |
| 231 | - end | |
| 232 | - end | |
| 233 | - end | |
| 234 | - -- 全地图事件 优先级高 | |
| 235 | - for stageType, events in pairs(mapData["events"]) do | |
| 236 | - for _, event in ipairs(events) do | |
| 237 | - local lastCount = stagePool["global"][stageType] and #stagePool["global"][stageType] or 0 | |
| 238 | - if lastCount <= 0 then break end | |
| 239 | - if math.randomFloat(0, 1) <= (event["rate"] or 1) then | |
| 240 | - local count = math.randomInt(math.min(lastCount, event["minc"]), math.min(lastCount, event["maxc"])) | |
| 241 | - for i = 1, count do | |
| 242 | - local idx = math.randomInt(1, lastCount) | |
| 243 | - local cur = stagePool["global"][stageType][idx] | |
| 244 | - randomEvent(cur["room"], cur["block"], event["event"]) | |
| 245 | - table.remove(stagePool["global"][stageType], idx) | |
| 246 | - lastCount = lastCount - 1 | |
| 247 | - stagePool[cur["room"]][stageType][cur["block"]] = nil | |
| 248 | - end | |
| 249 | - end | |
| 250 | - end | |
| 251 | - end | |
| 252 | - -- 随机单个房间的事件 | |
| 253 | - for roomId, roomName in pairs(mapData["rooms"]) do | |
| 254 | - local roomData | |
| 255 | - if roomName == "path" then | |
| 256 | - roomData = mapData["path"] | |
| 257 | - else | |
| 258 | - roomName = roomName:gsub("/", "_") | |
| 259 | - roomData = csvdb["room_" .. roomName .. "Csv"] | |
| 260 | - end | |
| 261 | - for stageType, events in pairs(roomData["events"]) do | |
| 262 | - local bpool = {} | |
| 263 | - if stagePool[roomId][stageType] then | |
| 264 | - for block, _ in pairs(stagePool[roomId][stageType]) do | |
| 265 | - table.insert(bpool, block) | |
| 266 | - end | |
| 267 | - end | |
| 268 | - for _, event in ipairs(events) do | |
| 269 | - if #bpool <= 0 then break end | |
| 270 | - if math.randomFloat(0, 1) <= (event["rate"] or 1) then | |
| 271 | - local count = math.randomInt(math.min(#bpool, event["minc"]), math.min(#bpool, event["maxc"])) | |
| 272 | - for i = 1, count do | |
| 273 | - local idx = math.randomInt(1, #bpool) | |
| 274 | - randomEvent(roomId, bpool[idx], event["event"]) | |
| 275 | - table.remove(bpool, idx) | |
| 276 | - end | |
| 277 | - end | |
| 278 | - end | |
| 279 | - end | |
| 280 | - end | |
| 281 | - if not haveBoss then | |
| 282 | - if not next(monsterEvents) then | |
| 283 | - print("这个地图没有钥匙!!! mapId : " .. mapId) | |
| 284 | - else | |
| 285 | - local event = monsterEvents[math.randomInt(1, #monsterEvents)] | |
| 286 | - event.item = {ItemId.AdvKey, 1} --掉落钥匙 | |
| 287 | - end | |
| 288 | - end | |
| 289 | -end | |
| 290 | 84 | |
| 291 | ---块类型 | |
| 292 | -local Block = class("Block") | |
| 293 | -function Block:ctor(blockId, event, isOpen) | |
| 294 | - self.blockId = blockId | |
| 295 | - self.col, self.row = getCrById(self.blockId) | |
| 296 | - self.isOpen = isOpen and true or false | |
| 297 | - self.event = event -- 拿到的是引用可以直接更新 | |
| 298 | -end | |
| 299 | -function Block:isBoss() | |
| 300 | - if not self.event then return end | |
| 301 | - return self.event["etype"] == AdvEventType.BOSS | |
| 302 | -end | |
| 85 | + advTeam.player = self.battle.player:getDB() | |
| 303 | 86 | |
| 304 | ---事件有需要额外处理的部分 | |
| 305 | -function Block:open(adv, room) | |
| 306 | - --如果翻开有数据处理在这里处理 | |
| 307 | - local randomFunc = {} | |
| 308 | - --怪 | |
| 309 | - randomFunc[AdvEventType.Monster] = function() | |
| 310 | - self.event.mId = adv.advInfo.enemyId --给怪一个有序id 回合逻辑时使用 | |
| 311 | - adv.advInfo.enemyId = adv.advInfo.enemyId + 1 | |
| 312 | - local enemy = adv.battle:getEnemy(room.roomId, self.blockId) | |
| 313 | - if enemy then | |
| 314 | - enemy:unlock(self.event.mId) | |
| 315 | - else | |
| 316 | - enemy = adv.battle:addEnemy(room, self) | |
| 317 | - end | |
| 318 | - enemy:triggerPassive(Passive.BORN_ONCE) | |
| 319 | - end | |
| 320 | - randomFunc[AdvEventType.BOSS] = randomFunc[AdvEventType.Monster] | |
| 321 | - --掉落 | |
| 322 | - randomFunc[AdvEventType.Drop] = function() | |
| 323 | - self.event.item = csvdb["event_dropCsv"][self.event.id]["range"]:randWeight(true) | |
| 324 | - end | |
| 325 | - --交易 | |
| 326 | - randomFunc[AdvEventType.Trader] = function() | |
| 327 | - local data = csvdb["event_traderCsv"][self.event.id] | |
| 328 | - self.event.shop = {} | |
| 329 | - self.event.status = "" --购买次数状态 1 就是购买过了 -- 购买id就是shop索引 | |
| 330 | - for i = 1, 10 do | |
| 331 | - local numS, rangeS = "num" .. i, "range" .. i | |
| 332 | - if data[numS] and data[rangeS] then | |
| 333 | - for j = 1, data[numS] do | |
| 334 | - table.insert(self.event.shop, data[rangeS]:randWeight(true)) | |
| 335 | - end | |
| 336 | - else | |
| 337 | - break | |
| 338 | - end | |
| 339 | - end | |
| 340 | - end | |
| 341 | - --建筑 | |
| 342 | - randomFunc[AdvEventType.Build] = function() | |
| 343 | - local data = csvdb["event_buildingCsv"][self.event.id] | |
| 344 | - self.event.effect = data["range"]:randWeight(true) --随出建筑效果 | |
| 345 | - if self.event.effect[1] == 1 then --获得某道具 | |
| 346 | - local reward = csvdb["event_dropCsv"][self.event.effect[2]]["range"]:randWeight(true) | |
| 347 | - self.event.effect[2] = reward[1] | |
| 348 | - self.event.effect[3] = reward[2] | |
| 349 | - end | |
| 350 | - end | |
| 351 | - randomFunc[AdvEventType.Trap] = function() | |
| 352 | - local data = csvdb["event_trapCsv"][self.event.id] | |
| 353 | - for _, buffId in ipairs(data.effect:toArray(true, "=")) do | |
| 354 | - adv.battle.player:addBuff(buffId) | |
| 355 | - end | |
| 356 | - adv:backTrap() | |
| 357 | - room:clearBEvent(self) | |
| 358 | - end | |
| 359 | - if self.event then -- 随机出具体的事件 | |
| 360 | - if randomFunc[self.event.etype] then | |
| 361 | - randomFunc[self.event.etype]() | |
| 362 | - end | |
| 87 | + else | |
| 88 | + advTeam.player = nil | |
| 363 | 89 | end |
| 364 | - self.isOpen = true | |
| 90 | + | |
| 91 | + self.owner:updateProperties({advInfo = advInfo, advTeam = advTeam}, notNotify) | |
| 365 | 92 | end |
| 366 | 93 | |
| 367 | -local Room = class("Room") | |
| 368 | -function Room:ctor(adv, roomId, csvData, info, isPath) | |
| 369 | - self.roomId = roomId | |
| 370 | - self.col, self.row = getCrById(self.roomId) | |
| 371 | - self.isPath = isPath | |
| 372 | - self.isBossRoom = false -- boss房间 --击败boss 以后重置为false | |
| 373 | - self.info = info -- 拿到引用 方便更新advInfo | |
| 374 | - self.isShow = false | |
| 375 | - self.blocks = {} | |
| 376 | - | |
| 377 | - for blockId, _ in pairs(csvData["blocks"]) do | |
| 378 | - self.blocks[blockId] = Block.new(blockId, info.event[blockId], info.open == 1 or info.open[blockId]) | |
| 379 | - if not self.isPath and self.blocks[blockId]:isBoss() then | |
| 380 | - self.isBossRoom = true | |
| 381 | - end | |
| 382 | - if self.blocks[blockId].isOpen then | |
| 383 | - self.isShow = true | |
| 384 | - else | |
| 385 | - if self.blocks[blockId].event and self.blocks[blockId].event.etype == AdvEventType.In then -- 开放 | |
| 386 | - self.isShow = true | |
| 387 | - self.blocks[blockId].isOpen = true | |
| 388 | - self.info.open[blockId] = 1 | |
| 389 | - | |
| 390 | - --入口房间只会在这里首次展示开放 --触发固有技 | |
| 391 | - adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
| 392 | - end | |
| 393 | - end | |
| 94 | +function Adv:initBattle() | |
| 95 | + self.battle = require("adv.AdvBattle").new(self) | |
| 96 | + for _, passiveC in ipairs(self.cachePassiveEvent or {}) do | |
| 97 | + self.battle:triggerPassive(passiveC[1], passiveC[2]) | |
| 394 | 98 | end |
| 99 | + self.cachePassiveEvent = {} | |
| 395 | 100 | end |
| 396 | 101 | |
| 397 | -function Room:tranGToL(c, r) | |
| 398 | - return c - self.col, r - self.row | |
| 102 | +function Adv:triggerPassive(condType, params) | |
| 103 | + self.cachePassiveEvent = self.cachePassiveEvent or {} | |
| 104 | + if not self.battle then | |
| 105 | + table.insert(self.cachePassiveEvent, {condType, params}) | |
| 106 | + else | |
| 107 | + self.battle:triggerPassive(condType, params) | |
| 108 | + end | |
| 399 | 109 | end |
| 400 | 110 | |
| 401 | -function Room:tranLtoG(c, r) | |
| 402 | - return c + self.col, r + self.row | |
| 111 | +function Adv:getCurMap() | |
| 112 | + return self.maps[self.mapStack[#self.mapStack]] | |
| 403 | 113 | end |
| 404 | 114 | |
| 405 | -function Room:getBByGPos(c, r) | |
| 406 | - local c, r = self:tranGToL(c, r) | |
| 407 | - return self.blocks[getIdByCr(c, r)] | |
| 115 | +function Adv:getCurMapIdx() | |
| 116 | + return self.mapStack[#self.mapStack] | |
| 408 | 117 | end |
| 409 | 118 | |
| 410 | -function Room:openBlock(block, adv) | |
| 411 | - if self.blocks[block.blockId] ~= block then return end | |
| 412 | - if block.isOpen == true then return end | |
| 413 | - if self.isBossRoom then | |
| 414 | - for _, _block in pairs(self.blocks) do | |
| 415 | - _block:open(adv, self) | |
| 416 | - end | |
| 417 | - else | |
| 418 | - block:open(adv, self) | |
| 119 | +function Adv:getRoom(roomId, mapIdx) | |
| 120 | + mapIdx = mapIdx or self:getCurMapIdx() | |
| 121 | + local map = self.maps[mapIdx] | |
| 122 | + if map then | |
| 123 | + return map.rooms[roomId] | |
| 419 | 124 | end |
| 420 | - local allOpen = true | |
| 421 | - for _, _block in pairs(self.blocks) do | |
| 422 | - if not _block.isOpen then | |
| 423 | - allOpen = false | |
| 424 | - break | |
| 425 | - end | |
| 426 | - end | |
| 427 | - | |
| 428 | - if allOpen then | |
| 429 | - self.info.open = 1 | |
| 430 | - else | |
| 431 | - self.info.open[block.blockId] = 1 | |
| 432 | - end | |
| 433 | - | |
| 434 | - adv:scoreChange(AdvScoreType.Block) | |
| 435 | - | |
| 436 | - if not self.isShow then | |
| 437 | - self.isShow = true | |
| 438 | - --首次展示房间 | |
| 439 | - adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
| 440 | - end | |
| 441 | 125 | end |
| 442 | 126 | |
| 443 | -function Room:clearBEvent(block) | |
| 444 | - if self.blocks[block.blockId] ~= block then return end | |
| 445 | - if block.event.etype == AdvEventType.Trap then -- 记录陷阱位置 | |
| 446 | - self.info.trap = self.info.trap or {} | |
| 447 | - self.info.trap[block.blockId] = block.event.id | |
| 127 | +function Adv:getBlock(roomId, blockId, mapIdx) | |
| 128 | + local room = self:getRoom(roomId, mapIdx) | |
| 129 | + if room then | |
| 130 | + return room.blocks[blockId] | |
| 448 | 131 | end |
| 449 | - block.event = nil | |
| 450 | - self.info.event[block.blockId] = nil | |
| 451 | 132 | end |
| 452 | 133 | |
| 453 | 134 | |
| 454 | 135 | |
| 455 | -local Adv = class("Adv") | |
| 456 | -function Adv:ctor(owner) | |
| 457 | - assert(owner, "Adv instance must have owner(role)") | |
| 458 | - self.owner = owner | |
| 459 | - self.advInfo = self.owner:getProperty("advInfo") --这个变量置空使用 table.clear | |
| 460 | - self.advTeam = self.owner:getProperty("advTeam") --这个变量置空使用 table.clear | |
| 461 | - self:clear() | |
| 462 | - self.backEvents = {} --发给客户端的事件组 | |
| 463 | - self.tempBackEvents = {} --发给客户端的事件组(缓存) | |
| 464 | -end | |
| 465 | - | |
| 466 | --- 清空自己组织的数据 | |
| 467 | -function Adv:clear() | |
| 468 | - self.rooms = {} | |
| 469 | - self.cachePassiveEvent = {} -- 在battle 没有创建成功时 触发的被动技信息 | |
| 470 | - self.battle = nil -- 战斗逻辑 | |
| 471 | -end | |
| 472 | - | |
| 473 | 136 | --关卡通关,非层 score < 0 失败 |
| 474 | 137 | function Adv:over(success) |
| 475 | 138 | local score = self:getScore() |
| 476 | - local scoreInfo = self.advInfo.score | |
| 139 | + local scoreInfo = self.score | |
| 477 | 140 | local reward |
| 478 | 141 | if success then |
| 479 | - self.owner:updateProperty({field = "advPass", self.owner:getProperty("advPass"):setv(self.advInfo.chapter, score)}) | |
| 142 | + self.owner:updateProperty({field = "advPass", self.owner:getProperty("advPass"):setv(self.chapterId, score)}) | |
| 480 | 143 | reward = self.owner:award(self.owner:getProperty("advItems"):toNumMap()) |
| 481 | 144 | |
| 482 | - self.owner:checkTaskEnter(self.owner.TaskType.AdvPass, {id = self.advInfo.chapter}) | |
| 145 | + self.owner:checkTaskEnter(self.owner.TaskType.AdvPass, {id = self.chapterId}) | |
| 483 | 146 | end |
| 484 | - table.clear(self.advInfo) --清空advInfo | |
| 485 | - self.advTeam.player = nil --重置玩家的数据 | |
| 486 | 147 | self:clear() |
| 487 | 148 | |
| 488 | 149 | self.owner:updateProperty({field = "advItems", value = ""}) |
| ... | ... | @@ -495,162 +156,41 @@ function Adv:exit() |
| 495 | 156 | self:saveDB() |
| 496 | 157 | end |
| 497 | 158 | |
| 498 | -function Adv:getMapInfo() | |
| 499 | - if not next(self.advInfo) then return end | |
| 500 | - return csvdb["mapCsv"][self.advInfo.mapId] | |
| 501 | -end | |
| 502 | - | |
| 503 | -function Adv:getMapData() | |
| 504 | - local mapInfo = self:getMapInfo() | |
| 505 | - if not mapInfo then return end | |
| 506 | - return csvdb["map_" .. self:getMapInfo()["path"] .. "Csv"] | |
| 507 | -end | |
| 508 | - | |
| 509 | -function Adv:initByInfo() | |
| 510 | - self:clear() | |
| 511 | - if not next(self.advInfo) then return end --未初始化的 advInfo | |
| 512 | - | |
| 513 | - local mapData = self:getMapData() | |
| 514 | - if not mapData then return end | |
| 515 | - | |
| 516 | - for roomId, roomName in pairs(mapData["rooms"]) do | |
| 517 | - if roomName == "path" then | |
| 518 | - self.rooms[roomId] = Room.new(self, roomId, mapData["path"], self.advInfo.rooms[roomId], true) | |
| 519 | - else | |
| 520 | - roomName = roomName:gsub("/", "_") | |
| 521 | - self.rooms[roomId] = Room.new(self, roomId, csvdb["room_" .. roomName .. "Csv"], self.advInfo.rooms[roomId], false) | |
| 522 | - end | |
| 523 | - end | |
| 524 | - self:initBattle() | |
| 525 | - return true | |
| 526 | -end | |
| 527 | - | |
| 528 | -function Adv:triggerPassive(condType, params) | |
| 529 | - if not self.battle then | |
| 530 | - table.insert(self.cachePassiveEvent, {condType, params}) | |
| 531 | - else | |
| 532 | - self.battle:triggerPassive(condType, params) | |
| 533 | - end | |
| 534 | -end | |
| 535 | - | |
| 536 | -function Adv:initBattle() | |
| 537 | - self.battle = require("adv.AdvBattle").new(self) | |
| 538 | - for _, passiveC in ipairs(self.cachePassiveEvent) do | |
| 539 | - self.battle:triggerPassive(passiveC[1], passiveC[2]) | |
| 540 | - end | |
| 541 | - self.cachePassiveEvent = {} | |
| 542 | -end | |
| 543 | - | |
| 544 | --- 随机地图 | |
| 545 | -function Adv:initByChapter(chapterId, level, notNotify) | |
| 546 | - level = level or 1 | |
| 547 | - randomAdvMap(self.owner, chapterId, level, notNotify) | |
| 548 | - if not next(self.advInfo) then return end | |
| 549 | - if level > 1 then | |
| 550 | - self:scoreChange(AdvScoreType.Level) | |
| 551 | - end | |
| 552 | - self:initByInfo() --初始化 | |
| 553 | - self.owner:updateProperties({advInfo = self.advInfo, advTeam = self.advTeam}, notNotify) | |
| 554 | -end | |
| 555 | - | |
| 556 | ---获取,某个位置上的 room 和 block | |
| 557 | -function Adv:getRBByPos(c, r) | |
| 558 | - for roomId, room in pairs(self.rooms) do | |
| 559 | - local block = room:getBByGPos(c, r) | |
| 560 | - if block then | |
| 561 | - return room, block | |
| 562 | - end | |
| 563 | - end | |
| 564 | -end | |
| 565 | - | |
| 566 | -function Adv:getAroundBlocks(room, block) | |
| 567 | - local blocks = {} | |
| 568 | - local range = {1, -1} | |
| 569 | - local col, row = room:tranLtoG(block.col, block.row) | |
| 570 | - for _, add in ipairs(range) do | |
| 571 | - local rroom, rblock = self:getRBByPos(col + add, row) | |
| 572 | - if rroom then | |
| 573 | - table.insert(blocks, {rroom, rblock}) | |
| 574 | - end | |
| 159 | +function Adv:randomMapId(chapterId, level) | |
| 160 | + local chapterData = csvdb["adv_chapterCsv"][chapterId] | |
| 161 | + if not chapterData then | |
| 162 | + error("chapterId " .. chapterId .. " dont exist!") | |
| 163 | + return | |
| 575 | 164 | end |
| 576 | - for _, add in ipairs(range) do | |
| 577 | - local rroom, rblock = self:getRBByPos(col, row + add) | |
| 578 | - if rroom then | |
| 579 | - table.insert(blocks, {rroom, rblock}) | |
| 580 | - end | |
| 165 | + if level > chapterData.limitlevel then | |
| 166 | + error("level overflow!") | |
| 167 | + return | |
| 581 | 168 | end |
| 582 | - return blocks | |
| 583 | -end | |
| 169 | + --随出地图Id | |
| 170 | + local raw_pool = chapterData.mapid:toArray(true, "=") | |
| 584 | 171 | |
| 585 | ---随机一个空的位置生成怪, 如果没有就没有 | |
| 586 | -function Adv:addNewMonsterRand(monsterId, where) | |
| 587 | - local room, block | |
| 588 | - if where then | |
| 589 | - room, block = where[1], where[2] | |
| 590 | - else | |
| 591 | - local pool = {} | |
| 592 | - for _, room_ in pairs(self.rooms) do | |
| 593 | - for _, block_ in pairs(room_.blocks) do | |
| 594 | - if block_.isOpen and not block_.event then | |
| 595 | - table.insert(pool, {room_, block_}) | |
| 596 | - end | |
| 597 | - end | |
| 598 | - end | |
| 599 | - if not next(pool) then return end | |
| 600 | - local idx = math.randomInt(1, #pool) | |
| 601 | - room, block = pool[idx][1], pool[idx][2] | |
| 172 | + local lastMapIds = {} | |
| 173 | + for id, map in ipairs(self.maps or {}) do | |
| 174 | + lastMapIds[map.mapId] = 1 | |
| 602 | 175 | end |
| 603 | 176 | |
| 604 | - if not monsterId then | |
| 605 | - local eventLib = getEventLib(self.advInfo.chapter, self.advInfo.level, AdvEventType.Monster) | |
| 606 | - if not next(eventLib[AdvEventType.Monster][0]) then return false end | |
| 607 | - monsterId = math.randWeight(eventLib[AdvEventType.Monster][0], "showup") | |
| 608 | - end | |
| 609 | - | |
| 610 | - local event = {etype = AdvEventType.Monster, mId = self.advInfo.enemyId} | |
| 611 | - self.advInfo.enemyId = self.advInfo.enemyId + 1 | |
| 612 | - event.id = monsterId | |
| 613 | - block.event = event | |
| 614 | - room.info.event[block.blockId] = event | |
| 615 | - self.battle:addEnemy(room, block):triggerPassive(Passive.BORN_ONCE) | |
| 616 | - | |
| 617 | - return room, block | |
| 618 | -end | |
| 619 | - | |
| 620 | --- 随机翻开 num 个 以开放的房间的 地块 | |
| 621 | -function Adv:openBlockRand(num) | |
| 622 | 177 | local pool = {} |
| 623 | - for _, room in pairs(self.rooms) do | |
| 624 | - if room.isShow and not room.isPath then | |
| 625 | - for _, block in pairs(room.blocks) do | |
| 626 | - if not block.isOpen then | |
| 627 | - table.insert(pool, {room.roomId, block.blockId}) | |
| 628 | - end | |
| 178 | + for _, mapId in ipairs(raw_pool) do | |
| 179 | + local temp = csvdb["mapCsv"][mapId] | |
| 180 | + if temp and not lastMapIds[mapId] then | |
| 181 | + if AdvCommon.checkIsIn(level, temp.leveltype, temp.levellimit) then | |
| 182 | + table.insert(pool, mapId) | |
| 629 | 183 | end |
| 630 | 184 | end |
| 631 | 185 | end |
| 632 | - if #pool <= num then | |
| 633 | - for _, temp in ipairs(pool) do | |
| 634 | - self:openBlock(temp[1], temp[2]) | |
| 635 | - end | |
| 636 | - else | |
| 637 | - for i = 1, num do | |
| 638 | - local idx = math.randomInt(1, #pool) | |
| 639 | - self:openBlock(pool[idx][1], pool[idx][2]) | |
| 640 | - table.remove(pool, idx) | |
| 641 | - end | |
| 186 | + if not next(pool) then | |
| 187 | + error("mapIds is empty!") | |
| 188 | + return | |
| 642 | 189 | end |
| 643 | -end | |
| 644 | --- 打开一个地块 | |
| 645 | -function Adv:openBlock(roomId, blockId) | |
| 646 | - local room = self.rooms[roomId] | |
| 647 | - if not room then return end | |
| 648 | - local block = room.blocks[blockId] | |
| 649 | - if not block then return end | |
| 650 | - room:openBlock(block, self) | |
| 651 | - self:backBlockChange(roomId, blockId) | |
| 190 | + return pool[math.randomInt(1, #pool)] | |
| 652 | 191 | end |
| 653 | 192 | |
| 193 | + | |
| 654 | 194 | -- 在冒险中获得的物品都发放在冒险背包内 |
| 655 | 195 | function Adv:award(gift, params) |
| 656 | 196 | params = params or {} |
| ... | ... | @@ -707,13 +247,19 @@ end |
| 707 | 247 | |
| 708 | 248 | --事件点击处理 |
| 709 | 249 | local function clickOut(self, room, block, params) |
| 710 | - if self:cost({[ItemId.AdvKey] = 1}, {}) then | |
| 711 | - if self.advInfo.level >= csvdb["adv_chapterCsv"][self.advInfo.chapter].limitlevel then --关卡结束 | |
| 712 | - self:over(true) | |
| 713 | - else | |
| 714 | - self:initByChapter(self.advInfo.chapter, self.advInfo.level + 1, true) | |
| 715 | - self:backNext() --下一关 | |
| 250 | + if self:getCurMap():checkOver() then --检查是否可以出去了 | |
| 251 | + if #self.mapStack > 1 then -- 处于夹层中 | |
| 252 | + table.remove(self.mapStack) --退出夹层 | |
| 253 | + self:backLayer() | |
| 254 | + else --处于底层 | |
| 255 | + if self.level >= csvdb["adv_chapterCsv"][self.chapterId].limitlevel then --关卡结束 | |
| 256 | + self:over(true) | |
| 257 | + else | |
| 258 | + self:initByChapter(self.chapterId, self.level + 1, true, true) | |
| 259 | + self:backNext() --下一关 | |
| 260 | + end | |
| 716 | 261 | end |
| 262 | + | |
| 717 | 263 | return true |
| 718 | 264 | end |
| 719 | 265 | end |
| ... | ... | @@ -739,17 +285,14 @@ local function clickChoose(self, room, block, params) |
| 739 | 285 | end, |
| 740 | 286 | -- xx角色(todo 队长) |
| 741 | 287 | [2] = function() |
| 742 | - for slot, heroId in pairs(self.advTeam.heros) do | |
| 743 | - if self.owner.heros[heroId] then | |
| 744 | - if self.owner.heros[heroId]:getProperty("type") == cond[2] then | |
| 745 | - return true | |
| 746 | - end | |
| 747 | - end | |
| 288 | + local hero = self.owner.heros[self.owner:getProperty("advTeam").leader] | |
| 289 | + if hero and hero:getProperty("type") == cond[2] then | |
| 290 | + return true | |
| 748 | 291 | end |
| 749 | 292 | end, |
| 750 | 293 | --消灭所有怪 |
| 751 | 294 | [3] = function() |
| 752 | - for _, room in pairs(self.rooms) do | |
| 295 | + for _, room in pairs(self:getCurMap().rooms) do | |
| 753 | 296 | for _, block in pairs(room.blocks) do |
| 754 | 297 | if block.event and (block.event.etype == AdvEventType.BOSS or block.event.etype == AdvEventType.Monster) then |
| 755 | 298 | return |
| ... | ... | @@ -784,7 +327,7 @@ local function clickChoose(self, room, block, params) |
| 784 | 327 | self.battle.player:addBuff(effect[2]) |
| 785 | 328 | end, |
| 786 | 329 | [3] = function() --发现怪物 |
| 787 | - self:addNewMonsterRand(effect[2], {room, block}) | |
| 330 | + self:getCurMap():addNewMonsterRand(effect[2], {room, block}) | |
| 788 | 331 | clearBlock = false |
| 789 | 332 | end, |
| 790 | 333 | [4] = function() --无事发生 |
| ... | ... | @@ -795,7 +338,7 @@ local function clickChoose(self, room, block, params) |
| 795 | 338 | end |
| 796 | 339 | |
| 797 | 340 | if clearBlock then |
| 798 | - room:clearBEvent(block) | |
| 341 | + block:clear() | |
| 799 | 342 | end |
| 800 | 343 | return true |
| 801 | 344 | end |
| ... | ... | @@ -804,7 +347,7 @@ local function clickDrop(self, room, block, params) |
| 804 | 347 | local reward = {} |
| 805 | 348 | if not block.event.item then return end |
| 806 | 349 | local reward = self:award({[block.event.item[1]] = block.event.item[2]}) |
| 807 | - room:clearBEvent(block) | |
| 350 | + block:clear() | |
| 808 | 351 | self:backReward(reward) |
| 809 | 352 | return true |
| 810 | 353 | end |
| ... | ... | @@ -840,7 +383,7 @@ local function clickBuild(self, room, block, params) |
| 840 | 383 | self.battle.player:addBuff(effect[2]) |
| 841 | 384 | end, |
| 842 | 385 | [3] = function() --发现怪物 |
| 843 | - self:addNewMonsterRand(effect[2], {room, block}) | |
| 386 | + self:getCurMap():addNewMonsterRand(effect[2], {room, block}) | |
| 844 | 387 | clearBlock = false |
| 845 | 388 | end, |
| 846 | 389 | [4] = function() --无事发生 |
| ... | ... | @@ -850,7 +393,7 @@ local function clickBuild(self, room, block, params) |
| 850 | 393 | if not self:cost(buildData.required:toNumMap(), {}) then return end |
| 851 | 394 | doEffect[effect[1]]() |
| 852 | 395 | if clearBlock then |
| 853 | - room:clearBEvent(block) | |
| 396 | + block:clear() | |
| 854 | 397 | end |
| 855 | 398 | return true |
| 856 | 399 | end |
| ... | ... | @@ -875,11 +418,28 @@ local function clickClick(self, room, block, params) |
| 875 | 418 | end, |
| 876 | 419 | } |
| 877 | 420 | if clearBlock then |
| 878 | - room:clearBEvent(block) | |
| 421 | + block:clear() | |
| 879 | 422 | end |
| 880 | 423 | return true |
| 881 | 424 | end |
| 882 | 425 | |
| 426 | +local function clickLayer(self, room, block, params) | |
| 427 | + if block.event.mapIdx then | |
| 428 | + table.insert(self.mapStack, block.event.mapIdx) --进入夹层 | |
| 429 | + else | |
| 430 | + --生成夹层 | |
| 431 | + local mapId = csvdb["event_layerCsv"][block.event.id].effect | |
| 432 | + local mapIdx = #self.maps + 1 | |
| 433 | + block.event.mapIdx = mapIdx | |
| 434 | + table.insert(self.mapStack, mapIdx) | |
| 435 | + | |
| 436 | + self.maps[mapIdx] = AdvMap.new(self, mapIdx, mapId) | |
| 437 | + self.battle:initMapEnemys(mapIdx) | |
| 438 | + end | |
| 439 | + self:backLayer() | |
| 440 | + return true | |
| 441 | +end | |
| 442 | + | |
| 883 | 443 | local eventCallFunc = { |
| 884 | 444 | [AdvEventType.Out] = clickOut, |
| 885 | 445 | [AdvEventType.BOSS] = clickMonster, |
| ... | ... | @@ -889,14 +449,15 @@ local eventCallFunc = { |
| 889 | 449 | [AdvEventType.Trader] = clickTrader, |
| 890 | 450 | [AdvEventType.Build] = clickBuild, |
| 891 | 451 | [AdvEventType.Click] = clickClick, |
| 452 | + [AdvEventType.Layer] = clickLayer, | |
| 892 | 453 | } |
| 893 | 454 | |
| 894 | 455 | --点击处理 roomId, blockId |
| 895 | 456 | --params 某些事件需要的客户端传递的参数 |
| 896 | 457 | function Adv:clickBlock(roomId, blockId, params) |
| 897 | - local room = self.rooms[roomId] | |
| 898 | - if not room then return end | |
| 899 | - local block = room.blocks[blockId] | |
| 458 | + local map = self:getCurMap() | |
| 459 | + local room = self:getRoom(roomId) | |
| 460 | + local block = self:getBlock(roomId, blockId) | |
| 900 | 461 | if not block then return end |
| 901 | 462 | |
| 902 | 463 | local status = false |
| ... | ... | @@ -904,15 +465,15 @@ function Adv:clickBlock(roomId, blockId, params) |
| 904 | 465 | if not block.isOpen then |
| 905 | 466 | local canOpen = false --如果未开放是否可以开放 |
| 906 | 467 | local hadMonster = false -- 周围是否有解锁的怪未击败 |
| 907 | - for _, one in ipairs(self:getAroundBlocks(room, block)) do | |
| 468 | + for _, one in ipairs(map:getAroundBlocks(room, block)) do | |
| 908 | 469 | local _room, _block = one[1], one[2] |
| 909 | 470 | if _block.isOpen then canOpen = true end |
| 910 | - if _block.isOpen and _block.event and (_block.event.etype == AdvEventType.BOSS or _block.event.etype == AdvEventType.Monster) then | |
| 471 | + if _block.isOpen and _block:isMonster() then | |
| 911 | 472 | hadMonster = true |
| 912 | 473 | end |
| 913 | 474 | end |
| 914 | 475 | if canOpen and not hadMonster then --开放 |
| 915 | - room:openBlock(block, self) | |
| 476 | + room:openBlock(block) | |
| 916 | 477 | status = true |
| 917 | 478 | end |
| 918 | 479 | else |
| ... | ... | @@ -922,15 +483,15 @@ function Adv:clickBlock(roomId, blockId, params) |
| 922 | 483 | return |
| 923 | 484 | end |
| 924 | 485 | --可点击的事件 |
| 925 | - if not room.isBossRoom or block.event.etype == AdvEventType.BOSS then | |
| 486 | + if not room.isBossRoom or block:isBoss() then | |
| 926 | 487 | if eventCallFunc[block.event.etype] then |
| 927 | - status = eventCallFunc[block.event.etype](self, room, block, params) | |
| 488 | + status = eventCallFunc[block:getEventType()](self, room, block, params) | |
| 928 | 489 | end |
| 929 | 490 | end |
| 930 | 491 | end |
| 931 | 492 | local needChange = true |
| 932 | 493 | if clickEvent and block.event then |
| 933 | - if block.event.etype == AdvEventType.Out then | |
| 494 | + if block:getEventType() == AdvEventType.Out then | |
| 934 | 495 | needChange = false |
| 935 | 496 | end |
| 936 | 497 | end |
| ... | ... | @@ -991,34 +552,33 @@ end |
| 991 | 552 | |
| 992 | 553 | --敌人死亡 |
| 993 | 554 | function Adv:enemyDead(roomId, blockId, escape) |
| 994 | - local room = self.rooms[roomId] | |
| 995 | - local block = room.blocks[blockId] | |
| 555 | + local map = self:getCurMap() | |
| 556 | + local room = self:getRoom(roomId) | |
| 557 | + local block = self:getBlock(roomId, blockId) | |
| 558 | + if not block then return end | |
| 996 | 559 | --死了以后掉东西 |
| 997 | - if block.event and (block.event.etype == AdvEventType.BOSS or block.event.etype == AdvEventType.Monster) then --处理死亡 | |
| 998 | - if block.event.etype == AdvEventType.BOSS then | |
| 560 | + if block:isMonster() then --处理死亡 | |
| 561 | + if block:isBoss() then | |
| 999 | 562 | room.isBossRoom = false |
| 1000 | 563 | end |
| 1001 | 564 | if escape then |
| 1002 | - room:clearBEvent(block) | |
| 565 | + block:clear() | |
| 1003 | 566 | else |
| 1004 | 567 | local monsterData = csvdb["event_monsterCsv"][block.event.id] |
| 1005 | 568 | self:scoreChange(AdvScoreType.Kill, monsterData.type) |
| 1006 | 569 | |
| 1007 | 570 | local item = block.event.item |
| 1008 | 571 | if not item then |
| 1009 | - if block.event.etype == AdvEventType.BOSS then | |
| 1010 | - item = {ItemId.AdvKey, 1} | |
| 1011 | - else | |
| 1012 | - local dropData = csvdb["event_dropCsv"][monsterData.dropid] | |
| 1013 | - item = dropData["range"]:randWeight(true) | |
| 1014 | - end | |
| 572 | + local dropData = csvdb["event_dropCsv"][monsterData.dropid] | |
| 573 | + item = dropData["range"]:randWeight(true) | |
| 1015 | 574 | end |
| 1016 | 575 | if item[1] == 0 then |
| 1017 | - room:clearBEvent(block) | |
| 576 | + block:clear() | |
| 1018 | 577 | else |
| 1019 | - table.clear(block.event) | |
| 1020 | - block.event.etype = AdvEventType.Drop | |
| 1021 | - block.event.item = item | |
| 578 | + block:updateEvent({ | |
| 579 | + etype = AdvEventType.Drop, | |
| 580 | + item = item | |
| 581 | + }) | |
| 1022 | 582 | end |
| 1023 | 583 | end |
| 1024 | 584 | end |
| ... | ... | @@ -1090,6 +650,10 @@ function Adv:backTrap() |
| 1090 | 650 | self:pushBackEvent(AdvBackEventType.Trap, {}) |
| 1091 | 651 | end |
| 1092 | 652 | |
| 653 | +function Adv:backLayer() | |
| 654 | + self:pushBackEvent(AdvBackEventType.Layer, {}) | |
| 655 | +end | |
| 656 | + | |
| 1093 | 657 | function Adv:scoreChange(scoreType, pms) |
| 1094 | 658 | local cutTypes = {} |
| 1095 | 659 | local score = 0 |
| ... | ... | @@ -1097,7 +661,7 @@ function Adv:scoreChange(scoreType, pms) |
| 1097 | 661 | score = globalCsv.adv_score_floor |
| 1098 | 662 | end |
| 1099 | 663 | cutTypes[AdvScoreType.Kill] = function() |
| 1100 | - local chapterData = csvdb["adv_chapterCsv"][self.advInfo.chapter] | |
| 664 | + local chapterData = csvdb["adv_chapterCsv"][self.chapterId] | |
| 1101 | 665 | score = globalCsv.adv_score_monster[pms] * chapterData["monRatio"] |
| 1102 | 666 | end |
| 1103 | 667 | cutTypes[AdvScoreType.Item] = function() |
| ... | ... | @@ -1114,25 +678,23 @@ function Adv:scoreChange(scoreType, pms) |
| 1114 | 678 | else |
| 1115 | 679 | return |
| 1116 | 680 | end |
| 1117 | - self.advInfo.score[scoreType] = self.advInfo.score[scoreType] or 0 | |
| 1118 | - self.advInfo.score[scoreType] = self.advInfo.score[scoreType] + score | |
| 681 | + self.score[scoreType] = self.score[scoreType] or 0 | |
| 682 | + self.score[scoreType] = self.score[scoreType] + score | |
| 1119 | 683 | end |
| 1120 | 684 | |
| 1121 | 685 | function Adv:getScore() |
| 1122 | - self.advInfo.score[AdvScoreType.Level] = math.floor(self.advInfo.score[AdvScoreType.Level] or 0) | |
| 1123 | - self.advInfo.score[AdvScoreType.Block] = math.floor(self.advInfo.score[AdvScoreType.Block] or 0) | |
| 1124 | - self.advInfo.score[AdvScoreType.Hurt] = math.max(math.floor(self.advInfo.score[AdvScoreType.Hurt] or 0), - (self.advInfo.score[AdvScoreType.Level] + self.advInfo.score[AdvScoreType.Block])) | |
| 1125 | - self.advInfo.score[AdvScoreType.Kill] = math.floor(self.advInfo.score[AdvScoreType.Kill] or 0) | |
| 1126 | - self.advInfo.score[AdvScoreType.Item] = math.floor(self.advInfo.score[AdvScoreType.Item] or 0) | |
| 1127 | - | |
| 1128 | - return self.advInfo.score[AdvScoreType.Level] + self.advInfo.score[AdvScoreType.Block] + self.advInfo.score[AdvScoreType.Hurt] | |
| 1129 | - + self.advInfo.score[AdvScoreType.Kill] + self.advInfo.score[AdvScoreType.Item] | |
| 686 | + self.score[AdvScoreType.Level] = math.floor(self.score[AdvScoreType.Level] or 0) | |
| 687 | + self.score[AdvScoreType.Block] = math.floor(self.score[AdvScoreType.Block] or 0) | |
| 688 | + self.score[AdvScoreType.Hurt] = math.max(math.floor(self.score[AdvScoreType.Hurt] or 0), - (self.score[AdvScoreType.Level] + self.score[AdvScoreType.Block])) | |
| 689 | + self.score[AdvScoreType.Kill] = math.floor(self.score[AdvScoreType.Kill] or 0) | |
| 690 | + self.score[AdvScoreType.Item] = math.floor(self.score[AdvScoreType.Item] or 0) | |
| 691 | + | |
| 692 | + return self.score[AdvScoreType.Level] + self.score[AdvScoreType.Block] + self.score[AdvScoreType.Hurt] | |
| 693 | + + self.score[AdvScoreType.Kill] + self.score[AdvScoreType.Item] | |
| 1130 | 694 | end |
| 1131 | 695 | |
| 1132 | 696 | function Adv:popBackEvents() |
| 1133 | 697 | local events = self.backEvents |
| 1134 | - -- TODO 缓存数据需要分类,防止发错,暂时只有战斗,可以不分 | |
| 1135 | - self.tempBackEvents = events | |
| 1136 | 698 | self.backEvents = {} |
| 1137 | 699 | return events |
| 1138 | 700 | end |
| ... | ... | @@ -1142,14 +704,6 @@ function Adv:afterRound() |
| 1142 | 704 | if self.battle then |
| 1143 | 705 | self.battle:afterRound() |
| 1144 | 706 | end |
| 1145 | - -- TODO 房间回合事件 | |
| 1146 | -end | |
| 1147 | - | |
| 1148 | -function Adv:saveDB() | |
| 1149 | - if self.battle then | |
| 1150 | - self.battle:getDB() | |
| 1151 | - end | |
| 1152 | - self.owner:updateProperties({advInfo = self.advInfo, advTeam = self.advTeam}) | |
| 1153 | 707 | end |
| 1154 | 708 | |
| 1155 | 709 | return Adv |
| 1156 | 710 | \ No newline at end of file | ... | ... |
src/adv/AdvBattle.lua
| ... | ... | @@ -7,7 +7,7 @@ function Battle:ctor(adv) |
| 7 | 7 | self.player = nil --玩家 |
| 8 | 8 | self.isNewPlayer = false |
| 9 | 9 | self.enemys = {} --怪 |
| 10 | - self.tempData = {} -- 临时回合数据 | |
| 10 | + self.cachePassiveEvent = {} | |
| 11 | 11 | self:initPlayer() |
| 12 | 12 | self:initEnemys() |
| 13 | 13 | self:initAfter() |
| ... | ... | @@ -17,9 +17,11 @@ function Battle:ctor(adv) |
| 17 | 17 | end |
| 18 | 18 | |
| 19 | 19 | function Battle:initAfter() |
| 20 | - self.player:initAfter(self.adv.advTeam.player) | |
| 21 | - for _, enemy in pairs(self.enemys) do | |
| 22 | - enemy:initAfter(self.adv.rooms[enemy.roomId].blocks[enemy.blockId].event.enemy) | |
| 20 | + self.player:initAfter(self.adv.owner:getProperty("advTeam").player) | |
| 21 | + for idx, mapEnemys in pairs(self.enemys) do | |
| 22 | + for _, enemy in ipairs(mapEnemys) do | |
| 23 | + enemy:initAfter(self.adv:getBlock(enemy.roomId, enemy.blockId, idx).event.enemy) | |
| 24 | + end | |
| 23 | 25 | end |
| 24 | 26 | end |
| 25 | 27 | --[[ |
| ... | ... | @@ -33,12 +35,14 @@ end |
| 33 | 35 | --]] |
| 34 | 36 | |
| 35 | 37 | function Battle:initPlayer() |
| 36 | - if not next(self.adv.advTeam.heros) then return end | |
| 37 | - if not self.adv.advTeam.player then | |
| 38 | - local player = {} | |
| 38 | + local advTeam = self.adv.owner:getProperty("advTeam") | |
| 39 | + if not next(advTeam.heros) then return end | |
| 40 | + local player = advTeam.player | |
| 41 | + if not player then | |
| 42 | + player = {} | |
| 39 | 43 | player.passives = {} |
| 40 | 44 | local heroLevel = 0 |
| 41 | - for slot, heroId in pairs(self.adv.advTeam.heros) do | |
| 45 | + for slot, heroId in pairs(advTeam.heros) do | |
| 42 | 46 | local hero = self.adv.owner.heros[heroId] |
| 43 | 47 | if hero then |
| 44 | 48 | heroLevel = heroLevel + hero:getProperty("level") |
| ... | ... | @@ -48,56 +52,77 @@ function Battle:initPlayer() |
| 48 | 52 | end |
| 49 | 53 | end |
| 50 | 54 | end |
| 51 | - player.growth = (self.adv.owner:getRealBattleValue(self.adv.advTeam.heros) / 80) ^ 0.52 + math.floor(heroLevel / 50) / 50 | |
| 55 | + player.growth = (self.adv.owner:getRealBattleValue(advTeam.heros) / 80) ^ 0.52 + math.floor(heroLevel / 50) / 50 | |
| 52 | 56 | player.level = 1 |
| 53 | 57 | player.exp = 0 |
| 54 | 58 | player.sp = 100 |
| 55 | 59 | local activeRelation = self.adv.owner:getHeroActiveRelation() |
| 56 | - local baseAttr = csvdb["adv_unitCsv"][math.floor(self.adv.advInfo.chapter / 100)] | |
| 60 | + local baseAttr = csvdb["adv_unitCsv"][math.floor(self.adv.chapterId / 100)] | |
| 57 | 61 | for _, attr in pairs(AttsEnumEx) do |
| 58 | 62 | if baseAttr[attr] then |
| 59 | 63 | player[attr] = baseAttr[attr] + baseAttr[attr] * player.growth * (player.level - 1) |
| 60 | 64 | end |
| 61 | 65 | end |
| 62 | 66 | player.hpMax = player.hp or 0 |
| 63 | - self.adv.advTeam.player = player | |
| 64 | 67 | self.isNewPlayer = true |
| 68 | + advTeam.player = player | |
| 65 | 69 | end |
| 66 | - self.player = Player.new(self, self.adv.advTeam.player) | |
| 70 | + self.player = Player.new(self, player) | |
| 67 | 71 | end |
| 68 | 72 | |
| 69 | 73 | function Battle:initEnemys() |
| 70 | - for _, room in pairs(self.adv.rooms) do | |
| 71 | - for _, block in pairs(room.blocks) do | |
| 72 | - self:addEnemy(room, block) | |
| 74 | + for idx, map in pairs(self.adv.maps) do | |
| 75 | + self:initMapEnemys(idx) | |
| 76 | + end | |
| 77 | +end | |
| 78 | + | |
| 79 | +function Battle:initMapEnemys(mapIdx) | |
| 80 | + self.enemys[mapIdx] = {} | |
| 81 | + local map = self.adv.maps[mapIdx] | |
| 82 | + if map then | |
| 83 | + for _, room in pairs(map.rooms) do | |
| 84 | + for _, block in pairs(room.blocks) do | |
| 85 | + self:addEnemy(room, block, mapIdx) | |
| 86 | + end | |
| 87 | + end | |
| 88 | + end | |
| 89 | + if self.cachePassiveEvent[mapIdx] then | |
| 90 | + for _, passiveC in ipairs(self.cachePassiveEvent or {}) do | |
| 91 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
| 92 | + enemy:triggerPassive(passiveC[1], passiveC[2]) | |
| 93 | + end | |
| 73 | 94 | end |
| 74 | 95 | end |
| 96 | + self.cachePassiveEvent[mapIdx] = nil | |
| 75 | 97 | end |
| 76 | 98 | |
| 77 | -function Battle:addEnemy(room, block) | |
| 78 | - if block.event and (block.event.etype == AdvEventType.BOSS or block.event.etype == AdvEventType.Monster) then | |
| 99 | +function Battle:addEnemy(room, block, mapIdx) | |
| 100 | + mapIdx = mapIdx or self.adv:getCurMapIdx() | |
| 101 | + | |
| 102 | + if block:isMonster() then | |
| 79 | 103 | if not block.event.enemy then |
| 80 | 104 | local enemyCsv = csvdb["event_monsterCsv"][block.event.id] |
| 81 | 105 | local enemy = {} |
| 82 | - enemy.hp = enemyCsv.hp + enemyCsv.levelhp * self.adv.advInfo.level | |
| 83 | - enemy.atk = enemyCsv.atk + enemyCsv.levelatk * self.adv.advInfo.level | |
| 84 | - enemy.hit = enemyCsv.hit + enemyCsv.levelhit * self.adv.advInfo.level | |
| 85 | - enemy.miss = enemyCsv.miss + enemyCsv.levelmiss * self.adv.advInfo.level | |
| 86 | - enemy.def = enemyCsv.def + enemyCsv.leveldef * self.adv.advInfo.level | |
| 106 | + enemy.hp = enemyCsv.hp + enemyCsv.levelhp * self.adv.level | |
| 107 | + enemy.atk = enemyCsv.atk + enemyCsv.levelatk * self.adv.level | |
| 108 | + enemy.hit = enemyCsv.hit + enemyCsv.levelhit * self.adv.level | |
| 109 | + enemy.miss = enemyCsv.miss + enemyCsv.levelmiss * self.adv.level | |
| 110 | + enemy.def = enemyCsv.def + enemyCsv.leveldef * self.adv.level | |
| 87 | 111 | enemy.passives = {} |
| 88 | 112 | for _, id in ipairs(enemyCsv.mapPassive:toArray(true, "=")) do |
| 89 | 113 | table.insert(enemy.passives, {id = id}) |
| 90 | 114 | end |
| 91 | 115 | block.event.enemy = enemy |
| 92 | 116 | end |
| 93 | - local player = Enemy.new(self, block.event.mId or 999, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.enemy) | |
| 94 | - table.insert(self.enemys, player) | |
| 117 | + local player = Enemy.new(self, block.event.mId or 999, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.enemy, mapIdx) | |
| 118 | + table.insert(self.enemys[mapIdx], player) | |
| 95 | 119 | return player |
| 96 | 120 | end |
| 97 | 121 | end |
| 98 | 122 | |
| 99 | -function Battle:getEnemy(roomId, blockId) | |
| 100 | - for _, enemy in ipairs(self.enemys) do | |
| 123 | +function Battle:getEnemy(roomId, blockId, mapIdx) | |
| 124 | + mapIdx = mapIdx or self.adv:getCurMapIdx() | |
| 125 | + for _, enemy in ipairs(self.enemys[mapIdx] or {}) do | |
| 101 | 126 | if enemy.roomId == roomId and enemy.blockId == blockId then |
| 102 | 127 | return enemy |
| 103 | 128 | end |
| ... | ... | @@ -105,45 +130,55 @@ function Battle:getEnemy(roomId, blockId) |
| 105 | 130 | end |
| 106 | 131 | |
| 107 | 132 | function Battle:getEnemyById(id) |
| 108 | - for _, enemy in ipairs(self.enemys) do | |
| 109 | - if enemy.id == id then | |
| 110 | - return enemy | |
| 133 | + for idx, mapEnemys in pairs(self.enemys) do | |
| 134 | + for _, enemy in ipairs(mapEnemys) do | |
| 135 | + if enemy.id == id then | |
| 136 | + return enemy | |
| 137 | + end | |
| 111 | 138 | end |
| 112 | 139 | end |
| 113 | 140 | end |
| 114 | 141 | |
| 115 | 142 | function Battle:getRBByEnemyId(enemyId) |
| 116 | 143 | local enemy = self:getEnemyById(enemyId) |
| 117 | - return enemy.roomId, enemy.blockId | |
| 144 | + return enemy.roomId, enemy.blockId, enemy.mapIdx | |
| 118 | 145 | end |
| 119 | 146 | |
| 120 | 147 | |
| 121 | 148 | --触发全员被动技能 |
| 122 | -function Battle:triggerPassive(condType, params) | |
| 149 | +function Battle:triggerPassive(condType, params, mapIdx) | |
| 150 | + mapIdx = mapIdx or self.adv:getCurMapIdx() | |
| 123 | 151 | self.player:triggerPassive(condType, params) |
| 124 | - for _, enemy in ipairs(self.enemys) do | |
| 125 | - enemy:triggerPassive(condType, params) | |
| 152 | + if not self.enemys[mapIdx] then | |
| 153 | + -- 缓存一下 | |
| 154 | + self.cachePassiveEvent[mapIdx] = self.cachePassiveEvent[mapIdx] or {} | |
| 155 | + table.insert(self.cachePassiveEvent[mapIdx], {condType, params}) | |
| 156 | + else | |
| 157 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
| 158 | + enemy:triggerPassive(condType, params) | |
| 159 | + end | |
| 126 | 160 | end |
| 127 | 161 | end |
| 128 | 162 | |
| 129 | 163 | --回合 |
| 130 | 164 | function Battle:afterRound() |
| 165 | + local mapIdx = self.adv:getCurMapIdx() | |
| 131 | 166 | self.player:afterRound() |
| 132 | - table.sort(self.enemys, function(e1, e2) | |
| 167 | + table.sort(self.enemys[mapIdx], function(e1, e2) | |
| 133 | 168 | return e1.id < e2.id |
| 134 | 169 | end) |
| 135 | - for _, enemy in ipairs(self.enemys) do | |
| 170 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
| 136 | 171 | enemy:afterRound() |
| 137 | 172 | end |
| 138 | 173 | self.player:clearRound() |
| 139 | - for _, enemy in ipairs(self.enemys) do | |
| 174 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
| 140 | 175 | enemy:clearRound() |
| 141 | 176 | end |
| 142 | - for i = #self.enemys, 1, -1 do | |
| 143 | - if self.enemys[i].isDead then | |
| 144 | - self.adv:enemyDead(self.enemys[i].roomId, self.enemys[i].blockId) | |
| 145 | - self.enemys[i]:clear() | |
| 146 | - table.remove(self.enemys, i) | |
| 177 | + for i = #self.enemys[mapIdx], 1, -1 do | |
| 178 | + if self.enemys[mapIdx][i].isDead then | |
| 179 | + self.adv:enemyDead(self.enemys[mapIdx][i].roomId, self.enemys[mapIdx][i].blockId) | |
| 180 | + self.enemys[mapIdx][i]:clear() | |
| 181 | + table.remove(self.enemys[mapIdx], i) | |
| 147 | 182 | end |
| 148 | 183 | end |
| 149 | 184 | |
| ... | ... | @@ -162,17 +197,25 @@ function Battle:battleBegin(roomId, blockId, params) |
| 162 | 197 | enemy:hurt(enemy.hp, self.player, {hurtType = 5}) |
| 163 | 198 | self.player:effectBattleBuff() |
| 164 | 199 | end |
| 165 | - self.player:hurt(math.max(0, math.ceil(self.player.hp - player.hp)), enemy, {hurtType = 5}) --战斗血量只会变少 | |
| 166 | - self.player:changeSp(math.min(0, math.floor(player.sp - self.player.sp)) , 0) --战斗魔力只会变少 | |
| 200 | + if player.hp > self.player.hp then | |
| 201 | + self.player:recover(player.hp - self.player.hp, player) | |
| 202 | + else | |
| 203 | + self.player:hurt(math.max(0, math.ceil(self.player.hp - player.hp)), enemy, {hurtType = 5}) --战斗血量只会变少 | |
| 204 | + end | |
| 205 | + | |
| 206 | + self.player:changeSp(math.floor(player.sp - self.player.sp) , 0) --战斗魔力只会变少 | |
| 167 | 207 | end |
| 168 | 208 | |
| 169 | 209 | |
| 170 | 210 | --写入数据 |
| 171 | -function Battle:getDB() | |
| 172 | - self.adv.advTeam.player = self.player:getDB() | |
| 173 | - for _, enemy in ipairs(self.enemys) do | |
| 174 | - local block = self.adv.rooms[enemy.roomId].blocks[enemy.blockId] | |
| 175 | - block.event.enemy = enemy:getDB() | |
| 211 | +function Battle:saveDB() | |
| 212 | + for idx, mapEnemys in pairs(self.enemys) do | |
| 213 | + for _, enemy in ipairs(mapEnemys) do | |
| 214 | + local block = self.adv:getBlock(enemy.roomId, enemy.blockId, idx) | |
| 215 | + if block and block:isMonster() then | |
| 216 | + block.event.enemy = enemy:getDB() | |
| 217 | + end | |
| 218 | + end | |
| 176 | 219 | end |
| 177 | 220 | end |
| 178 | 221 | ... | ... |
| ... | ... | @@ -0,0 +1,108 @@ |
| 1 | +--块类型 | |
| 2 | +local AdvCommon = require "adv.AdvCommon" | |
| 3 | +local Passive = require "adv.AdvPassive" | |
| 4 | + | |
| 5 | +local Block = class("AdvBlock") | |
| 6 | +function Block:ctor(room, blockId, event, isOpen, trapId) | |
| 7 | + self.room = room | |
| 8 | + self.blockId = blockId | |
| 9 | + self.col, self.row = AdvCommon.getCrById(self.blockId) | |
| 10 | + | |
| 11 | + self.isOpen = isOpen and true or false | |
| 12 | + self.trapId = trapId | |
| 13 | + | |
| 14 | + self:updateEvent(event) | |
| 15 | +end | |
| 16 | +function Block:isBoss() | |
| 17 | + return self:getEventType() == AdvEventType.BOSS | |
| 18 | +end | |
| 19 | + | |
| 20 | +function Block:isMonster() | |
| 21 | + return (self:getEventType() == AdvEventType.BOSS or self:getEventType() == AdvEventType.Monster) | |
| 22 | +end | |
| 23 | + | |
| 24 | +function Block:getEventType() | |
| 25 | + return self.event and self.event.etype | |
| 26 | +end | |
| 27 | + | |
| 28 | +function Block:updateEvent(event) | |
| 29 | + self.event = event | |
| 30 | +end | |
| 31 | + | |
| 32 | +function Block:clear() | |
| 33 | + if self:getEventType() == AdvEventType.Trap then | |
| 34 | + self.trapId = self.event.id | |
| 35 | + end | |
| 36 | + self.event = nil | |
| 37 | +end | |
| 38 | + | |
| 39 | +--事件有需要额外处理的部分 | |
| 40 | +function Block:open() | |
| 41 | + local room = self.room | |
| 42 | + local map = room.map | |
| 43 | + local adv = map.adv | |
| 44 | + --如果翻开有数据处理在这里处理 | |
| 45 | + local randomFunc = {} | |
| 46 | + --怪 | |
| 47 | + randomFunc[AdvEventType.Monster] = function() | |
| 48 | + self.event.mId = adv.lastEnemyId --给怪一个有序id 回合逻辑时使用 | |
| 49 | + adv.lastEnemyId = adv.lastEnemyId + 1 | |
| 50 | + local enemy = adv.battle:getEnemy(room.roomId, self.blockId, map.mapIdx) | |
| 51 | + if enemy then | |
| 52 | + enemy:unlock(self.event.mId) | |
| 53 | + else | |
| 54 | + enemy = adv.battle:addEnemy(room, self, map.mapIdx) | |
| 55 | + end | |
| 56 | + enemy:triggerPassive(Passive.BORN_ONCE) | |
| 57 | + end | |
| 58 | + randomFunc[AdvEventType.BOSS] = randomFunc[AdvEventType.Monster] | |
| 59 | + --掉落 | |
| 60 | + randomFunc[AdvEventType.Drop] = function() | |
| 61 | + self.event.item = csvdb["event_dropCsv"][self.event.id]["range"]:randWeight(true) | |
| 62 | + end | |
| 63 | + --交易 | |
| 64 | + randomFunc[AdvEventType.Trader] = function() | |
| 65 | + local data = csvdb["event_traderCsv"][self.event.id] | |
| 66 | + self.event.shop = {} | |
| 67 | + self.event.status = "" --购买次数状态 1 就是购买过了 -- 购买id就是shop索引 | |
| 68 | + for i = 1, 10 do | |
| 69 | + local numS, rangeS = "num" .. i, "range" .. i | |
| 70 | + if data[numS] and data[rangeS] then | |
| 71 | + for j = 1, data[numS] do | |
| 72 | + table.insert(self.event.shop, data[rangeS]:randWeight(true)) | |
| 73 | + end | |
| 74 | + else | |
| 75 | + break | |
| 76 | + end | |
| 77 | + end | |
| 78 | + end | |
| 79 | + --建筑 | |
| 80 | + randomFunc[AdvEventType.Build] = function() | |
| 81 | + local data = csvdb["event_buildingCsv"][self.event.id] | |
| 82 | + self.event.effect = data["range"]:randWeight(true) --随出建筑效果 | |
| 83 | + if self.event.effect[1] == 1 then --获得某道具 | |
| 84 | + local reward = csvdb["event_dropCsv"][self.event.effect[2]]["range"]:randWeight(true) | |
| 85 | + self.event.effect[2] = reward[1] | |
| 86 | + self.event.effect[3] = reward[2] | |
| 87 | + end | |
| 88 | + end | |
| 89 | + | |
| 90 | + randomFunc[AdvEventType.Trap] = function() | |
| 91 | + local data = csvdb["event_trapCsv"][self.event.id] | |
| 92 | + for _, buffId in ipairs(data.effect:toArray(true, "=")) do | |
| 93 | + adv.battle.player:addBuff(buffId) | |
| 94 | + end | |
| 95 | + adv:backTrap() | |
| 96 | + self:clear() | |
| 97 | + end | |
| 98 | + | |
| 99 | + | |
| 100 | + if self.event then -- 随机出具体的事件 | |
| 101 | + if randomFunc[self:getEventType()] then | |
| 102 | + randomFunc[self:getEventType()]() | |
| 103 | + end | |
| 104 | + end | |
| 105 | + self.isOpen = true | |
| 106 | +end | |
| 107 | + | |
| 108 | +return Block | |
| 0 | 109 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | +-- 工具函数--第一象限 < 10000 < 第二象限 < 20000 < 第四象限 < 30000 < 第三象限 | |
| 2 | + | |
| 3 | +local AdvCommon = {} | |
| 4 | + | |
| 5 | +function AdvCommon.getIdByCr(c, r) | |
| 6 | + local crId = math.abs(r) + math.abs(c) * 100 -- row + column * 100 | |
| 7 | + if c < 0 then | |
| 8 | + crId = crId + 10000 | |
| 9 | + end | |
| 10 | + if r < 0 then | |
| 11 | + crId = crId + 20000 | |
| 12 | + end | |
| 13 | + return crId | |
| 14 | +end | |
| 15 | + | |
| 16 | +function AdvCommon.getCrById(crId) | |
| 17 | + local c = math.floor(crId % 10000 / 100) | |
| 18 | + local r = crId % 100 | |
| 19 | + local last = math.floor(crId / 10000) | |
| 20 | + if last == 3 then | |
| 21 | + c, r = -c, -r | |
| 22 | + elseif last == 1 then | |
| 23 | + c = -c | |
| 24 | + elseif last == 2 then | |
| 25 | + r = -r | |
| 26 | + end | |
| 27 | + return c, r | |
| 28 | +end | |
| 29 | + | |
| 30 | +--检查 是否满足层数限制条件 -- if checktype == 1 then check value in range a=b else check value in array a=b=c | |
| 31 | +function AdvCommon.checkIsIn(checkValue, checkType, checkRange) | |
| 32 | + if not checkValue then return end | |
| 33 | + if checkType == 1 then | |
| 34 | + local limits = checkRange:toNumMap() | |
| 35 | + for min, max in pairs(limits) do | |
| 36 | + if checkValue >= min and checkValue <= max then | |
| 37 | + return true | |
| 38 | + end | |
| 39 | + end | |
| 40 | + else | |
| 41 | + local limit = checkRange:toArray(true, "=") | |
| 42 | + for _, _l in ipairs(limit) do | |
| 43 | + if _l == checkValue then | |
| 44 | + return true | |
| 45 | + end | |
| 46 | + end | |
| 47 | + end | |
| 48 | +end | |
| 49 | + | |
| 50 | +return AdvCommon | |
| 0 | 51 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,383 @@ |
| 1 | + | |
| 2 | +local Room = require "adv.AdvRoom" | |
| 3 | +local Passive = require "adv.AdvPassive" | |
| 4 | +local AdvCommon = require "adv.AdvCommon" | |
| 5 | +-- 一层地图 | |
| 6 | +local Map = class("AdvMap") | |
| 7 | +-- 内部方法声明 | |
| 8 | +local createMap, getEventLib | |
| 9 | + | |
| 10 | + | |
| 11 | +function Map:ctor(adv, mapIdx, mapInfo) | |
| 12 | + self.adv = adv | |
| 13 | + if type(mapInfo) == "number" then -- mapInfo 传入 id | |
| 14 | + mapInfo = createMap(mapInfo, self.adv.chapterId, self.adv.level) -- 生成地图 | |
| 15 | + end | |
| 16 | + if not mapInfo then return end | |
| 17 | + | |
| 18 | + self.mapIdx = mapIdx | |
| 19 | + self.mapId = mapInfo.mapId | |
| 20 | + self.rooms = {} | |
| 21 | + self:loadRooms(mapInfo.rooms) | |
| 22 | +end | |
| 23 | + | |
| 24 | +function Map:loadRooms(rooms) | |
| 25 | + local mapData = csvdb["map_" .. csvdb["mapCsv"][self.mapId]["path"] .. "Csv"] | |
| 26 | + for roomId, roomName in pairs(mapData["rooms"]) do | |
| 27 | + if roomName == "path" then | |
| 28 | + self.rooms[roomId] = Room.new(self, roomId, mapData["path"], rooms[roomId], true) | |
| 29 | + else | |
| 30 | + roomName = roomName:gsub("/", "_") | |
| 31 | + self.rooms[roomId] = Room.new(self, roomId, csvdb["room_" .. roomName .. "Csv"], rooms[roomId], false) | |
| 32 | + end | |
| 33 | + end | |
| 34 | +end | |
| 35 | + | |
| 36 | +function Map:getDB() | |
| 37 | + local map = {} | |
| 38 | + map.mapId = self.mapId | |
| 39 | + map.rooms = {} | |
| 40 | + for roomId, room in pairs(self.rooms) do | |
| 41 | + map.rooms[roomId] = room:getDB() | |
| 42 | + end | |
| 43 | + return map | |
| 44 | +end | |
| 45 | + | |
| 46 | +--结束本层的时候调用 | |
| 47 | +function Map:checkOver() | |
| 48 | + local mapCsv = csvdb["mapCsv"][self.mapId] | |
| 49 | + | |
| 50 | + if mapCsv.clearType == 1 then -- 消耗 | |
| 51 | + if self.adv:cost(mapCsv.clear:toNumMap()) then return true end | |
| 52 | + elseif mapCsv.clearType == 2 then -- 杀光 | |
| 53 | + if #self.adv.battle.player:getTeam(2) == 0 then return true end | |
| 54 | + elseif mapCsv.clearType == 3 then -- 持有 | |
| 55 | + if self.adv:cost(mapCsv.clear:toNumMap(), {}, true) then return true end | |
| 56 | + else | |
| 57 | + return true | |
| 58 | + end | |
| 59 | +end | |
| 60 | + | |
| 61 | +--随机一个空的位置生成怪, 如果没有就没有 | |
| 62 | +function Map:addNewMonsterRand(monsterId, where) | |
| 63 | + local room, block | |
| 64 | + if where then | |
| 65 | + room, block = where[1], where[2] | |
| 66 | + else | |
| 67 | + local pool = {} | |
| 68 | + for _, room_ in pairs(self.rooms) do | |
| 69 | + for _, block_ in pairs(room_.blocks) do | |
| 70 | + if block_.isOpen and not block_.event then | |
| 71 | + table.insert(pool, {room_, block_}) | |
| 72 | + end | |
| 73 | + end | |
| 74 | + end | |
| 75 | + if not next(pool) then return end | |
| 76 | + local idx = math.randomInt(1, #pool) | |
| 77 | + room, block = pool[idx][1], pool[idx][2] | |
| 78 | + end | |
| 79 | + | |
| 80 | + if not monsterId then | |
| 81 | + local eventLib = getEventLib(self.adv.chapterId, self.adv.level, AdvEventType.Monster) | |
| 82 | + if not next(eventLib[AdvEventType.Monster][0]) then return false end | |
| 83 | + monsterId = math.randWeight(eventLib[AdvEventType.Monster][0], "showup") | |
| 84 | + end | |
| 85 | + | |
| 86 | + local event = {etype = AdvEventType.Monster, mId = self.adv.lastEnemyId} | |
| 87 | + self.adv.lastEnemyId = self.adv.lastEnemyId + 1 | |
| 88 | + event.id = monsterId | |
| 89 | + block:updateEvent(event) | |
| 90 | + | |
| 91 | + self.adv.battle:addEnemy(room, block):triggerPassive(Passive.BORN_ONCE) | |
| 92 | + | |
| 93 | + return room, block | |
| 94 | +end | |
| 95 | + | |
| 96 | +-- 随机翻开 num 个 以开放的房间的 地块 | |
| 97 | +function Map:openBlockRand(num) | |
| 98 | + local pool = {} | |
| 99 | + for _, room in pairs(self.rooms) do | |
| 100 | + if room.isShow and not room.isPath then | |
| 101 | + for _, block in pairs(room.blocks) do | |
| 102 | + if not block.isOpen then | |
| 103 | + table.insert(pool, {room.roomId, block.blockId}) | |
| 104 | + end | |
| 105 | + end | |
| 106 | + end | |
| 107 | + end | |
| 108 | + if #pool <= num then | |
| 109 | + for _, temp in ipairs(pool) do | |
| 110 | + self:openBlock(temp[1], temp[2]) | |
| 111 | + end | |
| 112 | + else | |
| 113 | + for i = 1, num do | |
| 114 | + local idx = math.randomInt(1, #pool) | |
| 115 | + self:openBlock(pool[idx][1], pool[idx][2]) | |
| 116 | + table.remove(pool, idx) | |
| 117 | + end | |
| 118 | + end | |
| 119 | +end | |
| 120 | + | |
| 121 | + | |
| 122 | +-- 打开一个地块 | |
| 123 | +function Map:openBlock(roomId, blockId) | |
| 124 | + local room = self.rooms[roomId] | |
| 125 | + if not room then return end | |
| 126 | + local block = room.blocks[blockId] | |
| 127 | + if not block then return end | |
| 128 | + room:openBlock(block, self) | |
| 129 | + self:backBlockChange(roomId, blockId) | |
| 130 | +end | |
| 131 | + | |
| 132 | + | |
| 133 | +--获取,某个位置上的 room 和 block | |
| 134 | +function Map:getRBByPos(c, r) | |
| 135 | + for roomId, room in pairs(self.rooms) do | |
| 136 | + local block = room:getBByGPos(c, r) | |
| 137 | + if block then | |
| 138 | + return room, block | |
| 139 | + end | |
| 140 | + end | |
| 141 | +end | |
| 142 | + | |
| 143 | +function Map:getAroundBlocks(room, block) | |
| 144 | + local blocks = {} | |
| 145 | + local range = {1, -1} | |
| 146 | + local col, row = room:tranLtoG(block.col, block.row) | |
| 147 | + for _, add in ipairs(range) do | |
| 148 | + local rroom, rblock = self:getRBByPos(col + add, row) | |
| 149 | + if rroom then | |
| 150 | + table.insert(blocks, {rroom, rblock}) | |
| 151 | + end | |
| 152 | + end | |
| 153 | + for _, add in ipairs(range) do | |
| 154 | + local rroom, rblock = self:getRBByPos(col, row + add) | |
| 155 | + if rroom then | |
| 156 | + table.insert(blocks, {rroom, rblock}) | |
| 157 | + end | |
| 158 | + end | |
| 159 | + return blocks | |
| 160 | +end | |
| 161 | + | |
| 162 | +-----------------------------随机地图----------------------------- | |
| 163 | + | |
| 164 | +createMap = function(mapId, chapterId, level) | |
| 165 | + local mapInfo = {} | |
| 166 | + mapInfo.rooms = {} | |
| 167 | + mapInfo.mapId = mapId | |
| 168 | + local mapCsvData =csvdb["mapCsv"][mapId] | |
| 169 | + local mapData = csvdb["map_" .. mapCsvData["path"] .. "Csv"] | |
| 170 | + if not mapData then | |
| 171 | + error("mapId " .. mapId .. " dont exist!") | |
| 172 | + return | |
| 173 | + end | |
| 174 | + --事件随机 | |
| 175 | + local eventLib = getEventLib(chapterId, level) -- 同时记录出现次数 | |
| 176 | + local monsterEvents = {} --处理钥匙掉落 | |
| 177 | + local haveBoss = false | |
| 178 | + | |
| 179 | + | |
| 180 | + local function randomEvent(roomId, blockId, eventType) | |
| 181 | + if mapInfo.rooms[roomId]["event"][blockId] then return end --已经有事件了 不覆盖 | |
| 182 | + local etype, especial = eventType, 0 | |
| 183 | + if eventType > 100 then -- 特殊事件(固定) | |
| 184 | + etype = math.floor(eventType / 100) | |
| 185 | + especial = eventType % 100 | |
| 186 | + end | |
| 187 | + | |
| 188 | + local event = {etype = etype} | |
| 189 | + local randomFunc = {} | |
| 190 | + | |
| 191 | + local function randomCommon() | |
| 192 | + if not eventLib[etype] or not next(eventLib[etype]) or not eventLib[etype][especial] or not next(eventLib[etype][especial]) then return false end | |
| 193 | + event.id = math.randWeight(eventLib[etype][especial], "showup") | |
| 194 | + if not event.id then return false end | |
| 195 | + if eventLib[etype][especial][event.id].limit > 1 then | |
| 196 | + eventLib[etype][especial][event.id].limit = eventLib[etype][especial][event.id].limit - 1 | |
| 197 | + elseif eventLib[etype][especial][event.id].limit == 1 then | |
| 198 | + eventLib[etype][especial][event.id] = nil | |
| 199 | + end | |
| 200 | + end | |
| 201 | + | |
| 202 | + --入口 | |
| 203 | + randomFunc[AdvEventType.In] = function()end | |
| 204 | + --出口 | |
| 205 | + randomFunc[AdvEventType.Out] = function() end | |
| 206 | + --boss | |
| 207 | + randomFunc[AdvEventType.BOSS] = function() | |
| 208 | + if haveBoss then return false end | |
| 209 | + if randomCommon() == false then | |
| 210 | + return false | |
| 211 | + end | |
| 212 | + haveBoss = true | |
| 213 | + end | |
| 214 | + --怪物 | |
| 215 | + randomFunc[AdvEventType.Monster] = function() | |
| 216 | + if randomCommon() == false then | |
| 217 | + return false | |
| 218 | + end | |
| 219 | + table.insert(monsterEvents, event) | |
| 220 | + end | |
| 221 | + | |
| 222 | + --选择点 | |
| 223 | + randomFunc[AdvEventType.Choose] = randomCommon | |
| 224 | + --掉落点 | |
| 225 | + randomFunc[AdvEventType.Drop] = randomCommon | |
| 226 | + --交易所 | |
| 227 | + randomFunc[AdvEventType.Trader] = randomCommon | |
| 228 | + --建筑 | |
| 229 | + randomFunc[AdvEventType.Build] = randomCommon | |
| 230 | + --陷阱 | |
| 231 | + randomFunc[AdvEventType.Trap] = randomCommon | |
| 232 | + --点击生效 | |
| 233 | + randomFunc[AdvEventType.Click] = randomCommon | |
| 234 | + --跨层点 | |
| 235 | + randomFunc[AdvEventType.Layer] = randomCommon | |
| 236 | + | |
| 237 | + | |
| 238 | + if randomFunc[etype] then | |
| 239 | + if randomFunc[etype]() ~= false then | |
| 240 | + if mapCsvData.clearType == 1 and etype == AdvEventType.BOSS then | |
| 241 | + event.item = mapCsvData.clear:toArray(true, "=") | |
| 242 | + end | |
| 243 | + mapInfo.rooms[roomId]["event"][blockId] = event | |
| 244 | + end | |
| 245 | + end | |
| 246 | + end | |
| 247 | + | |
| 248 | + | |
| 249 | + local stagePool = {["global"] = {}} | |
| 250 | + for roomId, roomName in pairs(mapData["rooms"]) do | |
| 251 | + stagePool[roomId] = {} | |
| 252 | + mapInfo.rooms[roomId] = {event = {}, open = {}, trap = {}} -- 事件, open open == 1 房间内地块全部开放 | |
| 253 | + local roomData | |
| 254 | + if roomName == "path" then | |
| 255 | + roomData = mapData["path"] | |
| 256 | + else | |
| 257 | + roomName = roomName:gsub("/", "_") | |
| 258 | + roomData = csvdb["room_" .. roomName .. "Csv"] | |
| 259 | + end | |
| 260 | + for blockId, stageType in pairs(roomData["blocks"]) do | |
| 261 | + if AdvSpecialStage[stageType] then | |
| 262 | + local eventType = AdvEventType[AdvSpecialStage[stageType]] -- 地块固定类型 | |
| 263 | + randomEvent(roomId, blockId, eventType) | |
| 264 | + else | |
| 265 | + stagePool["global"][stageType] = stagePool["global"][stageType] or {} | |
| 266 | + stagePool[roomId][stageType] = stagePool[roomId][stageType] or {} | |
| 267 | + table.insert(stagePool["global"][stageType], {room = roomId, block = blockId}) | |
| 268 | + stagePool[roomId][stageType][blockId] = 1 | |
| 269 | + end | |
| 270 | + end | |
| 271 | + end | |
| 272 | + -- 全地图事件 优先级高 | |
| 273 | + for stageType, events in pairs(mapData["events"]) do | |
| 274 | + for _, event in ipairs(events) do | |
| 275 | + local lastCount = stagePool["global"][stageType] and #stagePool["global"][stageType] or 0 | |
| 276 | + if lastCount <= 0 then break end | |
| 277 | + if math.randomFloat(0, 1) <= (event["rate"] or 1) then | |
| 278 | + local count = math.randomInt(math.min(lastCount, event["minc"]), math.min(lastCount, event["maxc"])) | |
| 279 | + for i = 1, count do | |
| 280 | + local idx = math.randomInt(1, lastCount) | |
| 281 | + local cur = stagePool["global"][stageType][idx] | |
| 282 | + randomEvent(cur["room"], cur["block"], event["event"]) | |
| 283 | + table.remove(stagePool["global"][stageType], idx) | |
| 284 | + lastCount = lastCount - 1 | |
| 285 | + stagePool[cur["room"]][stageType][cur["block"]] = nil | |
| 286 | + end | |
| 287 | + end | |
| 288 | + end | |
| 289 | + end | |
| 290 | + -- 随机单个房间的事件 | |
| 291 | + for roomId, roomName in pairs(mapData["rooms"]) do | |
| 292 | + local roomData | |
| 293 | + if roomName == "path" then | |
| 294 | + roomData = mapData["path"] | |
| 295 | + else | |
| 296 | + roomName = roomName:gsub("/", "_") | |
| 297 | + roomData = csvdb["room_" .. roomName .. "Csv"] | |
| 298 | + end | |
| 299 | + for stageType, events in pairs(roomData["events"]) do | |
| 300 | + local bpool = {} | |
| 301 | + if stagePool[roomId][stageType] then | |
| 302 | + for block, _ in pairs(stagePool[roomId][stageType]) do | |
| 303 | + table.insert(bpool, block) | |
| 304 | + end | |
| 305 | + end | |
| 306 | + for _, event in ipairs(events) do | |
| 307 | + if #bpool <= 0 then break end | |
| 308 | + if math.randomFloat(0, 1) <= (event["rate"] or 1) then | |
| 309 | + local count = math.randomInt(math.min(#bpool, event["minc"]), math.min(#bpool, event["maxc"])) | |
| 310 | + for i = 1, count do | |
| 311 | + local idx = math.randomInt(1, #bpool) | |
| 312 | + randomEvent(roomId, bpool[idx], event["event"]) | |
| 313 | + table.remove(bpool, idx) | |
| 314 | + end | |
| 315 | + end | |
| 316 | + end | |
| 317 | + end | |
| 318 | + end | |
| 319 | + | |
| 320 | + if mapCsvData.clearType == 1 and not haveBoss then | |
| 321 | + if not next(monsterEvents) then | |
| 322 | + error("这个地图没有钥匙!!! mapId : " .. mapId) | |
| 323 | + else | |
| 324 | + local event = monsterEvents[math.randomInt(1, #monsterEvents)] | |
| 325 | + event.item = mapCsvData.clear:toArray(true, "=") --掉落钥匙 | |
| 326 | + end | |
| 327 | + end | |
| 328 | + return mapInfo | |
| 329 | +end | |
| 330 | + | |
| 331 | +--关卡事件库 | |
| 332 | +getEventLib = function(chapterId, level, needEventType) -- needEventType 需要的事件 | |
| 333 | + local chapter = math.floor(chapterId / 100) % 100 | |
| 334 | + | |
| 335 | + local libsToType = { | |
| 336 | + ["event_monsterCsv"] = {AdvEventType.Monster, AdvEventType.BOSS, AdvEventType.Monster}, | |
| 337 | + ["event_chooseCsv"] = AdvEventType.Choose, | |
| 338 | + ["event_dropCsv"] = AdvEventType.Drop, | |
| 339 | + ["event_buildingCsv"] = AdvEventType.Build, | |
| 340 | + ["event_traderCsv"] = AdvEventType.Trader, | |
| 341 | + ["event_trapCsv"] = AdvEventType.Trap, | |
| 342 | + ["event_clickCsv"] = AdvEventType.Click, | |
| 343 | + ["event_layerCsv"] = AdvEventType.Layer, | |
| 344 | + | |
| 345 | + } | |
| 346 | + local eventLib = {} | |
| 347 | + for lib, eventType in pairs(libsToType) do | |
| 348 | + -- init eventLib | |
| 349 | + if type(eventType) == "table" then | |
| 350 | + for _, temp in ipairs(eventType) do | |
| 351 | + eventLib[temp] = {} | |
| 352 | + end | |
| 353 | + else | |
| 354 | + eventLib[eventType] = {} | |
| 355 | + end | |
| 356 | + -- needEventType 只获取这个事件类型 | |
| 357 | + if not needEventType or eventLib[needEventType] then | |
| 358 | + for id, data in pairs(csvdb[lib]) do | |
| 359 | + if data.levelchapter == chapter then | |
| 360 | + if AdvCommon.checkIsIn(level, data.leveltype, data.levellimit) then | |
| 361 | + if type(eventType) == "table" then | |
| 362 | + eventLib[eventType[data.type]][data.BlockEventType] = eventLib[eventType[data.type]][data.BlockEventType] or {} | |
| 363 | + eventLib[eventType[data.type]][data.BlockEventType][id] = {showup = data.showup, limit = data.limit} | |
| 364 | + else | |
| 365 | + eventLib[eventType][data.BlockEventType] = eventLib[eventType][data.BlockEventType] or {} | |
| 366 | + eventLib[eventType][data.BlockEventType][id] = {showup = data.showup, limit = data.limit} | |
| 367 | + end | |
| 368 | + end | |
| 369 | + end | |
| 370 | + end | |
| 371 | + if needEventType then | |
| 372 | + break | |
| 373 | + end | |
| 374 | + end | |
| 375 | + end | |
| 376 | + return eventLib | |
| 377 | +end | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | +return Map | |
| 382 | + | |
| 383 | + | ... | ... |
src/adv/AdvPlayer.lua
| ... | ... | @@ -327,7 +327,8 @@ function BaseObject:releaseSkill(skillId, target) |
| 327 | 327 | end |
| 328 | 328 | |
| 329 | 329 | --0 全部 1 我方 2 敌方 |
| 330 | -function BaseObject:getTeam(nType, noSelf) | |
| 330 | +function BaseObject:getTeam(nType, noSelf, mapIdx) | |
| 331 | + mapIdx = mapIdx or self.battle.adv:getCurMapIdx() | |
| 331 | 332 | nType = nType or 0 |
| 332 | 333 | local team = {} |
| 333 | 334 | local function addPlayer() |
| ... | ... | @@ -338,7 +339,7 @@ function BaseObject:getTeam(nType, noSelf) |
| 338 | 339 | end |
| 339 | 340 | end |
| 340 | 341 | local function addEnemy() |
| 341 | - for _, enemy in pairs(self.battle.enemys) do | |
| 342 | + for _, enemy in pairs(self.battle.enemys[mapIdx]) do | |
| 342 | 343 | if not noSelf or enemy ~= self then |
| 343 | 344 | if not enemy.isDead and not enemy.lock then -- 已经翻开的 |
| 344 | 345 | table.insert(team, enemy) |
| ... | ... | @@ -396,13 +397,14 @@ function BaseObject:changeSp() |
| 396 | 397 | end |
| 397 | 398 | |
| 398 | 399 | local Enemy = class("Enemy", BaseObject) |
| 399 | -function Enemy:ctor(battle, mId, monsterId, roomId, blockId, lock, enemy) | |
| 400 | +function Enemy:ctor(battle, mId, monsterId, roomId, blockId, lock, enemy, mapIdx) | |
| 400 | 401 | Enemy.super.ctor(self, battle) |
| 401 | 402 | self.id = mId |
| 402 | 403 | self.monsterId = monsterId --数据id |
| 403 | 404 | self.roomId = roomId |
| 404 | 405 | self.blockId = blockId |
| 405 | 406 | self.lock = lock |
| 407 | + self.mapIdx = mapIdx | |
| 406 | 408 | self:initData(enemy) |
| 407 | 409 | end |
| 408 | 410 | function Enemy:unlock(id) | ... | ... |
| ... | ... | @@ -0,0 +1,93 @@ |
| 1 | +-- 房间 | |
| 2 | + | |
| 3 | +local AdvCommon = require "adv.AdvCommon" | |
| 4 | +local Block = require "adv.AdvBlock" | |
| 5 | +local Passive = require "adv.AdvPassive" | |
| 6 | + | |
| 7 | +local Room = class("AdvRoom") | |
| 8 | +function Room:ctor(map, roomId, csvData, info, isPath) | |
| 9 | + self.map = map | |
| 10 | + self.roomId = roomId | |
| 11 | + self.col, self.row = AdvCommon.getCrById(self.roomId) | |
| 12 | + self.isPath = isPath | |
| 13 | + self.isBossRoom = false -- boss房间 --击败boss 以后重置为false | |
| 14 | + self.isShow = false | |
| 15 | + | |
| 16 | + self.blocks = {} | |
| 17 | + self:loadBlocks(csvData, info) | |
| 18 | + | |
| 19 | +end | |
| 20 | + | |
| 21 | +function Room:loadBlocks(csvData, info) | |
| 22 | + for blockId, _ in pairs(csvData["blocks"]) do | |
| 23 | + self.blocks[blockId] = Block.new(self, blockId, info.event[blockId], info.open == 1 or info.open[blockId], info.trap[blockId]) | |
| 24 | + if not self.isPath and self.blocks[blockId]:isBoss() then | |
| 25 | + self.isBossRoom = true | |
| 26 | + end | |
| 27 | + if self.blocks[blockId].isOpen then | |
| 28 | + self.isShow = true | |
| 29 | + else | |
| 30 | + if self.blocks[blockId]:getEventType() == AdvEventType.In then -- 开放 | |
| 31 | + self.isShow = true | |
| 32 | + self.blocks[blockId].isOpen = true | |
| 33 | + --入口房间只会在这里首次展示开放 --触发固有技 | |
| 34 | + self.map.adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
| 35 | + end | |
| 36 | + end | |
| 37 | + end | |
| 38 | +end | |
| 39 | + | |
| 40 | +function Room:getDB() | |
| 41 | + local room = {event = {}, open = {}, trap = {}} | |
| 42 | + local allOpen = true | |
| 43 | + for blockId, block in pairs(self.blocks) do | |
| 44 | + room["event"][blockId] = block.event | |
| 45 | + room["open"][blockId] = block.isOpen and 1 or nil | |
| 46 | + if not block.isOpen then | |
| 47 | + allOpen = false | |
| 48 | + end | |
| 49 | + room["trap"][blockId] = block.trapId | |
| 50 | + end | |
| 51 | + if allOpen then | |
| 52 | + room["open"] = 1 | |
| 53 | + end | |
| 54 | + return room | |
| 55 | +end | |
| 56 | + | |
| 57 | +function Room:openBlock(block) | |
| 58 | + if self.blocks[block.blockId] ~= block then return end | |
| 59 | + if block.isOpen == true then return end | |
| 60 | + if self.isBossRoom then | |
| 61 | + for _, _block in pairs(self.blocks) do | |
| 62 | + _block:open() | |
| 63 | + end | |
| 64 | + else | |
| 65 | + block:open() | |
| 66 | + end | |
| 67 | + | |
| 68 | + self.map.adv:scoreChange(AdvScoreType.Block) | |
| 69 | + | |
| 70 | + if not self.isShow then | |
| 71 | + self.isShow = true | |
| 72 | + --首次展示房间 | |
| 73 | + self.map.adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
| 74 | + end | |
| 75 | +end | |
| 76 | + | |
| 77 | + | |
| 78 | +function Room:tranGToL(c, r) | |
| 79 | + return c - self.col, r - self.row | |
| 80 | +end | |
| 81 | + | |
| 82 | +function Room:tranLtoG(c, r) | |
| 83 | + return c + self.col, r + self.row | |
| 84 | +end | |
| 85 | + | |
| 86 | +function Room:getBByGPos(c, r) | |
| 87 | + local c, r = self:tranGToL(c, r) | |
| 88 | + return self.blocks[AdvCommon.getIdByCr(c, r)] | |
| 89 | +end | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | +return Room | |
| 0 | 94 | \ No newline at end of file | ... | ... |
src/models/RolePlugin.lua