|
@@ -0,0 +1,147 @@
|
|
|
+package me.shedaniel.lightoverlay;
|
|
|
+
|
|
|
+import com.mojang.blaze3d.platform.GlStateManager;
|
|
|
+import net.minecraft.block.BlockState;
|
|
|
+import net.minecraft.block.Blocks;
|
|
|
+import net.minecraft.client.Minecraft;
|
|
|
+import net.minecraft.client.entity.player.ClientPlayerEntity;
|
|
|
+import net.minecraft.client.renderer.ActiveRenderInfo;
|
|
|
+import net.minecraft.client.renderer.BufferBuilder;
|
|
|
+import net.minecraft.client.renderer.Tessellator;
|
|
|
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
|
+import net.minecraft.client.settings.KeyBinding;
|
|
|
+import net.minecraft.client.util.InputMappings;
|
|
|
+import net.minecraft.entity.Entity;
|
|
|
+import net.minecraft.entity.EntityClassification;
|
|
|
+import net.minecraft.entity.EntityType;
|
|
|
+import net.minecraft.entity.player.PlayerEntity;
|
|
|
+import net.minecraft.util.ResourceLocation;
|
|
|
+import net.minecraft.util.math.BlockPos;
|
|
|
+import net.minecraft.util.math.shapes.VoxelShape;
|
|
|
+import net.minecraft.util.text.TranslationTextComponent;
|
|
|
+import net.minecraft.world.LightType;
|
|
|
+import net.minecraft.world.World;
|
|
|
+import net.minecraftforge.api.distmarker.Dist;
|
|
|
+import net.minecraftforge.api.distmarker.OnlyIn;
|
|
|
+import net.minecraftforge.client.event.InputEvent;
|
|
|
+import net.minecraftforge.client.event.RenderWorldLastEvent;
|
|
|
+import net.minecraftforge.client.settings.KeyConflictContext;
|
|
|
+import net.minecraftforge.client.settings.KeyModifier;
|
|
|
+import net.minecraftforge.common.MinecraftForge;
|
|
|
+import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|
|
+import net.minecraftforge.fml.client.registry.ClientRegistry;
|
|
|
+import net.minecraftforge.fml.common.Mod;
|
|
|
+
|
|
|
+import java.awt.*;
|
|
|
+
|
|
|
+@OnlyIn(Dist.CLIENT)
|
|
|
+@Mod("lightoverlay-forge")
|
|
|
+public class LightOverlay {
|
|
|
+
|
|
|
+ private static final String KEYBIND_CATEGORY = "key.lightoverlay-forge.category";
|
|
|
+ private static final ResourceLocation ENABLE_OVERLAY_KEYBIND = new ResourceLocation("lightoverlay-forge", "enable_overlay");
|
|
|
+ private static final ResourceLocation INCREASE_REACH_KEYBIND = new ResourceLocation("lightoverlay-forge", "increase_reach");
|
|
|
+ private static final ResourceLocation DECREASE_REACH_KEYBIND = new ResourceLocation("lightoverlay-forge", "decrease_reach");
|
|
|
+ private static KeyBinding enableOverlay, increaseReach, decreaseReach;
|
|
|
+ private static boolean enabled = false;
|
|
|
+ private static int reach = 12;
|
|
|
+ private static EntityType<Entity> testingEntityType;
|
|
|
+
|
|
|
+ public LightOverlay() {
|
|
|
+ testingEntityType = EntityType.Builder.create(EntityClassification.MONSTER).size(0f, 0f).disableSerialization().build(null);
|
|
|
+ enableOverlay = registerKeybind(ENABLE_OVERLAY_KEYBIND, InputMappings.Type.KEYSYM, 296, KEYBIND_CATEGORY);
|
|
|
+ increaseReach = registerKeybind(INCREASE_REACH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY);
|
|
|
+ decreaseReach = registerKeybind(DECREASE_REACH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY);
|
|
|
+ MinecraftForge.EVENT_BUS.register(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static CrossType getCrossType(BlockPos pos, World world, PlayerEntity playerEntity) {
|
|
|
+ BlockState blockBelowState = world.getBlockState(pos.down());
|
|
|
+ BlockState blockState = world.getBlockState(pos);
|
|
|
+ if (blockBelowState.isAir() || !blockState.isAir())
|
|
|
+ return CrossType.NONE;
|
|
|
+ if (blockBelowState.getBlock() == Blocks.BEDROCK || blockBelowState.getBlock() == Blocks.BARRIER)
|
|
|
+ return CrossType.NONE;
|
|
|
+ if (!blockBelowState.canEntitySpawn(world, pos.down(), testingEntityType))
|
|
|
+ return CrossType.NONE;
|
|
|
+ if (world.getLightFor(LightType.BLOCK, pos) >= 8)
|
|
|
+ return CrossType.NONE;
|
|
|
+ if (world.getLightFor(LightType.SKY, pos) >= 8)
|
|
|
+ return CrossType.YELLOW;
|
|
|
+ return CrossType.RED;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void renderCross(BlockPos pos, Color color, PlayerEntity entity) {
|
|
|
+ ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
|
|
+ GlStateManager.lineWidth(1.0F);
|
|
|
+ GlStateManager.depthMask(false);
|
|
|
+ GlStateManager.disableTexture();
|
|
|
+ Tessellator tessellator = Tessellator.getInstance();
|
|
|
+ BufferBuilder buffer = tessellator.getBuffer();
|
|
|
+ double d0 = info.getProjectedView().x;
|
|
|
+ double d1 = info.getProjectedView().y - .005D;
|
|
|
+ double d2 = info.getProjectedView().z;
|
|
|
+
|
|
|
+ buffer.begin(1, DefaultVertexFormats.POSITION_COLOR);
|
|
|
+ buffer.pos(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
|
|
|
+ buffer.pos(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
|
|
|
+ buffer.pos(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
|
|
|
+ buffer.pos(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()).endVertex();
|
|
|
+ tessellator.draw();
|
|
|
+ GlStateManager.depthMask(true);
|
|
|
+ GlStateManager.enableTexture();
|
|
|
+ }
|
|
|
+
|
|
|
+ @SubscribeEvent(receiveCanceled = true)
|
|
|
+ public void handleInput(InputEvent.KeyInputEvent event) {
|
|
|
+ if (enableOverlay.isPressed())
|
|
|
+ enabled = !enabled;
|
|
|
+ if (increaseReach.isPressed()) {
|
|
|
+ if (reach < 50)
|
|
|
+ reach++;
|
|
|
+ Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_reach", reach), false);
|
|
|
+ }
|
|
|
+ if (decreaseReach.isPressed()) {
|
|
|
+ if (reach > 1)
|
|
|
+ reach--;
|
|
|
+ Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_reach", reach), false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @SubscribeEvent
|
|
|
+ public void renderWorldLast(RenderWorldLastEvent event) {
|
|
|
+ if (LightOverlay.enabled) {
|
|
|
+ Minecraft client = Minecraft.getInstance();
|
|
|
+ ClientPlayerEntity playerEntity = client.player;
|
|
|
+ World world = client.world;
|
|
|
+ GlStateManager.disableTexture();
|
|
|
+ GlStateManager.disableBlend();
|
|
|
+ BlockPos playerPos = new BlockPos(playerEntity.posX, playerEntity.posY, playerEntity.posZ);
|
|
|
+ BlockPos.getAllInBox(playerPos.add(-reach, -reach, -reach), playerPos.add(reach, reach, reach)).forEach(pos -> {
|
|
|
+ if (world.getBiome(pos).getSpawningChance() > 0) {
|
|
|
+ CrossType type = LightOverlay.getCrossType(pos, world, playerEntity);
|
|
|
+ if (type != CrossType.NONE) {
|
|
|
+ VoxelShape shape = world.getBlockState(pos).getCollisionShape(world, pos);
|
|
|
+ Color color = type == CrossType.RED ? Color.RED : Color.YELLOW;
|
|
|
+ LightOverlay.renderCross(pos, color, playerEntity);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ GlStateManager.enableBlend();
|
|
|
+ GlStateManager.enableTexture();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private KeyBinding registerKeybind(ResourceLocation resourceLocation, InputMappings.Type type, int keyCode, String category) {
|
|
|
+ KeyBinding keyBinding = new KeyBinding("key." + resourceLocation.getNamespace() + "." + resourceLocation.getPath(), KeyConflictContext.IN_GAME, KeyModifier.NONE, type, keyCode, category);
|
|
|
+ ClientRegistry.registerKeyBinding(keyBinding);
|
|
|
+ return keyBinding;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static enum CrossType {
|
|
|
+ YELLOW,
|
|
|
+ RED,
|
|
|
+ NONE
|
|
|
+ }
|
|
|
+
|
|
|
+}
|