1172 lines
32 KiB
Lua
1172 lines
32 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 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
|
|
|
|
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
|
|
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:setTeam(team)
|
|
self.team = team
|
|
end
|
|
|
|
function BattleUnitComp:_initBase()
|
|
self.isClear = false
|
|
self.isMove = false
|
|
self.deadTime = 0
|
|
self.attackTime = 0
|
|
self.currAttackDuration = 0
|
|
self.currAttackKeyTime = 0
|
|
self.switchTime = 0
|
|
self.isPlayHurt = 0
|
|
self.attackDurationMap = {}
|
|
self.attackKeyFrameTimeMap = {}
|
|
self.shieldBuffList = {}
|
|
self.activeSkillIndex = nil
|
|
self.currActiveSkill = nil
|
|
self.targetX = nil
|
|
self.assistingDmgAddition = 0
|
|
self.attackCount = 0
|
|
self.currState = UNIT_STATE.INIT
|
|
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()
|
|
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
|
|
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 == SPINE_ANIMATION_NAME.HIT then
|
|
self.isPlayHurt = 1
|
|
else
|
|
self.isPlayHurt = 0
|
|
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)
|
|
local time = self.attackKeyFrameTimeMap[animationName]
|
|
if time == nil then
|
|
time = self.baseObject:getAnimationKeyFrameTime(animationName)
|
|
if time <= 0 then -- 容错处理
|
|
time = 0.3
|
|
end
|
|
self.attackKeyFrameTimeMap[animationName] = time
|
|
end
|
|
return time
|
|
end
|
|
|
|
function BattleUnitComp:getIsCentralizedAttack()
|
|
return self.centralizedAttack
|
|
end
|
|
|
|
function BattleUnitComp:beforeAttack()
|
|
self.centralizedAttack = true
|
|
self.battleController:setIsPauseHpProgress(true)
|
|
self:checkPassiveEvent(PASSIVE_EVENT.ON_UNI_ATTACK_START, self)
|
|
end
|
|
|
|
function BattleUnitComp:useAssistingSkill(count, delay, callback)
|
|
local skill = self.unitEntity:getAssistingSkill()
|
|
if skill == nil then
|
|
callback()
|
|
return
|
|
end
|
|
self.assistingDmgAddition = count
|
|
local attrName = GConst.MATCH_ATTACK_NAME[self:getMatchType()]
|
|
self.assistingDmgAddCount = self.unitEntity:addAttr(attrName, count*DEFAULT_FACTOR, true)
|
|
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 = index
|
|
self.currActiveSkill = self.unitEntity:getAvailableActiveSkill(index)
|
|
self.normalSkillCount = count + self.unitEntity:getNormalAttackAddCount()
|
|
if self.currActiveSkill == nil then -- 没有技能就用普攻
|
|
if self.normalSkillCount <= 0 then
|
|
self.actionOverCallback = nil
|
|
self.activeSkillIndex = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
return
|
|
end
|
|
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
|
self.actionOverCallback = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
end
|
|
else
|
|
if not self:changeState(UNIT_STATE.SKILL_ATTACK) then
|
|
self.actionOverCallback = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
end
|
|
end
|
|
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()
|
|
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.centralizedAttack = false
|
|
callback()
|
|
return
|
|
end
|
|
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
|
self.actionOverCallback = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
end
|
|
else
|
|
if not self:changeState(UNIT_STATE.SKILL_ATTACK) then
|
|
self.actionOverCallback = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
end
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:useNormalSkill(count, callback)
|
|
self.actionOverCallback = callback
|
|
self.normalSkillCount = count + self.unitEntity:getNormalAttackAddCount()
|
|
if not self:changeState(UNIT_STATE.NORMAL_ATTACK) then
|
|
self.actionOverCallback = nil
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
self.centralizedAttack = false
|
|
callback()
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:addShield(num, buffEffect)
|
|
self.unitEntity:addShield(num)
|
|
self.team:addShield(buffEffect)
|
|
end
|
|
|
|
function BattleUnitComp:changeState(state)
|
|
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()
|
|
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.BORN then
|
|
self:enterBornState()
|
|
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()
|
|
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
|
|
self:changeState(UNIT_STATE.IDLE)
|
|
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()
|
|
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*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
|
|
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:updateHurt(dt)
|
|
end
|
|
|
|
function BattleUnitComp:playHurt()
|
|
self.hurtTime = 0
|
|
if self.currHitDuration == nil then
|
|
self.currHitDuration = self:getAnimationDuration(SPINE_ANIMATION_NAME.HIT)
|
|
end
|
|
self:playAnimation(SPINE_ANIMATION_NAME.HIT, false, false)
|
|
|
|
end
|
|
|
|
function BattleUnitComp:updateHurt(dt)
|
|
if self.isPlayHurt == 0 then
|
|
return
|
|
end
|
|
if self.isPlayHurt == 1 then
|
|
self.hurtTime = self.hurtTime + dt
|
|
if self.hurtTime >= self.currHitDuration then
|
|
self:playAnimation(SPINE_ANIMATION_NAME.IDLE, true, false)
|
|
self.isPlayHurt = 0
|
|
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.isMove = false
|
|
local skill = self.unitEntity:getAssistingSkill()
|
|
skill:startUse()
|
|
local attackName = skill:getSkillAttackName()
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
self:attackAndSpeedUp()
|
|
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 -- 到达关键后使用
|
|
self.currAttackKeyTime = 0
|
|
local skill = self.unitEntity:getAssistingSkill()
|
|
self:onSkillTakeEffect(skill)
|
|
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()
|
|
else
|
|
skill = self.currActiveSkill
|
|
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
|
|
self.attackTime = 0
|
|
local attackName
|
|
if self.normalSkillCount > 0 then
|
|
attackName = skill:getRandomNormalAttackName()
|
|
else
|
|
attackName = skill:getSkillAttackName()
|
|
end
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
self:attackAndSpeedUp()
|
|
end
|
|
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.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.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
|
|
return
|
|
else
|
|
self.currActiveSkill = currActiveSkill
|
|
self:doNextSkillAttack()
|
|
end
|
|
end
|
|
else
|
|
if self.currAttackKeyTime > 0 and self.attackTime >= self.currAttackKeyTime then -- 到达关键后使用
|
|
self.currAttackKeyTime = 0
|
|
if self.normalSkillCount > 0 then
|
|
if self.normalSkillCount == 1 and self.currActiveSkill == nil then -- 最后一次攻击
|
|
self.centralizedAttack = false
|
|
end
|
|
local skill = self.unitEntity:getNormalSkill()
|
|
self:onSkillTakeEffect(skill)
|
|
if self.normalSkillCount == 1 and self.currActiveSkill == nil then -- 最后一次攻击
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
end
|
|
else
|
|
local isHaveNextAttack = self:getIsHaveNextAvailableActiveSkill()
|
|
if not isHaveNextAttack then
|
|
self.centralizedAttack = false
|
|
end
|
|
self:onSkillTakeEffect(self.currActiveSkill)
|
|
if not isHaveNextAttack then
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:getIsHaveNextAvailableActiveSkill()
|
|
local skillCanUseTimes = self.currActiveSkill:getSkillCanUseTimes()
|
|
if skillCanUseTimes and skillCanUseTimes > 0 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
|
|
DataManager.BattleData:addTimeSpeed()
|
|
elseif self.attackCount == 5 then
|
|
DataManager.BattleData:addTimeSpeed()
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:doNextSkillAttack()
|
|
self.attackTime = 0
|
|
local attackName = self.currActiveSkill:getSkillAttackName()
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
self:attackAndSpeedUp()
|
|
end
|
|
|
|
function BattleUnitComp:doNextNormalAttack()
|
|
self.attackTime = 0
|
|
local skill = self.unitEntity:getNormalSkill()
|
|
local attackName = skill:getRandomNormalAttackName()
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
self:attackAndSpeedUp()
|
|
end
|
|
|
|
function BattleUnitComp:doNextAttack()
|
|
self.attackTime = 0
|
|
local attackName = nil
|
|
if self.normalSkillCount > 0 then
|
|
local skill = self.unitEntity:getNormalSkill()
|
|
attackName = skill:getRandomNormalAttackName()
|
|
elseif self.currActiveSkill then
|
|
attackName = self.currActiveSkill:getSkillAttackName()
|
|
end
|
|
if attackName then
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
self:attackAndSpeedUp()
|
|
else -- 归位
|
|
self:moveBackToInitPosition()
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:enterNormalAttackState()
|
|
self.attackOver = false
|
|
self.attackTime = 0
|
|
local skill = self.unitEntity:getNormalSkill()
|
|
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
|
|
self.attackTime = 0
|
|
local attackName = skill:getRandomNormalAttackName()
|
|
self.currAttackDuration = self:getAnimationDuration(attackName)
|
|
self.currAttackKeyTime = self:getAnimationKeyFrameTime(attackName)
|
|
self:playAnimation(attackName, false, false)
|
|
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 -- 到达关键后使用
|
|
self.currAttackKeyTime = 0
|
|
if self.normalSkillCount == 1 then -- 如果是最后一次攻击,那么敌人受到这次攻击可以开始嗝屁了
|
|
self.centralizedAttack = false
|
|
end
|
|
local skill = self.unitEntity:getNormalSkill()
|
|
self:onSkillTakeEffect(skill)
|
|
if self.normalSkillCount == 1 then -- 如果是最后一次攻击,那么可以开始跑血条了
|
|
self.battleController:setIsPauseHpProgress(false)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:addBuff(buffEffect)
|
|
self.team:addBuff(buffEffect)
|
|
end
|
|
|
|
function BattleUnitComp:updateBuffState(buff, num)
|
|
self.team:updateBuffState(buff, num)
|
|
end
|
|
|
|
function BattleUnitComp:onSkillTakeEffect(skill)
|
|
skill:endUse()
|
|
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)
|
|
if skill:getIsNormalType() then -- 普攻要计算一下格挡
|
|
local block = target.unitEntity:getBlock()
|
|
if block > 0 then
|
|
if BattleHelper:random(1, DEFAULT_FACTOR) <= block then -- 格挡成功
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local succ = false
|
|
for k, effect in ipairs(effectList) do
|
|
if self:takeEffect(effect, target) then
|
|
succ = true
|
|
end
|
|
end
|
|
if succ and skill:getIsNormalType() then -- 普攻攻击成功的话
|
|
self:checkPassiveEvent(PASSIVE_EVENT.USE_NORMAL_SKILL, target)
|
|
end
|
|
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
|
|
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
|
|
target:addBuff(buffEffect)
|
|
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 fxId = buff:getBuffHitFxId()
|
|
if fxId then
|
|
target:playHurtFx(fxId)
|
|
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, buff, num, effectType, effectStatus)
|
|
if self:getIsClear() then
|
|
return 0
|
|
end
|
|
if self.currState == UNIT_STATE.DEAD then
|
|
return 0
|
|
end
|
|
if num == 0 then
|
|
return 0
|
|
end
|
|
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
|
|
self.battleController:addBattleExp(math.floor(exp/self.unitEntity:getMaxHp()*-hpRealReduce))
|
|
end
|
|
end
|
|
local shieldHpDiff = self.unitEntity:getShieldHp() - shieldHpBefore
|
|
if shieldHpDiff < 0 then -- 说明护盾减少了
|
|
self:handleShield(shieldHpDiff, self)
|
|
end
|
|
local x, y, z = self.baseObject:fastGetLocalPosition()
|
|
self:showEffectNumber(num, x, y)
|
|
local hp = self.unitEntity:getHp()
|
|
local hpPercent = self.unitEntity:getHpPercent()
|
|
self.battleController:refreshHp(self.side, hp, hpPercent)
|
|
if atker:getIsCentralizedAttack() then
|
|
if self.currState == UNIT_STATE.IDLE then
|
|
self:playHurt()
|
|
end
|
|
else
|
|
if self.unitEntity:getIsDead() then
|
|
self:changeState(UNIT_STATE.DEAD)
|
|
elseif self.currState == UNIT_STATE.IDLE then
|
|
self:playHurt()
|
|
end
|
|
end
|
|
if hp > 0 then
|
|
self:checkPassiveEvent(PASSIVE_EVENT.HP_LOWER_THAN, atker, hpPercent)
|
|
end
|
|
end
|
|
|
|
function BattleUnitComp:showEffectNumber(num, x, y)
|
|
self.battleController:showEffectNumber(num, x, y)
|
|
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: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:tick(dt)
|
|
if self.isClear then
|
|
return
|
|
end
|
|
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)
|
|
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
|
|
end
|
|
|
|
function BattleUnitComp:recycle()
|
|
BattleHelper:recycleBattleHeroModel(self.modelId, self.baseObject)
|
|
end
|
|
|
|
return BattleUnitComp |