#include "precompile.h" #include "buff/sprint.h" #include "creature.h" #include "skillhelper.h" #include "skill.h" #include "room.h" #include "human.h" #include "ability.h" #include "collision.h" #include "lispenv.h" #include "mt/Buff.h" #include "mt/Skill.h" #include "mt/SkillNumber.h" void SprintBuff::Activate() { move_distance_limit_ = meta->GetBuffParam2(this); check_interval_time_ = meta->GetBuffParam5(this); check_distance_ = meta->GetBuffParam4(this); SprintMove(); CoCollisionCheck(); } void SprintBuff::Deactivate() { int i = 0; } void SprintBuff::SprintMove() { int old_times = owner->GetDisableMoveDirTimes(); owner->SetDisableMoveDirTimes(0); owner->SetMoveDir(owner->context_dir); owner->SetAttackDir(owner->context_dir); owner->SetDisableMoveDirTimes(old_times); #ifdef DEBUG a8::XPrintf("%f\n", { a8::Format("xxxxxxxx move_dir:%f,%f,%f attack_dir:%f,%f,%f speed:%d", { owner->GetMoveDir().x, owner->GetMoveDir().y, owner->GetMoveDir().z, owner->GetAttackDir().x, owner->GetAttackDir().y, owner->GetAttackDir().z, owner->GetSpeed() }) }); owner->room->xtimer.SetIntervalEx ( 2, [this] (int event, const a8::Args* args) { if (a8::TIMER_EXEC_EVENT == event) { Human* hum = owner->AsHuman(); a8::XPrintf("%s\n", { a8::Format("xxxxxxxx move_dir:%f,%f,%f attack_dir:%f,%f,%f speed:%d", { hum->GetMoveDir().x, hum->GetMoveDir().y, hum->GetMoveDir().z, hum->GetAttackDir().x, hum->GetAttackDir().y, hum->GetAttackDir().z, hum->GetSpeed() }) }); } }, &xtimer_attacher ); #endif } void SprintBuff::CoCollisionCheck() { std::map hited_objects = std::map(); Position pre_pos; pre_pos = owner->GetPos(); Position src_pos = owner->GetPos(); owner->room->xtimer.SetIntervalEx ( 1, [this, hited_objects, pre_pos, src_pos] (int event, const a8::Args* args) mutable { if (a8::TIMER_EXEC_EVENT == event) { Check(pre_pos, src_pos, hited_objects); } }, &xtimer_attacher); } void SprintBuff::Check(Position& pre_pos, Position& src_pos, std::map& hited_objects) { if (pre_pos.ManhattanDistance2D(owner->GetPos()) < 2) { ++stop_times_; if (stop_times_ > 3) { SprintEnd(); } return; } stop_times_ = 0; { float moved_distance = owner->GetPos().Distance2D2(src_pos); if (moved_distance >= move_distance_limit_) { owner->room->xtimer.SetTimeoutEx ( 1, [this] (int event, const a8::Args* args) { if (a8::TIMER_EXEC_EVENT == event) { #ifdef DEBUG1 a8::XPrintf("11111111111111111111111111\n", {}); #endif owner->TryAddBuff(owner, meta->_int_buff_param1, skill_meta); owner->RemoveBuffByUniId(buff_uniid); } }, &xtimer_attacher); return; } } glm::vec3 dir = owner->GetPos().ToGlmVec3() - pre_pos.ToGlmVec3(); dir.y = 0.0f; GlmHelper::Normalize(dir); float distance = owner->GetPos().Distance2D2(pre_pos); for (int i = 0; i < (distance + 6); i += 5) { glm::vec3 center = pre_pos.ToGlmVec3() + dir * (float)i; std::set enemys; owner->GetHitEnemys(enemys, center, check_distance_); for (auto& enemy : enemys) { if (enemy->IsEntityType(ET_Car)) { continue; } auto itr = hited_objects.find(enemy->GetUniId()); if (itr != hited_objects.end()) { if (owner->room->GetFrameNo() - itr->second < check_interval_time_ * SERVER_FRAME_RATE) { continue; } } hited_objects[enemy->GetUniId()] = owner->room->GetFrameNo(); OnEnemyHit(enemy); } } pre_pos = owner->GetPos(); if (meta->_buff_param6 && !hited_objects.empty()) { owner->TryAddBuff(owner, meta->_int_buff_param1, skill_meta); owner->RemoveBuffByUniId(buff_uniid); } } void SprintBuff::OnEnemyHit(Creature* enemy) { for (int buff_id : meta->_buff_param3_int_list) { enemy->TryAddBuff(owner, buff_id, skill_meta); } } void SprintBuff::SprintEnd() { owner->room->xtimer.SetTimeoutEx ( 1, [this] (int event, const a8::Args* args) { if (a8::TIMER_EXEC_EVENT == event) { owner->TryAddBuff(owner, meta->_int_buff_param1, skill_meta); owner->RemoveBuffByUniId(buff_uniid); } }, &xtimer_attacher); }