223 lines
5.7 KiB
C++
223 lines
5.7 KiB
C++
#include "precompile.h"
|
|
|
|
#include "gungrasp.h"
|
|
#include "creature.h"
|
|
#include "battledatacontext.h"
|
|
#include "trigger.h"
|
|
#include "room.h"
|
|
|
|
#include "mt/GraspBuff.h"
|
|
#include "mt/Grasp.h"
|
|
#include "mt/Hero.h"
|
|
|
|
struct GraspBuff
|
|
{
|
|
list_head entry;
|
|
std::tuple<const mt::GraspBuff*, const mt::GraspBuff*> buffs;
|
|
std::function<void()> on_remove;
|
|
a8::Attacher xtimer_attacher;
|
|
|
|
void ProcSignet(GunGrasp* gun_grasp, int count)
|
|
{
|
|
const mt::GraspBuff* buff1_meta = std::get<0>(buffs);
|
|
const mt::GraspBuff* buff2_meta = std::get<1>(buffs);
|
|
if (buff1_meta && buff2_meta) {
|
|
gun_grasp->AddSignet(buff1_meta->graspbuff_id(), count);
|
|
if (buff1_meta) {
|
|
int buff_time = buff1_meta->GetBuffTime(gun_grasp->GetHeroLv());
|
|
if (buff_time < 9999) {
|
|
gun_grasp->GetOwner()->room->xtimer.SetTimeoutEx
|
|
(
|
|
buff_time * SERVER_FRAME_RATE,
|
|
[this, gun_grasp, count, buff1_meta] (int event, const a8::Args* args)
|
|
{
|
|
gun_grasp->RemoveSignet(buff1_meta->graspbuff_id(), count);
|
|
},
|
|
&xtimer_attacher);
|
|
}
|
|
}
|
|
} else {
|
|
}
|
|
}
|
|
|
|
void Active(GunGrasp* gun_grasp)
|
|
{
|
|
std::array<const mt::GraspBuff*, 2> grasp_triggers_ = {std::get<0>(buffs), std::get<1>(buffs)};
|
|
for (auto& buff : grasp_triggers_) {
|
|
if (buff) {
|
|
if (buff->attr_id()) {
|
|
}
|
|
}//end if
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
GunGrasp::GunGrasp(Creature* owner)
|
|
{
|
|
owner_ = owner;
|
|
for (auto& node : grasp_triggers_) {
|
|
INIT_LIST_HEAD(&node);
|
|
}
|
|
}
|
|
|
|
GunGrasp::~GunGrasp()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void GunGrasp::Clear()
|
|
{
|
|
while (!event_listeners_.empty()) {
|
|
owner_->GetTrigger()->RemoveEventHandler(event_listeners_[0]);
|
|
event_listeners_.erase(event_listeners_.begin());
|
|
}
|
|
signet_hash_.clear();
|
|
for (auto& head : grasp_triggers_) {
|
|
while (!list_empty(&head)) {
|
|
GraspBuff* e = list_first_entry(&head,
|
|
GraspBuff,
|
|
entry);
|
|
list_del_init(&e->entry);
|
|
delete e;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GunGrasp::InstallTriggers()
|
|
{
|
|
Clear();
|
|
int hero_quality = 0;
|
|
owner_->GetBattleContext()->GetHeroLvQuality(hero_lv_, hero_quality);
|
|
if (owner_->GetHeroMeta()) {
|
|
mt::GraspBuffs* buffs = mt::Grasp::GetGrasp
|
|
(owner_->GetHeroMeta()->id(),
|
|
hero_lv_,
|
|
owner_->GetCurrWeapon()->weapon_id);
|
|
if (buffs) {
|
|
for (auto& tuple : *buffs) {
|
|
GraspBuff* p = new GraspBuff();
|
|
p->buffs = tuple;
|
|
list_add(&p->entry, &grasp_triggers_[std::get<0>(tuple)->_trigger_type]);
|
|
switch ((GraspBuffTrigger_e)std::get<0>(tuple)->_trigger_type) {
|
|
case GraspBuffTrigger_e::kHit:
|
|
{
|
|
ProcHit(p);
|
|
}
|
|
break;
|
|
case GraspBuffTrigger_e::kKill:
|
|
{
|
|
ProcKill(p);
|
|
}
|
|
break;
|
|
case GraspBuffTrigger_e::kTakeOn:
|
|
{
|
|
ProcTakeOn(p);
|
|
}
|
|
break;
|
|
case GraspBuffTrigger_e::kCond:
|
|
{
|
|
ProcCond(p);
|
|
}
|
|
break;
|
|
case GraspBuffTrigger_e::kHitAndEnd:
|
|
{
|
|
ProcHitAndEnd(p);
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
abort();
|
|
}
|
|
break;
|
|
}//end switch
|
|
}//end for
|
|
}//end if
|
|
}
|
|
}
|
|
|
|
void GunGrasp::ProcHit(GraspBuff* buff)
|
|
{
|
|
event_listeners_.push_back
|
|
(
|
|
owner_->GetTrigger()->AddListener
|
|
(
|
|
kBulletHitEvent,
|
|
[this, buff] (const a8::Args& args)
|
|
{
|
|
buff->ProcSignet(this, 1);
|
|
buff->Active(this);
|
|
})
|
|
);
|
|
}
|
|
|
|
void GunGrasp::ProcKill(GraspBuff* buff)
|
|
{
|
|
event_listeners_.push_back
|
|
(
|
|
owner_->GetTrigger()->AddListener
|
|
(
|
|
kKillEvent,
|
|
[this, buff] (const a8::Args& args)
|
|
{
|
|
buff->ProcSignet(this, 1);
|
|
buff->Active(this);
|
|
})
|
|
);
|
|
}
|
|
|
|
void GunGrasp::ProcTakeOn(GraspBuff* buff)
|
|
{
|
|
buff->ProcSignet(this, 1);
|
|
buff->Active(this);
|
|
}
|
|
|
|
void GunGrasp::ProcCond(GraspBuff* buff)
|
|
{
|
|
|
|
}
|
|
|
|
void GunGrasp::ProcHitAndEnd(GraspBuff* buff)
|
|
{
|
|
event_listeners_.push_back
|
|
(
|
|
owner_->GetTrigger()->AddListener
|
|
(
|
|
kBulletHitEvent,
|
|
[this, buff] (const a8::Args& args)
|
|
{
|
|
buff->ProcSignet(this, 1);
|
|
buff->Active(this);
|
|
})
|
|
);
|
|
}
|
|
|
|
void GunGrasp::AddSignet(int id, int count)
|
|
{
|
|
auto itr = signet_hash_.find(id);
|
|
if (itr != signet_hash_.end()) {
|
|
itr->second += count;
|
|
} else {
|
|
signet_hash_[id] = count;
|
|
}
|
|
}
|
|
|
|
void GunGrasp::RemoveSignet(int id, int count)
|
|
{
|
|
auto itr = signet_hash_.find(id);
|
|
if (itr != signet_hash_.end()) {
|
|
itr->second = std::max(0, itr->second - count);
|
|
}
|
|
}
|
|
|
|
int GunGrasp::GetSignetCount(int id)
|
|
{
|
|
auto itr = signet_hash_.find(id);
|
|
return itr != signet_hash_.end() ? itr->second : 0;
|
|
}
|
|
|
|
bool GunGrasp::HasBulletBlockBuff()
|
|
{
|
|
return !list_empty(&grasp_triggers_[(int)GraspBuffTrigger_e::kHitAndEnd]);
|
|
}
|