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