Mechanical Bearing
- The mechanical bearing now rotates attached structures
This commit is contained in:
parent
fb35aa7e10
commit
b7decf0d0f
7 changed files with 428 additions and 11 deletions
|
@ -3,10 +3,133 @@ package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
|
|
||||||
public class MechanicalBearingTileEntity extends KineticTileEntity {
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
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.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
|
||||||
|
public class MechanicalBearingTileEntity extends KineticTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
|
protected RotationConstruct movingConstruct;
|
||||||
|
protected float angle;
|
||||||
|
protected boolean running;
|
||||||
|
protected boolean assembleNextTick;
|
||||||
|
|
||||||
public MechanicalBearingTileEntity() {
|
public MechanicalBearingTileEntity() {
|
||||||
super(AllTileEntities.MECHANICAL_BEARING.type);
|
super(AllTileEntities.MECHANICAL_BEARING.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AxisAlignedBB getRenderBoundingBox() {
|
||||||
|
return INFINITE_EXTENT_AABB;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT write(CompoundNBT tag) {
|
||||||
|
tag.putBoolean("Running", running);
|
||||||
|
tag.putFloat("Angle", angle);
|
||||||
|
if (running)
|
||||||
|
tag.put("Construct", movingConstruct.writeNBT());
|
||||||
|
|
||||||
|
return super.write(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT tag) {
|
||||||
|
running = tag.getBoolean("Running");
|
||||||
|
angle = tag.getFloat("Angle");
|
||||||
|
if (running)
|
||||||
|
movingConstruct = RotationConstruct.fromNBT(tag.getCompound("Construct"));
|
||||||
|
|
||||||
|
super.read(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getInterpolatedAngle(float partialTicks) {
|
||||||
|
return MathHelper.lerp(partialTicks, angle, angle + getAngularSpeed());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSpeedChanged() {
|
||||||
|
super.onSpeedChanged();
|
||||||
|
assembleNextTick = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAngularSpeed() {
|
||||||
|
return speed / 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assembleConstruct() {
|
||||||
|
Direction direction = getBlockState().get(BlockStateProperties.FACING);
|
||||||
|
|
||||||
|
// Collect Construct
|
||||||
|
movingConstruct = RotationConstruct.getAttachedForRotating(getWorld(), getPos(), direction);
|
||||||
|
if (movingConstruct == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Run
|
||||||
|
running = true;
|
||||||
|
angle = 0;
|
||||||
|
sendData();
|
||||||
|
|
||||||
|
for (BlockInfo info : movingConstruct.blocks.values()) {
|
||||||
|
getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disassembleConstruct() {
|
||||||
|
if (!running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (BlockInfo block : movingConstruct.blocks.values()) {
|
||||||
|
BlockPos targetPos = block.pos.add(pos);
|
||||||
|
BlockState state = block.state;
|
||||||
|
|
||||||
|
for (Direction face : Direction.values())
|
||||||
|
state = state.updatePostPlacement(face, world.getBlockState(targetPos.offset(face)), world, targetPos,
|
||||||
|
targetPos.offset(face));
|
||||||
|
|
||||||
|
world.destroyBlock(targetPos, world.getBlockState(targetPos).getCollisionShape(world, targetPos).isEmpty());
|
||||||
|
getWorld().setBlockState(targetPos, state, 3);
|
||||||
|
TileEntity tileEntity = world.getTileEntity(targetPos);
|
||||||
|
if (tileEntity != null && block.nbt != null) {
|
||||||
|
((ChassisTileEntity) tileEntity).setRange(block.nbt.getInt("Range"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
movingConstruct = null;
|
||||||
|
angle = 0;
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
if (!world.isRemote && assembleNextTick) {
|
||||||
|
assembleNextTick = false;
|
||||||
|
if (running) {
|
||||||
|
if (speed == 0 && (Math.abs(angle) < Math.PI / 4f || Math.abs(angle) > 7 * Math.PI / 4f)) {
|
||||||
|
disassembleConstruct();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
assembleConstruct();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float angularSpeed = getAngularSpeed();
|
||||||
|
float newAngle = angle + angularSpeed;
|
||||||
|
angle = (float) (newAngle % (2 * Math.PI));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,40 @@
|
||||||
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.simibubi.create.AllBlocks;
|
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.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||||
|
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
import net.minecraftforge.client.model.animation.Animation;
|
import net.minecraftforge.client.model.animation.Animation;
|
||||||
|
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
|
|
||||||
public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRenderer {
|
public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRenderer {
|
||||||
|
|
||||||
|
protected static Cache<RotationConstruct, RotationConstructVertexBuffer> cachedConstructs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||||
int destroyStage, BufferBuilder buffer) {
|
int destroyStage, BufferBuilder buffer) {
|
||||||
|
MechanicalBearingTileEntity bearingTe = (MechanicalBearingTileEntity) te;
|
||||||
final Direction facing = te.getBlockState().get(BlockStateProperties.FACING);
|
final Direction facing = te.getBlockState().get(BlockStateProperties.FACING);
|
||||||
final BlockPos pos = te.getPos();
|
final BlockPos pos = te.getPos();
|
||||||
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
|
float time = Animation.getWorldTime(Minecraft.getInstance().world, partialTicks);
|
||||||
|
@ -33,9 +51,56 @@ public class MechanicalBearingTileEntityRenderer extends KineticTileEntityRender
|
||||||
|
|
||||||
angle += offset;
|
angle += offset;
|
||||||
angle = angle / 180f * (float) Math.PI;
|
angle = angle / 180f * (float) Math.PI;
|
||||||
|
float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks);
|
||||||
|
|
||||||
renderFromCache(buffer, shaftState, (float) x, (float) y, (float) z, pos, facing.getAxis(), angle);
|
renderFromCache(buffer, shaftState, (float) x, (float) y, (float) z, pos, facing.getAxis(), angle);
|
||||||
renderFromCache(buffer, capState, (float) x, (float) y, (float) z, pos, facing.getAxis(), angle);
|
renderFromCache(buffer, capState, (float) x, (float) y, (float) z, pos, facing.getAxis(), interpolatedAngle);
|
||||||
|
|
||||||
|
if (!bearingTe.running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cacheConstructIfMissing(bearingTe.movingConstruct);
|
||||||
|
renderConstructFromCache(bearingTe.movingConstruct, bearingTe, x, y, z, partialTicks, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void cacheConstructIfMissing(RotationConstruct c) {
|
||||||
|
if (cachedConstructs == null)
|
||||||
|
cachedConstructs = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.SECONDS).build();
|
||||||
|
if (cachedConstructs.getIfPresent(c) != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||||
|
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||||
|
Random random = new Random();
|
||||||
|
BufferBuilder builder = new BufferBuilder(0);
|
||||||
|
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||||
|
builder.setTranslation(0, 255, 0);
|
||||||
|
|
||||||
|
for (BlockPos localPos : c.blocks.keySet()) {
|
||||||
|
BlockInfo info = c.blocks.get(localPos);
|
||||||
|
IBakedModel originalModel = dispatcher.getModelForState(info.state);
|
||||||
|
blockRenderer.renderModel(getWorld(), originalModel, info.state, info.pos.down(255), builder, true, random,
|
||||||
|
42, EmptyModelData.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.finishDrawing();
|
||||||
|
cachedConstructs.put(c, new RotationConstructVertexBuffer(builder.getByteBuffer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderConstructFromCache(RotationConstruct c, MechanicalBearingTileEntity te, double x, double y,
|
||||||
|
double z, float partialTicks, BufferBuilder buffer) {
|
||||||
|
float zfightBonus = 1 / 128f;
|
||||||
|
Direction direction = te.getBlockState().get(BlockStateProperties.FACING);
|
||||||
|
Vec3i vec = direction.getDirectionVec();
|
||||||
|
buffer.putBulkData(cachedConstructs.getIfPresent(c).getTransformed(te, (float) (x) + vec.getX() * zfightBonus,
|
||||||
|
(float) (y) + vec.getY() * zfightBonus, (float) (z) + vec.getZ() * zfightBonus,
|
||||||
|
te.getInterpolatedAngle(partialTicks), direction.getAxis()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||||
|
return AllBlocks.SHAFT.block.getDefaultState().with(BlockStateProperties.AXIS,
|
||||||
|
((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,6 @@ public class MechanicalPistonTileEntity extends KineticTileEntity implements ITi
|
||||||
super(AllTileEntities.MECHANICAL_PISTON.type);
|
super(AllTileEntities.MECHANICAL_PISTON.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFastRenderer() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSpeedChanged() {
|
public void onSpeedChanged() {
|
||||||
super.onSpeedChanged();
|
super.onSpeedChanged();
|
||||||
|
|
|
@ -26,7 +26,7 @@ import net.minecraftforge.client.model.data.EmptyModelData;
|
||||||
|
|
||||||
public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer {
|
public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRenderer {
|
||||||
|
|
||||||
protected static Cache<TranslationConstruct, ConstructVertexBuffer> cachedConstructs;
|
protected static Cache<TranslationConstruct, TranslationConstructVertexBuffer> cachedConstructs;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
public void renderTileEntityFast(KineticTileEntity te, double x, double y, double z, float partialTicks,
|
||||||
|
@ -64,7 +64,7 @@ public class MechanicalPistonTileEntityRenderer extends KineticTileEntityRendere
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.finishDrawing();
|
builder.finishDrawing();
|
||||||
cachedConstructs.put(c, new ConstructVertexBuffer(builder.getByteBuffer()));
|
cachedConstructs.put(c, new TranslationConstructVertexBuffer(builder.getByteBuffer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderConstructFromCache(TranslationConstruct c, MechanicalPistonTileEntity te, double x, double y, double z,
|
protected void renderConstructFromCache(TranslationConstruct c, MechanicalPistonTileEntity te, double x, double y, double z,
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.PistonBlock;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.ListNBT;
|
||||||
|
import net.minecraft.nbt.NBTUtil;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.gen.feature.template.Template.BlockInfo;
|
||||||
|
|
||||||
|
public class RotationConstruct {
|
||||||
|
|
||||||
|
public static final int MAX_CHAINED_CHASSIS = 10;
|
||||||
|
|
||||||
|
protected Map<BlockPos, BlockInfo> blocks;
|
||||||
|
|
||||||
|
public RotationConstruct() {
|
||||||
|
blocks = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RotationConstruct getAttachedForRotating(World world, BlockPos pos, Direction direction) {
|
||||||
|
RotationConstruct construct = new RotationConstruct();
|
||||||
|
|
||||||
|
if (!construct.collectAttached(world, pos, direction))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return construct;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean collectAttached(World world, BlockPos pos, Direction direction) {
|
||||||
|
|
||||||
|
// Find chassis
|
||||||
|
List<BlockInfo> chassis = collectChassis(world, pos, direction);
|
||||||
|
if (chassis == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Get single block
|
||||||
|
if (chassis.isEmpty()) {
|
||||||
|
BlockPos blockPos = pos.offset(direction);
|
||||||
|
BlockState state = world.getBlockState(pos.offset(direction));
|
||||||
|
|
||||||
|
if (state.getMaterial().isReplaceable() || state.isAir(world, blockPos))
|
||||||
|
return true;
|
||||||
|
if (state.getCollisionShape(world, blockPos).isEmpty())
|
||||||
|
return true;
|
||||||
|
if (!canRotate(world, blockPos, direction))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
blocks.put(blockPos, new BlockInfo(blockPos.subtract(pos), state, null));
|
||||||
|
|
||||||
|
// Get attached blocks by chassis
|
||||||
|
} else {
|
||||||
|
List<BlockInfo> attachedBlocksByChassis = getAttachedBlocksByChassis(world, direction, chassis);
|
||||||
|
if (attachedBlocksByChassis == null)
|
||||||
|
return false;
|
||||||
|
attachedBlocksByChassis.forEach(info -> {
|
||||||
|
blocks.put(info.pos, new BlockInfo(info.pos.subtract(pos), info.state, info.nbt));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BlockInfo> getAttachedBlocksByChassis(World world, Direction direction, List<BlockInfo> chassis) {
|
||||||
|
List<BlockInfo> blocks = new ArrayList<>();
|
||||||
|
RotationChassisBlock def = (RotationChassisBlock) AllBlocks.ROTATION_CHASSIS.block;
|
||||||
|
|
||||||
|
for (BlockInfo chassisBlock : chassis) {
|
||||||
|
blocks.add(chassisBlock);
|
||||||
|
BlockState state = chassisBlock.state;
|
||||||
|
BlockPos currentPos = chassisBlock.pos;
|
||||||
|
TileEntity tileEntity = world.getTileEntity(currentPos);
|
||||||
|
|
||||||
|
if (!(tileEntity instanceof ChassisTileEntity))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int chassisRange = ((ChassisTileEntity) tileEntity).getRange();
|
||||||
|
Set<BlockPos> visited = new HashSet<>();
|
||||||
|
|
||||||
|
for (Direction facing : Direction.values()) {
|
||||||
|
if (facing.getAxis() == direction.getAxis())
|
||||||
|
continue;
|
||||||
|
if (!state.get(def.getGlueableSide(state, facing)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BlockPos startPos = currentPos.offset(facing);
|
||||||
|
List<BlockPos> frontier = new LinkedList<>();
|
||||||
|
frontier.add(startPos);
|
||||||
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
|
nbt.putInt("Range", chassisRange);
|
||||||
|
|
||||||
|
while (!frontier.isEmpty()) {
|
||||||
|
BlockPos searchPos = frontier.remove(0);
|
||||||
|
BlockState searchedState = world.getBlockState(searchPos);
|
||||||
|
|
||||||
|
if (visited.contains(searchPos))
|
||||||
|
continue;
|
||||||
|
if (!searchPos.withinDistance(currentPos, chassisRange + .5f))
|
||||||
|
continue;
|
||||||
|
if (searchedState.getMaterial().isReplaceable() || state.isAir(world, searchPos))
|
||||||
|
continue;
|
||||||
|
if (searchedState.getCollisionShape(world, searchPos).isEmpty())
|
||||||
|
continue;
|
||||||
|
if (!canRotate(world, searchPos, direction))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
visited.add(searchPos);
|
||||||
|
|
||||||
|
blocks.add(new BlockInfo(searchPos, searchedState,
|
||||||
|
AllBlocks.ROTATION_CHASSIS.typeOf(searchedState) ? nbt : null));
|
||||||
|
|
||||||
|
for (Direction offset : Direction.values()) {
|
||||||
|
if (offset.getAxis() == direction.getAxis())
|
||||||
|
continue;
|
||||||
|
if (searchPos.equals(currentPos) && offset != facing)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
frontier.add(searchPos.offset(offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<BlockInfo> collectChassis(World world, BlockPos pos, Direction direction) {
|
||||||
|
List<BlockInfo> chassis = new ArrayList<>();
|
||||||
|
for (int distance = 1; distance <= MAX_CHAINED_CHASSIS; distance++) {
|
||||||
|
BlockPos currentPos = pos.offset(direction, distance);
|
||||||
|
if (!world.isBlockPresent(currentPos))
|
||||||
|
return chassis;
|
||||||
|
|
||||||
|
BlockState state = world.getBlockState(currentPos);
|
||||||
|
if (!AllBlocks.ROTATION_CHASSIS.typeOf(state))
|
||||||
|
return chassis;
|
||||||
|
if (direction.getAxis() != state.get(BlockStateProperties.AXIS))
|
||||||
|
return chassis;
|
||||||
|
|
||||||
|
chassis.add(new BlockInfo(currentPos, state, null));
|
||||||
|
}
|
||||||
|
return chassis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundNBT writeNBT() {
|
||||||
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
|
ListNBT blocks = new ListNBT();
|
||||||
|
for (BlockInfo block : this.blocks.values()) {
|
||||||
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
c.put("Block", NBTUtil.writeBlockState(block.state));
|
||||||
|
c.put("Pos", NBTUtil.writeBlockPos(block.pos));
|
||||||
|
if (block.nbt != null)
|
||||||
|
c.put("Data", block.nbt);
|
||||||
|
blocks.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
nbt.put("Blocks", blocks);
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RotationConstruct fromNBT(CompoundNBT nbt) {
|
||||||
|
RotationConstruct construct = new RotationConstruct();
|
||||||
|
nbt.getList("Blocks", 10).forEach(c -> {
|
||||||
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
|
BlockInfo info = new BlockInfo(NBTUtil.readBlockPos(comp.getCompound("Pos")),
|
||||||
|
NBTUtil.readBlockState(comp.getCompound("Block")),
|
||||||
|
comp.contains("Data") ? comp.getCompound("Data") : null);
|
||||||
|
construct.blocks.put(info.pos, info);
|
||||||
|
});
|
||||||
|
|
||||||
|
return construct;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canRotate(World world, BlockPos pos, Direction direction) {
|
||||||
|
return PistonBlock.canPush(world.getBlockState(pos), world, pos, direction, true, direction)
|
||||||
|
|| AllBlocks.ROTATION_CHASSIS.typeOf(world.getBlockState(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.BufferManipulator;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
public class RotationConstructVertexBuffer extends BufferManipulator {
|
||||||
|
|
||||||
|
public RotationConstructVertexBuffer(ByteBuffer original) {
|
||||||
|
super(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuffer getTransformed(TileEntity te, float x, float y, float z, float angle, Axis axis) {
|
||||||
|
original.rewind();
|
||||||
|
mutable.rewind();
|
||||||
|
|
||||||
|
float cos = MathHelper.cos(angle);
|
||||||
|
float sin = MathHelper.sin(angle);
|
||||||
|
|
||||||
|
for (int vertex = 0; vertex < vertexCount(original); vertex++) {
|
||||||
|
float xL = getX(original, vertex) -.5f;
|
||||||
|
float yL = getY(original, vertex) -.5f;
|
||||||
|
float zL = getZ(original, vertex) -.5f;
|
||||||
|
|
||||||
|
float xL2 = rotateX(xL, yL, zL, sin, cos, axis) + .5f;
|
||||||
|
float yL2 = rotateY(xL, yL, zL, sin, cos, axis) + .5f;
|
||||||
|
float zL2 = rotateZ(xL, yL, zL, sin, cos, axis) + .5f;
|
||||||
|
|
||||||
|
putPos(mutable, vertex, xL2 + x, yL2 + y, zL2 + z);
|
||||||
|
BlockPos pos = new BlockPos(te.getPos().getX() + xL2, te.getPos().getY() + yL2, te.getPos().getZ() + zL2);
|
||||||
|
putLight(mutable, vertex, te.getWorld().getCombinedLight(pos, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return mutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,9 +8,9 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class ConstructVertexBuffer extends BufferManipulator {
|
public class TranslationConstructVertexBuffer extends BufferManipulator {
|
||||||
|
|
||||||
public ConstructVertexBuffer(ByteBuffer original) {
|
public TranslationConstructVertexBuffer(ByteBuffer original) {
|
||||||
super(original);
|
super(original);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue