1
This commit is contained in:
parent
c9d024e54e
commit
9a460eecba
@ -1,5 +1,7 @@
|
|||||||
#include "precompile.h"
|
#include "precompile.h"
|
||||||
|
|
||||||
|
#include <a8/collision.h>
|
||||||
|
|
||||||
#include "buff/callfunc.h"
|
#include "buff/callfunc.h"
|
||||||
|
|
||||||
#include "creature.h"
|
#include "creature.h"
|
||||||
@ -183,6 +185,11 @@ void CallFuncBuff::Activate()
|
|||||||
PlayFlyEffect();
|
PlayFlyEffect();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BuffCallFunc_e::kSpecCenterRangeHoldBuff:
|
||||||
|
{
|
||||||
|
SpecCenterRangeHoldBuff();
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -992,145 +999,7 @@ void CallFuncBuff::SummonCarSpecPoint()
|
|||||||
|
|
||||||
void CallFuncBuff::RangeHoldBuff()
|
void CallFuncBuff::RangeHoldBuff()
|
||||||
{
|
{
|
||||||
if (owner->dead) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct InnerObject
|
|
||||||
{
|
|
||||||
CreatureWeakPtr c;
|
|
||||||
std::vector<int> buff_uniids;
|
|
||||||
|
|
||||||
void OnEnter()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnLeave()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
auto context = A8_MAKE_ANON_STRUCT_SHARED
|
|
||||||
(
|
|
||||||
std::map<int, InnerObject> in_human_infos;
|
|
||||||
);
|
|
||||||
|
|
||||||
auto on_enter =
|
|
||||||
[this, context] (Creature* hum)
|
|
||||||
{
|
|
||||||
if (context->in_human_infos.find(hum->GetUniId()) != context->in_human_infos.end()) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
InnerObject o;
|
|
||||||
o.c = hum->GetWeakPtrRef();
|
|
||||||
|
|
||||||
if (owner->team_id == hum->team_id) {
|
|
||||||
for (int buff_id : meta->_buff_param3_int_list) {
|
|
||||||
o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int buff_id : meta->_buff_param4_int_list) {
|
|
||||||
o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context->in_human_infos[hum->GetUniId()] = o;
|
|
||||||
context->in_human_infos[hum->GetUniId()].OnEnter();
|
|
||||||
};
|
|
||||||
auto on_stay =
|
|
||||||
[this, context] (Creature* hum)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
auto on_leave =
|
|
||||||
[this, context] (Creature* hum)
|
|
||||||
{
|
|
||||||
auto itr = context->in_human_infos.find(hum->GetUniId());
|
|
||||||
if (itr == context->in_human_infos.end()) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
for (int buff_uniid : itr->second.buff_uniids) {
|
|
||||||
hum->RemoveBuffByUniId(buff_uniid);
|
|
||||||
}
|
|
||||||
itr->second.OnLeave();
|
|
||||||
};
|
|
||||||
auto check_cb =
|
|
||||||
[this, context, on_enter, on_stay, on_leave]
|
|
||||||
()
|
|
||||||
{
|
|
||||||
float range = meta->GetBuffParam2(this);
|
|
||||||
std::set<Creature*> hit_humans;
|
|
||||||
owner->room->TraverseAliveHumanList
|
|
||||||
(
|
|
||||||
[this, range, &hit_humans] (Human* hum) mutable
|
|
||||||
{
|
|
||||||
if (Collision::CheckCC(owner, owner->GetRadius(),
|
|
||||||
hum, range)) {
|
|
||||||
hit_humans.insert(hum);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
std::vector<Human*> leave_humans;
|
|
||||||
for (auto& pair : context->in_human_infos) {
|
|
||||||
if (hit_humans.find(pair.second.c.Get()) == hit_humans.end()) {
|
|
||||||
on_leave(pair.second.c.Get()->AsHuman());
|
|
||||||
leave_humans.push_back(pair.second.c.Get()->AsHuman());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (Human* hum : leave_humans) {
|
|
||||||
context->in_human_infos.erase(hum->GetUniId());
|
|
||||||
}
|
|
||||||
for (Creature* hum : hit_humans) {
|
|
||||||
if (context->in_human_infos.find(hum->GetUniId()) ==
|
|
||||||
context->in_human_infos.end()) {
|
|
||||||
on_enter(hum);
|
|
||||||
on_stay(hum);
|
|
||||||
} else {
|
|
||||||
on_stay(hum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
auto check_timer = owner->room->xtimer.SetIntervalWpEx
|
|
||||||
(
|
|
||||||
SERVER_FRAME_RATE,
|
|
||||||
[this, context, on_enter, on_stay, on_leave, check_cb]
|
|
||||||
(int event, const a8::Args* args) mutable
|
|
||||||
{
|
|
||||||
if (a8::TIMER_EXEC_EVENT == event) {
|
|
||||||
check_cb();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
&owner->xtimer_attacher);
|
|
||||||
auto clear_func =
|
|
||||||
[this, context, check_timer] () mutable
|
|
||||||
{
|
|
||||||
if (!check_timer.expired()) {
|
|
||||||
owner->room->xtimer.Delete(check_timer);
|
|
||||||
}
|
|
||||||
for (auto& pair : context->in_human_infos) {
|
|
||||||
for (int buff_uniid : pair.second.buff_uniids) {
|
|
||||||
if (pair.second.c.Get()) {
|
|
||||||
pair.second.c.Get()->RemoveBuffByUniId(buff_uniid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context->in_human_infos.clear();
|
|
||||||
};
|
|
||||||
{
|
|
||||||
event_handlers_.push_back(owner->GetTrigger()->AddListener
|
|
||||||
(
|
|
||||||
kDieEvent,
|
|
||||||
[this, clear_func] (const a8::Args& args) mutable
|
|
||||||
{
|
|
||||||
clear_func();
|
|
||||||
}
|
|
||||||
));
|
|
||||||
deactivate_cb_ =
|
|
||||||
[this, clear_func] () mutable
|
|
||||||
{
|
|
||||||
clear_func();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallFuncBuff::PlayFlyEffect()
|
void CallFuncBuff::PlayFlyEffect()
|
||||||
@ -1215,3 +1084,156 @@ void CallFuncBuff::LispEval()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CallFuncBuff::SpecCenterRangeHoldBuff()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallFuncBuff::InternalRangeHoldBuff(std::function<bool(glm::vec3&)> get_center_func)
|
||||||
|
{
|
||||||
|
if (owner->dead) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct InnerObject
|
||||||
|
{
|
||||||
|
CreatureWeakPtr c;
|
||||||
|
std::vector<int> buff_uniids;
|
||||||
|
|
||||||
|
void OnEnter()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLeave()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
auto context = A8_MAKE_ANON_STRUCT_SHARED
|
||||||
|
(
|
||||||
|
std::map<int, InnerObject> in_human_infos;
|
||||||
|
);
|
||||||
|
|
||||||
|
auto on_enter =
|
||||||
|
[this, context] (Creature* hum)
|
||||||
|
{
|
||||||
|
if (context->in_human_infos.find(hum->GetUniId()) != context->in_human_infos.end()) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
InnerObject o;
|
||||||
|
o.c = hum->GetWeakPtrRef();
|
||||||
|
|
||||||
|
if (owner->team_id == hum->team_id) {
|
||||||
|
for (int buff_id : meta->_buff_param3_int_list) {
|
||||||
|
o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int buff_id : meta->_buff_param4_int_list) {
|
||||||
|
o.buff_uniids.push_back(hum->TryAddBuff(GetCaster().Get(), buff_id, skill_meta));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context->in_human_infos[hum->GetUniId()] = o;
|
||||||
|
context->in_human_infos[hum->GetUniId()].OnEnter();
|
||||||
|
};
|
||||||
|
auto on_stay =
|
||||||
|
[this, context] (Creature* hum)
|
||||||
|
{
|
||||||
|
};
|
||||||
|
auto on_leave =
|
||||||
|
[this, context] (Creature* hum)
|
||||||
|
{
|
||||||
|
auto itr = context->in_human_infos.find(hum->GetUniId());
|
||||||
|
if (itr == context->in_human_infos.end()) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
for (int buff_uniid : itr->second.buff_uniids) {
|
||||||
|
hum->RemoveBuffByUniId(buff_uniid);
|
||||||
|
}
|
||||||
|
itr->second.OnLeave();
|
||||||
|
};
|
||||||
|
auto check_cb =
|
||||||
|
[this, context, on_enter, on_stay, on_leave, get_center_func]
|
||||||
|
()
|
||||||
|
{
|
||||||
|
float range = meta->GetBuffParam2(this);
|
||||||
|
std::set<Creature*> hit_humans;
|
||||||
|
owner->room->TraverseAliveHumanList
|
||||||
|
(
|
||||||
|
[this, range, &hit_humans, &get_center_func] (Human* hum) mutable
|
||||||
|
{
|
||||||
|
glm::vec3 center;
|
||||||
|
if (get_center_func(center)) {
|
||||||
|
if (a8::IntersectCylinderCylinder
|
||||||
|
(
|
||||||
|
center, owner->GetRadius(), 10,
|
||||||
|
hum->GetPos().ToGlmVec3(), range, 10
|
||||||
|
)) {
|
||||||
|
hit_humans.insert(hum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
std::vector<Human*> leave_humans;
|
||||||
|
for (auto& pair : context->in_human_infos) {
|
||||||
|
if (hit_humans.find(pair.second.c.Get()) == hit_humans.end()) {
|
||||||
|
on_leave(pair.second.c.Get()->AsHuman());
|
||||||
|
leave_humans.push_back(pair.second.c.Get()->AsHuman());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Human* hum : leave_humans) {
|
||||||
|
context->in_human_infos.erase(hum->GetUniId());
|
||||||
|
}
|
||||||
|
for (Creature* hum : hit_humans) {
|
||||||
|
if (context->in_human_infos.find(hum->GetUniId()) ==
|
||||||
|
context->in_human_infos.end()) {
|
||||||
|
on_enter(hum);
|
||||||
|
on_stay(hum);
|
||||||
|
} else {
|
||||||
|
on_stay(hum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto check_timer = owner->room->xtimer.SetIntervalWpEx
|
||||||
|
(
|
||||||
|
SERVER_FRAME_RATE,
|
||||||
|
[this, context, on_enter, on_stay, on_leave, check_cb]
|
||||||
|
(int event, const a8::Args* args) mutable
|
||||||
|
{
|
||||||
|
if (a8::TIMER_EXEC_EVENT == event) {
|
||||||
|
check_cb();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&owner->xtimer_attacher);
|
||||||
|
auto clear_func =
|
||||||
|
[this, context, check_timer] () mutable
|
||||||
|
{
|
||||||
|
if (!check_timer.expired()) {
|
||||||
|
owner->room->xtimer.Delete(check_timer);
|
||||||
|
}
|
||||||
|
for (auto& pair : context->in_human_infos) {
|
||||||
|
for (int buff_uniid : pair.second.buff_uniids) {
|
||||||
|
if (pair.second.c.Get()) {
|
||||||
|
pair.second.c.Get()->RemoveBuffByUniId(buff_uniid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context->in_human_infos.clear();
|
||||||
|
};
|
||||||
|
{
|
||||||
|
event_handlers_.push_back(owner->GetTrigger()->AddListener
|
||||||
|
(
|
||||||
|
kDieEvent,
|
||||||
|
[this, clear_func] (const a8::Args& args) mutable
|
||||||
|
{
|
||||||
|
clear_func();
|
||||||
|
}
|
||||||
|
));
|
||||||
|
deactivate_cb_ =
|
||||||
|
[this, clear_func] () mutable
|
||||||
|
{
|
||||||
|
clear_func();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ A8_DECLARE_CLASS_ENUM(BuffCallFunc_e, int,
|
|||||||
kRangeHoldBuff = 34,
|
kRangeHoldBuff = 34,
|
||||||
kPlayFlyEffect = 35,
|
kPlayFlyEffect = 35,
|
||||||
kLispEval = 36,
|
kLispEval = 36,
|
||||||
|
kSpecCenterRangeHoldBuff = 37,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ class CallFuncBuff : public Buff
|
|||||||
void RangeHoldBuff();
|
void RangeHoldBuff();
|
||||||
void PlayFlyEffect();
|
void PlayFlyEffect();
|
||||||
void LispEval();
|
void LispEval();
|
||||||
|
void SpecCenterRangeHoldBuff();
|
||||||
|
|
||||||
|
void InternalRangeHoldBuff(std::function<bool(glm::vec3&)> get_center_func);
|
||||||
|
|
||||||
float hold_param2_ = 0.0;
|
float hold_param2_ = 0.0;
|
||||||
Weapon* hold_weapon_ = nullptr;
|
Weapon* hold_weapon_ = nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user