java调用lua

back_recharge
mashiyu 2019-03-12 14:05:45 +08:00
parent e5d66d4bd3
commit 373664aef1
21 changed files with 3092 additions and 0 deletions

View File

@ -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战斗异常)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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",
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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普通 2Boss 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