aozhiwei fea2976b0f 1
2023-03-18 11:10:10 +08:00

217 lines
6.1 KiB
C++

#include "precompile.h"
#include "buff/cond_add.h"
#include "creature.h"
#include "room.h"
#include "mt/Buff.h"
/*
装备武器
子弹命中
击杀
子弹结束
*/
void CondAddBuff::Activate()
{
switch ((CondAddBuff_e)meta->_int_buff_param1) {
case CondAddBuff_e::kBulletHit:
{
ProcBulletHit();
}
break;
case CondAddBuff_e::kBulletKill:
{
ProcBulletKill();
}
break;
case CondAddBuff_e::kBulletEnd:
{
ProcBulletEnd();
}
break;
case CondAddBuff_e::kDisengageBattle:
{
ProcDisengageBattle();
}
break;
case CondAddBuff_e::kLimitTimeKillTarget:
{
ProcLimitTimeKillTarget();
}
break;
default:
{
}
break;
}
}
void CondAddBuff::Deactivate()
{
for (auto handler : handlers_) {
if (!handler.expired()) {
owner->GetTrigger()->RemoveEventHandler(handler);
}
}
handlers_.clear();
}
void CondAddBuff::ProcBulletHit()
{
const bool is_same_target = meta->_int_buff_param5 ? true : false;
const float interval_time = meta->_buff_param6 < 0.01 ? 9999999 : meta->_buff_param6;
const int hit_times = meta->_int_buff_param2;
auto context = A8_MAKE_ANON_STRUCT_SHARED
(
int last_hit_target_id = 0;
int hited_times = 0;
long long last_hit_frameno = 0;
);
handlers_.push_back
(
owner->GetTrigger()->AddListener
(
kBulletHitEvent,
[this, context, is_same_target, interval_time, hit_times]
(const a8::Args& args)
{
IBullet* bullet = args.Get<IBullet*>(0);
Creature* c = args.Get<Creature*>(1);
if (context->last_hit_frameno > 0 &&
c->room->GetFrameNo() - context->last_hit_frameno > interval_time * SERVER_FRAME_RATE) {
context->hited_times = 0;
}
if (is_same_target) {
if (context->last_hit_target_id != c->GetUniId()) {
context->hited_times = 0;
}
}
context->last_hit_target_id = c->GetUniId();
++context->hited_times;
context->last_hit_frameno = c->room->GetFrameNo();
if (context->hited_times >= hit_times) {
{
if (!c->dead) {
c->TryAddBuff(owner, meta->_int_buff_param3, skill_meta);
}
if (!owner->dead) {
owner->TryAddBuff(owner, meta->_int_buff_param4, skill_meta);
}
}
context->last_hit_target_id = 0;
context->hited_times = 0;
context->last_hit_frameno = 0;
}
})
);
}
void CondAddBuff::ProcBulletKill()
{
auto context = A8_MAKE_ANON_STRUCT_SHARED
(
);
handlers_.push_back
(
owner->GetTrigger()->AddListener
(
kBulletKill,
[this, context]
(const a8::Args& args)
{
IBullet* bullet = args.Get<IBullet*>(0);
Creature* c = args.Get<Creature*>(0);
if (!owner->dead) {
owner->TryAddBuff(owner, meta->_int_buff_param4, skill_meta);
}
})
);
}
void CondAddBuff::ProcBulletEnd()
{
}
void CondAddBuff::ProcDisengageBattle()
{
const float disengate_time = meta->GetBuffParam2(this);
auto context = A8_MAKE_ANON_STRUCT_SHARED
(
std::vector<std::tuple<int, int>> hold_buff_list;
long long last_check_frameno = 0;
);
a8::XTimerWp timer = owner->room->xtimer.SetIntervalWpEx
(
disengate_time * SERVER_FRAME_RATE,
[this, context] (int event, const a8::Args* args)
{
if (a8::TIMER_EXEC_EVENT == event) {
if (!owner->dead) {
for (int buff_id : meta->_buff_param4_int_list) {
int buff_uniid = owner->TryAddBuff
(
GetCaster().Get(),
buff_id,
skill_meta
);
if (!meta->_buff_param5_int_set.empty()) {
context->hold_buff_list.push_back
(
std::make_tuple(buff_uniid, buff_id)
);
}
}
if (owner->room->GetFrameNo() - context->last_check_frameno > SERVER_FRAME_RATE * 10 &&
!meta->_buff_param5_int_set.empty() &&
context->hold_buff_list.size() > 0) {
for (size_t i = context->hold_buff_list.size() - 1; i >= 0; --i) {
if (!owner->GetBuffByUniId(std::get<0>(context->hold_buff_list[i]))) {
context->hold_buff_list.erase(context->hold_buff_list.begin() + i);
}
}
}
}
}
},
&xtimer_attacher);
auto cb =
[this, timer, context] (const a8::Args& args) mutable
{
if (timer.expired()) {
return;
}
if (!meta->_buff_param5_int_set.empty()) {
for (auto& tuple : context->hold_buff_list) {
if (meta->_buff_param5_int_set.find(std::get<1>(tuple)) !=
meta->_buff_param5_int_set.end()) {
owner->RemoveBuffByUniId(std::get<0>(tuple));
}
}
context->hold_buff_list.clear();
}
owner->room->xtimer.ResetTimer(timer);
};
owner->GetTrigger()->AddListener
(
kReceiveDmgEvent,
cb
);
}
void CondAddBuff::ProcLimitTimeKillTarget()
{
}