aozhiwei e11a776f01 1
2023-01-04 11:02:10 +08:00

188 lines
5.5 KiB
C++

#include "precompile.h"
#include "buff/sprint.h"
#include "creature.h"
#include "skillhelper.h"
#include "skill.h"
#include "room.h"
#include "human.h"
#include "mt/Buff.h"
#include "mt/Skill.h"
void SprintBuff::Activate()
{
if (meta->_int_param5) {
owner->IncDisableMoveDirTimes();
}
if (caster_.Get()->IsPlayer()) {
SprintMove();
CoCollisionCheck();
}
ProcSkill();
}
void SprintBuff::Deactivate()
{
if (meta->_int_param5) {
owner->DecDisableMoveDirTimes();
}
if (owner->AsHuman()) {
owner->AsHuman()->last_shot_frameno_ = owner->room->GetFrameNo() + SERVER_FRAME_RATE;
}
}
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<int, long long> hited_objects = std::map<int, long long>();
Position pre_pos;
pre_pos = owner->GetPos();
owner->room->xtimer.SetIntervalEx
(
1,
[this, hited_objects, pre_pos]
(int event, const a8::Args* args) mutable
{
if (a8::TIMER_EXEC_EVENT == event) {
if (!meta->_param3_int_list.empty() || skill_meta) {
Check(pre_pos, hited_objects);
}
}
},
&xtimer_attacher);
}
void SprintBuff::Check(Position& pre_pos, std::map<int, long long>& hited_objects)
{
if (pre_pos.ManhattanDistance2D(owner->GetPos()) < 2) {
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 = owner->GetPos().ToGlmVec3() + dir * (float)i;
std::set<Creature*> enemys;
owner->GetHitEnemys(enemys, center, meta->_param4);
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) * FRAME_RATE_MS <
meta->_int_param5) {
continue;
}
}
hited_objects[enemy->GetUniId()] = owner->room->GetFrameNo();
OnEnemyHit(enemy);
}
}
pre_pos = owner->GetPos();
}
void SprintBuff::OnEnemyHit(Creature* enemy)
{
for (int buff_id : meta->_param3_int_list) {
enemy->TryAddBuff(owner, buff_id);
}
if (skill_meta) {
switch (skill_meta->GetMagicId()) {
case MAGIC_YMCZ:
{
float dmg = SkillHelper::GetYmczDmg(owner,
enemy,
skill_meta);
if (dmg > 0.0001f) {
enemy->DecHP(
dmg,
owner->GetUniId(),
owner->GetName(),
0,
owner->GetUniId(),
owner->GetName()
);
}
}
break;
default:
{
}
break;
}
}
}
void SprintBuff::ProcSkill()
{
if (skill_meta) {
switch (skill_meta->GetMagicId()) {
case MAGIC_YMCZ:
{
owner->room->xtimer.ModifyTime
(remover_timer,
SkillHelper::GetYmczBuffTime(skill_meta) / FRAME_RATE_MS);
}
break;
default:
{
}
break;
}
}
}