mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 11:43:41 +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.foundation.utility.Lang;
|
||||||
import com.simibubi.create.modules.contraptions.base.ProcessingRecipeSerializer;
|
import com.simibubi.create.modules.contraptions.base.ProcessingRecipeSerializer;
|
||||||
import com.simibubi.create.modules.contraptions.receivers.CrushingRecipe;
|
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.PressingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.receivers.SplashingRecipe;
|
import com.simibubi.create.modules.contraptions.receivers.SplashingRecipe;
|
||||||
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunUpgradeRecipe;
|
import com.simibubi.create.modules.curiosities.placementHandgun.BuilderGunUpgradeRecipe;
|
||||||
|
@ -23,6 +25,8 @@ public enum AllRecipes {
|
||||||
CRUSHING(() -> new ProcessingRecipeSerializer<>(CrushingRecipe::new), Types.CRUSHING),
|
CRUSHING(() -> new ProcessingRecipeSerializer<>(CrushingRecipe::new), Types.CRUSHING),
|
||||||
SPLASHING(() -> new ProcessingRecipeSerializer<>(SplashingRecipe::new), Types.SPLASHING),
|
SPLASHING(() -> new ProcessingRecipeSerializer<>(SplashingRecipe::new), Types.SPLASHING),
|
||||||
PRESSING(() -> new ProcessingRecipeSerializer<>(PressingRecipe::new), Types.PRESSING),
|
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<CrushingRecipe> CRUSHING = register("crushing");
|
||||||
public static IRecipeType<SplashingRecipe> SPLASHING = register("splashing");
|
public static IRecipeType<SplashingRecipe> SPLASHING = register("splashing");
|
||||||
public static IRecipeType<PressingRecipe> PRESSING = register("pressing");
|
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) {
|
static <T extends IRecipe<?>> IRecipeType<T> register(final String key) {
|
||||||
return Registry.register(Registry.RECIPE_TYPE, new ResourceLocation(key), new IRecipeType<T>() {
|
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.gui.ScreenOpener;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.TooltipHelper;
|
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.receivers.TurntableHandler;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltItemHandler;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltItemHandler;
|
||||||
|
|
||||||
|
@ -37,12 +39,17 @@ public class ClientEvents {
|
||||||
public static void onTick(ClientTickEvent event) {
|
public static void onTick(ClientTickEvent event) {
|
||||||
if (event.phase == Phase.START)
|
if (event.phase == Phase.START)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AnimationTickHolder.tick();
|
AnimationTickHolder.tick();
|
||||||
|
|
||||||
if (!isGameActive())
|
if (!isGameActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!KineticDebugger.isActive() && KineticTileEntityRenderer.rainbowMode) {
|
||||||
|
KineticTileEntityRenderer.rainbowMode = false;
|
||||||
|
KineticTileEntityRenderer.invalidateCache();
|
||||||
|
}
|
||||||
|
|
||||||
ScreenOpener.tick();
|
ScreenOpener.tick();
|
||||||
onGameTick();
|
onGameTick();
|
||||||
}
|
}
|
||||||
|
@ -57,6 +64,7 @@ public class ClientEvents {
|
||||||
CreateClient.schematicHandler.render();
|
CreateClient.schematicHandler.render();
|
||||||
CreateClient.schematicAndQuillHandler.render();
|
CreateClient.schematicAndQuillHandler.render();
|
||||||
CreateClient.schematicHologram.render();
|
CreateClient.schematicHologram.render();
|
||||||
|
KineticDebugger.renderSourceOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -69,6 +77,7 @@ public class ClientEvents {
|
||||||
|
|
||||||
public static void onRenderHotbar() {
|
public static void onRenderHotbar() {
|
||||||
CreateClient.schematicHandler.renderOverlay();
|
CreateClient.schematicHandler.renderOverlay();
|
||||||
|
KineticDebugger.renderOverlayText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -111,7 +120,7 @@ public class ClientEvents {
|
||||||
public static void addToItemTooltip(ItemTooltipEvent event) {
|
public static void addToItemTooltip(ItemTooltipEvent event) {
|
||||||
if (!CreateClientConfig.instance.enableTooltips.get())
|
if (!CreateClientConfig.instance.enableTooltips.get())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ItemStack stack = event.getItemStack();
|
ItemStack stack = event.getItemStack();
|
||||||
String translationKey = stack.getItem().getTranslationKey(stack);
|
String translationKey = stack.getItem().getTranslationKey(stack);
|
||||||
if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix))
|
if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix))
|
||||||
|
|
|
@ -112,10 +112,8 @@ public class Create {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||||
if (event.getConfig().getSpec() == CreateClientConfig.specification)
|
if (event.getConfig().getSpec() == CreateConfig.specification)
|
||||||
return;
|
config = event.getConfig();
|
||||||
|
|
||||||
config = event.getConfig();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void tick() {
|
public static void tick() {
|
||||||
|
|
|
@ -2,9 +2,13 @@ package com.simibubi.create;
|
||||||
|
|
||||||
import java.nio.file.InvalidPathException;
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
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;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||||
|
@ -56,6 +60,12 @@ public class CreateConfig {
|
||||||
inWorldProcessingTime;
|
inWorldProcessingTime;
|
||||||
public IntValue maxChassisForTranslation, maxChassisForRotation, maxChassisRange, maxPistonPoles;
|
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
|
// Logistics
|
||||||
public IntValue extractorDelay, extractorAmount, linkRange;
|
public IntValue extractorDelay, extractorAmount, linkRange;
|
||||||
|
|
||||||
|
@ -136,7 +146,7 @@ public class CreateConfig {
|
||||||
|
|
||||||
name = "cocoaLogGrowthSpeed";
|
name = "cocoaLogGrowthSpeed";
|
||||||
cocoaLogGrowthSpeed = builder.comment("", "% of random Ticks causing a Cocoa log to grow.")
|
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();
|
builder.pop();
|
||||||
}
|
}
|
||||||
|
@ -196,7 +206,7 @@ public class CreateConfig {
|
||||||
name = "fanRotationArgmax";
|
name = "fanRotationArgmax";
|
||||||
fanRotationArgmax = builder.comment("", "Rotation speed at which the maximum stats of fans are reached.")
|
fanRotationArgmax = builder.comment("", "Rotation speed at which the maximum stats of fans are reached.")
|
||||||
.translation(basePath + name).defineInRange(name, 8192, 64, Integer.MAX_VALUE);
|
.translation(basePath + name).defineInRange(name, 8192, 64, Integer.MAX_VALUE);
|
||||||
|
|
||||||
name = "generatingFanSpeed";
|
name = "generatingFanSpeed";
|
||||||
generatingFanSpeed = builder.comment("", "Rotation speed generated by a vertical fan above fire.")
|
generatingFanSpeed = builder.comment("", "Rotation speed generated by a vertical fan above fire.")
|
||||||
.translation(basePath + name).defineInRange(name, 32, 0, Integer.MAX_VALUE);
|
.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.")
|
maxPistonPoles = builder.comment("", "Maximum amount of extension poles behind a Mechanical Piston.")
|
||||||
.translation(basePath + name).defineInRange(name, 64, 1, Integer.MAX_VALUE);
|
.translation(basePath + name).defineInRange(name, 64, 1, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
initStress(builder);
|
||||||
|
|
||||||
builder.pop();
|
builder.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,9 +268,10 @@ public class CreateConfig {
|
||||||
.translation(basePath + name).defineInRange(name, 50, 10, Integer.MAX_VALUE);
|
.translation(basePath + name).defineInRange(name, 50, 10, Integer.MAX_VALUE);
|
||||||
|
|
||||||
name = "allowGlassPanesInPartialBlocks";
|
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);
|
.translation(basePath + name).define(name, true);
|
||||||
|
|
||||||
builder.pop();
|
builder.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,6 +331,83 @@ public class CreateConfig {
|
||||||
builder.pop();
|
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) {
|
private boolean isValidPath(Object path) {
|
||||||
if (!(path instanceof String))
|
if (!(path instanceof String))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -94,7 +94,7 @@ public abstract class BufferManipulator {
|
||||||
public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin,
|
public static ByteBuffer remanipulateBuffer(ByteBuffer buffer, float x, float y, float z, float xOrigin,
|
||||||
float yOrigin, float zOrigin, float yaw, float pitch) {
|
float yOrigin, float zOrigin, float yaw, float pitch) {
|
||||||
buffer.rewind();
|
buffer.rewind();
|
||||||
|
|
||||||
float cosYaw = MathHelper.cos(yaw);
|
float cosYaw = MathHelper.cos(yaw);
|
||||||
float sinYaw = MathHelper.sin(yaw);
|
float sinYaw = MathHelper.sin(yaw);
|
||||||
float cosPitch = MathHelper.cos(pitch);
|
float cosPitch = MathHelper.cos(pitch);
|
||||||
|
@ -118,7 +118,27 @@ public abstract class BufferManipulator {
|
||||||
float zPos = zL + z + zOrigin;
|
float zPos = zL + z + zOrigin;
|
||||||
putPos(buffer, vertex, xPos, yPos, zPos);
|
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;
|
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 com.simibubi.create.Create;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
|
|
||||||
public class Lang {
|
public class Lang {
|
||||||
|
|
||||||
|
@ -27,21 +23,6 @@ public class Lang {
|
||||||
player.sendStatusMessage(getTranslationComponent(key, args), true);
|
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) {
|
public static List<String> translatedOptions(String prefix, String... keys) {
|
||||||
List<String> result = new ArrayList<>(keys.length);
|
List<String> result = new ArrayList<>(keys.length);
|
||||||
for (String key : keys) {
|
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;
|
package com.simibubi.create.modules.contraptions;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
|
|
||||||
public class KineticNetwork {
|
public class KineticNetwork {
|
||||||
|
|
||||||
public UUID id;
|
public UUID id;
|
||||||
private float stressCapacityPool;
|
|
||||||
private float maxStress;
|
|
||||||
private float currentStress;
|
|
||||||
public boolean initialized;
|
public boolean initialized;
|
||||||
|
|
||||||
|
private float maxStress;
|
||||||
|
private float currentStress;
|
||||||
|
|
||||||
|
private float unloadedStressCapacity;
|
||||||
|
private float unloadedStress;
|
||||||
public Map<KineticTileEntity, Float> sources;
|
public Map<KineticTileEntity, Float> sources;
|
||||||
public Set<KineticTileEntity> members;
|
public Map<KineticTileEntity, Float> members;
|
||||||
|
|
||||||
public KineticNetwork() {
|
public KineticNetwork() {
|
||||||
id = UUID.randomUUID();
|
id = UUID.randomUUID();
|
||||||
maxStress = stressCapacityPool = 0;
|
|
||||||
setCurrentStress(0);
|
|
||||||
sources = new HashMap<>();
|
sources = new HashMap<>();
|
||||||
members = new HashSet<>();
|
members = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initFromTE(KineticTileEntity te) {
|
public void initFromTE(KineticTileEntity te) {
|
||||||
maxStress = stressCapacityPool = te.maxStress;
|
unloadedStressCapacity = te.maxStress;
|
||||||
currentStress = te.currentStress;
|
unloadedStress = te.currentStress;
|
||||||
initialized = true;
|
initialized = true;
|
||||||
addSilently(te);
|
updateStress();
|
||||||
|
updateStressCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSilently(KineticTileEntity te) {
|
public void addSilently(KineticTileEntity te) {
|
||||||
if (members.contains(te))
|
if (members.containsKey(te))
|
||||||
return;
|
return;
|
||||||
if (te.isSource()) {
|
if (te.isSource()) {
|
||||||
float capacity = te.getAddedStressCapacity();
|
float capacity = te.getAddedStressCapacity();
|
||||||
stressCapacityPool -= capacity;
|
unloadedStressCapacity -= capacity;
|
||||||
sources.put(te, capacity);
|
sources.put(te, capacity);
|
||||||
}
|
}
|
||||||
members.add(te);
|
float stressApplied = te.getStressApplied();
|
||||||
|
unloadedStress -= stressApplied;
|
||||||
|
members.put(te, stressApplied);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(KineticTileEntity te) {
|
public void add(KineticTileEntity te) {
|
||||||
if (members.contains(te))
|
if (members.containsKey(te))
|
||||||
return;
|
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()) {
|
if (te.isSource()) {
|
||||||
float capacity = te.getAddedStressCapacity();
|
sources.put(te, te.getAddedStressCapacity());
|
||||||
sources.put(te, capacity);
|
updateStressCapacity();
|
||||||
updateMaxStress();
|
|
||||||
}
|
}
|
||||||
members.add(te);
|
|
||||||
setCurrentStress(getCurrentStress() + te.getStressApplied());
|
members.put(te, te.getStressApplied());
|
||||||
|
updateStress();
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCapacityFor(KineticTileEntity te, float capacity) {
|
public void updateCapacityFor(KineticTileEntity te, float capacity) {
|
||||||
sources.put(te, capacity);
|
sources.put(te, capacity);
|
||||||
updateMaxStress();
|
updateStressCapacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStressFor(KineticTileEntity te, float stress) {
|
||||||
|
members.put(te, stress);
|
||||||
|
updateStress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(KineticTileEntity te) {
|
public void remove(KineticTileEntity te) {
|
||||||
if (!members.contains(te))
|
if (!members.containsKey(te))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Lang.debugChat(te.getType().getRegistryName().getPath() + " removed from Network");
|
// Debug.debugChat(te.getType().getRegistryName().getPath() + " removed from Network");
|
||||||
|
|
||||||
if (te.isSource()) {
|
if (te.isSource()) {
|
||||||
sources.remove(te);
|
sources.remove(te);
|
||||||
updateMaxStress();
|
updateStressCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
members.remove(te);
|
members.remove(te);
|
||||||
setCurrentStress(getCurrentStress() - te.getStressApplied());
|
updateStress();
|
||||||
sync();
|
sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sync() {
|
public void sync() {
|
||||||
for (KineticTileEntity te : members) {
|
for (KineticTileEntity te : members.keySet()) {
|
||||||
te.sync(id, getMaxStress(), getCurrentStress());
|
te.sync(maxStress, currentStress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getMaxStress() {
|
public void updateStressCapacity() {
|
||||||
return maxStress;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMaxStress() {
|
|
||||||
float presentCapacity = 0;
|
float presentCapacity = 0;
|
||||||
for (Float cap : sources.values())
|
for (KineticTileEntity te : sources.keySet())
|
||||||
presentCapacity += cap;
|
presentCapacity += sources.get(te) * getStressMultiplierForSpeed(te.getGeneratedSpeed());
|
||||||
float newMaxStress = presentCapacity + stressCapacityPool;
|
float newMaxStress = presentCapacity + unloadedStressCapacity;
|
||||||
if (maxStress != newMaxStress) {
|
if (maxStress != newMaxStress) {
|
||||||
maxStress = newMaxStress;
|
maxStress = newMaxStress;
|
||||||
sync();
|
sync();
|
||||||
|
// Debug.debugChatAndShowStack("Current Stress level: " + currentStress + "/" + maxStress, 5);
|
||||||
}
|
}
|
||||||
Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getCurrentStress() {
|
public void updateStress() {
|
||||||
return currentStress;
|
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) {
|
private float getStressMultiplierForSpeed(float speed) {
|
||||||
this.currentStress = currentStress;
|
return Math.abs(speed);
|
||||||
Lang.debugChat("Current Stress level: " + currentStress + "/" + maxStress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,46 +223,40 @@ public class RotationPropagator {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isSource = neighbourTE.isSource();
|
if (incompatible) {
|
||||||
boolean hasSource = neighbourTE.hasSource();
|
// Opposite directions
|
||||||
boolean poweredBySomethingElse = isSource
|
world.destroyBlock(pos, true);
|
||||||
|| hasSource && !neighbourTE.getSource().equals(updateTE.getPos());
|
return;
|
||||||
|
|
||||||
if (poweredBySomethingElse) {
|
} else {
|
||||||
if (neighbourTE.speed != newSpeed) {
|
// Same direction: overpower the slower speed
|
||||||
if (incompatible) {
|
if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) {
|
||||||
// Opposite directions
|
// Neighbour faster, overpower the incoming tree
|
||||||
world.destroyBlock(pos, true);
|
updateTE.setSource(neighbourTE.getPos());
|
||||||
return;
|
updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE));
|
||||||
|
updateTE.onSpeedChanged();
|
||||||
|
updateTE.sendData();
|
||||||
|
|
||||||
} else {
|
propagateNewSource(updateTE);
|
||||||
// Same direction: overpower the slower speed
|
return;
|
||||||
if (Math.abs(oppositeSpeed) > Math.abs(updateTE.speed)) {
|
}
|
||||||
// Neighbour faster, overpower the incoming tree
|
if (Math.abs(newSpeed) >= Math.abs(neighbourTE.speed)) {
|
||||||
updateTE.setSource(neighbourTE.getPos());
|
if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed) || updateTE.newNetworkID != null
|
||||||
updateTE.setSpeed(neighbourTE.speed * getRotationSpeedModifier(neighbourTE, updateTE));
|
&& !updateTE.newNetworkID.equals(neighbourTE.newNetworkID)) {
|
||||||
updateTE.onSpeedChanged();
|
// Current faster, overpower the neighbours' tree
|
||||||
updateTE.sendData();
|
|
||||||
propagateNewSource(updateTE);
|
if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) {
|
||||||
return;
|
updateTE.removeSource();
|
||||||
}
|
}
|
||||||
if (Math.abs(newSpeed) > Math.abs(neighbourTE.speed)) {
|
|
||||||
// Current faster, overpower the neighbours' tree
|
neighbourTE.setSource(updateTE.getPos());
|
||||||
|
neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE));
|
||||||
if (updateTE.hasSource() && updateTE.getSource().equals(neighbourTE.getPos())) {
|
neighbourTE.onSpeedChanged();
|
||||||
updateTE.removeSource();
|
neighbourTE.sendData();
|
||||||
}
|
propagateNewSource(neighbourTE);
|
||||||
|
}
|
||||||
neighbourTE.setSource(updateTE.getPos());
|
continue;
|
||||||
neighbourTE.setSpeed(updateTE.speed * getRotationSpeedModifier(updateTE, neighbourTE));
|
|
||||||
neighbourTE.onSpeedChanged();
|
|
||||||
neighbourTE.sendData();
|
|
||||||
propagateNewSource(neighbourTE);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighbourTE.speed == newSpeed)
|
if (neighbourTE.speed == newSpeed)
|
||||||
|
|
|
@ -7,14 +7,12 @@ import java.util.UUID;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
|
|
||||||
public class TorquePropagator {
|
public class TorquePropagator {
|
||||||
|
|
||||||
static Map<IWorld, Map<UUID, KineticNetwork>> networks = new HashMap<>();
|
static Map<IWorld, Map<UUID, KineticNetwork>> networks = new HashMap<>();
|
||||||
|
|
||||||
public void onLoadWorld(IWorld world) {
|
public void onLoadWorld(IWorld world) {
|
||||||
networks.put(world, new HashMap<>());
|
networks.put(world, new HashMap<>());
|
||||||
Create.logger.debug("Prepared Kinetic Network Space for " + world.getDimension().getType().getRegistryName());
|
Create.logger.debug("Prepared Kinetic Network Space for " + world.getDimension().getType().getRegistryName());
|
||||||
|
@ -24,17 +22,18 @@ public class TorquePropagator {
|
||||||
networks.remove(world);
|
networks.remove(world);
|
||||||
Create.logger.debug("Removed Kinetic Network Space for " + world.getDimension().getType().getRegistryName());
|
Create.logger.debug("Removed Kinetic Network Space for " + world.getDimension().getType().getRegistryName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public KineticNetwork getNetworkFor(KineticTileEntity te) {
|
public KineticNetwork getNetworkFor(KineticTileEntity te) {
|
||||||
UUID id = te.getNetworkID();
|
UUID id = te.getNetworkID();
|
||||||
KineticNetwork network;
|
KineticNetwork network;
|
||||||
Map<UUID, KineticNetwork> map = networks.get(te.getWorld());
|
Map<UUID, KineticNetwork> map = networks.get(te.getWorld());
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
network = new KineticNetwork();
|
network = new KineticNetwork();
|
||||||
|
|
||||||
//TODO
|
// Debug.debugChatAndShowStack(te.getType().getRegistryName().getPath() + " created new Network", 5);
|
||||||
Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(te.getType().getRegistryName().getPath() + " created new Network"), false);
|
|
||||||
|
te.newNetworkID = network.id;
|
||||||
|
te.updateNetwork = true;
|
||||||
map.put(id, network);
|
map.put(id, network);
|
||||||
} else {
|
} else {
|
||||||
if (!map.containsKey(id)) {
|
if (!map.containsKey(id)) {
|
||||||
|
@ -46,5 +45,5 @@ public class TorquePropagator {
|
||||||
}
|
}
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ import net.minecraft.world.World;
|
||||||
public abstract class KineticBlock extends Block implements IRotate {
|
public abstract class KineticBlock extends Block implements IRotate {
|
||||||
|
|
||||||
protected static final Palette color = Palette.Red;
|
protected static final Palette color = Palette.Red;
|
||||||
|
|
||||||
public KineticBlock(Properties properties) {
|
public KineticBlock(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,8 @@ public abstract class KineticBlock extends Block implements IRotate {
|
||||||
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
|
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
|
||||||
if (tileEntity == null)
|
if (tileEntity == null)
|
||||||
return;
|
return;
|
||||||
|
if (worldIn.isRemote())
|
||||||
|
return;
|
||||||
RotationPropagator.handleAdded(worldIn.getWorld(), pos, tileEntity);
|
RotationPropagator.handleAdded(worldIn.getWorld(), pos, tileEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
package com.simibubi.create.modules.contraptions.base;
|
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.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.CreateConfig;
|
||||||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
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.KineticNetwork;
|
||||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
||||||
|
|
||||||
|
@ -17,17 +22,23 @@ import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.common.ForgeConfigSpec.DoubleValue;
|
||||||
|
|
||||||
public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public abstract class KineticTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
|
// Speed related
|
||||||
public float speed;
|
public float speed;
|
||||||
protected Optional<BlockPos> source;
|
protected Optional<BlockPos> source;
|
||||||
public boolean reActivateSource;
|
public boolean reActivateSource;
|
||||||
|
|
||||||
|
// Torque related
|
||||||
public float maxStress;
|
public float maxStress;
|
||||||
public float currentStress;
|
public float currentStress;
|
||||||
public UUID networkID;
|
|
||||||
protected boolean overStressed;
|
protected boolean overStressed;
|
||||||
|
|
||||||
|
public UUID networkID;
|
||||||
|
public UUID newNetworkID;
|
||||||
|
public boolean updateNetwork;
|
||||||
protected boolean initNetwork;
|
protected boolean initNetwork;
|
||||||
|
|
||||||
public KineticTileEntity(TileEntityType<?> typeIn) {
|
public KineticTileEntity(TileEntityType<?> typeIn) {
|
||||||
|
@ -36,16 +47,13 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
source = Optional.empty();
|
source = Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sync(UUID networkID, float maxStress, float currentStress) {
|
public void sync(float maxStress, float currentStress) {
|
||||||
this.setNetworkID(networkID);
|
|
||||||
this.maxStress = maxStress;
|
this.maxStress = maxStress;
|
||||||
this.currentStress = currentStress;
|
this.currentStress = currentStress;
|
||||||
boolean overStressed = maxStress < currentStress;
|
boolean overStressed = maxStress < currentStress;
|
||||||
if (overStressed != this.overStressed) {
|
if (overStressed != this.overStressed) {
|
||||||
|
|
||||||
Lang.debugChat(getType().getRegistryName().getPath() + " jammed (" + currentStress + "/" + maxStress + ")");
|
|
||||||
|
|
||||||
this.overStressed = overStressed;
|
this.overStressed = overStressed;
|
||||||
|
onSpeedChanged();
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,17 +63,15 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getStressApplied() {
|
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) {
|
protected void notifyStressChange(float stress) {
|
||||||
KineticNetwork network = getNetwork();
|
getNetwork().updateStressFor(this, stress);
|
||||||
network.setCurrentStress(network.getCurrentStress() + diff);
|
|
||||||
network.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void notifyStressCapacityChange(float capacity) {
|
|
||||||
getNetwork().updateCapacityFor(this, capacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,10 +80,6 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSpeedChanged() {
|
public void onSpeedChanged() {
|
||||||
// if (isSource() && !world.isRemote) {
|
|
||||||
// if (networkID == null)
|
|
||||||
// getNetwork().add(this);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -122,14 +124,18 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
currentStress = compound.getFloat("Stress");
|
currentStress = compound.getFloat("Stress");
|
||||||
overStressed = maxStress < currentStress;
|
overStressed = maxStress < currentStress;
|
||||||
setNetworkID(NBTUtil.readUniqueId(compound.getCompound("Id")));
|
setNetworkID(NBTUtil.readUniqueId(compound.getCompound("Id")));
|
||||||
|
newNetworkID = networkID;
|
||||||
initNetwork = true;
|
initNetwork = true;
|
||||||
|
} else {
|
||||||
|
networkID = newNetworkID = null;
|
||||||
|
overStressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.read(compound);
|
super.read(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSource() {
|
public boolean isSource() {
|
||||||
return false;
|
return getGeneratedSpeed() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getSpeed() {
|
public float getSpeed() {
|
||||||
|
@ -138,6 +144,10 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getGeneratedSpeed() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSpeed(float speed) {
|
public void setSpeed(float speed) {
|
||||||
this.speed = speed;
|
this.speed = speed;
|
||||||
if (hasWorld() && speed != 0 && world.isRemote) {
|
if (hasWorld() && speed != 0 && world.isRemote) {
|
||||||
|
@ -169,16 +179,18 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
|
|
||||||
if (world == null || world.isRemote)
|
if (world == null || world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (hasNetwork()) {
|
|
||||||
getNetwork().remove(this);
|
|
||||||
networkID = null;
|
|
||||||
}
|
|
||||||
if (source == null)
|
if (source == null)
|
||||||
return;
|
return;
|
||||||
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source);
|
||||||
if (sourceTe == null)
|
if (sourceTe == null)
|
||||||
return;
|
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() {
|
public void removeSource() {
|
||||||
|
@ -186,23 +198,14 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
reActivateSource = true;
|
reActivateSource = true;
|
||||||
|
|
||||||
this.source = Optional.empty();
|
this.source = Optional.empty();
|
||||||
|
newNetworkID = null;
|
||||||
if (hasNetwork() && !isSource()) {
|
updateNetwork = true;
|
||||||
getNetwork().remove(this);
|
|
||||||
networkID = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSpeed(0);
|
setSpeed(0);
|
||||||
onSpeedChanged();
|
onSpeedChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public KineticNetwork getNetwork() {
|
public KineticNetwork getNetwork() {
|
||||||
KineticNetwork networkFor = Create.torquePropagator.getNetworkFor(this);
|
return Create.torquePropagator.getNetworkFor(this);
|
||||||
if (!networkFor.initialized) {
|
|
||||||
networkFor.add(this);
|
|
||||||
networkFor.initialized = true;
|
|
||||||
}
|
|
||||||
return networkFor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNetwork() {
|
public boolean hasNetwork() {
|
||||||
|
@ -241,20 +244,49 @@ public abstract class KineticTileEntity extends SyncedTileEntity implements ITic
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
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) {
|
if (reActivateSource) {
|
||||||
reActivateSource();
|
reActivateSource();
|
||||||
reActivateSource = false;
|
reActivateSource = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (initNetwork) {
|
public void addDebugInformation(List<String> lines) {
|
||||||
initNetwork = false;
|
lines.add("Speed: " + GREEN + speed);
|
||||||
KineticNetwork network = getNetwork();
|
lines.add("Cost: " + GREEN + getStressApplied() + WHITE + "/" + GREEN + getAddedStressCapacity());
|
||||||
if (network.initialized) {
|
lines.add("Stress: " + GREEN + currentStress + WHITE + "/" + GREEN + maxStress);
|
||||||
network.addSilently(this);
|
// lines.add("Network: " + (hasNetwork() ? networkID.toString() : "Missing"));
|
||||||
} else {
|
|
||||||
network.initFromTE(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import org.lwjgl.opengl.GL11;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.BufferManipulator;
|
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.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
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.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.model.IBakedModel;
|
import net.minecraft.client.renderer.model.IBakedModel;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
@ -32,6 +35,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTileEntity> {
|
public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTileEntity> {
|
||||||
|
|
||||||
protected static Map<BlockState, BufferManipulator> cachedBuffers;
|
protected static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||||
|
public static boolean rainbowMode = false;
|
||||||
|
|
||||||
protected static class BlockModelSpinner extends BufferManipulator {
|
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,
|
protected static void renderFromCache(BufferBuilder buffer, BlockState state, World world, float x, float y,
|
||||||
float z, BlockPos pos, Axis axis, float angle) {
|
float z, BlockPos pos, Axis axis, float angle) {
|
||||||
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
||||||
buffer.putBulkData(((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
ByteBuffer transformed = ((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
||||||
packedLightmapCoords));
|
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) {
|
public static BufferManipulator getBuffer(BlockState state) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions.generators;
|
package com.simibubi.create.modules.contraptions.generators;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket;
|
||||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
|
||||||
|
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -31,10 +30,8 @@ public class ConfigureMotorPacket extends TileEntityConfigurationPacket<MotorTil
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applySettings(MotorTileEntity te) {
|
protected void applySettings(MotorTileEntity te) {
|
||||||
RotationPropagator.handleRemoved(te.getWorld(), te.getPos(), te);
|
te.generatedSpeed = speed;
|
||||||
te.setSpeed(speed);
|
te.updateGeneratedRotation();
|
||||||
te.sendData();
|
|
||||||
RotationPropagator.handleAdded(te.getWorld(), te.getPos(), te);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,13 +71,13 @@ public class MotorBlock extends HorizontalKineticBlock
|
||||||
MotorTileEntity tileEntity = (MotorTileEntity) world.getTileEntity(pos);
|
MotorTileEntity tileEntity = (MotorTileEntity) world.getTileEntity(pos);
|
||||||
if (tileEntity == null)
|
if (tileEntity == null)
|
||||||
return 0;
|
return 0;
|
||||||
return tileEntity.getSpeedValue();
|
return tileEntity.newGeneratedSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta) {
|
public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta) {
|
||||||
withTileEntityDo(world, pos, te -> te
|
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
|
@Override
|
||||||
|
|
|
@ -1,82 +1,83 @@
|
||||||
package com.simibubi.create.modules.contraptions.generators;
|
package com.simibubi.create.modules.contraptions.generators;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.CreateConfig;
|
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;
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public class MotorTileEntity extends KineticTileEntity {
|
public class MotorTileEntity extends GeneratingKineticTileEntity {
|
||||||
|
|
||||||
public static final int DEFAULT_SPEED = 64;
|
public static final int DEFAULT_SPEED = 64;
|
||||||
public int newSpeed;
|
public int newGeneratedSpeed;
|
||||||
|
public int generatedSpeed;
|
||||||
public int lastModified;
|
public int lastModified;
|
||||||
|
|
||||||
public MotorTileEntity() {
|
public MotorTileEntity() {
|
||||||
super(AllTileEntities.MOTOR.type);
|
super(AllTileEntities.MOTOR.type);
|
||||||
setSpeed(DEFAULT_SPEED);
|
speed = generatedSpeed = newGeneratedSpeed = DEFAULT_SPEED;
|
||||||
|
updateNetwork = true;
|
||||||
|
newNetworkID = UUID.randomUUID();
|
||||||
lastModified = -1;
|
lastModified = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getAddedStressCapacity() {
|
public float getGeneratedSpeed() {
|
||||||
return 500;
|
return generatedSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getAddedStressCapacity() {
|
||||||
|
return CreateConfig.parameters.motorCapacity.get().floatValue();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasFastRenderer() {
|
public boolean hasFastRenderer() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSource() {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
return true;
|
compound.putInt("GeneratedSpeed", generatedSpeed);
|
||||||
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSpeed(float speed) {
|
public void read(CompoundNBT compound) {
|
||||||
super.setSpeed(speed);
|
generatedSpeed = compound.getInt("GeneratedSpeed");
|
||||||
newSpeed = (int) speed;
|
if (lastModified == -1)
|
||||||
}
|
newGeneratedSpeed = generatedSpeed;
|
||||||
|
super.read(compound);
|
||||||
@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 setSpeedValueLazily(int speed) {
|
public void setSpeedValueLazily(int speed) {
|
||||||
if (newSpeed == speed)
|
if (newGeneratedSpeed == speed)
|
||||||
return;
|
return;
|
||||||
Integer max = CreateConfig.parameters.maxMotorSpeed.get();
|
Integer max = CreateConfig.parameters.maxMotorSpeed.get();
|
||||||
if (newSpeed > 0 && speed == 0)
|
if (newGeneratedSpeed > 0 && speed == 0)
|
||||||
newSpeed = -1;
|
newGeneratedSpeed = -1;
|
||||||
else if (newSpeed < 0 && speed == 0)
|
else if (newGeneratedSpeed < 0 && speed == 0)
|
||||||
newSpeed = 1;
|
newGeneratedSpeed = 1;
|
||||||
else
|
else
|
||||||
newSpeed = MathHelper.clamp(speed, -max, max);
|
newGeneratedSpeed = MathHelper.clamp(speed, -max, max);
|
||||||
this.lastModified = 0;
|
this.lastModified = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (!world.isRemote)
|
if (!world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (lastModified == -1)
|
if (lastModified == -1)
|
||||||
return;
|
return;
|
||||||
if (lastModified++ > 10) {
|
if (lastModified++ > 10) {
|
||||||
lastModified = -1;
|
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);
|
WaterWheelTileEntity te = (WaterWheelTileEntity) world.getTileEntity(pos);
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return;
|
return;
|
||||||
te.updateSpeed();
|
te.updateGeneratedRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,20 +2,18 @@ package com.simibubi.create.modules.contraptions.generators;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
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.nbt.CompoundNBT;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
|
||||||
public class WaterWheelTileEntity extends KineticTileEntity {
|
public class WaterWheelTileEntity extends GeneratingKineticTileEntity {
|
||||||
|
|
||||||
private Map<Direction, Integer> flows;
|
private Map<Direction, Integer> flows;
|
||||||
private boolean hasFlows;
|
|
||||||
|
|
||||||
public WaterWheelTileEntity() {
|
public WaterWheelTileEntity() {
|
||||||
super(AllTileEntities.WATER_WHEEL.type);
|
super(AllTileEntities.WATER_WHEEL.type);
|
||||||
|
@ -53,41 +51,18 @@ public class WaterWheelTileEntity extends KineticTileEntity {
|
||||||
public void setFlow(Direction direction, int speed) {
|
public void setFlow(Direction direction, int speed) {
|
||||||
flows.put(direction, speed);
|
flows.put(direction, speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reActivateSource() {
|
|
||||||
updateSpeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateSpeed() {
|
@Override
|
||||||
|
public float getGeneratedSpeed() {
|
||||||
float speed = 0;
|
float speed = 0;
|
||||||
for (Integer i : flows.values())
|
for (Integer i : flows.values())
|
||||||
speed += i;
|
speed += i;
|
||||||
|
return speed;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getAddedStressCapacity() {
|
public float getAddedStressCapacity() {
|
||||||
float torque = 0;
|
return CreateConfig.parameters.waterWheelCapacity.get().floatValue();
|
||||||
for (Integer i : flows.values())
|
|
||||||
torque += i;
|
|
||||||
return Math.abs(torque);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
|
@ -25,6 +26,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public class BasinInputInventory extends RecipeWrapper {
|
||||||
|
public BasinInputInventory() {
|
||||||
|
super(inputInventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected ItemStackHandler inputInventory = new ItemStackHandler(9) {
|
protected ItemStackHandler inputInventory = new ItemStackHandler(9) {
|
||||||
protected void onContentsChanged(int slot) {
|
protected void onContentsChanged(int slot) {
|
||||||
|
@ -69,10 +76,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
||||||
|
|
||||||
protected LazyOptional<IItemHandlerModifiable> inventory = LazyOptional
|
protected LazyOptional<IItemHandlerModifiable> inventory = LazyOptional
|
||||||
.of(() -> new BasinInventory(inputInventory, outputInventory));
|
.of(() -> new BasinInventory(inputInventory, outputInventory));
|
||||||
|
public BasinInputInventory recipeInventory;
|
||||||
|
|
||||||
public BasinTileEntity() {
|
public BasinTileEntity() {
|
||||||
super(AllTileEntities.BASIN.type);
|
super(AllTileEntities.BASIN.type);
|
||||||
updateProcessing = true;
|
updateProcessing = true;
|
||||||
|
recipeInventory = new BasinInputInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,13 +5,12 @@ import java.util.List;
|
||||||
import com.simibubi.create.AllRecipes;
|
import com.simibubi.create.AllRecipes;
|
||||||
import com.simibubi.create.modules.contraptions.base.ProcessingRecipe;
|
import com.simibubi.create.modules.contraptions.base.ProcessingRecipe;
|
||||||
import com.simibubi.create.modules.contraptions.base.StochasticOutput;
|
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.item.crafting.Ingredient;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.World;
|
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,
|
public CrushingRecipe(ResourceLocation id, String group, List<Ingredient> ingredients,
|
||||||
List<StochasticOutput> results, int processingDuration) {
|
List<StochasticOutput> results, int processingDuration) {
|
||||||
|
@ -19,7 +18,7 @@ public class CrushingRecipe extends ProcessingRecipe<CrushingWheelControllerTile
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(Inventory inv, World worldIn) {
|
public boolean matches(ProcessingInventory inv, World worldIn) {
|
||||||
if (inv.isEmpty())
|
if (inv.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
return ingredients.get(0).test(inv.getStackInSlot(0));
|
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.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.StateContainer.Builder;
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
|
@ -38,6 +39,11 @@ public class CrushingWheelControllerBlock extends Block implements IWithoutBlock
|
||||||
public boolean hasTileEntity(BlockState state) {
|
public boolean hasTileEntity(BlockState state) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReplaceable(BlockState state, BlockItemUseContext useContext) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.inventory.ItemStackHelper;
|
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -23,59 +22,11 @@ import net.minecraft.particles.ItemParticleData;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.Vec3d;
|
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 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()
|
private static DamageSource damageSource = new DamageSource("create.crush").setDamageBypassesArmor()
|
||||||
.setDifficultyScaled();
|
.setDifficultyScaled();
|
||||||
|
|
||||||
|
@ -83,12 +34,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
private UUID entityUUID;
|
private UUID entityUUID;
|
||||||
protected boolean searchForEntity;
|
protected boolean searchForEntity;
|
||||||
|
|
||||||
private Inventory contents;
|
private ProcessingInventory contents;
|
||||||
public float crushingspeed;
|
public float crushingspeed;
|
||||||
|
|
||||||
public CrushingWheelControllerTileEntity() {
|
public CrushingWheelControllerTileEntity() {
|
||||||
super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type);
|
super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type);
|
||||||
contents = new Inventory();
|
contents = new ProcessingInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -236,7 +187,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
this.searchForEntity = true;
|
this.searchForEntity = true;
|
||||||
}
|
}
|
||||||
crushingspeed = compound.getFloat("Speed");
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -73,10 +73,10 @@ public class DrillTileEntity extends KineticTileEntity {
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING));
|
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 static net.minecraft.util.Direction.AxisDirection.POSITIVE;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlockTags;
|
import com.simibubi.create.AllBlockTags;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
@ -14,7 +13,7 @@ import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.CreateConfig;
|
import com.simibubi.create.CreateConfig;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
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;
|
||||||
import com.simibubi.create.modules.logistics.InWorldProcessing.Type;
|
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.Vec3d;
|
||||||
import net.minecraft.util.math.Vec3i;
|
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()
|
private static DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled()
|
||||||
.setFireDamage();
|
.setFireDamage();
|
||||||
|
@ -87,13 +86,13 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSource() {
|
public float getAddedStressCapacity() {
|
||||||
return isGenerator;
|
return isGenerator ? CreateConfig.parameters.generatingFanCapacity.get().floatValue() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getAddedStressCapacity() {
|
public float getGeneratedSpeed() {
|
||||||
return 50;
|
return isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateGenerator() {
|
public void updateGenerator() {
|
||||||
|
@ -102,14 +101,7 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isGenerator = shouldGenerate;
|
isGenerator = shouldGenerate;
|
||||||
if (isGenerator) {
|
updateGeneratedRotation();
|
||||||
notifyStressCapacityChange(getAddedStressCapacity());
|
|
||||||
removeSource();
|
|
||||||
} else {
|
|
||||||
notifyStressCapacityChange(0);
|
|
||||||
}
|
|
||||||
applyNewSpeed(isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0);
|
|
||||||
sendData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean blockBelowIsHot() {
|
public boolean blockBelowIsHot() {
|
||||||
|
@ -122,7 +114,7 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float speed = Math.abs(this.speed);
|
float speed = Math.abs(this.getSpeed());
|
||||||
float distanceFactor = Math.min(speed / parameters.fanRotationArgmax.get(), 1);
|
float distanceFactor = Math.min(speed / parameters.fanRotationArgmax.get(), 1);
|
||||||
|
|
||||||
pushDistance = MathHelper.lerp(distanceFactor, 3, parameters.fanMaxPushDistance.get());
|
pushDistance = MathHelper.lerp(distanceFactor, 3, parameters.fanMaxPushDistance.get());
|
||||||
|
@ -180,9 +172,9 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Direction getAirFlow() {
|
public Direction getAirFlow() {
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
return null;
|
return null;
|
||||||
return Direction.getFacingFromAxisDirection(getBlockState().get(AXIS), speed > 0 ? POSITIVE : NEGATIVE);
|
return Direction.getFacingFromAxisDirection(getBlockState().get(AXIS), getSpeed() > 0 ? POSITIVE : NEGATIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -191,17 +183,11 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
updateFrontBlock();
|
updateFrontBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reActivateSource() {
|
|
||||||
source = Optional.empty();
|
|
||||||
applyNewSpeed(isGenerator ? CreateConfig.parameters.generatingFanSpeed.get() : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (speed == 0 || isGenerator)
|
if (getSpeed() == 0 || isGenerator)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<Entity> frontEntities = world.getEntitiesWithinAABBExcludingEntity(null, frontBB);
|
List<Entity> frontEntities = world.getEntitiesWithinAABBExcludingEntity(null, frontBB);
|
||||||
|
@ -308,7 +294,7 @@ public class EncasedFanTileEntity extends KineticTileEntity {
|
||||||
Vec3i flow = getAirFlow().getDirectionVec();
|
Vec3i flow = getAirFlow().getDirectionVec();
|
||||||
|
|
||||||
float sneakModifier = entity.isSneaking() ? 4096f : 512f;
|
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)));
|
/ (entity.getPositionVec().distanceTo(center) / (push ? pushDistance : pullDistance)));
|
||||||
Vec3d previousMotion = entity.getMotion();
|
Vec3d previousMotion = entity.getMotion();
|
||||||
float maxAcceleration = 5;
|
float maxAcceleration = 5;
|
||||||
|
|
|
@ -87,6 +87,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getRenderedHeadRotationSpeed(float partialTicks) {
|
public float getRenderedHeadRotationSpeed(float partialTicks) {
|
||||||
|
float speed = getSpeed();
|
||||||
if (running) {
|
if (running) {
|
||||||
if (runningTicks < 15) {
|
if (runningTicks < 15) {
|
||||||
return speed;
|
return speed;
|
||||||
|
@ -154,13 +155,14 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float speed = Math.abs(getSpeed());
|
||||||
if (running) {
|
if (running) {
|
||||||
if (world.isRemote && runningTicks == 20)
|
if (world.isRemote && runningTicks == 20)
|
||||||
renderParticles();
|
renderParticles();
|
||||||
|
|
||||||
if (!world.isRemote && runningTicks == 20) {
|
if (!world.isRemote && runningTicks == 20) {
|
||||||
if (processingTicks < 0) {
|
if (processingTicks < 0) {
|
||||||
processingTicks = (MathHelper.log2((int) (8000 / Math.abs(speed)))) * 15 + 1;
|
processingTicks = (MathHelper.log2((int) (8000 / speed))) * 15 + 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
processingTicks--;
|
processingTicks--;
|
||||||
|
@ -178,7 +180,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Math.abs(speed) < 32)
|
if (speed < 32)
|
||||||
return;
|
return;
|
||||||
if (!checkBasin)
|
if (!checkBasin)
|
||||||
return;
|
return;
|
||||||
|
@ -229,7 +231,7 @@ public class MechanicalMixerTileEntity extends KineticTileEntity {
|
||||||
float angle = world.rand.nextFloat() * 360;
|
float angle = world.rand.nextFloat() * 360;
|
||||||
Vec3d offset = new Vec3d(0, 0, 0.25f);
|
Vec3d offset = new Vec3d(0, 0, 0.25f);
|
||||||
offset = VecHelper.rotate(offset, angle, Axis.Y);
|
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));
|
Vec3d center = offset.add(VecHelper.getCenterOf(pos));
|
||||||
target = VecHelper.offsetRandomly(target.subtract(offset), world.rand, 1 / 128f);
|
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.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.material.PushReaction;
|
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.item.BlockItemUseContext;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.StateContainer.Builder;
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
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.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
|
@ -26,6 +31,7 @@ public class SawBlock extends DirectionalAxisKineticBlock
|
||||||
implements IWithTileEntity<SawTileEntity>, IHaveMovementBehavior {
|
implements IWithTileEntity<SawTileEntity>, IHaveMovementBehavior {
|
||||||
|
|
||||||
public static final BooleanProperty RUNNING = BooleanProperty.create("running");
|
public static final BooleanProperty RUNNING = BooleanProperty.create("running");
|
||||||
|
public static DamageSource damageSourceSaw = new DamageSource("create.saw").setDamageBypassesArmor();
|
||||||
|
|
||||||
public SawBlock() {
|
public SawBlock() {
|
||||||
super(Properties.from(Blocks.ANDESITE));
|
super(Properties.from(Blocks.ANDESITE));
|
||||||
|
@ -67,6 +73,29 @@ public class SawBlock extends DirectionalAxisKineticBlock
|
||||||
return VoxelShapers.SHORT_CASING.get(state.get(FACING));
|
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
|
@Override
|
||||||
public PushReaction getPushReaction(BlockState state) {
|
public PushReaction getPushReaction(BlockState state) {
|
||||||
return PushReaction.PUSH_ONLY;
|
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 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.AllTileEntities;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
|
||||||
public class SawTileEntity extends KineticTileEntity {
|
public class SawTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
|
public ProcessingInventory inventory;
|
||||||
|
|
||||||
public SawTileEntity() {
|
public SawTileEntity() {
|
||||||
super(AllTileEntities.SAW.type);
|
super(AllTileEntities.SAW.type);
|
||||||
|
inventory = new ProcessingInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSpeedChanged() {
|
public void onSpeedChanged() {
|
||||||
boolean shouldRun = Math.abs(speed) > 1 / 64f;
|
boolean shouldRun = Math.abs(getSpeed()) > 1 / 64f;
|
||||||
boolean running = getBlockState().get(RUNNING);
|
boolean running = getBlockState().get(RUNNING);
|
||||||
if (shouldRun != running)
|
if (shouldRun != running)
|
||||||
world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun));
|
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;
|
package com.simibubi.create.modules.contraptions.receivers.constructs;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.modules.contraptions.RotationPropagator;
|
import com.simibubi.create.CreateConfig;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
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.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
public class MechanicalBearingTileEntity extends KineticTileEntity {
|
public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity {
|
||||||
|
|
||||||
protected RotationConstruct movingConstruct;
|
protected RotationConstruct movingConstruct;
|
||||||
protected float angle;
|
protected float angle;
|
||||||
|
@ -36,21 +34,16 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
public AxisAlignedBB getRenderBoundingBox() {
|
public AxisAlignedBB getRenderBoundingBox() {
|
||||||
return INFINITE_EXTENT_AABB;
|
return INFINITE_EXTENT_AABB;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
public double getMaxRenderDistanceSquared() {
|
public double getMaxRenderDistanceSquared() {
|
||||||
return super.getMaxRenderDistanceSquared() * 16;
|
return super.getMaxRenderDistanceSquared() * 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getAddedStressCapacity() {
|
|
||||||
return getWindmillSpeed() * 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSource() {
|
public float getAddedStressCapacity() {
|
||||||
return isWindmill;
|
return isWindmill ? CreateConfig.parameters.mechanicalBearingCapacity.get().floatValue() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void neighbourChanged() {
|
public void neighbourChanged() {
|
||||||
|
@ -59,20 +52,14 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
isWindmill = shouldWindmill;
|
isWindmill = shouldWindmill;
|
||||||
if (isWindmill)
|
if (isWindmill && !running)
|
||||||
removeSource();
|
|
||||||
|
|
||||||
if (isWindmill && !running) {
|
|
||||||
assembleNextTick = true;
|
assembleNextTick = true;
|
||||||
}
|
if (isWindmill && running)
|
||||||
|
updateGeneratedRotation();
|
||||||
if (isWindmill && running) {
|
|
||||||
applyNewSpeed(getWindmillSpeed());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isWindmill && running) {
|
if (!isWindmill && running) {
|
||||||
applyNewSpeed(0);
|
updateGeneratedRotation();
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
disassembleConstruct();
|
disassembleConstruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +73,9 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
super.remove();
|
super.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getWindmillSpeed() {
|
@Override
|
||||||
if (!running)
|
public float getGeneratedSpeed() {
|
||||||
|
if (!running || !isWindmill)
|
||||||
return 0;
|
return 0;
|
||||||
int sails = movingConstruct.getSailBlocks();
|
int sails = movingConstruct.getSailBlocks();
|
||||||
return MathHelper.clamp(sails, 0, 128);
|
return MathHelper.clamp(sails, 0, 128);
|
||||||
|
@ -128,7 +116,7 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getAngularSpeed() {
|
public float getAngularSpeed() {
|
||||||
return speed / 2048;
|
return getSpeed() / 2048;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assembleConstruct() {
|
public void assembleConstruct() {
|
||||||
|
@ -150,17 +138,7 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
|
getWorld().setBlockState(info.pos.add(pos), Blocks.AIR.getDefaultState(), 67);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyWindmillSpeed();
|
updateGeneratedRotation();
|
||||||
}
|
|
||||||
|
|
||||||
public void applyWindmillSpeed() {
|
|
||||||
if (isWindmill) {
|
|
||||||
RotationPropagator.handleRemoved(world, pos, this);
|
|
||||||
source = Optional.empty();
|
|
||||||
speed = getWindmillSpeed();
|
|
||||||
RotationPropagator.handleAdded(world, pos, this);
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassembleConstruct() {
|
public void disassembleConstruct() {
|
||||||
|
@ -186,18 +164,14 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
running = false;
|
running = false;
|
||||||
movingConstruct = null;
|
movingConstruct = null;
|
||||||
angle = 0;
|
angle = 0;
|
||||||
|
updateGeneratedRotation();
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reActivateSource() {
|
|
||||||
applyWindmillSpeed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (running && RotationConstruct.isFrozen())
|
if (running && RotationConstruct.isFrozen())
|
||||||
disassembleConstruct();
|
disassembleConstruct();
|
||||||
|
|
||||||
|
@ -210,6 +184,8 @@ public class MechanicalBearingTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
if (speed == 0 && !isWindmill)
|
||||||
|
return;
|
||||||
assembleConstruct();
|
assembleConstruct();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -189,11 +189,11 @@ public class MechanicalPistonTileEntity extends KineticTileEntity {
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (!world.isRemote && assembleNextTick) {
|
if (!world.isRemote && assembleNextTick) {
|
||||||
assembleNextTick = false;
|
assembleNextTick = false;
|
||||||
if (running) {
|
if (running) {
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
disassembleConstruct();
|
disassembleConstruct();
|
||||||
else {
|
else {
|
||||||
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors())
|
for (MutablePair<BlockInfo, MovementContext> pair : movedContraption.getActors())
|
||||||
|
|
|
@ -49,9 +49,8 @@ public class GearshiftBlock extends EncasedShaftBlock {
|
||||||
|
|
||||||
boolean previouslyPowered = state.get(POWERED);
|
boolean previouslyPowered = state.get(POWERED);
|
||||||
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
if (previouslyPowered != worldIn.isBlockPowered(pos)) {
|
||||||
worldIn.setBlockState(pos, state.cycle(POWERED), 2);
|
worldIn.setBlockState(pos, state.cycle(POWERED), 2 | 16);
|
||||||
if (!previouslyPowered)
|
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos));
|
||||||
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))
|
if (axis != world.getBlockState(second).get(BlockStateProperties.AXIS))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).getSpeed();
|
float speed1 = ((KineticTileEntity) world.getTileEntity(first)).speed;
|
||||||
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getSpeed();
|
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).speed;
|
||||||
if (Math.signum(speed1) != Math.signum(speed2) && speed1 != 0 && speed2 != 0)
|
if (Math.signum(speed1) != Math.signum(speed2) && speed1 != 0 && speed2 != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isLastBelt() {
|
protected boolean isLastBelt() {
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Direction direction = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
Direction direction = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING);
|
||||||
|
@ -83,7 +83,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
if (part == Part.MIDDLE)
|
if (part == Part.MIDDLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boolean movingPositively = (speed > 0 == (direction.getAxisDirection().getOffset() == 1))
|
boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1))
|
||||||
^ direction.getAxis() == Axis.X;
|
^ direction.getAxis() == Axis.X;
|
||||||
return part == Part.START ^ movingPositively;
|
return part == Part.START ^ movingPositively;
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (world != null && trackerUpdateTag != null) {
|
if (world != null && trackerUpdateTag != null) {
|
||||||
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
||||||
trackerUpdateTag = null;
|
trackerUpdateTag = null;
|
||||||
|
@ -169,7 +169,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
passengers.remove(e);
|
passengers.remove(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (speed == 0)
|
if (getSpeed() == 0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
BlockState blockState = info.lastCollidedState;
|
BlockState blockState = info.lastCollidedState;
|
||||||
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
Direction movementFacing = Direction.getFacingFromAxisDirection(
|
||||||
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
blockState.get(BlockStateProperties.HORIZONTAL_FACING).getAxis(),
|
||||||
speed < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
getSpeed() < 0 ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
||||||
|
|
||||||
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
boolean collidedWithBelt = te instanceof BeltTileEntity;
|
||||||
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
boolean betweenBelts = tileEntityBelowPassenger instanceof BeltTileEntity && tileEntityBelowPassenger != te;
|
||||||
|
|
|
@ -1,8 +1,17 @@
|
||||||
package com.simibubi.create.modules.curiosities.deforester;
|
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 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.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 {
|
public class DeforesterItem extends AxeItem {
|
||||||
|
|
||||||
|
@ -10,4 +19,22 @@ public class DeforesterItem extends AxeItem {
|
||||||
super(AllToolTiers.RADIANT, 10.0F, -3.1F, builder);
|
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