253 lines
5.7 KiB
C++
253 lines
5.7 KiB
C++
#include "precompile.h"
|
|
|
|
#include "entity.h"
|
|
#include "collider.h"
|
|
#include "room.h"
|
|
#include "building.h"
|
|
#include "human.h"
|
|
#include "app.h"
|
|
#include "perfmonitor.h"
|
|
|
|
Entity::Entity()
|
|
{
|
|
entity_weak_ptr_chunk_.Set(this);
|
|
}
|
|
|
|
Entity::~Entity()
|
|
{
|
|
ClearColliders();
|
|
}
|
|
|
|
void Entity::Initialize()
|
|
{
|
|
}
|
|
|
|
void Entity::GetAabbBox(AabbCollider& aabb_box)
|
|
{
|
|
aabb_box.active = true;
|
|
aabb_box.owner = this;
|
|
}
|
|
|
|
void Entity::GetCircleBox(CircleCollider& circle_box)
|
|
{
|
|
circle_box.active = true;
|
|
circle_box.owner = this;
|
|
circle_box.rad = 1;
|
|
}
|
|
|
|
bool Entity::TestCollision(Room* room, Entity* b)
|
|
{
|
|
PerfMonitor::Instance()->test_times++;
|
|
if (b->IsDead(room)) {
|
|
return false;
|
|
}
|
|
OnPreCollision(room);
|
|
b->OnPreCollision(room);
|
|
for (auto& a_collider : colliders_) {
|
|
for (auto& b_collider : b->colliders_) {
|
|
if (a_collider->Intersect(b_collider)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ColliderComponent* Entity::TestCollisionAndGetCollider(Room* room, Entity* b)
|
|
{
|
|
PerfMonitor::Instance()->test_times++;
|
|
if (b->IsDead(room)) {
|
|
return nullptr;
|
|
}
|
|
OnPreCollision(room);
|
|
b->OnPreCollision(room);
|
|
for (auto& a_collider : colliders_) {
|
|
for (auto& b_collider : b->colliders_) {
|
|
if (a_collider->Intersect(b_collider)) {
|
|
return b_collider;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool Entity::TestCollision(Room* room, ColliderComponent* b)
|
|
{
|
|
if (b->owner->IsDead(room)) {
|
|
return false;
|
|
}
|
|
OnPreCollision(room);
|
|
b->owner->OnPreCollision(room);
|
|
for (auto& a_collider : colliders_) {
|
|
if (a_collider->Intersect(b)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ColliderComponent* Entity::TestCollisionAndGetCollider(Room* room, ColliderComponent* b)
|
|
{
|
|
if (b->owner->IsDead(room)) {
|
|
return nullptr;
|
|
}
|
|
OnPreCollision(room);
|
|
b->owner->OnPreCollision(room);
|
|
for (auto& a_collider : colliders_) {
|
|
if (a_collider->Intersect(b)) {
|
|
return a_collider;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool Entity::TestCollisionEx(Room* room, const a8::Vec2& aabb_pos, AabbCollider& aabb_box)
|
|
{
|
|
OnPreCollision(room);
|
|
if (aabb_box.owner) {
|
|
aabb_box.owner->OnPreCollision(room);
|
|
}
|
|
for (auto& a_collider : colliders_) {
|
|
if (a_collider->IntersectEx(aabb_pos, &aabb_box)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Entity::ClearColliders()
|
|
{
|
|
for (auto& itr : colliders_) {
|
|
ColliderComponent* collider = itr;
|
|
DestoryCollider(collider);
|
|
}
|
|
colliders_.clear();
|
|
}
|
|
|
|
void Entity::BroadcastFullState(Room* room)
|
|
{
|
|
std::set<GridCell*> tmp_grids;
|
|
room->grid_service->GetAllCells(room, grid_id_, tmp_grids);
|
|
room->grid_service->TraverseAllLayerHumanList
|
|
(
|
|
room->GetRoomIdx(),
|
|
tmp_grids,
|
|
[this] (Human* hum, bool& stop)
|
|
{
|
|
hum->AddToNewObjects(this);
|
|
});
|
|
}
|
|
|
|
void Entity::BroadcastDeleteState(Room* room)
|
|
{
|
|
#if 0
|
|
room->TraverseHumanList
|
|
(
|
|
a8::XParams(),
|
|
[this] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
hum->RemoveObjects(this);
|
|
return true;
|
|
});
|
|
#else
|
|
std::set<GridCell*> tmp_grids;
|
|
room->grid_service->GetAllCells(room, grid_id_, tmp_grids);
|
|
room->grid_service->TraverseAllLayerHumanList
|
|
(
|
|
room->GetRoomIdx(),
|
|
tmp_grids,
|
|
[this] (Human* hum, bool& stop)
|
|
{
|
|
hum->RemoveObjects(this);
|
|
});
|
|
#endif
|
|
}
|
|
|
|
void Entity::RemoveFromAroundPlayers(Room* room)
|
|
{
|
|
#if 1
|
|
room->TraverseHumanList
|
|
(
|
|
a8::XParams(),
|
|
[this] (Human* hum, a8::XParams& param) -> bool
|
|
{
|
|
hum->RemovePartObjects(this);
|
|
return true;
|
|
});
|
|
#else
|
|
std::set<GridCell*> tmp_grids;
|
|
room->grid_service->GetAllCells(room, grid_id_, tmp_grids);
|
|
room->grid_service->TraverseAllLayerHumanList
|
|
(
|
|
room->GetRoomIdx(),
|
|
tmp_grids,
|
|
[this] (Human* hum, bool& stop)
|
|
{
|
|
hum->RemovePartObjects(this);
|
|
});
|
|
#endif
|
|
}
|
|
|
|
void Entity::AddEntityCollider(ColliderComponent* collider)
|
|
{
|
|
colliders_.push_back(collider);
|
|
}
|
|
|
|
bool Entity::IsClientCached(Human* hum)
|
|
{
|
|
ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetUniId());
|
|
if (sync_flags) {
|
|
int flags = sync_flags->flags;
|
|
if (IsDead(hum->room)) {
|
|
if (a8::HasBitFlag(flags, kOsfIsDead)) {
|
|
return sync_flags->last_sync_frameno > 0;
|
|
} else {
|
|
return false;
|
|
}
|
|
} else {
|
|
if (!a8::HasBitFlag(flags, kOsfIsDead)) {
|
|
return sync_flags->last_sync_frameno > 0;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Entity::CanClientCache(Human* hum)
|
|
{
|
|
ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetUniId());
|
|
return sync_flags != nullptr;
|
|
}
|
|
|
|
void Entity::AddClientCache(Human* hum)
|
|
{
|
|
ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetUniId());
|
|
if (sync_flags) {
|
|
int flags = sync_flags->flags;
|
|
if (IsDead(hum->room)) {
|
|
a8::SetBitFlag(flags, kOsfIsDead);
|
|
} else {
|
|
a8::UnSetBitFlag(flags, kOsfIsDead);
|
|
}
|
|
sync_flags->flags = flags;
|
|
sync_flags->last_sync_frameno = hum->room->GetFrameNo();
|
|
}
|
|
}
|
|
|
|
EntityWeakPtr Entity::AllocEntityWeakPtr()
|
|
{
|
|
EntityWeakPtr ptr;
|
|
ptr.Attach(this);
|
|
return ptr;
|
|
}
|
|
|
|
EntityWeakPtr& Entity::GetEntityWeakPtrRef()
|
|
{
|
|
if (!entity_weak_ptr_.Get()) {
|
|
entity_weak_ptr_.Attach(this);
|
|
}
|
|
return entity_weak_ptr_;
|
|
}
|