diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index f41ee169..e36e7583 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -1006,62 +1006,24 @@ void Creature::DoSkill(int skill_id, #endif CurrentSkill()->last_use_frameno = room->GetFrameNo(); skill->LockCastPhase(); - if (CurrentSkill()->meta->skill_target() == kST_Self - ) { - skill_target_id_ = GetUniId(); - } - if (CurrentSkill()->meta->skill_target() == kST_SpecDir) { - std::set target_list; - SelectSkillTargets(CurrentSkill(), GetPos(), target_list); - TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); - if (!CurrentSkill()->meta->_phases.empty() && - CurrentSkill()->meta->_phases[0].time_offset <= 0) { - UpdateSkill(); - } - } else { - if (skill_target_id_ == 0) { - if (CurrentSkill()->meta->skill_target() == kST_FriendlyIncludeSelf || - CurrentSkill()->meta->skill_target() == kST_FriendlyExcludeSelf) { - skill_target_id_ = GetUniId(); - } - } - Entity* entity = room->GetEntityByUniId(skill_target_id_); - if (entity && entity->IsCreature(room)) { - Creature* c = (Creature*)entity; - std::set target_list; - SelectSkillTargets(CurrentSkill(), c->GetPos(), target_list); - if (!CurrentSkill()->meta->_phases.empty() && - CurrentSkill()->meta->_phases[0].time_offset <= 0) { - if (CurrentSkill()->meta->_phases[0].func_id == kSkill_HoldShield) { - if (HasBuffEffect(kBET_HoldShield)) { - RemoveBuffByEffectId(kBET_HoldShield); - playing_skill = false; - } else { - UpdateSkill(); - } - } else { - TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); - UpdateSkill(); - } - } else { - TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); - } - } else { - std::set target_list; - SelectSkillTargets(CurrentSkill(), GetPos(), target_list); - TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); - if (!CurrentSkill()->meta->_phases.empty() && - CurrentSkill()->meta->_phases[0].func_id == kSkill_Shot) { - playing_skill = true; - } else { - playing_skill = false; - } - } - } if (HasBuffEffect(kBET_Camouflage)) { RemoveBuffByEffectId(kBET_Camouflage); } GetTrigger()->UseSkill(skill); + if (skill->meta->cast_time() > 0) { + room->xtimer.SetTimeoutEx + ( + skill->meta->cast_time() / FRAME_RATE_MS, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + InternalUseSkill(); + } + }, + &xtimer_attacher); + } else { + InternalUseSkill(); + } DoSkillPostProc(true, skill_id, target_id); if (IsHuman()) { ++AsHuman()->stats->use_skill_times; @@ -3798,3 +3760,62 @@ void Creature::LateUpdate(int delta_time) { trigger_->Update(); } + +void Creature::InternalUseSkill() +{ + if (dead) { + return; + } + if (CurrentSkill()->meta->skill_target() == kST_Self + ) { + skill_target_id_ = GetUniId(); + } + if (CurrentSkill()->meta->skill_target() == kST_SpecDir) { + std::set target_list; + SelectSkillTargets(CurrentSkill(), GetPos(), target_list); + TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); + if (!CurrentSkill()->meta->_phases.empty() && + CurrentSkill()->meta->_phases[0].time_offset <= 0) { + UpdateSkill(); + } + } else { + if (skill_target_id_ == 0) { + if (CurrentSkill()->meta->skill_target() == kST_FriendlyIncludeSelf || + CurrentSkill()->meta->skill_target() == kST_FriendlyExcludeSelf) { + skill_target_id_ = GetUniId(); + } + } + Entity* entity = room->GetEntityByUniId(skill_target_id_); + if (entity && entity->IsCreature(room)) { + Creature* c = (Creature*)entity; + std::set target_list; + SelectSkillTargets(CurrentSkill(), c->GetPos(), target_list); + if (!CurrentSkill()->meta->_phases.empty() && + CurrentSkill()->meta->_phases[0].time_offset <= 0) { + if (CurrentSkill()->meta->_phases[0].func_id == kSkill_HoldShield) { + if (HasBuffEffect(kBET_HoldShield)) { + RemoveBuffByEffectId(kBET_HoldShield); + playing_skill = false; + } else { + UpdateSkill(); + } + } else { + TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); + UpdateSkill(); + } + } else { + TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); + } + } else { + std::set target_list; + SelectSkillTargets(CurrentSkill(), GetPos(), target_list); + TriggerBuff(CurrentSkill(), target_list, kBTT_UseSkill); + if (!CurrentSkill()->meta->_phases.empty() && + CurrentSkill()->meta->_phases[0].func_id == kSkill_Shot) { + playing_skill = true; + } else { + playing_skill = false; + } + } + } +} diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 4ea6e48f..7ec2a0eb 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -420,6 +420,7 @@ private: void AutoSwitchWeapon(); void CheckLoadingBullet(); bool InternalCanUseSkill(Skill* skill); + void InternalUseSkill(); protected: bool need_sync_active_player_ = false;