Super cool entities and fun
- Conductor entities now rotate to face their carts' motion - Fixed Contraption passengers not visible to clients whenever the seat position offsets them out of ticking chunks just after loading in
This commit is contained in:
parent
273a276fda
commit
9d8803d280
5 changed files with 82 additions and 12 deletions
|
@ -28,6 +28,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.int
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.MountedContraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket;
|
||||
import com.simibubi.create.foundation.collision.Matrix3d;
|
||||
import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
@ -44,10 +45,13 @@ import net.minecraft.network.syncher.EntityDataAccessor;
|
|||
import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||
import net.minecraft.world.entity.decoration.HangingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.Projectile;
|
||||
|
@ -267,7 +271,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
}
|
||||
|
||||
@Override
|
||||
public final void tick() {
|
||||
public void tick() {
|
||||
if (contraption == null) {
|
||||
discard();
|
||||
return;
|
||||
|
@ -287,6 +291,40 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
contraption.onEntityTick(level);
|
||||
tickContraption();
|
||||
super.tick();
|
||||
|
||||
if (!(level instanceof ServerLevelAccessor sl))
|
||||
return;
|
||||
|
||||
for (Entity entity : getPassengers()) {
|
||||
if (entity instanceof Player)
|
||||
continue;
|
||||
if (entity.isAlwaysTicking())
|
||||
continue;
|
||||
if (sl.create$getEntityTickList()
|
||||
.contains(entity))
|
||||
continue;
|
||||
positionRider(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public void alignPassenger(Entity passenger) {
|
||||
Vec3 motion = getContactPointMotion(passenger.getEyePosition());
|
||||
if (Mth.equal(motion.length(), 0))
|
||||
return;
|
||||
if (passenger instanceof ArmorStand)
|
||||
return;
|
||||
if (!(passenger instanceof LivingEntity living))
|
||||
return;
|
||||
float angle = AngleHelper.deg(-Mth.atan2(motion.x, motion.z));
|
||||
if (level.isClientSide) {
|
||||
living.lerpTo(0, 0, 0, 0, 0, 0, false);
|
||||
living.lerpHeadTo(0, 0);
|
||||
living.setYRot(angle);
|
||||
living.setXRot(0);
|
||||
living.yBodyRot = angle;
|
||||
living.yHeadRot = angle;
|
||||
} else
|
||||
living.setYRot(angle);
|
||||
}
|
||||
|
||||
protected abstract void tickContraption();
|
||||
|
@ -496,7 +534,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
return;
|
||||
|
||||
StructureTransform transform = makeStructureTransform();
|
||||
|
||||
|
||||
contraption.stop(level);
|
||||
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||
new ContraptionDisassemblyPacket(this.getId(), transform));
|
||||
|
@ -561,9 +599,6 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||
@Override
|
||||
public void onRemovedFromWorld() {
|
||||
super.onRemovedFromWorld();
|
||||
if (level != null && level.isClientSide)
|
||||
return;
|
||||
getPassengers().forEach(Entity::discard);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Entity.RemovalReason;
|
||||
|
@ -160,18 +161,21 @@ public class Carriage {
|
|||
|
||||
public void createEntity(Level level) {
|
||||
Entity entity = EntityType.loadEntityRecursive(serialisedEntity, level, e -> {
|
||||
level.addFreshEntity(e);
|
||||
e.moveTo(positionAnchor);
|
||||
return e;
|
||||
});
|
||||
|
||||
if (!(entity instanceof CarriageContraptionEntity cce))
|
||||
return;
|
||||
|
||||
Vec3 pos = positionAnchor;
|
||||
cce.setPos(pos);
|
||||
cce.setCarriage(this);
|
||||
cce.setGraph(train.graph == null ? null : train.graph.id);
|
||||
cce.setCarriage(this);
|
||||
cce.syncCarriage();
|
||||
|
||||
this.entity = new WeakReference<>(cce);
|
||||
|
||||
if (level instanceof ServerLevel sl)
|
||||
sl.tryAddFreshEntityWithPassengers(entity);
|
||||
}
|
||||
|
||||
public void manageEntity(Level level) {
|
||||
|
@ -196,11 +200,13 @@ public class Carriage {
|
|||
}
|
||||
|
||||
private void removeAndSaveEntity(CarriageContraptionEntity entity) {
|
||||
serialisedEntity = entity.serializeNBT();
|
||||
|
||||
for (Entity passenger : entity.getPassengers())
|
||||
if (!(passenger instanceof Player))
|
||||
passenger.remove(RemovalReason.UNLOADED_WITH_PLAYER);
|
||||
serialisedEntity = entity.serializeNBT();
|
||||
passenger.discard();
|
||||
entity.discard();
|
||||
|
||||
this.entity.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -124,9 +124,24 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
|||
return entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (contraption instanceof CarriageContraption cc)
|
||||
for (Entity entity : getPassengers()) {
|
||||
BlockPos seatOf = cc.getSeatOf(entity.getUUID());
|
||||
if (seatOf == null)
|
||||
continue;
|
||||
if (cc.conductorSeats.get(seatOf) == null)
|
||||
continue;
|
||||
alignPassenger(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tickContraption() {
|
||||
if (!(contraption instanceof CarriageContraption))
|
||||
if (!(contraption instanceof CarriageContraption cc))
|
||||
return;
|
||||
if (carriage == null) {
|
||||
if (level.isClientSide) {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package com.simibubi.create.foundation.mixin.accessor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.entity.EntityTickList;
|
||||
|
||||
@Mixin(ServerLevel.class)
|
||||
public interface ServerLevelAccessor {
|
||||
@Accessor("entityTickList")
|
||||
EntityTickList create$getEntityTickList();
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
"accessor.AbstractProjectileDispenseBehaviorAccessor",
|
||||
"accessor.DispenserBlockAccessor",
|
||||
"accessor.FallingBlockEntityAccessor",
|
||||
"accessor.ServerLevelAccessor",
|
||||
"accessor.LivingEntityAccessor"
|
||||
],
|
||||
"client": [
|
||||
|
|
Loading…
Reference in a new issue