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

232 lines
9.5 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

local effect = require("Modules/Battle/Logic/Base/Effect")
local floor = math.floor
local max = math.max
local min = math.min
--local BattleConst = BattleConst
--local RoleDataName = RoleDataName
--local BattleEventName = BattleEventName
local effectPool = BattleObjectPool.New(function ()
return { type = 0, args = {}} -- type, {args, ...}
end)
local effectGroupPool = BattleObjectPool.New(function ()
return { chooseId = 0, duration = 0, effects = {}} -- chooseId, duration, {effect1, effect2, ...}
end)
Skill = {}
function Skill:New()
local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass=0,isTeamSkill=false,teamSkillType=0 }
setmetatable(o, self)
self.__index = self
return o
end
function Skill:Init(role, effectData, type) --type 0 异妖 1 点技 2 滑技
local isTeamSkill = type == 0
self.type = type
--skill = {技能ID, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
--效果 = {效果类型id, 效果参数1, 效果参数2, ...}
self.effectList:Clear()
self.owner = role
self.isTeamSkill = isTeamSkill
self.teamSkillType = isTeamSkill and floor(effectData[1] / 100) or 0
self.id = effectData[1] -- 技能ID
-- self.EffectDuration = 0 -- 效果命中需要的时间
for i=2, #effectData do
local v = effectData[i]
local effectGroup = effectGroupPool:Get() -- chooseId, duration, {effect1, effect2, ...}
effectGroup.chooseId = v[1] --chooseId
effectGroup.duration = v[2] --duration
for j=3, #v do --effectList
local effect = effectPool:Get() -- type, {args, ...}
effect.type = v[j][1]
for k=2, #v[j] do
effect.args[k-1] = v[j][k]
end
effectGroup.effects[j-2] = effect
end
self.effectList:Add(effectGroup)
end
end
function Skill:Dispose()
while self.effectList.size > 0 do
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
end
effectPool:Put(effect)
effectGroup.effects[k] = nil
end
effectGroupPool:Put(effectGroup)
self.effectList:Remove(self.effectList.size)
end
end
local function takeEffect(caster, target, effects, duration, skill)
for k=1, #effects do
local e = effects[k]
effect[e.type](caster, target, e.args, duration, skill)
if BattleLogic.IsOpenBattleRecord then
BattleLogic.RecordEffect(caster, target, e.type, e.args, duration)
end
end
end
-- 释放技能
-- func 技能释放完成回调
-- targets 指定技能释放目标
-- isAdd 是否是追加技能
function Skill:Cast(func, targets, isAdd)
self.castDoneFunc = func
self.effectTargets = {}
self.isAdd = isAdd
for i=1, self.effectList.size do
local effectGroup = self.effectList.buffer[i]
local chooseId = effectGroup.chooseId
local arr = targets or BattleUtil.ChooseTarget(self.owner, chooseId)
if #arr > 0 then
--效果延迟1帧生效
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
local duration = effectGroup.duration
local effects = effectGroup.effects
local weight = floor(chooseId % 10000 / 100)
local count = min(chooseId % 10, #arr)
if count == 0 then
count = #arr
end
-- 全部同时生效
for j=1, count do
if arr[j] and not arr[j].isDead then
takeEffect(self.owner, arr[j], effects, duration, self)
-- 加入目标列表
table.insert(self.effectTargets, arr[j])
end
end
-- if chooseId == 100000 or chooseId == 200000 then --10000 我方aoe 20000 敌方aoe
-- local camp = chooseId == 100000 and self.owner.camp or 1 - self.owner.camp
-- self.owner.Event:DispatchEvent(BattleEventName.AOE, camp)
-- for j=1, count do
-- takeEffect(self.owner, arr[j], effects, duration, self)
-- -- 加入目标列表
-- table.insert(self.effectTargets, arr[j])
-- end
-- elseif weight == 7 then --对位相邻的目标同时触发效果
-- for j=1, count do
-- takeEffect(self.owner, arr[j], effects, duration, self)
-- -- 加入目标列表
-- table.insert(self.effectTargets, arr[j])
-- end
-- else
-- for j = 1, count do
-- local index = j
-- local r = arr[index]
-- -- if not r or r.isDead then --当被选取的目标已经死亡或者没有,则重新选取,若重新选取的目标也死亡或者没有,则从之前的目标中选取第一个不死亡的
-- -- if not targets then -- 如果是指定目标释放的则不再选取目标
-- -- arr = BattleUtil.ChooseTarget(self.owner, chooseId)
-- -- r = arr[index]
-- -- if not r then --当没有新增的被选取目标时,可能为空
-- -- for i=1, #arr do
-- -- if not arr[i].isDead then
-- -- r = arr[i]
-- -- break
-- -- end
-- -- end
-- -- end
-- -- end
-- -- end
-- --
-- if r and not r.isDead then
-- takeEffect(self.owner, r, effects, duration, self)
-- -- 加入目标列表
-- table.insert(self.effectTargets, r)
-- end
-- end
-- end
end)
end
end
-- 计算技能CD的没有用了
-- if not self.isTeamSkill then
-- local type = BattleLogic.Type
-- local isPVEMonster = self.owner.camp == 1 and (type == 1 or type == 2 or type == 4 or type == 5 or type == 8)
-- local time = 0
-- if isPVEMonster then
-- if self.owner.superSkill == self then
-- --怪物绝技读条时间=max10-速度/8*(等级+10,2)
-- time = max(10-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 2)
-- else
-- --怪物普技读条时间==max9-速度/8*(等级+10,1)
-- time = max(9-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1)
-- end
-- else
-- if self.owner.superSkill == self then
-- --绝技读条时间=max9-速度/8*(等级+10,3)
-- time = max(9-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 3)
-- else
-- --普技读条时间=max7-速度/8*(等级+10,1.5)
-- time = max(7-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5)
-- end
-- end
-- self.owner.sp = 0
-- self.owner.spPass = floor(BattleUtil.ErrorCorrection(time) * BattleLogic.GameFrameRate)
-- else
-- self.owner.curSkill = self
-- end
--
if self.isTeamSkill then
self.owner.curSkill = self
end
-- 延时一帧执行,避免战斗还没开始就释放了技能
-- BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function()
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self)
-- end)
--技能的施法时间计算根据当前目标id关联的持续时间取其中时间最长的一个
local duration = 0
for i=1, self.effectList.size do
duration = max(duration, self.effectList.buffer[i].duration)
end
BattleLogic.SetSkillUsable(self.owner.camp, false)
BattleLogic.WaitForTrigger(duration, function()
BattleLogic.SetSkillUsable(self.owner.camp, true)
self.owner.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCastEnd, self)
for _, tr in ipairs(self.effectTargets) do
tr.Event:DispatchEvent(BattleEventName.BeSkillCastEnd, self)
end
-- 技能结束
self:EndSkill()
end)
end
-- 结束技能
function Skill:EndSkill()
-- 技能结束后摇后结束技能释放
-- if self.isAdd then
-- if self.castDoneFunc then self.castDoneFunc() end
-- else
-- 非追加技能加入技能后摇
BattleLogic.WaitForTrigger(0.5, function()
if self.castDoneFunc then self.castDoneFunc() end
end)
-- end
--
self.effectTargets = {}
self.isAdd = nil
end