736 lines
22 KiB
C++
736 lines
22 KiB
C++
#include "precompile.h"
|
|
|
|
#include <a8/list.h>
|
|
|
|
#include "trigger.h"
|
|
#include "creature.h"
|
|
#include "skill.h"
|
|
#include "room.h"
|
|
#include "human.h"
|
|
#include "car.h"
|
|
#include "bullet.h"
|
|
#include "buff.h"
|
|
#include "stats.h"
|
|
#include "team.h"
|
|
#include "perf.h"
|
|
|
|
#include "mt/Buff.h"
|
|
#include "mt/Skill.h"
|
|
#include "mt/SkillNumber.h"
|
|
#include "mt/Equip.h"
|
|
|
|
class EventHandler : public std::enable_shared_from_this<EventHandler>
|
|
{
|
|
public:
|
|
a8::CommonCbProc cb;
|
|
list_head entry;
|
|
std::shared_ptr<EventHandler> holder;
|
|
|
|
EventHandler()
|
|
{
|
|
++Perf::Instance()->event_handler_num;
|
|
}
|
|
|
|
~EventHandler()
|
|
{
|
|
--Perf::Instance()->event_handler_num;
|
|
}
|
|
|
|
};
|
|
|
|
void Trigger::Init()
|
|
{
|
|
INIT_LIST_HEAD(&delay_del_handles);
|
|
}
|
|
|
|
void Trigger::UnInit()
|
|
{
|
|
for (auto& pair : listeners_hash_) {
|
|
while (!list_empty(&pair.second)) {
|
|
EventHandler* e = list_first_entry(&pair.second,
|
|
EventHandler,
|
|
entry);
|
|
list_del_init(&e->entry);
|
|
#ifdef MYDEBUG
|
|
if (e->holder.use_count() > 1) {
|
|
A8_ABORT();
|
|
}
|
|
#endif
|
|
e->holder = nullptr;
|
|
}
|
|
}
|
|
ClearDelayDelHandlers();
|
|
}
|
|
|
|
void Trigger::TakeonWeapon(Weapon* old_weapon, Weapon* new_weapon)
|
|
{
|
|
{
|
|
const mt::Equip* weapon_meta = old_weapon ? old_weapon->meta : nullptr;
|
|
if (weapon_meta) {
|
|
for (int cond = kEventBuffUpdateWeaponId; cond <= kEventBuffUpdateWeaponType; cond++) {
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond, weapon_meta] (Buff* buff, bool& stop)
|
|
{
|
|
if (weapon_meta->Match((EventAddBuff_e)cond,
|
|
buff->meta->_int_buff_param3,
|
|
buff->meta->_int_buff_param5)) {
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case kWeaponOptTakeoff:
|
|
case kWeaponOptKeep:
|
|
{
|
|
RemoveBuffs(buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
{
|
|
const mt::Equip* weapon_meta = new_weapon ? new_weapon->meta : nullptr;
|
|
if (weapon_meta) {
|
|
for (int cond = kEventBuffUpdateWeaponId; cond <= kEventBuffUpdateWeaponType; cond++) {
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond, weapon_meta] (Buff* buff, bool& stop)
|
|
{
|
|
if (weapon_meta->Match((EventAddBuff_e)cond,
|
|
buff->meta->_int_buff_param3,
|
|
buff->meta->_int_buff_param5)) {
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case kWeaponOptTakeon:
|
|
{
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
case kWeaponOptKeep:
|
|
{
|
|
TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
DispatchEvent(kTakeonWeaponEvent, {old_weapon, new_weapon});
|
|
}
|
|
|
|
void Trigger::Shot(const mt::Equip* weapon_meta)
|
|
{
|
|
for (int cond = kEventBuffShotWeaponId; cond <= kEventBuffShotWeaponType; ++cond) {
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond, weapon_meta] (Buff* buff, bool& stop)
|
|
{
|
|
if (weapon_meta->Match((EventAddBuff_e)cond,
|
|
buff->meta->_int_buff_param2,
|
|
buff->meta->_int_buff_param5)) {
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
});
|
|
}
|
|
{
|
|
Buff* buff = owner_->GetBuffByEffectId(kBET_MachineGun);
|
|
if (buff && buff->meta->_int_buff_param2 == 1) {
|
|
auto buff_uniid = buff->buff_uniid;
|
|
owner_->room->xtimer.SetTimeoutEx
|
|
(buff->meta->_int_buff_param3 / FRAME_RATE_MS,
|
|
[this, buff_uniid] (int event, const a8::Args* args)
|
|
{
|
|
if (a8::TIMER_EXEC_EVENT == event) {
|
|
owner_->RemoveBuffByUniId(buff_uniid);
|
|
}
|
|
},
|
|
&owner_->xtimer_attacher);
|
|
}
|
|
}
|
|
DispatchEvent(kShotEvent, {});
|
|
}
|
|
|
|
void Trigger::Kill(Creature* target, int weapon_id)
|
|
{
|
|
if (owner_->IsHuman() && target->IsHuman()) {
|
|
Human* owner_hum = owner_->AsHuman();
|
|
Human* target_hum = target->AsHuman();
|
|
owner_hum->CalcAssists(target_hum);
|
|
if (target->GetUniId() != owner_->GetUniId()) {
|
|
if (owner_->room->IsMobaModeRoom()) {
|
|
if (!owner_->room->GetVictoryTeam()) {
|
|
owner_->AsHuman()->stats->kills++;
|
|
owner_->AsHuman()->GetTeam()->IncKillCount();
|
|
}
|
|
} else {
|
|
owner_->AsHuman()->stats->kills++;
|
|
owner_->AsHuman()->GetTeam()->IncKillCount();
|
|
}
|
|
}
|
|
owner_->AsHuman()->stats->last_kill_frameno = owner_->room->GetFrameNo();
|
|
owner_->AsHuman()->kill_humans.insert(target->AsHuman());
|
|
owner_->AsHuman()->SyncAroundPlayers(__FILE__, __LINE__, __func__);
|
|
}
|
|
if (owner_->IsCar()) {
|
|
owner_->AsCar()->OnKillTarget(target);
|
|
}
|
|
++kill_num_;
|
|
TraverseCondBuffs
|
|
(kEventBuffKillTarget,
|
|
[this] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff->meta->_int_buff_param2 > 0 && (kill_num_ % buff->meta->_int_buff_param2) == 0) {
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
});
|
|
DispatchEvent(kKillEvent, {kill_num_, target, weapon_id});
|
|
}
|
|
|
|
void Trigger::UseItemAction(int slot_id)
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventBuffEatDrug,
|
|
[this, slot_id] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff->meta->_buff_param2_int_set.find(slot_id) != buff->meta->_buff_param2_int_set.end()) {
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
});
|
|
}
|
|
|
|
void Trigger::UseSkill(Skill* skill)
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventBuffUseSkill,
|
|
[this, skill] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff->meta->_int_buff_param2 == skill->GetBaseSkillMeta()->skill_id()) {
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
});
|
|
DispatchEvent(kUseSkillEvent, {skill});
|
|
}
|
|
|
|
void Trigger::HpChg()
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventBuffHp,
|
|
[this] (Buff* buff, bool& stop)
|
|
{
|
|
bool match = false;
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case kHpOptLeAbs:
|
|
{
|
|
match = owner_->GetHP() < buff->meta->GetBuffParam3(buff);
|
|
}
|
|
break;
|
|
case kHpOptLeRate:
|
|
{
|
|
//match = (owner_->GetHP() / owner_->GetMaxHP() * 100) < buff->meta->_int_param3;
|
|
match = owner_->GetHP() / owner_->GetMaxHP() < buff->meta->GetBuffParam3(buff);
|
|
}
|
|
break;
|
|
case kHpOptGeAbs:
|
|
{
|
|
match = owner_->GetHP() > buff->meta->GetBuffParam3(buff);
|
|
}
|
|
break;
|
|
case kHpOptGeRate:
|
|
{
|
|
//match = (owner_->GetHP() / owner_->GetMaxHP() * 100) > buff->meta->_int_param3;
|
|
match = owner_->GetHP() / owner_->GetMaxHP() > buff->meta->GetBuffParam3(buff);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
#if 1
|
|
if (match) {
|
|
TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
#else
|
|
if (match) {
|
|
TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
} else {
|
|
RemoveBuffs(buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
#endif
|
|
});
|
|
DispatchEvent(kHpChgEvent, {});
|
|
}
|
|
|
|
void Trigger::ReceiveDmg()
|
|
{
|
|
TriggeCondBuffAll(kEventBuffReceiveDmg);
|
|
DispatchEvent(kReceiveDmgEvent, {});
|
|
}
|
|
|
|
void Trigger::PreDie(int killer_id, int weapon_id)
|
|
{
|
|
DispatchEvent(kPreDieEvent, {killer_id, weapon_id});
|
|
}
|
|
|
|
void Trigger::Die(int killer_id, int weapon_id)
|
|
{
|
|
{
|
|
std::vector<int> list;
|
|
owner_->TraverseBuff
|
|
(
|
|
[&list] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff->meta->dead_remove()) {
|
|
list.push_back(buff->buff_uniid);
|
|
}
|
|
});
|
|
for (int buff_uniid : list) {
|
|
owner_->RemoveBuffByUniId(buff_uniid);
|
|
}
|
|
}
|
|
{
|
|
if (owner_->skill_hold_skill_id != 0) {
|
|
owner_->ClearSkillHoldState();
|
|
}
|
|
}
|
|
Creature* killer = owner_->room->GetCreatureByUniId(killer_id);
|
|
TraverseCondBuffs
|
|
(kEventBuffDid,
|
|
[this, killer, killer_id] (Buff* buff, bool& stop)
|
|
{
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case 0:
|
|
{
|
|
auto buff_vars = std::make_shared<std::vector<float>>();
|
|
buff_vars->push_back(killer_id);
|
|
buff_vars->push_back(killer ? killer->team_id : 0);
|
|
//AddBuffs(buff, kEventBuffDid, buff->meta->_buff_param4_int_list);
|
|
AddBuffs(buff, kEventBuffDid, buff->meta->_buff_param4_int_list, buff_vars);
|
|
}
|
|
break;
|
|
case 1:
|
|
{
|
|
if (killer && killer->IsHuman()) {
|
|
auto buff_vars = std::make_shared<std::vector<float>>();
|
|
buff_vars->push_back(killer->GetUniId());
|
|
buff_vars->push_back(killer->GetTeam()->GetTeamId());
|
|
AddBuffs(buff, kEventBuffDid, buff->meta->_buff_param4_int_list, buff_vars);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
DispatchEvent(kDieEvent, {killer_id, weapon_id});
|
|
}
|
|
|
|
bool Trigger::HasCondBuff(int cond)
|
|
{
|
|
if (!IsValidEventBuff(cond)) {
|
|
return false;
|
|
}
|
|
list_head* pos = nullptr;
|
|
list_head* next = nullptr;
|
|
list_head* head = &owner_->cond_buffs_[cond];
|
|
list_for_each_safe(pos, next, head) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Trigger::TraverseCondBuffs(int cond, std::function<void (Buff*, bool&)> func)
|
|
{
|
|
if (!IsValidEventBuff(cond)) {
|
|
A8_ABORT();
|
|
}
|
|
if (!owner_->room->BattleStarted()) {
|
|
return;
|
|
}
|
|
|
|
list_head* pos = nullptr;
|
|
list_head* next = nullptr;
|
|
list_head* head = &owner_->cond_buffs_[cond];
|
|
RemoveBuffCbConext cb;
|
|
cb.next = &next;
|
|
INIT_LIST_HEAD(&cb.entry);
|
|
list_for_each_safe(pos, next, head) {
|
|
if (list_empty(next)) {
|
|
Buff *next_buff = list_entry(next, Buff, cond_entry);
|
|
list_add_tail(&cb.entry, &next_buff->on_remove_contexts);
|
|
}
|
|
Buff *curr_buff = list_entry(pos, Buff, cond_entry);
|
|
bool stop = false;
|
|
func(curr_buff, stop);
|
|
if (!list_empty(&cb.entry)) {
|
|
list_del_init(&cb.entry);
|
|
}
|
|
if (stop) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Trigger::TriggeCondBuffAll(int cond)
|
|
{
|
|
if (!owner_->room->BattleStarted()) {
|
|
return;
|
|
}
|
|
|
|
std::shared_ptr<Ability> old_context_ability = owner_->context_ability;
|
|
glm::vec3 old_context_dir = owner_->context_dir;
|
|
Position old_context_pos = owner_->context_pos;
|
|
owner_->context_dir = owner_->GetAttackDir();
|
|
owner_->context_pos = owner_->GetPos();
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond] (Buff* buff, bool& stop)
|
|
{
|
|
AddBuffs(buff, cond, buff->meta->_buff_param4_int_list);
|
|
});
|
|
owner_->context_dir = old_context_dir;
|
|
owner_->context_pos = old_context_pos;
|
|
owner_->context_ability = old_context_ability;
|
|
}
|
|
|
|
void Trigger::ActiveBuff(const mt::Buff* buff_meta)
|
|
{
|
|
for (int cond = kEventBuffUpdateBuffId; cond <= kEventBuffUpdateBuffEffect; ++cond) {
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond, buff_meta] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff_meta->Match((EventAddBuff_e)cond, buff->meta->_int_buff_param3)) {
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case kBuffOptActive:
|
|
{
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
case kBuffOptKeep:
|
|
{
|
|
TryAddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
void Trigger::DeactiveBuff(const mt::Buff* buff_meta)
|
|
{
|
|
for (int cond = kEventBuffUpdateBuffId; cond <= kEventBuffUpdateBuffEffect; ++cond) {
|
|
TraverseCondBuffs
|
|
(cond,
|
|
[this, cond, buff_meta] (Buff* buff, bool& stop)
|
|
{
|
|
if (buff_meta->Match((EventAddBuff_e)cond, buff->meta->_int_buff_param3)) {
|
|
switch (buff->meta->_int_buff_param2) {
|
|
case kBuffOptDeactive:
|
|
case kBuffOptKeep:
|
|
{
|
|
RemoveBuffs(buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
void Trigger::TryAddBuffs(Buff* buff, int cond, const std::vector<int>& buffids,
|
|
std::shared_ptr<std::vector<float>> buff_vars)
|
|
{
|
|
for (int buffid : buffids) {
|
|
if (!owner_->GetBuffById(buffid)) {
|
|
owner_->TryAddBuff(buff->GetCaster().Get(), buffid, buff->skill_meta, nullptr, buff_vars);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Trigger::AddBuffs(Buff* buff, int cond, const std::vector<int>& buffids,
|
|
std::shared_ptr<std::vector<float>> buff_vars)
|
|
{
|
|
for (int buffid : buffids) {
|
|
owner_->TryAddBuff(buff->GetCaster().Get(), buffid, buff->skill_meta, nullptr, buff_vars);
|
|
}
|
|
}
|
|
|
|
void Trigger::RemoveBuffs(int cond, const std::vector<int>& buffids)
|
|
{
|
|
for (int buffid : buffids) {
|
|
owner_->RemoveBuffById(buffid);
|
|
}
|
|
}
|
|
|
|
std::weak_ptr<EventHandler> Trigger::AddListener(int event_id, a8::CommonCbProc cb)
|
|
{
|
|
#ifdef MYDEBUG
|
|
if (owner_->room->IsDestorying()) {
|
|
A8_ABORT();
|
|
}
|
|
#endif
|
|
auto itr = listeners_hash_.find(event_id);
|
|
if (itr == listeners_hash_.end()) {
|
|
listeners_hash_[event_id] = list_head();
|
|
itr = listeners_hash_.find(event_id);
|
|
INIT_LIST_HEAD(&itr->second);
|
|
}
|
|
auto p = std::make_shared<EventHandler>();
|
|
p->cb = cb;
|
|
list_add_tail(&p->entry, &itr->second);
|
|
p->holder = p;
|
|
return p;
|
|
}
|
|
|
|
void Trigger::RemoveEventHandler(std::weak_ptr<EventHandler> handler)
|
|
{
|
|
if (!handler.expired()) {
|
|
auto p = handler.lock();
|
|
p->cb = nullptr;
|
|
list_del_init(&p->entry);
|
|
list_add_tail(&p->entry, &delay_del_handles);
|
|
}
|
|
}
|
|
|
|
void Trigger::RemoveEventHandlers(std::vector<std::weak_ptr<EventHandler>> handlers)
|
|
{
|
|
for (auto handler : handlers) {
|
|
RemoveEventHandler(handler);
|
|
}
|
|
}
|
|
|
|
void Trigger::DispatchEvent(int event_id, const std::vector<std::any>& param)
|
|
{
|
|
auto itr = listeners_hash_.find(event_id);
|
|
if (itr != listeners_hash_.end()) {
|
|
struct EventHandler *handle = nullptr, *tmp = nullptr;
|
|
list_for_each_entry_safe(handle, tmp, &itr->second, entry) {
|
|
handle->cb(param);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Trigger::BulletHit(IBullet* bullet, Creature* target)
|
|
{
|
|
if (bullet->GetSender().Get()) {
|
|
if (bullet->GetSender().Get()->IsPlayer()) {
|
|
int i = 0;
|
|
}
|
|
bullet->GetSender().Get()->GetTrigger()->DispatchEvent(kBulletHitEvent, {bullet, target});
|
|
}
|
|
}
|
|
|
|
void Trigger::ShieldDestory()
|
|
{
|
|
DispatchEvent(kShieldDestoryEvent, {});
|
|
}
|
|
|
|
void Trigger::StartRescue(Human* target)
|
|
{
|
|
DispatchEvent(kStartRescueEvent, {target});
|
|
}
|
|
|
|
void Trigger::EndRescue(Human* target)
|
|
{
|
|
DispatchEvent(kEndRescueEvent, {target});
|
|
}
|
|
|
|
void Trigger::YsBuffRemove(Buff* buff)
|
|
{
|
|
DispatchEvent(kYsRemoveEvent, {buff});
|
|
}
|
|
|
|
void Trigger::SkillBulletPreCreate(int delay_time, const mt::Skill* skill_meta)
|
|
{
|
|
DispatchEvent(kSkillBulletPreCreateEvent, {delay_time, skill_meta});
|
|
}
|
|
|
|
void Trigger::FlyHookCreate(Bullet* bullet)
|
|
{
|
|
DispatchEvent(kFlyHookCreateEvent, {bullet});
|
|
}
|
|
|
|
void Trigger::FlyHookDestory()
|
|
{
|
|
DispatchEvent(kFlyHookDestoryEvent, {});
|
|
}
|
|
|
|
void Trigger::BulletHitBuff(Bullet* bullet)
|
|
{
|
|
DispatchEvent(kTriggerBulletHitBuffEvent, {bullet});
|
|
}
|
|
|
|
void Trigger::Attacked(Creature* sender)
|
|
{
|
|
DispatchEvent(kAttacked, {sender});
|
|
sender->GetTrigger()->DispatchEvent(kAttackTargetEvent, {owner_});
|
|
}
|
|
|
|
void Trigger::DmgOut(Creature* target, float dmg)
|
|
{
|
|
DispatchEvent(kDmgOutEvent, {target, dmg});
|
|
if (HasCondBuff(kEventBuffDmgOut)) {
|
|
TraverseCondBuffs
|
|
(kEventBuffDmgOut,
|
|
[this, dmg] (Buff* buff, bool& stop)
|
|
{
|
|
auto buff_vars = std::make_shared<std::vector<float>>();
|
|
buff_vars->push_back(dmg);
|
|
AddBuffs(buff, buff->meta->_int_buff_param1, buff->meta->_buff_param4_int_list, buff_vars);
|
|
});
|
|
}
|
|
}
|
|
|
|
void Trigger::BulletBlock(IBullet* bullet, const glm::vec3& pos)
|
|
{
|
|
DispatchEvent(kBulletBlockEvent, {bullet, pos});
|
|
}
|
|
|
|
void Trigger::StartJump(Creature* sender)
|
|
{
|
|
DispatchEvent(kStartJump, {});
|
|
}
|
|
|
|
void Trigger::EndJump(Creature* sender)
|
|
{
|
|
DispatchEvent(kEndJump, {});
|
|
}
|
|
|
|
void Trigger::BulletKill(IBullet* bullet, Creature* target)
|
|
{
|
|
DispatchEvent(kBulletKill, {bullet, target});
|
|
}
|
|
|
|
void Trigger::Downed()
|
|
{
|
|
DispatchEvent(kDownedEvent, {});
|
|
}
|
|
|
|
void Trigger::StartReload()
|
|
{
|
|
DispatchEvent(kStartReloadEvent, {});
|
|
}
|
|
|
|
void Trigger::EndReload()
|
|
{
|
|
DispatchEvent(kEndReloadEvent, {});
|
|
}
|
|
|
|
void Trigger::UpdateEnergyShield(int value, int new_time)
|
|
{
|
|
DispatchEvent(kUpdateEnergyShieldEvent, {value, new_time});
|
|
}
|
|
|
|
void Trigger::DestoryEnergyShield()
|
|
{
|
|
DispatchEvent(kDestoryEnergyShieldEvent, {});
|
|
}
|
|
|
|
void Trigger::EnterCrazeMode()
|
|
{
|
|
if (!owner_->dead) {
|
|
DispatchEvent(kCrazeModeEvent, {});
|
|
}
|
|
}
|
|
|
|
void Trigger::Update()
|
|
{
|
|
ClearDelayDelHandlers();
|
|
}
|
|
|
|
void Trigger::ClearDelayDelHandlers()
|
|
{
|
|
while (!list_empty(&delay_del_handles)) {
|
|
EventHandler* e = list_first_entry(&delay_del_handles,
|
|
EventHandler,
|
|
entry);
|
|
list_del_init(&e->entry);
|
|
#ifdef MYDEBUG
|
|
if (e->holder.use_count() > 1) {
|
|
A8_ABORT();
|
|
}
|
|
#endif
|
|
e->holder = nullptr;
|
|
}
|
|
}
|
|
|
|
void Trigger::EnterBattleMode()
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventEnterBattleMode,
|
|
[this] (Buff* buff, bool& stop)
|
|
{
|
|
for (int buff_id : buff->meta->_buff_param4_int_list) {
|
|
if (buff_id > 0) {
|
|
owner_->TryAddBuff(owner_, buff_id, buff->skill_meta);
|
|
} else {
|
|
owner_->ClearBuffById(-buff_id);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
void Trigger::LeaveBattleMode()
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventLeaveBattleMode,
|
|
[this] (Buff* buff, bool& stop)
|
|
{
|
|
for (int buff_id : buff->meta->_buff_param4_int_list) {
|
|
if (buff_id > 0) {
|
|
owner_->TryAddBuff(owner_, buff_id, buff->skill_meta);
|
|
} else {
|
|
owner_->ClearBuffById(-buff_id);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
void Trigger::BeAttack(int attacker_id)
|
|
{
|
|
TraverseCondBuffs
|
|
(kEventBeAttack,
|
|
[this] (Buff* buff, bool& stop)
|
|
{
|
|
for (int buff_id : buff->meta->_buff_param4_int_list) {
|
|
if (buff_id > 0) {
|
|
owner_->TryAddBuff(owner_, buff_id, buff->skill_meta);
|
|
} else {
|
|
owner_->ClearBuffById(-buff_id);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
void Trigger::BulletDmgStart(Creature* target)
|
|
{
|
|
DispatchEvent(kBulletDmgStartEvent, {target});
|
|
}
|
|
|
|
void Trigger::BulletDmgEnd(Creature* target)
|
|
{
|
|
DispatchEvent(kBulletDmgEndEvent, {target});
|
|
}
|