Topic category: User side tutorials
This tutorial is a way to enable two player riding on an entity.
The link below shows you what you're done with.
STEP1
- Create a custom entity.
- Check the ride function.
- Save.
STEP2
- Open the Code Editor.
- Add an import.
import java.util.ArrayList;
import java.util.List;
- Modify the code.
The original code 1
*Change the 'test' part of the code to the 'name of the Workspace AND Entity name.'
public class TestEntity extends Monster {
public TestEntity(PlayMessages.SpawnEntity packet, Level world) {
this(TestModEntities.TEST.get(), world);
}
Changed code 1
public class TestEntity extends Monster {
private List<Entity> customPassengers = new ArrayList<>(); // Add Code
public TestEntity(PlayMessages.SpawnEntity packet, Level world) {
this(TestModEntities.TEST.get(), world);
}
The original code 2
@Override
public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) {
ItemStack itemstack = sourceentity.getItemInHand(hand);
InteractionResult retval = InteractionResult.sidedSuccess(this.level().isClientSide());
super.mobInteract(sourceentity, hand);
sourceentity.startRiding(this);
return retval;
}
Changed code 2
@Override
public InteractionResult mobInteract(Player sourceentity, InteractionHand hand) {
ItemStack itemstack = sourceentity.getItemInHand(hand);
InteractionResult retval = super.mobInteract(sourceentity, hand);
if (!this.customPassengers.contains(sourceentity) && this.customPassengers.size() < 2) { // Add Riding 2 players.
sourceentity.startRiding(this, true); // Add Code
customPassengers.add(sourceentity); // Add Code
}
return retval;
}
The original code 3
@Override
public void travel(Vec3 dir) {
Entity entity = this.getPassengers().isEmpty() ? null : (Entity) this.getPassengers().get(0);
if (this.isVehicle()) {
this.setYRot(entity.getYRot());
this.yRotO = this.getYRot();
this.setXRot(entity.getXRot() * 0.5F);
this.setRot(this.getYRot(), this.getXRot());
this.yBodyRot = entity.getYRot();
this.yHeadRot = entity.getYRot();
if (entity instanceof LivingEntity passenger) {
this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED));
float forward = passenger.zza;
float strafe = passenger.xxa;
super.travel(new Vec3(strafe, 0, forward));
}
double d1 = this.getX() - this.xo;
double d0 = this.getZ() - this.zo;
float f1 = (float) Math.sqrt(d1 * d1 + d0 * d0) * 4;
if (f1 > 1.0F)
f1 = 1.0F;
this.walkAnimation.setSpeed(this.walkAnimation.speed() + (f1 - this.walkAnimation.speed()) * 0.4F);
this.walkAnimation.position(this.walkAnimation.position() + this.walkAnimation.speed());
this.calculateEntityAnimation(true);
return;
}
super.travel(dir);
}
Changed code 3
@Override
public void travel(Vec3 dir) {
if (this.isVehicle() && !this.customPassengers.isEmpty()) { // Add Code
Entity entity = this.customPassengers.get(0); // Add Code
this.setYRot(entity.getYRot());
this.yRotO = this.getYRot();
this.setXRot(entity.getXRot() * 0.5F);
this.setRot(this.getYRot(), this.getXRot());
this.yBodyRot = entity.getYRot();
this.yHeadRot = entity.getYRot();
if (entity instanceof LivingEntity passenger) {
this.setSpeed((float) this.getAttributeValue(Attributes.MOVEMENT_SPEED));
float forward = passenger.zza;
float strafe = passenger.xxa;
super.travel(new Vec3(strafe, 0, forward));
}
double d1 = this.getX() - this.xo;
double d0 = this.getZ() - this.zo;
float f1 = (float) Math.sqrt(d1 * d1 + d0 * d0) * 4;
if (f1 > 1.0F)
f1 = 1.0F;
this.walkAnimation.setSpeed(this.walkAnimation.speed() + (f1 - this.walkAnimation.speed()) * 0.4F);
this.walkAnimation.position(this.walkAnimation.position() + this.walkAnimation.speed());
this.calculateEntityAnimation(true);
this.setMaxUpStep(1.0f); // Makes you climb the hill when you have a rider in the entity.
return;
}
super.travel(dir);
}
Lastly, please add the code.
public static AttributeSupplier.Builder createAttributes() {
AttributeSupplier.Builder builder = Mob.createMobAttributes();
builder = builder.add(Attributes.MOVEMENT_SPEED, 0.3);
builder = builder.add(Attributes.MAX_HEALTH, 10);
builder = builder.add(Attributes.ARMOR, 0);
builder = builder.add(Attributes.ATTACK_DAMAGE, 3);
builder = builder.add(Attributes.FOLLOW_RANGE, 16);
return builder;
}
//Please add the following code below this code.
@Override
protected void positionRider(Entity passenger, MoveFunction moveFunction) {
if (this.hasPassenger(passenger)) {
int passengerIndex = this.getPassengers().indexOf(passenger);
double offsetX = this.getX();
double offsetY = this.getY() + 1.0D + passenger.getMyRidingOffset(); // Change ride Y height
double offsetZ = this.getZ();
if (passengerIndex == 0) {
// Location of the first passenger
offsetX = this.getX();
offsetZ = this.getZ();
} else if (passengerIndex == 1) {
// Second passenger's position
offsetX = this.getX() - Math.sin(Math.toRadians(this.getYRot())) * -1.0D;
offsetZ = this.getZ() + Math.cos(Math.toRadians(this.getYRot())) * -1.0D;
}
passenger.setPos(offsetX, offsetY, offsetZ);
}
}
}
Save and test the code.
It was completed by exchanging many questions and answers with Copilot(AI) to find this method.
When I tested it, the code I just posted works fine on single, but it still hasn't deleted the passenger list on multiplayer.
If you add the code below, it will also work in multi.
Wow
It worked! That's such a relief. I thought that solution might not be compatible with my Geckolib entities but it does.
Thanks again!
Do you know if this will cause bugs in multiplayer? The way I understand it, the first player will be the one controllingthe entity and the second one will be passive? I have yet to try it out with another player.
This is how the code works unless there is a specific case.
1. The first player will be on board
You can get back on board after you get off
2. First player on board and then second player on board (control has first player only)
When the first player gets off, the second player moves to the first passenger's seat
(Securing Control)
When the first player gets back on board, he sits behind the second player (the second rider who has moved forward takes control)
This work in 2024.1 with geckolib?
Geckolib is not used.
It works in 2024.3 version
In 2024.4 version, some code needs to be modified to work.