CreateMod/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonRenderer.java
JozsefA aeff644cc3 Merge remote-tracking branch 'origin/mc1.16/dev' into mc1.16/chromatic-projector
# Conflicts:
#	src/generated/resources/assets/create/lang/en_us.json
#	src/generated/resources/assets/create/lang/unfinished/de_de.json
#	src/generated/resources/assets/create/lang/unfinished/es_es.json
#	src/generated/resources/assets/create/lang/unfinished/es_mx.json
#	src/generated/resources/assets/create/lang/unfinished/fr_fr.json
#	src/generated/resources/assets/create/lang/unfinished/it_it.json
#	src/generated/resources/assets/create/lang/unfinished/ja_jp.json
#	src/generated/resources/assets/create/lang/unfinished/ko_kr.json
#	src/generated/resources/assets/create/lang/unfinished/nl_nl.json
#	src/generated/resources/assets/create/lang/unfinished/pl_pl.json
#	src/generated/resources/assets/create/lang/unfinished/pt_br.json
#	src/generated/resources/assets/create/lang/unfinished/ru_ru.json
#	src/generated/resources/assets/create/lang/unfinished/zh_cn.json
#	src/generated/resources/assets/create/lang/unfinished/zh_tw.json
#	src/main/java/com/simibubi/create/AllContainerTypes.java
#	src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java
#	src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerHandler.java
#	src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java
#	src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintEntity.java
#	src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintOverlayRenderer.java
#	src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintRenderer.java
#	src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintScreen.java
#	src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java
#	src/main/java/com/simibubi/create/content/logistics/item/LinkedControllerScreen.java
#	src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterScreen.java
#	src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java
#	src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java
#	src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java
#	src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java
#	src/main/java/com/simibubi/create/foundation/gui/mainMenu/CreateMainMenuScreen.java
#	src/main/java/com/simibubi/create/foundation/ponder/content/ChainDriveScenes.java
#	src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java
#	src/main/resources/META-INF/mods.toml
#	src/main/resources/assets/create/lang/default/messages.json
#	src/main/resources/assets/create/lang/default/tooltips.json
2021-06-19 16:11:18 -07:00

196 lines
7.1 KiB
Java

package com.simibubi.create.content.schematics.block;
import java.util.Random;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
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.PartialBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraftforge.client.model.data.EmptyModelData;
public class SchematicannonRenderer extends SafeTileEntityRenderer<SchematicannonTileEntity> {
public SchematicannonRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}
@Override
public boolean isGlobalRenderer(SchematicannonTileEntity p_188185_1_) {
return true;
}
@Override
protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
IRenderTypeBuffer buffer, int light, int overlay) {
boolean blocksLaunching = !tileEntityIn.flyingBlocks.isEmpty();
if (blocksLaunching)
renderLaunchedBlocks(tileEntityIn, partialTicks, ms, buffer, light, overlay);
if (Backend.getInstance().canUseInstancing(tileEntityIn.getWorld())) return;
BlockPos pos = tileEntityIn.getPos();
double[] cannonAngles = getCannonAngles(tileEntityIn, pos, partialTicks);
double pitch = cannonAngles[0];
double yaw = cannonAngles[1];
double recoil = getRecoil(tileEntityIn, partialTicks);
ms.push();
BlockState state = tileEntityIn.getBlockState();
int lightCoords = WorldRenderer.getLightmapCoordinates(tileEntityIn.getWorld(), pos);
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
SuperByteBuffer connector = PartialBufferer.get(AllBlockPartials.SCHEMATICANNON_CONNECTOR, state);
connector.translate(.5f, 0, .5f);
connector.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
connector.translate(-.5f, 0, -.5f);
connector.light(lightCoords).renderInto(ms, vb);
SuperByteBuffer pipe = PartialBufferer.get(AllBlockPartials.SCHEMATICANNON_PIPE, state);
pipe.translate(.5f, 15 / 16f, .5f);
pipe.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
pipe.rotate(Direction.SOUTH, (float) (pitch / 180 * Math.PI));
pipe.translate(-.5f, -15 / 16f, -.5f);
pipe.translate(0, -recoil / 100, 0);
pipe.light(lightCoords).renderInto(ms, vb);
ms.pop();
}
public static double[] getCannonAngles(SchematicannonTileEntity tile, BlockPos pos, float partialTicks) {
double yaw = 0;
double pitch = 40;
BlockPos target = tile.printer.getCurrentTarget();
if (target != null) {
// Calculate Angle of Cannon
Vector3d diff = Vector3d.of(target.subtract(pos));
if (tile.previousTarget != null) {
diff = (Vector3d.of(tile.previousTarget)
.add(Vector3d.of(target.subtract(tile.previousTarget)).scale(partialTicks)))
.subtract(Vector3d.of(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)
continue;
// Calculate position of flying block
Vector3d start = Vector3d.of(tileEntityIn.getPos().add(.5f, 1, .5f));
Vector3d target = Vector3d.of(launched.target).add(-.5, 0, 1);
Vector3d distance = target.subtract(start);
double targetY = target.y - start.y;
double throwHeight = Math.sqrt(distance.lengthSquared()) * .6f + targetY;
Vector3d cannonOffset = distance.add(0, throwHeight, 0).normalize().scale(2);
start = start.add(cannonOffset);
float progress =
((float) launched.totalTicks - (launched.ticksRemaining + 1 - partialTicks)) / launched.totalTicks;
Vector3d blockLocationXZ = new Vector3d(.5, .5, .5).add(target.subtract(start).scale(progress).mul(1, 0, 1));
// Height is determined through a bezier curve
float t = progress;
double yOffset = 2 * (1 - t) * t * throwHeight + t * t * targetY;
Vector3d blockLocation = blockLocationXZ.add(0, yOffset + 1, 0).add(cannonOffset);
// Offset to position
ms.push();
ms.translate(blockLocation.x, blockLocation.y, blockLocation.z);
ms.multiply(new Vector3f(0, 1, 0).getDegreesQuaternion(360 * t * 2));
ms.multiply(new Vector3f(1, 0, 0).getDegreesQuaternion(360 * t * 2));
// Render the Block
if (launched instanceof ForBlockState) {
float scale = .3f;
ms.scale(scale, scale, scale);
Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(((ForBlockState) launched).state, ms, buffer, light, overlay, EmptyModelData.INSTANCE);
}
// Render the item
if (launched instanceof ForEntity) {
float scale = 1.2f;
ms.scale(scale, scale, scale);
Minecraft.getInstance().getItemRenderer().renderItem(launched.stack, TransformType.GROUND, light, overlay, ms, buffer);
}
ms.pop();
// Render particles for launch
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
tileEntityIn.firstRenderTick = false;
for (int i = 0; i < 10; i++) {
Random r = tileEntityIn.getWorld().getRandom();
double sX = cannonOffset.x * .01f;
double sY = (cannonOffset.y + 1) * .01f;
double sZ = cannonOffset.z * .01f;
double rX = r.nextFloat() - sX * 40;
double rY = r.nextFloat() - sY * 40;
double rZ = r.nextFloat() - sZ * 40;
tileEntityIn.getWorld().addParticle(ParticleTypes.CLOUD, start.x + rX, start.y + rY,
start.z + rZ, sX, sY, sZ);
}
}
}
}
}