From e0ae426cabb9ae9ec579d3d32604dd08d503b4a5 Mon Sep 17 00:00:00 2001 From: Waterpicker Date: Wed, 29 Apr 2020 22:02:00 -0500 Subject: [PATCH] Forgot the rest. --- .../client/DimensionalPortalRenderer.java | 335 ++++++------- .../EntranceRiftBlockEntityRenderer.java | 43 +- .../dimdev/dimdoors/client/MonolithModel.java | 71 +-- .../dimdoors/entity/MonolithEntity.java | 454 ++++++++++-------- .../dimdoors/entity/MonolithRenderer.java | 16 +- .../dimdoors/world/limbo/LimboBiome.java | 8 +- .../world/limbo/LimboChunkGenerator.java | 12 +- .../limbo/LimboChunkGeneratorConfig.java | 3 +- 8 files changed, 502 insertions(+), 440 deletions(-) diff --git a/src/main/java/org/dimdev/dimdoors/client/DimensionalPortalRenderer.java b/src/main/java/org/dimdev/dimdoors/client/DimensionalPortalRenderer.java index 6c27a8b7..43b0249d 100644 --- a/src/main/java/org/dimdev/dimdoors/client/DimensionalPortalRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/DimensionalPortalRenderer.java @@ -1,11 +1,27 @@ package org.dimdev.dimdoors.client; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.util.GlAllocationUtils; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; import net.minecraft.util.math.Direction; +import org.lwjgl.opengl.GL11; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import static com.mojang.blaze3d.platform.GlStateManager.TexCoord.*; +import static com.mojang.blaze3d.platform.GlStateManager.enableTexGen; public final class DimensionalPortalRenderer { // TODO -// private static final FloatBuffer buffer = GLAllocation.createDirectFloatBuffer(16); -// private static final Identifier warpPath = new Identifier("dimdoors" + ":textures/other/warp.png"); + private static final FloatBuffer buffer = GlAllocationUtils.allocateFloatBuffer(16); + private static final Identifier warpPath = new Identifier("dimdoors" + ":textures/other/warp.png"); /** * Renders a dimensional portal, for use in various situations. Code is mostly based @@ -22,165 +38,160 @@ public final class DimensionalPortalRenderer { // TODO * @param colors An array containing the color to use on each pass. Its length determines the number of passes to do. */ public static void renderDimensionalPortal(VertexConsumer vc, double x, double y, double z, Direction orientation, double width, double height, float[][] colors) { // TODO: Make this work at any angle -// RenderSystem.disableLighting(); -// RenderSystem.disableCull(); -// -// for (int pass = 0; pass < 16; pass++) { -// RenderSystem.pushMatrix(); -// -// float translationScale = 16 - pass; -// float scale = 0.2625F; -// float colorMultiplier = 1.0F / (translationScale + .80F); -// -// MinecraftClient.getInstance().getTextureManager().bindTexture(warpPath); -// RenderSystem.enableBlend(); -// -// if (pass == 0) { -// colorMultiplier = 0.1F; -// translationScale = 25.0F; -// scale = 0.125F; -// -// RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); -// } -// -// if (pass == 1) { -// scale = 0.5F; -// RenderSystem.blendFunc(GL11.GL_ONE, GL11.GL_ONE); -// } -// -// double offset = Minecraft.getSystemTime() % 200000L / 200000.0F; -// RenderSystem.translatef(offset, offset, offset); -// -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_LINEAR); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_LINEAR); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_LINEAR); -// -// if (orientation == Direction.UP || orientation == Direction.DOWN) { -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_EYE_LINEAR); -// } else { -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_OBJECT_LINEAR); -// } -// -// switch (orientation) { // TODO: Why 0.15F? Is that a door's thickness? If yes, don't hardcode that. -// case SOUTH: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, -0.15F)); -// break; -// case WEST: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.15F)); -// break; -// case NORTH: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.15F)); -// break; -// case EAST: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, -0.15F)); -// break; -// case UP: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_EYE_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// break; -// case DOWN: -// RenderSystem.texGen(RenderSystem.TexGen.S, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); -// RenderSystem.texGen(RenderSystem.TexGen.Q, GL11.GL_EYE_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); -// break; -// } -// -// RenderSystem.enableTexGenCoord(RenderSystem.TexGen.S); -// RenderSystem.enableTexGenCoord(RenderSystem.TexGen.T); -// RenderSystem.enableTexGenCoord(RenderSystem.TexGen.R); -// RenderSystem.enableTexGenCoord(RenderSystem.TexGen.Q); -// -// RenderSystem.popMatrix(); -// -// RenderSystem.matrixMode(GL11.GL_TEXTURE); -// RenderSystem.pushMatrix(); -// RenderSystem.loadIdentity(); -// RenderSystem.translatef(0.0F, offset * translationScale, 0.0F); -// RenderSystem.scaled(scale, scale, scale); -// RenderSystem.translatef(0.5F, 0.5F, 0.5F); -// RenderSystem.rotatef((pass * pass * 4321 + pass * 9) * 2.0F, 0.0F, 0.0F, 1.0F); -// RenderSystem.translatef(0.5F, 0.5F, 0.5F); -// -// Tessellator tessellator = Tessellator.getInstance(); -// BufferBuilder worldRenderer = tessellator.getBuffer(); -// worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION); -// -// RGBA color = colors[pass]; -// RenderSystem.color(color.getRed() * colorMultiplier, color.getGreen() * colorMultiplier, color.getBlue() * colorMultiplier, color.getAlpha()); -// -// switch (orientation) { -// case NORTH: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x, y + height, z).endVertex(); -// worldRenderer.pos(x + width, y + height, z).endVertex(); -// worldRenderer.pos(x + width, y, z).endVertex(); -// break; -// case SOUTH: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x + width, y, z).endVertex(); -// worldRenderer.pos(x + width, y + height, z).endVertex(); -// worldRenderer.pos(x, y + height, z).endVertex(); -// break; -// case WEST: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x, y, z + width).endVertex(); -// worldRenderer.pos(x, y + height, z + width).endVertex(); -// worldRenderer.pos(x, y + height, z).endVertex(); -// break; -// case EAST: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x, y + height, z).endVertex(); -// worldRenderer.pos(x, y + height, z + width).endVertex(); -// worldRenderer.pos(x, y, z + width).endVertex(); -// break; -// case UP: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x, y, z + width).endVertex(); -// worldRenderer.pos(x + width, y, z + width).endVertex(); -// worldRenderer.pos(x + width, y, z).endVertex(); -// break; -// case DOWN: -// worldRenderer.pos(x, y, z).endVertex(); -// worldRenderer.pos(x + width, y, z).endVertex(); -// worldRenderer.pos(x + width, y, z + width).endVertex(); -// worldRenderer.pos(x, y, z + width).endVertex(); -// break; -// } -// -// tessellator.draw(); -// -// RenderSystem.popMatrix(); -// RenderSystem.matrixMode(GL11.GL_MODELVIEW); -// } -// -// RenderSystem.disableBlend(); -// RenderSystem.disableTexGenCoord(RenderSystem.TexGen.S); -// RenderSystem.disableTexGenCoord(RenderSystem.TexGen.T); -// RenderSystem.disableTexGenCoord(RenderSystem.TexGen.R); -// RenderSystem.disableTexGenCoord(RenderSystem.TexGen.Q); -// RenderSystem.enableCull(); -// RenderSystem.enableLighting(); + RenderSystem.disableLighting(); + RenderSystem.disableCull(); + + for (int pass = 0; pass < 16; pass++) { + RenderSystem.pushMatrix(); + + float translationScale = 16 - pass; + float scale = 0.2625F; + float colorMultiplier = 1.0F / (translationScale + .80F); + + MinecraftClient.getInstance().getTextureManager().bindTexture(warpPath); + RenderSystem.enableBlend(); + + if (pass == 0) { + colorMultiplier = 0.1F; + translationScale = 25.0F; + scale = 0.125F; + + RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } + + if (pass == 1) { + scale = 0.5F; + RenderSystem.blendFunc(GL11.GL_ONE, GL11.GL_ONE); + } + + double offset = Util.getMeasuringTimeNano() % 200000L / 200000.0F; + RenderSystem.translated(offset, offset, offset); + + GlStateManager.texGenMode(S, GL11.GL_OBJECT_LINEAR); + GlStateManager.texGenMode(T, GL11.GL_OBJECT_LINEAR); + GlStateManager.texGenMode(R, GL11.GL_OBJECT_LINEAR); + + if (orientation == Direction.UP || orientation == Direction.DOWN) { + GlStateManager.texGenMode(Q, GL11.GL_EYE_LINEAR); + } else { + GlStateManager.texGenMode(Q, GL11.GL_OBJECT_LINEAR); + } + + switch (orientation) { // TODO: Why 0.15F? Is that a door's thickness? If yes, don't hardcode that. + case SOUTH: + GlStateManager.texGenParam(S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(T, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GlStateManager.texGenParam(Q, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, -0.15F)); + break; + case WEST: + GlStateManager.texGenParam(S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GlStateManager.texGenParam(R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GlStateManager.texGenParam(Q, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.15F)); + break; + case NORTH: + GlStateManager.texGenParam(S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(T, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GlStateManager.texGenParam(Q, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.15F)); + break; + case EAST: + GlStateManager.texGenParam(S, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GlStateManager.texGenParam(R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GlStateManager.texGenParam(Q, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, -0.15F)); + break; + case UP: + case DOWN: + GlStateManager.texGenParam(S, GL11.GL_OBJECT_PLANE, getBuffer(1.0F, 0.0F, 0.0F, 0.0F)); + GlStateManager.texGenParam(T, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 1.0F, 0.0F)); + GlStateManager.texGenParam(R, GL11.GL_OBJECT_PLANE, getBuffer(0.0F, 0.0F, 0.0F, 1.0F)); + GlStateManager.texGenParam(Q, GL11.GL_EYE_PLANE, getBuffer(0.0F, 1.0F, 0.0F, 0.0F)); + break; + } + + enableTexGen(S); + enableTexGen(T); + enableTexGen(R); + enableTexGen(Q); + + RenderSystem.popMatrix(); + + RenderSystem.matrixMode(GL11.GL_TEXTURE); + RenderSystem.pushMatrix(); + RenderSystem.loadIdentity(); + RenderSystem.translatef(0.0F, (float) (offset * translationScale), 0.0F); + RenderSystem.scaled(scale, scale, scale); + RenderSystem.translatef(0.5F, 0.5F, 0.5F); + RenderSystem.rotatef((pass * pass * 4321 + pass * 9) * 2.0F, 0.0F, 0.0F, 1.0F); + RenderSystem.translatef(0.5F, 0.5F, 0.5F); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder worldRenderer = tessellator.getBuffer(); + worldRenderer.begin(GL11.GL_QUADS, VertexFormats.POSITION); + + float[] color = colors[pass]; + RenderSystem.color4f(color[0] * colorMultiplier, color[1] * colorMultiplier, color[2] * colorMultiplier, color[3]); + + switch (orientation) { + case NORTH: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x, y + height, z).next(); + worldRenderer.vertex(x + width, y + height, z).next(); + worldRenderer.vertex(x + width, y, z).next(); + break; + case SOUTH: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x + width, y, z).next(); + worldRenderer.vertex(x + width, y + height, z).next(); + worldRenderer.vertex(x, y + height, z).next(); + break; + case WEST: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x, y, z + width).next(); + worldRenderer.vertex(x, y + height, z + width).next(); + worldRenderer.vertex(x, y + height, z).next(); + break; + case EAST: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x, y + height, z).next(); + worldRenderer.vertex(x, y + height, z + width).next(); + worldRenderer.vertex(x, y, z + width).next(); + break; + case UP: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x, y, z + width).next(); + worldRenderer.vertex(x + width, y, z + width).next(); + worldRenderer.vertex(x + width, y, z).next(); + break; + case DOWN: + worldRenderer.vertex(x, y, z).next(); + worldRenderer.vertex(x + width, y, z).next(); + worldRenderer.vertex(x + width, y, z + width).next(); + worldRenderer.vertex(x, y, z + width).next(); + break; + } + + tessellator.draw(); + + RenderSystem.popMatrix(); + RenderSystem.matrixMode(GL11.GL_MODELVIEW); + } + + RenderSystem.disableBlend(); + GlStateManager.disableTexGen(S); + GlStateManager.disableTexGen(T); + GlStateManager.disableTexGen(R); + GlStateManager.disableTexGen(Q); + RenderSystem.enableCull(); + RenderSystem.enableLighting(); + } + + private static FloatBuffer getBuffer(float f1, float f2, float f3, float f4) { + buffer.clear(); + buffer.put(f1).put(f2).put(f3).put(f4); + buffer.flip(); + return buffer; } -// -// private static FloatBuffer getBuffer(float f1, float f2, float f3, float f4) { -// buffer.clear(); -// buffer.put(f1).put(f2).put(f3).put(f4); -// buffer.flip(); -// return buffer; -// } } diff --git a/src/main/java/org/dimdev/dimdoors/client/EntranceRiftBlockEntityRenderer.java b/src/main/java/org/dimdev/dimdoors/client/EntranceRiftBlockEntityRenderer.java index 6568c44b..6101a4f5 100644 --- a/src/main/java/org/dimdev/dimdoors/client/EntranceRiftBlockEntityRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/EntranceRiftBlockEntityRenderer.java @@ -1,12 +1,16 @@ package org.dimdev.dimdoors.client; +import com.mojang.blaze3d.systems.RenderSystem; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; import net.minecraft.client.render.block.entity.BlockEntityRenderer; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import org.dimdev.dimdoors.block.entity.EntranceRiftBlockEntity; @Environment(EnvType.CLIENT) @@ -20,26 +24,23 @@ public class EntranceRiftBlockEntityRenderer extends BlockEntityRenderer= 1) { -// for (int i = 0; i < 1 + entrance.lockStatus; i++) { -// renderKeyHole(entrance, x, y, z, i); -// } -// } + /*Direction orientation = entrance.getOrientation(); + Vec3d offset = new Vec3d(orientation.getOpposite().getUnitVector().scale(orientation == Direction.NORTH || orientation == Direction.WEST || orientation == Direction.UP ? entrance.pushIn : entrance.pushIn - 1)); + DimensionalPortalRenderer.renderDimensionalPortal( + x + offset.x, + y + offset.y, + z + offset.z, + //entrance.orientation.getHorizontalAngle(), + //entrance.orientation.getDirectionVec().getY() * 90, + orientation, + extendLeft + entrance.extendRight, + extendDown + entrance.extendUp, + entrance.getColors(16));*/ + + /*if (entrance.lockStatus >= 1) { + for (int i = 0; i < 1 + entrance.lockStatus; i++) { + renderKeyHole(entrance, x, y, z, i); + } + }*/ } } diff --git a/src/main/java/org/dimdev/dimdoors/client/MonolithModel.java b/src/main/java/org/dimdev/dimdoors/client/MonolithModel.java index 468d3129..7ddbf9c1 100644 --- a/src/main/java/org/dimdev/dimdoors/client/MonolithModel.java +++ b/src/main/java/org/dimdev/dimdoors/client/MonolithModel.java @@ -1,34 +1,37 @@ -//package org.dimdev.dimdoors.client; -// -//import net.fabricmc.api.EnvType; -//import net.fabricmc.api.Environment; -//import net.minecraft.client.model.Model; -//import net.minecraft.client.model.ModelBase; -//import net.minecraft.client.model.ModelPart; -//import net.minecraft.client.model.ModelRenderer; -//import net.minecraft.client.renderer.RenderSystem; -//import net.minecraft.entity.Entity; -//import org.dimdev.dimdoors.entity.MonolithEntity; -// -//@Environment(EnvType.CLIENT) -//public class MonolithModel extends Model { -// private final ModelPart body; -// -// public MonolithModel() { -// super(); -// textureWidth = 256; -// textureHeight = 256; -// -// body = new ModelPart(this, 0, 0); -// body.addBox(-24F, -108F / 1.3F, -6F, 48, 108, 12); -// } -// -// @Override -// public void render(Entity entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) { -// MonolithEntity monolith = (MonolithEntity) entity; -// -// setRotationAngles(0, 0, 0, 0, 0, 0, monolith); -// RenderSystem.scale(monolith.getRenderSizeModifier(), monolith.getRenderSizeModifier(), monolith.getRenderSizeModifier()); -// this.body.render(scale); -// } -//} +package org.dimdev.dimdoors.client; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.util.math.MatrixStack; +import org.dimdev.dimdoors.entity.MonolithEntity; + +@Environment(EnvType.CLIENT) +public class MonolithModel extends EntityModel { + private final ModelPart body; + + public MonolithModel() { + super(); + textureWidth = 256; + textureHeight = 256; + + body = new ModelPart(this, 0, 0); + body.addCuboid(-24F, -108F / 1.3F, -6F, 48, 108, 12); + } + + @Override + public void setAngles(MonolithEntity entity, float f, float g, float h, float i, float j) { + + } + + @Override + public void animateModel(MonolithEntity entity, float f, float g, float h) { + } + + @Override + public void render(MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j, float f, float g, float h, float k) { + this.body.render(matrixStack, vertexConsumer, i, j, f, g, h, k); + } +} diff --git a/src/main/java/org/dimdev/dimdoors/entity/MonolithEntity.java b/src/main/java/org/dimdev/dimdoors/entity/MonolithEntity.java index a1f8da89..ace097f1 100644 --- a/src/main/java/org/dimdev/dimdoors/entity/MonolithEntity.java +++ b/src/main/java/org/dimdev/dimdoors/entity/MonolithEntity.java @@ -1,8 +1,31 @@ package org.dimdev.dimdoors.entity; +import com.flowpowered.math.vector.Vector3f; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.mob.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.sound.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.dimdev.dimdoors.ModConfig; +import org.dimdev.dimdoors.sound.ModSoundEvents; +import org.dimdev.dimdoors.world.limbo.LimboDimension; +import org.dimdev.dimdoors.world.pocketdimension.DungeonPocketDimension; +import org.dimdev.util.Location; +import org.dimdev.util.TeleportUtil; + +import static net.minecraft.entity.attribute.EntityAttributes.MAX_HEALTH; public class MonolithEntity extends MobEntity { private static final int MAX_AGGRO = 250; @@ -11,230 +34,241 @@ public class MonolithEntity extends MobEntity { private static final int MAX_TEXTURE_STATE = 18; private static final int MAX_SOUND_COOLDOWN = 200; private static final int MAX_AGGRO_RANGE = 35; - // private static final DataParameter AGGRO = EntityDataManager.createKey(MonolithEntity.class, VARINT); + private static final TrackedData AGGRO = DataTracker.registerData(MonolithEntity.class, TrackedDataHandlerRegistry.INTEGER); private static final float EYE_HEIGHT = 1.5f; public float pitchLevel; private int aggro = 0; private int soundTime = 0; -// private final int aggroCap; + private final int aggroCap; public MonolithEntity(EntityType type, World world) { super(type, world); -// noClip = true; -// aggroCap = MathHelper.getInt(rand, MIN_AGGRO_CAP, MAX_AGGRO_CAP); + noClip = true; + aggroCap = MathHelper.nextInt(getRandom(), MIN_AGGRO_CAP, MAX_AGGRO_CAP); } -// -// public boolean isDangerous() { -// return ModConfig.MONOLITHS.monolithTeleportation && (world.dimension instanceof LimboDimension || ModConfig.MONOLITHS.dangerousLimboMonoliths); -// } -// -// @Override -// public boolean attackEntityFrom(DamageSource source, float amount) { -// if (source != DamageSource.IN_WALL) { -// aggro = MAX_AGGRO; -// } -// return false; -// } -// -// @Override -// public boolean canBreatheUnderwater() { -// return true; -// } -// -// @Override -// public Box getCollisionBoundingBox() { -// return null; -// } -// -// @Override -// public Box getCollisionBox(Entity entity) { -// return null; -// } -// -// @Override -// public boolean canDespawn() { -// return false; -// } -// -// @Override -// protected void applyEntityAttributes() { -// super.applyEntityAttributes(); -// getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(57005); -// } -// + + public boolean isDangerous() { + return false; //return ModConfig.MONOLITHS.monolithTeleportation && (world.dimension instanceof LimboDimension || ModConfig.MONOLITHS.dangerousLimboMonoliths); + } + + @Override + public boolean damage(DamageSource source, float amount) { + if (source != DamageSource.IN_WALL) { + aggro = MAX_AGGRO; + } + return false; + } + + @Override + public int getMaxAir() { + return super.getMaxAir(); + } + + @Override + protected int getNextAirUnderwater(int i) { + return 10; + } + + @Override + protected int getNextAirOnLand(int i) { + return 10; + } + + @Override + public Box getCollisionBox() { + return null; + } + + @Override + public Box getHardCollisionBox(Entity entity) { + return null; + } + + @Override + public boolean cannotDespawn() { + return true; + } + + @Override + protected void initAttributes() { + super.initAttributes(); + getAttributes().get(MAX_HEALTH).setBaseValue(57005); + } + // @Override // public boolean canBePushed() { // return false; // } // -// @Override -// public float getEyeHeight() { -// return EYE_HEIGHT; -// } -// -// @Override -// protected void entityInit() { -// super.entityInit(); -// // Add a short for the aggro level -// dataManager.register(AGGRO, 0); -// } -// -// @Override -// public boolean isEntityAlive() { -// return false; -// } -// -// @Override -// public void onEntityUpdate() { -// // Remove this Monolith if it's not in Limbo or in a pocket dungeon -// if (!(world.dimension instanceof LimboDimension || world.dimension instanceof DungeonPocketDimension)) { -// setDead(); -// super.onEntityUpdate(); -// return; -// } -// -// super.onEntityUpdate(); -// -// // Check for players and update aggro levels even if there are no players in range -// PlayerEntity player = world.getClosestPlayerToEntity(this, MAX_AGGRO_RANGE); -// boolean visibility = player != null && player.canEntityBeSeen(this); -// updateAggroLevel(player, visibility); -// -// // Change orientation and face a player if one is in range -// if (player != null) { -// facePlayer(player); -// if (!world.isClient && isDangerous()) { -// // Play sounds on the server side, if the player isn't in Limbo. -// // Limbo is excluded to avoid drowning out its background music. -// // Also, since it's a large open area with many Monoliths, some -// // of the sounds that would usually play for a moment would -// // keep playing constantly and would get very annoying. -// playSounds(player.getPosition()); -// } -// -// if (visibility) { -// // Only spawn particles on the client side and outside Limbo -// if (world.isClient && isDangerous()) { -// spawnParticles(player); -// } -// -// // Teleport the target player if various conditions are met -// if (aggro >= MAX_AGGRO && !world.isClient && ModConfig.MONOLITHS.monolithTeleportation && !player.isCreative() && isDangerous()) { -// aggro = 0; + + + @Override + public double getEyeY() { + return super.getEyeY(); + } + + @Override + protected void initDataTracker() { + super.initDataTracker(); + // Add a short for the aggro level + dataTracker.startTracking(AGGRO, 0); + } + + @Override + public boolean isAlive() { + return false; + } + + @Override + protected void mobTick() { + // Remove this Monolith if it's not in Limbo or in a pocket dungeon + if (!(world.dimension instanceof LimboDimension || world.dimension instanceof DungeonPocketDimension)) { + remove(); + super.mobTick(); + return; + } + + super.mobTick(); + + // Check for players and update aggro levels even if there are no players in range + PlayerEntity player = world.getClosestPlayer(this, MAX_AGGRO_RANGE); + boolean visibility = player != null && player.canSee(this); + updateAggroLevel(player, visibility); + + // Change orientation and face a player if one is in range + if (player != null) { + facePlayer(player); + if (!world.isClient && isDangerous()) { + // Play sounds on the server side, if the player isn't in Limbo. + // Limbo is excluded to avoid drowning out its background music. + // Also, since it's a large open area with many Monoliths, some + // of the sounds that would usually play for a moment would + // keep playing constantly and would get very annoying. + playSounds(player.getPos()); + } + + if (visibility) { + // Only spawn particles on the client side and outside Limbo + if (world.isClient && isDangerous()) { + spawnParticles(player); + } + + // Teleport the target player if various conditions are met + if (aggro >= MAX_AGGRO && !world.isClient && ModConfig.MONOLITHS.monolithTeleportation && !player.isCreative() && isDangerous()) { + aggro = 0; // Location destination = LimboDimension.getLimboSkySpawn(player); // TeleportUtil.teleport(player, destination, 0, 0); -// player.world.playSound(null, player.getPosition(), ModSoundEvents.CRACK, SoundCategory.HOSTILE, 13, 1); -// } -// } -// } -// } -// -// private void updateAggroLevel(PlayerEntity player, boolean visibility) { -// // If we're working on the server side, adjust aggro level -// // If we're working on the client side, retrieve aggro level from dataWatcher -// if (!world.isClient) { -// // Server side... -// // Rapidly increase the aggro level if this Monolith can see the player -// if (visibility) { -// if (world.dimension instanceof LimboDimension) { -// if (isDangerous()) { -// aggro++; -// } else { -// aggro += 36; -// } -// } else { -// // Aggro increases faster outside of Limbo -// aggro += 3; -// } -// } else { -// if (isDangerous()) { -// if (aggro > aggroCap) { -// // Decrease aggro over time -// aggro--; -// } else if (player != null && aggro < aggroCap) { -// // Increase aggro if a player is within range and aggro < aggroCap -// aggro++; -// } -// } else { -// aggro -= 3; -// } -// } -// // Clamp the aggro level -// int maxAggro = isDangerous() ? MAX_AGGRO : 180; -// aggro = (short) MathHelper.clamp(aggro, 0, maxAggro); -// dataManager.set(AGGRO, aggro); -// } else { -// // Client side... -// aggro = dataManager.get(AGGRO); -// } -// } -// -// public int getTextureState() { -// // Determine texture state from aggro progress -// return MathHelper.clamp(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE); -// } -// -// /** -// * Plays sounds at different levels of aggro, using soundTime to prevent too many sounds at once. -// * -// * @param pos The position to play the sounds at -// */ -// private void playSounds(BlockPos pos) { -// float aggroPercent = getAggroProgress(); -// if (soundTime <= 0) { -// playSound(ModSoundEvents.MONK, 1F, 1F); -// soundTime = 100; -// } -// if (aggroPercent > 0.70 && soundTime < 100) { -// world.playSound(null, pos, ModSoundEvents.TEARING, SoundCategory.HOSTILE, 1F, (float) (1 + rand.nextGaussian())); -// soundTime = 100 + rand.nextInt(75); -// } -// if (aggroPercent > 0.80 && soundTime < MAX_SOUND_COOLDOWN) { -// world.playSound(null, pos, ModSoundEvents.TEARING, SoundCategory.HOSTILE, 7, 1F); -// soundTime = 250; -// } -// soundTime--; -// } -// -// private void spawnParticles(PlayerEntity player) { -// int count = 10 * aggro / MAX_AGGRO; -// for (int i = 1; i < count; ++i) { -// player.world.spawnParticle(EnumParticleTypes.PORTAL, player.posX + (rand.nextDouble() - 0.5D) * width, -// player.posY + rand.nextDouble() * player.height - 0.75D, -// player.posZ + (rand.nextDouble() - 0.5D) * player.width, -// (rand.nextDouble() - 0.5D) * 2.0D, -rand.nextDouble(), -// (rand.nextDouble() - 0.5D) * 2.0D); -// } -// } -// -// public float getAggroProgress() { -// return (float) aggro / MAX_AGGRO; -// } -// -// private void facePlayer(PlayerEntity player) { -// double d0 = player.posX - posX; -// double d1 = player.posZ - posZ; -// double d2 = player.posY + player.getEyeHeight() - (posY + EYE_HEIGHT); -// double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1); -// float f2 = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; -// pitchLevel = (float) -(Math.atan(d2 / d3) * 180.0D / Math.PI); -// rotationYaw = f2; -// rotationYawHead = f2; -// renderYawOffset = rotationYaw; -// } -// -// -// @Override -// public CompoundTag toTag(CompoundTag tag) { -// super.toTag(tag); -// tag.putInt("Aggro", aggro); -// return tag; -// } -// -// @Override -// public void fromTag(CompoundTag nbt) { -// super.readEntityFromNBT(nbt); -// aggro = nbt.getInteger("Aggro"); -// } + player.world.playSound(null, new BlockPos(player.getPos()), ModSoundEvents.CRACK, SoundCategory.HOSTILE, 13, 1); + } + } + } + } + + private void updateAggroLevel(PlayerEntity player, boolean visibility) { + // If we're working on the server side, adjust aggro level + // If we're working on the client side, retrieve aggro level from dataWatcher + if (!world.isClient) { + // Server side... + // Rapidly increase the aggro level if this Monolith can see the player + if (visibility) { + if (world.dimension instanceof LimboDimension) { + if (isDangerous()) { + aggro++; + } else { + aggro += 36; + } + } else { + // Aggro increases faster outside of Limbo + aggro += 3; + } + } else { + if (isDangerous()) { + if (aggro > aggroCap) { + // Decrease aggro over time + aggro--; + } else if (player != null && aggro < aggroCap) { + // Increase aggro if a player is within range and aggro < aggroCap + aggro++; + } + } else { + aggro -= 3; + } + } + // Clamp the aggro level + int maxAggro = isDangerous() ? MAX_AGGRO : 180; + aggro = (short) MathHelper.clamp(aggro, 0, maxAggro); + dataTracker.set(AGGRO, aggro); + } else { + // Client side... + aggro = dataTracker.get(AGGRO); + } + } + + public int getTextureState() { + // Determine texture state from aggro progress + return MathHelper.clamp(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE); + } + + /** + * Plays sounds at different levels of aggro, using soundTime to prevent too many sounds at once. + * + * @param pos The position to play the sounds at + */ + private void playSounds(Vec3d pos) { + float aggroPercent = getAggroProgress(); + if (soundTime <= 0) { + playSound(ModSoundEvents.MONK, 1F, 1F); + soundTime = 100; + } + if (aggroPercent > 0.70 && soundTime < 100) { + world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 1F, (float) (1 + getRandom().nextGaussian())); + soundTime = 100 + getRandom().nextInt(75); + } + if (aggroPercent > 0.80 && soundTime < MAX_SOUND_COOLDOWN) { + world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 7, 1F); + soundTime = 250; + } + soundTime--; + } + + private void spawnParticles(PlayerEntity player) { + int count = 10 * aggro / MAX_AGGRO; + for (int i = 1; i < count; ++i) { + player.world.addParticle(ParticleTypes.PORTAL, player.getX() + (getRandom().nextDouble() - 0.5D) * getWidth(), + player.getY() + getRandom().nextDouble() * player.getHeight() - 0.75D, + player.getZ() + (getRandom().nextDouble() - 0.5D) * player.getWidth(), + (getRandom().nextDouble() - 0.5D) * 2.0D, -getRandom().nextDouble(), + (getRandom().nextDouble() - 0.5D) * 2.0D); + } + } + + public float getAggroProgress() { + return (float) aggro / MAX_AGGRO; + } + + private void facePlayer(PlayerEntity player) { + double d0 = player.getX() - getX(); + double d1 = player.getZ() - getY(); + double d2 = player.getY() + player.getEyeHeight(player.getPose()) - (getY() + EYE_HEIGHT); + double d3 = MathHelper.sqrt(d0 * d0 + d1 * d1); + float f2 = (float) (Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; + setRotation((float) -(Math.atan(d2 / d3) * 180.0D / Math.PI), f2); + setYaw(f2); + setHeadYaw(f2); + //renderYawOffset = rotationYaw; + } + + @Override + public CompoundTag toTag(CompoundTag tag) { + super.toTag(tag); + tag.putInt("Aggro", aggro); + return tag; + } + + @Override + public void fromTag(CompoundTag nbt) { + super.fromTag(nbt); + aggro = nbt.getInt("Aggro"); + } } diff --git a/src/main/java/org/dimdev/dimdoors/entity/MonolithRenderer.java b/src/main/java/org/dimdev/dimdoors/entity/MonolithRenderer.java index 0a2e93e4..f6e7a803 100644 --- a/src/main/java/org/dimdev/dimdoors/entity/MonolithRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/entity/MonolithRenderer.java @@ -1,16 +1,28 @@ package org.dimdev.dimdoors.entity; import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Identifier; +import org.dimdev.dimdoors.client.MonolithModel; public class MonolithRenderer extends EntityRenderer { - private final EntityRendererRegistry.Context context; + private MonolithModel model = new MonolithModel(); protected MonolithRenderer(EntityRenderDispatcher dispatcher, EntityRendererRegistry.Context context) { super(dispatcher); - this.context = context; + } + + @Override + public void render(MonolithEntity entity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i) { + super.render(entity, f, g, matrixStack, vertexConsumerProvider, i); + + matrixStack.push(); + //model.render(entity); + matrixStack.pop(); + } @Override diff --git a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboBiome.java b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboBiome.java index f145ca76..368b20d7 100644 --- a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboBiome.java +++ b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboBiome.java @@ -16,9 +16,9 @@ public class LimboBiome extends Biome { .configureSurfaceBuilder( SurfaceBuilder.DEFAULT, new TernarySurfaceConfig( - ModBlocks.BLACK_FABRIC.getDefaultState(), - ModBlocks.BLACK_FABRIC.getDefaultState(), - ModBlocks.BLACK_FABRIC.getDefaultState() + ModBlocks.UNRAVELLED_FABRIC.getDefaultState(), + ModBlocks.UNRAVELLED_FABRIC.getDefaultState(), + ModBlocks.ETERNAL_FLUID.getDefaultState() ) ) .precipitation(Biome.Precipitation.NONE).category(Biome.Category.NETHER) @@ -39,6 +39,6 @@ public class LimboBiome extends Biome { .noises(ImmutableList.of(new Biome.MixedNoisePoint(0.0F, 0.0F, 0.0F, -0.5F, 1.0F)))); - addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(ModEntityTypes.MONOLITH, 100, 1, 1)); + //addSpawn(EntityCategory.MONSTER, new Biome.SpawnEntry(ModEntityTypes.MONOLITH, 100, 1, 1)); } } diff --git a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboChunkGenerator.java b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboChunkGenerator.java index 5af172cc..50e2ddec 100644 --- a/src/main/java/org/dimdev/dimdoors/world/limbo/LimboChunkGenerator.java +++ b/src/main/java/org/dimdev/dimdoors/world/limbo/LimboChunkGenerator.java @@ -15,25 +15,25 @@ public class LimboChunkGenerator extends SurfaceChunkGenerator