战斗同步
parent
ea09a2f3d3
commit
8c09de153d
|
@ -275,7 +275,9 @@ function BuffManager:PassUpdate()
|
||||||
local buff = buffList.buffer[index]
|
local buff = buffList.buffer[index]
|
||||||
if not buff.disperse -- 没过期
|
if not buff.disperse -- 没过期
|
||||||
and buff.caster.camp == curCamp -- 释放者是当前轮到的人
|
and buff.caster.camp == curCamp -- 释放者是当前轮到的人
|
||||||
and buff.caster.position == curPos then
|
and buff.caster.position == curPos
|
||||||
|
and buff.roundDuration > 0 -- 不是无限存在的buff
|
||||||
|
then
|
||||||
-- 当前轮释放的buff不结算
|
-- 当前轮释放的buff不结算
|
||||||
if buff.startRound ~= BattleLogic.GetCurRound() then
|
if buff.startRound ~= BattleLogic.GetCurRound() then
|
||||||
buff.roundPass = buff.roundPass + 1
|
buff.roundPass = buff.roundPass + 1
|
||||||
|
|
|
@ -2145,8 +2145,6 @@ local passivityList = {
|
||||||
local list = BattleLogic.Query(function(v) return v.camp == role.camp and v.position <= 3 end)
|
local list = BattleLogic.Query(function(v) return v.camp == role.camp and v.position <= 3 end)
|
||||||
for _, role in ipairs(list) do
|
for _, role in ipairs(list) do
|
||||||
BattleLogic.BuffMgr:QueryBuff(role, function(buff)
|
BattleLogic.BuffMgr:QueryBuff(role, function(buff)
|
||||||
Log(tostring(buff.type == BuffName.Shield))
|
|
||||||
Log(tostring(buff.ShieldType == ShieldTypeName.RateReduce))
|
|
||||||
if buff.type == BuffName.Shield and buff.shieldType == ShieldTypeName.RateReduce then
|
if buff.type == BuffName.Shield and buff.shieldType == ShieldTypeName.RateReduce then
|
||||||
buff:ChangeShieldValue(ct, f1)
|
buff:ChangeShieldValue(ct, f1)
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,7 +22,7 @@ function Skill:New()
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
function Skill:Init(role, effectData, type) --type 0 异妖 1 点技 2 滑技
|
function Skill:Init(role, effectData, type, targets, isAdd, isRage) --type 0 异妖 1 点技 2 滑技
|
||||||
local isTeamSkill = type == 0
|
local isTeamSkill = type == 0
|
||||||
self.type = type
|
self.type = type
|
||||||
--skill = {技能ID, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
|
--skill = {技能ID, {目标id1, 效果时间, 效果1, 效果2, ...},{目标id2, 效果时间, 效果3, 效果4, ...}, ...}
|
||||||
|
@ -34,6 +34,9 @@ function Skill:Init(role, effectData, type) --type 0 异妖 1 点技 2 滑技
|
||||||
self.id = effectData[1] -- 技能ID
|
self.id = effectData[1] -- 技能ID
|
||||||
-- self.EffectDuration = 0 -- 效果命中需要的时间
|
-- self.EffectDuration = 0 -- 效果命中需要的时间
|
||||||
|
|
||||||
|
self.targets = targets or {}
|
||||||
|
self.isAdd = isAdd
|
||||||
|
self.isRage = isRage
|
||||||
|
|
||||||
for i=2, #effectData do
|
for i=2, #effectData do
|
||||||
local v = effectData[i]
|
local v = effectData[i]
|
||||||
|
@ -95,20 +98,16 @@ end
|
||||||
|
|
||||||
-- 释放技能
|
-- 释放技能
|
||||||
-- func 技能释放完成回调
|
-- func 技能释放完成回调
|
||||||
-- targets 指定技能释放目标
|
function Skill:Cast(func)
|
||||||
-- isAdd 是否是追加技能
|
|
||||||
function Skill:Cast(func, targets, isAdd)
|
|
||||||
self.castDoneFunc = func
|
self.castDoneFunc = func
|
||||||
self.effectTargets = {}
|
self.effectTargets = {}
|
||||||
self.isAdd = isAdd
|
|
||||||
|
|
||||||
|
|
||||||
-- 先计算出技能的目标
|
-- 先计算出技能的目标
|
||||||
for i=1, self.effectList.size do
|
for i=1, self.effectList.size do
|
||||||
-- 是否重新选择目标
|
-- 是否重新选择目标
|
||||||
local isReTarget = true
|
local isReTarget = true
|
||||||
if targets and targets[i] then
|
if self.targets and self.targets[i] then
|
||||||
self.effectTargets[i] = targets[i]
|
self.effectTargets[i] = self.targets[i]
|
||||||
-- 判断是否有有效目标
|
-- 判断是否有有效目标
|
||||||
for _, role in ipairs(self.effectTargets[i]) do
|
for _, role in ipairs(self.effectTargets[i]) do
|
||||||
if not role.isDead then
|
if not role.isDead then
|
||||||
|
@ -116,7 +115,7 @@ function Skill:Cast(func, targets, isAdd)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- 重新选择目标
|
-- 重新选择目标a
|
||||||
if isReTarget then
|
if isReTarget then
|
||||||
local effectGroup = self.effectList.buffer[i]
|
local effectGroup = self.effectList.buffer[i]
|
||||||
local chooseId = effectGroup.chooseId
|
local chooseId = effectGroup.chooseId
|
||||||
|
@ -208,6 +207,5 @@ function Skill:EndSkill()
|
||||||
end)
|
end)
|
||||||
--
|
--
|
||||||
self.effectTargets = {}
|
self.effectTargets = {}
|
||||||
self.isAdd = nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ function BattleLogic.Init(data, optionData)
|
||||||
BattleLogic.BuffMgr:Init()
|
BattleLogic.BuffMgr:Init()
|
||||||
BattleLogic.IsEnd = false
|
BattleLogic.IsEnd = false
|
||||||
BattleLogic.Result = -1
|
BattleLogic.Result = -1
|
||||||
|
|
||||||
|
SkillManager.Init()
|
||||||
end
|
end
|
||||||
|
|
||||||
function BattleLogic.StartOrder()
|
function BattleLogic.StartOrder()
|
||||||
|
@ -568,6 +570,7 @@ function BattleLogic.Update()
|
||||||
end
|
end
|
||||||
|
|
||||||
BattleLogic.BuffMgr:Update()
|
BattleLogic.BuffMgr:Update()
|
||||||
|
SkillManager.Update()
|
||||||
|
|
||||||
bMyAllDead = true
|
bMyAllDead = true
|
||||||
bEnemyAllDead = true
|
bEnemyAllDead = true
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
require("Modules.Battle.Logic.SkillManager")
|
||||||
|
|
||||||
RoleLogic = {}
|
RoleLogic = {}
|
||||||
RoleLogic.__index = RoleLogic
|
RoleLogic.__index = RoleLogic
|
||||||
--local RoleLogic = RoleLogic
|
--local RoleLogic = RoleLogic
|
||||||
|
@ -42,24 +45,14 @@ function RoleLogic:Init(uid, data, position)
|
||||||
|
|
||||||
self.Event:ClearEvent()
|
self.Event:ClearEvent()
|
||||||
|
|
||||||
if data.skill and #data.skill > 0 then
|
self.skill = data.skill
|
||||||
self.skill = skillPool:Get()
|
self.superSkill = data.superSkill
|
||||||
self.skill:Init(self, data.skill, 1)
|
|
||||||
end
|
|
||||||
if data.superSkill and #data.superSkill > 0 then
|
|
||||||
self.superSkill = skillPool:Get()
|
|
||||||
self.superSkill:Init(self, data.superSkill, 2)
|
|
||||||
end
|
|
||||||
--首次读条时间=速度/(20*(等级+10)
|
--首次读条时间=速度/(20*(等级+10)
|
||||||
self.sp = 0
|
self.sp = 0
|
||||||
local time = self:GetRoleData(RoleDataName.Speed)/(20*(self:GetRoleData(RoleDataName.Level)+10))
|
local time = self:GetRoleData(RoleDataName.Speed)/(20*(self:GetRoleData(RoleDataName.Level)+10))
|
||||||
self.spPass = floor( BattleUtil.ErrorCorrection(time) * BattleLogic.GameFrameRate)
|
self.spPass = floor( BattleUtil.ErrorCorrection(time) * BattleLogic.GameFrameRate)
|
||||||
|
|
||||||
|
|
||||||
-- 技能释放列表 技能改为按列表顺序释放 方便添加追加技能
|
|
||||||
self.SkillList = {}
|
|
||||||
self.CurSkillCastIndex = 0
|
|
||||||
self.SkillCastDoneFunc = nil
|
|
||||||
--
|
--
|
||||||
self.passiveList = {}
|
self.passiveList = {}
|
||||||
if data.passivity and #data.passivity > 0 then
|
if data.passivity and #data.passivity > 0 then
|
||||||
|
@ -234,16 +227,7 @@ function RoleLogic:AddBuff(buff)
|
||||||
end
|
end
|
||||||
|
|
||||||
function RoleLogic:Dispose()
|
function RoleLogic:Dispose()
|
||||||
if self.skill then
|
|
||||||
self.skill:Dispose()
|
|
||||||
skillPool:Put(self.skill)
|
|
||||||
self.skill = nil
|
|
||||||
end
|
|
||||||
if self.superSkill then
|
|
||||||
self.superSkill:Dispose()
|
|
||||||
skillPool:Put(self.superSkill)
|
|
||||||
self.superSkill = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,47 +248,49 @@ function RoleLogic:IsAvailable()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 检测自身的技能释放
|
-- 释放技能
|
||||||
function RoleLogic:CheckCastSkill()
|
function RoleLogic:SkillCast(skill, func)
|
||||||
|
|
||||||
|
local _CastDone = function()
|
||||||
|
if func then
|
||||||
|
func()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- 角色不可用直接结束技能释放
|
-- 角色不可用直接结束技能释放
|
||||||
if not self:IsAvailable() then
|
if not skill or not self:IsAvailable() then
|
||||||
self:SkillCastDone()
|
_CastDone()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- 没有要释放的技能了结束技能释放
|
|
||||||
if self.CurSkillCastIndex >= #self.SkillList then
|
|
||||||
self:SkillCastDone()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
-- 拿到下一个技能
|
|
||||||
self.CurSkillCastIndex = self.CurSkillCastIndex + 1
|
|
||||||
local skill = self.SkillList[self.CurSkillCastIndex]
|
|
||||||
-- 技能释放回调(递归检测下一个技能)
|
|
||||||
local _CheckNext = function ()
|
|
||||||
self:CheckCastSkill()
|
|
||||||
end
|
|
||||||
-- 没有麻痹,释放普通攻击
|
-- 没有麻痹,释放普通攻击
|
||||||
if skill.type == BattleSkillType.Normal and not self.ctrl_palsy then
|
if skill.type == BattleSkillType.Normal and not self.ctrl_palsy then
|
||||||
-- 释放普技
|
|
||||||
self.skill:Cast(_CheckNext, skill.targets, skill.isAdd)
|
local function _CheckRage()
|
||||||
-- 后成长怒气
|
-- 后成长怒气
|
||||||
if skill.isRage then
|
if skill.isRage then
|
||||||
-- 检测被动技能对怒气成长的影响
|
-- 检测被动技能对怒气成长的影响
|
||||||
local grow = self.RageGrow
|
local grow = self.RageGrow
|
||||||
local _RageGrowPassivity = function(finalGrow)
|
local _RageGrowPassivity = function(finalGrow)
|
||||||
grow = finalGrow
|
grow = finalGrow
|
||||||
|
end
|
||||||
|
self.Event:DispatchEvent(BattleEventName.RoleRageGrow, grow, _RageGrowPassivity)
|
||||||
|
--
|
||||||
|
self.Rage = self.Rage + grow
|
||||||
end
|
end
|
||||||
self.Event:DispatchEvent(BattleEventName.RoleRageGrow, grow, _RageGrowPassivity)
|
-- 释放完成
|
||||||
--
|
_CastDone()
|
||||||
self.Rage = self.Rage + grow
|
|
||||||
end
|
end
|
||||||
|
-- 释放普技
|
||||||
|
skill:Cast(_CheckRage)
|
||||||
|
|
||||||
-- 没有沉默,释放大技能
|
-- 没有沉默,释放大技能
|
||||||
elseif skill.type == BattleSkillType.Special and not self.ctrl_slient then
|
elseif skill.type == BattleSkillType.Special and not self.ctrl_slient then
|
||||||
-- 先消耗怒气
|
-- 先消耗怒气
|
||||||
if skill.isRage then
|
if skill.isRage then
|
||||||
if self.Rage < self.SuperSkillRage then
|
if self.Rage < self.SuperSkillRage then
|
||||||
-- 怒气值不足不能释放技能
|
-- 怒气值不足不能释放技能
|
||||||
_CheckNext()
|
_CastDone()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- 检测被动技能对怒气消耗的影响
|
-- 检测被动技能对怒气消耗的影响
|
||||||
|
@ -323,51 +309,51 @@ function RoleLogic:CheckCastSkill()
|
||||||
self.Rage = self.Rage - costRage
|
self.Rage = self.Rage - costRage
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 释放绝技
|
-- 释放绝技
|
||||||
self.superSkill:Cast(_CheckNext, skill.targets, skill.isAdd)
|
skill:Cast(_CastDone)
|
||||||
|
|
||||||
-- 没有符合条件的技能直接进入下一个技能检测
|
-- 没有符合条件的技能直接进入下一个技能检测
|
||||||
else
|
else
|
||||||
_CheckNext()
|
_CastDone()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- 加入一个技能
|
-- 加入一个技能
|
||||||
-- type 加入的技能类型
|
-- type 加入的技能类型
|
||||||
-- targets 指定目标
|
-- targets 指定目标
|
||||||
-- isAdd 是否是追加技能
|
-- isAdd 是否是追加技能
|
||||||
-- isRage 是否正常操作怒气值
|
-- isRage 是否正常操作怒气值
|
||||||
function RoleLogic:AddSkill(type, isRage, isAdd, targets)
|
function RoleLogic:AddSkill(type, isRage, isAdd, targets)
|
||||||
local skill = {
|
if not self.SkillNum then
|
||||||
type = type,
|
self.SkillNum = 0
|
||||||
isRage = isRage,
|
end
|
||||||
isAdd = isAdd,
|
self.SkillNum = self.SkillNum + 1
|
||||||
targets = targets,
|
|
||||||
}
|
local effectData = type == BattleSkillType.Normal and self.skill or self.superSkill
|
||||||
table.insert(self.SkillList, skill)
|
SkillManager.AddSkill(self, effectData, type, targets, isAdd, isRage)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- 正常触发技能
|
-- 正常触发技能
|
||||||
function RoleLogic:CastSkill(func)
|
function RoleLogic:CastSkill(func)
|
||||||
self.SkillList = {}
|
-- 设置轮转方法
|
||||||
self.CurSkillCastIndex = 0
|
SkillManager.SetTurnRoundFunc(func)
|
||||||
self.SkillCastDoneFunc = func
|
|
||||||
-- 没有沉默
|
-- 没有沉默
|
||||||
if not self.ctrl_slient and self.Rage >= self.SuperSkillRage then
|
if not self.ctrl_slient and self.Rage >= self.SuperSkillRage then
|
||||||
-- 释放大技能
|
-- 释放大技能
|
||||||
self:AddSkill(BattleSkillType.Special, true, false, nil)
|
self:AddSkill(BattleSkillType.Special, true, false, nil)
|
||||||
self:CheckCastSkill()
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- 没有麻痹 释放普通技能
|
-- 没有麻痹 释放普通技能
|
||||||
if not self.ctrl_palsy then
|
if not self.ctrl_palsy then
|
||||||
self:AddSkill(BattleSkillType.Normal, true, false, nil)
|
self:AddSkill(BattleSkillType.Normal, true, false, nil)
|
||||||
self:CheckCastSkill()
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self:CheckCastSkill()
|
--
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 强制释放技能,测试技能时使用
|
-- 强制释放技能,测试技能时使用
|
||||||
|
@ -375,39 +361,41 @@ end
|
||||||
-- targets 追加技能的目标 nil则自动选择目标
|
-- targets 追加技能的目标 nil则自动选择目标
|
||||||
-- func 追加技能释放完成回调
|
-- func 追加技能释放完成回调
|
||||||
function RoleLogic:ForceCastSkill(type, targets, func)
|
function RoleLogic:ForceCastSkill(type, targets, func)
|
||||||
self.SkillList = {}
|
|
||||||
self.CurSkillCastIndex = 0
|
|
||||||
self.SkillCastDoneFunc = func
|
|
||||||
|
|
||||||
-- 清除技能控制
|
-- 清除技能控制
|
||||||
self.ctrl_dizzy = false --眩晕 不能释放技能
|
self.ctrl_dizzy = false --眩晕 不能释放技能
|
||||||
self.ctrl_slient = false --沉默 只能1技能
|
self.ctrl_slient = false --沉默 只能1技能
|
||||||
self.ctrl_palsy = false --麻痹 只能2技能
|
self.ctrl_palsy = false --麻痹 只能2技能
|
||||||
|
|
||||||
|
-- 设置轮转方法
|
||||||
|
SkillManager.SetTurnRoundFunc(func)
|
||||||
-- 释放技能
|
-- 释放技能
|
||||||
if type == 1 and self.skill then
|
if type == 1 and self.skill then
|
||||||
self:AddSkill(BattleSkillType.Normal, true, false, nil)
|
self:AddSkill(BattleSkillType.Normal, true, false, nil)
|
||||||
self:CheckCastSkill()
|
|
||||||
elseif type == 2 and self.superSkill then
|
elseif type == 2 and self.superSkill then
|
||||||
if self.Rage < self.SuperSkillRage then
|
if self.Rage < self.SuperSkillRage then
|
||||||
self.Rage = self.SuperSkillRage
|
self.Rage = self.SuperSkillRage
|
||||||
end
|
end
|
||||||
self:AddSkill(BattleSkillType.Special, true, false, nil)
|
self:AddSkill(BattleSkillType.Special, true, false, nil)
|
||||||
self:CheckCastSkill()
|
|
||||||
else
|
|
||||||
if func then func() end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- 技能释放完毕
|
-- 设置我被杀死时的信息
|
||||||
function RoleLogic:SkillCastDone()
|
function RoleLogic:SetkillMeInfo(caster, skill)
|
||||||
BattleLogic.WaitForTrigger(1, function()
|
self.killCaster = caster
|
||||||
if self.SkillCastDoneFunc then
|
self.killSkill = skill
|
||||||
self.SkillCastDoneFunc()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function RoleLogic:Update()
|
function RoleLogic:Update()
|
||||||
|
|
||||||
|
|
||||||
|
if self:GetRoleData(RoleDataName.Hp) <= 0 then
|
||||||
|
self.isDead = true
|
||||||
|
BattleLogic.BuffMgr:ClearBuff(self)
|
||||||
|
self.Event:DispatchEvent(BattleEventName.RoleDead, self.killCaster)
|
||||||
|
self.killCaster.Event:DispatchEvent(BattleEventName.RoleKill, self)
|
||||||
|
BattleLogic.Event:DispatchEvent(BattleEventName.BattleRoleDead, self, self.killCaster)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
SkillManager = {}
|
||||||
|
local this = SkillManager
|
||||||
|
|
||||||
|
local skillPool = BattleObjectPool.New(function ()
|
||||||
|
return Skill:New()
|
||||||
|
end)
|
||||||
|
|
||||||
|
--
|
||||||
|
this.SkillList = {}
|
||||||
|
this.IsSkilling = false
|
||||||
|
-- 初始化
|
||||||
|
function this.Init()
|
||||||
|
this.Clear()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 向技能列表中追加技能
|
||||||
|
function this.AddSkill(caster, effectData, type, targets, isAdd, isRage)
|
||||||
|
local skill = skillPool:Get()
|
||||||
|
skill:Init(caster, effectData, type, targets, isAdd, isRage)
|
||||||
|
table.insert(this.SkillList, skill)
|
||||||
|
return skill
|
||||||
|
end
|
||||||
|
-- 插入技能到技能列表首位
|
||||||
|
function this.InsertSkill(caster, effectData, type, targets, isAdd, isRage)
|
||||||
|
local skill = skillPool:Get()
|
||||||
|
skill:Init(caster, effectData, type, targets, isAdd, isRage)
|
||||||
|
table.insert(this.SkillList, skill, 1)
|
||||||
|
return skill
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 设置用于轮转的方法
|
||||||
|
function this.SetTurnRoundFunc(func)
|
||||||
|
this.TurnRoundFunc = func
|
||||||
|
end
|
||||||
|
function this.CheckTurnRound()
|
||||||
|
if this.IsSkilling then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if this.SkillList and #this.SkillList > 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- 没有技能释放的时候才轮转
|
||||||
|
if this.TurnRoundFunc then
|
||||||
|
BattleLogic.WaitForTrigger(1, function()
|
||||||
|
this.TurnRoundFunc()
|
||||||
|
this.TurnRoundFunc = nil
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
function this.Update()
|
||||||
|
--
|
||||||
|
if this.IsSkilling then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not this.SkillList or #this.SkillList == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local skill = this.SkillList[1]
|
||||||
|
table.remove(this.SkillList, 1)
|
||||||
|
this.IsSkilling = true
|
||||||
|
-- 检测技能释放
|
||||||
|
skill.owner:SkillCast(skill, function()
|
||||||
|
skill:Dispose()
|
||||||
|
skillPool:Put(skill)
|
||||||
|
this.IsSkilling = false
|
||||||
|
-- 检测一下轮转
|
||||||
|
this.CheckTurnRound()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 清除
|
||||||
|
function this.Clear()
|
||||||
|
for _, skill in ipairs(this.SkillList) do
|
||||||
|
skill:Dispose()
|
||||||
|
skillPool:Put(skill)
|
||||||
|
|
||||||
|
end
|
||||||
|
this.SkillList = {}
|
||||||
|
this.IsSkilling = false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return SkillManager
|
Loading…
Reference in New Issue