diff --git a/server/server.cpp b/server/server.cpp index 463d04b..75d8874 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -82,7 +82,7 @@ class Session : public std::enable_shared_from_this { timedClientStates.add_state(receivedState); } else if (parts[0] == "FIRE") { - if (parts.size() < 8) { + if (parts.size() < 10) { std::cerr << "Invalid FIRE: too few parts\n"; return; } @@ -91,17 +91,19 @@ class Session : public std::enable_shared_from_this { Eigen::Vector3f pos{ std::stof(parts[2]), std::stof(parts[3]), std::stof(parts[4]) }; - Eigen::Vector3f dir{ - std::stof(parts[5]), std::stof(parts[6]), std::stof(parts[7]) + Eigen::Quaternion dir{ + std::stof(parts[5]), std::stof(parts[6]), std::stof(parts[7]), std::stof(parts[8]) }; - int shotCount = 1; - if (parts.size() >= 9) { + float velocity = std::stof(parts[9]); + + int shotCount = 2; + if (parts.size() >= 11) { try { - shotCount = std::stoi(parts[8]); + shotCount = std::stoi(parts[10]); } catch (...) { - shotCount = 1; + shotCount = 2; } } @@ -111,9 +113,11 @@ class Session : public std::enable_shared_from_this { std::to_string(pos.x()) + ":" + std::to_string(pos.y()) + ":" + std::to_string(pos.z()) + ":" + + std::to_string(dir.w()) + ":" + std::to_string(dir.x()) + ":" + std::to_string(dir.y()) + ":" + std::to_string(dir.z()) + ":" + + std::to_string(velocity) + ":" + std::to_string(shotCount); std::lock_guard lock(g_sessions_mutex); diff --git a/src/Game.cpp b/src/Game.cpp index 2e7aa41..6f50d2a 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -236,6 +236,7 @@ namespace ZL uint64_t now = SDL_GetTicks64(); if (now - lastProjectileFireTime >= static_cast(projectileCooldownMs)) { lastProjectileFireTime = now; + const float projectileSpeed = 60.0f; this->fireProjectiles(); @@ -245,15 +246,21 @@ namespace ZL Eigen::Vector3f centerPos = Environment::shipState.position + Environment::shipState.rotation * Vector3f{ 0, 0.9f, 5.0f }; + Eigen::Quaternionf q(Environment::shipState.rotation); + float speedToSend = projectileSpeed + Environment::shipState.velocity; + int shotCount = 2; + std::string fireMsg = "FIRE:" + std::to_string(now) + ":" + std::to_string(centerPos.x()) + ":" + std::to_string(centerPos.y()) + ":" + std::to_string(centerPos.z()) + ":" + - std::to_string(worldForward.x()) + ":" + - std::to_string(worldForward.y()) + ":" + - std::to_string(worldForward.z()) + ":" + - "2"; + std::to_string(q.w()) + ":" + + std::to_string(q.x()) + ":" + + std::to_string(q.y()) + ":" + + std::to_string(q.z()) + ":" + + std::to_string(speedToSend) + ":" + + std::to_string(shotCount); networkClient->Send(fireMsg); } @@ -1149,7 +1156,37 @@ namespace ZL const float projectileSpeed = 60.0f; const float lifeMs = 5000.0f; const float size = 0.5f; + for (const auto& pi : pending) { + const std::vector localOffsets = { + Vector3f{ -1.5f, 0.9f, 5.0f }, + Vector3f{ 1.5f, 0.9f, 5.0f } + //Vector3f{}, + //Vector3f{} + }; + Vector3f localForward = { 0, 0, -1 }; + Vector3f worldForward = pi.rotation * localForward; + + float len = worldForward.norm(); + if (len <= 1e-6f) { + continue; + } + worldForward /= len; + + Vector3f baseVel = worldForward * pi.velocity; + + for (const auto& off : localOffsets) { + Vector3f shotPos = pi.position + (pi.rotation * off); + + for (auto& p : projectiles) { + if (!p->isActive()) { + p->init(shotPos, baseVel, lifeMs, size, projectileTexture, renderer); + break; + } + } + } + } + /* auto remotePlayersSnapshot = networkClient->getRemotePlayers(); for (const auto& pi : pending) { Eigen::Vector3f dir = pi.direction; @@ -1190,7 +1227,7 @@ namespace ZL } } } - } + }*/ } } } diff --git a/src/network/NetworkInterface.h b/src/network/NetworkInterface.h index 6bb64be..fc03c53 100644 --- a/src/network/NetworkInterface.h +++ b/src/network/NetworkInterface.h @@ -11,7 +11,9 @@ namespace ZL { int shooterId = -1; uint64_t clientTime = 0; Eigen::Vector3f position = Eigen::Vector3f::Zero(); - Eigen::Vector3f direction = Eigen::Vector3f::Zero(); + //Eigen::Vector3f direction = Eigen::Vector3f::Zero(); + Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity(); + float velocity = 0; }; class INetworkClient { diff --git a/src/network/WebSocketClient.cpp b/src/network/WebSocketClient.cpp index 047066b..6e6b7b8 100644 --- a/src/network/WebSocketClient.cpp +++ b/src/network/WebSocketClient.cpp @@ -128,7 +128,7 @@ namespace ZL { if (msg.rfind("PROJECTILE:", 0) == 0) { auto parts = split(msg, ':'); - if (parts.size() >= 9) { + if (parts.size() >= 10) { try { ProjectileInfo pi; pi.shooterId = std::stoi(parts[1]); @@ -138,11 +138,15 @@ namespace ZL { std::stof(parts[4]), std::stof(parts[5]) ); - pi.direction = Eigen::Vector3f( + Eigen::Quaternionf q( std::stof(parts[6]), std::stof(parts[7]), - std::stof(parts[8]) + std::stof(parts[8]), + std::stof(parts[9]) ); + pi.rotation = q.toRotationMatrix(); + + pi.velocity = std::stof(parts[10]); std::lock_guard pl(projMutex_); pendingProjectiles_.push_back(pi); }