WIP on master: 3474689 1
This commit is contained in:
commit
725e992797
@ -97,6 +97,71 @@ bool ColliderComponent::Intersect(ColliderComponent* b)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ColliderComponent::IntersectEx(const a8::Vec2& pos, ColliderComponent* b)
|
||||
{
|
||||
switch (type) {
|
||||
case CT_None:
|
||||
break;
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* a_aabb = (AabbCollider*)this;
|
||||
switch (b->type) {
|
||||
case CT_None:
|
||||
break;
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* b_aabb = (AabbCollider*)b;
|
||||
return a8::IntersectAabbAabb(a_aabb->owner->pos + a_aabb->_min,
|
||||
a_aabb->owner->pos + a_aabb->_max,
|
||||
pos + b_aabb->_min,
|
||||
pos + b_aabb->_max
|
||||
);
|
||||
}
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* b_circle = (CircleCollider*)b;
|
||||
return a8::IntersectAabbCircle(a_aabb->owner->pos + a_aabb->_min,
|
||||
a_aabb->owner->pos + a_aabb->_max,
|
||||
pos + b_circle->pos,
|
||||
b_circle->rad);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* a_circle = (CircleCollider*)this;
|
||||
switch (b->type) {
|
||||
case CT_None:
|
||||
break;
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* b_aabb = (AabbCollider*)b;
|
||||
return a8::IntersectAabbCircle(pos + b_aabb->_min,
|
||||
pos + b_aabb->_max,
|
||||
a_circle->owner->pos + a_circle->pos,
|
||||
a_circle->rad);
|
||||
}
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* b_circle = (CircleCollider*)b;
|
||||
return a8::IntersectCircleCircle(
|
||||
a_circle->owner->pos + a_circle->pos,
|
||||
a_circle->rad,
|
||||
pos + b_circle->pos,
|
||||
b_circle->rad);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ColliderComponent::CalcSafePoint(ColliderComponent* b, a8::Vec2& new_pos)
|
||||
{
|
||||
switch (type) {
|
||||
@ -164,6 +229,73 @@ bool ColliderComponent::CalcSafePoint(ColliderComponent* b, a8::Vec2& new_pos)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ColliderComponent::CalcSafePointEx(const a8::Vec2& a_pos, ColliderComponent* b, a8::Vec2& new_pos)
|
||||
{
|
||||
switch (type) {
|
||||
case CT_None:
|
||||
break;
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* a_aabb = (AabbCollider*)this;
|
||||
switch (b->type) {
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* b_aabb = (AabbCollider*)b;
|
||||
return a8::CalcAabbAabbSafePoint(a_pos + a_aabb->_min,
|
||||
a_pos + a_aabb->_max,
|
||||
b_aabb->owner->pos + b_aabb->_min,
|
||||
b_aabb->owner->pos + b_aabb->_max,
|
||||
new_pos);
|
||||
}
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* b_circle = (CircleCollider*)b;
|
||||
return a8::CalcAabbAabbSafePoint(a_pos + a_aabb->_min,
|
||||
a_pos + a_aabb->_max,
|
||||
b_circle->owner->pos + b_circle->pos,
|
||||
b_circle->rad,
|
||||
new_pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* a_circle = (CircleCollider*)this;
|
||||
switch (b->type) {
|
||||
case CT_Aabb:
|
||||
{
|
||||
AabbCollider* b_aabb = (AabbCollider*)b;
|
||||
return a8::CalcCircleAabbSafePoint(
|
||||
a_pos + a_circle->pos,
|
||||
a_circle->rad,
|
||||
b_aabb->owner->pos + b_aabb->_min,
|
||||
b_aabb->owner->pos + b_aabb->_max,
|
||||
new_pos);
|
||||
}
|
||||
break;
|
||||
case CT_Circle:
|
||||
{
|
||||
CircleCollider* b_circle = (CircleCollider*)b;
|
||||
return a8::CalcCircleCircleSafePoint(
|
||||
a_pos + a_circle->pos,
|
||||
a_circle->rad,
|
||||
b_circle->owner->pos + b_circle->pos,
|
||||
b_circle->rad,
|
||||
new_pos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DestoryCollider(ColliderComponent* collider)
|
||||
{
|
||||
switch (collider->type) {
|
||||
|
@ -16,8 +16,10 @@ class ColliderComponent
|
||||
bool active = true;
|
||||
|
||||
bool Intersect(ColliderComponent* b);
|
||||
bool IntersectEx(const a8::Vec2& pos, ColliderComponent* b);
|
||||
bool IntersectSegment(a8::Vec2& p0, a8::Vec2& p1);
|
||||
bool CalcSafePoint(ColliderComponent* b, a8::Vec2& new_pos);
|
||||
bool CalcSafePointEx(const a8::Vec2& a_pos, ColliderComponent* b, a8::Vec2& new_pos);
|
||||
};
|
||||
|
||||
class AabbCollider : public ColliderComponent
|
||||
|
@ -61,6 +61,16 @@ bool Entity::TestCollision(ColliderComponent* b)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Entity::TestCollisionEx(const a8::Vec2& aabb_pos, AabbCollider& aabb_box)
|
||||
{
|
||||
for (auto& a_collider : colliders) {
|
||||
if (a_collider->IntersectEx(aabb_pos, &aabb_box)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Entity::ClearColliders()
|
||||
{
|
||||
for (auto& itr : colliders) {
|
||||
|
@ -43,6 +43,7 @@ class Entity
|
||||
virtual void GetCircleBox(CircleCollider& circle_box);
|
||||
bool TestCollision(Entity* b);
|
||||
bool TestCollision(ColliderComponent* b);
|
||||
bool TestCollisionEx(const a8::Vec2& aabb_pos, AabbCollider& aabb_box);
|
||||
void FindLocationWithTarget(Entity* target);
|
||||
void BroadcastFullState();
|
||||
void BroadcastDeleteState();
|
||||
|
@ -333,17 +333,6 @@ void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg)
|
||||
msg.set_player_id(self_hum->entity_uniid);
|
||||
msg.set_started(false);
|
||||
msg.set_room_uuid(a8::XValue(room_uuid).GetString());
|
||||
#if 0
|
||||
for (auto& pair : uniid_hash_) {
|
||||
if (pair.second->entity_type == ET_Player) {
|
||||
Human* hum = (Human*)pair.second;
|
||||
cs::MFPlayerInfo* info = msg.add_player_infos();
|
||||
info->set_player_id(hum->entity_uniid);
|
||||
info->set_team_id(hum->team_id);
|
||||
info->set_name(hum->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Room::ScatterDrop(a8::Vec2 center, int drop_id)
|
||||
@ -735,6 +724,99 @@ void Room::OnPlayerOffline(Player* hum)
|
||||
}
|
||||
}
|
||||
|
||||
Entity* Room::FindFirstCollisonEntity(const a8::Vec2& aabb_pos, AabbCollider& aabb_box)
|
||||
{
|
||||
Entity* target = nullptr;
|
||||
std::set<GridCell*> grid_list;
|
||||
grid_service.GetAllCellsByXy(aabb_pos.x, aabb_pos.y, grid_list);
|
||||
for (auto& grid : grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Obstacle:
|
||||
{
|
||||
if (!target) {
|
||||
if (entity->TestCollisionEx(aabb_pos, aabb_box)) {
|
||||
target = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ET_Building:
|
||||
{
|
||||
if (!target || target->entity_type != ET_Building) {
|
||||
AabbCollider building_aabb_box;
|
||||
entity->GetAabbBox(building_aabb_box);
|
||||
if (building_aabb_box.IntersectEx(aabb_pos, &aabb_box)) {
|
||||
target = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
void Room::FindLocationWithAabb(Entity* target, const a8::Vec2& aabb_pos, AabbCollider* aabb_box,
|
||||
float& new_x, float& new_y)
|
||||
{
|
||||
a8::Vec2 old_pos = aabb_pos;
|
||||
a8::Vec2 new_pos = aabb_pos;
|
||||
AabbCollider target_collider;
|
||||
target->GetAabbBox(target_collider);
|
||||
{
|
||||
bool ret = aabb_box->CalcSafePointEx(aabb_pos, &target_collider, new_pos);
|
||||
if (!ret) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
a8::Vec2 new_pos_dir = new_pos - old_pos;
|
||||
new_pos_dir.Normalize();
|
||||
float distance = (new_pos - old_pos).Norm();
|
||||
for (int i = distance; i < 10000000; i += 5) {
|
||||
a8::Vec2 pos = old_pos + new_pos_dir * i;
|
||||
|
||||
Entity* building = nullptr;
|
||||
std::set<GridCell*> new_grid_list;
|
||||
grid_service.GetAllCellsByXy(pos.x, pos.y, new_grid_list);
|
||||
for (auto& grid : new_grid_list) {
|
||||
for (Entity* entity : grid->entity_list) {
|
||||
switch (entity->entity_type) {
|
||||
case ET_Building:
|
||||
{
|
||||
if (entity->TestCollisionEx(pos, *aabb_box)) {
|
||||
building = entity;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (building) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (building) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!building) {
|
||||
bool is_collision = false;
|
||||
std::set<ColliderComponent*> colliders;
|
||||
map_service.GetColliders(pos.x, pos.y, colliders);
|
||||
for (ColliderComponent* collider : colliders) {
|
||||
if (collider->IntersectEx(pos, &target_collider)) {
|
||||
is_collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!is_collision) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<Human*>* Room::GetAliveTeam()
|
||||
{
|
||||
for (auto& pair : team_hash_) {
|
||||
@ -1116,7 +1198,6 @@ void Room::AirDrop(int appear_time, int box_id)
|
||||
a8::Vec2 dir = a8::Vec2::UP;
|
||||
dir.Rotate(a8::RandAngle());
|
||||
a8::Vec2 box_pos = gas_data.pos_new + dir * (500 + rand() % 300);
|
||||
#if 1
|
||||
if (box_pos.x < 1.0f) {
|
||||
box_pos.x = 1.0f;
|
||||
}
|
||||
@ -1129,7 +1210,21 @@ void Room::AirDrop(int appear_time, int box_id)
|
||||
if (box_pos.y >= MAP_HEIGHT) {
|
||||
box_pos.y = MAP_HEIGHT - 1;
|
||||
}
|
||||
#endif
|
||||
AabbCollider air_drop_aabb_box;
|
||||
{
|
||||
air_drop_aabb_box._min.x = box_pos.x - thing_meta->i->width()/2.0f;
|
||||
air_drop_aabb_box._min.y = box_pos.y - thing_meta->i->height()/2.0f;
|
||||
air_drop_aabb_box._max.x = box_pos.x + thing_meta->i->width()/2.0f;
|
||||
air_drop_aabb_box._max.y = box_pos.y + thing_meta->i->height()/2.0f;
|
||||
}
|
||||
Entity* target = FindFirstCollisonEntity(box_pos, air_drop_aabb_box);
|
||||
if (target) {
|
||||
float new_x = box_pos.x;
|
||||
float new_y = box_pos.y;
|
||||
FindLocationWithAabb(target, box_pos, &air_drop_aabb_box, new_x, new_y);
|
||||
box_pos.x = new_x;
|
||||
box_pos.y = new_y;
|
||||
}
|
||||
frame_event.AddAirDrop(appear_time, box_id, box_pos);
|
||||
xtimer.AddDeadLineTimerAndAttach(SERVER_FRAME_RATE * appear_time / 1000.f,
|
||||
a8::XParams()
|
||||
|
@ -30,6 +30,7 @@ class Human;
|
||||
class Player;
|
||||
class Building;
|
||||
class Hero;
|
||||
class AabbCollider;
|
||||
class Room
|
||||
{
|
||||
public:
|
||||
@ -93,6 +94,9 @@ public:
|
||||
std::set<Human*>* GetAliveTeam();
|
||||
bool CanJoin(const std::string& accountid);
|
||||
void OnPlayerOffline(Player* hum);
|
||||
Entity* FindFirstCollisonEntity(const a8::Vec2& aabb_pos, AabbCollider& aabb_box);
|
||||
void FindLocationWithAabb(Entity* target, const a8::Vec2& aabb_pos, AabbCollider* aabb_box,
|
||||
float& new_x, float& new_y);
|
||||
|
||||
private:
|
||||
int AllocUniid();
|
||||
|
Loading…
x
Reference in New Issue
Block a user