gitMerge branch 'main' into linux
This commit is contained in:
commit
24526efb8d
BIN
resources/button_take.png
(Stored with Git LFS)
Normal file
BIN
resources/button_take.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resources/button_take_disabled.png
(Stored with Git LFS)
Normal file
BIN
resources/button_take_disabled.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resources/button_take_pressed.png
(Stored with Git LFS)
Normal file
BIN
resources/button_take_pressed.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -64,7 +64,7 @@
|
|||||||
"vertical_gravity": "bottom",
|
"vertical_gravity": "bottom",
|
||||||
"textures": {
|
"textures": {
|
||||||
"normal": "resources/button_minus.png",
|
"normal": "resources/button_minus.png",
|
||||||
"hover": "resources/button_minus_pressed.png",
|
"hover": "resources/button_minus.png",
|
||||||
"pressed": "resources/button_minus_pressed.png",
|
"pressed": "resources/button_minus_pressed.png",
|
||||||
"disabled" : "resources/button_minus_disabled.png"
|
"disabled" : "resources/button_minus_disabled.png"
|
||||||
}
|
}
|
||||||
@ -81,10 +81,27 @@
|
|||||||
"vertical_gravity": "bottom",
|
"vertical_gravity": "bottom",
|
||||||
"textures": {
|
"textures": {
|
||||||
"normal": "resources/button_plus.png",
|
"normal": "resources/button_plus.png",
|
||||||
"hover": "resources/button_plus_pressed.png",
|
"hover": "resources/button_plus.png",
|
||||||
"pressed": "resources/button_plus_pressed.png",
|
"pressed": "resources/button_plus_pressed.png",
|
||||||
"disabled" : "resources/button_plus_disabled.png"
|
"disabled" : "resources/button_plus_disabled.png"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Button",
|
||||||
|
"name": "takeButton",
|
||||||
|
"x": -20,
|
||||||
|
"y": 320,
|
||||||
|
"width": 150,
|
||||||
|
"height": 150,
|
||||||
|
"border" : 20,
|
||||||
|
"horizontal_gravity": "right",
|
||||||
|
"vertical_gravity": "bottom",
|
||||||
|
"textures": {
|
||||||
|
"normal": "resources/button_take.png",
|
||||||
|
"hover": "resources/button_take.png",
|
||||||
|
"pressed": "resources/button_take_pressed.png",
|
||||||
|
"disabled" : "resources/button_take_disabled.png"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,6 +136,7 @@ namespace ZL {
|
|||||||
uiManager.replaceRoot(gameplayRoot);
|
uiManager.replaceRoot(gameplayRoot);
|
||||||
|
|
||||||
uiManager.findButton("minusButton")->state = ButtonState::Disabled;
|
uiManager.findButton("minusButton")->state = ButtonState::Disabled;
|
||||||
|
if (auto btn = uiManager.findButton("takeButton")) btn->state = ButtonState::Disabled;
|
||||||
|
|
||||||
|
|
||||||
auto velocityTv = uiManager.findTextView("velocityText");
|
auto velocityTv = uiManager.findTextView("velocityText");
|
||||||
@ -144,8 +145,6 @@ namespace ZL {
|
|||||||
velocityTv->rect.y = static_cast<float>(Environment::height) - velocityTv->rect.h - 10.0f;
|
velocityTv->rect.y = static_cast<float>(Environment::height) - velocityTv->rect.h - 10.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//uiManager.startAnimationOnNode("backgroundNode", "bgScroll");
|
|
||||||
|
|
||||||
uiManager.setButtonPressCallback("shootButton", [this](const std::string&) {
|
uiManager.setButtonPressCallback("shootButton", [this](const std::string&) {
|
||||||
if (onFirePressed) onFirePressed();
|
if (onFirePressed) onFirePressed();
|
||||||
});
|
});
|
||||||
@ -180,13 +179,19 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
if (onVelocityChanged) onVelocityChanged(newVel);
|
if (onVelocityChanged) onVelocityChanged(newVel);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
uiManager.setButtonPressCallback("takeButton", [this](const std::string&) {
|
||||||
|
if (onTakeButtonPressed) onTakeButtonPressed();
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
uiManager.setSliderCallback("velocitySlider", [this](const std::string&, float value) {
|
uiManager.setSliderCallback("velocitySlider", [this](const std::string&, float value) {
|
||||||
int newVel = static_cast<int>(roundf(value * 10));
|
int newVel = static_cast<int>(roundf(value * 10));
|
||||||
if (newVel > 2) newVel = 2;
|
if (newVel > 2) newVel = 2;
|
||||||
if (newVel != Environment::shipState.selectedVelocity) {
|
if (newVel != Environment::shipState.selectedVelocity) {
|
||||||
if (onVelocityChanged) onVelocityChanged(newVel);
|
if (onVelocityChanged) onVelocityChanged(newVel);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── State: GameOver ──────────────────────────────────────────────────────
|
// ── State: GameOver ──────────────────────────────────────────────────────
|
||||||
|
|||||||
@ -70,6 +70,7 @@ namespace ZL {
|
|||||||
std::function<void()> onRestartPressed;
|
std::function<void()> onRestartPressed;
|
||||||
std::function<void(float)> onVelocityChanged;
|
std::function<void(float)> onVelocityChanged;
|
||||||
std::function<void()> onFirePressed;
|
std::function<void()> onFirePressed;
|
||||||
|
std::function<void()> onTakeButtonPressed;
|
||||||
std::function<void(const std::string&, int)> onSingleplayerPressed;
|
std::function<void(const std::string&, int)> onSingleplayerPressed;
|
||||||
std::function<void(const std::string&, int)> onMultiplayerPressed;
|
std::function<void(const std::string&, int)> onMultiplayerPressed;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -317,6 +317,26 @@ namespace ZL
|
|||||||
firePressed = true;
|
firePressed = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
menuManager.onTakeButtonPressed = [this]() {
|
||||||
|
if (Environment::shipState.shipType != 1) return;
|
||||||
|
if (!networkClient) return;
|
||||||
|
|
||||||
|
int bestIdx = -1;
|
||||||
|
float bestDistSq = BOX_PICKUP_RADIUS * BOX_PICKUP_RADIUS;
|
||||||
|
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
||||||
|
if (i >= boxAlive.size() || !boxAlive[i]) continue;
|
||||||
|
Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.f, 0.f, 45000.f };
|
||||||
|
float distSq = (Environment::shipState.position - boxWorld).squaredNorm();
|
||||||
|
if (distSq <= bestDistSq) {
|
||||||
|
bestDistSq = distSq;
|
||||||
|
bestIdx = static_cast<int>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestIdx >= 0) {
|
||||||
|
networkClient->Send("BOX_PICKUP:" + std::to_string(bestIdx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
bool cfgLoaded = sparkEmitter.loadFromJsonFile("resources/config/spark_config.json", renderer, CONST_ZIP_FILE);
|
||||||
bool cfgLoaded2 = sparkEmitterCargo.loadFromJsonFile("resources/config/spark_config_cargo.json", renderer, CONST_ZIP_FILE);
|
bool cfgLoaded2 = sparkEmitterCargo.loadFromJsonFile("resources/config/spark_config_cargo.json", renderer, CONST_ZIP_FILE);
|
||||||
sparkEmitter.setIsActive(false);
|
sparkEmitter.setIsActive(false);
|
||||||
@ -395,7 +415,7 @@ namespace ZL
|
|||||||
boxLabels.clear();
|
boxLabels.clear();
|
||||||
boxLabels.reserve(boxCoordsArr.size());
|
boxLabels.reserve(boxCoordsArr.size());
|
||||||
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
||||||
boxLabels.push_back("Box " + std::to_string(i + 1));
|
boxLabels.push_back("Box " + std::to_string(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cfgLoaded)
|
if (!cfgLoaded)
|
||||||
@ -658,6 +678,11 @@ namespace ZL
|
|||||||
for (size_t i = 0; i < n; ++i) {
|
for (size_t i = 0; i < n; ++i) {
|
||||||
if (destroyedFlags[i]) boxAlive[i] = false; // destroyed => не рисуем
|
if (destroyedFlags[i]) boxAlive[i] = false; // destroyed => не рисуем
|
||||||
}
|
}
|
||||||
|
boxLabels.clear();
|
||||||
|
boxLabels.resize(boxCoordsArr.size());
|
||||||
|
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
||||||
|
boxLabels[i] = "Box " + std::to_string(i);
|
||||||
|
}
|
||||||
serverBoxesApplied = true;
|
serverBoxesApplied = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1776,6 +1801,24 @@ namespace ZL
|
|||||||
std::string velocityStr = "Velocity: " + std::to_string(static_cast<int>(Environment::shipState.velocity));
|
std::string velocityStr = "Velocity: " + std::to_string(static_cast<int>(Environment::shipState.velocity));
|
||||||
menuManager.uiManager.setText("velocityText", velocityStr);
|
menuManager.uiManager.setText("velocityText", velocityStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool canPickup = false;
|
||||||
|
if (Environment::shipState.shipType == 1) {
|
||||||
|
for (size_t i = 0; i < boxCoordsArr.size(); ++i) {
|
||||||
|
if (i >= boxAlive.size() || !boxAlive[i]) continue;
|
||||||
|
Vector3f boxWorld = boxCoordsArr[i].pos + Vector3f{ 0.f, 0.f, 45000.f };
|
||||||
|
float distSq = (Environment::shipState.position - boxWorld).squaredNorm();
|
||||||
|
if (distSq <= BOX_PICKUP_RADIUS * BOX_PICKUP_RADIUS) {
|
||||||
|
canPickup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (canPickup != nearPickupBox) {
|
||||||
|
nearPickupBox = canPickup;
|
||||||
|
if (auto btn = menuManager.uiManager.findButton("takeButton"))
|
||||||
|
btn->state = canPickup ? ButtonState::Normal : ButtonState::Disabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1890,7 +1933,7 @@ namespace ZL
|
|||||||
if (d.killerId == localId) {
|
if (d.killerId == localId) {
|
||||||
this->playerScore += 1;
|
this->playerScore += 1;
|
||||||
std::cout << "Client: Increased local score to " << this->playerScore << std::endl;
|
std::cout << "Client: Increased local score to " << this->playerScore << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1952,6 +1995,35 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto boxPickups = networkClient->getPendingBoxPickups();
|
||||||
|
for (const auto& pickup : boxPickups) {
|
||||||
|
int idx = pickup.boxIndex;
|
||||||
|
if (idx >= 0 && idx < (int)boxCoordsArr.size() && idx < (int)boxAlive.size()) {
|
||||||
|
if (boxAlive[idx]) {
|
||||||
|
boxAlive[idx] = false;
|
||||||
|
boxRenderArr[idx].data.PositionData.clear();
|
||||||
|
boxRenderArr[idx].vao.reset();
|
||||||
|
boxRenderArr[idx].positionVBO.reset();
|
||||||
|
boxRenderArr[idx].texCoordVBO.reset();
|
||||||
|
std::cout << "Client: Box " << idx << " picked up by player " << pickup.pickedUpBy << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto boxRespawns = networkClient->getPendingBoxRespawns();
|
||||||
|
for (const auto& respawn : boxRespawns) {
|
||||||
|
int idx = respawn.boxIndex;
|
||||||
|
if (idx >= 0 && idx < (int)boxCoordsArr.size()) {
|
||||||
|
boxCoordsArr[idx].pos = respawn.position;
|
||||||
|
boxCoordsArr[idx].m = respawn.rotation;
|
||||||
|
boxAlive[idx] = true;
|
||||||
|
boxRenderArr[idx].AssignFrom(boxBase);
|
||||||
|
boxRenderArr[idx].RefreshVBO();
|
||||||
|
std::cout << "Client: Box " << idx << " respawned" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::handleDown(int mx, int my)
|
void Space::handleDown(int mx, int my)
|
||||||
|
|||||||
@ -113,6 +113,7 @@ namespace ZL {
|
|||||||
const uint64_t explosionDurationMs = 500;
|
const uint64_t explosionDurationMs = 500;
|
||||||
|
|
||||||
bool serverBoxesApplied = false;
|
bool serverBoxesApplied = false;
|
||||||
|
bool nearPickupBox = false;
|
||||||
|
|
||||||
static constexpr float MAX_DIST_SQ = 10000.f * 10000.f;
|
static constexpr float MAX_DIST_SQ = 10000.f * 10000.f;
|
||||||
static constexpr float FADE_START = 6000.f;
|
static constexpr float FADE_START = 6000.f;
|
||||||
|
|||||||
@ -34,6 +34,7 @@ constexpr float PROJECTILE_LIFE = 15000.f; //ms
|
|||||||
const float projectileHitRadius = 1.5f * 5;
|
const float projectileHitRadius = 1.5f * 5;
|
||||||
const float boxCollisionRadius = 2.0f * 5;
|
const float boxCollisionRadius = 2.0f * 5;
|
||||||
const float shipCollisionRadius = 15.0f * 5;
|
const float shipCollisionRadius = 15.0f * 5;
|
||||||
|
const float BOX_PICKUP_RADIUS = shipCollisionRadius * 5;
|
||||||
const float npcCollisionRadius = 5.0f * 5;
|
const float npcCollisionRadius = 5.0f * 5;
|
||||||
|
|
||||||
uint32_t fnv1a_hash(const std::string& data);
|
uint32_t fnv1a_hash(const std::string& data);
|
||||||
|
|||||||
@ -274,6 +274,24 @@ namespace ZL {
|
|||||||
std::cout << "LocalClient: Box " << boxIdx << " destroyed by projectile from player "
|
std::cout << "LocalClient: Box " << boxIdx << " destroyed by projectile from player "
|
||||||
<< projectiles[projIdx].shooterId << std::endl;
|
<< projectiles[projIdx].shooterId << std::endl;
|
||||||
|
|
||||||
|
// Respawn box
|
||||||
|
{
|
||||||
|
std::random_device rd2;
|
||||||
|
std::mt19937 gen2(rd2());
|
||||||
|
std::uniform_real_distribution<float> angleDist(0.f, static_cast<float>(M_PI * 2.0));
|
||||||
|
Eigen::Vector3f newPos = generateRespawnBoxPos(static_cast<int>(boxIdx));
|
||||||
|
Eigen::Vector3f axis = Eigen::Vector3f::Random().normalized();
|
||||||
|
Eigen::Matrix3f newRot = Eigen::AngleAxisf(angleDist(gen2), axis).toRotationMatrix();
|
||||||
|
serverBoxes[boxIdx].position = newPos;
|
||||||
|
serverBoxes[boxIdx].rotation = newRot;
|
||||||
|
serverBoxes[boxIdx].destroyed = false;
|
||||||
|
BoxRespawnInfo respawn;
|
||||||
|
respawn.boxIndex = static_cast<int>(boxIdx);
|
||||||
|
respawn.position = newPos;
|
||||||
|
respawn.rotation = newRot;
|
||||||
|
pendingBoxRespawns.push_back(respawn);
|
||||||
|
}
|
||||||
|
|
||||||
if (std::find(projIndicesToRemove.begin(), projIndicesToRemove.end(), (int)projIdx)
|
if (std::find(projIndicesToRemove.begin(), projIndicesToRemove.end(), (int)projIdx)
|
||||||
== projIndicesToRemove.end()) {
|
== projIndicesToRemove.end()) {
|
||||||
projIndicesToRemove.push_back(static_cast<int>(projIdx));
|
projIndicesToRemove.push_back(static_cast<int>(projIdx));
|
||||||
@ -352,11 +370,62 @@ namespace ZL {
|
|||||||
|
|
||||||
std::cout << "LocalClient: Box " << bi << " destroyed by ship collision with player "
|
std::cout << "LocalClient: Box " << bi << " destroyed by ship collision with player "
|
||||||
<< GetClientId() << std::endl;
|
<< GetClientId() << std::endl;
|
||||||
|
|
||||||
|
// Respawn box
|
||||||
|
{
|
||||||
|
std::random_device rd2;
|
||||||
|
std::mt19937 gen2(rd2());
|
||||||
|
std::uniform_real_distribution<float> angleDist(0.f, static_cast<float>(M_PI * 2.0));
|
||||||
|
Eigen::Vector3f newPos = generateRespawnBoxPos(static_cast<int>(bi));
|
||||||
|
Eigen::Vector3f axis = Eigen::Vector3f::Random().normalized();
|
||||||
|
Eigen::Matrix3f newRot = Eigen::AngleAxisf(angleDist(gen2), axis).toRotationMatrix();
|
||||||
|
serverBoxes[bi].position = newPos;
|
||||||
|
serverBoxes[bi].rotation = newRot;
|
||||||
|
serverBoxes[bi].destroyed = false;
|
||||||
|
BoxRespawnInfo respawn;
|
||||||
|
respawn.boxIndex = static_cast<int>(bi);
|
||||||
|
respawn.position = newPos;
|
||||||
|
respawn.rotation = newRot;
|
||||||
|
pendingBoxRespawns.push_back(respawn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Eigen::Vector3f LocalClient::generateRespawnBoxPos(int skipIdx) {
|
||||||
|
std::random_device rd;
|
||||||
|
std::mt19937 gen(rd());
|
||||||
|
std::uniform_real_distribution<float> dist(-1000.f, 1000.f);
|
||||||
|
|
||||||
|
for (int attempt = 0; attempt < 500; ++attempt) {
|
||||||
|
Eigen::Vector3f cand(dist(gen), dist(gen), dist(gen));
|
||||||
|
bool safe = true;
|
||||||
|
for (int i = 0; i < (int)serverBoxes.size(); ++i) {
|
||||||
|
if (i == skipIdx) continue;
|
||||||
|
if (serverBoxes[i].destroyed) continue;
|
||||||
|
if ((cand - serverBoxes[i].position).squaredNorm() < 9.f) {
|
||||||
|
safe = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (safe) return cand;
|
||||||
|
}
|
||||||
|
return Eigen::Vector3f(dist(gen), dist(gen), dist(gen));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BoxPickedUpInfo> LocalClient::getPendingBoxPickups() {
|
||||||
|
auto result = pendingBoxPickups;
|
||||||
|
pendingBoxPickups.clear();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BoxRespawnInfo> LocalClient::getPendingBoxRespawns() {
|
||||||
|
auto result = pendingBoxRespawns;
|
||||||
|
pendingBoxRespawns.clear();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void LocalClient::Send(const std::string& message) {
|
void LocalClient::Send(const std::string& message) {
|
||||||
auto parts = [](const std::string& s, char delimiter) {
|
auto parts = [](const std::string& s, char delimiter) {
|
||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens;
|
||||||
@ -372,6 +441,51 @@ namespace ZL {
|
|||||||
|
|
||||||
std::string type = parts[0];
|
std::string type = parts[0];
|
||||||
|
|
||||||
|
if (type == "BOX_PICKUP") {
|
||||||
|
if (parts.size() < 2) return;
|
||||||
|
if (!hasLocalPlayerState || localPlayerState.shipType != 1) return;
|
||||||
|
|
||||||
|
int boxIdx = -1;
|
||||||
|
try { boxIdx = std::stoi(parts[1]); } catch (...) { return; }
|
||||||
|
|
||||||
|
if (boxIdx < 0 || boxIdx >= (int)serverBoxes.size()) return;
|
||||||
|
if (serverBoxes[boxIdx].destroyed) return;
|
||||||
|
|
||||||
|
Eigen::Vector3f boxWorld = serverBoxes[boxIdx].position + Eigen::Vector3f(0.f, 0.f, 45000.f);
|
||||||
|
float distSq = (localPlayerState.position - boxWorld).squaredNorm();
|
||||||
|
if (distSq > BOX_PICKUP_RADIUS * BOX_PICKUP_RADIUS) return;
|
||||||
|
|
||||||
|
serverBoxes[boxIdx].destroyed = true;
|
||||||
|
|
||||||
|
BoxPickedUpInfo pickup;
|
||||||
|
pickup.boxIndex = boxIdx;
|
||||||
|
pickup.pickedUpBy = GetClientId();
|
||||||
|
pendingBoxPickups.push_back(pickup);
|
||||||
|
|
||||||
|
std::cout << "LocalClient: Box " << boxIdx << " picked up by player " << GetClientId() << "\n";
|
||||||
|
|
||||||
|
// Respawn box at new position
|
||||||
|
{
|
||||||
|
std::random_device rd2;
|
||||||
|
std::mt19937 gen2(rd2());
|
||||||
|
std::uniform_real_distribution<float> angleDist(0.f, static_cast<float>(M_PI * 2.0));
|
||||||
|
Eigen::Vector3f newPos = generateRespawnBoxPos(boxIdx);
|
||||||
|
Eigen::Vector3f axis = Eigen::Vector3f::Random().normalized();
|
||||||
|
Eigen::Matrix3f newRot = Eigen::AngleAxisf(angleDist(gen2), axis).toRotationMatrix();
|
||||||
|
serverBoxes[boxIdx].position = newPos;
|
||||||
|
serverBoxes[boxIdx].rotation = newRot;
|
||||||
|
serverBoxes[boxIdx].destroyed = false;
|
||||||
|
|
||||||
|
BoxRespawnInfo respawn;
|
||||||
|
respawn.boxIndex = boxIdx;
|
||||||
|
respawn.position = newPos;
|
||||||
|
respawn.rotation = newRot;
|
||||||
|
pendingBoxRespawns.push_back(respawn);
|
||||||
|
std::cout << "LocalClient: Box " << boxIdx << " respawned after pickup\n";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == "FIRE") {
|
if (type == "FIRE") {
|
||||||
if (parts.size() < 10) return;
|
if (parts.size() < 10) return;
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,8 @@ namespace ZL {
|
|||||||
std::vector<ProjectileInfo> pendingProjectiles;
|
std::vector<ProjectileInfo> pendingProjectiles;
|
||||||
std::vector<DeathInfo> pendingDeaths;
|
std::vector<DeathInfo> pendingDeaths;
|
||||||
std::vector<BoxDestroyedInfo> pendingBoxDestructions;
|
std::vector<BoxDestroyedInfo> pendingBoxDestructions;
|
||||||
|
std::vector<BoxPickedUpInfo> pendingBoxPickups;
|
||||||
|
std::vector<BoxRespawnInfo> pendingBoxRespawns;
|
||||||
std::vector<int> pendingRespawns;
|
std::vector<int> pendingRespawns;
|
||||||
|
|
||||||
uint64_t lastUpdateMs = 0;
|
uint64_t lastUpdateMs = 0;
|
||||||
@ -56,6 +58,7 @@ namespace ZL {
|
|||||||
void initializeNPCs();
|
void initializeNPCs();
|
||||||
void updateNPCs();
|
void updateNPCs();
|
||||||
Eigen::Vector3f generateRandomPosition();
|
Eigen::Vector3f generateRandomPosition();
|
||||||
|
Eigen::Vector3f generateRespawnBoxPos(int skipIdx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Connect(const std::string& host, uint16_t port) override;
|
void Connect(const std::string& host, uint16_t port) override;
|
||||||
@ -79,6 +82,8 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<BoxDestroyedInfo> getPendingBoxDestructions() override;
|
std::vector<BoxDestroyedInfo> getPendingBoxDestructions() override;
|
||||||
|
std::vector<BoxPickedUpInfo> getPendingBoxPickups() override;
|
||||||
|
std::vector<BoxRespawnInfo> getPendingBoxRespawns() override;
|
||||||
|
|
||||||
void setLocalPlayerState(const ClientState& state) {
|
void setLocalPlayerState(const ClientState& state) {
|
||||||
localPlayerState = state;
|
localPlayerState = state;
|
||||||
|
|||||||
@ -30,6 +30,17 @@ namespace ZL {
|
|||||||
int destroyedBy = -1;
|
int destroyedBy = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BoxPickedUpInfo {
|
||||||
|
int boxIndex = -1;
|
||||||
|
int pickedUpBy = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoxRespawnInfo {
|
||||||
|
int boxIndex = -1;
|
||||||
|
Eigen::Vector3f position = Eigen::Vector3f::Zero();
|
||||||
|
Eigen::Matrix3f rotation = Eigen::Matrix3f::Identity();
|
||||||
|
};
|
||||||
|
|
||||||
class INetworkClient {
|
class INetworkClient {
|
||||||
public:
|
public:
|
||||||
virtual ~INetworkClient() = default;
|
virtual ~INetworkClient() = default;
|
||||||
@ -50,6 +61,8 @@ namespace ZL {
|
|||||||
virtual std::vector<int> getPendingRespawns() = 0;
|
virtual std::vector<int> getPendingRespawns() = 0;
|
||||||
virtual int GetClientId() const { return -1; }
|
virtual int GetClientId() const { return -1; }
|
||||||
virtual std::vector<BoxDestroyedInfo> getPendingBoxDestructions() = 0;
|
virtual std::vector<BoxDestroyedInfo> getPendingBoxDestructions() = 0;
|
||||||
|
virtual std::vector<BoxPickedUpInfo> getPendingBoxPickups() { return {}; }
|
||||||
|
virtual std::vector<BoxRespawnInfo> getPendingBoxRespawns() { return {}; }
|
||||||
virtual int64_t getTimeOffset() const { return 0; }
|
virtual int64_t getTimeOffset() const { return 0; }
|
||||||
virtual std::vector<int> getPendingDisconnects() { return {}; }
|
virtual std::vector<int> getPendingDisconnects() { return {}; }
|
||||||
|
|
||||||
|
|||||||
@ -129,6 +129,45 @@ namespace ZL {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg.rfind("BOX_PICKED_UP:", 0) == 0) {
|
||||||
|
if (parts.size() >= 3) {
|
||||||
|
try {
|
||||||
|
BoxPickedUpInfo pickup;
|
||||||
|
pickup.boxIndex = std::stoi(parts[1]);
|
||||||
|
pickup.pickedUpBy = std::stoi(parts[2]);
|
||||||
|
pendingBoxPickups_.push_back(pickup);
|
||||||
|
std::cout << "Client: Received BOX_PICKED_UP box=" << pickup.boxIndex
|
||||||
|
<< " by player " << pickup.pickedUpBy << std::endl;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.rfind("BOX_RESPAWN:", 0) == 0) {
|
||||||
|
if (parts.size() >= 9) {
|
||||||
|
try {
|
||||||
|
BoxRespawnInfo respawn;
|
||||||
|
respawn.boxIndex = std::stoi(parts[1]);
|
||||||
|
float px = std::stof(parts[2]);
|
||||||
|
float py = std::stof(parts[3]);
|
||||||
|
float pz = std::stof(parts[4]);
|
||||||
|
Eigen::Quaternionf q(
|
||||||
|
std::stof(parts[5]),
|
||||||
|
std::stof(parts[6]),
|
||||||
|
std::stof(parts[7]),
|
||||||
|
std::stof(parts[8])
|
||||||
|
);
|
||||||
|
respawn.position = Eigen::Vector3f(px, py, pz);
|
||||||
|
respawn.rotation = q.toRotationMatrix();
|
||||||
|
pendingBoxRespawns_.push_back(respawn);
|
||||||
|
std::cout << "Client: Received BOX_RESPAWN box=" << respawn.boxIndex << std::endl;
|
||||||
|
}
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (msg.rfind("BOX_DESTROYED:", 0) == 0) {
|
if (msg.rfind("BOX_DESTROYED:", 0) == 0) {
|
||||||
//auto parts = split(msg, ':');
|
//auto parts = split(msg, ':');
|
||||||
if (parts.size() >= 7) {
|
if (parts.size() >= 7) {
|
||||||
@ -369,6 +408,18 @@ namespace ZL {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<BoxPickedUpInfo> WebSocketClientBase::getPendingBoxPickups() {
|
||||||
|
std::vector<BoxPickedUpInfo> copy;
|
||||||
|
copy.swap(pendingBoxPickups_);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<BoxRespawnInfo> WebSocketClientBase::getPendingBoxRespawns() {
|
||||||
|
std::vector<BoxRespawnInfo> copy;
|
||||||
|
copy.swap(pendingBoxRespawns_);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<int> WebSocketClientBase::getPendingDisconnects() {
|
std::vector<int> WebSocketClientBase::getPendingDisconnects() {
|
||||||
std::vector<int> copy;
|
std::vector<int> copy;
|
||||||
copy.swap(pendingDisconnects_);
|
copy.swap(pendingDisconnects_);
|
||||||
|
|||||||
@ -20,6 +20,8 @@ namespace ZL {
|
|||||||
std::vector<DeathInfo> pendingDeaths_;
|
std::vector<DeathInfo> pendingDeaths_;
|
||||||
std::vector<int> pendingRespawns_;
|
std::vector<int> pendingRespawns_;
|
||||||
std::vector<BoxDestroyedInfo> pendingBoxDestructions_;
|
std::vector<BoxDestroyedInfo> pendingBoxDestructions_;
|
||||||
|
std::vector<BoxPickedUpInfo> pendingBoxPickups_;
|
||||||
|
std::vector<BoxRespawnInfo> pendingBoxRespawns_;
|
||||||
std::vector<int> pendingDisconnects_;
|
std::vector<int> pendingDisconnects_;
|
||||||
int clientId = -1;
|
int clientId = -1;
|
||||||
int64_t timeOffset = 0;
|
int64_t timeOffset = 0;
|
||||||
@ -50,6 +52,8 @@ namespace ZL {
|
|||||||
std::vector<DeathInfo> getPendingDeaths() override;
|
std::vector<DeathInfo> getPendingDeaths() override;
|
||||||
std::vector<int> getPendingRespawns() override;
|
std::vector<int> getPendingRespawns() override;
|
||||||
std::vector<BoxDestroyedInfo> getPendingBoxDestructions() override;
|
std::vector<BoxDestroyedInfo> getPendingBoxDestructions() override;
|
||||||
|
std::vector<BoxPickedUpInfo> getPendingBoxPickups() override;
|
||||||
|
std::vector<BoxRespawnInfo> getPendingBoxRespawns() override;
|
||||||
std::vector<int> getPendingDisconnects() override;
|
std::vector<int> getPendingDisconnects() override;
|
||||||
std::vector<ClientState> getPendingSpawns();
|
std::vector<ClientState> getPendingSpawns();
|
||||||
int getClientId() const { return clientId; }
|
int getClientId() const { return clientId; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user