Blame view

src/models/RoleAdv.lua 7.8 KB
23d89d13   zhouahaihai   冒险 结构
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