diff --git a/server/gameserver/building.cc b/server/gameserver/building.cc index 7841e9d..d0759d8 100644 --- a/server/gameserver/building.cc +++ b/server/gameserver/building.cc @@ -56,22 +56,6 @@ void Building::FillMFObjectFull(cs::MFObjectFull* full_data) p->set_building_id(meta->i->mapid()); } -ColliderComponent* Building::GetBoxBound() -{ - AabbCollider* collider = new AabbCollider(); - collider->active = true; - collider->owner = this; - collider->_min = Vector2D( - -meta->i->tilewidth()/2.0, - -meta->i->tileheight()/2.0 - ); - collider->_max = Vector2D( - meta->i->tilewidth()/2.0, - meta->i->tileheight()/2.0 - ); - return collider; -} - void Building::GetAabbBox(AabbCollider& aabb_box) { aabb_box.active = true; diff --git a/server/gameserver/building.h b/server/gameserver/building.h index cabf6e6..42a8e68 100644 --- a/server/gameserver/building.h +++ b/server/gameserver/building.h @@ -24,6 +24,5 @@ class Building : public Entity void RecalcSelfCollider(); virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override; virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override; - virtual ColliderComponent* GetBoxBound() override; virtual void GetAabbBox(AabbCollider& aabb_box) override; }; diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index bcec2dc..7caa5f0 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -256,15 +256,6 @@ void Bullet::MapServiceUpdate() for (ColliderComponent* collider : colliders) { if (TestCollision(collider)) { objects.insert(collider->owner); -#if 0 - a8::XPrintf("%d,%d collider:%d,%d \n", - { - pos.x, - pos.y, - collider->owner->pos.x, - collider->owner->pos.y - }); -#endif } } } diff --git a/server/gameserver/collider.cc b/server/gameserver/collider.cc index a90156e..a4ba4ef 100644 --- a/server/gameserver/collider.cc +++ b/server/gameserver/collider.cc @@ -107,7 +107,7 @@ bool ColliderComponent::CalcSafePoint(ColliderComponent* b, Vector2D& new_pos) switch (b->type) { case CT_Aabb: { - AabbCollider* b_aabb = (AabbCollider*)this; + AabbCollider* b_aabb = (AabbCollider*)b; return CalcAabbAabbSafePoint(a_aabb->owner->pos + a_aabb->_min, a_aabb->owner->pos + a_aabb->_max, b_aabb->owner->pos + b_aabb->_min, diff --git a/server/gameserver/collision.cc b/server/gameserver/collision.cc index 10fea5e..a7e93a4 100644 --- a/server/gameserver/collision.cc +++ b/server/gameserver/collision.cc @@ -143,12 +143,34 @@ bool CalcAabbAabbSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vecto Vector2D& new_pos) { Vector2D a_pos = a_min + (a_max - a_min)/2.0f; - float a_rad = (a_max - a_min).Norm(); - Vector2D b_pos = b_min + (b_max - b_min)/2.0f; - float b_rad = (b_max - b_min).Norm(); - Vector2D dir = (a_pos - b_pos); - dir.Normalize(); - new_pos = b_pos + dir*(a_rad + b_rad) + 1; + new_pos = a_pos; + bool at_left = std::abs(a_pos.x - b_min.x) < std::abs(a_pos.x - b_max.x); + bool at_down = std::abs(a_pos.y - b_min.y) < std::abs(a_pos.y - b_max.y); + float x_len = at_left ? std::abs(a_pos.x - b_min.x) : std::abs(a_pos.x - b_max.x); + float y_len = at_down ? std::abs(a_pos.y - b_min.y) : std::abs(a_pos.y - b_max.y); + if (at_left) { + if (x_len < y_len) { + //左 + new_pos.x = b_min.x - (a_max.x - a_min.x)/2.0f - 1; + } else { + if (at_down) { + new_pos.y = b_min.y - (a_max.y - a_min.y)/2.0f - 1; + } else { + new_pos.y = b_max.y + (a_max.y - a_min.y)/2.0f + 1; + } + } + } else { + if (x_len < y_len) { + //右 + new_pos.x = b_max.x + (a_max.x - a_min.x)/2.0f + 1; + } else { + if (at_down) { + new_pos.y = b_min.y - (a_max.y - a_min.y)/2.0f - 1; + } else { + new_pos.y = b_max.y + (a_max.y - a_min.y)/2.0f + 1; + } + } + } return true; } @@ -156,9 +178,33 @@ bool CalcAabbCircleSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_pos, flo Vector2D& new_pos) { Vector2D a_pos = a_min + (a_max - a_min)/2.0f; - float a_rad = (a_max - a_min).Norm(); - Vector2D dir = a_pos - b_pos; - dir.Normalize(); - new_pos = b_pos + dir*(a_rad + b_rad) + 1; + new_pos = a_pos; + bool at_left = std::abs(a_min.x - b_pos.x) < std::abs(a_max.x - b_pos.x); + bool at_down = std::abs(a_min.y - b_pos.y) < std::abs(a_max.y - b_pos.y); + float x_len = at_left ? std::abs(a_min.x - b_pos.x) : std::abs(a_max.x - b_pos.x); + float y_len = at_down ? std::abs(a_min.y - b_pos.y) : std::abs(a_max.y - b_pos.y); + if (at_left) { + if (x_len < y_len) { + //左 + new_pos.x = b_pos.x - (a_max.x - a_min.x)/2.0f - 1; + } else { + if (at_down) { + new_pos.y = b_pos.y - (a_max.y - a_min.y)/2.0f - 1; + } else { + new_pos.y = b_pos.y + (a_max.y - a_min.y)/2.0f + 1; + } + } + } else { + if (x_len < y_len) { + //右 + new_pos.x = b_pos.x + (a_max.x - a_min.x)/2.0f + 1; + } else { + if (at_down) { + new_pos.y = b_pos.y - (a_max.y - a_min.y)/2.0f - 1; + } else { + new_pos.y = b_pos.y + (a_max.y - a_min.y)/2.0f + 1; + } + } + } return true; } diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 31676f8..3c14c17 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -135,6 +135,33 @@ enum EquipAttr_e EA_End }; +enum EntityType_e +{ + ET_None = 0, + ET_Player = 1, + ET_Obstacle = 2, + ET_Building = 3, + //ET_LootSpawner = 4, + ET_Loot = 5, + //ET_DeadBody = 6, + //ET_Decal = 7, + //ET_Projectile = 8, + ET_Smoke = 9, + ET_Hero = 10, + + ET_Bullet = 20, + + ET_Android = 30, + ET_MAX +}; + +enum EntitySubType_e +{ + EST_None = 0, + EST_Player = 1, + EST_Android = 2, +}; + const char* const PROJ_NAME_FMT = "game%d_gameserver"; const char* const PROJ_ROOT_FMT = "/data/logs/%s"; @@ -172,4 +199,3 @@ const int MAX_INSTANCE_ID = 500; const int WALK_ZONE_WIDTH = 100; const int MAX_TEAM_NUM = 4; - diff --git a/server/gameserver/entity.cc b/server/gameserver/entity.cc index 3d23289..78e36ba 100644 --- a/server/gameserver/entity.cc +++ b/server/gameserver/entity.cc @@ -22,14 +22,6 @@ void Entity::Initialize() xtimer_attacher.xtimer = &room->xtimer; } -ColliderComponent* Entity::GetBoxBound() -{ - CircleCollider* collider = new CircleCollider(); - collider->active = true; - collider->owner = this; - return collider; -} - void Entity::GetAabbBox(AabbCollider& aabb_box) { aabb_box.active = true; @@ -80,45 +72,60 @@ void Entity::ClearColliders() void Entity::FindLocationWithTarget(Entity* target) { - ColliderComponent* a_collider = GetBoxBound(); Vector2D old_pos = pos; Vector2D new_pos = pos; - ColliderComponent* target_collider = target->GetBoxBound(); + AabbCollider a_collider; + GetAabbBox(a_collider); + AabbCollider target_collider; + target->GetAabbBox(target_collider); { - bool ret = a_collider->CalcSafePoint(target_collider, new_pos); + bool ret = a_collider.CalcSafePoint(&target_collider, new_pos); if (!ret) { abort(); } } Vector2D new_pos_dir = new_pos - old_pos; - float distance = (new_pos - old_pos).Norm(); new_pos_dir.Normalize(); - for (float i = distance; i < 10000000; i += 5.0f) { + float distance = (new_pos - old_pos).Norm(); + for (int i = distance; i < 10000000; i += 5) { pos = old_pos + new_pos_dir * i; + + Entity* building = nullptr; std::set new_grid_list; room->grid_service.GetAllCellsByXy(pos.x, pos.y, new_grid_list); - - std::vector objects; for (auto& grid : new_grid_list) { for (Entity* entity : grid->entity_list) { switch (entity->entity_type) { - case ET_Obstacle: + case ET_Building: { - if (entity != this && TestCollision(entity)){ - objects.push_back(entity); - break; + if (TestCollision(entity)) { + building = entity; } } break; - default: - { - } + } + if (building) { break; } } + if (building) { + break; + } } - if (objects.empty()) { - break; + + if (!building) { + bool is_collision = false; + std::set colliders; + room->map_service.GetColliders(pos.x, pos.y, colliders); + for (ColliderComponent* collider : colliders) { + if (TestCollision(collider)) { + is_collision = true; + break; + } + } + if (!is_collision) { + break; + } } } @@ -143,9 +150,6 @@ void Entity::FindLocationWithTarget(Entity* target) break; } } - - DestoryCollider(target_collider); - DestoryCollider(a_collider); } void Entity::BroadcastFullState() diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index 93c51ba..ba20dce 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -8,33 +8,6 @@ namespace cs class MFObjectFull; } -enum EntityType_e -{ - ET_None = 0, - ET_Player = 1, - ET_Obstacle = 2, - ET_Building = 3, - //ET_LootSpawner = 4, - ET_Loot = 5, - //ET_DeadBody = 6, - //ET_Decal = 7, - //ET_Projectile = 8, - ET_Smoke = 9, - ET_Hero = 10, - - ET_Bullet = 20, - - ET_Android = 30, - ET_MAX -}; - -enum EntitySubType_e -{ - EST_None = 0, - EST_Player = 1, - EST_Android = 2, -}; - class Room; class Obstacle; class ColliderComponent; @@ -66,7 +39,6 @@ class Entity virtual void FillMFObjectPart(cs::MFObjectPart* part_data) {}; virtual void FillMFObjectFull(cs::MFObjectFull* full_data) {}; virtual float GetSpeed() { return 1.0f;}; - virtual ColliderComponent* GetBoxBound(); virtual void GetAabbBox(AabbCollider& aabb_box); virtual void GetCircleBox(CircleCollider& circle_box); bool TestCollision(Entity* b); diff --git a/server/gameserver/hero.cc b/server/gameserver/hero.cc index ec1a32f..d3f80ba 100644 --- a/server/gameserver/hero.cc +++ b/server/gameserver/hero.cc @@ -55,12 +55,3 @@ void Hero::FillMFObjectFull(cs::MFObjectFull* full_data) weapon.ToPB(p->mutable_weapon()); p->set_energy_shield(energy_shield); } - -ColliderComponent* Hero::GetBoxBound() -{ - CircleCollider* collider = new CircleCollider(); - collider->owner = this; - collider->pos = Vector2D(); - collider->rad = master->GetRadius(); - return collider; -} diff --git a/server/gameserver/hero.h b/server/gameserver/hero.h index f7c1688..be41223 100644 --- a/server/gameserver/hero.h +++ b/server/gameserver/hero.h @@ -28,7 +28,6 @@ class Hero : public Entity void RecalcSelfCollider(); virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override; virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override; - virtual ColliderComponent* GetBoxBound() override; private: CircleCollider* self_collider_ = nullptr; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 66c2624..3fb5abe 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -142,15 +142,6 @@ void Human::FillMFObjectFull(cs::MFObjectFull* full_data) FillBodyState(p->mutable_states()); } -ColliderComponent* Human::GetBoxBound() -{ - CircleCollider* collider = new CircleCollider(); - collider->owner = this; - collider->pos = Vector2D(); - collider->rad = GetRadius(); - return collider; -} - void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb) { stats_pb->set_player_id(entity_uniid); @@ -180,6 +171,19 @@ void Human::FillMFPlayerStats(cs::MFPlayerStats* stats_pb) stats_pb->set_account_id(account_id); } +void Human::GetAabbBox(AabbCollider& aabb_box) +{ + if (!meta) { + abort(); + } + aabb_box.active = true; + aabb_box.owner = this; + aabb_box._min.x = -meta->i->radius(); + aabb_box._min.y = -meta->i->radius(); + aabb_box._max.x = meta->i->radius(); + aabb_box._max.y = meta->i->radius(); +} + void Human::FillMFTeamData(cs::MFTeamData* team_data) { team_data->set_player_id(entity_uniid); @@ -1138,70 +1142,34 @@ void Human::DoSkill() void Human::FindLocation() { - { - std::vector objects; - room->BuildingBoxBoundCollisionDetection(this, objects); - if (objects.size() > 1) { - #if 0 - abort(); - #endif - } - if (!objects.empty()) { - Building* building = (Building*)objects[0]; - Vector2D b_min = Vector2D( - building->pos.x - building->meta->i->tilewidth()/2.0, - building->pos.y - building->meta->i->tileheight()/2.0 - ); - Vector2D b_max = Vector2D( - building->pos.x + building->meta->i->tilewidth()/2.0, - building->pos.y + building->meta->i->tileheight()/2.0 - ); - Vector2D new_pos; - bool ret = CalcCircleAabbSafePoint( - pos, - GetRadius(), - b_min, - b_max, - new_pos - ); - if (!ret) { - abort(); - } - if (ret) { - pos = new_pos; - room->grid_service.MoveHuman(this); - return; + Entity* target = nullptr; + for (auto& grid : grid_list) { + for (Entity* entity : grid->entity_list) { + switch (entity->entity_type) { + case ET_Obstacle: + { + if (!target) { + if (TestCollision(entity)) { + target = entity; + } + } + } + break; + case ET_Building: + { + if (!target || target->entity_type != ET_Building) { + AabbCollider aabb_box; + entity->GetAabbBox(aabb_box); + if (TestCollision(&aabb_box)) { + target = entity; + } + } + } + break; } } } - { - std::vector objects; - for (auto& grid : grid_list) { - for (Entity* entity : grid->entity_list) { - switch (entity->entity_type) { - case ET_Obstacle: - { - if (TestCollision(entity)){ - objects.push_back(entity); - } - } - break; - default: - { - } - break; - } - } - } - if (objects.empty()) { - return; - } - std::sort(objects.begin(), objects.end(), - [this] (Entity* a, Entity *b) -> bool - { - return (this->pos - a->pos).Norm() < (this->pos - b->pos).Norm(); - }); - Entity* target = objects[0]; + if (target) { FindLocationWithTarget(target); } } diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 3982bcd..a332a96 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -122,8 +122,8 @@ class Human : public Entity virtual float GetSpeed4(); virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override; virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override; - virtual ColliderComponent* GetBoxBound() override; virtual void FillMFPlayerStats(cs::MFPlayerStats* stats); + virtual void GetAabbBox(AabbCollider& aabb_box); void FillMFTeamData(cs::MFTeamData* team_data); void Shot(Vector2D& target_dir); void RecalcSelfCollider(); diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index 2bb2b66..a0e931c 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -132,21 +132,6 @@ void Obstacle::FillMFObjectFull(cs::MFObjectFull* full_data) } } -ColliderComponent* Obstacle::GetBoxBound() -{ - if (self_collider_) { - CircleCollider* collider = new CircleCollider(); - *collider = *self_collider_; - return collider; - } - if (self_collider2_) { - AabbCollider* collider = new AabbCollider(); - *collider = *self_collider2_; - return collider; - } - return nullptr; -} - void Obstacle::GetAabbBox(AabbCollider& aabb_box) { if (self_collider2_) { diff --git a/server/gameserver/obstacle.h b/server/gameserver/obstacle.h index 4d8a47a..d2c9fdd 100644 --- a/server/gameserver/obstacle.h +++ b/server/gameserver/obstacle.h @@ -41,7 +41,6 @@ class Obstacle : public Entity void RecalcSelfCollider(); virtual void FillMFObjectPart(cs::MFObjectPart* part_data) override; virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override; - virtual ColliderComponent* GetBoxBound() override; virtual void GetAabbBox(AabbCollider& aabb_box) override; virtual void GetCircleBox(CircleCollider& circle_box) override; void Explosion(Bullet* bullet); diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 5ef6103..a336375 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -324,21 +324,6 @@ Human* Room::FindEnemy(Human* hum) return !enemys.empty() ? enemys[0] : nullptr; } -void Room::BuildingBoxBoundCollisionDetection(Entity* sender, std::vector& objects) -{ - ColliderComponent* a_collider = sender->GetBoxBound(); - for (auto& pair : uniid_hash_) { - if (pair.second->entity_type == ET_Building) { - ColliderComponent* target_collider = pair.second->GetBoxBound(); - if (a_collider->Intersect(target_collider)) { - objects.push_back(pair.second); - } - DestoryCollider(target_collider); - } - } - DestoryCollider(a_collider); -} - void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg) { msg.set_team_mode(msg.team_mode()); @@ -873,9 +858,9 @@ void Room::UpdateGas() { if (a8::HasBitFlag(hum->status, HS_Fly)) { hum->DoJump(); - if (hum->entity_subtype == EST_Player) { - GameLog::Instance()->GameStart((Player*)hum); - } + } + if (hum->entity_subtype == EST_Player) { + GameLog::Instance()->GameStart((Player*)hum); } return true; }); diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 10479d8..0862b66 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -62,7 +62,6 @@ public: void AddPlayer(Player* hum); Human* FindEnemy(Human* hum); - void BuildingBoxBoundCollisionDetection(Entity* sender, std::vector& objects); void RemoveObjectLater(Entity* entity); void FetchBuilding(Human* hum);