From 170d953fe26476ad57227de794cc2e5da2cebee5 Mon Sep 17 00:00:00 2001 From: john Date: Sun, 18 Oct 2026 12:49:24 -0400 Subject: [PATCH] finaliisss --- Engine.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/Engine.cpp b/Engine.cpp index 2945248..d367485 100644 --- a/Engine.cpp +++ b/Engine.cpp @@ -130,6 +130,7 @@ void Engine::Initiate() Texture* blanktex = new Texture("assets/blanktexture.png"); Texture* magic = new Texture("assets/itsmagicbitch.jpg"); Texture* snowflake = new Texture("assets/snowflake.png"); + Texture* shockwavetex = new Texture("assets/shockwave.png"); Texture* leontex = new Texture("assets/revolvertex.png"); // ------------------------------------------------------------------------ @@ -191,6 +192,7 @@ void Engine::Initiate() struct RemotePlayer { Character* character = nullptr; double lastSeen = 0.0; + p* body = nullptr; // host only: lets the host's cubes collide with this player }; std::map remotes; auto SpawnRemote = [&]() -> Character* { @@ -518,7 +520,7 @@ void Engine::Initiate() Mesh* blastMesh = CreateCubeMesh(); blastMesh->name = "shockblast"; - blastMesh->meshTexture = blanktex; + blastMesh->meshTexture = shockwavetex; blastMesh->t.TranslateTo(hiddenPos); blastMesh->BindToRenderSystem(); mainf->AddChild(blastMesh); @@ -567,6 +569,15 @@ void Engine::Initiate() shockActive = false; shockMesh->t.TranslateTo(hiddenPos); } + else if (lan && lan->IsActive()) { + // Another player's blast: launch the cubes (host: the real ones; client: its local copies) + for (p* obj : physicsengine->GetObjects()) { + bool isCube = false; + for (const HostCube& hc : hostCubes) if (obj->pointer == hc.mesh) isCube = true; + for (auto& kv : puppetCubes) if (obj->pointer == kv.second.mesh) isCube = true; + if (isCube) launch(obj->pointer->t.GetTranslation(), obj); + } + } blastMesh->t.TranslateTo(center); blastMesh->t.ScaleTo(glm::vec3(0.5f)); blastTime = blastShowTime; @@ -1090,14 +1101,25 @@ void Engine::Initiate() m->t.ScaleTo(1.0f); m->BindToRenderSystem(); mainf->AddChild(m); - // Solid for the local player, but moved only by the host's stream (like the floor, never simulated here) - p* cubeBody = new p(m); - cubeBody->velocity = false; - physicsengine->AddObject(cubeBody); + // Simulated locally exactly like the host's cubes (so the local player pushes them with + // no lag); the host's stream below only corrects drift. + physicsengine->AddObject(new p(m)); + m->t.TranslateTo(nc.position); + m->t.RotateToQuaternion(nc.rotation); it = puppetCubes.emplace(nc.id, PuppetCube{ m, now }).first; } - it->second.mesh->t.TranslateTo(nc.position); - it->second.mesh->t.RotateToQuaternion(nc.rotation); + else { + t& ct = it->second.mesh->t; + const glm::vec3 err = nc.position - ct.GetTranslation(); + if (glm::length(err) > 3.0f) { + ct.TranslateTo(nc.position); + ct.RotateToQuaternion(nc.rotation); + } + else { + ct.TranslateBy(err * 0.35f); + ct.RotateToQuaternion(glm::slerp(ct.GetRotationQuaternion(), nc.rotation, 0.35f)); + } + } it->second.lastSeen = now; } for (auto it = puppetCubes.begin(); it != puppetCubes.end();) { @@ -1128,12 +1150,22 @@ void Engine::Initiate() rp.character = SpawnRemote(); rp.character->body->t.TranslateTo(u.state.position); rp.character->body->t.RotateToQuaternion(u.state.rotation); + if (lan->GetMode() == Lan::Mode::Host) { + // Solid for the host's cubes (kinematic: moved by the client's stream only) + rp.body = new p(rp.character->body); + rp.body->velocity = false; + physicsengine->AddObject(rp.body); + } it = remotes.emplace(u.id, rp).first; } else { // Smooth over the 60 Hz updates t& rt = it->second.character->body->t; + const glm::vec3 before = rt.GetTranslation(); rt.TranslateTo(glm::mix(rt.GetTranslation(), u.state.position, 0.5f)); + // Kinematic body: its velocity makes it push cubes like the client's own body does there + if (it->second.body && deltatime > 0.0f) + it->second.body->linearvelocity = (rt.GetTranslation() - before) / deltatime; rt.RotateToQuaternion(glm::slerp(rt.GetRotationQuaternion(), u.state.rotation, 0.5f)); } it->second.lastSeen = now; @@ -1143,6 +1175,7 @@ void Engine::Initiate() for (auto it = remotes.begin(); it != remotes.end();) { if (now - it->second.lastSeen > 2.0) { rendersystem->RemoveRenderable(it->second.character); + if (it->second.body) physicsengine->RemoveObject(it->second.character->body); delete it->second.character; it = remotes.erase(it); }