From 31c2699a323904459817d12e64d0480474da0973 Mon Sep 17 00:00:00 2001 From: Chase Cooper Date: Thu, 5 Mar 2026 16:25:52 -0500 Subject: [PATCH] Fixed boats falling and a TP glitch #266 --- Minecraft.World/Boat.cpp | 107 ++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/Minecraft.World/Boat.cpp b/Minecraft.World/Boat.cpp index 1783a8d90..1811c2094 100644 --- a/Minecraft.World/Boat.cpp +++ b/Minecraft.World/Boat.cpp @@ -74,7 +74,7 @@ bool Boat::isPushable() Boat::Boat(Level *level, double x, double y, double z) : Entity( level ) { _init(); - setPos(x, y + heightOffset + 0.1, z); + setPos(x, y + heightOffset, z); xd = 0; yd = 0; @@ -209,9 +209,30 @@ void Boat::tick() } double lastSpeed = sqrt(xd * xd + zd * zd); - if (lastSpeed > MAX_COLLISION_SPEED && waterPercentage > 1) + if (lastSpeed > MAX_COLLISION_SPEED) { - createSplash(lastSpeed); + double xa = cos(yRot * PI / 180); + double za = sin(yRot * PI / 180); + + for (int i = 0; i < 1 + lastSpeed * 60; i++) + { + + double side = (random->nextFloat() * 2 - 1); + + double side2 = (random->nextInt(2) * 2 - 1) * 0.7; + if (random->nextBoolean()) + { + double xx = x - xa * side * 0.8 + za * side2; + double zz = z - za * side * 0.8 - xa * side2; + level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); + } + else + { + double xx = x + xa + za * side * 0.7; + double zz = z + za - xa * side * 0.7; + level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); + } + } } if (level->isClientSide && doLerp) @@ -224,8 +245,8 @@ void Boat::tick() double yrd = Mth::wrapDegrees(lyr - yRot); - yRot += static_cast((yrd) / lSteps); - xRot += static_cast((lxr - xRot) / lSteps); + yRot += (float) ( (yrd) / lSteps ); + xRot += (float) ( (lxr - xRot) / lSteps ); lSteps--; setPos(xt, yt, zt); @@ -233,6 +254,7 @@ void Boat::tick() } else { +#if 1 // Original //double xt = x + xd; //double yt = y + yd; @@ -251,23 +273,51 @@ void Boat::tick() xd *= 0.99f; yd *= 0.95f; zd *= 0.99f; +#else + // 4J Stu - Fix for #8280 - Gameplay : Boats behave erratically when exited next to land. + // The client shouldn't change the position of the boat + double xt = x;// + xd; + double yt = y + yd; + double zt = z;// + zd; + this->setPos(xt, yt, zt); + + // 4J Stu - Fix for #9579 - GAMEPLAY: Boats with a player in them slowly sink under the water over time, and with no player in them they float into the sky. + // Just make the boats bob up and down rather than any other client-side movement when not receiving packets from server + if (waterPercentage > 0) + { + double bob = waterPercentage * 2 - 1; + yd += 0.04f * bob; + } + else + { + if (yd < 0) yd /= 2; + yd += 0.007f; + } + //if (onGround) + //{ + xd *= 0.5f; + yd *= 0.5f; + zd *= 0.5f; + //} + //xd *= 0.99f; + //yd *= 0.95f; + //zd *= 0.99f; +#endif } return; } - // Bob on water if (waterPercentage > 0) { double bob = waterPercentage * 2 - 1; yd += 0.04f * bob; } - - // Reimplement "gravity" - if (level->getTile(x, Mth::floor(y - 0.15), z) == 0 && !onGround) { - yd += 0.04f * -1.0; // -1.0 is what bob should return in this situation, just hardcoded. + else + { + yd = 0; } - // Rider Controls + if ( rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY) ) { shared_ptr livingRider = dynamic_pointer_cast(rider.lock()); @@ -284,7 +334,6 @@ void Boat::tick() double curSpeed = sqrt(xd * xd + zd * zd); - // Speed Clamp if (curSpeed > MAX_SPEED) { double ratio = MAX_SPEED / curSpeed; @@ -305,15 +354,14 @@ void Boat::tick() if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION; } - // Slow speed on ground if (onGround) { xd *= 0.5f; + yd *= 0.5f; zd *= 0.5f; } move(xd, yd, zd); - // Break boat if ((horizontalCollision && lastSpeed > 0.20)) { if (!level->isClientSide && !removed) @@ -342,7 +390,7 @@ void Boat::tick() double zDiff = zo - z; if (xDiff * xDiff + zDiff * zDiff > 0.001) { - yRotT = static_cast(atan2(zDiff, xDiff) * 180 / PI); + yRotT = (float) (atan2(zDiff, xDiff) * 180 / PI); } double rotDiff = Mth::wrapDegrees(yRotT - yRot); @@ -350,10 +398,9 @@ void Boat::tick() if (rotDiff > 20) rotDiff = 20; if (rotDiff < -20) rotDiff = -20; - yRot += static_cast(rotDiff); + yRot += (float) rotDiff; setRot(yRot, xRot); - // Server only code below if(level->isClientSide) return; vector > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f)); @@ -397,37 +444,13 @@ void Boat::tick() } } -void Boat::createSplash(double particleStrengh) { - double xa = cos(yRot * PI / 180); - double za = sin(yRot * PI / 180); - - for (int i = 0; i < 1 + particleStrengh * 60; i++) - { - double side = (random->nextFloat() * 2 - 1); - - double side2 = (random->nextInt(2) * 2 - 1) * 0.7; - if (random->nextBoolean()) - { - double xx = x - xa * side * 0.8 + za * side2; - double zz = z - za * side * 0.8 - xa * side2; - level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); - } - else - { - double xx = x + xa + za * side * 0.7; - double zz = z + za - xa * side * 0.7; - level->addParticle(eParticleType_splash, xx, y - 2 / 16.0f, zz, +xd, yd, +zd); - } - } -} - void Boat::positionRider() { if (rider.lock() == NULL) return; double xa = cos(yRot * PI / 180) * 0.4; double za = sin(yRot * PI / 180) * 0.4; - rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight()-0.5, z + za); + rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight(), z + za); }