mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 01:45:00 +01:00
VERY crude rendering of mirror beams (A LOT of things are broken!)
This commit is contained in:
parent
6326215fc5
commit
53e1f0f416
11 changed files with 315 additions and 53 deletions
|
@ -1651,7 +1651,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
|
||||||
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
|
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
|
||||||
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
|
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
|
||||||
f98bf9f870ac5ee5b31c12a20739773c5fee4949 assets/create/sounds.json
|
f98bf9f870ac5ee5b31c12a20739773c5fee4949 assets/create/sounds.json
|
||||||
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json
|
5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json
|
||||||
187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json
|
187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json
|
||||||
0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json
|
0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json
|
||||||
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json
|
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
"trigger": "create:bracket_apply",
|
"trigger": "create:bracket_apply",
|
||||||
"conditions": {
|
"conditions": {
|
||||||
"accepted_entries": [
|
"accepted_entries": [
|
||||||
"create:cogwheel",
|
"create:large_cogwheel",
|
||||||
"create:large_cogwheel"
|
"create:cogwheel"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Random;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.config.CRecipes;
|
import com.simibubi.create.foundation.config.CRecipes;
|
||||||
|
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
@ -15,17 +16,12 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.tileentity.BeaconTileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.math.RayTraceContext;
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
import net.minecraft.util.math.RayTraceContext.BlockMode;
|
||||||
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
import net.minecraft.util.math.RayTraceContext.FluidMode;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.gen.Heightmap;
|
|
||||||
|
|
||||||
public class ChromaticCompoundItem extends Item {
|
public class ChromaticCompoundItem extends Item {
|
||||||
|
|
||||||
|
@ -114,35 +110,7 @@ public class ChromaticCompoundItem extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is inside beacon beam?
|
// Is inside beacon beam?
|
||||||
boolean isOverBeacon = false;
|
if (BeaconHelper.isAboveActiveBeacon(entity.getPositionVec(), world)) {
|
||||||
int entityX = MathHelper.floor(entity.getX());
|
|
||||||
int entityZ = MathHelper.floor(entity.getZ());
|
|
||||||
int localWorldHeight = world.getHeight(Heightmap.Type.WORLD_SURFACE, entityX, entityZ);
|
|
||||||
|
|
||||||
BlockPos.Mutable testPos =
|
|
||||||
new BlockPos.Mutable(entityX, Math.min(MathHelper.floor(entity.getY()), localWorldHeight), entityZ);
|
|
||||||
|
|
||||||
while (testPos.getY() > 0) {
|
|
||||||
testPos.move(Direction.DOWN);
|
|
||||||
BlockState state = world.getBlockState(testPos);
|
|
||||||
if (state.getOpacity(world, testPos) >= 15 && state.getBlock() != Blocks.BEDROCK)
|
|
||||||
break;
|
|
||||||
if (state.getBlock() == Blocks.BEACON) {
|
|
||||||
TileEntity te = world.getTileEntity(testPos);
|
|
||||||
|
|
||||||
if (!(te instanceof BeaconTileEntity))
|
|
||||||
break;
|
|
||||||
|
|
||||||
BeaconTileEntity bte = (BeaconTileEntity) te;
|
|
||||||
|
|
||||||
if (bte.getLevels() != 0 && !bte.beamSegments.isEmpty())
|
|
||||||
isOverBeacon = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOverBeacon) {
|
|
||||||
ItemStack newStack = AllItems.REFINED_RADIANCE.asStack();
|
ItemStack newStack = AllItems.REFINED_RADIANCE.asStack();
|
||||||
newStack.setCount(stack.getCount());
|
newStack.setCount(stack.getCount());
|
||||||
data.putBoolean("JustCreated", true);
|
data.putBoolean("JustCreated", true);
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
|
public class BeamSegment {
|
||||||
|
public final float[] colors;
|
||||||
|
private final Vector3d direction;
|
||||||
|
private final Vector3d start;
|
||||||
|
private int length;
|
||||||
|
|
||||||
|
public BeamSegment(@Nonnull float[] color, Vector3d start, Vector3d direction) {
|
||||||
|
this.colors = color;
|
||||||
|
this.direction = direction;
|
||||||
|
this.start = start;
|
||||||
|
this.length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementLength() {
|
||||||
|
++this.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getColors() {
|
||||||
|
return this.colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLength() {
|
||||||
|
return this.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public interface ILightHandler<T extends TileEntity & ILightHandler<T>> {
|
||||||
|
Vector3d getBeamDirection();
|
||||||
|
|
||||||
|
default double getBeamLenght() {
|
||||||
|
T te = getTile();
|
||||||
|
World world = te.getWorld();
|
||||||
|
BlockPos pos = te.getPos();
|
||||||
|
if (pos == BlockPos.ZERO || world == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Vector3d direction = getBeamDirection();
|
||||||
|
BlockRayTraceResult raytrace = world
|
||||||
|
.rayTraceBlocks(new RayTraceContext(Vector3d.of(pos).add(direction),
|
||||||
|
direction.normalize()
|
||||||
|
.scale(128)
|
||||||
|
.add(Vector3d.of(pos)),
|
||||||
|
RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, null));
|
||||||
|
|
||||||
|
return Vector3d.of(raytrace.getPos()
|
||||||
|
.subtract(pos))
|
||||||
|
.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
T getTile();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
public class BeaconSegmentListWrapper {
|
||||||
|
|
||||||
|
}
|
|
@ -1,23 +1,62 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
import com.simibubi.create.content.optics.BeamSegment;
|
||||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Matrix3f;
|
||||||
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
public class MirrorRenderer extends KineticTileEntityRenderer {
|
public class MirrorRenderer extends KineticTileEntityRenderer {
|
||||||
public MirrorRenderer(TileEntityRendererDispatcher dispatcher) {
|
public MirrorRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||||
super(dispatcher);
|
super(dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void method_22741(MatrixStack ms, IVertexBuilder builder, float[] colors, float p_228840_5_, int p_228840_6_, int p_228840_7_, float p_228840_8_, float p_228840_9_, float p_228840_10_, float p_228840_11_, float p_228840_12_, float p_228840_13_, float p_228840_14_, float p_228840_15_, float p_228840_16_, float p_228840_17_, float p_228840_18_, float p_228840_19_) {
|
||||||
|
MatrixStack.Entry matrixstack$entry = ms.peek();
|
||||||
|
Matrix4f matrix4f = matrixstack$entry.getModel();
|
||||||
|
Matrix3f matrix3f = matrixstack$entry.getNormal();
|
||||||
|
method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_8_, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_);
|
||||||
|
method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_);
|
||||||
|
method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_);
|
||||||
|
method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_12_, p_228840_13_, p_228840_8_, p_228840_9_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void method_22740(Matrix4f matrix, Matrix3f p_228839_1_, IVertexBuilder builder, float p_228839_3_, float p_228839_4_, float p_228839_5_, float p_228839_6_, int p_228839_7_, int p_228839_8_, float p_228839_9_, float p_228839_10_, float p_228839_11_, float p_228839_12_, float p_228839_13_, float p_228839_14_, float p_228839_15_, float p_228839_16_) {
|
||||||
|
method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_8_, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_15_);
|
||||||
|
method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_7_, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_16_);
|
||||||
|
method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_7_, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_16_);
|
||||||
|
method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_8_, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_15_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void method_23076(Matrix4f p_228838_0_, Matrix3f p_228838_1_, IVertexBuilder builder, float p_228838_3_, float p_228838_4_, float p_228838_5_, float p_228838_6_, int p_228838_7_, float p_228838_8_, float p_228838_9_, float p_228838_10_, float p_228838_11_) {
|
||||||
|
builder.vertex(p_228838_0_, p_228838_8_, (float) p_228838_7_, p_228838_9_)
|
||||||
|
.color(p_228838_3_, p_228838_4_, p_228838_5_, p_228838_6_)
|
||||||
|
.texture(p_228838_10_, p_228838_11_)
|
||||||
|
.overlay(OverlayTexture.DEFAULT_UV)
|
||||||
|
.light(15728880)
|
||||||
|
.normal(p_228838_1_, 0.0F, 1.0F, 0.0F)
|
||||||
|
.endVertex();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
int light, int overlay) {
|
int light, int overlay) {
|
||||||
|
@ -25,24 +64,66 @@ public class MirrorRenderer extends KineticTileEntityRenderer {
|
||||||
// if (FastRenderDispatcher.available(te.getWorld())) return;
|
// if (FastRenderDispatcher.available(te.getWorld())) return;
|
||||||
|
|
||||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||||
|
MirrorTileEntity mirrorTe = (MirrorTileEntity) te;
|
||||||
|
|
||||||
|
renderMirror(mirrorTe, partialTicks, ms, buffer, light);
|
||||||
|
renderOutBeam(mirrorTe, partialTicks, ms, buffer, light);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderOutBeam(MirrorTileEntity mirrorTe, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
||||||
|
|
||||||
|
int start = 0;
|
||||||
|
|
||||||
|
for (int k = 0; k < mirrorTe.beam.size(); k++) {
|
||||||
|
BeamSegment beamSegment = mirrorTe.beam.get(k);
|
||||||
|
renderSegment(beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld()
|
||||||
|
.getGameTime(),
|
||||||
|
beamSegment.getDirection()
|
||||||
|
.scale(start + beamSegment.getLength())
|
||||||
|
.length());
|
||||||
|
start += beamSegment.getLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderSegment(BeamSegment beamSegment, MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, long gameTime, double length) {
|
||||||
|
float adjustedGameTime = (float) Math.floorMod(gameTime, 40L) + partialTicks;
|
||||||
|
ms.push();
|
||||||
|
ms.translate(0.5D, 0.0D, 0.5D);
|
||||||
|
ms.push();
|
||||||
|
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(adjustedGameTime * 2.25F - 45.0F));
|
||||||
|
float f2 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F));
|
||||||
|
float f15 = f2 - 1;
|
||||||
|
float f16 = (float) beamSegment.getLength() * 1F * (0.5F / 0.2F) + f15;
|
||||||
|
method_22741(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), beamSegment.colors, 1F, MathHelper.floor(length - beamSegment.getLength()), MathHelper.floor(length), 0F, 0.2F, .2F, 0F, -.2f, 0f, 0f, -.2f, 0f, 1f, f16, f15);
|
||||||
|
ms.pop();
|
||||||
|
ms.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
||||||
|
|
||||||
MirrorTileEntity bearingTe = (MirrorTileEntity) te;
|
|
||||||
final Direction.Axis facing = te.getBlockState()
|
final Direction.Axis facing = te.getBlockState()
|
||||||
.get(BlockStateProperties.AXIS);
|
.get(BlockStateProperties.AXIS);
|
||||||
SuperByteBuffer superBuffer = AllBlockPartials.MIRROR_PLANE.renderOn(te.getBlockState());
|
SuperByteBuffer superBuffer = AllBlockPartials.MIRROR_PLANE.renderOn(te.getBlockState());
|
||||||
|
|
||||||
float interpolatedAngle = bearingTe.getInterpolatedAngle(partialTicks - 1);
|
float interpolatedAngle = te.getInterpolatedAngle(partialTicks - 1);
|
||||||
kineticRotationTransform(superBuffer, te, facing, (float) (interpolatedAngle / 180 * Math.PI), light);
|
kineticRotationTransform(superBuffer, te, facing, (float) (interpolatedAngle / 180 * Math.PI), light);
|
||||||
|
|
||||||
if (facing == Direction.Axis.X) {
|
switch (facing) {
|
||||||
|
case X:
|
||||||
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(90));
|
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(90));
|
||||||
}
|
break;
|
||||||
if (facing == Direction.Axis.Y) {
|
case Y:
|
||||||
superBuffer.rotateCentered(Direction.EAST, AngleHelper.rad(90));
|
superBuffer.rotateCentered(Direction.EAST, AngleHelper.rad(90));
|
||||||
}
|
break;
|
||||||
if (facing == Direction.Axis.Z) {
|
default:
|
||||||
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(180));
|
superBuffer.rotateCentered(Direction.UP, AngleHelper.rad(180));
|
||||||
}
|
}
|
||||||
|
|
||||||
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
superBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGlobalRenderer(KineticTileEntity tileEntity) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,39 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
|
import com.simibubi.create.content.optics.BeamSegment;
|
||||||
|
import com.simibubi.create.content.optics.ILightHandler;
|
||||||
|
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.item.DyeColor;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.BeaconTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
public class MirrorTileEntity extends KineticTileEntity {
|
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
||||||
|
public final List<BeamSegment> beam;
|
||||||
protected float angle;
|
protected float angle;
|
||||||
protected float clientAngleDiff;
|
protected float clientAngleDiff;
|
||||||
private float prevAngle;
|
private float prevAngle;
|
||||||
|
private double length;
|
||||||
|
private Optional<BeaconTileEntity> beacon;
|
||||||
|
|
||||||
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
setLazyTickRate(3);
|
beacon = Optional.empty();
|
||||||
|
beam = new ArrayList<>();
|
||||||
|
setLazyTickRate(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,7 +63,7 @@ public class MirrorTileEntity extends KineticTileEntity {
|
||||||
float speed = getSpeed() * 3 / 10f;
|
float speed = getSpeed() * 3 / 10f;
|
||||||
if (getSpeed() == 0)
|
if (getSpeed() == 0)
|
||||||
speed = 0;
|
speed = 0;
|
||||||
if (world.isRemote) {
|
if (world != null && world.isRemote) {
|
||||||
speed *= ServerSpeedProvider.get();
|
speed *= ServerSpeedProvider.get();
|
||||||
speed += clientAngleDiff / 3f;
|
speed += clientAngleDiff / 3f;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +75,7 @@ public class MirrorTileEntity extends KineticTileEntity {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
prevAngle = angle;
|
prevAngle = angle;
|
||||||
if (world.isRemote)
|
if (world != null && world.isRemote)
|
||||||
clientAngleDiff /= 2;
|
clientAngleDiff /= 2;
|
||||||
|
|
||||||
float angularSpeed = getAngularSpeed();
|
float angularSpeed = getAngularSpeed();
|
||||||
|
@ -65,6 +83,35 @@ public class MirrorTileEntity extends KineticTileEntity {
|
||||||
angle = newAngle % 360;
|
angle = newAngle % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lazyTick() {
|
||||||
|
super.lazyTick();
|
||||||
|
beacon = BeaconHelper.getBeaconTE(pos, world);
|
||||||
|
length = getBeamLenght();
|
||||||
|
|
||||||
|
if (length < 1)
|
||||||
|
return;
|
||||||
|
Vector3d direction = VecHelper.step(getBeamDirection());
|
||||||
|
Vector3d startPos = VecHelper.getCenterOf(getPos());
|
||||||
|
beam.clear();
|
||||||
|
|
||||||
|
float[] startColor = DyeColor.WHITE.getColorComponentValues(); // TODO: Add mirroring of color
|
||||||
|
BeamSegment segment = new BeamSegment(startColor, startPos, direction);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
startPos = startPos.add(direction); // check next block
|
||||||
|
float[] newColor = BeaconHelper.getBeaconColorAt(startPos, world);
|
||||||
|
if (newColor != null && !Arrays.equals(startColor, newColor)) {
|
||||||
|
beam.add(segment);
|
||||||
|
startColor = new float[]{(segment.colors[0] + newColor[0]) / 2.0F, (segment.colors[1] + newColor[1]) / 2.0F, (segment.colors[2] + newColor[2]) / 2.0F};
|
||||||
|
segment = new BeamSegment(newColor, startPos, direction);
|
||||||
|
} else {
|
||||||
|
segment.incrementLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
beam.add(segment);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRenderAsTE() {
|
public boolean shouldRenderAsTE() {
|
||||||
return true;
|
return true;
|
||||||
|
@ -73,4 +120,15 @@ public class MirrorTileEntity extends KineticTileEntity {
|
||||||
public void setAngle(float forcedAngle) {
|
public void setAngle(float forcedAngle) {
|
||||||
angle = forcedAngle;
|
angle = forcedAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3d getBeamDirection() {
|
||||||
|
// TODO: Implement properly
|
||||||
|
return VecHelper.step(Vector3d.of(Direction.SOUTH.getDirectionVec()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MirrorTileEntity getTile() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.IBeaconBeamColorProvider;
|
||||||
|
import net.minecraft.tileentity.BeaconTileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.gen.Heightmap;
|
||||||
|
|
||||||
|
public class BeaconHelper {
|
||||||
|
private BeaconHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<BeaconTileEntity> getBeaconTE(@Nullable BlockPos testPos, @Nullable IBlockReader world) {
|
||||||
|
if (testPos == null || world == null)
|
||||||
|
return Optional.empty();
|
||||||
|
while (testPos.getY() > 0) {
|
||||||
|
testPos = testPos.down();
|
||||||
|
BlockState state = world.getBlockState(testPos);
|
||||||
|
if (state.getOpacity(world, testPos) >= 15 && state.getBlock() != Blocks.BEDROCK)
|
||||||
|
break;
|
||||||
|
if (state.getBlock() == Blocks.BEACON) {
|
||||||
|
TileEntity te = world.getTileEntity(testPos);
|
||||||
|
|
||||||
|
if (!(te instanceof BeaconTileEntity))
|
||||||
|
break;
|
||||||
|
return Optional.of((BeaconTileEntity) te);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<BeaconTileEntity> getBeaconTE(Vector3d pos, World world) {
|
||||||
|
int testX = MathHelper.floor(pos.getX());
|
||||||
|
int testZ = MathHelper.floor(pos.getZ());
|
||||||
|
int localWorldHeight = world.getHeight(Heightmap.Type.WORLD_SURFACE, testX, testZ);
|
||||||
|
return getBeaconTE(new BlockPos(testX, Math.min(MathHelper.floor(pos.getY()), localWorldHeight), testZ), world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAboveActiveBeacon(Vector3d pos, World world) {
|
||||||
|
return getBeaconTE(pos, world).filter(bte -> bte.getLevels() != 0 && !bte.beamSegments.isEmpty())
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static float[] getBeaconColorAt(Vector3d pos, @Nullable IBlockReader world) {
|
||||||
|
if (world == null)
|
||||||
|
return null;
|
||||||
|
Block block = world.getBlockState(new BlockPos(pos.x, pos.y, pos.z))
|
||||||
|
.getBlock();
|
||||||
|
if (!(block instanceof IBeaconBeamColorProvider))
|
||||||
|
return null;
|
||||||
|
return ((IBeaconBeamColorProvider) block).getColor()
|
||||||
|
.getColorComponentValues();
|
||||||
|
}
|
||||||
|
}
|
|
@ -214,4 +214,15 @@ public class VecHelper {
|
||||||
return new Vector3d(-result3f.getX() * scale_factor, result3f.getY() * scale_factor, result3f.getZ());
|
return new Vector3d(-result3f.getX() * scale_factor, result3f.getY() * scale_factor, result3f.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector3d step(Vector3d direction) {
|
||||||
|
return direction.scale(1 / varMax(Math.abs(direction.x), Math.abs(direction.y), Math.abs(direction.z)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double varMax(double n, double ... numbers) {
|
||||||
|
for (double test : numbers) {
|
||||||
|
if (test > n)
|
||||||
|
n = test;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "side",
|
"name": "side",
|
||||||
"from": [2, 0, 2],
|
"from": [2, 1, 2],
|
||||||
"to": [14, 1, 14],
|
"to": [14, 2, 14],
|
||||||
"rotation": {"angle": 0, "axis": "x", "origin": [8, -10, 8]},
|
"rotation": {"angle": 0, "axis": "x", "origin": [8, -10, 8]},
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [2, 11, 14, 12], "rotation": 180, "texture": "#4"},
|
"north": {"uv": [2, 11, 14, 12], "rotation": 180, "texture": "#4"},
|
||||||
|
|
Loading…
Reference in a new issue