diff --git a/server/server.cpp b/server/server.cpp index db50b1a..cc65de9 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -689,13 +689,15 @@ void Server::update_world() { std::vector boxesToRespawn; - // --- Tick: box-projectile collisions --- { + std::vector localBoxDestructions; + std::lock_guard bm(g_boxes_mutex); + std::lock_guard pm(g_projectiles_mutex); - - std::vector> boxProjectileCollisions; + std::vector projectilesToRemove; + std::vector projectileUsed(g_projectiles.size(), 0); for (size_t bi = 0; bi < g_serverBoxes.size(); ++bi) { if (g_serverBoxes[bi].destroyed) continue; @@ -703,37 +705,58 @@ void Server::update_world() { Eigen::Vector3f boxWorld = g_serverBoxes[bi].position + Eigen::Vector3f(0.0f, 0.0f, 45000.0f); for (size_t pi = 0; pi < g_projectiles.size(); ++pi) { + if (projectileUsed[pi]) continue; + const auto& pr = g_projectiles[pi]; Eigen::Vector3f diff = pr.pos - boxWorld; - float thresh = boxCollisionRadius + projectileHitRadius; + + float thresh = g_serverBoxes[bi].collisionRadius + projectileHitRadius; if (diff.squaredNorm() <= thresh * thresh) { - boxProjectileCollisions.push_back({ bi, pi }); + g_serverBoxes[bi].destroyed = true; + + BoxDestroyedInfo destruction; + destruction.boxIndex = static_cast(bi); + destruction.serverTime = now_ms; + destruction.position = boxWorld; + destruction.destroyedBy = pr.shooterId; + + localBoxDestructions.push_back(destruction); + boxesToRespawn.push_back(static_cast(bi)); + + projectileUsed[pi] = 1; + projectilesToRemove.push_back(static_cast(pi)); + + std::cout << "Server: Box " << bi + << " destroyed by projectile from player " + << pr.shooterId << std::endl; + + break; // одна пуля уничтожает только одну коробку } } } - for (const auto& [boxIdx, projIdx] : boxProjectileCollisions) { - if (g_serverBoxes[boxIdx].destroyed) continue; - g_serverBoxes[boxIdx].destroyed = true; + if (!projectilesToRemove.empty()) { + std::sort(projectilesToRemove.rbegin(), projectilesToRemove.rend()); + projectilesToRemove.erase( + std::unique(projectilesToRemove.begin(), projectilesToRemove.end()), + projectilesToRemove.end() + ); - Eigen::Vector3f boxWorld = g_serverBoxes[boxIdx].position + Eigen::Vector3f(0.0f, 0.0f, 45000.0f); - - BoxDestroyedInfo destruction; - destruction.boxIndex = static_cast(boxIdx); - destruction.serverTime = now_ms; - destruction.position = boxWorld; - destruction.destroyedBy = g_projectiles[projIdx].shooterId; - - { - std::lock_guard dm(g_boxDestructions_mutex); - g_boxDestructions.push_back(destruction); + for (int idx : projectilesToRemove) { + if (idx >= 0 && idx < (int)g_projectiles.size()) { + g_projectiles.erase(g_projectiles.begin() + idx); + } } + } - boxesToRespawn.push_back(static_cast(boxIdx)); - - std::cout << "Server: Box " << boxIdx << " destroyed by projectile from player " - << g_projectiles[projIdx].shooterId << std::endl; + if (!localBoxDestructions.empty()) { + std::lock_guard dm(g_boxDestructions_mutex); + g_boxDestructions.insert( + g_boxDestructions.end(), + localBoxDestructions.begin(), + localBoxDestructions.end() + ); } } @@ -759,7 +782,7 @@ void Server::update_world() { if (!session->fetchStateAtTime(now, shipState)) continue; Eigen::Vector3f diff = shipState.position - boxWorld; - float thresh = shipCollisionRadius + boxCollisionRadius; + float thresh = shipCollisionRadius + g_serverBoxes[bi].collisionRadius; if (diff.squaredNorm() <= thresh * thresh) { g_serverBoxes[bi].destroyed = true; diff --git a/server/server.h b/server/server.h index a53ee50..ba3ad11 100644 --- a/server/server.h +++ b/server/server.h @@ -38,7 +38,7 @@ struct DeathInfo { struct ServerBox { Eigen::Vector3f position; Eigen::Matrix3f rotation; - float collisionRadius = 2.0f; + float collisionRadius = 1.0f; bool destroyed = false; }; diff --git a/src/Space.cpp b/src/Space.cpp index 84de330..41f9d53 100644 --- a/src/Space.cpp +++ b/src/Space.cpp @@ -1598,11 +1598,7 @@ namespace ZL this->fireProjectiles(); - Eigen::Vector3f localForward = { 0, 0, -1 }; - Eigen::Vector3f worldForward = (Environment::shipState.rotation * localForward).normalized(); - - Eigen::Vector3f centerPos = Environment::shipState.position + - Environment::shipState.rotation * Vector3f{ 0, 0.9f - 6.0f, 5.0f }; + Eigen::Vector3f shipPos = Environment::shipState.position; Eigen::Quaternionf q(Environment::shipState.rotation); float speedToSend = projectileSpeed + Environment::shipState.velocity; @@ -1610,9 +1606,9 @@ namespace ZL std::string fireMsg = "FIRE:" + std::to_string(now_ms) + ":" + - std::to_string(centerPos.x()) + ":" + - std::to_string(centerPos.y()) + ":" + - std::to_string(centerPos.z()) + ":" + + std::to_string(shipPos.x()) + ":" + + std::to_string(shipPos.y()) + ":" + + std::to_string(shipPos.z()) + ":" + std::to_string(q.w()) + ":" + std::to_string(q.x()) + ":" + std::to_string(q.y()) + ":" +