diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 32f1fd28..b6682453 100644 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -475,7 +475,8 @@ enum PolyExtDataFlag_e A8_DECLARE_ENUM(TimerUserEvent_e, kCheckShotHoldStateTimerEvent = 100, kShenBaoAddTimeTimerEvent, - kAddDjsHaloRangeTimerEvent + kActiveDjsSkillTimerEvent, + kDeactiveDjsSkillTimerEvent ); const char* const PROJ_NAME_FMT = "game%d_gameserver"; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index ae319f75..72203a86 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -3340,8 +3340,6 @@ int Human::GetTeamMode() return GetTeam()->GetMemberNum() <= 1 ? 0 : 1; } - - void Human::CalcAssists(Human* target) { if (GetTeam() && GetTeam()->GetMemberNum() > 1) { diff --git a/server/gameserver/skill.cc b/server/gameserver/skill.cc index d37ae205..3f8b7c3b 100644 --- a/server/gameserver/skill.cc +++ b/server/gameserver/skill.cc @@ -628,45 +628,123 @@ void Skill::Proc30501TZ() void Skill::Proc30601DJS() { - a8::XTimerWp timer = owner->room->xtimer.SetIntervalWpEx - ( - SERVER_FRAME_RATE, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - if (!owner->dead) { - owner->GetTeam()->TraverseMembers - ( - [this] (Human* hum) - { - if (owner != hum && - Collision::CheckCC(owner, owner->GetRadius(), - hum, meta->_number_meta->_float_range2)) { - if (hum->GetHP() < hum->GetMaxHP()) { - hum->AddHp(hum->GetMaxHP() * meta->_number_meta->resume()); - } - } - return true; - }); - } - } - }, - &xtimer_attacher); + a8::XTimerWp passive_skill_timer; + { + const mt::Skill* active_skill_meta = nullptr; + std::set in_range_humans; + auto on_enter = + [] (Human* num) + { - owner->GetTrigger()->AddListener - ( - kUseSkillEvent, - [this, timer] (const a8::Args& args) mutable - { - if (!timer.expired()) { + }; + auto on_stay = + [] (Human* hum) + { + + }; + auto on_leave = + [] (Human* hum) + { + + }; + passive_skill_timer = owner->room->xtimer.SetIntervalWpEx + ( + SERVER_FRAME_RATE, + [this, in_range_humans, active_skill_meta, on_enter, on_stay, on_leave] + (int event, const a8::Args* args) mutable + { + if (a8::TIMER_EXEC_EVENT == event) { + if (!owner->dead) { + float range = meta->_number_meta->_float_range2; + float resume_hp = meta->_number_meta->resume(); + int size = 0; + std::array hit_humans; + owner->GetTeam()->TraverseMembers + ( + [this, range, hit_humans, &size] (Human* hum) mutable + { + if (owner != hum && + Collision::CheckCC(owner, owner->GetRadius(), + hum, range)) { + if (size < MAX_TEAM_NUM) { + hit_humans[size++] = hum; + } + } + return true; + }); + std::vector leave_humans; + for (Human* hum : in_range_humans) { + bool found = false; + for (int i = 0; i < size; ++i){ + if (hit_humans[i] == hum) { + found = true; + break; + } + } + if (!found) { + on_leave(hum); + leave_humans.push_back(hum); + } + } + for (Human* hum : leave_humans) { + in_range_humans.erase(hum); + } + for (int i = 0; i < size; ++i){ + if (in_range_humans.find(hit_humans[i]) == in_range_humans.end()) { + on_enter(hit_humans[i]); + in_range_humans.insert(hit_humans[i]); + } else { + on_stay(hit_humans[i]); + } + } + } + } else if (kActiveDjsSkillTimerEvent == event) { + active_skill_meta = args->Get(0); + //owner->GetAbility()->AddSpeedRuduce(active_skill_meta->_number_meta->speed()); + } else if (kDeactiveDjsSkillTimerEvent == event) { + //owner->GetAbility()->DecSpeedRuduce(active_skill_meta->_number_meta->speed()); + active_skill_meta = nullptr; + } + }, + &xtimer_attacher); + } + + { + a8::XTimerWp active_skill_timer; + owner->GetTrigger()->AddListener + ( + kUseSkillEvent, + [this, passive_skill_timer, active_skill_timer] (const a8::Args& args) mutable + { + if (passive_skill_timer.expired()) { + return; + } Skill* skill = args.Get(0); if (skill->meta->GetMagicId() == MAGIC_20601_DJS) { - a8::Args args({}); - owner->room->xtimer.FireEvent(timer, kAddDjsHaloRangeTimerEvent, &args); + if (!active_skill_timer.expired()) { + return; + } + a8::Args event_args({skill->meta}); + owner->room->xtimer.FireEvent(passive_skill_timer, + kActiveDjsSkillTimerEvent, + &event_args); + active_skill_timer = owner->room->xtimer.SetTimeoutWpEx + ( + skill->meta->_number_meta->_float_time / FRAME_RATE_MS, + [this, passive_skill_timer] (int event, const a8::Args* args) mutable + { + if (a8::TIMER_DELETE_EVENT == event) { + a8::Args event_args({}); + owner->room->xtimer.FireEvent(passive_skill_timer, + kDeactiveDjsSkillTimerEvent, + &event_args); + } + }, + &xtimer_attacher); } } - } - ); + ); + } } void Skill::Proc30701BAO()