game2006/server/gameserver/gungrasp.cc
aozhiwei e6fdc460ac 1
2023-02-24 11:30:27 +08:00

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]);
}