169 lines
5.0 KiB
C++
169 lines
5.0 KiB
C++
#include "WorldServerPch.hxx"
|
|
#include "./ZoneCommunity.h"
|
|
|
|
#include "./FieldInfo.h"
|
|
#include "Objects/WorldUser.h"
|
|
|
|
//==================================================================================================
|
|
|
|
ns_world::community::ZoneCommunity::ZoneCommunity(
|
|
DWORD zone_key, const sMAPINFO* map_info,
|
|
const ns_world::community::FieldInfo* field_info)
|
|
: zone_key_(zone_key)
|
|
, map_info_(map_info)
|
|
, field_info_(field_info)
|
|
, shout_range_(NULL)
|
|
, blocked_chat_(false)
|
|
{
|
|
util::LList::Init(&user_list_);
|
|
if (field_info_ != NULL) {
|
|
sectors_.Build(field_info_->GetSectorGridInfo());
|
|
};
|
|
}
|
|
|
|
ns_world::community::ZoneCommunity::~ZoneCommunity()
|
|
{
|
|
ASSERT(util::LList::IsEmpty(&user_list_));
|
|
ZoneUserNode* it = user_list_.next;
|
|
while (it != &user_list_)
|
|
{
|
|
if (ns_world::ConnectedCharInfo* char_info = &it->base->connected_char_info_)
|
|
{
|
|
char_info->zone_type = 0;
|
|
char_info->zone_key = 0;
|
|
char_info->map_code = 0;
|
|
char_info->field_code = 0;
|
|
ZeroMemory(&char_info->position, sizeof(char_info->position));
|
|
};
|
|
it->link_zone = NULL;
|
|
util::LList::Delete(&it->sector_node);
|
|
//
|
|
it = util::LList::Delete(it);
|
|
};
|
|
}
|
|
|
|
// ICommunity interface
|
|
ns_world::community::eCommunityType ns_world::community::ZoneCommunity::GetCommunityType() const
|
|
{
|
|
return eCommunity_Zone;
|
|
}
|
|
|
|
bool ns_world::community::ZoneCommunity::EnabledChat() const
|
|
{
|
|
return (blocked_chat_ == false);
|
|
}
|
|
|
|
void ns_world::community::ZoneCommunity::ConfigureChatEnabled(bool enabled)
|
|
{
|
|
blocked_chat_ = !enabled;
|
|
}
|
|
|
|
// ICommunity interface
|
|
bool ns_world::community::ZoneCommunity::Enter(
|
|
WorldUser* user, const ns_world::ConnectedCharInfo& char_info)
|
|
{
|
|
ns_world::community::ZoneUserNode* const user_node = &user->zone_node_;
|
|
util::LList::Delete(user_node);
|
|
util::LList::Delete(&user_node->sector_node);
|
|
//
|
|
user_node->link_zone = this;
|
|
util::LList::AddPrev(user_node, &user_list_);
|
|
sectors_.Link(&user_node->sector_node, char_info.position);
|
|
|
|
return true;
|
|
}
|
|
|
|
// ICommunity interface
|
|
bool ns_world::community::ZoneCommunity::Leave(
|
|
WorldUser* user, ns_world::ConnectedCharInfo* const backup_info)
|
|
{
|
|
util::LList::Delete(&user->zone_node_);
|
|
util::LList::Delete(&user->zone_node_.sector_node);
|
|
user->zone_node_.link_zone = NULL;
|
|
return true;
|
|
}
|
|
|
|
bool ns_world::community::ZoneCommunity::SendToAll(MSG_BASE* msg_base, uint16_t msg_size) const
|
|
{
|
|
// TODO: use 1toN broadcaster
|
|
ZoneUserNode* it = user_list_.next;
|
|
for (; it != &user_list_; it = it->next)
|
|
{
|
|
ns_world::WorldUser* user = it->base;
|
|
user->SendPacket(msg_base, msg_size);
|
|
};
|
|
return true;
|
|
}
|
|
|
|
bool ns_world::community::ZoneCommunity::SendPacketAround(
|
|
MSG_BASE* msg_base, uint16_t msg_size, const ns_world::WorldUser* talker) const
|
|
{
|
|
assert(this != NULL && this == talker->zone_node_.link_zone);
|
|
if (field_info_ == NULL) {
|
|
return this->SendToAll(msg_base, msg_size);
|
|
};
|
|
//
|
|
const ns_world::ConnectedCharInfo& char_info = talker->GetConnectedCharInfo();
|
|
|
|
if (sectors_.IsNullVector(&char_info.position)) {
|
|
// unset position
|
|
return false;
|
|
};
|
|
// pseudo code
|
|
// #1. find position
|
|
// #2. get sector array based on position
|
|
// #3. foreach(sector in sectors)
|
|
// foreach(user in sector)
|
|
// user->SendPacket
|
|
//
|
|
const ns_world::grid::SECTOR_IDX center_index = sectors_.GetSectorIndex(&char_info.position);
|
|
if (center_index == INVALID_SECTOR_INDEX) {
|
|
return false;
|
|
};
|
|
//
|
|
ns_world::grid::SectorGrid3x3 grid;
|
|
if (sectors_.GetAroundSectors(center_index, &grid) == false) {
|
|
return false;
|
|
};
|
|
FOREACH_ARRAY(const ns_world::grid::SECTOR_IDX sector_index, grid.Grid,
|
|
ns_world::grid::SectorGrid3x3::GridArray)
|
|
{
|
|
if (sector_index == INVALID_SECTOR_INDEX) {
|
|
continue;
|
|
};
|
|
const ns_world::grid::SectorGrid::Node* const sector_root = \
|
|
sectors_.GetSector(sector_index);
|
|
if (sector_root == NULL)
|
|
{
|
|
assert(!"unexpected state");
|
|
continue;
|
|
};
|
|
const ns_world::grid::SectorGrid::Node* member_it = sector_root->next;
|
|
for (; member_it != sector_root; member_it = member_it->next)
|
|
{
|
|
member_it->user->SendPacket(msg_base, msg_size);
|
|
};
|
|
};
|
|
return true;
|
|
}
|
|
|
|
void ns_world::community::ZoneCommunity::RegisterShoutRange(
|
|
const ns_world::community::ShoutRange* shout_range)
|
|
{
|
|
shout_range_ = shout_range;
|
|
};
|
|
|
|
bool ns_world::community::ZoneCommunity::UpdatePosition(ns_world::WorldUser* user)
|
|
{
|
|
if (field_info_ == NULL) {
|
|
// no sector control
|
|
return true;
|
|
};
|
|
const ns_world::ConnectedCharInfo& char_info = user->GetConnectedCharInfo();
|
|
return sectors_.Link(&user->zone_node_.sector_node, char_info.position);
|
|
}
|
|
|
|
bool ns_world::community::ZoneCommunity::Empty() const
|
|
{
|
|
return util::LList::IsEmpty(&user_list_);
|
|
}; |