Commit 2a1d5c8cfea1c9a713f331f125c679952f31cc0d

Authored by zhouhaihai
2 parents 496414bc c2e42a2d

Merge branch 'develop' into qa

1   -Subproject commit dce531485f84bb7a555e9bb35b22c58fb469192c
  1 +Subproject commit 6c778575d99577c0c653b65b4025e2a88e6ce705
... ...
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
... ...
src/actions/ActivityAction.lua 0 → 100644
... ... @@ -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, {&quot;通关挂机副本&quot;, &quot;fb&quot;, &quot;挂卡id&quot;})
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 -- 血量&lt;=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 &quot;adv.AdvBlock&quot;
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 &quot;skynet.manager&quot;
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(&quot;.RoleLog&quot;) --日志相关
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
... ... @@ -32,6 +32,7 @@ local LogType = {
32 32 diner_action = "common",
33 33 tower_action = "common",
34 34 gm_action = "common",
  35 + act_action = "common",
35 36 }
36 37  
37 38 -- 如要修改 要提前修改 _template mapping -- 对应 mapping 为 gamelog-*
... ...
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
... ... @@ -11,7 +11,7 @@ local string_format = string.format
11 11  
12 12 local poold
13 13  
  14 +-- agent过期时间 5分钟
14 15 local AGENT_EXPIRE_TIME = 300
15 16  
16 17 local _M = {
... ...
src/services/chated.lua
... ... @@ -35,12 +35,13 @@ if mode == &quot;sub&quot; 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 &quot;skynet.manager&quot;
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
... ... @@ -129,8 +129,8 @@ local function __init__()
129 129 end
130 130 end
131 131 end)
132   - redisd = skynet.localname(".REDIS")
133   - skynet.register(".GLOBALD")
  132 + redisd = skynet.localname(".redis")
  133 + skynet.register(".globald")
134 134  
135 135 end
136 136  
... ...
src/services/httpweb.lua
... ... @@ -8,9 +8,8 @@ skynet = require &quot;skynet&quot;
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
... ... @@ -108,7 +108,7 @@ local function __init__()
108 108 end)
109 109 cs = queue()
110 110  
111   - skynet.register(".LOGD")
  111 + skynet.register(".log")
112 112 end
113 113  
114 114 skynet.start(__init__)
... ...
src/services/named.lua
... ... @@ -35,12 +35,13 @@ if mode == &quot;sub&quot; 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(&quot;shared.json&quot;)
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
... ... @@ -24,5 +24,5 @@ skynet.start(function()
24 24 skynet.ret(skynet.pack(db[string.lower(cmd)](db, ...)))
25 25 end
26 26 end)
27   - skynet.register ".REDIS"
  27 + skynet.register ".redis"
28 28 end)
29 29 \ No newline at end of file
... ...
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 &quot;services.agent_ctrl&quot;
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 &quot;logd&quot;)
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 -- 日志服务
... ...
src/shared/csvdata.lua 0 → 100644
... ... @@ -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
... ...