Fixed boats falling and a TP glitch #266

This commit is contained in:
Chase Cooper 2026-03-05 16:25:52 -05:00
parent d965a71464
commit 31c2699a32

View file

@ -74,7 +74,7 @@ bool Boat::isPushable()
Boat::Boat(Level *level, double x, double y, double z) : Entity( level ) Boat::Boat(Level *level, double x, double y, double z) : Entity( level )
{ {
_init(); _init();
setPos(x, y + heightOffset + 0.1, z); setPos(x, y + heightOffset, z);
xd = 0; xd = 0;
yd = 0; yd = 0;
@ -209,9 +209,30 @@ void Boat::tick()
} }
double lastSpeed = sqrt(xd * xd + zd * zd); 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) if (level->isClientSide && doLerp)
@ -224,8 +245,8 @@ void Boat::tick()
double yrd = Mth::wrapDegrees(lyr - yRot); double yrd = Mth::wrapDegrees(lyr - yRot);
yRot += static_cast<float>((yrd) / lSteps); yRot += (float) ( (yrd) / lSteps );
xRot += static_cast<float>((lxr - xRot) / lSteps); xRot += (float) ( (lxr - xRot) / lSteps );
lSteps--; lSteps--;
setPos(xt, yt, zt); setPos(xt, yt, zt);
@ -233,6 +254,7 @@ void Boat::tick()
} }
else else
{ {
#if 1
// Original // Original
//double xt = x + xd; //double xt = x + xd;
//double yt = y + yd; //double yt = y + yd;
@ -251,23 +273,51 @@ void Boat::tick()
xd *= 0.99f; xd *= 0.99f;
yd *= 0.95f; yd *= 0.95f;
zd *= 0.99f; 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; return;
} }
// Bob on water
if (waterPercentage > 0) if (waterPercentage > 0)
{ {
double bob = waterPercentage * 2 - 1; double bob = waterPercentage * 2 - 1;
yd += 0.04f * bob; yd += 0.04f * bob;
} }
else
// Reimplement "gravity" {
if (level->getTile(x, Mth::floor(y - 0.15), z) == 0 && !onGround) { yd = 0;
yd += 0.04f * -1.0; // -1.0 is what bob should return in this situation, just hardcoded.
} }
// Rider Controls
if ( rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY) ) if ( rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY) )
{ {
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock()); shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
@ -284,7 +334,6 @@ void Boat::tick()
double curSpeed = sqrt(xd * xd + zd * zd); double curSpeed = sqrt(xd * xd + zd * zd);
// Speed Clamp
if (curSpeed > MAX_SPEED) if (curSpeed > MAX_SPEED)
{ {
double ratio = MAX_SPEED / curSpeed; double ratio = MAX_SPEED / curSpeed;
@ -305,15 +354,14 @@ void Boat::tick()
if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION; if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION;
} }
// Slow speed on ground
if (onGround) if (onGround)
{ {
xd *= 0.5f; xd *= 0.5f;
yd *= 0.5f;
zd *= 0.5f; zd *= 0.5f;
} }
move(xd, yd, zd); move(xd, yd, zd);
// Break boat
if ((horizontalCollision && lastSpeed > 0.20)) if ((horizontalCollision && lastSpeed > 0.20))
{ {
if (!level->isClientSide && !removed) if (!level->isClientSide && !removed)
@ -342,7 +390,7 @@ void Boat::tick()
double zDiff = zo - z; double zDiff = zo - z;
if (xDiff * xDiff + zDiff * zDiff > 0.001) if (xDiff * xDiff + zDiff * zDiff > 0.001)
{ {
yRotT = static_cast<float>(atan2(zDiff, xDiff) * 180 / PI); yRotT = (float) (atan2(zDiff, xDiff) * 180 / PI);
} }
double rotDiff = Mth::wrapDegrees(yRotT - yRot); double rotDiff = Mth::wrapDegrees(yRotT - yRot);
@ -350,10 +398,9 @@ void Boat::tick()
if (rotDiff > 20) rotDiff = 20; if (rotDiff > 20) rotDiff = 20;
if (rotDiff < -20) rotDiff = -20; if (rotDiff < -20) rotDiff = -20;
yRot += static_cast<float>(rotDiff); yRot += (float) rotDiff;
setRot(yRot, xRot); setRot(yRot, xRot);
// Server only code below
if(level->isClientSide) return; if(level->isClientSide) return;
vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f)); vector<shared_ptr<Entity> > *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() void Boat::positionRider()
{ {
if (rider.lock() == NULL) return; if (rider.lock() == NULL) return;
double xa = cos(yRot * PI / 180) * 0.4; double xa = cos(yRot * PI / 180) * 0.4;
double za = sin(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);
} }