diff --git a/Minecraft.Client/TrackedEntity.cpp b/Minecraft.Client/TrackedEntity.cpp index 161c5b0c..4cff1725 100644 --- a/Minecraft.Client/TrackedEntity.cpp +++ b/Minecraft.Client/TrackedEntity.cpp @@ -290,24 +290,53 @@ void TrackedEntity::tick(EntityTracker *tracker, vector > *pl wasRiding = false; } else - { - bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL; - if (rot) - { - // 4J: Changed this to use deltas - broadcast(std::make_shared(e->entityId, static_cast(yRota), static_cast(xRota))); - yRotp = yRotn; - xRotp = xRotn; - } +{ + // the entity have a rider, the code didnt send position updates, + // causing desync between client and server when boat was spritning. - xp = Mth::floor(e->x * 32.0); - yp = Mth::floor(e->y * 32.0); - zp = Mth::floor(e->z * 32.0); + bool rot = abs(yRotn - yRotp) >= TOLERANCE_LEVEL || abs(xRotn - xRotp) >= TOLERANCE_LEVEL; + if (rot) + { + + broadcast(std::make_shared(e->entityId, static_cast(yRota), static_cast(xRota))); + yRotp = yRotn; + xRotp = xRotn; + } - sendDirtyEntityData(); + int xn = Mth::floor(e->x * 32.0); + int yn = Mth::floor(e->y * 32.0); + int zn = Mth::floor(e->z * 32.0); + int xa = xn - xp; + int ya = yn - yp; + int za = zn - zp; - wasRiding = true; - } + // send only if the boat moved enough + // or 3 seconds periodically + bool pos = abs(xa) >= TOLERANCE_LEVEL || abs(ya) >= TOLERANCE_LEVEL || abs(za) >= TOLERANCE_LEVEL + || (tickCount % (SharedConstants::TICKS_PER_SECOND * 3) == 0); + + if (pos) + { + // if deltapos is too much big use teleport. + if (xa < -128 || xa >= 128 || ya < -128 || ya >= 128 || za < -128 || za >= 128) + { + broadcast(std::make_shared(e->entityId, xn, yn, zn, + static_cast(yRotn), static_cast(xRotn))); + } + else + { + // small movement, delta + broadcast(std::make_shared(e->entityId, + static_cast(xa), static_cast(ya), static_cast(za))); + } + xp = xn; + yp = yn; + zp = zn; + } + + sendDirtyEntityData(); + wasRiding = true; +} int yHeadRot = Mth::floor(e->getYHeadRot() * 256 / 360); if (abs(yHeadRot - yHeadRotp) >= TOLERANCE_LEVEL) diff --git a/Minecraft.World/Boat.cpp b/Minecraft.World/Boat.cpp index 8cb14e1e..7c62e4ee 100644 --- a/Minecraft.World/Boat.cpp +++ b/Minecraft.World/Boat.cpp @@ -148,7 +148,7 @@ void Boat::lerpTo(double x, double y, double z, float yRot, float xRot, int step { if (doLerp) { - lSteps = steps + 5; + lSteps = steps +5; } else { @@ -188,6 +188,10 @@ void Boat::lerpMotion(double xd, double yd, double zd) void Boat::tick() { Entity::tick(); + + + + if (getHurtTime() > 0) setHurtTime(getHurtTime() - 1); if (getDamage() > 0) setDamage(getDamage() - 1); xo = x; @@ -199,8 +203,8 @@ void Boat::tick() double waterPercentage = 0; for (int i = 0; i < steps; i++) { - double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps - 2 / 16.0f; - double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps - 2 / 16.0f; + double y0 = bb->y0 + (bb->y1 - bb->y0) * (i + 0) / steps + 1.5f / 16.0f; + double y1 = bb->y0 + (bb->y1 - bb->y0) * (i + 1) / steps + 1.5f / 16.0f; AABB *bb2 = AABB::newTemp(bb->x0, y0, bb->z0, bb->x1, y1, bb->z1); if (level->containsLiquid(bb2, Material::water)) { @@ -257,18 +261,19 @@ void Boat::tick() return; } - // Bob in water - if (waterPercentage > 0) + // Bob in water & gravity + if (waterPercentage < 1.0) { - double bob = waterPercentage * 2 - 1; + double bob = waterPercentage * 2.0 - 1.0; yd += 0.04f * bob; } - - // Reimplement gravity again (??) - int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z)); - if (tileUnder == 0 && !onGround) + else { - yd -= 0.04f; + if (yd < 0.0) + { + yd /= 2.0; + } + yd += 0.007f; } // Rider controls @@ -281,24 +286,16 @@ void Boat::tick() { double riderXd = -sin(livingRider->yRot * PI / 180); double riderZd = cos(livingRider->yRot * PI / 180); - float mult = livingRider->isSprinting() ? 2.0f : 1.0f; + double currentSpeed = sqrt(xd * xd + zd * zd); float moveFactor = (float)forward; if (forward < 0) moveFactor *= 0.5f; // Move slower backwards - xd += riderXd * acceleration * 0.05f * mult * moveFactor; - zd += riderZd * acceleration * 0.05f * mult * moveFactor; + xd += riderXd * acceleration * 0.05f * moveFactor; + zd += riderZd * acceleration * 0.05f * moveFactor; } } double curSpeed = sqrt(xd * xd + zd * zd); double maxSpeed = MAX_SPEED; - if (rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY)) - { - shared_ptr livingRider = dynamic_pointer_cast(rider.lock()); - if (livingRider->isSprinting()) - { - maxSpeed *= 1.5; - } - } if (curSpeed > maxSpeed) { @@ -330,10 +327,12 @@ void Boat::tick() move(xd, yd, zd); // Break boat on high speed collision + float breakThreshold = (rider.lock() != nullptr) ? 0.35f : 0.20f; if ((horizontalCollision && lastSpeed > 0.20)) { if (!level->isClientSide && !removed) { + remove(); for (int i = 0; i < 3; i++) { @@ -343,6 +342,9 @@ void Boat::tick() { spawnAtLocation(Item::stick->id, 1, 0); } + + + } } else @@ -472,10 +474,19 @@ bool Boat::interact(shared_ptr player) if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true; if (!level->isClientSide) { + bool isRiding = (rider.lock() == player); + + if (isRiding) + { + + player->xd = 0; + player->yd = 0; + player->zd = 0; + } // 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446) - player->ride( rider.lock() == player ? nullptr : shared_from_this() ); - } - return true; + player->ride(isRiding ? nullptr : shared_from_this()); + } + return true; } void Boat::setDamage(float damage)