RoleAdv.lua
7.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
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