Commit ccbafe671db4e819e1f896ec4918eba5949e49b9

Authored by zhouhaihai
1 parent 4b61215f

冒险神器和buff

src/GlobalVar.lua
... ... @@ -16,6 +16,15 @@ AttsEnum = {
16 16 pierce = 10, -- 穿透
17 17 }
18 18  
  19 +--冒险属性
  20 +AdvAttsEnum = {
  21 + hp = 1, -- 血量
  22 + atk = 2, -- 攻击
  23 + def = 3, -- 物理防御
  24 + hit = 4, -- 命中
  25 + miss = 5, -- 闪避
  26 +}
  27 +
19 28 AttsEnumEx = {
20 29 [1] = "hp", -- 血量
21 30 [2] = "atk", -- 攻击
... ... @@ -78,6 +87,7 @@ ItemId = {
78 87 DinerCoin = 12, --后勤物资
79 88 LoveUp = 14, --好感度提升道具
80 89 OldCoin = 15, --古代金币
  90 + AdvPoint = 16, -- 探险点
81 91 DinerSpTask = 20, -- 餐厅任务采购券
82 92 LoveBreak = 21, --好感度突破道具
83 93 PvpKey = 22, -- pvp钥匙
... ... @@ -131,6 +141,7 @@ AdvBackEventType = {
131 141 Trap = 17, --陷阱
132 142 Layer = 18, --切换层
133 143 MapShow = 19, -- 展示地图
  144 + ChooseArtifact = 20, -- 等待选择神器
134 145 }
135 146  
136 147 AdvScoreType = {
... ...
src/ProtocolCode.lua
... ... @@ -56,6 +56,9 @@ actionCodes = {
56 56 Adv_workshopRpc = 162,
57 57 Adv_wheelSurfRpc = 163,
58 58 Adv_finishAchievRpc = 164,
  59 + Adv_chooseArtifactRpc = 165,
  60 + Adv_wearArtifactRpc = 166,
  61 + Adv_upArtifactRpc = 167,
59 62  
60 63 Hero_loadInfos = 201,
61 64 Hero_updateProperty = 202,
... ...
src/actions/AdvAction.lua
... ... @@ -259,6 +259,7 @@ function _M.clickBlockRpc(agent, data)
259 259 local msg = MsgPack.unpack(data)
260 260  
261 261 local adv = role:getAdvData()
  262 + if adv:isWaitChooseArtifact() then return end
262 263 local status = adv:clickBlock(msg.roomId, msg.blockId, msg)
263 264 if not status then return end
264 265 SendPacket(actionCodes.Adv_clickBlockRpc, MsgPack.pack({events = adv:popBackEvents()}))
... ... @@ -278,6 +279,7 @@ function _M.useItemRpc(agent, data)
278 279 if not itemData then return end
279 280  
280 281 local adv = role:getAdvData()
  282 + if adv:isWaitChooseArtifact() then return end
281 283 --重置数量
282 284 if itemData["function"] == 0 or itemData["function"] == 2 then count = 1 end
283 285 if not adv:cost({[itemId] = count}, {}, true) then return true end
... ... @@ -324,7 +326,8 @@ function _M.usePotionRpc(agent, data)
324 326 if own <= 0 then return 4 end
325 327  
326 328 local adv = role:getAdvData()
327   -
  329 + if adv:isWaitChooseArtifact() then return end
  330 +
328 331 local status = adv:doActive(potionData.effect, target) -- target
329 332 if not status then return end
330 333  
... ... @@ -338,6 +341,67 @@ function _M.usePotionRpc(agent, data)
338 341 return true
339 342 end
340 343  
  344 +-- 选择神器
  345 +function _M.chooseArtifactRpc(agent, data)
  346 + local role = agent.role
  347 + local msg = MsgPack.unpack(data)
  348 + local adv = role:getAdvData()
  349 +
  350 + if not msg.idx then return end
  351 + if not adv:isWaitChooseArtifact() then return end
  352 + local status = adv:chooseArtifact(msg.idx)
  353 + if not status then return end
  354 + adv:saveDB()
  355 +
  356 + SendPacket(actionCodes.Adv_chooseArtifactRpc, '')
  357 + return true
  358 +end
  359 +
  360 +-- 穿戴神器
  361 +function _M.wearArtifactRpc(agent, data)
  362 + local role = agent.role
  363 + local msg = MsgPack.unpack(data)
  364 + local slot = msg.slot
  365 + local id = msg.id
  366 +
  367 + local adv = role:getAdvData()
  368 +
  369 + if math.illegalNum(slot, 1, 5) then return end
  370 + if not adv:isHaveArtifact(id) then return end
  371 + if not adv:isWaitChooseArtifact() then return end
  372 +
  373 + local status = adv:wearArtifact(slot, id)
  374 + if not status then return end
  375 + adv:saveDB()
  376 +
  377 + SendPacket(actionCodes.Adv_wearArtifactRpc, '')
  378 + return true
  379 +end
  380 +
  381 +-- 升级神器
  382 +function _M.upArtifactRpc(agent, data)
  383 + local role = agent.role
  384 + local msg = MsgPack.unpack(data)
  385 + local id = msg.id
  386 +
  387 + local adv = role:getAdvData()
  388 + local curLevel = adv:isHaveArtifact(id)
  389 + if not curLevel then return end
  390 + if not role:isArtifactOpen(id, adv:isEndless(), curLevel + 1) then return end
  391 + local cost = csvdb["adv_artifactCsv"][curLevel].exp:toNumMap()
  392 + if not adv:cost(cost, {}, true) then return end
  393 +
  394 + local status = adv:artifactLevelUp(id)
  395 + if not status then return end
  396 + adv:cost(cost, {})
  397 +
  398 + if status == 1 then -- 现在穿着呢。更新下
  399 + adv:saveDB()
  400 + end
  401 + SendPacket(actionCodes.Adv_upArtifactRpc, '')
  402 + return true
  403 +end
  404 +
341 405 --退出
342 406 function _M.exitAdvRpc(agent, data)
343 407 local role = agent.role
... ... @@ -361,6 +425,7 @@ function _M.startBattleRpc(agent, data)
361 425 if not enemyId then return end
362 426  
363 427 local adv = role:getAdvData()
  428 + if adv:isWaitChooseArtifact() then return end
364 429 local enemy = adv.battle:getEnemyById(enemyId)
365 430  
366 431 if enemy.monsterId ~= monsterId or enemy.roomId ~= roomId or enemy.blockId ~= blockId or enemy.lock or enemy.isDead then return end
... ... @@ -387,6 +452,7 @@ function _M.endBattleRpc(agent, data)
387 452  
388 453 if not player or not player.hp or not player.sp or not enemyId or not key then return end
389 454 local adv = role:getAdvData()
  455 + if adv:isWaitChooseArtifact() then return end
390 456 -- 校验
391 457 if not adv.__battleCache then return end
392 458 if adv.__battleCache.enemyId ~= enemyId then return end
... ...
src/adv/Adv.lua
... ... @@ -33,6 +33,7 @@ function Adv:initByInfo(advInfo)
33 33 self.lastEnemyId = advInfo.lastEId or 1
34 34 self.mapStack = advInfo.mstack or {}
35 35 self.lchoose = advInfo.lch or {}
  36 + self.waitArtifact = advInfo.waitAF
36 37 self.maps = {}
37 38 for id, map in ipairs(advInfo.maps or {}) do
38 39 self.maps[id] = AdvMap.new(self, id, map)
... ... @@ -87,6 +88,7 @@ function Adv:clear()
87 88 self.lchoose = {}
88 89 self.maps = {}
89 90 self.battle = nil
  91 + self.waitArtifact = nil
90 92 end
91 93  
92 94 function Adv:saveDB(notNotify)
... ... @@ -100,6 +102,7 @@ function Adv:saveDB(notNotify)
100 102 advInfo.lastEId = self.lastEnemyId
101 103 advInfo.mstack = self.mapStack
102 104 advInfo.lch = self.lchoose
  105 + advInfo.waitAF = self.waitArtifact
103 106 advInfo.maps = {}
104 107  
105 108 self.battle:saveDB()
... ... @@ -159,7 +162,146 @@ function Adv:getBlock(roomId, blockId, mapIdx)
159 162 end
160 163 end
161 164  
  165 +function Adv:isHaveArtifact(id)
  166 + return self.owner:getProperty("advAFGet")[id]
  167 +end
  168 +
  169 +function Adv:awardArtifact(id, params)
  170 + if self:isHaveArtifact(id) then return end
  171 + self.owner:changeUpdates({{type = "advAFGet", field = id, value = 1}}, params.notNotify)
  172 +end
  173 +
  174 +
  175 +function Adv:delArtifactEffect(effect)
  176 + for _, eff in ipairs(effect:toArray()) do
  177 + local etype, id = table.unpack(eff:toArray(true, "="))
  178 + if etype == 1 then
  179 + self.battle.player:addPassive({id = id})
  180 + elseif etype == 2 then
  181 + self.battle.player:addBuff(id)
  182 + end
  183 + end
  184 +end
  185 +
  186 +function Adv:addArtifactEffect(effect)
  187 + for _, eff in ipairs(effect:toArray()) do
  188 + local etype, id = table.unpack(eff:toArray(true, "="))
  189 + if etype == 1 then
  190 + self.battle.player:delPassiveById(id)
  191 + elseif etype == 2 then
  192 + self.battle.player:delBuffById(id)
  193 + end
  194 + end
  195 +end
  196 +
  197 +function Adv:wearArtifact(slot, id)
  198 + local advAFGet = self.owner:getProperty("advAFGet")
  199 + local advAFWear = self.owner:getProperty("advAFWear")
  200 +
  201 + local curWear = {}
  202 + for _, _id in pairs(advAFWear) do
  203 + curWear[_id] = 1
  204 + end
  205 + if curWear[id] then return end
  206 +
  207 + if advAFWear[slot] then
  208 + local oldData = csvdb["adv_artifactCsv"][advAFWear[slot]][advAFGet[advAFWear[slot]]]
  209 + self:delArtifactEffect(oldData.effect)
  210 + if oldData.comboId ~= 0 then
  211 + local comboData = csvdb["adv_artifact_comboCsv"][oldData.comboId]
  212 + if comboData then
  213 + local isHaveCombo = true
  214 + for _, _id in ipairs(comboData.artifactid:toArray(true)) do
  215 + if not curWear[_id] then
  216 + isHaveCombo = false
  217 + break
  218 + end
  219 + end
  220 + if isHaveCombo then
  221 + self:delArtifactEffect(comboData.effect)
  222 + end
  223 + end
  224 + end
  225 + curWear[advAFWear[slot]] = nil
  226 + end
  227 +
  228 + curWear[id] = 1
  229 + local newData = csvdb["adv_artifactCsv"][id][advAFGet[id]]
  230 + self:addArtifactEffect(newData.effect)
  231 + if newData.comboId ~= 0 then
  232 + local comboData = csvdb["adv_artifact_comboCsv"][newData.comboId]
  233 + if comboData then
  234 + local isHaveCombo = true
  235 + for _, _id in ipairs(comboData.artifactid:toArray(true)) do
  236 + if not curWear[_id] then
  237 + isHaveCombo = false
  238 + break
  239 + end
  240 + end
  241 + if isHaveCombo then
  242 + self:addArtifactEffect(comboData.effect)
  243 + end
  244 + end
  245 + end
162 246  
  247 + self.owner:changeUpdates({{type = "advAFWear", field = slot, value = id}})
  248 + return true
  249 +end
  250 +
  251 +function Adv:artifactLevelUp(id)
  252 + local advAFGet = self.owner:getProperty("advAFGet")
  253 + local advAFWear = self.owner:getProperty("advAFWear")
  254 + local status = 0
  255 + if advAFWear[id] then -- 穿着呢
  256 + local oldData = csvdb["adv_artifactCsv"][id][advAFGet[id]]
  257 + local newData = csvdb["adv_artifactCsv"][id][advAFGet[id] + 1]
  258 + self:delArtifactEffect(oldData.effect)
  259 + self:addArtifactEffect(newData.effect)
  260 + status = 1
  261 + end
  262 + self.owner:changeUpdates({{type = "advAFGet", field = id, value = advAFGet[id] + 1}})
  263 + return status
  264 +end
  265 +
  266 +function Adv:waitChooseArtifact()
  267 + local chooses = {}
  268 + local pool = {}
  269 + local count = 3 --需要多少个
  270 +
  271 + for id, temp in pairs(csvdb["adv_artifactCsv"]) do
  272 + if not self:isHaveArtifact(id) and self.owner:isArtifactOpen(id, self:isEndless()) then
  273 + table.insert(pool, id)
  274 + end
  275 + end
  276 +
  277 + for i = 1, count do
  278 + if len(pool) <= 0 then
  279 + table.insert(chooses, {ItemId.AdvPoint, 48})
  280 + else
  281 + local idx = math.randomInt(1, #pool)
  282 + table.insert(chooses, pool[idx])
  283 + table.remove(pool, idx)
  284 + end
  285 + end
  286 + self.waitArtifact = chooses
  287 + self:backChooseArtifact()
  288 +end
  289 +
  290 +function Adv:isWaitChooseArtifact()
  291 + return self.waitArtifact
  292 +end
  293 +
  294 +function Adv:chooseArtifact(index)
  295 + if not self.waitArtifact or not self.waitArtifact[index] then return end
  296 + local itemId = type(self.waitArtifact[index]) == "table" and self.waitArtifact[index][1] or self.waitArtifact[index]
  297 + local count = type(self.waitArtifact[index]) == "table" and self.waitArtifact[index][2] or 1
  298 + self:award({[itemId] = count})
  299 + return true
  300 +end
  301 +
  302 +function Adv:isEndless()
  303 + return AdvCommon.isEndless(self.chapterId)
  304 +end
163 305  
164 306 --关卡通关,非层 score < 0 失败
165 307 function Adv:over(success, isAllPass)
... ... @@ -183,6 +325,7 @@ function Adv:over(success, isAllPass)
183 325 self:clear()
184 326 self.owner:checkTaskEnter("AdvScore", {score = score})
185 327 self.owner:updateProperty({field = "advItems", value = ""})
  328 + self.owner:updateProperty({field = "advAFGet", value = {}})
186 329  
187 330 self:backEnd(success, score, scoreInfo, reward)
188 331 end
... ... @@ -244,136 +387,34 @@ function Adv:award(gift, params)
244 387 tgift = gift
245 388 end
246 389 local items = self.owner:getProperty("advItems")
  390 + local oldItems = items
247 391 for itemId, count in pairs(tgift) do
248 392 if count > 0 then
  393 + local buffAdd = self.battle.player:getRewardChange(itemId)
  394 + count = math.max(0, (count + buffAdd[0]) * (1 + buffAdd[1])) --附加 buff 的影响
249 395 self:scoreChange(AdvScoreType.Item, {itemId, count})
250 396 self:checkTask(Adv.TaskType.Item, count, itemId)
251 397 self:checkAchievement(Adv.AchievType.GetItem, count, itemId)
252 398 end
  399 + tgift[itemId] = count
253 400 local origin = items:getv(itemId, 0)
254 401 local nums = origin + count
255   - if csvdb["adv_artifactCsv"][itemId] then
256   - nums = self:checkArtifact(itemId, origin, count, nums)
257   - end
258   - if nums <= 0 then
259   - items = items:delk(itemId)
260   - nums = 0
261   - else
262   - items = items:setv(itemId, nums)
263   - end
264   - end
265   -
266   - self.owner:updateProperty({field = "advItems", value = items, notNotify = params.notNotify})
267   - return tgift
268   -end
269   -
270 402  
271   -function Adv:delArtifactEffect(effectType, effects)
272   - if effectType == 1 then
273   - for _, id in ipairs(effects:toArray(true, "=")) do
274   - self.battle.player:delPassiveById(id)
275   - end
276   - elseif effectType == 2 then
277   - for _, id in ipairs(effects:toArray(true, "=")) do
278   - self.battle.player:delBuffById(id)
279   - end
280   - end
281   -end
282   -
283   -function Adv:addArtifactEffect(effectType, effects)
284   - if effectType == 1 then
285   - for _, id in ipairs(effects:toArray(true, "=")) do
286   - self.battle.player:addPassive({id = id})
287   - end
288   - elseif effectType == 2 then
289   - for _, id in ipairs(effects:toArray(true, "=")) do
290   - self.battle.player:addBuff(id)
291   - end
292   - end
293   -end
294   --- 检查神器
295   -function Adv:checkArtifact(itemId, origin, count, nums)
296   - local artifactData = csvdb["adv_artifactCsv"][itemId]
297   - if count == 0 or not artifactData then return nums end
298   - local advItems = self.owner:getProperty("advItems")
299   - if count < 0 then --删除
300   - nums = 0
301   - local curData = artifactData[origin]
302   - if curData then
303   - -- 删除自己的效果
304   - self:delArtifactEffect(curData.type, curData.effect)
305   -
306   - --删除组合效果
307   - if curData.comboId ~= 0 then
308   - local comboLv = advItems:getv(curData.comboId, 0)
309   - if comboLv ~= 0 then
310   - --删除自己的组合效果
311   - if curData.comboType == 1 or curData.comboType == 2 then
312   - self:delArtifactEffect(curData.comboType, curData.comboEffect)
313   - elseif curData.comboType == 3 then
314   - self:delArtifactEffect(curData.type, curData.comboEffect)
315   - end
316   -
317   - -- 删除组合的组合效果
318   - local comboData = (csvdb["adv_artifactCsv"][curData.comboId] or {})[comboLv]
319   - if comboData then
320   - if comboData.comboType == 1 or comboData.comboType == 2 then
321   - self:delArtifactEffect(comboData.comboType, comboData.comboEffect)
322   - elseif comboData.comboType == 3 then
323   - self:delArtifactEffect(comboData.type, comboData.comboEffect)
324   - self:addArtifactEffect(comboData.type, comboData.effect)
325   - end
326   - end
327   - end
328   - end
329   - end
330   - else
331   - nums = math.max(0, math.min(nums, #artifactData))
332   - if nums == origin then return nums end
333   - if origin == 0 then --初始获得
334   - local curData = artifactData[nums]
335   - local addSelfEffect = true
336   - --查看是否有组合
337   - if curData.comboId ~= 0 then
338   - local comboLv = advItems:getv(curData.comboId, 0)
339   - if comboLv ~= 0 then
340   - --自己的组合效果
341   - if curData.comboType == 1 or curData.comboType == 2 then
342   - self:addArtifactEffect(curData.comboType, curData.comboEffect)
343   - elseif curData.comboType == 3 then
344   - self:addArtifactEffect(curData.type, curData.comboEffect)
345   - addSelfEffect = false
346   - end
347   -
348   - --对方的组合效果
349   - local comboData = (csvdb["adv_artifactCsv"][curData.comboId] or {})[comboLv]
350   - if comboData then
351   - if comboData.comboType == 1 or comboData.comboType == 2 then
352   - self:addArtifactEffect(comboData.comboType, comboData.comboEffect)
353   - elseif comboData.comboType == 3 then
354   - self:delArtifactEffect(comboData.type, comboData.effect)
355   - self:addArtifactEffect(comboData.type, comboData.comboEffect)
356   - end
357   - end
358   - end
359   - end
360   - if addSelfEffect then
361   - self:addArtifactEffect(curData.type, curData.effect)
362   - end
363   - else --升级
364   - local originData = artifactData[origin]
365   - local curData = artifactData[nums]
366   -
367   - if originData then
368   - self:delArtifactEffect(originData.type, originData.effect)
369   - end
370   -
371   - if curData then
372   - self:addArtifactEffect(curData.type, curData.effect)
  403 + if csvdb["adv_artifactCsv"][itemId] then -- 获得神器
  404 + self:awardArtifact(itemId, params)
  405 + else
  406 + if nums <= 0 then
  407 + items = items:delk(itemId)
  408 + nums = 0
  409 + else
  410 + items = items:setv(itemId, nums)
373 411 end
374 412 end
375 413 end
376   - return nums
  414 + if items ~= oldItems then
  415 + self.owner:updateProperty({field = "advItems", value = items, notNotify = params.notNotify})
  416 + end
  417 + return tgift
377 418 end
378 419  
379 420  
... ... @@ -397,7 +438,9 @@ function Adv:cost(item, params, check)
397 438 if next(less) and not self.owner:checkItemEnough(less) then return end --不够
398 439 if check then return true end
399 440 self:award(advCost, params)
400   - self.owner:costItems(less, params)
  441 + if next(less) then
  442 + self.owner:costItems(less, params)
  443 + end
401 444 return true
402 445 end
403 446  
... ... @@ -411,7 +454,7 @@ local function clickOut(self, room, block, params)
411 454  
412 455 local advPass = self.owner:getProperty("advPass")
413 456  
414   - if AdvCommon.isEndless(self.chapterId) then
  457 + if self:isEndless() then
415 458 -- 刷新最高层
416 459 if self.owner:getProperty("advElM") < self.level then
417 460 self.owner:updateProperty({field = "advElM", value = self.level})
... ... @@ -427,8 +470,8 @@ local function clickOut(self, room, block, params)
427 470  
428 471 self:checkAchievement(Adv.AchievType.OverWin, 1, self.level)
429 472 local levellimit = csvdb["adv_chapterCsv"][self.chapterId].limitlevel
430   - if params.relay or (not AdvCommon.isEndless(self.chapterId) and (self.level >= levellimit or not self.owner:advChapterIsOpen(self.chapterId, self.level + 1))) then --关卡结束
431   - self:over(true, not AdvCommon.isEndless(self.chapterId) and self.level >= levellimit)
  473 + if params.relay or (not self:isEndless() and (self.level >= levellimit or not self.owner:advChapterIsOpen(self.chapterId, self.level + 1))) then --关卡结束
  474 + self:over(true, not self:isEndless() and self.level >= levellimit)
432 475 else
433 476 self:initByChapter(self.chapterId, self.level + 1, true, true)
434 477 self:backNext() --下一关
... ... @@ -522,6 +565,9 @@ local function chooseCommon(self, room, block, chooseData, choose)
522 565 clearBlock = false
523 566 end,
524 567 [4] = function() --无事发生
  568 + end,
  569 + [11] = function() -- 获得神器
  570 + self:waitChooseArtifact() --等待获取神器
525 571 end
526 572 }
527 573 assert(doEffect[effect[1]], "error effect, event_[link]chooseCsv id :" .. block.event.id)
... ... @@ -1078,6 +1124,10 @@ function Adv:backMapShow()
1078 1124 self:pushBackEvent(AdvBackEventType.MapShow, {})
1079 1125 end
1080 1126  
  1127 +function Adv:backChooseArtifact()
  1128 + self:pushBackEvent(AdvBackEventType.ChooseArtifact, {})
  1129 +end
  1130 +
1081 1131 function Adv:scoreChange(scoreType, pms)
1082 1132 local cutTypes = {}
1083 1133 local score = 0
... ...
src/adv/AdvBattle.lua
... ... @@ -41,29 +41,30 @@ function Battle:initPlayer()
41 41 local player = advTeam.player
42 42 if not player then
43 43 player = {}
  44 + player.level = 1
  45 + player.exp = 0
  46 + player.sp = 100
  47 + player.growth = {}
44 48 player.passives = {}
45   - local heroLevel = 0
  49 +
46 50 for slot, heroId in pairs(advTeam.heros) do
47 51 local hero = self.adv.owner.heros[heroId]
48 52 if hero then
49   - heroLevel = heroLevel + hero:getProperty("level")
50 53 local advSkillId = csvdb["unitCsv"][self.adv.owner.heros[heroId]:getProperty("type")]["adv"]
51 54 if advSkillId > 1000 then
52 55 table.insert(player.passives, {id = advSkillId, level = hero:getSkillLevel(4)})
53 56 end
54 57 end
55 58 end
56   - player.growth = (self.adv.owner:getRealBattleValue(advTeam.heros) / 80) ^ 0.52 + math.floor(heroLevel / 50) / 50
57   - player.level = 1
58   - player.exp = 0
59   - player.sp = 100
60   - local activeRelation = self.adv.owner:getHeroActiveRelation()
61   - local baseAttr = csvdb["adv_unitCsv"][self.adv.chapterId]
62   - for _, attr in pairs(AttsEnumEx) do
63   - if baseAttr[attr] then
64   - player[attr] = baseAttr[attr] + player.growth * (player.level - 1)
  59 +
  60 + local attrs = self.adv.owner:getTeamBattleInfo(advTeam).heros
  61 + for attrName, _ in pairs(AdvAttsEnum) do
  62 + for _, hero in pairs(attrs) do
  63 + player[attrName] = (player[attrName] or 0) + hero[attrName]
65 64 end
  65 + palyer.growth[attrName] = player[attrName] * 0.025
66 66 end
  67 +
67 68 player.hpMax = player.hp or 0
68 69 self.isNewPlayer = true
69 70 advTeam.player = player
... ...
src/adv/AdvBuff.lua
... ... @@ -27,6 +27,9 @@ Buff.EXP_UP = 24 -- 杀敌经验提高
27 27 Buff.DISABLE_BUFF = 25 -- 禁用固有技
28 28 Buff.ATTR_CHANGE_COND = 26 --属性变化(状态)有条件
29 29 Buff.CHANGE_DROP_TO_CLICK = 27 --掉落转换为click
  30 +Buff.SP_MAX_CHANGE = 28, -- 魔法上限
  31 +Buff.ITEM_GET_UP = 29, -- 获得道具数量增加
  32 +Buff.Buff_EFFECT_CHANGE = 30, -- 改变 buff 效果
30 33  
31 34 --角色一些属性的变化
32 35 local function commonAttr(_Buff, attrName)
... ... @@ -34,26 +37,46 @@ local function commonAttr(_Buff, attrName)
34 37 self.owner:reSetAttr(attrName)
35 38 end
36 39 _Buff._effectValue = function(self)
37   - return self.buffData.effectValue1, self.buffData.effectValue2
  40 + return self.buffData.effectValue1, self:doEffectChange(self.buffData.effectValue2) * self.layer, attrName
  41 + end
  42 + _Buff._overlay = function(self)
  43 + self.owner:reSetAttr(attrName)
  44 + end
  45 + _Buff._uncover = function(self)
  46 + self.owner:reSetAttr(attrName)
38 47 end
39 48 _Buff._endBuff = function(self, data)
40 49 self.owner:reSetAttr(attrName)
41 50 end
  51 + _Buff._effectChange = function(self)
  52 + self.owner:reSetAttr(attrName)
  53 + end
42 54 end
43 55 local function commonAttCond(_Buff, attrName)
44 56 _Buff._init = function(self, data) --初始化变化值
  57 + self._changeV = self:_calculate()
  58 + self.owner:reSetAttr(attrName)
  59 + end
  60 + _Buff._overlay = function(self)
  61 + self._changeV = (self._changeV or 0) + self:_calculate()
  62 + self.owner:reSetAttr(attrName)
  63 + end
  64 + _Buff._uncover = function(self)
  65 + self._changeV = self._changeV - self._changeV / (self.layer + 1)
  66 + self.owner:reSetAttr(attrName)
  67 + end
  68 + _Buff._calculate = function(self)
45 69 local effectCount = 0
46 70 if self.buffData.effectValue4 == 0 then
47 71 effectCount = self.owner.battle.adv.owner:getProperty("advItems"):getv(ItemId.OldCoin, 0)
48 72 end
49   - self._changeV = self.buffData.effectValue2 * effectCount / self.buffData.effectValue5
50   - self.owner:reSetAttr(attrName)
  73 + return self.buffData.effectValue2 * effectCount / tonumber(self.buffData.effectValue5)
51 74 end
52 75 _Buff._initDB = function(self, data)
53 76 self._changeV = data.cv
54 77 end
55 78 _Buff._effectValue = function(self)
56   - return self.buffData.effectValue1, self._changeV
  79 + return self.buffData.effectValue1, self._changeV, attrName
57 80 end
58 81 _Buff._endBuff = function(self, data)
59 82 self.owner:reSetAttr(attrName)
... ... @@ -66,19 +89,29 @@ end
66 89 local BuffFactory = {
67 90 [Buff.HP_CHANGE] = function(_Buff)
68 91 _Buff._init = function(self, data) --初始化变化值
69   - self._changeV = 0
  92 + self._changeV = self:_calculate()
  93 + end
  94 + _Buff._overlay = function(self)
  95 + self._changeV = (self._changeV or 0) + self:_calculate()
  96 + end
  97 + _Buff._uncover = function(self)
  98 + self._changeV = self._changeV - self._changeV / (self.layer + 1)
  99 + end
  100 + _Buff._calculate = function(self)
  101 + local curValue = 0
70 102 if self.buffData.effectValue1 == 0 then --固定值
71   - self._changeV = self.buffData.effectValue2
  103 + curValue = self.buffData.effectValue2
72 104 elseif self.buffData.effectValue1 == 1 then
73 105 local baseOwner = self.buffData.effectValue4 == 1 and self.owner or self.release
74 106 local attrs = {[0] = "hp", [1] = "hpMax", [2] = "atk"}
75   - self._changeV = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100
  107 + curValue = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100
76 108 end
77   - if self._changeV < 0 then
  109 + if curValue < 0 then
78 110 if self.release then
79   - self._changeV = -self.release:getHurtValue(-self._changeV)
  111 + curValue = -self.release:getHurtValue(-curValue)
80 112 end
81 113 end
  114 + return curValue
82 115 end
83 116 _Buff._initDB = function(self, data)
84 117 self._changeV = data.cv
... ... @@ -92,8 +125,9 @@ local BuffFactory = {
92 125 end
93 126 end
94 127 _Buff._effectValue = function(self)
95   - return self._changeV
  128 + return self:doEffectChange(self._changeV)
96 129 end
  130 +
97 131 _Buff._getDB = function(self)
98 132 return {cv = self._changeV}
99 133 end
... ... @@ -101,33 +135,60 @@ local BuffFactory = {
101 135  
102 136 [Buff.HP_MAX_CHANGE] = function(_Buff)
103 137 _Buff._init = function(self, data) --初始化变化值
104   - self._changeV = 0
  138 + self._changeV = self:_calculate()
  139 + self:_hpChange()
  140 + end
  141 + _Buff._overlay = function(self)
  142 + self._changeV = (self._changeV or 0) + self:_calculate()
  143 + self:_hpChange()
  144 + end
  145 +
  146 + _Buff._uncover = function(self)
  147 + self._changeV = self._changeV - self._changeV / (self.layer + 1)
  148 + self.owner:reSetHpMax()
  149 + end
  150 +
  151 + -- 提高生命上限的时候要相应提高生命值
  152 + _Buff._hpChange = function(self)
  153 + local oldHpMax = self.owner.hpMax
  154 + self.owner:reSetHpMax()
  155 +
  156 + local curValue = self.owner.hpMax - oldHpMax
  157 + if curValue > 0 then
  158 + self.owner:recover(curValue, self.release) -- 防止release不存在,地图点buff
  159 + elseif curValue < 0 then
  160 + self.owner:hurt(self.release and self.release:getHurtValue(-curValue) or -curValue, self.release, {hurtType = 2, buffId = self.id})
  161 + end
  162 + end
  163 +
  164 + _Buff._calculate = function(self)
  165 + local curValue = 0
105 166 if self.buffData.effectValue1 == 0 then --固定值
106   - self._changeV = self.buffData.effectValue2
  167 + curValue = self.buffData.effectValue2
107 168 elseif self.buffData.effectValue1 == 1 then
108 169 local baseOwner = self.buffData.effectValue4 == 1 and self.owner or self.release
109 170 local attrs = {[0] = "hp", [1] = "hpMax", [2] = "atk"}
110   - self._changeV = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100
111   - end
112   - local old = self.owner.hpMax
113   - self.owner.hpMax = math.max(1, self.owner.hpMax + self._changeV)
114   - self._changeV = self.owner.hpMax - old
115   - if self._changeV > 0 then
116   - self.owner:recover(self._changeV, self.release) -- 防止release不存在,地图点buff
117   - elseif self._changeV < 0 then
118   - self.owner:hurt(self.release and self.release:getHurtValue(-self._changeV) or -self._changeV, self.release, {hurtType = 2, buffId = self.id})
119   - self.owner.hp = math.min(self.owner.hpMax, self.owner.hp)
  171 + curValue = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100
120 172 end
  173 + return curValue
  174 + end
  175 +
  176 + _Buff._effectValue = function(self)
  177 + return self:doEffectChange(self._changeV)
  178 + end
  179 +
  180 + _Buff._endBuff = function(self)
  181 + self.owner:reSetHpMax()
121 182 end
  183 +
  184 + _Buff._effectChange = function(self)
  185 + self.owner:reSetHpMax()
  186 + end
  187 +
122 188 _Buff._initDB = function(self, data)
123 189 self._changeV = data.cv
124 190 end
125   - _Buff._endBuff = function(self, data)
126   - if self._changeV then
127   - self.owner.hpMax = math.max(1, self.owner.hpMax - self._changeV)
128   - self.owner.hp = math.min(self.owner.hpMax, self.owner.hp)
129   - end
130   - end
  191 +
131 192 _Buff._getDB = function(self)
132 193 return {cv = self._changeV}
133 194 end
... ... @@ -137,61 +198,23 @@ local BuffFactory = {
137 198 commonAttr(_Buff, attrName)
138 199 end,
139 200  
140   - [Buff.ATTR_CHANGE] = function(_Buff)
  201 + [Buff.ATTR_CHANGE_COND] = function(_Buff)
141 202 local attrName = AttsEnumEx[_Buff.buffData.effectValue3]
142 203 commonAttCond(_Buff, attrName)
143 204 end,
144 205  
145 206  
146   - [Buff.BACK_HURT] = function(_Buff)
147   - _Buff._effectValue = function(self)
148   - return self.buffData.effectValue1, self.buffData.effectValue2, self.buffData.effectValue3
149   - end
150   - end,
151   -
152   - [Buff.HURT_CHANGE] = function(_Buff)
153   - _Buff._effectValue = function(self)
154   - return self.buffData.effectValue1, self.buffData.effectValue2
155   - end
156   - end,
157   -
158   - [Buff.INJURED_CHANGE] = function(_Buff)
159   - _Buff._effectValue = function(self)
160   - return self.buffData.effectValue1, self.buffData.effectValue2, self.buffData.effectValue3
161   - end
162   - end,
163   -
164   - [Buff.HURT_TRANSFER] = function(_Buff)
165   - _Buff._effectValue = function(self)
166   - return self.buffData.effectValue1, self.buffData.effectValue2
167   - end
168   - end,
169   -
170   - [Buff.HURT_ABSORB] = function(_Buff)
171   - _Buff._effectValue = function(self)
172   - return self.buffData.effectValue1, self.buffData.effectValue2
173   - end
174   - end,
175   -
176   - [Buff.CHANGE_DROP] = function(_Buff)
177   - _Buff._effectValue = function(self)
178   - return self.buffData.effectValue1, self.buffData.effectValue2
179   - end
180   - end,
181   -
182 207 [Buff.CHANGE_DROP_TO_CLICK] = function(_Buff)
183 208 _Buff._effectValue = function(self)
  209 + -- id
184 210 return self.buffData.effectValue1
185 211 end
186 212 end,
187 213  
188 214 [Buff.IMMNUE_BUFF] = function(_Buff)
189   - _Buff._init = function(self, data)
190   - self.count = self.buffData.effectValue3
191   - end
192 215 _Buff._canEffect = function(self, buffId, buffGroup)
193 216 local cType, aim = self.buffData.effectValue1, self.buffData.effectValue2
194   - if (cType == 0 and buffId == aim) or (cType == 1 and buffGroup == aim) then
  217 + if buffData.dispel == 0 and (not cType or (cType == 0 and buffId == aim) or (cType == 1 and buffData.group == aim)) then
195 218 return true
196 219 end
197 220 end
... ... @@ -199,17 +222,19 @@ local BuffFactory = {
199 222  
200 223 [Buff.CLEAR_BUFF] = function(_Buff)
201 224 _Buff._init = function(self, data)
202   - self.count = self.buffData.effectValue3
203 225 for _, buff in ipairs(self.buffs) do -- 挂上就清除一下子
204   - if not buff.isDel and self:canEffect(buff.id, buff:getGroup()) then
205   - buff.isDel = true
206   - self:effect()
  226 + if not buff.isDel and self:canEffect(buff.id) and not self.isDel then
  227 + if not buff.isDel and not self.isDel then
  228 + self:effect()
  229 + buff:uncover()
  230 + end
207 231 end
208 232 end
209 233 end
210   - _Buff._canEffect = function(self, buffId, buffGroup)
  234 + _Buff._canEffect = function(self, buffId)
  235 + local buffData = csvdb["adv_map_buffCsv"][buffId]
211 236 local cType, aim = self.buffData.effectValue1, self.buffData.effectValue2
212   - if (cType == 0 and buffId == aim) or (cType == 1 and buffGroup == aim) then
  237 + if buffData.dispel == 0 and (not cType or (cType == 0 and buffId == aim) or (cType == 1 and buffData.group == aim)) then
213 238 return true
214 239 end
215 240 end
... ... @@ -221,78 +246,114 @@ local BuffFactory = {
221 246 self.owner.battle.adv:openBlockRand(roomNum)
222 247 end
223 248 _Buff._effectValue = function(self)
224   - return self.buffData.effectValue1
  249 + -- 数量
  250 + return self.buffData.effectValue1 * self.layer
225 251 end
226 252 end,
227 253  
228 254 [Buff.SP_CHANGE] = function(_Buff)
229   - --cType 0 or nil 值 1 百分比
230 255 _Buff._afterRound = function(self)
231   - local value, cType = self:effect()
  256 + local cType, value = self:effect()
232 257 self.owner:changeSp(value, cType)
233 258 end
234 259 _Buff._effectValue = function(self)
235   - return self.buffData.effectValue2, self.buffData.effectValue1
  260 + -- 值/% 数量
  261 + return self.buffData.effectValue1, self:doEffectChange(self.buffData.effectValue2) * self.layer
236 262 end
237 263 end,
238 264  
239   - [Buff.HP_CHANGE_NOW] = function(_Buff)
240   - _Buff._init = function(self, data) --初始化变化值
241   - self._changeV = 0
242   - if self.buffData.effectValue1 == 0 then --固定值
243   - self._changeV = self.buffData.effectValue2
244   - elseif self.buffData.effectValue1 == 1 then
245   - local baseOwner = self.buffData.effectValue4 == 1 and self.owner or self.release
246   - local attrs = {[0] = "hp", [1] = "hpMax", [2] = "atk"}
247   - self._changeV = baseOwner[attrs[self.buffData.effectValue3]] * self.buffData.effectValue2 / 100
248   - end
249   - if self._changeV < 0 then
250   - self._changeV = self.release and -self.release:getHurtValue(-self._changeV) or self._changeV
251   - end
252   - end
253   - _Buff._initDB = function(self, data)
254   - self._changeV = data.cv
255   - end
  265 + [Buff.EXP_ADD] = function(_Buff)
256 266 _Buff._afterRound = function(self)
257 267 local value = self:effect()
258   - if value > 0 then
259   - self.owner:recover(value, self.release)
260   - elseif value < 0 then
261   - self.owner:hurt(-value, self.release, {hurtType = self.buffData.effectValue5 == "1" and 6 or 2, buffId = self.id})
262   - end
  268 + self.owner.battle.player:addExp(value)
263 269 end
264 270 _Buff._effectValue = function(self)
265   - return self._changeV
266   - end
267   - _Buff._getDB = function(self)
268   - return {cv = self._changeV}
  271 + -- 经验值
  272 + return self.buffData.effectValue1 * self.layer
269 273 end
270 274 end,
271 275  
272   - [Buff.EXP_ADD] = function(_Buff)
273   - --cType 0 or nil 值 1 百分比
274   - _Buff._afterRound = function(self)
275   - local value = self:effect()
276   - self.owner.battle.player:addExp(value)
277   - end
  276 + [Buff.DISABLE_BUFF] = function(_Buff)
278 277 _Buff._effectValue = function(self)
279 278 return self.buffData.effectValue1
280 279 end
281 280 end,
282 281  
283   - [Buff.EXP_UP] = function(_Buff)
284   - --cType 0 or nil 值 1 百分比
  282 + [Buff.SP_MAX_CHANGE] = function(_Buff)
  283 + _Buff._init = function(self, data) --初始化变化值
  284 + self:_spChange()
  285 + end
  286 + _Buff._overlay = function(self)
  287 + self:_spChange()
  288 + end
  289 +
  290 + _Buff._uncover = function(self)
  291 + self.owner:reSetSpMax()
  292 + end
  293 +
  294 + _Buff._spChange = function(self)
  295 + local oldSpMax = self.owner.spMax
  296 + self.owner:reSetSpMax()
  297 +
  298 + local curValue = self.owner.spMax - oldSpMax
  299 + self.owner:changeSp(curValue)
  300 + end
  301 +
  302 + _Buff._endBuff = function(self)
  303 + self.owner:reSetSpMax()
  304 + end
  305 +
  306 + _Buff._effectValue = function(self)
  307 + return self.buffData.effectValue1, self.buffData.effectValue2 * self.layer
  308 + end
  309 + end
  310 +
  311 + [Buff.ITEM_GET_UP] = function(_Buff)
285 312 _Buff._effectValue = function(self)
286   - return self.buffData.effectValue1, self.buffData.effectValue2
  313 + -- 值/% 数量 id
  314 + return self.buffData.effectValue1, self.buffData.effectValue2 * self.layer, self.buffData.effectValue3
287 315 end
288 316 end,
289   - [Buff.DISABLE_BUFF] = function(_Buff)
  317 +
  318 + -- 影响到的buff类型 1=生命变化、2=生命上限、3=属性变化、6=伤害变化、7=受伤变化、15=回魔、16=生命变化 (胡博文)
  319 + [Buff.Buff_EFFECT_CHANGE] = function(_Buff)
  320 + _Buff._init = function(self)
  321 + -- 先给自己的buff 搞一下子
  322 + for _, buff in ipairs(self.owner.buffs) do
  323 + if not buff.isDel and buff.classify == self.buffData.effectValue1 then
  324 + buff:effectChange()
  325 + end
  326 + end
  327 + end
290 328 _Buff._effectValue = function(self)
291   - return self.buffData.effectValue1
  329 + return self.buffData.effectValue1, self.buffData.effectValue2 * self.layer
  330 + end
  331 + _Buff._overlay = function(self)
  332 + self:_init()
  333 + end
  334 + _Buff._uncover = function(self)
  335 + self:_init()
292 336 end
293 337 end,
294 338 }
295 339  
  340 +-- 同样的返回 effectValue1, effectValue2 * self.layer 类型的buff
  341 +local function CommonFuncBackEffect12(_Buff)
  342 + _Buff._effectValue = function(self)
  343 + return self.buffData.effectValue1, self:doEffectChange(self.buffData.effectValue2) * self.layer
  344 + end
  345 +end
  346 +
  347 +BuffFactory[Buff.BACK_HURT] = CommonFuncBackEffect12 -- 值/% 数量
  348 +BuffFactory[Buff.HURT_CHANGE] = CommonFuncBackEffect12 -- 值/% 数量
  349 +BuffFactory[Buff.INJURED_CHANGE] = CommonFuncBackEffect12 -- 值/% 数量
  350 +BuffFactory[Buff.HURT_TRANSFER] = CommonFuncBackEffect12 -- 值/% 数量
  351 +BuffFactory[Buff.HURT_ABSORB] = CommonFuncBackEffect12 -- 值/% 数量
  352 +BuffFactory[Buff.CHANGE_DROP] = CommonFuncBackEffect12 -- id 数量
  353 +BuffFactory[Buff.EXP_UP] = CommonFuncBackEffect12 -- 值/% 数量
  354 +-- 历史遗留问题
  355 +BuffFactory[Buff.HP_CHANGE_NOW] = BuffFactory[Buff.HP_CHANGE]
  356 +
296 357 function Buff:ctor(owner, id)
297 358 self.owner = owner
298 359 self.id = id
... ... @@ -301,6 +362,7 @@ function Buff:ctor(owner, id)
301 362 self.roundSpace = 0 --生效间隔
302 363 self.round = 0 --剩余的回合
303 364 self.count = -1 -- 可生效的次数 -1 无次数限制
  365 + self.layer = 1 -- 当前buff 层数
304 366  
305 367 if BuffFactory[self.buffData.type] then
306 368 BuffFactory[self.buffData.type](self)
... ... @@ -322,6 +384,8 @@ end
322 384 function Buff:initNew(release, data)
323 385 self.release = release or self.owner
324 386 self.round = self.buffData.round
  387 + self.roundSpace = 0 --生效间隔
  388 + self.layer = 1
325 389 if self.buffData.effectTime > 0 then
326 390 self.count = self.buffData.effectTime
327 391 end
... ... @@ -339,11 +403,11 @@ function Buff:initByDB(data)
339 403 end
340 404 end
341 405 self.round = data.round
342   - self.roundSpace = data.roundSp -- 可以优化为0的时候不记录
  406 + self.roundSpace = data.roundSp
343 407 if data.count then
344 408 self.count = data.count
345 409 end
346   -
  410 + self.layer = data.layer or 1
347 411 if self._initDB then
348 412 self:_initDB(data)
349 413 end
... ... @@ -352,6 +416,13 @@ end
352 416  
353 417 function Buff:afterRound()
354 418 if self.isDel or self.owner.isDead then return end
  419 +
  420 + -- keepTerm 检查
  421 + if not self:checkKeep() then
  422 + self.isDel = true
  423 + return
  424 + end
  425 +
355 426 if self.roundSpace > 0 then
356 427 self.roundSpace = self.roundSpace - 1
357 428 self:decRound()
... ... @@ -366,6 +437,56 @@ function Buff:afterRound()
366 437 self:decRound()
367 438 end
368 439  
  440 +-- 只使用owner 和 buffData
  441 +function Buff:checkKeep()
  442 + if self.buffData.keepTerm == "" then return true end
  443 + --[[
  444 + 1=怪物id;
  445 + 2=建筑id;
  446 + 3=事件id
  447 + 4=队伍为特定属性时
  448 + --]]
  449 +
  450 + local checkFunc = {}
  451 + checkFunc[1] = function(_, enemyId)
  452 + local enemys = self.owner.battle.player:getTeam(2)
  453 + for _, enemy in pairs(enemys) do
  454 + if enemy.monsterId == enemyId then
  455 + return true
  456 + end
  457 + end
  458 + return false
  459 + end
  460 + checkFunc[2] = function(_, buildId)
  461 + for roomId, room in pairs(self.owner.battle.adv:getCurMap().rooms) do
  462 + for blockId, block in pairs(room.blocks) do
  463 + if block.isOpen and block:getEventType() == AdvEventType.Build and block.event.id == buildId then
  464 + return true
  465 + end
  466 + end
  467 + end
  468 + return false
  469 + end
  470 + checkFunc[3] = function(_, chooseId)
  471 + for roomId, room in pairs(self.owner.battle.adv:getCurMap().rooms) do
  472 + for blockId, block in pairs(room.blocks) do
  473 + if block.isOpen and (block:getEventType() == AdvEventType.Choose or block:getEventType() == AdvEventType.LinkChoose) and block.event.id == chooseId then
  474 + return true
  475 + end
  476 + end
  477 + end
  478 + return false
  479 + end
  480 + checkFunc[4] = function(_, teamAttr)
  481 + local role = self.owner.battle.adv.owner
  482 + return role:getHerosCamp(role:getProperty("advTeam").heros) == teamAttr
  483 + end
  484 +
  485 + local keepTerm = self.buffData.keepTerm:toArray(true, "=")
  486 + if not checkFunc[keepTerm[1]] then return true end
  487 + return checkFunc[keepTerm[1]](table.unpack(keepTerm))
  488 +end
  489 +
369 490 function Buff:decRound()
370 491 if self.buffData.round <= 0 then
371 492 return
... ... @@ -415,8 +536,69 @@ function Buff:decCount()
415 536 end
416 537 end
417 538  
418   -function Buff:getGroup()
419   - return self.buffData.group
  539 +function Buff:getOverlay()
  540 + if self.buffData.overlay == "" then
  541 + return false
  542 + end
  543 + local otype, layer = table.unpack(self.buffData.overlay:toArray(true, "="))
  544 + if otype == 1 then -- 叠加
  545 + return true, layer or 0 -- 0 叠加无数层
  546 + end
  547 + return false
  548 +end
  549 +
  550 +-- 叠加
  551 +function Buff:overlay(releaser, data)
  552 + local otype, maxLayer = self:getOverlay()
  553 + if self.isDel or not otype then -- 新获得的 (不可叠加相当于新获得的)
  554 + self.isDel = false
  555 + self:endBuff()
  556 + self:initNew(releaser, data)
  557 + else
  558 + -- 重置回合 次数
  559 + self.roundSpace = 0
  560 + self.round = self.buffData.round
  561 + if self.buffData.effectTime > 0 then
  562 + self.count = self.buffData.effectTime
  563 + else
  564 + self.count = -1
  565 + end
  566 +
  567 + self.release = releaser or self.release
  568 + -- 叠加层数
  569 + self.layer = self.layer + 1
  570 + if maxLayer ~= 0 then
  571 + self.layer = math.min(maxLayer, self.layer)
  572 + end
  573 + if self._overlay then
  574 + self:_overlay()
  575 + end
  576 + end
  577 +end
  578 +
  579 +-- 扣减层数
  580 +function Buff:uncover()
  581 + if self.layer <= 1 then
  582 + self.isDel = true
  583 + end
  584 +
  585 + self.layer = self.layer - 1
  586 + if self._uncover then
  587 + self:_uncover()
  588 + end
  589 +end
  590 +
  591 +-- buff 效果增益减益
  592 +function Buff:effectChange()
  593 + if self._effectChange then
  594 + self:_effectChange()
  595 + end
  596 +end
  597 +
  598 +function Buff:doEffectChange(effect)
  599 + if not self.buffData.classify then return effect end
  600 + local change = self.owner:getBuffEffectChange(self.buffData.classify)
  601 + return effect * (1 + change)
420 602 end
421 603  
422 604 function Buff:getDB()
... ... @@ -435,6 +617,7 @@ function Buff:getDB()
435 617 if self.count ~= -1 then
436 618 db.count = self.count
437 619 end
  620 + db.layer = self.layer
438 621 return db
439 622 end
440 623  
... ...
src/adv/AdvPlayer.lua
... ... @@ -31,6 +31,7 @@ function BaseObject:initData(data)
31 31 self._miss = data._miss or self.miss
32 32 self._hit = data._hit or self.hit
33 33 self._def = data._def or self.def
  34 + self._hpMax = data._hpMax or self.hpMax
34 35 end
35 36 -- 角色初始化完以后才是 技能和被动技能 方便初始化 buff 的 释放对象
36 37 function BaseObject:initAfter(data)
... ... @@ -124,30 +125,51 @@ function BaseObject:addBuff(buffId, releaser)
124 125 if not buffData then return end
125 126 for _, buff in ipairs(self.buffs) do
126 127 if not buff.isDel and (buff:getType() == Buff.CLEAR_BUFF or buff:getType() == Buff.IMMNUE_BUFF) then
127   - if buff:canEffect(buffId, buffData.group) then
  128 + if buff:canEffect(buffId) then
128 129 buff:effect()
129 130 return
130 131 end
131 132 end
132 133 end
133   - table.insert(self.buffs, Buff.create(self, releaser, {id = buffId}))
134   -
  134 + local oldBuff = self:getBuffById(buffId)
  135 + if oldBuff then
  136 + if not oldBuff:checkKeep() then return end
  137 + oldBuff:overlay(releaser, {}) -- 叠加
  138 + else
  139 + -- 不能保持的buff 也加不上去
  140 + if not Buff.checkKeep({
  141 + owner = self,
  142 + buffData = buffData,
  143 + }) then return end
  144 + table.insert(self.buffs, Buff.create(self, releaser, {id = buffId}))
  145 + end
135 146 self.battle.adv:backBuff(self.id, buffId)
136 147 end
137 148  
  149 +function BaseObject:getBuffById(bId)
  150 + for idx, buff in ipairs(self.buffs) do
  151 + if buff.id == bId then
  152 + return buff
  153 + end
  154 + end
  155 +end
  156 +
138 157 function BaseObject:delBuffById(bId)
139   - for _, buff in ipairs(self.buffs) do
140   - if not buff.isDel and buff.id == bId then
141   - buff.isDel = true
  158 + for idx, buff in ipairs(self.buffs) do
  159 + if buff.id == bId then
  160 + self.battle.adv:backBuff(self.id, buff.id, true)
  161 + buff:endBuff()
  162 + table.remove(self.buffs, idx)
142 163 return buff
143 164 end
144 165 end
145 166 end
146 167  
147 168 function BaseObject:delPassiveById(pId)
148   - for _, passive in ipairs(self.passives) do
149   - if not passive.isDel and passive.id == pId then
150   - passive.isDel = true
  169 + for idx, passive in ipairs(self.passives) do
  170 + if passive.id == pId then
  171 + passive:endPassive()
  172 + table.remove(self.passives, idx)
151 173 return passive
152 174 end
153 175 end
... ... @@ -171,12 +193,12 @@ end
171 193  
172 194  
173 195 -- 通用的buff 效果汇总 -- 0 固定 1百分比 两种分类
174   -function BaseObject:getCommonBuffEffect(bType)
  196 +function BaseObject:getCommonBuffEffect(bType, otherCond)
175 197 local effect, count = {[0] = 0, [1] = 0}, 0
176 198 for _, buff in ipairs(self.buffs) do
177 199 if not buff.isDel and buff:getType() == bType then
178   - local cType, value = buff:effect()
179   - if cType then
  200 + local cType, value, cond = buff:effect()
  201 + if cType and (not otherCond or otherCond == cond) then
180 202 effect[cType] = effect[cType] + value
181 203 count = count + 1
182 204 end
... ... @@ -186,15 +208,13 @@ function BaseObject:getCommonBuffEffect(bType)
186 208 return effect, count --效果 和生效的buff 个数
187 209 end
188 210 --伤害反弹
189   -function BaseObject:getBackHurtBuff(isAtk)
  211 +function BaseObject:getBackHurtBuff()
190 212 local effect = {[0] = 0, [1] = 0}
191 213 for _, buff in ipairs(self.buffs) do
192 214 if not buff.isDel and buff:getType() == Buff.BACK_HURT then
193   - local cType, value, aType = buff:effect() -- aType 0 全部 1 普通攻击
  215 + local cType, value = buff:effect() -- aType 0 全部 1 普通攻击
194 216 if cType then
195   - if aType == 0 or isAtk then
196   - effect[cType] = effect[cType] + value
197   - end
  217 + effect[cType] = effect[cType] + value
198 218 end
199 219 end
200 220 end
... ... @@ -211,12 +231,50 @@ function BaseObject:getInjuredChange()
211 231 local change = self:getCommonBuffEffect(Buff.INJURED_CHANGE)
212 232 return change
213 233 end
  234 +-- 奖励道具变化
  235 +function BaseObject:getRewardChange(itemId)
  236 + local change = self:getCommonBuffEffect(Buff.ITEM_GET_UP, itemId)
  237 + return change
  238 +end
  239 +
  240 +-- buff 增益 检疫
  241 +function BaseObject:getBuffEffectChange(classify)
  242 + local effect = 0
  243 + for _, buff in ipairs(self.buffs) do
  244 + if not buff.isDel and buff:getType() == Buff_EFFECT_CHANGE then
  245 + local cType, value = buff:effect()
  246 + if cType and cType == classify then
  247 + effect = effect + value
  248 + end
  249 + end
  250 + end
  251 + effect = effect / 100
  252 + return effect
  253 +end
  254 +
  255 +function BaseObject:getAttrBuffChange(attr)
  256 + local AttrBuff = {
  257 + [Buff.ATTR_CHANGE] = 1,
  258 + [Buff.ATTR_CHANGE_COND] = 1,
  259 + }
  260 + local effect, count = {[0] = 0, [1] = 0}, 0
  261 + for _, buff in ipairs(self.buffs) do
  262 + if not buff.isDel and AttrBuff[buff:getType()] then
  263 + local cType, value, attrName = buff:effect()
  264 + if cType and attr == attrName then
  265 + effect[cType] = effect[cType] + value
  266 + count = count + 1
  267 + end
  268 + end
  269 + end
  270 + effect[1] = effect[1] / 100
  271 + return effect, count
  272 +end
214 273 --重新计算属性
215 274 function BaseObject:reSetAttr(field)
216 275 local old = self[field]
217 276 self[field] = self["_" .. field] --重置一下
218   - local fieldToBuff = {atk = Buff.ATK_CHANGE, hit = Buff.HIT_CHANGE, miss = Buff.MISS_CHANGE, def = Buff.DEF_CHANGE}
219   - local effect = self:getCommonBuffEffect(fieldToBuff[field])
  277 + local effect = self:getAttrBuffChange(field)
220 278 self[field] = math.ceil((self[field] + effect[0]) * (1 + effect[1]))
221 279 local delta = self[field] - old
222 280 if delta ~= 0 then
... ... @@ -228,6 +286,21 @@ function BaseObject:reSetAttr(field)
228 286 end
229 287 end
230 288  
  289 +-- 重新计算 血量上限
  290 +function BaseObject:reSetHpMax()
  291 + self.hpMax = self._hpMax
  292 + for _, buff in ipairs(self.buffs) do
  293 + if not buff.isDel and buff:getType() == Buff.HP_MAX_CHANGE then
  294 + local cv = buff:effect()
  295 + if cv then
  296 + self.hpMax = self.hpMax + cv
  297 + end
  298 + end
  299 + end
  300 + self.hpMax = math.max(1, self.hpMax)
  301 + self.hp = math.min(self.hpMax, self.hp)
  302 +end
  303 +
231 304 --计算打出伤害加成后的值
232 305 function BaseObject:getHurtValue(value)
233 306 value = value or self.atk
... ... @@ -306,7 +379,7 @@ function BaseObject:hurt(value, releaser, params)
306 379 if value == 0 then return end
307 380 -- 反弹伤害
308 381 if params.hurtType ~= 3 and params.hurtType ~= 5 and releaser and not releaser.isDead then
309   - local backEffect = self:getBackHurtBuff(params.hurtType == 1)
  382 + local backEffect = self:getBackHurtBuff()
310 383 local backValue = math.max(0, value * backEffect[1] + backEffect[0])
311 384 releaser:hurt(backValue, releaser, {hurtType = 3})
312 385 end
... ... @@ -408,9 +481,8 @@ end
408 481  
409 482 function BaseObject:getDB()
410 483 local db = {}
411   - db.hpMax = self.hpMax
412 484 db.hp = self.hp
413   - local baseAttr = {"atk", "miss", "hit", "def"}
  485 + local baseAttr = {"atk", "miss", "hit", "def", "hpMax"}
414 486 for _, field in pairs(baseAttr) do
415 487 db[field] = self[field]
416 488 db["_"..field] = self["_" .. field]
... ... @@ -465,9 +537,11 @@ end
465 537 function Player:initData(data)
466 538 Player.super.initData(self, data)
467 539 self.level = data.level or 1 --level 每增加1级 属性增长 growth * baseAttr
468   - self.growth = data.growth or 0
  540 + self.growth = data.growth
469 541 self.exp = data.exp or 0
470 542 self.sp = data.sp or 100
  543 + self.spMax = data.spMax or 100
  544 + self._spMax = data._spMax or 100
471 545 end
472 546  
473 547 function Player:addExp(value)
... ... @@ -488,15 +562,14 @@ function Player:addExp(value)
488 562 end
489 563 local delta = level - self.level
490 564 if delta > 0 then
491   - local baseAttr = csvdb["adv_unitCsv"][self.battle.adv.chapterId]
492   - for _, attr in pairs(AttsEnumEx) do
493   - if baseAttr[attr] then
494   - self[attr] = self[attr] + self.growth * delta
495   - if attr == "hp" then
496   - self.hpMax = self.hpMax + self.growth * delta
497   - else
498   - self["_" .. attr] = self["_" .. attr] + self.growth * delta
499   - end
  565 + for _, attr in pairs(AdvAttsEnum) do
  566 + if attr == "hp" then
  567 + self[attr] = self[attr] + self.growth[attr] * delta
  568 + self._hpMax = self._hpMax + self.growth[attr] * delta
  569 + self:reSetHpMax()
  570 + else
  571 + self["_" .. attr] = self["_" .. attr] + self.growth[attr] * delta
  572 + self:reSetAttr(attr)
500 573 end
501 574 end
502 575 end
... ... @@ -512,10 +585,19 @@ function Player:changeSp(value, cType)
512 585 elseif cType == 1 then
513 586 self.sp = self.sp + self.sp * value / 100
514 587 end
515   - self.sp = math.floor(math.max(0, self.sp))
  588 + self.sp = math.floor(math.min(self.spMax, math.max(0, self.sp)))
516 589 self.battle.adv:pushBackEvent(AdvBackEventType.SpChange)
517 590 end
518 591  
  592 +-- 重新计算 魔法上限
  593 +function BaseObject:reSetSpMax()
  594 + self.spMax = self._spMax
  595 + local change = self:getCommonBuffEffect(Buff.SP_MAX_CHANGE)
  596 + self.spMax = math.ceil((self.spMax + change[0]) * (1 + change[1]))
  597 + self.spMax = math.max(1, self.spMax)
  598 + self.sp = math.min(self.spMax, self.sp)
  599 +end
  600 +
519 601 --战斗结束了扣战斗buff次数
520 602 function Player:effectBattleBuff()
521 603 for _, buff in ipairs(self.buffs) do
... ... @@ -535,9 +617,10 @@ end
535 617  
536 618 function Player:getDB()
537 619 local db = Player.super.getDB(self)
538   - for _ , field in pairs({"level", "exp", "growth", "sp"}) do
  620 + for _ , field in pairs({"level", "exp", "growth", "sp", "spMax"}) do
539 621 db[field] = self[field]
540 622 end
  623 + db["_spMax"] = self._spMax
541 624 return db
542 625 end
543 626  
... ...
src/adv/AdvTask.lua
... ... @@ -260,8 +260,7 @@ function AdvTask.bind(Adv)
260 260 if status == -1 or count < achievData.pt then return end
261 261  
262 262 local reward = self.owner:award(achievData.reward)
263   - self.owner:changeUpdates({{type = "advAchiev", field = {chapterId, "pts", taskId}, value = -1}}, notNotify)
264   -
  263 + insertChange(chapterId, taskId, -1)
265 264 return true, reward
266 265 end
267 266  
... ...
src/models/Role.lua
... ... @@ -65,7 +65,9 @@ Role.schema = {
65 65 advL = {"table", {0, 0}}, -- 冒险队等级 {lv, winCount}
66 66 advElM = {"number", 0}, -- 无尽模式通关的最高层数 endless max layer
67 67 advElS = {"number", globalCsv.adv_endless_season}, -- 无尽模式记录的赛季 endless season
68   - advAFOpen = {"table", {}}, -- 解锁的神器
  68 + advAFOpen = {"table", {}}, -- 解锁的神器 {[id] = 1}
  69 + advAFGet = {"table", {}}, -- 当前拥有的神器 {[id] = 等级}
  70 + advAFWear = {"table", {}}, -- 当前拥有的神器 {[slot] = id}
69 71  
70 72 --挂机相关
71 73 hangPass = {"table", {}}, -- 挂机通过的最大关卡
... ... @@ -244,6 +246,8 @@ function Role:data()
244 246 advAchiev = self:getProperty("advAchiev"),
245 247 advL = self:getProperty("advL"),
246 248 advElM = self:getProperty("advElM"),
  249 + advAFGet = self:getProperty("advAFGet"),
  250 + advAFWear = self:getProperty("advAFWear"),
247 251  
248 252 hangPass = self:getProperty("hangPass"),
249 253 hangTeam = self:getProperty("hangTeam"),
... ...
src/models/RolePlugin.lua
... ... @@ -641,6 +641,25 @@ function RolePlugin.bind(Role)
641 641 return result
642 642 end
643 643  
  644 + function Role:getHerosCamp(heros)
  645 + local had = {}
  646 + for _, id in pairs(heros or {}) do
  647 + local hero = self.heros[id]
  648 + if hero then
  649 + local camp = csvdb["unitCsv"][hero:getProperty("type")].camp
  650 + had[camp] = (had[camp] or 0) + 1
  651 + end
  652 + end
  653 + local curCamp = 0
  654 + for camp , count in pairs(had) do
  655 + if count >= 3 then
  656 + curCamp = camp
  657 + break
  658 + end
  659 + end
  660 + return curCamp
  661 + end
  662 +
644 663 function Role:getRealBattleValue(heros, activeRelation) -- 获取队伍战斗力 羁绊加成
645 664 heros = heros or {}
646 665 local activeRelation = activeRelation or self:getHeroActiveRelation(heros)
... ... @@ -673,6 +692,23 @@ function RolePlugin.bind(Role)
673 692 return self:getProperty("funcLv")[func] or 1
674 693 end
675 694  
  695 + -- 参数有level 则是检查是否可以升级
  696 + function Role:isArtifactOpen(id, isEndless, level)
  697 + local isCheckLevel = not not level
  698 + level = level or 1
  699 + local curData = (csvdb["adv_artifactCsv"][id] or {})[level]
  700 + if not curData then return false end
  701 +
  702 + if curData.unlock == 1 then -- 获得解锁
  703 + return self:getProperty("advAFOpen")[id] and true or false
  704 + elseif temp[1].unlock == 2 then -- 特殊神器 不可解锁
  705 + return isCheckLevel
  706 + elseif temp[1].unlock == 3 then
  707 + return isEndless
  708 + end
  709 + return true
  710 + end
  711 +
676 712 function Role:funcOpen(func, count)
677 713 count = count or 1
678 714 if csvdb["itemCsv"][func] and csvdb["itemCsv"][func].type == ItemType.FuncOpen then
... ...