mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 11:33:43 +01:00
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
This commit is contained in:
parent
5655fa0609
commit
6f185d4540
39 changed files with 1016 additions and 393 deletions
|
@ -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<CrushingRecipe> CRUSHING = register("crushing");
|
||||
public static IRecipeType<SplashingRecipe> SPLASHING = register("splashing");
|
||||
public static IRecipeType<PressingRecipe> PRESSING = register("pressing");
|
||||
public static IRecipeType<CuttingRecipe> CUTTING = register("cutting");
|
||||
public static IRecipeType<MixingRecipe> MIXING = register("mixing");
|
||||
|
||||
static <T extends IRecipe<?>> IRecipeType<T> register(final String key) {
|
||||
return Registry.register(Registry.RECIPE_TYPE, new ResourceLocation(key), new IRecipeType<T>() {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -43,6 +45,11 @@ public class ClientEvents {
|
|||
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
|
||||
|
|
|
@ -112,9 +112,7 @@ public class Create {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||
if (event.getConfig().getSpec() == CreateClientConfig.specification)
|
||||
return;
|
||||
|
||||
if (event.getConfig().getSpec() == CreateConfig.specification)
|
||||
config = event.getConfig();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<String, DoubleValue> 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();
|
||||
}
|
||||
|
@ -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,7 +268,8 @@ 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;
|
||||
|
|
|
@ -122,4 +122,24 @@ public abstract class BufferManipulator {
|
|||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 + " ...";
|
||||
}
|
||||
|
||||
}
|
|
@ -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<String> translatedOptions(String prefix, String... keys) {
|
||||
List<String> result = new ArrayList<>(keys.length);
|
||||
for (String key : keys) {
|
||||
|
|
|
@ -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<BlockPos> logs;
|
||||
public List<BlockPos> leaves;
|
||||
|
||||
public Tree(List<BlockPos> logs, List<BlockPos> 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<BlockPos> logs = new ArrayList<>();
|
||||
List<BlockPos> leaves = new ArrayList<>();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
List<BlockPos> 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<BlockPos> visited = new HashSet<>();
|
||||
List<BlockPos> 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<BlockPos> frontier, Set<BlockPos> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<String> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<KineticTileEntity, Float> sources;
|
||||
public Set<KineticTileEntity> members;
|
||||
public Map<KineticTileEntity, Float> 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");
|
||||
|
||||
te.setNetworkID(this.id);
|
||||
// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " added to Network", 5);
|
||||
|
||||
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();
|
||||
}
|
||||
Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress);
|
||||
}
|
||||
|
||||
public float getCurrentStress() {
|
||||
return currentStress;
|
||||
}
|
||||
|
||||
public void setCurrentStress(float currentStress) {
|
||||
this.currentStress = currentStress;
|
||||
Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress);
|
||||
// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private float getStressMultiplierForSpeed(float speed) {
|
||||
return Math.abs(speed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -223,13 +223,6 @@ public class RotationPropagator {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean isSource = neighbourTE.isSource();
|
||||
boolean hasSource = neighbourTE.hasSource();
|
||||
boolean poweredBySomethingElse = isSource
|
||||
|| hasSource && !neighbourTE.getSource().equals(updateTE.getPos());
|
||||
|
||||
if (poweredBySomethingElse) {
|
||||
if (neighbourTE.speed != newSpeed) {
|
||||
if (incompatible) {
|
||||
// Opposite directions
|
||||
world.destroyBlock(pos, true);
|
||||
|
@ -243,10 +236,13 @@ public class RotationPropagator {
|
|||
updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE));
|
||||
updateTE.onSpeedChanged();
|
||||
updateTE.sendData();
|
||||
|
||||
propagateNewSource(updateTE);
|
||||
return;
|
||||
}
|
||||
if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed)) {
|
||||
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())) {
|
||||
|
@ -258,12 +254,10 @@ public class RotationPropagator {
|
|||
neighbourTE.onSpeedChanged();
|
||||
neighbourTE.sendData();
|
||||
propagateNewSource(neighbourTE);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (neighbourTE.speed == newSpeed)
|
||||
continue;
|
||||
|
|
|
@ -7,8 +7,6 @@ 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 {
|
||||
|
@ -32,9 +30,10 @@ public class TorquePropagator {
|
|||
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)) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<BlockPos> 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<String, DoubleValue> 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<String> 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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<KineticTileEntity> {
|
||||
|
||||
protected static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||
public static boolean rainbowMode = false;
|
||||
|
||||
protected static class BlockModelSpinner extends BufferManipulator {
|
||||
|
||||
|
@ -84,8 +88,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
protected static void renderFromCache(BufferBuilder buffer, BlockState state, World world, float x, float y,
|
||||
float z, BlockPos pos, Axis axis, float angle) {
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
||||
buffer.putBulkData(((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
||||
packedLightmapCoords));
|
||||
ByteBuffer transformed = ((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
||||
packedLightmapCoords);
|
||||
|
||||
if (KineticDebugger.isActive()) {
|
||||
rainbowMode = true;
|
||||
TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (tileEntity instanceof KineticTileEntity && ((KineticTileEntity) tileEntity).hasNetwork()) {
|
||||
int color = LogisticalActorTileEntity.colorFromUUID(((KineticTileEntity) tileEntity).getNetworkID());
|
||||
BufferManipulator.recolorBuffer(transformed, color);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.putBulkData(transformed);
|
||||
}
|
||||
|
||||
public static BufferManipulator getBuffer(BlockState state) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.generators;
|
||||
|
||||
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -31,10 +30,8 @@ public class ConfigureMotorPacket extends TileEntityConfigurationPacket<MotorTil
|
|||
|
||||
@Override
|
||||
protected void applySettings(MotorTileEntity te) {
|
||||
RotationPropagator.handleRemoved(te.getWorld(), te.getPos(), te);
|
||||
te.setSpeed(speed);
|
||||
te.sendData();
|
||||
RotationPropagator.handleAdded(te.getWorld(), te.getPos(), te);
|
||||
te.generatedSpeed = speed;
|
||||
te.updateGeneratedRotation();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,13 +71,13 @@ public class MotorBlock extends HorizontalKineticBlock
|
|||
MotorTileEntity tileEntity = (MotorTileEntity) world.getTileEntity(pos);
|
||||
if (tileEntity == null)
|
||||
return 0;
|
||||
return tileEntity.getSpeedValue();
|
||||
return tileEntity.newGeneratedSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta) {
|
||||
withTileEntityDo(world, pos, te -> te
|
||||
.setSpeedValueLazily((int) (te.getSpeedValue() * (delta > 0 ^ te.getSpeedValue() < 0 ? 2 : .5f))));
|
||||
.setSpeedValueLazily((int) (te.newGeneratedSpeed * (delta > 0 ^ te.newGeneratedSpeed < 0 ? 2 : .5f))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,27 +1,38 @@
|
|||
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 getGeneratedSpeed() {
|
||||
return generatedSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAddedStressCapacity() {
|
||||
return 500;
|
||||
return CreateConfig.parameters.motorCapacity.get().floatValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,39 +41,29 @@ public class MotorTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,7 @@ public class MotorTileEntity extends KineticTileEntity {
|
|||
return;
|
||||
if (lastModified++ > 10) {
|
||||
lastModified = -1;
|
||||
AllPackets.channel.sendToServer(new ConfigureMotorPacket(pos, newSpeed));
|
||||
AllPackets.channel.sendToServer(new ConfigureMotorPacket(pos, newGeneratedSpeed));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
|
|||
WaterWheelTileEntity te = (WaterWheelTileEntity) world.getTileEntity(pos);
|
||||
if (te == null)
|
||||
return;
|
||||
te.updateSpeed();
|
||||
te.updateGeneratedRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<Direction, Integer> flows;
|
||||
private boolean hasFlows;
|
||||
|
||||
public WaterWheelTileEntity() {
|
||||
super(AllTileEntities.WATER_WHEEL.type);
|
||||
|
@ -55,39 +53,16 @@ public class WaterWheelTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reActivateSource() {
|
||||
updateSpeed();
|
||||
}
|
||||
|
||||
public void updateSpeed() {
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
@ -26,6 +27,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
|||
}
|
||||
};
|
||||
|
||||
public class BasinInputInventory extends RecipeWrapper {
|
||||
public BasinInputInventory() {
|
||||
super(inputInventory);
|
||||
}
|
||||
}
|
||||
|
||||
protected ItemStackHandler inputInventory = new ItemStackHandler(9) {
|
||||
protected void onContentsChanged(int slot) {
|
||||
updateProcessing = true;
|
||||
|
@ -69,10 +76,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
|||
|
||||
protected LazyOptional<IItemHandlerModifiable> inventory = LazyOptional
|
||||
.of(() -> new BasinInventory(inputInventory, outputInventory));
|
||||
public BasinInputInventory recipeInventory;
|
||||
|
||||
public BasinTileEntity() {
|
||||
super(AllTileEntities.BASIN.type);
|
||||
updateProcessing = true;
|
||||
recipeInventory = new BasinInputInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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<CrushingWheelControllerTileEntity.Inventory> {
|
||||
public class CrushingRecipe extends ProcessingRecipe<ProcessingInventory> {
|
||||
|
||||
public CrushingRecipe(ResourceLocation id, String group, List<Ingredient> ingredients,
|
||||
List<StochasticOutput> results, int processingDuration) {
|
||||
|
@ -19,7 +18,7 @@ public class CrushingRecipe extends ProcessingRecipe<CrushingWheelControllerTile
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Inventory inv, World worldIn) {
|
||||
public boolean matches(ProcessingInventory inv, World worldIn) {
|
||||
if (inv.isEmpty())
|
||||
return false;
|
||||
return ingredients.get(0).test(inv.getStackInSlot(0));
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
|
@ -39,6 +40,11 @@ public class CrushingWheelControllerBlock extends Block implements IWithoutBlock
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplaceable(BlockState state, BlockItemUseContext useContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return new CrushingWheelControllerTileEntity();
|
||||
|
|
|
@ -12,7 +12,6 @@ import com.simibubi.create.foundation.block.SyncedTileEntity;
|
|||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.inventory.ItemStackHelper;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -23,59 +22,11 @@ import net.minecraft.particles.ItemParticleData;
|
|||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
public class CrushingWheelControllerTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||
|
||||
public static class Inventory extends RecipeWrapper {
|
||||
protected int processingDuration;
|
||||
protected boolean appliedRecipe;
|
||||
|
||||
public Inventory() {
|
||||
super(new ItemStackHandler(10));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
processingDuration = 0;
|
||||
appliedRecipe = false;
|
||||
}
|
||||
|
||||
public void write(CompoundNBT nbt) {
|
||||
NonNullList<ItemStack> 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<ItemStack> 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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ProcessingInventory> {
|
||||
|
||||
public CuttingRecipe(ResourceLocation id, String group, List<Ingredient> ingredients,
|
||||
List<StochasticOutput> 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -76,7 +76,7 @@ public class DrillTileEntity extends KineticTileEntity {
|
|||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (speed == 0)
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
|
||||
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
|
||||
|
|
|
@ -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<Entity> 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<BasinInputInventory> {
|
||||
|
||||
public MixingRecipe(ResourceLocation id, String group, List<Ingredient> ingredients,
|
||||
List<StochasticOutput> 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<Ingredient> ingredients = getIngredients();
|
||||
if (!ingredients.stream().allMatch(Ingredient::isSimple))
|
||||
return false;
|
||||
|
||||
List<ItemStack> 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<Ingredient> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ItemStack> 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<ItemStack> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<SawTileEntity>, 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;
|
||||
|
|
|
@ -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<CuttingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CUTTING, inventory, world);
|
||||
|
||||
inventory.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
||||
inventory.appliedRecipe = false;
|
||||
entity.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -45,12 +43,7 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
|||
|
||||
@Override
|
||||
public float getAddedStressCapacity() {
|
||||
return getWindmillSpeed() * 50;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSource() {
|
||||
return isWindmill;
|
||||
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,14 +164,10 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
|||
running = false;
|
||||
movingConstruct = null;
|
||||
angle = 0;
|
||||
updateGeneratedRotation();
|
||||
sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reActivateSource() {
|
||||
applyWindmillSpeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
@ -210,6 +184,8 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
|||
}
|
||||
return;
|
||||
} else {
|
||||
if (speed == 0 && !isWindmill)
|
||||
return;
|
||||
assembleConstruct();
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -193,7 +193,7 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
|||
if (!world.isRemote && assembleNextTick) {
|
||||
assembleNextTick = false;
|
||||
if (running) {
|
||||
if (speed == 0)
|
||||
if (getSpeed() == 0)
|
||||
disassembleConstruct();
|
||||
else {
|
||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors())
|
||||
|
|
|
@ -49,8 +49,7 @@ public class GearshiftBlock extends EncasedShaftBlock {
|
|||
|
||||
boolean previouslyPowered = state.get(POWERED);
|
||||
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
||||
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
|
||||
if (!previouslyPowered)
|
||||
worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16);
|
||||
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue