miduo_server/luafight/Modules/Battle/Logic/Base/Skill.lua

273 lines
9.6 KiB
Lua
Raw Normal View History

2019-03-12 14:05:45 +08:00
local effect = require("Modules/Battle/Logic/Base/Effect")
local floor = math.floor
local max = math.max
2019-03-21 14:33:56 +08:00
local min = math.min
2019-03-12 14:05:45 +08:00
--local BattleConst = BattleConst
--local RoleDataName = RoleDataName
--local BattleEventName = BattleEventName
2019-03-25 10:58:38 +08:00
local effectPool = BattleObjectPool.New(function ()
2019-04-17 21:04:32 +08:00
return { type = 0, args = {}} -- type, {args, ...}
2019-03-25 10:58:38 +08:00
end)
local effectGroupPool = BattleObjectPool.New(function ()
2020-07-18 21:06:17 +08:00
return { chooseId = 0, effects = {}} -- chooseId, {effect1, effect2, ...}
2019-03-25 10:58:38 +08:00
end)
2019-03-12 14:05:45 +08:00
Skill = {}
2019-03-21 14:33:56 +08:00
function Skill:New()
2019-10-23 13:40:57 +08:00
local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass=0,isTeamSkill=false,teamSkillType=0 }
2019-03-21 14:33:56 +08:00
setmetatable(o, self)
self.__index = self
return o
end
2020-05-02 05:12:07 +08:00
function Skill:Init(role, effectData, type, targets, isAdd, isRage) --type 0 异妖 1 点技 2 滑技
2019-10-10 11:03:42 +08:00
local isTeamSkill = type == 0
2020-04-10 14:52:41 +08:00
self.type = type
2020-07-18 21:06:17 +08:00
--skill = {技能ID, 命中时间, 持续时间, 伤害次数, {目标id1, 效果1, 效果2, ...},{目标id2, 效果3, 效果4, ...}, ...}
2019-03-12 14:05:45 +08:00
--效果 = {效果类型id, 效果参数1, 效果参数2, ...}
2019-03-21 14:33:56 +08:00
self.effectList:Clear()
self.owner = role
2019-07-25 16:20:33 +08:00
self.isTeamSkill = isTeamSkill
self.teamSkillType = isTeamSkill and floor(effectData[1] / 100) or 0
2020-08-02 23:44:02 +08:00
self.id = effectData[1] -- 技能ID
2020-07-18 21:06:17 +08:00
self.hitTime = effectData[2] -- 效果命中需要的时间
self.continueTime = effectData[3] -- 命中后伤害持续时间
self.attackCount = effectData[4] -- 伤害持续时间内伤害次数
2020-10-29 15:36:43 +08:00
self.isTriggePassivity = false -- 是否一个技能只触发一次被动 true每次释放技能只会触发一次
self.triggerPassivityId={}
2020-05-02 05:12:07 +08:00
self.targets = targets or {}
self.isAdd = isAdd
self.isRage = isRage
2020-10-29 15:36:43 +08:00
self.isKill = false --是否技能击杀目标
2020-07-18 21:06:17 +08:00
for i=5, #effectData do
2019-04-17 21:04:32 +08:00
local v = effectData[i]
2020-07-18 21:06:17 +08:00
local effectGroup = effectGroupPool:Get() -- chooseId, {effect1, effect2, ...}
2020-08-02 23:44:02 +08:00
effectGroup.chooseId = v[1] -- chooseId
2020-07-18 21:06:17 +08:00
for j=2, #v do -- effectList
2019-03-25 10:58:38 +08:00
local effect = effectPool:Get() -- type, {args, ...}
2019-04-17 21:04:32 +08:00
effect.type = v[j][1]
2019-03-12 14:05:45 +08:00
for k=2, #v[j] do
2019-04-17 21:04:32 +08:00
effect.args[k-1] = v[j][k]
2019-03-12 14:05:45 +08:00
end
2020-07-18 21:06:17 +08:00
effectGroup.effects[j-1] = effect
2019-03-12 14:05:45 +08:00
end
2019-03-21 14:33:56 +08:00
self.effectList:Add(effectGroup)
2019-03-12 14:05:45 +08:00
end
2019-03-21 14:33:56 +08:00
end
2019-03-12 14:05:45 +08:00
2019-03-25 10:58:38 +08:00
function Skill:Dispose()
while self.effectList.size > 0 do
2019-04-17 21:04:32 +08:00
local effectGroup = self.effectList.buffer[self.effectList.size]
for k=1, #effectGroup.effects do
local effect = effectGroup.effects[k]
for j=1, #effect.args do
effect.args[j] = nil
2019-03-25 19:41:30 +08:00
end
effectPool:Put(effect)
2019-04-17 21:04:32 +08:00
effectGroup.effects[k] = nil
2019-03-25 10:58:38 +08:00
end
effectGroupPool:Put(effectGroup)
self.effectList:Remove(self.effectList.size)
end
end
2020-07-18 21:06:17 +08:00
local function DoEffect(caster, target, eff, duration, skill)
2020-08-02 23:44:02 +08:00
local e = {type = 0, args = {}}
2020-07-18 21:06:17 +08:00
e.type = eff.type
for i=1, #eff.args do
e.args[i] = eff.args[i]
2020-08-02 23:44:02 +08:00
end
2020-04-21 20:51:31 +08:00
2020-08-02 23:44:02 +08:00
-- 检测被动技能对技能参数的影响
local function _PassiveCheck(pe)
if pe then
e = pe
2020-04-21 20:51:31 +08:00
end
2020-08-02 23:44:02 +08:00
end
caster.Event:DispatchEvent(BattleEventName.SkillEffectBefore, skill, e, _PassiveCheck)
target.Event:DispatchEvent(BattleEventName.BeSkillEffectBefore, skill, e, _PassiveCheck)
2020-04-21 20:51:31 +08:00
2020-08-02 23:44:02 +08:00
--
if effect[e.type] then
effect[e.type](caster, target, e.args, duration, skill)
2020-06-26 00:42:16 +08:00
2020-08-02 23:44:02 +08:00
BattleLogManager.Log(
"Take Effect",
"tcamp", target.camp,
"tpos", target.position,
"type", e.type
)
2019-03-12 14:05:45 +08:00
end
2020-08-02 23:44:02 +08:00
end
2020-07-18 21:06:17 +08:00
function Skill:takeEffect(caster, target, effects, effectIndex, duration, skill)
for k=1, #effects do
-- 如果不是第一个效果对列的第一个效果则判断是否命中
if k ~= 1 and effectIndex == 1 then
if self:CheckTargetIsHit(target) then
DoEffect(caster, target, effects[k], duration, skill)
end
else
DoEffect(caster, target, effects[k], duration, skill)
end
end
2019-03-12 14:05:45 +08:00
end
2020-04-10 14:52:41 +08:00
-- 释放技能
-- func 技能释放完成回调
2020-05-02 05:12:07 +08:00
function Skill:Cast(func)
2020-04-10 14:52:41 +08:00
self.castDoneFunc = func
self.effectTargets = {}
2020-07-18 21:06:17 +08:00
self.targetIsHit = {}
2020-10-29 15:36:43 +08:00
self.isTriggePassivity=false
self.triggerPassivityId={}
2020-04-16 15:10:04 +08:00
-- 先计算出技能的目标
for i=1, self.effectList.size do
-- 是否重新选择目标
local isReTarget = true
2020-05-02 05:12:07 +08:00
if self.targets and self.targets[i] then
self.effectTargets[i] = self.targets[i]
2020-04-16 15:10:04 +08:00
-- 判断是否有有效目标
for _, role in ipairs(self.effectTargets[i]) do
2020-05-06 16:49:24 +08:00
if not role:IsRealDead() then
2020-04-16 15:10:04 +08:00
isReTarget = false
end
end
end
2020-05-02 05:12:07 +08:00
-- 重新选择目标a
2020-04-16 15:10:04 +08:00
if isReTarget then
local effectGroup = self.effectList.buffer[i]
local chooseId = effectGroup.chooseId
self.effectTargets[i] = BattleUtil.ChooseTarget(self.owner, chooseId)
2020-05-11 11:53:05 +08:00
-- 检测被动对攻击目标的影响
if i == 1 then
local function _PassiveTarget(targets)
self.effectTargets[i] = targets
end
self.owner.Event:DispatchEvent(BattleEventName.SkillTargetCheck, _PassiveTarget)
end
2020-04-16 15:10:04 +08:00
end
end
2020-06-26 00:42:16 +08:00
--
BattleLogManager.Log(
"Cast Skill",
"camp", self.owner.camp,
"pos", self.owner.position,
"type", self.type,
"isRage", tostring(self.isRage),
"isAdd", tostring(self.isAdd)
)
2020-04-16 15:10:04 +08:00
-- 对目标造成相应的效果
2019-03-21 14:33:56 +08:00
for i=1, self.effectList.size do
local effectGroup = self.effectList.buffer[i]
2019-04-17 21:04:32 +08:00
local chooseId = effectGroup.chooseId
2020-04-16 15:10:04 +08:00
local arr = self.effectTargets[i]
if arr and #arr > 0 then
2020-08-02 23:44:02 +08:00
-- 效果延迟1帧生效
2019-04-17 21:04:32 +08:00
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
local effects = effectGroup.effects
2019-10-23 13:40:57 +08:00
local weight = floor(chooseId % 10000 / 100)
2019-05-10 19:31:20 +08:00
local count = min(chooseId % 10, #arr)
2019-05-07 20:01:07 +08:00
if count == 0 then
count = #arr
end
2020-04-10 14:52:41 +08:00
-- 全部同时生效
for j=1, count do
2020-08-02 23:44:02 +08:00
if arr[j] and not arr[j]:IsRealDead() then
2020-07-18 21:06:17 +08:00
-- 检测是否命中
if i == 1 then
self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.owner, arr[j])
end
self:takeEffect(self.owner, arr[j], effects, i, self.hitTime, self)
-- if i == 1 then
-- self.targetIsHit[arr[j]] = BattleUtil.CheckIsHit(self.owner, arr[j])
-- takeEffect(self.owner, arr[j], effects, self.hitTime, self)
-- else
-- -- 未命中的目标不会产生后续技能效果
-- if self:CheckTargetIsHit(arr[j]) then
-- takeEffect(self.owner, arr[j], effects, self.hitTime, self)
-- end
-- end
2019-03-12 14:05:45 +08:00
end
end
end)
end
end
2019-04-17 21:04:32 +08:00
2020-04-10 14:52:41 +08:00
if self.isTeamSkill then
2019-07-11 15:18:00 +08:00
self.owner.curSkill = self
2019-04-17 21:04:32 +08:00
end
2020-04-10 14:52:41 +08:00
2020-04-16 15:10:04 +08:00
-- 释放技能开始
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
-- 只对效果1的目标发送事件效果1是技能的直接伤害目标
for _, tr in ipairs(self.effectTargets[1]) do
tr.Event:DispatchEvent(BattleEventName.BeSkillCast, self)
end
2019-05-07 20:01:07 +08:00
--技能的施法时间计算根据当前目标id关联的持续时间取其中时间最长的一个
2020-07-18 21:06:17 +08:00
local duration = self.hitTime + self.continueTime
2020-04-16 15:10:04 +08:00
-- 结算时间向后延长0.2秒,避免在效果结算完成前就结束了技能释放
2020-10-29 15:36:43 +08:00
BattleLogic.WaitForTrigger(duration + 0.8, function()
2019-10-23 13:40:57 +08:00
self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
2020-10-29 15:36:43 +08:00
2020-04-16 15:10:04 +08:00
-- 只对效果1的目标发送事件效果1是技能的直接伤害目标
for _, tr in ipairs(self.effectTargets[1]) do
2020-04-10 14:52:41 +08:00
tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
end
-- 技能结束
self:EndSkill()
2020-10-29 15:36:43 +08:00
--技能消息发送完后 iskill 设置为false
self.isKill=false
2019-04-17 21:04:32 +08:00
end)
2019-03-12 14:05:45 +08:00
2020-04-10 14:52:41 +08:00
end
2019-03-12 14:05:45 +08:00
2020-04-16 15:10:04 +08:00
2020-07-18 21:06:17 +08:00
-- 获取技能的直接目标,和策划规定第一个效果的目标为直接效果目标,(包含miss的目标)
2020-04-16 15:10:04 +08:00
function Skill:GetDirectTargets()
return self.effectTargets[1]
end
2020-07-18 21:06:17 +08:00
-- 获取直接目标不包含miss的目标可能为空
function Skill:GetDirectTargetsNoMiss()
local list = {}
for _, role in ipairs(self.effectTargets[1]) do
2020-07-17 11:54:33 +08:00
if self:CheckTargetIsHit(role) then
2020-07-18 21:06:17 +08:00
table.insert(list, role)
end
end
return list
end
2020-04-21 20:51:31 +08:00
-- 获取技能目标最大人数
function Skill:GetMaxTargetNum()
local mainEffect = self.effectList.buffer[1]
if not mainEffect then
return 0
end
return BattleUtil.GetMaxTargetNum(mainEffect.chooseId)
end
2020-08-02 23:44:02 +08:00
2020-07-18 21:06:17 +08:00
-- 判断是否命中
function Skill:CheckTargetIsHit(role)
return self.targetIsHit[role]
end
2020-04-16 15:10:04 +08:00
2020-04-10 14:52:41 +08:00
-- 结束技能
function Skill:EndSkill()
2020-04-16 15:10:04 +08:00
-- 技能后摇
2020-04-10 14:52:41 +08:00
-- 技能结束后摇后结束技能释放
2020-04-16 15:10:04 +08:00
BattleLogic.WaitForTrigger(0.3, function()
-- 结束回调
2020-10-29 15:36:43 +08:00
self.isTriggePassivity=false
self.triggerPassivityId={}
2020-04-16 15:10:04 +08:00
if self.castDoneFunc then self.castDoneFunc() end
end)
2020-04-10 14:52:41 +08:00
--
self.effectTargets = {}
end