122 lines
4.3 KiB
C++
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()
|
|
{
|
|
|
|
}
|