aozhiwei e1365f04b5 1
2022-12-29 09:58:05 +08:00

122 lines
4.3 KiB
C++

#include "precompile.h"
#include "buff/turnover.h"
#include "creature.h"
#include "room.h"
#include "skill.h"
#include "mt/Buff.h"
#include "mt/Skill.h"
void TurnOverBuff::Activate()
{
Skill* skill = owner->CurrentSkill();
if (!skill) {
return;
}
const mt::SkillPhase* phase = owner->GetCurrSkillPhase();
if (!phase) {
return;
}
#if 0
if (phase->time_offset < skill->GetPassedTime()) {
return;
}
#endif
glm::vec3 old_dir = owner->GetMoveDir();
Position old_pos = owner->GetPos();
float distance =
owner->HasBuffEffect(kBET_Car) ? phase->param1.GetDouble() * 1.5 : phase->param1.GetDouble();
#ifdef DEBUG
caster_.Get()->SendDebugMsg(a8::Format("ProcBecome currTimes:%d last_pos:%d,%d curr_pos:%d,%d",
{
skill->GetCurrTimes(),
owner->last_turn_over_pos.x,
owner->last_turn_over_pos.y,
owner->GetPos().x,
owner->GetPos().y
}));
#endif
Global::Instance()->verify_set_pos = 1;
owner->ForwardMove(distance);
Global::Instance()->verify_set_pos = 0;
owner->SetMoveDir(old_dir);
if (phase->param2.GetInt() == 1) {
++owner->turn_over_times;
owner->last_turn_over_pos = old_pos;
}
float moved_distance = owner->GetPos().Distance2D2(old_pos);
moved_distance = std::min(moved_distance, 200.0f);
if (!meta->_param1_int_list.empty() && moved_distance > 2.0f) {
std::set<Creature*> target_list;
owner->TraverseCreatures
(
[this, &target_list] (Creature* c, bool& stop)
{
if (owner->IsProperTarget(c) && owner->GetPos().Distance2D2(c->GetPos()) < 300) {
target_list.insert(c);
}
});
Position curr_pos = owner->GetPos();
glm::vec3 dir = old_pos.CalcDir(owner->GetPos());
GlmHelper::Normalize(dir);
for (int i = 5; i < moved_distance; i += 5) {
owner->GetMutablePos().FromGlmVec3(old_pos.ToGlmVec3() + dir * (float)i);
std::list<Creature*> hit_objects;
for (auto& target : target_list) {
if (owner->TestCollision(owner->room, target)) {
hit_objects.push_back(target);
}
}
for (auto& target : hit_objects) {
target_list.erase(target);
target->room->xtimer.SetTimeoutEx
(
meta->_int_param4 / FRAME_RATE_MS * (i / moved_distance),
[this, target] (int event, const a8::Args* args) mutable
{
Creature* c = target;
const mt::Buff* buff_meta = meta;
Entity* caster = c->room->GetEntityByUniId(owner->GetUniId());
if (caster && caster->IsCreature(c->room)) {
for (int buff_id : buff_meta->_param1_int_list) {
c->TryAddBuff((Creature*)caster, buff_id);
}
}
},
&target->xtimer_attacher);
}
}
owner->SetPos(curr_pos);
}
if (!meta->_param2_int_list.empty()) {
owner->room->xtimer.SetTimeoutEx
(
meta->_int_param4 / FRAME_RATE_MS,
[this] (int event, const a8::Args* args) mutable
{
Creature* c = owner;
const mt::Buff* buff_meta = meta;
c->TraverseCreatures
(
[c, buff_meta] (Creature* target, bool& stop)
{
if (c->GetPos().Distance2D2(target->GetPos()) < buff_meta->_int_param3) {
for (int buff_id : buff_meta->_param2_int_list) {
target->TryAddBuffWithTarget(c, buff_id);
}
}
});
},
&owner->xtimer_attacher
);
}
}
void TurnOverBuff::Deactivate()
{
}