Super cool entities and fun, Part II
- Cats and Wolves will now sit down properly on seats - Adjusted some vertical offsets for seated passengers - Driver entities will now wear a hat when their train is given a schedule
This commit is contained in:
parent
dc44c7aa68
commit
0f994ecad2
13 changed files with 416 additions and 2 deletions
|
@ -143,6 +143,8 @@ public class AllBlockPartials {
|
||||||
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
|
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
|
||||||
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
|
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
|
||||||
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),
|
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),
|
||||||
|
|
||||||
|
TRAIN_HAT = entity("train_hat"),
|
||||||
|
|
||||||
COUPLING_ATTACHMENT = entity("minecart_coupling/attachment"), COUPLING_RING = entity("minecart_coupling/ring"),
|
COUPLING_ATTACHMENT = entity("minecart_coupling/attachment"), COUPLING_RING = entity("minecart_coupling/ring"),
|
||||||
COUPLING_CONNECTOR = entity("minecart_coupling/connector")
|
COUPLING_CONNECTOR = entity("minecart_coupling/connector")
|
||||||
|
|
|
@ -18,6 +18,7 @@ import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.Mob;
|
import net.minecraft.world.entity.Mob;
|
||||||
|
import net.minecraft.world.entity.TamableAnimal;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.CreativeModeTab;
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
import net.minecraft.world.item.DyeColor;
|
import net.minecraft.world.item.DyeColor;
|
||||||
|
@ -161,6 +162,8 @@ public class SeatBlock extends Block {
|
||||||
seat.setPos(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f);
|
seat.setPos(pos.getX() + .5f, pos.getY(), pos.getZ() + .5f);
|
||||||
world.addFreshEntity(seat);
|
world.addFreshEntity(seat);
|
||||||
entity.startRiding(seat, true);
|
entity.startRiding(seat, true);
|
||||||
|
if (entity instanceof TamableAnimal ta)
|
||||||
|
ta.setInSittingPose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DyeColor getColor() {
|
public DyeColor getColor() {
|
||||||
|
|
|
@ -13,6 +13,13 @@ import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.TamableAnimal;
|
||||||
|
import net.minecraft.world.entity.animal.Cat;
|
||||||
|
import net.minecraft.world.entity.animal.Parrot;
|
||||||
|
import net.minecraft.world.entity.animal.Wolf;
|
||||||
|
import net.minecraft.world.entity.monster.Creeper;
|
||||||
|
import net.minecraft.world.entity.monster.Skeleton;
|
||||||
|
import net.minecraft.world.entity.monster.Slime;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
@ -45,6 +52,30 @@ public class SeatEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||||
setBoundingBox(bb.move(diff));
|
setBoundingBox(bb.move(diff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void positionRider(Entity pEntity, Entity.MoveFunction pCallback) {
|
||||||
|
if (!this.hasPassenger(pEntity))
|
||||||
|
return;
|
||||||
|
double d0 = this.getY() + this.getPassengersRidingOffset() + pEntity.getMyRidingOffset();
|
||||||
|
pCallback.accept(pEntity, this.getX(), d0 + getCustomEntitySeatOffset(pEntity), this.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double getCustomEntitySeatOffset(Entity entity) {
|
||||||
|
if (entity instanceof Slime)
|
||||||
|
return 0.25f;
|
||||||
|
if (entity instanceof Parrot)
|
||||||
|
return 1 / 16f;
|
||||||
|
if (entity instanceof Skeleton)
|
||||||
|
return 1 / 8f;
|
||||||
|
if (entity instanceof Creeper)
|
||||||
|
return 1 / 8f;
|
||||||
|
if (entity instanceof Cat)
|
||||||
|
return 1 / 8f;
|
||||||
|
if (entity instanceof Wolf)
|
||||||
|
return 1 / 16f;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDeltaMovement(Vec3 p_213317_1_) {}
|
public void setDeltaMovement(Vec3 p_213317_1_) {}
|
||||||
|
|
||||||
|
@ -69,6 +100,8 @@ public class SeatEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||||
@Override
|
@Override
|
||||||
protected void removePassenger(Entity entity) {
|
protected void removePassenger(Entity entity) {
|
||||||
super.removePassenger(entity);
|
super.removePassenger(entity);
|
||||||
|
if (entity instanceof TamableAnimal ta)
|
||||||
|
ta.setInSittingPose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -51,6 +51,7 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.TamableAnimal;
|
||||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
import net.minecraft.world.entity.decoration.ArmorStand;
|
||||||
import net.minecraft.world.entity.decoration.HangingEntity;
|
import net.minecraft.world.entity.decoration.HangingEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
@ -120,6 +121,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
passenger.startRiding(this, true);
|
passenger.startRiding(this, true);
|
||||||
|
if (passenger instanceof TamableAnimal ta)
|
||||||
|
ta.setInSittingPose(true);
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
contraption.getSeatMapping()
|
contraption.getSeatMapping()
|
||||||
|
@ -132,6 +135,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
protected void removePassenger(Entity passenger) {
|
protected void removePassenger(Entity passenger) {
|
||||||
Vec3 transformedVector = getPassengerPosition(passenger, 1);
|
Vec3 transformedVector = getPassengerPosition(passenger, 1);
|
||||||
super.removePassenger(passenger);
|
super.removePassenger(passenger);
|
||||||
|
if (passenger instanceof TamableAnimal ta)
|
||||||
|
ta.setInSittingPose(false);
|
||||||
if (level.isClientSide)
|
if (level.isClientSide)
|
||||||
return;
|
return;
|
||||||
if (transformedVector != null)
|
if (transformedVector != null)
|
||||||
|
@ -150,7 +155,8 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
||||||
Vec3 transformedVector = getPassengerPosition(passenger, 1);
|
Vec3 transformedVector = getPassengerPosition(passenger, 1);
|
||||||
if (transformedVector == null)
|
if (transformedVector == null)
|
||||||
return;
|
return;
|
||||||
callback.accept(passenger, transformedVector.x, transformedVector.y, transformedVector.z);
|
callback.accept(passenger, transformedVector.x,
|
||||||
|
transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, transformedVector.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vec3 getPassengerPosition(Entity passenger, float partialTicks) {
|
protected Vec3 getPassengerPosition(Entity passenger, float partialTicks) {
|
||||||
|
|
|
@ -52,6 +52,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
SynchedEntityData.defineId(CarriageContraptionEntity.class, AllEntityDataSerializers.CARRIAGE_DATA);
|
SynchedEntityData.defineId(CarriageContraptionEntity.class, AllEntityDataSerializers.CARRIAGE_DATA);
|
||||||
private static final EntityDataAccessor<Optional<UUID>> TRACK_GRAPH =
|
private static final EntityDataAccessor<Optional<UUID>> TRACK_GRAPH =
|
||||||
SynchedEntityData.defineId(CarriageContraptionEntity.class, EntityDataSerializers.OPTIONAL_UUID);
|
SynchedEntityData.defineId(CarriageContraptionEntity.class, EntityDataSerializers.OPTIONAL_UUID);
|
||||||
|
private static final EntityDataAccessor<Boolean> SCHEDULED =
|
||||||
|
SynchedEntityData.defineId(CarriageContraptionEntity.class, EntityDataSerializers.BOOLEAN);
|
||||||
|
|
||||||
public UUID trainId;
|
public UUID trainId;
|
||||||
public int carriageIndex;
|
public int carriageIndex;
|
||||||
|
@ -79,6 +81,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
super.defineSynchedData();
|
super.defineSynchedData();
|
||||||
entityData.define(CARRIAGE_DATA, new CarriageSyncData());
|
entityData.define(CARRIAGE_DATA, new CarriageSyncData());
|
||||||
entityData.define(TRACK_GRAPH, Optional.empty());
|
entityData.define(TRACK_GRAPH, Optional.empty());
|
||||||
|
entityData.define(SCHEDULED, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void syncCarriage() {
|
public void syncCarriage() {
|
||||||
|
@ -113,6 +116,10 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
private CarriageSyncData getCarriageData() {
|
private CarriageSyncData getCarriageData() {
|
||||||
return entityData.get(CARRIAGE_DATA);
|
return entityData.get(CARRIAGE_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasSchedule() {
|
||||||
|
return entityData.get(SCHEDULED);
|
||||||
|
}
|
||||||
|
|
||||||
public static CarriageContraptionEntity create(Level world, CarriageContraption contraption) {
|
public static CarriageContraptionEntity create(Level world, CarriageContraption contraption) {
|
||||||
CarriageContraptionEntity entity =
|
CarriageContraptionEntity entity =
|
||||||
|
@ -167,6 +174,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
CarriageSyncData carriageData = getCarriageData();
|
CarriageSyncData carriageData = getCarriageData();
|
||||||
|
|
||||||
if (!level.isClientSide) {
|
if (!level.isClientSide) {
|
||||||
|
entityData.set(SCHEDULED, carriage.train.runtime.getSchedule() != null);
|
||||||
if (tickCount % getType().updateInterval() == 0 && carriageData.isDirty()) {
|
if (tickCount % getType().updateInterval() == 0 && carriageData.isDirty()) {
|
||||||
entityData.set(CARRIAGE_DATA, null);
|
entityData.set(CARRIAGE_DATA, null);
|
||||||
entityData.set(CARRIAGE_DATA, carriageData);
|
entityData.set(CARRIAGE_DATA, carriageData);
|
||||||
|
@ -257,9 +265,9 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
|
||||||
|
|
||||||
public Couple<Boolean> checkConductors() {
|
public Couple<Boolean> checkConductors() {
|
||||||
Couple<Boolean> sides = Couple.create(false, false);
|
Couple<Boolean> sides = Couple.create(false, false);
|
||||||
|
|
||||||
if (!(contraption instanceof CarriageContraption cc))
|
if (!(contraption instanceof CarriageContraption cc))
|
||||||
return sides;
|
return sides;
|
||||||
|
|
||||||
sides.setFirst(cc.blazeBurnerConductors.getFirst());
|
sides.setFirst(cc.blazeBurnerConductors.getFirst());
|
||||||
sides.setSecond(cc.blazeBurnerConductors.getSecond());
|
sides.setSecond(cc.blazeBurnerConductors.getSecond());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
package com.simibubi.create.content.logistics.trains.management.schedule;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.simibubi.create.AllBlockPartials;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
|
||||||
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||||
|
import com.simibubi.create.foundation.mixin.accessor.AgeableListModelAccessor;
|
||||||
|
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||||
|
import com.simibubi.create.foundation.utility.Couple;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.AgeableListModel;
|
||||||
|
import net.minecraft.client.model.AxolotlModel;
|
||||||
|
import net.minecraft.client.model.EntityModel;
|
||||||
|
import net.minecraft.client.model.HierarchicalModel;
|
||||||
|
import net.minecraft.client.model.LavaSlimeModel;
|
||||||
|
import net.minecraft.client.model.SlimeModel;
|
||||||
|
import net.minecraft.client.model.WolfModel;
|
||||||
|
import net.minecraft.client.model.geom.ModelPart;
|
||||||
|
import net.minecraft.client.model.geom.ModelPart.Cube;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.Sheets;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.RenderLayerParent;
|
||||||
|
import net.minecraft.client.renderer.entity.layers.RenderLayer;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class TrainHatArmorLayer<T extends LivingEntity, M extends EntityModel<T>> extends RenderLayer<T, M> {
|
||||||
|
|
||||||
|
private Vec3 offset;
|
||||||
|
|
||||||
|
public TrainHatArmorLayer(RenderLayerParent<T, M> renderer, Vec3 offset) {
|
||||||
|
super(renderer);
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(PoseStack ms, MultiBufferSource buffer, int light, LivingEntity entity, float yaw, float pitch,
|
||||||
|
float pt, float p_225628_8_, float p_225628_9_, float p_225628_10_) {
|
||||||
|
if (!shouldRenderOn(entity))
|
||||||
|
return;
|
||||||
|
|
||||||
|
M entityModel = getParentModel();
|
||||||
|
RenderType renderType = Sheets.cutoutBlockSheet();
|
||||||
|
ms.pushPose();
|
||||||
|
|
||||||
|
boolean valid = false;
|
||||||
|
TransformStack msr = TransformStack.cast(ms);
|
||||||
|
|
||||||
|
if (entityModel instanceof AgeableListModel<?> model) {
|
||||||
|
if (model.young) {
|
||||||
|
if (model.scaleHead) {
|
||||||
|
float f = 1.5F / model.babyHeadScale;
|
||||||
|
ms.scale(f, f, f);
|
||||||
|
}
|
||||||
|
ms.translate(0.0D, model.babyYHeadOffset / 16.0F, model.babyZHeadOffset / 16.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelPart head = getHeadPart(model);
|
||||||
|
if (head != null) {
|
||||||
|
head.translateAndRotate(ms);
|
||||||
|
|
||||||
|
if (model instanceof WolfModel)
|
||||||
|
head = head.getChild("real_head");
|
||||||
|
if (model instanceof AxolotlModel)
|
||||||
|
head = head.getChild("head");
|
||||||
|
|
||||||
|
ms.translate(offset.x / 16f, offset.y / 16f, offset.z / 16f);
|
||||||
|
|
||||||
|
if (!head.isEmpty()) {
|
||||||
|
Cube cube = head.cubes.get(0);
|
||||||
|
ms.translate(offset.x / 16f, (cube.minY - cube.maxY + offset.y) / 16f, offset.z / 16f);
|
||||||
|
float max = Math.max(cube.maxX - cube.minX, cube.maxZ - cube.minZ) / 8f;
|
||||||
|
ms.scale(max, max, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (entityModel instanceof HierarchicalModel<?> model) {
|
||||||
|
boolean slime = model instanceof SlimeModel || model instanceof LavaSlimeModel;
|
||||||
|
ModelPart head = model.root().children.get(slime ? "cube" : "head");
|
||||||
|
|
||||||
|
if (head != null) {
|
||||||
|
head.translateAndRotate(ms);
|
||||||
|
|
||||||
|
if (!head.isEmpty()) {
|
||||||
|
Cube cube = head.cubes.get(0);
|
||||||
|
ms.translate(offset.x, (cube.minY - cube.maxY + offset.y) / 16f, offset.z / 16f);
|
||||||
|
float max = Math.max(cube.maxX - cube.minX, cube.maxZ - cube.minZ) / (slime ? 6.5f : 8f);
|
||||||
|
ms.scale(max, max, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
ms.scale(1, -1, -1);
|
||||||
|
ms.translate(0, -2.25f / 16f, 0);
|
||||||
|
msr.rotateX(-8.5f);
|
||||||
|
BlockState air = Blocks.AIR.defaultBlockState();
|
||||||
|
CachedBufferer.partial(AllBlockPartials.TRAIN_HAT, air)
|
||||||
|
.forEntityRender()
|
||||||
|
.light(light)
|
||||||
|
.renderInto(ms, buffer.getBuffer(renderType));
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.popPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldRenderOn(LivingEntity entity) {
|
||||||
|
if (entity == null)
|
||||||
|
return false;
|
||||||
|
if (!entity.isPassenger())
|
||||||
|
return false;
|
||||||
|
Entity vehicle = entity.getVehicle();
|
||||||
|
if (!(vehicle instanceof CarriageContraptionEntity cce))
|
||||||
|
return false;
|
||||||
|
if (!cce.hasSchedule())
|
||||||
|
return false;
|
||||||
|
Contraption contraption = cce.getContraption();
|
||||||
|
if (!(contraption instanceof CarriageContraption cc))
|
||||||
|
return false;
|
||||||
|
BlockPos seatOf = cc.getSeatOf(entity.getUUID());
|
||||||
|
if (seatOf == null)
|
||||||
|
return false;
|
||||||
|
Couple<Boolean> validSides = cc.conductorSeats.get(seatOf);
|
||||||
|
return validSides != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerOnAll(EntityRenderDispatcher renderManager) {
|
||||||
|
for (EntityRenderer<? extends Player> renderer : renderManager.getSkinMap()
|
||||||
|
.values())
|
||||||
|
registerOn(renderer);
|
||||||
|
for (EntityRenderer<?> renderer : renderManager.renderers.values())
|
||||||
|
registerOn(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
public static void registerOn(EntityRenderer<?> entityRenderer) {
|
||||||
|
if (!(entityRenderer instanceof LivingEntityRenderer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
LivingEntityRenderer<?, ?> livingRenderer = (LivingEntityRenderer<?, ?>) entityRenderer;
|
||||||
|
EntityModel<?> model = livingRenderer.getModel();
|
||||||
|
|
||||||
|
if (!(model instanceof HierarchicalModel) && !(model instanceof AgeableListModel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vec3 offset = TrainHatOffsets.getOffset(model);
|
||||||
|
TrainHatArmorLayer<?, ?> layer = new TrainHatArmorLayer<>(livingRenderer, offset);
|
||||||
|
livingRenderer.addLayer((TrainHatArmorLayer) layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ModelPart getHeadPart(AgeableListModel<?> model) {
|
||||||
|
for (ModelPart part : ((AgeableListModelAccessor) model).create$callHeadParts())
|
||||||
|
return part;
|
||||||
|
for (ModelPart part : ((AgeableListModelAccessor) model).create$callBodyParts())
|
||||||
|
return part;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package com.simibubi.create.content.logistics.trains.management.schedule;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.AgeableListModel;
|
||||||
|
import net.minecraft.client.model.AxolotlModel;
|
||||||
|
import net.minecraft.client.model.BeeModel;
|
||||||
|
import net.minecraft.client.model.BlazeModel;
|
||||||
|
import net.minecraft.client.model.ChickenModel;
|
||||||
|
import net.minecraft.client.model.CowModel;
|
||||||
|
import net.minecraft.client.model.EntityModel;
|
||||||
|
import net.minecraft.client.model.FoxModel;
|
||||||
|
import net.minecraft.client.model.GuardianModel;
|
||||||
|
import net.minecraft.client.model.HierarchicalModel;
|
||||||
|
import net.minecraft.client.model.HoglinModel;
|
||||||
|
import net.minecraft.client.model.IronGolemModel;
|
||||||
|
import net.minecraft.client.model.LavaSlimeModel;
|
||||||
|
import net.minecraft.client.model.OcelotModel;
|
||||||
|
import net.minecraft.client.model.PandaModel;
|
||||||
|
import net.minecraft.client.model.ParrotModel;
|
||||||
|
import net.minecraft.client.model.PigModel;
|
||||||
|
import net.minecraft.client.model.QuadrupedModel;
|
||||||
|
import net.minecraft.client.model.SheepModel;
|
||||||
|
import net.minecraft.client.model.SlimeModel;
|
||||||
|
import net.minecraft.client.model.SnowGolemModel;
|
||||||
|
import net.minecraft.client.model.SpiderModel;
|
||||||
|
import net.minecraft.client.model.WolfModel;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class TrainHatOffsets {
|
||||||
|
|
||||||
|
// sorry
|
||||||
|
public static Vec3 getOffset(EntityModel<?> model) {
|
||||||
|
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
|
float z = 0;
|
||||||
|
|
||||||
|
if (model instanceof AgeableListModel) {
|
||||||
|
if (model instanceof WolfModel) {
|
||||||
|
x += .5f;
|
||||||
|
y += 1.5f;
|
||||||
|
z += .25f;
|
||||||
|
} else if (model instanceof OcelotModel) {
|
||||||
|
y += 1f;
|
||||||
|
z -= .25f;
|
||||||
|
} else if (model instanceof ChickenModel) {
|
||||||
|
z -= .25f;
|
||||||
|
} else if (model instanceof FoxModel) {
|
||||||
|
x += .5f;
|
||||||
|
y += 2f;
|
||||||
|
z -= 1f;
|
||||||
|
} else if (model instanceof QuadrupedModel) {
|
||||||
|
y += 2f;
|
||||||
|
|
||||||
|
if (model instanceof CowModel)
|
||||||
|
z -= 1.25f;
|
||||||
|
else if (model instanceof PandaModel)
|
||||||
|
z += .5f;
|
||||||
|
else if (model instanceof PigModel)
|
||||||
|
z -= 2f;
|
||||||
|
else if (model instanceof SheepModel) {
|
||||||
|
z -= .75f;
|
||||||
|
y -= 1.5f;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (model instanceof HoglinModel)
|
||||||
|
z -= 4.5f;
|
||||||
|
else if (model instanceof BeeModel) {
|
||||||
|
z -= .75f;
|
||||||
|
y -= 4f;
|
||||||
|
} else if (model instanceof AxolotlModel) {
|
||||||
|
z -= 5f;
|
||||||
|
y += .5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model instanceof HierarchicalModel) {
|
||||||
|
if (model instanceof BlazeModel)
|
||||||
|
y += 4;
|
||||||
|
else if (model instanceof GuardianModel)
|
||||||
|
y += 20;
|
||||||
|
else if (model instanceof IronGolemModel) {
|
||||||
|
z -= 1.5f;
|
||||||
|
y -= 2f;
|
||||||
|
} else if (model instanceof SnowGolemModel) {
|
||||||
|
z -= .75f;
|
||||||
|
y -= 3f;
|
||||||
|
} else if (model instanceof SlimeModel || model instanceof LavaSlimeModel) {
|
||||||
|
y += 22;
|
||||||
|
} else if (model instanceof SpiderModel) {
|
||||||
|
z -= 3.5f;
|
||||||
|
y += 2f;
|
||||||
|
} else if (model instanceof ParrotModel) {
|
||||||
|
z -= 1.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Vec3(x, y, z);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.CarriageCouplingRenderer;
|
import com.simibubi.create.content.logistics.trains.entity.CarriageCouplingRenderer;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.TrainRelocator;
|
import com.simibubi.create.content.logistics.trains.entity.TrainRelocator;
|
||||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
|
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
|
||||||
|
import com.simibubi.create.content.logistics.trains.management.schedule.TrainHatArmorLayer;
|
||||||
import com.simibubi.create.content.logistics.trains.track.TrackPlacement;
|
import com.simibubi.create.content.logistics.trains.track.TrackPlacement;
|
||||||
import com.simibubi.create.content.logistics.trains.track.TrackRemoval;
|
import com.simibubi.create.content.logistics.trains.track.TrackRemoval;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
|
@ -352,6 +353,7 @@ public class ClientEvents {
|
||||||
EntityRenderDispatcher dispatcher = Minecraft.getInstance()
|
EntityRenderDispatcher dispatcher = Minecraft.getInstance()
|
||||||
.getEntityRenderDispatcher();
|
.getEntityRenderDispatcher();
|
||||||
CopperBacktankArmorLayer.registerOnAll(dispatcher);
|
CopperBacktankArmorLayer.registerOnAll(dispatcher);
|
||||||
|
TrainHatArmorLayer.registerOnAll(dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.simibubi.create.foundation.mixin.accessor;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
import net.minecraft.client.model.AgeableListModel;
|
||||||
|
import net.minecraft.client.model.geom.ModelPart;
|
||||||
|
|
||||||
|
@Mixin(AgeableListModel.class)
|
||||||
|
public interface AgeableListModelAccessor {
|
||||||
|
@Invoker("headParts")
|
||||||
|
Iterable<ModelPart> create$callHeadParts();
|
||||||
|
@Invoker("bodyParts")
|
||||||
|
Iterable<ModelPart> create$callBodyParts();
|
||||||
|
}
|
|
@ -29,3 +29,12 @@ public net.minecraft.world.level.biome.BiomeManager f_47863_ # biomeZoomSeed
|
||||||
public net.minecraft.world.level.block.entity.BeaconBlockEntity f_58648_ # beamSections
|
public net.minecraft.world.level.block.entity.BeaconBlockEntity f_58648_ # beamSections
|
||||||
public net.minecraft.world.level.chunk.HashMapPalette f_62658_ # values
|
public net.minecraft.world.level.chunk.HashMapPalette f_62658_ # values
|
||||||
public net.minecraft.world.level.chunk.PaletteResize
|
public net.minecraft.world.level.chunk.PaletteResize
|
||||||
|
|
||||||
|
public net.minecraft.client.model.geom.ModelPart f_104212_ # cubes
|
||||||
|
public net.minecraft.client.model.geom.ModelPart f_104213_ # children
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_102007_ # scaleHead
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_170338_ # babyYHeadOffset
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_170339_ # babyZHeadOffset
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_102010_ # babyHeadScale
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_102011_ # babyBodyScale
|
||||||
|
public net.minecraft.client.model.AgeableListModel f_102012_ # bodyYOffset
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
"credit": "Made with Blockbench",
|
||||||
|
"textures": {
|
||||||
|
"0": "create:entity/train_hat",
|
||||||
|
"particle": "create:entity/train_hat"
|
||||||
|
},
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"from": [-4.5, 0, -4.5],
|
||||||
|
"to": [4.5, 3, 4.5],
|
||||||
|
"rotation": {"angle": 0, "axis": "x", "origin": [0, 0, -1.5]},
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [12, 4, 15, 13], "rotation": 90, "texture": "#0"},
|
||||||
|
"east": {"uv": [9, 4, 12, 13], "rotation": 270, "texture": "#0"},
|
||||||
|
"south": {"uv": [0, 2, 9, 5], "rotation": 180, "texture": "#0"},
|
||||||
|
"west": {"uv": [9, 4, 12, 13], "rotation": 90, "texture": "#0"},
|
||||||
|
"up": {"uv": [0, 5, 9, 14], "rotation": 180, "texture": "#0"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [4.5, 0, -4.5],
|
||||||
|
"to": [-4.5, 3, 4.5],
|
||||||
|
"rotation": {"angle": 0, "axis": "x", "origin": [0, 0, -1.5]},
|
||||||
|
"faces": {
|
||||||
|
"north": {"uv": [12, 4, 15, 13], "rotation": 90, "texture": "#0"},
|
||||||
|
"east": {"uv": [9, 4, 12, 13], "rotation": 270, "texture": "#0"},
|
||||||
|
"south": {"uv": [0, 2, 9, 5], "rotation": 180, "texture": "#0"},
|
||||||
|
"west": {"uv": [9, 4, 12, 13], "rotation": 90, "texture": "#0"},
|
||||||
|
"up": {"uv": [0, 5, 9, 14], "rotation": 180, "texture": "#0"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [-4.7, 0, -0.3],
|
||||||
|
"to": [4.7, 2, 4.7],
|
||||||
|
"rotation": {"angle": 0, "axis": "x", "origin": [0, 0, -1.5]},
|
||||||
|
"faces": {
|
||||||
|
"east": {"uv": [2, 16, 7, 14], "rotation": 180, "texture": "#0"},
|
||||||
|
"south": {"uv": [7, 14, 16, 16], "texture": "#0"},
|
||||||
|
"west": {"uv": [2, 14, 7, 16], "texture": "#0"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [-4.5, 1.3961, 4.04328],
|
||||||
|
"to": [4.5, 2.3961, 6.04328],
|
||||||
|
"rotation": {"angle": 22.5, "axis": "x", "origin": [0, 0, -1.5]},
|
||||||
|
"faces": {
|
||||||
|
"up": {"uv": [0, 0, 9, 2], "rotation": 180, "texture": "#0"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": [-4.5, 2.31684, 3.9585],
|
||||||
|
"to": [4.5, 3.31684, 5.9585],
|
||||||
|
"rotation": {"angle": 22.5, "axis": "x", "origin": [0, 0, -1.5]},
|
||||||
|
"faces": {
|
||||||
|
"down": {"uv": [0, 0, 9, 2], "texture": "#0"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
src/main/resources/assets/create/textures/entity/train_hat.png
Normal file
BIN
src/main/resources/assets/create/textures/entity/train_hat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -19,6 +19,7 @@
|
||||||
"HeavyBootsOnPlayerMixin",
|
"HeavyBootsOnPlayerMixin",
|
||||||
"ModelDataRefreshMixin",
|
"ModelDataRefreshMixin",
|
||||||
"WindowResizeMixin",
|
"WindowResizeMixin",
|
||||||
|
"accessor.AgeableListModelAccessor",
|
||||||
"accessor.GameRendererAccessor",
|
"accessor.GameRendererAccessor",
|
||||||
"accessor.ParticleEngineAccessor"
|
"accessor.ParticleEngineAccessor"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue