#include "precompile.h" #include "skill.h" #include "creature.h" #include "room.h" #include "metamgr.h" void Skill::Initialzie() { curr_times_ = GetMaxTimes(); switch (meta->i->skill_type()) { case kActiveSkill: { inc_times_timer_ = owner->room->xtimer.AddRepeatTimerAndAttach ( GetCd() / FRAME_RATE_MS, a8::XParams() .SetSender(this), [] (const a8::XParams& param) { Skill* skill = (Skill*)param.sender.GetUserData(); if (skill->GetCurrTimes() < skill->GetMaxTimes()) { skill->curr_times_++; skill->NotifySkillState(); } }, &xtimer_attacher.timer_list_); } break; default: { } break; } } int Skill::GetCd() { return meta->i->skill_cd() * 1000; } int Skill::GetPassedTime() { if (!inc_times_timer_) { abort(); } if (GetCurrTimes() >= GetMaxTimes()) { return GetCd(); } else { int remain_time = owner->room->xtimer.GetRemainTime(inc_times_timer_); int passed_time = GetCd() - remain_time * FRAME_RATE_MS; passed_time = std::max(0, passed_time); return passed_time; } } int Skill::GetLeftTime() { int passed_time = GetPassedTime(); int skill_left_time = std::max(0, GetCd() - passed_time); return skill_left_time; } void Skill::FillMFSkill(cs::MFSkill* skill_pb) { skill_pb->set_skill_id(meta->i->skill_id()); skill_pb->set_left_time(GetLeftTime()); skill_pb->set_cd_time(GetCd()); skill_pb->set_curr_times(GetCurrTimes()); skill_pb->set_max_times(GetMaxTimes()); } void Skill::ClearPassiveSkillBuff() { for (int buff_id : meta->buff_list) { Buff* buff = owner->GetBuffById(buff_id); if (buff && (buff->meta->i->buff_target() == kBuffTargetSelf || buff->meta->i->buff_target() == kBuffTargetFriendly)) { owner->RemoveBuffById(buff_id); } } } void Skill::AddPassiveSkillBuff() { int old_skill_target_id_ = owner->skill_target_id_; a8::Vec2 old_skill_target_pos_ = owner->skill_target_pos_; owner->skill_target_id_ = owner->GetUniId(); owner->skill_target_pos_ = owner->GetPos(); std::set target_list; owner->SelectSkillTargets(this, owner->GetPos(), target_list); owner->TriggerBuff(this, target_list, kBTT_UseSkill); owner->skill_target_id_ = old_skill_target_id_; owner->skill_target_pos_ = old_skill_target_pos_; } void Skill::DecTimes() { if (!inc_times_timer_) { abort(); } if (GetCurrTimes() >= GetMaxTimes()) { owner->room->xtimer.ModifyTimer(inc_times_timer_, GetCd() / FRAME_RATE_MS); } --curr_times_; if (curr_times_ < 0) { curr_times_ = 0; } } int Skill::GetCurrTimes() { return curr_times_; } int Skill::GetMaxTimes() { return meta->i->max_times(); } void Skill::NotifySkillState() { if (owner->IsHuman()) { if (GetCurrTimes() < GetMaxTimes()) { owner->room->frame_event.AddSkillCdChg(owner->AllocWeakPtr(), meta->i->skill_id(), GetCd()); } else { owner->room->frame_event.AddSkillCdChg(owner->AllocWeakPtr(), meta->i->skill_id(), 0); } owner->room->frame_event.AddSkillCurrTimesChg(owner->AllocWeakPtr(), meta->i->skill_id(), GetCurrTimes()); } } void Skill::ResetSkillCd() { if (!meta->IsTurnOverSkill()) { curr_times_ = 0; if (inc_times_timer_) { owner->room->xtimer.ModifyTimer(inc_times_timer_, GetCd() / FRAME_RATE_MS); NotifySkillState(); } } } void Skill::Accelerate(int time) { if (inc_times_timer_) { int remain_time = owner->room->xtimer.GetRemainTime(inc_times_timer_) * FRAME_RATE_MS; remain_time += time; remain_time = std::max(remain_time, 0); owner->room->xtimer.ModifyTimer(inc_times_timer_, remain_time / FRAME_RATE_MS); NotifySkillState(); } } void Skill::LockCastPhase() { if (meta->i->cast_time() > 0) { int buff_uniid = owner->TryAddBuff(owner, kVertigoBuffId); Buff* buff = owner->GetBuffByUniId(buff_uniid); if (buff && buff->remover_timer) { owner->room->xtimer.ModifyTimer(buff->remover_timer, meta->i->cast_time() / FRAME_RATE_MS); } } }