mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-11 13:04:19 +01:00
It's alive
- Contraptions pushed by Mechanical Pistons are now wrapped into entities - Fixed Lighting and Positioning of Contraption entities
This commit is contained in:
parent
1d96f50b9a
commit
1563a3991c
@ -8,13 +8,11 @@ import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.TooltipHelper;
|
||||
import com.simibubi.create.modules.contraptions.KineticDebugger;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.TurntableHandler;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItemHandler;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -1,12 +1,11 @@
|
||||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.foundation.world.OreGeneration;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.simibubi.create.foundation.world.OreGeneration;
|
||||
import com.simibubi.create.modules.ModuleLoadedCondition;
|
||||
import com.simibubi.create.modules.contraptions.TorquePropagator;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MovingConstructHandler;
|
||||
import com.simibubi.create.modules.logistics.FrequencyHandler;
|
||||
import com.simibubi.create.modules.logistics.management.LogisticalNetworkHandler;
|
||||
import com.simibubi.create.modules.logistics.transport.villager.LogisticianHandler;
|
||||
@ -25,7 +24,6 @@ import net.minecraft.village.PointOfInterestType;
|
||||
import net.minecraftforge.common.crafting.CraftingHelper;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
@ -43,7 +41,6 @@ public class Create {
|
||||
public static ItemGroup creativeTab = new CreateItemGroup();
|
||||
public static ServerSchematicLoader schematicReceiver;
|
||||
public static FrequencyHandler frequencyHandler;
|
||||
public static MovingConstructHandler constructHandler;
|
||||
public static LogisticalNetworkHandler logisticalNetworkHandler;
|
||||
public static TorquePropagator torquePropagator;
|
||||
public static LogisticianHandler logisticianHandler;
|
||||
@ -75,7 +72,6 @@ public class Create {
|
||||
public static void init(final FMLCommonSetupEvent event) {
|
||||
schematicReceiver = new ServerSchematicLoader();
|
||||
frequencyHandler = new FrequencyHandler();
|
||||
constructHandler = new MovingConstructHandler();
|
||||
logisticalNetworkHandler = new LogisticalNetworkHandler();
|
||||
torquePropagator = new TorquePropagator();
|
||||
|
||||
|
@ -44,7 +44,6 @@ public class Events {
|
||||
public static void onLoadWorld(WorldEvent.Load event) {
|
||||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onLoadWorld(world);
|
||||
Create.constructHandler.onLoadWorld(world);
|
||||
Create.logisticalNetworkHandler.onLoadWorld(world);
|
||||
Create.torquePropagator.onLoadWorld(world);
|
||||
}
|
||||
@ -53,7 +52,6 @@ public class Events {
|
||||
public static void onUnloadWorld(WorldEvent.Unload event) {
|
||||
IWorld world = event.getWorld();
|
||||
Create.frequencyHandler.onUnloadWorld(world);
|
||||
Create.constructHandler.onUnloadWorld(world);
|
||||
Create.logisticalNetworkHandler.onUnloadWorld(world);
|
||||
Create.torquePropagator.onUnloadWorld(world);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public class SuperByteBuffer {
|
||||
// Vertex Lighting
|
||||
private boolean shouldLight;
|
||||
private IVertexLighter vertexLighter;
|
||||
private float lightOffsetX, lightOffsetY, lightOffsetZ;
|
||||
private int packedLightCoords;
|
||||
|
||||
// Vertex Coloring
|
||||
@ -84,7 +85,8 @@ public class SuperByteBuffer {
|
||||
|
||||
if (shouldLight) {
|
||||
if (vertexLighter != null)
|
||||
putLight(mutable, vertex, vertexLighter.getPackedLight(x2, y2, z2));
|
||||
putLight(mutable, vertex,
|
||||
vertexLighter.getPackedLight(x2 + lightOffsetX, y2 + lightOffsetY, z2 + lightOffsetZ));
|
||||
else
|
||||
putLight(mutable, vertex, packedLightCoords);
|
||||
}
|
||||
@ -153,6 +155,7 @@ public class SuperByteBuffer {
|
||||
|
||||
public SuperByteBuffer light(int packedLightCoords) {
|
||||
shouldLight = true;
|
||||
vertexLighter = null;
|
||||
this.packedLightCoords = packedLightCoords;
|
||||
return this;
|
||||
}
|
||||
@ -163,6 +166,13 @@ public class SuperByteBuffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer offsetLighting(double x, double y, double z) {
|
||||
lightOffsetX = (float) x;
|
||||
lightOffsetY = (float) y;
|
||||
lightOffsetZ = (float) z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SuperByteBuffer color(int color) {
|
||||
shouldColor = true;
|
||||
r = ((color >> 16) & 0xFF);
|
||||
|
@ -20,6 +20,8 @@ import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateConfig;
|
||||
import com.simibubi.create.modules.contraptions.receivers.SawBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.mounted.MountedContraption;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.piston.PistonContraption;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.FallingBlock;
|
||||
@ -117,13 +119,13 @@ public class Contraption {
|
||||
return cachedColliders;
|
||||
}
|
||||
|
||||
protected boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
|
||||
public boolean searchMovedStructure(World world, BlockPos pos, Direction direction) {
|
||||
List<BlockPos> frontier = new ArrayList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
anchor = pos;
|
||||
|
||||
if (constructCollisionBox == null)
|
||||
constructCollisionBox = new AxisAlignedBB(pos);
|
||||
constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO);
|
||||
|
||||
frontier.add(pos);
|
||||
if (!addToInitialFrontier(world, pos, direction, frontier))
|
||||
@ -433,12 +435,24 @@ public class Contraption {
|
||||
return compoundnbt;
|
||||
}
|
||||
|
||||
protected void add(BlockPos pos, BlockInfo block) {
|
||||
BlockInfo blockInfo = new BlockInfo(pos, block.state, block.nbt);
|
||||
blocks.put(pos, blockInfo);
|
||||
public void add(BlockPos pos, BlockInfo block) {
|
||||
BlockPos localPos = pos.subtract(anchor);
|
||||
BlockInfo blockInfo = new BlockInfo(localPos, block.state, block.nbt);
|
||||
blocks.put(localPos, blockInfo);
|
||||
if (block.state.getBlock() instanceof IHaveMovementBehavior)
|
||||
getActors().add(MutablePair.of(blockInfo, null));
|
||||
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(pos));
|
||||
constructCollisionBox = constructCollisionBox.union(new AxisAlignedBB(localPos));
|
||||
}
|
||||
|
||||
public static Contraption fromNBT(CompoundNBT nbt) {
|
||||
String type = nbt.getString("Type");
|
||||
Contraption contraption = new Contraption();
|
||||
if (type.equals("Piston"))
|
||||
contraption = new PistonContraption();
|
||||
if (type.equals("Mounted"))
|
||||
contraption = new MountedContraption();
|
||||
contraption.readNBT(nbt);
|
||||
return contraption;
|
||||
}
|
||||
|
||||
public void readNBT(CompoundNBT nbt) {
|
||||
@ -469,6 +483,12 @@ public class Contraption {
|
||||
|
||||
public CompoundNBT writeNBT() {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
|
||||
if (this instanceof PistonContraption)
|
||||
nbt.putString("Type", "Piston");
|
||||
if (this instanceof MountedContraption)
|
||||
nbt.putString("Type", "Mounted");
|
||||
|
||||
ListNBT blocks = new ListNBT();
|
||||
for (BlockInfo block : this.blocks.values()) {
|
||||
CompoundNBT c = new CompoundNBT();
|
||||
@ -520,7 +540,12 @@ public class Contraption {
|
||||
return CreateConfig.parameters.freezePistonConstructs.get();
|
||||
}
|
||||
|
||||
public void disassemble(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customPlacement) {
|
||||
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
|
||||
disassemble(world, offset, yaw, pitch, (pos, state) -> false);
|
||||
}
|
||||
|
||||
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch,
|
||||
BiPredicate<BlockPos, BlockState> customPlacement) {
|
||||
for (BlockInfo block : blocks.values()) {
|
||||
BlockPos targetPos = block.pos.add(offset);
|
||||
BlockState state = block.state;
|
||||
@ -550,4 +575,8 @@ public class Contraption {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public BlockPos getAnchor() {
|
||||
return anchor;
|
||||
}
|
||||
|
||||
}
|
@ -31,7 +31,7 @@ public class ContraptionRenderer {
|
||||
public static void render(World world, Contraption c, Consumer<SuperByteBuffer> transform, BufferBuilder buffer) {
|
||||
SuperByteBuffer contraptionBuffer = CreateClient.bufferCache.get(CONTRAPTION, c, () -> renderContraption(c));
|
||||
transform.accept(contraptionBuffer);
|
||||
buffer.putBulkData(contraptionBuffer.build());
|
||||
contraptionBuffer.light((lx, ly, lz) -> world.getCombinedLight(new BlockPos(lx, ly, lz), 0)).renderInto(buffer);
|
||||
renderActors(world, c, transform, buffer);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.receivers.constructs.mounted;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.RenderUtilityBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption;
|
||||
|
||||
import net.minecraft.block.AbstractRailBlock;
|
||||
import net.minecraft.block.Block;
|
||||
@ -72,7 +73,7 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||
if (!cart.getPassengers().isEmpty())
|
||||
return;
|
||||
|
||||
MountedContraption contraption = MountedContraption.assembleMinecart(world, pos, cart);
|
||||
Contraption contraption = MountedContraption.assembleMinecart(world, pos, cart);
|
||||
ContraptionEntity entity = new ContraptionEntity(world, contraption,
|
||||
ContraptionEntity.yawFromMotion(cart.getMotion()));
|
||||
entity.setPosition(pos.getX(), pos.getY(), pos.getZ());
|
||||
@ -86,11 +87,11 @@ public class CartAssemblerBlock extends AbstractRailBlock {
|
||||
Entity entity = cart.getPassengers().get(0);
|
||||
if (!(entity instanceof ContraptionEntity))
|
||||
return;
|
||||
MountedContraption contraption = ((ContraptionEntity) entity).contraption;
|
||||
Contraption contraption = ((ContraptionEntity) entity).getContraption();
|
||||
if (contraption == null)
|
||||
return;
|
||||
|
||||
contraption.disassemble(world, pos.subtract(contraption.getAnchor()), (targetPos, state) -> {
|
||||
contraption.disassemble(world, pos.subtract(contraption.getAnchor()), 0, 0, (targetPos, state) -> {
|
||||
return targetPos.equals(pos);
|
||||
});
|
||||
|
||||
|
@ -2,35 +2,36 @@ package com.simibubi.create.modules.contraptions.receivers.constructs.mounted;
|
||||
|
||||
import com.simibubi.create.AllEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.network.FMLPlayMessages.SpawnEntity;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||
|
||||
protected MountedContraption contraption;
|
||||
private Contraption contraption;
|
||||
protected float initialAngle;
|
||||
|
||||
enum MovementType {
|
||||
TRANSLATION, ROTATION, MOUNTED;
|
||||
}
|
||||
|
||||
// Not synchronizing any of these
|
||||
protected BlockPos controllerPos;
|
||||
protected IControlContraption controllerTE;
|
||||
|
||||
// Not synchronizing any of these yet
|
||||
public float targetYaw;
|
||||
public float targetPitch;
|
||||
public float contraptionYaw;
|
||||
@ -44,7 +45,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
this(AllEntities.CONTRAPTION.type, world);
|
||||
}
|
||||
|
||||
public ContraptionEntity(World world, MountedContraption contraption, float initialAngle) {
|
||||
public ContraptionEntity(World world, Contraption contraption, float initialAngle) {
|
||||
this(world);
|
||||
this.contraption = contraption;
|
||||
this.initialAngle = initialAngle;
|
||||
@ -53,16 +54,19 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
this.targetYaw = initialAngle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerData() {
|
||||
public <T extends TileEntity & IControlContraption> ContraptionEntity controlledBy(T controller) {
|
||||
this.controllerPos = controller.getPos();
|
||||
this.controllerTE = controller;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
attachToController();
|
||||
Entity e = getRidingEntity();
|
||||
if (e == null)
|
||||
remove();
|
||||
return;
|
||||
else {
|
||||
Vec3d movementVector = e.getMotion();
|
||||
Vec3d motion = movementVector.normalize();
|
||||
@ -86,7 +90,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
}
|
||||
|
||||
public void tickActors(Vec3d movementVector) {
|
||||
contraption.getActors().forEach(pair -> {
|
||||
getContraption().getActors().forEach(pair -> {
|
||||
MovementContext context = pair.right;
|
||||
float deg = -contraptionYaw + initialAngle;
|
||||
context.motion = VecHelper.rotate(movementVector, deg, Axis.Y);
|
||||
@ -94,15 +98,15 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
if (context.world == null)
|
||||
context.world = world;
|
||||
|
||||
Vec3d offset = new Vec3d(pair.left.pos.subtract(contraption.getAnchor()));
|
||||
Vec3d offset = new Vec3d(pair.left.pos.subtract(getContraption().getAnchor()));
|
||||
world.addParticle(ParticleTypes.BUBBLE, offset.x, offset.y, offset.z, 0, 0, 0);
|
||||
|
||||
|
||||
offset = VecHelper.rotate(offset, deg, Axis.Y);
|
||||
world.addParticle(ParticleTypes.CRIT, offset.x, offset.y, offset.z, 0, 0, 0);
|
||||
|
||||
|
||||
offset = offset.add(new Vec3d(getPosition()).add(0.5, 0, 0.5));
|
||||
world.addParticle(ParticleTypes.NOTE, offset.x, offset.y, offset.z, 0, 10, 0);
|
||||
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
@ -116,6 +120,20 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPosition(double x, double y, double z) {
|
||||
this.posX = x;
|
||||
this.posY = y;
|
||||
this.posZ = z;
|
||||
if (this.isAddedToWorld() && !this.world.isRemote && world instanceof ServerWorld)
|
||||
((ServerWorld) this.world).chunkCheck(this); // Forge - Process chunk registration after moving.
|
||||
if (contraption != null) {
|
||||
AxisAlignedBB cbox = contraption.getCollisionBoxFront();
|
||||
if (cbox != null)
|
||||
this.setBoundingBox(cbox.offset(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
public static float yawFromMotion(Vec3d motion) {
|
||||
return (float) ((Math.PI / 2 - Math.atan2(motion.z, motion.x)) / Math.PI * 180);
|
||||
}
|
||||
@ -137,49 +155,46 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
return current + shortest_angle * pct;
|
||||
}
|
||||
|
||||
public boolean hitByEntity(Entity entityIn) {
|
||||
return entityIn instanceof PlayerEntity
|
||||
? this.attackEntityFrom(DamageSource.causePlayerDamage((PlayerEntity) entityIn), 0.0F)
|
||||
: false;
|
||||
}
|
||||
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
if (this.isInvulnerableTo(source)) {
|
||||
return false;
|
||||
} else {
|
||||
if (this.isAlive() && !this.world.isRemote) {
|
||||
this.remove();
|
||||
this.markVelocityChanged();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EntityType.Builder<ContraptionEntity> entityBuilder = (EntityType.Builder<ContraptionEntity>) builder;
|
||||
return entityBuilder.setCustomClientFactory(ContraptionEntity::spawn).size(1, 1);
|
||||
return entityBuilder.size(1, 1);
|
||||
}
|
||||
|
||||
public static ContraptionEntity spawn(SpawnEntity spawnEntity, World world) {
|
||||
return new ContraptionEntity(world);
|
||||
@Override
|
||||
protected void registerData() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditional(CompoundNBT compound) {
|
||||
contraption = new MountedContraption();
|
||||
contraption.readNBT(compound.getCompound("Contraption"));
|
||||
contraption = Contraption.fromNBT(compound.getCompound("Contraption"));
|
||||
initialAngle = compound.getFloat("InitialAngle");
|
||||
if (compound.contains("Controller"))
|
||||
controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller"));
|
||||
prevRotationYaw = initialAngle;
|
||||
contraptionYaw = initialAngle;
|
||||
targetYaw = initialAngle;
|
||||
}
|
||||
|
||||
public void attachToController() {
|
||||
if (controllerPos != null && controllerTE == null) {
|
||||
if (!world.isBlockPresent(controllerPos))
|
||||
return;
|
||||
TileEntity te = world.getTileEntity(controllerPos);
|
||||
if (te == null || !(te instanceof IControlContraption))
|
||||
remove();
|
||||
IControlContraption controllerTE = (IControlContraption) te;
|
||||
this.controllerTE = controllerTE;
|
||||
controllerTE.attach(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeAdditional(CompoundNBT compound) {
|
||||
compound.put("Contraption", contraption.writeNBT());
|
||||
compound.put("Contraption", getContraption().writeNBT());
|
||||
compound.putFloat("InitialAngle", initialAngle);
|
||||
if (controllerPos != null)
|
||||
compound.put("Controller", NBTUtil.writeBlockPos(controllerPos));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -199,4 +214,15 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||
readAdditional(additionalData.readCompoundTag());
|
||||
}
|
||||
|
||||
public void disassemble() {
|
||||
if (getContraption() != null)
|
||||
getContraption().disassemble(world, new BlockPos(getPositionVec().add(.5, .5, .5)), contraptionYaw,
|
||||
contraptionPitch);
|
||||
remove();
|
||||
}
|
||||
|
||||
public Contraption getContraption() {
|
||||
return contraption;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package com.simibubi.create.modules.contraptions.receivers.constructs.mounted;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||
@ -13,7 +13,6 @@ import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
@ -32,18 +31,17 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
||||
public void doRender(ContraptionEntity entity, double x, double y, double z, float yaw, float partialTicks) {
|
||||
if (!entity.isAlive())
|
||||
return;
|
||||
if (entity.contraption == null)
|
||||
if (entity.getContraption() == null)
|
||||
return;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(0, .5, 0);
|
||||
|
||||
float angleYaw = (float) (entity.getYaw(partialTicks) / 180 * Math.PI);
|
||||
float anglePitch = (float) (entity.getPitch(partialTicks) / 180 * Math.PI);
|
||||
|
||||
Entity ridingEntity = entity.getRidingEntity();
|
||||
if (ridingEntity != null && ridingEntity instanceof AbstractMinecartEntity) {
|
||||
AbstractMinecartEntity cart = (AbstractMinecartEntity) ridingEntity;
|
||||
GlStateManager.translated(0, .5, 0);
|
||||
|
||||
long i = (long) entity.getEntityId() * 493286711L;
|
||||
i = i * i * 4392167121L + i * 98761L;
|
||||
@ -74,21 +72,27 @@ public class ContraptionEntityRenderer extends EntityRenderer<ContraptionEntity>
|
||||
}
|
||||
}
|
||||
|
||||
BlockPos anchor = entity.contraption.getAnchor();
|
||||
Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
|
||||
// BlockPos anchor = entity.getContraption().getAnchor();
|
||||
// Vec3d rotationOffset = VecHelper.getCenterOf(anchor);
|
||||
// Vec3d offset = VecHelper.getCenterOf(anchor).scale(-1);
|
||||
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
ContraptionRenderer.render(entity.world, entity.contraption, superByteBuffer -> {
|
||||
superByteBuffer.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
|
||||
ContraptionRenderer.render(entity.world, entity.getContraption(), superByteBuffer -> {
|
||||
// superByteBuffer.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z);
|
||||
superByteBuffer.rotate(Axis.Y, angleYaw);
|
||||
superByteBuffer.rotate(Axis.Z, anglePitch);
|
||||
superByteBuffer.translate(x, y, z);
|
||||
superByteBuffer.offsetLighting(-x + entity.posX, -y + entity.posY, -z + entity.posZ);
|
||||
|
||||
}, Tessellator.getInstance().getBuffer());
|
||||
TessellatorHelper.draw();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.shadeModel(7424);
|
||||
GlStateManager.alphaFunc(516, 0.1F);
|
||||
GlStateManager.matrixMode(5888);
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
super.doRender(entity, x, y, z, yaw, partialTicks);
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package com.simibubi.create.modules.contraptions.receivers.constructs.mounted;
|
||||
|
||||
public interface IControlContraption {
|
||||
|
||||
public void attach(ContraptionEntity contraption);
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
|
||||
public class MountedContraption extends Contraption {
|
||||
|
||||
public static MountedContraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
public static Contraption assembleMinecart(World world, BlockPos pos, AbstractMinecartEntity cart) {
|
||||
if (isFrozen())
|
||||
return null;
|
||||
|
||||
@ -34,7 +34,7 @@ public class MountedContraption extends Contraption {
|
||||
if (!state.has(RAIL_SHAPE))
|
||||
return null;
|
||||
|
||||
MountedContraption contraption = new MountedContraption();
|
||||
Contraption contraption = new MountedContraption();
|
||||
Vec3d vec = cart.getMotion();
|
||||
if (!contraption.searchMovedStructure(world, pos, Direction.getFacingFromVector(vec.x, vec.y, vec.z)))
|
||||
return null;
|
||||
@ -83,8 +83,4 @@ public class MountedContraption extends Contraption {
|
||||
return capture;
|
||||
}
|
||||
|
||||
public BlockPos getAnchor() {
|
||||
return anchor;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,20 +1,14 @@
|
||||
package com.simibubi.create.modules.contraptions.receivers.constructs.piston;
|
||||
|
||||
import static com.simibubi.create.CreateConfig.parameters;
|
||||
import static com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.STATE;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MovementContext;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior.MoverType;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.mounted.ContraptionEntity;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.mounted.IControlContraption;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.piston.MechanicalPistonBlock.PistonState;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
@ -30,14 +24,16 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
public class MechanicalPistonTileEntity extends KineticTileEntity implements IControlContraption {
|
||||
|
||||
protected PistonContraption movedContraption;
|
||||
protected float offset;
|
||||
protected boolean running;
|
||||
protected boolean assembleNextTick;
|
||||
protected boolean hadCollisionWithOtherPiston;
|
||||
|
||||
protected ContraptionEntity movedContraption;
|
||||
protected int extensionLength;
|
||||
|
||||
public MechanicalPistonTileEntity() {
|
||||
super(AllTileEntities.MECHANICAL_PISTON.type);
|
||||
}
|
||||
@ -71,9 +67,7 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
public CompoundNBT write(CompoundNBT tag) {
|
||||
tag.putBoolean("Running", running);
|
||||
tag.putFloat("Offset", offset);
|
||||
if (running && !PistonContraption.isFrozen())
|
||||
tag.put("Construct", movedContraption.writeNBT());
|
||||
|
||||
tag.putInt("ExtensionLength", extensionLength);
|
||||
return super.write(tag);
|
||||
}
|
||||
|
||||
@ -81,76 +75,40 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
public void read(CompoundNBT tag) {
|
||||
running = tag.getBoolean("Running");
|
||||
offset = tag.getFloat("Offset");
|
||||
if (running && !PistonContraption.isFrozen()) {
|
||||
movedContraption = new PistonContraption();
|
||||
movedContraption.readNBT(tag.getCompound("Construct"));
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
|
||||
MovementContext context = new MovementContext(pair.left.state, MoverType.PISTON);
|
||||
context.world = world;
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
context.motion = new Vec3d(direction.getDirectionVec()).scale(getMovementSpeed()).normalize();
|
||||
context.currentGridPos = pair.left.pos.offset(direction, getModulatedOffset(offset));
|
||||
pair.setRight(context);
|
||||
}
|
||||
}
|
||||
|
||||
extensionLength = tag.getInt("ExtensionLength");
|
||||
super.read(tag);
|
||||
}
|
||||
|
||||
protected void onBlockVisited(float newOffset) {
|
||||
if (PistonContraption.isFrozen())
|
||||
return;
|
||||
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
|
||||
BlockInfo block = pair.left;
|
||||
MovementContext context = pair.right;
|
||||
|
||||
BlockPos newPos = block.pos.offset(direction, getModulatedOffset(newOffset));
|
||||
context.currentGridPos = newPos;
|
||||
|
||||
IHaveMovementBehavior actor = (IHaveMovementBehavior) block.state.getBlock();
|
||||
actor.visitPosition(context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void assembleConstruct() {
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
|
||||
// Collect Construct
|
||||
movedContraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
|
||||
if (movedContraption == null)
|
||||
PistonContraption contraption = PistonContraption.movePistonAt(world, pos, direction, getMovementSpeed() < 0);
|
||||
if (contraption == null)
|
||||
return;
|
||||
|
||||
// Check if not at limit already
|
||||
float resultingOffset = movedContraption.initialExtensionProgress + getMovementSpeed();
|
||||
if (resultingOffset <= 0 || resultingOffset >= movedContraption.extensionLength) {
|
||||
movedContraption = null;
|
||||
return;
|
||||
}
|
||||
if (hasBlockCollisions(resultingOffset + .5f)) {
|
||||
movedContraption = null;
|
||||
float resultingOffset = contraption.initialExtensionProgress + Math.signum(getMovementSpeed()) * .5f;
|
||||
extensionLength = contraption.extensionLength;
|
||||
if (resultingOffset <= 0 || resultingOffset >= extensionLength) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run
|
||||
running = true;
|
||||
offset = movedContraption.initialExtensionProgress;
|
||||
if (!world.isRemote)
|
||||
Create.constructHandler.add(this);
|
||||
|
||||
offset = contraption.initialExtensionProgress;
|
||||
sendData();
|
||||
|
||||
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.MOVING), 66);
|
||||
for (BlockInfo block : movedContraption.blocks.values()) {
|
||||
BlockPos startPos = block.pos.offset(direction, movedContraption.initialExtensionProgress);
|
||||
if (startPos.equals(pos))
|
||||
for (BlockInfo block : contraption.blocks.values()) {
|
||||
BlockPos startPos = block.pos.offset(direction, contraption.initialExtensionProgress);
|
||||
BlockPos add = startPos.add(contraption.getAnchor());
|
||||
if (add.equals(pos))
|
||||
continue;
|
||||
getWorld().setBlockState(startPos, Blocks.AIR.getDefaultState(), 67);
|
||||
getWorld().setBlockState(add, Blocks.AIR.getDefaultState(), 67);
|
||||
}
|
||||
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors()) {
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : contraption.getActors()) {
|
||||
MovementContext context = new MovementContext(pair.left.state, MoverType.PISTON);
|
||||
context.world = world;
|
||||
context.motion = new Vec3d(direction.getDirectionVec()).scale(getMovementSpeed()).normalize();
|
||||
@ -158,28 +116,19 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
pair.setRight(context);
|
||||
}
|
||||
|
||||
onBlockVisited(offset);
|
||||
movedContraption = new ContraptionEntity(getWorld(), contraption, 0).controlledBy(this);
|
||||
moveContraption();
|
||||
world.addEntity(movedContraption);
|
||||
}
|
||||
|
||||
public void disassembleConstruct() {
|
||||
if (!running)
|
||||
return;
|
||||
|
||||
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||
if (!removed)
|
||||
getWorld().setBlockState(pos, getBlockState().with(MechanicalPistonBlock.STATE, PistonState.EXTENDED), 3);
|
||||
movedContraption.disassemble(world, BlockPos.ZERO.offset(direction, getModulatedOffset(offset)),
|
||||
(targetPos, state) -> {
|
||||
if (targetPos.equals(pos)) {
|
||||
if (!AllBlocks.PISTON_POLE.typeOf(state) && !removed)
|
||||
world.setBlockState(pos, getBlockState().with(STATE, PistonState.RETRACTED), 3);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
movedContraption.disassemble();
|
||||
running = false;
|
||||
if (!world.isRemote)
|
||||
Create.constructHandler.remove(this);
|
||||
movedContraption = null;
|
||||
sendData();
|
||||
|
||||
@ -196,13 +145,8 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
if (running) {
|
||||
if (getSpeed() == 0)
|
||||
disassembleConstruct();
|
||||
else {
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors())
|
||||
pair.right.motion = new Vec3d(
|
||||
getBlockState().get(BlockStateProperties.FACING).getDirectionVec())
|
||||
.scale(getMovementSpeed());
|
||||
else
|
||||
sendData();
|
||||
}
|
||||
return;
|
||||
}
|
||||
assembleConstruct();
|
||||
@ -213,120 +157,114 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
return;
|
||||
|
||||
float movementSpeed = getMovementSpeed();
|
||||
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
|
||||
float newOffset = offset + movementSpeed;
|
||||
|
||||
MovingConstructHandler.moveEntities(this, movementSpeed, movementDirection, newOffset);
|
||||
|
||||
if (world.isRemote) {
|
||||
offset = newOffset;
|
||||
if (movedContraption == null)
|
||||
return;
|
||||
}
|
||||
|
||||
if (getModulatedOffset(newOffset) != getModulatedOffset(offset)) {
|
||||
onBlockVisited(newOffset);
|
||||
}
|
||||
|
||||
float movement = .5f + (movementSpeed < 0 ? -1f : 0);
|
||||
if (getModulatedOffset(newOffset + movement) != getModulatedOffset(offset + movement)) {
|
||||
if (hasBlockCollisions(newOffset + movement)) {
|
||||
disassembleConstruct();
|
||||
if (hadCollisionWithOtherPiston)
|
||||
hadCollisionWithOtherPiston = false;
|
||||
else if (movementSpeed > 0)
|
||||
assembleNextTick = true;
|
||||
return;
|
||||
}
|
||||
if (!world.isRemote && getModulatedOffset(newOffset) != getModulatedOffset(offset)) {
|
||||
offset = newOffset;
|
||||
sendData();
|
||||
}
|
||||
|
||||
offset = newOffset;
|
||||
moveContraption();
|
||||
|
||||
if (offset <= 0 || offset >= movedContraption.extensionLength) {
|
||||
disassembleConstruct();
|
||||
if (offset <= 0 || offset >= extensionLength) {
|
||||
offset = offset <= 0 ? 0 : extensionLength;
|
||||
if (!world.isRemote)
|
||||
disassembleConstruct();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasBlockCollisions(float newOffset) {
|
||||
if (PistonContraption.isFrozen())
|
||||
return true;
|
||||
|
||||
Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
|
||||
BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
|
||||
|
||||
// Other moving Pistons
|
||||
int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get()
|
||||
+ parameters.maxChassisForTranslation.get();
|
||||
Iterator<MechanicalPistonTileEntity> iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this)
|
||||
.iterator();
|
||||
pistonLoop: while (iterator.hasNext()) {
|
||||
MechanicalPistonTileEntity otherPiston = iterator.next();
|
||||
|
||||
if (otherPiston == this)
|
||||
continue;
|
||||
if (!otherPiston.running || otherPiston.movedContraption == null) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
|
||||
continue;
|
||||
|
||||
Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
|
||||
BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
||||
getModulatedOffset(otherPiston.offset));
|
||||
|
||||
for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox,
|
||||
movedContraption.pistonCollisionBox)) {
|
||||
for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox,
|
||||
otherPiston.movedContraption.pistonCollisionBox)) {
|
||||
if (tBB == null || oBB == null)
|
||||
continue;
|
||||
|
||||
boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite();
|
||||
BlockPos thisColliderOffset = relativePos.offset(movementDirection,
|
||||
frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0);
|
||||
AxisAlignedBB thisBB = tBB.offset(thisColliderOffset);
|
||||
AxisAlignedBB otherBB = oBB.offset(otherRelativePos);
|
||||
|
||||
if (thisBB.intersects(otherBB)) {
|
||||
boolean actuallyColliding = false;
|
||||
for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) {
|
||||
colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos);
|
||||
if (!otherPiston.movedContraption.blocks.containsKey(colliderPos))
|
||||
continue;
|
||||
actuallyColliding = true;
|
||||
}
|
||||
if (!actuallyColliding)
|
||||
continue pistonLoop;
|
||||
hadCollisionWithOtherPiston = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void moveContraption() {
|
||||
if (movedContraption != null) {
|
||||
Vec3d constructOffset = getConstructOffset(0.5f);
|
||||
Vec3d vec = constructOffset.add(new Vec3d(movedContraption.getContraption().getAnchor()));
|
||||
movedContraption.setPosition(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
if (!running)
|
||||
return false;
|
||||
|
||||
// Other Blocks in world
|
||||
for (BlockPos pos : movedContraption.getColliders(world,
|
||||
getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
|
||||
BlockPos colliderPos = pos.add(relativePos);
|
||||
|
||||
if (!world.isBlockPresent(colliderPos))
|
||||
return true;
|
||||
if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
|
||||
&& !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// private boolean hasBlockCollisions(float newOffset) {
|
||||
// if (PistonContraption.isFrozen())
|
||||
// return true;
|
||||
//
|
||||
// Direction movementDirection = getBlockState().get(BlockStateProperties.FACING);
|
||||
// BlockPos relativePos = BlockPos.ZERO.offset(movementDirection, getModulatedOffset(newOffset));
|
||||
//
|
||||
// // Other moving Pistons
|
||||
// int maxPossibleRange = parameters.maxPistonPoles.get() + parameters.maxChassisRange.get()
|
||||
// + parameters.maxChassisForTranslation.get();
|
||||
// Iterator<MechanicalPistonTileEntity> iterator = Create.constructHandler.getOtherMovingPistonsInWorld(this)
|
||||
// .iterator();
|
||||
// pistonLoop: while (iterator.hasNext()) {
|
||||
// MechanicalPistonTileEntity otherPiston = iterator.next();
|
||||
//
|
||||
// if (otherPiston == this)
|
||||
// continue;
|
||||
// if (!otherPiston.running || otherPiston.movedContraption == null) {
|
||||
// iterator.remove();
|
||||
// continue;
|
||||
// }
|
||||
// if (otherPiston.pos.manhattanDistance(pos) > maxPossibleRange * 2)
|
||||
// continue;
|
||||
//
|
||||
// Direction otherMovementDirection = otherPiston.getBlockState().get(BlockStateProperties.FACING);
|
||||
// BlockPos otherRelativePos = BlockPos.ZERO.offset(otherMovementDirection,
|
||||
// getModulatedOffset(otherPiston.offset));
|
||||
//
|
||||
// for (AxisAlignedBB tBB : Arrays.asList(movedContraption.constructCollisionBox,
|
||||
// movedContraption.pistonCollisionBox)) {
|
||||
// for (AxisAlignedBB oBB : Arrays.asList(otherPiston.movedContraption.constructCollisionBox,
|
||||
// otherPiston.movedContraption.pistonCollisionBox)) {
|
||||
// if (tBB == null || oBB == null)
|
||||
// continue;
|
||||
//
|
||||
// boolean frontalCollision = otherMovementDirection == movementDirection.getOpposite();
|
||||
// BlockPos thisColliderOffset = relativePos.offset(movementDirection,
|
||||
// frontalCollision ? (getMovementSpeed() > 0 ? 1 : -1) : 0);
|
||||
// AxisAlignedBB thisBB = tBB.offset(thisColliderOffset);
|
||||
// AxisAlignedBB otherBB = oBB.offset(otherRelativePos);
|
||||
//
|
||||
// if (thisBB.intersects(otherBB)) {
|
||||
// boolean actuallyColliding = false;
|
||||
// for (BlockPos colliderPos : movedContraption.getColliders(world, movementDirection)) {
|
||||
// colliderPos = colliderPos.add(thisColliderOffset).subtract(otherRelativePos);
|
||||
// if (!otherPiston.movedContraption.blocks.containsKey(colliderPos))
|
||||
// continue;
|
||||
// actuallyColliding = true;
|
||||
// }
|
||||
// if (!actuallyColliding)
|
||||
// continue pistonLoop;
|
||||
// hadCollisionWithOtherPiston = true;
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (!running)
|
||||
// return false;
|
||||
//
|
||||
// // Other Blocks in world
|
||||
// for (BlockPos pos : movedContraption.getColliders(world,
|
||||
// getMovementSpeed() > 0 ? movementDirection : movementDirection.getOpposite())) {
|
||||
// BlockPos colliderPos = pos.add(relativePos);
|
||||
//
|
||||
// if (!world.isBlockPresent(colliderPos))
|
||||
// return true;
|
||||
// if (!world.getBlockState(colliderPos).getMaterial().isReplaceable()
|
||||
// && !world.getBlockState(colliderPos).getCollisionShape(world, colliderPos).isEmpty())
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
// }
|
||||
|
||||
private int getModulatedOffset(float offset) {
|
||||
return MathHelper.clamp((int) (offset + .5f), 0, movedContraption.extensionLength);
|
||||
return MathHelper.clamp((int) (offset + .5f), 0, extensionLength);
|
||||
}
|
||||
|
||||
public float getMovementSpeed() {
|
||||
@ -338,8 +276,17 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||
|
||||
public Vec3d getConstructOffset(float partialTicks) {
|
||||
float interpolatedOffset = MathHelper.clamp(offset + (partialTicks - .5f) * getMovementSpeed(), 0,
|
||||
movedContraption.extensionLength);
|
||||
extensionLength);
|
||||
return new Vec3d(getBlockState().get(BlockStateProperties.FACING).getDirectionVec()).scale(interpolatedOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attach(ContraptionEntity contraption) {
|
||||
if (contraption.getContraption() instanceof PistonContraption) {
|
||||
this.movedContraption = contraption;
|
||||
if (!world.isRemote)
|
||||
sendData();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,10 @@ import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.ContraptionRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
|
||||
@ -17,14 +15,6 @@ public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRendere
|
||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||
int destroyStage, BufferBuilder buffer) {
|
||||
super.renderTileEntityFast(te, x, y, z, partialTicks, destroyStage, buffer);
|
||||
|
||||
MechanicalPistonTileEntity pistonTe = (MechanicalPistonTileEntity) te;
|
||||
if (!pistonTe.running)
|
||||
return;
|
||||
Vec3d offset = pistonTe.getConstructOffset(partialTicks).subtract(new Vec3d(pistonTe.getPos()));
|
||||
ContraptionRenderer.render(getWorld(), pistonTe.movedContraption, (superBuffer) -> {
|
||||
superBuffer.translate(x + offset.x, y + offset.y, z + offset.z);
|
||||
}, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,32 +1,15 @@
|
||||
package com.simibubi.create.modules.contraptions.receivers.constructs.piston;
|
||||
/*package com.simibubi.create.modules.contraptions.receivers.constructs.piston;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.Contraption;
|
||||
|
||||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.ReuseableStream;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
@ -45,112 +28,112 @@ public class MovingConstructHandler {
|
||||
Create.logger.debug("Removed Construct List for " + world.getDimension().getType().getRegistryName());
|
||||
}
|
||||
|
||||
public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
|
||||
float newOffset) {
|
||||
if (PistonContraption.isFrozen())
|
||||
return;
|
||||
|
||||
World world = te.getWorld();
|
||||
Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
|
||||
Contraption construct = te.movedContraption;
|
||||
|
||||
// if (world.isRemote) {
|
||||
// renderedBBs.clear();
|
||||
// if (construct.pistonCollisionBox != null)
|
||||
// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0)));
|
||||
// if (construct.constructCollisionBox != null)
|
||||
// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0)));
|
||||
// public static void moveEntities(MechanicalPistonTileEntity te, float movementSpeed, Direction movementDirection,
|
||||
// float newOffset) {
|
||||
// if (PistonContraption.isFrozen())
|
||||
// return;
|
||||
//
|
||||
// World world = te.getWorld();
|
||||
// Vec3d movementVec = new Vec3d(te.getBlockState().get(BlockStateProperties.FACING).getDirectionVec());
|
||||
// Contraption construct = te.movedContraption;
|
||||
//
|
||||
//// if (world.isRemote) {
|
||||
//// renderedBBs.clear();
|
||||
//// if (construct.pistonCollisionBox != null)
|
||||
//// renderedBBs.add(construct.pistonCollisionBox.offset(te.getConstructOffset(0)));
|
||||
//// if (construct.constructCollisionBox != null)
|
||||
//// renderedBBs.add(construct.constructCollisionBox.offset(te.getConstructOffset(0)));
|
||||
////
|
||||
//// }
|
||||
//
|
||||
// if (construct.getCollisionBoxFront() != null) {
|
||||
// AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
|
||||
//
|
||||
// for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
|
||||
// e -> e.getPushReaction() == PushReaction.NORMAL)) {
|
||||
//
|
||||
// AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset))
|
||||
// .grow(.5f);
|
||||
// BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ);
|
||||
// BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ);
|
||||
//
|
||||
// Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
|
||||
// .map(pos -> {
|
||||
// Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0));
|
||||
// return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
|
||||
// vec.y, vec.z);
|
||||
// });
|
||||
// ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
|
||||
//
|
||||
// AxisAlignedBB entityBB = entity.getBoundingBox();
|
||||
// Vec3d motion = entity.getMotion();
|
||||
// Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion);
|
||||
// Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world,
|
||||
// ISelectionContext.forEntity(entity), potentialHits);
|
||||
//
|
||||
// for (Object shape : potentialHits.createStream().toArray()) {
|
||||
// VoxelShape voxelShape = (VoxelShape) shape;
|
||||
// if (!entityBB.intersects(voxelShape.getBoundingBox()))
|
||||
// continue;
|
||||
//
|
||||
// Direction bestSide = Direction.DOWN;
|
||||
// double bestOffset = 100;
|
||||
// double finalOffset = 0;
|
||||
//
|
||||
// for (Direction face : Direction.values()) {
|
||||
// Axis axis = face.getAxis();
|
||||
// double d = axis == Axis.X ? entityBB.getXSize()
|
||||
// : axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize();
|
||||
// d = d + 1.5f;
|
||||
//
|
||||
// Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
|
||||
// AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
|
||||
// double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
|
||||
// double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
|
||||
// double abs = Math.abs(nudgeDistance - offset);
|
||||
// if (abs < Math.abs(bestOffset) && abs != 0) {
|
||||
// bestOffset = abs;
|
||||
// finalOffset = abs;
|
||||
// bestSide = face;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (bestOffset != 0) {
|
||||
// entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
|
||||
// switch (bestSide.getAxis()) {
|
||||
// case X:
|
||||
// entity.setMotion(0, motion.y, motion.z);
|
||||
// break;
|
||||
// case Y:
|
||||
// entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z);
|
||||
// entity.fall(entity.fallDistance, 1);
|
||||
// entity.fallDistance = 0;
|
||||
// entity.onGround = true;
|
||||
// break;
|
||||
// case Z:
|
||||
// entity.setMotion(motion.x, motion.y, 0);
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!allowedMovement.equals(movement)) {
|
||||
// if (allowedMovement.y != movement.y) {
|
||||
// entity.fall(entity.fallDistance, 1);
|
||||
// entity.fallDistance = 0;
|
||||
// entity.onGround = true;
|
||||
// }
|
||||
// if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
// return;
|
||||
// entity.setMotion(allowedMovement.subtract(movement.subtract(motion)));
|
||||
// entity.velocityChanged = true;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
if (construct.getCollisionBoxFront() != null) {
|
||||
AxisAlignedBB constructBB = construct.getCollisionBoxFront().offset(te.getConstructOffset(0)).grow(.5f);
|
||||
|
||||
for (Entity entity : world.getEntitiesWithinAABB((EntityType<?>) null, constructBB,
|
||||
e -> e.getPushReaction() == PushReaction.NORMAL)) {
|
||||
|
||||
AxisAlignedBB entityScanBB = entity.getBoundingBox().offset(movementVec.scale(-1 * newOffset))
|
||||
.grow(.5f);
|
||||
BlockPos min = new BlockPos(entityScanBB.minX, entityScanBB.minY, entityScanBB.minZ);
|
||||
BlockPos max = new BlockPos(entityScanBB.maxX, entityScanBB.maxY, entityScanBB.maxZ);
|
||||
|
||||
Stream<VoxelShape> hits = BlockPos.getAllInBox(min, max).filter(construct.blocks::containsKey)
|
||||
.map(pos -> {
|
||||
Vec3d vec = new Vec3d(pos).add(te.getConstructOffset(te.getMovementSpeed() > 0 ? 1 : 0));
|
||||
return construct.blocks.get(pos).state.getShape(world, new BlockPos(vec)).withOffset(vec.x,
|
||||
vec.y, vec.z);
|
||||
});
|
||||
ReuseableStream<VoxelShape> potentialHits = new ReuseableStream<>(hits);
|
||||
|
||||
AxisAlignedBB entityBB = entity.getBoundingBox();
|
||||
Vec3d motion = entity.getMotion();
|
||||
Vec3d movement = new Vec3d(movementDirection.getDirectionVec()).scale(-movementSpeed).add(motion);
|
||||
Vec3d allowedMovement = Entity.getAllowedMovement(movement, entityBB, world,
|
||||
ISelectionContext.forEntity(entity), potentialHits);
|
||||
|
||||
for (Object shape : potentialHits.createStream().toArray()) {
|
||||
VoxelShape voxelShape = (VoxelShape) shape;
|
||||
if (!entityBB.intersects(voxelShape.getBoundingBox()))
|
||||
continue;
|
||||
|
||||
Direction bestSide = Direction.DOWN;
|
||||
double bestOffset = 100;
|
||||
double finalOffset = 0;
|
||||
|
||||
for (Direction face : Direction.values()) {
|
||||
Axis axis = face.getAxis();
|
||||
double d = axis == Axis.X ? entityBB.getXSize()
|
||||
: axis == Axis.Y ? entityBB.getYSize() : entityBB.getZSize();
|
||||
d = d + 1.5f;
|
||||
|
||||
Vec3d nudge = new Vec3d(face.getDirectionVec()).scale(d);
|
||||
AxisAlignedBB nudgedBB = entityBB.offset(nudge.getX(), nudge.getY(), nudge.getZ());
|
||||
double nudgeDistance = face.getAxisDirection() == AxisDirection.POSITIVE ? -d : d;
|
||||
double offset = voxelShape.getAllowedOffset(face.getAxis(), nudgedBB, nudgeDistance);
|
||||
double abs = Math.abs(nudgeDistance - offset);
|
||||
if (abs < Math.abs(bestOffset) && abs != 0) {
|
||||
bestOffset = abs;
|
||||
finalOffset = abs;
|
||||
bestSide = face;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestOffset != 0) {
|
||||
entity.move(MoverType.SELF, new Vec3d(bestSide.getDirectionVec()).scale(finalOffset));
|
||||
switch (bestSide.getAxis()) {
|
||||
case X:
|
||||
entity.setMotion(0, motion.y, motion.z);
|
||||
break;
|
||||
case Y:
|
||||
entity.setMotion(motion.x, bestSide == Direction.UP ? movementSpeed + 1 / 8f : 0, motion.z);
|
||||
entity.fall(entity.fallDistance, 1);
|
||||
entity.fallDistance = 0;
|
||||
entity.onGround = true;
|
||||
break;
|
||||
case Z:
|
||||
entity.setMotion(motion.x, motion.y, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allowedMovement.equals(movement)) {
|
||||
if (allowedMovement.y != movement.y) {
|
||||
entity.fall(entity.fallDistance, 1);
|
||||
entity.fallDistance = 0;
|
||||
entity.onGround = true;
|
||||
}
|
||||
if (entity instanceof PlayerEntity && !world.isRemote)
|
||||
return;
|
||||
entity.setMotion(allowedMovement.subtract(movement.subtract(motion)));
|
||||
entity.velocityChanged = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
public void add(MechanicalPistonTileEntity mechanicalPistonTileEntity) {
|
||||
movingPistons.get(mechanicalPistonTileEntity.getWorld()).add(mechanicalPistonTileEntity);
|
||||
@ -181,4 +164,4 @@ public class MovingConstructHandler {
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}*/
|
||||
|
@ -18,9 +18,11 @@ import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.state.properties.PistonType;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||
|
||||
@ -39,8 +41,7 @@ public class PistonContraption extends Contraption {
|
||||
construct.orientation = direction;
|
||||
if (!construct.collectExtensions(world, pos, direction))
|
||||
return null;
|
||||
if (!construct.searchMovedStructure(world, pos.offset(direction, construct.initialExtensionProgress + 1),
|
||||
retract ? direction.getOpposite() : direction))
|
||||
if (!construct.searchMovedStructure(world, construct.anchor, retract ? direction.getOpposite() : direction))
|
||||
return null;
|
||||
return construct;
|
||||
}
|
||||
@ -93,13 +94,18 @@ public class PistonContraption extends Contraption {
|
||||
initialExtensionProgress = extensionsInFront;
|
||||
pistonCollisionBox = new AxisAlignedBB(end.offset(direction, -extensionsInFront));
|
||||
|
||||
anchor = pos.offset(direction, initialExtensionProgress + 1);
|
||||
|
||||
if (extensionLength == 0)
|
||||
return false;
|
||||
|
||||
for (BlockInfo pole : poles) {
|
||||
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront);
|
||||
BlockPos polePos = pole.pos.offset(direction, -extensionsInFront).subtract(anchor);
|
||||
blocks.put(polePos, new BlockInfo(polePos, pole.state, null));
|
||||
pistonCollisionBox = pistonCollisionBox.union(new AxisAlignedBB(polePos));
|
||||
}
|
||||
|
||||
constructCollisionBox = new AxisAlignedBB(pos.offset(direction, initialExtensionProgress));
|
||||
constructCollisionBox = new AxisAlignedBB(BlockPos.ZERO.offset(direction, -initialExtensionProgress));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -125,14 +131,35 @@ public class PistonContraption extends Contraption {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void add(BlockPos pos, BlockInfo block) {
|
||||
public void add(BlockPos pos, BlockInfo block) {
|
||||
// super.add(pos, block);
|
||||
super.add(pos.offset(orientation, -initialExtensionProgress), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disassemble(IWorld world, BlockPos offset, float yaw, float pitch) {
|
||||
super.disassemble(world, offset, yaw, pitch, (pos, state) -> {
|
||||
BlockPos pistonPos = anchor.offset(orientation, -initialExtensionProgress - 1);
|
||||
BlockState pistonState = world.getBlockState(pistonPos);
|
||||
TileEntity te = world.getTileEntity(pistonPos);
|
||||
if (pos.equals(pistonPos)) {
|
||||
if (te == null || te.isRemoved())
|
||||
return true;
|
||||
if (!AllBlocks.PISTON_POLE.typeOf(state) && pistonState.getBlock() instanceof MechanicalPistonBlock)
|
||||
world.setBlockState(pistonPos, pistonState.with(MechanicalPistonBlock.STATE, PistonState.RETRACTED),
|
||||
3);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readNBT(CompoundNBT nbt) {
|
||||
super.readNBT(nbt);
|
||||
extensionLength = nbt.getInt("ExtensionLength");
|
||||
initialExtensionProgress = nbt.getInt("InitialLength");
|
||||
orientation = Direction.byIndex(nbt.getInt("Orientation"));
|
||||
if (nbt.contains("BoundsBack"))
|
||||
pistonCollisionBox = readAABB(nbt.getList("BoundsBack", 5));
|
||||
}
|
||||
@ -145,7 +172,9 @@ public class PistonContraption extends Contraption {
|
||||
ListNBT bb = writeAABB(pistonCollisionBox);
|
||||
nbt.put("BoundsBack", bb);
|
||||
}
|
||||
nbt.putInt("InitialLength", initialExtensionProgress);
|
||||
nbt.putInt("ExtensionLength", extensionLength);
|
||||
nbt.putInt("Orientation", orientation.getIndex());
|
||||
|
||||
return nbt;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user