java调用lua
parent
e5d66d4bd3
commit
373664aef1
|
|
@ -0,0 +1,417 @@
|
|||
package.path = package.path ..';luafight\\?.lua';
|
||||
|
||||
require("Modules.Battle.Logic.Misc.BattleDefine")
|
||||
require("Modules.Battle.Logic.Misc.BattleUtil")
|
||||
require("Modules.Battle.Logic.Misc.BattleQueue")
|
||||
require("Modules.Battle.Logic.Misc.BattleDictionary")
|
||||
|
||||
require("Modules.Battle.Logic.Base.BattleEvent")
|
||||
require("Modules.Battle.Logic.Base.Random")
|
||||
require("Modules.Battle.Logic.Base.RoleData")
|
||||
require("Modules.Battle.Logic.Base.Buff")
|
||||
require("Modules.Battle.Logic.Base.Skill")
|
||||
require("Modules.Battle.Logic.Base.Passivity")
|
||||
|
||||
require("Modules.Battle.Logic.BattleLogic")
|
||||
require("Modules.Battle.Logic.RoleLogic")
|
||||
|
||||
--捕获异常,并输出错误日志
|
||||
local function error( err )
|
||||
local time = string.format("%d-%d-%d-%d-%d-%d",
|
||||
os.date("%Y"),
|
||||
os.date("%m"),
|
||||
os.date("%d"),
|
||||
os.date("%H"),
|
||||
os.date("%M"),
|
||||
os.date("%S"))
|
||||
local file = io.open("LogError/"..time..".txt", "a")
|
||||
file:write(debug.traceback(err))
|
||||
io.close(file)
|
||||
end
|
||||
|
||||
--测试战斗数据
|
||||
local test_fight_data={
|
||||
playerData = {
|
||||
[1] = {
|
||||
--角色id
|
||||
roleId = 10001,
|
||||
--职业id 0 无职业 1 秘法;2 天罚 3 武卫;4 玄策 5 生花
|
||||
professionId = 4,
|
||||
--角色类型 1人形 2亡灵 3动物 4魔人
|
||||
type = 1,
|
||||
--品质 1普通 2精英 3首领 4史诗
|
||||
quality = 1,
|
||||
--camp 0我方, 1敌方
|
||||
camp = 0,
|
||||
--skill = {cd, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
|
||||
--效果 = {效果类型id, 效果参数1, 效果参数2, ...}
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
--同skill
|
||||
superSkill = { 0.5, {20011, 0.7, {1, 0.1, 1}}
|
||||
},
|
||||
--passivity = {被动1, 被动2, ...}
|
||||
--被动 = {被动类型id1, 被动参数1, 被动参数2, ...}
|
||||
passivity = {},
|
||||
--属性 {等级,生命,最大生命,攻击力,护甲,魔抗,速度,伤害加成系数(%,伤害减免系数(%),命中率(%),闪避率(%),暴击率(%),暴击伤害系数(%),治疗加成系数(%)
|
||||
-- ,火系伤害加成系数(%),火系伤害减免系数(%),冰系伤害加成系数(%),冰系伤害减免系数(%),雷系伤害加成系数(%),雷系伤害减免系数(%),风系伤害加成系数(%)
|
||||
-- ,风系伤害减免系数(%),地系伤害加成系数(%),地系伤害减免系数(%),暗系伤害加成系数(%),暗系伤害减免系数(%)}
|
||||
property = {1, 2390, 2390, 169, 271, 95, 176, 0, 0, 0.3, 0.15, 0.3, 1.5, 1, 0.05, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0},
|
||||
},
|
||||
[2] = {
|
||||
roleId = 10001,
|
||||
professionId = 4,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 0, --阵营 0我方 1敌方
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
passivity = {
|
||||
--{201011, {30, 1, 0.2, 24, 0}},
|
||||
--passivity = {被动1, 被动2, ...}
|
||||
--被动 = {被动id, 被动参数1, 被动参数2, ...}
|
||||
},
|
||||
property = {1, 10000, 10000, 169, 271, 95, 176, 0, 0, 0.3, 0.15, 0.3, 1.5, 1, 0.05, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0},
|
||||
},
|
||||
[3] = {
|
||||
roleId = 10001,
|
||||
professionId = 4,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 0,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
passivity = {
|
||||
--{201011, {30, 1, 0.2, 24, 0}},
|
||||
},
|
||||
property = {1, 10000, 10000, 169, 271, 95, 176, 0, 0, 0.3, 0.15, 0.3, 1.5, 1, 0.05, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0},
|
||||
},
|
||||
[4] = {
|
||||
roleId = 10001,
|
||||
professionId = 4,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 0,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
passivity = {
|
||||
--{201011, {30, 1, 0.2, 24, 0}},
|
||||
},
|
||||
property = {1, 10000, 10000, 169, 271, 95, 176, 0, 0, 0.3, 0.15, 0.3, 1.5, 1, 0.05, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0},
|
||||
},
|
||||
[5] = {
|
||||
roleId = 10001,
|
||||
professionId = 4,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 0,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
passivity = {
|
||||
--{201011, {30, 1, 0.2, 24, 0}},
|
||||
},
|
||||
property = {1, 10000, 10000, 169, 271, 95, 176, 0, 0, 0.3, 0.15, 0.3, 1.5, 1, 0.05, 0, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0},
|
||||
},
|
||||
},
|
||||
enemyData = {
|
||||
[1] = {
|
||||
[1] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {1, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[2] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {9, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[3] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {7, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[4] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {5, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[5] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {3, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
},
|
||||
[2] = {
|
||||
[1] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {1, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[2] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {9, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[3] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {7, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[4] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {9, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[5] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {7, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
},
|
||||
[3] = {
|
||||
[1] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {1, 1044, 1044, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[2] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {9, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
[3] = {
|
||||
roleId = 1,
|
||||
professionId = 2,
|
||||
type = 1,
|
||||
quality = 1,
|
||||
camp = 1,
|
||||
skill = { 0.5, {20011, 0.7,{1, 0.1, 1}}
|
||||
},
|
||||
superSkill = {
|
||||
|
||||
},
|
||||
passivity = {
|
||||
--{206021, {1,1}},
|
||||
},
|
||||
property = {7, 144, 144, 285, 152, 53, 154, 0, 0, 0.7, 0.35, 0.3, 1.5, 1, 0, 0, 0, 0, 0.05, 0, 0, 0, 0, 0, 0.05, 0},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
local optionData = {
|
||||
{14,1,0}, --{第几帧,操作类型,操作参数}
|
||||
{132,2,3},
|
||||
{152,2,5},
|
||||
{178,3,2},
|
||||
{219,2,4},
|
||||
{260,3,1},
|
||||
{287,2,2},
|
||||
{312,3,5},
|
||||
{467,1,1},
|
||||
}
|
||||
|
||||
local BattleMain = {}
|
||||
|
||||
function BattleMain.Execute(seed, fightData, optionData)
|
||||
--该开关用于输出战斗过程中的日志,用于验证前后端是否出现战斗不同步
|
||||
--BattleLogic.IsOpenBattleRecord = true
|
||||
|
||||
Random.SetSeed(seed)
|
||||
BattleLogic.Init(fightData, optionData)
|
||||
BattleLogic.StartOrder()
|
||||
|
||||
if xpcall(function ()
|
||||
while not BattleLogic.IsEnd do
|
||||
BattleLogic.Update()
|
||||
end
|
||||
end, error) then
|
||||
local resultList = {}
|
||||
if BattleLogic.Result == 1 then --胜利记录我方剩余血量
|
||||
local arr = BattleLogic.Query(function (r) return r.camp == 0 end, true)
|
||||
for i=1, #arr do
|
||||
resultList[i] = arr[i]:GetRoleData(RoleDataName.Hp)
|
||||
end
|
||||
elseif BattleLogic.Result == 0 then --失败记录敌方剩余血量
|
||||
local arr = BattleLogic.Query(function (r) return r.camp == 1 end, true)
|
||||
for i=1, #arr do
|
||||
resultList[i] = arr[i]:GetRoleData(RoleDataName.Hp)
|
||||
end
|
||||
end
|
||||
resultList.result = BattleLogic.Result
|
||||
|
||||
-- print -----------------------------------------
|
||||
for i=1, #resultList do
|
||||
print("hp:"..resultList[i])
|
||||
end
|
||||
print("最终运行帧数:"..BattleLogic.CurFrame())
|
||||
print("result:"..BattleLogic.Result)
|
||||
|
||||
|
||||
return resultList
|
||||
--[[ --TODO:需要导入cjson库
|
||||
--local json = require("cjson")
|
||||
--local time = string.format("%d-%d-%d-%d-%d-%d",
|
||||
-- os.date("%Y"),
|
||||
-- os.date("%m"),
|
||||
-- os.date("%d"),
|
||||
-- os.date("%H"),
|
||||
-- os.date("%M"),
|
||||
-- os.date("%S"))
|
||||
--local file = io.open("BattleRecord/"..time..".txt", "a")
|
||||
--file:write(json.encode(test_fight_data))
|
||||
--io.close(file)
|
||||
]]
|
||||
end
|
||||
return { result = -1 }
|
||||
end
|
||||
BattleMain.Execute(932590676, test_fight_data, optionData)
|
||||
|
||||
return BattleMain
|
||||
--> hp:2084
|
||||
--> hp:9934
|
||||
--> hp:9781
|
||||
--> hp:9868
|
||||
--> hp:9752
|
||||
--> 最终运行帧数:2735
|
||||
--> result:1 (1胜,0负,-1战斗异常)
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
BattleEvent={}
|
||||
BattleEvent.__index = BattleEvent
|
||||
|
||||
function BattleEvent.New()
|
||||
local instance = {}
|
||||
setmetatable(instance, BattleEvent)
|
||||
instance.m_listeners = {}
|
||||
return instance
|
||||
end
|
||||
|
||||
function BattleEvent:AddEvent(sEventName, fListener, pObj, bOnce)
|
||||
if self.m_listeners[sEventName] == nil then
|
||||
self.m_listeners[sEventName] = {}
|
||||
end
|
||||
table.insert(self.m_listeners[sEventName],{ func = fListener, obj = pObj, once = bOnce } )
|
||||
|
||||
end
|
||||
function BattleEvent:RemoveEvent(sEventName, fListener)
|
||||
if self.m_listeners[sEventName] == nil then
|
||||
return
|
||||
end
|
||||
local v
|
||||
for i=1, #self.m_listeners[sEventName] do
|
||||
v = self.m_listeners[sEventName][i]
|
||||
if v.func == fListener then
|
||||
table.remove(self.m_listeners[sEventName], i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BattleEvent:DispatchEvent(sEventName,...)
|
||||
if self.m_listeners[sEventName] == nil then
|
||||
return
|
||||
end
|
||||
local v
|
||||
for i=1, #self.m_listeners[sEventName] do
|
||||
v = self.m_listeners[sEventName][i]
|
||||
if nil == v.obj then
|
||||
v.func(...)
|
||||
else
|
||||
v.func(v.obj, ...)
|
||||
end
|
||||
if v.once then
|
||||
self:RemoveEvent(sEventName, v)
|
||||
end
|
||||
end
|
||||
end
|
||||
function BattleEvent:ClearEvent()
|
||||
self.m_listeners={}
|
||||
end
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
Buff = {}
|
||||
|
||||
local floor = math.floor
|
||||
function Buff:New()
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function Buff.Create(caster, type, duration, ...)
|
||||
local instance = require("Modules/Battle/Logic/Buff/"..type):New()
|
||||
|
||||
instance.type = type
|
||||
instance.id = BattleLogic.GenerateBuffId()
|
||||
instance.caster = caster
|
||||
instance.disperse = false
|
||||
instance.cover = false
|
||||
|
||||
instance.duration = duration --持续时间为0时buff永久存在
|
||||
instance.interval = -1 --间隔帧为0时每帧触发,小于0不触发 默认不触发OnTrigger
|
||||
instance.maxCount = 0 --限定效果最大数量
|
||||
instance.framePass = 0
|
||||
|
||||
instance:SetData(...)
|
||||
return instance
|
||||
end
|
||||
|
||||
BuffManager = {}
|
||||
BuffManager.__index = BuffManager
|
||||
|
||||
function BuffManager.New(owner)
|
||||
local instance = {}
|
||||
instance.owner = owner
|
||||
instance.buffQueue = BattleQueue.New()
|
||||
instance.buffList = BattleDictionary.New()
|
||||
|
||||
setmetatable(instance, BuffManager)
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
function BuffManager:AddBuff(buff)
|
||||
self.buffQueue:Enqueue(buff)
|
||||
if not buff.exCtrlTime then
|
||||
buff.exCtrlTime = 0
|
||||
end
|
||||
buff.frameDuration = floor(buff.duration * (1 + buff.exCtrlTime) * BattleLogic.GameFrameRate)
|
||||
--if buff.isBuff then --TODO:增益buff持续时间加成
|
||||
-- local buffBocus = buff.caster:GetRoleData(RoleDataName.BuffBocus)
|
||||
-- buff.frameDuration = floor(buff.duration * (1 + buffBocus + buff.exCtrlTime) * BattleLogic.GameFrameRate)
|
||||
--end
|
||||
--
|
||||
--if buff.isDeBuff then --TODO:减益buff持续时间减免
|
||||
-- local debuffReduce = self.owner:GetRoleData(RoleDataName.DebuffReduce)
|
||||
-- buff.frameDuration = floor(buff.duration * (1 - debuffReduce - buff.exCtrlTime) * BattleLogic.GameFrameRate)
|
||||
--end
|
||||
|
||||
buff.frameInterval = floor(buff.interval * BattleLogic.GameFrameRate)
|
||||
end
|
||||
|
||||
function BuffManager:HasBuff(type, checkFunc)
|
||||
local v
|
||||
for i=1, self.buffList:Count() do
|
||||
v = self.buffList.vList[i]
|
||||
if #v > 0 then
|
||||
if v[1].type == type and (not checkFunc or (checkFunc and checkFunc(v[1]))) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function BuffManager:ClearBuff(func)
|
||||
for i = 1, self.buffList.size do
|
||||
local k = self.buffList.kList[i]
|
||||
local v = self.buffList.vList[i]
|
||||
local count = #v
|
||||
if count > 0 then
|
||||
local removeCount = 0
|
||||
local idx = 1
|
||||
while idx <= count do
|
||||
if func(v[idx]) then
|
||||
table.remove(v, idx)
|
||||
count = count - 1
|
||||
removeCount = removeCount + 1
|
||||
else
|
||||
idx = idx + 1
|
||||
end
|
||||
end
|
||||
if removeCount > 0 then
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, k, count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BuffManager:GetBuffCount(id)
|
||||
if self.buffList[id] then
|
||||
return self.buffList[id]:Count()
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function BuffManager:Update()
|
||||
for i=1, self.buffQueue.size do
|
||||
local buff = self.buffQueue:Dequeue()
|
||||
if not buff.caster then
|
||||
--logErrorTrace("buff's caster can't be nil!")
|
||||
return
|
||||
end
|
||||
local buffList
|
||||
if not self.buffList.kvList[buff.id] then
|
||||
buffList = {}
|
||||
self.buffList:Add(buff.id, buffList)
|
||||
else
|
||||
buffList = self.buffList.kvList[buff.id]
|
||||
end
|
||||
local count = #buffList
|
||||
if buff.cover and count > 0 then
|
||||
if buffList[1]:OnCover(buff) then --判定该效果能否被覆盖
|
||||
buffList[1]:OnEnd(self.owner)
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffEnd, buffList[1])
|
||||
buffList[1] = buff
|
||||
buff.target = self.owner
|
||||
buff:OnStart()
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffStart, buff)
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffCover, buff)
|
||||
end
|
||||
else
|
||||
if buff.maxCount == 0 or count < buff.maxCount then --限制相同效果的数量,为0则不限制
|
||||
count = count + 1
|
||||
buffList[count] = buff
|
||||
buff.target = self.owner
|
||||
buff:OnStart()
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffStart, buff)
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, buff.id, count)
|
||||
end
|
||||
end
|
||||
end
|
||||
for i = 1, self.buffList.size do
|
||||
local k = self.buffList.kList[i]
|
||||
local v = self.buffList.vList[i]
|
||||
local count = #v
|
||||
if count > 0 then
|
||||
local removeCount = 0
|
||||
local idx = 1
|
||||
local buff
|
||||
while idx <= count do
|
||||
buff = v[idx]
|
||||
--印记类型的buff不处理更新逻辑
|
||||
if buff.frameDuration == 0 and buff.frameInterval < 0 then
|
||||
else
|
||||
buff.framePass = buff.framePass + 1
|
||||
if buff.frameDuration == 0 then
|
||||
if buff.frameInterval == 0 or buff.framePass % buff.frameInterval == 0 then
|
||||
if not buff:OnTrigger() then
|
||||
buff.disperse = true
|
||||
end
|
||||
buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
|
||||
end
|
||||
elseif buff.frameInterval < 0 then
|
||||
if buff.framePass > buff.frameDuration then
|
||||
buff.disperse = true
|
||||
end
|
||||
else
|
||||
if buff.frameInterval == 0 or buff.framePass % buff.frameInterval == 0 then
|
||||
if not buff:OnTrigger() then
|
||||
buff.disperse = true
|
||||
end
|
||||
buff.target.Event:DispatchEvent(BattleEventName.BuffTrigger, buff)
|
||||
end
|
||||
|
||||
if buff.framePass > buff.frameDuration then
|
||||
buff.disperse = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if buff.disperse then
|
||||
buff:OnEnd()
|
||||
buff.target.Event:DispatchEvent(BattleEventName.BuffEnd, buff)
|
||||
table.remove(v, idx)
|
||||
count = count - 1
|
||||
removeCount = removeCount + 1
|
||||
else
|
||||
idx = idx + 1
|
||||
end
|
||||
end
|
||||
if removeCount > 0 then
|
||||
self.owner.Event:DispatchEvent(BattleEventName.BuffCountChange, k, count)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,431 @@
|
|||
local floor = math.floor
|
||||
--local RoleDataName = RoleDataName
|
||||
--local BattleLogic = BattleLogic
|
||||
--local BattleUtil = BattleUtil
|
||||
|
||||
--属性编号
|
||||
local propertyList = {
|
||||
RoleDataName.Attack,
|
||||
RoleDataName.PhysicalDefence,
|
||||
RoleDataName.MagicDefence,
|
||||
RoleDataName.Speed,
|
||||
RoleDataName.DamageBocusFactor,
|
||||
RoleDataName.DamageReduceFactor,
|
||||
RoleDataName.Hit,
|
||||
RoleDataName.Dodge,
|
||||
RoleDataName.Crit,
|
||||
RoleDataName.CritDamageFactor,
|
||||
RoleDataName.TreatFacter,
|
||||
}
|
||||
|
||||
--效果表
|
||||
local effectList = {
|
||||
--造成[a]%的[b]伤害
|
||||
--a[float],b[伤害类型]
|
||||
[1] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害【AOE】
|
||||
--a[float],b[伤害类型]
|
||||
[2] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
--[a]%概率[b],持续[c]秒
|
||||
--a[float],b[控制状态],c[float]
|
||||
[3] = function(caster, target, args, interval)
|
||||
local f1 = args[1] * (1 + caster:GetRoleData(RoleDataName.Hit) / (1 + target:GetRoleData(RoleDataName.Dodge)))
|
||||
local cb1 = args[2]
|
||||
local f2 = args[3]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
BattleUtil.RandomAction(f1, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.Control, f2, cb1))
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
--[d]改变[a]属性[b]%,持续[c]秒
|
||||
--a[属性],b[float],c[int],d[改变类型]
|
||||
[4] = function(caster, target, args, interval)
|
||||
local pro1 = args[1]
|
||||
local f1 = args[2]
|
||||
local f2 = args[3]
|
||||
local ct = args[4]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.PropertyChange, f2, propertyList[pro1], f1, ct))
|
||||
end)
|
||||
end,
|
||||
--持续恢复[a]*[b]%生命,持续[c]秒
|
||||
--a[属性],b[float],c[int]
|
||||
[5] = function(caster, target, args, interval)
|
||||
local pro1 = args[1]
|
||||
local f1 = args[2]
|
||||
local f2 = args[3]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.HOT, f2, 1, floor(caster:GetRoleData(propertyList[pro1]) * f1)))
|
||||
end)
|
||||
end,
|
||||
--造成[a]到[b]次[c]%的[d]伤害
|
||||
--a[int],b[int],c[float],d[伤害类型]
|
||||
[6] = function(caster, target, args, interval)
|
||||
local i1 = args[1]
|
||||
local i2 = args[2]
|
||||
local f1 = args[3]
|
||||
local dt = args[4]
|
||||
|
||||
local count = Random.RangeInt(i1, i2)
|
||||
local d = interval / count
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, d)
|
||||
end
|
||||
for i=1, count do
|
||||
BattleLogic.WaitForTrigger(d * (i-1), function ()
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, d)
|
||||
BattleLogic.WaitForTrigger(d, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
--造成[a]到[b]次[c]%的[d]伤害【AOE】
|
||||
--a[int],b[int],c[float],d[伤害类型]
|
||||
[7] = function(caster, target, args, interval)
|
||||
local i1 = args[1]
|
||||
local i2 = args[2]
|
||||
local f1 = args[3]
|
||||
local dt = args[4]
|
||||
|
||||
local count = Random.RangeInt(i1, i2)
|
||||
local d = interval / count
|
||||
for i=1, count do
|
||||
BattleLogic.WaitForTrigger(d * (i-1), function ()
|
||||
BattleLogic.WaitForTrigger(d, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
--[b]%改变[c]下次重击技能CD[a]秒
|
||||
--a[float],b[float]
|
||||
[8] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2] * (1 + caster:GetRoleData(RoleDataName.Hit) / (1 + target:GetRoleData(RoleDataName.Dodge)))
|
||||
local ct = args[3]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
BattleUtil.RandomAction(f2, function ()
|
||||
if target.skill then
|
||||
if f2 == 0 then --值为0时,直接清除CD
|
||||
target.skill.sp = target.skill.spPass
|
||||
else
|
||||
if ct == 1 then --加算
|
||||
target.skill.sp = target.skill.sp - floor(f1 * BattleLogic.GameFrameRate)
|
||||
elseif ct == 2 then --乘加算(百分比属性加算)
|
||||
target.skill.sp = floor(target.skill.sp * (1 - f1))
|
||||
elseif ct == 3 then --减算
|
||||
target.skill.sp = target.skill.sp + floor(f1 * BattleLogic.GameFrameRate)
|
||||
elseif ct == 4 then --乘减算(百分比属性减算)
|
||||
target.skill.sp = floor(target.skill.sp * (1 + f1))
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
--添加[a]的[b]%护盾,持续[c]秒,盾消失的时候反射吸收伤害的[d]%
|
||||
--a[属性],b[float],c[int],d[float]
|
||||
[9] = function(caster, target, args, interval)
|
||||
local pro1 = args[1]
|
||||
local f1 = args[2]
|
||||
local f2 = args[3]
|
||||
local f3 = args[4]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.Shield, f2, floor(caster:GetRoleData(propertyList[pro1]) * f1), f3))
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,自身恢复造成伤害[c]%的生命
|
||||
--a[float],b[伤害类型],c[float]
|
||||
[10] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local dmg = BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
BattleUtil.ApplyTreat(caster, caster, floor(dmg * f2))
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,对[c]造成额外[d]%伤害
|
||||
--a[float],b[伤害类型,]c[职业],d[float]
|
||||
[11] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local i1 = args[3]
|
||||
local f2 = args[4]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
if target.professionId == i1 then
|
||||
f1 = f1 + f2
|
||||
end
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
--每秒造成[a]的[b]的伤害,持续[c]秒
|
||||
--a[float],b[伤害类型],c[int]
|
||||
[12] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.DOT, f2, 1, 0, dt, f1))
|
||||
end)
|
||||
end,
|
||||
--造成[c],每秒造成[d]的[e]的伤害,持续[f]秒
|
||||
--c[持续伤害状态].d[float],e[伤害类型],f[int]
|
||||
[13] = function(caster, target, args, interval)
|
||||
local d1 = args[1]
|
||||
local f1 = args[2]
|
||||
local dt = args[3]
|
||||
local f2 = args[4]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.DOT, f2, 1, d1, dt, f1))
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,[c]%概率[d]专属伤害加深印记(如果有印记,无印记伤害*(1+印记数量*[e])
|
||||
--a[float],b[伤害类型],c[float],d[角色id],e[float]
|
||||
[14] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3] * (1 + caster:GetRoleData(RoleDataName.Hit) / (1 + target:GetRoleData(RoleDataName.Dodge)))
|
||||
local rid = args[4]
|
||||
local f3 = args[5]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local layer
|
||||
if target.BuffMgr:HasBuff(BuffName.Brand, function (buff)
|
||||
local b = buff.flag == rid
|
||||
if b then
|
||||
layer = buff.layer
|
||||
end
|
||||
return b
|
||||
end) then
|
||||
BattleUtil.CalDamage(caster, target, dt,f1 + layer * f3)
|
||||
else
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end
|
||||
BattleUtil.RandomAction(f2, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.Brand,0, rid))
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,如果击杀,则其他人再受到此次伤害的[c]%的伤害
|
||||
--a[float],b[伤害类型],c[float]
|
||||
[15] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local dmg = BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
if target.isDead then
|
||||
local arr = BattleLogic.Query(function (r) return r.camp ~= caster.camp and r.uid ~= target.uid end)
|
||||
for i=1, #arr do
|
||||
BattleUtil.ApplyDamage(caster, arr[i], floor(dmg * f2))
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
--吸取[a]%的[b],持续[c]秒
|
||||
--a[float],b[属性],c[float]
|
||||
[16] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
local value = floor(target:GetRoleData(propertyList[dt]) * f1)
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.PropertyChange, f2, value, f1, 3))
|
||||
caster:AddBuff(Buff.Create(caster, BuffName.PropertyChange, f2, value, f1, 1))
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,如果是[c],有[d]%必定暴击
|
||||
--a[float],b[伤害类型],c[职业],d[float]
|
||||
[17] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local i1 = args[3]
|
||||
local f2 = args[4] * (1 + caster:GetRoleData(RoleDataName.Hit) / (1 + target:GetRoleData(RoleDataName.Dodge)))
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local dmg = floor(caster:GetRoleData(propertyList[dt]) * f1)
|
||||
if target.professionId == i1 then
|
||||
BattleUtil.RandomAction(f2, function ()
|
||||
target.isFlagCrit = true
|
||||
BattleUtil.CalDamage(caster, target, dmg)
|
||||
target.isFlagCrit = false
|
||||
end)
|
||||
else
|
||||
BattleUtil.CalDamage(caster, target, dmg)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,若暴击,则减少下次发动技能CD[c]秒。
|
||||
--a[float],b[伤害类型],c[float]
|
||||
[18] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local d, crit = BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
if crit then
|
||||
if target.skill then
|
||||
target.skill.sp = target.skill.sp + floor(f2 * BattleLogic.GameFrameRate)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,若暴击,则减少下次发动技能CD[c]秒。
|
||||
--a[float],b[伤害类型],c[float]
|
||||
[18] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
local d, crit = BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
if crit then
|
||||
if target.skill then
|
||||
target.skill.sp = target.skill.sp + floor(f2 * BattleLogic.GameFrameRate)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,有[c]%的概率追加伤害,最多可追加[d]次。(0无限追加)
|
||||
--a[float],b[伤害类型],c[float],d[int]
|
||||
[19] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local f2 = args[3]
|
||||
local i1 = args[4]
|
||||
|
||||
if i1 == 0 then
|
||||
i1 = floor(interval * BattleLogic.GameFrameRate)
|
||||
end
|
||||
local count = 1
|
||||
while Random.Range01() <= f2 and count <= i1 do
|
||||
count = count + 1
|
||||
end
|
||||
local d = interval / count
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, d)
|
||||
end
|
||||
for i=1, count do
|
||||
BattleLogic.WaitForTrigger(d * (i-1), function ()
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, d)
|
||||
BattleLogic.WaitForTrigger(d, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
--造成[a]%的[b]伤害,对[c]造成额外[d]%伤害
|
||||
--a[float],b[伤害类型,]c[控制状态],d[float]
|
||||
[20] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local i1 = args[3]
|
||||
local f2 = args[4]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
if target.BuffMgr:HasBuff(BuffName.Control, function (buff) return i1 == 0 or buff.ctrlType == i1 end) then
|
||||
f1 = f1 + f2
|
||||
end
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,对[c]有[d]%造成[e],持续[f]秒【AOE】
|
||||
--a[float],b[伤害类型,]c[持续伤害状态],d[float],e[控制状态],f[int]
|
||||
[21] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local dot = args[3]
|
||||
local f2 = args[4] * (1 + caster:GetRoleData(RoleDataName.Hit) / (1 + target:GetRoleData(RoleDataName.Dodge)))
|
||||
local ct = args[5]
|
||||
local f3 = args[6]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
if target.BuffMgr:HasBuff(BuffName.DOT, function (buff) return dot == 0 or buff.damageType == dot end) then
|
||||
BattleUtil.RandomAction(f2, function ()
|
||||
target:AddBuff(Buff.Create(caster, BuffName.Control, f3, ct))
|
||||
end)
|
||||
end
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,对[c]造成额外[d]%伤害【AOE】
|
||||
--a[float],b[伤害类型,]c[持续伤害状态],d[float]
|
||||
[22] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local dot = args[3]
|
||||
local f2 = args[4]
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
if target.BuffMgr:HasBuff(BuffName.DOT, function (buff) return dot == 0 or buff.damageType == dot end) then
|
||||
f1 = f1 + f2
|
||||
end
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
--造成[a]%的[b]伤害,对[c]造成额外[d]%伤害
|
||||
--a[float],b[伤害类型,]c[持续回复状态],d[float]
|
||||
[23] = function(caster, target, args, interval)
|
||||
local f1 = args[1]
|
||||
local dt = args[2]
|
||||
local ht = args[3]
|
||||
local f2 = args[4]
|
||||
caster.Event:DispatchEvent(BattleEventName.RoleViewBullet, interval)
|
||||
if caster.camp == 0 and target.camp == 1 then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, target, interval)
|
||||
end
|
||||
BattleLogic.WaitForTrigger(interval, function ()
|
||||
if target.BuffMgr:HasBuff(BuffName.HOT, function (buff) return true end) then
|
||||
f1 = f1 + f2
|
||||
end
|
||||
BattleUtil.CalDamage(caster, target, dt, f1)
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
return effectList
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
local floor = math.floor
|
||||
local max = math.max
|
||||
--local RoleDataName = RoleDataName
|
||||
--local BattleLogic = BattleLogic
|
||||
--local BattleUtil = BattleUtil
|
||||
--local BattleEventName = BattleEventName
|
||||
--local BuffName = BuffName
|
||||
|
||||
local function queryAllies(role) return function (r) return r.camp == role.camp end end
|
||||
local function queryEnemy(role) return function (r) return r.camp ~= role.camp end end
|
||||
--被动技能表
|
||||
local passivityList = {
|
||||
--受到暴击伤害时,有(a%)的概率发动一次反击,对敌人造成【b*c+d】的【e】伤害
|
||||
[201011] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
local pro1 = args[2]
|
||||
local f2 = args[3]
|
||||
local pro2 = args[4]
|
||||
local dt = args[5]
|
||||
|
||||
local OnCrit = function(atkRole)
|
||||
BattleUtil.RandomAction(f1, function ()
|
||||
local value = role:GetRoleData(BattleUtil.GetPropertyName(pro1)) * f2 + role:GetRoleData(BattleUtil.GetPropertyName(pro2))
|
||||
BattleUtil.CalDamage(role, atkRole, value, 1, dt)
|
||||
end)
|
||||
end
|
||||
role.Event:AddEvent(BattleEventName.RoleBeCrit, OnCrit)
|
||||
end,
|
||||
|
||||
--生命低于(a%)的时候,提升自身减伤率(b%),持续(c)秒。每场战斗只能触发一次。
|
||||
[201021] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2]
|
||||
local f3 = args[3]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
|
||||
local triggerCount = 0
|
||||
local OnDamaged = function(atkRole)
|
||||
if BattleUtil.GetHPPencent(role) < f1 then
|
||||
if triggerCount < 1 then
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, f3, RoleDataName.DamageReduceFactor, f2, 1)
|
||||
role:AddBuff(buff)
|
||||
triggerCount = triggerCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
role.Event:AddEvent(BattleEventName.RoleBeDamaged, OnDamaged)
|
||||
end,
|
||||
|
||||
--开场降低敌方全体(a%)的【c】,持续(bs)。
|
||||
[202011] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
local f2 = args[2]
|
||||
local pro1 = args[3]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
|
||||
local arr = BattleLogic.Query(queryEnemy(role))
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, f2, BattleUtil.GetPropertyName(pro1), f1, 2)
|
||||
v:AddBuff(buff)
|
||||
end
|
||||
end,
|
||||
|
||||
--开场增加增加全队暴击率(a%),持续(b)秒。
|
||||
[202021] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
local f2 = args[2]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
|
||||
local arr = BattleLogic.Query(queryAllies(role))
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, f2, RoleDataName.Crit, f1, 2)
|
||||
v:AddBuff(buff)
|
||||
end
|
||||
end,
|
||||
|
||||
--场上每有1个流血目标,GCD降低(a)秒。最高降低(b)秒。
|
||||
[203011] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
|
||||
local originGcd = role:GetRoleData(RoleDataName.GCD)
|
||||
local aurabuff = Buff.Create(role, BuffName.Aura, buffId1, 0, function (role)
|
||||
local arr = BattleLogic.Query(queryEnemy(role))
|
||||
local count = 0
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
if v.BuffMgr:HasBuff(BuffName.Bleed) then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
role.data:SetValue(RoleDataName.GCD, max(originGcd - count * f1, f2))
|
||||
end)
|
||||
aurabuff.interval = 0
|
||||
role:AddBuff(aurabuff)
|
||||
end,
|
||||
|
||||
--每次受到伤害,额外提升伤害(a%)(最多b%)。
|
||||
[203021] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
local f2 = args[2]/100
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local totalFactor = 0
|
||||
|
||||
local OnDamaged = function(atkRole)
|
||||
if totalFactor <= f2 then
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, 0, RoleDataName.DamageBocusFactor, f2, 1)
|
||||
role:AddBuff(buff)
|
||||
totalFactor = totalFactor + f1
|
||||
end
|
||||
end
|
||||
role.Event:AddEvent(BattleEventName.RoleBeDamaged, OnDamaged)
|
||||
end,
|
||||
|
||||
--开场额外增加暴击率(a%)。
|
||||
[204011] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, 0, RoleDataName.Crit, f1, 1)
|
||||
role:AddBuff(buff)
|
||||
end,
|
||||
|
||||
--受到攻击时,攻击者有(a%)的概率被附加1个印记。
|
||||
[204021] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local OnDamaged = function(atkRole)
|
||||
BattleUtil.RandomAction(f1, function ()
|
||||
local buff = Buff.Create(role, BuffName.Brand, buffId1, 0, "咒术师印记")
|
||||
atkRole:AddBuff(buff)
|
||||
end)
|
||||
end
|
||||
|
||||
role.Event:AddEvent(BattleEventName.RoleBeDamaged, OnDamaged)
|
||||
end,
|
||||
|
||||
--生命低于(a%),治疗量增加(b%),持续(c)秒。每场战斗只能触发一次。
|
||||
[205011] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2]/100
|
||||
local f3 = args[3]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
|
||||
local triggerCount = 0
|
||||
local OnDamaged = function(atkRole)
|
||||
if BattleUtil.GetHPPencent(role) < f1 then
|
||||
if triggerCount < 1 then
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, f3, RoleDataName.TreatFacter, f2, 1)
|
||||
role:AddBuff(buff)
|
||||
triggerCount = triggerCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
role.Event:AddEvent(BattleEventName.RoleBeDamaged, OnDamaged)
|
||||
end,
|
||||
|
||||
--生命低于(a%),提升友军(b%)的【e】,并且(d%)概率眩晕对方全体(c)秒,每场战斗只能触发一次。
|
||||
[205021] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2]/100
|
||||
local f3 = args[3]
|
||||
local f4 = args[4]/100
|
||||
local pro1 = args[5]
|
||||
local f5 = args[6]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local buffId2 = BattleUtil.CreateBuffId(role, 2)
|
||||
|
||||
local triggerCount = 0
|
||||
local OnDamaged = function(atkRole)
|
||||
if BattleUtil.GetHPPencent(role) < f1 then
|
||||
if triggerCount < 1 then
|
||||
local arr = BattleLogic.Query(queryAllies(role))
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId1, f5, BattleUtil.GetPropertyName(pro1), f2, 1)
|
||||
v:AddBuff(buff)
|
||||
end
|
||||
|
||||
BattleUtil.RandomAction(f4, function ()
|
||||
local arr = BattleLogic.Query(queryEnemy(role))
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
local stun = Buff.Create(role, BuffName.Stun, buffId2, f3)
|
||||
v:AddBuff(stun)
|
||||
end
|
||||
end)
|
||||
triggerCount = triggerCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
role.Event:AddEvent(BattleEventName.RoleBeDamaged, OnDamaged)
|
||||
end,
|
||||
|
||||
--每(a)秒恢复(b)魂能
|
||||
[206021] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local i1 = args[2]
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local aurabuff = Buff.Create(role, BuffName.Aura, buffId1, 0, function (role)
|
||||
BattleLogic.AddMP(role.camp, i1)
|
||||
end)
|
||||
aurabuff.interval = f1
|
||||
role:AddBuff(aurabuff)
|
||||
end,
|
||||
|
||||
--自身生命高于(a%),暴击率提高(b%)
|
||||
[207011] = function(role, args)
|
||||
local f1 = args[1]
|
||||
local f2 = args[2]/100
|
||||
|
||||
local buffId1 = BattleUtil.CreateBuffId(role, 1)
|
||||
local buffId2 = BattleUtil.CreateBuffId(role, 2)
|
||||
|
||||
local buff = Buff.Create(role, BuffName.PropertyChange, buffId2, 0, RoleDataName.Crit, f2, 1)
|
||||
local active = BattleUtil.GetHPPencent(role) > f1
|
||||
if active then
|
||||
role:AddBuff(buff)
|
||||
end
|
||||
|
||||
local aurabuff = Buff.Create(role, BuffName.Aura, buffId1, 0, function (role)
|
||||
local curActive = BattleUtil.GetHPPencent(role) > f1
|
||||
if active ~= curActive then
|
||||
active = curActive
|
||||
if active then
|
||||
buff.disperse = false
|
||||
role:AddBuff(buff)
|
||||
else
|
||||
buff.disperse = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
aurabuff.interval = 0
|
||||
role:AddBuff(aurabuff)
|
||||
end,
|
||||
|
||||
--召唤物存在期间,场上伙伴阵亡超过2名时,冰雪皇后会牺牲并复活所有已阵亡的队友,保留其(a%)的生命,全场只可触发1次
|
||||
[208011] = function(role, args)
|
||||
local f1 = args[1]/100
|
||||
|
||||
local deadCount = 0
|
||||
local triggerCount = 0
|
||||
|
||||
local OnDead = function(role)
|
||||
if role.camp == role.camp and role.roleType ~= 3 then
|
||||
deadCount = deadCount + 1
|
||||
if deadCount > 2 and role.summon and triggerCount < 1 then
|
||||
BattleLogic.RemoveSummon(role.summon)
|
||||
local arr = BattleLogic.Query(function (r) return r.camp == role.camp and r.roleType ~= 3 end, true)
|
||||
local v
|
||||
for i=1, #arr do
|
||||
v = arr[i]
|
||||
local hp = v:GetRoleData(RoleDataName.MaxHp)
|
||||
v.data:AddValue(RoleDataName.Hp, floor(hp*f1))
|
||||
v.Event:DispatchEvent(BattleEventName.RoleRevive)
|
||||
end
|
||||
triggerCount = triggerCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
BattleLogic.Event:AddEvent(BattleEventName.BattleRoleDead, OnDead)
|
||||
end,
|
||||
}
|
||||
return passivityList
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
Random = {}
|
||||
|
||||
local floor = math.floor
|
||||
local seed = 0
|
||||
|
||||
local function random()
|
||||
local r = seed
|
||||
local m = 123459876
|
||||
if r < m then
|
||||
r, m = m, r
|
||||
end
|
||||
local res = 0
|
||||
local shift = 1
|
||||
local b
|
||||
while r ~= 0 do
|
||||
b = (r % 2 + m % 2) == 1 and 1 or 0
|
||||
res = shift * b + res
|
||||
shift = shift * 2
|
||||
r = floor( r * 0.5)
|
||||
m = floor( m * 0.5)
|
||||
end
|
||||
local k = floor(res / 127773)
|
||||
r = 16807 * (res - k * 127773) - 2836 * k
|
||||
if r < 0 then
|
||||
r = r + 2147483647
|
||||
end
|
||||
seed = r
|
||||
return r
|
||||
end
|
||||
function Random.SetSeed(sd)
|
||||
seed = sd
|
||||
end
|
||||
|
||||
function Random.GetSeed()
|
||||
return seed
|
||||
end
|
||||
|
||||
--随机0-1
|
||||
function Random.Range01()
|
||||
local var = random() / 2147483647
|
||||
if BattleLogic.IsOpenBattleRecord then
|
||||
BattleLogic.RecordSeed(seed)
|
||||
end
|
||||
return var
|
||||
end
|
||||
|
||||
--随机v1-v2
|
||||
function Random.Range(v1, v2)
|
||||
if v2 > v1 then
|
||||
return Random.Range01()*(v2-v1)+v1
|
||||
elseif v1 > v2 then
|
||||
return Random.Range01()*(v1-v2)+v2
|
||||
else
|
||||
return v1
|
||||
end
|
||||
end
|
||||
|
||||
--随机v1-v2 返回整数
|
||||
function Random.RangeInt(v1, v2)
|
||||
if v2 > v1 then
|
||||
return floor(Random.Range01()*(v2-v1) + 0.5)+v1
|
||||
elseif v1 > v2 then
|
||||
return floor(Random.Range01()*(v1-v2) + 0.5)+v2
|
||||
else
|
||||
return v1
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
RoleData = {}
|
||||
RoleData.__index = RoleData
|
||||
local max = math.max
|
||||
|
||||
function RoleData.New(role, data)
|
||||
local instance = {}
|
||||
setmetatable(instance, RoleData)
|
||||
instance.role = role
|
||||
instance.data = data
|
||||
return instance
|
||||
end
|
||||
|
||||
function RoleData:GetData(name)
|
||||
if self.data[name] then
|
||||
return self.data[name][1]
|
||||
end
|
||||
end
|
||||
|
||||
function RoleData:SetValue(name, value)
|
||||
if self.data[name][1] then
|
||||
local delta = self.data[name][1]
|
||||
self.data[name][1] = value
|
||||
delta = value - delta
|
||||
if delta ~= 0 then
|
||||
self.role.Event:DispatchEvent(BattleEventName.RolePropertyChanged, name, value, delta)
|
||||
if BattleLogic.IsOpenBattleRecord then
|
||||
BattleLogic.RecordRoleProperty(self.role.uid, self.role.camp, name, value, delta)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function RoleData:AddValue(name, delta)
|
||||
if delta < 0 or not self.data[name] then --delta必须非负
|
||||
return 0
|
||||
end
|
||||
if self.data[name][1] then
|
||||
self:SetValue(name, self.data[name][1] + delta)
|
||||
end
|
||||
return delta
|
||||
end
|
||||
|
||||
function RoleData:AddPencentValue(name, pencent)
|
||||
if self.data[name][1] and not self.data[name][2] then
|
||||
return self:AddValue(name, self.data[name][1] * pencent)
|
||||
else
|
||||
return self:AddValue(name, pencent)
|
||||
end
|
||||
end
|
||||
|
||||
function RoleData:SubDeltaValue(name, delta)
|
||||
if delta < 0 or not self.data[name] then --delta必须非负
|
||||
return 0
|
||||
end
|
||||
if self.data[name][1] then
|
||||
self:SetValue(name, self.data[name][1] - delta)
|
||||
end
|
||||
return delta
|
||||
end
|
||||
|
||||
function RoleData:SubValue(name, delta)
|
||||
if delta < 0 or not self.data[name] then --delta必须非负
|
||||
return 0
|
||||
end
|
||||
local orVal = self.data[name][1]
|
||||
if orVal then
|
||||
if self.data[name][2] then
|
||||
self:SetValue(name, self.data[name][1] * (1 - delta))
|
||||
else
|
||||
self:SetValue(name, max(self.data[name][1] - delta, 0))
|
||||
end
|
||||
orVal = orVal - self.data[name][1]
|
||||
end
|
||||
return orVal
|
||||
end
|
||||
|
||||
function RoleData:SubPencentValue(name, pencent)
|
||||
if self.data[name][1] and not self.data[name][2] then
|
||||
return self:SubValue(name, self.data[name][1] * pencent)
|
||||
else
|
||||
return self:SubValue(name, pencent)
|
||||
end
|
||||
end
|
||||
|
||||
--Debug
|
||||
function RoleData:Foreach(func)
|
||||
for k,v in ipairs(self.data) do
|
||||
func(k, v[1])
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
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
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,400 @@
|
|||
BattleLogic = {}
|
||||
|
||||
local floor = math.floor
|
||||
local tbObjList
|
||||
local tbActionList
|
||||
local tbActionListCount = 0
|
||||
local curUid
|
||||
local curBuffId
|
||||
local curFrame
|
||||
|
||||
local playerMP
|
||||
local enemyMP
|
||||
|
||||
local playerAggro
|
||||
local enemyAggro
|
||||
local playerAggroChangable
|
||||
local enemyAggroChangable
|
||||
|
||||
local fightData
|
||||
local record
|
||||
local optionRecord
|
||||
|
||||
BattleLogic.IsEnd = false
|
||||
BattleLogic.Result = -1
|
||||
BattleLogic.Event = BattleEvent:New()
|
||||
--是否开启战斗日志
|
||||
BattleLogic.IsOpenBattleRecord = false
|
||||
--逻辑帧频
|
||||
BattleLogic.GameFrameRate = 30
|
||||
BattleLogic.GameDeltaTime = 1 / BattleLogic.GameFrameRate
|
||||
BattleLogic.SkillUsable = true
|
||||
--总波次
|
||||
BattleLogic.TotalOrder = 0
|
||||
--当前波次
|
||||
BattleLogic.CurOrder = 0
|
||||
|
||||
function BattleLogic.Init(data, optionData)
|
||||
if BattleLogic.IsOpenBattleRecord then
|
||||
record = {}
|
||||
end
|
||||
|
||||
fightData = data
|
||||
if optionData then
|
||||
optionRecord = optionData
|
||||
else
|
||||
optionRecord = {}
|
||||
end
|
||||
|
||||
BattleLogic.CurOrder = 0
|
||||
BattleLogic.TotalOrder = #data.enemyData
|
||||
|
||||
tbObjList = BattleDictionary.New()
|
||||
tbActionList = {}
|
||||
tbActionListCount = 0
|
||||
curUid = 0
|
||||
curBuffId = 0
|
||||
curFrame = 0
|
||||
playerMP = 0
|
||||
enemyMP = 0
|
||||
playerAggroChangable = true
|
||||
enemyAggroChangable = true
|
||||
BattleLogic.Event:ClearEvent()
|
||||
BattleLogic.IsEnd = false
|
||||
BattleLogic.Result = -1
|
||||
BattleLogic.SkillUsable = true
|
||||
end
|
||||
|
||||
function BattleLogic.StartOrder()
|
||||
BattleLogic.CurOrder = BattleLogic.CurOrder + 1
|
||||
if BattleLogic.CurOrder == 1 then
|
||||
for i=1, #fightData.playerData do
|
||||
BattleLogic.AddRole(fightData.playerData[i])
|
||||
end
|
||||
for i=1, #fightData.enemyData[BattleLogic.CurOrder] do
|
||||
BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i])
|
||||
end
|
||||
else
|
||||
BattleLogic.ClearOrder()
|
||||
for i=1, #fightData.enemyData[BattleLogic.CurOrder] do
|
||||
BattleLogic.AddRole(fightData.enemyData[BattleLogic.CurOrder][i])
|
||||
end
|
||||
end
|
||||
BattleLogic.InitAggro()
|
||||
end
|
||||
|
||||
function BattleLogic.AddMP(camp, mp)
|
||||
if camp == 0 then
|
||||
playerMP = math.min(playerMP + mp, 100)
|
||||
else
|
||||
enemyMP = math.min(playerMP + mp, 100)
|
||||
end
|
||||
end
|
||||
|
||||
function BattleLogic.GetMP(camp)
|
||||
return camp == 0 and playerMP or enemyMP
|
||||
end
|
||||
|
||||
function BattleLogic.GenerateBuffId()
|
||||
curBuffId = curBuffId + 1
|
||||
return curBuffId
|
||||
end
|
||||
|
||||
function BattleLogic.AddRole(roleData)
|
||||
curUid = curUid + 1
|
||||
local data = RoleLogic.New(curUid, roleData)
|
||||
tbObjList:Add(curUid, data)
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.AddRole, data)
|
||||
end
|
||||
|
||||
function BattleLogic.InitAggro()
|
||||
for i=1, tbObjList.size do
|
||||
if tbObjList.vList[i].camp == 1 then
|
||||
playerAggro = tbObjList.vList[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
for i=1, tbObjList.size do
|
||||
if tbObjList.vList[i].camp == 0 then
|
||||
enemyAggro = tbObjList.vList[i]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BattleLogic.SetAggro(role, duration)
|
||||
if role.camp == 1 then
|
||||
if playerAggroChangable then
|
||||
playerAggro = role
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.ZoomChange, role, math.max(duration, 0.3))
|
||||
playerAggroChangable = false
|
||||
BattleLogic.WaitForTrigger(duration-BattleLogic.GameDeltaTime, function () --减去一帧避免卡点
|
||||
playerAggroChangable = true
|
||||
end)
|
||||
end
|
||||
else
|
||||
if enemyAggroChangable then
|
||||
enemyAggro = role
|
||||
enemyAggroChangable = false
|
||||
BattleLogic.WaitForTrigger(duration-BattleLogic.GameDeltaTime, function () --减去一帧避免卡点
|
||||
enemyAggroChangable = true
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BattleLogic.GetAggro(camp)
|
||||
if camp == 0 then
|
||||
if not playerAggro or playerAggro.isDead then
|
||||
for i=1, tbObjList.size do
|
||||
if tbObjList.vList[i].camp == 1 and not tbObjList.vList[i].isDead then
|
||||
playerAggro = tbObjList.vList[i]
|
||||
BattleLogic.SetAggro(playerAggro, 0)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return playerAggro
|
||||
else
|
||||
if not enemyAggro or enemyAggro.isDead then
|
||||
for i=1, tbObjList.size do
|
||||
if tbObjList.vList[i].camp == 0 and not tbObjList.vList[i].isDead then
|
||||
enemyAggro = tbObjList.vList[i]
|
||||
BattleLogic.SetAggro(enemyAggro, 0)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return enemyAggro
|
||||
end
|
||||
end
|
||||
|
||||
function BattleLogic.WaitForTrigger(delayTime, action)
|
||||
tbActionListCount = tbActionListCount + 1
|
||||
tbActionList[tbActionListCount] = { curFrame + floor(delayTime * BattleLogic.GameFrameRate + 0.5), action }
|
||||
end
|
||||
|
||||
function BattleLogic.AddOption(opType, opArg)
|
||||
table.insert(optionRecord, {curFrame + 1, opType, opArg})
|
||||
end
|
||||
|
||||
function BattleLogic.GetOption()
|
||||
return optionRecord
|
||||
end
|
||||
|
||||
function BattleLogic.HasObj(obj)
|
||||
return obj and tbObjList.kvList[obj.uid]
|
||||
end
|
||||
|
||||
function BattleLogic.RemoveObj(uid)
|
||||
local role = tbObjList.kvList[uid]
|
||||
if role then
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.RemoveRole, role)
|
||||
tbObjList:Remove(uid)
|
||||
end
|
||||
end
|
||||
|
||||
function BattleLogic.CurFrame()
|
||||
return curFrame
|
||||
end
|
||||
|
||||
function BattleLogic.Query(func, inCludeDeadRole)
|
||||
local list = {}
|
||||
local index = 1
|
||||
if func then
|
||||
for i=1, tbObjList.size do
|
||||
local v = tbObjList.vList[i]
|
||||
if func(v) and (inCludeDeadRole or not v.isDead) then
|
||||
list[index] = v
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function BattleLogic.ClearOrder()
|
||||
local index = 1
|
||||
local count = tbObjList.size
|
||||
while index <= count do
|
||||
if tbObjList.vList[index].camp == 1 then
|
||||
BattleLogic.RemoveObj(tbObjList.vList[index].uid)
|
||||
count = count - 1
|
||||
else
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local tmpObj, index, bMyAllDead, bEnemyAllDead
|
||||
|
||||
function BattleLogic.Update()
|
||||
curFrame = curFrame + 1
|
||||
|
||||
for i=1, #optionRecord do
|
||||
if optionRecord[i][1] == curFrame then
|
||||
local opType = optionRecord[i][2]
|
||||
local opArg = optionRecord[i][3]
|
||||
if opType == 1 then --自动手动
|
||||
for i=1, tbObjList.size do
|
||||
tmpObj = tbObjList.vList[i]
|
||||
if tmpObj.camp == 0 then
|
||||
tmpObj.Auto = opArg == 1
|
||||
end
|
||||
end
|
||||
elseif opType == 2 then --释放skill
|
||||
local role = tbObjList.kvList[opArg]
|
||||
if role and role.skill then
|
||||
role.skill:Cast()
|
||||
end
|
||||
elseif opType == 3 then --释放superSkill
|
||||
local role = tbObjList.kvList[opArg]
|
||||
if role and role.superSkill then
|
||||
role.superSkill:Cast()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
index = 1
|
||||
while index <= tbActionListCount do
|
||||
if tbActionList[index][1] <= curFrame then
|
||||
if tbActionList[index][2] then
|
||||
tbActionList[index][2]()
|
||||
end
|
||||
table.remove(tbActionList, index)
|
||||
tbActionListCount = tbActionListCount - 1
|
||||
else
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
|
||||
if playerMP == 100 then
|
||||
if Random.Range01() < 0.5 then
|
||||
local roleArr = BattleLogic.Query(function (r) return r.camp == 0 end)
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.AOE, 0)
|
||||
--延迟1帧释放效果
|
||||
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function ()
|
||||
for i = 1, #roleArr do
|
||||
local role = roleArr[i]
|
||||
BattleLogic.WaitForTrigger(0.3, function ()
|
||||
BattleUtil.ApplyTreat(role, role, 50)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
else
|
||||
local roleArr = BattleLogic.Query(function (r) return r.camp == 1 end)
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.AOE, 1)
|
||||
--延迟1帧释放效果
|
||||
BattleLogic.WaitForTrigger(BattleLogic.GameDeltaTime, function ()
|
||||
for i = 1, #roleArr do
|
||||
local role = roleArr[i]
|
||||
for j=1, 4 do
|
||||
BattleLogic.WaitForTrigger(0.1 * (j-1), function ()
|
||||
BattleUtil.ApplyDamage(nil, role, 5)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
playerMP = 0
|
||||
BattleLogic.SkillUsable = false
|
||||
BattleLogic.WaitForTrigger(2, function ()
|
||||
BattleLogic.SkillUsable = true
|
||||
end)
|
||||
end
|
||||
|
||||
bMyAllDead = true
|
||||
bEnemyAllDead = true
|
||||
for i=1, tbObjList.size do
|
||||
tmpObj = tbObjList.vList[i]
|
||||
if not tmpObj.isDead then
|
||||
tmpObj:Update()
|
||||
if tmpObj.camp == 0 then
|
||||
bMyAllDead = false
|
||||
else
|
||||
bEnemyAllDead = false
|
||||
end
|
||||
end
|
||||
end
|
||||
if bMyAllDead then
|
||||
BattleLogic.IsEnd = true
|
||||
BattleLogic.Result = 0
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, 0)
|
||||
end
|
||||
if bEnemyAllDead then
|
||||
if BattleLogic.CurOrder == BattleLogic.TotalOrder then
|
||||
BattleLogic.IsEnd = true
|
||||
BattleLogic.Result = 1
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.BattleEnd, 1)
|
||||
else
|
||||
BattleLogic.CurOrder = BattleLogic.CurOrder + 1
|
||||
--for i=1, tbObjList.size do --切波次重置技能冷却时间
|
||||
-- tmpObj = tbObjList.vList[i]
|
||||
-- if tmpObj.camp == 0 then
|
||||
-- if tmpObj.skill then
|
||||
-- tmpObj.skill.sp = 0
|
||||
-- end
|
||||
-- if tmpObj.superSkill then
|
||||
-- tmpObj.superSkill.sp = 0
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
--playerMP = 0
|
||||
--tbActionList = {}
|
||||
--tbActionListCount = 0
|
||||
BattleLogic.SkillUsable = true
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.BattleOrderChange, BattleLogic.CurOrder)
|
||||
BattleLogic.StartOrder()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--Debug专用
|
||||
function BattleLogic.SetDebug()
|
||||
local v
|
||||
for i=1, tbObjList.size do
|
||||
v = tbObjList.vList[i]
|
||||
v.IsDebug = not v.IsDebug
|
||||
end
|
||||
end
|
||||
|
||||
--Debug专用
|
||||
function BattleLogic.SetRoleValue(uid, name, value)
|
||||
if tbObjList.kvList[uid] then
|
||||
tbObjList.kvList[uid].data:SetValue(name, value)
|
||||
end
|
||||
end
|
||||
|
||||
--Debug专用
|
||||
function BattleLogic.SetRoleDebug(uid, isDebug)
|
||||
if tbObjList.kvList[uid] then
|
||||
tbObjList.kvList[uid].IsDebug = isDebug
|
||||
end
|
||||
end
|
||||
|
||||
--Record专用
|
||||
function BattleLogic.RecordSeed(seed)
|
||||
table.insert(record, string.format("frame:%d, seed:%d", curFrame, seed))
|
||||
end
|
||||
|
||||
--Record专用
|
||||
function BattleLogic.RecordRoleProperty(uid, camp, name, value, delta)
|
||||
table.insert(record, string.format("frame:%d, uid:%d, camp:%d, name:%s, value:%d, delta:%d", curFrame, uid, camp, name, value, delta))
|
||||
end
|
||||
|
||||
--Record专用
|
||||
function BattleLogic.GenerateRecordFile()
|
||||
local time = string.format("%d-%d-%d-%d-%d-%d",
|
||||
os.date("%Y"),
|
||||
os.date("%m"),
|
||||
os.date("%d"),
|
||||
os.date("%H"),
|
||||
os.date("%M"),
|
||||
os.date("%S"))
|
||||
local file = io.open("BattleRecord/"..time..".txt", "a")
|
||||
for i=1, #record do
|
||||
file:write(record[i].."\n")
|
||||
end
|
||||
io.close(file)
|
||||
end
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
Aura = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function Aura:SetData(...)
|
||||
--log("Aura:SetData")
|
||||
local args = {...}
|
||||
self.action = args[1]
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function Aura:OnStart()
|
||||
--log("Aura:OnStart")
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function Aura:OnTrigger()
|
||||
--log("Aura:OnTrigger")
|
||||
if self.action then
|
||||
self.action(self.target)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function Aura:OnEnd()
|
||||
--log("Aura:OnEnd")
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function Aura:OnCover(newBuff)
|
||||
--log("Aura:OnCover")
|
||||
return true
|
||||
end
|
||||
|
||||
return Aura
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
Brand = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function Brand:SetData(...)
|
||||
--log("Brand:SetData")
|
||||
local args = {...}
|
||||
self.flag = args[1]
|
||||
self.cover = true
|
||||
self.layer = 1
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function Brand:OnStart()
|
||||
--log("Brand:OnStart")
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function Brand:OnTrigger()
|
||||
--log("Brand:OnTrigger")
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function Brand:OnEnd()
|
||||
--log("Brand:OnEnd")
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function Brand:OnCover(newBuff)
|
||||
--log("Brand:OnCover")
|
||||
newBuff.layer = self.layer + 1
|
||||
return true
|
||||
end
|
||||
|
||||
return Brand
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
Control = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function Control:SetData(...)
|
||||
--log("Control:SetData")
|
||||
local args = {...}
|
||||
self.ctrlType = args[1]
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function Control:OnStart()
|
||||
--log("Control:OnStart")
|
||||
if self.ctrlType == 1 then --眩晕
|
||||
self.target.enable = false
|
||||
elseif self.ctrlType == 2 then --沉默
|
||||
|
||||
elseif self.ctrlType == 3 then --嘲讽
|
||||
self.target.lockTarget = self.caster
|
||||
elseif self.ctrlType == 4 then --禁疗
|
||||
|
||||
elseif self.ctrlType == 5 then --致盲
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function Control:OnTrigger()
|
||||
--log("Control:OnTrigger")
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function Control:OnEnd()
|
||||
--log("Control:OnEnd")
|
||||
if self.ctrlType == 1 then --眩晕
|
||||
self.target.enable = true
|
||||
elseif self.ctrlType == 2 then --沉默
|
||||
|
||||
elseif self.ctrlType == 3 then --嘲讽
|
||||
self.target.lockTarget = nil
|
||||
elseif self.ctrlType == 4 then --禁疗
|
||||
|
||||
elseif self.ctrlType == 5 then --致盲
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function Control:OnCover(newBuff)
|
||||
--log("Control:OnCover")
|
||||
return true
|
||||
end
|
||||
|
||||
return Control
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
DOT = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function DOT:SetData(...)
|
||||
--log("DOT:SetData")
|
||||
local args = {...}
|
||||
self.interval = args[1]
|
||||
self.damageType = args[2] --1 燃烧 2 中毒 3 流血
|
||||
self.damagePro = args[3] --1 物理 2 魔法
|
||||
self.damageFactor = args[4] --伤害系数
|
||||
self.isDeBuff = true
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function DOT:OnStart()
|
||||
--log("DOT:OnStart")
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function DOT:OnTrigger()
|
||||
--log("DOT:OnTrigger")
|
||||
BattleUtil.CalDamage(self.caster, self.target, self.damagePro, self.damageFactor)
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function DOT:OnEnd()
|
||||
--log("DOT:OnEnd")
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function DOT:OnCover(newBuff)
|
||||
--log("DOT:OnCover")
|
||||
return true
|
||||
end
|
||||
|
||||
return DOT
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
HOT = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function HOT:SetData(...)
|
||||
--log("HOT:SetData")
|
||||
local args = {...}
|
||||
self.interval = args[1]
|
||||
self.healValue = args[2]
|
||||
self.isBuff = true
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function HOT:OnStart()
|
||||
--log("HOT:OnStart")
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function HOT:OnTrigger()
|
||||
--log("HOT:OnTrigger")
|
||||
BattleUtil.ApplyTreat(self.caster, self.target, self.healValue)
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function HOT:OnEnd()
|
||||
--log("HOT:OnEnd")
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function HOT:OnCover(newBuff)
|
||||
--log("HOT:OnCover")
|
||||
return true
|
||||
end
|
||||
|
||||
return HOT
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
PropertyChange = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function PropertyChange:SetData(...)
|
||||
--log("PropertyChange:SetData")
|
||||
local args = {...}
|
||||
self.propertyName = args[1]
|
||||
self.Value = args[2]
|
||||
self.changeType = args[3]
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function PropertyChange:OnStart()
|
||||
--log("PropertyChange:OnStart")
|
||||
if self.changeType == 1 then --加算
|
||||
self.delta = self.target.data:AddValue(self.propertyName, self.Value)
|
||||
self.isBuff = true
|
||||
elseif self.changeType == 2 then --乘加算(百分比属性加算)
|
||||
self.delta = self.target.data:AddPencentValue(self.propertyName, self.Value)
|
||||
self.isBuff = true
|
||||
elseif self.changeType == 3 then --减算
|
||||
self.delta = self.target.data:SubValue(self.propertyName, self.Value)
|
||||
self.isDeBuff = true
|
||||
elseif self.changeType == 4 then --乘减算(百分比属性减算)
|
||||
self.delta = self.target.data:SubPencentValue(self.propertyName, self.Value)
|
||||
self.isDeBuff = true
|
||||
end
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function PropertyChange:OnTrigger()
|
||||
--log("PropertyChange:OnTrigger")
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function PropertyChange:OnEnd()
|
||||
--log("PropertyChange:OnEnd")
|
||||
if self.changeType == 3 or self.changeType == 4 then
|
||||
self.target.data:AddValue(self.propertyName, self.delta)
|
||||
else
|
||||
self.target.data:SubDeltaValue(self.propertyName, self.delta)
|
||||
end
|
||||
end
|
||||
|
||||
--只有当Cover字段为true时触发,返回true则被新效果覆盖
|
||||
function PropertyChange:OnCover(newBuff)
|
||||
--log("PropertyChange:OnCover")
|
||||
if self.layer then
|
||||
if self.maxCount == 0 then
|
||||
newBuff.layer = self.layer + 1
|
||||
else
|
||||
newBuff.layer = math.min(self.layer + 1, self.maxCount)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
return PropertyChange
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
require("Modules/Battle/Logic/Base/Buff")
|
||||
Shield = Buff:New()
|
||||
|
||||
--初始化Buff,通过传入一些自定义参数控制成长相关的数值
|
||||
function Shield:SetData(...)
|
||||
--log("Shield:SetData")
|
||||
local args = {...}
|
||||
self.shieldValue = args[1] --护盾值
|
||||
self.dmgReboundFactor = args[2] --伤害反弹系数
|
||||
self.damageSum = 0 --记录承受的伤害
|
||||
end
|
||||
|
||||
--初始化后调用一次
|
||||
function Shield:OnStart()
|
||||
--log("Shield:OnStart")
|
||||
if not self.target.shield then
|
||||
self.target.shield = {}
|
||||
end
|
||||
table.insert(self.target.shield, self)
|
||||
self.target.Event:DispatchEvent(BattleEventName.ShieldAdd, self)
|
||||
end
|
||||
|
||||
--间隔N帧触发,返回true时表示继续触发,返回false立刻触发OnEnd
|
||||
function Shield:OnTrigger()
|
||||
--log("Shield:OnTrigger")
|
||||
return true
|
||||
end
|
||||
|
||||
--效果结束时调用一次
|
||||
function Shield:OnEnd()
|
||||
--log("Shield:OnEnd")
|
||||
if self.target.shield then
|
||||
for i = 1, #self.target.shield do
|
||||
if self.target.shield[i] == self then
|
||||
table.remove(self.target.shield, i)
|
||||
BattleUtil.ApplyDamage(self.caster, self.target, math.floor(self.dmgReboundFactor * self.damageSum))
|
||||
self.target.Event:DispatchEvent(BattleEventName.ShieldEnd, self)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--只有当cover字段为true时触发,返回true则被新效果覆盖
|
||||
function Shield:OnCover(newBuff)
|
||||
--log("Shield:OnCover")
|
||||
return true
|
||||
end
|
||||
|
||||
return Shield
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
local index = 0
|
||||
local function indexAdd()
|
||||
index = index + 1
|
||||
return index
|
||||
end
|
||||
|
||||
BattleEventName = {
|
||||
BattleOrderChange = indexAdd(),
|
||||
BattleEnd = indexAdd(),
|
||||
AddRole = indexAdd(),
|
||||
RemoveRole = indexAdd(),
|
||||
MpChanged = indexAdd(),
|
||||
MpAdd = indexAdd(),
|
||||
MpSub = indexAdd(),
|
||||
BattleRoleDead = indexAdd(),
|
||||
|
||||
RoleBeDamaged = indexAdd(),
|
||||
RoleDamage = indexAdd(),
|
||||
RoleBeTreated = indexAdd(),
|
||||
RoleTreat = indexAdd(),
|
||||
RoleBeCrit = indexAdd(),
|
||||
RoleCrit = indexAdd(),
|
||||
RoleDodge = indexAdd(),
|
||||
RoleBeDodge = indexAdd(),
|
||||
RoleDead = indexAdd(),
|
||||
RoleRevive = indexAdd(),
|
||||
RolePropertyChanged = indexAdd(),
|
||||
|
||||
SkillCast = indexAdd(),
|
||||
|
||||
ZoomIn = indexAdd(),
|
||||
ZoomChange = indexAdd(),
|
||||
ZoomOut = indexAdd(),
|
||||
|
||||
AOE = indexAdd(),
|
||||
|
||||
RoleViewBullet = indexAdd(), --弹道飞行击中表现
|
||||
|
||||
BuffStart = indexAdd(),
|
||||
BuffTrigger = indexAdd(),
|
||||
BuffEnd = indexAdd(),
|
||||
BuffCountChange = indexAdd(),
|
||||
BuffCover = indexAdd(),
|
||||
|
||||
ShieldAdd = indexAdd(),
|
||||
ShieldEnd = indexAdd(),
|
||||
}
|
||||
|
||||
index = 0
|
||||
RoleDataName = {
|
||||
Level = indexAdd(), --等级
|
||||
Hp = indexAdd(), --生命
|
||||
MaxHp = indexAdd(), --最大生命
|
||||
Attack = indexAdd(), --攻击力
|
||||
PhysicalDefence = indexAdd(),--护甲
|
||||
MagicDefence = indexAdd(),--魔抗
|
||||
Speed = indexAdd(),--速度
|
||||
DamageBocusFactor = indexAdd(), --伤害加成系数(%)
|
||||
DamageReduceFactor = indexAdd(), --伤害减免系数(%)
|
||||
Hit = indexAdd(), --命中率(%)
|
||||
Dodge = indexAdd(), --闪避率(%)
|
||||
Crit = indexAdd(), --暴击率(%)
|
||||
CritDamageFactor = indexAdd(), --暴击伤害系数(%)
|
||||
TreatFacter = indexAdd(),--治疗加成系数(%)
|
||||
|
||||
FireDamageBocusFactor = indexAdd(), --火系伤害加成系数(%)
|
||||
FireDamageReduceFactor = indexAdd(), --火系伤害减免系数(%)
|
||||
WindDamageBocusFactor = indexAdd(), --风系伤害加成系数(%)
|
||||
WindDamageReduceFactor = indexAdd(), --风系伤害减免系数(%)
|
||||
IceDamageBocusFactor = indexAdd(), --冰系伤害加成系数(%)
|
||||
IceDamageReduceFactor = indexAdd(), --冰系伤害减免系数(%)
|
||||
LandDamageBocusFactor = indexAdd(), --地系伤害加成系数(%)
|
||||
LandDamageReduceFactor = indexAdd(), --地系伤害减免系数(%)
|
||||
LightDamageBocusFactor = indexAdd(), --光系伤害加成系数(%)
|
||||
LightDamageReduceFactor = indexAdd(), --光系伤害减免系数(%)
|
||||
DarkDamageBocusFactor = indexAdd(), --暗系伤害加成系数(%)
|
||||
DarkDamageReduceFactor = indexAdd(), --暗系伤害减免系数(%)
|
||||
}
|
||||
|
||||
BuffName = {
|
||||
Poison = "Poison",
|
||||
PropertyChange = "PropertyChange",
|
||||
Taunt = "Taunt",
|
||||
Bleed = "Bleed",
|
||||
Frozen = "Frozen",
|
||||
Stun = "Stun",
|
||||
HOT = "HOT",
|
||||
DOT = "DOT",
|
||||
Control = "Control",
|
||||
Aura = "Aura",
|
||||
Brand = "Brand",
|
||||
Shield = "Shield",
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
BattleDictionary = {}
|
||||
function BattleDictionary.New()
|
||||
local o = {}
|
||||
setmetatable(o, BattleDictionary)
|
||||
BattleDictionary.__index = BattleDictionary
|
||||
o.kList = {}
|
||||
o.vList = {}
|
||||
o.kvList = {}
|
||||
o.size = 0
|
||||
return o
|
||||
end
|
||||
|
||||
function BattleDictionary:Add(k,v)
|
||||
if not self.kvList[k] then
|
||||
self.size = self.size + 1
|
||||
self.kvList[k] = v
|
||||
self.kList[self.size] = k
|
||||
self.vList[self.size] = v
|
||||
end
|
||||
end
|
||||
|
||||
function BattleDictionary:Remove(k)
|
||||
if self.kvList[k] then
|
||||
for i=1, self.size do
|
||||
if self.vList[i] == self.kvList[k] then
|
||||
self.size = self.size - 1
|
||||
table.remove(self.kList, i)
|
||||
table.remove(self.vList, i)
|
||||
self.kvList[k] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BattleDictionary:Set(k,v)
|
||||
self:Remove(k)
|
||||
self:Add(k,v)
|
||||
end
|
||||
|
||||
function BattleDictionary:Clear()
|
||||
self.kList = {}
|
||||
self.vList = {}
|
||||
self.kvList = {}
|
||||
self.size = 0
|
||||
end
|
||||
|
||||
function BattleDictionary:Count()
|
||||
return self.size
|
||||
end
|
||||
|
||||
function BattleDictionary:Foreach(func)
|
||||
for i = 1, self.size do
|
||||
if func then
|
||||
func(self.kList[i], self.vList[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
BattleQueue = {}
|
||||
function BattleQueue.New()
|
||||
local o = {}
|
||||
setmetatable(o, BattleQueue)
|
||||
BattleQueue.__index = BattleQueue
|
||||
o.head = -1
|
||||
o.rear = -1
|
||||
o.list = {}
|
||||
o.size = 0
|
||||
return o
|
||||
end
|
||||
|
||||
function BattleQueue:Enqueue(e)
|
||||
if self.size == 0 then
|
||||
self.head = 0
|
||||
self.rear = 1
|
||||
self.size = 1
|
||||
self.list[self.rear] = e
|
||||
else
|
||||
self.rear = self.rear + 1
|
||||
self.list[self.rear] = e
|
||||
self.size = self.size + 1
|
||||
end
|
||||
end
|
||||
|
||||
function BattleQueue:Dequeue()
|
||||
if self.size == 0 then
|
||||
error("lua queue is isEmpty")
|
||||
return nil
|
||||
end
|
||||
self.size = self.size - 1
|
||||
self.head = self.head + 1
|
||||
return self.list[self.head]
|
||||
end
|
||||
|
||||
function BattleQueue:Clear()
|
||||
self.list = {}
|
||||
self.size = 0
|
||||
self.head = -1
|
||||
self.rear = -1
|
||||
end
|
||||
|
||||
function BattleQueue:Count()
|
||||
return self.size
|
||||
end
|
||||
|
||||
function BattleQueue:Foreach(func)
|
||||
for i = self.head + 1, self.rear do
|
||||
if func then
|
||||
func(self.list[i])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function BattleQueue:Contain(e)
|
||||
for i = self.head + 1, self.rear do
|
||||
if e == self.list[i] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
BattleUtil = {}
|
||||
--local BattleUtil = BattleUtil
|
||||
local floor = math.floor
|
||||
local max = math.max
|
||||
local min = math.min
|
||||
--local Random = Random
|
||||
--local RoleDataName = RoleDataName
|
||||
--local BattleEventName = BattleEventName
|
||||
|
||||
local function clamp(v, minValue, maxValue)
|
||||
if v < minValue then
|
||||
return minValue
|
||||
end
|
||||
if v > maxValue then
|
||||
return maxValue
|
||||
end
|
||||
return v
|
||||
end
|
||||
|
||||
function BattleUtil.CreateBuffId(skill, index)
|
||||
local id = 0
|
||||
if skill.preAI then --主动技能生成buff
|
||||
id = skill.owner.uid * 10000 + index
|
||||
else --被动技能生成buff
|
||||
id = skill.owner.uid * 1000 + index
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
function BattleUtil.CalBaseDamage(atkRole, defRole, baseDamage, baseFactor)
|
||||
local atkData, defData = atkRole.data, defRole.data
|
||||
if not baseFactor then baseFactor = 1 end
|
||||
|
||||
local elementDamage, elementReduce = 0
|
||||
if skillAttribute == 0 then --无属性
|
||||
elementDamage = 0
|
||||
elementReduce = 0
|
||||
elseif skillAttribute == 1 then --火系
|
||||
elementDamage = atkData:GetData(RoleDataName.FireDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.FireDamageReduceFactor)
|
||||
elseif skillAttribute == 2 then --风系
|
||||
elementDamage = atkData:GetData(RoleDataName.WindDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.WindDamageReduceFactor)
|
||||
elseif skillAttribute == 3 then --水系
|
||||
elementDamage = atkData:GetData(RoleDataName.IceDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.IceDamageReduceFactor)
|
||||
elseif skillAttribute == 4 then --地系
|
||||
elementDamage = atkData:GetData(RoleDataName.LandDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.LandDamageReduceFactor)
|
||||
elseif skillAttribute == 5 then --光系
|
||||
elementDamage = atkData:GetData(RoleDataName.LightDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.LightDamageReduceFactor)
|
||||
elseif skillAttribute == 6 then --暗系
|
||||
elementDamage = atkData:GetData(RoleDataName.DarkDamageBocusFactor)
|
||||
elementReduce = defData:GetData(RoleDataName.DarkDamageReduceFactor)
|
||||
end
|
||||
|
||||
|
||||
--伤害 =(基础伤害*(1+己伤害加成-目标伤害减免)*(1+己方属性伤害加成-目标属性伤害减免),10%*己攻)
|
||||
local damage = baseDamage * baseFactor *
|
||||
(1 + atkData:GetData(RoleDataName.DamageBocusFactor)) * (1 - defData:GetData(RoleDataName.DamageReduceFactor)) *
|
||||
(1 + atkData:GetData(RoleDataName.FireDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.FireDamageReduceFactor)) * --火系
|
||||
(1 + atkData:GetData(RoleDataName.WindDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.WindDamageReduceFactor)) * --风系
|
||||
(1 + atkData:GetData(RoleDataName.IceDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.IceDamageReduceFactor)) * --冰系
|
||||
(1 + atkData:GetData(RoleDataName.LandDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.LandDamageReduceFactor)) * --地系
|
||||
(1 + atkData:GetData(RoleDataName.LightDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.LightDamageReduceFactor)) * --光系
|
||||
(1 + atkData:GetData(RoleDataName.DarkDamageBocusFactor)) * (1 - defData:GetData(RoleDataName.DarkDamageReduceFactor)) --暗系
|
||||
return damage
|
||||
end
|
||||
|
||||
function BattleUtil.CalHit(atkRole, defRole)
|
||||
--命中率 = clamp(自身命中率-敌方闪避率,0,1)
|
||||
local hit = atkRole:GetRoleData(RoleDataName.Hit)
|
||||
local dodge = defRole:GetRoleData(RoleDataName.Dodge)
|
||||
|
||||
local bHit = Random.Range01() <= clamp(hit - dodge, 0, 1)
|
||||
|
||||
if bHit then
|
||||
else
|
||||
atkRole.Event:DispatchEvent(BattleEventName.RoleDodge)
|
||||
defRole.Event:DispatchEvent(BattleEventName.RoleBeDodge)
|
||||
end
|
||||
return bHit
|
||||
end
|
||||
|
||||
function BattleUtil.CalCrit(atkRole, defRole)
|
||||
local bCrit = Random.Range01() <= clamp(atkRole:GetRoleData(RoleDataName.Crit), 0, 1)
|
||||
|
||||
if bCrit then
|
||||
atkRole.Event:DispatchEvent(BattleEventName.RoleCrit, defRole)
|
||||
defRole.Event:DispatchEvent(BattleEventName.RoleBeCrit, atkRole)
|
||||
end
|
||||
return bCrit
|
||||
end
|
||||
|
||||
function BattleUtil.CalShield(atkRole, defRole, damage)
|
||||
if defRole.shield then
|
||||
local buff
|
||||
for i=1, #defRole.shield do
|
||||
buff = defRole.shield[i]
|
||||
if damage < buff.shieldValue then
|
||||
buff.shieldValue = buff.shieldValue - damage
|
||||
buff.damageSum = buff.damageSum + damage
|
||||
return 0
|
||||
else
|
||||
buff.damageSum = buff.damageSum + buff.shieldValue
|
||||
damage = damage - buff.shieldValue
|
||||
buff.shieldValue = 0
|
||||
buff.disperse = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return damage
|
||||
end
|
||||
|
||||
function BattleUtil.ApplyDamage(atkRole, defRole, damage, bCrit)
|
||||
if not bCrit then bCrit = false end
|
||||
damage = floor(damage + 0.5)
|
||||
local finalDmg = defRole.data:SubValue(RoleDataName.Hp, damage)
|
||||
if finalDmg > 0 then
|
||||
if atkRole then
|
||||
atkRole.Event:DispatchEvent(BattleEventName.RoleDamage, defRole, damage, bCrit)
|
||||
end
|
||||
defRole.Event:DispatchEvent(BattleEventName.RoleBeDamaged, atkRole, damage, bCrit)
|
||||
|
||||
if defRole:GetRoleData(RoleDataName.Hp) <= 0 then
|
||||
defRole.isDead = true
|
||||
defRole.Event:DispatchEvent(BattleEventName.RoleDead)
|
||||
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, defRole)
|
||||
end
|
||||
end
|
||||
return finalDmg
|
||||
end
|
||||
|
||||
--执行完整的命中,伤害,暴击计算,返回命中,暴击
|
||||
function BattleUtil.CalDamage(atkRole, defRole, damageType, baseFactor)
|
||||
local bCrit = false
|
||||
local baseDamage
|
||||
bCrit = BattleUtil.CalCrit(atkRole, defRole)
|
||||
local defence = 0
|
||||
if damageType == 1 then --1 物理 2 魔法
|
||||
defence = defRole:GetRoleData(RoleDataName.PhysicalDefence)
|
||||
else
|
||||
defence = defRole:GetRoleData(RoleDataName.MagicDefence)
|
||||
end
|
||||
local attack = 0
|
||||
if atkRole.GetAttackFunc then
|
||||
attack = atkRole.GetAttackFunc(bCrit)
|
||||
else
|
||||
attack = atkRole:GetRoleData(RoleDataName.Attack)
|
||||
end
|
||||
--计算暴击
|
||||
if bCrit or defRole.isFlagCrit then
|
||||
local critDamageFactor = atkRole:GetRoleData(RoleDataName.CritDamageFactor)
|
||||
baseDamage = attack * critDamageFactor - 0.5 * defence
|
||||
else
|
||||
baseDamage = attack - 0.5 * defence
|
||||
end
|
||||
baseDamage = BattleUtil.CalBaseDamage(atkRole, defRole, baseDamage, baseFactor)
|
||||
baseDamage = max(baseDamage, 0.1 * attack)
|
||||
baseDamage = BattleUtil.CalShield(atkRole, defRole, baseDamage)
|
||||
local finalDmg = 0 --计算实际造成的扣血
|
||||
if not defRole.isDead then
|
||||
finalDmg = BattleUtil.ApplyDamage(atkRole, defRole, baseDamage, bCrit)
|
||||
end
|
||||
return finalDmg, bCrit
|
||||
end
|
||||
|
||||
function BattleUtil.ApplyTreat(castRole, targetRole, value, baseFactor)
|
||||
if not baseFactor then baseFactor = 1 end
|
||||
local maxHp = targetRole:GetRoleData(RoleDataName.MaxHp)
|
||||
local hp = targetRole:GetRoleData(RoleDataName.Hp)
|
||||
local factor = castRole:GetRoleData(RoleDataName.TreatFacter)
|
||||
local treat = min(floor(value * baseFactor * factor + 0.5), maxHp - hp)
|
||||
targetRole.data:AddValue(RoleDataName.Hp, treat)
|
||||
castRole.Event:DispatchEvent(BattleEventName.RoleTreat, targetRole, treat)
|
||||
targetRole.Event:DispatchEvent(BattleEventName.RoleBeTreated, castRole, treat)
|
||||
end
|
||||
|
||||
function BattleUtil.RandomAction(rand, action)
|
||||
if Random.Range01() <= rand and action then
|
||||
action()
|
||||
end
|
||||
end
|
||||
|
||||
function BattleUtil.RandomList(arr)
|
||||
if #arr <= 1 then return end
|
||||
local index
|
||||
for i=#arr, 1, -1 do
|
||||
index = Random.RangeInt(1, i)
|
||||
arr[i], arr[index] = arr[index], arr[i]
|
||||
end
|
||||
end
|
||||
|
||||
function BattleUtil.GetPropertyName(type)
|
||||
if type == 1 then
|
||||
return RoleDataName.Strength
|
||||
elseif type == 2 then
|
||||
return RoleDataName.Energy
|
||||
elseif type == 3 then
|
||||
return RoleDataName.Vitality
|
||||
elseif type == 4 then
|
||||
return RoleDataName.Dexterity
|
||||
elseif type == 5 then
|
||||
return RoleDataName.Speed
|
||||
elseif type == 6 then
|
||||
return RoleDataName.PhysicalAttack
|
||||
elseif type == 7 then
|
||||
return RoleDataName.MagicAttack
|
||||
elseif type == 8 then
|
||||
return RoleDataName.PhysicalDefence
|
||||
elseif type == 9 then
|
||||
return RoleDataName.MagicDefence
|
||||
end
|
||||
end
|
||||
|
||||
function BattleUtil.GetHPPencent(role)
|
||||
return role:GetRoleData(RoleDataName.Hp) / role:GetRoleData(RoleDataName.MaxHp) * 100
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
RoleLogic = {}
|
||||
RoleLogic.__index = RoleLogic
|
||||
--local RoleLogic = RoleLogic
|
||||
--local RoleDataName = RoleDataName
|
||||
--local BattleLogic = BattleLogic
|
||||
local Random = Random
|
||||
local floor = math.floor
|
||||
local max = math.max
|
||||
local Passivity = require("Modules/Battle/Logic/Base/Passivity")
|
||||
local function InitData(property)
|
||||
--初始化属性
|
||||
local index = 1
|
||||
local getData = function(property)
|
||||
local p = property[index]
|
||||
index = index + 1
|
||||
return p
|
||||
end
|
||||
return {
|
||||
[RoleDataName.Level] = {getData(property), false},
|
||||
[RoleDataName.Hp] = {getData(property), false},
|
||||
[RoleDataName.MaxHp] = {getData(property), false},
|
||||
[RoleDataName.Attack] = {getData(property), false},
|
||||
[RoleDataName.PhysicalDefence] = {getData(property), false},
|
||||
[RoleDataName.MagicDefence] = {getData(property), false},
|
||||
[RoleDataName.Speed] = {getData(property), false},
|
||||
[RoleDataName.DamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.DamageReduceFactor] = {getData(property), true},
|
||||
[RoleDataName.Hit] = {getData(property), true},
|
||||
[RoleDataName.Dodge] = {getData(property), true},
|
||||
[RoleDataName.Crit] = {getData(property), true},
|
||||
[RoleDataName.CritDamageFactor] = {getData(property), true},
|
||||
[RoleDataName.TreatFacter] = {getData(property), true},
|
||||
[RoleDataName.FireDamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.IceDamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.LightDamageBocusFactor] = { getData(property), true},
|
||||
[RoleDataName.WindDamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.LandDamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.DarkDamageBocusFactor] = {getData(property), true},
|
||||
[RoleDataName.FireDamageReduceFactor] = {getData(property), true},
|
||||
[RoleDataName.IceDamageReduceFactor] = {getData(property), true},
|
||||
[RoleDataName.LightDamageReduceFactor] = { getData(property), true},
|
||||
[RoleDataName.WindDamageReduceFactor] = {getData(property), true},
|
||||
[RoleDataName.LandDamageReduceFactor] = {getData(property), true},
|
||||
[RoleDataName.DarkDamageReduceFactor] = {getData(property), true},
|
||||
}
|
||||
end
|
||||
|
||||
function RoleLogic.New(uid, data)
|
||||
local instance = {}
|
||||
setmetatable(instance, RoleLogic)
|
||||
|
||||
instance.uid = uid
|
||||
instance.roleData = data
|
||||
instance.data = RoleData.New(instance, InitData(data.property))
|
||||
|
||||
instance.camp = data.camp --阵营 0:我方 1:敌方
|
||||
instance.name = data.name
|
||||
instance.roleType = 1 --阵营 1:普通 2:Boss 3:召唤物
|
||||
|
||||
instance.BuffMgr = BuffManager.New(instance)
|
||||
instance.Event = BattleEvent:New()
|
||||
|
||||
instance.passiveList = {}
|
||||
if data.skill and #data.skill > 0 then
|
||||
instance.skill = Skill:New(instance, data.skill)
|
||||
instance.skill.sp = 0
|
||||
local time = max(6-instance:GetRoleData(RoleDataName.Speed)/(8*(instance:GetRoleData(RoleDataName.Level)+10)), 1.5)
|
||||
instance.skill.spPass = floor( time * BattleLogic.GameFrameRate)
|
||||
end
|
||||
if data.superSkill and #data.superSkill > 0 then
|
||||
instance.superSkill = Skill:New(instance, data.superSkill)
|
||||
instance.superSkill.spPass = floor(instance.superSkill.cd * BattleLogic.GameFrameRate)
|
||||
instance.superSkill.sp = instance.superSkill.spPass
|
||||
end
|
||||
for i = 1, #data.passivity do
|
||||
local v = data.passivity[i]
|
||||
local id = v[1]
|
||||
local args = v[2]
|
||||
Passivity[id](instance, args)
|
||||
end
|
||||
|
||||
instance.isDead = false
|
||||
instance.Auto = true
|
||||
instance.IsDebug = false
|
||||
instance.enable = true
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
function RoleLogic:GetRoleData(property)
|
||||
return self.data:GetData(property)
|
||||
end
|
||||
|
||||
function RoleLogic:AddBuff(buff)
|
||||
self.BuffMgr:AddBuff(buff)
|
||||
end
|
||||
|
||||
function RoleLogic:Update()
|
||||
self.BuffMgr:Update()
|
||||
if not self.enable then
|
||||
return
|
||||
end
|
||||
if self.superSkill then
|
||||
if self.superSkill.sp >= self.superSkill.spPass then
|
||||
if self.skill then
|
||||
if self.skill.sp >= self.skill.spPass then
|
||||
if self.Auto and not self.IsDebug then
|
||||
if Random.Range01() <= 0.75 then
|
||||
self.skill:Cast()
|
||||
else
|
||||
self.superSkill:Cast()
|
||||
end
|
||||
end
|
||||
else
|
||||
self.skill.sp = self.skill.sp + 1
|
||||
end
|
||||
else
|
||||
if self.Auto and not self.IsDebug then
|
||||
self.superSkill:Cast()
|
||||
end
|
||||
end
|
||||
else
|
||||
self.superSkill.sp = self.superSkill.sp + 1
|
||||
end
|
||||
else
|
||||
if self.skill then
|
||||
if self.skill.sp >= self.skill.spPass then
|
||||
if self.Auto and not self.IsDebug then
|
||||
self.skill:Cast()
|
||||
end
|
||||
else
|
||||
self.skill.sp = self.skill.sp + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in New Issue