275 lines
11 KiB
Lua
275 lines
11 KiB
Lua
local effect = require("Modules/Battle/Logic/Base/Effect")
|
||
local floor = math.floor
|
||
local max = math.max
|
||
--local BattleConst = BattleConst
|
||
--local RoleDataName = RoleDataName
|
||
--local BattleEventName = BattleEventName
|
||
local function queryExceptList(r, exceptList)
|
||
if not exceptList then return true end
|
||
for i=1, #exceptList do
|
||
if r.uid == exceptList[i].uid then
|
||
return false
|
||
end
|
||
end
|
||
return true
|
||
end
|
||
local function queryAllies(role, exceptList)
|
||
return function (r) return r.camp == role.camp and queryExceptList(r, exceptList) end
|
||
end
|
||
local function queryAlliesExceptSelf(role, exceptList)
|
||
return function (r) return r.camp == role.camp and r.uid ~= role.uid and queryExceptList(r, exceptList) end
|
||
end
|
||
local function queryEnemy(role, exceptList)
|
||
return function (r) return r.camp ~= role.camp and queryExceptList(r, exceptList) end
|
||
end
|
||
|
||
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
|
||
local num = chooseId % 10
|
||
|
||
local arr = {}
|
||
if chooseType == 1 then
|
||
arr = BattleLogic.Query(queryAllies(role, exceptList))
|
||
elseif chooseType == 2 then
|
||
if role.lockTarget and num == 1 then
|
||
return {role.lockTarget}
|
||
end
|
||
arr = BattleLogic.Query(queryEnemy(role, exceptList))
|
||
elseif chooseType == 3 then
|
||
return {role}
|
||
elseif chooseType == 4 then
|
||
return {BattleLogic.GetAggro(role.camp)}
|
||
end
|
||
|
||
if chooseWeight == 0 then
|
||
BattleUtil.RandomList(arr)
|
||
elseif chooseWeight == 1 then
|
||
table.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
|
||
table.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
|
||
table.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
|
||
table.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
|
||
table.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
|
||
table.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
|
||
table.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
|
||
|
||
local arr2 = {}
|
||
for i=1, exceptNum do
|
||
arr2[i] = exceptList[i]
|
||
end
|
||
if #arr >= num then
|
||
for i=1+exceptNum, num == 0 and #arr or num do
|
||
arr2[i] = arr[i]
|
||
end
|
||
end
|
||
arr = arr2
|
||
return arr
|
||
end
|
||
|
||
Skill = {}
|
||
|
||
function Skill:New(role, effectData)
|
||
local o = {}
|
||
o.cd = effectData[1]
|
||
|
||
--skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
|
||
--效果 = {效果类型id, 效果参数1, 效果参数2, ...}
|
||
o.effectList = {}
|
||
|
||
o.owner = role
|
||
o.sp = 0
|
||
o.spPass = 0
|
||
o.choosedList = {}
|
||
|
||
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
|
||
o.effectList[i-1] = effectGroup
|
||
end
|
||
setmetatable(o, self)
|
||
self.__index = self
|
||
|
||
return o
|
||
end
|
||
|
||
function Skill:ResetCD()
|
||
if self.owner.superSkill == self then
|
||
if BattleLogic.SkillUsable then
|
||
self.sp = 0
|
||
self.spPass = floor(self.cd * BattleLogic.GameFrameRate)
|
||
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
|
||
BattleLogic.SkillUsable = false
|
||
BattleLogic.WaitForTrigger(self.cd, function()
|
||
BattleLogic.SkillUsable = true
|
||
end)
|
||
BattleLogic.AddMP(self.owner.camp, 8)
|
||
if self.owner.skill then
|
||
local skill = self.owner.skill
|
||
skill.sp = 0
|
||
skill.spPass = floor(skill.cd * BattleLogic.GameFrameRate)
|
||
end
|
||
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, 4)
|
||
self.owner.Event:DispatchEvent(BattleEventName.SkillCast, self)
|
||
end
|
||
end
|
||
|
||
function Skill:Cast()
|
||
if self.owner.superSkill == self and not BattleLogic.SkillUsable then
|
||
return
|
||
end
|
||
for i=1, #self.effectList do
|
||
local effectGroup = self.effectList[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]
|
||
effect[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]
|
||
effect[v[1]](self.owner, arr[j], v[2], duration)
|
||
end
|
||
end
|
||
elseif nn == 1 then
|
||
for j=1, #arr do
|
||
for k=1, #effectGroup[3] do
|
||
local v = effectGroup[3][k]
|
||
effect[v[1]](self.owner, arr[j], v[2], duration)
|
||
end
|
||
end
|
||
else
|
||
local d = duration / (#arr + 1) --分割多人目标施加效果的时间,按照(1+1+..+2)的时间权重占比分配
|
||
for j=1, #arr do
|
||
local index = j
|
||
local cd = j == #arr and d * 2 or d
|
||
BattleLogic.WaitForTrigger(d * (j-1), function()
|
||
local r = arr[index]
|
||
if 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]
|
||
effect[v[1]](self.owner, r, v[2], cd)
|
||
end
|
||
return
|
||
end
|
||
end
|
||
if not r then
|
||
return
|
||
end
|
||
end
|
||
end
|
||
table.insert(self.choosedList, r)
|
||
for k=1, #effectGroup[3] do
|
||
local v = effectGroup[3][k]
|
||
effect[v[1]](self.owner, r, v[2], cd)
|
||
end
|
||
end)
|
||
end
|
||
BattleLogic.WaitForTrigger(duration, function()
|
||
self.choosedList = {}
|
||
end)
|
||
end
|
||
end)
|
||
end
|
||
end
|
||
BattleLogic.SetAggro(self.owner, 0)
|
||
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.SkillUsable
|
||
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
|
||
|
||
|
||
|