Files
2022-10-26 12:25:11 +08:00

259 lines
8.4 KiB
C++

#include "stdafx.h"
#include "./TriggerArea.h"
#include "./TriggerAreaManager.h"
//==================================================================================================
void TriggerArea::Clear()
{
TriggerPlayerLink* it = static_cast<TriggerPlayerLink*>(char_list_root_.next);
while (it != &char_list_root_) {
it = it->Delete();
};
}
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
void TriggerArea::InsertAreaCondition(TriggerAreaLocalStorage* area_item)
{
// (NOTE) 초기화시 한번 수행되는 영역이다.
if (area_item == NULL) { // client?
return;
}
area_item->Delete();
area_item->last_updated_number_of_chars_ = 0;
util::LList::AddNext(area_item, &area_conditions_);
}
bool TriggerArea::EnterArea(TriggerAreaManager* area_manager, const TRIGGER_ENTER_AREA* msg)
{
TriggerPlayerLink* item = msg->m_pLink;
// (WAVERIX) (090904) (BUG-FIX) 클라이언트 영역 이벤트 처리 순서 (enter->enter->leave) 역전 현상
// 감안한 추가 처리
if (item->object_key_)
{
TriggerArea* prev_trigger_area = area_manager->FindArea(item->area_id_);
if (prev_trigger_area != NULL)
{
TriggerAreaLocalStorage* it = prev_trigger_area->area_conditions_.next;
while (it != &prev_trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
}
TriggerArea* trigger_area = area_manager->FindArea(msg->m_AreaID);
if (trigger_area == NULL) {
SUNLOG(eCRITICAL_LOG, "Can't Find Area %d", msg->m_AreaID); // where?
return false;
}
//
item->Delete();
item->object_key_ = msg->m_PlayerKey;
item->area_id_ = trigger_area->area_id_;
util::LList::AddNext(item, &trigger_area->char_list_root_);
//
return true;
}
bool TriggerArea::LeaveArea(TriggerAreaManager* area_manager, const TRIGGER_LEAVE_AREA* msg)
{
TriggerPlayerLink* item = msg->m_pLink;
if (util::LList::IsEmpty(item)) {
return true;
}
// Enter(1) -> Enter(2) -> Leave(1)의 형식으로 클라이언트 요청되는 사례가 있다.
// (WAVERIX) (090904) (BUG-FIX) Enter에서 Leave조건을 클리어 한다.
const int area_id = msg->m_AreaID;
if (item->area_id_ == area_id)
{
item->Delete();
item->object_key_ = 0; //초기값을 명확히 구분할 필요 있다.
item->area_id_ = 0;
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
//__NAM00000_090621_TRIGGER_LOGIC_REARRANGE2__
TriggerArea* trigger_area = area_manager->FindArea(area_id);
if (trigger_area != NULL)
{
TriggerAreaLocalStorage* it = trigger_area->area_conditions_.next;
while (it != &trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
}
return true;
}
bool TriggerArea::ForceLeave(TriggerAreaManager* area_manager, TriggerPlayerLink* link)
{
//__NA000000_090613_TRIGGER_LOGIC_REARRANGE2__
TriggerArea* trigger_area = area_manager->FindArea(link->area_id_);
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
if (trigger_area != NULL)
{
TriggerAreaLocalStorage* it = trigger_area->area_conditions_.next;
while (it != &trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
//
link->object_key_ = 0;
link->area_id_ = 0;
link->Delete();
//
return true;
}
DWORD TriggerArea::GetPlayerNumber() const
{
DWORD number_of_players = 0;
TriggerPlayerLink* it = static_cast<TriggerPlayerLink*>(char_list_root_.next);
for (; it != &char_list_root_; it = static_cast<TriggerPlayerLink*>(it->next)) {
++number_of_players;
}
return number_of_players;
}
//==================================================================================================
//==================================================================================================
//==================================================================================================
// NOTE: f110311.4L, _NA_002098_20110307_ADD_NPC_CONTROL_TRIGGER_BASE
void TriggerAreaForNpc::Clear()
{
TriggerNpcLink* it = static_cast<TriggerNpcLink*>(char_list_root_.next);
while (it != &char_list_root_) {
it = it->Delete();
};
}
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
void TriggerAreaForNpc::InsertAreaCondition(TriggerAreaLocalStorageForNpc* area_item)
{
// (NOTE) 초기화시 한번 수행되는 영역이다.
if (area_item == NULL) { // client?
return;
}
area_item->Delete();
area_item->last_updated_number_of_chars_ = 0;
util::LList::AddNext(area_item, &area_conditions_);
}
bool TriggerAreaForNpc::EnterArea(TriggerAreaManagerForNpc* area_manager,
const TRIGGER_NPC_ENTER_AREA* msg)
{
TriggerNpcLink* item = msg->link;
// (WAVERIX) (090904) (BUG-FIX) 클라이언트 영역 이벤트 처리 순서 (enter->enter->leave) 역전 현상
// 감안한 추가 처리
if (item->object_key_)
{
TriggerAreaForNpc* prev_trigger_area = area_manager->FindArea(item->area_id_);
if (prev_trigger_area != NULL)
{
TriggerAreaLocalStorageForNpc* it = prev_trigger_area->area_conditions_.next;
while (it != &prev_trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
}
TriggerAreaForNpc* trigger_area = area_manager->FindArea(msg->area_id);
if (trigger_area == NULL) {
SUNLOG(eCRITICAL_LOG, "Can't Find Area %d", msg->area_id); // where?
return false;
}
//
item->Delete();
item->object_key_ = msg->object_key;
item->area_id_ = trigger_area->area_id_;
util::LList::AddNext(item, &trigger_area->char_list_root_);
//
return true;
}
bool TriggerAreaForNpc::LeaveArea(TriggerAreaManagerForNpc* area_manager,
const TRIGGER_NPC_LEAVE_AREA* msg)
{
TriggerNpcLink* item = msg->link;
if (util::LList::IsEmpty(item)) {
return true;
}
// Enter(1) -> Enter(2) -> Leave(1)의 형식으로 클라이언트 요청되는 사례가 있다.
// (WAVERIX) (090904) (BUG-FIX) Enter에서 Leave조건을 클리어 한다.
const int area_id = msg->area_id;
if (item->area_id_ == area_id)
{
item->Delete();
item->object_key_ = 0; //초기값을 명확히 구분할 필요 있다.
item->area_id_ = 0;
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
//__NAM00000_090621_TRIGGER_LOGIC_REARRANGE2__
TriggerAreaForNpc* trigger_area = area_manager->FindArea(area_id);
if (trigger_area != NULL)
{
TriggerAreaLocalStorageForNpc* it = trigger_area->area_conditions_.next;
while (it != &trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
}
return true;
}
bool TriggerAreaForNpc::ForceLeave(TriggerAreaManagerForNpc* area_manager, TriggerNpcLink* link)
{
//__NA000000_090613_TRIGGER_LOGIC_REARRANGE2__
TriggerAreaForNpc* trigger_area = area_manager->FindArea(link->area_id_);
// (WAVERIX) (090831) (BUG-FIX) 트리거 관련
if (trigger_area != NULL)
{
TriggerAreaLocalStorageForNpc* it = trigger_area->area_conditions_.next;
while (it != &trigger_area->area_conditions_)
{
if (it->last_updated_number_of_chars_) {
--(it->last_updated_number_of_chars_);
}
it = it->next;
}
}
//
link->object_key_ = 0;
link->area_id_ = 0;
link->Delete();
//
return true;
}
DWORD TriggerAreaForNpc::GetNpcNumber() const
{
DWORD number_of_chars = 0;
TriggerNpcLink* it = static_cast<TriggerNpcLink*>(char_list_root_.next);
for (; it != &char_list_root_; it = static_cast<TriggerNpcLink*>(it->next)) {
++number_of_chars;
}
return number_of_chars;
}
//==================================================================================================