From 55ed1af4b6760859aeeec7792e124c4d20a64c39 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 14 May 2024 16:42:04 +0800 Subject: [PATCH] 1 --- server/gameserver/bullet.cc | 77 +++++++++++++++++++++++++++++++++- server/gameserver/bullet.h | 2 + server/gameserver/collision.cc | 22 ++++++++++ server/gameserver/collision.h | 6 +++ server/gameserver/room.cc | 11 +++++ server/gameserver/room.h | 1 + 6 files changed, 118 insertions(+), 1 deletion(-) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index a490339c..c3668963 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -32,6 +32,7 @@ #include "skill.h" #include "netdata.h" #include "cs_proto.pb.h" +#include "team.h" #include "mt/Param.h" #include "mt/Equip.h" @@ -99,12 +100,46 @@ void Bullet::Initialize() } } #endif + switch (gun_meta->equip_subtype()) { + case GUN_SUB_EQUIP_TYPE_FLY_LASER: + { + room->xtimer.SetTimeoutEx + (SERVER_FRAME_RATE * 2, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + ForceRemove(); + } + }, + &xtimer_attacher + ); + + room->xtimer.SetIntervalEx + (SERVER_FRAME_RATE, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (!later_removed_) { + ProcLaster(); + } + } + }, + &xtimer_attacher + ); + ProcLaster(); + } + break; + default: + { + } + break; + } } void Bullet::Update(int delta_time) { if (shot_animi_time <= (room->GetFrameNo() - create_frameno_) * FRAME_RATE_MS) { - if (!trace_target_id && !reporter_list && !IsClientHook()) { + if (!trace_target_id && !reporter_list && !IsClientHook() && !IsSpecBullet()) { MapServiceUpdate(); ++updated_times_; } @@ -1212,3 +1247,43 @@ bool Bullet::IsClientHook() return true; } } + +bool Bullet::IsSpecBullet() +{ + return (gun_meta->equip_subtype() == GUN_SUB_EQUIP_TYPE_FLY_LASER); +} + +void Bullet::ProcLaster() +{ + std::set objects; + room->TraverseCreatureList + ( + [this, &objects] (Creature* c) -> bool + { + if (!c->GetTeam() || c->GetTeam()->GetTeamId() == sender.Get()->GetTeam()->GetTeamId()) { + return true; + } + if (c->dead) { + return true; + } + if (c->IsInvincible()) { + return true; + } + glm::vec3 ray_orig = born_pos.ToGlmVec3(); + ray_orig.y = 0.0f; + glm::vec3 ray_dir = dir; + ray_dir.y = 0.0f; + glm::vec3 sphere_center = c->GetPos().ToGlmVec3(); + sphere_center.y = 0.0f; + + float intersection_distance = 0.0; + bool ret = Collision::IntersectRaySphere(GetHitRadius(), + ray_orig, ray_dir, sphere_center, c->GetHitRadius(), + intersection_distance); + if (ret) { + objects.insert(c); + } + return true; + }); + OnHit(objects); +} diff --git a/server/gameserver/bullet.h b/server/gameserver/bullet.h index 1a7c9115..2fafc127 100644 --- a/server/gameserver/bullet.h +++ b/server/gameserver/bullet.h @@ -82,6 +82,7 @@ protected: void ProcShieldWallBomb(int delay_time); void ProcOilBucketBomb(int delay_time); void ProcFlyHook(Entity* target); + void ProcLaster(); inline void MapServiceUpdate(); void Check(float distance); void AddGunBuff(); @@ -92,6 +93,7 @@ protected: void GetHitCreatures(BulletCheckResult& result); void Raycast(); bool IsClientHook(); + bool IsSpecBullet(); private: bool later_removed_ = false; diff --git a/server/gameserver/collision.cc b/server/gameserver/collision.cc index f62a48f1..e3956198 100644 --- a/server/gameserver/collision.cc +++ b/server/gameserver/collision.cc @@ -3,6 +3,9 @@ #include #include +#include +#include +#include #include "collision.h" #include "creature.h" @@ -141,6 +144,25 @@ bool Collision::Check2dRotationRectangle(float rx, float ry, float r, float dx, return (tmp_dx1 - new_rx) * (tmp_dx1 - new_rx) + (tmp_dy1 - new_ry) * (tmp_dy1 - new_ry) <= r * r; } +bool Collision::IntersectRaySphere(float ray_width, + glm::vec3 ray_starting, glm::vec3 ray_normalized_direction, + glm::vec3 sphere_center, float sphere_radius, + float &intersection_distance + ) +{ + ray_starting.y = 0.0f; + ray_normalized_direction.y = 0.0f; + sphere_center.y = 0.0f; + sphere_radius += ray_width * 0.5f; + + glm::vec3 intersection_position; + glm::vec3 intersection_normal; + + bool ret = glm::intersectRaySphere(ray_starting, ray_normalized_direction, sphere_center, sphere_radius, + intersection_position, intersection_normal); + return ret; +} + bool Collision::InSquare(const glm::vec3& center, const glm::vec3& pos, float side_len) { float x_distance = std::fabs(pos.x - center.x); diff --git a/server/gameserver/collision.h b/server/gameserver/collision.h index 07d2cf85..bb08592b 100644 --- a/server/gameserver/collision.h +++ b/server/gameserver/collision.h @@ -25,6 +25,12 @@ class Collision static bool Check2dRotationRectangle(float rx, float ry, float r, float dx, float dy, float dw, float dh, float dro); + static bool IntersectRaySphere(float ray_width, + glm::vec3 ray_starting, glm::vec3 ray_normalized_direction, + glm::vec3 sphere_center, float sphere_radius, + float &intersection_distance + ); + static bool InSquare(const glm::vec3& center, const glm::vec3& pos, float side_len); }; diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 85190afc..08669fbe 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -1282,6 +1282,17 @@ void Room::TraverseAliveHumanList(std::function func) } } +void Room::TraverseCreatureList(std::function func) +{ + for (auto& pair : moveable_hash_) { + if (pair.second && !pair.second->IsOb() && pair.second->IsCreature(this)) { + if (!func((Creature*)pair.second)) { + break; + } + } + } +} + void Room::TraverseEntityList(std::function func) { for (auto& pair : uniid_hash_) { diff --git a/server/gameserver/room.h b/server/gameserver/room.h index db4d54e9..0b252440 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -160,6 +160,7 @@ public: void TraverseAliveHumanList(std::function func); void TraverseEntityList(std::function func); void TraverseAlivePlayers(std::function func); + void TraverseCreatureList(std::function func); void BroadcastDebugMsg(const std::string& debug_msg); void ScatterDrop(const glm::vec3& center, int drop_id, bool no_adjust = false,