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