aozhiwei abf555c009 1
2022-10-06 14:35:26 +08:00

429 lines
9.3 KiB
C++

#include "precompile.h"
#include "skill.h"
#include "creature.h"
#include "room.h"
#include "metamgr.h"
#include "trigger.h"
void Skill::Initialzie()
{
curr_times_ = GetMaxTimes();
switch (meta->i->skill_type()) {
case kActiveSkill:
{
InitActiveSkill();
}
break;
case kPassiveSkill:
{
InitPassiveSkill();
}
break;
default:
{
}
break;
}
}
int Skill::GetCd()
{
return meta->i->skill_cd() * 1000;
}
int Skill::GetPassedTime()
{
if (!inc_times_timer_) {
A8_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());
if (minor_type_) {
int minor_left_time = std::max(0, minor_cd_time_ - (int)(owner->room->GetFrameNo() - minor_frameno_));
skill_pb->set_minor_type(minor_type_);
skill_pb->set_minor_left_time(minor_left_time);
skill_pb->set_minor_cd_time(minor_cd_time_);
skill_pb->set_left_time(GetCd());
#ifdef DEBUG
a8::XPrintf("type: %d, lefttime:%d cd_time:%d\n", {
minor_type_,
minor_left_time,
minor_cd_time_
});
#endif
}
}
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<Creature*> 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_) {
A8_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);
}
}
}
int Skill::GetCurrExp()
{
return curr_exp_;
}
void Skill::SetCurrExp(int exp)
{
curr_exp_ = std::max(0, exp);
}
int Skill::GetMaxExp()
{
return meta->i->up_exp();
}
void Skill::AddMinorMode(
int minor_type,
int minor_cd_time,
std::function<void()> cb
)
{
if (minor_mode_timer_) {
owner->room->xtimer.DeleteTimer(minor_mode_timer_);
minor_mode_timer_ = nullptr;
}
minor_type_ = minor_type;
minor_cd_time_ = minor_cd_time;
minor_frameno_ = owner->room->GetFrameNo();
minor_cb_ = cb;
minor_mode_timer_ = owner->room->xtimer.AddDeadLineTimerAndAttach
(minor_cd_time / FRAME_RATE_MS,
a8::XParams()
.SetSender(this),
[] (const a8::XParams& param)
{
Skill* skill = (Skill*)param.sender.GetUserData();
},
&xtimer_attacher.timer_list_,
[] (const a8::XParams& param)
{
Skill* skill = (Skill*)param.sender.GetUserData();
skill->minor_type_ = SMT_NONE;
skill->minor_cd_time_ = 0;
skill->minor_frameno_ = 0;
skill->minor_cb_ = nullptr;
skill->minor_mode_timer_ = nullptr;
}
);
owner->need_sync_active_player = true;
}
void Skill::DoMinorMode()
{
if (GetMinorType() != SMT_NONE) {
minor_cb_();
minor_type_ = SMT_NONE;
minor_cd_time_ = 0;
minor_cb_ = nullptr;
ResetSkillCd();
owner->need_sync_active_player = true;
}
}
void Skill::InitActiveSkill()
{
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_);
}
void Skill::InitPassiveSkill()
{
switch (meta->GetMagicId()) {
case MAGIC_SJXY:
{
ProcSJXY();
}
break;
case MAGIC_SSJS:
{
ProcSSJS();
}
break;
case MAGIC_JSHX:
{
ProcJSHX();
}
break;
case MAGIC_SWZB:
{
ProcSWZB();
}
break;
case MAGIC_CMXD:
{
ProcCMXD();
}
break;
case MAGIC_MYXY:
{
ProcMYXY();
}
break;
case MAGIC_GZJS:
{
ProcGZJS();
}
break;
case MAGIC_JYFH:
{
ProcJYFH();
}
break;
case MAGIC_FH:
{
ProcFH();
}
break;
case MAGIC_YSHF:
{
ProcYSHF();
}
break;
default:
{
}
break;
}
}
void Skill::ProcSJXY()
{
owner->GetTrigger()->AddListener
(
kBulletHitEvent,
[this] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcSSJS()
{
owner->GetTrigger()->AddListener
(
kReceiveDmgEvent,
[] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcJSHX()
{
owner->GetTrigger()->AddListener
(
kKillEvent,
[] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcSWZB()
{
owner->GetTrigger()->AddListener
(
kDieEvent,
[] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcCMXD()
{
owner->GetTrigger()->AddListener
(
kShieldDestoryEvent,
[this] (const std::vector<std::any>& params)
{
Buff* hold_shield_buff = owner->GetBuffByEffectId(kBET_HoldShield);
if (hold_shield_buff) {
}
}
);
}
void Skill::ProcMYXY()
{
}
void Skill::ProcGZJS()
{
}
void Skill::ProcJYFH()
{
owner->GetTrigger()->AddListener
(
kRescueEvent,
[] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcFH()
{
owner->GetTrigger()->AddListener
(
kDieEvent,
[] (const std::vector<std::any>& params)
{
}
);
}
void Skill::ProcYSHF()
{
#if 0
owner->GetTrigger()->AddListener
(
kDieEvent,
[] (const std::vector<std::any>& params)
{
}
);
#endif
}