1948 lines
57 KiB
Lua
1948 lines
57 KiB
Lua
local BattleConst = require "app/module/battle/battle_const"
|
||
local BattleHelper = require "app/module/battle/helper/battle_helper"
|
||
local BattleBuffHandle = require "app/module/battle/helper/battle_buff_handle"
|
||
local BATTLE_BOARD_SKILL_HANDLE = require "app/module/battle/skill/battle_board_skill_handle"
|
||
local BATTLE_SKILL_CONDITION_HANDLE = require "app/module/battle/helper/battle_skill_condition_handle"
|
||
local BattlePassive = require "app/module/battle/helper/battle_passive"
|
||
|
||
local BattleUnitComp = class("BattleUnitComp", LuaComponent)
|
||
|
||
local UNIT_STATE = BattleConst.UNIT_STATE
|
||
local SIDE_ATK = BattleConst.SIDE_ATK
|
||
local SPINE_ANIMATION_NAME = BattleConst.SPINE_ANIMATION_NAME
|
||
local DEFAULT_FACTOR = BattleConst.DEFAULT_FACTOR
|
||
local PASSIVE_EVENT = BattleConst.PASSIVE_EVENT
|
||
local HURT_STATE_CRIT = BattleConst.HURT_STATE_CRIT
|
||
local EFFECT_TYPE = BattleConst.EFFECT_TYPE
|
||
local TIME_FACTOR = BattleConst.TIME_FACTOR
|
||
local HURT_ANI_NAME_LIST = {SPINE_ANIMATION_NAME.HIT, SPINE_ANIMATION_NAME.HIT_2}
|
||
|
||
function BattleUnitComp:ctor()
|
||
end
|
||
|
||
function BattleUnitComp:initPosition()
|
||
if self.unitEntity:getSide() == SIDE_ATK then
|
||
self.baseObject:setLocalPosition(-BattleConst.INIT_POS_X, 0, 0)
|
||
self.body:setLocalScaleX(1)
|
||
self.direction = 1
|
||
else
|
||
self.baseObject:setLocalPosition(BattleConst.INIT_POS_X, 0, 0)
|
||
self.body:setLocalScaleX(-1)
|
||
self.direction = -1
|
||
end
|
||
self.isOutside = false
|
||
end
|
||
|
||
function BattleUnitComp:playBorn()
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
end
|
||
|
||
function BattleUnitComp:playSwitchIn()
|
||
self.baseObject:getTransform():SetAsLastSibling()
|
||
self:changeState(UNIT_STATE.SWITCH_IN)
|
||
end
|
||
|
||
function BattleUnitComp:playSwitchOut()
|
||
self:changeState(UNIT_STATE.SWITCH_OUT)
|
||
end
|
||
|
||
function BattleUnitComp:getModelId()
|
||
return self.modelId
|
||
end
|
||
|
||
function BattleUnitComp:getMatchType()
|
||
return self.unitEntity:getMatchType()
|
||
end
|
||
|
||
function BattleUnitComp:getIsBoss()
|
||
return self.unitEntity:getIsBoss()
|
||
end
|
||
|
||
function BattleUnitComp:getIsLimit()
|
||
return self.unitEntity:getIsLimit()
|
||
end
|
||
|
||
function BattleUnitComp:getIsLethargy()
|
||
return self.unitEntity:getIsLethargy()
|
||
end
|
||
|
||
function BattleUnitComp:getActiveSkillLimit()
|
||
return self.unitEntity:getActiveSkillLimit()
|
||
end
|
||
|
||
function BattleUnitComp:setTeam(team)
|
||
self.team = team
|
||
end
|
||
|
||
function BattleUnitComp:_initBase()
|
||
self.isClear = false
|
||
self.isMove = false
|
||
self.deadTime = 0
|
||
self.attackTime = 0
|
||
self.skillSlowDownTime = nil -- 开始攻击后,x秒后开始子弹时间
|
||
self.skillSlowDownDuration = 0 -- 子弹时间持续的时间
|
||
self.skillSlowDownScale = 1 -- 子弹时间减慢的倍率
|
||
self.currAttackDuration = 0
|
||
self.currAttackKeyTime = 0
|
||
self.currAttackBlockIndex = 0 -- 多段伤害索引
|
||
self.validEffectIdx = {}
|
||
self.switchTime = 0
|
||
self.isPlayingSubAni = false
|
||
self.playSubAniDuration = {}
|
||
self.attackDurationMap = {}
|
||
self.attackKeyFrameTimeMap = {}
|
||
self.shieldBuffList = {}
|
||
self.loopFxMap = {}
|
||
self.activeSkillIndex = nil
|
||
self.currActiveSkill = nil
|
||
self.targetX = nil
|
||
self.assistingDmgAddition = 0
|
||
self.attackCount = 0
|
||
self.currState = UNIT_STATE.INIT
|
||
self.isOutside = false
|
||
end
|
||
|
||
function BattleUnitComp:initWithEntity(modelId, entity, battleController, target)
|
||
self.modelId = modelId
|
||
self.unitEntity = entity
|
||
self.battleController = battleController
|
||
self.target = target
|
||
self.body = self.baseObject:getChildByName("body")
|
||
self.side = entity:getSide()
|
||
self:_initBase()
|
||
self:initPosition()
|
||
self:initPassiveSkills()
|
||
self:playBorn()
|
||
self:initHitAniInfo()
|
||
end
|
||
|
||
function BattleUnitComp:initHitAniInfo()
|
||
self.hurtAniNameList = {}
|
||
self.hurtAniNameCount = 0
|
||
for _, name in ipairs(HURT_ANI_NAME_LIST) do
|
||
local duration = self:getAnimationDuration(name)
|
||
if duration > 0 then
|
||
table.insert(self.hurtAniNameList, name)
|
||
self.hurtAniNameCount = self.hurtAniNameCount + 1
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:prepare()
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_UNIT_PREPARE_OVER, self)
|
||
self:checkPassiveEvent(PASSIVE_EVENT.HP_LOWER_THAN, nil, self.unitEntity:getHpPercent())
|
||
end
|
||
|
||
function BattleUnitComp:resetBeforeAttack()
|
||
self.attackCount = 0
|
||
self.baseObject:getTransform():SetAsLastSibling()
|
||
end
|
||
|
||
function BattleUnitComp:initPassiveSkills()
|
||
local pasSkills = self.unitEntity:getPassiveSkills()
|
||
if pasSkills and #pasSkills > 0 then
|
||
if self.passiveSkills == nil then
|
||
self.passiveSkills = {}
|
||
else
|
||
self:removeAllPassiveSkills()
|
||
end
|
||
for k, skill in ipairs(pasSkills) do
|
||
local id = skill:getPassiveTriggerId()
|
||
if id then
|
||
skill:clearRecordData()
|
||
local skills = self.passiveSkills[id]
|
||
if skills == nil then
|
||
skills = {}
|
||
self.passiveSkills[id] = skills
|
||
end
|
||
table.insert(skills, skill)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:addPassiveSkill(pasSkill)
|
||
pasSkill:clearRecordData()
|
||
if self.passiveSkills == nil then
|
||
self.passiveSkills = {}
|
||
end
|
||
local id = pasSkill:getPassiveTriggerId()
|
||
if id then
|
||
local skills = self.passiveSkills[id]
|
||
if skills == nil then
|
||
skills = {}
|
||
self.passiveSkills[id] = skills
|
||
end
|
||
table.insert(skills, pasSkill)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:removePassiveSkill(skill)
|
||
if self.passiveSkills == nil then
|
||
return
|
||
end
|
||
local id = skill:getPassiveTriggerId()
|
||
if id then
|
||
local skills = self.passiveSkills[id]
|
||
if skills then
|
||
for k, v in ipairs(skills) do
|
||
if v == skill then
|
||
table.remove(skills, k)
|
||
break
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:removeAllPassiveSkills()
|
||
if self.passiveSkills then
|
||
for _, skills in pairs(self.passiveSkills) do
|
||
local count = #skills
|
||
for i = 1, count do
|
||
table.remove(skills)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:addSkill(skillId)
|
||
local skillEntity = self.unitEntity:addSkill(skillId)
|
||
if skillEntity then
|
||
if skillEntity:getIsPassiveType() then -- 添加被动
|
||
self:addPassiveSkill(skillEntity)
|
||
end
|
||
return skillEntity:getSid()
|
||
end
|
||
return 0
|
||
end
|
||
|
||
function BattleUnitComp:removeSkill(skillId, sid)
|
||
local skillEntity = self.unitEntity:removeSkill(skillId, sid)
|
||
if skillEntity and skillEntity:getIsPassiveType() then
|
||
self:removePassiveSkill(skillEntity)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:hideOutsideScreen()
|
||
if self.unitEntity:getSide() == SIDE_ATK then
|
||
self.baseObject:setLocalPosition(-GConst.UI_SCREEN_WIDTH/2 - BattleConst.UNIT_BODY_WIDTH, 0, 0)
|
||
else
|
||
self.baseObject:setLocalPosition(GConst.UI_SCREEN_WIDTH/2 + BattleConst.UNIT_BODY_WIDTH, 0, 0)
|
||
end
|
||
self.isOutside = true
|
||
end
|
||
|
||
function BattleUnitComp:playRunAction()
|
||
self:playAnimation(SPINE_ANIMATION_NAME.MOVE, true)
|
||
end
|
||
|
||
function BattleUnitComp:stopRunAction()
|
||
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true)
|
||
end
|
||
|
||
function BattleUnitComp:playAnimation(name, loop, forceRefresh)
|
||
if name == self.curHurtName or name == SPINE_ANIMATION_NAME.BLOCK then
|
||
self.isPlayingSubAni = true
|
||
end
|
||
self.currAnimationName = name
|
||
self.baseObject:playAnimation(name, loop, forceRefresh)
|
||
end
|
||
|
||
function BattleUnitComp:getAnimationDuration(aniName)
|
||
local duration = self.attackDurationMap[aniName]
|
||
if duration == nil then
|
||
duration = self.baseObject:getAnimationDuration(aniName)
|
||
self.attackDurationMap[aniName] = duration
|
||
end
|
||
return duration or 0
|
||
end
|
||
|
||
function BattleUnitComp:getAnimationKeyFrameTime(animationName, index)
|
||
index = index or 1
|
||
local timeList = self.attackKeyFrameTimeMap[animationName]
|
||
if timeList == nil then
|
||
timeList = self.baseObject:getAnimationKeyFrameTimes(animationName)
|
||
if not timeList[1] then
|
||
table.insert(timeList, 0.3)
|
||
end
|
||
self.attackKeyFrameTimeMap[animationName] = timeList
|
||
end
|
||
return timeList[index] or 0.3
|
||
end
|
||
|
||
function BattleUnitComp:getKeyFrameTime(skill, blockIndex, animationName)
|
||
if not skill then
|
||
return 0
|
||
end
|
||
|
||
self.currAttackBlockIndex = blockIndex
|
||
local time = 0
|
||
local blockList = skill:getEffectBlock()
|
||
if blockList[blockIndex] then
|
||
local beforeIndex = blockIndex - 1
|
||
self.validEffectIdx[1] = blockList[beforeIndex] or 0
|
||
self.validEffectIdx[2] = blockList[blockIndex] or 1
|
||
time = skill:getEffectBlockTime()[blockIndex]
|
||
if not time then
|
||
time = self:getAnimationKeyFrameTime(animationName, blockIndex)
|
||
end
|
||
end
|
||
|
||
return time
|
||
end
|
||
|
||
function BattleUnitComp:getIsCentralizedAttack()
|
||
return self.team:getCentralizedAttack()
|
||
end
|
||
|
||
function BattleUnitComp:getIsFinalBlock()
|
||
return self.team:getIsFinalBlock()
|
||
end
|
||
|
||
function BattleUnitComp:getCurAttackActionState()
|
||
return self.curAttackActionState
|
||
end
|
||
|
||
function BattleUnitComp:beforeAttack(actionState)
|
||
self.team:setCentralizedAttack(true)
|
||
self.team:setIsFinalBlock(false)
|
||
self.battleController:setIsPauseHpProgress(true)
|
||
self.curAttackActionState = actionState
|
||
if actionState == BattleConst.ATTACK_ACTION_STATE.NORMAL then
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_UNI_ATTACK_START, self)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:useAssistingSkill(count, delay, callback)
|
||
local skill = self.unitEntity:getAssistingSkill()
|
||
if skill == nil then
|
||
callback()
|
||
return
|
||
end
|
||
local attrName = GConst.MATCH_ATTACK_NAME[self:getMatchType()]
|
||
self.assistingDmgAddition = count - 1
|
||
if self.assistingDmgAddition <= 0 then
|
||
self.assistingDmgAddition = 0
|
||
self.assistingDmgAddCount = 0
|
||
else
|
||
self.assistingDmgAddCount = self.unitEntity:addAttr(attrName, self.assistingDmgAddition*DEFAULT_FACTOR, true)
|
||
end
|
||
self.actionOverCallback = callback
|
||
if delay > 0 then
|
||
self.waitTime = delay
|
||
self.waitingState = UNIT_STATE.ASSISTING_ATTACK
|
||
if not self:changeState(UNIT_STATE.WAIT) then
|
||
if not self:changeState(UNIT_STATE.ASSISTING_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.unitEntity:addAttr(attrName, -self.assistingDmgAddCount, false)
|
||
callback()
|
||
end
|
||
end
|
||
else
|
||
if not self:changeState(UNIT_STATE.ASSISTING_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.unitEntity:addAttr(attrName, -self.assistingDmgAddCount, false)
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:useSkill(index, count, callback)
|
||
self.actionOverCallback = callback
|
||
self.activeSkillIndex = nil
|
||
self.currActiveSkill = self.unitEntity:getAvailableActiveSkill(index)
|
||
if self:getActiveSkillLimit() then
|
||
self.currActiveSkill = nil
|
||
end
|
||
if count <= 0 then
|
||
self.normalSkillCount = 0
|
||
else
|
||
self.normalSkillCount = count + self.unitEntity:getNormalAttackAddCount()
|
||
end
|
||
if self.currActiveSkill == nil then -- 没有技能就用普攻
|
||
if self.normalSkillCount <= 0 then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
return false
|
||
end
|
||
if self.isOutside then
|
||
self:playSwitchIn()
|
||
else
|
||
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
return false
|
||
end
|
||
end
|
||
else
|
||
if self.isOutside then
|
||
self:playSwitchIn()
|
||
else
|
||
if count <= 0 then
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_ACTIVE_SKILL_BEFORE, self)
|
||
end
|
||
if not self:changeState(UNIT_STATE.SKILL_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
return false
|
||
end
|
||
end
|
||
end
|
||
return true
|
||
end
|
||
|
||
function BattleUnitComp:useAllSkills(callback)
|
||
self.actionOverCallback = callback
|
||
self.normalSkillCount = self.unitEntity:getNormalSkillCount() + self.unitEntity:getNormalAttackAddCount()
|
||
self.activeSkillIndex = 1
|
||
self.currActiveSkill = nil
|
||
local activeSkillCount = self.unitEntity:getActiveSkillCount()
|
||
if self:getActiveSkillLimit() then
|
||
activeSkillCount = 0
|
||
end
|
||
while self.activeSkillIndex <= activeSkillCount do
|
||
self.currActiveSkill = self.unitEntity:getAvailableActiveSkill(self.activeSkillIndex)
|
||
if self.currActiveSkill then
|
||
break
|
||
end
|
||
self.activeSkillIndex = self.activeSkillIndex + 1
|
||
end
|
||
if self.currActiveSkill == nil then -- 没有技能就用普攻
|
||
if self.normalSkillCount <= 0 then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
return
|
||
end
|
||
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
else
|
||
if not self:changeState(UNIT_STATE.SKILL_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:useNormalSkill(count, effectType, callback)
|
||
self.actionOverCallback = callback
|
||
self.normalSkillCount = count
|
||
if effectType == BattleConst.EFFECT_TYPE.DIRECT then
|
||
self.normalSkillCount = self.normalSkillCount + self.unitEntity:getNormalAttackAddCount()
|
||
end
|
||
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:addShield(num, buffEffect)
|
||
self.unitEntity:addShield(num)
|
||
self.team:addShield(buffEffect)
|
||
end
|
||
|
||
function BattleUnitComp:removeShield(buffEffect)
|
||
if buffEffect == nil then
|
||
return
|
||
end
|
||
if buffEffect.result > 0 then
|
||
self.unitEntity:addShield(-buffEffect.result)
|
||
buffEffect.result = 0
|
||
end
|
||
self.team:removeShield(buffEffect)
|
||
end
|
||
|
||
function BattleUnitComp:changeState(state)
|
||
-- 进入目标状态
|
||
if state == UNIT_STATE.IDLE then -- idle为默认状态,其状态下判定特殊状态
|
||
if self.unitEntity:getIsFrozen() then -- 有冰冻buff
|
||
state = UNIT_STATE.FROZEN
|
||
elseif self.unitEntity:getIsLethargy() or self.unitEntity:getIsStun() then
|
||
state = UNIT_STATE.VERITGO
|
||
end
|
||
end
|
||
|
||
if self.currState == state and not self:repeatCurrState() then
|
||
return false
|
||
end
|
||
if self.currState == UNIT_STATE.DEAD then -- 死亡后只能去死亡状态
|
||
if state ~= UNIT_STATE.DEAD then
|
||
return false
|
||
end
|
||
end
|
||
-- 离开当前状态
|
||
if self.currState == UNIT_STATE.IDLE then
|
||
self:exitIdleState()
|
||
elseif self.currState == UNIT_STATE.NORMAL_ATTACK then
|
||
self:exitNormalAttackState()
|
||
elseif self.currState == UNIT_STATE.SKILL_ATTACK then
|
||
self:exitSkillAttackState()
|
||
elseif self.currState == UNIT_STATE.ASSISTING_ATTACK then
|
||
self:exitAssistingAttackState()
|
||
elseif self.currState == UNIT_STATE.DEAD then
|
||
self:exitDeadState()
|
||
elseif self.currState == UNIT_STATE.ENTER_BATTLEFIELD then
|
||
self:exitEnterBattlefieldState()
|
||
elseif self.currState == UNIT_STATE.SWITCH_IN then
|
||
self:exitSwitchInState()
|
||
elseif self.currState == UNIT_STATE.SWITCH_OUT then
|
||
self:exitSwitchOutState()
|
||
elseif self.currState == UNIT_STATE.WAIT then
|
||
self:exitWaitState()
|
||
elseif self.currState == UNIT_STATE.RECOVER_HP_WAVE then
|
||
self:exitRecoverHpWaveState()
|
||
elseif self.currState == UNIT_STATE.FROZEN then
|
||
self:exitFrozenState()
|
||
elseif self.currState == UNIT_STATE.VERITGO then
|
||
self:exitVeritgoState()
|
||
end
|
||
|
||
self.currState = state
|
||
|
||
if state == UNIT_STATE.IDLE then
|
||
self:enterIdleState()
|
||
elseif state == UNIT_STATE.NORMAL_ATTACK then
|
||
self:enterNormalAttackState()
|
||
elseif state == UNIT_STATE.SKILL_ATTACK then
|
||
self:enterSkillAttackState()
|
||
elseif state == UNIT_STATE.ASSISTING_ATTACK then
|
||
self:enterAssistingAttackState()
|
||
elseif state == UNIT_STATE.DEAD then
|
||
self:enterDeadState()
|
||
elseif state == UNIT_STATE.ENTER_BATTLEFIELD then
|
||
self:enterEnterBattlefieldState()
|
||
elseif state == UNIT_STATE.SWITCH_IN then
|
||
self:enterSwitchInState()
|
||
elseif state == UNIT_STATE.SWITCH_OUT then
|
||
self:enterSwitchOutState()
|
||
elseif state == UNIT_STATE.WAIT then
|
||
self:enterWaitState()
|
||
elseif state == UNIT_STATE.RECOVER_HP_WAVE then
|
||
self:enterRecoverHpWaveState()
|
||
elseif state == UNIT_STATE.FROZEN then
|
||
self:enterFrozenState()
|
||
elseif state == UNIT_STATE.VERITGO then
|
||
self:enterVeritgoState()
|
||
end
|
||
return true
|
||
end
|
||
|
||
function BattleUnitComp:repeatCurrState()
|
||
if self.currState == UNIT_STATE.NORMAL_ATTACK then
|
||
return true
|
||
elseif self.currState == UNIT_STATE.SKILL_ATTACK then
|
||
return true
|
||
end
|
||
return false
|
||
end
|
||
|
||
function BattleUnitComp:updateSwitchInState(dt)
|
||
self.switchTime = self.switchTime - dt
|
||
if self.switchTime < 0 then
|
||
if self.actionOverCallback then
|
||
if self.currActiveSkill then
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_ACTIVE_SKILL_BEFORE, self)
|
||
if not self:changeState(UNIT_STATE.SKILL_ATTACK) then
|
||
local callback = self.actionOverCallback
|
||
self.actionOverCallback = nil
|
||
self.activeSkillIndex = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
elseif self.normalSkillCount > 0 then
|
||
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
||
local callback = self.actionOverCallback
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
else
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
local callback = self.actionOverCallback
|
||
self.actionOverCallback = nil
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
self.team:setCentralizedAttack(false)
|
||
callback()
|
||
end
|
||
else
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterSwitchInState()
|
||
local aniName = SPINE_ANIMATION_NAME.BORN
|
||
self.switchTime = self:getAnimationDuration(aniName) + 0.1
|
||
self:initPosition()
|
||
self:playAnimation(aniName, false, true)
|
||
end
|
||
|
||
function BattleUnitComp:exitSwitchInState()
|
||
end
|
||
|
||
function BattleUnitComp:updateSwitchOutState(dt)
|
||
self.switchTime = self.switchTime - dt
|
||
if self.switchTime < 0 then
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterSwitchOutState()
|
||
local aniName = SPINE_ANIMATION_NAME.OUT
|
||
self.switchTime = self:getAnimationDuration(aniName) + 0.1
|
||
self:playAnimation(aniName, false, true)
|
||
end
|
||
|
||
function BattleUnitComp:exitSwitchOutState()
|
||
self:hideOutsideScreen()
|
||
end
|
||
|
||
function BattleUnitComp:updateDead(dt)
|
||
self.deadTime = self.deadTime - dt
|
||
if self.deadTime <= 0 then
|
||
self:clear()
|
||
if self.deadOverCallback then
|
||
local callback = self.deadOverCallback
|
||
self.deadOverCallback = nil
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:exitDeadState()
|
||
end
|
||
|
||
function BattleUnitComp:enterDeadState()
|
||
self:removeAllBuff()
|
||
local aniName = SPINE_ANIMATION_NAME.DEAD
|
||
self.deadTime = self:getAnimationDuration(aniName) + 0.1
|
||
self:playAnimation(aniName, false, false)
|
||
end
|
||
|
||
function BattleUnitComp:updateEnterBattlefieldState(dt)
|
||
if self.isMove then
|
||
local addX = dt*BattleConst.MOVE_SPEED_ENTER*self.moveDirection
|
||
self.positionX = self.positionX + addX
|
||
if (self.moveDirection > 0 and self.positionX >= self.targetX) or (self.moveDirection < 0 and self.positionX <= self.targetX) then
|
||
self.isMove = false
|
||
self.positionX = self.targetX
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
end
|
||
self.baseObject:setLocalPosition(self.positionX, 0, 0)
|
||
else
|
||
self.waitTime = self.waitTime - dt
|
||
if self.waitTime < 0 then
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:exitEnterBattlefieldState()
|
||
local callback = self.finishEnterBattlefieldCallback
|
||
self.finishEnterBattlefieldCallback = nil
|
||
if callback then
|
||
callback()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterEnterBattlefieldState()
|
||
if self.isMove then
|
||
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true, false)
|
||
self.positionX = self.baseObject:fastGetLocalPosition()
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
self.targetX = -BattleConst.INIT_POS_X
|
||
self.moveDirection = 1
|
||
else
|
||
self.targetX = BattleConst.INIT_POS_X
|
||
self.moveDirection = -1
|
||
end
|
||
local time = math.abs(self.targetX - self.positionX)/BattleConst.MOVE_SPEED_ENTER
|
||
self.battleController:moveBattlefield(time)
|
||
else
|
||
self:playAnimation(SPINE_ANIMATION_NAME.BORN, false, false)
|
||
self.waitTime = self:getAnimationDuration(SPINE_ANIMATION_NAME.BORN)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:exitIdleState()
|
||
end
|
||
|
||
function BattleUnitComp:enterIdleState()
|
||
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true, false)
|
||
end
|
||
|
||
function BattleUnitComp:updateIdle(dt)
|
||
self:updateIdleSubAni(dt, SPINE_ANIMATION_NAME.IDLE)
|
||
end
|
||
|
||
function BattleUnitComp:updateIdleSubAni(...)
|
||
if not self.currAnimationName or not self.isPlayingSubAni then
|
||
return
|
||
end
|
||
if self.currAnimationName == self.curHurtName then
|
||
self:updateHurt(...)
|
||
elseif self.currAnimationName == SPINE_ANIMATION_NAME.BLOCK then
|
||
self:updateBlock(...)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:playHurt()
|
||
if self.currState == UNIT_STATE.IDLE or
|
||
self.currState == UNIT_STATE.VERITGO then
|
||
if self.hurtAniNameCount <= 0 then
|
||
return
|
||
end
|
||
local name = self.hurtAniNameList[math.random(1, self.hurtAniNameCount)]
|
||
self.playSubAniTime = 0
|
||
self.curHurtName = name
|
||
if self.playSubAniDuration[name] == nil then
|
||
self.playSubAniDuration[name] = self:getAnimationDuration(name)
|
||
end
|
||
self:playAnimation(name, false, false)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:updateHurt(dt, overAniName)
|
||
self.playSubAniTime = self.playSubAniTime + dt
|
||
if self.playSubAniTime >= self.playSubAniDuration[self.curHurtName or SPINE_ANIMATION_NAME.HIT] then
|
||
self:playAnimation(overAniName, true, false)
|
||
self.isPlayingSubAni = false
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:playBlock()
|
||
if self.currState == UNIT_STATE.IDLE then
|
||
local name = SPINE_ANIMATION_NAME.BLOCK
|
||
self.playSubAniTime = 0
|
||
if self.playSubAniDuration[name] == nil then
|
||
self.playSubAniDuration[name] = self:getAnimationDuration(name)
|
||
end
|
||
self:playAnimation(name, false, false)
|
||
end
|
||
|
||
local direction = BattleConst.EFFECT_TYPE_MOVE_R
|
||
local x, y = self.baseObject:fastGetLocalPosition()
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
direction = BattleConst.EFFECT_TYPE_MOVE_L
|
||
end
|
||
|
||
self:showEffectNumber(BattleConst.EFFECT_COLOR_SPECIAL, direction, I18N:getGlobalText(I18N.GlobalConst.BLOCK_DESC), x, y, 0)
|
||
end
|
||
|
||
|
||
function BattleUnitComp:updateBlock(dt, overAniName)
|
||
self.playSubAniTime = self.playSubAniTime + dt
|
||
if self.playSubAniTime >= self.playSubAniDuration[SPINE_ANIMATION_NAME.BLOCK] then
|
||
self:playAnimation(overAniName, true, false)
|
||
self.isPlayingSubAni = false
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:exitFrozenState()
|
||
end
|
||
|
||
function BattleUnitComp:enterFrozenState()
|
||
self:playAnimation(SPINE_ANIMATION_NAME.FROZEN, true, false)
|
||
end
|
||
|
||
function BattleUnitComp:updateFrozen(dt)
|
||
self:updateIdleSubAni(dt, SPINE_ANIMATION_NAME.FROZEN)
|
||
end
|
||
|
||
function BattleUnitComp:exitVeritgoState()
|
||
end
|
||
|
||
function BattleUnitComp:enterVeritgoState()
|
||
self:playAnimation(SPINE_ANIMATION_NAME.VERTIGO, true, false)
|
||
end
|
||
|
||
function BattleUnitComp:updateVeritgo(dt)
|
||
self:updateIdleSubAni(dt, SPINE_ANIMATION_NAME.VERTIGO)
|
||
end
|
||
|
||
function BattleUnitComp:enterRecoverHpWaveState()
|
||
self.recoverHpCount = BattleConst.RECOVER_HP_COUNT
|
||
self.recoverHpTime = BattleConst.RECOVER_HP_INTERVAL / 2
|
||
end
|
||
|
||
function BattleUnitComp:exitRecoverHpWaveState()
|
||
end
|
||
|
||
function BattleUnitComp:updateRecoverHpWaveState(dt)
|
||
if self.recoverHpCount <= 0 then
|
||
return
|
||
end
|
||
self.recoverHpTime = self.recoverHpTime - dt
|
||
if self.recoverHpTime < 0 then
|
||
self.recoverHpCount = self.recoverHpCount - 1
|
||
self.recoverHpTime = BattleConst.RECOVER_HP_INTERVAL
|
||
local healNum = BattleConst.RECOVER_HP_PERCENT * self.unitEntity:getMaxHp() // DEFAULT_FACTOR
|
||
if healNum < 0 then -- 治疗效果不能为负数
|
||
healNum = 0
|
||
end
|
||
self:takeDamageOrCure(self, healNum, EFFECT_TYPE.HEAL, 0, BattleConst.SPECIAL_DAMAGE_OR_CURE_TYPE.ROUND_BEGIN_HEAL)
|
||
if self.recoverHpCount <= 0 then
|
||
if self.finishRecoverHpCallback then
|
||
local callback = self.finishRecoverHpCallback
|
||
self.finishRecoverHpCallback = nil
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterWaitState()
|
||
end
|
||
|
||
function BattleUnitComp:exitWaitState()
|
||
end
|
||
|
||
function BattleUnitComp:updateWaitState(dt)
|
||
self.waitTime = self.waitTime - dt
|
||
if self.waitTime < 0 then
|
||
self:changeState(self.waitingState)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterAssistingAttackState()
|
||
self.attackOver = false
|
||
self.attackTime = 0
|
||
self.skillSlowDownTime = nil
|
||
self.isMove = false
|
||
local skill = self.unitEntity:getAssistingSkill()
|
||
skill:startUse()
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(skill)
|
||
self:initPosition()
|
||
end
|
||
|
||
function BattleUnitComp:exitAssistingAttackState()
|
||
self:hideOutsideScreen()
|
||
if self.assistingDmgAddition > 0 then
|
||
local attrName = GConst.MATCH_ATTACK_NAME[self:getMatchType()]
|
||
self.unitEntity:addAttr(attrName, -self.assistingDmgAddCount, false)
|
||
self.assistingDmgAddition = 0
|
||
self.assistingDmgAddCount = 0
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:updateAssistingAttackState(dt)
|
||
self.attackTime = self.attackTime + dt
|
||
if self.attackTime >= self.currAttackDuration then
|
||
self.attackOver = true
|
||
self:onAttackOver()
|
||
else
|
||
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then -- 到达关键后使用
|
||
local skill = self.unitEntity:getAssistingSkill()
|
||
local isFinalBlock = skill and skill:isFinalBlock(self.currAttackBlockIndex)
|
||
self:onSkillTakeEffect(skill, isFinalBlock, self.validEffectIdx)
|
||
|
||
if skill then
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, self.currAttackBlockIndex + 1, attackName)
|
||
else
|
||
self.currAttackKeyTime = 0
|
||
end
|
||
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterSkillAttackState()
|
||
self.attackOver = false
|
||
self.attackTime = 0
|
||
self.targetX = nil
|
||
local skill
|
||
if self.normalSkillCount > 0 then
|
||
skill = self.unitEntity:getNormalSkill(true)
|
||
self.skillSlowDownTime = nil
|
||
else
|
||
skill = self.currActiveSkill
|
||
local slowDownBulletTimeParams = skill:getSlowDownBulletTimeParams()
|
||
if slowDownBulletTimeParams and #slowDownBulletTimeParams == 3 then
|
||
self.skillSlowDownTime = slowDownBulletTimeParams[1] / TIME_FACTOR
|
||
self.skillSlowDownScale = slowDownBulletTimeParams[2] / DEFAULT_FACTOR
|
||
self.skillSlowDownDuration = slowDownBulletTimeParams[3] / TIME_FACTOR
|
||
else
|
||
self.skillSlowDownTime = nil
|
||
end
|
||
end
|
||
skill:startUse()
|
||
if skill:getMoveType() == BattleConst.SKILL_MOVE_TYPE.MOVE then
|
||
self.isMove = true
|
||
self:playAnimation(BattleConst.SPINE_ANIMATION_NAME.MOVE, true, false)
|
||
self.positionX = self.baseObject:fastGetLocalPosition()
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
self.targetX = BattleConst.UNIT_FRONT_POS_X
|
||
self.moveDirection = 1
|
||
else
|
||
self.targetX = -BattleConst.UNIT_FRONT_POS_X
|
||
self.moveDirection = -1
|
||
end
|
||
else
|
||
self.isMove = false
|
||
local attackName = skill:getSkillAttackName()
|
||
if self.normalSkillCount > 0 then
|
||
self:attackAndSpeedUp()
|
||
end
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(skill)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:checkSkillSlowDown(dt)
|
||
if self.skillSlowDownTime == nil then
|
||
return
|
||
end
|
||
self.skillSlowDownTime = self.skillSlowDownTime - dt
|
||
if self.skillSlowDownTime >= 0 then
|
||
return
|
||
end
|
||
self.skillSlowDownTime = nil
|
||
self.battleController:setSkillSlowDown(self.skillSlowDownScale, self.skillSlowDownDuration)
|
||
end
|
||
|
||
function BattleUnitComp:exitSkillAttackState()
|
||
end
|
||
|
||
function BattleUnitComp:updateSkillAttack(dt)
|
||
if self.isMove then
|
||
local addX = dt*BattleConst.MOVE_SPEED*self.moveDirection
|
||
self.positionX = self.positionX + addX
|
||
if (self.moveDirection > 0 and self.positionX >= self.targetX) or (self.moveDirection < 0 and self.positionX <= self.targetX) then
|
||
self.isMove = false
|
||
self.positionX = self.targetX
|
||
if self.attackOver then -- 归位后该下一步了
|
||
self:onAttackOver()
|
||
else -- 到位置该攻击了
|
||
self:doNextAttack()
|
||
end
|
||
end
|
||
self.baseObject:setLocalPosition(self.positionX, 0, 0)
|
||
return
|
||
end
|
||
self:checkSkillSlowDown(dt)
|
||
self.attackTime = self.attackTime + dt
|
||
if self.attackTime >= self.currAttackDuration then
|
||
self.attackOver = true
|
||
if self.normalSkillCount > 0 then
|
||
self.normalSkillCount = self.normalSkillCount - 1
|
||
if self.normalSkillCount <= 0 then
|
||
if self.currActiveSkill == nil then
|
||
if self.targetX then -- 移动过,准备归位
|
||
self:moveBackToInitPosition()
|
||
else
|
||
self:onAttackOver()
|
||
end
|
||
return
|
||
else
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_ACTIVE_SKILL_BEFORE, self)
|
||
self.currActiveSkill:startUse()
|
||
self:doNextSkillAttack()
|
||
end
|
||
else -- 继续普攻
|
||
self:doNextNormalAttack()
|
||
end
|
||
else
|
||
local currActiveSkill = nil
|
||
local skillCanUseTimes = self.currActiveSkill:getSkillCanUseTimes()
|
||
if skillCanUseTimes and skillCanUseTimes > 0 then -- 当前技能可以多次使用
|
||
currActiveSkill = self.currActiveSkill
|
||
elseif self.activeSkillIndex then
|
||
self.activeSkillIndex = self.activeSkillIndex + 1
|
||
local activeSkillCount = self.unitEntity:getActiveSkillCount()
|
||
while self.activeSkillIndex <= activeSkillCount do
|
||
currActiveSkill = self.unitEntity:getAvailableActiveSkill(self.activeSkillIndex)
|
||
if currActiveSkill then
|
||
currActiveSkill:startUse()
|
||
break
|
||
end
|
||
self.activeSkillIndex = self.activeSkillIndex + 1
|
||
end
|
||
end
|
||
if currActiveSkill == nil then
|
||
if self.targetX then -- 移动过,准备归位
|
||
self:moveBackToInitPosition()
|
||
else
|
||
self:onAttackOver()
|
||
end
|
||
|
||
local target = self.battleController:getOtherSideMainUnit(self.side)
|
||
if target and target.unitEntity:getIsDead() then
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ON_DEAD_BY_SKILL, self)
|
||
end
|
||
return
|
||
else
|
||
self.currActiveSkill = currActiveSkill
|
||
self:doNextSkillAttack()
|
||
end
|
||
end
|
||
else
|
||
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then -- 到达关键后使用
|
||
if self.normalSkillCount > 0 then
|
||
local skill = self.unitEntity:getNormalSkill()
|
||
local isFinalBlock = skill and skill:isFinalBlock(self.currAttackBlockIndex)
|
||
|
||
if self.normalSkillCount == 1 and self.currActiveSkill == nil and isFinalBlock then -- 最后一次攻击
|
||
self.team:setCentralizedAttack(false)
|
||
end
|
||
self:onSkillTakeEffect(skill, isFinalBlock, self.validEffectIdx)
|
||
if self.normalSkillCount == 1 and self.currActiveSkill == nil and isFinalBlock then -- 最后一次攻击
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
end
|
||
|
||
if skill then
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, self.currAttackBlockIndex + 1, attackName)
|
||
else
|
||
self.currAttackKeyTime = 0
|
||
end
|
||
else
|
||
local isFinalBlock = self.currActiveSkill:isFinalBlock(self.currAttackBlockIndex)
|
||
|
||
local isHaveNextAttack = self:getIsHaveNextAvailableActiveSkill()
|
||
if not isHaveNextAttack and isFinalBlock then
|
||
self.team:setCentralizedAttack(false)
|
||
self.team:setIsFinalBlock(isFinalBlock)
|
||
end
|
||
self:onSkillTakeEffect(self.currActiveSkill, isFinalBlock, self.validEffectIdx)
|
||
if not isHaveNextAttack and isFinalBlock then
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
end
|
||
|
||
local attackName = self.currActiveSkill:getSkillAttackName()
|
||
self.currAttackKeyTime = self:getKeyFrameTime(self.currActiveSkill, self.currAttackBlockIndex + 1, attackName)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:getIsHaveNextAvailableActiveSkill()
|
||
local skillCanUseTimes = self.currActiveSkill:getSkillCanUseTimes()
|
||
-- 当前技能可以多次使用,onSkillTakeEffect才会次数减1,所以这次大于1的时候才说明可以多次使用
|
||
if skillCanUseTimes and skillCanUseTimes > 1 then
|
||
return true
|
||
elseif self.activeSkillIndex then
|
||
local currActiveSkill = nil
|
||
local activeSkillIndex = self.activeSkillIndex + 1
|
||
local activeSkillCount = self.unitEntity:getActiveSkillCount()
|
||
while activeSkillIndex <= activeSkillCount do
|
||
currActiveSkill = self.unitEntity:getAvailableActiveSkill(activeSkillIndex)
|
||
if currActiveSkill then
|
||
return true
|
||
end
|
||
activeSkillIndex = activeSkillIndex + 1
|
||
end
|
||
end
|
||
return false
|
||
end
|
||
|
||
function BattleUnitComp:moveBackToInitPosition()
|
||
self.isMove = true
|
||
self:playAnimation(BattleConst.SPINE_ANIMATION_NAME.MOVE, true, false)
|
||
self.positionX = self.baseObject:fastGetLocalPosition()
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
self.targetX = -BattleConst.INIT_POS_X
|
||
self.moveDirection = -1
|
||
else
|
||
self.targetX = BattleConst.INIT_POS_X
|
||
self.moveDirection = 1
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:onAttackOver()
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
local callback = self.actionOverCallback
|
||
self.actionOverCallback = nil
|
||
if callback then
|
||
callback()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:attackAndSpeedUp()
|
||
self.attackCount = self.attackCount + 1
|
||
if self.attackCount == 3 then
|
||
self.battleController:addTimeSpeed()
|
||
elseif self.attackCount == 5 then
|
||
self.battleController:addTimeSpeed()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:doNextSkillAttack()
|
||
self.attackTime = 0
|
||
local slowDownBulletTimeParams = self.currActiveSkill:getSlowDownBulletTimeParams()
|
||
if slowDownBulletTimeParams and #slowDownBulletTimeParams == 3 then
|
||
self.skillSlowDownTime = slowDownBulletTimeParams[1] / TIME_FACTOR
|
||
self.skillSlowDownScale = slowDownBulletTimeParams[2] / DEFAULT_FACTOR
|
||
self.skillSlowDownDuration = slowDownBulletTimeParams[3] / TIME_FACTOR
|
||
else
|
||
self.skillSlowDownTime = nil
|
||
end
|
||
local attackName = self.currActiveSkill:getSkillAttackName()
|
||
if not attackName then -- 没有攻击动画
|
||
self.currAttackDuration = 0
|
||
self.currAttackKeyTime = 0
|
||
self.battleController:resetTimeSpeed()
|
||
local isFinalBlock = true
|
||
local isHaveNextAttack = self:getIsHaveNextAvailableActiveSkill()
|
||
if not isHaveNextAttack and isFinalBlock then
|
||
self.team:setCentralizedAttack(false)
|
||
self.team:setIsFinalBlock(isFinalBlock)
|
||
end
|
||
self:onSkillTakeEffect(self.currActiveSkill, isFinalBlock)
|
||
if not isHaveNextAttack and isFinalBlock then
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
end
|
||
return
|
||
end
|
||
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(self.currActiveSkill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(self.currActiveSkill)
|
||
self.battleController:resetTimeSpeed()
|
||
end
|
||
|
||
function BattleUnitComp:doNextNormalAttack()
|
||
self.attackTime = 0
|
||
self.skillSlowDownTime = nil
|
||
local skill = self.unitEntity:getNormalSkill(true)
|
||
skill:startUse()
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(skill)
|
||
self:attackAndSpeedUp()
|
||
end
|
||
|
||
function BattleUnitComp:doNextAttack()
|
||
self.attackTime = 0
|
||
local attackName = nil
|
||
if self.normalSkillCount > 0 then
|
||
self.skillSlowDownTime = nil
|
||
local skill = self.unitEntity:getNormalSkill(true)
|
||
skill:startUse()
|
||
attackName = skill:getSkillAttackName()
|
||
if attackName then
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(skill)
|
||
self:attackAndSpeedUp()
|
||
else
|
||
self:moveBackToInitPosition()
|
||
end
|
||
elseif self.currActiveSkill then
|
||
local slowDownBulletTimeParams = self.currActiveSkill:getSlowDownBulletTimeParams()
|
||
if slowDownBulletTimeParams and #slowDownBulletTimeParams == 3 then
|
||
self.skillSlowDownTime = slowDownBulletTimeParams[1] / TIME_FACTOR
|
||
self.skillSlowDownScale = slowDownBulletTimeParams[2] / DEFAULT_FACTOR
|
||
self.skillSlowDownDuration = slowDownBulletTimeParams[3] / TIME_FACTOR
|
||
else
|
||
self.skillSlowDownTime = nil
|
||
end
|
||
self.currActiveSkill:startUse()
|
||
attackName = self.currActiveSkill:getSkillAttackName()
|
||
if attackName then
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(self.currActiveSkill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(self.currActiveSkill)
|
||
self.battleController:resetTimeSpeed()
|
||
else
|
||
self:moveBackToInitPosition()
|
||
end
|
||
else
|
||
self:moveBackToInitPosition()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:enterNormalAttackState()
|
||
self.attackOver = false
|
||
self.attackTime = 0
|
||
self.skillSlowDownTime = nil
|
||
local skill = self.unitEntity:getNormalSkill(true)
|
||
skill:startUse()
|
||
if skill:getMoveType() == BattleConst.SKILL_MOVE_TYPE.MOVE then
|
||
self.isMove = true
|
||
self:playAnimation(BattleConst.SPINE_ANIMATION_NAME.MOVE, true, false)
|
||
self.positionX = self.baseObject:fastGetLocalPosition()
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
self.targetX = BattleConst.UNIT_FRONT_POS_X
|
||
self.moveDirection = 1
|
||
else
|
||
self.targetX = -BattleConst.UNIT_FRONT_POS_X
|
||
self.moveDirection = -1
|
||
end
|
||
else
|
||
self.isMove = false
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackDuration = self:getAnimationDuration(attackName)
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, 1, attackName)
|
||
self:playAnimation(attackName, false, false)
|
||
self:playSkillFx(skill)
|
||
self:attackAndSpeedUp()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:exitNormalAttackState()
|
||
end
|
||
|
||
function BattleUnitComp:updateNormalAttack(dt)
|
||
if self.isMove then
|
||
local addX = dt*BattleConst.MOVE_SPEED*self.moveDirection
|
||
self.positionX = self.positionX + addX
|
||
if (self.moveDirection > 0 and self.positionX >= self.targetX) or (self.moveDirection < 0 and self.positionX <= self.targetX) then
|
||
self.isMove = false
|
||
self.positionX = self.targetX
|
||
if self.attackOver then -- 归位后该下一步了
|
||
self:onAttackOver()
|
||
else -- 到位置该攻击了
|
||
self:doNextNormalAttack()
|
||
end
|
||
end
|
||
self.baseObject:setLocalPosition(self.positionX, 0, 0)
|
||
return
|
||
end
|
||
self.attackTime = self.attackTime + dt
|
||
if self.attackTime >= self.currAttackDuration then
|
||
self.attackOver = true
|
||
self.normalSkillCount = self.normalSkillCount - 1
|
||
if self.normalSkillCount <= 0 then
|
||
local skill = self.unitEntity:getNormalSkill()
|
||
if skill:getMoveType() == BattleConst.SKILL_MOVE_TYPE.MOVE then
|
||
self:moveBackToInitPosition()
|
||
else
|
||
self:onAttackOver()
|
||
end
|
||
return
|
||
else -- 继续攻击
|
||
self:doNextNormalAttack()
|
||
end
|
||
else
|
||
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then -- 到达关键后使用
|
||
local skill = self.unitEntity:getNormalSkill()
|
||
local isFinalBlock = skill and skill:isFinalBlock(self.currAttackBlockIndex) or false
|
||
if self.normalSkillCount == 1 and isFinalBlock then -- 如果是最后一次攻击,那么敌人受到这次攻击可以开始嗝屁了
|
||
self.team:setCentralizedAttack(false)
|
||
self.team:setIsFinalBlock(isFinalBlock)
|
||
end
|
||
self:onSkillTakeEffect(skill, isFinalBlock, self.validEffectIdx)
|
||
if self.normalSkillCount == 1 and isFinalBlock then -- 如果是最后一次攻击,那么可以开始跑血条了
|
||
self.battleController:setIsPauseHpProgress(false)
|
||
end
|
||
|
||
if skill then
|
||
local attackName = skill:getSkillAttackName()
|
||
self.currAttackKeyTime = self:getKeyFrameTime(skill, self.currAttackBlockIndex + 1, attackName)
|
||
else
|
||
self.currAttackKeyTime = 0
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:addMaxHp(percent)
|
||
self.unitEntity:addMaxHp(percent)
|
||
local hpPercent = self.unitEntity:getHpPercent()
|
||
local hp = self.unitEntity:getHp()
|
||
self.battleController:refreshHp(self.side, hp, hpPercent)
|
||
end
|
||
|
||
function BattleUnitComp:addBuff(buffEffect)
|
||
return self.team:addBuff(buffEffect)
|
||
end
|
||
|
||
function BattleUnitComp:getBuffCountByName(buffName)
|
||
return self.team:getBuffCountByName(buffName)
|
||
end
|
||
|
||
function BattleUnitComp:updateBuffState(buff, num)
|
||
self.team:updateBuffState(buff, num)
|
||
end
|
||
|
||
function BattleUnitComp:removeAllBuff()
|
||
self.team:removeAllBuff()
|
||
end
|
||
|
||
function BattleUnitComp:removeBuffByName(buffName)
|
||
self.team:removeBuffByName(buffName)
|
||
end
|
||
|
||
function BattleUnitComp:putCacheBuff(buffEffect)
|
||
self.team:putCacheBuff(buffEffect)
|
||
end
|
||
|
||
function BattleUnitComp:putCacheBuffByDecr(buffDecr)
|
||
self.team:putCacheBuffByDecr(buffDecr)
|
||
end
|
||
|
||
function BattleUnitComp:popCacheBuffByDecr(buffDecr)
|
||
self.team:popCacheBuffByDecr(buffDecr)
|
||
end
|
||
|
||
function BattleUnitComp:onSkillTakeEffect(skill, isFinalBlock, validEffectIdx)
|
||
if isFinalBlock == nil then
|
||
isFinalBlock = true
|
||
end
|
||
if isFinalBlock then
|
||
skill:endUse()
|
||
if skill:isAttackOverActive() then
|
||
BATTLE_BOARD_SKILL_HANDLE.activeAttackOverSkill(self, skill, self.battleController)
|
||
end
|
||
end
|
||
|
||
local effectList = skill:getEffectList()
|
||
if effectList == nil then
|
||
return
|
||
end
|
||
if #effectList == 0 then
|
||
return
|
||
end
|
||
local targetType = skill:getTargetType()
|
||
local target
|
||
if targetType == 1 then -- 自己
|
||
target = self
|
||
else
|
||
target = self.battleController:getOtherSideMainUnit(self.side)
|
||
if skill:getIsNormalType() then -- 普攻要计算一下格挡
|
||
local block = target.unitEntity:getBlock()
|
||
if block > 0 then
|
||
if BattleHelper:random(1, DEFAULT_FACTOR) <= block then -- 格挡成功
|
||
target:playBlock()
|
||
return
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
local succ = false
|
||
local effectStartIdx = 1
|
||
local effectEndIdx = 1
|
||
if validEffectIdx then
|
||
effectStartIdx = validEffectIdx[1] + 1
|
||
effectEndIdx = validEffectIdx[2]
|
||
else
|
||
effectEndIdx = #effectList
|
||
end
|
||
for i = effectStartIdx, effectEndIdx do
|
||
local effect = effectList[i]
|
||
if effect then
|
||
if self:judgeSkillEffectCondition(skill, i) then
|
||
if self:takeEffect(effect, target) then
|
||
succ = true
|
||
end
|
||
end
|
||
else
|
||
break
|
||
end
|
||
end
|
||
|
||
if succ then
|
||
if skill:getIsHurtType() then
|
||
self.team:addCombo()
|
||
end
|
||
if isFinalBlock then
|
||
if skill:getIsNormalType() then -- 普攻攻击成功的话
|
||
self:checkPassiveEvent(PASSIVE_EVENT.USE_NORMAL_SKILL, target)
|
||
elseif skill:getIsActiveType() then
|
||
self:checkPassiveEvent(PASSIVE_EVENT.ACTIVE_SKILL_HIT, target)
|
||
end
|
||
end
|
||
|
||
local shakeType = skill:getShakeType()
|
||
if shakeType then
|
||
local shakeTime = skill:getShakeTime() or 0
|
||
if shakeTime > 0 then
|
||
self.battleController:shakeScreen(shakeType, shakeTime/TIME_FACTOR)
|
||
end
|
||
end
|
||
local soundHit = skill:getSoundHit()
|
||
if soundHit then
|
||
BattleHelper:playSkillSound(soundHit, 0)
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:judgeSkillEffectCondition(skill, index)
|
||
if not skill or skill:haveBuffCondition() then
|
||
return true
|
||
end
|
||
|
||
local buffConditionIndex, conditionRel = skill:getBuffConditionRel(index)
|
||
if not buffConditionIndex then
|
||
return true
|
||
end
|
||
local buffConditions = skill:getBuffCondition(buffConditionIndex)
|
||
|
||
return BATTLE_SKILL_CONDITION_HANDLE.judgeSkillEffectCondition(buffConditions, conditionRel, self.battleController)
|
||
end
|
||
|
||
function BattleUnitComp:takeEffect(buff, target)
|
||
local ratio = buff:getRatio()
|
||
if ratio < DEFAULT_FACTOR then
|
||
if BattleHelper:random(1, DEFAULT_FACTOR) > ratio then -- 没有通过命中概率
|
||
return false
|
||
end
|
||
end
|
||
if self.unitEntity:getIsFrozen() and buff:getDecr() == BattleConst.BUFF_DECR_TYPE.INCREASE_GAIN then -- 冻结状态,缓存增益buff
|
||
if buff:getRound() > 0 then
|
||
local buffEffect = BattleHelper:getBuffEffect()
|
||
buffEffect.buff = buff
|
||
buffEffect.result = nil
|
||
buffEffect.round = buff:getRound()
|
||
buffEffect.target = target
|
||
buffEffect.sender = self
|
||
target:putCacheBuff(buffEffect)
|
||
end
|
||
return
|
||
end
|
||
local round = buff:getRound()
|
||
local buffEffect
|
||
if round > 0 then
|
||
buffEffect = BattleHelper:getBuffEffect()
|
||
buffEffect.buff = buff
|
||
buffEffect.result = nil
|
||
buffEffect.round = round
|
||
buffEffect.target = target
|
||
buffEffect.sender = self
|
||
buffEffect = target:addBuff(buffEffect)
|
||
end
|
||
if buffEffect and buffEffect.result then
|
||
return
|
||
end
|
||
local func = BattleBuffHandle.takeBuffEffect[buff:getBuffType()]
|
||
if func then
|
||
local result = func(self, buff, target, buffEffect)
|
||
if buffEffect then
|
||
buffEffect.result = result
|
||
end
|
||
local success = result ~= nil
|
||
if success then
|
||
local fxList = buff:getFxGet()
|
||
if fxList then
|
||
for _, v in ipairs(fxList) do
|
||
target:playFx(v, 0)
|
||
end
|
||
end
|
||
end
|
||
return success
|
||
end
|
||
return false
|
||
end
|
||
|
||
function BattleUnitComp:reTakeEffectByBuffEffect(buffEffect)
|
||
local round = buffEffect.round
|
||
local target = buffEffect.target
|
||
local buff = buffEffect.buff
|
||
if round > 0 then
|
||
buffEffect.result = nil
|
||
buffEffect = target:addBuff(buffEffect)
|
||
end
|
||
if buffEffect and buffEffect.result then
|
||
return
|
||
end
|
||
local func = BattleBuffHandle.takeBuffEffect[buff:getBuffType()]
|
||
if func then
|
||
local result = func(self, buff, target, buffEffect)
|
||
if buffEffect then
|
||
buffEffect.result = result
|
||
end
|
||
local success = result ~= nil
|
||
if success then
|
||
local fxList = buff:getFxGet()
|
||
if fxList then
|
||
for _, v in ipairs(fxList) do
|
||
target:playFx(v, 0)
|
||
end
|
||
end
|
||
end
|
||
return success
|
||
end
|
||
return false
|
||
end
|
||
|
||
function BattleUnitComp:removeEffect(buff, target)
|
||
local round = buff:getRound()
|
||
if round > 0 then
|
||
return
|
||
end
|
||
local func = BattleBuffHandle.removeEffect[buff:getBuffType()]
|
||
if func then
|
||
func(self, target, buff)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:takeDamageOrCure(atker, num, effectType, effectStatus, damageOrCureType)
|
||
if self:getIsClear() then
|
||
return 0
|
||
end
|
||
if self.currState == UNIT_STATE.DEAD then
|
||
return 0
|
||
end
|
||
if num == 0 then
|
||
return 0
|
||
end
|
||
if num < 0 and atker.unitEntity:getBeDmgToHeal() > 0 then
|
||
num = -num * atker.unitEntity:getBeDmgToHeal() // DEFAULT_FACTOR
|
||
end
|
||
atker.unitEntity:addDamageCount(num)
|
||
local shieldHpBefore = self.unitEntity:getShieldHp()
|
||
local hpRealReduce = self.unitEntity:takeDamageOrCure(num)
|
||
if hpRealReduce < 0 and self.side == BattleConst.SIDE_DEF then -- 实际掉血了
|
||
local exp = self.unitEntity:getExp()
|
||
if exp > 0 then
|
||
local expTime = atker.unitEntity:getExpTime()
|
||
local addExp = math.floor(exp/self.unitEntity:getMaxHp()*-hpRealReduce)
|
||
if expTime > 0 then
|
||
addExp = addExp * (DEFAULT_FACTOR + expTime) // DEFAULT_FACTOR
|
||
end
|
||
self.battleController:addBattleExp(addExp)
|
||
end
|
||
end
|
||
local shieldHpDiff = self.unitEntity:getShieldHp() - shieldHpBefore
|
||
if shieldHpDiff < 0 then -- 说明护盾减少了
|
||
self.team:handleShield(shieldHpDiff, self)
|
||
end
|
||
local hp = self.unitEntity:getHp()
|
||
local x, y = self.baseObject:fastGetLocalPosition()
|
||
local damage = num
|
||
if num < 0 then -- 伤害
|
||
local delayTime = 0
|
||
if shieldHpDiff < 0 then
|
||
damage = damage - shieldHpDiff
|
||
delayTime = BattleConst.EFFECT_NUMBER_DELAY
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
self:showEffectNumber(BattleConst.EFFECT_COLOR_BLUE, BattleConst.EFFECT_TYPE_MOVE_L, shieldHpDiff, x, y, 0)
|
||
else
|
||
self:showEffectNumber(BattleConst.EFFECT_COLOR_BLUE, BattleConst.EFFECT_TYPE_MOVE_R, shieldHpDiff, x, y, 0)
|
||
end
|
||
end
|
||
if damage < 0 then
|
||
if effectStatus == HURT_STATE_CRIT then
|
||
self:showEffectNumber(BattleConst.EFFECT_COLOR_RED, BattleConst.EFFECT_TYPE_CRIT, "c" .. damage, x, y, delayTime)
|
||
else
|
||
local effectColor = BattleConst.EFFECT_COLOR_RED
|
||
local damageStr = damage
|
||
local direction = BattleConst.EFFECT_TYPE_MOVE_R
|
||
local elementType = BattleHelper:getDamageOrCureType2MatchType(damageOrCureType)
|
||
local weekNessValue = self.unitEntity:getWeakness(elementType)
|
||
if weekNessValue > 0 then
|
||
damageStr = "a" .. damage
|
||
else
|
||
local decGmgValue = self.unitEntity:getDecDmg(elementType)
|
||
if decGmgValue > 0 then
|
||
effectColor = BattleConst.EFFECT_COLOR_WHILTE
|
||
damageStr = "d" .. damage
|
||
end
|
||
end
|
||
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
direction = BattleConst.EFFECT_TYPE_MOVE_L
|
||
end
|
||
|
||
self:showEffectNumber(effectColor, direction, damageStr, x, y, delayTime)
|
||
end
|
||
end
|
||
if atker:getCurAttackActionState() == BattleConst.ATTACK_ACTION_STATE.NORMAL then
|
||
if self.unitEntity:getCounterAttack() > 0 then -- 触发反击
|
||
local counterattack = self.unitEntity:getCounterAttack()
|
||
if counterattack > DEFAULT_FACTOR or BattleHelper:random(1, DEFAULT_FACTOR) <= counterattack then -- 通过命中概率
|
||
self.unitEntity:addCounterAttackCount(1)
|
||
self.battleController:showCounterAttack(self.unitEntity:getCounterAttackCount(), self.side)
|
||
end
|
||
end
|
||
end
|
||
if effectType == EFFECT_TYPE.DIRECT then
|
||
if hp > 0 and self.unitEntity:getShieldRebound() then -- 伤害反弹
|
||
atker:takeDamageOrCure(self, num*self.unitEntity:getShieldRebound() // DEFAULT_FACTOR, EFFECT_TYPE.REBOUND, 0, BattleConst.BUFF_NAME.SHIELD_REBOUND_200)
|
||
end
|
||
if self.unitEntity:getBeSucked() > 0 then -- 吸血
|
||
atker:takeDamageOrCure(self, -num*self.unitEntity:getBeSucked() // DEFAULT_FACTOR, EFFECT_TYPE.HEAL, 0, BattleConst.SPECIAL_DAMAGE_OR_CURE_TYPE.BE_SUCKED)
|
||
end
|
||
if self.unitEntity:getIsLethargy() then -- 移除昏睡
|
||
self:removeBuffByName(BattleConst.BUFF_NAME.LETHARGY)
|
||
end
|
||
if self.unitEntity:getThorns() > 0 then -- 反伤
|
||
atker:takeDamageOrCure(self, num*self.unitEntity:getThorns() // DEFAULT_FACTOR, EFFECT_TYPE.REBOUND, 0, BattleConst.BUFF_NAME.THORNS)
|
||
end
|
||
end
|
||
elseif num > 0 then -- 治疗
|
||
local time = Time:getServerTime()
|
||
if self.lastHealTime == time then
|
||
self.lastSameTimeHealCount = self.lastSameTimeHealCount + 1
|
||
else
|
||
self.lastHealTime = time
|
||
self.lastSameTimeHealCount = 0
|
||
end
|
||
local delayTime = self.lastSameTimeHealCount * 0.1
|
||
self:showEffectNumber(BattleConst.EFFECT_COLOR_GREEN, BattleConst.EFFECT_TYPE_BUFF, "+" .. num, x, y, delayTime)
|
||
end
|
||
local hpPercent = self.unitEntity:getHpPercent()
|
||
self.battleController:refreshHp(self.side, hp, hpPercent)
|
||
if not atker:getIsFinalBlock() or not self.battleController:getIsLastInstruction() then
|
||
if damage < 0 then
|
||
self:playHurt()
|
||
end
|
||
else
|
||
if self.unitEntity:getIsDead() then
|
||
if damageOrCureType == BattleConst.BUFF_NAME.BURN then
|
||
local team = self.battleController:getOtherSideTeam(self.side)
|
||
team:checkPassiveEvent(BattleConst.PASSIVE_EVENT.ON_DEAD_BY_BURN)
|
||
end
|
||
if self.unitEntity:getAttrValue(BattleConst.ATTR_NAME.BLEED) > 0 then
|
||
local team = self.battleController:getOtherSideTeam(self.side)
|
||
team:checkPassiveEvent(BattleConst.PASSIVE_EVENT.ON_DEAD_WITH_BLEED)
|
||
end
|
||
|
||
if self.actionOverCallback then -- 被反击时死亡
|
||
self:onAttackOver()
|
||
end
|
||
|
||
self.battleController:resetTimeSpeed()
|
||
|
||
self:changeState(UNIT_STATE.DEAD)
|
||
elseif damage < 0 then
|
||
self:playHurt()
|
||
end
|
||
end
|
||
|
||
if hp > 0 then
|
||
self.team:checkPassiveEvent(PASSIVE_EVENT.HP_LOWER_THAN, atker, hpPercent)
|
||
else
|
||
self.team:checkPassiveEvent(PASSIVE_EVENT.ON_DEAD, atker)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:showEffectNumber(colorType, effectType, num, x, y, delayTime)
|
||
local addY = BattleConst.MIN_NODE_HEIGHT[self.unitEntity:getBody()] or BattleConst.MIN_NODE_HEIGHT_DEFAULT
|
||
self.battleController:showEffectNumber(colorType, effectType, num, x, y + addY, delayTime)
|
||
end
|
||
|
||
function BattleUnitComp:playDead(callback)
|
||
self.deadOverCallback = callback
|
||
if self:getIsClear() then
|
||
self.deadOverCallback = nil
|
||
if callback then
|
||
callback()
|
||
end
|
||
return
|
||
end
|
||
if self.currState ~= UNIT_STATE.DEAD and not self:changeState(UNIT_STATE.DEAD) then
|
||
self.deadOverCallback = nil
|
||
if callback then
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:recoverHpOnWaveOver(callback)
|
||
self.finishRecoverHpCallback = callback
|
||
if not self:changeState(UNIT_STATE.RECOVER_HP_WAVE) then
|
||
self.finishRecoverHpCallback = nil
|
||
callback()
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:playEnterBattlefield(isBoss, callback)
|
||
self.finishEnterBattlefieldCallback = callback
|
||
if isBoss then
|
||
self.isMove = true
|
||
self:hideOutsideScreen()
|
||
if not self:changeState(UNIT_STATE.ENTER_BATTLEFIELD) then
|
||
self.finishEnterBattlefieldCallback = nil
|
||
self.isMove = false
|
||
self:initPosition()
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
callback()
|
||
end
|
||
else
|
||
self.isMove = false
|
||
self:initPosition()
|
||
if not self:changeState(UNIT_STATE.ENTER_BATTLEFIELD) then
|
||
self.finishEnterBattlefieldCallback = nil
|
||
self:changeState(UNIT_STATE.IDLE)
|
||
callback()
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:onRoundEnd()
|
||
self.unitEntity:onRoundEnd()
|
||
end
|
||
|
||
function BattleUnitComp:playSkillFx(skill)
|
||
self:playSkillSelfFx(skill)
|
||
self:playSkillTargetFx(skill)
|
||
end
|
||
|
||
function BattleUnitComp:playSkillSelfFx(skill)
|
||
local fxId = skill:getFxSelf()
|
||
if fxId == nil then
|
||
return
|
||
end
|
||
local delay = skill:getFxSelfDelay()
|
||
self:playFx(fxId, delay)
|
||
end
|
||
|
||
function BattleUnitComp:playSkillTargetFx(skill)
|
||
local fxId = skill:getFxTarget()
|
||
if fxId == nil then
|
||
return
|
||
end
|
||
local delay = skill:getFxTargetDelay()
|
||
local targetType = skill:getTargetType()
|
||
if targetType == 1 then -- 自己
|
||
self:playFx(fxId, delay)
|
||
else
|
||
local target = self.battleController:getOtherSideMainUnit(self.side)
|
||
target:playFx(fxId, delay)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:playFx(fxId, delay)
|
||
if delay and delay > 0 then
|
||
if self.waitPlayFxList == nil then
|
||
self.waitPlayFxList = {}
|
||
self.waitPlayFxCount = 0
|
||
end
|
||
self.waitPlayFxCount = self.waitPlayFxCount + 1
|
||
local waitPlayFxObj = self.waitPlayFxList[self.waitPlayFxCount]
|
||
if waitPlayFxObj == nil then
|
||
waitPlayFxObj = {}
|
||
self.waitPlayFxList[self.waitPlayFxCount] = waitPlayFxObj
|
||
end
|
||
waitPlayFxObj.time = delay / TIME_FACTOR
|
||
waitPlayFxObj.fxId = fxId
|
||
waitPlayFxObj.sender = self
|
||
return
|
||
end
|
||
local fxInfo = BattleHelper:getFxConfig()[fxId]
|
||
if fxInfo then
|
||
self:getEffectAndPlay(fxInfo)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:getEffectAndPlay(fxInfo, isLoop)
|
||
local bindNode = fxInfo.bind
|
||
local inScene = fxInfo.in_scene == 1
|
||
local fxScale = fxInfo.scale or 1
|
||
BattleHelper:getEffectAsync(fxInfo.res, self.battleController:getFxNode(), function(effectObj)
|
||
if isLoop and self.team:getLoopFxResCount(fxInfo.res) <= 0 then
|
||
BattleHelper:recycleEffect(effectObj)
|
||
return
|
||
end
|
||
if inScene then
|
||
if bindNode then
|
||
local boneX, boneY, boneZ = self.baseObject:fastGetBonePosition(bindNode)
|
||
effectObj:setLocalPosition(boneX, boneY, boneZ)
|
||
else
|
||
effectObj:setLocalPosition(0, 0, 0)
|
||
end
|
||
else
|
||
if bindNode then
|
||
local boneFollower = BattleHelper:addSpineBoneFollowerGraphic(effectObj)
|
||
boneFollower.SkeletonGraphic = self.baseObject:getSkeletonGraphic()
|
||
boneFollower:SetBone(bindNode)
|
||
else
|
||
effectObj:setLocalPosition(0, 0, 0)
|
||
end
|
||
end
|
||
if fxInfo.follow_direction then
|
||
if self.side == BattleConst.SIDE_ATK then
|
||
if effectObj:getIsEulerAnglesFlip() then
|
||
effectObj:setLocalEulerAngles(0, 0, 0)
|
||
end
|
||
effectObj:setLocalScale(fxScale, fxScale, fxScale)
|
||
else
|
||
if effectObj:getIsEulerAnglesFlip() then
|
||
effectObj:setLocalEulerAngles(0, 180, 0)
|
||
effectObj:setLocalScale(fxScale, fxScale, fxScale)
|
||
else
|
||
effectObj:setLocalScale(-fxScale, fxScale, fxScale)
|
||
end
|
||
end
|
||
else
|
||
if effectObj:getIsEulerAnglesFlip() then
|
||
effectObj:setLocalEulerAngles(0, 0, 0)
|
||
end
|
||
effectObj:setLocalScale(fxScale, fxScale, fxScale)
|
||
end
|
||
local baseOrder = BattleHelper:getBaseOrder()
|
||
effectObj:setSortingOrder(baseOrder, 10)
|
||
effectObj:play()
|
||
if isLoop then
|
||
if self.loopFxMap[fxInfo.res] then
|
||
BattleHelper:recycleEffect(effectObj)
|
||
else
|
||
self.loopFxMap[fxInfo.res] = effectObj
|
||
end
|
||
else
|
||
BattleHelper:performDurationDelay(effectObj:getDuration(), function()
|
||
BattleHelper:recycleEffect(effectObj)
|
||
end)
|
||
end
|
||
end)
|
||
end
|
||
|
||
function BattleUnitComp:removeFx(res)
|
||
local effect = self.loopFxMap[res]
|
||
if effect then
|
||
self.loopFxMap[res] = nil
|
||
BattleHelper:recycleEffect(effect)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:tick(dt)
|
||
if self.isClear then
|
||
return
|
||
end
|
||
self:checkFx(dt)
|
||
if self.currState == UNIT_STATE.DEAD then
|
||
self:updateDead(dt)
|
||
return
|
||
end
|
||
if self.currState == UNIT_STATE.IDLE then
|
||
self:updateIdle(dt)
|
||
return
|
||
end
|
||
if self.currState == UNIT_STATE.NORMAL_ATTACK then
|
||
self:updateNormalAttack(dt)
|
||
elseif self.currState == UNIT_STATE.SKILL_ATTACK then
|
||
self:updateSkillAttack(dt)
|
||
elseif self.currState == UNIT_STATE.ASSISTING_ATTACK then
|
||
self:updateAssistingAttackState(dt)
|
||
elseif self.currState == UNIT_STATE.ENTER_BATTLEFIELD then
|
||
self:updateEnterBattlefieldState(dt)
|
||
elseif self.currState == UNIT_STATE.SWITCH_IN then
|
||
self:updateSwitchInState(dt)
|
||
elseif self.currState == UNIT_STATE.SWITCH_OUT then
|
||
self:updateSwitchOutState(dt)
|
||
elseif self.currState == UNIT_STATE.WAIT then
|
||
self:updateWaitState(dt)
|
||
elseif self.currState == UNIT_STATE.RECOVER_HP_WAVE then
|
||
self:updateRecoverHpWaveState(dt)
|
||
elseif self.currState == UNIT_STATE.FROZEN then
|
||
self:updateFrozen(dt)
|
||
elseif self.currState == UNIT_STATE.VERITGO then
|
||
self:updateVeritgo(dt)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:checkFx(dt)
|
||
if self.waitPlayFxCount == nil then
|
||
return
|
||
end
|
||
if self.waitPlayFxCount <= 0 then
|
||
return
|
||
end
|
||
for i = self.waitPlayFxCount, 1, -1 do
|
||
local fxObj = self.waitPlayFxList[i]
|
||
fxObj.time = fxObj.time - dt
|
||
if fxObj.time <= 0 then -- 该播了
|
||
self:playFx(fxObj.fxId, 0)
|
||
local tailFxObj = self.waitPlayFxList[self.waitPlayFxCount]
|
||
fxObj.time = tailFxObj.time
|
||
fxObj.fxId = tailFxObj.fxId
|
||
fxObj.sender = tailFxObj.sender
|
||
self.waitPlayFxCount = self.waitPlayFxCount - 1
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:checkPassiveEvent(eventId, targetComp, ...)
|
||
if self.passiveSkills == nil then
|
||
return
|
||
end
|
||
local skills = self.passiveSkills[eventId]
|
||
if skills and #skills > 0 then
|
||
local func = BattlePassive.checkTrigger[eventId]
|
||
if func then
|
||
for _, skill in ipairs(skills) do
|
||
local count = func(self, skill, targetComp, ...)
|
||
if count > 0 and skill:getIsAvailable() then
|
||
for i = 1, count do
|
||
self:usePassiveSkill(skill)
|
||
end
|
||
elseif count < 0 then
|
||
count = -count
|
||
for i = 1, count do
|
||
self:cancelPassiveSkillEffect(skill)
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:usePassiveSkill(skill)
|
||
self:onSkillTakeEffect(skill)
|
||
end
|
||
|
||
function BattleUnitComp:cancelPassiveSkillEffect(skill)
|
||
local effectList = skill:getEffectList()
|
||
if effectList == nil then
|
||
return
|
||
end
|
||
local targetType = skill:getTargetType()
|
||
local target
|
||
if targetType == 1 then -- 自己
|
||
target = self
|
||
else
|
||
target = self.battleController:getOtherSideMainUnit(self.side)
|
||
end
|
||
for k, effect in ipairs(effectList) do
|
||
self:removeEffect(effect, target)
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:getIsClear()
|
||
return self.isClear
|
||
end
|
||
|
||
function BattleUnitComp:clear()
|
||
if self.isClear then
|
||
return
|
||
end
|
||
self.isClear = true
|
||
if self.waitPlayFxList then
|
||
for i = 1, #self.waitPlayFxList do
|
||
table.remove(self.waitPlayFxList)
|
||
end
|
||
self.waitPlayFxCount = 0
|
||
end
|
||
end
|
||
|
||
function BattleUnitComp:recycle()
|
||
for k, v in pairs(self.loopFxMap) do
|
||
BattleHelper:recycleEffect(v)
|
||
self.loopFxMap[k] = nil
|
||
end
|
||
BattleHelper:recycleBattleHeroModel(self.modelId, self.baseObject)
|
||
end
|
||
|
||
return BattleUnitComp |