mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 20:11:35 +01:00
Merge remote-tracking branch 'origin/mc1.15/dev' into mc1.15/dev
This commit is contained in:
commit
0448d3f6f3
91 changed files with 2568 additions and 500 deletions
|
@ -16,8 +16,11 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
|
|||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -259,4 +262,22 @@ public class AllBlockPartials {
|
|||
return dispatcher.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms);
|
||||
}
|
||||
|
||||
public InstancedModel<ModelData> renderOnHorizontalModel(InstancedTileRenderer<?> dispatcher, BlockState referenceState) {
|
||||
Direction facing = referenceState.get(HORIZONTAL_FACING);
|
||||
return renderOnDirectionalSouthModel(dispatcher, referenceState, facing);
|
||||
}
|
||||
|
||||
public InstancedModel<ModelData> renderOnDirectionalSouthModel(InstancedTileRenderer<?> dispatcher, BlockState referenceState, Direction facing) {
|
||||
Supplier<MatrixStack> ms = () -> {
|
||||
MatrixStack stack = new MatrixStack();
|
||||
MatrixStacker.of(stack)
|
||||
.centre()
|
||||
.rotateY(AngleHelper.horizontalAngle(facing))
|
||||
.rotateX(AngleHelper.verticalAngle(facing))
|
||||
.unCentre();
|
||||
return stack;
|
||||
};
|
||||
return dispatcher.getMaterial(RenderMaterials.MODELS).getModel(this, referenceState, facing, ms);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import com.simibubi.create.content.contraptions.components.fan.NozzleTileEntity;
|
|||
import com.simibubi.create.content.contraptions.components.flywheel.FlyWheelInstance;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineInstance;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.EngineRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.millstone.MillStoneCogInstance;
|
||||
|
@ -39,10 +40,12 @@ import com.simibubi.create.content.contraptions.components.millstone.MillstoneRe
|
|||
import com.simibubi.create.content.contraptions.components.millstone.MillstoneTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.mixer.MechanicalMixerTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.mixer.MixerInstance;
|
||||
import com.simibubi.create.content.contraptions.components.motor.CreativeMotorRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.motor.CreativeMotorTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.press.PressInstance;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawInstance;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
|
||||
|
@ -137,6 +140,7 @@ import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity;
|
|||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchTileEntity;
|
||||
import com.simibubi.create.content.schematics.block.SchematicTableTileEntity;
|
||||
import com.simibubi.create.content.schematics.block.SchematicannonInstance;
|
||||
import com.simibubi.create.content.schematics.block.SchematicannonRenderer;
|
||||
import com.simibubi.create.content.schematics.block.SchematicannonTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer;
|
||||
|
@ -149,6 +153,7 @@ public class AllTileEntities {
|
|||
.tileEntity("schematicannon", SchematicannonTileEntity::new)
|
||||
.validBlocks(AllBlocks.SCHEMATICANNON)
|
||||
.renderer(() -> SchematicannonRenderer::new)
|
||||
.onRegister(SchematicannonInstance::register)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<SchematicTableTileEntity> SCHEMATIC_TABLE = Create.registrate()
|
||||
|
@ -454,6 +459,7 @@ public class AllTileEntities {
|
|||
.tileEntity("furnace_engine", FurnaceEngineTileEntity::new)
|
||||
.validBlocks(AllBlocks.FURNACE_ENGINE)
|
||||
.renderer(() -> EngineRenderer::new)
|
||||
.onRegister(EngineInstance::register)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<MillstoneTileEntity> MILLSTONE = Create.registrate()
|
||||
|
@ -488,14 +494,14 @@ public class AllTileEntities {
|
|||
.tileEntity("mechanical_press", MechanicalPressTileEntity::new)
|
||||
.validBlocks(AllBlocks.MECHANICAL_PRESS)
|
||||
.renderer(() -> MechanicalPressRenderer::new)
|
||||
.onRegister(ShaftInstance::register)
|
||||
.onRegister(PressInstance::register)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<MechanicalMixerTileEntity> MECHANICAL_MIXER = Create.registrate()
|
||||
.tileEntity("mechanical_mixer", MechanicalMixerTileEntity::new)
|
||||
.validBlocks(AllBlocks.MECHANICAL_MIXER)
|
||||
.renderer(() -> MechanicalMixerRenderer::new)
|
||||
.onRegister(ShaftlessCogInstance::register)
|
||||
.onRegister(MixerInstance::register)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<DeployerTileEntity> DEPLOYER = Create.registrate()
|
||||
|
|
|
@ -58,7 +58,7 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
|
|||
}
|
||||
|
||||
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = ((time * te.getSpeed() * 3f / 10 + offset) % 360) / 180 * (float) Math.PI;
|
||||
return angle;
|
||||
|
|
|
@ -24,6 +24,7 @@ import net.minecraft.util.Direction;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntity> {
|
||||
|
||||
|
@ -36,7 +37,8 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
|
|||
int light, int overlay) {
|
||||
BlockState blockState = te.getBlockState();
|
||||
SuperByteBuffer superBuffer = AllBlockPartials.HARVESTER_BLADE.renderOn(blockState);
|
||||
transform(blockState.get(HarvesterBlock.HORIZONTAL_FACING), superBuffer, te.manuallyAnimatedSpeed);
|
||||
transform(te.getWorld(), blockState.get(HarvesterBlock.HORIZONTAL_FACING), superBuffer,
|
||||
te.manuallyAnimatedSpeed);
|
||||
superBuffer.light(light)
|
||||
.renderInto(ms, buffer.getBuffer(RenderType.getCutoutMipped()));
|
||||
}
|
||||
|
@ -70,17 +72,17 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
|
|||
if (context.contraption.stalled)
|
||||
speed = 0;
|
||||
|
||||
transform(facing, superBuffer, speed);
|
||||
transform(context.world, facing, superBuffer, speed);
|
||||
|
||||
superBuffer.light(msLocal.peek()
|
||||
.getModel(), ContraptionRenderDispatcher.getLightOnContraption(context))
|
||||
.renderInto(ms, buffers.getBuffer(RenderType.getCutoutMipped()));
|
||||
}
|
||||
|
||||
public static void transform(Direction facing, SuperByteBuffer superBuffer, float speed) {
|
||||
public static void transform(World world, Direction facing, SuperByteBuffer superBuffer, float speed) {
|
||||
float originOffset = 1 / 16f;
|
||||
Vec3d rotOffset = new Vec3d(0, -2 * originOffset, originOffset).add(VecHelper.getCenterOf(BlockPos.ZERO));
|
||||
float time = AnimationTickHolder.getRenderTime() / 20;
|
||||
float time = AnimationTickHolder.getRenderTime(world) / 20;
|
||||
float angle = (time * speed) % 360;
|
||||
|
||||
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing)))
|
||||
|
|
|
@ -89,7 +89,7 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
|||
ms.translate(0, isBlockItem ? 9 / 16f : 11 / 16f, 0);
|
||||
ms.scale(scale, scale, scale);
|
||||
transform = TransformType.GROUND;
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AnimationTickHolder.getRenderTime()));
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AnimationTickHolder.getRenderTime(te.getWorld())));
|
||||
|
||||
} else {
|
||||
float scale = punching ? .75f : isBlockItem ? .75f - 1 / 64f : .5f;
|
||||
|
|
|
@ -41,7 +41,7 @@ public class EncasedFanRenderer extends KineticTileEntityRenderer {
|
|||
SuperByteBuffer fanInner =
|
||||
AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouth(te.getBlockState(), direction.getOpposite());
|
||||
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
float speed = te.getSpeed() * 5;
|
||||
if (speed > 0)
|
||||
speed = MathHelper.clamp(speed, 80, 64 * 20);
|
||||
|
|
|
@ -1,34 +1,59 @@
|
|||
package com.simibubi.create.content.contraptions.components.flywheel;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.base.IRotate;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
|
||||
import com.simibubi.create.content.contraptions.base.RotatingData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> {
|
||||
public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> implements ITickableInstance {
|
||||
public static void register(TileEntityType<? extends FlywheelTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, FlyWheelInstance::new));
|
||||
}
|
||||
|
||||
protected Direction facing;
|
||||
protected boolean connectedLeft;
|
||||
protected float connectorAngleMult;
|
||||
|
||||
protected Direction connection;
|
||||
|
||||
protected InstanceKey<RotatingData> shaft;
|
||||
// protected InstanceKey<RotatingData> wheel;
|
||||
|
||||
protected InstanceKey<ModelData> wheel;
|
||||
protected InstanceKey<ModelData> upperRotating;
|
||||
protected InstanceKey<ModelData> lowerRotating;
|
||||
protected InstanceKey<ModelData> upperSliding;
|
||||
protected InstanceKey<ModelData> lowerSliding;
|
||||
|
||||
protected List<InstanceKey<ModelData>> connectors;
|
||||
|
||||
protected float lastAngle = Float.NaN;
|
||||
|
||||
protected boolean firstFrame = true;
|
||||
|
||||
public FlyWheelInstance(InstancedTileRenderer<?> modelManager, FlywheelTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
|
@ -40,35 +65,154 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> {
|
|||
|
||||
Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState);
|
||||
shaft = setup(shaftModel().createInstance(), tile.getSpeed(), axis);
|
||||
// wheel = wheelModel().setupInstance(setup);
|
||||
|
||||
wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, lastState.rotate(Rotation.CLOCKWISE_90)).createInstance();
|
||||
|
||||
connection = FlywheelBlock.getConnection(lastState);
|
||||
if (connection != null) {
|
||||
connectedLeft = lastState.get(FlywheelBlock.CONNECTION) == FlywheelBlock.ConnectionState.LEFT;
|
||||
|
||||
boolean flipAngle = connection.getAxis() == Direction.Axis.X ^ connection.getAxisDirection() == Direction.AxisDirection.NEGATIVE;
|
||||
|
||||
connectorAngleMult = flipAngle ? -1 : 1;
|
||||
|
||||
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
|
||||
|
||||
upperRotating = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_ROTATING, lastState).createInstance();
|
||||
lowerRotating = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_ROTATING, lastState).createInstance();
|
||||
upperSliding = mat.getModel(AllBlockPartials.FLYWHEEL_UPPER_SLIDING, lastState).createInstance();
|
||||
lowerSliding = mat.getModel(AllBlockPartials.FLYWHEEL_LOWER_SLIDING, lastState).createInstance();
|
||||
|
||||
connectors = Lists.newArrayList(upperRotating, lowerRotating, upperSliding, lowerSliding);
|
||||
} else {
|
||||
connectors = Collections.emptyList();
|
||||
}
|
||||
|
||||
updateLight();
|
||||
firstFrame = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
|
||||
float partialTicks = AnimationTickHolder.getPartialTicks();
|
||||
|
||||
float speed = tile.visualSpeed.get(partialTicks) * 3 / 10f;
|
||||
float angle = tile.angle + speed * partialTicks;
|
||||
|
||||
if (!firstFrame && Math.abs(angle - lastAngle) < 0.001) return;
|
||||
|
||||
MatrixStack ms = new MatrixStack();
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
|
||||
msr.translate(getFloatingPos());
|
||||
|
||||
if (connection != null) {
|
||||
float rotation = angle * connectorAngleMult;
|
||||
|
||||
ms.push();
|
||||
rotateToFacing(msr, connection);
|
||||
|
||||
ms.push();
|
||||
transformConnector(msr, true, true, rotation, connectedLeft);
|
||||
upperRotating.getInstance().setTransform(ms);
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
transformConnector(msr, false, true, rotation, connectedLeft);
|
||||
lowerRotating.getInstance().setTransform(ms);
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
transformConnector(msr, true, false, rotation, connectedLeft);
|
||||
upperSliding.getInstance().setTransform(ms);
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
transformConnector(msr, false, false, rotation, connectedLeft);
|
||||
lowerSliding.getInstance().setTransform(ms);
|
||||
ms.pop();
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
msr.centre()
|
||||
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle))
|
||||
.unCentre();
|
||||
|
||||
wheel.getInstance().setTransformNoCopy(ms);
|
||||
|
||||
lastAngle = angle;
|
||||
firstFrame = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onUpdate() {
|
||||
Direction.Axis axis = ((IRotate) lastState.getBlock()).getRotationAxis(lastState);
|
||||
updateRotation(shaft, axis);
|
||||
// updateRotation(wheel, axis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
relight(shaft);
|
||||
// wheel.modifyInstance(this::relight);
|
||||
int block = world.getLightLevel(LightType.BLOCK, pos);
|
||||
int sky = world.getLightLevel(LightType.SKY, pos);
|
||||
|
||||
shaft.getInstance().setBlockLight(block).setSkyLight(sky);
|
||||
wheel.getInstance().setBlockLight(block).setSkyLight(sky);
|
||||
|
||||
if (connection != null) {
|
||||
BlockPos pos = this.pos.offset(connection);
|
||||
|
||||
int connectionBlock = world.getLightLevel(LightType.BLOCK, pos);
|
||||
int connectionSky = world.getLightLevel(LightType.SKY, pos);
|
||||
connectors.stream()
|
||||
.map(InstanceKey::getInstance)
|
||||
.forEach(data -> data.setBlockLight(connectionBlock).setSkyLight(connectionSky));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
shaft.delete();
|
||||
// wheel.delete();
|
||||
// wheel = null;
|
||||
wheel.delete();
|
||||
|
||||
connectors.forEach(InstanceKey::delete);
|
||||
connectors.clear();
|
||||
}
|
||||
|
||||
protected InstancedModel<RotatingData> shaftModel() {
|
||||
return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, lastState, facing.getOpposite());
|
||||
}
|
||||
|
||||
protected InstancedModel<RotatingData> wheelModel() {
|
||||
BlockState rotate = lastState.rotate(Rotation.CLOCKWISE_90);
|
||||
return AllBlockPartials.FLYWHEEL.renderOnDirectionalSouthRotating(modelManager, rotate, rotate.get(BlockStateProperties.HORIZONTAL_FACING));
|
||||
protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) {
|
||||
float shift = upper ? 1 / 4f : -1 / 8f;
|
||||
float offset = upper ? 1 / 4f : 1 / 4f;
|
||||
float radians = (float) (angle / 180 * Math.PI);
|
||||
float shifting = MathHelper.sin(radians) * shift + offset;
|
||||
|
||||
float maxAngle = upper ? -5 : -15;
|
||||
float minAngle = upper ? -45 : 5;
|
||||
float barAngle = 0;
|
||||
|
||||
if (rotating)
|
||||
barAngle = MathHelper.lerp((MathHelper.sin((float) (radians + Math.PI / 2)) + 1) / 2, minAngle, maxAngle);
|
||||
|
||||
float pivotX = (upper ? 8f : 3f) / 16;
|
||||
float pivotY = (upper ? 8f : 2f) / 16;
|
||||
float pivotZ = (upper ? 23f : 21.5f) / 16f;
|
||||
|
||||
ms.translate(pivotX, pivotY, pivotZ + shifting);
|
||||
if (rotating)
|
||||
ms.rotate(Direction.EAST, AngleHelper.rad(barAngle));
|
||||
ms.translate(-pivotX, -pivotY, -pivotZ);
|
||||
|
||||
if (flip && !upper)
|
||||
ms.translate(9 / 16f, 0, 0);
|
||||
}
|
||||
|
||||
protected void rotateToFacing(MatrixStacker buffer, Direction facing) {
|
||||
buffer.centre()
|
||||
.rotate(Direction.UP, AngleHelper.rad(AngleHelper.horizontalAngle(facing)))
|
||||
.unCentre();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock.ConnectionState;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -33,10 +34,11 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
|
|||
int light, int overlay) {
|
||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||
|
||||
BlockState blockState = te.getBlockState();
|
||||
FlywheelTileEntity wte = (FlywheelTileEntity) te;
|
||||
|
||||
SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90));
|
||||
float speed = wte.visualSpeed.get(partialTicks) * 3 / 10f;
|
||||
float angle = wte.angle + speed * partialTicks;
|
||||
|
||||
|
@ -68,6 +70,7 @@ public class FlywheelRenderer extends KineticTileEntityRenderer {
|
|||
.renderInto(ms, vb);
|
||||
}
|
||||
|
||||
SuperByteBuffer wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontal(blockState.rotate(Rotation.CLOCKWISE_90));
|
||||
kineticRotationTransform(wheel, te, blockState.get(HORIZONTAL_FACING)
|
||||
.getAxis(), AngleHelper.rad(angle), light);
|
||||
wheel.renderInto(ms, vb);
|
||||
|
|
|
@ -100,9 +100,4 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity {
|
|||
updateGeneratedRotation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderAsTE() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
|
||||
public static void register(TileEntityType<? extends EngineTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, EngineInstance::new));
|
||||
}
|
||||
|
||||
protected InstanceKey<ModelData> frame;
|
||||
|
||||
public EngineInstance(InstancedTileRenderer<?> modelManager, EngineTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
Block block = lastState
|
||||
.getBlock();
|
||||
if (!(block instanceof EngineBlock))
|
||||
return;
|
||||
|
||||
EngineBlock engineBlock = (EngineBlock) block;
|
||||
AllBlockPartials frame = engineBlock.getFrameModel();
|
||||
|
||||
Direction facing = lastState.get(BlockStateProperties.HORIZONTAL_FACING);
|
||||
|
||||
this.frame = modelManager.getMaterial(RenderMaterials.MODELS).getModel(frame, lastState).createInstance();
|
||||
|
||||
float angle = AngleHelper.rad(AngleHelper.horizontalAngle(facing));
|
||||
|
||||
MatrixStack ms = new MatrixStack();
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
|
||||
msr.translate(getFloatingPos())
|
||||
.nudge(tile.hashCode())
|
||||
.centre()
|
||||
.rotate(Direction.UP, angle)
|
||||
.unCentre()
|
||||
.translate(0, 0, -1);
|
||||
|
||||
this.frame.getInstance()
|
||||
.setTransformNoCopy(ms);
|
||||
|
||||
updateLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
frame.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
int block = world.getLightLevel(LightType.BLOCK, pos);
|
||||
int sky = world.getLightLevel(LightType.SKY, pos);
|
||||
|
||||
frame.getInstance().setBlockLight(block).setSkyLight(sky);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
|||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
|
||||
|
@ -21,6 +22,9 @@ public class EngineRenderer<T extends EngineTileEntity> extends SafeTileEntityRe
|
|||
@Override
|
||||
protected void renderSafe(T te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light,
|
||||
int overlay) {
|
||||
|
||||
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||
|
||||
Block block = te.getBlockState()
|
||||
.getBlock();
|
||||
if (block instanceof EngineBlock) {
|
||||
|
|
|
@ -3,8 +3,10 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
|||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelBlock;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.FlywheelTileEntity;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
|
@ -16,8 +18,10 @@ import net.minecraft.util.math.AxisAlignedBB;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
|
||||
public class EngineTileEntity extends SmartTileEntity {
|
||||
public class EngineTileEntity extends SmartTileEntity implements IInstanceRendered {
|
||||
|
||||
public float appliedCapacity;
|
||||
public float appliedSpeed;
|
||||
|
@ -100,4 +104,16 @@ public class EngineTileEntity extends SmartTileEntity {
|
|||
poweredWheel.setRotation(appliedSpeed, appliedCapacity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkLightUpdate() {
|
||||
CreateClient.kineticRenderer.onLightUpdate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,22 +31,23 @@ public class MechanicalMixerRenderer extends KineticTileEntityRenderer {
|
|||
@Override
|
||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
|
||||
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||
|
||||
BlockState blockState = te.getBlockState();
|
||||
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) te;
|
||||
BlockPos pos = te.getPos();
|
||||
|
||||
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
||||
|
||||
if (!FastRenderDispatcher.available(te.getWorld())) {
|
||||
SuperByteBuffer superBuffer = AllBlockPartials.SHAFTLESS_COGWHEEL.renderOn(blockState);
|
||||
standardKineticRotationTransform(superBuffer, te, light).renderInto(ms, vb);
|
||||
}
|
||||
SuperByteBuffer superBuffer = AllBlockPartials.SHAFTLESS_COGWHEEL.renderOn(blockState);
|
||||
standardKineticRotationTransform(superBuffer, te, light).renderInto(ms, vb);
|
||||
|
||||
int packedLightmapCoords = WorldRenderer.getLightmapCoordinates(te.getWorld(), blockState, pos);
|
||||
float renderedHeadOffset = mixer.getRenderedHeadOffset(partialTicks);
|
||||
float speed = mixer.getRenderedHeadRotationSpeed(partialTicks);
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float angle = (float) (((time * speed * 6 / 10f) % 360) / 180 * (float) Math.PI);
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
float angle = ((time * speed * 6 / 10f) % 360) / 180 * (float) Math.PI;
|
||||
|
||||
SuperByteBuffer poleRender = AllBlockPartials.MECHANICAL_MIXER_POLE.renderOn(blockState);
|
||||
poleRender.translate(0, -renderedHeadOffset, 0)
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package com.simibubi.create.content.contraptions.components.mixer;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.RotatingData;
|
||||
import com.simibubi.create.content.contraptions.base.ShaftlessCogInstance;
|
||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.client.renderer.Vector3d;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class MixerInstance extends ShaftlessCogInstance implements ITickableInstance {
|
||||
public static void register(TileEntityType<? extends KineticTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, MixerInstance::new));
|
||||
}
|
||||
|
||||
private InstanceKey<RotatingData> mixerHead;
|
||||
private InstanceKey<ModelData> mixerPole;
|
||||
|
||||
public MixerInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
|
||||
super(dispatcher, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
mixerHead = rotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, lastState)
|
||||
.createInstance();
|
||||
|
||||
mixerHead.getInstance()
|
||||
.setRotationAxis(Direction.Axis.Y);
|
||||
|
||||
mixerPole = modelManager.getMaterial(RenderMaterials.MODELS)
|
||||
.getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, lastState)
|
||||
.createInstance();
|
||||
|
||||
|
||||
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tile;
|
||||
float renderedHeadOffset = getRenderedHeadOffset(mixer);
|
||||
|
||||
transformPole(renderedHeadOffset);
|
||||
transformHead(mixer, renderedHeadOffset);
|
||||
updateLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
MechanicalMixerTileEntity mixer = (MechanicalMixerTileEntity) tile;
|
||||
|
||||
float renderedHeadOffset = getRenderedHeadOffset(mixer);
|
||||
|
||||
if (mixer.running) {
|
||||
transformPole(renderedHeadOffset);
|
||||
}
|
||||
|
||||
transformHead(mixer, renderedHeadOffset);
|
||||
}
|
||||
|
||||
private void transformHead(MechanicalMixerTileEntity mixer, float renderedHeadOffset) {
|
||||
float speed = mixer.getRenderedHeadRotationSpeed(AnimationTickHolder.getPartialTicks());
|
||||
|
||||
mixerHead.getInstance()
|
||||
.setPosition(pos)
|
||||
.nudge(0, -renderedHeadOffset, 0)
|
||||
.setRotationalSpeed(speed * 2);
|
||||
}
|
||||
|
||||
private void transformPole(float renderedHeadOffset) {
|
||||
MatrixStack ms = new MatrixStack();
|
||||
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
msr.translate(getFloatingPos());
|
||||
msr.translate(0, -renderedHeadOffset, 0);
|
||||
|
||||
mixerPole.getInstance().setTransformNoCopy(ms);
|
||||
}
|
||||
|
||||
private float getRenderedHeadOffset(MechanicalMixerTileEntity mixer) {
|
||||
return mixer.getRenderedHeadOffset(AnimationTickHolder.getPartialTicks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
super.updateLight();
|
||||
|
||||
BlockPos down = pos.down();
|
||||
mixerHead.getInstance()
|
||||
.setBlockLight(world.getLightLevel(LightType.BLOCK, down))
|
||||
.setSkyLight(world.getLightLevel(LightType.SKY, down));
|
||||
|
||||
mixerPole.getInstance()
|
||||
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
|
||||
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
mixerHead.delete();
|
||||
mixerPole.delete();
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
@ -29,13 +30,17 @@ public class MechanicalPressRenderer extends KineticTileEntityRenderer {
|
|||
int light, int overlay) {
|
||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||
|
||||
BlockPos pos = te.getPos();
|
||||
BlockState blockState = te.getBlockState();
|
||||
int packedLightmapCoords = WorldRenderer.getLightmapCoordinates(te.getWorld(), blockState, pos);
|
||||
float renderedHeadOffset = ((MechanicalPressTileEntity) te).getRenderedHeadOffset(partialTicks);
|
||||
|
||||
SuperByteBuffer headRender = AllBlockPartials.MECHANICAL_PRESS_HEAD.renderOnHorizontal(blockState);
|
||||
headRender.translate(0, -renderedHeadOffset, 0).light(packedLightmapCoords).renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
headRender.translate(0, -renderedHeadOffset, 0)
|
||||
.light(packedLightmapCoords)
|
||||
.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package com.simibubi.create.content.contraptions.components.press;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class PressInstance extends ShaftInstance implements ITickableInstance {
|
||||
public static void register(TileEntityType<? extends KineticTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, PressInstance::new));
|
||||
}
|
||||
|
||||
private InstanceKey<ModelData> pressHead;
|
||||
|
||||
public PressInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
|
||||
super(dispatcher, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
pressHead = modelManager.getMaterial(RenderMaterials.MODELS)
|
||||
.getModel(AllBlockPartials.MECHANICAL_PRESS_HEAD, lastState)
|
||||
.createInstance();
|
||||
|
||||
updateLight();
|
||||
transformModels((MechanicalPressTileEntity) tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
MechanicalPressTileEntity press = (MechanicalPressTileEntity) tile;
|
||||
if (!press.running)
|
||||
return;
|
||||
|
||||
transformModels(press);
|
||||
}
|
||||
|
||||
private void transformModels(MechanicalPressTileEntity press) {
|
||||
float renderedHeadOffset = getRenderedHeadOffset(press);
|
||||
|
||||
MatrixStack ms = new MatrixStack();
|
||||
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
msr.translate(getFloatingPos());
|
||||
msr.translate(0, -renderedHeadOffset, 0);
|
||||
|
||||
pressHead.getInstance()
|
||||
.setTransformNoCopy(ms);
|
||||
}
|
||||
|
||||
private float getRenderedHeadOffset(MechanicalPressTileEntity press) {
|
||||
return press.getRenderedHeadOffset(AnimationTickHolder.getPartialTicks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
super.updateLight();
|
||||
|
||||
pressHead.getInstance()
|
||||
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
|
||||
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
pressHead.delete();
|
||||
}
|
||||
}
|
|
@ -20,6 +20,9 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IFlywheelWorld;
|
||||
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||
import com.simibubi.create.foundation.utility.*;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
|
@ -53,12 +56,6 @@ import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock
|
|||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
import com.simibubi.create.foundation.render.backend.light.EmptyLighter;
|
||||
import com.simibubi.create.foundation.utility.BlockFace;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||
import com.simibubi.create.foundation.utility.UniqueLinkedList;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||
|
||||
import net.minecraft.block.AbstractButtonBlock;
|
||||
|
@ -85,7 +82,6 @@ import net.minecraft.state.properties.PistonType;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -853,16 +849,7 @@ public abstract class Contraption {
|
|||
TileEntity te = TileEntity.create(tag);
|
||||
if (te == null)
|
||||
return;
|
||||
te.setLocation(new WrappedWorld(world) {
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
if (!pos.equals(te.getPos()))
|
||||
return Blocks.AIR.getDefaultState();
|
||||
return info.state;
|
||||
}
|
||||
|
||||
}, te.getPos());
|
||||
te.setLocation(new ContraptionTileWorld(world, te, info), te.getPos());
|
||||
if (te instanceof KineticTileEntity)
|
||||
((KineticTileEntity) te).setSpeed(0);
|
||||
te.getBlockState();
|
||||
|
@ -1091,27 +1078,25 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
public void expandBoundsAroundAxis(Axis axis) {
|
||||
AxisAlignedBB bb = bounds;
|
||||
double maxXDiff = Math.max(bb.maxX - 1, -bb.minX);
|
||||
double maxYDiff = Math.max(bb.maxY - 1, -bb.minY);
|
||||
double maxZDiff = Math.max(bb.maxZ - 1, -bb.minZ);
|
||||
double maxDiff = 0;
|
||||
Set<BlockPos> blocks = getBlocks().keySet();
|
||||
|
||||
if (axis == Axis.X)
|
||||
maxDiff = Math.max(maxZDiff, maxYDiff);
|
||||
if (axis == Axis.Y)
|
||||
maxDiff = Math.max(maxZDiff, maxXDiff);
|
||||
if (axis == Axis.Z)
|
||||
maxDiff = Math.max(maxXDiff, maxYDiff);
|
||||
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
|
||||
|
||||
Vec3d vec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis)
|
||||
.getDirectionVec());
|
||||
Vec3d planeByNormal = VecHelper.axisAlingedPlaneOf(vec);
|
||||
Vec3d min = vec.mul(bb.minX, bb.minY, bb.minZ)
|
||||
.add(planeByNormal.scale(-maxDiff));
|
||||
Vec3d max = vec.mul(bb.maxX, bb.maxY, bb.maxZ)
|
||||
.add(planeByNormal.scale(maxDiff + 1));
|
||||
bounds = new AxisAlignedBB(min, max);
|
||||
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
|
||||
|
||||
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(bounds);
|
||||
if (axis == Direction.Axis.X) {
|
||||
betterBounds.maxX = contraptionBounds.maxX;
|
||||
betterBounds.minX = contraptionBounds.minX;
|
||||
} else if (axis == Direction.Axis.Y) {
|
||||
betterBounds.maxY = contraptionBounds.maxY;
|
||||
betterBounds.minY = contraptionBounds.minY;
|
||||
} else if (axis == Direction.Axis.Z) {
|
||||
betterBounds.maxZ = contraptionBounds.maxZ;
|
||||
betterBounds.minZ = contraptionBounds.minZ;
|
||||
}
|
||||
|
||||
bounds = betterBounds.toAABB();
|
||||
}
|
||||
|
||||
public void addExtraInventories(Entity entity) {}
|
||||
|
@ -1163,4 +1148,51 @@ public abstract class Contraption {
|
|||
return new EmptyLighter(this);
|
||||
}
|
||||
|
||||
public static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
|
||||
switch (axis) {
|
||||
case X:
|
||||
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
|
||||
case Y:
|
||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
|
||||
case Z:
|
||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Impossible axis");
|
||||
}
|
||||
|
||||
public static float getMaxDistSqr(Set<BlockPos> blocks, Coordinate one, Coordinate other) {
|
||||
float maxDistSq = -1;
|
||||
for (BlockPos pos : blocks) {
|
||||
float a = one.get(pos);
|
||||
float b = other.get(pos);
|
||||
|
||||
float distSq = a * a + b * b;
|
||||
|
||||
|
||||
if (distSq > maxDistSq) maxDistSq = distSq;
|
||||
}
|
||||
|
||||
return maxDistSq;
|
||||
}
|
||||
|
||||
private static class ContraptionTileWorld extends WrappedWorld implements IFlywheelWorld {
|
||||
|
||||
private final TileEntity te;
|
||||
private final BlockInfo info;
|
||||
|
||||
public ContraptionTileWorld(World world, TileEntity te, BlockInfo info) {
|
||||
super(world);
|
||||
this.te = te;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
if (!pos.equals(te.getPos()))
|
||||
return Blocks.AIR.getDefaultState();
|
||||
return info.state;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||
|
||||
public class AnchoredLighter extends ContraptionLighter<Contraption> {
|
||||
|
||||
public AnchoredLighter(Contraption contraption) {
|
||||
super(contraption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GridAlignedBB getContraptionBounds() {
|
||||
GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds);
|
||||
bb.translate(contraption.anchor);
|
||||
return bb;
|
||||
}
|
||||
}
|
|
@ -97,6 +97,6 @@ public class BearingContraption extends Contraption {
|
|||
@OnlyIn(Dist.CLIENT)
|
||||
@Override
|
||||
public ContraptionLighter<?> makeLighter() {
|
||||
return new BearingLighter(this);
|
||||
return new AnchoredLighter(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class BearingLighter extends ContraptionLighter<BearingContraption> {
|
||||
|
||||
public BearingLighter(BearingContraption contraption) {
|
||||
super(contraption);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GridAlignedBB getContraptionBounds() {
|
||||
Set<BlockPos> blocks = contraption.getBlocks().keySet();
|
||||
|
||||
Direction orientation = contraption.facing;
|
||||
Direction.Axis axis = orientation.getAxis();
|
||||
|
||||
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
|
||||
|
||||
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
|
||||
|
||||
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(contraption.bounds);
|
||||
if (axis == Direction.Axis.X) {
|
||||
betterBounds.maxX = contraptionBounds.maxX;
|
||||
betterBounds.minX = contraptionBounds.minX;
|
||||
} else if (axis == Direction.Axis.Y) {
|
||||
betterBounds.maxY = contraptionBounds.maxY;
|
||||
betterBounds.minY = contraptionBounds.minY;
|
||||
} else if (axis == Direction.Axis.Z) {
|
||||
betterBounds.maxZ = contraptionBounds.maxZ;
|
||||
betterBounds.minZ = contraptionBounds.minZ;
|
||||
}
|
||||
|
||||
betterBounds.translate(contraption.anchor);
|
||||
return betterBounds;
|
||||
}
|
||||
|
||||
private static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
|
||||
switch (axis) {
|
||||
case X:
|
||||
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
|
||||
case Y:
|
||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
|
||||
case Z:
|
||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Impossible axis");
|
||||
}
|
||||
|
||||
private static float getMaxDistSqr(Set<BlockPos> blocks, Coordinate one, Coordinate other) {
|
||||
float maxDistSq = -1;
|
||||
for (BlockPos pos : blocks) {
|
||||
float a = one.get(pos);
|
||||
float b = other.get(pos);
|
||||
|
||||
float distSq = a * a + b * b;
|
||||
|
||||
|
||||
if (distSq > maxDistSq) maxDistSq = distSq;
|
||||
}
|
||||
|
||||
return maxDistSq;
|
||||
}
|
||||
|
||||
private interface Coordinate {
|
||||
float get(BlockPos from);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,8 @@ import net.minecraft.util.Direction.Axis;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class ClockworkBearingTileEntity extends KineticTileEntity implements IBearingTileEntity, IDisplayAssemblyExceptions {
|
||||
public class ClockworkBearingTileEntity extends KineticTileEntity
|
||||
implements IBearingTileEntity, IDisplayAssemblyExceptions {
|
||||
|
||||
protected ControlledContraptionEntity hourHand;
|
||||
protected ControlledContraptionEntity minuteHand;
|
||||
|
@ -40,9 +41,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
protected boolean running;
|
||||
protected boolean assembleNextTick;
|
||||
protected AssemblyException lastException;
|
||||
|
||||
protected ScrollOptionBehaviour<ClockHands> operationMode;
|
||||
|
||||
private float prevForcedAngle;
|
||||
|
||||
public ClockworkBearingTileEntity(TileEntityType<? extends ClockworkBearingTileEntity> type) {
|
||||
super(type);
|
||||
setLazyTickRate(3);
|
||||
|
@ -67,6 +69,7 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
super.tick();
|
||||
|
||||
if (world.isRemote) {
|
||||
prevForcedAngle = hourAngle;
|
||||
clientMinuteAngleDiff /= 2;
|
||||
clientHourAngleDiff /= 2;
|
||||
}
|
||||
|
@ -341,6 +344,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
|
||||
@Override
|
||||
public float getInterpolatedAngle(float partialTicks) {
|
||||
if (isVirtual())
|
||||
return MathHelper.lerp(partialTicks, prevForcedAngle, hourAngle);
|
||||
if (hourHand == null || hourHand.isStalled())
|
||||
partialTicks = 0;
|
||||
return MathHelper.lerp(partialTicks, hourAngle, hourAngle + getHourArmSpeed());
|
||||
|
@ -414,4 +419,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
|
|||
public boolean shouldRenderAsTE() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setAngle(float forcedAngle) {
|
||||
hourAngle = forcedAngle;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.HashSet;
|
|||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
|
@ -129,4 +130,8 @@ public class ClockworkContraption extends Contraption {
|
|||
HOUR, MINUTE
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContraptionLighter<?> makeLighter() {
|
||||
return new AnchoredLighter(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,7 @@ public interface IBearingTileEntity extends IControlContraption {
|
|||
return bearingAxis != axis;
|
||||
});
|
||||
}
|
||||
|
||||
void setAngle(float forcedAngle);
|
||||
|
||||
}
|
||||
|
|
|
@ -4,12 +4,11 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.world.LightType;
|
||||
|
@ -24,7 +23,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
|
|||
|
||||
float lastOffset = Float.NaN;
|
||||
|
||||
private InstanceKey<TransformData> head;
|
||||
private InstanceKey<ModelData> head;
|
||||
|
||||
public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
|
@ -61,7 +60,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
|
|||
.translate(0, (offset * offset) * 4 / 16f, 0);
|
||||
|
||||
head.getInstance()
|
||||
.setTransform(stack);
|
||||
.setTransformNoCopy(stack);
|
||||
|
||||
lastOffset = offset;
|
||||
}
|
||||
|
@ -69,8 +68,8 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
|
|||
@Override
|
||||
public void updateLight() {
|
||||
head.getInstance()
|
||||
.setBlockLight((byte) (world.getLightLevel(LightType.BLOCK, pos) << 4))
|
||||
.setSkyLight((byte) (world.getLightLevel(LightType.SKY, pos) << 4));
|
||||
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
|
||||
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.simibubi.create.foundation.render.backend.instancing.ITickableInstanc
|
|||
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
|
@ -28,7 +28,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
|||
InstancedTileRenderRegistry.instance.register(type, GantryCarriageInstance::new));
|
||||
}
|
||||
|
||||
private InstanceKey<TransformData> gantryCogs;
|
||||
private InstanceKey<ModelData> gantryCogs;
|
||||
|
||||
public GantryCarriageInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
|
||||
super(dispatcher, tile);
|
||||
|
@ -47,7 +47,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
lastState = world.getBlockState(pos);
|
||||
lastState = tile.getBlockState();
|
||||
Direction facing = lastState.get(GantryCarriageBlock.FACING);
|
||||
Boolean alongFirst = lastState.get(GantryCarriageBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
Direction.Axis rotationAxis = KineticTileEntityRenderer.getRotationAxisOf(tile);
|
||||
|
@ -80,14 +80,14 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
|
|||
.translate(0, 9 / 16f, 0)
|
||||
.unCentre();
|
||||
|
||||
gantryCogs.getInstance().setTransform(ms);
|
||||
gantryCogs.getInstance().setTransformNoCopy(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
gantryCogs.getInstance()
|
||||
.setBlockLight((byte) (world.getLightLevel(LightType.BLOCK, pos) << 4))
|
||||
.setSkyLight((byte) (world.getLightLevel(LightType.SKY, pos) << 4));
|
||||
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
|
||||
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,7 +72,7 @@ public class GantryCarriageRenderer extends KineticTileEntityRenderer {
|
|||
}
|
||||
|
||||
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
return ((time * te.getSpeed() * 3f / 20 + offset) % 360) / 180 * (float) Math.PI;
|
||||
}
|
||||
|
|
|
@ -41,9 +41,7 @@ public class PulleyRenderer extends AbstractPulleyRenderer {
|
|||
@Override
|
||||
protected float getOffset(KineticTileEntity te, float partialTicks) {
|
||||
PulleyTileEntity pulley = (PulleyTileEntity) te;
|
||||
boolean running = pulley.running;
|
||||
boolean moving = running && (pulley.movedContraption == null || !pulley.movedContraption.isStalled());
|
||||
float offset = pulley.getInterpolatedOffset(moving ? partialTicks : 0.5f);
|
||||
float offset = pulley.getInterpolatedOffset(partialTicks);
|
||||
|
||||
if (pulley.movedContraption != null) {
|
||||
AbstractContraptionEntity e = pulley.movedContraption;
|
||||
|
@ -57,7 +55,7 @@ public class PulleyRenderer extends AbstractPulleyRenderer {
|
|||
|
||||
@Override
|
||||
protected boolean isRunning(KineticTileEntity te) {
|
||||
return ((PulleyTileEntity) te).running;
|
||||
return ((PulleyTileEntity) te).running || te.isVirtual();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class PulleyTileEntity extends LinearActuatorTileEntity {
|
||||
|
||||
protected int initialOffset;
|
||||
private float prevAnimatedOffset;
|
||||
|
||||
public PulleyTileEntity(TileEntityType<? extends PulleyTileEntity> type) {
|
||||
super(type);
|
||||
|
@ -41,6 +42,13 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
public double getMaxRenderDistanceSquared() {
|
||||
return super.getMaxRenderDistanceSquared() + offset * offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (isVirtual())
|
||||
prevAnimatedOffset = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assemble() throws AssemblyException {
|
||||
|
@ -219,4 +227,16 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
|
|||
return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInterpolatedOffset(float partialTicks) {
|
||||
if (isVirtual())
|
||||
return MathHelper.lerp(partialTicks, prevAnimatedOffset, offset);
|
||||
boolean moving = running && (movedContraption == null || !movedContraption.isStalled());
|
||||
return super.getInterpolatedOffset(moving ? partialTicks : 0.5f);
|
||||
}
|
||||
|
||||
public void animateOffset(float forcedOffset) {
|
||||
offset = forcedOffset;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
|||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedInstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
|
||||
|
||||
@Override
|
||||
public void registerMaterials() {
|
||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedInstancedModel::new));
|
||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::new));
|
||||
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingInstancedModel::new));
|
||||
|
|
|
@ -67,7 +67,7 @@ public class RotationIndicatorParticle extends SimpleAnimatedParticle {
|
|||
}
|
||||
|
||||
public void move(double x, double y, double z) {
|
||||
float time = AnimationTickHolder.getTicks();
|
||||
float time = AnimationTickHolder.getTicks(world);
|
||||
float angle = (float) ((time * speed) % 360) - (speed / 2 * age * (((float) age) / maxAge));
|
||||
if (speed < 0 && axis.isVertical())
|
||||
angle += 180;
|
||||
|
|
|
@ -72,8 +72,9 @@ public class BasinRenderer extends SmartTileEntityRenderer<BasinTileEntity> {
|
|||
|
||||
if (fluidLevel > 0) {
|
||||
ms.translate(0,
|
||||
(MathHelper.sin(AnimationTickHolder.getRenderTime() / 12f + anglePartition * itemCount) + 1.5f) * 1
|
||||
/ 32f,
|
||||
(MathHelper.sin(
|
||||
AnimationTickHolder.getRenderTime(basin.getWorld()) / 12f + anglePartition * itemCount) + 1.5f)
|
||||
* 1 / 32f,
|
||||
0);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class BlazeBurnerRenderer extends SafeTileEntityRenderer<BlazeBurnerTileE
|
|||
if (heatLevel == HeatLevel.NONE)
|
||||
return;
|
||||
|
||||
float renderTick = AnimationTickHolder.getRenderTime() + (te.hashCode() % 13) * 16f;
|
||||
float renderTick = AnimationTickHolder.getRenderTime(te.getWorld()) + (te.hashCode() % 13) * 16f;
|
||||
float offset = (MathHelper.sin((float) ((renderTick / 16f) % (2 * Math.PI))) + .5f) / 16f;
|
||||
|
||||
AllBlockPartials blazeModel = AllBlockPartials.BLAZES.get(heatLevel);
|
||||
|
|
|
@ -74,7 +74,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||
MatrixStack localTransforms = new MatrixStack();
|
||||
MatrixStacker msr = MatrixStacker.of(localTransforms);
|
||||
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
|
||||
float renderTick = AnimationTickHolder.getRenderTime();
|
||||
float renderTick = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
|
||||
msr.centre();
|
||||
msr.rotateY(AngleHelper.horizontalAngle(facing) + (upward ? 180 : 0) + (sideways ? 270 : 0));
|
||||
|
|
|
@ -32,7 +32,7 @@ public class SplitShaftRenderer extends KineticTileEntityRenderer {
|
|||
Block block = te.getBlockState().getBlock();
|
||||
final Axis boxAxis = ((IRotate) block).getRotationAxis(te.getBlockState());
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
|
||||
for (Direction direction : Iterate.directions) {
|
||||
Axis axis = direction.getAxis();
|
||||
|
|
|
@ -30,7 +30,7 @@ public class GearboxRenderer extends KineticTileEntityRenderer {
|
|||
|
||||
final Axis boxAxis = te.getBlockState().get(BlockStateProperties.AXIS);
|
||||
final BlockPos pos = te.getPos();
|
||||
float time = AnimationTickHolder.getRenderTime();
|
||||
float time = AnimationTickHolder.getRenderTime(te.getWorld());
|
||||
|
||||
for (Direction direction : Iterate.directions) {
|
||||
final Axis axis = direction.getAxis();
|
||||
|
|
|
@ -1,29 +1,178 @@
|
|||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.RotatingData;
|
||||
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedValue;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class ArmInstance extends SingleRotatingInstance {
|
||||
import java.util.ArrayList;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ArmInstance extends SingleRotatingInstance implements ITickableInstance {
|
||||
public static void register(TileEntityType<? extends KineticTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, ArmInstance::new));
|
||||
}
|
||||
private InstanceKey<ModelData> base;
|
||||
private InstanceKey<ModelData> lowerBody;
|
||||
private InstanceKey<ModelData> upperBody;
|
||||
private InstanceKey<ModelData> head;
|
||||
private InstanceKey<ModelData> claw;
|
||||
private ArrayList<InstanceKey<ModelData>> clawGrips;
|
||||
|
||||
private ArrayList<InstanceKey<ModelData>> models;
|
||||
|
||||
private boolean firstTick = true;
|
||||
|
||||
public ArmInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
|
||||
|
||||
base = mat.getModel(AllBlockPartials.ARM_BASE, lastState).createInstance();
|
||||
lowerBody = mat.getModel(AllBlockPartials.ARM_LOWER_BODY, lastState).createInstance();
|
||||
upperBody = mat.getModel(AllBlockPartials.ARM_UPPER_BODY, lastState).createInstance();
|
||||
head = mat.getModel(AllBlockPartials.ARM_HEAD, lastState).createInstance();
|
||||
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, lastState).createInstance();
|
||||
|
||||
InstancedModel<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, lastState);
|
||||
InstanceKey<ModelData> clawGrip1 = clawHalfModel.createInstance();
|
||||
InstanceKey<ModelData> clawGrip2 = clawHalfModel.createInstance();
|
||||
|
||||
clawGrips = Lists.newArrayList(clawGrip1, clawGrip2);
|
||||
models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2);
|
||||
|
||||
tick();
|
||||
updateLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ArmTileEntity arm = (ArmTileEntity) tile;
|
||||
|
||||
boolean settled = Stream.of(arm.baseAngle, arm.lowerArmAngle, arm.upperArmAngle, arm.headAngle).allMatch(InterpolatedValue::settled);
|
||||
boolean rave = arm.phase == ArmTileEntity.Phase.DANCING;
|
||||
|
||||
if (!settled || rave || firstTick)
|
||||
transformModels(arm, rave);
|
||||
|
||||
if (settled)
|
||||
firstTick = false;
|
||||
}
|
||||
|
||||
private void transformModels(ArmTileEntity arm, boolean rave) {
|
||||
float pt = AnimationTickHolder.getPartialTicks();
|
||||
int color = 0xFFFFFF;
|
||||
|
||||
float baseAngle = arm.baseAngle.get(pt);
|
||||
float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135;
|
||||
float upperArmAngle = arm.upperArmAngle.get(pt) - 90;
|
||||
float headAngle = arm.headAngle.get(pt);
|
||||
|
||||
if (rave) {
|
||||
float renderTick = AnimationTickHolder.getRenderTime(arm.getWorld()) + (tile.hashCode() % 64);
|
||||
baseAngle = (renderTick * 10) % 360;
|
||||
lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15);
|
||||
upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95);
|
||||
headAngle = -lowerArmAngle;
|
||||
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
|
||||
}
|
||||
|
||||
|
||||
MatrixStack msLocal = new MatrixStack();
|
||||
MatrixStacker msr = MatrixStacker.of(msLocal);
|
||||
msr.translate(getFloatingPos());
|
||||
msr.centre();
|
||||
|
||||
if (lastState.get(ArmBlock.CEILING))
|
||||
msr.rotateX(180);
|
||||
|
||||
ArmRenderer.transformBase(msr, baseAngle);
|
||||
base.getInstance()
|
||||
.setTransform(msLocal);
|
||||
|
||||
ArmRenderer.transformLowerArm(msr, lowerArmAngle);
|
||||
lowerBody.getInstance()
|
||||
.setColor(color)
|
||||
.setTransform(msLocal);
|
||||
|
||||
ArmRenderer.transformUpperArm(msr, upperArmAngle);
|
||||
upperBody.getInstance()
|
||||
.setColor(color)
|
||||
.setTransform(msLocal);
|
||||
|
||||
ArmRenderer.transformHead(msr, headAngle);
|
||||
head.getInstance()
|
||||
.setTransform(msLocal);
|
||||
|
||||
ArmRenderer.transformClaw(msr);
|
||||
claw.getInstance()
|
||||
.setTransform(msLocal);
|
||||
|
||||
ItemStack item = arm.heldItem;
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
boolean hasItem = !item.isEmpty();
|
||||
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
||||
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
||||
.isGui3d();
|
||||
|
||||
for (int index : Iterate.zeroAndOne) {
|
||||
msLocal.push();
|
||||
int flip = index * 2 - 1;
|
||||
ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip);
|
||||
clawGrips.get(index)
|
||||
.getInstance()
|
||||
.setTransform(msLocal);
|
||||
msLocal.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
super.updateLight();
|
||||
int block = world.getLightLevel(LightType.BLOCK, pos);
|
||||
int sky = world.getLightLevel(LightType.SKY, pos);
|
||||
|
||||
|
||||
models.stream()
|
||||
.map(InstanceKey::getInstance)
|
||||
.forEach(data -> data.setSkyLight(sky).setBlockLight(block));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstancedModel<RotatingData> getModel() {
|
||||
return AllBlockPartials.ARM_COG.renderOnRotating(modelManager, tile.getBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
models.forEach(InstanceKey::delete);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
|||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.Backend;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
@ -39,6 +41,21 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||
int overlay) {
|
||||
super.renderSafe(te, pt, ms, buffer, light, overlay);
|
||||
ArmTileEntity arm = (ArmTileEntity) te;
|
||||
|
||||
boolean usingFlywheel = FastRenderDispatcher.available(te.getWorld());
|
||||
|
||||
ItemStack item = arm.heldItem;
|
||||
boolean hasItem = !item.isEmpty();
|
||||
|
||||
if (usingFlywheel && !hasItem) return;
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
|
||||
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
||||
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
||||
.isGui3d();
|
||||
|
||||
IVertexBuilder builder = buffer.getBuffer(RenderType.getSolid());
|
||||
BlockState blockState = te.getBlockState();
|
||||
|
||||
|
@ -52,7 +69,7 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||
float headAngle = arm.headAngle.get(pt);
|
||||
|
||||
boolean rave = arm.phase == Phase.DANCING;
|
||||
float renderTick = AnimationTickHolder.getRenderTime() + (te.hashCode() % 64);
|
||||
float renderTick = AnimationTickHolder.getRenderTime(te.getWorld()) + (te.hashCode() % 64);
|
||||
if (rave) {
|
||||
baseAngle = (renderTick * 10) % 360;
|
||||
lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15);
|
||||
|
@ -61,59 +78,15 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||
color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100);
|
||||
}
|
||||
|
||||
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
||||
SuperByteBuffer lowerBody = AllBlockPartials.ARM_LOWER_BODY.renderOn(blockState).light(light);
|
||||
SuperByteBuffer upperBody = AllBlockPartials.ARM_UPPER_BODY.renderOn(blockState).light(light);
|
||||
SuperByteBuffer head = AllBlockPartials.ARM_HEAD.renderOn(blockState).light(light);
|
||||
SuperByteBuffer claw = AllBlockPartials.ARM_CLAW_BASE.renderOn(blockState).light(light);
|
||||
SuperByteBuffer clawGrip = AllBlockPartials.ARM_CLAW_GRIP.renderOn(blockState);
|
||||
|
||||
msr.centre();
|
||||
|
||||
|
||||
if (blockState.get(ArmBlock.CEILING))
|
||||
msr.rotateX(180);
|
||||
|
||||
msLocal.translate(0, 4 / 16d, 0);
|
||||
msr.rotateY(baseAngle);
|
||||
base.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
msLocal.translate(0, 1 / 16d, -2 / 16d);
|
||||
msr.rotateX(lowerArmAngle);
|
||||
msLocal.translate(0, -1 / 16d, 0);
|
||||
lowerBody.color(color)
|
||||
.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
msLocal.translate(0, 12 / 16d, 12 / 16d);
|
||||
msr.rotateX(upperArmAngle);
|
||||
upperBody.color(color)
|
||||
.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
msLocal.translate(0, 11 / 16d, -11 / 16d);
|
||||
msr.rotateX(headAngle);
|
||||
head.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
msLocal.translate(0, 0, -4 / 16d);
|
||||
claw.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
ItemStack item = arm.heldItem;
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
boolean hasItem = !item.isEmpty();
|
||||
boolean isBlockItem = hasItem && (item.getItem() instanceof BlockItem)
|
||||
&& itemRenderer.getItemModelWithOverrides(item, Minecraft.getInstance().world, null)
|
||||
.isGui3d();
|
||||
|
||||
for (int flip : Iterate.positiveAndNegative) {
|
||||
msLocal.push();
|
||||
msLocal.translate(0, flip * 3 / 16d, -1 / 16d);
|
||||
msr.rotateX(flip * (hasItem ? isBlockItem ? 0 : -35 : 0));
|
||||
clawGrip.light(light).transform(msLocal).renderInto(ms, builder);
|
||||
msLocal.pop();
|
||||
}
|
||||
if (usingFlywheel)
|
||||
doItemTransforms(msr, baseAngle, lowerArmAngle, upperArmAngle, headAngle);
|
||||
else
|
||||
renderArm(builder, ms, msLocal, msr, blockState, color, baseAngle, lowerArmAngle, upperArmAngle, headAngle, hasItem, isBlockItem, light);
|
||||
|
||||
if (hasItem) {
|
||||
ms.push();
|
||||
|
@ -131,6 +104,83 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||
|
||||
}
|
||||
|
||||
private void renderArm(IVertexBuilder builder, MatrixStack ms, MatrixStack msLocal, MatrixStacker msr, BlockState blockState, int color, float baseAngle, float lowerArmAngle, float upperArmAngle, float headAngle, boolean hasItem, boolean isBlockItem, int light) {
|
||||
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
||||
SuperByteBuffer lowerBody = AllBlockPartials.ARM_LOWER_BODY.renderOn(blockState).light(light);
|
||||
SuperByteBuffer upperBody = AllBlockPartials.ARM_UPPER_BODY.renderOn(blockState).light(light);
|
||||
SuperByteBuffer head = AllBlockPartials.ARM_HEAD.renderOn(blockState).light(light);
|
||||
SuperByteBuffer claw = AllBlockPartials.ARM_CLAW_BASE.renderOn(blockState).light(light);
|
||||
SuperByteBuffer clawGrip = AllBlockPartials.ARM_CLAW_GRIP.renderOn(blockState);
|
||||
|
||||
transformBase(msr, baseAngle);
|
||||
base.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
transformLowerArm(msr, lowerArmAngle);
|
||||
lowerBody.color(color)
|
||||
.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
transformUpperArm(msr, upperArmAngle);
|
||||
upperBody.color(color)
|
||||
.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
transformHead(msr, headAngle);
|
||||
head.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
transformClaw(msr);
|
||||
claw.transform(msLocal)
|
||||
.renderInto(ms, builder);
|
||||
|
||||
for (int flip : Iterate.positiveAndNegative) {
|
||||
msLocal.push();
|
||||
transformClawHalf(msr, hasItem, isBlockItem, flip);
|
||||
clawGrip.light(light).transform(msLocal).renderInto(ms, builder);
|
||||
msLocal.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private void doItemTransforms(MatrixStacker msr, float baseAngle, float lowerArmAngle, float upperArmAngle, float headAngle) {
|
||||
|
||||
transformBase(msr, baseAngle);
|
||||
transformLowerArm(msr, lowerArmAngle);
|
||||
transformUpperArm(msr, upperArmAngle);
|
||||
transformHead(msr, headAngle);
|
||||
transformClaw(msr);
|
||||
}
|
||||
|
||||
public static void transformClawHalf(MatrixStacker msr, boolean hasItem, boolean isBlockItem, int flip) {
|
||||
msr.translate(0, flip * 3 / 16d, -1 / 16d);
|
||||
msr.rotateX(flip * (hasItem ? isBlockItem ? 0 : -35 : 0));
|
||||
}
|
||||
|
||||
public static void transformClaw(MatrixStacker msr) {
|
||||
msr.translate(0, 0, -4 / 16d);
|
||||
}
|
||||
|
||||
public static void transformHead(MatrixStacker msr, float headAngle) {
|
||||
msr.translate(0, 11 / 16d, -11 / 16d);
|
||||
msr.rotateX(headAngle);
|
||||
}
|
||||
|
||||
public static void transformUpperArm(MatrixStacker msr, float upperArmAngle) {
|
||||
msr.translate(0, 12 / 16d, 12 / 16d);
|
||||
msr.rotateX(upperArmAngle);
|
||||
}
|
||||
|
||||
public static void transformLowerArm(MatrixStacker msr, float lowerArmAngle) {
|
||||
msr.translate(0, 1 / 16d, -2 / 16d);
|
||||
msr.rotateX(lowerArmAngle);
|
||||
msr.translate(0, -1 / 16d, 0);
|
||||
}
|
||||
|
||||
public static void transformBase(MatrixStacker msr, float baseAngle) {
|
||||
msr.translate(0, 4 / 16d, 0);
|
||||
msr.rotateY(baseAngle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
|
||||
return AllBlockPartials.ARM_COG.renderOn(te.getBlockState());
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package com.simibubi.create.content.schematics.block;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.RenderMaterials;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.LightType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
||||
public class SchematicannonInstance extends TileEntityInstance<SchematicannonTileEntity> implements ITickableInstance {
|
||||
public static void register(TileEntityType<? extends SchematicannonTileEntity> type) {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () ->
|
||||
InstancedTileRenderRegistry.instance.register(type, SchematicannonInstance::new));
|
||||
}
|
||||
|
||||
private InstanceKey<ModelData> connector;
|
||||
private InstanceKey<ModelData> pipe;
|
||||
|
||||
public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) {
|
||||
super(modelManager, tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
|
||||
RenderMaterial<?, InstancedModel<ModelData>> mat = modelManager.getMaterial(RenderMaterials.MODELS);
|
||||
|
||||
connector = mat.getModel(AllBlockPartials.SCHEMATICANNON_CONNECTOR, lastState).createInstance();
|
||||
pipe = mat.getModel(AllBlockPartials.SCHEMATICANNON_PIPE, lastState).createInstance();
|
||||
|
||||
updateLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
float partialTicks = AnimationTickHolder.getPartialTicks();
|
||||
|
||||
double[] cannonAngles = SchematicannonRenderer.getCannonAngles(tile, pos, partialTicks);
|
||||
|
||||
double pitch = cannonAngles[0];
|
||||
double yaw = cannonAngles[1];
|
||||
|
||||
double recoil = SchematicannonRenderer.getRecoil(tile, partialTicks);
|
||||
|
||||
MatrixStack ms = new MatrixStack();
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
|
||||
msr.translate(getFloatingPos());
|
||||
|
||||
ms.push();
|
||||
msr.centre();
|
||||
msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
|
||||
msr.unCentre();
|
||||
connector.getInstance().setTransform(ms);
|
||||
ms.pop();
|
||||
|
||||
msr.translate(.5f, 15 / 16f, .5f);
|
||||
msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
|
||||
msr.rotate(Direction.SOUTH, (float) (pitch / 180 * Math.PI));
|
||||
msr.translate(-.5f, -15 / 16f, -.5f);
|
||||
msr.translate(0, -recoil / 100, 0);
|
||||
|
||||
pipe.getInstance().setTransformNoCopy(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
connector.delete();
|
||||
pipe.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLight() {
|
||||
int block = world.getLightLevel(LightType.BLOCK, pos);
|
||||
int sky = world.getLightLevel(LightType.SKY, pos);
|
||||
|
||||
connector.getInstance()
|
||||
.setBlockLight(block)
|
||||
.setSkyLight(sky);
|
||||
|
||||
pipe.getInstance()
|
||||
.setBlockLight(block)
|
||||
.setSkyLight(sky);
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import com.simibubi.create.AllBlockPartials;
|
|||
import com.simibubi.create.content.schematics.block.LaunchedItem.ForBlockState;
|
||||
import com.simibubi.create.content.schematics.block.LaunchedItem.ForEntity;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -40,33 +41,20 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
|
||||
IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
|
||||
double yaw = 0;
|
||||
double pitch = 40;
|
||||
boolean blocksLaunching = !tileEntityIn.flyingBlocks.isEmpty();
|
||||
if (blocksLaunching)
|
||||
renderLaunchedBlocks(tileEntityIn, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
if (FastRenderDispatcher.available(tileEntityIn.getWorld())) return;
|
||||
|
||||
BlockPos pos = tileEntityIn.getPos();
|
||||
if (tileEntityIn.target != null) {
|
||||
|
||||
// Calculate Angle of Cannon
|
||||
Vec3d diff = new Vec3d(tileEntityIn.target.subtract(pos));
|
||||
if (tileEntityIn.previousTarget != null) {
|
||||
diff = (new Vec3d(tileEntityIn.previousTarget)
|
||||
.add(new Vec3d(tileEntityIn.target.subtract(tileEntityIn.previousTarget)).scale(partialTicks)))
|
||||
.subtract(new Vec3d(pos));
|
||||
}
|
||||
double[] cannonAngles = getCannonAngles(tileEntityIn, pos, partialTicks);
|
||||
|
||||
double diffX = diff.getX();
|
||||
double diffZ = diff.getZ();
|
||||
yaw = MathHelper.atan2(diffX, diffZ);
|
||||
yaw = yaw / Math.PI * 180;
|
||||
double pitch = cannonAngles[0];
|
||||
double yaw = cannonAngles[1];
|
||||
|
||||
float distance = MathHelper.sqrt(diffX * diffX + diffZ * diffZ);
|
||||
double yOffset = 0 + distance * 2f;
|
||||
pitch = MathHelper.atan2(distance, diff.getY() * 3 + yOffset);
|
||||
pitch = pitch / Math.PI * 180 + 10;
|
||||
|
||||
}
|
||||
|
||||
double recoil = !tileEntityIn.flyingBlocks.isEmpty() ? getRecoil(tileEntityIn, partialTicks, ms, buffer, light, overlay) : 0;
|
||||
double recoil = getRecoil(tileEntityIn, partialTicks);
|
||||
|
||||
ms.push();
|
||||
BlockState state = tileEntityIn.getBlockState();
|
||||
|
@ -91,9 +79,51 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
ms.pop();
|
||||
}
|
||||
|
||||
private double getRecoil(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
public static double[] getCannonAngles(SchematicannonTileEntity tile, BlockPos pos, float partialTicks) {
|
||||
double yaw = 0;
|
||||
double pitch = 40;
|
||||
|
||||
if (tile.target != null) {
|
||||
|
||||
// Calculate Angle of Cannon
|
||||
Vec3d diff = new Vec3d(tile.target.subtract(pos));
|
||||
if (tile.previousTarget != null) {
|
||||
diff = (new Vec3d(tile.previousTarget)
|
||||
.add(new Vec3d(tile.target.subtract(tile.previousTarget)).scale(partialTicks)))
|
||||
.subtract(new Vec3d(pos));
|
||||
}
|
||||
|
||||
double diffX = diff.getX();
|
||||
double diffZ = diff.getZ();
|
||||
yaw = MathHelper.atan2(diffX, diffZ);
|
||||
yaw = yaw / Math.PI * 180;
|
||||
|
||||
float distance = MathHelper.sqrt(diffX * diffX + diffZ * diffZ);
|
||||
double yOffset = 0 + distance * 2f;
|
||||
pitch = MathHelper.atan2(distance, diff.getY() * 3 + yOffset);
|
||||
pitch = pitch / Math.PI * 180 + 10;
|
||||
|
||||
}
|
||||
|
||||
return new double[] { pitch, yaw };
|
||||
}
|
||||
|
||||
public static double getRecoil(SchematicannonTileEntity tileEntityIn, float partialTicks) {
|
||||
double recoil = 0;
|
||||
|
||||
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
|
||||
|
||||
if (launched.ticksRemaining == 0) continue;
|
||||
|
||||
// Apply Recoil if block was just launched
|
||||
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10)
|
||||
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
|
||||
}
|
||||
|
||||
return recoil;
|
||||
}
|
||||
|
||||
private static void renderLaunchedBlocks(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
|
||||
|
||||
if (launched.ticksRemaining == 0)
|
||||
|
@ -141,10 +171,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
|
||||
ms.pop();
|
||||
|
||||
// Apply Recoil if block was just launched
|
||||
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10)
|
||||
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
|
||||
|
||||
// Render particles for launch
|
||||
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
|
||||
tileEntityIn.firstRenderTick = false;
|
||||
|
@ -162,8 +188,6 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
return recoil;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltPart;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
|
||||
|
@ -23,6 +24,7 @@ import com.simibubi.create.foundation.config.AllConfigs;
|
|||
import com.simibubi.create.foundation.config.CSchematics;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
|
@ -63,11 +65,12 @@ import net.minecraft.world.gen.feature.template.Template;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider {
|
||||
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider, IInstanceRendered {
|
||||
|
||||
public static final int NEIGHBOUR_CHECKING = 100;
|
||||
public static final int MAX_ANCHOR_DISTANCE = 256;
|
||||
|
@ -934,4 +937,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
findInventories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.kineticRenderer.add(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkLightUpdate() {
|
||||
CreateClient.kineticRenderer.onLightUpdate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderAsTE() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,8 @@ public class AllIcons implements IScreenRenderable {
|
|||
I_MTD_CLOSE = next(),
|
||||
I_MTD_RIGHT = next(),
|
||||
I_MTD_SCAN = next(),
|
||||
I_MTD_REPLAY = next();
|
||||
I_MTD_REPLAY = next(),
|
||||
I_MTD_USER_MODE = next();
|
||||
|
||||
public AllIcons(int x, int y) {
|
||||
iconX = x * 16;
|
||||
|
|
|
@ -16,5 +16,9 @@ public class InterpolatedValue {
|
|||
public float get(float partialTicks) {
|
||||
return MathHelper.lerp(partialTicks, lastValue, value);
|
||||
}
|
||||
|
||||
public boolean settled() {
|
||||
return Math.abs(value - lastValue) < 1e-3;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,10 +76,13 @@ public class PonderScene {
|
|||
WorldSectionElement baseWorldSection;
|
||||
Entity renderViewEntity;
|
||||
|
||||
int offsetX;
|
||||
int offsetZ;
|
||||
int size;
|
||||
int basePlateOffsetX;
|
||||
int basePlateOffsetZ;
|
||||
int basePlateSize;
|
||||
float scaleFactor;
|
||||
float yOffset;
|
||||
|
||||
boolean stoppedCounting;
|
||||
int totalTime;
|
||||
int currentTime;
|
||||
|
||||
|
@ -97,10 +100,12 @@ public class PonderScene {
|
|||
schedule = new ArrayList<>();
|
||||
activeSchedule = new ArrayList<>();
|
||||
transform = new SceneTransform();
|
||||
size = getBounds().getXSize();
|
||||
basePlateSize = getBounds().getXSize();
|
||||
info = new SceneRenderInfo();
|
||||
baseWorldSection = new WorldSectionElement();
|
||||
renderViewEntity = new ArmorStandEntity(world, 0, 0, 0);
|
||||
scaleFactor = 1;
|
||||
yOffset = 0;
|
||||
|
||||
setPointOfInterest(new Vec3d(0, 4, 0));
|
||||
}
|
||||
|
@ -135,11 +140,12 @@ public class PonderScene {
|
|||
BlockPos selectedPos = nearestHit.getValue()
|
||||
.getSecond();
|
||||
|
||||
BlockPos origin = new BlockPos(offsetX, 0, offsetZ);
|
||||
BlockPos origin = new BlockPos(basePlateOffsetX, 0, basePlateOffsetZ);
|
||||
if (!world.getBounds()
|
||||
.isVecInside(selectedPos))
|
||||
return Pair.of(ItemStack.EMPTY, null);
|
||||
if (new MutableBoundingBox(origin, origin.add(new Vec3i(size - 1, 0, size - 1))).isVecInside(selectedPos)) {
|
||||
if (new MutableBoundingBox(origin, origin.add(new Vec3i(basePlateSize - 1, 0, basePlateSize - 1)))
|
||||
.isVecInside(selectedPos)) {
|
||||
if (PonderIndex.EDITOR_MODE)
|
||||
nearestHit.getValue()
|
||||
.getFirst()
|
||||
|
@ -189,6 +195,7 @@ public class PonderScene {
|
|||
elements.add(baseWorldSection);
|
||||
|
||||
totalTime = 0;
|
||||
stoppedCounting = false;
|
||||
activeSchedule.addAll(schedule);
|
||||
activeSchedule.forEach(i -> i.onScheduled(this));
|
||||
}
|
||||
|
@ -269,7 +276,12 @@ public class PonderScene {
|
|||
}
|
||||
|
||||
public void addToSceneTime(int time) {
|
||||
totalTime += time;
|
||||
if (!stoppedCounting)
|
||||
totalTime += time;
|
||||
}
|
||||
|
||||
public void stopCounting() {
|
||||
stoppedCounting = true;
|
||||
}
|
||||
|
||||
public void addElement(PonderElement e) {
|
||||
|
@ -376,11 +388,11 @@ public class PonderScene {
|
|||
}
|
||||
|
||||
public MatrixStack apply(MatrixStack ms) {
|
||||
return apply(ms, AnimationTickHolder.getPartialTicks());
|
||||
return apply(ms, AnimationTickHolder.getPartialTicks(world));
|
||||
}
|
||||
|
||||
public MatrixStack apply(MatrixStack ms, float pt) {
|
||||
ms.translate(width / 2, height / 2, 200);
|
||||
ms.translate(width / 2, height / 2, 200 + offset);
|
||||
|
||||
MatrixStacker.of(ms)
|
||||
.rotateX(-35)
|
||||
|
@ -389,12 +401,15 @@ public class PonderScene {
|
|||
MatrixStacker.of(ms)
|
||||
.rotateY(-55)
|
||||
.rotateX(35);
|
||||
|
||||
MatrixStacker.of(ms)
|
||||
.rotateX(xRotation.getValue(pt))
|
||||
.rotateY(yRotation.getValue(pt));
|
||||
ms.scale(30, -30, 30);
|
||||
ms.translate((size + offsetX) / -2f, -1f, (size + offsetZ) / -2f);
|
||||
|
||||
float f = 30 * scaleFactor;
|
||||
|
||||
ms.scale(f, -f, f);
|
||||
ms.translate((basePlateSize + basePlateOffsetX) / -2f, -1f + yOffset,
|
||||
(basePlateSize + basePlateOffsetZ) / -2f);
|
||||
|
||||
return ms;
|
||||
}
|
||||
|
@ -409,7 +424,7 @@ public class PonderScene {
|
|||
float pt = AnimationTickHolder.getPartialTicks();
|
||||
Vec3d vec = new Vec3d(x, y, depth);
|
||||
|
||||
vec = vec.subtract(width / 2, height / 2, 200);
|
||||
vec = vec.subtract(width / 2, height / 2, 200 + offset);
|
||||
vec = VecHelper.rotate(vec, 35, Axis.X);
|
||||
vec = VecHelper.rotate(vec, -55, Axis.Y);
|
||||
vec = vec.subtract(offset, 0, 0);
|
||||
|
@ -417,8 +432,12 @@ public class PonderScene {
|
|||
vec = VecHelper.rotate(vec, -35, Axis.X);
|
||||
vec = VecHelper.rotate(vec, -xRotation.getValue(pt), Axis.X);
|
||||
vec = VecHelper.rotate(vec, -yRotation.getValue(pt), Axis.Y);
|
||||
vec = vec.mul(1f / 30, 1f / -30, 1f / 30);
|
||||
vec = vec.subtract((size + offsetX) / -2f, -1f, (size + offsetZ) / -2f);
|
||||
|
||||
float f = 1f / (30 * scaleFactor);
|
||||
|
||||
vec = vec.mul(f, -f, f);
|
||||
vec = vec.subtract((basePlateSize + basePlateOffsetX) / -2f, -1f + yOffset,
|
||||
(basePlateSize + basePlateOffsetZ) / -2f);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,8 @@ public class PonderTooltipHandler {
|
|||
}
|
||||
|
||||
public static void addToTooltip(List<ITextComponent> toolTip, ItemStack stack) {
|
||||
float renderPartialTicks = AnimationTickHolder.getPartialTicks();
|
||||
float renderPartialTicks = Minecraft.getInstance()
|
||||
.getRenderPartialTicks();
|
||||
if (lastHoveredStack != stack)
|
||||
return;
|
||||
ITextComponent component = subject ? Lang.createTranslationTextComponent(SUBJECT)
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.simibubi.create.foundation.ponder.content.PonderTag;
|
|||
import com.simibubi.create.foundation.ponder.content.PonderTagScreen;
|
||||
import com.simibubi.create.foundation.ponder.ui.PonderButton;
|
||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -38,6 +37,7 @@ import net.minecraft.client.GameSettings;
|
|||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.Widget;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
|
@ -55,6 +55,9 @@ import net.minecraftforge.registries.ForgeRegistries;
|
|||
|
||||
public class PonderUI extends AbstractSimiScreen {
|
||||
|
||||
public static int ponderTicks;
|
||||
public static float ponderPartialTicksPaused;
|
||||
|
||||
public static final String PONDERING = PonderLocalization.LANG_PREFIX + "pondering";
|
||||
public static final String IDENTIFY_MODE = PonderLocalization.LANG_PREFIX + "identify_mode";
|
||||
public static final String IN_CHAPTER = PonderLocalization.LANG_PREFIX + "in_chapter";
|
||||
|
@ -68,6 +71,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
ItemStack stack;
|
||||
PonderChapter chapter = null;
|
||||
|
||||
private boolean userViewMode;
|
||||
private boolean identifyMode;
|
||||
private ItemStack hoveredTooltipItem;
|
||||
private BlockPos hoveredBlockPos;
|
||||
|
@ -79,7 +83,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
private int index = 0;
|
||||
private PonderTag referredToByTag;
|
||||
|
||||
private PonderButton left, right, scan, chap;
|
||||
private PonderButton left, right, scan, chap, userMode;
|
||||
|
||||
public static PonderUI of(ItemStack item) {
|
||||
return new PonderUI(PonderRegistry.compile(item.getItem()
|
||||
|
@ -134,7 +138,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
tags.forEach(t -> {
|
||||
int i = tagButtons.size();
|
||||
int x = 31;
|
||||
int y = 71 + i * 30;
|
||||
int y = 81 + i * 30;
|
||||
PonderButton b = new PonderButton(x, y, (mouseX, mouseY) -> {
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(new PonderTagScreen(t));
|
||||
|
@ -165,10 +169,19 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
if (!identifyMode)
|
||||
scenes.get(index)
|
||||
.deselect();
|
||||
else
|
||||
ponderPartialTicksPaused = minecraft.getRenderPartialTicks();
|
||||
}).showing(AllIcons.I_MTD_SCAN)
|
||||
.shortcut(bindings.keyBindDrop)
|
||||
.fade(0, -1));
|
||||
|
||||
if (PonderIndex.EDITOR_MODE) {
|
||||
widgets.add(userMode = new PonderButton(31, bY, () -> {
|
||||
userViewMode = !userViewMode;
|
||||
}).showing(AllIcons.I_MTD_USER_MODE)
|
||||
.fade(0, -1));
|
||||
}
|
||||
|
||||
bX += 50 + spacing;
|
||||
widgets.add(left = new PonderButton(bX, bY, () -> this.scroll(false)).showing(AllIcons.I_MTD_LEFT)
|
||||
.shortcut(bindings.keyBindLeft)
|
||||
|
@ -215,8 +228,10 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
}
|
||||
|
||||
PonderScene activeScene = scenes.get(index);
|
||||
if (!identifyMode)
|
||||
if (!identifyMode) {
|
||||
ponderTicks++;
|
||||
activeScene.tick();
|
||||
}
|
||||
sceneProgress.chase(activeScene.getSceneProgress(), .5f, Chaser.EXP);
|
||||
lazyIndex.tickChaser();
|
||||
fadeIn.tickChaser();
|
||||
|
@ -295,8 +310,13 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
@Override
|
||||
protected void renderWindow(int mouseX, int mouseY, float partialTicks) {
|
||||
RenderSystem.enableBlend();
|
||||
renderVisibleScenes(mouseX, mouseY, identifyMode ? 0 : partialTicks);
|
||||
renderWidgets(mouseX, mouseY, identifyMode ? 0 : partialTicks);
|
||||
renderVisibleScenes(mouseX, mouseY, identifyMode ? ponderPartialTicksPaused : partialTicks);
|
||||
renderWidgets(mouseX, mouseY, identifyMode ? ponderPartialTicksPaused : partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderBackground() {
|
||||
super.renderBackground();
|
||||
}
|
||||
|
||||
protected void renderVisibleScenes(int mouseX, int mouseY, float partialTicks) {
|
||||
|
@ -310,7 +330,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance();
|
||||
PonderScene story = scenes.get(i);
|
||||
MatrixStack ms = new MatrixStack();
|
||||
double value = lazyIndex.getValue(AnimationTickHolder.getPartialTicks());
|
||||
double value = lazyIndex.getValue(minecraft.getRenderPartialTicks());
|
||||
double diff = i - value;
|
||||
double slide = MathHelper.lerp(diff * diff, 200, 600) * diff;
|
||||
|
||||
|
@ -325,15 +345,36 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
story.renderScene(buffer, ms, partialTicks);
|
||||
buffer.draw();
|
||||
|
||||
// coords for debug
|
||||
if (PonderIndex.EDITOR_MODE) {
|
||||
MutableBoundingBox bounds = story.getBounds();
|
||||
MutableBoundingBox bounds = story.getBounds();
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.multMatrix(ms.peek()
|
||||
.getModel());
|
||||
|
||||
// kool shadow fx
|
||||
{
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.multMatrix(ms.peek()
|
||||
.getModel());
|
||||
RenderSystem.translated(story.basePlateOffsetX, 0, story.basePlateOffsetZ);
|
||||
RenderSystem.scaled(1, -1, 1);
|
||||
for (int f = 0; f < 4; f++) {
|
||||
RenderSystem.translated(story.basePlateSize, 0, 0);
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translated(0, 0, 1/1024f);
|
||||
GuiUtils.drawGradientRect(0, 0, 0, -story.basePlateSize, 4, 0x66_000000, 0x00_000000);
|
||||
RenderSystem.popMatrix();
|
||||
RenderSystem.rotatef(-90, 0, 1, 0);
|
||||
}
|
||||
RenderSystem.popMatrix();
|
||||
RenderSystem.disableCull();
|
||||
RenderSystem.disableDepthTest();
|
||||
}
|
||||
|
||||
RenderSystem.scaled(-1 / 16d, -1 / 16d, 1 / 16d);
|
||||
// coords for debug
|
||||
if (PonderIndex.EDITOR_MODE && !userViewMode) {
|
||||
|
||||
RenderSystem.scaled(-1, -1, 1);
|
||||
RenderSystem.scaled(1 / 16d, 1 / 16d, 1 / 16d);
|
||||
RenderSystem.translated(1, -8, -1 / 64f);
|
||||
|
||||
// X AXIS
|
||||
|
@ -373,11 +414,11 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
RenderSystem.popMatrix();
|
||||
}
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
buffer.draw();
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
|
@ -388,6 +429,10 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
PonderScene activeScene = scenes.get(index);
|
||||
int textColor = 0xeeeeee;
|
||||
|
||||
boolean noWidgetsHovered = true;
|
||||
for (Widget widget : widgets)
|
||||
noWidgetsHovered &= !widget.isMouseOver(mouseX, mouseY);
|
||||
|
||||
{
|
||||
// Chapter title
|
||||
RenderSystem.pushMatrix();
|
||||
|
@ -396,7 +441,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
int y = 31;
|
||||
|
||||
String title = activeScene.getTitle();
|
||||
int wordWrappedHeight = font.getWordWrappedHeight(title, left.x);
|
||||
int wordWrappedHeight = font.getWordWrappedHeight(title, left.x - 51);
|
||||
|
||||
int streakHeight = 35 - 9 + wordWrappedHeight;
|
||||
UIRenderHelper.streak(0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade), 0x101010);
|
||||
|
@ -415,7 +460,7 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
RenderSystem.translated(x, y, 0);
|
||||
RenderSystem.rotatef(indexDiff * -75, 1, 0, 0);
|
||||
RenderSystem.translated(0, 0, 5);
|
||||
font.drawSplitString(title, 0, 0, left.x, ColorHelper.applyAlpha(textColor, 1 - indexDiff));
|
||||
font.drawSplitString(title, 0, 0, left.x - 51, ColorHelper.applyAlpha(textColor, 1 - indexDiff));
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
if (chapter != null) {
|
||||
|
@ -433,34 +478,42 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
}
|
||||
|
||||
if (identifyMode) {
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translated(mouseX, mouseY, 100);
|
||||
if (hoveredTooltipItem.isEmpty()) {
|
||||
String tooltip = Lang
|
||||
.createTranslationTextComponent(IDENTIFY_MODE,
|
||||
new StringTextComponent(minecraft.gameSettings.keyBindDrop.getKeyBinding()
|
||||
.getLocalizedName()).applyTextStyle(TextFormatting.WHITE))
|
||||
.applyTextStyle(TextFormatting.GRAY)
|
||||
.getFormattedText();
|
||||
renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);
|
||||
} else
|
||||
renderTooltip(hoveredTooltipItem, 0, 0);
|
||||
if (hoveredBlockPos != null && PonderIndex.EDITOR_MODE) {
|
||||
RenderSystem.translated(0, -15, 0);
|
||||
boolean copied = copiedBlockPos != null && hoveredBlockPos.equals(copiedBlockPos);
|
||||
String coords = new StringTextComponent(
|
||||
hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
.applyTextStyles(copied ? TextFormatting.GREEN : TextFormatting.GOLD)
|
||||
if (noWidgetsHovered) {
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translated(mouseX, mouseY, 100);
|
||||
if (hoveredTooltipItem.isEmpty()) {
|
||||
String tooltip = Lang
|
||||
.createTranslationTextComponent(IDENTIFY_MODE,
|
||||
new StringTextComponent(minecraft.gameSettings.keyBindDrop.getKeyBinding()
|
||||
.getLocalizedName()).applyTextStyle(TextFormatting.WHITE))
|
||||
.applyTextStyle(TextFormatting.GRAY)
|
||||
.getFormattedText();
|
||||
renderTooltip(coords, 0, 0);
|
||||
renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);
|
||||
} else
|
||||
renderTooltip(hoveredTooltipItem, 0, 0);
|
||||
if (hoveredBlockPos != null && PonderIndex.EDITOR_MODE && !userViewMode) {
|
||||
RenderSystem.translated(0, -15, 0);
|
||||
boolean copied = copiedBlockPos != null && hoveredBlockPos.equals(copiedBlockPos);
|
||||
String coords = new StringTextComponent(
|
||||
hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
.applyTextStyles(copied ? TextFormatting.GREEN : TextFormatting.GOLD)
|
||||
.getFormattedText();
|
||||
renderTooltip(coords, 0, 0);
|
||||
}
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
scan.flash();
|
||||
} else {
|
||||
scan.dim();
|
||||
}
|
||||
|
||||
if (PonderIndex.EDITOR_MODE) {
|
||||
if (userViewMode)
|
||||
userMode.flash();
|
||||
else
|
||||
userMode.dim();
|
||||
}
|
||||
|
||||
{
|
||||
// Scene overlay
|
||||
RenderSystem.pushMatrix();
|
||||
|
@ -494,11 +547,16 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
int x = (width / 2) - 110;
|
||||
int y = right.y + right.getHeight() + 4;
|
||||
int w = width - 2 * x;
|
||||
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translated(0, 0, 400);
|
||||
renderBox(x, y, w, 1, false);
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.translated(x - 2, y - 2, 0);
|
||||
RenderSystem.scaled((w + 4) * sceneProgress.getValue(partialTicks), 1, 1);
|
||||
GuiUtils.drawGradientRect(200, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd);
|
||||
GuiUtils.drawGradientRect(500, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd);
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
|
||||
|
@ -602,8 +660,12 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
return true;
|
||||
}
|
||||
|
||||
clipboardHelper.setClipboardString(handle, "util.grid.at(" + hoveredBlockPos.getX() + ", "
|
||||
+ hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ() + ")");
|
||||
if (hasShiftDown())
|
||||
clipboardHelper.setClipboardString(handle, "util.select.position(" + hoveredBlockPos.getX() + ", "
|
||||
+ hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ() + ")");
|
||||
else
|
||||
clipboardHelper.setClipboardString(handle, "util.grid.at(" + hoveredBlockPos.getX() + ", "
|
||||
+ hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ() + ")");
|
||||
copiedBlockPos = hoveredBlockPos;
|
||||
return true;
|
||||
}
|
||||
|
@ -773,8 +835,25 @@ public class PonderUI extends AbstractSimiScreen {
|
|||
|
||||
@Override
|
||||
public void shareContextWith(AbstractSimiScreen other) {
|
||||
if (other instanceof PonderUI)
|
||||
((PonderUI) other).referredToByTag = referredToByTag;
|
||||
if (other instanceof PonderUI) {
|
||||
PonderUI ponderUI = (PonderUI) other;
|
||||
ponderUI.referredToByTag = referredToByTag;
|
||||
}
|
||||
}
|
||||
|
||||
public static float getPartialTicks() {
|
||||
if (Minecraft.getInstance().currentScreen instanceof PonderUI) {
|
||||
PonderUI ui = (PonderUI) Minecraft.getInstance().currentScreen;
|
||||
if (ui.identifyMode)
|
||||
return ponderPartialTicksPaused;
|
||||
}
|
||||
return Minecraft.getInstance()
|
||||
.getRenderPartialTicks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.simibubi.create.foundation.ponder.instructions.DisplayWorldSectionIns
|
|||
import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction;
|
||||
import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter;
|
||||
import com.simibubi.create.foundation.ponder.instructions.FadeOutOfSceneInstruction;
|
||||
import com.simibubi.create.foundation.ponder.instructions.HighlightValueBoxInstruction;
|
||||
import com.simibubi.create.foundation.ponder.instructions.LineInstruction;
|
||||
import com.simibubi.create.foundation.ponder.instructions.MarkAsFinishedInstruction;
|
||||
import com.simibubi.create.foundation.ponder.instructions.MovePoiInstruction;
|
||||
|
@ -140,9 +141,29 @@ public class SceneBuilder {
|
|||
* assumes it to be square
|
||||
*/
|
||||
public void configureBasePlate(int xOffset, int zOffset, int basePlateSize) {
|
||||
scene.offsetX = xOffset;
|
||||
scene.offsetZ = zOffset;
|
||||
scene.size = basePlateSize;
|
||||
scene.basePlateOffsetX = xOffset;
|
||||
scene.basePlateOffsetZ = zOffset;
|
||||
scene.basePlateSize = basePlateSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this in case you are not happy with the scale of the scene relative to
|
||||
* the overlay
|
||||
*
|
||||
* @param factor >1 will make the scene appear larger, smaller otherwise
|
||||
*/
|
||||
public void scaleSceneView(float factor) {
|
||||
scene.scaleFactor = factor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this in case you are not happy with the vertical alignment of the scene
|
||||
* relative to the overlay
|
||||
*
|
||||
* @param yOffset >0 moves the scene up, down otherwise
|
||||
*/
|
||||
public void setSceneOffsetY(float yOffset) {
|
||||
scene.yOffset = yOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -150,8 +171,10 @@ public class SceneBuilder {
|
|||
* of the schematic's structure. Makes for a nice opener
|
||||
*/
|
||||
public void showBasePlate() {
|
||||
world.showSection(scene.getSceneBuildingUtil().select.cuboid(new BlockPos(scene.offsetX, 0, scene.offsetZ),
|
||||
new Vec3i(scene.size, 0, scene.size)), Direction.UP);
|
||||
world.showSection(
|
||||
scene.getSceneBuildingUtil().select.cuboid(new BlockPos(scene.basePlateOffsetX, 0, scene.basePlateOffsetZ),
|
||||
new Vec3i(scene.basePlateSize, 0, scene.basePlateSize)),
|
||||
Direction.UP);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,6 +307,15 @@ public class SceneBuilder {
|
|||
addInstruction(new ChaseAABBInstruction(color, slot, boundingBox, duration));
|
||||
}
|
||||
|
||||
public void showCenteredScrollInput(BlockPos pos, Direction side, int duration) {
|
||||
Axis axis = side.getAxis();
|
||||
float s = 1 / 16f;
|
||||
float q = 1 / 4f;
|
||||
Vec3d expands = new Vec3d(axis == Axis.X ? s : q, axis == Axis.Y ? s : q, axis == Axis.Z ? s : q);
|
||||
addInstruction(new HighlightValueBoxInstruction(scene.getSceneBuildingUtil().vector.blockSurface(pos, side),
|
||||
expands, duration));
|
||||
}
|
||||
|
||||
public void showLine(PonderPalette color, Vec3d start, Vec3d end, int duration) {
|
||||
addInstruction(new LineInstruction(color, start, end, duration));
|
||||
}
|
||||
|
@ -350,6 +382,12 @@ public class SceneBuilder {
|
|||
Optional.of(() -> scene.resolve(link))));
|
||||
}
|
||||
|
||||
public void glueBlockOnto(BlockPos position, Direction fadeInDirection, ElementLink<WorldSectionElement> link) {
|
||||
addInstruction(new DisplayWorldSectionInstruction(15, fadeInDirection,
|
||||
scene.getSceneBuildingUtil().select.position(position), Optional.of(() -> scene.resolve(link)),
|
||||
position));
|
||||
}
|
||||
|
||||
public ElementLink<WorldSectionElement> showIndependentSection(Selection selection, Direction fadeInDirection) {
|
||||
DisplayWorldSectionInstruction instruction =
|
||||
new DisplayWorldSectionInstruction(15, fadeInDirection, selection, Optional.empty());
|
||||
|
@ -405,6 +443,11 @@ public class SceneBuilder {
|
|||
.setCenterOfRotation(anchor));
|
||||
}
|
||||
|
||||
public void configureStabilization(ElementLink<WorldSectionElement> link, Vec3d anchor) {
|
||||
addInstruction(scene -> scene.resolve(link)
|
||||
.stabilizeRotation(anchor));
|
||||
}
|
||||
|
||||
public void moveSection(ElementLink<WorldSectionElement> link, Vec3d offset, int duration) {
|
||||
addInstruction(AnimateWorldSectionInstruction.move(link, offset, duration));
|
||||
}
|
||||
|
@ -504,7 +547,7 @@ public class SceneBuilder {
|
|||
return;
|
||||
behaviour.handleInsertion(stack, insertionSide.getOpposite(), false);
|
||||
});
|
||||
flapFunnels(scene.getSceneBuildingUtil().select.position(location.up()), true);
|
||||
flapFunnel(location.up(), true);
|
||||
}
|
||||
|
||||
public ElementLink<BeltItemElement> createItemOnBelt(BlockPos beltLocation, Direction insertionSide,
|
||||
|
@ -532,9 +575,8 @@ public class SceneBuilder {
|
|||
scene.linkElement(tracker, link);
|
||||
return TransportedResult.doNothing();
|
||||
});
|
||||
|
||||
});
|
||||
flapFunnels(scene.getSceneBuildingUtil().select.position(beltLocation.up()), true);
|
||||
flapFunnel(beltLocation.up(), true);
|
||||
return link;
|
||||
}
|
||||
|
||||
|
@ -596,8 +638,7 @@ public class SceneBuilder {
|
|||
modifyTileNBT(selection, teType, consumer, false);
|
||||
}
|
||||
|
||||
public <T extends TileEntity> void modifyTileEntity(BlockPos position, Class<T> teType,
|
||||
Consumer<T> consumer) {
|
||||
public <T extends TileEntity> void modifyTileEntity(BlockPos position, Class<T> teType, Consumer<T> consumer) {
|
||||
addInstruction(scene -> {
|
||||
TileEntity tileEntity = scene.world.getTileEntity(position);
|
||||
if (teType.isInstance(tileEntity))
|
||||
|
@ -613,11 +654,8 @@ public class SceneBuilder {
|
|||
}, reDrawBlocks));
|
||||
}
|
||||
|
||||
public void flapFunnels(Selection selection, boolean outward) {
|
||||
addInstruction(new TileEntityDataInstruction(selection, FunnelTileEntity.class, nbt -> {
|
||||
nbt.putInt("Flap", outward ? -1 : 1);
|
||||
return nbt;
|
||||
}, false));
|
||||
public void flapFunnel(BlockPos position, boolean outward) {
|
||||
modifyTileEntity(position, FunnelTileEntity.class, funnel -> funnel.flap(!outward));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import com.simibubi.create.foundation.utility.Pointing;
|
|||
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -22,6 +21,9 @@ public class BearingScenes {
|
|||
|
||||
public static void windmillsAsSource(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("windmill_source", "Generating Rotational Force using Windmill Bearings");
|
||||
scene.configureBasePlate(1, 1, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
scene.world.showSection(util.select.fromTo(1, 0, 1, 5, 0, 5), Direction.UP);
|
||||
scene.world.setBlock(util.grid.at(2, -1, 0), AllBlocks.SAIL.getDefaultState()
|
||||
.with(SailBlock.FACING, Direction.NORTH), false);
|
||||
|
@ -102,7 +104,7 @@ public class BearingScenes {
|
|||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.topOf(windmill))
|
||||
.placeNearTarget()
|
||||
.text("Once Activated, the Windmill Bearing will start providing Rotational Force");
|
||||
.text("Activated with Right-Click, the Windmill Bearing will start providing Rotational Force");
|
||||
scene.idle(70);
|
||||
|
||||
scene.overlay.showText(60)
|
||||
|
@ -113,19 +115,14 @@ public class BearingScenes {
|
|||
scene.idle(90);
|
||||
|
||||
Vec3d surface = util.vector.blockSurface(windmill, Direction.WEST);
|
||||
AxisAlignedBB point = new AxisAlignedBB(surface, surface);
|
||||
AxisAlignedBB expanded = point.grow(1 / 16f, 1 / 4f, 1 / 4f);
|
||||
|
||||
scene.overlay.showControls(new InputWindowElement(surface, Pointing.DOWN).scroll()
|
||||
.withWrench(), 60);
|
||||
scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, point, point, 1);
|
||||
scene.idle(1);
|
||||
scene.overlay.chaseBoundingBoxOutline(PonderPalette.WHITE, point, expanded, 50);
|
||||
scene.overlay.showCenteredScrollInput(windmill, Direction.WEST, 50);
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(surface)
|
||||
.placeNearTarget()
|
||||
.text("Use a Wrench to configure its rotation direction");
|
||||
scene.idle(35);
|
||||
scene.idle(36);
|
||||
|
||||
scene.world.rotateBearing(windmill, -90 - 45, 75);
|
||||
scene.world.rotateSection(structure, 0, 0, -90 - 45, 75);
|
||||
|
@ -150,6 +147,8 @@ public class BearingScenes {
|
|||
|
||||
public static void windmillsAnyStructure(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("windmill_structure", "Windmill Contraptions");
|
||||
scene.configureBasePlate(1, 1, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
|
||||
|
@ -186,13 +185,380 @@ public class BearingScenes {
|
|||
new InputWindowElement(util.vector.blockSurface(bearingPos, Direction.WEST), Pointing.LEFT).rightClick(),
|
||||
40);
|
||||
scene.idle(7);
|
||||
scene.markAsFinished();
|
||||
scene.world.rotateBearing(bearingPos, -720, 400);
|
||||
scene.world.rotateSection(contraption, 0, -720, 0, 400);
|
||||
scene.world.modifyTileEntity(util.grid.at(2, 1, 5), HarvesterTileEntity.class,
|
||||
hte -> hte.setAnimatedSpeed(-150));
|
||||
scene.markAsFinished();
|
||||
scene.idle(400);
|
||||
scene.world.modifyTileEntity(util.grid.at(2, 1, 5), HarvesterTileEntity.class, hte -> hte.setAnimatedSpeed(0));
|
||||
}
|
||||
|
||||
public static void mechanicalBearing(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("mechanical_bearing", "Movings Structures using the Mechanical Bearing");
|
||||
scene.configureBasePlate(1, 1, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.layer(1), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSection(util.select.layer(2), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
Selection cog1 = util.select.position(6, 0, 4);
|
||||
Selection cog2 = util.select.position(5, 1, 4);
|
||||
Selection cog3 = util.select.position(4, 1, 3);
|
||||
Selection cog4 = util.select.position(3, 1, 3);
|
||||
Selection all = cog1.copy()
|
||||
.add(cog2)
|
||||
.add(cog3)
|
||||
.add(cog4);
|
||||
|
||||
BlockPos bearingPos = util.grid.at(3, 2, 3);
|
||||
scene.overlay.showSelectionWithText(util.select.position(bearingPos.up()), 60)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("Mechanical Bearings attach to the block in front of them");
|
||||
scene.idle(50);
|
||||
|
||||
ElementLink<WorldSectionElement> plank = scene.world.showIndependentSection(util.select.position(bearingPos.up()
|
||||
.east()
|
||||
.north()), Direction.DOWN);
|
||||
scene.world.moveSection(plank, util.vector.of(-1, 0, 1), 0);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.setKineticSpeed(cog1, -8);
|
||||
scene.world.setKineticSpeed(cog2, 8);
|
||||
scene.world.setKineticSpeed(cog3, -16);
|
||||
scene.world.setKineticSpeed(cog4, 16);
|
||||
scene.effects.rotationSpeedIndicator(bearingPos.down());
|
||||
scene.world.rotateBearing(bearingPos, 360, 37 * 2);
|
||||
scene.world.rotateSection(plank, 0, 360, 0, 37 * 2);
|
||||
|
||||
scene.overlay.showText(80)
|
||||
.pointAt(util.vector.topOf(bearingPos.up()))
|
||||
.placeNearTarget()
|
||||
.text("Upon receiving Rotational Force, it will assemble it into a Rotating Contraption");
|
||||
scene.idle(37 * 2);
|
||||
scene.world.setKineticSpeed(all, 0);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.hideIndependentSection(plank, Direction.UP);
|
||||
scene.idle(15);
|
||||
Selection plank2 = util.select.position(4, 3, 2);
|
||||
ElementLink<WorldSectionElement> contraption = scene.world.showIndependentSection(util.select.layersFrom(3)
|
||||
.substract(plank2), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSectionAndMerge(plank2, Direction.SOUTH, contraption);
|
||||
scene.idle(15);
|
||||
scene.effects.superGlue(util.grid.at(4, 3, 2), Direction.SOUTH, true);
|
||||
scene.idle(5);
|
||||
|
||||
scene.world.configureCenterOfRotation(contraption, util.vector.topOf(bearingPos));
|
||||
scene.world.setKineticSpeed(cog1, -8);
|
||||
scene.world.setKineticSpeed(cog2, 8);
|
||||
scene.world.setKineticSpeed(cog3, -16);
|
||||
scene.world.setKineticSpeed(cog4, 16);
|
||||
scene.effects.rotationSpeedIndicator(bearingPos.down());
|
||||
scene.world.rotateBearing(bearingPos, 360 * 2, 37 * 4);
|
||||
scene.world.rotateSection(contraption, 0, 360 * 2, 0, 37 * 4);
|
||||
|
||||
scene.overlay.showText(120)
|
||||
.pointAt(util.vector.topOf(bearingPos.up()))
|
||||
.placeNearTarget()
|
||||
.sharedText("movement_anchors");
|
||||
|
||||
scene.idle(37 * 4);
|
||||
scene.world.setKineticSpeed(all, 0);
|
||||
}
|
||||
|
||||
public static void bearingModes(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("bearing_modes", "Movement Modes of the Mechanical Bearing");
|
||||
scene.configureBasePlate(1, 1, 6);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
Selection sideCog = util.select.position(util.grid.at(7, 0, 3));
|
||||
Selection cogColumn = util.select.fromTo(6, 1, 3, 6, 4, 3);
|
||||
Selection cogAndClutch = util.select.fromTo(5, 3, 1, 5, 4, 2);
|
||||
BlockPos leverPos = util.grid.at(5, 3, 1);
|
||||
|
||||
scene.world.setKineticSpeed(sideCog, 4);
|
||||
scene.world.setKineticSpeed(cogColumn, -4);
|
||||
scene.world.setKineticSpeed(cogAndClutch, 8);
|
||||
scene.world.toggleRedstonePower(cogAndClutch);
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(cogColumn, Direction.DOWN);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(cogAndClutch, Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
BlockPos bearingPos = util.grid.at(5, 2, 2);
|
||||
scene.world.showSection(util.select.position(bearingPos), Direction.UP);
|
||||
scene.idle(10);
|
||||
|
||||
ElementLink<WorldSectionElement> contraption =
|
||||
scene.world.showIndependentSection(util.select.fromTo(5, 1, 2, 2, 1, 2), Direction.EAST);
|
||||
scene.world.configureCenterOfRotation(contraption, util.vector.centerOf(bearingPos));
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.toggleRedstonePower(cogAndClutch);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.rotateSection(contraption, 0, 55, 0, 23);
|
||||
scene.world.rotateBearing(bearingPos, 55, 23);
|
||||
scene.idle(24);
|
||||
|
||||
scene.world.toggleRedstonePower(cogAndClutch);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.rotateSection(contraption, 0, 35, 0, 0);
|
||||
scene.world.rotateBearing(bearingPos, 35, 0);
|
||||
|
||||
Vec3d target = util.vector.topOf(bearingPos.down());
|
||||
scene.overlay.showLine(PonderPalette.RED, target.add(-2.5, 0, 3.5), target, 50);
|
||||
scene.overlay.showLine(PonderPalette.GREEN, target.add(0, 0, 4.5), target, 50);
|
||||
|
||||
scene.idle(50);
|
||||
|
||||
scene.overlay.showText(100)
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.colored(PonderPalette.RED)
|
||||
.text("When Stopped, the Bearing will place the structure at the nearest grid-aligned Angle");
|
||||
scene.idle(110);
|
||||
|
||||
scene.overlay.showCenteredScrollInput(bearingPos, Direction.NORTH, 60);
|
||||
scene.overlay.showControls(
|
||||
new InputWindowElement(util.vector.blockSurface(bearingPos, Direction.NORTH), Pointing.DOWN).scroll()
|
||||
.withWrench(),
|
||||
60);
|
||||
scene.idle(10);
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.sharedText("behaviour_modify_wrench");
|
||||
scene.idle(70);
|
||||
|
||||
scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f);
|
||||
scene.world.toggleRedstonePower(cogAndClutch);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.rotateSection(contraption, 0, -55, 0, 23);
|
||||
scene.world.rotateBearing(bearingPos, -55, 23);
|
||||
scene.idle(24);
|
||||
|
||||
scene.world.toggleRedstonePower(cogAndClutch);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.idle(40);
|
||||
|
||||
scene.overlay.showText(120)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.pointAt(util.vector.blockSurface(util.grid.at(3, 1, 3), Direction.UP))
|
||||
.text("It can be configured never to revert to solid blocks, or only near the angle it started at");
|
||||
|
||||
}
|
||||
|
||||
public static void stabilizedBearings(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("stabilized_bearings", "Stabilized Contraptions");
|
||||
scene.configureBasePlate(1, 1, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
Selection beltAndBearing = util.select.fromTo(3, 3, 4, 3, 1, 6);
|
||||
Selection largeCog = util.select.position(2, 0, 6);
|
||||
BlockPos parentBearingPos = util.grid.at(3, 3, 4);
|
||||
BlockPos bearingPos = util.grid.at(3, 4, 2);
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(beltAndBearing, Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
ElementLink<WorldSectionElement> contraption =
|
||||
scene.world.showIndependentSection(util.select.fromTo(3, 3, 3, 3, 4, 3), Direction.SOUTH);
|
||||
scene.world.configureCenterOfRotation(contraption, util.vector.centerOf(parentBearingPos));
|
||||
scene.idle(20);
|
||||
scene.world.glueBlockOnto(bearingPos, Direction.SOUTH, contraption);
|
||||
|
||||
scene.idle(15);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.position(bearingPos), 60)
|
||||
.text("Whenever Mechanical Bearings are themselves part of a moving Structure..")
|
||||
.placeNearTarget();
|
||||
scene.idle(70);
|
||||
|
||||
scene.world.setKineticSpeed(largeCog, -8);
|
||||
scene.world.setKineticSpeed(beltAndBearing, 16);
|
||||
scene.world.rotateBearing(parentBearingPos, 360, 74);
|
||||
scene.world.rotateSection(contraption, 0, 0, 360, 74);
|
||||
scene.world.rotateBearing(bearingPos, -360, 74);
|
||||
scene.idle(74);
|
||||
|
||||
scene.world.setKineticSpeed(largeCog, 0);
|
||||
scene.world.setKineticSpeed(beltAndBearing, 0);
|
||||
scene.overlay.showText(60)
|
||||
.text("..they will attempt to keep themselves upright")
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.NORTH))
|
||||
.placeNearTarget();
|
||||
scene.idle(70);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.position(bearingPos.north()), 60)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.text("Once again, the bearing will attach to the block in front of it")
|
||||
.placeNearTarget();
|
||||
scene.idle(70);
|
||||
|
||||
ElementLink<WorldSectionElement> subContraption =
|
||||
scene.world.showIndependentSection(util.select.fromTo(4, 4, 1, 2, 4, 1), Direction.SOUTH);
|
||||
scene.world.configureCenterOfRotation(subContraption, util.vector.centerOf(parentBearingPos));
|
||||
scene.world.configureStabilization(subContraption, util.vector.centerOf(bearingPos));
|
||||
scene.idle(20);
|
||||
|
||||
scene.overlay.showText(80)
|
||||
.text("As a result, the entire sub-Contraption will stay upright");
|
||||
|
||||
scene.world.setKineticSpeed(largeCog, -8);
|
||||
scene.world.setKineticSpeed(beltAndBearing, 16);
|
||||
scene.world.rotateBearing(parentBearingPos, 360 * 2, 74 * 2);
|
||||
scene.world.rotateSection(contraption, 0, 0, 360 * 2, 74 * 2);
|
||||
scene.world.rotateBearing(bearingPos, -360 * 2, 74 * 2);
|
||||
scene.world.rotateSection(subContraption, 0, 0, 360 * 2, 74 * 2);
|
||||
|
||||
scene.markAsFinished();
|
||||
scene.idle(74 * 2);
|
||||
scene.world.setKineticSpeed(largeCog, 0);
|
||||
scene.world.setKineticSpeed(beltAndBearing, 0);
|
||||
}
|
||||
|
||||
public static void clockwork(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("clockwork_bearing", "Animating Structures using Clockwork Bearings");
|
||||
|
||||
Selection kinetics = util.select.fromTo(3, 3, 4, 3, 1, 6);
|
||||
Selection largeCog = util.select.position(2, 0, 6);
|
||||
BlockPos bearingPos = util.grid.at(3, 3, 3);
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(kinetics, Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSection(util.select.position(bearingPos), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.position(bearingPos.north()), 60)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("Clockwork Bearings attach to blocks in front of them");
|
||||
scene.idle(50);
|
||||
|
||||
ElementLink<WorldSectionElement> plank =
|
||||
scene.world.showIndependentSection(util.select.position(2, 3, 2), Direction.SOUTH);
|
||||
scene.world.moveSection(plank, util.vector.of(1, 0, 0), 0);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.rotateSection(plank, 0, 0, 60, 25);
|
||||
scene.world.rotateBearing(bearingPos, 60, 25);
|
||||
scene.world.setKineticSpeed(kinetics, 8);
|
||||
scene.world.setKineticSpeed(largeCog, -4);
|
||||
|
||||
scene.idle(25);
|
||||
scene.overlay.showText(80)
|
||||
.pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH))
|
||||
.placeNearTarget()
|
||||
.text("Upon receiving Rotational Force, the structure will be rotated according to the hour of the day");
|
||||
scene.idle(90);
|
||||
|
||||
scene.overlay.showText(30)
|
||||
.pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH))
|
||||
.placeNearTarget()
|
||||
.text("3:00");
|
||||
scene.world.rotateSection(plank, 0, 0, 30, 12);
|
||||
scene.world.rotateBearing(bearingPos, 30, 12);
|
||||
scene.idle(42);
|
||||
scene.overlay.showText(30)
|
||||
.pointAt(util.vector.blockSurface(bearingPos.north(), Direction.NORTH))
|
||||
.placeNearTarget()
|
||||
.text("4:00");
|
||||
scene.world.rotateSection(plank, 0, 0, 30, 12);
|
||||
scene.world.rotateBearing(bearingPos, 30, 12);
|
||||
scene.idle(42);
|
||||
|
||||
InputWindowElement clickTheBearing = new InputWindowElement(util.vector.topOf(bearingPos), Pointing.DOWN);
|
||||
InputWindowElement clickTheBearingSide =
|
||||
new InputWindowElement(util.vector.blockSurface(bearingPos, Direction.WEST), Pointing.LEFT);
|
||||
|
||||
scene.overlay.showControls(clickTheBearing.rightClick(), 60);
|
||||
scene.idle(7);
|
||||
scene.world.rotateSection(plank, 0, 0, -120, 0);
|
||||
scene.world.rotateBearing(bearingPos, -120, 0);
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.blockSurface(bearingPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("Right-Click the bearing to start or stop animating the structure");
|
||||
scene.idle(70);
|
||||
|
||||
scene.world.hideIndependentSection(plank, Direction.NORTH);
|
||||
scene.idle(15);
|
||||
|
||||
ElementLink<WorldSectionElement> hourHand =
|
||||
scene.world.showIndependentSection(util.select.fromTo(3, 3, 1, 3, 5, 2), Direction.SOUTH);
|
||||
scene.world.configureCenterOfRotation(hourHand, util.vector.centerOf(bearingPos));
|
||||
scene.idle(15);
|
||||
scene.overlay.showSelectionWithText(util.select.fromTo(3, 3, 1, 3, 4, 2), 80)
|
||||
.placeNearTarget()
|
||||
.sharedText("movement_anchors");
|
||||
scene.idle(90);
|
||||
|
||||
scene.overlay.showControls(clickTheBearingSide.rightClick(), 20);
|
||||
scene.idle(7);
|
||||
scene.world.rotateSection(hourHand, 0, 0, 120, 50);
|
||||
scene.world.rotateBearing(bearingPos, 120, 50);
|
||||
scene.idle(60);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.position(bearingPos.north(3)), 80)
|
||||
.placeNearTarget()
|
||||
.colored(PonderPalette.BLUE)
|
||||
.text("In front of the Hour Hand, a second structure can be added");
|
||||
scene.idle(90);
|
||||
scene.overlay.showControls(clickTheBearingSide.rightClick(), 20);
|
||||
scene.idle(7);
|
||||
scene.world.rotateSection(hourHand, 0, 0, -120, 0);
|
||||
scene.world.rotateBearing(bearingPos, -120, 0);
|
||||
scene.idle(10);
|
||||
|
||||
ElementLink<WorldSectionElement> minuteHand =
|
||||
scene.world.showIndependentSection(util.select.fromTo(3, 3, 0, 3, 6, 0), Direction.SOUTH);
|
||||
scene.world.configureCenterOfRotation(minuteHand, util.vector.centerOf(bearingPos));
|
||||
scene.idle(30);
|
||||
|
||||
scene.overlay.showOutline(PonderPalette.BLUE, minuteHand, util.select.fromTo(3, 3, 0, 3, 6, 0), 85);
|
||||
scene.overlay.showSelectionWithText(util.select.fromTo(3, 3, 1, 3, 4, 2), 80)
|
||||
.placeNearTarget()
|
||||
.colored(PonderPalette.GREEN)
|
||||
.text("Ensure the two Structures are not attached to each other through super glue or similar");
|
||||
scene.idle(90);
|
||||
|
||||
scene.overlay.showControls(clickTheBearingSide.rightClick(), 20);
|
||||
scene.idle(7);
|
||||
|
||||
scene.world.rotateSection(hourHand, 0, 0, 120, 50);
|
||||
scene.world.rotateSection(minuteHand, 0, 0, 180, 75);
|
||||
scene.world.rotateBearing(bearingPos, 120, 50);
|
||||
scene.idle(90);
|
||||
scene.world.rotateSection(minuteHand, 0, 0, 6, 3);
|
||||
|
||||
scene.overlay.showText(80)
|
||||
.placeNearTarget()
|
||||
.pointAt(util.vector.blockSurface(bearingPos.north(3), Direction.NORTH))
|
||||
.colored(PonderPalette.GREEN)
|
||||
.text("The Second Structure will now rotate as the Minute Hand");
|
||||
scene.markAsFinished();
|
||||
|
||||
for (int i = 0; i < 40; i++) {
|
||||
scene.idle(23);
|
||||
scene.world.rotateSection(minuteHand, 0, 0, 6, 3);
|
||||
if (i == 29)
|
||||
scene.world.rotateSection(hourHand, 0, 0, 30, 20);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -161,6 +161,7 @@ public class BeltScenes {
|
|||
public static void directions(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("belt_directions", "Valid Orientations for Mechanical Belts");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.showBasePlate();
|
||||
scene.idle(5);
|
||||
|
||||
|
@ -305,6 +306,7 @@ public class BeltScenes {
|
|||
public static void transport(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("belt_transport", "Using Mechanical Belts for Logistics");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -.6f * f);
|
||||
scene.showBasePlate();
|
||||
scene.idle(5);
|
||||
|
@ -379,6 +381,7 @@ public class BeltScenes {
|
|||
public static void beltsCanBeEncased(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("belt_casing", "Encasing Belts");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.showBasePlate();
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.layersFrom(1), Direction.DOWN);
|
||||
|
|
|
@ -92,7 +92,8 @@ public class ChainDriveScenes {
|
|||
|
||||
public static void adjustableChainGearshift(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("chain_gearshift", "Controlling rotational speed with Chain Gearshifts");
|
||||
scene.configureBasePlate(0, 0, 7);
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
|
||||
BlockPos leverPos = util.grid.at(3, 1, 0);
|
||||
|
|
|
@ -52,12 +52,11 @@ public class FunnelScenes {
|
|||
BlockPos entryBeltPos = util.grid.at(3, 1, 2);
|
||||
BlockPos exitBeltPos = util.grid.at(1, 1, 2);
|
||||
ItemStack itemStack = AllBlocks.BRASS_BLOCK.asStack();
|
||||
Selection exitFunnel = util.select.position(exitBeltPos.up());
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
scene.idle(8);
|
||||
scene.world.removeItemsFromBelt(exitBeltPos);
|
||||
scene.world.flapFunnels(exitFunnel, false);
|
||||
scene.world.flapFunnel(exitBeltPos.up(), false);
|
||||
if (i == 2)
|
||||
scene.rotateCameraY(70);
|
||||
if (i < 6)
|
||||
|
@ -94,7 +93,7 @@ public class FunnelScenes {
|
|||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
scene.idle(8);
|
||||
scene.world.flapFunnels(outputFunnel, false);
|
||||
scene.world.flapFunnel(util.grid.at(1, 2, 4), false);
|
||||
scene.world.createItemEntity(sideItemSpawn, util.vector.of(-.05, 0, 0), itemStack);
|
||||
}
|
||||
|
||||
|
@ -198,7 +197,7 @@ public class FunnelScenes {
|
|||
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.flapFunnels(sideFunnelSelection, true);
|
||||
scene.world.flapFunnel(sideFunnel, true);
|
||||
itemLink = scene.world.createItemEntity(sideCenter.subtract(0, .45, 0), util.vector.of(0, 0, -0.1), itemStack);
|
||||
scene.idle(60);
|
||||
scene.world.hideSection(sideFunnelSelection, Direction.UP);
|
||||
|
@ -233,7 +232,7 @@ public class FunnelScenes {
|
|||
scene.idle(35);
|
||||
|
||||
scene.world.removeItemsFromBelt(beltPos);
|
||||
scene.world.flapFunnels(beltFunnelSetup, false);
|
||||
scene.world.flapFunnel(util.grid.at(2, 2, 2), false);
|
||||
|
||||
if (i == 0) {
|
||||
scene.idle(50);
|
||||
|
@ -374,7 +373,7 @@ public class FunnelScenes {
|
|||
scene.idle(10);
|
||||
scene.world.createItemOnBeltLike(andesiteFunnel.down()
|
||||
.north(), Direction.SOUTH, itemStack);
|
||||
scene.world.flapFunnels(util.select.position(andesiteFunnel), true);
|
||||
scene.world.flapFunnel(andesiteFunnel, true);
|
||||
scene.idle(60);
|
||||
|
||||
scene.overlay.showText(60)
|
||||
|
@ -384,7 +383,7 @@ public class FunnelScenes {
|
|||
scene.idle(10);
|
||||
scene.world.createItemOnBeltLike(brassFunnel.down()
|
||||
.north(), Direction.SOUTH, ItemHandlerHelper.copyStackWithSize(itemStack, 64));
|
||||
scene.world.flapFunnels(util.select.position(brassFunnel), true);
|
||||
scene.world.flapFunnel(brassFunnel, true);
|
||||
scene.idle(60);
|
||||
|
||||
AxisAlignedBB filterSlot = new AxisAlignedBB(brassFunnel).grow(-.35, -.35, -.35)
|
||||
|
@ -421,7 +420,7 @@ public class FunnelScenes {
|
|||
|
||||
if (i > 0 && (i < 3 || i % 3 == 0)) {
|
||||
scene.world.removeItemsFromBelt(brassFunnel.down());
|
||||
scene.world.flapFunnels(util.select.position(brassFunnel), false);
|
||||
scene.world.flapFunnel(brassFunnel, false);
|
||||
}
|
||||
|
||||
scene.world.modifyEntities(ItemEntity.class, e -> {
|
||||
|
|
|
@ -241,6 +241,7 @@ public class GantryScenes {
|
|||
public static void subgantry(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("gantry_cascaded", "Cascaded Gantries");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -2 * f);
|
||||
scene.world.showSection(util.select.layer(0)
|
||||
.add(util.select.column(5, 3))
|
||||
|
|
|
@ -279,6 +279,8 @@ public class KineticsScenes {
|
|||
public static void gearbox(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("gearbox", "Relaying rotational force using Gearboxes");
|
||||
scene.configureBasePlate(1, 1, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.world.showSection(util.select.fromTo(4, 1, 6, 3, 2, 5), Direction.UP);
|
||||
scene.idle(10);
|
||||
|
|
|
@ -22,7 +22,9 @@ public class MovementActorScenes {
|
|||
|
||||
public static void psiTransfer(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("portable_storage_interface", "Contraption Storage Exchange");
|
||||
scene.configureBasePlate(0, 0, 8);
|
||||
scene.configureBasePlate(0, 0, 6);
|
||||
scene.scaleSceneView(0.95f);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
|
||||
|
@ -112,7 +114,7 @@ public class MovementActorScenes {
|
|||
scene.world.modifyEntity(entity2, Entity::remove);
|
||||
|
||||
scene.overlay
|
||||
.showControls(new InputWindowElement(util.vector.topOf(6, 3, 2), Pointing.DOWN).withItem(itemStack), 40);
|
||||
.showControls(new InputWindowElement(util.vector.topOf(5, 3, 2), Pointing.DOWN).withItem(itemStack), 40);
|
||||
|
||||
scene.idle(30);
|
||||
scene.world.hideSection(util.select.position(hopper), Direction.UP);
|
||||
|
@ -148,7 +150,8 @@ public class MovementActorScenes {
|
|||
|
||||
public static void psiRedstone(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("portable_storage_interface_redstone", "Redstone Control");
|
||||
scene.configureBasePlate(0, 0, 6);
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
Class<PortableItemInterfaceTileEntity> psiClass = PortableItemInterfaceTileEntity.class;
|
||||
Selection psis = util.select.fromTo(1, 1, 3, 1, 3, 3);
|
||||
|
|
|
@ -0,0 +1,279 @@
|
|||
package com.simibubi.create.foundation.ponder.content;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonHeadBlock;
|
||||
import com.simibubi.create.foundation.ponder.ElementLink;
|
||||
import com.simibubi.create.foundation.ponder.SceneBuilder;
|
||||
import com.simibubi.create.foundation.ponder.SceneBuildingUtil;
|
||||
import com.simibubi.create.foundation.ponder.Selection;
|
||||
import com.simibubi.create.foundation.ponder.elements.InputWindowElement;
|
||||
import com.simibubi.create.foundation.ponder.elements.ParrotElement;
|
||||
import com.simibubi.create.foundation.ponder.elements.ParrotElement.FaceCursorPose;
|
||||
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
|
||||
import com.simibubi.create.foundation.utility.Pointing;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.DoublePlantBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.state.properties.DoubleBlockHalf;
|
||||
import net.minecraft.state.properties.PistonType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class PistonScenes {
|
||||
|
||||
public static void movement(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("mechanical_piston", "Moving Structures using Mechanical Pistons");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.world.showSection(util.select.layer(0)
|
||||
.add(util.select.position(0, 1, 2)), Direction.UP);
|
||||
|
||||
Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2);
|
||||
BlockPos piston = util.grid.at(3, 1, 2);
|
||||
BlockPos leverPos = util.grid.at(3, 2, 4);
|
||||
BlockPos shaft = util.grid.at(3, 1, 3);
|
||||
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSection(util.select.position(piston), Direction.DOWN);
|
||||
ElementLink<WorldSectionElement> contraption =
|
||||
scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN);
|
||||
scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0);
|
||||
scene.idle(20);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east()), Direction.DOWN, contraption);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east(2)), Direction.DOWN, contraption);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.west()), Direction.DOWN, contraption);
|
||||
scene.idle(15);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
scene.overlay.showText(55)
|
||||
.pointAt(util.vector.topOf(piston))
|
||||
.placeNearTarget()
|
||||
.text("Mechanical Pistons can move blocks in front of them");
|
||||
scene.idle(65);
|
||||
|
||||
scene.overlay.showText(45)
|
||||
.pointAt(util.vector.blockSurface(shaft, Direction.SOUTH))
|
||||
.placeNearTarget()
|
||||
.text("Speed and direction of movement depend on the Rotational Input");
|
||||
scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.AIR.getDefaultState(), false);
|
||||
scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.OAK_PLANKS.getDefaultState(), false);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40);
|
||||
scene.idle(60);
|
||||
|
||||
scene.overlay.showControls(
|
||||
new InputWindowElement(util.vector.blockSurface(piston, Direction.WEST), Pointing.DOWN).rightClick()
|
||||
.withItem(new ItemStack(Items.SLIME_BALL)),
|
||||
30);
|
||||
scene.idle(7);
|
||||
scene.world.modifyBlock(piston.north(), s -> s.with(MechanicalPistonHeadBlock.TYPE, PistonType.STICKY), false);
|
||||
scene.effects.superGlue(piston, Direction.WEST, true);
|
||||
|
||||
scene.idle(33);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
|
||||
scene.idle(25);
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.topOf(piston))
|
||||
.placeNearTarget()
|
||||
.text("Sticky Mechanical Pistons can pull the attached blocks back");
|
||||
scene.idle(20);
|
||||
scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.OAK_PLANKS.getDefaultState(), false);
|
||||
scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.AIR.getDefaultState(), false);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40);
|
||||
|
||||
scene.idle(50);
|
||||
scene.world.setBlock(util.grid.at(2, 1, 1), Blocks.AIR.getDefaultState(), false);
|
||||
ElementLink<WorldSectionElement> chassis =
|
||||
scene.world.showIndependentSection(util.select.fromTo(2, 2, 0, 2, 3, 2), Direction.DOWN);
|
||||
scene.world.moveSection(chassis, util.vector.of(0, -1, 1), 0);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(1, 2, 0), Direction.EAST, chassis);
|
||||
scene.idle(15);
|
||||
scene.effects.superGlue(piston.west()
|
||||
.north(), Direction.WEST, true);
|
||||
scene.overlay.showText(80)
|
||||
.pointAt(util.vector.topOf(piston.west()))
|
||||
.placeNearTarget()
|
||||
.sharedText("movement_anchors");
|
||||
|
||||
scene.idle(90);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
scene.world.moveSection(chassis, util.vector.of(-2, 0, 0), 40);
|
||||
}
|
||||
|
||||
public static void poles(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("piston_pole", "Piston Extension Poles");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.world.modifyKineticSpeed(util.select.everywhere(), f -> -f);
|
||||
|
||||
Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2);
|
||||
BlockPos piston = util.grid.at(3, 1, 2);
|
||||
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSection(util.select.position(piston), Direction.DOWN);
|
||||
ElementLink<WorldSectionElement> contraption =
|
||||
scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN);
|
||||
scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0);
|
||||
scene.idle(20);
|
||||
|
||||
BlockPos leverPos = util.grid.at(3, 2, 4);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.setKineticSpeed(kinetics, 16);
|
||||
scene.idle(10);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.position(piston), 50)
|
||||
.colored(PonderPalette.RED)
|
||||
.placeNearTarget()
|
||||
.text("Without attached Poles, a Mechanical Piston cannot move");
|
||||
scene.idle(60);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.setKineticSpeed(kinetics, 0);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east()), Direction.DOWN, contraption);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east(2)), Direction.DOWN, contraption);
|
||||
scene.idle(10);
|
||||
|
||||
scene.overlay.showOutline(PonderPalette.RED, new Object(), util.select.fromTo(piston.east(), piston.east(2)),
|
||||
100);
|
||||
scene.overlay.showSelectionWithText(util.select.fromTo(piston.west(), piston.west(2)), 100)
|
||||
.text("The Length of pole added at its back determines the Extension Range")
|
||||
.placeNearTarget()
|
||||
.colored(PonderPalette.GREEN);
|
||||
scene.idle(110);
|
||||
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.west()), Direction.EAST, contraption);
|
||||
scene.idle(10);
|
||||
ElementLink<ParrotElement> birb =
|
||||
scene.special.createBirb(util.vector.topOf(piston.west()), FaceCursorPose::new);
|
||||
scene.idle(15);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.setKineticSpeed(kinetics, 16);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
scene.special.moveParrot(birb, util.vector.of(-2, 0, 0), 40);
|
||||
|
||||
}
|
||||
|
||||
public static void movementModes(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("mechanical_piston_modes", "Movement Modes of the Mechanical Piston");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
Selection rose = util.select.fromTo(0, 2, 2, 0, 1, 2);
|
||||
scene.world.showSection(util.select.layer(0)
|
||||
.add(rose), Direction.UP);
|
||||
|
||||
Selection kinetics = util.select.fromTo(3, 1, 3, 3, 1, 2);
|
||||
BlockPos piston = util.grid.at(3, 1, 2);
|
||||
BlockPos leverPos = util.grid.at(3, 2, 4);
|
||||
BlockPos shaft = util.grid.at(3, 1, 3);
|
||||
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.fromTo(3, 1, 3, 3, 2, 5), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
scene.world.showSection(util.select.position(piston), Direction.DOWN);
|
||||
ElementLink<WorldSectionElement> contraption =
|
||||
scene.world.showIndependentSection(util.select.position(3, 1, 1), Direction.DOWN);
|
||||
scene.world.moveSection(contraption, util.vector.of(0, 0, 1), 0);
|
||||
scene.idle(20);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east()), Direction.DOWN, contraption);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.east(2)), Direction.DOWN, contraption);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.west()), Direction.DOWN, contraption);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(piston.north()
|
||||
.west()
|
||||
.up()), Direction.DOWN, contraption);
|
||||
scene.idle(15);
|
||||
scene.effects.superGlue(piston.west(), Direction.UP, true);
|
||||
scene.idle(10);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
scene.idle(40);
|
||||
|
||||
scene.world.destroyBlock(util.grid.at(0, 1, 2));
|
||||
scene.world.destroyBlock(util.grid.at(0, 2, 2));
|
||||
scene.idle(10);
|
||||
scene.overlay.showSelectionWithText(rose, 70)
|
||||
.text("Whenever Pistons stop moving, the moved structure reverts to blocks")
|
||||
.colored(PonderPalette.RED);
|
||||
scene.idle(80);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(2, 0, 0), 40);
|
||||
scene.world.hideSection(rose, Direction.UP);
|
||||
scene.idle(50);
|
||||
|
||||
scene.world.setBlock(util.grid.at(0, 1, 2), Blocks.ROSE_BUSH.getDefaultState(), false);
|
||||
scene.world.setBlock(util.grid.at(0, 2, 2), Blocks.ROSE_BUSH.getDefaultState()
|
||||
.with(DoublePlantBlock.HALF, DoubleBlockHalf.UPPER), false);
|
||||
scene.world.showIndependentSection(rose, Direction.DOWN);
|
||||
scene.overlay.showCenteredScrollInput(piston, Direction.UP, 60);
|
||||
scene.overlay.showControls(new InputWindowElement(util.vector.topOf(piston), Pointing.DOWN).scroll()
|
||||
.withWrench(), 60);
|
||||
scene.overlay.showText(70)
|
||||
.pointAt(util.vector.topOf(piston))
|
||||
.placeNearTarget()
|
||||
.sharedText("behaviour_modify_wrench");
|
||||
scene.idle(80);
|
||||
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.toggleRedstonePower(util.select.fromTo(leverPos, leverPos.down()));
|
||||
scene.world.modifyKineticSpeed(kinetics, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(shaft);
|
||||
scene.world.moveSection(contraption, util.vector.of(-2, 0, 0), 40);
|
||||
scene.idle(50);
|
||||
scene.overlay.showText(120)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.pointAt(util.vector.blockSurface(util.grid.at(0, 1, 2), Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("It can be configured never to revert to solid blocks, or only at the location it started at");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -77,12 +77,42 @@ public class PonderIndex {
|
|||
.addStoryBoard("funnels/transposer", FunnelScenes::transposer);
|
||||
PonderRegistry.addStoryBoard(AllBlocks.ANDESITE_FUNNEL, "funnels/brass", FunnelScenes::brass);
|
||||
|
||||
// Mechanical Piston
|
||||
PonderRegistry.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON)
|
||||
.addStoryBoard("mechanical_piston/anchor", PistonScenes::movement, PonderTag.KINETIC_APPLIANCES,
|
||||
PonderTag.MOVEMENT_ANCHOR);
|
||||
PonderRegistry
|
||||
.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON,
|
||||
AllBlocks.PISTON_EXTENSION_POLE)
|
||||
.addStoryBoard("mechanical_piston/piston_pole", PistonScenes::poles);
|
||||
PonderRegistry.forComponents(AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON)
|
||||
.addStoryBoard("mechanical_piston/modes", PistonScenes::movementModes);
|
||||
|
||||
// Windmill Bearing
|
||||
PonderRegistry.forComponents(AllBlocks.ROPE_PULLEY)
|
||||
.addStoryBoard("rope_pulley/anchor", PulleyScenes::movement, PonderTag.KINETIC_APPLIANCES,
|
||||
PonderTag.MOVEMENT_ANCHOR)
|
||||
.addStoryBoard("rope_pulley/modes", PulleyScenes::movementModes)
|
||||
.addStoryBoard("rope_pulley/attachment", PulleyScenes::attachment);
|
||||
|
||||
// Windmill Bearing
|
||||
PonderRegistry.forComponents(AllBlocks.WINDMILL_BEARING)
|
||||
.addStoryBoard("windmill_bearing/source", BearingScenes::windmillsAsSource, PonderTag.KINETIC_SOURCES)
|
||||
.addStoryBoard("windmill_bearing/structure", BearingScenes::windmillsAnyStructure,
|
||||
PonderTag.MOVEMENT_ANCHOR);
|
||||
|
||||
// Mechanical Bearing
|
||||
PonderRegistry.forComponents(AllBlocks.MECHANICAL_BEARING)
|
||||
.addStoryBoard("mechanical_bearing/anchor", BearingScenes::mechanicalBearing, PonderTag.KINETIC_APPLIANCES,
|
||||
PonderTag.MOVEMENT_ANCHOR)
|
||||
.addStoryBoard("mechanical_bearing/modes", BearingScenes::bearingModes)
|
||||
.addStoryBoard("mechanical_bearing/stabilized", BearingScenes::stabilizedBearings,
|
||||
PonderTag.CONTRAPTION_ACTOR);
|
||||
|
||||
// Clockwork Bearing
|
||||
PonderRegistry.addStoryBoard(AllBlocks.CLOCKWORK_BEARING, "clockwork_bearing", BearingScenes::clockwork,
|
||||
PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR);
|
||||
|
||||
// Gantries
|
||||
PonderRegistry.addStoryBoard(AllBlocks.GANTRY_SHAFT, "gantry/intro", GantryScenes::introForShaft,
|
||||
PonderTag.KINETIC_APPLIANCES, PonderTag.MOVEMENT_ANCHOR);
|
||||
|
|
|
@ -49,43 +49,39 @@ public class PonderIndexScreen extends AbstractSimiScreen {
|
|||
protected void init() {
|
||||
super.init();
|
||||
|
||||
//populate lists
|
||||
// populate lists
|
||||
widgets.clear();
|
||||
|
||||
chapters.clear();
|
||||
//chapters.addAll(PonderRegistry.chapters.getAllChapters());
|
||||
// chapters.addAll(PonderRegistry.chapters.getAllChapters());
|
||||
|
||||
items.clear();
|
||||
PonderRegistry.all.keySet()
|
||||
.stream()
|
||||
.map(key -> {
|
||||
Item item = ForgeRegistries.ITEMS.getValue(key);
|
||||
if (item == null) {
|
||||
Block b = ForgeRegistries.BLOCKS.getValue(key);
|
||||
if (b != null)
|
||||
item = b.asItem();
|
||||
}
|
||||
return item;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.filter(PonderIndexScreen::exclusions)
|
||||
.forEach(items::add);
|
||||
.stream()
|
||||
.map(key -> {
|
||||
Item item = ForgeRegistries.ITEMS.getValue(key);
|
||||
if (item == null) {
|
||||
Block b = ForgeRegistries.BLOCKS.getValue(key);
|
||||
if (b != null)
|
||||
item = b.asItem();
|
||||
}
|
||||
return item;
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.filter(PonderIndexScreen::exclusions)
|
||||
.forEach(items::add);
|
||||
|
||||
boolean hasChapters = !chapters.isEmpty();
|
||||
|
||||
//setup chapters
|
||||
LayoutHelper layout = LayoutHelper.centeredHorizontal(
|
||||
chapters.size(),
|
||||
MathHelper.clamp((int) Math.ceil(chapters.size() / 4f), 1, 4),
|
||||
200,
|
||||
38,
|
||||
16
|
||||
);
|
||||
// setup chapters
|
||||
LayoutHelper layout = LayoutHelper.centeredHorizontal(chapters.size(),
|
||||
MathHelper.clamp((int) Math.ceil(chapters.size() / 4f), 1, 4), 200, 38, 16);
|
||||
chapterArea = layout.getArea();
|
||||
int chapterCenterX = (int) (width * chapterXmult);
|
||||
int chapterCenterY = (int) (height * chapterYmult);
|
||||
|
||||
//todo at some point pagination or horizontal scrolling may be needed for chapters/items
|
||||
// todo at some point pagination or horizontal scrolling may be needed for
|
||||
// chapters/items
|
||||
for (PonderChapter chapter : chapters) {
|
||||
ChapterLabel label = new ChapterLabel(chapter, chapterCenterX + layout.getX(),
|
||||
chapterCenterY + layout.getY(), (mouseX, mouseY) -> {
|
||||
|
@ -97,44 +93,40 @@ public class PonderIndexScreen extends AbstractSimiScreen {
|
|||
layout.next();
|
||||
}
|
||||
|
||||
//setup items
|
||||
// setup items
|
||||
if (!hasChapters) {
|
||||
itemYmult = 0.5;
|
||||
}
|
||||
|
||||
int maxItemRows = hasChapters ? 4 : 7;
|
||||
layout = LayoutHelper.centeredHorizontal(
|
||||
items.size(),
|
||||
MathHelper.clamp((int) Math.ceil(items.size() / 11f), 1, maxItemRows),
|
||||
28,
|
||||
28,
|
||||
8
|
||||
);
|
||||
layout = LayoutHelper.centeredHorizontal(items.size(),
|
||||
MathHelper.clamp((int) Math.ceil(items.size() / 11f), 1, maxItemRows), 28, 28, 8);
|
||||
itemArea = layout.getArea();
|
||||
int itemCenterX = (int) (width * itemXmult);
|
||||
int itemCenterY = (int) (height * itemYmult);
|
||||
|
||||
for (Item item : items) {
|
||||
PonderButton button = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (x, y) -> {
|
||||
if (!PonderRegistry.all.containsKey(item.getRegistryName()))
|
||||
return;
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (x, y) -> {
|
||||
if (!PonderRegistry.all.containsKey(item.getRegistryName()))
|
||||
return;
|
||||
|
||||
centerScalingOn(x, y);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item)));
|
||||
}).showing(new ItemStack(item));
|
||||
centerScalingOn(x, y);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item)));
|
||||
}).showing(new ItemStack(item));
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
layout.next();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static boolean exclusions(Item item) {
|
||||
if (item instanceof BlockItem) {
|
||||
Block block = ((BlockItem) item).getBlock();
|
||||
if (block instanceof ValveHandleBlock && !AllBlocks.COPPER_VALVE_HANDLE.is(item)) return false;
|
||||
if (block instanceof ValveHandleBlock && !AllBlocks.COPPER_VALVE_HANDLE.is(item))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -143,6 +135,7 @@ public class PonderIndexScreen extends AbstractSimiScreen {
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
PonderUI.ponderTicks++;
|
||||
|
||||
hoveredItem = ItemStack.EMPTY;
|
||||
MainWindow w = minecraft.getWindow();
|
||||
|
@ -224,4 +217,9 @@ public class PonderIndexScreen extends AbstractSimiScreen {
|
|||
public ItemStack getHoveredTooltipItem() {
|
||||
return hoveredItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,13 +77,16 @@ public class PonderTagScreen extends AbstractSimiScreen {
|
|||
int itemCenterY = getItemsY();
|
||||
|
||||
for (Item i : items) {
|
||||
final boolean canClick = PonderRegistry.all.containsKey(i.getRegistryName());
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (mouseX, mouseY) -> {
|
||||
if (!PonderRegistry.all.containsKey(i.getRegistryName()))
|
||||
if (!canClick)
|
||||
return;
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i), tag));
|
||||
}).showing(new ItemStack(i));
|
||||
if (!canClick)
|
||||
button.noClickEvent();
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
|
@ -92,18 +95,20 @@ public class PonderTagScreen extends AbstractSimiScreen {
|
|||
|
||||
if (!tag.getMainItem()
|
||||
.isEmpty()) {
|
||||
final boolean canClick = PonderRegistry.all.containsKey(tag.getMainItem()
|
||||
.getItem()
|
||||
.getRegistryName());
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10, (mouseX, mouseY) -> {
|
||||
if (!PonderRegistry.all.containsKey(tag.getMainItem()
|
||||
.getItem()
|
||||
.getRegistryName()))
|
||||
if (!canClick)
|
||||
return;
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag));
|
||||
}).showing(tag.getMainItem());
|
||||
if (!canClick)
|
||||
button.noClickEvent();
|
||||
|
||||
button.fade(1);
|
||||
// button.flash();
|
||||
widgets.add(button);
|
||||
}
|
||||
|
||||
|
@ -133,6 +138,7 @@ public class PonderTagScreen extends AbstractSimiScreen {
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
PonderUI.ponderTicks++;
|
||||
|
||||
hoveredItem = ItemStack.EMPTY;
|
||||
MainWindow w = minecraft.getWindow();
|
||||
|
@ -291,5 +297,10 @@ public class PonderTagScreen extends AbstractSimiScreen {
|
|||
return tag == ((PonderTagScreen) other).tag;
|
||||
return super.isEquivalentTo(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
package com.simibubi.create.foundation.ponder.content;
|
||||
|
||||
import com.simibubi.create.foundation.ponder.ElementLink;
|
||||
import com.simibubi.create.foundation.ponder.SceneBuilder;
|
||||
import com.simibubi.create.foundation.ponder.SceneBuildingUtil;
|
||||
import com.simibubi.create.foundation.ponder.Selection;
|
||||
import com.simibubi.create.foundation.ponder.elements.InputWindowElement;
|
||||
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
|
||||
import com.simibubi.create.foundation.utility.Pointing;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class PulleyScenes {
|
||||
|
||||
public static void movement(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("rope_pulley", "Moving Structures using Rope Pulleys");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.scaleSceneView(0.95f);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
Selection reversable = util.select.fromTo(2, 3, 4, 2, 4, 2);
|
||||
BlockPos leverPos = util.grid.at(1, 2, 4);
|
||||
BlockPos pulleyPos = util.grid.at(2, 4, 2);
|
||||
Selection redstoneStuff = util.select.fromTo(leverPos, leverPos.east());
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
ElementLink<WorldSectionElement> plank =
|
||||
scene.world.showIndependentSection(util.select.position(2, 1, 2), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.fromTo(1, 4, 3, 2, 1, 4), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
scene.world.showSection(util.select.position(pulleyPos), Direction.SOUTH);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, 2, 40);
|
||||
|
||||
scene.idle(45);
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.blockSurface(pulleyPos, Direction.WEST))
|
||||
.text("Rope Pulleys can move blocks vertically when given Rotational Force")
|
||||
.placeNearTarget();
|
||||
scene.idle(70);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, -2, 40);
|
||||
scene.world.moveSection(plank, util.vector.of(0, 2, 0), 40);
|
||||
scene.idle(60);
|
||||
|
||||
scene.overlay.showText(60)
|
||||
.pointAt(util.vector.blockSurface(pulleyPos, Direction.SOUTH))
|
||||
.text("Direction and Speed of movement depend on the Rotational Input")
|
||||
.placeNearTarget();
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, 2, 40);
|
||||
scene.world.moveSection(plank, util.vector.of(0, -2, 0), 40);
|
||||
scene.idle(50);
|
||||
|
||||
scene.world.hideIndependentSection(plank, Direction.NORTH);
|
||||
scene.idle(15);
|
||||
ElementLink<WorldSectionElement> chassis =
|
||||
scene.world.showIndependentSection(util.select.fromTo(2, 1, 1, 0, 2, 1), Direction.SOUTH);
|
||||
scene.world.moveSection(chassis, util.vector.of(1, 0, 1), 0);
|
||||
scene.idle(5);
|
||||
scene.world.showSectionAndMerge(util.select.position(2, 1, 0), Direction.SOUTH, chassis);
|
||||
scene.idle(15);
|
||||
scene.effects.superGlue(util.grid.at(3, 1, 1), Direction.SOUTH, true);
|
||||
scene.overlay.showText(80)
|
||||
.pointAt(util.vector.blockSurface(util.grid.at(1, 2, 2), Direction.NORTH))
|
||||
.placeNearTarget()
|
||||
.sharedText("movement_anchors");
|
||||
scene.idle(90);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, -2, 40);
|
||||
scene.world.moveSection(chassis, util.vector.of(0, 2, 0), 40);
|
||||
scene.idle(50);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, 2, 40);
|
||||
scene.world.moveSection(chassis, util.vector.of(0, -2, 0), 40);
|
||||
scene.idle(50);
|
||||
}
|
||||
|
||||
public static void movementModes(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("rope_pulley_modes", "Movement Modes of the Rope Pulley");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.scaleSceneView(0.95f);
|
||||
scene.setSceneOffsetY(-1);
|
||||
|
||||
Selection reversable = util.select.fromTo(2, 3, 4, 2, 4, 2);
|
||||
BlockPos leverPos = util.grid.at(1, 2, 4);
|
||||
BlockPos pulleyPos = util.grid.at(2, 4, 2);
|
||||
Selection redstoneStuff = util.select.fromTo(leverPos, leverPos.east());
|
||||
BlockPos flowerPos = util.grid.at(2, 1, 2);
|
||||
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.world.showSection(util.select.position(flowerPos), Direction.UP);
|
||||
scene.idle(5);
|
||||
scene.world.showSection(util.select.fromTo(1, 4, 3, 2, 1, 4), Direction.DOWN);
|
||||
scene.idle(10);
|
||||
|
||||
scene.world.showSection(util.select.position(pulleyPos), Direction.SOUTH);
|
||||
ElementLink<WorldSectionElement> glass =
|
||||
scene.world.showIndependentSection(util.select.position(pulleyPos.down()), Direction.UP);
|
||||
scene.idle(20);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, 2, 40);
|
||||
scene.world.moveSection(glass, util.vector.of(0, -2, 0), 40);
|
||||
scene.idle(40);
|
||||
|
||||
scene.world.destroyBlock(flowerPos);
|
||||
scene.idle(10);
|
||||
scene.overlay.showSelectionWithText(util.select.position(flowerPos), 70)
|
||||
.text("Whenever Pulleys stop moving, the moved structure reverts to blocks")
|
||||
.placeNearTarget()
|
||||
.colored(PonderPalette.RED);
|
||||
scene.idle(80);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, -2, 40);
|
||||
scene.world.moveSection(glass, util.vector.of(0, 2, 0), 40);
|
||||
scene.world.hideSection(util.select.position(flowerPos), Direction.DOWN);
|
||||
scene.idle(40);
|
||||
|
||||
scene.world.setBlock(flowerPos, Blocks.BLUE_ORCHID.getDefaultState(), false);
|
||||
scene.world.showSection(util.select.position(flowerPos), Direction.DOWN);
|
||||
scene.overlay.showCenteredScrollInput(pulleyPos, Direction.UP, 60);
|
||||
scene.overlay.showControls(new InputWindowElement(util.vector.topOf(pulleyPos), Pointing.DOWN).scroll()
|
||||
.withWrench(), 60);
|
||||
scene.overlay.showText(70)
|
||||
.pointAt(util.vector.topOf(pulleyPos))
|
||||
.placeNearTarget()
|
||||
.sharedText("behaviour_modify_wrench");
|
||||
scene.idle(80);
|
||||
|
||||
scene.world.toggleRedstonePower(redstoneStuff);
|
||||
scene.effects.indicateRedstone(leverPos);
|
||||
scene.world.modifyKineticSpeed(reversable, f -> -f);
|
||||
scene.effects.rotationDirectionIndicator(pulleyPos.south());
|
||||
scene.world.movePulley(pulleyPos, 2, 40);
|
||||
scene.world.moveSection(glass, util.vector.of(0, -2, 0), 40);
|
||||
scene.idle(50);
|
||||
scene.overlay.showText(120)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.pointAt(util.vector.blockSurface(flowerPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("It can be configured never to revert to solid blocks, or only at the location it started at");
|
||||
}
|
||||
|
||||
public static void attachment(SceneBuilder scene, SceneBuildingUtil util) {
|
||||
scene.title("rope_pulley_attachment", "Moving Pulleys as part of a Contraption");
|
||||
scene.configureBasePlate(0, 0, 5);
|
||||
scene.scaleSceneView(0.95f);
|
||||
scene.setSceneOffsetY(-1);
|
||||
scene.world.showSection(util.select.layer(0), Direction.UP);
|
||||
scene.idle(5);
|
||||
|
||||
Selection kinetics = util.select.fromTo(4, 3, 2, 4, 1, 5);
|
||||
Selection largeCog = util.select.position(3, 0, 5);
|
||||
|
||||
scene.world.showSection(kinetics, Direction.DOWN);
|
||||
ElementLink<WorldSectionElement> poles =
|
||||
scene.world.showIndependentSection(util.select.fromTo(4, 4, 2, 6, 4, 2), Direction.DOWN);
|
||||
scene.world.moveSection(poles, util.vector.of(0, -1, 0), 0);
|
||||
scene.idle(10);
|
||||
|
||||
BlockPos pulleyPos = util.grid.at(3, 3, 2);
|
||||
ElementLink<WorldSectionElement> pulley =
|
||||
scene.world.showIndependentSection(util.select.position(pulleyPos), Direction.EAST);
|
||||
scene.idle(10);
|
||||
scene.world.showSectionAndMerge(util.select.fromTo(3, 1, 1, 3, 1, 2)
|
||||
.add(util.select.position(3, 2, 1)), Direction.SOUTH, pulley);
|
||||
|
||||
scene.idle(10);
|
||||
scene.overlay.showText(50)
|
||||
.pointAt(util.vector.blockSurface(pulleyPos, Direction.WEST))
|
||||
.placeNearTarget()
|
||||
.text("Whenever Pulleys are themselves being moved by a Contraption...");
|
||||
scene.idle(60);
|
||||
|
||||
scene.world.setKineticSpeed(largeCog, -16);
|
||||
scene.world.setKineticSpeed(kinetics, 32);
|
||||
scene.effects.rotationDirectionIndicator(util.grid.at(4, 1, 5));
|
||||
scene.world.moveSection(poles, util.vector.of(-2, 0, 0), 40);
|
||||
scene.world.moveSection(pulley, util.vector.of(-2, 0, 0), 40);
|
||||
scene.idle(40);
|
||||
|
||||
scene.overlay.showSelectionWithText(util.select.fromTo(1, 1, 1, 1, 1, 2), 50)
|
||||
.colored(PonderPalette.GREEN)
|
||||
.placeNearTarget()
|
||||
.text("...its attached structure will be dragged with it");
|
||||
scene.idle(60);
|
||||
scene.overlay.showText(80)
|
||||
.colored(PonderPalette.RED)
|
||||
.pointAt(util.vector.topOf(pulleyPos.west(2)))
|
||||
.placeNearTarget()
|
||||
.text("Mind that pulleys are only movable while stopped");
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ public class SharedText {
|
|||
add("rpm32", "32 RPM");
|
||||
|
||||
add("movement_anchors", "With the help of Chassis or Super Glue, larger structures can be moved.");
|
||||
add("behaviour_modify_wrench", "This behaviour can be modified using a Wrench");
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
import com.simibubi.create.foundation.ponder.PonderWorld;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
|
@ -170,7 +170,7 @@ public class ParrotElement extends AnimatedSceneElement {
|
|||
.length();
|
||||
entity.onGround = false;
|
||||
double phase = Math.min(length * 15, 8);
|
||||
float f = (float) ((AnimationTickHolder.getTicks() % 100) * phase);
|
||||
float f = (float) ((PonderUI.ponderTicks % 100) * phase);
|
||||
entity.flapSpeed = MathHelper.sin(f) + 1;
|
||||
if (length == 0)
|
||||
entity.flapSpeed = 0;
|
||||
|
|
|
@ -64,6 +64,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
|
|||
Vec3d prevAnimatedRotation = Vec3d.ZERO;
|
||||
Vec3d animatedRotation = Vec3d.ZERO;
|
||||
Vec3d centerOfRotation = Vec3d.ZERO;
|
||||
Vec3d stabilizationAnchor = null;
|
||||
|
||||
BlockPos selectedBlock;
|
||||
|
||||
|
@ -103,6 +104,10 @@ public class WorldSectionElement extends AnimatedSceneElement {
|
|||
centerOfRotation = center;
|
||||
}
|
||||
|
||||
public void stabilizeRotation(Vec3d anchor) {
|
||||
stabilizationAnchor = anchor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(PonderScene scene) {
|
||||
super.reset(scene);
|
||||
|
@ -194,11 +199,21 @@ public class WorldSectionElement extends AnimatedSceneElement {
|
|||
if (!animatedRotation.equals(Vec3d.ZERO) || !prevAnimatedRotation.equals(Vec3d.ZERO)) {
|
||||
if (centerOfRotation == null)
|
||||
centerOfRotation = section.getCenter();
|
||||
double rotX = MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x);
|
||||
double rotZ = MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z);
|
||||
double rotY = MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y);
|
||||
in = in.subtract(centerOfRotation);
|
||||
in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x), Axis.X);
|
||||
in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z), Axis.Z);
|
||||
in = VecHelper.rotate(in, -MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y), Axis.Y);
|
||||
in = VecHelper.rotate(in, -rotX, Axis.X);
|
||||
in = VecHelper.rotate(in, -rotZ, Axis.Z);
|
||||
in = VecHelper.rotate(in, -rotY, Axis.Y);
|
||||
in = in.add(centerOfRotation);
|
||||
if (stabilizationAnchor != null) {
|
||||
in = in.subtract(stabilizationAnchor);
|
||||
in = VecHelper.rotate(in, rotX, Axis.X);
|
||||
in = VecHelper.rotate(in, rotZ, Axis.Z);
|
||||
in = VecHelper.rotate(in, rotY, Axis.Y);
|
||||
in = in.add(stabilizationAnchor);
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -209,12 +224,23 @@ public class WorldSectionElement extends AnimatedSceneElement {
|
|||
if (!animatedRotation.equals(Vec3d.ZERO) || !prevAnimatedRotation.equals(Vec3d.ZERO)) {
|
||||
if (centerOfRotation == null)
|
||||
centerOfRotation = section.getCenter();
|
||||
double rotX = MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x);
|
||||
double rotZ = MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z);
|
||||
double rotY = MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y);
|
||||
MatrixStacker.of(ms)
|
||||
.translate(centerOfRotation)
|
||||
.rotateX(MathHelper.lerp(pt, prevAnimatedRotation.x, animatedRotation.x))
|
||||
.rotateZ(MathHelper.lerp(pt, prevAnimatedRotation.z, animatedRotation.z))
|
||||
.rotateY(MathHelper.lerp(pt, prevAnimatedRotation.y, animatedRotation.y))
|
||||
.rotateX(rotX)
|
||||
.rotateZ(rotZ)
|
||||
.rotateY(rotY)
|
||||
.translateBack(centerOfRotation);
|
||||
if (stabilizationAnchor != null) {
|
||||
MatrixStacker.of(ms)
|
||||
.translate(stabilizationAnchor)
|
||||
.rotateX(-rotX)
|
||||
.rotateZ(-rotZ)
|
||||
.rotateY(-rotY)
|
||||
.translateBack(stabilizationAnchor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,10 +313,9 @@ public class WorldSectionElement extends AnimatedSceneElement {
|
|||
transformMS(ms, pt);
|
||||
RenderSystem.disableTexture();
|
||||
WorldRenderer.drawBox(ms, buffer.getBuffer(RenderType.getLines()), shape.getBoundingBox()
|
||||
.offset(selectedBlock), 1, 1, 1, 1);
|
||||
if (buffer instanceof SuperRenderTypeBuffer)
|
||||
((SuperRenderTypeBuffer) buffer).draw(RenderType.getLines());
|
||||
RenderSystem.enableTexture();
|
||||
.offset(selectedBlock), 1, 1, 1, 0.6f);
|
||||
// if (buffer instanceof SuperRenderTypeBuffer)
|
||||
// ((SuperRenderTypeBuffer) buffer).draw(RenderType.getLines());
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
|||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.bearing.IBearingTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.PonderWorld;
|
||||
|
@ -24,14 +24,14 @@ public class AnimateTileEntityInstruction extends TickingInstruction {
|
|||
|
||||
public static AnimateTileEntityInstruction bearing(BlockPos location, float totalDelta, int ticks) {
|
||||
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
||||
(w, f) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)),
|
||||
(w) -> castIfPresent(w, location, MechanicalBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0))
|
||||
(w, f) -> castIfPresent(w, location, IBearingTileEntity.class).ifPresent(bte -> bte.setAngle(f)),
|
||||
(w) -> castIfPresent(w, location, IBearingTileEntity.class).map(bte -> bte.getInterpolatedAngle(0))
|
||||
.orElse(0f));
|
||||
}
|
||||
|
||||
public static AnimateTileEntityInstruction pulley(BlockPos location, float totalDelta, int ticks) {
|
||||
return new AnimateTileEntityInstruction(location, totalDelta, ticks,
|
||||
(w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.offset = f),
|
||||
(w, f) -> castIfPresent(w, location, PulleyTileEntity.class).ifPresent(pulley -> pulley.animateOffset(f)),
|
||||
(w) -> castIfPresent(w, location, PulleyTileEntity.class).map(pulley -> pulley.offset)
|
||||
.orElse(0f));
|
||||
}
|
||||
|
|
|
@ -3,27 +3,40 @@ package com.simibubi.create.foundation.ponder.instructions;
|
|||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueItem;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.Selection;
|
||||
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
|
||||
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class DisplayWorldSectionInstruction extends FadeIntoSceneInstruction<WorldSectionElement> {
|
||||
|
||||
private Selection initialSelection;
|
||||
private Optional<Supplier<WorldSectionElement>> mergeOnto;
|
||||
private BlockPos glue;
|
||||
|
||||
public DisplayWorldSectionInstruction(int fadeInTicks, Direction fadeInFrom, Selection selection,
|
||||
Optional<Supplier<WorldSectionElement>> mergeOnto) {
|
||||
this(fadeInTicks, fadeInFrom, selection, mergeOnto, null);
|
||||
}
|
||||
|
||||
public DisplayWorldSectionInstruction(int fadeInTicks, Direction fadeInFrom, Selection selection,
|
||||
Optional<Supplier<WorldSectionElement>> mergeOnto, @Nullable BlockPos glue) {
|
||||
super(fadeInTicks, fadeInFrom, new WorldSectionElement(selection));
|
||||
initialSelection = selection;
|
||||
this.mergeOnto = mergeOnto;
|
||||
this.glue = glue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void firstTick(PonderScene scene) {
|
||||
super.firstTick(scene);
|
||||
mergeOnto.ifPresent(wse -> element.setAnimatedOffset(wse.get()
|
||||
.getAnimatedOffset(), true));
|
||||
element.set(initialSelection);
|
||||
element.setVisible(true);
|
||||
}
|
||||
|
@ -34,6 +47,8 @@ public class DisplayWorldSectionInstruction extends FadeIntoSceneInstruction<Wor
|
|||
if (remainingTicks > 0)
|
||||
return;
|
||||
mergeOnto.ifPresent(c -> element.mergeOnto(c.get()));
|
||||
if (glue != null)
|
||||
SuperGlueItem.spawnParticles(scene.getWorld(), glue, fadeInFrom, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,7 +9,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public abstract class FadeIntoSceneInstruction<T extends AnimatedSceneElement> extends TickingInstruction {
|
||||
|
||||
private Direction fadeInFrom;
|
||||
protected Direction fadeInFrom;
|
||||
protected T element;
|
||||
private ElementLink<T> elementLink;
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.foundation.ponder.instructions;
|
||||
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.content.PonderPalette;
|
||||
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class HighlightValueBoxInstruction extends TickingInstruction {
|
||||
|
||||
private Vec3d vec;
|
||||
private Vec3d expands;
|
||||
|
||||
public HighlightValueBoxInstruction(Vec3d vec, Vec3d expands, int duration) {
|
||||
super(false, duration);
|
||||
this.vec = vec;
|
||||
this.expands = expands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(PonderScene scene) {
|
||||
super.tick(scene);
|
||||
AxisAlignedBB point = new AxisAlignedBB(vec, vec);
|
||||
AxisAlignedBB expanded = point.grow(expands.x, expands.y, expands.z);
|
||||
scene.getOutliner()
|
||||
.chaseAABB(vec, remainingTicks == totalTicks ? point : expanded)
|
||||
.lineWidth(1 / 32f)
|
||||
.colored(PonderPalette.WHITE.getColor());
|
||||
}
|
||||
|
||||
}
|
|
@ -14,5 +14,10 @@ public class MarkAsFinishedInstruction extends PonderInstruction {
|
|||
public void tick(PonderScene scene) {
|
||||
scene.setFinished(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScheduled(PonderScene scene) {
|
||||
scene.stopCounting();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import com.simibubi.create.foundation.gui.GuiGameElement;
|
|||
import com.simibubi.create.foundation.gui.IScreenRenderable;
|
||||
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.LerpedFloat;
|
||||
|
||||
|
@ -26,6 +25,7 @@ public class PonderButton extends AbstractSimiWidget {
|
|||
private float fade;
|
||||
private KeyBinding shortcut;
|
||||
private LerpedFloat flash;
|
||||
private boolean noClickEvent;
|
||||
|
||||
public static final int SIZE = 20;
|
||||
|
||||
|
@ -54,6 +54,11 @@ public class PonderButton extends AbstractSimiWidget {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PonderButton noClickEvent() {
|
||||
this.noClickEvent = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PonderButton shortcut(KeyBinding key) {
|
||||
this.shortcut = key;
|
||||
return this;
|
||||
|
@ -86,7 +91,7 @@ public class PonderButton extends AbstractSimiWidget {
|
|||
if (fade < .1f)
|
||||
return;
|
||||
|
||||
isHovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height && fade > .75f;
|
||||
isHovered = isMouseOver(mouseX, mouseY) && fade > .75f;
|
||||
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.disableDepthTest();
|
||||
|
@ -95,11 +100,13 @@ public class PonderButton extends AbstractSimiWidget {
|
|||
|
||||
float flashValue = flash.getValue(partialTicks);
|
||||
if (flashValue > .1f)
|
||||
fade *= 3 * flashValue + Math.sin((AnimationTickHolder.getTicks() + partialTicks) / 6);
|
||||
fade *= 3 * flashValue + Math.sin((PonderUI.ponderTicks + partialTicks) / 6);
|
||||
|
||||
int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade);
|
||||
int borderColorStart = ColorHelper.applyAlpha(isHovered ? 0x70ffffff : 0x40aa9999, fade);
|
||||
int borderColorEnd = ColorHelper.applyAlpha(isHovered ? 0x30ffffff : 0x20aa9999, fade);
|
||||
int borderColorStart =
|
||||
ColorHelper.applyAlpha(noClickEvent ? 0x70984500 : isHovered ? 0x70ffffff : 0x40aa9999, fade);
|
||||
int borderColorEnd =
|
||||
ColorHelper.applyAlpha(noClickEvent ? 0x70692400 : isHovered ? 0x30ffffff : 0x20aa9999, fade);
|
||||
|
||||
PonderUI.renderBox(x, y, width, height, backgroundColor, borderColorStart, borderColorEnd);
|
||||
RenderSystem.translated(0, 0, 800);
|
||||
|
@ -153,4 +160,13 @@ public class PonderButton extends AbstractSimiWidget {
|
|||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver(double x, double y) {
|
||||
double m = 4;
|
||||
x = Math.floor(x);
|
||||
y = Math.floor(y);
|
||||
return active && visible
|
||||
&& !(x < this.x - m || x > this.x + width + m - 1 || y < this.y - m || y > this.y + height + m - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
|
|||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedInstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
@ -27,7 +27,7 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
|
|||
|
||||
@Override
|
||||
public void registerMaterials() {
|
||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedInstancedModel::new));
|
||||
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.MODEL, BasicInstancedModel::new));
|
||||
|
||||
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
|
||||
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingInstancedModel::new));
|
||||
|
|
|
@ -13,6 +13,8 @@ import com.simibubi.create.foundation.render.backend.gl.GlFog;
|
|||
import com.simibubi.create.foundation.render.backend.gl.GlFogMode;
|
||||
import com.simibubi.create.foundation.render.backend.gl.shader.*;
|
||||
import com.simibubi.create.foundation.render.backend.gl.versioned.GlFeatureCompat;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.IFlywheelWorld;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.opengl.GL;
|
||||
|
@ -65,6 +67,10 @@ public class Backend {
|
|||
return (P) programs.get(spec).get(GlFog.getFogMode());
|
||||
}
|
||||
|
||||
public static boolean isFlywheelWorld(World world) {
|
||||
return world == Minecraft.getInstance().world || (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel());
|
||||
}
|
||||
|
||||
public static boolean available() {
|
||||
return canUseVBOs();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class FastRenderDispatcher {
|
|||
}
|
||||
|
||||
public static boolean available(World world) {
|
||||
return Backend.canUseInstancing() && !(world instanceof SchematicWorld);
|
||||
return Backend.canUseInstancing() && Backend.isFlywheelWorld(world);
|
||||
}
|
||||
|
||||
public static int getDebugMode() {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package com.simibubi.create.foundation.render.backend;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
|
||||
|
||||
public class RenderMaterials {
|
||||
public static final MaterialType<InstancedModel<TransformData>> MODELS = new MaterialType<>();
|
||||
public static final MaterialType<InstancedModel<ModelData>> MODELS = new MaterialType<>();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ public enum InstanceVertexAttributes implements IVertexAttrib {
|
|||
TRANSFORM("aTransform", MatrixAttributes.MAT4),
|
||||
NORMAL_MAT("aNormalMat", MatrixAttributes.MAT3),
|
||||
LIGHT("aLight", CommonAttributes.LIGHT),
|
||||
COLOR("aColor", CommonAttributes.RGBA),
|
||||
;
|
||||
|
||||
private final String name;
|
||||
|
|
|
@ -6,16 +6,16 @@ import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
|||
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
|
||||
public class TransformedInstancedModel extends InstancedModel<TransformData> {
|
||||
public class BasicInstancedModel extends InstancedModel<ModelData> {
|
||||
public static final VertexFormat INSTANCE_FORMAT = VertexFormat.builder().addAttributes(InstanceVertexAttributes.class).build();
|
||||
|
||||
public TransformedInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
public BasicInstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
|
||||
super(renderer, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TransformData newInstance() {
|
||||
return new TransformData(this);
|
||||
protected ModelData newInstance() {
|
||||
return new ModelData(this);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,100 @@
|
|||
package com.simibubi.create.foundation.render.backend.instancing.impl;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.render.backend.RenderUtil;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import net.minecraft.client.renderer.Matrix3f;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ModelData extends InstanceData {
|
||||
private static final Matrix4f IDENT4 = new Matrix4f();
|
||||
private static final Matrix3f IDENT3 = new Matrix3f();
|
||||
static {
|
||||
IDENT4.loadIdentity();
|
||||
IDENT3.loadIdentity();
|
||||
}
|
||||
|
||||
private Matrix4f modelMat = IDENT4;
|
||||
private Matrix3f normalMat = IDENT3;
|
||||
|
||||
private byte blockLight;
|
||||
private byte skyLight;
|
||||
|
||||
private byte r = (byte) 0xFF;
|
||||
private byte g = (byte) 0xFF;
|
||||
private byte b = (byte) 0xFF;
|
||||
private byte a = (byte) 0xFF;
|
||||
|
||||
public ModelData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public ModelData setModelMat(Matrix4f modelMat) {
|
||||
this.modelMat = modelMat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setNormalMat(Matrix3f normalMat) {
|
||||
this.normalMat = normalMat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setTransform(MatrixStack stack) {
|
||||
this.modelMat = stack.peek().getModel().copy();
|
||||
this.normalMat = stack.peek().getNormal().copy();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setTransformNoCopy(MatrixStack stack) {
|
||||
this.modelMat = stack.peek().getModel();
|
||||
this.normalMat = stack.peek().getNormal();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setBlockLight(int blockLight) {
|
||||
this.blockLight = (byte) (blockLight << 4);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setSkyLight(int skyLight) {
|
||||
this.skyLight = (byte) (skyLight << 4);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setColor(int color) {
|
||||
byte a = (byte) ((color >> 24) & 0xFF);
|
||||
byte r = (byte) ((color >> 16) & 0xFF);
|
||||
byte g = (byte) ((color >> 8) & 0xFF);
|
||||
byte b = (byte) (color & 0xFF);
|
||||
return setColor(r, g, b);
|
||||
}
|
||||
|
||||
public ModelData setColor(int r, int g, int b) {
|
||||
return setColor((byte) r, (byte) g, (byte) b);
|
||||
}
|
||||
|
||||
public ModelData setColor(byte r, byte g, byte b) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelData setColor(byte r, byte g, byte b, byte a) {
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
this.a = a;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buf) {
|
||||
RenderUtil.writeMat4(buf, modelMat);
|
||||
RenderUtil.writeMat3(buf, normalMat);
|
||||
buf.put(new byte[] { blockLight, skyLight, r, g, b, a });
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package com.simibubi.create.foundation.render.backend.instancing.impl;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.render.backend.RenderUtil;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
|
||||
import net.minecraft.client.renderer.Matrix3f;
|
||||
import net.minecraft.client.renderer.Matrix4f;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class TransformData extends InstanceData {
|
||||
|
||||
private Matrix4f modelMat;
|
||||
private Matrix3f normalMat;
|
||||
|
||||
private byte blockLight;
|
||||
private byte skyLight;
|
||||
|
||||
public TransformData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
||||
public TransformData setModelMat(Matrix4f modelMat) {
|
||||
this.modelMat = modelMat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformData setNormalMat(Matrix3f normalMat) {
|
||||
this.normalMat = normalMat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformData setTransform(MatrixStack stack) {
|
||||
this.modelMat = stack.peek().getModel();
|
||||
this.normalMat = stack.peek().getNormal();
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformData setBlockLight(byte blockLight) {
|
||||
this.blockLight = blockLight;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TransformData setSkyLight(byte skyLight) {
|
||||
this.skyLight = skyLight;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buf) {
|
||||
RenderUtil.writeMat4(buf, modelMat);
|
||||
RenderUtil.writeMat3(buf, normalMat);
|
||||
buf.put(new byte[] { blockLight, skyLight });
|
||||
}
|
||||
}
|
|
@ -269,6 +269,10 @@ public class GridAlignedBB {
|
|||
}
|
||||
}
|
||||
|
||||
public AxisAlignedBB toAABB() {
|
||||
return toAABB(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
import com.simibubi.create.foundation.ponder.PonderWorld;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
public class AnimationTickHolder {
|
||||
|
||||
|
@ -15,6 +19,10 @@ public class AnimationTickHolder {
|
|||
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTicks() {
|
||||
return ticks;
|
||||
}
|
||||
|
||||
public static float getRenderTime() {
|
||||
return getTicks() + getPartialTicks();
|
||||
|
@ -24,8 +32,16 @@ public class AnimationTickHolder {
|
|||
Minecraft mc = Minecraft.getInstance();
|
||||
return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks());
|
||||
}
|
||||
|
||||
public static int getTicks() {
|
||||
return ticks;
|
||||
|
||||
public static int getTicks(IWorld world) {
|
||||
return world instanceof PonderWorld ? PonderUI.ponderTicks : getTicks();
|
||||
}
|
||||
|
||||
public static float getRenderTime(IWorld world) {
|
||||
return getTicks(world) + getPartialTicks(world);
|
||||
}
|
||||
|
||||
public static float getPartialTicks(IWorld world) {
|
||||
return world instanceof PonderWorld ? PonderUI.getPartialTicks() : getPartialTicks();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Coordinate {
|
||||
float get(BlockPos from);
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -23,6 +24,14 @@ public class MatrixStacker {
|
|||
return instance;
|
||||
}
|
||||
|
||||
public MatrixStacker rotate(Direction axis, float radians) {
|
||||
if (radians == 0)
|
||||
return this;
|
||||
ms.multiply(axis.getUnitVector()
|
||||
.getRadialQuaternion(radians));
|
||||
return this;
|
||||
}
|
||||
|
||||
public MatrixStacker rotate(double angle, Axis axis) {
|
||||
Vector3f vec =
|
||||
axis == Axis.X ? Vector3f.POSITIVE_X : axis == Axis.Y ? Vector3f.POSITIVE_Y : Vector3f.POSITIVE_Z;
|
||||
|
@ -75,7 +84,7 @@ public class MatrixStacker {
|
|||
}
|
||||
|
||||
public MatrixStacker nudge(int id) {
|
||||
long randomBits = (long) id * 493286711L;
|
||||
long randomBits = (long) id * 31L * 493286711L;
|
||||
randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
|
||||
float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
|
||||
float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F;
|
||||
|
@ -84,7 +93,7 @@ public class MatrixStacker {
|
|||
return this;
|
||||
}
|
||||
|
||||
private MatrixStacker multiply(Vector3f axis, double angle) {
|
||||
public MatrixStacker multiply(Vector3f axis, double angle) {
|
||||
if (angle == 0)
|
||||
return this;
|
||||
ms.multiply(axis.getDegreesQuaternion((float) angle));
|
||||
|
|
|
@ -7,6 +7,7 @@ attribute vec2 aTexCoords;
|
|||
attribute mat4 aTransform;
|
||||
attribute mat3 aNormalMat;
|
||||
attribute vec2 aLight;
|
||||
attribute vec4 aColor;
|
||||
|
||||
varying vec2 TexCoords;
|
||||
varying vec4 Color;
|
||||
|
@ -72,5 +73,5 @@ void main() {
|
|||
Light = aLight;
|
||||
gl_Position = uViewProjection * worldPos;
|
||||
|
||||
Color = vec4(1.);
|
||||
Color = aColor;
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
src/main/resources/ponder/clockwork_bearing.nbt
Normal file
BIN
src/main/resources/ponder/clockwork_bearing.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_bearing/anchor.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_bearing/anchor.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_bearing/modes.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_bearing/modes.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_bearing/stabilized.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_bearing/stabilized.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_piston/anchor.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_piston/anchor.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_piston/modes.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_piston/modes.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/mechanical_piston/piston_pole.nbt
Normal file
BIN
src/main/resources/ponder/mechanical_piston/piston_pole.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/rope_pulley/anchor.nbt
Normal file
BIN
src/main/resources/ponder/rope_pulley/anchor.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/rope_pulley/attachment.nbt
Normal file
BIN
src/main/resources/ponder/rope_pulley/attachment.nbt
Normal file
Binary file not shown.
BIN
src/main/resources/ponder/rope_pulley/modes.nbt
Normal file
BIN
src/main/resources/ponder/rope_pulley/modes.nbt
Normal file
Binary file not shown.
Loading…
Reference in a new issue