From ce3715d80f411b3e0faaab87bc00af0adced8d15 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 20 Apr 2021 14:33:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AC=E5=94=A4=E8=8B=B1=E9=9B=84Ok?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/creature.cc | 98 ++++++++++++++++----------------- server/gameserver/creature.h | 6 +- server/gameserver/mapservice.cc | 40 ++++++++++++++ server/gameserver/mapservice.h | 4 ++ server/gameserver/metadata.cc | 18 ++++++ server/gameserver/metadata.h | 1 + server/gameserver/room.cc | 84 +++++++++++++++++++++------- server/gameserver/room.h | 3 +- 8 files changed, 183 insertions(+), 71 deletions(-) diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index bf2bef6..518cb7b 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -37,7 +37,7 @@ void InternalShot(Creature* c, a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple)); bullet_born_offset.Rotate(c->attack_dir.CalcAngle(a8::Vec2::UP)); a8::Vec2 bullet_born_pos = c->GetPos() + bullet_born_offset; - if (c->room->OverBorder(bullet_born_pos, 0)) { + if (c->room->OverBorder(bullet_born_pos, 0.0f)) { return; } } @@ -846,7 +846,9 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff) break; case kBET_SummonHero: { - buff->ProcSummonHero(caster); + SummonHero(GetPos(), + GetMoveDir(), + buff->meta->hero_infos); } break; case kBET_Shield: @@ -1377,45 +1379,17 @@ RoomObstacle* Creature::SummonObstacle(int id, const a8::Vec2& pos) bool Creature::CollisonDetection() { - if (room->OverBorder(GetPos(), GetRadius())){ - return true; - } - if (HasBuffEffect(kBET_ThroughWall) || - HasBuffEffect(kBET_Fly)) { - return false; - } - - std::set colliders; - room->map_service->GetColliders(room, GetX(), GetY(), colliders); - + bool through_wall = HasBuffEffect(kBET_ThroughWall) || + HasBuffEffect(kBET_Fly); AabbCollider aabb_box; GetAabbBox(aabb_box); - for (ColliderComponent* collider : colliders) { - switch (collider->owner->GetEntityType()) { - case ET_Obstacle: - { - Obstacle* obstacle = (Obstacle*)collider->owner; - if (!obstacle->IsDead(room) && - (collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) - ) { - return true; - } - } - break; - case ET_Building: - { - if ( - (collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) - ) { - return true; - } - } - break; - default: - break; - } - } - return false; + return room->map_service->CollisionDetection + ( + room, + through_wall, + GetPos(), + &aabb_box + ); } void Creature::FillSkillCasterState(SkillCasterState* caster_state) @@ -1514,16 +1488,42 @@ void Creature::ResetAllSkillCd() } } -void Creature::SummonHero(const a8::Vec2& pos, int hero_id, int hero_num) +void Creature::SummonHero(const a8::Vec2& pos, + const a8::Vec2& dir, + std::vector>& infos) { - MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id); - if (hero_meta && hero_num > 0 && !dead) { - Hero* hero = room->CreateHero - (this, - hero_meta, - GetPos(), - GetMoveDir(), - team_id - ); + for (auto& info : infos) { + int through_wall = std::get<0>(info); + float x = std::get<1>(info); + float y = std::get<2>(info) ; + int hero_id = std::get<3>(info); + MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id); + if (hero_meta && !dead) { + for (int i = 0; i < 4; ++i) { + a8::Vec2 born_dir = dir; + a8::Vec2 born_offset(x, y); + born_offset.Rotate(born_dir.CalcAngle(a8::Vec2::UP)); + born_offset.Rotate(i * 0.5); + a8::Vec2 hero_pos = pos + born_offset; + CircleCollider collider; + collider.pos = hero_pos; + collider.rad = hero_meta->i->radius(); + if (!room->map_service->CollisionDetection + ( + room, + through_wall, + hero_pos, + &collider + )) { + Hero* hero = room->CreateHero + (this, + hero_meta, + hero_pos, + dir, + team_id + ); + } + } + } } } diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 9d95894..8555150 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -131,9 +131,11 @@ class Creature : public MoveableEntity virtual void _UpdateMove(int speed) {}; void CheckSpecObject(); - RoomObstacle* SummonObstacle(int id, const a8::Vec2& pos); - void SummonHero(const a8::Vec2& pos, int hero_id, int hero_num); bool CollisonDetection(); + RoomObstacle* SummonObstacle(int id, const a8::Vec2& pos); + void SummonHero(const a8::Vec2& pos, + const a8::Vec2& dir, + std::vector>& infos); void FillSkillCasterState(SkillCasterState* caster_state); void RecoverSkillCasterState(SkillCasterState* caster_state); CreatureWeakPtr AllocWeakPtr(); diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index 3af8fd4..0a086df 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -7,6 +7,7 @@ #include "collider.h" #include "entity.h" #include "roomobstacle.h" +#include "room.h" MapService::MapService() { @@ -284,3 +285,42 @@ void MapService::RemoveFindPathRequest(Human* hum, int query_id) { } + +bool MapService::CollisionDetection(Room* room, + bool through_wall, + const a8::Vec2& pos, + ColliderComponent* a_collider) +{ + if (room->OverBorder(pos, a_collider)){ + return true; + } + if (through_wall) { + return false; + } + + std::set colliders; + GetColliders(room, pos.x, pos.y, colliders); + + for (ColliderComponent* collider : colliders) { + switch (collider->owner->GetEntityType()) { + case ET_Obstacle: + { + Obstacle* obstacle = (Obstacle*)collider->owner; + if (!obstacle->IsDead(room) && collider->IntersectEx(pos, a_collider)) { + return true; + } + } + break; + case ET_Building: + { + if (collider->IntersectEx(pos, a_collider)) { + return true; + } + } + break; + default: + break; + } + } + return false; +} diff --git a/server/gameserver/mapservice.h b/server/gameserver/mapservice.h index f7d81bf..5b4a3b2 100644 --- a/server/gameserver/mapservice.h +++ b/server/gameserver/mapservice.h @@ -54,6 +54,10 @@ class MapService int max_step_num); FindPathStatus* QueryFindPathStatus(int query_id); void RemoveFindPathRequest(Human* hum, int query_id); + bool CollisionDetection(Room* room, + bool through_wall, + const a8::Vec2& pos, + ColliderComponent* collider); private: int GetGridId(float world_x, float world_y); diff --git a/server/gameserver/metadata.cc b/server/gameserver/metadata.cc index c2a69c0..b39cee2 100644 --- a/server/gameserver/metadata.cc +++ b/server/gameserver/metadata.cc @@ -566,6 +566,24 @@ namespace MetaData } } } + { + std::vector strings; + a8::Split(i->post_remove_action(), strings, '|'); + for (auto& str : strings) { + std::vector strings2; + a8::Split(str, strings2, ':'); + if (strings2.size() > 4) { + int through_wall = a8::XValue(strings2[0]); + float x = a8::XValue(strings2[1]).GetDouble(); + float y = a8::XValue(strings2[2]).GetDouble(); + int hero_id = a8::XValue(strings2[3]); + hero_infos.push_back + ( + std::make_tuple(through_wall, x, y, hero_id) + ); + } + } + } if (i->buff_effect() == kBET_BatchAddBuff) { std::vector strings1; a8::Split(i->buff_param1(), strings1, '|'); diff --git a/server/gameserver/metadata.h b/server/gameserver/metadata.h index c6d9790..ada7b02 100755 --- a/server/gameserver/metadata.h +++ b/server/gameserver/metadata.h @@ -174,6 +174,7 @@ namespace MetaData std::vector>>> batch_add_list; std::vector>> post_remove_action; std::set immune_buffeffect; + std::vector> hero_infos; }; struct SkillPhase diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 0d29afd..5dd2255 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -745,29 +745,75 @@ void Room::OnHumanRevive(Human* hum) NotifyUiUpdate(); } -bool Room::OverBorder(const a8::Vec2 pos, float radius) +bool Room::OverBorder(const a8::Vec2& pos, float radius) { - //检查x轴 - { - int left_x = pos.x - radius; - if (left_x < 0.001f) { - return true; + CircleCollider collider; + collider.pos = pos; + collider.rad = radius; + return OverBorder(pos, &collider); +} + +bool Room::OverBorder(const a8::Vec2& pos, ColliderComponent* collider) +{ + switch (collider->type) { + case CT_Aabb: + { + AabbCollider* aabb_box = (AabbCollider*)collider; + //检查x轴 + { + float left_x = (pos + aabb_box->_min).x; + if (left_x < 0.001f) { + return true; + } + float right_x = (pos + aabb_box->_max).x; + if (right_x > map_meta_->i->map_width()) { + return true; + } + } + //检查y轴 + { + float down_y = (pos + aabb_box->_min).y; + if (down_y < 0.001f) { + return true; + } + float up_y = (pos + aabb_box->_max).y; + if (up_y > map_meta_->i->map_height()) { + return true; + } + } } - int right_x = pos.x + radius; - if (right_x > map_meta_->i->map_width()) { - return true; + break; + case CT_Circle: + { + CircleCollider* circle_collider = (CircleCollider*)collider; + //检查x轴 + { + float left_x = pos.x - circle_collider->rad; + if (left_x < 0.001f) { + return true; + } + float right_x = pos.x + circle_collider->rad; + if (right_x > map_meta_->i->map_width()) { + return true; + } + } + //检查y轴 + { + float down_y = pos.y - circle_collider->rad; + if (down_y < 0.001f) { + return true; + } + float up_y = pos.y + circle_collider->rad; + if (up_y > map_meta_->i->map_height()) { + return true; + } + } } - } - //检查y轴 - { - int up_y = pos.y + radius; - if (up_y > map_meta_->i->map_height()) { - return true; - } - int down_y = pos.y - radius; - if (down_y < 0.001f) { - return true; + break; + default: + { } + break; } return false; } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 8703f1d..467906e 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -129,7 +129,8 @@ public: void OnHumanDie(Human* hum); void OnHumanRevive(Human* hum); - bool OverBorder(const a8::Vec2 pos, float radius); + bool OverBorder(const a8::Vec2& pos, float radius); + bool OverBorder(const a8::Vec2& pos, ColliderComponent* collider); Human* GetWatchWarTarget(Human* hum); bool BattleStarted(); int GetAliveTeamNum();