From d7e1777e1edeaa7b65ed605e2bf552be15852900 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 1 Jul 2021 17:55:30 +0800 Subject: [PATCH] 1 --- server/gameserver/bullet.cc | 1 + server/gameserver/creature.cc | 63 ++++++++++++++++++++++++++------- server/gameserver/creature.h | 3 +- server/gameserver/entity.cc | 35 +++++++++++++++++- server/gameserver/entity.h | 2 ++ server/gameserver/mapservice.cc | 23 ++++++++++++ server/gameserver/mapservice.h | 5 +++ 7 files changed, 117 insertions(+), 15 deletions(-) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index da36d76..24ec824 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -103,6 +103,7 @@ void Bullet::ProcBomb() switch (entity->GetEntityType()) { case ET_Obstacle: case ET_Building: + case ET_Dummy: { if (TestCollision(room, entity)) { objects.insert(entity); diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 38f6beb..a68393e 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -1625,17 +1625,24 @@ void Creature::SummonObstacle(Buff* buff, int id, const a8::Vec2& pos) } bool Creature::CollisonDetection() +{ + ColliderComponent* pickup_collider = nullptr; + return CollisonDetectionAndGetCollider(&pickup_collider); +} + +bool Creature::CollisonDetectionAndGetCollider(ColliderComponent** pickup_collider) { bool through_wall = HasBuffEffect(kBET_ThroughWall) || HasBuffEffect(kBET_Fly); AabbCollider aabb_box; GetAabbBox(aabb_box); - return room->map_service->CollisionDetection + return room->map_service->CollisionDetectionAndGetCollider ( room, through_wall, GetPos(), - &aabb_box + &aabb_box, + pickup_collider ); } @@ -1949,18 +1956,25 @@ void Creature::SetInfiniteBulletMode() inventory_[IS_RPG].num = FIGHTING_MODE_BULLET_NUM; } -void Creature::FindLocationWithTarget(Entity* target) +void Creature::FindLocationWithTarget(Entity* target, ColliderComponent* target_collider) { a8::Vec2 old_pos = GetPos(); a8::Vec2 new_pos = GetPos(); AabbCollider a_collider; GetAabbBox(a_collider); - AabbCollider target_collider; - target->GetAabbBox(target_collider); { - bool ret = a_collider.CalcSafePoint(&target_collider, new_pos); - if (!ret) { - abort(); + if (target_collider) { + bool ret = a_collider.CalcSafePoint(target_collider, new_pos); + if (!ret) { + abort(); + } + } else { + AabbCollider aabb_collider; + target->GetAabbBox(aabb_collider); + bool ret = a_collider.CalcSafePoint(&aabb_collider, new_pos); + if (!ret) { + abort(); + } } } a8::Vec2 new_pos_dir = new_pos - old_pos; @@ -2014,16 +2028,20 @@ void Creature::FindLocationWithTarget(Entity* target) void Creature::FindLocation() { Entity* target = nullptr; + ColliderComponent* target_collider = nullptr; TraverseAllLayerEntityList ( - [this, &target] (Entity* entity, bool& stop) + [this, &target, &target_collider] (Entity* entity, bool& stop) { + ColliderComponent* collider = nullptr; switch (entity->GetEntityType()) { case ET_Obstacle: { if (!target) { - if (TestCollision(room, entity)) { + collider = TestCollisionAndGetCollider(room, entity); + if (collider) { target = entity; + target_collider = collider; } } } @@ -2033,15 +2051,23 @@ void Creature::FindLocation() if (!target || !target->IsEntityType(ET_Building)) { AabbCollider aabb_box; entity->GetAabbBox(aabb_box); - if (TestCollision(room, &aabb_box)) { + collider = TestCollisionAndGetCollider(room, &aabb_box); + if (collider) { target = entity; + target_collider = nullptr; } } } break; case ET_Dummy: { - + if (!target) { + collider = TestCollisionAndGetCollider(room, entity); + if (collider) { + target = entity; + target_collider = collider; + } + } } break; default: @@ -2051,7 +2077,7 @@ void Creature::FindLocation() } }); if (target) { - FindLocationWithTarget(target); + FindLocationWithTarget(target, target_collider); } } @@ -2128,6 +2154,17 @@ bool Creature::CheckCollision() } } break; + case ET_Dummy: + { + if ( + (collider->type == CT_Aabb && aabb_box.Intersect(collider)) || + (collider->type == CT_Circle && self_collider_->Intersect(collider)) + ) { + Global::last_collider = collider; + return true; + } + } + break; default: { } diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 16dd2cf..81dbae8 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -170,6 +170,7 @@ class Creature : public MoveableEntity void CheckSpecObject(); bool CollisonDetection(); + bool CollisonDetectionAndGetCollider(ColliderComponent** pickup_collider); void SummonObstacle(Buff* buff, int id, const a8::Vec2& pos); void SummonHero(Buff* buff, const a8::Vec2& pos, const a8::Vec2& dir); void FillSkillCasterState(SkillCasterState* caster_state); @@ -192,7 +193,7 @@ class Creature : public MoveableEntity bool TryMove(const a8::Vec2& target_pos, a8::Vec2& out_pos); void SetInfiniteBulletMode(); void FindLocation(); - void FindLocationWithTarget(Entity* target); + void FindLocationWithTarget(Entity* target, ColliderComponent* target_collider); Entity* GetLastCollisionDoor() { return last_collision_door_; } void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; } bool CheckCollision(); diff --git a/server/gameserver/entity.cc b/server/gameserver/entity.cc index 652fc15..895718d 100644 --- a/server/gameserver/entity.cc +++ b/server/gameserver/entity.cc @@ -53,7 +53,25 @@ bool Entity::TestCollision(Room* room, Entity* b) return false; } -bool Entity::TestCollision(Room* room,ColliderComponent* b) +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; @@ -68,6 +86,21 @@ bool Entity::TestCollision(Room* room,ColliderComponent* b) 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); diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index e4e0d77..2b16784 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -48,7 +48,9 @@ class Entity { return subtype == entity_subtype_;} int GetGridId() const { return grid_id_; } bool TestCollision(Room* room, Entity* b); + ColliderComponent* TestCollisionAndGetCollider(Room* room, Entity* b); bool TestCollision(Room* room, ColliderComponent* b); + ColliderComponent* TestCollisionAndGetCollider(Room* room, ColliderComponent* b); bool TestCollisionEx(Room* room, const a8::Vec2& aabb_pos, AabbCollider& aabb_box); void BroadcastFullState(Room* room); void BroadcastDeleteState(Room* room); diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index b1ccc03..325672f 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -72,6 +72,7 @@ void MapService::UnInit() void MapService::AddCollider(ColliderComponent* collider) { if (!(collider->owner->IsEntityType(ET_Obstacle) || + collider->owner->IsEntityType(ET_Dummy) || collider->owner->IsEntityType(ET_Building))) { abort(); } @@ -221,6 +222,7 @@ void MapService::GetColliders(Room* room, } break; case ET_Building: + case ET_Dummy: { colliders.insert(node->collider); } @@ -292,6 +294,24 @@ bool MapService::CollisionDetection(Room* room, const a8::Vec2& pos, ColliderComponent* a_collider) { + ColliderComponent* pickup_collider = nullptr; + return CollisionDetectionAndGetCollider + ( + room, + through_wall, + pos, + a_collider, + &pickup_collider + ); +} + +bool MapService::CollisionDetectionAndGetCollider(Room* room, + bool through_wall, + const a8::Vec2& pos, + ColliderComponent* a_collider, + ColliderComponent** pickup_collider) +{ + *pickup_collider = nullptr; if (room->OverBorder(pos, a_collider)){ return true; } @@ -309,14 +329,17 @@ bool MapService::CollisionDetection(Room* room, Obstacle* obstacle = (Obstacle*)collider->owner; if (obstacle->meta->i->collision_hit() != kCollisionHitPass) { if (!obstacle->IsDead(room) && collider->IntersectEx(pos, a_collider)) { + *pickup_collider = collider; return true; } } } break; case ET_Building: + case ET_Dummy: { if (collider->IntersectEx(pos, a_collider)) { + *pickup_collider = collider; return true; } } diff --git a/server/gameserver/mapservice.h b/server/gameserver/mapservice.h index 5b4a3b2..9f20a9e 100644 --- a/server/gameserver/mapservice.h +++ b/server/gameserver/mapservice.h @@ -58,6 +58,11 @@ class MapService bool through_wall, const a8::Vec2& pos, ColliderComponent* collider); + bool CollisionDetectionAndGetCollider(Room* room, + bool through_wall, + const a8::Vec2& pos, + ColliderComponent* collider, + ColliderComponent** pickup_collider); private: int GetGridId(float world_x, float world_y);