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

289 lines
11 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 gameFrameRate = BattleLogic.GameFrameRate
--local BattleConst = BattleConst
--local RoleDataName = RoleDataName
--local BattleEventName = BattleEventName
local function chooseTarget(role, chooseId, exceptList)
local chooseType = floor(chooseId / 10000) % 10
local chooseWeight = floor(chooseId / 100) % 10
local sort = floor(chooseId / 10) % 10
local exceptNum = exceptList.size
local num = chooseId % 10
local arr
if chooseType == 1 then
arr = BattleLogic.Query(function (r)
for i=1, exceptList.size do
if r.uid == exceptList.buffer[i].uid then
return false
end
end
return r.camp == role.camp
end)
elseif chooseType == 2 then
if role.lockTarget and num == 1 then
return {role.lockTarget}
end
arr = BattleLogic.Query(function (r)
for i=1, exceptList.size do
if r.uid == exceptList.buffer[i].uid then
return false
end
end
return r.camp ~= role.camp
end)
elseif chooseType == 3 then
return {role}
elseif chooseType == 4 then
return {BattleLogic.GetAggro(role.camp)}
else
arr = BattleLogic.Query()
end
BattleUtil.RandomList(arr)
if chooseWeight == 0 then
BattleUtil.RandomList(arr)
elseif chooseWeight == 1 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.Hp)
local r2 = b:GetRoleData(RoleDataName.Hp)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 2 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.Hp) / a:GetRoleData(RoleDataName.MaxHp)
local r2 = b:GetRoleData(RoleDataName.Hp) / b:GetRoleData(RoleDataName.MaxHp)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 3 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.Attack)
local r2 = b:GetRoleData(RoleDataName.Attack)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 4 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.PhysicalDefence)
local r2 = b:GetRoleData(RoleDataName.PhysicalDefence)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 5 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.PhysicalDefence)
local r2 = b:GetRoleData(RoleDataName.PhysicalDefence)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 6 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.MagicDefence)
local r2 = b:GetRoleData(RoleDataName.MagicDefence)
return sort == 1 and r1 < r2 or r1 > r2
end)
elseif chooseWeight == 7 then
BattleUtil.Sort(arr, function(a, b)
local r1 = a:GetRoleData(RoleDataName.MagicDefence)
local r2 = b:GetRoleData(RoleDataName.MagicDefence)
return sort == 1 and r1 < r2 or r1 > r2
end)
end
if exceptNum > 0 then
local count = #arr
for i=1, min(exceptNum, count) do
for j=count, i+1, -1 do
arr[j] = arr[j-1]
end
arr[i] = exceptList.buffer[i]
end
end
return arr
end
Skill = {}
function Skill:New()
local o = {cd=0,effectList = BattleList.New(),owner=0,sp=0,spPass = 0,choosedList = BattleList.New(),isTeamSkill=false }
setmetatable(o, self)
self.__index = self
return o
end
function Skill:Init(role, effectData)
self.cd = effectData[1]
--skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
--效果 = {效果类型id, 效果参数1, 效果参数2, ...}
self.effectList:Clear()
self.owner = role
self.sp = 0
self.spPass = 0
self.choosedList:Clear()
self.isTeamSkill = false
local v
for i=2, #effectData do
v = effectData[i]
local effectGroup = { 0, 0, {}} -- chooseId, duration, {effect1, effect2, ...}
effectGroup[1] = v[1] --chooseId
effectGroup[2] = v[2] --duration
for j=3, #v do --effectList
local effect = {0, {}} -- type, {args, ...}
effect[1] = v[j][1]
for k=2, #v[j] do
effect[2][k-1] = v[j][k]
end
effectGroup[3][j-2] = effect
end
self.effectList:Add(effectGroup)
end
end
function Skill:ResetCD()
if not self.isTeamSkill then
if self.owner.superSkill == self then
self.sp = 0
self.spPass = floor(self.cd * BattleLogic.GameFrameRate)
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
BattleLogic.AddMP(self.owner.camp, 10)
if self.owner.skill then
local skill = self.owner.skill
local time = max(6-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5)
skill.sp = 0
skill.spPass = floor(time * BattleLogic.GameFrameRate)
end
else
local time = max(6-self.owner:GetRoleData(RoleDataName.Speed)/(8*(self.owner:GetRoleData(RoleDataName.Level)+10)), 1.5)
self.sp = 0
self.spPass = floor(time * BattleLogic.GameFrameRate)
BattleLogic.AddMP(self.owner.camp, 8)
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
end
else
BattleLogic.Event:DispatchEvent(BattleEventName.SkillCast, self.cd) --队伍技能结构和其他相同只是cd项为对应异妖类型
end
local duration = 0
for i=1, self.effectList.size do
duration = max(duration, self.effectList.buffer[i][2])
end
BattleLogic.SetSkillUsable(self.owner.camp, false)
BattleLogic.WaitForTrigger(duration, function()
BattleLogic.SetSkillUsable(self.owner.camp, true)
end)
BattleLogic.SetAggro(self.owner, 0)
end
local function takeEffect(type, caster, target, args, interval)
effect[type](caster, target, args, interval)
if BattleLogic.IsOpenBattleRecord then
BattleLogic.RecordEffect(caster, target, type, args, interval)
end
end
function Skill:Cast()
for i=1, self.effectList.size do
local effectGroup = self.effectList.buffer[i]
local chooseId = effectGroup[1]
local duration = effectGroup[2]
local arr = chooseTarget(self.owner, chooseId, self.choosedList)
if #arr > 0 then
--延迟1帧释放效果
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function ()
local nn = floor(chooseId / 10000) % 10
if self.owner.camp == 0 and nn == 2 then --我方释放效果开始切镜头
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomIn, 0.3)
BattleLogic.WaitForTrigger(duration, function()
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomOut, 0.3)
end)
end
if chooseId == 10000 then --我方aoe
self.owner.Event:DispatchEvent(BattleEventName.AOE, 0)
for j=1, #arr do
for k=1, #effectGroup[3] do
local v = effectGroup[3][k]
takeEffect(v[1], self.owner, arr[j], v[2], duration)
end
end
elseif chooseId == 20000 then --敌方aoe
self.owner.Event:DispatchEvent(BattleEventName.AOE, 1)
for j=1, #arr do
for k=1, #effectGroup[3] do
local v = effectGroup[3][k]
takeEffect(v[1], self.owner, arr[j], v[2], duration)
end
end
elseif nn == 1 or nn == 3 then
for j=1, #arr do
for k=1, #effectGroup[3] do
local v = effectGroup[3][k]
takeEffect(v[1], self.owner, arr[j], v[2], duration)
end
end
else
local count = chooseId % 10
local d = duration / (count + 1) --分割多人目标施加效果的时间按照1+1+..+2的时间权重占比分配
for j=1, count do
local index = j
local cd = j == count and d * 2 or d
BattleLogic.WaitForTrigger(d * (j-1), function()
local r = arr[index]
if not r or r.isDead then --当被选取的目标已经死亡或者没有,则重新选取,若重新选取的目标也死亡或者没有,则从之前的目标中选取第一个不死亡的
arr = chooseTarget(self.owner, chooseId, self.choosedList)
r = arr[index]
if not r then --当没有新增的被选取目标时,可能为空
for i=1, #arr do
if not arr[i].isDead then
r = arr[i]
for k=1, #effectGroup[3] do
local v = effectGroup[3][k]
takeEffect(v[1], self.owner, r, v[2], cd)
end
return
end
end
if not r then
return
end
end
end
self.choosedList:Add(r)
for k=1, #effectGroup[3] do
local v = effectGroup[3][k]
takeEffect(v[1], self.owner, r, v[2], cd)
end
end)
end
BattleLogic.WaitForTrigger(duration, function()
self.choosedList:Clear()
end)
end
end)
end
end
self:ResetCD()
end
--表现层调用
function Skill:CanManualCast()
return not self.owner.IsDebug and self.owner.camp == 0 and not self.owner.Auto and self.sp >= self.spPass and BattleLogic.GetSkillUsable(self.owner.camp)
end
--表现层调用
function Skill:ManualCast()
--非调试模式下,只有我方阵营角色,且处在非自动状态下可手动释放技能
local b = self:CanManualCast()
--调试模式下,可无条件手动释放技能
local b2 = self.owner.IsDebug
if b or b2 then
if self.owner.skill == self then
BattleLogic.AddOption(2, self.owner.uid)
else
BattleLogic.AddOption(3, self.owner.uid)
end
end
end