Commit 2a1d5c8cfea1c9a713f331f125c679952f31cc0d
Merge branch 'develop' into qa
Showing
46 changed files
with
1855 additions
and
840 deletions
Show diff stats
src/GlobalVar.lua
... | ... | @@ -134,11 +134,14 @@ TimeReset = { |
134 | 134 | DailyBattle2 = 14, -- 特殊-每日副本(贴纸) |
135 | 135 | DailyBattle1 = 15, -- 特殊-每日副本(装备) |
136 | 136 | DailyBattle3 = 16, -- 特殊-每日副本(时钟箱) |
137 | + DrawType1 = 17, -- 变异 抽卡加成 | |
138 | + DrawType2 = 18, -- 通常 抽卡加成 | |
139 | + DrawType3 = 19, -- 魔法 抽卡加成 | |
137 | 140 | } |
138 | 141 | |
139 | 142 | GuideStep = { |
140 | - AdvGuide = 1010, | |
141 | - AdvRelay = 1012, | |
143 | + AdvGuide = 41, | |
144 | + AdvRelay = 42, | |
142 | 145 | } |
143 | 146 | |
144 | 147 | --客户端不需要知道这个 |
... | ... | @@ -191,7 +194,7 @@ AdvBackEventType = { |
191 | 194 | Trader = 12, -- 召唤商人 |
192 | 195 | Monster = 13, -- 召唤怪物 |
193 | 196 | RelayReward = 14, -- 中级层奖励 |
194 | - | |
197 | + Exp = 15, -- 经验飘字 | |
195 | 198 | Cost = 16, -- 消耗道具 |
196 | 199 | Trap = 17, --陷阱 |
197 | 200 | Layer = 18, --切换层 | ... | ... |
src/ProtocolCode.lua
... | ... | @@ -41,6 +41,7 @@ actionCodes = { |
41 | 41 | Role_changeHeadRpc = 127, |
42 | 42 | Role_openSpeedUpBoxRpc = 128, |
43 | 43 | Role_guideRpc = 129, |
44 | + Role_getRandomNameRpc = 130, | |
44 | 45 | |
45 | 46 | Adv_startAdvRpc = 151, |
46 | 47 | Adv_startHangRpc = 152, |
... | ... | @@ -97,6 +98,7 @@ actionCodes = { |
97 | 98 | Hang_buyBonusCountRpc = 259, |
98 | 99 | Hang_startBonusBattleRpc = 260, |
99 | 100 | Hang_endBonusBattleRpc = 261, |
101 | + Hang_hangGiftRpc = 262, | |
100 | 102 | |
101 | 103 | Diner_updateProperty = 300, |
102 | 104 | Diner_addSellRpc = 301, |
... | ... | @@ -179,6 +181,9 @@ actionCodes = { |
179 | 181 | Email_checkRpc = 603, |
180 | 182 | Email_delRpc = 604, |
181 | 183 | |
184 | + Activity_sudokuRpc = 650, | |
185 | + Activity_signRpc = 651, | |
186 | + Activity_sudokuRewardRpc = 652, | |
182 | 187 | } |
183 | 188 | |
184 | 189 | rpcResponseBegin = 10000 | ... | ... |
... | ... | @@ -0,0 +1,138 @@ |
1 | +local ipairs = ipairs | |
2 | +local table = table | |
3 | +local math = math | |
4 | +local string = string | |
5 | +local redisproxy = redisproxy | |
6 | +local MsgPack = MsgPack | |
7 | +local string_format = string.format | |
8 | +local tonumber = tonumber | |
9 | +local table_insert = table.insert | |
10 | +local table_unpack = table.unpack | |
11 | +local table_find = table.find | |
12 | +local table_nums = table.nums | |
13 | +local math_random = math.randomInt | |
14 | + | |
15 | + | |
16 | +local _M = {} | |
17 | + | |
18 | + | |
19 | +function _M.sudokuRpc(agent, data) | |
20 | + local role = agent.role | |
21 | + local msg = MsgPack.unpack(data) | |
22 | + local id = msg.id | |
23 | + | |
24 | + local sudoku = role:getProperty("sudoku") | |
25 | + local phase = sudoku[-1] or 1 | |
26 | + local curData = (csvdb["guide_sudokuCsv"][phase] or {})[id] | |
27 | + if phase == -1 or not curData then return 1 end | |
28 | + | |
29 | + sudoku.task = sudoku.task or {} | |
30 | + sudoku.task[phase] = sudoku.task[phase] or {} | |
31 | + | |
32 | + if (sudoku.task[phase][id] or 0) < curData.con1 then return 2 end | |
33 | + | |
34 | + sudoku.task[phase][id] = -1 | |
35 | + local task = role:award(curData.reward, {log = {desc = "sudoku", int1 = id, int2 = phase}}) -- 任务奖励 | |
36 | + | |
37 | + local reward = {} | |
38 | + local rId = {} | |
39 | + for pid, pdata in pairs(csvdb["guide_sudoku_rewardCsv"][phase] or {}) do | |
40 | + local pos = pdata.pos:toArray(true, "=") | |
41 | + local ok, is = true, false | |
42 | + for _, one in pairs(pos) do | |
43 | + if one == id then | |
44 | + is = true | |
45 | + end | |
46 | + if sudoku.task[phase][one] ~= -1 then | |
47 | + ok = false | |
48 | + break | |
49 | + end | |
50 | + end | |
51 | + | |
52 | + if ok and is then | |
53 | + for itemId, count in pairs(pdata.reward:toNumMap()) do | |
54 | + reward[itemId] = (reward[itemId] or 0) + count | |
55 | + end | |
56 | + table.insert(rId, pid) | |
57 | + end | |
58 | + end | |
59 | + | |
60 | + if not next(reward) then | |
61 | + reward = nil | |
62 | + else | |
63 | + reward = role:award(reward, {log = {desc = "sudokuR", int1 = id, int2 = phase}}) | |
64 | + end | |
65 | + | |
66 | + role:updateProperty({field = "sudoku", value = sudoku}) | |
67 | + | |
68 | + role:log("act_action", {desc = "sudoku", int1 = id, int2 = phase}) | |
69 | + | |
70 | + SendPacket(actionCodes.Activity_sudokuRpc, MsgPack.pack({task = task, reward = reward, rId = rId})) | |
71 | + return true | |
72 | +end | |
73 | + | |
74 | +function _M.sudokuRewardRpc(agent, data) | |
75 | + local role = agent.role | |
76 | + | |
77 | + | |
78 | + local sudoku = role:getProperty("sudoku") | |
79 | + local phase = sudoku[-1] or 1 | |
80 | + | |
81 | + local curData = csvdb["guide_sudokuCsv"][phase] | |
82 | + if not curData then return end | |
83 | + if not globalCsv.guide_sudoku_reward[phase] then return end | |
84 | + | |
85 | + local curTask = (sudoku.task or {})[phase] or {} | |
86 | + | |
87 | + for id, _ in pairs(curData) do | |
88 | + if curTask[id] ~= -1 then | |
89 | + return | |
90 | + end | |
91 | + end | |
92 | + | |
93 | + local reward = role:award(globalCsv.guide_sudoku_reward[phase], {log = {desc = "sudokuRP", int1 = phase}}) | |
94 | + | |
95 | + sudoku[-1] = phase + 1 | |
96 | + sudoku.task[phase] = nil | |
97 | + if not csvdb["guide_sudokuCsv"][sudoku[-1]] then | |
98 | + sudoku[-1] = -1 | |
99 | + sudoku.task = nil | |
100 | + end | |
101 | + role:updateProperty({field = "sudoku", value = sudoku}) | |
102 | + | |
103 | + SendPacket(actionCodes.Activity_sudokuRewardRpc, MsgPack.pack(reward)) | |
104 | + return true | |
105 | +end | |
106 | + | |
107 | + | |
108 | +function _M.signRpc(agent, data) | |
109 | + local role = agent.role | |
110 | + | |
111 | + local serverT = skynet.timex() | |
112 | + local tm = os.date("*t", serverT) | |
113 | + | |
114 | + local curDay = tm.day | |
115 | + | |
116 | + local yearMonth = tm.year * 100 + tm.month | |
117 | + local monthData = csvdb["daily_signInCsv"][yearMonth] | |
118 | + if not monthData or not monthData[curDay] then | |
119 | + return 1 | |
120 | + end | |
121 | + | |
122 | + local signs = role:getProperty("sign") | |
123 | + if signs[curDay] == yearMonth then -- 未重置的还可以签到正常(本月已经签到) | |
124 | + return 2 | |
125 | + end | |
126 | + signs[curDay] = yearMonth | |
127 | + | |
128 | + local raward = role:award(monthData[curDay].item, {log = {desc = "sign", int1 = yearMonth, int2 = curDay}}) | |
129 | + role:changeUpdates({{type = "sign", field = curDay, value = yearMonth}}) | |
130 | + | |
131 | + SendPacket(actionCodes.Activity_signRpc, MsgPack.pack(raward)) | |
132 | + return true | |
133 | +end | |
134 | + | |
135 | + | |
136 | + | |
137 | + | |
138 | +return _M | |
0 | 139 | \ No newline at end of file | ... | ... |
src/actions/AdvAction.lua
... | ... | @@ -104,21 +104,24 @@ function _M.startAdvRpc( agent, data ) |
104 | 104 | if not role:isFuncOpen(FuncOpenType.AdvEndless) then return 11 end -- 无尽模式 才可以玩儿无尽模式 |
105 | 105 | |
106 | 106 | local advElM = role:getProperty("advElM") --最高通关的层数 |
107 | + if not role:advChapterIsOpen(chapterId) then return 13 end | |
107 | 108 | |
108 | - if layer == 1 then | |
109 | - if not role:advChapterIsOpen(chapterId, layer) then return 13 end | |
110 | - else | |
109 | + if layer ~= 1 then | |
111 | 110 | local relayData = role:getAdvData():isHaveRelay(layer, chapterId) |
112 | - if not relayData then return end -- 不是中继层 | |
113 | - if advElM < relayData.unlockfloor then return end --未解锁 | |
111 | + if not relayData then return 14 end -- 不是中继层 | |
112 | + if advElM < relayData.unlockfloor then return 15 end --未解锁 | |
114 | 113 | end |
115 | 114 | else -- 普通模式判断 |
116 | 115 | if role.dailyData:getProperty("advC") >= role:getAdvHangLimit() then return 2 end -- 是否有体力 |
117 | - if layer > chapterData.limitlevel then return 4 end | |
116 | + if layer >= chapterData.limitlevel then return 4 end | |
118 | 117 | -- 关卡开放判断 |
119 | - if not role:advChapterIsOpen(chapterId, layer) then return 5 end | |
120 | - -- 普通模式没有中继 只能从1 开始 中继开放判断 | |
121 | - if layer ~= 1 then return 6 end | |
118 | + if not role:advChapterIsOpen(chapterId) then return 5 end | |
119 | + | |
120 | + if layer ~= 1 then | |
121 | + local relayData = role:getAdvData():isHaveRelay(layer, chapterId) | |
122 | + if not relayData then return 6 end -- 不是中继层 | |
123 | + if (advPass[chapterId] or 0) < relayData.floor then return 21 end | |
124 | + end | |
122 | 125 | end |
123 | 126 | |
124 | 127 | if not checkFormat(role, format) then return 7 end |
... | ... | @@ -158,8 +161,13 @@ function _M.startAdvRpc( agent, data ) |
158 | 161 | end |
159 | 162 | end |
160 | 163 | end |
161 | - | |
162 | - role:getAdvData():initByChapter(chapterId, layer, false, false, layer ~= 1, true, support) | |
164 | + role:getAdvData():initByChapter({ | |
165 | + chapterId = chapterId, | |
166 | + level = layer, | |
167 | + isRelay = layer ~= 1, | |
168 | + isEnter = true, | |
169 | + support = support, | |
170 | + }) | |
163 | 171 | role:checkTaskEnter("AdvStart", {id = chapterId}) |
164 | 172 | role:checkTaskEnter("AdvStartSelf", {id = chapterId}) |
165 | 173 | role:getAdvData():popBackEvents() -- 清一下事件 |
... | ... | @@ -242,11 +250,11 @@ function _M.quickHangRpc(agent, data) |
242 | 250 | local cost = math.ceil((info.time - skynet.timex()) / chapterData.idleTime * chapterData.accelerate) |
243 | 251 | |
244 | 252 | if not role:checkItemEnough({[ItemId.Diamond] = cost}) then return end |
245 | - role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "quickHang", int1 = chapterId}}) | |
253 | + role:costItems({[ItemId.Diamond] = cost}, {log = {desc = "advQuickHang", int1 = chapterId}}) | |
246 | 254 | info.time = 0 |
247 | 255 | role:changeUpdates({{type = "advHang", field = chapterId, value = info}}) |
248 | 256 | |
249 | - role:log("adv_action", {desc = "quickHang", int1 = chapterId}) | |
257 | + role:log("adv_action", {desc = "advQuickHang", int1 = chapterId}) | |
250 | 258 | |
251 | 259 | SendPacket(actionCodes.Adv_quickHangRpc, '') |
252 | 260 | return true |
... | ... | @@ -454,13 +462,13 @@ function _M.chooseArtifactRpc(agent, data) |
454 | 462 | local role = agent.role |
455 | 463 | local msg = MsgPack.unpack(data) |
456 | 464 | |
457 | - if not isCanContinue(role) then return end | |
465 | + if not isCanContinue(role) then return 1 end | |
458 | 466 | |
459 | 467 | local adv = role:getAdvData() |
460 | - if not msg.idx then return end | |
461 | - if not adv:isWaitChooseArtifact() then return end | |
468 | + if not msg.idx then return 2 end | |
469 | + if not adv:isWaitChooseArtifact() then return 3 end | |
462 | 470 | local status = adv:chooseArtifact(msg.idx) |
463 | - if not status then return end | |
471 | + if not status then return 4 end | |
464 | 472 | adv:saveDB() |
465 | 473 | |
466 | 474 | SendPacket(actionCodes.Adv_chooseArtifactRpc, '') |
... | ... | @@ -511,6 +519,8 @@ function _M.upArtifactRpc(agent, data) |
511 | 519 | adv:backCost(cost) |
512 | 520 | if status == 1 then -- 现在穿着呢。更新下 |
513 | 521 | adv:saveDB() |
522 | + else | |
523 | + adv:updateAchievement() | |
514 | 524 | end |
515 | 525 | SendPacket(actionCodes.Adv_upArtifactRpc, '') |
516 | 526 | return true | ... | ... |
src/actions/CarAction.lua
... | ... | @@ -103,7 +103,7 @@ function _M.runeUpRpc( agent, data ) |
103 | 103 | local uid = msg.uid |
104 | 104 | local ownRune = role.runeBag[uid] |
105 | 105 | if not ownRune then return 1 end |
106 | - if ownRune:getProperty("refer") ~= 0 then return 2 end | |
106 | + | |
107 | 107 | |
108 | 108 | local typ = ownRune:getProperty("type") |
109 | 109 | local id = ownRune:getProperty("id") |
... | ... | @@ -126,6 +126,12 @@ function _M.runeUpRpc( agent, data ) |
126 | 126 | ownRune:updateProperty({field = "level",value = level+1}) |
127 | 127 | role:checkTaskEnter("RuneUp") |
128 | 128 | |
129 | + if ownRune:getProperty("refer") ~= 0 then | |
130 | + local hero = role.heros[ownRune:getProperty("refer")] | |
131 | + if hero then | |
132 | + hero:updateProperty({field = "battleV", value = hero:getBattleValue()}) | |
133 | + end | |
134 | + end | |
129 | 135 | ownRune:log({desc = "runeUp", int1 = level + 1}) |
130 | 136 | |
131 | 137 | SendPacket(actionCodes.Car_runeUpRpc, '') | ... | ... |
src/actions/DinerAction.lua
... | ... | @@ -364,8 +364,7 @@ function _M.talentUpRpc( agent, data ) |
364 | 364 | end |
365 | 365 | |
366 | 366 | if talentData.levelFront ~= "" then |
367 | - local hangPass = role:getProperty("hangPass") | |
368 | - if not hangPass[tonumber(talentData.levelFront)] then | |
367 | + if not role:checkHangPass(tonumber(talentData.levelFront)) then | |
369 | 368 | return 9 |
370 | 369 | end |
371 | 370 | end |
... | ... | @@ -399,7 +398,7 @@ function _M.talentUpRpc( agent, data ) |
399 | 398 | -- role:award(treePoint) |
400 | 399 | -- end |
401 | 400 | |
402 | - role:checkTaskEnter("DinerTalentUp", {type = talentData.effect:toArray(true,"=")[1]}) | |
401 | + role:checkTaskEnter("DinerTalentUp", {type = talentData.effect:toArray(true,"=")[1], level = dishLevel + 1}) | |
403 | 402 | |
404 | 403 | role:log("diner_action", {desc = "talentUp", int1 = dish, int2 = dishLevel + 1}) |
405 | 404 | |
... | ... | @@ -635,8 +634,7 @@ function _M.addWantFoodRpc(agent , data) |
635 | 634 | local foodData = csvdb["diner_materialCsv"][itemId] |
636 | 635 | if not foodData then return 3 end |
637 | 636 | if foodData.unlock ~= 0 then |
638 | - local hangPass = role:getProperty("hangPass") | |
639 | - if not hangPass[foodData.unlock] then | |
637 | + if not role:checkHangPass(foodData.unlock) then | |
640 | 638 | return 4 |
641 | 639 | end |
642 | 640 | end |
... | ... | @@ -683,7 +681,7 @@ function _M.getGreenhouseRpc( agent, data ) |
683 | 681 | end |
684 | 682 | end |
685 | 683 | role.dinerData:updateProperty({field = "gfood", value = gfood}) |
686 | - local reward = role:award(reward, {log = {desc = "greenHourse"}}) | |
684 | + local reward = role:award(reward, {log = {desc = "greenHourse", int1 = level}}) | |
687 | 685 | role:checkTaskEnter("FoodMGet") |
688 | 686 | |
689 | 687 | role:log("diner_action", {desc = "greenHourse"}) | ... | ... |
src/actions/FriendAction.lua
... | ... | @@ -316,11 +316,15 @@ function _M.handleApplyRpc(agent, data) |
316 | 316 | end |
317 | 317 | |
318 | 318 | redisproxy:pipelining(function (red) |
319 | - red:ZREM(FRIEND_APPLY_KEY:format(roleId), table_unpack(needAdd)) | |
320 | - red:HMSET(FRIEND_KEY:format(roleId), table_unpack(needAddMy)) | |
321 | - for _, objectId in pairs(needAdd) do | |
322 | - red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) | |
323 | - red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 | |
319 | + if next(needAdd) then | |
320 | + red:ZREM(FRIEND_APPLY_KEY:format(roleId), table_unpack(needAdd)) | |
321 | + for _, objectId in pairs(needAdd) do | |
322 | + red:ZREM(FRIEND_APPLY_KEY:format(objectId), roleId) | |
323 | + red:hsetnx(FRIEND_KEY:format(objectId), roleId, newTag)--告知对放有新好友 | |
324 | + end | |
325 | + end | |
326 | + if next(needAddMy) then | |
327 | + red:HMSET(FRIEND_KEY:format(roleId), table_unpack(needAddMy)) | |
324 | 328 | end |
325 | 329 | end) |
326 | 330 | local myInfo = role:friendSInfo() | ... | ... |
src/actions/GmAction.lua
... | ... | @@ -16,7 +16,7 @@ function _M.clientRequest(agent, data) |
16 | 16 | end |
17 | 17 | |
18 | 18 | function _M.testhotfix(role, pms) |
19 | - return csvdb["itemCsv"][1]["name"] .. " -=- " .. csvdb["itemCsv"][2]["name"] .. " -=- " .. role:getItemCount(123) .. " -=- " .. table.pack(next(role.heros))[2]:getBattleValue() | |
19 | + return csvdb["itemCsv"][1]["name"] .. " -=- " .. globalCsv["codeVersion"] .. " -=- " .. role:getItemCount(123) .. " -=- " .. table.pack(next(role.heros))[2]:getBattleValue() | |
20 | 20 | end |
21 | 21 | |
22 | 22 | function _M.ignoreout(role, pms) |
... | ... | @@ -178,19 +178,17 @@ table.insert(helpDes, {"通关挂机副本", "fb", "挂卡id"}) |
178 | 178 | function _M.fb(role, pms) -- 直接通关 |
179 | 179 | local carbonId = tonum(pms.pm1) |
180 | 180 | if not csvdb["idle_battleCsv"][carbonId] then return "不存在的carbon" end |
181 | - local passCarbon = role:getProperty("hangPass") | |
182 | 181 | local addPre |
183 | 182 | addPre = function(carbonId) |
184 | 183 | local carbonData = csvdb["idle_battleCsv"][carbonId] |
185 | 184 | for _, pre in ipairs(carbonData.prepose:toArray(true, "=")) do |
186 | - passCarbon[pre] = 1 | |
185 | + role:hangFinish(pre) | |
187 | 186 | role:checkTaskEnter("HangPass", {id = pre}) |
188 | 187 | addPre(pre) |
189 | 188 | end |
190 | 189 | end |
191 | - passCarbon[carbonId] = 1 | |
190 | + role:hangFinish(carbonId) | |
192 | 191 | addPre(carbonId) |
193 | - role:updateProperty({field = "hangPass", value = passCarbon}) | |
194 | 192 | |
195 | 193 | role:log("gm_action", {desc = "fb", int1 = carbonId, key1 = pms.sender}) |
196 | 194 | |
... | ... | @@ -207,14 +205,14 @@ function _M.fbc(role, pms) -- 直接通关 |
207 | 205 | addPre = function(carbonId) |
208 | 206 | local carbonData = csvdb["idle_battleCsv"][carbonId] |
209 | 207 | for _, pre in ipairs(carbonData.prepose:toArray(true, "=")) do |
210 | - passCarbon[pre] = 1 | |
208 | + role:hangFinish(pre) | |
211 | 209 | role:checkTaskEnter("HangPass", {id = pre}) |
212 | 210 | addPre(pre) |
213 | 211 | end |
214 | 212 | end |
213 | + role:updateProperty({field = "hangPass", value = {}}) | |
215 | 214 | addPre(carbonId) |
216 | - role:updateProperty({field = "hangInfo", value = {}}) | |
217 | - role:updateProperty({field = "hangPass", value = passCarbon}) | |
215 | + | |
218 | 216 | role:checkTaskEnter("HangPass", {id = carbonId}) |
219 | 217 | |
220 | 218 | role:log("gm_action", {desc = "fbc", int1 = carbonId, key1 = pms.sender}) |
... | ... | @@ -355,24 +353,14 @@ function _M.adv(role, pms) |
355 | 353 | local layer = tonum(pms.pm2) |
356 | 354 | |
357 | 355 | local advCsv = csvdb["adv_chapterCsv"][chapterId] |
358 | - if not advCsv then return end | |
356 | + if not advCsv then return "不存在的章节" end | |
359 | 357 | if math.floor(chapterId / 100) ~= 2 then |
360 | 358 | layer = math.min(layer, advCsv.limitlevel) |
361 | 359 | end |
362 | 360 | local advPass = role:getProperty("advPass") |
363 | - local addPre | |
364 | - addPre = function(chapterId) | |
365 | - local advCsv = csvdb["adv_chapterCsv"][chapterId] | |
366 | - for pre, l in ipairs(advCsv.prepose:toNumMap()) do | |
367 | - if (advPass[pre] or 0) < l then | |
368 | - advPass[pre] = l | |
369 | - addPre(pre) | |
370 | - end | |
371 | - end | |
372 | - end | |
361 | + | |
373 | 362 | if (advPass[chapterId] or 0) < layer then |
374 | 363 | advPass[chapterId] = layer |
375 | - addPre(chapterId) | |
376 | 364 | role:updateProperty({field = "advPass", value = advPass}) |
377 | 365 | end |
378 | 366 | role:log("gm_action", {desc = "advf", int1 = chapterId, int2 = layer, key1 = pms.sender}) |
... | ... | @@ -380,30 +368,29 @@ function _M.adv(role, pms) |
380 | 368 | return "成功" |
381 | 369 | end |
382 | 370 | |
383 | -table.insert(helpDes, {"冒险到达指定层", "advt", "章节id", "层数"}) | |
371 | +table.insert(helpDes, {"冒险到达指定层", "advt", "章节id", "层数", "地图id(选)"}) | |
384 | 372 | function _M.advt(role, pms) |
385 | 373 | local chapterId = tonum(pms.pm1) |
386 | 374 | local layer = tonum(pms.pm2) |
375 | + local mapId = tonum(pms.pm3) | |
387 | 376 | local advCsv = csvdb["adv_chapterCsv"][chapterId] |
388 | 377 | if not advCsv then return "不存在的章节" end |
389 | 378 | |
379 | + local status = _M.adv(role, {pm1 = chapterId, pm2 = layer - 1}) | |
380 | + if status ~= "成功" then return status end | |
381 | + | |
390 | 382 | local advData = role:getAdvData() |
391 | - if not advData.chapterId then | |
392 | - return "先随便开启一关" | |
393 | - end | |
394 | - if not advData:isEndless() then | |
395 | - layer = math.min(layer, advCsv.limitlevel) | |
383 | + if advData:isRunning() then | |
384 | + advData:forceOver() | |
396 | 385 | end |
397 | - | |
398 | - _M.adv(role, {pm1 = chapterId, pm2 = layer - 1}) | |
399 | 386 | |
400 | - | |
401 | - advData.chapterId = chapterId | |
402 | - advData.level = layer | |
403 | - | |
404 | - advData:saveDB() | |
387 | + advData:initByChapter({ | |
388 | + chapterId = chapterId, | |
389 | + level = layer, | |
390 | + isEnter = true, | |
391 | + debugMapId = mapId, | |
392 | + }) | |
405 | 393 | role:log("gm_action", {desc = "advt", int1 = chapterId, int2 = layer, key1 = pms.sender}) |
406 | - | |
407 | 394 | return "成功" |
408 | 395 | end |
409 | 396 | ... | ... |
src/actions/HangAction.lua
... | ... | @@ -75,10 +75,9 @@ function _M.startRpc( agent, data ) |
75 | 75 | if not role:isFuncUnlock(FuncUnlock.DifficultHang) then return end |
76 | 76 | end |
77 | 77 | |
78 | - local hangPass = role:getProperty("hangPass") | |
79 | 78 | |
80 | 79 | for _, preCarbonId in ipairs(carbonData.prepose:toArray(true, "=")) do |
81 | - if not hangPass[preCarbonId] then return 2 end | |
80 | + if not role:checkHangPass(preCarbonId) then return 2 end | |
82 | 81 | end |
83 | 82 | |
84 | 83 | if checkReward(role) then |
... | ... | @@ -98,7 +97,7 @@ function _M.startRpc( agent, data ) |
98 | 97 | hangInfo.coinTime = math.min(nowTime, hangInfo.endCoinTime) |
99 | 98 | hangInfo.itemTime = math.min(nowTime, hangInfo.endItemTime) |
100 | 99 | end |
101 | - if not hangPass[carbonId] then | |
100 | + if not role:checkHangPass(carbonId) then | |
102 | 101 | hangInfo.bossTime = nowTime + carbonData.idle_time |
103 | 102 | else |
104 | 103 | hangInfo.bossTime = nil |
... | ... | @@ -140,8 +139,7 @@ function _M.startBattleRpc(agent, data) |
140 | 139 | end |
141 | 140 | end |
142 | 141 | |
143 | - local hangPass = role:getProperty("hangPass") | |
144 | - if hangPass[carbonId] then | |
142 | + if role:checkHangPass(carbonId) then | |
145 | 143 | return 3 |
146 | 144 | end |
147 | 145 | |
... | ... | @@ -169,14 +167,13 @@ function _M.endBattleRpc(agent, data) |
169 | 167 | return 3 |
170 | 168 | end |
171 | 169 | end |
172 | - local hangPass = role:getProperty("hangPass") | |
173 | - if hangPass[carbonId] then | |
170 | + | |
171 | + if role:checkHangPass(carbonId) then | |
174 | 172 | return 4 |
175 | 173 | end |
176 | 174 | local reward |
177 | 175 | if msg.starNum and msg.starNum > 0 then --win |
178 | - hangPass[carbonId] = 1 | |
179 | - role:updateProperty({field = "hangPass", value = hangPass}) | |
176 | + role:hangFinish(carbonId) | |
180 | 177 | if carbonData.main ~= 1 then |
181 | 178 | hangInfo.bossTime = nil |
182 | 179 | end |
... | ... | @@ -193,8 +190,9 @@ function _M.endBattleRpc(agent, data) |
193 | 190 | role:checkTaskEnter("HangPass", {id = carbonId}) |
194 | 191 | end |
195 | 192 | role:updateProperty({field = "hangInfo", value = hangInfo}) |
196 | - | |
197 | - role:log("hang_action", {desc = "hangBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = carbonId}) | |
193 | + | |
194 | + local team = role:getProperty("pvpTC") | |
195 | + role:log("hang_action", {desc = "hangBattle", short1 = msg.starNum > 0 and 1 or 0, int1 = carbonId, int2 = role:getProperty("hangTBV"), cint1 = role:getHerosCamp(team.heros)}) | |
198 | 196 | |
199 | 197 | SendPacket(actionCodes.Hang_endBattleRpc, MsgPack.pack({ |
200 | 198 | starNum = msg.starNum, |
... | ... | @@ -439,8 +437,7 @@ function _M.startBonusBattleRpc(agent, data) |
439 | 437 | if not role:isTimeResetOpen(TimeReset["DailyBattle" .. bonusData.type]) then return end |
440 | 438 | |
441 | 439 | if not bonusData then return 1 end |
442 | - local hangPass = role:getProperty("hangPass") | |
443 | - if not hangPass[bonusData.unlock] then return 2 end | |
440 | + if not role:checkHangPass(bonusData.unlock) then return 2 end | |
444 | 441 | |
445 | 442 | if not next(role:getProperty("bTeam")) then return 3 end |
446 | 443 | |
... | ... | @@ -489,6 +486,25 @@ function _M.endBonusBattleRpc(agent, data) |
489 | 486 | return true |
490 | 487 | end |
491 | 488 | |
489 | +function _M.hangGiftRpc(agent, data) | |
490 | + local role = agent.role | |
491 | + local msg = MsgPack.unpack(data) | |
492 | + | |
493 | + local id = msg.id | |
494 | + local carbonData = csvdb["idle_battleCsv"][id] | |
495 | + if not carbonData or carbonData.item_clear_special == "" then return 1 end | |
496 | + | |
497 | + local hangGift = role:getProperty("hangGift") | |
498 | + if hangGift[id] then return 2 end | |
499 | + | |
500 | + local reward = role:award(carbonData.item_clear_special, {log = {desc = "hangGift", int1 = id}}) | |
501 | + role:log("hang_action", {desc = "hangGift", int1 = id}) | |
502 | + | |
503 | + role:changeUpdates({{type = "hangGift", field = id, value = 1}}) | |
504 | + | |
505 | + SendPacket(actionCodes.Hang_hangGiftRpc, MsgPack.pack(reward)) | |
506 | + return true | |
507 | +end | |
492 | 508 | |
493 | 509 | |
494 | 510 | return _M |
495 | 511 | \ No newline at end of file | ... | ... |
src/actions/HeroAction.lua
... | ... | @@ -233,7 +233,7 @@ function _M.commentHeroRpc(agent, data) |
233 | 233 | result.status = 1 |
234 | 234 | else |
235 | 235 | local commentKey = getCommentKey(heroType) |
236 | - local SERV = string.format(".NAMED%d", math.random(1, 5)) | |
236 | + local SERV = string.format(".chated%d", math.random(1, 5)) | |
237 | 237 | local legal, mod = skynet.call(SERV, "lua", "check", content) |
238 | 238 | if not legal then |
239 | 239 | content = mod or "" |
... | ... | @@ -536,13 +536,29 @@ function _M.referRunesRpc(agent, data) |
536 | 536 | local runes = msg.runes |
537 | 537 | if not runes or not next(runes) then return 11 end |
538 | 538 | |
539 | + local used = {} | |
539 | 540 | for typ = 1, 6 do |
540 | 541 | if runes[typ] and runes[typ] ~= 0 then |
541 | 542 | local ownRune = role.runeBag[runes[typ]] |
542 | 543 | if not ownRune then return end |
543 | - if ownRune:getProperty("refer") ~= 0 then return end | |
544 | + if ownRune:getProperty("refer") ~= 0 then | |
545 | + used[ownRune:getProperty("refer")] = used[ownRune:getProperty("refer")] or {} | |
546 | + used[ownRune:getProperty("refer")][runes[typ]] = 1 | |
547 | + end | |
548 | + end | |
549 | + end | |
550 | + | |
551 | + for cheroId, cIds in pairs(used) do | |
552 | + local chero = role.heros[cheroId] | |
553 | + local hrunes = chero:getProperty("rune") | |
554 | + for slot, rId in pairs(hrunes:toNumMap()) do | |
555 | + if cIds[rId] then | |
556 | + hrunes = hrunes:delk(slot) | |
557 | + end | |
544 | 558 | end |
559 | + chero:updateProperty({field = "rune", value = hrunes}) | |
545 | 560 | end |
561 | + | |
546 | 562 | local curRune = hero:getProperty("rune") |
547 | 563 | for typ = 1, 6 do |
548 | 564 | if runes[typ] then |
... | ... | @@ -668,208 +684,261 @@ function _M.getResetRewardRpc(agent, data) |
668 | 684 | end |
669 | 685 | |
670 | 686 | |
671 | -local function randomDrawCondition(pool, condition) | |
672 | - local value = {} | |
673 | - for idx, field in ipairs(condition) do | |
674 | - local lpool = {} | |
675 | - local curIdx = 1 | |
676 | - while pool[field .. "_" .. curIdx] do | |
677 | - table.insert(lpool, {pool[field .. "_" .. curIdx]}) | |
678 | - curIdx = curIdx + 1 | |
679 | - end | |
680 | - if next(lpool) then | |
681 | - value[idx] = math.randWeight(lpool, 1) | |
682 | - end | |
683 | - end | |
684 | - return value | |
685 | -end | |
686 | - | |
687 | - | |
688 | -local function fillDrawPool(curPool, resultPool, isNeedFunc) | |
689 | - for itemId, oneData in pairs(csvdb["build_poolCsv"]) do | |
690 | - if oneData["pool_" .. curPool] and oneData["pool_" .. curPool] ~= "" then | |
691 | - local itemData = csvdb["itemCsv"][itemId] | |
692 | - if itemData and isNeedFunc(itemData) then | |
693 | - for _, one in ipairs(oneData["pool_" .. curPool]:toTableArray(true)) do | |
694 | - table.insert(resultPool, {itemId, one[1], one[2]}) -- itemId, count, 概率 | |
695 | - end | |
696 | - end | |
697 | - end | |
698 | - end | |
699 | -end | |
700 | 687 | |
701 | 688 | function _M.drawHeroRpc(agent, data) |
702 | 689 | local role = agent.role |
703 | 690 | local msg = MsgPack.unpack(data) |
704 | 691 | |
705 | 692 | if not role:isFuncUnlock(FuncUnlock.GetHero) then return end |
706 | - local pool = msg.pool -- 1 2 3 | |
693 | + local btype = msg.pool -- 1 2 3 4 | |
707 | 694 | local drawType = msg.type -- 1 单抽 2 十连 |
695 | + local guide = msg.guide -- 是否是引导抽的 | |
708 | 696 | |
709 | - local buildTypeData = csvdb["build_typeCsv"][pool] | |
697 | + local buildTypeData = csvdb["build_typeCsv"][btype] | |
710 | 698 | if not buildTypeData then return 1 end |
711 | 699 | |
712 | - local costs = {{"draw_card", "draw_coin"}, {"draw10_card", "draw10_coin"}} -- 抽取消耗 | |
713 | 700 | local drawCount = {1, 10} -- 抽取次数 |
701 | + if not drawCount[drawType] then return 2 end | |
714 | 702 | |
715 | - local costT = costs[drawType] | |
716 | - if not costT then return 2 end | |
717 | - local cost = buildTypeData[costT[1]]:toNumMap() | |
718 | - if not role:checkItemEnough(cost) then | |
719 | - cost = buildTypeData[costT[2]]:toNumMap() | |
720 | - if not role:checkItemEnough(cost) then | |
721 | - return 3 | |
703 | + local newerDraw | |
704 | + if btype == 4 then | |
705 | + newerDraw = role:getProperty("newerDraw") | |
706 | + if math.illegalNum(globalCsv.draw_newer[2] - (newerDraw[1] or 0), drawCount[drawType], globalCsv.draw_newer[2]) then return 11 end | |
707 | + end | |
708 | + | |
709 | + local cost = {} | |
710 | + local lastCount = drawCount[drawType] | |
711 | + for _, costType in ipairs({"draw_card", "draw_coin"}) do | |
712 | + if buildTypeData[costType] ~= "" then | |
713 | + local curCost = buildTypeData[costType]:toArray(true, "=") | |
714 | + local hadCount = role:getItemCount(curCost[1]) | |
715 | + local curCount = math.floor(hadCount / curCost[2]) | |
716 | + if curCount >= lastCount then | |
717 | + cost[curCost[1]] = curCost[2] * lastCount | |
718 | + lastCount = 0 | |
719 | + break | |
720 | + elseif curCount > 0 then | |
721 | + cost[curCost[1]] = curCost[2] * curCount | |
722 | + lastCount = lastCount - curCount | |
723 | + end | |
722 | 724 | end |
723 | 725 | end |
726 | + if lastCount > 0 then -- 钱不够 | |
727 | + return 3 | |
728 | + end | |
724 | 729 | |
725 | - -- 开始抽 | |
726 | - local rateTypes = {"unitRate", "fragmentRate", "itemRate"} | |
730 | + -- pool 固定的 | |
731 | + local poolEnum = { | |
732 | + [1] = { | |
733 | + [1] = 1, | |
734 | + [2] = 2, | |
735 | + [3] = 3, | |
736 | + }, | |
737 | + [2] = 10, | |
738 | + [3] = 11, | |
739 | + [4] = 12, | |
740 | + } | |
727 | 741 | |
728 | - local typePool = {} | |
729 | - for _, rateType in ipairs(rateTypes) do | |
730 | - table.insert(typePool, {buildTypeData[rateType]}) | |
742 | + -- 抽取的池子 | |
743 | + local pool = poolEnum[btype] | |
744 | + if btype == 1 then | |
745 | + -- 超级卡池子 每周轮换 有活动覆盖之 | |
746 | + --TODO 活动判断 | |
747 | + if false then | |
748 | + else | |
749 | + for idx, poolId in pairs(pool) do | |
750 | + if role:isTimeResetOpen(TimeReset["DrawType" .. idx]) then | |
751 | + pool = poolId | |
752 | + break | |
753 | + end | |
754 | + end | |
755 | + if type(pool) ~= "number" then | |
756 | + pool = -1 | |
757 | + end | |
758 | + end | |
731 | 759 | end |
760 | + local unitPool = csvdb["build_unitCsv"][pool] | |
761 | + if not unitPool then return 4 end | |
732 | 762 | |
763 | + -- 开始抽 | |
733 | 764 | local resultPool = {} |
765 | + local function fillDrawPool(fixRare, fixCamp, ssrUp) | |
766 | + local condition = {"rare", "camp"} | |
767 | + local values = {fixRare, fixCamp} | |
768 | + | |
769 | + for idx, field in ipairs(condition) do | |
770 | + if not values[idx] then | |
771 | + local lpool = {} | |
772 | + local curIdx = 1 | |
773 | + while unitPool[field .. "_" .. curIdx] do | |
774 | + lpool[curIdx] = {unitPool[field .. "_" .. curIdx]} | |
775 | + curIdx = curIdx + 1 | |
776 | + end | |
734 | 777 | |
735 | - local fillPoolFunc = { | |
736 | - unitRate = function(fixRare, fixCamp, fixJob) | |
737 | - local condition = {"rare", "camp", "job"} | |
738 | - local values = randomDrawCondition(csvdb["build_unitCsv"][pool], condition) | |
739 | - values[1] = fixRare or values[1] | |
740 | - values[2] = fixCamp or values[2] | |
741 | - values[3] = fixJob or values[3] | |
742 | - fillDrawPool(pool, resultPool, function(itemData) | |
743 | - if itemData.type ~= ItemType.Hero then return end | |
744 | - local heroData = csvdb["unitCsv"][itemData.id - ItemStartId.Hero] | |
745 | - if not heroData then return end | |
746 | - for idx, field in ipairs(condition) do | |
747 | - if heroData[field] ~= values[idx] then return end | |
778 | + -- 稀有度 ssr up | |
779 | + if field == "rare" then | |
780 | + local all = 0 | |
781 | + for _, weight in pairs(lpool) do | |
782 | + all = all + weight[1] | |
783 | + end | |
784 | + | |
785 | + lpool[4][1] = lpool[4][1] + (ssrUp or 0) * all | |
748 | 786 | end |
749 | - return true | |
750 | - end) | |
751 | - end, | |
752 | - fragmentRate = function(fixRare, fixCamp, fixJob) | |
753 | - local condition = {"rare", "camp", "job"} | |
754 | - local values = randomDrawCondition(csvdb["build_fragmentCsv"][pool], condition) | |
755 | - values[1] = fixRare or values[1] | |
756 | - values[2] = fixCamp or values[2] | |
757 | - values[3] = fixJob or values[3] | |
758 | - fillDrawPool(pool, resultPool, function(itemData) | |
759 | - if itemData.type ~= ItemType.HeroFragment then return end | |
760 | - local heroData = csvdb["unitCsv"][itemData.id] | |
761 | - if not heroData then return end | |
762 | - for idx, field in ipairs(condition) do | |
763 | - if heroData[field] ~= values[idx] then return end | |
787 | + | |
788 | + if next(lpool) then | |
789 | + values[idx] = math.randWeight(lpool, 1) | |
764 | 790 | end |
765 | - return true | |
766 | - end) | |
767 | - end, | |
768 | - itemRate = function() | |
769 | - fillDrawPool(pool, resultPool, function(itemData) | |
770 | - if itemData.type == ItemType.HeroFragment or itemData.type == ItemType.Hero then return end | |
771 | - return true | |
772 | - end) | |
773 | - end, | |
774 | - } | |
791 | + end | |
792 | + end | |
793 | + | |
794 | + for itemId, oneData in pairs(csvdb["build_poolCsv"]) do | |
795 | + if oneData["pool_" .. pool] and oneData["pool_" .. pool] ~= "" then | |
796 | + local itemData = csvdb["itemCsv"][itemId] | |
797 | + while itemData do | |
798 | + if itemData.type ~= ItemType.Hero then break end | |
799 | + local heroData = csvdb["unitCsv"][itemData.id - ItemStartId.Hero] | |
800 | + if not heroData then break end | |
801 | + local ok = true | |
802 | + for idx, field in ipairs(condition) do | |
803 | + if heroData[field] ~= values[idx] then ok = false break end | |
804 | + end | |
805 | + if not ok then break end | |
806 | + if oneData["pool_" .. pool] > 0 then | |
807 | + resultPool[itemId] = {oneData["pool_" .. pool]} -- itemId, count, 概率 | |
808 | + end | |
809 | + break | |
810 | + end | |
811 | + end | |
812 | + end | |
813 | + end | |
814 | + | |
815 | + role:costItems(cost, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) | |
775 | 816 | |
776 | - role:costItems(cost, {log = {desc = "drawHero", short1 = pool}}) | |
777 | - local floorHeroCount = role:getProperty("floorHero")[pool] or 0 | |
817 | + local draw_floor_back_counts = globalCsv.draw_floor_back_counts[btype] | |
818 | + local draw_ssr_up_count_rate = globalCsv.draw_ssr_up_count_rate[btype] | |
819 | + local floorHeroCount = role:getProperty("floorHero")[btype] or 0 | |
820 | + local ssrUpCount = role:getProperty("ssrUp")[btype] or 0 | |
821 | + | |
822 | + local newerDrawCount, newerHadSSR | |
823 | + if btype == 4 then | |
824 | + newerDrawCount = newerDraw[1] or 0 | |
825 | + newerHadSSR = newerDraw[2] or 0 | |
826 | + end | |
778 | 827 | |
779 | 828 | local ssrCount = 0 |
780 | 829 | local reward = {} |
781 | 830 | for i = 1, drawCount[drawType] do |
782 | 831 | floorHeroCount = floorHeroCount + 1 |
832 | + if btype == 4 then | |
833 | + newerDrawCount = newerDrawCount + 1 | |
834 | + end | |
783 | 835 | |
784 | 836 | resultPool = {} |
785 | - local isFloorBack = globalCsv.draw_floor_back_counts[pool] and floorHeroCount >= globalCsv.draw_floor_back_counts[pool] | |
786 | - while not next(resultPool) do | |
787 | - local rateType | |
837 | + local isFloorBack = draw_floor_back_counts and floorHeroCount >= draw_floor_back_counts | |
838 | + local isNewerSSR = btype == 4 and (newerHadSSR == 0 and newerDrawCount >= globalCsv.draw_newer[1]) or false | |
788 | 839 | |
789 | - if isFloorBack then | |
790 | - rateType = 1 --保底英雄 | |
791 | - else | |
792 | - rateType = math.randWeight(typePool, 1) | |
793 | - end | |
794 | - if not fillPoolFunc[rateTypes[rateType]] then return 4 end | |
795 | - if isFloorBack then | |
796 | - fillPoolFunc[rateTypes[rateType]](3) -- 保底 sr 【郑斌】明确 | |
840 | + local ssrUp = 0 | |
841 | + if draw_ssr_up_count_rate then | |
842 | + ssrUp = math.floor(ssrUpCount / draw_ssr_up_count_rate[1]) * draw_ssr_up_count_rate[2] / 100 | |
843 | + end | |
844 | + while not next(resultPool) do | |
845 | + if isNewerSSR then | |
846 | + fillDrawPool(4) -- 新手保底的 ssr | |
847 | + elseif isFloorBack then | |
848 | + fillDrawPool(3) -- 保底 sr 【郑斌】明确 | |
797 | 849 | else |
798 | - fillPoolFunc[rateTypes[rateType]]() | |
850 | + fillDrawPool(nil, nil, ssrUp) | |
799 | 851 | end |
800 | 852 | end |
801 | 853 | |
802 | - local idx = math.randWeight(resultPool, 3) | |
803 | - local temp = resultPool[idx] | |
804 | - local itemData = csvdb["itemCsv"][temp[1]] | |
805 | - | |
806 | - if itemData.type == ItemType.Hero then | |
807 | - if itemData.quality == 4 then | |
808 | - ssrCount = ssrCount + 1 | |
809 | - elseif itemData.quality == 3 then | |
810 | - floorHeroCount = 0 | |
854 | + -- 引导必送 613 丝路德 | |
855 | + local itemId = guide and 613 or math.randWeight(resultPool, 1) | |
856 | + local itemData = csvdb["itemCsv"][itemId] | |
857 | + if itemData.quality == 4 then | |
858 | + ssrCount = ssrCount + 1 | |
859 | + ssrUpCount = 0 | |
860 | + | |
861 | + if btype == 4 then | |
862 | + newerHadSSR = newerHadSSR + 1 | |
811 | 863 | end |
864 | + elseif itemData.quality == 3 then | |
865 | + floorHeroCount = 0 | |
866 | + ssrUpCount = ssrUpCount + 1 | |
867 | + else | |
868 | + ssrUpCount = ssrUpCount + 1 | |
812 | 869 | end |
813 | 870 | |
814 | - if itemData.type == ItemType.Hero and role:isHaveHero(itemData.id - ItemStartId.Hero) then | |
871 | + if role:isHaveHero(itemData.id - ItemStartId.Hero) then | |
815 | 872 | local fragId = itemData.id - ItemStartId.Hero |
816 | 873 | local heroData = csvdb["unitCsv"][fragId] |
817 | - local count = globalCsv.draw_unit_tofragment[heroData.rare] * temp[2] | |
818 | - role:award({[fragId] = count}, {log = {desc = "drawHero", short1 = pool}}) | |
819 | - table.insert(reward, {id = fragId, count = count, from = temp[1], fcount = temp[2]}) | |
874 | + local count = globalCsv.draw_unit_tofragment[heroData.rare] | |
875 | + role:award({[fragId] = count}, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) | |
876 | + table.insert(reward, {id = fragId, count = count, from = itemId, fcount = 1}) | |
820 | 877 | else |
821 | - role:award({[temp[1]] = temp[2]}, {log = {desc = "drawHero", short1 = pool}}) | |
822 | - table.insert(reward, {id = temp[1], count = temp[2]}) | |
878 | + role:award({[itemId] = 1}, {log = {desc = "drawHero", short1 = btype, int1 = pool}}) | |
879 | + table.insert(reward, {id = itemId, count = 1}) | |
823 | 880 | end |
824 | 881 | end |
825 | 882 | |
826 | - if globalCsv.draw_floor_back_counts[pool] then | |
883 | + if draw_floor_back_counts then | |
827 | 884 | local floorHero = role:getProperty("floorHero") |
828 | 885 | floorHero[pool] = floorHeroCount |
829 | - role:updateProperty({field = "floorHero", value = floorHero}) | |
886 | + role:setProperty("floorHero", floorHero) | |
830 | 887 | end |
831 | 888 | |
832 | - if pool == 1 then | |
833 | - local repayHero = role:getProperty("repayHero") | |
834 | - repayHero = math.min(globalCsv.draw_super_repay_count, repayHero + drawCount[drawType]) | |
835 | - role:updateProperty({field = "repayHero", value = repayHero}) | |
889 | + if draw_ssr_up_count_rate then | |
890 | + local ssrUp = role:getProperty("ssrUp") | |
891 | + ssrUp[pool] = ssrUpCount | |
892 | + role:setProperty("ssrUp", ssrUp) | |
836 | 893 | end |
837 | 894 | |
895 | + if btype == 4 then | |
896 | + newerDraw[1] = newerDrawCount | |
897 | + newerDraw[2] = newerHadSSR | |
898 | + role:updateProperty({field = "newerDraw", value = newerDraw}) | |
899 | + end | |
900 | + | |
901 | + -- if pool == 1 then | |
902 | + -- local repayHero = role:getProperty("repayHero") | |
903 | + -- repayHero = math.min(globalCsv.draw_super_repay_count, repayHero + drawCount[drawType]) | |
904 | + -- role:updateProperty({field = "repayHero", value = repayHero}) | |
905 | + -- end | |
906 | + | |
838 | 907 | role:checkTaskEnter("DrawHero", {pool = pool, count = drawCount[drawType]}) |
839 | 908 | if ssrCount > 0 then |
840 | 909 | role:checkTaskEnter("DrawSSR", {count = ssrCount}) |
841 | 910 | end |
842 | - role:log("hero_action", {desc = "drawHero", short1 = pool, int1 = drawCount[drawType]}) | |
911 | + role:log("hero_action", {desc = "drawHero", short1 = btype, int1 = drawCount[drawType], int2 = pool}) | |
843 | 912 | SendPacket(actionCodes.Hero_drawHeroRpc, MsgPack.pack({reward = reward})) -- 这个 reward 是数组 |
844 | 913 | return true |
845 | 914 | end |
846 | 915 | |
847 | -function _M.repayHeroRpc(agent, data) | |
848 | - local role = agent.role | |
849 | - | |
850 | - local repayHero = role:getProperty("repayHero") | |
851 | - if repayHero < globalCsv.draw_super_repay_count then | |
852 | - return | |
853 | - end | |
916 | +-- function _M.repayHeroRpc(agent, data) | |
917 | +-- local role = agent.role | |
854 | 918 | |
855 | - role:updateProperty({field = "repayHero", value = 0}) | |
856 | - local id = math.randWeight(csvdb["build_giftCsv"], "pool_1") | |
919 | +-- local repayHero = role:getProperty("repayHero") | |
920 | +-- if repayHero < globalCsv.draw_super_repay_count then | |
921 | +-- return | |
922 | +-- end | |
857 | 923 | |
858 | - local reward = {} | |
859 | - local itemData = csvdb["itemCsv"][id] | |
860 | - if itemData.type == ItemType.Hero and role:isHaveHero(itemData.id - ItemStartId.Hero) then | |
861 | - local fragId = itemData.id - ItemStartId.Hero | |
862 | - local heroData = csvdb["unitCsv"][fragId] | |
863 | - local count = globalCsv.draw_unit_tofragment[heroData.rare] | |
864 | - role:award({[fragId] = count}, {log = {desc = "heroRepay"}}) | |
865 | - reward = {id = fragId, count = count, from = id, fcount = 1} | |
866 | - else | |
867 | - role:award({[id] = 1}, {log = {desc = "heroRepay"}}) | |
868 | - reward = {id = id, count = 1} | |
869 | - end | |
870 | - role:log("hero_action", {desc = "heroRepay"}) | |
871 | - SendPacket(actionCodes.Hero_repayHeroRpc, MsgPack.pack({reward = reward})) | |
872 | - return true | |
873 | -end | |
924 | +-- role:updateProperty({field = "repayHero", value = 0}) | |
925 | +-- local id = math.randWeight(csvdb["build_giftCsv"], "pool_1") | |
926 | + | |
927 | +-- local reward = {} | |
928 | +-- local itemData = csvdb["itemCsv"][id] | |
929 | +-- if itemData.type == ItemType.Hero and role:isHaveHero(itemData.id - ItemStartId.Hero) then | |
930 | +-- local fragId = itemData.id - ItemStartId.Hero | |
931 | +-- local heroData = csvdb["unitCsv"][fragId] | |
932 | +-- local count = globalCsv.draw_unit_tofragment[heroData.rare] | |
933 | +-- role:award({[fragId] = count}, {log = {desc = "heroRepay"}}) | |
934 | +-- reward = {id = fragId, count = count, from = id, fcount = 1} | |
935 | +-- else | |
936 | +-- role:award({[id] = 1}, {log = {desc = "heroRepay"}}) | |
937 | +-- reward = {id = id, count = 1} | |
938 | +-- end | |
939 | +-- role:log("hero_action", {desc = "heroRepay"}) | |
940 | +-- SendPacket(actionCodes.Hero_repayHeroRpc, MsgPack.pack({reward = reward})) | |
941 | +-- return true | |
942 | +-- end | |
874 | 943 | |
875 | 944 | return _M |
876 | 945 | \ No newline at end of file | ... | ... |
src/actions/HttpAction.lua
1 | -local codecache = require "skynet.codecache" -- 清空缓存用 | |
2 | - | |
3 | 1 | |
4 | 2 | local _M = {} |
5 | 3 | |
... | ... | @@ -19,45 +17,12 @@ local _M = {} |
19 | 17 | ]=] |
20 | 18 | |
21 | 19 | |
22 | --- 清空缓存 | |
23 | -function _M.clearcache(query, body) | |
24 | - skynet.error(string.format("clearcache time: %s", skynet.timex())) | |
25 | - codecache.clear() | |
26 | - return 'success' | |
27 | -end | |
28 | - | |
29 | ---重新加载 需要修改的csvdb -- 单字段修改 优先使用hotfix_csvdata | |
30 | ---[=[ eg: | |
31 | - body = """ | |
32 | - csvdb["itemCsv"][1]["name"] = "测试一下" | |
33 | - """ | |
34 | -]=] | |
35 | - | |
36 | -function _M.reload_csvdata(query, body) | |
37 | - if not body or body == "" then | |
38 | - return 'no body' | |
39 | - end | |
40 | - | |
41 | - local ok = pcall(load, body) | |
42 | - if not ok then | |
43 | - return "code error" | |
44 | - end | |
45 | - | |
46 | - local ok, status = pcall(skynet.call, '.CSVDATA', "lua", "reload", body) | |
47 | - if status == "ok" then | |
48 | - skynet.error(string.format("reload_csvdata time: %s, code: %s", skynet.timex(), body)) | |
49 | - return 'success' | |
50 | - else | |
51 | - return 'error update' | |
52 | - end | |
53 | -end | |
54 | - | |
55 | ---指定更新某个字段值 | |
56 | 20 | --[=[ |
57 | 21 | 解码后 |
58 | 22 | body = { |
59 | - {"itemCsv", 1, "name", "测试一下"}, | |
60 | - {"itemCsv", 2, "name", "测试一下"} | |
23 | + "src/csvdata/init.lua", | |
24 | + "unitCsv", | |
25 | + "story_cgCsv", | |
61 | 26 | } |
62 | 27 | ]=] |
63 | 28 | function _M.hotfix_csvdata(query, body) |
... | ... | @@ -69,14 +34,10 @@ function _M.hotfix_csvdata(query, body) |
69 | 34 | if not ok or type(result) ~= 'table' then |
70 | 35 | return "decode error" |
71 | 36 | end |
72 | - local ok, status = pcall(skynet.call, '.CSVDATA', "lua", "hotfix", result) | |
73 | 37 | |
74 | - if status == "ok" then | |
75 | - skynet.error(string.format("hotfix_csvdata time: %s, code: %s", skynet.timex(), body)) | |
76 | - return 'success' | |
77 | - else | |
78 | - return 'error update' | |
79 | - end | |
38 | + csvdb.hotfix(table.unpack(result)) | |
39 | + | |
40 | + return 'success' | |
80 | 41 | end |
81 | 42 | |
82 | 43 | -- 热更新代码 -- 针对 agent 执行发送过来的代码 -- 代码要规范~ |
... | ... | @@ -150,7 +111,7 @@ function _M.hotfix_code(query, body) |
150 | 111 | |
151 | 112 | skynet.error(string.format("hotfix_code time: %s, code: %s", skynet.timex(), body)) |
152 | 113 | |
153 | - pcall(skynet.call, '.WATCHDOG', "lua", "hotfix", body) | |
114 | + pcall(skynet.call, '.watchdog', "lua", "hotfix", body) | |
154 | 115 | return 'success' |
155 | 116 | end |
156 | 117 | ... | ... |
src/actions/RoleAction.lua
... | ... | @@ -22,7 +22,7 @@ local function validName(name) |
22 | 22 | local exist = redisproxy:exists(string_format("user:%s", name)) |
23 | 23 | if exist then return "existed" end |
24 | 24 | |
25 | - local SERV = string_format(".NAMED%d", math.random(1, 5)) | |
25 | + local SERV = string_format(".named%d", math.random(1, 5)) | |
26 | 26 | local legal = skynet.call(SERV, "lua", "check", name) |
27 | 27 | return legal and "ok" or "illegal" |
28 | 28 | end |
... | ... | @@ -217,7 +217,7 @@ function _M.loginRpc( agent, data ) |
217 | 217 | |
218 | 218 | -- 发下缓存的世界消息 |
219 | 219 | local worldChatResponse = {worldChats = {}} |
220 | - local ok, msgs = pcall(skynet.call, '.GLOBALD', "lua", "getWorldMsg", role._channelIdx) | |
220 | + local ok, msgs = pcall(skynet.call, '.globald', "lua", "getWorldMsg", role._channelIdx) | |
221 | 221 | if not ok then |
222 | 222 | msgs = {} |
223 | 223 | end |
... | ... | @@ -245,8 +245,10 @@ function _M.loginRpc( agent, data ) |
245 | 245 | -- 玩家登陆做的一些操作 |
246 | 246 | role:saveHangTeam() |
247 | 247 | role:savePvpCTeam() |
248 | + role:savePvpHTeam() | |
248 | 249 | |
249 | - role:log("login", {key1 = agent.ip:toArray(false, ":")[1]}) | |
250 | + local hangPass = role:getProperty("hangPass") | |
251 | + role:log("login", {key1 = agent.ip:toArray(false, ":")[1], int1 = hangPass[1] or 0}) | |
250 | 252 | |
251 | 253 | return true |
252 | 254 | end |
... | ... | @@ -332,15 +334,15 @@ function _M.changeNameRpc(agent, data) |
332 | 334 | SendPacket(actionCodes.Role_changeNameRpc, MsgPack.pack({result = 3})) |
333 | 335 | return true |
334 | 336 | end |
335 | - | |
336 | - local result = redisproxy:setnx(string_format("user:%s", newName), roleId) | |
337 | + local dbName = string.upper(newName) | |
338 | + local result = redisproxy:setnx(string_format("user:%s", dbName), roleId) | |
337 | 339 | if result == 0 then |
338 | 340 | SendPacket(actionCodes.Role_changeNameRpc, MsgPack.pack({result = 1})) |
339 | 341 | return true |
340 | 342 | end |
341 | 343 | redisproxy:pipelining(function (red) |
342 | - red:del(string_format("user:%s", oldName)) | |
343 | - red:set(string_format("uid:%s", role:getProperty("uid")), newName) | |
344 | + red:del(string_format("user:%s", string.upper(oldName))) | |
345 | + red:set(string_format("uid:%s", role:getProperty("uid")), dbName) | |
344 | 346 | end) |
345 | 347 | |
346 | 348 | role:updateProperties({ |
... | ... | @@ -352,6 +354,12 @@ function _M.changeNameRpc(agent, data) |
352 | 354 | return true |
353 | 355 | end |
354 | 356 | |
357 | +function _M.getRandomNameRpc() | |
358 | + local name = randomRoleName() | |
359 | + SendPacket(actionCodes.Role_getRandomNameRpc, MsgPack.pack({name = name})) | |
360 | + return true | |
361 | +end | |
362 | + | |
355 | 363 | function _M.changeIntroRpc(agent, data) |
356 | 364 | local role = agent.role |
357 | 365 | local roleId = role:getProperty("id") |
... | ... | @@ -359,7 +367,7 @@ function _M.changeIntroRpc(agent, data) |
359 | 367 | local content = msg.content |
360 | 368 | if not content or type(content) ~= "string" then return end |
361 | 369 | |
362 | - local SERV = string_format(".CHATED%d", math.random(1, 5)) | |
370 | + local SERV = string_format(".chated%d", math.random(1, 5)) | |
363 | 371 | local legal, mod = skynet.call(SERV, "lua", "check", content) |
364 | 372 | if not legal then |
365 | 373 | content = mod or "" |
... | ... | @@ -744,7 +752,7 @@ function _M.chatRpc(agent, data) |
744 | 752 | -- 判断禁言 |
745 | 753 | local result = nil |
746 | 754 | |
747 | - local SERV = string_format(".CHATED%d", math.random(1, 5)) | |
755 | + local SERV = string_format(".chated%d", math.random(1, 5)) | |
748 | 756 | local legal, mod = skynet.call(SERV, "lua", "check", content) |
749 | 757 | if not legal then |
750 | 758 | content = mod or "" |
... | ... | @@ -799,7 +807,7 @@ function _M.chatRpc(agent, data) |
799 | 807 | end |
800 | 808 | end |
801 | 809 | mcast_util.pub_world(actionCodes.Role_chat, MsgPack.pack(response)) |
802 | - pcall(skynet.send, '.GLOBALD', "lua", "sendWorldMsg", role._channelIdx, response) | |
810 | + pcall(skynet.send, '.globald', "lua", "sendWorldMsg", role._channelIdx, response) | |
803 | 811 | end, |
804 | 812 | -- 私聊 |
805 | 813 | [2] = function () | ... | ... |
src/adv/Adv.lua
... | ... | @@ -74,7 +74,16 @@ function Adv:isHaveRelay(level, chapterId) |
74 | 74 | end |
75 | 75 | |
76 | 76 | -- 随机新的地图 |
77 | -function Adv:initByChapter(chapterId, level, isToNext, notNotify, isRelay, isEnter, support) | |
77 | +function Adv:initByChapter(params) | |
78 | + local chapterId = params.chapterId | |
79 | + local level = params.level | |
80 | + local isToNext = params.isToNext | |
81 | + local notNotify = params.notNotify | |
82 | + local isRelay = params.isRelay | |
83 | + local isEnter = params.isEnter | |
84 | + local support = params.support | |
85 | + local debugMapId = params.debugMapId | |
86 | + | |
78 | 87 | if not self.chapterId then -- 开始新的章节 |
79 | 88 | self.chapterId = chapterId |
80 | 89 | self:checkAchievement(Adv.AchievType.StartBattle, 1) |
... | ... | @@ -99,21 +108,23 @@ function Adv:initByChapter(chapterId, level, isToNext, notNotify, isRelay, isEnt |
99 | 108 | end |
100 | 109 | |
101 | 110 | -- 随机出地图 |
102 | - local mapId | |
103 | - if isRelay then | |
104 | - local relayData = self:isHaveRelay(level, chapterId) | |
105 | - if relayData then | |
106 | - mapId = relayData.map | |
111 | + local mapId, relayData | |
112 | + | |
113 | + if debugMapId and csvdb["mapCsv"][debugMapId] then | |
114 | + mapId = debugMapId | |
115 | + end | |
116 | + if not mapId then | |
117 | + if isRelay then | |
118 | + relayData = self:isHaveRelay(level, chapterId) | |
119 | + if relayData then | |
120 | + mapId = relayData.map | |
121 | + else | |
122 | + isRelay = false | |
123 | + mapId = self:randomMapId(chapterId, level) | |
124 | + end | |
107 | 125 | else |
108 | - isRelay = false | |
109 | 126 | mapId = self:randomMapId(chapterId, level) |
110 | 127 | end |
111 | - else | |
112 | - mapId = self:randomMapId(chapterId, level) | |
113 | - end | |
114 | - | |
115 | - if isEnter and not self.owner:checkOverGuide(GuideStep.AdvGuide) then | |
116 | - mapId = 101 | |
117 | 128 | end |
118 | 129 | |
119 | 130 | self.isRelay = isRelay |
... | ... | @@ -141,9 +152,21 @@ function Adv:initByChapter(chapterId, level, isToNext, notNotify, isRelay, isEnt |
141 | 152 | |
142 | 153 | self:checkTask(Adv.TaskType.Arrive) |
143 | 154 | self:checkAdvUnlock(1, self.level) |
155 | + | |
144 | 156 | if isToNext then |
145 | 157 | self.battle.player:afterLayer() -- 玩家的buff 清理一下 |
146 | 158 | end |
159 | + | |
160 | + -- 不是中继层 加上 层 和 地图的buff和被动 | |
161 | + if not self.isRelay then | |
162 | + self.battle:initMapEffect() | |
163 | + end | |
164 | + | |
165 | + -- 中继进入奖励 | |
166 | + if relayData and isEnter then | |
167 | + self:awardRelay(relayData, notNotify) | |
168 | + end | |
169 | + | |
147 | 170 | if not notNotify then |
148 | 171 | self:saveDB(notNotify) |
149 | 172 | end |
... | ... | @@ -201,6 +224,44 @@ function Adv:saveDB(notNotify) |
201 | 224 | self.owner:updateProperties({advInfo = advInfo, advTeam = advTeam}, notNotify) |
202 | 225 | end |
203 | 226 | |
227 | +function Adv:awardRelay(relayData, notNotify) | |
228 | + local gift = {} | |
229 | + | |
230 | + if relayData.artifact > 0 then | |
231 | + local pool = {} | |
232 | + for id, temp in pairs(csvdb["adv_artifactCsv"]) do | |
233 | + if not self:isHaveArtifact(id) and self.owner:isArtifactOpen(id, self:isEndless()) then | |
234 | + table.insert(pool, id) | |
235 | + end | |
236 | + end | |
237 | + for i = 1, math.min(relayData.artifact, #pool) do | |
238 | + local idx = math.randomInt(1, #pool) | |
239 | + gift[pool[idx]] = 1 | |
240 | + table.remove(pool, idx) | |
241 | + end | |
242 | + end | |
243 | + | |
244 | + if relayData.point > 0 then | |
245 | + gift[ItemId.AdvPoint] = relayData.point | |
246 | + end | |
247 | + | |
248 | + if relayData.otherAward ~= "" then | |
249 | + for dropId, count in pairs(relayData.otherAward:toNumMap()) do | |
250 | + for i = 1, count do | |
251 | + local dropData = csvdb["event_dropCsv"][dropId] | |
252 | + if dropData then | |
253 | + local item = dropData["range"]:randWeight(true) | |
254 | + gift[item[1]] = (gift[item[1]] or 0) + item[2] | |
255 | + else | |
256 | + skynet.error(string.format("[ERROR]: event_dropCsv no id %s, adv_chapter_campsite", dropId)) | |
257 | + end | |
258 | + end | |
259 | + end | |
260 | + end | |
261 | + | |
262 | + self:award(gift, {notNotify = notNotify, log = {desc = "relayEnter", int1 = self.chapterId, int2 = self.level}}) | |
263 | +end | |
264 | + | |
204 | 265 | function Adv:initSupport(supports) |
205 | 266 | self.support = {} |
206 | 267 | |
... | ... | @@ -743,6 +804,7 @@ function Adv:over(success, rewardRatio, overType) |
743 | 804 | |
744 | 805 | self:log({desc = "over", short1 = success and 1 or 0, int1 = overType}) |
745 | 806 | |
807 | + local chapterId = self.chapterId | |
746 | 808 | self:clear() |
747 | 809 | self.owner:checkTaskEnter("AdvScore", {score = score}) |
748 | 810 | |
... | ... | @@ -751,7 +813,7 @@ function Adv:over(success, rewardRatio, overType) |
751 | 813 | advAFGet = {}, |
752 | 814 | advAFWear = {}, |
753 | 815 | }) |
754 | - self:backEnd(success, score, scoreInfo, reward, overType, scoreReward) | |
816 | + self:backEnd(success, score, scoreInfo, reward, overType, scoreReward, chapterId) | |
755 | 817 | end |
756 | 818 | |
757 | 819 | function Adv:exit() |
... | ... | @@ -787,7 +849,7 @@ function Adv:randomMapId(chapterId, level) |
787 | 849 | local temp = csvdb["mapCsv"][mapId] |
788 | 850 | if temp and not lastMapIds[mapId] then |
789 | 851 | if AdvCommon.checkIsIn(level, temp.leveltype, temp.levellimit) then |
790 | - table.insert(pool, mapId) | |
852 | + pool[mapId] = {showup = temp.showup} | |
791 | 853 | end |
792 | 854 | end |
793 | 855 | end |
... | ... | @@ -795,10 +857,10 @@ function Adv:randomMapId(chapterId, level) |
795 | 857 | error("mapIds is empty!") |
796 | 858 | return |
797 | 859 | end |
798 | - return pool[math.randomInt(1, #pool)] | |
860 | + return math.randWeight(pool, "showup") | |
799 | 861 | end |
800 | 862 | |
801 | - | |
863 | +-- log long1 字段被征用!!! | |
802 | 864 | -- 在冒险中获得的物品都发放在冒险背包内 |
803 | 865 | function Adv:award(gift, params) |
804 | 866 | params = params or {} |
... | ... | @@ -835,11 +897,13 @@ function Adv:award(gift, params) |
835 | 897 | |
836 | 898 | if params.log then |
837 | 899 | local log = clone(params.log) |
838 | - if log["cint1"] or log["cint2"] or log["cint3"] then | |
900 | + if log["cint1"] or log["cint2"] or log["cint3"] or log["long1"] then | |
839 | 901 | print("addAdvItem error log have cint1 or cint2 or cint3 ", debug.traceback()) |
840 | 902 | end |
841 | - log["cint1"] = origin | |
903 | + log["cint1"] = itemId | |
842 | 904 | log["cint2"] = math.abs(count) |
905 | + log["cint3"] = self.chapterId | |
906 | + log["long1"] = self.level | |
843 | 907 | if count >= 0 then |
844 | 908 | self.owner:log("in_adv", log) |
845 | 909 | else |
... | ... | @@ -921,7 +985,7 @@ local function clickOut(self, room, block, params, isExit) |
921 | 985 | self:scoreChange(AdvScoreType.Level, curFloorData.advScore) --增加层级加分 |
922 | 986 | end |
923 | 987 | |
924 | - if not self:isEndless() and (self.level >= csvdb["adv_chapterCsv"][self.chapterId].limitlevel or not self.owner:advChapterIsOpen(self.chapterId, self.level + 1)) then --关卡结束 | |
988 | + if not self:isEndless() and (self.level >= csvdb["adv_chapterCsv"][self.chapterId].limitlevel) then --关卡结束 | |
925 | 989 | self:over(true) |
926 | 990 | else |
927 | 991 | self.battle.player:triggerPassive(Passive.DOWN_LAYER) |
... | ... | @@ -933,10 +997,21 @@ local function clickOut(self, room, block, params, isExit) |
933 | 997 | |
934 | 998 | self.owner:getProperty("advTeam").player = self.battle.player:getDB() -- 临时缓存住 battle 的player |
935 | 999 | if isHaveRelay and not self.isRelay then |
936 | - self:initByChapter(self.chapterId, self.level, true, true, true, false) | |
1000 | + self:initByChapter({ | |
1001 | + chapterId = self.chapterId, | |
1002 | + level = self.level, | |
1003 | + isToNext = true, | |
1004 | + notNotify = true, | |
1005 | + isRelay = true, | |
1006 | + }) | |
937 | 1007 | else |
938 | 1008 | self:log({desc = "pass"}) |
939 | - self:initByChapter(self.chapterId, self.level + 1, true, true, false, false) | |
1009 | + self:initByChapter({ | |
1010 | + chapterId = self.chapterId, | |
1011 | + level = self.level + 1, | |
1012 | + isToNext = true, | |
1013 | + notNotify = true, | |
1014 | + }) | |
940 | 1015 | end |
941 | 1016 | self:backNext() --下一关 |
942 | 1017 | end |
... | ... | @@ -958,9 +1033,10 @@ local function clickMonster(self, room, block, params) |
958 | 1033 | end |
959 | 1034 | |
960 | 1035 | local function chooseCommon(self, room, block, chooseData, choose, tag) |
1036 | + if not choose then return end | |
961 | 1037 | if not chooseData or not chooseData["button".. choose .."cond"] then return end |
962 | 1038 | |
963 | - local cond = chooseData["button".. choose .."cond"]:toArray(true, "=") | |
1039 | + local conds = chooseData["button".. choose .."cond"]:toTableArray(true) | |
964 | 1040 | local checkCond = { |
965 | 1041 | -- 没有条件 |
966 | 1042 | [0] = function() |
... | ... | @@ -1035,10 +1111,54 @@ local function chooseCommon(self, room, block, chooseData, choose, tag) |
1035 | 1111 | [10] = function(_, artifactId) |
1036 | 1112 | return not self:isHaveArtifact(artifactId) |
1037 | 1113 | end, |
1114 | + -- 11 = 地图上没有指定id 的怪 | |
1115 | + [11] = function(_, monsterId) | |
1116 | + for _, room in pairs(self:getCurMap().rooms) do | |
1117 | + for _, block in pairs(room.blocks) do | |
1118 | + if block:isMonster() then | |
1119 | + if not monsterId then return false end | |
1120 | + if block.event.id == monsterId then | |
1121 | + return false | |
1122 | + end | |
1123 | + end | |
1124 | + end | |
1125 | + end | |
1126 | + return true | |
1127 | + end, | |
1128 | + -- 12 = 地图上没有指定id 的建筑 | |
1129 | + [12] = function(_, buildId) | |
1130 | + for _, room in pairs(self:getCurMap().rooms) do | |
1131 | + for _, block in pairs(room.blocks) do | |
1132 | + if block:isBuild() then | |
1133 | + if not buildId then return false end | |
1134 | + if block.event.id == buildId then | |
1135 | + return false | |
1136 | + end | |
1137 | + end | |
1138 | + end | |
1139 | + end | |
1140 | + return true | |
1141 | + end, | |
1142 | + -- 13 = 地图上没有指定的 选择点 | |
1143 | + [13] = function(_, chooseId) | |
1144 | + for _, room in pairs(self:getCurMap().rooms) do | |
1145 | + for _, block in pairs(room.blocks) do | |
1146 | + if block:isChoose() then | |
1147 | + if not chooseId then return false end | |
1148 | + if block.event.id == chooseId then | |
1149 | + return false | |
1150 | + end | |
1151 | + end | |
1152 | + end | |
1153 | + end | |
1154 | + return true | |
1155 | + end, | |
1038 | 1156 | } |
1039 | - assert(not cond[1] or checkCond[cond[1]], "error cond, event_" .. (tag or "choose") .. "Csv id :" .. block.event.id) | |
1040 | - | |
1041 | - if cond[1] and not checkCond[cond[1]](table.unpack(cond)) then return end | |
1157 | + for _, cond in ipairs(conds) do | |
1158 | + assert(not cond[1] or checkCond[cond[1]], "error cond, event_" .. (tag or "choose") .. "Csv id :" .. block.event.id) | |
1159 | + if cond[1] and not checkCond[cond[1]](table.unpack(cond)) then return end | |
1160 | + end | |
1161 | + | |
1042 | 1162 | local clearBlock = chooseData.keep ~= 1 |
1043 | 1163 | local effects = chooseData["button".. choose .."effect"]:toTableArray(true) |
1044 | 1164 | for _, effect in ipairs(effects) do |
... | ... | @@ -1047,8 +1167,13 @@ local function chooseCommon(self, room, block, chooseData, choose, tag) |
1047 | 1167 | local count = effect[3] or 1 |
1048 | 1168 | local reward = {} |
1049 | 1169 | for i = 1, count do |
1050 | - local item = csvdb["event_dropCsv"][effect[2]]["range"]:randWeight(true) | |
1051 | - reward[item[1]] = (reward[item[1]] or 0) + item[2] | |
1170 | + local dropData = csvdb["event_dropCsv"][effect[2]] | |
1171 | + if dropData then | |
1172 | + local item = dropData["range"]:randWeight(true) | |
1173 | + reward[item[1]] = (reward[item[1]] or 0) + item[2] | |
1174 | + else | |
1175 | + skynet.error(string.format("[ERROR]: event_dropCsv no id %s in %s id: %s", effect[2], tag, chooseData.id)) | |
1176 | + end | |
1052 | 1177 | end |
1053 | 1178 | self:backReward(self:award(reward, {log = {desc = "chooseEvent", key1 = tag, int1 = chooseData.id}}), {roomId = room.roomId, blockId = block.blockId}) |
1054 | 1179 | end, |
... | ... | @@ -1059,9 +1184,6 @@ local function chooseCommon(self, room, block, chooseData, choose, tag) |
1059 | 1184 | end |
1060 | 1185 | end, |
1061 | 1186 | [3] = function() --发现怪物 |
1062 | - if block:getEventType() == AdvEventType.Build then | |
1063 | - self.battle:removeBuildByPos(room.roomId, block.blockId) | |
1064 | - end | |
1065 | 1187 | self:getCurMap():addNewMonsterRand(effect[2], {room, block}) |
1066 | 1188 | self:pushBackEvent(AdvBackEventType.Monster, {id = effect[2]}) |
1067 | 1189 | clearBlock = false |
... | ... | @@ -1083,59 +1205,71 @@ local function chooseCommon(self, room, block, chooseData, choose, tag) |
1083 | 1205 | etype = AdvEventType.Trader, |
1084 | 1206 | id = effect[2] |
1085 | 1207 | }) |
1086 | - block:randomEvent() | |
1087 | 1208 | self:pushBackEvent(AdvBackEventType.Trader, {id = effect[2]}) |
1088 | 1209 | clearBlock = false |
1089 | 1210 | end, |
1090 | 1211 | [7] = function() -- 建筑 |
1091 | - if block:getEventType() == AdvEventType.Build then | |
1092 | - self.battle:removeBuildByPos(room.roomId, block.blockId) | |
1093 | - end | |
1094 | 1212 | block:updateEvent({ |
1095 | 1213 | etype = AdvEventType.Build, |
1096 | 1214 | id = effect[2] |
1097 | 1215 | }) |
1098 | - block:randomEvent() | |
1099 | 1216 | clearBlock = false |
1100 | 1217 | end, |
1101 | 1218 | [8] = function() -- 选择 |
1102 | - if block:getEventType() == AdvEventType.Build then | |
1103 | - self.battle:removeBuildByPos(room.roomId, block.blockId) | |
1104 | - end | |
1105 | 1219 | block:updateEvent({ |
1106 | 1220 | etype = AdvEventType.Choose, |
1107 | 1221 | id = effect[2] |
1108 | 1222 | }) |
1109 | - block:randomEvent() | |
1110 | 1223 | clearBlock = false |
1111 | 1224 | end, |
1112 | 1225 | [9] = function() -- click |
1113 | - if block:getEventType() == AdvEventType.Build then | |
1114 | - self.battle:removeBuildByPos(room.roomId, block.blockId) | |
1115 | - end | |
1116 | 1226 | block:updateEvent({ |
1117 | 1227 | etype = AdvEventType.Click, |
1118 | 1228 | id = effect[2] |
1119 | 1229 | }) |
1120 | - block:randomEvent() | |
1121 | 1230 | clearBlock = false |
1122 | 1231 | end, |
1123 | 1232 | [10] = function() -- 陷阱 |
1124 | - if block:getEventType() == AdvEventType.Build then | |
1125 | - self.battle:removeBuildByPos(room.roomId, block.blockId) | |
1126 | - end | |
1127 | 1233 | block:updateEvent({ |
1128 | 1234 | etype = AdvEventType.Trap, |
1129 | 1235 | id = effect[2] |
1130 | 1236 | }) |
1131 | - block:randomEvent() | |
1132 | 1237 | clearBlock = false |
1133 | 1238 | end, |
1134 | 1239 | [11] = function() -- 获得神器 |
1135 | 1240 | self:waitChooseArtifact() --等待获取神器 |
1136 | - end | |
1241 | + end, | |
1242 | + [12] = function() | |
1243 | + -- buffId | |
1244 | + local targers = self.battle.player:getTeam(2, nil, nil, true) | |
1245 | + for _, target in pairs(targers) do | |
1246 | + target:addBuff(effect[2]) | |
1247 | + end | |
1248 | + end, | |
1249 | + [13] = function() -- 显示地图 | |
1250 | + self:getCurMap():showMap() | |
1251 | + self:backMapShow() | |
1252 | + end, | |
1253 | + [14] = function() -- 指定地块召唤 指定类型的id | |
1254 | + local change = self:getCurMap():layEventToStage(effect[2], effect[3], effect[4], effect[5]) | |
1255 | + for _, one in ipairs(change) do | |
1256 | + self:backBlockChange(one[1].roomId, one[2].blockId) | |
1257 | + end | |
1258 | + end, | |
1259 | + [15] = function() -- 移除指定事件 | |
1260 | + local change = self:getCurMap():clearEventById(effect[2], effect[3], effect[4]) | |
1261 | + for _, one in ipairs(change) do | |
1262 | + self:backBlockChange(one[1].roomId, one[2].blockId) | |
1263 | + end | |
1264 | + end, | |
1265 | + [16] = function() -- 指定事件转移 | |
1266 | + local change = self:getCurMap():eventChangeToOther(effect[2], effect[3], effect[4], effect[5], effect[6]) | |
1267 | + for _, one in ipairs(change) do | |
1268 | + self:backBlockChange(one[1].roomId, one[2].blockId) | |
1269 | + end | |
1270 | + end, | |
1137 | 1271 | } |
1138 | - assert(doEffect[effect[1]], "error effect, event_" .. (tag or "choose") .. "Csv id :" .. block.event.id) | |
1272 | + assert(doEffect[effect[1]], "error effect, event_" .. (tag or "choose") .. "Csv id :" .. (block.event and block.event.id or 0) .. "effect " .. effect[1]) | |
1139 | 1273 | doEffect[effect[1]]() |
1140 | 1274 | end |
1141 | 1275 | self:scoreChange(AdvScoreType.Event, chooseData.advScore) --增加加分 |
... | ... | @@ -1201,7 +1335,9 @@ end |
1201 | 1335 | local function clickDrop(self, room, block, params) |
1202 | 1336 | local reward = {} |
1203 | 1337 | if not block.event.item then return end |
1338 | + if not self.battle or not self.battle.player then return end | |
1204 | 1339 | self.battle.player:triggerPassive(Passive.CLICK_DROP) |
1340 | + | |
1205 | 1341 | local reward = self:award({[block.event.item[1]] = block.event.item[2]}, {log = {desc = "clickDrop"}}) |
1206 | 1342 | -- local reward = self:award({[5801] = 1}) |
1207 | 1343 | block:clear() |
... | ... | @@ -1306,7 +1442,8 @@ local function clickLayer(self, room, block, params) |
1306 | 1442 | table.insert(self.mapStack, mapIdx) |
1307 | 1443 | |
1308 | 1444 | self.maps[mapIdx] = AdvMap.new(self, mapIdx, mapId) |
1309 | - self.battle:initMapEnemys(mapIdx) | |
1445 | + self.battle:initMapEnemys(mapIdx, true) | |
1446 | + self.battle:initMapEffect(true) | |
1310 | 1447 | self.maps[mapIdx]:initBattleAfter() |
1311 | 1448 | self:checkAchievement(Adv.AchievType.EnterILayer, 1, mapId) |
1312 | 1449 | end |
... | ... | @@ -1347,7 +1484,7 @@ function Adv:clickBlock(roomId, blockId, params) |
1347 | 1484 | if not ignoreGuard and _block:isGuard() then |
1348 | 1485 | if _block:isMonster() then |
1349 | 1486 | local enemy = self.battle:getEnemy(_room.roomId, _block.blockId) |
1350 | - if not enemy:hadBuff(Buff.DONT_DEFEND) then | |
1487 | + if not enemy:hadBuff(Buff.DONT_DEFEND) and not self.battle.player:hadBuff(Buff.SNEAK) then | |
1351 | 1488 | return false |
1352 | 1489 | end |
1353 | 1490 | else |
... | ... | @@ -1485,7 +1622,6 @@ function Adv:doActive(activeId, target) |
1485 | 1622 | etype = AdvEventType.Trader, |
1486 | 1623 | id = traderId, |
1487 | 1624 | }) |
1488 | - target:randomEvent() | |
1489 | 1625 | self:backBlockChange(target.room.roomId, target.blockId) |
1490 | 1626 | self:pushBackEvent(AdvBackEventType.Trader, {id = traderId}) |
1491 | 1627 | end |
... | ... | @@ -1497,7 +1633,6 @@ function Adv:doActive(activeId, target) |
1497 | 1633 | doActiveEffect[3] = function(_, monsterId) |
1498 | 1634 | for _, target in ipairs(targers) do |
1499 | 1635 | if not target.lock and not target.isDead then |
1500 | - self.battle:removeEnemyById(target.id) | |
1501 | 1636 | self:getCurMap():addNewMonsterRand(monsterId, {self:getRoom(target.roomId), self:getBlock(target.roomId, target.blockId)}) |
1502 | 1637 | self:backBlockChange(target.roomId, target.blockId) |
1503 | 1638 | self:pushBackEvent(AdvBackEventType.Monster, {id = monsterId}) |
... | ... | @@ -1515,7 +1650,7 @@ function Adv:doActive(activeId, target) |
1515 | 1650 | doActiveEffect[5] = function(_) |
1516 | 1651 | for _, target in ipairs(targers) do |
1517 | 1652 | if not target.lock and not target.isDead then |
1518 | - target.isDead = true | |
1653 | + target:kill() | |
1519 | 1654 | self:backBlockChange(target.roomId, target.blockId) |
1520 | 1655 | end |
1521 | 1656 | end |
... | ... | @@ -1679,8 +1814,12 @@ function Adv:enemyDead(enemy, escape) |
1679 | 1814 | if buff then |
1680 | 1815 | item = table.pack(buff:effect()) |
1681 | 1816 | else |
1682 | - local dropData = csvdb["event_dropCsv"][monsterData.dropid] | |
1683 | - item = dropData["range"]:randWeight(true) | |
1817 | + if monsterData.dropid == 0 then | |
1818 | + item = {0, 0} | |
1819 | + else | |
1820 | + local dropData = csvdb["event_dropCsv"][monsterData.dropid] | |
1821 | + item = dropData["range"]:randWeight(true) | |
1822 | + end | |
1684 | 1823 | end |
1685 | 1824 | |
1686 | 1825 | end |
... | ... | @@ -1688,6 +1827,11 @@ function Adv:enemyDead(enemy, escape) |
1688 | 1827 | block:clear() |
1689 | 1828 | self.battle.player:triggerPassive(Passive.BATTLE_WIN) |
1690 | 1829 | else |
1830 | + local buff = enemy:hadBuff(Buff.DROP_BUFF_BY_ENEMY) -- 根据敌人数量变化个数 | |
1831 | + if buff then | |
1832 | + local team = enemy:getTeam(1, true) | |
1833 | + item[2] = math.floor(item[2] * (1 + 0.2 * #team)) | |
1834 | + end | |
1691 | 1835 | block:updateEvent({ |
1692 | 1836 | etype = AdvEventType.Drop, |
1693 | 1837 | item = item |
... | ... | @@ -1736,8 +1880,8 @@ function Adv:backNext() |
1736 | 1880 | self:pushBackEvent(AdvBackEventType.Next, {}) |
1737 | 1881 | end |
1738 | 1882 | |
1739 | -function Adv:backEnd(success, score, scoreInfo, reward, overType, scoreAward) | |
1740 | - self:pushBackEvent(AdvBackEventType.End, {success = success, score = score, scoreInfo = scoreInfo, reward = reward, type = overType, scoreAward = scoreAward}) | |
1883 | +function Adv:backEnd(success, score, scoreInfo, reward, overType, scoreAward, chapterId) | |
1884 | + self:pushBackEvent(AdvBackEventType.End, {success = success, score = score, scoreInfo = scoreInfo, reward = reward, type = overType, scoreAward = scoreAward, chapterId = chapterId}) | |
1741 | 1885 | end |
1742 | 1886 | |
1743 | 1887 | function Adv:backBlockChange(roomId, blockId, itemChangeType) | ... | ... |
src/adv/AdvBattle.lua
... | ... | @@ -18,16 +18,22 @@ function Battle:ctor(adv) |
18 | 18 | end |
19 | 19 | end |
20 | 20 | |
21 | -function Battle:initAfter() | |
22 | - self.player:initAfter(self.adv.owner:getProperty("advTeam").player) | |
21 | +function Battle:initAfter(mapIdx) | |
22 | + if not mapIdx then | |
23 | + self.player:initAfter(self.adv.owner:getProperty("advTeam").player) | |
24 | + end | |
23 | 25 | for idx, mapEnemys in pairs(self.enemys) do |
24 | - for _, enemy in ipairs(mapEnemys) do | |
25 | - enemy:initAfter(self.adv:getBlock(enemy.roomId, enemy.blockId, idx).event.enemy) | |
26 | + if not mapIdx or idx == mapIdx then | |
27 | + for _, enemy in ipairs(mapEnemys) do | |
28 | + enemy:initAfter(self.adv:getBlock(enemy.roomId, enemy.blockId, idx).event.enemy) | |
29 | + end | |
26 | 30 | end |
27 | 31 | end |
28 | 32 | for idx, mapBuilds in pairs(self.builds) do |
29 | - for _, build in ipairs(mapBuilds) do | |
30 | - build:initAfter(self.adv:getBlock(build.roomId, build.blockId, idx).event.build) | |
33 | + if not mapIdx or idx == mapIdx then | |
34 | + for _, build in ipairs(mapBuilds) do | |
35 | + build:initAfter(self.adv:getBlock(build.roomId, build.blockId, idx).event.build) | |
36 | + end | |
31 | 37 | end |
32 | 38 | end |
33 | 39 | end |
... | ... | @@ -65,7 +71,9 @@ function Battle:initPlayer() |
65 | 71 | player.level = 1 |
66 | 72 | if self.adv.level ~= 1 then |
67 | 73 | local relayData = self.adv:isHaveRelay() |
68 | - player.level = relayData.level | |
74 | + if relayData then | |
75 | + player.level = relayData.level | |
76 | + end | |
69 | 77 | end |
70 | 78 | player.exp = 0 |
71 | 79 | player.sp = getAdvLvAttrUp(advAddAttrs, "sp", 100) |
... | ... | @@ -109,18 +117,21 @@ function Battle:initEnemys() |
109 | 117 | end |
110 | 118 | end |
111 | 119 | |
112 | - | |
113 | -function Battle:initMapEnemys(mapIdx) | |
120 | +-- after 是否是 后创建的夹层 | |
121 | +function Battle:initMapEnemys(mapIdx, after) | |
114 | 122 | self.enemys[mapIdx] = {} |
115 | 123 | self.builds[mapIdx] = {} |
116 | 124 | local map = self.adv.maps[mapIdx] |
117 | 125 | if map then |
118 | 126 | for _, room in pairs(map.rooms) do |
119 | 127 | for _, block in pairs(room.blocks) do |
120 | - self:addEnemy(room, block, mapIdx) | |
128 | + self:addEnemy(room, block, mapIdx, true) | |
121 | 129 | end |
122 | 130 | end |
123 | 131 | end |
132 | + if after then | |
133 | + self:initAfter(mapIdx) | |
134 | + end | |
124 | 135 | if self.cachePassiveEvent[mapIdx] then |
125 | 136 | for _, passiveC in ipairs(self.cachePassiveEvent or {}) do |
126 | 137 | for _, enemy in ipairs(self.enemys[mapIdx]) do |
... | ... | @@ -135,9 +146,10 @@ function Battle:initMapEnemys(mapIdx) |
135 | 146 | self.cachePassiveEvent[mapIdx] = nil |
136 | 147 | end |
137 | 148 | |
138 | -function Battle:addEnemy(room, block, mapIdx) | |
149 | +function Battle:addEnemy(room, block, mapIdx, init) | |
139 | 150 | mapIdx = mapIdx or self.adv:getCurMapIdx() |
140 | 151 | |
152 | + local isNew, player, data | |
141 | 153 | if block:isMonster() then |
142 | 154 | if not block.event.enemy then |
143 | 155 | local enemyCsv = csvdb["event_monsterCsv"][block.event.id] |
... | ... | @@ -151,10 +163,15 @@ function Battle:addEnemy(room, block, mapIdx) |
151 | 163 | table.insert(enemy.passives, {id = id}) |
152 | 164 | end |
153 | 165 | block.event.enemy = enemy |
166 | + isNew = true | |
167 | + end | |
168 | + if not block.event.mId then | |
169 | + block.event.mId = self.adv.lastEnemyId | |
170 | + self.adv.lastEnemyId = self.adv.lastEnemyId + 1 | |
154 | 171 | end |
155 | - local player = Enemy.new(self, block.event.mId or 999, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.enemy, mapIdx) | |
172 | + data = block.event.enemy | |
173 | + player = Enemy.new(self, block.event.mId, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.enemy, mapIdx) | |
156 | 174 | table.insert(self.enemys[mapIdx], player) |
157 | - return player | |
158 | 175 | elseif block:isBuild() then |
159 | 176 | if not block.event.build then |
160 | 177 | local buildCsv = csvdb["event_buildingCsv"][block.event.id] |
... | ... | @@ -164,11 +181,28 @@ function Battle:addEnemy(room, block, mapIdx) |
164 | 181 | table.insert(build.passives, {id = id}) |
165 | 182 | end |
166 | 183 | block.event.build = build |
184 | + isNew = true | |
167 | 185 | end |
168 | - local player = Build.new(self, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.build, mapIdx) | |
186 | + data = block.event.build | |
187 | + player = Build.new(self, block.event.id, room.roomId, block.blockId, not block.isOpen, block.event.build, mapIdx) | |
169 | 188 | table.insert(self.builds[mapIdx], player) |
170 | - return player | |
171 | 189 | end |
190 | + if not init then | |
191 | + player:initAfter(data) | |
192 | + | |
193 | + -- 游戏中新创建的 加上地图 floor 效果 | |
194 | + if isNew then | |
195 | + local passives, buffs = self:getMapEffect(2, true, mapIdx) | |
196 | + for _, passive in ipairs(passives) do | |
197 | + player:addPassive({id = passive}) | |
198 | + end | |
199 | + | |
200 | + for _, buff in ipairs(buffs) do | |
201 | + enemy:addBuff(buff) | |
202 | + end | |
203 | + end | |
204 | + end | |
205 | + return player | |
172 | 206 | end |
173 | 207 | |
174 | 208 | function Battle:getEnemy(roomId, blockId, mapIdx) |
... | ... | @@ -249,16 +283,29 @@ end |
249 | 283 | --回合 |
250 | 284 | function Battle:afterRound() |
251 | 285 | local mapIdx = self.adv:getCurMapIdx() |
252 | - self.player:afterRound() | |
286 | + | |
253 | 287 | table.sort(self.enemys[mapIdx], function(e1, e2) |
254 | 288 | return e1.id < e2.id |
255 | 289 | end) |
290 | + | |
291 | + self.player:afterRound("passive") | |
256 | 292 | for _, enemy in ipairs(self.enemys[mapIdx]) do |
257 | - enemy:afterRound() | |
293 | + enemy:afterRound("passive") | |
258 | 294 | end |
259 | 295 | for _, build in ipairs(self.builds[mapIdx]) do |
260 | - build:afterRound() | |
296 | + build:afterRound("passive") | |
297 | + end | |
298 | + | |
299 | + self.player:afterRound("buff") | |
300 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
301 | + enemy:afterRound("buff") | |
261 | 302 | end |
303 | + for _, build in ipairs(self.builds[mapIdx]) do | |
304 | + build:afterRound("buff") | |
305 | + end | |
306 | + | |
307 | + | |
308 | + | |
262 | 309 | self.player:clearRound() |
263 | 310 | for _, enemy in ipairs(self.enemys[mapIdx]) do |
264 | 311 | enemy:clearRound() |
... | ... | @@ -292,9 +339,10 @@ function Battle:battleBegin(roomId, blockId, params) |
292 | 339 | local enemy = self:getEnemy(roomId, blockId) |
293 | 340 | if not enemy then return end |
294 | 341 | local player = params.player |
342 | + if not player then return end | |
295 | 343 | -- 玩家没死就是怪死了 |
296 | 344 | if player.hp > 0 then |
297 | - enemy:hurt(enemy.hp, self.player, {hurtType = 5}) | |
345 | + enemy:kill() | |
298 | 346 | self.player:effectBattleBuff() |
299 | 347 | |
300 | 348 | self.adv.owner:checkTaskEnter("AdvBattleWin", {id = self.adv.chapterId}) |
... | ... | @@ -312,6 +360,63 @@ function Battle:battleBegin(roomId, blockId, params) |
312 | 360 | end |
313 | 361 | |
314 | 362 | |
363 | +function Battle:getMapEffect(ctype, ilayer, mapIdx) | |
364 | + mapIdx = mapIdx or self.adv:getCurMapIdx() | |
365 | + local mapData = self.adv.maps[mapIdx]:getMapInfoCsv() or {} | |
366 | + local floorData = self.adv:getCurFloorData() or {} | |
367 | + | |
368 | + local passives = {} | |
369 | + local buffs = {} | |
370 | + | |
371 | + for _type, temp in ipairs({mapData, floorData}) do | |
372 | + for _, one in ipairs((temp.passive or ""):toTableArray(true)) do | |
373 | + passives[one[1]] = passives[one[1]] or {} | |
374 | + if ilayer and one[1] == 1 and _type == 2 then | |
375 | + else | |
376 | + table.insert(passives[one[1]], one[2]) | |
377 | + end | |
378 | + end | |
379 | + for _, one in ipairs((temp.buff or ""):toTableArray(true)) do | |
380 | + buffs[one[1]] = buffs[one[1]] or {} | |
381 | + if ilayer and one[1] == 1 and _type == 2 then | |
382 | + else | |
383 | + table.insert(buffs[one[1]], one[2]) | |
384 | + end | |
385 | + end | |
386 | + end | |
387 | + if ctype then | |
388 | + passives = passives[ctype] or {} | |
389 | + buffs = buffs[ctype] or {} | |
390 | + end | |
391 | + return passives, buffs | |
392 | +end | |
393 | +-- 夹层玩家 不重复加 floor | |
394 | +function Battle:initMapEffect(ilayer) | |
395 | + local passives, buffs = self:getMapEffect(nil, ilayer) | |
396 | + local mapIdx = self.adv:getCurMapIdx() | |
397 | + | |
398 | + for _, passive in ipairs(passives[1] or {}) do | |
399 | + self.player:addPassive({id = passive}) | |
400 | + end | |
401 | + | |
402 | + for _, passive in ipairs(passives[2] or {}) do | |
403 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
404 | + enemy:addPassive({id = passive}) | |
405 | + end | |
406 | + end | |
407 | + | |
408 | + for _, buff in ipairs(buffs[1] or {}) do | |
409 | + self.palyer:addBuff(buff) | |
410 | + end | |
411 | + | |
412 | + for _, buff in ipairs(buffs[2] or {}) do | |
413 | + for _, enemy in ipairs(self.enemys[mapIdx]) do | |
414 | + enemy:addBuff(buff) | |
415 | + end | |
416 | + end | |
417 | +end | |
418 | + | |
419 | + | |
315 | 420 | --写入数据 |
316 | 421 | function Battle:saveDB() |
317 | 422 | for idx, mapEnemys in pairs(self.enemys) do | ... | ... |
src/adv/AdvBlock.lua
... | ... | @@ -25,12 +25,39 @@ function Block:isBuild() |
25 | 25 | return self:getEventType() == AdvEventType.Build |
26 | 26 | end |
27 | 27 | |
28 | +function Block:isChoose() | |
29 | + return self:getEventType() == AdvEventType.Choose | |
30 | +end | |
31 | + | |
28 | 32 | function Block:getEventType() |
29 | 33 | return self.event and self.event.etype |
30 | 34 | end |
31 | 35 | |
36 | +function Block:getStageType() | |
37 | + return self.room:getStageType(self.blockId) | |
38 | +end | |
39 | + | |
32 | 40 | function Block:updateEvent(event, isInit) |
41 | + if not isInit then | |
42 | + -- 有些事件删除 需要处理 | |
43 | + if self:isBuild() then | |
44 | + self.room.map.adv.battle:removeBuildByPos(self.room.roomId, self.blockId) | |
45 | + elseif self:isMonster() then | |
46 | + if self.event.mId then | |
47 | + self.room.map.adv.battle:removeEnemyById(self.event.mId) | |
48 | + end | |
49 | + end | |
50 | + end | |
33 | 51 | self.event = event |
52 | + if not isInit and self.event then | |
53 | + -- 判断下类型是不是错的 | |
54 | + if not self:getEventData() and (self:getEventType() ~= AdvEventType.Drop or not self.event.item) then | |
55 | + self:clear() | |
56 | + assert(false, "updateEvent error, : event " .. (event.etype or "nil")) | |
57 | + return | |
58 | + end | |
59 | + self:randomEvent() | |
60 | + end | |
34 | 61 | end |
35 | 62 | |
36 | 63 | function Block:clear() |
... | ... | @@ -54,14 +81,11 @@ function Block:randomEvent() |
54 | 81 | local randomFunc = {} |
55 | 82 | --怪 |
56 | 83 | randomFunc[AdvEventType.Monster] = function() |
57 | - self.event.mId = adv.lastEnemyId --给怪一个有序id 回合逻辑时使用 | |
58 | - adv.lastEnemyId = adv.lastEnemyId + 1 | |
59 | 84 | local enemy = adv.battle:getEnemy(room.roomId, self.blockId, map.mapIdx) |
60 | 85 | if enemy then |
61 | - enemy:unlock(self.event.mId) | |
86 | + enemy:unlock() | |
62 | 87 | else |
63 | 88 | enemy = adv.battle:addEnemy(room, self, map.mapIdx) |
64 | - enemy:initAfter(self.event.enemy) | |
65 | 89 | end |
66 | 90 | enemy:triggerPassive(Passive.BORN_ONCE) |
67 | 91 | |
... | ... | @@ -73,7 +97,9 @@ function Block:randomEvent() |
73 | 97 | randomFunc[AdvEventType.BOSS] = randomFunc[AdvEventType.Monster] |
74 | 98 | --掉落 |
75 | 99 | randomFunc[AdvEventType.Drop] = function() |
76 | - self.event.item = csvdb["event_dropCsv"][self.event.id]["range"]:randWeight(true) | |
100 | + if not self.event.item then | |
101 | + self.event.item = csvdb["event_dropCsv"][self.event.id]["range"]:randWeight(true) | |
102 | + end | |
77 | 103 | end |
78 | 104 | --交易 |
79 | 105 | randomFunc[AdvEventType.Trader] = function() |
... | ... | @@ -144,7 +170,6 @@ function Block:randomEvent() |
144 | 170 | build:unlock() |
145 | 171 | else |
146 | 172 | build = adv.battle:addEnemy(room, self, map.mapIdx) |
147 | - build:initAfter(self.event.build) | |
148 | 173 | end |
149 | 174 | build:triggerPassive(Passive.BORN_ONCE) |
150 | 175 | end |
... | ... | @@ -155,13 +180,18 @@ function Block:randomEvent() |
155 | 180 | adv.battle.player:triggerPassive(Passive.CLICK_TRAP) |
156 | 181 | |
157 | 182 | local buffs = data.effect:toArray(true, "=") |
158 | - for _, buffId in ipairs(buffs) do | |
159 | - adv.battle.player:addBuff(buffId) | |
160 | - end | |
183 | + | |
161 | 184 | |
162 | 185 | local backTrap = true |
163 | - if data.target == 1 then-- 给所有敌人同样增加buff | |
186 | + if data.target == 0 then -- 给玩家增加buff | |
187 | + for _, buffId in ipairs(buffs) do | |
188 | + adv.battle.player:addBuff(buffId) | |
189 | + end | |
190 | + elseif data.target == 1 then-- 给玩家 和 所有敌人同样增加buff | |
164 | 191 | local enemys = adv.battle.player:getTeam(2) |
192 | + for _, buffId in ipairs(buffs) do | |
193 | + adv.battle.player:addBuff(buffId) | |
194 | + end | |
165 | 195 | for k , enemy in ipairs(enemys) do |
166 | 196 | for _, buffId in ipairs(buffs) do |
167 | 197 | enemy:addBuff(buffId) |
... | ... | @@ -170,6 +200,14 @@ function Block:randomEvent() |
170 | 200 | elseif data.target == 2 then -- 翻开房间 |
171 | 201 | self.room.map.adv:getCurMap():openBlocksByRoom(self.room.roomId) |
172 | 202 | backTrap = false |
203 | + elseif data.target == 3 then -- 翻开周围8格,并给怪物附带buff(不伤害玩家) | |
204 | + self.room.map.adv:getCurMap():openBlocksBySize(self.room.roomId, self.blockId, 2) | |
205 | + local enemys = self.room.map.adv:getCurMap():getEnemysBySize(self.room.roomId, self.blockId, 2) | |
206 | + for _, e in ipairs(enemys) do | |
207 | + for _, buffId in ipairs(buffs) do | |
208 | + e:addBuff(buffId) | |
209 | + end | |
210 | + end | |
173 | 211 | end |
174 | 212 | |
175 | 213 | if data.specialEff ~= "" then |
... | ... | @@ -223,8 +261,8 @@ function Block:open() |
223 | 261 | local room = self.room |
224 | 262 | local map = room.map |
225 | 263 | local adv = map.adv |
226 | - self:randomEvent() | |
227 | 264 | self.isOpen = true |
265 | + self:randomEvent() | |
228 | 266 | return true |
229 | 267 | end |
230 | 268 | ... | ... |
src/adv/AdvBuff.lua
... | ... | @@ -22,7 +22,8 @@ Buff.CHANGE_DROP = 18 -- 转换掉落 |
22 | 22 | Buff.BATTLE_PASSIVE = 19 -- 切换为战斗中的被动技 |
23 | 23 | Buff.EXP_ADD = 20 -- 增加exp(每回合) |
24 | 24 | Buff.DONT_DEFEND = 21 -- 不看守地板 -- 怪周围点半可点击 |
25 | - | |
25 | +Buff.SHOW_DANGER = 22 -- 扫雷 展示地上怪物和陷阱数量的标记 | |
26 | +Buff.SHOW_MONSTER_POS = 23 -- 蓝臂章训练场 感知 | |
26 | 27 | Buff.EXP_UP = 24 -- 杀敌经验提高 |
27 | 28 | Buff.DISABLE_BUFF = 25 -- 禁用固有技 |
28 | 29 | Buff.ATTR_CHANGE_COND = 26 --属性变化(状态)有条件 |
... | ... | @@ -31,6 +32,8 @@ Buff.SP_MAX_CHANGE = 28 -- 魔法上限 |
31 | 32 | Buff.ITEM_GET_UP = 29 -- 获得道具数量增加 |
32 | 33 | Buff.Buff_EFFECT_CHANGE = 30 -- 改变 buff 效果 |
33 | 34 | Buff.Buff_NO_PASSIVE_MONSTER = 31 -- 地图被动刷新不出来怪物 |
35 | +Buff.SNEAK = 32 --潜行 | |
36 | +Buff.DROP_BUFF_BY_ENEMY = 33 -- 怪物掉落加成 -- 怪物使用 | |
34 | 37 | |
35 | 38 | |
36 | 39 | --角色一些属性的变化 |
... | ... | @@ -81,7 +84,9 @@ local function commonAttCond(_Buff, attrName) |
81 | 84 | effectCount = self.owner.battle.adv.level |
82 | 85 | elseif self.buffData.effectValue4 == 2 then |
83 | 86 | local buff = self.owner.battle.player:getBuffById(tonumber(self.buffData.effectValue5)) |
84 | - effectCount = buff.layer | |
87 | + if buff then | |
88 | + effectCount = buff.layer | |
89 | + end | |
85 | 90 | end |
86 | 91 | return self.buffData.effectValue2 * effectCount |
87 | 92 | end |
... | ... | @@ -153,11 +158,15 @@ local BuffFactory = { |
153 | 158 | [Buff.HP_MAX_CHANGE] = function(_Buff) |
154 | 159 | _Buff._init = function(self) --初始化变化值 |
155 | 160 | self._changeV = self:_calculate() |
161 | + local old = self.owner.hpMax | |
156 | 162 | self.owner:reSetHpMax() |
163 | + self:_addHpByMax(old) | |
157 | 164 | end |
158 | 165 | _Buff._overlay = function(self) |
159 | 166 | self._changeV = (self._changeV or 0) + self:_calculate() |
167 | + local old = self.owner.hpMax | |
160 | 168 | self.owner:reSetHpMax() |
169 | + self:_addHpByMax(old) | |
161 | 170 | end |
162 | 171 | |
163 | 172 | _Buff._uncover = function(self) |
... | ... | @@ -170,7 +179,7 @@ local BuffFactory = { |
170 | 179 | if self.buffData.effectValue1 == 0 then --固定值 |
171 | 180 | curValue = self.buffData.effectValue2 |
172 | 181 | elseif self.buffData.effectValue1 == 1 then |
173 | - local baseOwner = self.buffData.effectValue4 == 1 and self.owner or self.release | |
182 | + local baseOwner = self.buffData.effectValue4 == 1 and self.owner or self.release | |
174 | 183 | local attrs = {[0] = "hp", [1] = "hpMax", [2] = "atk"} |
175 | 184 | curValue = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100 |
176 | 185 | end |
... | ... | @@ -181,6 +190,15 @@ local BuffFactory = { |
181 | 190 | return self:doEffectChange(self._changeV) |
182 | 191 | end |
183 | 192 | |
193 | + _Buff._addHpByMax = function(self, old) | |
194 | + if self.buffData.effectValue5 == "1" then | |
195 | + local change = self.owner.hpMax - old | |
196 | + if change > 0 then | |
197 | + self.owner:recover(change, self.release) -- 防止release不存在,地图点buff | |
198 | + end | |
199 | + end | |
200 | + end | |
201 | + | |
184 | 202 | _Buff._endBuff = function(self) |
185 | 203 | self.owner:reSetHpMax() |
186 | 204 | end |
... | ... | @@ -355,7 +373,11 @@ local BuffFactory = { |
355 | 373 | return self.buffData.effectValue1 |
356 | 374 | end |
357 | 375 | end, |
358 | - | |
376 | + [Buff.SNEAK] = function(_Buff) | |
377 | + _Buff._init = function(self) | |
378 | + self.layer = self.buffData.effectValue1 | |
379 | + end | |
380 | + end, | |
359 | 381 | } |
360 | 382 | |
361 | 383 | -- 同样的返回 effectValue1, effectValue2 * self.layer 类型的buff |
... | ... | @@ -472,6 +494,7 @@ function Buff:checkKeep() |
472 | 494 | 2=建筑id; |
473 | 495 | 3=事件id |
474 | 496 | 4=队伍为特定属性时 |
497 | + 5=拥有指定buff | |
475 | 498 | --]] |
476 | 499 | |
477 | 500 | local checkFunc = {} |
... | ... | @@ -508,6 +531,13 @@ function Buff:checkKeep() |
508 | 531 | local role = self.owner.battle.adv.owner |
509 | 532 | return role:getHerosCamp(role:getProperty("advTeam").heros) == teamAttr |
510 | 533 | end |
534 | + checkFunc[5] = function(_, buffId) | |
535 | + local buff = self.owner:getBuffById(buffId) | |
536 | + if buff and not buff.isDel then | |
537 | + return true | |
538 | + end | |
539 | + return false | |
540 | + end | |
511 | 541 | |
512 | 542 | local keepTerm = self.buffData.keepTerm:toArray(true, "=") |
513 | 543 | if not checkFunc[keepTerm[1]] then return true end |
... | ... | @@ -526,7 +556,7 @@ end |
526 | 556 | |
527 | 557 | function Buff:afterLayer() |
528 | 558 | -- 持续一层 |
529 | - if self.buffData.round == 0 then | |
559 | + if self.buffData.round == 0 or self.buffData.mapLock == 1 then | |
530 | 560 | self.isDel = true |
531 | 561 | end |
532 | 562 | end | ... | ... |
src/adv/AdvMap.lua
... | ... | @@ -2,6 +2,8 @@ |
2 | 2 | local Room = require "adv.AdvRoom" |
3 | 3 | local Passive = require "adv.AdvPassive" |
4 | 4 | local AdvCommon = require "adv.AdvCommon" |
5 | + | |
6 | +local Buff = require "adv.AdvBuff" | |
5 | 7 | -- 一层地图 |
6 | 8 | local Map = class("AdvMap") |
7 | 9 | -- 内部方法声明 |
... | ... | @@ -10,7 +12,8 @@ local createMap, getEventLib |
10 | 12 | |
11 | 13 | function Map:ctor(adv, mapIdx, mapInfo, isEnter, isNewRelay) |
12 | 14 | self.adv = adv |
13 | - if type(mapInfo) == "number" then -- mapInfo 传入 id | |
15 | + local isNew = type(mapInfo) == "number" | |
16 | + if isNew then -- mapInfo 传入 id | |
14 | 17 | mapInfo = createMap(self, mapInfo, isEnter, isNewRelay) -- 生成地图 |
15 | 18 | end |
16 | 19 | if not mapInfo then return end |
... | ... | @@ -19,19 +22,25 @@ function Map:ctor(adv, mapIdx, mapInfo, isEnter, isNewRelay) |
19 | 22 | self.mapId = mapInfo.mapId |
20 | 23 | self.isShow = mapInfo.isShow -- 是否全部展示 -- 客户端用 |
21 | 24 | self.rooms = {} |
22 | - self:loadRooms(mapInfo.rooms, isNewRelay) | |
25 | + self:loadRooms(mapInfo.rooms, isNew, isNewRelay) | |
23 | 26 | end |
24 | 27 | |
25 | -function Map:loadRooms(rooms, isNewRelay) | |
26 | - local mapData = csvdb["map_" .. csvdb["mapCsv"][self.mapId]["path"] .. "Csv"] | |
28 | +function Map:loadRooms(rooms, isNew, isNewRelay) | |
29 | + local mapInfoCsv = csvdb["mapCsv"][self.mapId] | |
30 | + local mapData = csvdb["map_" .. mapInfoCsv["path"] .. "Csv"] | |
31 | + | |
27 | 32 | for roomId, roomName in pairs(mapData["rooms"]) do |
28 | 33 | if roomName == "path" then |
29 | - self.rooms[roomId] = Room.new(self, roomId, mapData["path"], rooms[roomId], true, isNewRelay) | |
34 | + self.rooms[roomId] = Room.new(self, roomId, mapData["path"], rooms[roomId], true, isNewRelay, mapInfoCsv.type) | |
30 | 35 | else |
31 | 36 | roomName = roomName:gsub("/", "_") |
32 | - self.rooms[roomId] = Room.new(self, roomId, csvdb["room_" .. roomName .. "Csv"], rooms[roomId], false, isNewRelay) | |
37 | + self.rooms[roomId] = Room.new(self, roomId, csvdb["room_" .. roomName .. "Csv"], rooms[roomId], false, isNewRelay, mapInfoCsv.type) | |
33 | 38 | end |
34 | 39 | end |
40 | + | |
41 | + if mapInfoCsv.type == 2 and isNew then | |
42 | + self:showMap() | |
43 | + end | |
35 | 44 | end |
36 | 45 | |
37 | 46 | function Map:initBattleAfter() |
... | ... | @@ -40,6 +49,11 @@ function Map:initBattleAfter() |
40 | 49 | end |
41 | 50 | end |
42 | 51 | |
52 | + | |
53 | +function Map:getMapInfoCsv() | |
54 | + return csvdb["mapCsv"][self.mapId] | |
55 | +end | |
56 | + | |
43 | 57 | function Map:getDB() |
44 | 58 | local map = {} |
45 | 59 | map.mapId = self.mapId |
... | ... | @@ -108,16 +122,104 @@ function Map:addNewMonsterRand(monsterId, where) |
108 | 122 | monsterId = math.randWeight(eventLib[AdvEventType.Monster][0], "showup") |
109 | 123 | end |
110 | 124 | |
111 | - local event = {etype = AdvEventType.Monster, mId = self.adv.lastEnemyId} | |
112 | - self.adv.lastEnemyId = self.adv.lastEnemyId + 1 | |
113 | - event.id = monsterId | |
125 | + local event = { | |
126 | + etype = AdvEventType.Monster, | |
127 | + id = monsterId, | |
128 | + } | |
114 | 129 | block:updateEvent(event) |
115 | 130 | |
116 | - self.adv.battle:addEnemy(room, block):triggerPassive(Passive.BORN_ONCE) | |
117 | - | |
118 | 131 | return room, block |
119 | 132 | end |
120 | 133 | |
134 | +-- 在指定地块类型上 放置指定类型事件id | |
135 | +function Map:layEventToStage(eventType, eventId, count, stage) | |
136 | + local pool = {} | |
137 | + for _, room_ in pairs(self.rooms) do | |
138 | + for _, block_ in pairs(room_.blocks) do | |
139 | + if block_.isOpen and not block_.event and block_:getStageType() == stage then | |
140 | + table.insert(pool, {room_, block_}) | |
141 | + end | |
142 | + end | |
143 | + end | |
144 | + if not next(pool) then return {} end | |
145 | + local change = {} | |
146 | + count = math.min(#pool, count) | |
147 | + for i = 1, count do | |
148 | + local idx = math.randomInt(1, #pool) | |
149 | + local room, block = pool[idx][1], pool[idx][2] | |
150 | + table.remove(pool, idx) | |
151 | + | |
152 | + local event = { | |
153 | + etype = eventType, | |
154 | + id = eventId, | |
155 | + } | |
156 | + block:updateEvent(event) | |
157 | + table.insert(change, {room, block}) | |
158 | + end | |
159 | + return change | |
160 | +end | |
161 | + | |
162 | +-- 地图中指定事件 切换为另一个事件 | |
163 | +function Map:eventChangeToOther(eventTypeF, eventIdF, eventTypeT, eventIdT, count) | |
164 | + count = count or 1 | |
165 | + local pool = {} | |
166 | + for _, room_ in pairs(self.rooms) do | |
167 | + for _, block_ in pairs(room_.blocks) do | |
168 | + if block_.isOpen and block_:getEventType() == eventTypeF and block_.event.id == eventIdF then | |
169 | + table.insert(pool, {room_, block_}) | |
170 | + end | |
171 | + end | |
172 | + end | |
173 | + if not next(pool) then return {} end | |
174 | + local change = {} | |
175 | + count = math.min(#pool, count) | |
176 | + for i = 1, count do | |
177 | + local idx = math.randomInt(1, #pool) | |
178 | + local room, block = pool[idx][1], pool[idx][2] | |
179 | + table.remove(pool, idx) | |
180 | + | |
181 | + local event = { | |
182 | + etype = eventTypeT, | |
183 | + id = eventIdT, | |
184 | + } | |
185 | + block:updateEvent(event) | |
186 | + table.insert(change, {room, block}) | |
187 | + end | |
188 | + return change | |
189 | +end | |
190 | + | |
191 | +function Map:clearEventById(eventType, eventId, count, exclude) | |
192 | + count = count or 0 | |
193 | + eventId = eventId or 0 | |
194 | + exclude = exclude or {} | |
195 | + | |
196 | + local pool = {} | |
197 | + for roomId, room_ in pairs(self.rooms) do | |
198 | + exclude[roomId] = exclude[roomId] or {} | |
199 | + for blockId, block_ in pairs(room_.blocks) do | |
200 | + if not exclude[roomId][blockId] and block_.isOpen and block_:getEventType() == eventType and (eventId == 0 or block_.event.id == eventId) then | |
201 | + table.insert(pool, {room_, block_}) | |
202 | + end | |
203 | + end | |
204 | + end | |
205 | + if not next(pool) then return {} end | |
206 | + local change = {} | |
207 | + if count == 0 then | |
208 | + count = #pool | |
209 | + else | |
210 | + count = math.min(#pool, count) | |
211 | + end | |
212 | + for i = 1, count do | |
213 | + local idx = math.randomInt(1, #pool) | |
214 | + local room, block = pool[idx][1], pool[idx][2] | |
215 | + table.remove(pool, idx) | |
216 | + | |
217 | + block:updateEvent(nil) | |
218 | + table.insert(change, {room, block}) | |
219 | + end | |
220 | + return change | |
221 | +end | |
222 | + | |
121 | 223 | -- 随机翻开 num 个 以开放的房间的 地块 |
122 | 224 | function Map:openBlockRand(num, isPlayer, ignoreBack) |
123 | 225 | local pool = {} |
... | ... | @@ -156,11 +258,21 @@ function Map:openBlock(roomId, blockId, isPlayer, ignoreBack) |
156 | 258 | if isPlayer then |
157 | 259 | self.adv.battle.player:triggerPassive(Passive.OPEN_BLOCK) |
158 | 260 | self.adv.owner:checkTaskEnter("AdvOpenBlock") |
261 | + | |
262 | + -- 潜行检查 | |
263 | + local sneakBuff = self.adv.battle.player:hadBuff(Buff.SNEAK) | |
264 | + if sneakBuff then | |
265 | + local enemys = self:getEnemysBySize(roomId, blockId, 2) | |
266 | + if #enemys > 0 then | |
267 | + sneakBuff:uncover() | |
268 | + end | |
269 | + end | |
159 | 270 | end |
160 | 271 | |
161 | 272 | if not ignoreBack then |
162 | 273 | self.adv:backBlockChange(roomId, blockId) |
163 | 274 | end |
275 | + | |
164 | 276 | end |
165 | 277 | end |
166 | 278 | |
... | ... | @@ -237,6 +349,20 @@ function Map:getBlocksBySize(roomId, blockId, size) |
237 | 349 | return blocks |
238 | 350 | end |
239 | 351 | |
352 | +function Map:getEnemysBySize(roomId, blockId, size) | |
353 | + local blocks = self:getBlocksBySize(roomId, blockId, size) | |
354 | + local enemys = {} | |
355 | + for _, block in ipairs(blocks) do | |
356 | + if block:isMonster() then | |
357 | + local e = self.adv.battle:getEnemy(block.room.roomId, block.blockId) | |
358 | + if e then | |
359 | + table.insert(enemys, e) | |
360 | + end | |
361 | + end | |
362 | + end | |
363 | + return enemys | |
364 | +end | |
365 | + | |
240 | 366 | -----------------------------随机地图----------------------------- |
241 | 367 | |
242 | 368 | -- isEnter isNewRelay 区分中继层的类型 --是否是开始进入 是否是第一次进入 |
... | ... | @@ -250,6 +376,31 @@ createMap = function(self, mapId, isEnter, isNewRelay) |
250 | 376 | error("mapId " .. mapId .. " dont exist!") |
251 | 377 | return |
252 | 378 | end |
379 | + | |
380 | + local etypeToStr = { | |
381 | + [AdvEventType.Choose] = "choose", | |
382 | + [AdvEventType.Drop] = "drop", | |
383 | + [AdvEventType.Monster] = "monster", | |
384 | + [AdvEventType.Trader] = "trader", | |
385 | + [AdvEventType.Build] = "building", | |
386 | + [AdvEventType.Trap] = "trap", | |
387 | + [AdvEventType.Click] = "click", | |
388 | + } | |
389 | + | |
390 | + local highLevelEvent = {} | |
391 | + for _etype, _str in pairs(etypeToStr) do | |
392 | + if mapCsvData[_str] ~= "" then | |
393 | + highLevelEvent[_etype] = {} | |
394 | + end | |
395 | + for _id, _count in pairs(mapCsvData[_str]:toNumMap()) do | |
396 | + local _curData = csvdb["event_" .. _str .. "Csv"][_id] | |
397 | + if _curData then | |
398 | + highLevelEvent[_etype][_curData.BlockEventType] = highLevelEvent[_etype][_curData.BlockEventType] or {} | |
399 | + highLevelEvent[_etype][_curData.BlockEventType][_id] = {showup = _curData.showup, limit = _count, dlimit = _curData.limit} | |
400 | + end | |
401 | + end | |
402 | + end | |
403 | + | |
253 | 404 | --事件随机 |
254 | 405 | local eventLib = getEventLib(self) -- 同时记录出现次数 |
255 | 406 | local monsterEvents = {} --处理钥匙掉落 |
... | ... | @@ -270,42 +421,60 @@ createMap = function(self, mapId, isEnter, isNewRelay) |
270 | 421 | local randomFunc = {} |
271 | 422 | |
272 | 423 | local function randomCommon() |
273 | - if not eventLib[etype] or not next(eventLib[etype]) or not eventLib[etype][especial] or not next(eventLib[etype][especial]) then return false end | |
274 | - event.id = math.randWeight(eventLib[etype][especial], "showup") | |
275 | - if not event.id then return false end | |
276 | - | |
277 | - -- 不是 0 才会记录 | |
278 | - if eventLib[etype][especial][event.id].dlimit ~= 0 then | |
279 | - eventLimit[etype] = eventLimit[etype] or {} | |
280 | - eventLimit[etype][event.id] = (eventLimit[etype][event.id] or 0) + 1 | |
424 | + -- 刷新地图专属的 | |
425 | + | |
426 | + local function randomByLevelLib(lib) | |
427 | + -- 刷新通用的 | |
428 | + if not lib[etype] or not next(lib[etype]) or not lib[etype][especial] then return false end | |
429 | + -- 清一下全关卡次数用完的 | |
430 | + for _eid, _edata in pairs(lib[etype][especial]) do | |
431 | + if _edata.dlimit ~= 0 and ((eventLimit[etype] or {})[_eid] or 0) >= _edata.dlimit then | |
432 | + lib[etype][especial][_eid] = nil | |
433 | + end | |
434 | + end | |
435 | + | |
436 | + if not next(lib[etype][especial]) then return false end | |
437 | + event.id = math.randWeight(lib[etype][especial], "showup") | |
438 | + if not event.id then return false end | |
439 | + | |
440 | + -- 不是 0 才会记录 | |
441 | + if lib[etype][especial][event.id].dlimit ~= 0 then | |
442 | + eventLimit[etype] = eventLimit[etype] or {} | |
443 | + eventLimit[etype][event.id] = (eventLimit[etype][event.id] or 0) + 1 | |
444 | + end | |
445 | + | |
446 | + -- 消除单层次数用完的 | |
447 | + if lib[etype][especial][event.id].limit > 1 then | |
448 | + lib[etype][especial][event.id].limit = lib[etype][especial][event.id].limit - 1 | |
449 | + elseif lib[etype][especial][event.id].limit == 1 then | |
450 | + lib[etype][especial][event.id] = nil | |
451 | + end | |
452 | + return true | |
281 | 453 | end |
282 | 454 | |
283 | - -- 消除 | |
284 | - if eventLib[etype][especial][event.id].limit > 1 then | |
285 | - eventLib[etype][especial][event.id].limit = eventLib[etype][especial][event.id].limit - 1 | |
286 | - elseif eventLib[etype][especial][event.id].limit == 1 then | |
287 | - eventLib[etype][especial][event.id] = nil | |
455 | + local status = randomByLevelLib(highLevelEvent) | |
456 | + if not status then | |
457 | + status = randomByLevelLib(eventLib) | |
288 | 458 | end |
459 | + return status | |
289 | 460 | end |
290 | 461 | |
291 | 462 | --入口 |
292 | 463 | randomFunc[AdvEventType.In] = function()end |
293 | 464 | --出口 |
294 | - randomFunc[AdvEventType.Out] = function() | |
295 | - if not self.adv:isEndless() and self.adv.isRelay and not self.adv.owner:checkOverGuide(GuideStep.AdvRelay) then | |
296 | - return false | |
297 | - end | |
298 | - end | |
299 | - --中继点出口 | |
300 | - randomFunc[AdvEventType.Exit] = function() | |
301 | - if not self.adv.isRelay or self.adv.owner:checkOverGuide(GuideStep.AdvRelay) then return false end | |
302 | - end | |
465 | + randomFunc[AdvEventType.Out] = function()end | |
466 | + -- --中继点出口 | |
467 | + -- randomFunc[AdvEventType.Exit] = function() | |
468 | + -- -- if not self.adv.isRelay or self.adv.owner:checkOverGuide(GuideStep.AdvRelay) then return false end | |
469 | + -- return false | |
470 | + -- end | |
303 | 471 | --开放出口 |
304 | 472 | randomFunc[AdvEventType.InOut] = function() end |
305 | 473 | |
306 | 474 | --开放出口 |
307 | 475 | randomFunc[AdvEventType.Diner] = function() |
308 | - if not self.adv.isRelay or isEnter or isNewRelay then return false end | |
476 | + -- if not self.adv.isRelay or isEnter or isNewRelay then return false end | |
477 | + if not self.adv.isRelay or isEnter then return false end | |
309 | 478 | end |
310 | 479 | |
311 | 480 | --boss |
... | ... | @@ -344,7 +513,8 @@ createMap = function(self, mapId, isEnter, isNewRelay) |
344 | 513 | randomFunc[AdvEventType.Drop] = randomCommon |
345 | 514 | --交易所 |
346 | 515 | randomFunc[AdvEventType.Trader] = function() |
347 | - if self.adv.isRelay and isNewRelay then return false end | |
516 | + -- if self.adv.isRelay and isNewRelay then return false end | |
517 | + if self.adv.isRelay then return false end | |
348 | 518 | return randomCommon() |
349 | 519 | end |
350 | 520 | --建筑 |
... | ... | @@ -584,15 +754,8 @@ getEventLib = function(self, needEventType) -- needEventType 需要的事件 |
584 | 754 | end |
585 | 755 | end |
586 | 756 | |
587 | - -- data.limit 改为 整个冒险全程 | |
588 | - local limit = data.limit | |
589 | - if data.limit ~= 0 then | |
590 | - limit = data.limit - ((eventLimit[etype] or {})[id] or 0) | |
591 | - if limit <= 0 then | |
592 | - add = false | |
593 | - end | |
594 | - end | |
595 | - | |
757 | + -- limit 单次上限 默认无限 | |
758 | + local limit = 0 | |
596 | 759 | if add and (etype == AdvEventType.LinkChoose or etype == AdvEventType.Choose) then --只能有一次 |
597 | 760 | limit = 1 |
598 | 761 | end | ... | ... |
src/adv/AdvPassive.lua
... | ... | @@ -6,6 +6,7 @@ Filter.HP_LOW_WITH_EQUAL = 3 -- 血量<=value% |
6 | 6 | Filter.HP_LOW = 4 -- 血量<value% |
7 | 7 | Filter.BUFF_BY_TYPE = 5 -- 指定类型buff |
8 | 8 | Filter.BUFF_BY_ID = 6 -- 指定id的buff |
9 | +Filter.CAMP = 7 -- 玩家是指定阵营 | |
9 | 10 | |
10 | 11 | local FilterFactory = {} |
11 | 12 | FilterFactory[Filter.HP_UP_WITH_EQUAL] = function (_Filter) |
... | ... | @@ -38,6 +39,13 @@ FilterFactory[Filter.BUFF_BY_ID] = function (_Filter) |
38 | 39 | return target:hadBuffById(self.value) |
39 | 40 | end |
40 | 41 | end |
42 | +FilterFactory[Filter.CAMP] = function (_Filter) | |
43 | + _Filter._execute = function (self, target) | |
44 | + local role = self.owner.battle.adv.owner | |
45 | + return role:getHerosCamp(role:getProperty("advTeam").heros) == self.value | |
46 | + end | |
47 | +end | |
48 | + | |
41 | 49 | |
42 | 50 | function Filter:ctor(params) |
43 | 51 | self.owner = params.owner |
... | ... | @@ -145,7 +153,9 @@ PassiveCondFactory[Passive.OPEN_BLOCK] = PassiveCondFactory[Passive.HURT_PERCENT |
145 | 153 | PassiveCondFactory[Passive.SELF_HURT] = function(_Passive) |
146 | 154 | _Passive._trigger = function(self, params) |
147 | 155 | local buffId = params.buffId |
156 | + if not buffId then return end | |
148 | 157 | local data = csvdb["adv_map_buffCsv"][buffId] |
158 | + if not data then return end | |
149 | 159 | if data.classify:sismember(self.passiveData.value, " ") then |
150 | 160 | return true |
151 | 161 | end |
... | ... | @@ -297,7 +307,7 @@ function Passive:canEffect(effType, effValue) |
297 | 307 | end |
298 | 308 | |
299 | 309 | function Passive:effect(triggerPms) |
300 | - for _, effect in pairs(self.effects) do | |
310 | + for _, effect in ipairs(self.effects) do | |
301 | 311 | local effType = effect[1] |
302 | 312 | local effValue = effect[2] |
303 | 313 | local otherPms = {} |
... | ... | @@ -314,7 +324,7 @@ function Passive:effect(triggerPms) |
314 | 324 | self.round = self.passiveData.round |
315 | 325 | end |
316 | 326 | |
317 | - if self.count <= 0 and self.passiveData.refresh == 1 then -- 次数 <= 0 并且一次冒险内不刷新,被动可以直接移除 | |
327 | + if self.count <= 0 then -- 次数 <= 0 并且一次冒险内不刷新,被动可以直接移除 | |
318 | 328 | self.isDel = true |
319 | 329 | end |
320 | 330 | end |
... | ... | @@ -332,6 +342,12 @@ function Passive:afterRound() |
332 | 342 | end |
333 | 343 | end |
334 | 344 | |
345 | +function Passive:afterLayer() | |
346 | + if self.passiveData.mapLock == 1 or self.passiveData.floorType == 1 then | |
347 | + self.isDel = true | |
348 | + end | |
349 | +end | |
350 | + | |
335 | 351 | -- 可以触发 |
336 | 352 | function Passive:canTrigger( ) |
337 | 353 | return self.count > 0 and self.delay <= 0 |
... | ... | @@ -427,11 +443,13 @@ function Passive:effect5(monsterId) |
427 | 443 | |
428 | 444 | end |
429 | 445 | |
430 | ---6=给所有场上怪物增加buff | |
431 | -function Passive:effect6(value) | |
446 | +--6=给所有场上怪物增加buff 《 限定 怪 id》 | |
447 | +function Passive:effect6(value, triggerPms, enemyId) | |
432 | 448 | local aims = self.owner.battle.player:getTeam(2) |
433 | 449 | for k , aim in pairs(aims) do |
434 | - aim:addBuff(value, self.owner) | |
450 | + if not enemyId or enemyId == 0 or aim.monsterId == enemyId then | |
451 | + aim:addBuff(value, self.owner) | |
452 | + end | |
435 | 453 | end |
436 | 454 | end |
437 | 455 | |
... | ... | @@ -471,4 +489,33 @@ function Passive:effect10(count, triggerPms) |
471 | 489 | end |
472 | 490 | end |
473 | 491 | |
492 | +-- 将地图上的A事件替换成B事件 | |
493 | +function Passive:effect11(eventTypeF, triggerPms, eventIdF, eventTypeT, eventIdT, count) | |
494 | + local change = self.owner.battle.adv:getCurMap():eventChangeToOther(eventTypeF, eventIdF, eventTypeT, eventIdT, count) | |
495 | + for _, one in ipairs(change) do | |
496 | + self.owner.battle.adv:backBlockChange(one[1].roomId, one[2].blockId) | |
497 | + end | |
498 | +end | |
499 | + | |
500 | +-- 在指定地点召唤event项目 | |
501 | +function Passive:effect12(eventType, triggerPms, eventId, count, stage) | |
502 | + local change = self.owner.battle.adv:getCurMap():layEventToStage(eventType, eventId, count, stage) | |
503 | + for _, one in ipairs(change) do | |
504 | + self.owner.battle.adv:backBlockChange(one[1].roomId, one[2].blockId) | |
505 | + end | |
506 | +end | |
507 | + | |
508 | +-- 移除指定项目 | |
509 | +function Passive:effect13(eventType, triggerPms, eventId, count) | |
510 | + local exclude = {} | |
511 | + if self.owner:is("Enemy") then | |
512 | + exclude[self.owner.roomId] = {[self.owner.blockId] = 1} | |
513 | + end | |
514 | + local change = self.owner.battle.adv:getCurMap():clearEventById(eventType, eventId, count, exclude) | |
515 | + for _, one in ipairs(change) do | |
516 | + self.owner.battle.adv:backBlockChange(one[1].roomId, one[2].blockId) | |
517 | + end | |
518 | +end | |
519 | + | |
520 | + | |
474 | 521 | return Passive |
475 | 522 | \ No newline at end of file | ... | ... |
src/adv/AdvPlayer.lua
... | ... | @@ -50,19 +50,21 @@ function BaseObject:reset(data) |
50 | 50 | self:initAfter(data) |
51 | 51 | end |
52 | 52 | |
53 | -function BaseObject:afterRound() | |
54 | - for _, passive in ipairs(self.passives) do | |
55 | - passive:afterRound(self) | |
56 | - end | |
57 | - for _, buff in ipairs(self.buffs) do | |
58 | - buff:afterRound() | |
53 | +function BaseObject:afterRound(roundType) | |
54 | + if roundType == "passive" then | |
55 | + for _, passive in ipairs(self.passives) do | |
56 | + passive:afterRound(self) | |
57 | + end | |
58 | + elseif roundType == "buff" then | |
59 | + for _, buff in ipairs(self.buffs) do | |
60 | + buff:afterRound() | |
61 | + end | |
59 | 62 | end |
60 | 63 | end |
61 | 64 | |
62 | 65 | function BaseObject:clearRound() |
63 | 66 | for i = #self.passives, 1, -1 do |
64 | 67 | if self.passives[i].isDel then |
65 | - self.passives[i]:endPassive() | |
66 | 68 | table.remove(self.passives, i) |
67 | 69 | end |
68 | 70 | end |
... | ... | @@ -82,33 +84,33 @@ function BaseObject:clear() |
82 | 84 | self.passives = {} |
83 | 85 | end |
84 | 86 | |
85 | -function BaseObject:battleBegin() | |
86 | - for _, passive in ipairs(self.passives) do | |
87 | - passive:battleBegin() | |
88 | - end | |
89 | -end | |
90 | - | |
91 | -function BaseObject:battleEnd() | |
92 | - for _, buff in ipairs(self.buffs) do | |
93 | - buff:battleEnd() | |
94 | - end | |
95 | -end | |
96 | - | |
97 | 87 | function BaseObject:addPassive(params) |
98 | 88 | local skillId = params.id |
99 | 89 | local skillData = csvdb["adv_map_passiveCsv"][skillId] |
100 | 90 | if not skillData then return end |
101 | 91 | local level = params.level or 1 |
102 | 92 | if not skillData[level] then return end |
93 | + | |
94 | + if self:getPassiveById(skillId) then return end -- 被动技不能重复 | |
95 | + | |
103 | 96 | table.insert(self.passives, Passive.new(self, { id = skillId, level = level })) |
104 | 97 | end |
105 | 98 | |
99 | +function BaseObject:getPassiveById(bId) | |
100 | + for idx, passive in ipairs(self.passives) do | |
101 | + if passive.id == bId then | |
102 | + return passive | |
103 | + end | |
104 | + end | |
105 | +end | |
106 | + | |
106 | 107 | function BaseObject:getPassiveIdx(passive) |
107 | 108 | for idx, passive_ in ipairs(self.passives) do |
108 | 109 | if passive_ == passive then |
109 | 110 | return idx |
110 | 111 | end |
111 | 112 | end |
113 | + return 999 | |
112 | 114 | end |
113 | 115 | |
114 | 116 | function BaseObject:getDisablePassiveCount() |
... | ... | @@ -524,8 +526,7 @@ function Enemy:ctor(battle, mId, monsterId, roomId, blockId, lock, enemy, mapIdx |
524 | 526 | self.mapIdx = mapIdx |
525 | 527 | self:initData(enemy) |
526 | 528 | end |
527 | -function Enemy:unlock(id) | |
528 | - self.id = id | |
529 | +function Enemy:unlock() | |
529 | 530 | self.lock = nil |
530 | 531 | end |
531 | 532 | |
... | ... | @@ -533,6 +534,10 @@ function Enemy:isEnemy() |
533 | 534 | return true |
534 | 535 | end |
535 | 536 | |
537 | +function Enemy:kill() | |
538 | + self:hurt(self.hp, self.battle.player, {hurtType = 5}) | |
539 | +end | |
540 | + | |
536 | 541 | local Player = class("Player", BaseObject) |
537 | 542 | function Player:ctor(battle, data) |
538 | 543 | Player.super.ctor(self, battle) |
... | ... | @@ -566,6 +571,9 @@ function Player:addExp(value) |
566 | 571 | if level >= #csvdb["adv_levelCsv"] then break end |
567 | 572 | end |
568 | 573 | local delta = level - self.level |
574 | + | |
575 | + self.battle.adv:pushBackEvent(AdvBackEventType.Exp, {delta = value}) | |
576 | + | |
569 | 577 | if delta > 0 then |
570 | 578 | for attr, _ in pairs(AdvAttsEnum) do |
571 | 579 | self:addBaseAttr(attr, self.growth[attr] * delta, 0, true) |
... | ... | @@ -643,11 +651,18 @@ function Player:effectBattleBuff() |
643 | 651 | end |
644 | 652 | |
645 | 653 | function Player:afterLayer() |
654 | + for _, passive in ipairs(self.passives) do | |
655 | + if not passive.isDel then | |
656 | + passive:afterLayer() | |
657 | + end | |
658 | + end | |
646 | 659 | for _, buff in ipairs(self.buffs) do |
647 | 660 | if not buff.isDel then |
648 | 661 | buff:afterLayer() |
649 | 662 | end |
650 | 663 | end |
664 | + | |
665 | + self:clearRound() | |
651 | 666 | end |
652 | 667 | |
653 | 668 | function Player:addBuff(buffId, releaser) | ... | ... |
src/adv/AdvRoom.lua
... | ... | @@ -5,7 +5,7 @@ local Block = require "adv.AdvBlock" |
5 | 5 | local Passive = require "adv.AdvPassive" |
6 | 6 | |
7 | 7 | local Room = class("AdvRoom") |
8 | -function Room:ctor(map, roomId, csvData, info, isPath, isNewRelay) | |
8 | +function Room:ctor(map, roomId, csvData, info, isPath, isNewRelay, mapType) | |
9 | 9 | self.map = map |
10 | 10 | self.roomId = roomId |
11 | 11 | self.col, self.row = AdvCommon.getCrById(self.roomId) |
... | ... | @@ -13,14 +13,15 @@ function Room:ctor(map, roomId, csvData, info, isPath, isNewRelay) |
13 | 13 | self.isBossRoom = false -- boss房间 --击败boss 以后重置为false |
14 | 14 | self.isShow = false |
15 | 15 | self.battleAfterCall = {} |
16 | + self.csvData = csvData | |
16 | 17 | |
17 | 18 | self.blocks = {} |
18 | - self:loadBlocks(csvData, info, isNewRelay) | |
19 | + self:loadBlocks(info, isNewRelay, mapType) | |
19 | 20 | end |
20 | 21 | |
21 | -function Room:loadBlocks(csvData, info, isNewRelay) | |
22 | +function Room:loadBlocks(info, isNewRelay, mapType) | |
22 | 23 | local isFirstOpen = false |
23 | - for blockId, _ in pairs(csvData["blocks"]) do | |
24 | + for blockId, _ in pairs(self.csvData["blocks"]) do | |
24 | 25 | self.blocks[blockId] = Block.new(self, blockId, info.event[blockId], info.open == 1 or info.open[blockId], info.trap[blockId]) |
25 | 26 | if not self.isPath and self.blocks[blockId]:isBoss() then |
26 | 27 | self.isBossRoom = true |
... | ... | @@ -32,19 +33,29 @@ function Room:loadBlocks(csvData, info, isNewRelay) |
32 | 33 | self.isShow = true |
33 | 34 | self.blocks[blockId].isOpen = true |
34 | 35 | isFirstOpen = true |
35 | - --入口房间只会在这里首次展示开放 --触发固有技 | |
36 | - self.map.adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
37 | 36 | end |
38 | 37 | end |
39 | 38 | end |
40 | 39 | --中继层全部开放 boss 房间 开启所有的地块 |
41 | - if (self.map.adv.isRelay and not isNewRelay) or (self.isBossRoom and self.isShow and isFirstOpen) then | |
40 | + if (self.map.adv.isRelay and not isNewRelay) or (self.isBossRoom and self.isShow and isFirstOpen) or (isFirstOpen and mapType == 1) then | |
42 | 41 | table.insert(self.battleAfterCall, function() |
43 | 42 | for _, block in pairs(self.blocks) do |
44 | 43 | self:openBlock(block) |
45 | 44 | end |
46 | 45 | end) |
47 | 46 | end |
47 | + if isFirstOpen then | |
48 | + table.insert(self.battleAfterCall, function() | |
49 | + --入口房间只会在这里首次展示开放 --触发固有技 | |
50 | + self.map.adv:triggerPassive(Passive.ROOM_SHOW, {roomId = self.roomId}) | |
51 | + end) | |
52 | + end | |
53 | +end | |
54 | + | |
55 | +function Room:getStageType(blockId) | |
56 | + if not self.blocks[blockId] then return end | |
57 | + if not self.csvData["blocks"][blockId] then return end | |
58 | + return self.csvData["blocks"][blockId] | |
48 | 59 | end |
49 | 60 | |
50 | 61 | function Room:initBattleAfter() | ... | ... |
src/adv/AdvTask.lua
... | ... | @@ -248,18 +248,33 @@ function AdvTask.bind(Adv) |
248 | 248 | |
249 | 249 | local advAchievChange = {} |
250 | 250 | |
251 | - local function insertChange(chapterId, taskId, value, pts) | |
251 | + local function insertChange(self, chapterId, taskId, value, pts) | |
252 | 252 | local achievField = AdvCommon.isEndless(chapterId) and "advEAchiev" or "advAchiev" |
253 | + local dbData = self.owner:getProperty(achievField) | |
253 | 254 | if pts then |
254 | - table.insert(advAchievChange, {type = achievField, field = {chapterId, "pts", taskId}, value = value}) | |
255 | + advAchievChange[achievField] = advAchievChange[achievField] or {} | |
256 | + advAchievChange[achievField][chapterId] = advAchievChange[achievField][chapterId] or {} | |
257 | + advAchievChange[achievField][chapterId]["pts"] = advAchievChange[achievField][chapterId]["pts"] or {} | |
258 | + advAchievChange[achievField][chapterId]["pts"][taskId] = value | |
259 | + | |
260 | + dbData[chapterId] = dbData[chapterId] or {} | |
261 | + dbData[chapterId]["pts"] = dbData[chapterId]["pts"] or {} | |
262 | + dbData[chapterId]["pts"][taskId] = value | |
255 | 263 | else |
256 | - table.insert(advAchievChange, {type = achievField, field = {chapterId, taskId}, value = value}) | |
264 | + advAchievChange[achievField] = advAchievChange[achievField] or {} | |
265 | + advAchievChange[achievField][chapterId] = advAchievChange[achievField][chapterId] or {} | |
266 | + advAchievChange[achievField][chapterId][taskId] = value | |
267 | + | |
268 | + dbData[chapterId] = dbData[chapterId] or {} | |
269 | + dbData[chapterId][taskId] = value | |
257 | 270 | end |
258 | 271 | end |
259 | 272 | |
260 | 273 | function Adv:checkAchievement(taskType, count, cond, cond2) |
261 | 274 | local achievField = self:isEndless() and "advEAchiev" or "advAchiev" |
262 | - local advAchiev = self.owner:getProperty(achievField)[self.chapterId] or {} | |
275 | + local dbData = self.owner:getProperty(achievField) | |
276 | + dbData[self.chapterId] = dbData[self.chapterId] or {} | |
277 | + local advAchiev = dbData[self.chapterId] | |
263 | 278 | for taskId , data in pairs(csvdb["adv_achievementCsv"][self.chapterId] or {}) do |
264 | 279 | local oldStatus = advAchiev[taskId] or 0 |
265 | 280 | if oldStatus ~= -1 and data.type == taskType then |
... | ... | @@ -332,18 +347,19 @@ function AdvTask.bind(Adv) |
332 | 347 | |
333 | 348 | if self:isEndless() then |
334 | 349 | if status and status ~= oldStatus then |
335 | - insertChange(self.chapterId, taskId, status) | |
350 | + insertChange(self, self.chapterId, taskId, status) | |
336 | 351 | end |
337 | 352 | else |
338 | 353 | if (status or -1) >= data.value1 then |
339 | 354 | status = -1 |
355 | + self.owner:log("adv_action", {desc = "finishAchiev", short1 = 1, int1 = self.chapterId, int2 = taskId}) | |
340 | 356 | end |
341 | 357 | if status and status ~= oldStatus then |
342 | - insertChange(self.chapterId, taskId, status) | |
358 | + insertChange(self, self.chapterId, taskId, status) | |
343 | 359 | if status == -1 then |
344 | - local ptcount = (self.owner:getProperty(achievField)[self.chapterId] or {})[-1] or 0 | |
360 | + local ptcount = advAchiev[-1] or 0 | |
345 | 361 | ptcount = ptcount + data.pt |
346 | - insertChange(self.chapterId, -1, ptcount) | |
362 | + insertChange(self, self.chapterId, -1, ptcount) | |
347 | 363 | end |
348 | 364 | end |
349 | 365 | end |
... | ... | @@ -361,10 +377,10 @@ function AdvTask.bind(Adv) |
361 | 377 | |
362 | 378 | local reward = {} |
363 | 379 | if status >= achievData.value1 then |
364 | - insertChange(chapterId, taskId, -1) | |
380 | + insertChange(self, chapterId, taskId, -1) | |
365 | 381 | local count = (self.owner:getProperty(achievField)[chapterId] or {})[-1] or 0 |
366 | 382 | count = count + achievData.pt |
367 | - insertChange(chapterId, -1, count) | |
383 | + insertChange(self, chapterId, -1, count) | |
368 | 384 | |
369 | 385 | -- 发放奖励 |
370 | 386 | reward = self.owner:award(achievData.reward, {log = {desc = "advAchiev", int1 = chapterId, int2 = taskId}}) |
... | ... | @@ -380,13 +396,14 @@ function AdvTask.bind(Adv) |
380 | 396 | if status == -1 or count < achievData.pt then return end |
381 | 397 | |
382 | 398 | local reward = self.owner:award(achievData.reward, {log = {desc = "advAchievReward", int1 = chapterId, int2 = taskId}}) |
383 | - insertChange(chapterId, taskId, -1, true) | |
399 | + insertChange(self, chapterId, taskId, -1, true) | |
384 | 400 | return true, reward |
385 | 401 | end |
386 | 402 | |
387 | 403 | function Adv:updateAchievement(notNotify) |
388 | 404 | if not next(advAchievChange) then return end |
389 | - self.owner:changeUpdates(advAchievChange, notNotify) | |
405 | + self.owner:changeMapUpdates(advAchievChange, notNotify) | |
406 | + advAchievChange = {} | |
390 | 407 | end |
391 | 408 | |
392 | 409 | end | ... | ... |
src/agent.lua
... | ... | @@ -8,14 +8,13 @@ require "skynet.manager" |
8 | 8 | local queue = require "skynet.queue" |
9 | 9 | local netpack = require "skynet.netpack" |
10 | 10 | local socket = require "skynet.socket" |
11 | -local sharedata = require "skynet.sharedata" | |
12 | 11 | local xxtea = require "xxtea" |
13 | 12 | |
14 | 13 | skynet = require "skynet" |
15 | 14 | redisproxy = require "shared.redisproxy" |
16 | 15 | datacenter = require "skynet.datacenter" |
17 | 16 | mcast_util = require "services/mcast_util" |
18 | -globalCsv = require "csvdata/GlobalDefine" | |
17 | +csvdb = require "shared.csvdata" | |
19 | 18 | |
20 | 19 | local CMD = {} |
21 | 20 | local agentInfo = {} -- { client_fd, role, gate_serv, open_timer} |
... | ... | @@ -217,7 +216,7 @@ skynet.register_protocol { |
217 | 216 | |
218 | 217 | skynet.register_protocol { |
219 | 218 | name = "role", |
220 | - id = 13, | |
219 | + id = 101, | |
221 | 220 | pack = skynet.pack, |
222 | 221 | unpack = skynet.unpack, |
223 | 222 | dispatch = function(session, address, submethod, ...) |
... | ... | @@ -326,20 +325,28 @@ skynet.start(function() |
326 | 325 | end |
327 | 326 | end) |
328 | 327 | |
329 | - redisd = skynet.localname(".REDIS") | |
328 | + skynet.info_func(function() | |
329 | + local info = {} | |
330 | + info.ip = agentInfo.ip | |
331 | + if agentInfo.role then | |
332 | + info.roldId = agentInfo.role:getProperty("id") | |
333 | + end | |
334 | + return info | |
335 | + end) | |
336 | + | |
337 | + redisd = skynet.localname(".redis") | |
330 | 338 | if tonumber(skynet.getenv "logd") == 1 then |
331 | - logd = skynet.localname(".LOGD") | |
339 | + logd = skynet.localname(".log") | |
332 | 340 | end |
333 | 341 | |
334 | 342 | cs = queue() |
335 | 343 | |
336 | - csvdb = sharedata.query("csvdata") | |
337 | - pvpd = skynet.localname(".PVPCROSS") | |
344 | + pvpd = skynet.localname(".pvpcross") | |
338 | 345 | -- 错误码特殊处理 |
339 | 346 | -- todo |
340 | 347 | -- for key, value in pairs(csvdb["sys_codesCsv"]) do |
341 | 348 | -- _G[string.upper(value.varname)] = key |
342 | 349 | -- end |
343 | - | |
350 | + globalCsv = csvdb["GlobalDefineCsv"] | |
344 | 351 | agent_util = require "services/agent_util" |
345 | 352 | end) | ... | ... |
src/models/Diner.lua
... | ... | @@ -28,7 +28,6 @@ function Diner:refreshDailyData(notify) |
28 | 28 | |
29 | 29 | -- 委托 |
30 | 30 | local entrust = self:getProperty("entrust") |
31 | - local hangPass = self.owner:getProperty("hangPass") | |
32 | 31 | local entrustB = self:getProperty("entrustB") |
33 | 32 | local had = {} |
34 | 33 | local pool = {} |
... | ... | @@ -41,11 +40,11 @@ function Diner:refreshDailyData(notify) |
41 | 40 | if data.show ~= "" then |
42 | 41 | -- 不填=默认刷出,1=达成前置任务,2=通关关卡 |
43 | 42 | local showC = data.show:toArray(true, "=") |
44 | - if showC[1] == 1 then | |
45 | - if not hangPass[showC[2]] then | |
43 | + if showC[1] == 2 then | |
44 | + if not self.owner:checkHangPass(showC[2]) then | |
46 | 45 | show = false |
47 | 46 | end |
48 | - elseif showC[1] == 2 then | |
47 | + elseif showC[1] == 1 then | |
49 | 48 | if not entrustB[showC[2]] then |
50 | 49 | show = false |
51 | 50 | end |
... | ... | @@ -70,6 +69,18 @@ function Diner:refreshDailyData(notify) |
70 | 69 | had[entrust[i]] = 1 |
71 | 70 | end |
72 | 71 | end |
72 | + | |
73 | + local guide = self.owner:getProperty("newerGuide") | |
74 | + local master, slave = string.match(guide,"(%d+)=(%d+)") | |
75 | + if tonumber(master) <= 26 then | |
76 | + entrust[1] = 1031 | |
77 | + entrust[2] = 3 | |
78 | + elseif tonumber(master) <= 29 then | |
79 | + local temp = entrust[1] | |
80 | + entrust[1] = 3 | |
81 | + entrust[2] = temp | |
82 | + end | |
83 | + | |
73 | 84 | self:updateProperty({field = "entrust", value = entrust, notNotify = not notify}) |
74 | 85 | |
75 | 86 | -- 每日加速次数 |
... | ... | @@ -301,9 +312,8 @@ end |
301 | 312 | function Diner:getMaxSlots() |
302 | 313 | local slotCount = globalCsv.diner_sell_slots_init |
303 | 314 | |
304 | - local hangPass = self.owner:getProperty("hangPass") | |
305 | 315 | for _, carbonId in ipairs(globalCsv.diner_sell_slots_unlock) do |
306 | - if hangPass[carbonId] then | |
316 | + if self.owner:checkHangPass(carbonId) then | |
307 | 317 | slotCount = slotCount + 1 |
308 | 318 | end |
309 | 319 | end | ... | ... |
src/models/HeroPlugin.lua
... | ... | @@ -18,6 +18,28 @@ function HeroPlugin.bind(Hero) |
18 | 18 | return math.min(#csvdb["unit_expCsv"], csvdb["unit_breakCsv"][self:getProperty("breakL")].levelLimit) |
19 | 19 | end |
20 | 20 | |
21 | + | |
22 | + -- 纯% 的属性 | |
23 | + local PercentAttr = { | |
24 | + crit = 6, -- 暴击 | |
25 | + critHurt = 8, -- 暴伤 | |
26 | + vampire = 9, -- 吸血 | |
27 | + pierce = 10, -- 穿透 | |
28 | + } | |
29 | + -- base 原, add 增加值 ,atype 增加类型(0 值 1%) | |
30 | + local function addAttr(base, add, atype, attrName) | |
31 | + base = base or 0 | |
32 | + add = add or 0 | |
33 | + if PercentAttr[attrName] then | |
34 | + atype = 0 | |
35 | + end | |
36 | + if atype == 1 then | |
37 | + return base * add / 100 | |
38 | + else | |
39 | + return add | |
40 | + end | |
41 | + end | |
42 | + | |
21 | 43 | --角色自身 = 初始 *(1+升级)*(1+突破)*(1+觉醒)+ 天赋升级 + 天赋阶段 |
22 | 44 | function Hero:getBaseAttrs(params) |
23 | 45 | params = params or {} |
... | ... | @@ -53,7 +75,7 @@ function HeroPlugin.bind(Hero) |
53 | 75 | |
54 | 76 | for _, attrName in pairs(AttsEnumEx) do |
55 | 77 | if talentAttrS[attrName] then |
56 | - talentAttrS[attrName] = (unitData[attrName] or 0) * talentAttrS[attrName] | |
78 | + talentAttrS[attrName] = addAttr(unitData[attrName], talentAttrS[attrName], 1, attrName) | |
57 | 79 | end |
58 | 80 | end |
59 | 81 | |
... | ... | @@ -66,16 +88,16 @@ function HeroPlugin.bind(Hero) |
66 | 88 | local blData = csvdb["unit_breakCsv"][breakL] |
67 | 89 | local wData = csvdb["unit_wakeCsv"][wakeL] |
68 | 90 | for attr, value in pairs(attrs) do |
69 | - attrs[attr] = attrs[attr] * (1 + (lData[attr .. "Level"] or 0) / 100) | |
70 | - * (1 + (blData[attr .. "Level"] or 0) / 100) | |
71 | - * (1 + (wData[attr .. "Level"] or 0) / 100) + (talentAttrS[attr] or 0) | |
91 | + attrs[attr] = attrs[attr] + addAttr(attrs[attr], lData[attr .. "Level"], 1, attr) | |
92 | + attrs[attr] = attrs[attr] + addAttr(attrs[attr], blData[attr .. "Level"], 1, attr) | |
93 | + attrs[attr] = attrs[attr] + addAttr(attrs[attr], wData[attr .. "Level"], 1, attr) + (talentAttrS[attr] or 0) | |
72 | 94 | end |
73 | 95 | |
74 | 96 | return attrs |
75 | 97 | end |
76 | 98 | |
77 | 99 | |
78 | - --当前属性 = [ 角色属性值 + 基础装备(固定)+ 专属装备(固定)] * [ 1 + 基础装备(百分比) + 专属装备(百分比)] | |
100 | + --当前属性 = 角色属性值 * (1 + 装备套装(百分比) + 铭文套装(百分比))+ (装备(固定)+ 铭文(固定)) | |
79 | 101 | function Hero:getTotalAttrs(params) |
80 | 102 | params = params or {} |
81 | 103 | local attrs = self:getBaseAttrs() |
... | ... | @@ -83,13 +105,15 @@ function HeroPlugin.bind(Hero) |
83 | 105 | local equipAttrs = self:getRuneEquipAttrs() |
84 | 106 | |
85 | 107 | for _, attName in pairs(AttsEnumEx) do |
86 | - attrs[attName] = ((attrs[attName] or 0) + equipAttrs.value[attName]) * (1 + equipAttrs.percent[attName] / 100) | |
108 | + attrs[attName] = attrs[attName] or 0 | |
109 | + attrs[attName] = attrs[attName] + addAttr(attrs[attName], equipAttrs.percent[attName], 1, attName) | |
110 | + attrs[attName] = attrs[attName] + addAttr(attrs[attName], equipAttrs.value[attName], 0, attName) | |
87 | 111 | end |
88 | 112 | |
89 | 113 | -- 羁绊加成 |
90 | 114 | if params.activeRelation then |
91 | - for k, v in pairs(AttsEnumEx) do | |
92 | - attrs[v] = (attrs[v] or 0) * (1 + (params.activeRelation[v] or 0) / 100) | |
115 | + for k, attName in pairs(AttsEnumEx) do | |
116 | + attrs[attName] = attrs[attName] + addAttr(attrs[attName], params.activeRelation[attName], 1, attName) | |
93 | 117 | end |
94 | 118 | end |
95 | 119 | return attrs |
... | ... | @@ -137,20 +161,32 @@ function HeroPlugin.bind(Hero) |
137 | 161 | end |
138 | 162 | end |
139 | 163 | -- 零件效果 |
140 | - local suits = {} | |
141 | - for _, uid in pairs(self:getProperty("rune"):toNumMap()) do | |
142 | - if uid > 0 then | |
143 | - local rune = self.owner.runeBag[uid] | |
144 | - local buildData = csvdb["rune_buildCsv"][rune:getProperty("level")] | |
145 | - for k,v in pairs(rune:getProperty("attrs"):toNumMap()) do | |
146 | - attrs.value[AttsEnumEx[k]] = attrs.value[AttsEnumEx[k]] + (v / 10 * (1 + buildData.effect/100)) -- 零件的加成属性有特殊需求 填的是 10倍的值 | |
147 | - | |
148 | - end | |
149 | - local csvData = csvdb["runeCsv"][rune:getProperty("type")][rune:getProperty("id")] | |
150 | - if not suits[csvData.suit] then suits[csvData.suit] = {} end | |
151 | - table.insert(suits[csvData.suit],csvData) | |
152 | - end | |
153 | - end | |
164 | + local suits = {} | |
165 | + for _, uid in pairs(self:getProperty("rune"):toNumMap()) do | |
166 | + if uid > 0 then | |
167 | + local rune = self.owner.runeBag[uid] | |
168 | + local csvData = csvdb["runeCsv"][rune:getProperty("type")][rune:getProperty("id")] | |
169 | + local runeRareData = csvdb["rune_rareCsv"][csvData.rarity] | |
170 | + local buildData = csvdb["rune_buildCsv"][rune:getProperty("level")] | |
171 | + for k, v in pairs(rune:getProperty("attrs"):toNumMap()) do | |
172 | + local attName = AttsEnumEx[k] | |
173 | + --零件的加成属性有特殊需求 填的是 10倍的值 | |
174 | + --rare的effect不影响 特殊属性 | |
175 | + | |
176 | + --铭文单件普通属性=attr*(1+[rune_build表effect]/100*[rune_rare表effect]/100) | |
177 | + --铭文单件特殊属性=attr+[rune_build表effect] | |
178 | + | |
179 | + local effect = buildData[attName] | |
180 | + if not PercentAttr[attName] then | |
181 | + effect = buildData[attName] * runeRareData.effect / 100 | |
182 | + end | |
183 | + attrs.value[attName] = attrs.value[attName] + (v / 100) + addAttr(v / 100, effect, 1, attName) | |
184 | + end | |
185 | + | |
186 | + if not suits[csvData.suit] then suits[csvData.suit] = {} end | |
187 | + table.insert(suits[csvData.suit],csvData) | |
188 | + end | |
189 | + end | |
154 | 190 | -- 零件套装效果 |
155 | 191 | for suitId,runeDatas in pairs(suits) do |
156 | 192 | local suitCsv = csvdb["rune_suitCsv"][tonumber(suitId)] |
... | ... | @@ -214,6 +250,52 @@ function HeroPlugin.bind(Hero) |
214 | 250 | end |
215 | 251 | return {} |
216 | 252 | end |
253 | + | |
254 | + function Hero:getRunes() | |
255 | + local rune = self:getProperty("rune") | |
256 | + if not rune or rune == "" then | |
257 | + rune = "1=0 2=0 3=0 4=0 5=0 6=0" | |
258 | + end | |
259 | + local result = rune:toNumMap() | |
260 | + for i = 1, 6 do | |
261 | + if not result[i] then | |
262 | + result[i] = 0 | |
263 | + end | |
264 | + end | |
265 | + return result | |
266 | + end | |
267 | + | |
268 | + -- 101 冒险战斗被动技 | |
269 | + -- 102 挂机战斗被动技 | |
270 | + function Hero:getRuneSkill(skillType) | |
271 | + local suits = {} | |
272 | + for _,uid in pairs(self:getRunes()) do | |
273 | + if uid > 0 then | |
274 | + local runeData = self.owner.runeBag[uid] | |
275 | + if not runeData then return end | |
276 | + local csvData = csvdb["runeCsv"][runeData:getProperty("type")][runeData:getProperty("id")] | |
277 | + if not suits[csvData.suit] then suits[csvData.suit] = {} end | |
278 | + table.insert(suits[csvData.suit],csvData) | |
279 | + end | |
280 | + end | |
281 | + | |
282 | + for suitId,runes in pairs(suits) do | |
283 | + local suitCsv = csvdb["rune_suitCsv"][tonumber(suitId)] | |
284 | + if not suitCsv then return end | |
285 | + local effects = suitCsv.effect:toTableArray(true) | |
286 | + local count = #runes | |
287 | + if count >= 2 and effects[1][1] == skillType then | |
288 | + return effects[1][2] | |
289 | + end | |
290 | + if count >= 4 and effects[2][1] == skillType then | |
291 | + return effects[2][2] | |
292 | + end | |
293 | + if count >= 6 and effects[3][1] == skillType then | |
294 | + return effects[3][2] | |
295 | + end | |
296 | + end | |
297 | + return | |
298 | + end | |
217 | 299 | end |
218 | 300 | |
219 | 301 | ... | ... |
src/models/Role.lua
... | ... | @@ -4,7 +4,6 @@ local RoleLog = import(".RoleLog") --日志相关 |
4 | 4 | local RolePlugin = import(".RolePlugin") --基础功能 |
5 | 5 | local RoleTimeReset = import(".RoleTimeReset") --时间重置相关 |
6 | 6 | local RoleTask = import(".RoleTask") --角色任务 |
7 | -local RoleActivity = import(".RoleActivity") --活动相关 | |
8 | 7 | local RoleChangeStruct = import(".RoleChangeStruct") --角色数据额结构更改 |
9 | 8 | local RolePvp = import(".RolePvp") -- pvp |
10 | 9 | local RoleCross = import(".RoleCross") -- 跨服务请求相关 |
... | ... | @@ -13,7 +12,6 @@ RoleLog.bind(Role) |
13 | 12 | RolePlugin.bind(Role) |
14 | 13 | RoleTimeReset.bind(Role) |
15 | 14 | RoleTask.bind(Role) |
16 | -RoleActivity.bind(Role) | |
17 | 15 | RoleChangeStruct.bind(Role) |
18 | 16 | RolePvp.bind(Role) |
19 | 17 | RoleCross.bind(Role) |
... | ... | @@ -88,6 +86,7 @@ Role.schema = { |
88 | 86 | |
89 | 87 | --挂机相关 |
90 | 88 | hangPass = {"table", {}}, -- 挂机通过的最大关卡 |
89 | + hangGift = {"table", {}}, -- 挂机奖励 {id = 1} | |
91 | 90 | hangTeam = {"table", {}}, -- 挂机队伍 |
92 | 91 | hangTS = {"table", {}}, -- 挂机队伍他人可读的队伍信息 |
93 | 92 | hangTB = {"table", {}}, -- 挂机队伍他人可用的战斗信息mao |
... | ... | @@ -144,8 +143,13 @@ Role.schema = { |
144 | 143 | |
145 | 144 | emailSync = {"number", 0}, -- 已经同步到的邮件Id |
146 | 145 | |
147 | - repayHero = {"number", 0}, -- 超级招募 回馈 | |
146 | + -- repayHero = {"number", 0}, -- 超级招募 回馈 | |
148 | 147 | floorHero = {"table", {}}, -- 招募保底 -- {[poolId] = count} |
148 | + ssrUp = {"table", {}}, -- ssr up -- {[poolId] = count} | |
149 | + newerDraw = {"table", {}}, -- 新手池子 {N, 1} 抽了多少次, 是否出了ssr | |
150 | + | |
151 | + sudoku = {"table", {}}, -- 九宫格 {[-1] = 1, task = {[1] = {}, [2] = {}}}} -- [-1] 阶段 如果为 -1 关闭(都做完了), task 当前阶段任务进度, reward 连串奖励领取情况 | |
152 | + sign = {"table", {}}, -- 签到记录 {[1] = 20181029} | |
149 | 153 | } |
150 | 154 | |
151 | 155 | |
... | ... | @@ -192,8 +196,39 @@ function Role:notifyUpdateProperties(params) |
192 | 196 | SendPacket(actionCodes.Role_updateProperties, MsgPack.pack(params)) |
193 | 197 | end |
194 | 198 | |
199 | +local mapToList | |
200 | +mapToList = function(map) | |
201 | + local result = {} | |
202 | + if type(map) == "table" then | |
203 | + for k, v in pairs(map) do | |
204 | + for _, _one in ipairs(mapToList(v)) do | |
205 | + table.insert(result, {k, table.unpack(_one)}) | |
206 | + end | |
207 | + end | |
208 | + else | |
209 | + table.insert(result, {map}) | |
210 | + end | |
211 | + return result | |
212 | +end | |
213 | + | |
214 | +function Role:changeMapUpdates(params, notNotify) | |
215 | + local changes = {} | |
216 | + for _, one in ipairs(mapToList(params)) do | |
217 | + local ftype = table.remove(one, 1) | |
218 | + local value = table.remove(one, #one) | |
219 | + if ftype and value and #one > 0 then | |
220 | + table.insert(changes, {type = ftype, field = #one > 1 and one or one[1], value = value}) | |
221 | + else | |
222 | + print("ERROR: changeMapUpdates") | |
223 | + dump(params) | |
224 | + end | |
225 | + end | |
226 | + self:changeUpdates(changes, notNotify) | |
227 | +end | |
228 | + | |
195 | 229 | -- 某些字段 更新改变量 改变量的定义由字段自身决定 {{type = ""}, } |
196 | 230 | function Role:changeUpdates(params, notNotify) |
231 | + local needSetProperty = {} | |
197 | 232 | local changeUpdateFunc = { |
198 | 233 | -- ["loveStatus"] = function(info) |
199 | 234 | -- self:setProperty("loveStatus", self:getProperty("loveStatus"):setv(info["field"], info["value"])) |
... | ... | @@ -219,7 +254,7 @@ function Role:changeUpdates(params, notNotify) |
219 | 254 | else |
220 | 255 | curValue[info["field"]] = info["value"] |
221 | 256 | end |
222 | - self:setProperty(fieldType) | |
257 | + needSetProperty[fieldType] = 1 | |
223 | 258 | return {type = fieldType, field = info["field"], value = info["value"]} |
224 | 259 | end, |
225 | 260 | ["onlyToC"] = function(info) |
... | ... | @@ -238,6 +273,10 @@ function Role:changeUpdates(params, notNotify) |
238 | 273 | table.insert(updates, changeUpdateFunc["tableCommon"](one["type"], one)) |
239 | 274 | end |
240 | 275 | end |
276 | + | |
277 | + for fieldType, _ in pairs(needSetProperty) do | |
278 | + self:setProperty(fieldType) | |
279 | + end | |
241 | 280 | if not notNotify and next(updates) then |
242 | 281 | SendPacket(actionCodes.Role_changeUpdate, MsgPack.pack(updates)) |
243 | 282 | end |
... | ... | @@ -283,6 +322,7 @@ function Role:data() |
283 | 322 | advSup = self:getProperty("advSup"), |
284 | 323 | |
285 | 324 | hangPass = self:getProperty("hangPass"), |
325 | + hangGift = self:getProperty("hangGift"), | |
286 | 326 | hangTeam = self:getProperty("hangTeam"), |
287 | 327 | hangInfo = self:getProperty("hangInfo"), |
288 | 328 | hangBag = self:getProperty("hangBag"), |
... | ... | @@ -314,8 +354,11 @@ function Role:data() |
314 | 354 | dinerS = self:getProperty("dinerS"), |
315 | 355 | |
316 | 356 | rmbC = self:getProperty("rmbC"), |
317 | - repayHero = self:getProperty("repayHero"), | |
318 | - floorHero = self:getProperty("floorHero"), | |
357 | + -- repayHero = self:getProperty("repayHero"), | |
358 | + newerDraw = self:getProperty("newerDraw"), | |
359 | + | |
360 | + sudoku = self:getProperty("sudoku"), | |
361 | + sign = self:getProperty("sign"), | |
319 | 362 | } |
320 | 363 | end |
321 | 364 | ... | ... |
src/models/RoleActivity.lua
1 | +local Activity = class("Activity", require("shared.ModelBase")) | |
1 | 2 | |
2 | 3 | |
3 | -local RoleActivity = {} | |
4 | +Activity.ActivityType = { | |
4 | 5 | |
5 | -function RoleActivity.bind(Role) | |
6 | +} | |
6 | 7 | |
8 | +local function checkActivityType(activityType) | |
9 | + if type(activityType) == "string" then | |
10 | + activityType = Activity.ActivityType[activityType] | |
11 | + end | |
12 | + return activityType | |
13 | +end | |
14 | + | |
15 | + | |
16 | +function Activity:ctor(properties) | |
17 | + Activity.super.ctor(self, properties) | |
18 | + | |
19 | + self.open = {} | |
20 | + | |
21 | +end | |
7 | 22 | |
8 | 23 | |
24 | +Activity.schema = { | |
25 | + _1 = {"table", {}}, | |
26 | +} | |
9 | 27 | |
28 | +function Activity:data() | |
29 | + return { | |
30 | + _1 = self:getProperty("_1"), | |
31 | + } | |
10 | 32 | end |
11 | 33 | |
12 | -return RoleActivity | |
13 | 34 | \ No newline at end of file |
35 | + | |
36 | + | |
37 | +return Activity | |
14 | 38 | \ No newline at end of file | ... | ... |
src/models/RoleCross.lua
... | ... | @@ -144,19 +144,17 @@ RoleCross.bind = function (Role) |
144 | 144 | |
145 | 145 | -- fb |
146 | 146 | local carbonId = initData.fb |
147 | - local passCarbon = self:getProperty("hangPass") | |
148 | 147 | local addPre |
149 | 148 | addPre = function(carbonId) |
150 | 149 | local carbonData = csvdb["idle_battleCsv"][carbonId] |
151 | 150 | for _, pre in ipairs(carbonData.prepose:toArray(true, "=")) do |
152 | - passCarbon[pre] = 1 | |
151 | + self:checkHangPass(pre) | |
153 | 152 | self:checkTaskEnter("HangPass", {id = pre}) |
154 | 153 | addPre(pre) |
155 | 154 | end |
156 | 155 | end |
157 | - passCarbon[carbonId] = 1 | |
156 | + self:checkHangPass(carbonId) | |
158 | 157 | addPre(carbonId) |
159 | - self:updateProperty({field = "hangPass", value = passCarbon}) | |
160 | 158 | self:checkTaskEnter("HangPass", {id = carbonId}) |
161 | 159 | |
162 | 160 | -- talent | ... | ... |
src/models/RoleLog.lua
src/models/RolePlugin.lua
... | ... | @@ -401,10 +401,18 @@ function RolePlugin.bind(Role) |
401 | 401 | |
402 | 402 | redisproxy:sadd(string.format(R_HEROS, roleId), heroId) |
403 | 403 | |
404 | + local wakeL = 1 | |
405 | + if unitData.rare == 3 then | |
406 | + wakeL = 2 | |
407 | + elseif unitData.rare == 4 then | |
408 | + wakeL = 3 | |
409 | + end | |
410 | + | |
404 | 411 | local heroInfo = { |
405 | 412 | key = string.format(R_HERO, roleId, heroId), |
406 | 413 | id = heroId, |
407 | 414 | type= heroType, |
415 | + wakeL = wakeL, | |
408 | 416 | } |
409 | 417 | |
410 | 418 | local newHero = require("models.Hero").new(heroInfo) |
... | ... | @@ -837,8 +845,7 @@ function RolePlugin.bind(Role) |
837 | 845 | local data = csvdb["guide_unlockCsv"][func] |
838 | 846 | if not data then return true end -- 没有就是解锁了 |
839 | 847 | |
840 | - local hangPass = self:getProperty("hangPass") | |
841 | - if hangPass[data.carbonId] then | |
848 | + if self:checkHangPass(data.carbonId) then | |
842 | 849 | return true |
843 | 850 | else |
844 | 851 | return false |
... | ... | @@ -916,25 +923,10 @@ function RolePlugin.bind(Role) |
916 | 923 | end |
917 | 924 | end |
918 | 925 | |
919 | - function Role:advChapterIsOpen(chapterId, layer) | |
920 | - layer = layer or 1 | |
921 | - local exlayer = math.floor((layer - 1) / 10) * 10 + 1 | |
922 | - | |
923 | - if exlayer == 1 then --第一层判断前置 | |
924 | - local advPass = self:getProperty("advPass") | |
925 | - local chapterData = csvdb["adv_chapterCsv"][chapterId] | |
926 | - for id, l in pairs(chapterData.prepose:toNumMap()) do | |
927 | - if (advPass[id] or 0) < l then return false end -- 前置 | |
928 | - end | |
929 | - return true | |
930 | - end | |
931 | - | |
932 | - local unlock = {} | |
933 | - for func , data in pairs(csvdb["unlockCsv"]) do | |
934 | - if data.type == 1 and chapterId == data.value1 and exlayer == data.value2 then | |
935 | - return self:isFuncOpen(func) | |
936 | - end | |
937 | - end | |
926 | + function Role:advChapterIsOpen(chapterId) | |
927 | + local chapterData = csvdb["adv_chapterCsv"][chapterId] | |
928 | + if chapterData.prepose ~= 0 and not self:checkHangPass(chapterData.prepose) then return false end | |
929 | + return true | |
938 | 930 | end |
939 | 931 | |
940 | 932 | function Role:advEventOpenStatus() |
... | ... | @@ -995,7 +987,7 @@ function RolePlugin.bind(Role) |
995 | 987 | for id, status in pairs(advEAchiev[self.advElChapter] or {}) do |
996 | 988 | if status == -1 then |
997 | 989 | local achvData = csvdb["adv_achievementCsv"][id] |
998 | - if achvData.support ~= 0 then | |
990 | + if achvData and achvData.support ~= 0 then | |
999 | 991 | effect[achvData.support] = 1 |
1000 | 992 | end |
1001 | 993 | end |
... | ... | @@ -1198,8 +1190,10 @@ function RolePlugin.bind(Role) |
1198 | 1190 | end |
1199 | 1191 | info.type = hero:getProperty("type") |
1200 | 1192 | info.level = hero:getProperty("level") |
1193 | + info.wakeL = hero:getProperty("wakeL") | |
1201 | 1194 | info.blockLevel = hero:getSkillLevel(4) |
1202 | 1195 | info.specialLevel = hero:getSkillLevel(1) |
1196 | + info.runeSkill = hero:getRuneSkill(102) | |
1203 | 1197 | teamInfo.heros[slot] = info |
1204 | 1198 | end |
1205 | 1199 | for slot, id in pairs(team.supports or {}) do |
... | ... | @@ -1267,9 +1261,11 @@ function RolePlugin.bind(Role) |
1267 | 1261 | |
1268 | 1262 | local pvpTSH, pvpTBH, pvpTBVH = {}, {}, {} |
1269 | 1263 | for i = 1, 3 do |
1270 | - pvpTSH[i] = self:getTeamHerosInfo(team[i].heros) | |
1271 | - pvpTBH[i] = self:getTeamBattleInfo(team[i]) | |
1272 | - pvpTBVH[i] = self:getTeamBattleValue(team[i].heros) | |
1264 | + if team[i] then | |
1265 | + pvpTSH[i] = self:getTeamHerosInfo(team[i].heros) | |
1266 | + pvpTBH[i] = self:getTeamBattleInfo(team[i]) | |
1267 | + pvpTBVH[i] = self:getTeamBattleValue(team[i].heros) | |
1268 | + end | |
1273 | 1269 | end |
1274 | 1270 | |
1275 | 1271 | self:setProperties({ |
... | ... | @@ -1363,6 +1359,21 @@ function RolePlugin.bind(Role) |
1363 | 1359 | end |
1364 | 1360 | end |
1365 | 1361 | |
1362 | + function Role:checkHangPass(carbonId) | |
1363 | + local hangPass = self:getProperty("hangPass") | |
1364 | + local diff = math.floor(carbonId / 10000) | |
1365 | + return (hangPass[diff] or 0) >= carbonId | |
1366 | + end | |
1367 | + | |
1368 | + function Role:hangFinish(carbonId) | |
1369 | + local hangPass = self:getProperty("hangPass") | |
1370 | + local diff = math.floor(carbonId / 10000) | |
1371 | + if (hangPass[diff] or 0) < carbonId then | |
1372 | + hangPass[diff] = carbonId | |
1373 | + self:updateProperty({field = "hangPass", value = hangPass}) | |
1374 | + end | |
1375 | + end | |
1376 | + | |
1366 | 1377 | function Role:getAdvRankKey() |
1367 | 1378 | local round = self:getProperty("advElS") |
1368 | 1379 | local idx = 1 | ... | ... |
src/models/RoleTask.lua
... | ... | @@ -59,11 +59,12 @@ local TaskType = { |
59 | 59 | FoodSellGold = 607, -- 贩卖获得齿轮 - count |
60 | 60 | DinerPopular = 608, -- 人气值 - count |
61 | 61 | DinerLevelUp = 609, -- 餐厅升级 - level type |
62 | - DinerTalentUp = 610, -- 天赋升级 - type | |
62 | + DinerTalentUp = 610, -- 天赋升级 - type level | |
63 | 63 | |
64 | 64 | -- 车厢相关 |
65 | 65 | PotionMake = 701, -- 营养剂制作 - id count |
66 | 66 | OpenBox = 702, -- 拆解时间箱 - id |
67 | + SupportSkill = 703, -- 后勤支援技升级 - id level | |
67 | 68 | |
68 | 69 | |
69 | 70 | -- pvp相关 |
... | ... | @@ -87,8 +88,8 @@ local TaskType = { |
87 | 88 | ShopAll = 1013, -- 在任意商店购买 |
88 | 89 | } |
89 | 90 | |
90 | -local function f(field) | |
91 | - return {type = "field", value = field} | |
91 | +local function f(field, func) | |
92 | + return {type = "field", value = field, func = func} | |
92 | 93 | end |
93 | 94 | |
94 | 95 | -- 剧情任务监听 |
... | ... | @@ -183,11 +184,33 @@ local AchievListener = { |
183 | 184 | } |
184 | 185 | } |
185 | 186 | |
187 | +local SudokuListerer = { | |
188 | + func = "checkSudokuTask", | |
189 | + listen = { | |
190 | + [TaskType.HangPass] = {{1, 1, f("id")}}, | |
191 | + [TaskType.DrawHero] = {{4, f("count")}}, | |
192 | + [TaskType.HeroLevelUp] = {{5, f("level")}}, | |
193 | + [TaskType.Wake] = {{6, f("wakeL")}}, | |
194 | + [TaskType.AddFriend] = {{7, f("count")}}, | |
195 | + [TaskType.GetFriendP] = {{8, f("count")}}, | |
196 | + [TaskType.AdvStart] = {{9, 1}}, | |
197 | + [TaskType.AdvDraw] = {{10, f("count")}}, | |
198 | + [TaskType.DinerLevelUp] = {{11, f("level"), f("type")}}, | |
199 | + [TaskType.FoodSell] = {{12, f("count")}}, | |
200 | + [TaskType.OpenBox] = {{13, 1}}, | |
201 | + [TaskType.TowerPass] = {{14, f("level")}}, | |
202 | + [TaskType.PvpWin] = {{15, 1}}, | |
203 | + [TaskType.DinerTalentUp] = {{16, f("level"), f("type")}}, | |
204 | + [TaskType.RuneUp] = {{17, 1}}, | |
205 | + } | |
206 | +} | |
207 | + | |
186 | 208 | |
187 | 209 | local TaskListeners = { |
188 | 210 | StoryListener, |
189 | 211 | CommonListener, |
190 | 212 | AchievListener, |
213 | + SudokuListerer, | |
191 | 214 | } |
192 | 215 | |
193 | 216 | local RoleTask = {} |
... | ... | @@ -207,7 +230,11 @@ function RoleTask.bind(Role) |
207 | 230 | for __, v in ipairs(vs) do |
208 | 231 | if type(v) == "table" and v.type then |
209 | 232 | if v.type == "field" then |
210 | - table.insert(pms, params[v.value]) | |
233 | + local value = params[v.value] | |
234 | + if v.func then | |
235 | + value = v.func(value) | |
236 | + end | |
237 | + table.insert(pms, value) | |
211 | 238 | else |
212 | 239 | table.insert(pms, v) |
213 | 240 | end |
... | ... | @@ -442,6 +469,54 @@ function RoleTask.bind(Role) |
442 | 469 | end |
443 | 470 | end |
444 | 471 | |
472 | + -- 九宫格任务 | |
473 | + function Role:checkSudokuTask(notNotify, stype, count, cond) | |
474 | + local change = false | |
475 | + local sudoku = self:getProperty("sudoku") | |
476 | + | |
477 | + local curPhase = sudoku[-1] or 1 | |
478 | + if curPhase == -1 then return end | |
479 | + | |
480 | + local IsFindMax = { | |
481 | + [5] = true, | |
482 | + [6] = true, | |
483 | + [7] = true, | |
484 | + [11] = true, | |
485 | + [14] = true, | |
486 | + [16] = true, | |
487 | + } | |
488 | + | |
489 | + sudoku.task = sudoku.task or {} | |
490 | + for pause, guide_sudokuData in pairs(csvdb["guide_sudokuCsv"]) do | |
491 | + if pause >= curPhase then | |
492 | + sudoku.task[pause] = sudoku.task[pause] or {} | |
493 | + for id , sudikuData in pairs(guide_sudokuData) do | |
494 | + local curStatus = sudoku.task[pause][id] or 0 | |
495 | + | |
496 | + if curStatus ~= -1 and sudikuData.type == stype and (sudikuData.unlock == 0 or self:checkHangPass(sudikuData.unlock)) then | |
497 | + if IsFindMax[sudikuData.type] then -- 最大值 | |
498 | + if sudikuData.con2 == 0 or sudikuData.con2 == cond then | |
499 | + if (count or 0) > curStatus then | |
500 | + change = true | |
501 | + sudoku.task[pause][id] = count | |
502 | + end | |
503 | + end | |
504 | + else --通用增加 | |
505 | + if sudikuData.con2 == 0 or sudikuData.con2 == cond then | |
506 | + change = true | |
507 | + sudoku.task[pause][id] = curStatus + (count or 1) | |
508 | + end | |
509 | + end | |
510 | + end | |
511 | + end | |
512 | + end | |
513 | + end | |
514 | + | |
515 | + if change then | |
516 | + self:updateProperty({field = "sudoku", value = sudoku, notNotify = notNotify}) | |
517 | + end | |
518 | + end | |
519 | + | |
445 | 520 | end |
446 | 521 | |
447 | 522 | return RoleTask |
448 | 523 | \ No newline at end of file | ... | ... |
src/models/Rune.lua
... | ... | @@ -63,14 +63,16 @@ end |
63 | 63 | |
64 | 64 | -- types 类型=权重"2=100 3=100 4=100" value最大值=最小值 "50=100 50=100 100=200" |
65 | 65 | local function getRandomValue(types,values) |
66 | - local typeMap = types:toNumMap() | |
66 | + local typeMap = types:toArray() | |
67 | 67 | local valueArry = values:toArray() |
68 | 68 | |
69 | - if table.nums(typeMap) ~= #valueArry then return nil end | |
69 | + if #typeMap ~= #valueArry then return nil end | |
70 | + | |
70 | 71 | local typ, value |
71 | 72 | local typTab = {} |
72 | - for t,w in pairs(typeMap) do | |
73 | - table.insert(typTab,{t=t,w=w}) | |
73 | + for _,w in ipairs(typeMap) do | |
74 | + w = w:toArray(true, "=") | |
75 | + table.insert(typTab,{t=w[1],w=w[2]}) | |
74 | 76 | end |
75 | 77 | |
76 | 78 | local tk = math.randWeight(typTab, "w") |
... | ... | @@ -89,7 +91,7 @@ function Rune:generateAttrs() |
89 | 91 | local attrs = "" |
90 | 92 | local typ, value = getRandomValue(runeData.attr1,runeData.range1) |
91 | 93 | attrs = attrs:setv(typ, value) |
92 | - local typ, value = getRandomValue(runeData.attr1,runeData.range1) | |
94 | + local typ, value = getRandomValue(runeData.attr2,runeData.range2) | |
93 | 95 | attrs = attrs:setv(typ, value) |
94 | 96 | self:setProperty("attrs",attrs) |
95 | 97 | end | ... | ... |
src/services/agent_ctrl.lua
src/services/chated.lua
... | ... | @@ -35,12 +35,13 @@ if mode == "sub" then |
35 | 35 | skynet.ret(skynet.pack(f(...))) |
36 | 36 | end) |
37 | 37 | |
38 | - skynet.register(string.format(".CHATED%d", id)) | |
38 | + skynet.register(string.format(".chated%d", id)) | |
39 | 39 | end) |
40 | 40 | else |
41 | 41 | skynet.start(function() |
42 | - local ok, forbidNames = pcall(require, "csvdata.forbid_chat") | |
43 | - if not ok then forbidNames = {} end | |
42 | + local csvdb = require "shared.csvdata" | |
43 | + local forbidNames = csvdb["forbid_chatCsv"] | |
44 | + if not forbidNames then forbidNames = {} end | |
44 | 45 | |
45 | 46 | local words = {} |
46 | 47 | for _, data in ipairs(forbidNames) do |
... | ... | @@ -52,5 +53,6 @@ else |
52 | 53 | for i = 1, 5 do |
53 | 54 | skynet.newservice(SERVICE_NAME, "sub", i, d) |
54 | 55 | end |
56 | + skynet.exit() | |
55 | 57 | end) |
56 | 58 | end | ... | ... |
src/services/csvdatad.lua deleted
... | ... | @@ -1,115 +0,0 @@ |
1 | -local sharedata = require "skynet.sharedata" | |
2 | -local skynet = require "skynet" | |
3 | -local lfs = require "lfs" | |
4 | -local redisproxy = require "shared.redisproxy" | |
5 | -require "shared.init" | |
6 | -require "utils.init" | |
7 | -require "csvdata.init" | |
8 | -require "skynet.manager" | |
9 | -require "RedisKeys" | |
10 | - | |
11 | --- local csvdb = {} | |
12 | - | |
13 | -local function formatFileName(filename) | |
14 | - filename = string.trim(filename) | |
15 | - local basename = filename:match("([^/]+)%.lua$") | |
16 | - if not basename then return end | |
17 | - local loadname = filename:match("^src/([^.]+)%.lua$") | |
18 | - loadname = loadname:gsub('/', '.') | |
19 | - return basename, loadname | |
20 | -end | |
21 | - | |
22 | -local function travCsv(rootPath, pathes) | |
23 | - pathes = pathes or {} | |
24 | - local modified = false | |
25 | - local ok, files, iter = pcall(lfs.dir, rootPath) | |
26 | - if not ok then return modified end | |
27 | - for entry in files, iter do | |
28 | - -- 过滤 . 开始的字符串包括 . .. .git .开头的文件名 | |
29 | - if string.byte(entry, 1) ~= 46 then | |
30 | - local pathfile = rootPath .. '/' .. entry | |
31 | - local attrs = lfs.attributes(pathfile) | |
32 | - if attrs.mode == 'directory' then | |
33 | - modified = travCsv(pathfile, pathes) or modified | |
34 | - else | |
35 | - local basename, loadname = formatFileName(pathfile) | |
36 | - if basename then | |
37 | - if tonum(pathes[loadname]) < attrs.modification then | |
38 | - modified = true | |
39 | - pathes[loadname] = attrs.modification | |
40 | - end | |
41 | - if basename == "init" or basename == "init_adv" then | |
42 | - require(loadname) | |
43 | - end | |
44 | - end | |
45 | - end | |
46 | - end | |
47 | - end | |
48 | - return modified | |
49 | -end | |
50 | - | |
51 | --- 每分钟检查是否有更改 | |
52 | -local file2timeMap = {} | |
53 | -local function handle_timeout() | |
54 | - if travCsv("src/csvdata", file2timeMap) then | |
55 | - sharedata.update("csvdata", csvdb) | |
56 | - end | |
57 | - skynet.timeout(100*5, handle_timeout) | |
58 | -end | |
59 | - | |
60 | --- 重新加载csvdb | |
61 | - | |
62 | - | |
63 | -local CMD = {} | |
64 | - | |
65 | -function CMD.reload(code) | |
66 | - csvdb = csvdb or {} | |
67 | - | |
68 | - local ok, func = pcall(load, code) | |
69 | - if ok then | |
70 | - ok = pcall(func) | |
71 | - end | |
72 | - if not ok then | |
73 | - skynet.error("reload_csvdata error by code " .. code) | |
74 | - return 'error' | |
75 | - end | |
76 | - | |
77 | - sharedata.update("csvdata", csvdb) | |
78 | - return 'ok' | |
79 | -end | |
80 | - | |
81 | ---更新已经存在的 | |
82 | -function CMD.hotfix(fieldss) | |
83 | - csvdb = csvdb or {} | |
84 | - for _, fields in ipairs(fieldss) do | |
85 | - if #fields >= 3 and (type(fields[#fields]) == 'number' or type(fields[#fields]) == 'string') then | |
86 | - local temp = csvdb | |
87 | - local ok = false | |
88 | - for i = 1, #fields - 1 do | |
89 | - if type(temp) ~= 'table' then break end | |
90 | - if type(fields[i]) ~= 'number' and type(fields[i]) ~= 'string' then break end | |
91 | - if i == #fields - 1 then | |
92 | - if type(temp[fields[i]]) ~= 'number' and type(temp[fields[i]]) ~= 'string' then break end | |
93 | - temp[fields[i]] = fields[#fields] | |
94 | - else | |
95 | - temp = temp[fields[i]] | |
96 | - end | |
97 | - end | |
98 | - end | |
99 | - end | |
100 | - sharedata.update("csvdata", csvdb) | |
101 | - return 'ok' | |
102 | -end | |
103 | - | |
104 | -skynet.start(function () | |
105 | - travCsv("src/csvdata", file2timeMap) | |
106 | - sharedata.new("csvdata", csvdb) | |
107 | - -- handle_timeout() | |
108 | - | |
109 | - skynet.dispatch("lua", function(_, _, command, ...) | |
110 | - local f = CMD[command] | |
111 | - skynet.ret(skynet.pack(f(...))) | |
112 | - end) | |
113 | - | |
114 | - skynet.register(".CSVDATA") | |
115 | -end) |
src/services/dbseed.lua
1 | -require "csvdata.init" | |
2 | 1 | require "shared.init" |
3 | 2 | require "utils.init" |
4 | 3 | require "GlobalVar" |
... | ... | @@ -9,7 +8,6 @@ require "skynet.manager" |
9 | 8 | skynet = require "skynet" |
10 | 9 | |
11 | 10 | redisproxy = require("shared.redisproxy") |
12 | -globalCsv = require "csvdata/GlobalDefine" | |
13 | 11 | |
14 | 12 | SendPacket = function ( ... ) end |
15 | 13 | |
... | ... | @@ -36,7 +34,7 @@ local steps = { |
36 | 34 | } |
37 | 35 | |
38 | 36 | skynet.start(function () |
39 | - redisd = skynet.localname(".REDIS") | |
37 | + redisd = skynet.localname(".redis") | |
40 | 38 | |
41 | 39 | redisproxy = require("shared.redisproxy") |
42 | 40 | |
... | ... | @@ -46,6 +44,8 @@ skynet.start(function () |
46 | 44 | skynet.exit() |
47 | 45 | return |
48 | 46 | end |
47 | + csvdb = require "shared.csvdata" | |
48 | + globalCsv = csvdb["GlobalDefineCsv"] | |
49 | 49 | |
50 | 50 | for _, action in ipairs(steps) do |
51 | 51 | print(action.desc .. "start ...") | ... | ... |
src/services/globald.lua
src/services/httpweb.lua
... | ... | @@ -8,9 +8,8 @@ skynet = require "skynet" |
8 | 8 | redisproxy = require "shared.redisproxy" |
9 | 9 | netpack = require "skynet.netpack" |
10 | 10 | datacenter = require "skynet.datacenter" |
11 | -sharedata = require "skynet.sharedata" | |
12 | 11 | mcast_util = require "services/mcast_util" |
13 | -globalCsv = require "csvdata/GlobalDefine" | |
12 | +csvdb = require "shared.csvdata" | |
14 | 13 | |
15 | 14 | local socket = require "skynet.socket" |
16 | 15 | |
... | ... | @@ -33,7 +32,7 @@ local string = string |
33 | 32 | |
34 | 33 | skynet.register_protocol { |
35 | 34 | name = "role", |
36 | - id = 13, | |
35 | + id = 101, | |
37 | 36 | pack = skynet.pack, |
38 | 37 | unpack = skynet.unpack, |
39 | 38 | } |
... | ... | @@ -54,8 +53,12 @@ end |
54 | 53 | local CMD = require "actions.HttpAction" |
55 | 54 | |
56 | 55 | local function start() |
57 | - redisd = skynet.localname(".REDIS") | |
58 | - csvdb = sharedata.query("csvdata") | |
56 | + redisd = skynet.localname(".redis") | |
57 | + globalCsv = csvdb["GlobalDefineCsv"] | |
58 | + | |
59 | + if tonumber(skynet.getenv "logd") == 1 then | |
60 | + logd = skynet.localname(".log") | |
61 | + end | |
59 | 62 | |
60 | 63 | local listen_socket = socket.listen("0.0.0.0", port) |
61 | 64 | print("Listen web port " .. port) |
... | ... | @@ -83,7 +86,7 @@ local function start() |
83 | 86 | if not content then |
84 | 87 | code = 404 |
85 | 88 | end |
86 | - response(id, code, content) | |
89 | + response(id, code, tostring(content)) | |
87 | 90 | end |
88 | 91 | else |
89 | 92 | if url == sockethelper.socket_error then | ... | ... |
src/services/logd.lua
src/services/named.lua
... | ... | @@ -35,12 +35,13 @@ if mode == "sub" then |
35 | 35 | skynet.ret(skynet.pack(f(...))) |
36 | 36 | end) |
37 | 37 | |
38 | - skynet.register(string.format(".NAMED%d", id)) | |
38 | + skynet.register(string.format(".named%d", id)) | |
39 | 39 | end) |
40 | 40 | else |
41 | 41 | skynet.start(function() |
42 | - local ok, forbidNames = pcall(require, "csvdata.forbid_name") | |
43 | - if not ok then forbidNames = {} end | |
42 | + local csvdb = require "shared.csvdata" | |
43 | + local forbidNames = csvdb["forbid_nameCsv"] | |
44 | + if not forbidNames then forbidNames = {} end | |
44 | 45 | |
45 | 46 | local words = {} |
46 | 47 | for _, data in ipairs(forbidNames) do |
... | ... | @@ -52,5 +53,6 @@ else |
52 | 53 | for i = 1, 5 do |
53 | 54 | skynet.newservice(SERVICE_NAME, "sub", i, d) |
54 | 55 | end |
56 | + skynet.exit() | |
55 | 57 | end) |
56 | 58 | end | ... | ... |
src/services/pvpd.lua
... | ... | @@ -3,13 +3,12 @@ local json = require("shared.json") |
3 | 3 | redisproxy = require("shared.redisproxy") |
4 | 4 | local cluster = require "skynet.cluster" |
5 | 5 | local serverId = tonumber(skynet.getenv("servId")) |
6 | -local sharedata = require "skynet.sharedata" | |
7 | 6 | datacenter = require "skynet.datacenter" |
7 | +csvdb = require "shared.csvdata" | |
8 | 8 | require "shared.init" |
9 | 9 | require "utils.init" |
10 | 10 | require "RedisKeys" |
11 | 11 | require "skynet.manager" |
12 | -globalCsv = require "csvdata/GlobalDefine" | |
13 | 12 | require "GlobalVar" |
14 | 13 | |
15 | 14 | |
... | ... | @@ -30,7 +29,7 @@ end |
30 | 29 | |
31 | 30 | skynet.register_protocol { |
32 | 31 | name = "role", |
33 | - id = 13, | |
32 | + id = 101, | |
34 | 33 | pack = skynet.pack, |
35 | 34 | unpack = skynet.unpack, |
36 | 35 | dispatch = function(session, address, submethod, ...) |
... | ... | @@ -294,7 +293,9 @@ end |
294 | 293 | |
295 | 294 | ------------------------------------------------------ |
296 | 295 | function CMD.start() |
297 | - redisd = skynet.localname(".REDIS") | |
296 | + redisd = skynet.localname(".redis") | |
297 | + globalCsv = csvdb["GlobalDefineCsv"] | |
298 | + | |
298 | 299 | pvpInfo = require("models.Pvpd").new({key = "cross:pvpInfo"}) |
299 | 300 | pvpInfo:load() |
300 | 301 | end |
... | ... | @@ -308,9 +309,8 @@ local function __init__() |
308 | 309 | skynet.ret(skynet.pack(f(...))) |
309 | 310 | end |
310 | 311 | end) |
311 | - csvdb = sharedata.query("csvdata") | |
312 | 312 | |
313 | - skynet.register(".PVPCROSS") | |
313 | + skynet.register(".pvpcross") | |
314 | 314 | end |
315 | 315 | |
316 | 316 | skynet.start(__init__) | ... | ... |
src/services/redisd.lua
src/services/uniond.lua deleted
... | ... | @@ -1,143 +0,0 @@ |
1 | -require "shared.init" | |
2 | -require "utils.init" | |
3 | -require "ProtocolCode" | |
4 | -require "GlobalVar" | |
5 | -require "RedisKeys" | |
6 | -require "skynet.manager" | |
7 | - | |
8 | -local sharedata = require "sharedata" | |
9 | -local redisproxy = require "shared.redisproxy" | |
10 | -local datacenter = require "datacenter" | |
11 | -local queue = require "skynet.queue" | |
12 | - | |
13 | -skynet = require "skynet" | |
14 | -globalCsv = require "csvdata.GlobalDefine" | |
15 | - | |
16 | -local table_pack = table.pack | |
17 | -local table_unpack = table.unpack | |
18 | -local string_format = string.format | |
19 | -local pairs = pairs | |
20 | -local ipairs = ipairs | |
21 | -local tonumber = tonumber | |
22 | - | |
23 | --- 维护在线状态 | |
24 | - | |
25 | -local unionInfo, CMD, cs = {}, {} | |
26 | - | |
27 | -skynet.register_protocol { | |
28 | - name = "role", | |
29 | - id = 13, | |
30 | - pack = skynet.pack, | |
31 | - unpack = skynet.unpack, | |
32 | -} | |
33 | - | |
34 | -local function handle_timeout() | |
35 | - local now = skynet.timex() | |
36 | - unionInfo:onTimer(now) | |
37 | - skynet.timeout(100, handle_timeout) | |
38 | -end | |
39 | - | |
40 | ---[[ | |
41 | -getProperties({"field1", "field2", ...}) | |
42 | -return: {field1 = value1, field2 = value2, ...} | |
43 | -------- | |
44 | -setProperties({field1 = value1, field2 = value2, ...}) | |
45 | -]] | |
46 | -function rpcRole(roleId, funcName, ...) | |
47 | - if not unionInfo.members[roleId] then return end | |
48 | - local serv = unionInfo.members[roleId].serv | |
49 | - if serv then | |
50 | - if funcName == "getProperties" then | |
51 | - return skynet.call(serv, "role", funcName, table_unpack(...)) | |
52 | - else | |
53 | - return skynet.call(serv, "role", funcName, ...) | |
54 | - end | |
55 | - else | |
56 | - local rediskey = string_format("role:%d", roleId) | |
57 | - if funcName == "getProperty" then | |
58 | - return redisproxy:hget(rediskey, ...) | |
59 | - elseif funcName == "setProperty" then | |
60 | - return redisproxy:hset(rediskey, ...) | |
61 | - elseif funcName == "getProperties" then | |
62 | - local sRole = require "models.Role" | |
63 | - local fields = table_pack(...) | |
64 | - local rets = redisproxy:hmget(rediskey, table_unpack(fields, 1, fields.n)) | |
65 | - local result = {} | |
66 | - for i=1, fields.n do | |
67 | - local typ = sRole.schema[fields[i]][1] | |
68 | - local def = sRole.schema[fields[i]][2] | |
69 | - if typ == "number" then | |
70 | - result[fields[i]] = tonumber(rets[i] or def) | |
71 | - else | |
72 | - result[fields[i]] = rets[i] | |
73 | - end | |
74 | - end | |
75 | - return result | |
76 | - elseif funcName == "setProperties" then | |
77 | - local fields = ... | |
78 | - local params = {} | |
79 | - for field, value in pairs(fields) do | |
80 | - params[#params+1] = field | |
81 | - params[#params+1] = value | |
82 | - end | |
83 | - return redisproxy:hmset(rediskey, table_unpack(params)) | |
84 | - end | |
85 | - end | |
86 | -end | |
87 | - | |
88 | --- 加载联盟数据 | |
89 | -function CMD.load(unionId) | |
90 | - unionInfo = require("models.Union").new({key = UNION_KEY:format(unionId)}) | |
91 | - unionInfo:load() | |
92 | - unionInfo:loadMembers() | |
93 | -end | |
94 | - | |
95 | --- 创建一个联盟 | |
96 | -function CMD.new(roleId) | |
97 | - local unionId = redisproxy:hincrby("autoincrement_set", "union", 1) | |
98 | - unionInfo = require("models.Union").new({ | |
99 | - key = UNION_KEY:format(unionId), | |
100 | - master = roleId | |
101 | - }) | |
102 | - unionInfo:create() | |
103 | - unionInfo:addMember(roleId, true) | |
104 | - redisproxy:sadd(UNION_SET, unionId) | |
105 | - return unionId | |
106 | -end | |
107 | - | |
108 | --- 登录/登出 需要向联盟服务报备 | |
109 | -function CMD.sign(cmd, roleId, serv) | |
110 | - if not unionInfo.members[roleId] then return end | |
111 | - if cmd == "login" then | |
112 | - unionInfo.members[roleId].serv = serv | |
113 | - elseif cmd == "logout" then | |
114 | - unionInfo.members[roleId].serv = nil | |
115 | - end | |
116 | -end | |
117 | - | |
118 | -local function __init__() | |
119 | - skynet.dispatch("lua", function(_, _, command, ...) | |
120 | - cs(function (...) | |
121 | - if CMD[command] then | |
122 | - skynet.ret(skynet.pack(CMD[command](...))) | |
123 | - return | |
124 | - else | |
125 | - if unionInfo and unionInfo[submethod] then | |
126 | - if command == 'dismiss' then | |
127 | - unionInfo:dismiss(...) | |
128 | - return | |
129 | - end | |
130 | - local result = unionInfo[submethod](unionInfo, ...) | |
131 | - skynet.ret(skynet.pack(result)) | |
132 | - return | |
133 | - end | |
134 | - end | |
135 | - skynet.error("uniond commond error cmd=", command) | |
136 | - end) | |
137 | - end) | |
138 | - skynet.register("UNIOND") | |
139 | - csvdb = sharedata.query("csvdata") | |
140 | - cs = queue() | |
141 | -end | |
142 | - | |
143 | -skynet.start(__init__) | |
144 | 0 | \ No newline at end of file |
src/services/watchdog.lua
... | ... | @@ -9,6 +9,7 @@ local agent_ctrl = require "services.agent_ctrl" |
9 | 9 | local xxtea = require "xxtea" |
10 | 10 | local mc = require "skynet.multicast" |
11 | 11 | local cluster = require "skynet.cluster" |
12 | +local csvdata = require "shared.csvdata" | |
12 | 13 | |
13 | 14 | require "ProtocolCode" |
14 | 15 | require "GlobalVar" |
... | ... | @@ -50,7 +51,7 @@ local use_logd = tonumber(skynet.getenv "logd") |
50 | 51 | -- @desc: agent状态定时检测 |
51 | 52 | function check_agent_status() |
52 | 53 | pcall(agent_ctrl.check_agent_status, agent_ctrl) |
53 | - skynet.timeout(1, check_agent_status) | |
54 | + skynet.timeout(100, check_agent_status) | |
54 | 55 | end |
55 | 56 | |
56 | 57 | -- 创建world以及union channel 用于广播 |
... | ... | @@ -107,12 +108,12 @@ skynet.start(function() |
107 | 108 | skynet.ret(skynet.pack(f(subcmd, ...))) |
108 | 109 | end |
109 | 110 | end) |
110 | - skynet.register ".WATCHDOG" | |
111 | + skynet.register ".watchdog" | |
111 | 112 | -- 数据库服务 |
112 | 113 | redisd = skynet.newservice("services/redisd") |
113 | 114 | |
114 | - -- load all csv data | |
115 | - skynet.newservice("services/csvdatad") | |
115 | + -- 提前加载好 | |
116 | + csvdata.init() | |
116 | 117 | print("launch csvdatad ...") |
117 | 118 | |
118 | 119 | -- 日志服务 | ... | ... |
... | ... | @@ -0,0 +1,183 @@ |
1 | +-- 对sharetable 的一层封装 实现热更新 | |
2 | + | |
3 | +local skynet = require "skynet" | |
4 | +local service = require "skynet.service" | |
5 | +local sharetable = require "skynet.sharetable" | |
6 | + | |
7 | +local function sharetable_service() | |
8 | + local skynet = require "skynet" | |
9 | + local sharetable = require "skynet.sharetable" | |
10 | + | |
11 | + local files = {} -- filename | |
12 | + local csvdata = {} | |
13 | + | |
14 | + local initfile = { | |
15 | + ["src/csvdata/init.lua"] = {}, | |
16 | + ["src/csvdata/init_adv.lua"] = {}, | |
17 | + } | |
18 | + | |
19 | + function csvdata.query(source, filename) | |
20 | + files[filename] = files[filename] or {} | |
21 | + files[filename][source] = 1 | |
22 | + end | |
23 | + | |
24 | + function csvdata.close(source) | |
25 | + for filename, info in pairs(files) do | |
26 | + info[source] = nil | |
27 | + end | |
28 | + end | |
29 | + | |
30 | + function csvdata.realName(file) | |
31 | + if string.match(file, "Csv$") then | |
32 | + if initfile["src/csvdata/init.lua"] and initfile["src/csvdata/init.lua"][file] then | |
33 | + file = initfile["src/csvdata/init.lua"][file] | |
34 | + elseif initfile["src/csvdata/init_adv.lua"] and initfile["src/csvdata/init_adv.lua"][file] then | |
35 | + file = initfile["src/csvdata/init_adv.lua"][file] | |
36 | + end | |
37 | + file = "src/" .. file .. ".lua" | |
38 | + end | |
39 | + return file | |
40 | + end | |
41 | + | |
42 | + function csvdata.hotfix(_, ...) | |
43 | + local now = skynet.timex() | |
44 | + | |
45 | + local filenames = {...} | |
46 | + | |
47 | + local needHotfix = {} | |
48 | + for _, filename in ipairs(filenames) do | |
49 | + -- 更新下 | |
50 | + skynet.error(string.format("hotfix_csvdata time: %s, file: %s", now, filename)) | |
51 | + | |
52 | + if initfile[filename] then | |
53 | + sharetable.loadfile(filename) | |
54 | + sharetable.update(filename) | |
55 | + else | |
56 | + sharetable.loadfile(csvdata.realName(filename)) | |
57 | + end | |
58 | + | |
59 | + if files[filename] then | |
60 | + for source, _ in pairs(files[filename]) do | |
61 | + needHotfix[source] = needHotfix[source] or {} | |
62 | + table.insert(needHotfix[source], filename) | |
63 | + end | |
64 | + end | |
65 | + end | |
66 | + | |
67 | + for source, files in pairs(needHotfix) do | |
68 | + skynet.send(source, "csvdata", "hotfix", table.unpack(files)) | |
69 | + end | |
70 | + end | |
71 | + | |
72 | + skynet.dispatch("lua", function(_,source,cmd,...) | |
73 | + skynet.ignoreret() | |
74 | + csvdata[cmd](source,...) | |
75 | + end) | |
76 | + | |
77 | + skynet.register_protocol { | |
78 | + name = "csvdata", | |
79 | + id = 102, | |
80 | + pack = skynet.pack, | |
81 | + unpack = skynet.unpack, | |
82 | + } | |
83 | + | |
84 | + -- 初始化csvdata | |
85 | + skynet.start(function() | |
86 | + for file, _ in pairs(initfile) do | |
87 | + sharetable.loadfile(file) | |
88 | + local init = sharetable.query(file) | |
89 | + if not init then | |
90 | + error("csvdata load init file error " .. file) | |
91 | + return | |
92 | + end | |
93 | + initfile[file] = init | |
94 | + for _, one in pairs(init) do | |
95 | + sharetable.loadfile("src/" .. one .. ".lua") | |
96 | + end | |
97 | + end | |
98 | + end) | |
99 | +end | |
100 | + | |
101 | + | |
102 | +local cache = {} | |
103 | +local csvdata | |
104 | + | |
105 | +local function load_csvdata(t, key) | |
106 | + if key == "address" then | |
107 | + t.address = service.new("csvdata", sharetable_service) | |
108 | + return t.address | |
109 | + else | |
110 | + if cache[key] then return cache[key] end | |
111 | + | |
112 | + local realName = csvdata.realName(key) | |
113 | + | |
114 | + local tab = sharetable.query(realName) | |
115 | + if not tab then | |
116 | + error("dont have csvdata : " .. realName) | |
117 | + return | |
118 | + end | |
119 | + cache[key] = tab | |
120 | + -- 增加引用 | |
121 | + skynet.send(csvdata.address, "lua", "query", key) | |
122 | + return tab | |
123 | + end | |
124 | +end | |
125 | + | |
126 | +local function close_hotfix(t) | |
127 | + local addr = rawget(t, "address") | |
128 | + if addr then | |
129 | + skynet.send(addr, "lua", "close") | |
130 | + end | |
131 | +end | |
132 | + | |
133 | +csvdata = setmetatable ( {} , { | |
134 | + __index = load_csvdata, | |
135 | + __gc = close_hotfix, | |
136 | +}) | |
137 | + | |
138 | +function csvdata.init() | |
139 | + return csvdata.address | |
140 | +end | |
141 | + | |
142 | +function csvdata.hotfix(...) | |
143 | + skynet.send(csvdata.address, "lua", "hotfix", ...) | |
144 | +end | |
145 | + | |
146 | +function csvdata.realName(file) | |
147 | + if string.match(file, "Csv$") then | |
148 | + if csvdata["src/csvdata/init.lua"] and csvdata["src/csvdata/init.lua"][file] then | |
149 | + file = csvdata["src/csvdata/init.lua"][file] | |
150 | + elseif csvdata["src/csvdata/init_adv.lua"] and csvdata["src/csvdata/init_adv.lua"][file] then | |
151 | + file = csvdata["src/csvdata/init_adv.lua"][file] | |
152 | + end | |
153 | + file = "src/" .. file .. ".lua" | |
154 | + end | |
155 | + return file | |
156 | +end | |
157 | + | |
158 | +local function update(file) | |
159 | + -- 更新一下 | |
160 | + if cache[file] then | |
161 | + sharetable.update(csvdata.realName(file)) | |
162 | + end | |
163 | +end | |
164 | + | |
165 | +skynet.register_protocol { | |
166 | + name = "csvdata", | |
167 | + id = 102, | |
168 | + pack = skynet.pack, | |
169 | + unpack = skynet.unpack, | |
170 | + dispatch = function(_, _, cmd, ...) | |
171 | + skynet.ignoreret() | |
172 | + if cmd == "hotfix" then | |
173 | + -- skynet.error("csvdara hotfix update", ...) | |
174 | + local files = {...} | |
175 | + for _, file in ipairs(files) do | |
176 | + update(file) | |
177 | + end | |
178 | + return | |
179 | + end | |
180 | + end, | |
181 | +} | |
182 | + | |
183 | +return csvdata | ... | ... |
src/shared/redisproxy.lua
... | ... | @@ -5,6 +5,10 @@ local table_insert = table.insert |
5 | 5 | |
6 | 6 | local redisproxy = {} |
7 | 7 | |
8 | + | |
9 | +local isUsePika = false | |
10 | + | |
11 | + | |
8 | 12 | setmetatable(redisproxy, { __index = function(t, k) |
9 | 13 | local cmd = string.upper(k) |
10 | 14 | local f = function (self, ...) |
... | ... | @@ -38,14 +42,61 @@ function redisproxy:runScripts(name, ...) |
38 | 42 | end |
39 | 43 | |
40 | 44 | local meta = {__index = function (tab, name) return function (_, ...) tab[#tab+1]={name, ...} end end} |
41 | -function redisproxy:pipelining(block) | |
42 | - local ops = setmetatable({{"multi"}}, meta) | |
45 | +function redisproxy:pipelining(block, transaction) | |
46 | + if transaction == nil then transaction = true end -- 默认具有事务性 | |
47 | + if isUsePika then transaction = false end | |
48 | + | |
49 | + local ops = setmetatable({}, meta) | |
50 | + if transaction then | |
51 | + ops[#ops+1]={"multi"} | |
52 | + end | |
43 | 53 | block(ops) |
44 | - if #ops == 1 then return end | |
45 | - ops[#ops+1]={"exec"} | |
46 | - return self:pipeline(ops) | |
54 | + if transaction then | |
55 | + if #ops == 1 then return end | |
56 | + ops[#ops+1]={"exec"} | |
57 | + else | |
58 | + if #ops == 0 then return end | |
59 | + end | |
60 | + return self:pipeline(ops, transaction) | |
61 | +end | |
62 | + | |
63 | +if isUsePika then | |
64 | + | |
65 | +function redisproxy:insertEmail(params) | |
66 | + local roleId = params.roleId | |
67 | + local emailId = params.emailId | |
68 | + local createtime = params.createtime or skynet.timex() | |
69 | + local contentPms = params.contentPms or {} | |
70 | + local rewardPms = params.rewardPms or {} | |
71 | + local title = params.title or "" | |
72 | + local stitle = params.stitle or "" | |
73 | + local content = params.content or "" | |
74 | + local attachments = params.attachments or "" | |
75 | + | |
76 | + local id = self:HINCRBY(string.format("role:%d:autoincr", roleId), "email", 1) | |
77 | + self:LPUSH(string.format("role:%d:emailIds", roleId), id) | |
78 | + local deleteIds = self:LRANGE(string.format("role:%d:emailIds", roleId), EMAIL_LIMIT, -1) | |
79 | + self:pipelining(function(red) | |
80 | + for _, deleteId in ipairs(deleteIds) do | |
81 | + red:DEL(string.format("email:%d:%d", roleId, deleteId)) | |
82 | + end | |
83 | + red:LTRIM(string.format("role:%d:emailIds", roleId), 0, EMAIL_LIMIT - 1) | |
84 | + red:HMSET(string.format("email:%d:%d", roleId, id), | |
85 | + "id", tostring(id), | |
86 | + "emailId", emailId, | |
87 | + "status", "0", | |
88 | + "createtime", createtime, | |
89 | + "contentPms", MsgPack.pack(contentPms), | |
90 | + "rewardPms", MsgPack.pack(rewardPms), | |
91 | + "title", title, | |
92 | + "stitle", stitle, | |
93 | + "content", content, | |
94 | + "attachments", attachments) | |
95 | + end) | |
47 | 96 | end |
48 | 97 | |
98 | +else | |
99 | + | |
49 | 100 | function redisproxy:insertEmail(params) |
50 | 101 | local pms = { |
51 | 102 | roleId = params.roleId, |
... | ... | @@ -64,4 +115,7 @@ function redisproxy:insertEmail(params) |
64 | 115 | return true |
65 | 116 | end |
66 | 117 | |
118 | + | |
119 | +end | |
120 | + | |
67 | 121 | return redisproxy |
68 | 122 | \ No newline at end of file | ... | ... |