aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Boat.cpp
diff options
context:
space:
mode:
authorqwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com>2026-03-16 21:44:26 -0500
committerGitHub <noreply@github.com>2026-03-16 21:44:26 -0500
commitce739f6045ec72127491286ea3f3f21e537c1b55 (patch)
treef33bd42a47c1b4a7b2153a7fb77127ee3b407db9 /Minecraft.World/Boat.cpp
parent255a18fe8e9b57377975f82e2b227afe2a12eda0 (diff)
parent5a59f5d146b43811dde6a5a0245ee9875d7b5cd1 (diff)
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.World/Boat.cpp')
-rw-r--r--Minecraft.World/Boat.cpp119
1 files changed, 51 insertions, 68 deletions
diff --git a/Minecraft.World/Boat.cpp b/Minecraft.World/Boat.cpp
index 1811c209..60d0c807 100644
--- a/Minecraft.World/Boat.cpp
+++ b/Minecraft.World/Boat.cpp
@@ -27,7 +27,7 @@ void Boat::_init()
blocksBuilding = true;
setSize(1.5f, 0.6f);
- heightOffset = bbHeight / 2.0f;
+ heightOffset = (bbHeight / 2.0f) + 0.2f;
// 4J Stu - This function call had to be moved here from the Entity ctor to ensure that
// the derived version of the function is called
@@ -97,7 +97,7 @@ bool Boat::hurt(DamageSource *source, float hurtDamage)
// 4J-JEV: Fix for #88212,
// Untrusted players shouldn't be able to damage minecarts or boats.
- if (dynamic_cast<EntityDamageSource *>(source) != NULL)
+ if (dynamic_cast<EntityDamageSource *>(source) != nullptr)
{
shared_ptr<Entity> attacker = source->getDirectEntity();
@@ -113,18 +113,18 @@ bool Boat::hurt(DamageSource *source, float hurtDamage)
// 4J Stu - If someone is riding in this, then it can tick multiple times which causes the damage to
// decrease too quickly. So just make the damage a bit higher to start with for similar behaviour
// to an unridden one. Only do this change if the riding player is attacking it.
- if( rider.lock() != NULL && rider.lock() == source->getEntity() ) hurtDamage += 1;
+ if( rider.lock() != nullptr && rider.lock() == source->getEntity() ) hurtDamage += 1;
setDamage(getDamage() + hurtDamage * 10);
markHurt();
// 4J Stu - Brought froward from 12w36 to fix #46611 - TU5: Gameplay: Minecarts and boat requires more hits than one to be destroyed in creative mode
// 4J-PB - Fix for XB1 #175735 - [CRASH] [Multi-Plat]: Code: Gameplay: Placing a boat on harmful surfaces causes the game to crash
- bool creativePlayer = (source->getEntity() != NULL) && source->getEntity()->instanceof(eTYPE_PLAYER) && dynamic_pointer_cast<Player>(source->getEntity())->abilities.instabuild;
+ bool creativePlayer = (source->getEntity() != nullptr) && source->getEntity()->instanceof(eTYPE_PLAYER) && dynamic_pointer_cast<Player>(source->getEntity())->abilities.instabuild;
if (creativePlayer || getDamage() > 20 * 2)
{
- if (rider.lock() != NULL) rider.lock()->ride( shared_from_this() );
+ if (rider.lock() != nullptr) rider.lock()->ride( shared_from_this() );
if (!creativePlayer) spawnAtLocation(Item::boat_Id, 1, 0);
remove();
}
@@ -194,7 +194,7 @@ void Boat::tick()
yo = y;
zo = z;
-
+ // Check how much of the boat is in water
int steps = 5;
double waterPercentage = 0;
for (int i = 0; i < steps; i++)
@@ -208,33 +208,14 @@ void Boat::tick()
}
}
+ // Create particles
double lastSpeed = sqrt(xd * xd + zd * zd);
- if (lastSpeed > MAX_COLLISION_SPEED)
+ if (lastSpeed > MAX_COLLISION_SPEED && waterPercentage > 0)
{
- 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);
- }
- }
+ createSplash(lastSpeed);
}
+ // Interpolation
if (level->isClientSide && doLerp)
{
if (lSteps > 0)
@@ -254,7 +235,6 @@ void Boat::tick()
}
else
{
-#if 1
// Original
//double xt = x + xd;
//double yt = y + yd;
@@ -273,52 +253,26 @@ 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 in water
if (waterPercentage > 0)
{
double bob = waterPercentage * 2 - 1;
yd += 0.04f * bob;
}
- else
+
+ // Reimplement gravity again (??)
+ int tileUnder = level->getTile(Mth::floor(x), Mth::floor(y-0.15), Mth::floor(z));
+ if (tileUnder == 0 && !onGround)
{
- yd = 0;
+ yd -= 0.04f;
}
-
- if ( rider.lock() != NULL && rider.lock()->instanceof(eTYPE_LIVINGENTITY) )
+ // Rider controls
+ if ( rider.lock() != nullptr && rider.lock()->instanceof(eTYPE_LIVINGENTITY) )
{
shared_ptr<LivingEntity> livingRider = dynamic_pointer_cast<LivingEntity>(rider.lock());
double forward = livingRider->yya;
@@ -354,6 +308,7 @@ void Boat::tick()
if (acceleration < MIN_ACCELERATION) acceleration = MIN_ACCELERATION;
}
+ // Slow on ground
if (onGround)
{
xd *= 0.5f;
@@ -362,6 +317,7 @@ void Boat::tick()
}
move(xd, yd, zd);
+ // Break boat on high speed collision
if ((horizontalCollision && lastSpeed > 0.20))
{
if (!level->isClientSide && !removed)
@@ -401,6 +357,7 @@ void Boat::tick()
yRot += (float) rotDiff;
setRot(yRot, xRot);
+ // Server code after this
if(level->isClientSide) return;
vector<shared_ptr<Entity> > *entities = level->getEntities(shared_from_this(), bb->grow(0.2f, 0, 0.2f));
@@ -438,19 +395,44 @@ void Boat::tick()
}
- if (rider.lock() != NULL)
+ if (rider.lock() != nullptr)
{
if (rider.lock()->removed) rider = weak_ptr<Entity>();
}
}
+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;
+ if (rider.lock() == nullptr) 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(), z + za);
+ // We minus 0.4 to ensure that the player is not hovering above the boat.
+ rider.lock()->setPos(x + xa, y + getRideHeight() + rider.lock()->getRidingHeight()-0.4, z + za);
}
@@ -475,7 +457,7 @@ wstring Boat::getName()
bool Boat::interact(shared_ptr<Player> player)
{
- if ( (rider.lock() != NULL) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true;
+ if ( (rider.lock() != nullptr) && rider.lock()->instanceof(eTYPE_PLAYER) && (rider.lock() != player) ) return true;
if (!level->isClientSide)
{
// 4J HEG - Fixed issue with player not being able to dismount boat (issue #4446)
@@ -523,3 +505,4 @@ void Boat::setDoLerp(bool doLerp)
{
this->doLerp = doLerp;
}
+