From 6f185d4540bf21bb1b4151848200e19ab87db26e Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 7 Nov 2019 11:30:29 +0100 Subject: [PATCH] Finite Energy - Added a torque system with stress vs capacity scores for networks. - Added config values for stress and capacity - Added rainbow debug (tm) - Added infinite new bugs --- .../java/com/simibubi/create/AllRecipes.java | 6 + .../com/simibubi/create/ClientEvents.java | 15 +- src/main/java/com/simibubi/create/Create.java | 6 +- .../com/simibubi/create/CreateConfig.java | 98 +++++++++++- .../foundation/utility/BufferManipulator.java | 24 ++- .../create/foundation/utility/Debug.java | 47 ++++++ .../create/foundation/utility/Lang.java | 19 --- .../create/foundation/utility/TreeCutter.java | 141 ++++++++++++++++++ .../modules/contraptions/KineticDebugger.java | 85 +++++++++++ .../modules/contraptions/KineticNetwork.java | 107 +++++++------ .../contraptions/RotationPropagator.java | 68 ++++----- .../contraptions/TorquePropagator.java | 17 +-- .../base/GeneratingKineticTileEntity.java | 71 +++++++++ .../contraptions/base/KineticBlock.java | 4 +- .../contraptions/base/KineticTileEntity.java | 126 ++++++++++------ .../base/KineticTileEntityRenderer.java | 19 ++- .../generators/ConfigureMotorPacket.java | 7 +- .../contraptions/generators/MotorBlock.java | 4 +- .../generators/MotorTileEntity.java | 67 +++++---- .../generators/WaterWheelBlock.java | 2 +- .../generators/WaterWheelTileEntity.java | 39 +---- .../receivers/BasinTileEntity.java | 9 ++ .../receivers/CrushingRecipe.java | 5 +- .../CrushingWheelControllerBlock.java | 6 + .../CrushingWheelControllerTileEntity.java | 55 +------ .../contraptions/receivers/CuttingRecipe.java | 27 ++++ .../receivers/DrillTileEntity.java | 4 +- .../receivers/EncasedFanTileEntity.java | 38 ++--- .../receivers/MechanicalMixerTileEntity.java | 8 +- .../contraptions/receivers/MixingRecipe.java | 60 ++++++++ .../receivers/ProcessingInventory.java | 53 +++++++ .../contraptions/receivers/SawBlock.java | 29 ++++ .../contraptions/receivers/SawTileEntity.java | 29 +++- .../MechanicalBearingTileEntity.java | 64 +++----- .../MechanicalPistonTileEntity.java | 4 +- .../contraptions/relays/GearshiftBlock.java | 5 +- .../contraptions/relays/belt/BeltItem.java | 4 +- .../relays/belt/BeltTileEntity.java | 10 +- .../deforester/DeforesterItem.java | 27 ++++ 39 files changed, 1016 insertions(+), 393 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/utility/Debug.java create mode 100644 src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/receivers/CuttingRecipe.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/receivers/MixingRecipe.java create mode 100644 src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java diff --git a/src/main/java/com/simibubi/create/AllRecipes.java b/src/main/java/com/simibubi/create/AllRecipes.java index 659f6321f..64a33d3a1 100644 --- a/src/main/java/com/simibubi/create/AllRecipes.java +++ b/src/main/java/com/simibubi/create/AllRecipes.java @@ -5,6 +5,8 @@ import java.util.function.Supplier; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.ProcessingRecipeSerializer; import com.simibubi.create.modules.contraptions.receivers.CrushingRecipe; +import com.simibubi.create.modules.contraptions.receivers.CuttingRecipe; +import com.simibubi.create.modules.contraptions.receivers.MixingRecipe; import com.simibubi.create.modules.contraptions.receivers.PressingRecipe; import com.simibubi.create.modules.contraptions.receivers.SplashingRecipe; import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunUpgradeRecipe; @@ -23,6 +25,8 @@ public enum AllRecipes { CRUSHING(() -> new ProcessingRecipeSerializer<>(CrushingRecipe::new), Types.CRUSHING), SPLASHING(() -> new ProcessingRecipeSerializer<>(SplashingRecipe::new), Types.SPLASHING), PRESSING(() -> new ProcessingRecipeSerializer<>(PressingRecipe::new), Types.PRESSING), + CUTTING(() -> new ProcessingRecipeSerializer<>(CuttingRecipe::new), Types.CUTTING), + MIXING(() -> new ProcessingRecipeSerializer<>(MixingRecipe::new), Types.MIXING), ; @@ -30,6 +34,8 @@ public enum AllRecipes { public static IRecipeType CRUSHING = register("crushing"); public static IRecipeType SPLASHING = register("splashing"); public static IRecipeType PRESSING = register("pressing"); + public static IRecipeType CUTTING = register("cutting"); + public static IRecipeType MIXING = register("mixing"); static > IRecipeType register(final String key) { return Registry.register(Registry.RECIPE_TYPE, new ResourceLocation(key), new IRecipeType() { diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/ClientEvents.java index 0e8739337..d33ca1cff 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/ClientEvents.java @@ -7,6 +7,8 @@ import com.simibubi.create.foundation.block.IBlockWithScrollableValue; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.TooltipHelper; +import com.simibubi.create.modules.contraptions.KineticDebugger; +import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.receivers.TurntableHandler; import com.simibubi.create.modules.contraptions.relays.belt.BeltItemHandler; @@ -37,12 +39,17 @@ public class ClientEvents { public static void onTick(ClientTickEvent event) { if (event.phase == Phase.START) return; - + AnimationTickHolder.tick(); - + if (!isGameActive()) return; + if (!KineticDebugger.isActive() && KineticTileEntityRenderer.rainbowMode) { + KineticTileEntityRenderer.rainbowMode = false; + KineticTileEntityRenderer.invalidateCache(); + } + ScreenOpener.tick(); onGameTick(); } @@ -57,6 +64,7 @@ public class ClientEvents { CreateClient.schematicHandler.render(); CreateClient.schematicAndQuillHandler.render(); CreateClient.schematicHologram.render(); + KineticDebugger.renderSourceOutline(); } @SubscribeEvent @@ -69,6 +77,7 @@ public class ClientEvents { public static void onRenderHotbar() { CreateClient.schematicHandler.renderOverlay(); + KineticDebugger.renderOverlayText(); } @SubscribeEvent @@ -111,7 +120,7 @@ public class ClientEvents { public static void addToItemTooltip(ItemTooltipEvent event) { if (!CreateClientConfig.instance.enableTooltips.get()) return; - + ItemStack stack = event.getItemStack(); String translationKey = stack.getItem().getTranslationKey(stack); if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix)) diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 86f16c969..653e1e745 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -112,10 +112,8 @@ public class Create { @SubscribeEvent public static void createConfigs(ModConfig.ModConfigEvent event) { - if (event.getConfig().getSpec() == CreateClientConfig.specification) - return; - - config = event.getConfig(); + if (event.getConfig().getSpec() == CreateConfig.specification) + config = event.getConfig(); } public static void tick() { diff --git a/src/main/java/com/simibubi/create/CreateConfig.java b/src/main/java/com/simibubi/create/CreateConfig.java index 792214ec7..320943489 100644 --- a/src/main/java/com/simibubi/create/CreateConfig.java +++ b/src/main/java/com/simibubi/create/CreateConfig.java @@ -2,9 +2,13 @@ package com.simibubi.create; import java.nio.file.InvalidPathException; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; import org.apache.commons.lang3.tuple.Pair; +import com.simibubi.create.modules.contraptions.base.KineticBlock; + import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; import net.minecraftforge.common.ForgeConfigSpec.Builder; @@ -56,6 +60,12 @@ public class CreateConfig { inWorldProcessingTime; public IntValue maxChassisForTranslation, maxChassisForRotation, maxChassisRange, maxPistonPoles; + public DoubleValue waterWheelCapacity; + public DoubleValue generatingFanCapacity; + public DoubleValue mechanicalBearingCapacity; + public DoubleValue motorCapacity; + public Map stressEntries = new HashMap<>(); + // Logistics public IntValue extractorDelay, extractorAmount, linkRange; @@ -136,7 +146,7 @@ public class CreateConfig { name = "cocoaLogGrowthSpeed"; cocoaLogGrowthSpeed = builder.comment("", "% of random Ticks causing a Cocoa log to grow.") - .translation(basePath + name).defineInRange(name, 0D, 20D, 100D); + .translation(basePath + name).defineInRange(name, 20D, 0D, 100D); builder.pop(); } @@ -196,7 +206,7 @@ public class CreateConfig { name = "fanRotationArgmax"; fanRotationArgmax = builder.comment("", "Rotation speed at which the maximum stats of fans are reached.") .translation(basePath + name).defineInRange(name, 8192, 64, Integer.MAX_VALUE); - + name = "generatingFanSpeed"; generatingFanSpeed = builder.comment("", "Rotation speed generated by a vertical fan above fire.") .translation(basePath + name).defineInRange(name, 32, 0, Integer.MAX_VALUE); @@ -231,6 +241,8 @@ public class CreateConfig { maxPistonPoles = builder.comment("", "Maximum amount of extension poles behind a Mechanical Piston.") .translation(basePath + name).defineInRange(name, 64, 1, Integer.MAX_VALUE); + initStress(builder); + builder.pop(); } @@ -256,9 +268,10 @@ public class CreateConfig { .translation(basePath + name).defineInRange(name, 50, 10, Integer.MAX_VALUE); name = "allowGlassPanesInPartialBlocks"; - allowGlassPanesInPartialBlocks = builder.comment("", "Allow Glass Panes to be put inside Blocks like Stairs, Slabs, Fences etc.") + allowGlassPanesInPartialBlocks = builder + .comment("", "Allow Glass Panes to be put inside Blocks like Stairs, Slabs, Fences etc.") .translation(basePath + name).define(name, true); - + builder.pop(); } @@ -318,6 +331,83 @@ public class CreateConfig { builder.pop(); } + private void initStress(final ForgeConfigSpec.Builder builder) { + builder.comment( + "Configure the individual stress impact of mechanical blocks. Note that this cost is doubled for every speed increase it receives.") + .push("stress"); + + for (AllBlocks block : AllBlocks.values()) { + if (block.get() instanceof KineticBlock) + initStressEntry(block, builder); + } + + builder.pop(); + + builder.comment("Configure how much stress a source can accommodate.").push("capacity"); + + String basePath = "create.config.capacity."; + String name = ""; + + name = "waterWheelCapacity"; + waterWheelCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 32D, 0D, 4096D); + name = "generatingFanCapacity"; + generatingFanCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 64D, 0D, 4096D); + name = "mechanicalBearingCapacity"; + mechanicalBearingCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 256D, 0D, + 4096D); + name = "motorCapacity"; + motorCapacity = builder.comment("").translation(basePath + name).defineInRange(name, 1024D, 0D, 4096D); + + builder.pop(); + + } + + private void initStressEntry(AllBlocks block, final ForgeConfigSpec.Builder builder) { + String basePath = "create.config.stress."; + String name = block.name(); + stressEntries.put(block.get().getRegistryName().getPath(), builder.comment("").translation(basePath + name) + .defineInRange(name, getDefaultStressImpact(block), 0, 2048)); + } + + public static double getDefaultStressImpact(AllBlocks block) { + + switch (block) { + case CRUSHING_WHEEL: + case MECHANICAL_PRESS: + case MOTOR: + return 32; + + case DRILL: + case SAW: + case MECHANICAL_PISTON: + case STICKY_MECHANICAL_PISTON: + return 16; + + case ENCASED_FAN: + case MECHANICAL_MIXER: + case MECHANICAL_BEARING: + return 8; + + case WATER_WHEEL: + case TURNTABLE: + case GEARBOX: + case GEARSHIFT: + case LARGE_COGWHEEL: + return 4; + + case CLUTCH: + return 2; + + case BELT: + case COGWHEEL: + case ENCASED_BELT: + case ENCASED_SHAFT: + case SHAFT: + default: + return 1; + } + } + private boolean isValidPath(Object path) { if (!(path instanceof String)) return false; diff --git a/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java b/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java index 2888abfe8..db17c9363 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java +++ b/src/main/java/com/simibubi/create/foundation/utility/BufferManipulator.java @@ -94,7 +94,7 @@ public abstract class BufferManipulator { public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin, float yOrigin, float zOrigin, float yaw, float pitch) { buffer.rewind(); - + float cosYaw = MathHelper.cos(yaw); float sinYaw = MathHelper.sin(yaw); float cosPitch = MathHelper.cos(pitch); @@ -118,7 +118,27 @@ public abstract class BufferManipulator { float zPos = zL + z + zOrigin; putPos(buffer, vertex, xPos, yPos, zPos); } - + + return buffer; + } + + public static ByteBuffer recolorBuffer(ByteBuffer buffer, int color) { + buffer.rewind(); + + boolean defaultColor = color == -1; + int b = defaultColor ? 128 : color & 0xFF; + int g = defaultColor ? 128 : (color >> 8) & 0xFF; + int r = defaultColor ? 128 : (color >> 16) & 0xFF; + + for (int vertex = 0; vertex < vertexCount(buffer); vertex++) { + float lum = 1; + + int r2 = (int) (r * lum); + int g2 = (int) (g * lum); + int b2 = (int) (b * lum); + putColor(buffer, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) 255); + } + return buffer; } diff --git a/src/main/java/com/simibubi/create/foundation/utility/Debug.java b/src/main/java/com/simibubi/create/foundation/utility/Debug.java new file mode 100644 index 000000000..5b99afbe8 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/Debug.java @@ -0,0 +1,47 @@ +package com.simibubi.create.foundation.utility; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.common.thread.EffectiveSide; + +/** Deprecated so simi doensn't forget to remove debug calls **/ +@OnlyIn(value = Dist.CLIENT) +@Deprecated +public class Debug { + + public static void debugChat(String message) { + if (Minecraft.getInstance().player != null) + Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(message), false); + } + + public static void debugChatAndShowStack(String message, int depth) { + if (Minecraft.getInstance().player != null) + Minecraft.getInstance().player + .sendStatusMessage(new StringTextComponent(message + " @" + debugStack(depth)), false); + } + + public static void debugMessage(String message) { + if (Minecraft.getInstance().player != null) + Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(message), true); + } + + public static String getLogicalSide() { + return EffectiveSide.get().isClient() ? "CL" : "SV"; + } + + public static String debugStack(int depth) { + StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); + String text = "[" + TextFormatting.GOLD + getLogicalSide() + TextFormatting.WHITE + "] "; + for (int i = 1; i < depth + 2 && i < stackTraceElements.length; i++) { + StackTraceElement e = stackTraceElements[i]; + if (e.getClassName().equals(Debug.class.getName())) + continue; + text = text + TextFormatting.YELLOW + e.getMethodName() + TextFormatting.WHITE + ", "; + } + return text + TextFormatting.GRAY + " ..."; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/Lang.java b/src/main/java/com/simibubi/create/foundation/utility/Lang.java index 81196ba1a..07705b7a3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Lang.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Lang.java @@ -6,12 +6,8 @@ import java.util.Locale; import com.simibubi.create.Create; -import net.minecraft.client.Minecraft; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TranslationTextComponent; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; public class Lang { @@ -27,21 +23,6 @@ public class Lang { player.sendStatusMessage(getTranslationComponent(key, args), true); } - // Deprecated so simi doensn't forget to remove debug calls - @OnlyIn(value = Dist.CLIENT) - @Deprecated - public static void debugChat(String message) { - if (Minecraft.getInstance().player != null) - Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(message), false); - } - - @OnlyIn(value = Dist.CLIENT) - @Deprecated - public static void debugMessage(String message) { - if (Minecraft.getInstance().player != null) - Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(message), true); - } - public static List translatedOptions(String prefix, String... keys) { List result = new ArrayList<>(keys.length); for (String key : keys) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java new file mode 100644 index 000000000..c5cd0aec3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java @@ -0,0 +1,141 @@ +package com.simibubi.create.foundation.utility; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import com.google.common.base.Predicates; + +import net.minecraft.block.BlockState; +import net.minecraft.block.LeavesBlock; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; + +public class TreeCutter { + + public static class Tree { + public List logs; + public List leaves; + + public Tree(List logs, List leaves) { + this.logs = logs; + this.leaves = leaves; + } + } + + /** + * Finds a tree at the given pos. Block at the position should be air + * + * @param reader + * @param pos + * @return null if not found or not fully cut + */ + public static Tree cutTree(IBlockReader reader, BlockPos pos) { + List logs = new ArrayList<>(); + List leaves = new ArrayList<>(); + Set visited = new HashSet<>(); + List frontier = new LinkedList<>(); + + if (!validateCut(reader, pos)) + return null; + + visited.add(pos); + addNeighbours(pos, frontier, visited); + + // Find all logs + while (!frontier.isEmpty()) { + BlockPos currentPos = frontier.remove(0); + visited.add(currentPos); + + if (!isLog(reader.getBlockState(currentPos))) + continue; + logs.add(currentPos); + addNeighbours(currentPos, frontier, visited); + } + + // Find all leaves + visited.clear(); + visited.addAll(logs); + frontier.addAll(logs); + while (!frontier.isEmpty()) { + BlockPos currentPos = frontier.remove(0); + visited.add(currentPos); + + BlockState blockState = reader.getBlockState(currentPos); + boolean isLog = !isLog(blockState); + boolean isLeaf = !isLeaf(blockState); + + if (!isLog && !isLeaf) + continue; + if (isLeaf) + leaves.add(currentPos); + + int distance = isLog ? 0 : blockState.get(LeavesBlock.DISTANCE); + for (Direction direction : Direction.values()) { + BlockPos offset = currentPos.offset(direction); + if (visited.contains(offset)) + continue; + BlockState state = reader.getBlockState(offset); + if (isLeaf(state) && state.get(LeavesBlock.DISTANCE) > distance) + frontier.add(offset); + } + + } + + return new Tree(logs, leaves); + } + + /** + * Checks whether a tree was fully cut by seeing whether the layer above the cut + * is not supported by any more logs. + * + * @param reader + * @param pos + * @return + */ + private static boolean validateCut(IBlockReader reader, BlockPos pos) { + Set visited = new HashSet<>(); + List frontier = new LinkedList<>(); + frontier.add(pos.up()); + + while (!frontier.isEmpty()) { + BlockPos currentPos = frontier.remove(0); + visited.add(currentPos); + + if (!isLog(reader.getBlockState(currentPos))) + continue; + if (isLog(reader.getBlockState(currentPos.down()))) + return false; + + for (Direction direction : Direction.values()) { + if (direction.getAxis().isVertical()) + continue; + BlockPos offset = currentPos.offset(direction); + if (visited.contains(offset)) + continue; + frontier.add(offset); + } + + } + + return true; + } + + private static void addNeighbours(BlockPos pos, List frontier, Set visited) { + BlockPos.getAllInBox(pos.add(-1, -1, -1), pos.add(1, 1, 1)).filter(Predicates.not(visited::contains)) + .forEach(frontier::add); + } + + private static boolean isLog(BlockState state) { + return state.isIn(BlockTags.LOGS); + } + + private static boolean isLeaf(BlockState state) { + return state.has(LeavesBlock.DISTANCE); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java b/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java new file mode 100644 index 000000000..9d2e10935 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticDebugger.java @@ -0,0 +1,85 @@ +package com.simibubi.create.modules.contraptions; + +import java.util.ArrayList; +import java.util.List; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.World; + +public class KineticDebugger { + + public static void renderSourceOutline() { + if (!isActive()) + return; + KineticTileEntity te = getSelectedTE(); + if (te == null) + return; + + World world = Minecraft.getInstance().world; + BlockPos toOutline = te.hasSource() ? te.getSource() : te.getPos(); + VoxelShape shape = world.getBlockState(toOutline).getShape(world, toOutline); + + TessellatorHelper.prepareForDrawing(); + GlStateManager.disableTexture(); + GlStateManager.lineWidth(2); + + WorldRenderer.drawShape(shape, toOutline.getX(), toOutline.getY(), toOutline.getZ(), te.hasSource() ? .5f : 1, + .75f, .75f, 1); + + GlStateManager.lineWidth(1); + GlStateManager.enableTexture(); + TessellatorHelper.cleanUpAfterDrawing(); + } + + public static void renderOverlayText() { + if (!isActive()) + return; + KineticTileEntity te = getSelectedTE(); + if (te == null) + return; + + List info = new ArrayList<>(); + te.addDebugInformation(info); + Minecraft mc = Minecraft.getInstance(); + int x = mc.mainWindow.getScaledWidth() / 2 - 25; + int y = mc.mainWindow.getScaledHeight() / 2 + 25; + for (String text : info) { + mc.fontRenderer.drawStringWithShadow(text, x, y, 0xFFFFFF); + y += 10; + } + } + + public static boolean isActive() { + return Minecraft.getInstance().gameSettings.showDebugInfo; + } + + public static KineticTileEntity getSelectedTE() { + RayTraceResult obj = Minecraft.getInstance().objectMouseOver; + ClientWorld world = Minecraft.getInstance().world; + if (obj == null) + return null; + if (world == null) + return null; + if (!(obj instanceof BlockRayTraceResult)) + return null; + + BlockRayTraceResult ray = (BlockRayTraceResult) obj; + TileEntity te = world.getTileEntity(ray.getPos()); + if (te == null || !(te instanceof KineticTileEntity)) + return null; + + return (KineticTileEntity) te; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java index 583da6d5e..3771b8a30 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/KineticNetwork.java @@ -1,118 +1,127 @@ package com.simibubi.create.modules.contraptions; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.UUID; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; public class KineticNetwork { public UUID id; - private float stressCapacityPool; - private float maxStress; - private float currentStress; public boolean initialized; + private float maxStress; + private float currentStress; + + private float unloadedStressCapacity; + private float unloadedStress; public Map sources; - public Set members; + public Map members; public KineticNetwork() { id = UUID.randomUUID(); - maxStress = stressCapacityPool = 0; - setCurrentStress(0); sources = new HashMap<>(); - members = new HashSet<>(); + members = new HashMap<>(); } - + public void initFromTE(KineticTileEntity te) { - maxStress = stressCapacityPool = te.maxStress; - currentStress = te.currentStress; + unloadedStressCapacity = te.maxStress; + unloadedStress = te.currentStress; initialized = true; - addSilently(te); + updateStress(); + updateStressCapacity(); } - + public void addSilently(KineticTileEntity te) { - if (members.contains(te)) + if (members.containsKey(te)) return; if (te.isSource()) { float capacity = te.getAddedStressCapacity(); - stressCapacityPool -= capacity; + unloadedStressCapacity -= capacity; sources.put(te, capacity); } - members.add(te); + float stressApplied = te.getStressApplied(); + unloadedStress -= stressApplied; + members.put(te, stressApplied); } public void add(KineticTileEntity te) { - if (members.contains(te)) + if (members.containsKey(te)) return; - Lang.debugChat(te.getType().getRegistryName().getPath() + " added to Network"); +// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " added to Network", 5); - te.setNetworkID(this.id); - if (te.isSource()) { - float capacity = te.getAddedStressCapacity(); - sources.put(te, capacity); - updateMaxStress(); + sources.put(te, te.getAddedStressCapacity()); + updateStressCapacity(); } - members.add(te); - setCurrentStress(getCurrentStress() + te.getStressApplied()); + + members.put(te, te.getStressApplied()); + updateStress(); sync(); } - + public void updateCapacityFor(KineticTileEntity te, float capacity) { sources.put(te, capacity); - updateMaxStress(); + updateStressCapacity(); + } + + public void updateStressFor(KineticTileEntity te, float stress) { + members.put(te, stress); + updateStress(); } public void remove(KineticTileEntity te) { - if (!members.contains(te)) + if (!members.containsKey(te)) return; - Lang.debugChat(te.getType().getRegistryName().getPath() + " removed from Network"); +// Debug.debugChat(te.getType().getRegistryName().getPath() + " removed from Network"); if (te.isSource()) { sources.remove(te); - updateMaxStress(); + updateStressCapacity(); } + members.remove(te); - setCurrentStress(getCurrentStress() - te.getStressApplied()); + updateStress(); sync(); } public void sync() { - for (KineticTileEntity te : members) { - te.sync(id, getMaxStress(), getCurrentStress()); + for (KineticTileEntity te : members.keySet()) { + te.sync(maxStress, currentStress); } } - public float getMaxStress() { - return maxStress; - } - - private void updateMaxStress() { + public void updateStressCapacity() { float presentCapacity = 0; - for (Float cap : sources.values()) - presentCapacity += cap; - float newMaxStress = presentCapacity + stressCapacityPool; + for (KineticTileEntity te : sources.keySet()) + presentCapacity += sources.get(te) * getStressMultiplierForSpeed(te.getGeneratedSpeed()); + float newMaxStress = presentCapacity + unloadedStressCapacity; if (maxStress != newMaxStress) { maxStress = newMaxStress; sync(); +// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5); } - Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress); + } - public float getCurrentStress() { - return currentStress; + public void updateStress() { + float presentStress = 0; + + for (KineticTileEntity te : members.keySet()) + presentStress += members.get(te) * getStressMultiplierForSpeed(te.speed); + float newStress = presentStress + unloadedStress; + if (currentStress != newStress) { + currentStress = newStress; + sync(); +// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5); + } } - public void setCurrentStress(float currentStress) { - this.currentStress = currentStress; - Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress); + private float getStressMultiplierForSpeed(float speed) { + return Math.abs(speed); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java index 7781a6fc0..d3a5b4c6d 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/RotationPropagator.java @@ -223,46 +223,40 @@ public class RotationPropagator { return; } - boolean isSource = neighbourTE.isSource(); - boolean hasSource = neighbourTE.hasSource(); - boolean poweredBySomethingElse = isSource - || hasSource && !neighbourTE.getSource().equals(updateTE.getPos()); + if (incompatible) { + // Opposite directions + world.destroyBlock(pos, true); + return; - if (poweredBySomethingElse) { - if (neighbourTE.speed != newSpeed) { - if (incompatible) { - // Opposite directions - world.destroyBlock(pos, true); - return; + } else { + // Same direction: overpower the slower speed + if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) { + // Neighbour faster, overpower the incoming tree + updateTE.setSource(neighbourTE.getPos()); + updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE)); + updateTE.onSpeedChanged(); + updateTE.sendData(); - } else { - // Same direction: overpower the slower speed - if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) { - // Neighbour faster, overpower the incoming tree - updateTE.setSource(neighbourTE.getPos()); - updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE)); - updateTE.onSpeedChanged(); - updateTE.sendData(); - propagateNewSource(updateTE); - return; - } - if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed)) { - // Current faster, overpower the neighbours' tree - - if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) { - updateTE.removeSource(); - } - - neighbourTE.setSource(updateTE.getPos()); - neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE)); - neighbourTE.onSpeedChanged(); - neighbourTE.sendData(); - propagateNewSource(neighbourTE); - continue; - } - } + propagateNewSource(updateTE); + return; + } + if (Math.abs(newSpeed) >= Math.abs(neighbourTE.speed)) { + if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed) || updateTE.newNetworkID != null + && !updateTE.newNetworkID.equals(neighbourTE.newNetworkID)) { + // Current faster, overpower the neighbours' tree + + if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) { + updateTE.removeSource(); + } + + neighbourTE.setSource(updateTE.getPos()); + neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE)); + neighbourTE.onSpeedChanged(); + neighbourTE.sendData(); + propagateNewSource(neighbourTE); + } + continue; } - continue; } if (neighbourTE.speed == newSpeed) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java b/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java index 83a715886..3305b659c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/TorquePropagator.java @@ -7,14 +7,12 @@ import java.util.UUID; import com.simibubi.create.Create; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; -import net.minecraft.client.Minecraft; -import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.IWorld; public class TorquePropagator { static Map> networks = new HashMap<>(); - + public void onLoadWorld(IWorld world) { networks.put(world, new HashMap<>()); Create.logger.debug("Prepared Kinetic Network Space for " + world.getDimension().getType().getRegistryName()); @@ -24,17 +22,18 @@ public class TorquePropagator { networks.remove(world); Create.logger.debug("Removed Kinetic Network Space for " + world.getDimension().getType().getRegistryName()); } - + public KineticNetwork getNetworkFor(KineticTileEntity te) { UUID id = te.getNetworkID(); KineticNetwork network; Map map = networks.get(te.getWorld()); if (id == null) { network = new KineticNetwork(); - - //TODO - Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(te.getType().getRegistryName().getPath() + " created new Network"), false); - + +// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " created new Network", 5); + + te.newNetworkID = network.id; + te.updateNetwork = true; map.put(id, network); } else { if (!map.containsKey(id)) { @@ -46,5 +45,5 @@ public class TorquePropagator { } return network; } - + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java new file mode 100644 index 000000000..2fef619b8 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/GeneratingKineticTileEntity.java @@ -0,0 +1,71 @@ +package com.simibubi.create.modules.contraptions.base; + +import java.util.Optional; +import java.util.UUID; + +import net.minecraft.tileentity.TileEntityType; + +public abstract class GeneratingKineticTileEntity extends KineticTileEntity { + + public GeneratingKineticTileEntity(TileEntityType typeIn) { + super(typeIn); + } + + protected void notifyStressCapacityChange(float capacity) { + getNetwork().updateCapacityFor(this, capacity); + } + + @Override + public void reActivateSource() { + updateGeneratedRotation(); + } + + public void updateGeneratedRotation() { + float speed = getGeneratedSpeed(); + + if (this.speed != speed) { + if (speed == 0) { + if (hasSource()) + notifyStressCapacityChange(0); + else { + detachKinetics(); + setSpeed(speed); + newNetworkID = null; + updateNetwork = true; + } + } else if (this.speed == 0) { + setSpeed(speed); + newNetworkID = UUID.randomUUID(); + updateNetwork = true; + attachKinetics(); + } else { + if (hasSource()) { + if (Math.abs(this.speed) >= Math.abs(speed)) { + if (Math.signum(this.speed) == Math.signum(speed)) + notifyStressCapacityChange(getAddedStressCapacity()); + else + world.destroyBlock(pos, true); + } else { + detachKinetics(); + setSpeed(speed); + source = Optional.empty(); + newNetworkID = UUID.randomUUID(); + updateNetwork = true; + attachKinetics(); + } + } else { + detachKinetics(); + setSpeed(speed); + attachKinetics(); + } + } + } + + if (hasNetwork() && speed != 0) + getNetwork().updateStressCapacity(); + + onSpeedChanged(); + sendData(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java index 3ec2e3b67..285519ac7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticBlock.java @@ -18,7 +18,7 @@ import net.minecraft.world.World; public abstract class KineticBlock extends Block implements IRotate { protected static final Palette color = Palette.Red; - + public KineticBlock(Properties properties) { super(properties); } @@ -62,6 +62,8 @@ public abstract class KineticBlock extends Block implements IRotate { KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos); if (tileEntity == null) return; + if (worldIn.isRemote()) + return; RotationPropagator.handleAdded(worldIn.getWorld(), pos, tileEntity); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java index 7d2561a34..914c18d37 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntity.java @@ -1,12 +1,17 @@ package com.simibubi.create.modules.contraptions.base; +import static net.minecraft.util.text.TextFormatting.GREEN; +import static net.minecraft.util.text.TextFormatting.WHITE; + +import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Random; import java.util.UUID; import com.simibubi.create.Create; +import com.simibubi.create.CreateConfig; import com.simibubi.create.foundation.block.SyncedTileEntity; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.KineticNetwork; import com.simibubi.create.modules.contraptions.RotationPropagator; @@ -17,17 +22,23 @@ import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.ForgeConfigSpec.DoubleValue; public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity { + // Speed related public float speed; protected Optional source; public boolean reActivateSource; + // Torque related public float maxStress; public float currentStress; - public UUID networkID; protected boolean overStressed; + + public UUID networkID; + public UUID newNetworkID; + public boolean updateNetwork; protected boolean initNetwork; public KineticTileEntity(TileEntityType typeIn) { @@ -36,16 +47,13 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic source = Optional.empty(); } - public void sync(UUID networkID, float maxStress, float currentStress) { - this.setNetworkID(networkID); + public void sync(float maxStress, float currentStress) { this.maxStress = maxStress; this.currentStress = currentStress; boolean overStressed = maxStress < currentStress; if (overStressed != this.overStressed) { - - Lang.debugChat(getType().getRegistryName().getPath() + " jammed (" + currentStress + "/" + maxStress + ")"); - this.overStressed = overStressed; + onSpeedChanged(); sendData(); } } @@ -55,17 +63,15 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic } public float getStressApplied() { - return isSource() ? 0 : 1; + Map stressEntries = CreateConfig.parameters.stressEntries; + String path = getBlockState().getBlock().getRegistryName().getPath(); + if (!stressEntries.containsKey(path)) + return 1; + return stressEntries.get(path).get().floatValue(); } - protected void notifyStressChange(float diff) { - KineticNetwork network = getNetwork(); - network.setCurrentStress(network.getCurrentStress() + diff); - network.sync(); - } - - protected void notifyStressCapacityChange(float capacity) { - getNetwork().updateCapacityFor(this, capacity); + protected void notifyStressChange(float stress) { + getNetwork().updateStressFor(this, stress); } @Override @@ -74,10 +80,6 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic } public void onSpeedChanged() { -// if (isSource() && !world.isRemote) { -// if (networkID == null) -// getNetwork().add(this); -// } } @Override @@ -122,14 +124,18 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic currentStress = compound.getFloat("Stress"); overStressed = maxStress < currentStress; setNetworkID(NBTUtil.readUniqueId(compound.getCompound("Id"))); + newNetworkID = networkID; initNetwork = true; + } else { + networkID = newNetworkID = null; + overStressed = false; } super.read(compound); } public boolean isSource() { - return false; + return getGeneratedSpeed() != 0; } public float getSpeed() { @@ -138,6 +144,10 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic return speed; } + public float getGeneratedSpeed() { + return 0; + } + public void setSpeed(float speed) { this.speed = speed; if (hasWorld() && speed != 0 && world.isRemote) { @@ -169,16 +179,18 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic if (world == null || world.isRemote) return; - if (hasNetwork()) { - getNetwork().remove(this); - networkID = null; - } if (source == null) return; KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); if (sourceTe == null) return; - Create.torquePropagator.getNetworkFor(sourceTe).add(this); + + if (reActivateSource && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) { + reActivateSource = false; + } + + newNetworkID = sourceTe.newNetworkID; + updateNetwork = true; } public void removeSource() { @@ -186,23 +198,14 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic reActivateSource = true; this.source = Optional.empty(); - - if (hasNetwork() && !isSource()) { - getNetwork().remove(this); - networkID = null; - } - + newNetworkID = null; + updateNetwork = true; setSpeed(0); onSpeedChanged(); } public KineticNetwork getNetwork() { - KineticNetwork networkFor = Create.torquePropagator.getNetworkFor(this); - if (!networkFor.initialized) { - networkFor.add(this); - networkFor.initialized = true; - } - return networkFor; + return Create.torquePropagator.getNetworkFor(this); } public boolean hasNetwork() { @@ -241,20 +244,49 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic @Override public void tick() { + if (world.isRemote) + return; + + if (initNetwork) { + initNetwork = false; + + KineticNetwork network = getNetwork(); + if (!network.initialized) + network.initFromTE(this); + network.addSilently(this); + } + + if (updateNetwork) { + updateNetwork = false; + + if (hasNetwork() && !networkID.equals(newNetworkID)) { + getNetwork().remove(this); + networkID = null; + maxStress = currentStress = 0; + overStressed = false; + } + + if (newNetworkID != null) { + networkID = newNetworkID; + KineticNetwork network = getNetwork(); + network.initialized = true; + network.add(this); + } + + sendData(); + } + if (reActivateSource) { reActivateSource(); reActivateSource = false; } + } - if (initNetwork) { - initNetwork = false; - KineticNetwork network = getNetwork(); - if (network.initialized) { - network.addSilently(this); - } else { - network.initFromTE(this); - } - } + public void addDebugInformation(List lines) { + lines.add("Speed: " + GREEN + speed); + lines.add("Cost: " + GREEN + getStressApplied() + WHITE + "/" + GREEN + getAddedStressCapacity()); + lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress); +// lines.add("Network: " + (hasNetwork() ? networkID.toString() : "Missing")); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java index 96dc88c3f..e3bb21e9c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java @@ -11,6 +11,8 @@ import org.lwjgl.opengl.GL11; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.BufferManipulator; +import com.simibubi.create.modules.contraptions.KineticDebugger; +import com.simibubi.create.modules.logistics.management.base.LogisticalActorTileEntity; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; @@ -19,6 +21,7 @@ import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -32,6 +35,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; public class KineticTileEntityRenderer extends TileEntityRendererFast { protected static Map cachedBuffers; + public static boolean rainbowMode = false; protected static class BlockModelSpinner extends BufferManipulator { @@ -84,8 +88,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast te - .setSpeedValueLazily((int) (te.getSpeedValue() * (delta > 0 ^ te.getSpeedValue() < 0 ? 2 : .5f)))); + .setSpeedValueLazily((int) (te.newGeneratedSpeed * (delta > 0 ^ te.newGeneratedSpeed < 0 ? 2 : .5f)))); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/generators/MotorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/generators/MotorTileEntity.java index f859e518f..1ca65409f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/generators/MotorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/generators/MotorTileEntity.java @@ -1,82 +1,83 @@ package com.simibubi.create.modules.contraptions.generators; +import java.util.UUID; + import com.simibubi.create.AllPackets; import com.simibubi.create.AllTileEntities; import com.simibubi.create.CreateConfig; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.MathHelper; -public class MotorTileEntity extends KineticTileEntity { +public class MotorTileEntity extends GeneratingKineticTileEntity { public static final int DEFAULT_SPEED = 64; - public int newSpeed; + public int newGeneratedSpeed; + public int generatedSpeed; public int lastModified; public MotorTileEntity() { super(AllTileEntities.MOTOR.type); - setSpeed(DEFAULT_SPEED); + speed = generatedSpeed = newGeneratedSpeed = DEFAULT_SPEED; + updateNetwork = true; + newNetworkID = UUID.randomUUID(); lastModified = -1; } @Override - public float getAddedStressCapacity() { - return 500; + public float getGeneratedSpeed() { + return generatedSpeed; } - + + @Override + public float getAddedStressCapacity() { + return CreateConfig.parameters.motorCapacity.get().floatValue(); + } + @Override public boolean hasFastRenderer() { return true; } @Override - public boolean isSource() { - return true; + public CompoundNBT write(CompoundNBT compound) { + compound.putInt("GeneratedSpeed", generatedSpeed); + return super.write(compound); } @Override - public void setSpeed(float speed) { - super.setSpeed(speed); - newSpeed = (int) speed; - } - - @Override - public void removeSource() { - float speed = this.speed; - super.removeSource(); - setSpeed(speed); - } - - public int getSpeedValue() { - if (world.isRemote) - return newSpeed; - return (int) speed; + public void read(CompoundNBT compound) { + generatedSpeed = compound.getInt("GeneratedSpeed"); + if (lastModified == -1) + newGeneratedSpeed = generatedSpeed; + super.read(compound); } public void setSpeedValueLazily(int speed) { - if (newSpeed == speed) + if (newGeneratedSpeed == speed) return; Integer max = CreateConfig.parameters.maxMotorSpeed.get(); - if (newSpeed > 0 && speed == 0) - newSpeed = -1; - else if (newSpeed < 0 && speed == 0) - newSpeed = 1; + if (newGeneratedSpeed > 0 && speed == 0) + newGeneratedSpeed = -1; + else if (newGeneratedSpeed < 0 && speed == 0) + newGeneratedSpeed = 1; else - newSpeed = MathHelper.clamp(speed, -max, max); + newGeneratedSpeed = MathHelper.clamp(speed, -max, max); this.lastModified = 0; } @Override public void tick() { super.tick(); - + if (!world.isRemote) return; if (lastModified == -1) return; if (lastModified++ > 10) { lastModified = -1; - AllPackets.channel.sendToServer(new ConfigureMotorPacket(pos, newSpeed)); + AllPackets.channel.sendToServer(new ConfigureMotorPacket(pos, newGeneratedSpeed)); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java index 36bbac595..c4e65ba9e 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelBlock.java @@ -108,7 +108,7 @@ public class WaterWheelBlock extends HorizontalKineticBlock { WaterWheelTileEntity te = (WaterWheelTileEntity) world.getTileEntity(pos); if (te == null) return; - te.updateSpeed(); + te.updateGeneratedRotation(); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelTileEntity.java index 57bfc0d60..53b7bcd81 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/generators/WaterWheelTileEntity.java @@ -2,20 +2,18 @@ package com.simibubi.create.modules.contraptions.generators; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.contraptions.RotationPropagator; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.CreateConfig; +import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; -public class WaterWheelTileEntity extends KineticTileEntity { +public class WaterWheelTileEntity extends GeneratingKineticTileEntity { private Map flows; - private boolean hasFlows; public WaterWheelTileEntity() { super(AllTileEntities.WATER_WHEEL.type); @@ -53,41 +51,18 @@ public class WaterWheelTileEntity extends KineticTileEntity { public void setFlow(Direction direction, int speed) { flows.put(direction, speed); } - - @Override - public void reActivateSource() { - updateSpeed(); - } - public void updateSpeed() { + @Override + public float getGeneratedSpeed() { float speed = 0; for (Integer i : flows.values()) speed += i; - - if (this.speed != speed) { - hasFlows = speed != 0; - notifyStressCapacityChange(getAddedStressCapacity()); - source = Optional.empty(); - RotationPropagator.handleRemoved(world, pos, this); - this.setSpeed(speed); - sendData(); - RotationPropagator.handleAdded(world, pos, this); - } - - onSpeedChanged(); - } - - @Override - public boolean isSource() { - return hasFlows; + return speed; } @Override public float getAddedStressCapacity() { - float torque = 0; - for (Integer i : flows.values()) - torque += i; - return Math.abs(torque); + return CreateConfig.parameters.waterWheelCapacity.get().floatValue(); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/BasinTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/BasinTileEntity.java index eddbc3e5b..e1513a9f5 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/BasinTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/BasinTileEntity.java @@ -14,6 +14,7 @@ import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.CombinedInvWrapper; +import net.minecraftforge.items.wrapper.RecipeWrapper; public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEntity { @@ -25,6 +26,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn markDirty(); } }; + + public class BasinInputInventory extends RecipeWrapper { + public BasinInputInventory() { + super(inputInventory); + } + } protected ItemStackHandler inputInventory = new ItemStackHandler(9) { protected void onContentsChanged(int slot) { @@ -69,10 +76,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn protected LazyOptional inventory = LazyOptional .of(() -> new BasinInventory(inputInventory, outputInventory)); + public BasinInputInventory recipeInventory; public BasinTileEntity() { super(AllTileEntities.BASIN.type); updateProcessing = true; + recipeInventory = new BasinInputInventory(); } @Override diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingRecipe.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingRecipe.java index a6e9f02d0..4eced9e84 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingRecipe.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingRecipe.java @@ -5,13 +5,12 @@ import java.util.List; import com.simibubi.create.AllRecipes; import com.simibubi.create.modules.contraptions.base.ProcessingRecipe; import com.simibubi.create.modules.contraptions.base.StochasticOutput; -import com.simibubi.create.modules.contraptions.receivers.CrushingWheelControllerTileEntity.Inventory; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; -public class CrushingRecipe extends ProcessingRecipe { +public class CrushingRecipe extends ProcessingRecipe { public CrushingRecipe(ResourceLocation id, String group, List ingredients, List results, int processingDuration) { @@ -19,7 +18,7 @@ public class CrushingRecipe extends ProcessingRecipe stacks = NonNullList.create(); - for (int slot = 0; slot < inv.getSlots(); slot++) { - ItemStack stack = inv.getStackInSlot(slot); - stacks.add(stack); - } - ItemStackHelper.saveAllItems(nbt, stacks); - nbt.putInt("ProcessingTime", processingDuration); - nbt.putBoolean("AppliedRecipe", appliedRecipe); - } - - public static Inventory read(CompoundNBT nbt) { - Inventory inventory = new Inventory(); - NonNullList stacks = NonNullList.withSize(10, ItemStack.EMPTY); - ItemStackHelper.loadAllItems(nbt, stacks); - - for (int slot = 0; slot < stacks.size(); slot++) - inventory.setInventorySlotContents(slot, stacks.get(slot)); - inventory.processingDuration = nbt.getInt("ProcessingTime"); - inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe"); - - return inventory; - } - - public ItemStackHandler getItems() { - return (ItemStackHandler) inv; - } - - } - private static DamageSource damageSource = new DamageSource("create.crush").setDamageBypassesArmor() .setDifficultyScaled(); @@ -83,12 +34,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen private UUID entityUUID; protected boolean searchForEntity; - private Inventory contents; + private ProcessingInventory contents; public float crushingspeed; public CrushingWheelControllerTileEntity() { super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type); - contents = new Inventory(); + contents = new ProcessingInventory(); } @Override @@ -236,7 +187,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen this.searchForEntity = true; } crushingspeed = compound.getFloat("Speed"); - contents = Inventory.read(compound); + contents = ProcessingInventory.read(compound); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CuttingRecipe.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CuttingRecipe.java new file mode 100644 index 000000000..00bf4885c --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CuttingRecipe.java @@ -0,0 +1,27 @@ +package com.simibubi.create.modules.contraptions.receivers; + +import java.util.List; + +import com.simibubi.create.AllRecipes; +import com.simibubi.create.modules.contraptions.base.ProcessingRecipe; +import com.simibubi.create.modules.contraptions.base.StochasticOutput; + +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class CuttingRecipe extends ProcessingRecipe { + + public CuttingRecipe(ResourceLocation id, String group, List ingredients, + List results, int processingDuration) { + super(AllRecipes.CUTTING, id, group, ingredients, results, processingDuration); + } + + @Override + public boolean matches(ProcessingInventory inv, World worldIn) { + if (inv.isEmpty()) + return false; + return ingredients.get(0).test(inv.getStackInSlot(0)); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java index 8c015ad8b..0190db31a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java @@ -73,10 +73,10 @@ public class DrillTileEntity extends KineticTileEntity { @Override public void tick() { super.tick(); - + if (world.isRemote) return; - if (speed == 0) + if (getSpeed() == 0) return; BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING)); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/EncasedFanTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/EncasedFanTileEntity.java index b62bbda53..806902bce 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/EncasedFanTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/EncasedFanTileEntity.java @@ -6,7 +6,6 @@ import static net.minecraft.util.Direction.AxisDirection.NEGATIVE; import static net.minecraft.util.Direction.AxisDirection.POSITIVE; import java.util.List; -import java.util.Optional; import com.simibubi.create.AllBlockTags; import com.simibubi.create.AllBlocks; @@ -14,7 +13,7 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.CreateClient; import com.simibubi.create.CreateConfig; import com.simibubi.create.foundation.utility.VecHelper; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; import com.simibubi.create.modules.logistics.InWorldProcessing; import com.simibubi.create.modules.logistics.InWorldProcessing.Type; @@ -35,7 +34,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; -public class EncasedFanTileEntity extends KineticTileEntity { +public class EncasedFanTileEntity extends GeneratingKineticTileEntity { private static DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled() .setFireDamage(); @@ -87,13 +86,13 @@ public class EncasedFanTileEntity extends KineticTileEntity { } @Override - public boolean isSource() { - return isGenerator; + public float getAddedStressCapacity() { + return isGenerator ? CreateConfig.parameters.generatingFanCapacity.get().floatValue() : 0; } @Override - public float getAddedStressCapacity() { - return 50; + public float getGeneratedSpeed() { + return isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0; } public void updateGenerator() { @@ -102,14 +101,7 @@ public class EncasedFanTileEntity extends KineticTileEntity { return; isGenerator = shouldGenerate; - if (isGenerator) { - notifyStressCapacityChange(getAddedStressCapacity()); - removeSource(); - } else { - notifyStressCapacityChange(0); - } - applyNewSpeed(isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0); - sendData(); + updateGeneratedRotation(); } public boolean blockBelowIsHot() { @@ -122,7 +114,7 @@ public class EncasedFanTileEntity extends KineticTileEntity { if (world.isRemote) return; - float speed = Math.abs(this.speed); + float speed = Math.abs(this.getSpeed()); float distanceFactor = Math.min(speed / parameters.fanRotationArgmax.get(), 1); pushDistance = MathHelper.lerp(distanceFactor, 3, parameters.fanMaxPushDistance.get()); @@ -180,9 +172,9 @@ public class EncasedFanTileEntity extends KineticTileEntity { } public Direction getAirFlow() { - if (speed == 0) + if (getSpeed() == 0) return null; - return Direction.getFacingFromAxisDirection(getBlockState().get(AXIS), speed > 0 ? POSITIVE : NEGATIVE); + return Direction.getFacingFromAxisDirection(getBlockState().get(AXIS), getSpeed() > 0 ? POSITIVE : NEGATIVE); } @Override @@ -191,17 +183,11 @@ public class EncasedFanTileEntity extends KineticTileEntity { updateFrontBlock(); } - @Override - public void reActivateSource() { - source = Optional.empty(); - applyNewSpeed(isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0); - } - @Override public void tick() { super.tick(); - if (speed == 0 || isGenerator) + if (getSpeed() == 0 || isGenerator) return; List frontEntities = world.getEntitiesWithinAABBExcludingEntity(null, frontBB); @@ -308,7 +294,7 @@ public class EncasedFanTileEntity extends KineticTileEntity { Vec3i flow = getAirFlow().getDirectionVec(); float sneakModifier = entity.isSneaking() ? 4096f : 512f; - float acceleration = (float) (speed * 1 / sneakModifier + float acceleration = (float) (getSpeed() * 1 / sneakModifier / (entity.getPositionVec().distanceTo(center) / (push ? pushDistance : pullDistance))); Vec3d previousMotion = entity.getMotion(); float maxAcceleration = 5; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerTileEntity.java index 2695d66e9..55b0d9263 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MechanicalMixerTileEntity.java @@ -87,6 +87,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity { } public float getRenderedHeadRotationSpeed(float partialTicks) { + float speed = getSpeed(); if (running) { if (runningTicks < 15) { return speed; @@ -154,13 +155,14 @@ public class MechanicalMixerTileEntity extends KineticTileEntity { } } + float speed = Math.abs(getSpeed()); if (running) { if (world.isRemote && runningTicks == 20) renderParticles(); if (!world.isRemote && runningTicks == 20) { if (processingTicks < 0) { - processingTicks = (MathHelper.log2((int) (8000 / Math.abs(speed)))) * 15 + 1; + processingTicks = (MathHelper.log2((int) (8000 / speed))) * 15 + 1; return; } processingTicks--; @@ -178,7 +180,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity { return; } - if (Math.abs(speed) < 32) + if (speed < 32) return; if (!checkBasin) return; @@ -229,7 +231,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity { float angle = world.rand.nextFloat() * 360; Vec3d offset = new Vec3d(0, 0, 0.25f); offset = VecHelper.rotate(offset, angle, Axis.Y); - Vec3d target = VecHelper.rotate(offset, speed > 0 ? 25 : -25, Axis.Y).add(0, .25f, 0); + Vec3d target = VecHelper.rotate(offset, getSpeed() > 0 ? 25 : -25, Axis.Y).add(0, .25f, 0); Vec3d center = offset.add(VecHelper.getCenterOf(pos)); target = VecHelper.offsetRandomly(target.subtract(offset), world.rand, 1 / 128f); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/MixingRecipe.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MixingRecipe.java new file mode 100644 index 000000000..0d5809b11 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/MixingRecipe.java @@ -0,0 +1,60 @@ +package com.simibubi.create.modules.contraptions.receivers; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import com.simibubi.create.AllRecipes; +import com.simibubi.create.modules.contraptions.base.ProcessingRecipe; +import com.simibubi.create.modules.contraptions.base.StochasticOutput; +import com.simibubi.create.modules.contraptions.receivers.BasinTileEntity.BasinInputInventory; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +public class MixingRecipe extends ProcessingRecipe { + + public MixingRecipe(ResourceLocation id, String group, List ingredients, + List results, int processingDuration) { + super(AllRecipes.MIXING, id, group, ingredients, results, processingDuration); + } + + @Override + public boolean matches(BasinInputInventory inv, World worldIn) { + if (inv.isEmpty()) + return false; + + NonNullList ingredients = getIngredients(); + if (!ingredients.stream().allMatch(Ingredient::isSimple)) + return false; + + List remaining = new ArrayList<>(); + for (int slot = 0; slot < inv.getSizeInventory(); ++slot) { + ItemStack itemstack = inv.getStackInSlot(slot); + if (!itemstack.isEmpty()) { + remaining.add(itemstack.copy()); + } + } + + // sort by leniency + List sortedIngredients = new LinkedList<>(ingredients); + sortedIngredients.sort((i1, i2) -> i1.getMatchingStacks().length - i2.getMatchingStacks().length); + Ingredients: for (Ingredient ingredient : sortedIngredients) { + for (ItemStack stack : remaining) { + if (stack.isEmpty()) + continue; + if (ingredient.test(stack)) { + stack.shrink(1); + continue Ingredients; + } + } + return false; + } + return true; + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java new file mode 100644 index 000000000..8c66ebcd3 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java @@ -0,0 +1,53 @@ +package com.simibubi.create.modules.contraptions.receivers; + +import net.minecraft.inventory.ItemStackHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.NonNullList; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.wrapper.RecipeWrapper; + +public class ProcessingInventory extends RecipeWrapper { + protected int processingDuration; + protected boolean appliedRecipe; + + public ProcessingInventory() { + super(new ItemStackHandler(10)); + } + + @Override + public void clear() { + super.clear(); + processingDuration = 0; + appliedRecipe = false; + } + + public void write(CompoundNBT nbt) { + NonNullList stacks = NonNullList.create(); + for (int slot = 0; slot < inv.getSlots(); slot++) { + ItemStack stack = inv.getStackInSlot(slot); + stacks.add(stack); + } + ItemStackHelper.saveAllItems(nbt, stacks); + nbt.putInt("ProcessingTime", processingDuration); + nbt.putBoolean("AppliedRecipe", appliedRecipe); + } + + public static ProcessingInventory read(CompoundNBT nbt) { + ProcessingInventory inventory = new ProcessingInventory(); + NonNullList stacks = NonNullList.withSize(10, ItemStack.EMPTY); + ItemStackHelper.loadAllItems(nbt, stacks); + + for (int slot = 0; slot < stacks.size(); slot++) + inventory.setInventorySlotContents(slot, stacks.get(slot)); + inventory.processingDuration = nbt.getInt("ProcessingTime"); + inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe"); + + return inventory; + } + + public ItemStackHandler getItems() { + return (ItemStackHandler) inv; + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java index d2301ba22..84c2c4c93 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java @@ -9,14 +9,19 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.material.PushReaction; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.DamageSource; 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.MathHelper; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; @@ -26,6 +31,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEntity, IHaveMovementBehavior { public static final BooleanProperty RUNNING = BooleanProperty.create("running"); + public static DamageSource damageSourceSaw = new DamageSource("create.saw").setDamageBypassesArmor(); public SawBlock() { super(Properties.from(Blocks.ANDESITE)); @@ -67,6 +73,29 @@ public class SawBlock extends DirectionalAxisKineticBlock return VoxelShapers.SHORT_CASING.get(state.get(FACING)); } + @Override + public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { + if (entityIn instanceof ItemEntity) + return; + if (!new AxisAlignedBB(pos).shrink(.1f).intersects(entityIn.getBoundingBox())) + return; + withTileEntityDo(worldIn, pos, te -> { + if (te.getSpeed() == 0) + return; + entityIn.attackEntityFrom(damageSourceSaw, MathHelper.clamp(Math.abs(te.speed / 512f) + 1, 0, 20)); + }); + } + + @Override + public void onLanded(IBlockReader worldIn, Entity entityIn) { + super.onLanded(worldIn, entityIn); + if (!(entityIn instanceof ItemEntity)) + return; + withTileEntityDo(entityIn.world, entityIn.getPosition(), te -> { + + }); + } + @Override public PushReaction getPushReaction(BlockState state) { return PushReaction.PUSH_ONLY; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java index 88be6d034..c63007490 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java @@ -2,21 +2,48 @@ package com.simibubi.create.modules.contraptions.receivers; import static com.simibubi.create.modules.contraptions.receivers.SawBlock.RUNNING; +import java.util.Optional; + +import com.simibubi.create.AllRecipes; import com.simibubi.create.AllTileEntities; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import net.minecraft.entity.item.ItemEntity; + public class SawTileEntity extends KineticTileEntity { + public ProcessingInventory inventory; + public SawTileEntity() { super(AllTileEntities.SAW.type); + inventory = new ProcessingInventory(); } @Override public void onSpeedChanged() { - boolean shouldRun = Math.abs(speed) > 1 / 64f; + boolean shouldRun = Math.abs(getSpeed()) > 1 / 64f; boolean running = getBlockState().get(RUNNING); if (shouldRun != running) world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun)); } + @Override + public void tick() { + super.tick(); + + } + + public void insertItem(ItemEntity entity) { + if (!inventory.isEmpty()) + return; + + inventory.clear(); + inventory.setInventorySlotContents(0, entity.getItem().copy()); + Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CUTTING, inventory, world); + + inventory.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100; + inventory.appliedRecipe = false; + entity.remove(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java index 00f35b07c..750ba20b6 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalBearingTileEntity.java @@ -1,10 +1,8 @@ package com.simibubi.create.modules.contraptions.receivers.constructs; -import java.util.Optional; - import com.simibubi.create.AllTileEntities; -import com.simibubi.create.modules.contraptions.RotationPropagator; -import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.CreateConfig; +import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -19,7 +17,7 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -public class MechanicalBearingTileEntity extends KineticTileEntity { +public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity { protected RotationConstruct movingConstruct; protected float angle; @@ -36,21 +34,16 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { public AxisAlignedBB getRenderBoundingBox() { return INFINITE_EXTENT_AABB; } - + @Override @OnlyIn(Dist.CLIENT) public double getMaxRenderDistanceSquared() { return super.getMaxRenderDistanceSquared() * 16; } - - @Override - public float getAddedStressCapacity() { - return getWindmillSpeed() * 50; - } @Override - public boolean isSource() { - return isWindmill; + public float getAddedStressCapacity() { + return isWindmill ? CreateConfig.parameters.mechanicalBearingCapacity.get().floatValue() : 0; } public void neighbourChanged() { @@ -59,20 +52,14 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { return; isWindmill = shouldWindmill; - if (isWindmill) - removeSource(); - - if (isWindmill && !running) { + if (isWindmill && !running) assembleNextTick = true; - } - - if (isWindmill && running) { - applyNewSpeed(getWindmillSpeed()); - } + if (isWindmill && running) + updateGeneratedRotation(); if (!isWindmill && running) { - applyNewSpeed(0); - if (speed == 0) + updateGeneratedRotation(); + if (getSpeed() == 0) disassembleConstruct(); } @@ -86,8 +73,9 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { super.remove(); } - public float getWindmillSpeed() { - if (!running) + @Override + public float getGeneratedSpeed() { + if (!running || !isWindmill) return 0; int sails = movingConstruct.getSailBlocks(); return MathHelper.clamp(sails, 0, 128); @@ -128,7 +116,7 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { } public float getAngularSpeed() { - return speed / 2048; + return getSpeed() / 2048; } public void assembleConstruct() { @@ -150,17 +138,7 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67); } - applyWindmillSpeed(); - } - - public void applyWindmillSpeed() { - if (isWindmill) { - RotationPropagator.handleRemoved(world, pos, this); - source = Optional.empty(); - speed = getWindmillSpeed(); - RotationPropagator.handleAdded(world, pos, this); - sendData(); - } + updateGeneratedRotation(); } public void disassembleConstruct() { @@ -186,18 +164,14 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { running = false; movingConstruct = null; angle = 0; + updateGeneratedRotation(); sendData(); } - - @Override - public void reActivateSource() { - applyWindmillSpeed(); - } @Override public void tick() { super.tick(); - + if (running && RotationConstruct.isFrozen()) disassembleConstruct(); @@ -210,6 +184,8 @@ public class MechanicalBearingTileEntity extends KineticTileEntity { } return; } else { + if (speed == 0 && !isWindmill) + return; assembleConstruct(); } return; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java index c9527b66a..6ff49a4c3 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MechanicalPistonTileEntity.java @@ -189,11 +189,11 @@ public class MechanicalPistonTileEntity extends KineticTileEntity { @Override public void tick() { super.tick(); - + if (!world.isRemote && assembleNextTick) { assembleNextTick = false; if (running) { - if (speed == 0) + if (getSpeed() == 0) disassembleConstruct(); else { for (MutablePair pair : movedContraption.getActors()) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/GearshiftBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/GearshiftBlock.java index 31a792392..7ddb1e766 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/GearshiftBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/GearshiftBlock.java @@ -49,9 +49,8 @@ public class GearshiftBlock extends EncasedShaftBlock { boolean previouslyPowered = state.get(POWERED); if (previouslyPowered != worldIn.isBlockPowered(pos)) { - worldIn.setBlockState(pos, state.cycle(POWERED), 2); - if (!previouslyPowered) - RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos)); + worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16); + RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos)); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltItem.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltItem.java index a6a2c730d..6760981ea 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltItem.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltItem.java @@ -181,8 +181,8 @@ public class BeltItem extends Item { if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS)) return false; - float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed(); - float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed(); + float speed1 = ((KineticTileEntity) world.getTileEntity(first)).speed; + float speed2 = ((KineticTileEntity) world.getTileEntity(second)).speed; if (Math.signum(speed1) != Math.signum(speed2) && speed1 != 0 && speed2 != 0) return false; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index baa90e188..af0e97f2c 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -72,7 +72,7 @@ public class BeltTileEntity extends KineticTileEntity { } protected boolean isLastBelt() { - if (speed == 0) + if (getSpeed() == 0) return false; Direction direction = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING); @@ -83,7 +83,7 @@ public class BeltTileEntity extends KineticTileEntity { if (part == Part.MIDDLE) return false; - boolean movingPositively = (speed > 0 == (direction.getAxisDirection().getOffset() == 1)) + boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1)) ^ direction.getAxis() == Axis.X; return part == Part.START ^ movingPositively; } @@ -140,7 +140,7 @@ public class BeltTileEntity extends KineticTileEntity { @Override public void tick() { super.tick(); - + if (world != null && trackerUpdateTag != null) { attachmentTracker.readAndSearch(trackerUpdateTag, this); trackerUpdateTag = null; @@ -169,7 +169,7 @@ public class BeltTileEntity extends KineticTileEntity { passengers.remove(e); }); - if (speed == 0) + if (getSpeed() == 0) return; } @@ -180,7 +180,7 @@ public class BeltTileEntity extends KineticTileEntity { BlockState blockState = info.lastCollidedState; Direction movementFacing = Direction.getFacingFromAxisDirection( blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(), - speed < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE); + getSpeed() < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE); boolean collidedWithBelt = te instanceof BeltTileEntity; boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te; diff --git a/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java b/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java index 8af07c21d..417440782 100644 --- a/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java +++ b/src/main/java/com/simibubi/create/modules/curiosities/deforester/DeforesterItem.java @@ -1,8 +1,17 @@ package com.simibubi.create.modules.curiosities.deforester; +import com.simibubi.create.foundation.utility.TreeCutter; +import com.simibubi.create.foundation.utility.TreeCutter.Tree; import com.simibubi.create.modules.curiosities.tools.AllToolTiers; +import net.minecraft.block.BlockState; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.AxeItem; +import net.minecraft.item.ItemStack; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; public class DeforesterItem extends AxeItem { @@ -10,4 +19,22 @@ public class DeforesterItem extends AxeItem { super(AllToolTiers.RADIANT, 10.0F, -3.1F, builder); } + @Override + public boolean onBlockDestroyed(ItemStack stack, World worldIn, BlockState state, BlockPos pos, + LivingEntity entityLiving) { + + if (state.isIn(BlockTags.LOGS) && !entityLiving.isSneaking()) { + Tree tree = TreeCutter.cutTree(worldIn, pos); + if (tree == null) + return super.onBlockDestroyed(stack, worldIn, state, pos, entityLiving); + boolean dropBlock = !(entityLiving instanceof PlayerEntity) || !((PlayerEntity) entityLiving).isCreative(); + for (BlockPos log : tree.logs) + worldIn.destroyBlock(log, dropBlock); + for (BlockPos leaf : tree.leaves) + worldIn.destroyBlock(leaf, dropBlock); + } + + return super.onBlockDestroyed(stack, worldIn, state, pos, entityLiving); + } + }