143 lines
4.8 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|
|
}
|