game2005/server/gameserver/building.cc
2020-10-28 11:50:16 +08:00

150 lines
4.9 KiB
C++

#include "precompile.h"
#include "building.h"
#include "collider.h"
#include "metamgr.h"
#include "loot.h"
#include "app.h"
#include "typeconvert.h"
#include "mapservice.h"
#include "cs_proto.pb.h"
#include "perfmonitor.h"
Building::Building():Entity()
{
++PerfMonitor::Instance()->entity_num[ET_Building];
}
Building::~Building()
{
--PerfMonitor::Instance()->entity_num[ET_Building];
}
void Building::Initialize()
{
Entity::Initialize();
RecalcSelfCollider();
}
void Building::RecalcSelfCollider()
{
std::vector<AabbCollider*> collider_list;
collider_list.reserve(meta->i->staticobj_size());
for (auto& obj : meta->i->staticobj()) {
AabbCollider* collider = new AabbCollider();
collider->owner = this;
collider->_min = a8::Vec2(obj.x() - obj.width()/2.0 - meta->i->tilewidth()/2.0,
obj.y() - obj.height()/2.0 - meta->i->tileheight()/2.0);
collider->_max = a8::Vec2(obj.x() + obj.width()/2.0 - meta->i->tilewidth()/2.0,
obj.y() + obj.height()/2.0 - meta->i->tileheight()/2.0);
AddEntityCollider(collider);
collider_list.push_back(collider);
permanent_map_service->AddCollider(collider);
}
for (auto& obj : meta->i->halfwallobj()) {
AabbCollider* collider = new AabbCollider();
collider->owner = this;
collider->_min = a8::Vec2(obj.x() - obj.width()/2.0 - meta->i->tilewidth()/2.0,
obj.y() - obj.height()/2.0 - meta->i->tileheight()/2.0);
collider->_max = a8::Vec2(obj.x() + obj.width()/2.0 - meta->i->tilewidth()/2.0,
obj.y() + obj.height()/2.0 - meta->i->tileheight()/2.0);
a8::SetBitFlag(collider->tag, kHalfWallTag);
AddEntityCollider(collider);
collider_list.push_back(collider);
permanent_map_service->AddCollider(collider);
}
AutoAdjust(collider_list);
}
void Building::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
{
part_data->set_object_type(ET_Building);
cs::MFBuildingPart* p = part_data->mutable_union_obj_3();
p->set_obj_uniid(GetEntityUniId());
TypeConvert::ToPb(GetPos(), p->mutable_pos());
}
void Building::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
{
full_data->set_object_type(ET_Building);
if (IsClientCached(hum)) {
int object_flags = 0;
a8::SetBitFlag(object_flags, kOfReadCache);
full_data->set_obj_uniid(GetEntityUniId());
full_data->set_object_flags(object_flags);
return;
}
cs::MFBuildingFull* p = full_data->mutable_union_obj_3();
if (CanClientCache(hum)) {
int object_flags = 0;
a8::SetBitFlag(object_flags, kOfWriteCache);
#if 0
full_data->set_obj_uniid(GetEntityUniId());
#endif
full_data->set_object_flags(object_flags);
AddClientCache(hum);
}
p->set_obj_uniid(GetEntityUniId());
TypeConvert::ToPb(GetPos(), p->mutable_pos());
p->set_building_id(meta->i->mapid());
}
void Building::GetAabbBox(AabbCollider& aabb_box)
{
aabb_box.active = true;
aabb_box.owner = this;
aabb_box._min.x = -meta->i->tilewidth()/2.0;
aabb_box._min.y = -meta->i->tileheight()/2.0;
aabb_box._max.x = meta->i->tilewidth()/2.0;
aabb_box._max.y = meta->i->tileheight()/2.0;
}
void Building::AutoAdjust(std::vector<AabbCollider*>& collider_list)
{
for (int dir = 0; dir < 4; ++dir) {
for (size_t i = 0; i < collider_list.size(); ++i) {
AabbCollider* a_collider = collider_list[i];
for (size_t ii = i + 1; ii < collider_list.size(); ++ii) {
AabbCollider* b_collider = collider_list[ii];
switch (dir) {
case 0:
{
if (std::fabs(a_collider->_min.x - b_collider->_min.x) < 2.0f) {
b_collider->_min.x = a_collider->_min.x;
}
}
break;
case 1:
{
if (std::fabs(a_collider->_min.y - b_collider->_min.y) < 2.0f) {
b_collider->_min.y = a_collider->_min.y;
}
}
break;
case 2:
{
if (std::fabs(a_collider->_max.x - b_collider->_max.x) < 2.0f) {
b_collider->_max.x = a_collider->_max.x;
}
}
break;
case 3:
{
if (std::fabs(a_collider->_max.y - b_collider->_max.y) < 2.0f) {
b_collider->_max.y = a_collider->_max.y;
}
}
break;
}
}
}
}
}