aozhiwei 5ecce5e9d9 1
2023-03-24 21:10:29 +08:00

143 lines
4.8 KiB
C++

#include "precompile.h"
#include "buff/hide.h"
#include "creature.h"
#include "room.h"
#include "trigger.h"
#include "collision.h"
#include "human.h"
#include "mt/Buff.h"
#include "mt/Skill.h"
#include "mt/SkillNumber.h"
void HideBuff::Activate()
{
alert_range = meta->GetBuffParam2(this);
alert_time = meta->GetBuffParam3(this);
if (alert_range > 1.0f) {
owner->room->xtimer.SetIntervalWpEx
(
SERVER_FRAME_RATE,
[this]
(int event, const a8::Args* args) mutable
{
if (a8::TIMER_EXEC_EVENT == event) {
++step_;
owner->TraverseCreatures
(
[this] (Creature* target, bool& stop)
{
if (!target->dead && target->team_id != owner->team_id &&
Collision::CheckCC(owner,
alert_range,
target,
target->GetRadius()
)) {
AddInRangeObject(target);
}
});
Check();
}
},
&xtimer_attacher
);
}
}
void HideBuff::Deactivate()
{
for (auto& pair : alert_buff_hash_) {
auto& tuple = pair.second;
if (std::get<0>(tuple).Get()) {
std::get<0>(tuple).Get()->RemoveBuffByUniId(std::get<3>(tuple));
}
}
alert_buff_hash_.clear();
}
void HideBuff::AddInRangeObject(Creature* target)
{
auto itr = alert_buff_hash_.find(target->GetUniId());
if (itr != alert_buff_hash_.end()) {
std::get<2>(itr->second) = step_;
} else {
int buff_uniid = target->TryAddBuff(GetCaster().Get(), meta->_int_buff_param4, skill_meta);
CreatureWeakPtr weak_ptr = target->GetWeakPtrRef();
#if 1
auto tuple = std::make_tuple(weak_ptr,
owner->room->GetFrameNo(),
step_,
buff_uniid);
alert_buff_hash_[target->GetUniId()] = tuple;
#else
alert_buff_hash_[target->GetUniId()] = std::make_tuple(weak_ptr,
owner->room->GetFrameNo(),
step_,
buff_uniid);
#endif
}
}
void HideBuff::Check()
{
bool timeout = false;
std::vector<int> leave_targets;
for (auto& pair : alert_buff_hash_) {
auto& tuple = pair.second;
if (std::get<2>(tuple) < step_) {
if (std::get<0>(tuple).Get()) {
if (Collision::CheckCC(owner,
alert_range,
std::get<0>(tuple).Get(),
std::get<0>(tuple).Get()->GetRadius()
)) {
if (!std::get<0>(tuple).Get()->dead) {
if (owner->room->GetFrameNo() - std::get<1>(tuple) >= alert_time * SERVER_FRAME_RATE) {
timeout = true;
break;
}
}
} else {
leave_targets.push_back(pair.first);
}
} else {
leave_targets.push_back(pair.first);
}
} else {
if (std::get<0>(tuple).Get()) {
if (!std::get<0>(tuple).Get()->dead) {
if (owner->room->GetFrameNo() - std::get<1>(tuple) >= alert_time * SERVER_FRAME_RATE) {
timeout = true;
break;
}
}
}
}
}
if (timeout) {
for (auto& pair : alert_buff_hash_) {
auto& tuple = pair.second;
if (std::get<0>(tuple).Get()) {
std::get<0>(tuple).Get()->RemoveBuffByUniId(std::get<3>(tuple));
}
}
alert_buff_hash_.clear();
owner->RemoveBuffByUniId(buff_uniid);
} else if (!leave_targets.empty()) {
for (int obj_uniid : leave_targets) {
auto itr = alert_buff_hash_.find(obj_uniid);
if (itr != alert_buff_hash_.end()) {
auto& tuple = itr->second;
if (std::get<0>(tuple).Get()) {
std::get<0>(tuple).Get()->RemoveBuffByUniId(std::get<3>(tuple));
}
alert_buff_hash_.erase(itr);
}
}
}
}