Merge remote-tracking branch 'origin/mc1.14-v0.2.3' into mc1.15-v0.2.2

# Conflicts:
#	build.gradle
#	src/main/java/com/simibubi/create/foundation/utility/SuperByteBuffer.java
#	src/main/java/com/simibubi/create/foundation/world/AllWorldFeatures.java
#	src/main/java/com/simibubi/create/modules/contraptions/components/crusher/CrushingWheelBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/components/fan/EncasedFanBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/components/millstone/MillstoneBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/components/turntable/TurntableBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/processing/BasinBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/redstone/AnalogLeverBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltBlock.java
#	src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java
#	src/main/java/com/simibubi/create/modules/curiosities/partialWindows/WindowInABlockModel.java
#	src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkBlock.java
#	src/main/java/com/simibubi/create/modules/logistics/block/StockswitchBlock.java
#	src/main/java/com/simibubi/create/modules/palettes/CTGlassPaneBlock.java
#	src/main/java/com/simibubi/create/modules/schematics/block/SchematicTableBlock.java
#	src/main/java/com/simibubi/create/modules/schematics/block/SchematicannonBlock.java
#	src/main/resources/META-INF/mods.toml
This commit is contained in:
tterrag 2020-04-12 15:25:52 -04:00
commit a1605af46a
138 changed files with 3025 additions and 1226 deletions

38
README.md Normal file
View file

@ -0,0 +1,38 @@
# Create
Welcome to Create, a mod offering a variety of tools and blocks for Building, Decoration and Aesthetic Automation.
The added elements of tech are designed to leave as many design choices to the player as possible, where item processing doesn't happen inside a single block with funny textures, it requires a set of actors working together in many possible arrangements.
Check out the wiki and in-game Tool-tips for further info on how to use these features, and stay tuned for an ever-growing selection of possibilities for Creative and Survival Minecraft.
## Links
[<img src="https://i.imgur.com/0lLX9Oy.jpg" width="320">](https://github.com/simibubi/Create/issues "Report Issues")
[<img src="https://i.imgur.com/bjEZraY.jpg" width="320">](https://www.youtube.com/playlist?list=PLyADkcfPLU8ywCXZPaDbQ_JZJL0CGDN5Z "Watch Videos")
[<img src="https://i.imgur.com/aWrjfKJ.jpg" width="320">](https://discord.gg/hmaD7Se "Feedback & Help")
[<img src="https://i.imgur.com/xj8o2xC.jpg" width="320">](https://www.patreon.com/simibubi "Support Us")
## Current Progress
- Create 0.2.2 is coming soon with more bug-fixes. Thank you for testing Create with us!
- Support for Minecraft 1.12: Not planned
- Support for Minecraft 1.15: Porting work is in Progress!
- Support for Fabric: Not planned
## The Creators of Create
- evanthebruce - Resident Nitwit
- fuzzyweapon - Contributor
- LeastReality - Artist
- Zelophed - Developer
- simibubi - Developer & Artist
- tterrag - Developer & Port-Meister
## Localization
| Code | Version | Language | Author |
|-------|---------|------------|--------------------------|
| en_us | 0.2.2 | English US | |
| de_de | 0.1 | German | Vexatos & Azratosh |
| nl_nl | 0.1 | Dutch | Prusias |
| fr_fr | 0.2.1 | French | Kiro |
| zh_cn | 0.2.1 | Chinese | noptia & spider_stranger |
| ru_ru | 0.1 | Russian | sirabein |
| pt_br | 0.1 | Brazilian | lucassabreu |

View file

@ -13,7 +13,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'eclipse' apply plugin: 'eclipse'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
version = 'mc1.15.2_v0.2.2' version = 'mc1.15.2_v0.2.3'
group = 'com.simibubi.create' group = 'com.simibubi.create'
archivesBaseName = 'create' archivesBaseName = 'create'
@ -21,6 +21,7 @@ sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = co
minecraft { minecraft {
mappings channel: 'snapshot', version: '20200301-mixed-1.15.2' mappings channel: 'snapshot', version: '20200301-mixed-1.15.2'
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs { runs {
client { client {

View file

@ -1,5 +1,8 @@
package com.simibubi.create; package com.simibubi.create;
import java.util.HashSet;
import java.util.Set;
import com.simibubi.create.foundation.block.IHaveColorHandler; import com.simibubi.create.foundation.block.IHaveColorHandler;
import com.simibubi.create.foundation.block.IHaveCustomBlockItem; import com.simibubi.create.foundation.block.IHaveCustomBlockItem;
import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
@ -45,7 +48,6 @@ import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerBlock; import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerBlock;
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock; import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelBlock;
import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock;
import com.simibubi.create.modules.contraptions.relays.encased.AdjustablePulleyBlock; import com.simibubi.create.modules.contraptions.relays.encased.AdjustablePulleyBlock;
@ -62,14 +64,15 @@ import com.simibubi.create.modules.curiosities.symmetry.block.TriplePlaneSymmetr
import com.simibubi.create.modules.gardens.CocoaLogBlock; import com.simibubi.create.modules.gardens.CocoaLogBlock;
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock; import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
import com.simibubi.create.modules.logistics.block.StockswitchBlock; import com.simibubi.create.modules.logistics.block.StockswitchBlock;
import com.simibubi.create.modules.logistics.block.belts.BeltObserverBlock; import com.simibubi.create.modules.logistics.block.belts.observer.BeltObserverBlock;
import com.simibubi.create.modules.logistics.block.belts.FunnelBlock; import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock; import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock;
import com.simibubi.create.modules.logistics.block.diodes.LatchBlock; import com.simibubi.create.modules.logistics.block.diodes.LatchBlock;
import com.simibubi.create.modules.logistics.block.diodes.PulseRepeaterBlock; import com.simibubi.create.modules.logistics.block.diodes.PulseRepeaterBlock;
import com.simibubi.create.modules.logistics.block.diodes.ToggleLatchBlock; import com.simibubi.create.modules.logistics.block.diodes.ToggleLatchBlock;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorBlock;
import com.simibubi.create.modules.logistics.block.funnel.FunnelBlock;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerBlock; import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerBlock;
import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock;
@ -107,9 +110,6 @@ import net.minecraftforge.common.ToolType;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.IForgeRegistry;
import java.util.HashSet;
import java.util.Set;
public enum AllBlocks { public enum AllBlocks {
__SCHEMATICS__(), __SCHEMATICS__(),

View file

@ -55,8 +55,6 @@ public enum AllContainers {
bind(SCHEMATIC_TABLE, SchematicTableScreen::new); bind(SCHEMATIC_TABLE, SchematicTableScreen::new);
bind(SCHEMATICANNON, SchematicannonScreen::new); bind(SCHEMATICANNON, SchematicannonScreen::new);
bind(FLEXCRATE, FlexcrateScreen::new); bind(FLEXCRATE, FlexcrateScreen::new);
// bind(LOGISTICAL_INDEX, LogisticalIndexScreen::new);
// bind(LOGISTICAL_CONTROLLER, LogisticalInventoryControllerScreen::new);
bind(FILTER, FilterScreen::new); bind(FILTER, FilterScreen::new);
bind(ATTRIBUTE_FILTER, AttributeFilterScreen::new); bind(ATTRIBUTE_FILTER, AttributeFilterScreen::new);
} }

View file

@ -16,7 +16,7 @@ import com.simibubi.create.foundation.utility.data.ITaggable;
import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.IModule;
import com.simibubi.create.modules.contraptions.GogglesItem; import com.simibubi.create.modules.contraptions.GogglesItem;
import com.simibubi.create.modules.contraptions.WrenchItem; import com.simibubi.create.modules.contraptions.WrenchItem;
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItem; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem; import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem; import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
import com.simibubi.create.modules.curiosities.RefinedRadianceItem; import com.simibubi.create.modules.curiosities.RefinedRadianceItem;
@ -42,8 +42,8 @@ import net.minecraft.item.Item;
import net.minecraft.item.Item.Properties; import net.minecraft.item.Item.Properties;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Rarity; import net.minecraft.item.Rarity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.item.SwordItem; import net.minecraft.item.SwordItem;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;

View file

@ -56,8 +56,6 @@ import com.simibubi.create.modules.contraptions.relays.advanced.SpeedControllerT
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity; import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntityRenderer; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.elementary.ShaftTileEntity; import com.simibubi.create.modules.contraptions.relays.elementary.ShaftTileEntity;
import com.simibubi.create.modules.contraptions.relays.encased.AdjustablePulleyTileEntity; import com.simibubi.create.modules.contraptions.relays.encased.AdjustablePulleyTileEntity;
import com.simibubi.create.modules.contraptions.relays.encased.ClutchTileEntity; import com.simibubi.create.modules.contraptions.relays.encased.ClutchTileEntity;
@ -74,14 +72,16 @@ import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEnti
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockTileEntity; import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockTileEntity;
import com.simibubi.create.modules.logistics.block.RedstoneLinkTileEntity; import com.simibubi.create.modules.logistics.block.RedstoneLinkTileEntity;
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity; import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
import com.simibubi.create.modules.logistics.block.belts.BeltObserverTileEntity; import com.simibubi.create.modules.logistics.block.belts.observer.BeltObserverTileEntity;
import com.simibubi.create.modules.logistics.block.belts.BeltObserverTileEntityRenderer; import com.simibubi.create.modules.logistics.block.belts.observer.BeltObserverTileEntityRenderer;
import com.simibubi.create.modules.logistics.block.belts.FunnelTileEntity; import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelTileEntity;
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelTileEntityRenderer;
import com.simibubi.create.modules.logistics.block.diodes.FlexPulsepeaterTileEntity; import com.simibubi.create.modules.logistics.block.diodes.FlexPulsepeaterTileEntity;
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntity; import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntity;
import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntityRenderer; import com.simibubi.create.modules.logistics.block.diodes.FlexpeaterTileEntityRenderer;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity; import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity;
import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorTileEntity; import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorTileEntity;
import com.simibubi.create.modules.logistics.block.funnel.FunnelTileEntity;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateTileEntity; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateTileEntity;
import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerTileEntity; import com.simibubi.create.modules.logistics.block.transposer.LinkedTransposerTileEntity;
import com.simibubi.create.modules.logistics.block.transposer.TransposerTileEntity; import com.simibubi.create.modules.logistics.block.transposer.TransposerTileEntity;

View file

@ -14,7 +14,7 @@ import com.simibubi.create.modules.contraptions.KineticDebugger;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay; import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay;
import com.simibubi.create.modules.contraptions.components.turntable.TurntableHandler; import com.simibubi.create.modules.contraptions.components.turntable.TurntableHandler;
import com.simibubi.create.modules.contraptions.relays.belt.BeltConnectorItemHandler; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorHandler;
import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainZapperRenderHandler; import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainZapperRenderHandler;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -65,7 +65,7 @@ public class ClientEvents {
public static void onGameTick() { public static void onGameTick() {
CreateClient.gameTick(); CreateClient.gameTick();
BeltConnectorItemHandler.gameTick(); BeltConnectorHandler.gameTick();
TerrainZapperRenderHandler.tick(); TerrainZapperRenderHandler.tick();
} }

View file

@ -1,27 +1,10 @@
package com.simibubi.create; package com.simibubi.create;
import java.util.Arrays;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.modules.curiosities.partialWindows.WindowInABlockTileEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.FourWayBlock;
import net.minecraft.block.WallBlock;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.state.BooleanProperty;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.Tags;
import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.event.TickEvent.ServerTickEvent; import net.minecraftforge.event.TickEvent.ServerTickEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.Event.Result;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -59,60 +42,4 @@ public class Events {
Create.torquePropagator.onUnloadWorld(world); Create.torquePropagator.onUnloadWorld(world);
} }
@SubscribeEvent
public static void onRightClickBlock(RightClickBlock event) {
if (event.getUseItem() == Result.DENY)
return;
if (event.getEntityLiving().isSneaking())
return;
if (!event.getPlayer().isAllowEdit())
return;
if (!AllConfigs.SERVER.curiosities.allowGlassPanesInPartialBlocks.get())
return;
ItemStack stack = event.getItemStack();
if (stack.isEmpty())
return;
if (!(stack.getItem() instanceof BlockItem))
return;
BlockItem item = (BlockItem) stack.getItem();
if (!item.isIn(Tags.Items.GLASS_PANES)
&& (item.getBlock() == null || !item.getBlock().isIn(Tags.Blocks.GLASS_PANES)))
return;
BlockPos pos = event.getPos();
World world = event.getWorld();
BlockState blockState = world.getBlockState(pos);
if (!AllBlockTags.WINDOWABLE.matches(blockState))
return;
if (AllBlocks.WINDOW_IN_A_BLOCK.typeOf(blockState))
return;
BlockState defaultState = AllBlocks.WINDOW_IN_A_BLOCK.get().getDefaultState();
world.setBlockState(pos, defaultState);
TileEntity te = world.getTileEntity(pos);
if (te != null && te instanceof WindowInABlockTileEntity) {
WindowInABlockTileEntity wte = (WindowInABlockTileEntity) te;
wte.setWindowBlock(item.getBlock().getDefaultState());
wte.updateWindowConnections();
if (blockState.getBlock() instanceof FourWayBlock) {
for (BooleanProperty side : Arrays.asList(FourWayBlock.EAST, FourWayBlock.NORTH, FourWayBlock.SOUTH,
FourWayBlock.WEST))
blockState = blockState.with(side, false);
}
if (blockState.getBlock() instanceof WallBlock)
blockState = blockState.with(WallBlock.UP, true);
wte.setPartialBlock(blockState);
wte.requestModelDataUpdate();
if (!event.getPlayer().isCreative())
stack.shrink(1);
event.getPlayer().swingArm(event.getHand());
}
event.setCanceled(true);
}
} }

View file

@ -3,6 +3,7 @@ package com.simibubi.create.config;
public class CCommon extends ConfigBase { public class CCommon extends ConfigBase {
public CWorldGen worldGen = nested(0, CWorldGen::new, Comments.worldGen); public CWorldGen worldGen = nested(0, CWorldGen::new, Comments.worldGen);
public ConfigBool logTeErrors = b(false, "logTeErrors", Comments.logTeErrors);
@Override @Override
public String getName() { public String getName() {
@ -11,6 +12,7 @@ public class CCommon extends ConfigBase {
private static class Comments { private static class Comments {
static String worldGen = "Modify Create's impact on your terrain"; static String worldGen = "Modify Create's impact on your terrain";
static String logTeErrors = "Forward caught TileEntityExceptions to the log at debug level.";
} }
} }

View file

@ -11,7 +11,6 @@ public class CCuriosities extends ConfigBase {
public ConfigBool enableRefinedRadianceRecipe = b(true, "enableRefinedRadianceRecipe", public ConfigBool enableRefinedRadianceRecipe = b(true, "enableRefinedRadianceRecipe",
Comments.refinedRadianceRecipe); Comments.refinedRadianceRecipe);
public ConfigBool enableShadowSteelRecipe = b(true, "enableShadowSteelRecipe", Comments.shadowSteelRecipe); public ConfigBool enableShadowSteelRecipe = b(true, "enableShadowSteelRecipe", Comments.shadowSteelRecipe);
public ConfigBool enableSandPaperToolPolishing = b(true, "enableSandPaperToolPolishing", Comments.sandPaperOnTools);
public ConfigFloat cocoaLogGrowthSpeed = f(20, 0, 100, "cocoaLogGrowthSpeed", Comments.cocoa); public ConfigFloat cocoaLogGrowthSpeed = f(20, 0, 100, "cocoaLogGrowthSpeed", Comments.cocoa);
@Override @Override
@ -24,7 +23,6 @@ public class CCuriosities extends ConfigBase {
static String refinedRadiance = "The amount of Light sources destroyed before Chromatic Compound turns into Refined Radiance."; static String refinedRadiance = "The amount of Light sources destroyed before Chromatic Compound turns into Refined Radiance.";
static String refinedRadianceRecipe = "Allow the standard Refined Radiance recipes."; static String refinedRadianceRecipe = "Allow the standard Refined Radiance recipes.";
static String shadowSteelRecipe = "Allow the standard Shadow Steel recipe."; static String shadowSteelRecipe = "Allow the standard Shadow Steel recipe.";
static String sandPaperOnTools = "Enable the tool repairing mechanic involving sand paper.";
static String windowsInBlocks = "Allow Glass Panes to be put inside Blocks like Stairs, Slabs, Fences etc."; static String windowsInBlocks = "Allow Glass Panes to be put inside Blocks like Stairs, Slabs, Fences etc.";
static String cocoa = "% of random Ticks causing a Cocoa log to grow."; static String cocoa = "% of random Ticks causing a Cocoa log to grow.";
static String zapperUndoLogLength = "The maximum amount of operations, a blockzapper can remember for undoing. (0 to disable undo)"; static String zapperUndoLogLength = "The maximum amount of operations, a blockzapper can remember for undoing. (0 to disable undo)";

View file

@ -28,7 +28,7 @@ public class CWorldGen extends ConfigBase {
@Override @Override
public String getName() { public String getName() {
return "world"; return "worldgen.v" + AllWorldFeatures.forcedUpdateVersion;
} }
private static class Comments { private static class Comments {

View file

@ -0,0 +1,100 @@
package com.simibubi.create.foundation.block;
import java.util.function.Consumer;
import com.simibubi.create.Create;
import com.simibubi.create.config.AllConfigs;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.dimension.Dimension;
import net.minecraft.world.dimension.DimensionType;
public interface ITE<T extends TileEntity> {
Class<T> getTileEntityClass();
default void withTileEntityDo(IBlockReader world, BlockPos pos, Consumer<T> action) {
try {
action.accept(getTileEntity(world, pos));
} catch (TileEntityException e) {}
}
@SuppressWarnings("unchecked")
default T getTileEntity(IBlockReader worldIn, BlockPos pos) throws TileEntityException {
TileEntity tileEntity = worldIn.getTileEntity(pos);
Class<T> expectedClass = getTileEntityClass();
IWorld world = null;
if (worldIn instanceof IWorld)
world = (IWorld) worldIn;
if (tileEntity == null)
throw new MissingTileEntityException(world, pos, expectedClass);
if (!expectedClass.isInstance(tileEntity))
throw new InvalidTileEntityException(world, pos, expectedClass, tileEntity.getClass());
return (T) tileEntity;
}
static class TileEntityException extends Throwable {
private static final long serialVersionUID = 1L;
public TileEntityException(IWorld world, BlockPos pos, Class<?> teClass) {
super(makeBaseMessage(world, pos, teClass));
}
public TileEntityException(String message) {
super(message);
report(this);
}
static String makeBaseMessage(IWorld world, BlockPos pos, Class<?> expectedTeClass) {
return String.format("[%s] @(%d, %d, %d), expecting a %s", getDimensionName(world), pos.getX(), pos.getY(),
pos.getZ(), expectedTeClass.getSimpleName());
}
static String getDimensionName(IWorld world) {
String notAvailable = "Dim N/A";
if (world == null)
return notAvailable;
Dimension dimension = world.getDimension();
if (dimension == null)
return notAvailable;
DimensionType type = dimension.getType();
if (type == null)
return notAvailable;
ResourceLocation registryName = type.getRegistryName();
if (registryName == null)
return notAvailable;
return registryName.toString();
}
}
static class MissingTileEntityException extends TileEntityException {
private static final long serialVersionUID = 1L;
public MissingTileEntityException(IWorld world, BlockPos pos, Class<?> teClass) {
super("Missing TileEntity: " + makeBaseMessage(world, pos, teClass));
}
}
static class InvalidTileEntityException extends TileEntityException {
private static final long serialVersionUID = 1L;
public InvalidTileEntityException(IWorld world, BlockPos pos, Class<?> expectedTeClass, Class<?> foundTeClass) {
super("Wrong TileEntity: " + makeBaseMessage(world, pos, expectedTeClass) + ", found "
+ foundTeClass.getSimpleName());
}
}
static void report(TileEntityException e) {
if (AllConfigs.COMMON.logTeErrors.get())
Create.logger.debug("TileEntityException thrown!", e);
}
}

View file

@ -7,13 +7,15 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkHooks;
public interface IWithContainerTileEntity<T extends TileEntity & IWithContainer<T, ?>> extends IWithTileEntity<T> { public interface IWithContainerTileEntity<T extends TileEntity & IWithContainer<T, ?>> extends ITE<T> {
default void open(IWorld world, BlockPos pos, PlayerEntity player) { default void open(IWorld world, BlockPos pos, PlayerEntity player) {
T te = getTileEntity(world, pos); if (world.isRemote())
if (te == null || world.isRemote())
return; return;
NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer); try {
T te = getTileEntity(world, pos);
NetworkHooks.openGui((ServerPlayerEntity) player, te, te::sendToContainer);
} catch (TileEntityException e) {}
} }
} }

View file

@ -1,27 +0,0 @@
package com.simibubi.create.foundation.block;
import java.util.function.Consumer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
public interface IWithTileEntity<T extends TileEntity> {
default void withTileEntityDo(IBlockReader world, BlockPos pos, Consumer<T> action) {
@SuppressWarnings("unchecked")
T te = (T) world.getTileEntity(pos);
if (te == null)
return;
action.accept(te);
}
default T getTileEntity(IBlockReader world, BlockPos pos) {
@SuppressWarnings("unchecked")
T te = (T) world.getTileEntity(pos);
if (te == null)
return null;
return te;
}
}

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.PaneBlock;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.BakedQuad;
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;
@ -56,7 +57,7 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
CTData data = new CTData(); CTData data = new CTData();
for (Direction face : Direction.values()) { for (Direction face : Direction.values()) {
if (!Block.shouldSideBeRendered(state, world, pos, face)) if (!Block.shouldSideBeRendered(state, world, pos, face) && !(state.getBlock() instanceof PaneBlock))
continue; continue;
CTSpriteShiftEntry spriteShift = behaviour.get(state, face); CTSpriteShiftEntry spriteShift = behaviour.get(state, face);
if (spriteShift == null) if (spriteShift == null)
@ -86,9 +87,6 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
if (index == -1) if (index == -1)
continue; continue;
float uShift = spriteShift.getUShift(index);
float vShift = spriteShift.getVShift(index);
BakedQuad newQuad = BakedQuad newQuad =
new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), quad.getTintIndex(), new BakedQuad(Arrays.copyOf(quad.getVertexData(), quad.getVertexData().length), quad.getTintIndex(),
quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting()); quad.getFace(), quad.getSprite(), quad.shouldApplyDiffuseLighting());
@ -101,10 +99,8 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
int vIndex = vertex + uvOffset + 1; int vIndex = vertex + uvOffset + 1;
float u = Float.intBitsToFloat(vertexData[uIndex]); float u = Float.intBitsToFloat(vertexData[uIndex]);
float v = Float.intBitsToFloat(vertexData[vIndex]); float v = Float.intBitsToFloat(vertexData[vIndex]);
u += uShift; vertexData[uIndex] = Float.floatToRawIntBits(spriteShift.getTargetU(u, index));
v += vShift; vertexData[vIndex] = Float.floatToRawIntBits(spriteShift.getTargetV(v, index));
vertexData[uIndex] = Float.floatToIntBits(u);
vertexData[vIndex] = Float.floatToIntBits(v);
} }
quads.set(i, newQuad); quads.set(i, newQuad);
} }

View file

@ -11,14 +11,16 @@ public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {
this.textureSheetSize = sheetSize; this.textureSheetSize = sheetSize;
} }
public float getUShift(int index) { public float getTargetU(float localU, int index) {
return getTarget().getInterpolatedU((index % textureSheetSize) * (16 / textureSheetSize)) float uOffset = (index % textureSheetSize);
- getOriginal().getMinU(); return getTarget().getInterpolatedU(
(getOriginal().getUnInterpolatedU(localU) + (uOffset * 16)) / ((float) textureSheetSize));
} }
public float getVShift(int index) { public float getTargetV(float localV, int index) {
return getTarget().getInterpolatedV((index / textureSheetSize) * (16 / textureSheetSize)) float vOffset = (index / textureSheetSize);
- getOriginal().getMinV(); return getTarget().getInterpolatedV(
(getOriginal().getUnInterpolatedV(localV) + (vOffset * 16)) / ((float) textureSheetSize));
} }
public abstract int getTextureIndex(CTContext context); public abstract int getTextureIndex(CTContext context);

View file

@ -12,15 +12,23 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient; import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.NonNullList; import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
public class ItemHelper { public class ItemHelper {
public static void dropContents(World world, BlockPos pos, IItemHandler inv) {
for (int slot = 0; slot < inv.getSlots(); slot++)
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), inv.getStackInSlot(slot));
}
public static List<ItemStack> multipliedOutput(ItemStack in, ItemStack out) { public static List<ItemStack> multipliedOutput(ItemStack in, ItemStack out) {
List<ItemStack> stacks = new ArrayList<>(); List<ItemStack> stacks = new ArrayList<>();
ItemStack result = out.copy(); ItemStack result = out.copy();

View file

@ -15,14 +15,16 @@ import com.simibubi.create.modules.IModule;
import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.components.flywheel.engine.EngineBlock; import com.simibubi.create.modules.contraptions.components.flywheel.engine.EngineBlock;
import com.simibubi.create.modules.curiosities.tools.AllToolTiers; import com.simibubi.create.modules.curiosities.tools.AllToolTiers;
import com.simibubi.create.modules.curiosities.tools.SandPaperItem; import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.TieredItem;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
public class TooltipHelper { public class TooltipHelper {
@ -169,11 +171,11 @@ public class TooltipHelper {
} }
public static String getTooltipTranslationKey(ItemStack stack) { public static String getTooltipTranslationKey(ItemStack stack) {
Item item = stack.getItem();
if (stack.getItem() instanceof AbstractToolItem) { if (item instanceof TieredItem) {
AbstractToolItem abstractToolItem = (AbstractToolItem) stack.getItem(); TieredItem tieredItem = (TieredItem) stack.getItem();
if (abstractToolItem.getTier() instanceof AllToolTiers) { if (tieredItem.getTier() instanceof AllToolTiers) {
AllToolTiers allToolTiers = (AllToolTiers) abstractToolItem.getTier(); AllToolTiers allToolTiers = (AllToolTiers) tieredItem.getTier();
return "tool.create." + Lang.asId(allToolTiers.name()) + ".tooltip"; return "tool.create." + Lang.asId(allToolTiers.name()) + ".tooltip";
} }
} }

View file

@ -1,7 +1,11 @@
package com.simibubi.create.foundation.utility; package com.simibubi.create.foundation.utility;
import java.util.Arrays;
import java.util.List;
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.BlockPos;
public class Iterate { public class Iterate {
@ -18,4 +22,9 @@ public class Iterate {
return directions; return directions;
} }
public static List<BlockPos> hereAndBelow(BlockPos pos) {
return Arrays.asList(pos, pos.down());
}
} }

View file

@ -6,13 +6,13 @@ import java.nio.ByteOrder;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.mojang.datafixers.util.Pair; import com.mojang.datafixers.util.Pair;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.BufferBuilder.DrawState; import net.minecraft.client.renderer.BufferBuilder.DrawState;
import net.minecraft.client.renderer.GLAllocation; import net.minecraft.client.renderer.GLAllocation;
import net.minecraft.client.renderer.Matrix4f; import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Vector4f; import net.minecraft.client.renderer.Vector4f;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
@ -33,7 +33,9 @@ public class SuperByteBuffer {
// Vertex Texture Coords // Vertex Texture Coords
private boolean shouldShiftUV; private boolean shouldShiftUV;
private float uShift, vShift; private boolean resetUV;
private SpriteShiftEntry spriteShift;
private float uTarget, vTarget;
// Vertex Lighting // Vertex Lighting
private boolean shouldLight; private boolean shouldLight;
@ -44,6 +46,7 @@ public class SuperByteBuffer {
// Vertex Coloring // Vertex Coloring
private boolean shouldColor; private boolean shouldColor;
private int r, g, b, a; private int r, g, b, a;
private float sheetSize;
public SuperByteBuffer(BufferBuilder buf) { public SuperByteBuffer(BufferBuilder buf) {
Pair<DrawState, ByteBuffer> state = buf.popData(); Pair<DrawState, ByteBuffer> state = buf.popData();
@ -81,8 +84,18 @@ public class SuperByteBuffer {
putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a); putColor(mutable, vertex, (byte) r2, (byte) g2, (byte) b2, (byte) a);
} }
if (shouldShiftUV) if (shouldShiftUV) {
putUV(mutable, vertex, getU(original, vertex) + uShift, getV(original, vertex) + vShift); float u = getU(original, vertex);
float v = getV(original, vertex);
float targetU = spriteShift.getTarget()
.getInterpolatedU((spriteShift.getOriginal().getUnInterpolatedU(u) / sheetSize) + uTarget * 16);
float targetV = spriteShift.getTarget()
.getInterpolatedV((spriteShift.getOriginal().getUnInterpolatedV(v) / sheetSize) + vTarget * 16);
putUV(mutable, vertex, targetU, targetV);
}
if (resetUV)
putUV(mutable, vertex, getU(original, vertex), getV(original, vertex));
if (shouldLight) { if (shouldLight) {
if (vertexLighter != null) if (vertexLighter != null)
@ -141,24 +154,29 @@ public class SuperByteBuffer {
return translate(.5f, .5f, .5f).rotate(axis, radians).translate(-.5f, -.5f, -.5f); return translate(.5f, .5f, .5f).rotate(axis, radians).translate(-.5f, -.5f, -.5f);
} }
public SuperByteBuffer shiftUV(TextureAtlasSprite from, TextureAtlasSprite to) { public SuperByteBuffer shiftUV(SpriteShiftEntry entry) {
shouldShiftUV = true; shouldShiftUV = true;
uShift = to.getMinU() - from.getMinU(); resetUV = false;
vShift = to.getMinV() - from.getMinV(); spriteShift = entry;
uTarget = 0;
vTarget = 0;
sheetSize = 1;
return this; return this;
} }
public SuperByteBuffer shiftUVtoSheet(TextureAtlasSprite from, TextureAtlasSprite to, int sheetX, int sheetY) { public SuperByteBuffer shiftUVtoSheet(SpriteShiftEntry entry, float uTarget, float vTarget, int sheetSize) {
shouldShiftUV = true; shouldShiftUV = true;
uShift = to.getInterpolatedU(sheetX * 16f / to.getWidth()) - from.getMinU(); resetUV = false;
vShift = to.getInterpolatedV(sheetY * 16f / to.getHeight()) - from.getMinV(); spriteShift = entry;
this.uTarget = uTarget;
this.vTarget = vTarget;
this.sheetSize = sheetSize;
return this; return this;
} }
public SuperByteBuffer dontShiftUV() { public SuperByteBuffer dontShiftUV() {
shouldShiftUV = false; shouldShiftUV = false;
uShift = 0; resetUV = true;
vShift = 0;
return this; return this;
} }

View file

@ -1,6 +1,11 @@
package com.simibubi.create.foundation.utility.data; package com.simibubi.create.foundation.utility.data;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.BlockTagsProvider; import net.minecraft.data.BlockTagsProvider;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataGenerator;
@ -8,10 +13,6 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class AllBlocksTagProvider extends BlockTagsProvider { public class AllBlocksTagProvider extends BlockTagsProvider {
static Map<ResourceLocation, BlockTags.Wrapper> createdTags; static Map<ResourceLocation, BlockTags.Wrapper> createdTags;

View file

@ -1,5 +1,8 @@
package com.simibubi.create.foundation.world; package com.simibubi.create.foundation.world;
import static net.minecraft.world.biome.Biome.Category.DESERT;
import static net.minecraft.world.biome.Biome.Category.OCEAN;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -9,19 +12,18 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.Biomes;
import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
public enum AllWorldFeatures { public enum AllWorldFeatures {
COPPER_ORE(new CountedOreFeature(AllBlocks.COPPER_ORE.get(), 21, 1).between(40, 96)), COPPER_ORE(new CountedOreFeature(AllBlocks.COPPER_ORE.get(), 18, 2).between(40, 86)),
COPPER_ORE_OCEAN( COPPER_ORE_OCEAN(new CountedOreFeature(AllBlocks.COPPER_ORE.get(), 15, 4).between(20, 55).inBiomes(OCEAN)),
new CountedOreFeature(AllBlocks.COPPER_ORE.get(), 15, 4).between(20, 55).inBiomes(Biome.Category.OCEAN)),
ZINC_ORE(new CountedOreFeature(AllBlocks.ZINC_ORE.get(), 8, 1).between(55, 80)), ZINC_ORE(new CountedOreFeature(AllBlocks.ZINC_ORE.get(), 14, 4).between(15, 70)),
ZINC_ORE_DESERT( ZINC_ORE_DESERT(new CountedOreFeature(AllBlocks.ZINC_ORE.get(), 17, 5).between(10, 85).inBiomes(DESERT)),
new CountedOreFeature(AllBlocks.ZINC_ORE.get(), 10, 5).between(50, 85).inBiomes(Biome.Category.DESERT)),
LIMESTONE(new ChanceOreFeature(AllBlocks.LIMESTONE.get(), 128, 1 / 32f).between(30, 70)), LIMESTONE(new ChanceOreFeature(AllBlocks.LIMESTONE.get(), 128, 1 / 32f).between(30, 70)),
WEATHERED_LIMESTONE(new ChanceOreFeature(AllBlocks.WEATHERED_LIMESTONE.get(), 128, 1 / 32f).between(10, 30)), WEATHERED_LIMESTONE(new ChanceOreFeature(AllBlocks.WEATHERED_LIMESTONE.get(), 128, 1 / 32f).between(10, 30)),
@ -31,6 +33,13 @@ public enum AllWorldFeatures {
; ;
/**
* Increment this number if all worldgen entries should be overwritten in this
* update. Worlds from the previous version will overwrite potentially changed
* values with the new defaults.
*/
public static final int forcedUpdateVersion = 1;
public IFeature feature; public IFeature feature;
private Map<Biome, ConfiguredFeature<?, ?>> featureInstances; private Map<Biome, ConfiguredFeature<?, ?>> featureInstances;
@ -44,9 +53,13 @@ public enum AllWorldFeatures {
for (AllWorldFeatures entry : AllWorldFeatures.values()) { for (AllWorldFeatures entry : AllWorldFeatures.values()) {
for (Biome biome : ForgeRegistries.BIOMES) { for (Biome biome : ForgeRegistries.BIOMES) {
if (biome == Biomes.THE_VOID)
continue;
if (biome == Biomes.NETHER)
continue;
if (entry.featureInstances.containsKey(biome)) if (entry.featureInstances.containsKey(biome))
biome.getFeatures(entry.feature.getGenerationStage()).remove(entry.featureInstances.remove(biome)); biome.getFeatures(entry.feature.getGenerationStage()).remove(entry.featureInstances.remove(biome));
Optional<ConfiguredFeature<?, ?>> createFeature = entry.feature.createFeature(biome); Optional<ConfiguredFeature<?, ?>> createFeature = entry.feature.createFeature(biome);
if (!createFeature.isPresent()) if (!createFeature.isPresent())
continue; continue;

View file

@ -1,13 +1,70 @@
package com.simibubi.create.modules.contraptions; package com.simibubi.create.modules.contraptions;
import com.simibubi.create.foundation.utility.VoxelShaper;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.world.World;
public interface IWrenchable { public interface IWrenchable {
public default ActionResultType onWrenched(BlockState state, ItemUseContext context) { default ActionResultType onWrenched(BlockState state, ItemUseContext context) {
return ActionResultType.PASS; World world = context.getWorld();
BlockState rotated = getRotatedBlockState(state, context.getFace());
if (!rotated.isValidPosition(world, context.getPos()))
return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), updateAfterWrenched(rotated, context));
TileEntity te = context.getWorld().getTileEntity(context.getPos());
if (te instanceof GeneratingKineticTileEntity) {
((GeneratingKineticTileEntity) te).updateGeneratedRotation();
}
return ActionResultType.SUCCESS;
}
default BlockState updateAfterWrenched(BlockState newState, ItemUseContext context) {
return newState;
}
static BlockState getRotatedBlockState(BlockState originalState, Direction targetedFace){
BlockState newState = originalState;
if (targetedFace.getAxis() == Direction.Axis.Y) {
if (originalState.has(HorizontalAxisKineticBlock.HORIZONTAL_AXIS))
return originalState.with(HorizontalAxisKineticBlock.HORIZONTAL_AXIS, VoxelShaper.axisAsFace(originalState.get(HorizontalAxisKineticBlock.HORIZONTAL_AXIS)).rotateAround(targetedFace.getAxis()).getAxis());
if (originalState.has(HorizontalKineticBlock.HORIZONTAL_FACING))
return originalState.with(HorizontalKineticBlock.HORIZONTAL_FACING, originalState.get(HorizontalKineticBlock.HORIZONTAL_FACING).rotateAround(targetedFace.getAxis()));
}
if (originalState.has(RotatedPillarKineticBlock.AXIS))
return originalState.with(RotatedPillarKineticBlock.AXIS, VoxelShaper.axisAsFace(originalState.get(RotatedPillarKineticBlock.AXIS)).rotateAround(targetedFace.getAxis()).getAxis());
if (!originalState.has(DirectionalKineticBlock.FACING)) return originalState;
Direction stateFacing = originalState.get(DirectionalKineticBlock.FACING);
if (stateFacing.getAxis().equals(targetedFace.getAxis())) {
if (originalState.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) return originalState.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
else return originalState;
} else {
do {
newState = newState.with(DirectionalKineticBlock.FACING, newState.get(DirectionalKineticBlock.FACING).rotateAround(targetedFace.getAxis()));
if (targetedFace.getAxis() == Direction.Axis.Y && newState.has(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE)) newState = newState.cycle(DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE);
} while (newState.get(DirectionalKineticBlock.FACING).getAxis().equals(targetedFace.getAxis()));
}
return newState;
} }
} }

View file

@ -84,7 +84,7 @@ public class KineticDebugger {
BlockRayTraceResult ray = (BlockRayTraceResult) obj; BlockRayTraceResult ray = (BlockRayTraceResult) obj;
TileEntity te = world.getTileEntity(ray.getPos()); TileEntity te = world.getTileEntity(ray.getPos());
if (te == null || !(te instanceof KineticTileEntity)) if (!(te instanceof KineticTileEntity))
return null; return null;
return (KineticTileEntity) te; return (KineticTileEntity) te;

View file

@ -38,12 +38,12 @@ public class KineticNetwork {
return; return;
if (te.isSource()) { if (te.isSource()) {
unloadedCapacity -= lastCapacity * getStressMultiplierForSpeed(te.getGeneratedSpeed()); unloadedCapacity -= lastCapacity * getStressMultiplierForSpeed(te.getGeneratedSpeed());
float addedStressCapacity = te.getAddedStressCapacity(); float addedStressCapacity = te.calculateAddedStressCapacity();
sources.put(te, addedStressCapacity); sources.put(te, addedStressCapacity);
} }
unloadedStress -= lastStress * getStressMultiplierForSpeed(te.getTheoreticalSpeed()); unloadedStress -= lastStress * getStressMultiplierForSpeed(te.getTheoreticalSpeed());
float stressApplied = te.getStressApplied(); float stressApplied = te.calculateStressApplied();
members.put(te, stressApplied); members.put(te, stressApplied);
unloadedMembers--; unloadedMembers--;
@ -59,8 +59,8 @@ public class KineticNetwork {
if (members.containsKey(te)) if (members.containsKey(te))
return; return;
if (te.isSource()) if (te.isSource())
sources.put(te, te.getAddedStressCapacity()); sources.put(te, te.calculateAddedStressCapacity());
members.put(te, te.getStressApplied()); members.put(te, te.calculateStressApplied());
te.updateFromNetwork(currentCapacity, currentStress, getSize()); te.updateFromNetwork(currentCapacity, currentStress, getSize());
te.networkDirty = true; te.networkDirty = true;
} }

View file

@ -327,7 +327,10 @@ public class RotationPropagator {
while (!frontier.isEmpty()) { while (!frontier.isEmpty()) {
final BlockPos pos = frontier.remove(0); final BlockPos pos = frontier.remove(0);
final KineticTileEntity currentTE = (KineticTileEntity) world.getTileEntity(pos); TileEntity tileEntity = world.getTileEntity(pos);
if (!(tileEntity instanceof KineticTileEntity))
continue;
final KineticTileEntity currentTE = (KineticTileEntity) tileEntity;
currentTE.removeSource(); currentTE.removeSource();
currentTE.sendData(); currentTE.sendData();

View file

@ -3,10 +3,8 @@ package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
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.util.ActionResultType;
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.Rotation; import net.minecraft.util.Rotation;
@ -86,17 +84,6 @@ public abstract class DirectionalAxisKineticBlock extends DirectionalKineticBloc
return this.getDefaultState().with(FACING, facing).with(AXIS_ALONG_FIRST_COORDINATE, alongFirst); return this.getDefaultState().with(FACING, facing).with(AXIS_ALONG_FIRST_COORDINATE, alongFirst);
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
World world = context.getWorld();
Direction face = context.getFace();
if ((turnBackOnWrenched() ? face.getOpposite() : face) == state.get(FACING)) {
KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(AXIS_ALONG_FIRST_COORDINATE));
return ActionResultType.SUCCESS;
}
return super.onWrenched(state, context);
}
@Override @Override
public Axis getRotationAxis(BlockState state) { public Axis getRotationAxis(BlockState state) {
Axis pistonAxis = state.get(FACING).getAxis(); Axis pistonAxis = state.get(FACING).getAxis();

View file

@ -3,15 +3,12 @@ package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.DirectionProperty; import net.minecraft.state.DirectionProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Mirror; import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.world.World;
public abstract class DirectionalKineticBlock extends KineticBlock { public abstract class DirectionalKineticBlock extends KineticBlock {
@ -45,24 +42,6 @@ public abstract class DirectionalKineticBlock extends KineticBlock {
return prefferedSide; return prefferedSide;
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Direction facing = turnBackOnWrenched() ? context.getFace().getOpposite() : context.getFace();
World world = context.getWorld();
if (facing == state.get(FACING))
return ActionResultType.PASS;
BlockState with = state.with(FACING, facing);
if (!with.isValidPosition(world, context.getPos()))
return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), with);
return ActionResultType.SUCCESS;
}
protected boolean turnBackOnWrenched() {
return false;
}
@Override @Override
public BlockState getStateForPlacement(BlockItemUseContext context) { public BlockState getStateForPlacement(BlockItemUseContext context) {
Direction preferred = getPreferredFacing(context); Direction preferred = getPreferredFacing(context);

View file

@ -7,6 +7,7 @@ import com.simibubi.create.modules.contraptions.KineticNetwork;
import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel; import com.simibubi.create.modules.contraptions.base.IRotate.SpeedLevel;
import com.simibubi.create.modules.contraptions.goggle.IHaveGoggleInformation; import com.simibubi.create.modules.contraptions.goggle.IHaveGoggleInformation;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
@ -33,7 +34,10 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
@Override @Override
public void setSource(BlockPos source) { public void setSource(BlockPos source) {
super.setSource(source); super.setSource(source);
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); TileEntity tileEntity = world.getTileEntity(source);
if (!(tileEntity instanceof KineticTileEntity))
return;
KineticTileEntity sourceTe = (KineticTileEntity) tileEntity;
if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed())) if (reActivateSource && sourceTe != null && Math.abs(sourceTe.getSpeed()) >= Math.abs(getGeneratedSpeed()))
reActivateSource = false; reActivateSource = false;
} }
@ -51,7 +55,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) { public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking); boolean added = super.addToGoggleTooltip(tooltip, isPlayerSneaking);
float stressBase = getAddedStressCapacity(); float stressBase = calculateAddedStressCapacity();
if (stressBase != 0 && IRotate.StressImpact.isEnabled()) { if (stressBase != 0 && IRotate.StressImpact.isEnabled()) {
tooltip.add(spacing + Lang.translate("gui.goggles.generator_stats")); tooltip.add(spacing + Lang.translate("gui.goggles.generator_stats"));
tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.capacityProvided")); tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.capacityProvided"));
@ -93,8 +97,8 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
if (hasNetwork() && speed != 0) { if (hasNetwork() && speed != 0) {
KineticNetwork network = getOrCreateNetwork(); KineticNetwork network = getOrCreateNetwork();
notifyStressCapacityChange(getAddedStressCapacity()); notifyStressCapacityChange(calculateAddedStressCapacity());
getOrCreateNetwork().updateStressFor(this, getStressApplied()); getOrCreateNetwork().updateStressFor(this, calculateStressApplied());
network.updateStress(); network.updateStress();
} }
@ -108,7 +112,7 @@ public abstract class GeneratingKineticTileEntity extends KineticTileEntity {
if (speed == 0) { if (speed == 0) {
if (hasSource()) { if (hasSource()) {
notifyStressCapacityChange(0); notifyStressCapacityChange(0);
getOrCreateNetwork().updateStressFor(this, getStressApplied()); getOrCreateNetwork().updateStressFor(this, calculateStressApplied());
return; return;
} }
detachKinetics(); detachKinetics();

View file

@ -3,11 +3,9 @@ package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.ActionResultType;
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.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
@ -15,7 +13,6 @@ import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
public abstract class HorizontalAxisKineticBlock extends KineticBlock { public abstract class HorizontalAxisKineticBlock extends KineticBlock {
@ -69,18 +66,6 @@ public abstract class HorizontalAxisKineticBlock extends KineticBlock {
return face.getAxis() == state.get(HORIZONTAL_AXIS); return face.getAxis() == state.get(HORIZONTAL_AXIS);
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Direction facing = context.getFace();
if (facing.getAxis().isVertical())
return ActionResultType.PASS;
World world = context.getWorld();
if (facing.getAxis() == state.get(HORIZONTAL_AXIS))
return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), state.cycle(HORIZONTAL_AXIS));
return ActionResultType.SUCCESS;
}
@Override @Override
public BlockState rotate(BlockState state, Rotation rot) { public BlockState rotate(BlockState state, Rotation rot) {
Axis axis = state.get(HORIZONTAL_AXIS); Axis axis = state.get(HORIZONTAL_AXIS);

View file

@ -3,15 +3,12 @@ package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Mirror; import net.minecraft.util.Mirror;
import net.minecraft.util.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.world.World;
public abstract class HorizontalKineticBlock extends KineticBlock { public abstract class HorizontalKineticBlock extends KineticBlock {
@ -52,18 +49,6 @@ public abstract class HorizontalKineticBlock extends KineticBlock {
return prefferedSide; return prefferedSide;
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Direction facing = context.getFace();
if (facing.getAxis().isVertical())
return ActionResultType.PASS;
World world = context.getWorld();
if (facing == state.get(HORIZONTAL_FACING))
return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), state.with(HORIZONTAL_FACING, facing));
return ActionResultType.SUCCESS;
}
@Override @Override
public BlockState rotate(BlockState state, Rotation rot) { public BlockState rotate(BlockState state, Rotation rot) {
return state.with(HORIZONTAL_FACING, rot.rotate(state.get(HORIZONTAL_FACING))); return state.with(HORIZONTAL_FACING, rot.rotate(state.get(HORIZONTAL_FACING)));

View file

@ -72,30 +72,19 @@ public abstract class KineticBlock extends Block implements IRotate {
@Override @Override
public abstract TileEntity createTileEntity(BlockState state, IBlockReader world); public abstract TileEntity createTileEntity(BlockState state, IBlockReader world);
@Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
if (isMoving) {
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
if (tileEntity == null)
return;
if (worldIn.isRemote())
return;
tileEntity.network = null;
tileEntity.source = null;
tileEntity.speed = 0;
}
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) { public void updateNeighbors(BlockState stateIn, IWorld worldIn, BlockPos pos, int flags) {
super.updateNeighbors(stateIn, worldIn, pos, flags); super.updateNeighbors(stateIn, worldIn, pos, flags);
KineticTileEntity tileEntity = (KineticTileEntity) worldIn.getTileEntity(pos);
if (tileEntity == null)
return;
if (worldIn.isRemote()) if (worldIn.isRemote())
return; return;
RotationPropagator.handleAdded(worldIn.getWorld(), pos, tileEntity);
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (!(tileEntity instanceof KineticTileEntity))
return;
KineticTileEntity kte = (KineticTileEntity) tileEntity;
RotationPropagator.handleAdded(worldIn.getWorld(), pos, kte);
} }
// @Override // TODO 1.15 register layer // @Override // TODO 1.15 register layer
@ -107,12 +96,13 @@ public abstract class KineticBlock extends Block implements IRotate {
@Override @Override
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (tileEntity == null || !(tileEntity instanceof KineticTileEntity))
return;
if (worldIn.isRemote) if (worldIn.isRemote)
return; return;
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (!(tileEntity instanceof KineticTileEntity))
return;
KineticTileEntity kte = (KineticTileEntity) tileEntity; KineticTileEntity kte = (KineticTileEntity) tileEntity;
kte.effects.queueRotationIndicators(); kte.effects.queueRotationIndicators();
} }

View file

@ -104,7 +104,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
if (!world.isBlockPresent(source)) if (!world.isBlockPresent(source))
return; return;
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); TileEntity tileEntity = world.getTileEntity(source);
KineticTileEntity sourceTe =
tileEntity instanceof KineticTileEntity ? (KineticTileEntity) tileEntity : null;
if (sourceTe == null || sourceTe.speed == 0) { if (sourceTe == null || sourceTe.speed == 0) {
removeSource(); removeSource();
detachKinetics(); detachKinetics();
@ -137,20 +139,22 @@ public abstract class KineticTileEntity extends SmartTileEntity
} }
} }
public float getAddedStressCapacity() { public float calculateAddedStressCapacity() {
Map<ResourceLocation, ConfigValue<Double>> capacityMap = AllConfigs.SERVER.kinetics.stressValues.capacities; Map<ResourceLocation, ConfigValue<Double>> capacityMap = AllConfigs.SERVER.kinetics.stressValues.capacities;
ResourceLocation path = getBlockState().getBlock().getRegistryName(); ResourceLocation path = getBlockState().getBlock().getRegistryName();
if (!capacityMap.containsKey(path))
return 0; float capacity = capacityMap.containsKey(path) ? capacityMap.get(path).get().floatValue() : 0;
return capacityMap.get(path).get().floatValue(); this.lastCapacityProvided = capacity;
return capacity;
} }
public float getStressApplied() { public float calculateStressApplied() {
Map<ResourceLocation, ConfigValue<Double>> stressEntries = AllConfigs.SERVER.kinetics.stressValues.impacts; Map<ResourceLocation, ConfigValue<Double>> stressEntries = AllConfigs.SERVER.kinetics.stressValues.impacts;
ResourceLocation path = getBlockState().getBlock().getRegistryName(); ResourceLocation path = getBlockState().getBlock().getRegistryName();
if (!stressEntries.containsKey(path))
return 1; float impact = stressEntries.containsKey(path) ? stressEntries.get(path).get().floatValue() : 1;
return stressEntries.get(path).get().floatValue(); this.lastStressApplied = impact;
return impact;
} }
public void onSpeedChanged(float previousSpeed) { public void onSpeedChanged(float previousSpeed) {
@ -185,12 +189,10 @@ public abstract class KineticTileEntity extends SmartTileEntity
networkTag.putFloat("Capacity", capacity); networkTag.putFloat("Capacity", capacity);
networkTag.putInt("Size", networkSize); networkTag.putInt("Size", networkSize);
float stressApplied = getStressApplied(); if (lastStressApplied != 0)
float addedStressCapacity = getAddedStressCapacity(); networkTag.putFloat("AddedStress", lastStressApplied);
if (stressApplied != 0) if (lastCapacityProvided != 0)
networkTag.putFloat("AddedStress", stressApplied); networkTag.putFloat("AddedCapacity", lastCapacityProvided);
if (addedStressCapacity != 0)
networkTag.putFloat("AddedCapacity", addedStressCapacity);
compound.put("Network", networkTag); compound.put("Network", networkTag);
} }
@ -201,7 +203,6 @@ public abstract class KineticTileEntity extends SmartTileEntity
@Override @Override
public void read(CompoundNBT compound) { public void read(CompoundNBT compound) {
speed = compound.getFloat("Speed"); speed = compound.getFloat("Speed");
source = null; source = null;
network = null; network = null;
overStressed = false; overStressed = false;
@ -266,12 +267,13 @@ public abstract class KineticTileEntity extends SmartTileEntity
if (world == null || world.isRemote) if (world == null || world.isRemote)
return; return;
KineticTileEntity sourceTe = (KineticTileEntity) world.getTileEntity(source); TileEntity tileEntity = world.getTileEntity(source);
if (sourceTe == null) { if (!(tileEntity instanceof KineticTileEntity)) {
removeSource(); removeSource();
return; return;
} }
KineticTileEntity sourceTe = (KineticTileEntity) tileEntity;
setNetwork(sourceTe.network); setNetwork(sourceTe.network);
} }
@ -336,9 +338,11 @@ public abstract class KineticTileEntity extends SmartTileEntity
public static void switchToBlockState(World world, BlockPos pos, BlockState state) { public static void switchToBlockState(World world, BlockPos pos, BlockState state) {
if (world.isRemote) if (world.isRemote)
return; return;
TileEntity tileEntityIn = world.getTileEntity(pos); TileEntity tileEntityIn = world.getTileEntity(pos);
if (!(tileEntityIn instanceof KineticTileEntity)) if (!(tileEntityIn instanceof KineticTileEntity))
return; return;
KineticTileEntity tileEntity = (KineticTileEntity) tileEntityIn; KineticTileEntity tileEntity = (KineticTileEntity) tileEntityIn;
if (tileEntity.hasNetwork()) if (tileEntity.hasNetwork())
tileEntity.getOrCreateNetwork().remove(tileEntity); tileEntity.getOrCreateNetwork().remove(tileEntity);
@ -387,9 +391,9 @@ public abstract class KineticTileEntity extends SmartTileEntity
@Override @Override
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) { public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
boolean added = false; boolean added = false;
float stressAtBase = getStressApplied(); float stressAtBase = calculateStressApplied();
if (getStressApplied() != 0 && StressImpact.isEnabled()) { if (calculateStressApplied() != 0 && StressImpact.isEnabled()) {
tooltip.add(spacing + Lang.translate("gui.goggles.kinetic_stats")); tooltip.add(spacing + Lang.translate("gui.goggles.kinetic_stats"));
tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.stressImpact")); tooltip.add(spacing + TextFormatting.GRAY + Lang.translate("tooltip.stressImpact"));

View file

@ -3,15 +3,12 @@ package com.simibubi.create.modules.contraptions.base;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.EnumProperty; import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer; import net.minecraft.state.StateContainer;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.ActionResultType;
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.Rotation; import net.minecraft.util.Rotation;
import net.minecraft.world.World;
public abstract class RotatedPillarKineticBlock extends KineticBlock { public abstract class RotatedPillarKineticBlock extends KineticBlock {
@ -72,14 +69,4 @@ public abstract class RotatedPillarKineticBlock extends KineticBlock {
: context.getNearestLookingDirection().getAxis()); : context.getNearestLookingDirection().getAxis());
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Axis axis = context.getFace().getAxis();
World world = context.getWorld();
if (axis == state.get(AXIS))
return ActionResultType.PASS;
KineticTileEntity.switchToBlockState(world, context.getPos(), state.with(AXIS, axis));
return ActionResultType.SUCCESS;
}
} }

View file

@ -1,12 +1,14 @@
package com.simibubi.create.modules.contraptions.components.actors; package com.simibubi.create.modules.contraptions.components.actors;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour;
import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext; import com.simibubi.create.modules.contraptions.components.contraptions.MovementContext;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
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.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
@ -37,8 +39,17 @@ public class BlockBreakingMovementBehaviour extends MovementBehaviour {
if (damageSource == null) if (damageSource == null)
return; return;
for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) { for (Entity entity : world.getEntitiesWithinAABB(Entity.class, new AxisAlignedBB(pos))) {
if (entity instanceof ItemEntity) if (entity instanceof ItemEntity)
return; return;
if (entity instanceof ContraptionEntity)
return;
if (entity instanceof AbstractMinecartEntity)
for (Entity passenger : entity.getRecursivePassengers())
if (passenger instanceof ContraptionEntity
&& ((ContraptionEntity) passenger).getContraption() == context.contraption)
return;
float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20); float damage = (float) MathHelper.clamp(Math.abs(context.relativeMotion.length() * 10) + 1, 5, 20);
entity.attackEntityFrom(damageSource, damage); entity.attackEntityFrom(damageSource, damage);
entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3))); entity.setMotion(entity.getMotion().add(context.relativeMotion.scale(3)));

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.contraptions.components.actors; package com.simibubi.create.modules.contraptions.components.actors;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
@ -25,7 +25,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class DrillBlock extends DirectionalKineticBlock implements IPortableBlock, IWithTileEntity<DrillTileEntity> { public class DrillBlock extends DirectionalKineticBlock implements IPortableBlock, ITE<DrillTileEntity> {
public static MovementBehaviour MOVEMENT = new DrillMovementBehaviour(); public static MovementBehaviour MOVEMENT = new DrillMovementBehaviour();
public static DamageSource damageSourceDrill = new DamageSource("create.drill").setDamageBypassesArmor(); public static DamageSource damageSourceDrill = new DamageSource("create.drill").setDamageBypassesArmor();
@ -93,4 +93,9 @@ public class DrillBlock extends DirectionalKineticBlock implements IPortableBloc
return MOVEMENT; return MOVEMENT;
} }
@Override
public Class<DrillTileEntity> getTileEntityClass() {
return DrillTileEntity.class;
}
} }

View file

@ -102,8 +102,8 @@ public class StorageInterfaceMovement extends MovementBehaviour {
extracting.withAmountThreshold(stack -> { extracting.withAmountThreshold(stack -> {
ItemStack tester = stack.copy(); ItemStack tester = stack.copy();
tester.setCount(64); tester.setCount(tester.getMaxStackSize());
return 64 - ItemHandlerHelper.insertItemStacked(inv, stack, true).getCount(); return stack.getCount() - ItemHandlerHelper.insertItemStacked(inv, stack, true).getCount();
}); });
extracting.setCallback(stack -> { extracting.setCallback(stack -> {

View file

@ -3,10 +3,19 @@ package com.simibubi.create.modules.contraptions.components.contraptions;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock; import com.simibubi.create.modules.contraptions.components.actors.HarvesterBlock;
import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock; import com.simibubi.create.modules.contraptions.components.actors.PortableStorageInterfaceBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.ClockworkBearingTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.bearing.MechanicalBearingTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
import com.simibubi.create.modules.logistics.block.belts.FunnelBlock; import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
import com.simibubi.create.modules.logistics.block.AttachedLogisticalBlock;
import com.simibubi.create.modules.logistics.block.RedstoneLinkBlock;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
import com.simibubi.create.modules.logistics.block.funnel.FunnelBlock;
import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock;
import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.AbstractPressurePlateBlock;
@ -27,6 +36,7 @@ import net.minecraft.block.WallTorchBlock;
import net.minecraft.block.material.PushReaction; import net.minecraft.block.material.PushReaction;
import net.minecraft.state.properties.AttachFace; import net.minecraft.state.properties.AttachFace;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -55,6 +65,26 @@ public class BlockMovementTraits {
return false; return false;
if (block == Blocks.OBSIDIAN) if (block == Blocks.OBSIDIAN)
return false; return false;
// Move controllers only when they aren't moving
if (block instanceof MechanicalPistonBlock && blockState.get(MechanicalPistonBlock.STATE) != PistonState.MOVING)
return true;
if (block instanceof MechanicalBearingBlock) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof MechanicalBearingTileEntity)
return !((MechanicalBearingTileEntity) te).isRunning();
}
if (block instanceof ClockworkBearingBlock) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof ClockworkBearingTileEntity)
return !((ClockworkBearingTileEntity) te).isRunning();
}
if (block instanceof PulleyBlock) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof PulleyTileEntity)
return !((PulleyTileEntity) te).running && ((PulleyTileEntity) te).offset == 0;
}
if (AllBlocks.BELT.typeOf(blockState)) if (AllBlocks.BELT.typeOf(blockState))
return true; return true;
if (block instanceof ExtractorBlock) if (block instanceof ExtractorBlock)
@ -94,6 +124,8 @@ public class BlockMovementTraits {
return true; return true;
if (block instanceof RedstoneWireBlock) if (block instanceof RedstoneWireBlock)
return true; return true;
if (block instanceof RedstoneLinkBlock)
return true;
return false; return false;
} }
@ -112,6 +144,8 @@ public class BlockMovementTraits {
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock)) if (block instanceof AttachedLogisticalBlock && !(block instanceof TransposerBlock))
return direction == AttachedLogisticalBlock.getBlockFacing(state); return direction == AttachedLogisticalBlock.getBlockFacing(state);
if (block instanceof RedstoneLinkBlock)
return direction.getOpposite() == state.get(RedstoneLinkBlock.FACING);
if (block instanceof FlowerPotBlock) if (block instanceof FlowerPotBlock)
return direction == Direction.DOWN; return direction == Direction.DOWN;
if (block instanceof RedstoneDiodeBlock) if (block instanceof RedstoneDiodeBlock)
@ -156,14 +190,4 @@ public class BlockMovementTraits {
return isBrittle(state); return isBrittle(state);
} }
public static boolean movementIgnored(BlockState state) {
if (AllBlocks.MECHANICAL_PISTON.typeOf(state))
return true;
if (AllBlocks.STICKY_MECHANICAL_PISTON.typeOf(state))
return true;
if (AllBlocks.MECHANICAL_PISTON_HEAD.typeOf(state))
return true;
return false;
}
} }

View file

@ -25,17 +25,23 @@ import com.simibubi.create.foundation.utility.WrappedWorld;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
import com.simibubi.create.modules.contraptions.components.saw.SawBlock; import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
import com.simibubi.create.modules.contraptions.redstone.ContactBlock; import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock; import com.simibubi.create.modules.logistics.block.inventories.FlexcrateBlock;
import net.minecraft.block.AbstractButtonBlock;
import net.minecraft.block.Block; 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.ChestBlock; import net.minecraft.block.ChestBlock;
import net.minecraft.block.DoorBlock; import net.minecraft.block.DoorBlock;
import net.minecraft.block.PressurePlateBlock;
import net.minecraft.block.SlimeBlock; import net.minecraft.block.SlimeBlock;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.RenderTypeLookup;
@ -159,6 +165,49 @@ public abstract class Contraption {
if (prevPos != null && !visited.contains(prevPos)) if (prevPos != null && !visited.contains(prevPos))
frontier.add(prevPos); frontier.add(prevPos);
} }
if (state.getBlock() instanceof MechanicalPistonBlock) {
int limit = AllConfigs.SERVER.kinetics.maxPistonPoles.get();
Direction direction = state.get(MechanicalPistonBlock.FACING);
if (state.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) {
BlockPos searchPos = pos;
while (limit-- >= 0) {
searchPos = searchPos.offset(direction);
BlockState blockState = world.getBlockState(searchPos);
if (AllBlocks.PISTON_POLE.typeOf(blockState)) {
if (blockState.get(PistonPoleBlock.FACING).getAxis() != direction.getAxis())
break;
if (!visited.contains(searchPos))
frontier.add(searchPos);
continue;
}
if (blockState.getBlock() instanceof MechanicalPistonHeadBlock)
if (!visited.contains(searchPos))
frontier.add(searchPos);
break;
}
if (limit <= -1)
return false;
}
BlockPos searchPos = pos;
while (limit-- >= 0) {
searchPos = searchPos.offset(direction.getOpposite());
BlockState blockState = world.getBlockState(searchPos);
if (AllBlocks.PISTON_POLE.typeOf(blockState)) {
if (blockState.get(PistonPoleBlock.FACING).getAxis() != direction.getAxis())
break;
if (!visited.contains(searchPos))
frontier.add(searchPos);
continue;
}
break;
}
if (limit <= -1)
return false;
}
if (state.getBlock() instanceof DoorBlock) { if (state.getBlock() instanceof DoorBlock) {
BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1); BlockPos otherPartPos = pos.up(state.get(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? 1 : -1);
if (!visited.contains(otherPartPos)) if (!visited.contains(otherPartPos))
@ -169,7 +218,7 @@ public abstract class Contraption {
for (Direction offset : Direction.values()) { for (Direction offset : Direction.values()) {
BlockPos offsetPos = pos.offset(offset); BlockPos offsetPos = pos.offset(offset);
BlockState blockState = world.getBlockState(offsetPos); BlockState blockState = world.getBlockState(offsetPos);
if (BlockMovementTraits.movementIgnored(blockState)) if (isAnchoringBlockAt(offsetPos))
continue; continue;
if (!BlockMovementTraits.movementAllowed(world, offsetPos)) { if (!BlockMovementTraits.movementAllowed(world, offsetPos)) {
if (offset == forcedDirection && isSlimeBlock) if (offset == forcedDirection && isSlimeBlock)
@ -187,6 +236,10 @@ public abstract class Contraption {
return true; return true;
} }
protected boolean isAnchoringBlockAt(BlockPos pos) {
return pos.equals(anchor);
}
protected static boolean isChassis(BlockState state) { protected static boolean isChassis(BlockState state) {
return state.getBlock() instanceof AbstractChassisBlock; return state.getBlock() instanceof AbstractChassisBlock;
} }
@ -217,6 +270,14 @@ public abstract class Contraption {
blockstate = blockstate.with(FlexcrateBlock.DOUBLE, false); blockstate = blockstate.with(FlexcrateBlock.DOUBLE, false);
if (AllBlocks.CONTACT.typeOf(blockstate)) if (AllBlocks.CONTACT.typeOf(blockstate))
blockstate = blockstate.with(ContactBlock.POWERED, true); blockstate = blockstate.with(ContactBlock.POWERED, true);
if (blockstate.getBlock() instanceof AbstractButtonBlock) {
blockstate = blockstate.with(AbstractButtonBlock.POWERED, false);
world.getPendingBlockTicks().scheduleTick(pos, blockstate.getBlock(), -1);
}
if (blockstate.getBlock() instanceof PressurePlateBlock) {
blockstate = blockstate.with(PressurePlateBlock.POWERED, false);
world.getPendingBlockTicks().scheduleTick(pos, blockstate.getBlock(), -1);
}
CompoundNBT compoundnbt = getTileEntityNBT(world, pos); CompoundNBT compoundnbt = getTileEntityNBT(world, pos);
TileEntity tileentity = world.getTileEntity(pos); TileEntity tileentity = world.getTileEntity(pos);
return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity); return Pair.of(new BlockInfo(pos, blockstate, compoundnbt), tileentity);

View file

@ -14,6 +14,7 @@ import net.minecraft.entity.EntityType;
import net.minecraft.entity.IProjectile; import net.minecraft.entity.IProjectile;
import net.minecraft.entity.MoverType; import net.minecraft.entity.MoverType;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
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.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
@ -73,6 +74,7 @@ public class ContraptionCollider {
if (allowedMovement.equals(relativeMotion)) if (allowedMovement.equals(relativeMotion))
continue; continue;
if (allowedMovement.y != relativeMotion.y) { if (allowedMovement.y != relativeMotion.y) {
entity.handleFallDamage(entity.fallDistance, 1); entity.handleFallDamage(entity.fallDistance, 1);
entity.fallDistance = 0; entity.fallDistance = 0;
@ -80,6 +82,8 @@ public class ContraptionCollider {
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity)); DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> checkForClientPlayerCollision(entity));
} }
if (entity instanceof ServerPlayerEntity)
((ServerPlayerEntity) entity).connection.floatingTickCount = 0;
if (entity instanceof PlayerEntity && !world.isRemote) if (entity instanceof PlayerEntity && !world.isRemote)
return; return;

View file

@ -25,11 +25,6 @@ public abstract class BearingBlock extends DirectionalKineticBlock {
return true; return true;
} }
@Override
protected boolean turnBackOnWrenched() {
return true;
}
@Override @Override
public Axis getRotationAxis(BlockState state) { public Axis getRotationAxis(BlockState state) {
return state.get(FACING).getAxis(); return state.get(FACING).getAxis();

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing; package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -12,7 +12,7 @@ import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class ClockworkBearingBlock extends BearingBlock implements IWithTileEntity<ClockworkBearingTileEntity> { public class ClockworkBearingBlock extends BearingBlock implements ITE<ClockworkBearingTileEntity> {
@Override @Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) { public TileEntity createTileEntity(BlockState state, IBlockReader world) {
@ -41,4 +41,9 @@ public class ClockworkBearingBlock extends BearingBlock implements IWithTileEnti
return ActionResultType.PASS; return ActionResultType.PASS;
} }
@Override
public Class<ClockworkBearingTileEntity> getTileEntityClass() {
return ClockworkBearingTileEntity.class;
}
} }

View file

@ -299,4 +299,8 @@ public class ClockworkBearingTileEntity extends KineticTileEntity implements IBe
return this.minuteHand == contraption; return this.minuteHand == contraption;
} }
public boolean isRunning() {
return running;
}
} }

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing; package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -13,7 +13,7 @@ import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class MechanicalBearingBlock extends BearingBlock implements IWithTileEntity<MechanicalBearingTileEntity> { public class MechanicalBearingBlock extends BearingBlock implements ITE<MechanicalBearingTileEntity> {
@Override @Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) { public TileEntity createTileEntity(BlockState state, IBlockReader world) {
@ -56,4 +56,9 @@ public class MechanicalBearingBlock extends BearingBlock implements IWithTileEnt
withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged); withTileEntityDo(worldIn, pos, MechanicalBearingTileEntity::neighbourChanged);
} }
@Override
public Class<MechanicalBearingTileEntity> getTileEntityClass() {
return MechanicalBearingTileEntity.class;
}
} }

View file

@ -52,13 +52,13 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
} }
@Override @Override
public float getAddedStressCapacity() { public float calculateAddedStressCapacity() {
return isWindmill ? super.getAddedStressCapacity() : 0; return isWindmill ? super.calculateAddedStressCapacity() : 0;
} }
@Override @Override
public float getStressApplied() { public float calculateStressApplied() {
return isWindmill ? 0 : super.getStressApplied(); return isWindmill ? 0 : super.calculateStressApplied();
} }
public void neighbourChanged() { public void neighbourChanged() {
@ -299,4 +299,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
return movedContraption == contraption; return movedContraption == contraption;
} }
public boolean isRunning() {
return running;
}
} }

View file

@ -130,6 +130,11 @@ public class CartAssemblerBlock extends AbstractRailBlock {
return PushReaction.BLOCK; return PushReaction.BLOCK;
} }
@Override
public boolean isNormalCube(BlockState state, IBlockReader worldIn, BlockPos pos) {
return false;
}
public static class MinecartAnchorBlock extends RenderUtilityBlock { public static class MinecartAnchorBlock extends RenderUtilityBlock {
@Override @Override

View file

@ -3,7 +3,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
@ -34,7 +34,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.Tags; import net.minecraftforge.common.Tags;
public class MechanicalPistonBlock extends DirectionalAxisKineticBlock public class MechanicalPistonBlock extends DirectionalAxisKineticBlock
implements IWithTileEntity<MechanicalPistonTileEntity> { implements ITE<MechanicalPistonTileEntity> {
public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class); public static final EnumProperty<PistonState> STATE = EnumProperty.create("state", PistonState.class);
protected boolean isSticky; protected boolean isSticky;
@ -102,11 +102,6 @@ public class MechanicalPistonBlock extends DirectionalAxisKineticBlock
return super.onWrenched(state, context); return super.onWrenched(state, context);
} }
@Override
protected boolean turnBackOnWrenched() {
return true;
}
public enum PistonState implements IStringSerializable { public enum PistonState implements IStringSerializable {
RETRACTED, MOVING, EXTENDED; RETRACTED, MOVING, EXTENDED;
@ -176,4 +171,9 @@ public class MechanicalPistonBlock extends DirectionalAxisKineticBlock
return VoxelShapes.fullCube(); return VoxelShapes.fullCube();
} }
@Override
public Class<MechanicalPistonTileEntity> getTileEntityClass() {
return MechanicalPistonTileEntity.class;
}
} }

View file

@ -9,6 +9,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M
import net.minecraft.block.Block; 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.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty; import net.minecraft.state.EnumProperty;
@ -37,6 +38,11 @@ public class MechanicalPistonHeadBlock extends ProperDirectionalBlock implements
super.fillStateContainer(builder); super.fillStateContainer(builder);
} }
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.NORMAL;
}
@Override @Override
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
PlayerEntity player) { PlayerEntity player) {

View file

@ -7,6 +7,7 @@ import com.simibubi.create.modules.contraptions.components.contraptions.piston.M
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.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
@ -26,6 +27,11 @@ public class PistonPoleBlock extends ProperDirectionalBlock {
setDefaultState(getDefaultState().with(FACING, Direction.UP)); setDefaultState(getDefaultState().with(FACING, Direction.UP));
} }
@Override
public PushReaction getPushReaction(BlockState state) {
return PushReaction.NORMAL;
}
@Override @Override
public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) {
Axis axis = state.get(FACING).getAxis(); Axis axis = state.get(FACING).getAxis();

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.contraptions.components.contraptions.pulley;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
@ -24,7 +24,7 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class PulleyBlock extends HorizontalAxisKineticBlock implements IWithTileEntity<PulleyTileEntity> { public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<PulleyTileEntity> {
public static EnumProperty<Axis> HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS; public static EnumProperty<Axis> HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS;
@ -131,4 +131,9 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements IWithTile
} }
@Override
public Class<PulleyTileEntity> getTileEntityClass() {
return PulleyTileEntity.class;
}
} }

View file

@ -30,6 +30,11 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
return super.getRenderBoundingBox().expand(0, -offset, 0); return super.getRenderBoundingBox().expand(0, -offset, 0);
} }
@Override
public double getMaxRenderDistanceSquared() {
return super.getMaxRenderDistanceSquared() + offset * offset;
}
@Override @Override
protected void assemble() { protected void assemble() {
if (speed == 0) if (speed == 0)
@ -151,7 +156,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
@Override @Override
protected int getExtensionRange() { protected int getExtensionRange() {
return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1); return Math.max(0, Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1));
} }
@Override @Override

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.contraptions.components.crafter;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour; import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import com.simibubi.create.foundation.block.connected.IHaveConnectedTextures; import com.simibubi.create.foundation.block.connected.IHaveConnectedTextures;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
@ -41,7 +41,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
public class MechanicalCrafterBlock extends HorizontalKineticBlock public class MechanicalCrafterBlock extends HorizontalKineticBlock
implements IWithTileEntity<MechanicalCrafterTileEntity>, IHaveConnectedTextures { implements ITE<MechanicalCrafterTileEntity>, IHaveConnectedTextures {
public static final EnumProperty<Pointing> POINTING = EnumProperty.create("pointing", Pointing.class); public static final EnumProperty<Pointing> POINTING = EnumProperty.create("pointing", Pointing.class);
@ -290,4 +290,9 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
return new InputCTBehaviour(); return new InputCTBehaviour();
} }
@Override
public Class<MechanicalCrafterTileEntity> getTileEntityClass() {
return MechanicalCrafterTileEntity.class;
}
} }

View file

@ -309,7 +309,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
if (!AllBlocks.BELT.typeOf(world.getBlockState(targetPos))) if (!AllBlocks.BELT.typeOf(world.getBlockState(targetPos)))
return false; return false;
TileEntity te = world.getTileEntity(targetPos); TileEntity te = world.getTileEntity(targetPos);
if (te == null || !(te instanceof BeltTileEntity)) if (!(te instanceof BeltTileEntity))
return false; return false;
return ((KineticTileEntity) te).getSpeed() != 0; return ((KineticTileEntity) te).getSpeed() != 0;
} }

View file

@ -163,10 +163,9 @@ public class MechanicalCrafterTileEntityRenderer extends SafeTileEntityRenderer<
if (te.phase == Phase.EXPORTING) { if (te.phase == Phase.EXPORTING) {
int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks)); int textureIndex = (int) ((te.getCountDownSpeed() / 128f * AnimationTickHolder.ticks));
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), beltBuffer.shiftUVtoSheet(animatedTexture, (textureIndex % 4) / 4f, 0, 1);
(textureIndex % 4) * 4, 0);
} else { } else {
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), 0, 0); beltBuffer.dontShiftUV();
} }
beltBuffer.renderInto(ms, vb); beltBuffer.renderInto(ms, vb);

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.contraptions.components.crank; package com.simibubi.create.modules.contraptions.components.crank;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
@ -22,7 +22,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class HandCrankBlock extends DirectionalKineticBlock implements IWithTileEntity<HandCrankTileEntity> { public class HandCrankBlock extends DirectionalKineticBlock implements ITE<HandCrankTileEntity> {
public HandCrankBlock() { public HandCrankBlock() {
super(Properties.from(AllBlocks.COGWHEEL.get())); super(Properties.from(AllBlocks.COGWHEEL.get()));
@ -96,4 +96,9 @@ public class HandCrankBlock extends DirectionalKineticBlock implements IWithTile
return state.get(FACING).getAxis(); return state.get(FACING).getAxis();
} }
@Override
public Class<HandCrankTileEntity> getTileEntityClass() {
return HandCrankTileEntity.class;
}
} }

View file

@ -3,8 +3,8 @@ package com.simibubi.create.modules.contraptions.components.crusher;
import static com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerBlock.VALID; import static com.simibubi.create.modules.contraptions.components.crusher.CrushingWheelControllerBlock.VALID;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -20,7 +20,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class CrushingWheelBlock extends RotatedPillarKineticBlock { public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE<CrushingWheelTileEntity> {
public CrushingWheelBlock() { public CrushingWheelBlock() {
super(Properties.from(Blocks.DIORITE)); super(Properties.from(Blocks.DIORITE));
@ -74,15 +74,22 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock {
BlockState otherState = world.getBlockState(otherWheelPos); BlockState otherState = world.getBlockState(otherWheelPos);
if (AllBlocks.CRUSHING_WHEEL.typeOf(otherState)) { if (AllBlocks.CRUSHING_WHEEL.typeOf(otherState)) {
controllerShouldExist = true; controllerShouldExist = true;
KineticTileEntity te = (KineticTileEntity) world.getTileEntity(pos);
KineticTileEntity otherTe = (KineticTileEntity) world.getTileEntity(otherWheelPos); try {
if (te != null && otherTe != null && (te.getSpeed() > 0) != (otherTe.getSpeed() > 0) CrushingWheelTileEntity te = getTileEntity(world, pos);
&& te.getSpeed() != 0) { CrushingWheelTileEntity otherTe = getTileEntity(world, otherWheelPos);
float signum = Math.signum(te.getSpeed()) * (state.get(AXIS) == Axis.X ? -1 : 1);
controllerShouldBeValid = facing.getAxisDirection().getOffset() != signum; if (te != null && otherTe != null && (te.getSpeed() > 0) != (otherTe.getSpeed() > 0)
} && te.getSpeed() != 0) {
if (otherState.get(AXIS) != state.get(AXIS)) float signum = Math.signum(te.getSpeed()) * (state.get(AXIS) == Axis.X ? -1 : 1);
controllerShouldBeValid = facing.getAxisDirection().getOffset() != signum;
}
if (otherState.get(AXIS) != state.get(AXIS))
controllerShouldExist = false;
} catch (TileEntityException e) {
controllerShouldExist = false; controllerShouldExist = false;
}
} }
if (!controllerShouldExist) { if (!controllerShouldExist) {
@ -107,24 +114,25 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock {
@Override @Override
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
KineticTileEntity te = (KineticTileEntity) worldIn.getTileEntity(pos); try {
if (te == null) CrushingWheelTileEntity te = getTileEntity(worldIn, pos);
return; if (entityIn.getY() < pos.getY() + 1.25f || !entityIn.onGround)
if (entityIn.getY() < pos.getY() + 1.25f || !entityIn.onGround) return;
return;
double x = 0; double x = 0;
double z = 0; double z = 0;
if (state.get(AXIS) == Axis.X) { if (state.get(AXIS) == Axis.X) {
z = te.getSpeed() / 20f; z = te.getSpeed() / 20f;
x += (pos.getX() + .5f - entityIn.getX()) * .1f; x += (pos.getX() + .5f - entityIn.getX()) * .1f;
} }
if (state.get(AXIS) == Axis.Z) { if (state.get(AXIS) == Axis.Z) {
x = te.getSpeed() / -20f; x = te.getSpeed() / -20f;
z += (pos.getZ() + .5f - entityIn.getZ()) * .1f; z += (pos.getZ() + .5f - entityIn.getZ()) * .1f;
} }
entityIn.setMotion(entityIn.getMotion().add(x, 0, z)); entityIn.setMotion(entityIn.getMotion().add(x, 0, z));
} catch (TileEntityException e) {}
} }
@Override @Override
@ -169,4 +177,9 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock {
return 1f; return 1f;
} }
@Override
public Class<CrushingWheelTileEntity> getTileEntityClass() {
return CrushingWheelTileEntity.class;
}
} }

View file

@ -4,6 +4,8 @@ import java.util.Random;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -12,7 +14,6 @@ import net.minecraft.block.Blocks;
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.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
@ -33,7 +34,8 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockItem { public class CrushingWheelControllerBlock extends Block
implements IHaveNoBlockItem, ITE<CrushingWheelControllerTileEntity> {
public static final BooleanProperty VALID = BooleanProperty.create("valid"); public static final BooleanProperty VALID = BooleanProperty.create("valid");
@ -51,6 +53,11 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
return false; return false;
} }
@Override
public boolean addRunningEffects(BlockState state, World world, BlockPos pos, Entity entity) {
return true;
}
@Override @Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) { public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return new CrushingWheelControllerTileEntity(); return new CrushingWheelControllerTileEntity();
@ -65,11 +72,10 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
if (!state.get(VALID) || CrushingWheelControllerTileEntity.isFrozen()) if (!state.get(VALID) || CrushingWheelControllerTileEntity.isFrozen())
return; return;
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos); withTileEntityDo(worldIn, pos, te -> {
if (te == null) if (te.processingEntity == entityIn)
return; entityIn.setMotionMultiplier(state, new Vec3d(0.25D, (double) 0.05F, 0.25D));
if (te.processingEntity == entityIn) });
entityIn.setMotionMultiplier(state, new Vec3d(0.25D, (double) 0.05F, 0.25D));
} }
@Override @Override
@ -77,25 +83,23 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
super.onLanded(worldIn, entityIn); super.onLanded(worldIn, entityIn);
if (CrushingWheelControllerTileEntity.isFrozen()) if (CrushingWheelControllerTileEntity.isFrozen())
return; return;
TileEntity tileEntity = worldIn.getTileEntity(entityIn.getPosition().down());
if (tileEntity == null)
return;
if (!(tileEntity instanceof CrushingWheelControllerTileEntity))
return;
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) tileEntity;
if (te.crushingspeed == 0)
return;
if (entityIn instanceof ItemEntity)
((ItemEntity) entityIn).setPickupDelay(10);
if (te.isOccupied())
return;
boolean isPlayer = entityIn instanceof PlayerEntity;
if (isPlayer && ((PlayerEntity) entityIn).isCreative())
return;
if (isPlayer && entityIn.world.getDifficulty() == Difficulty.PEACEFUL)
return;
te.startCrushing(entityIn); try {
CrushingWheelControllerTileEntity te = getTileEntity(worldIn, entityIn.getPosition().down());
if (te.crushingspeed == 0)
return;
if (entityIn instanceof ItemEntity)
((ItemEntity) entityIn).setPickupDelay(10);
if (te.isOccupied())
return;
boolean isPlayer = entityIn instanceof PlayerEntity;
if (isPlayer && ((PlayerEntity) entityIn).isCreative())
return;
if (isPlayer && entityIn.world.getDifficulty() == Difficulty.PEACEFUL)
return;
te.startCrushing(entityIn);
} catch (TileEntityException e) {}
} }
@Override @Override
@ -118,32 +122,29 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
} }
public void updateSpeed(BlockState state, World world, BlockPos pos) { public void updateSpeed(BlockState state, World world, BlockPos pos) {
TileEntity tileEntity = world.getTileEntity(pos); withTileEntityDo(world, pos, te -> {
if (tileEntity == null || !(tileEntity instanceof CrushingWheelControllerTileEntity)) if (!state.get(VALID) || CrushingWheelControllerTileEntity.isFrozen()) {
return; if (te.crushingspeed != 0) {
te.crushingspeed = 0;
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) tileEntity; te.sendData();
if (!state.get(VALID) || CrushingWheelControllerTileEntity.isFrozen()) { }
if (te.crushingspeed != 0) { return;
te.crushingspeed = 0;
te.sendData();
} }
return;
}
for (Direction d : Direction.values()) { for (Direction d : Direction.values()) {
if (d.getAxis().isVertical()) if (d.getAxis().isVertical())
continue; continue;
BlockState neighbour = world.getBlockState(pos.offset(d)); BlockState neighbour = world.getBlockState(pos.offset(d));
if (!AllBlocks.CRUSHING_WHEEL.typeOf(neighbour)) if (!AllBlocks.CRUSHING_WHEEL.typeOf(neighbour))
continue; continue;
if (neighbour.get(BlockStateProperties.AXIS) == d.getAxis()) if (neighbour.get(BlockStateProperties.AXIS) == d.getAxis())
continue; continue;
KineticTileEntity wheelTe = (KineticTileEntity) world.getTileEntity(pos.offset(d)); KineticTileEntity wheelTe = (KineticTileEntity) world.getTileEntity(pos.offset(d));
te.crushingspeed = Math.abs(wheelTe.getSpeed() / 50f); te.crushingspeed = Math.abs(wheelTe.getSpeed() / 50f);
te.sendData(); te.sendData();
break; break;
} }
});
} }
@Override @Override
@ -165,29 +166,27 @@ public class CrushingWheelControllerBlock extends Block implements IHaveNoBlockI
if (new AxisAlignedBB(pos).contains(entity.getPositionVec())) if (new AxisAlignedBB(pos).contains(entity.getPositionVec()))
return VoxelShapes.empty(); return VoxelShapes.empty();
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos); try {
if (te == null) CrushingWheelControllerTileEntity te = getTileEntity(worldIn, pos);
return VoxelShapes.fullCube(); if (te.processingEntity == entity)
if (te.processingEntity == entity) return VoxelShapes.empty();
return VoxelShapes.empty(); } catch (TileEntityException e) {}
} }
return VoxelShapes.fullCube(); return VoxelShapes.fullCube();
} }
@Override @Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { if (!state.hasTileEntity() || state.getBlock() == newState.getBlock())
if (worldIn.getTileEntity(pos) == null) return;
return;
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos);
for (int slot = 0; slot < te.inventory.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inventory.getStackInSlot(slot));
}
worldIn.removeTileEntity(pos); withTileEntityDo(worldIn, pos, te -> ItemHelper.dropContents(worldIn, pos, te.inventory));
} worldIn.removeTileEntity(pos);
}
@Override
public Class<CrushingWheelControllerTileEntity> getTileEntityClass() {
return CrushingWheelControllerTileEntity.class;
} }
} }

View file

@ -204,7 +204,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
@Override @Override
public CompoundNBT write(CompoundNBT compound) { public CompoundNBT write(CompoundNBT compound) {
if (hasEntity() && !isFrozen()) if (hasEntity())
compound.put("Entity", NBTUtil.writeUniqueId(entityUUID)); compound.put("Entity", NBTUtil.writeUniqueId(entityUUID));
compound.put("Inventory", inventory.serializeNBT()); compound.put("Inventory", inventory.serializeNBT());
compound.putFloat("Speed", crushingspeed); compound.putFloat("Speed", crushingspeed);

View file

@ -3,7 +3,7 @@ package com.simibubi.create.modules.contraptions.components.deployer;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock;
@ -26,7 +26,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class DeployerBlock extends DirectionalAxisKineticBlock public class DeployerBlock extends DirectionalAxisKineticBlock
implements IWithTileEntity<DeployerTileEntity>, IPortableBlock { implements ITE<DeployerTileEntity>, IPortableBlock {
public static MovementBehaviour MOVEMENT = new DeployerMovementBehaviour(); public static MovementBehaviour MOVEMENT = new DeployerMovementBehaviour();
@ -111,4 +111,9 @@ public class DeployerBlock extends DirectionalAxisKineticBlock
return MOVEMENT; return MOVEMENT;
} }
@Override
public Class<DeployerTileEntity> getTileEntityClass() {
return DeployerTileEntity.class;
}
} }

View file

@ -0,0 +1,104 @@
package com.simibubi.create.modules.contraptions.components.deployer;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemHandlerHelper;
public class DeployerItemHandler implements IItemHandlerModifiable {
private DeployerTileEntity te;
private DeployerFakePlayer player;
public DeployerItemHandler(DeployerTileEntity te) {
this.te = te;
this.player = te.player;
}
@Override
public int getSlots() {
return 1;
}
@Override
public ItemStack getStackInSlot(int slot) {
return getHeld();
}
public ItemStack getHeld() {
if (player == null)
return ItemStack.EMPTY;
return player.getHeldItemMainhand();
}
public void set(ItemStack stack) {
if (player == null)
return;
if (te.getWorld().isRemote)
return;
player.setHeldItem(Hand.MAIN_HAND, stack);
te.markDirty();
te.sendData();
}
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
ItemStack held = getHeld();
if (!isItemValid(slot, stack))
return stack;
if (held.isEmpty()) {
if (!simulate)
set(stack);
return ItemStack.EMPTY;
}
if (!ItemHandlerHelper.canItemStacksStack(held, stack))
return stack;
int space = held.getMaxStackSize() - held.getCount();
ItemStack split = stack.copy().split(space);
if (space == 0)
return stack;
if (!simulate) {
held = held.copy();
held.setCount(held.getCount() + split.getCount());
set(held);
}
return split;
}
@Override
public ItemStack extractItem(int slot, int amount, boolean simulate) {
ItemStack held = getHeld();
if (amount == 0 || held.isEmpty())
return ItemStack.EMPTY;
if (simulate)
return held.copy().split(amount);
ItemStack toReturn = held.split(amount);
te.markDirty();
te.sendData();
return toReturn;
}
@Override
public int getSlotLimit(int slot) {
return Math.min(getHeld().getMaxStackSize(), 64);
}
@Override
public boolean isItemValid(int slot, ItemStack stack) {
FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get(te, FilteringBehaviour.TYPE);
return filteringBehaviour == null || filteringBehaviour.test(stack);
}
@Override
public void setStackInSlot(int slot, ItemStack stack) {
set(stack);
}
}

View file

@ -41,8 +41,12 @@ import net.minecraft.util.math.RayTraceContext.BlockMode;
import net.minecraft.util.math.RayTraceContext.FluidMode; import net.minecraft.util.math.RayTraceContext.FluidMode;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
public class DeployerTileEntity extends KineticTileEntity { public class DeployerTileEntity extends KineticTileEntity {
@ -61,6 +65,7 @@ public class DeployerTileEntity extends KineticTileEntity {
protected boolean boop = false; protected boolean boop = false;
protected List<ItemStack> overflowItems = new ArrayList<>(); protected List<ItemStack> overflowItems = new ArrayList<>();
private ListNBT deferredInventoryList; private ListNBT deferredInventoryList;
private LazyOptional<IItemHandlerModifiable> invHandler;
enum State { enum State {
WAITING, EXPANDING, RETRACTING, DUMPING; WAITING, EXPANDING, RETRACTING, DUMPING;
@ -98,7 +103,10 @@ public class DeployerTileEntity extends KineticTileEntity {
heldItem = player.getHeldItemMainhand(); heldItem = player.getHeldItemMainhand();
sendData(); sendData();
} }
Vec3d initialPos = VecHelper.getCenterOf(pos.offset(getBlockState().get(FACING)));
player.setPosition(initialPos.x, initialPos.y, initialPos.z);
} }
invHandler = LazyOptional.of(this::createHandler);
} }
protected void onExtract(ItemStack stack) { protected void onExtract(ItemStack stack) {
@ -372,6 +380,10 @@ public class DeployerTileEntity extends KineticTileEntity {
super.readClientUpdate(tag); super.readClientUpdate(tag);
} }
private IItemHandlerModifiable createHandler() {
return new DeployerItemHandler(this);
}
@Override @Override
public boolean hasFastRenderer() { public boolean hasFastRenderer() {
return false; return false;
@ -387,15 +399,24 @@ public class DeployerTileEntity extends KineticTileEntity {
return super.getRenderBoundingBox().grow(3); return super.getRenderBoundingBox().grow(3);
} }
@Override
public void remove() {
super.remove();
invHandler.invalidate();
}
public void changeMode() { public void changeMode() {
eject();
mode = mode == Mode.PUNCH ? Mode.USE : Mode.PUNCH; mode = mode == Mode.PUNCH ? Mode.USE : Mode.PUNCH;
markDirty(); markDirty();
sendData(); sendData();
} }
protected void eject() { @Override
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && invHandler != null) {
return invHandler.cast();
}
return super.getCapability(cap, side);
} }
} }

View file

@ -9,6 +9,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.particle.AirFlowParticleData; import com.simibubi.create.modules.contraptions.particle.AirFlowParticleData;
import com.simibubi.create.modules.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
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;
@ -17,6 +18,7 @@ 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.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@ -94,6 +96,9 @@ public class AirCurrent {
entity.setMotion(previousMotion.add(new Vec3d(xIn, yIn, zIn).scale(1 / 8f))); entity.setMotion(previousMotion.add(new Vec3d(xIn, yIn, zIn).scale(1 / 8f)));
entity.fallDistance = 0; entity.fallDistance = 0;
if (entity instanceof ServerPlayerEntity)
((ServerPlayerEntity) entity).connection.floatingTickCount = 0;
if (InWorldProcessing.isFrozen()) if (InWorldProcessing.isFrozen())
return; return;
@ -267,15 +272,16 @@ public class AirCurrent {
public void tickBelts() { public void tickBelts() {
for (Pair<BeltTileEntity, Type> pair : affectedBelts) { for (Pair<BeltTileEntity, Type> pair : affectedBelts) {
BeltTileEntity belt = pair.getKey(); BeltTileEntity belt = pair.getKey();
World world = belt.getWorld();
InWorldProcessing.Type processingType = pair.getRight(); InWorldProcessing.Type processingType = pair.getRight();
BeltTileEntity controller = belt.getControllerTE(); BeltTileEntity controller = belt.getControllerTE();
if (controller == null) if (controller == null)
continue; continue;
World world = belt.getWorld();
controller.getInventory().forEachWithin(belt.index + .5f, .51f, (transported) -> { controller.getInventory().forEachWithin(belt.index + .5f, .51f, (transported) -> {
InWorldProcessing.spawnParticlesForProcessing(world, InWorldProcessing.spawnParticlesForProcessing(world,
controller.getInventory().getVectorForOffset(transported.beltPosition), processingType); BeltHelper.getVectorForOffset(controller, transported.beltPosition), processingType);
if (world.isRemote) if (world.isRemote)
return null; return null;
return InWorldProcessing.applyProcessing(transported, belt, processingType); return InWorldProcessing.applyProcessing(transported, belt, processingType);

View file

@ -1,12 +1,13 @@
package com.simibubi.create.modules.contraptions.components.fan; package com.simibubi.create.modules.contraptions.components.fan;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalKineticBlock;
import net.minecraft.block.Block; 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.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemUseContext;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
@ -16,7 +17,7 @@ import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class EncasedFanBlock extends DirectionalKineticBlock implements IWithTileEntity<EncasedFanTileEntity> { public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<EncasedFanTileEntity> {
public EncasedFanBlock() { public EncasedFanBlock() {
super(Properties.from(Blocks.ANDESITE)); super(Properties.from(Blocks.ANDESITE));
@ -49,15 +50,21 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements IWithTil
protected void blockUpdate(BlockState state, World worldIn, BlockPos pos) { protected void blockUpdate(BlockState state, World worldIn, BlockPos pos) {
notifyFanTile(worldIn, pos); notifyFanTile(worldIn, pos);
if (worldIn.isRemote || state.get(FACING) != Direction.DOWN) if (worldIn.isRemote)
return; return;
withTileEntityDo(worldIn, pos, EncasedFanTileEntity::updateGenerator); withTileEntityDo(worldIn, pos, te -> te.updateGenerator(state.get(FACING)));
} }
protected void notifyFanTile(IWorld world, BlockPos pos) { protected void notifyFanTile(IWorld world, BlockPos pos) {
withTileEntityDo(world, pos, EncasedFanTileEntity::blockInFrontChanged); withTileEntityDo(world, pos, EncasedFanTileEntity::blockInFrontChanged);
} }
@Override
public BlockState updateAfterWrenched(BlockState newState, ItemUseContext context) {
blockUpdate(newState, context.getWorld(), context.getPos());
return newState;
}
// @Override // TODO 1.15 register layer // @Override // TODO 1.15 register layer
// public BlockRenderLayer getRenderLayer() { // public BlockRenderLayer getRenderLayer() {
// return BlockRenderLayer.CUTOUT; // return BlockRenderLayer.CUTOUT;
@ -83,4 +90,9 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements IWithTil
return true; return true;
} }
@Override
public Class<EncasedFanTileEntity> getTileEntityClass() {
return EncasedFanTileEntity.class;
}
} }

View file

@ -45,13 +45,13 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
} }
@Override @Override
public float getAddedStressCapacity() { public float calculateAddedStressCapacity() {
return isGenerator ? super.getAddedStressCapacity() : 0; return isGenerator ? super.calculateAddedStressCapacity() : 0;
} }
@Override @Override
public float getStressApplied() { public float calculateStressApplied() {
return isGenerator ? 0 : super.getStressApplied(); return isGenerator ? 0 : super.calculateStressApplied();
} }
@Override @Override
@ -59,8 +59,8 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
return isGenerator ? AllConfigs.SERVER.kinetics.generatingFanSpeed.get() : 0; return isGenerator ? AllConfigs.SERVER.kinetics.generatingFanSpeed.get() : 0;
} }
public void updateGenerator() { public void updateGenerator(Direction facing) {
boolean shouldGenerate = world.isBlockPowered(pos) && world.isBlockPresent(pos.down()) && blockBelowIsHot(); boolean shouldGenerate = world.isBlockPowered(pos) && facing == Direction.DOWN && world.isBlockPresent(pos.down()) && blockBelowIsHot();
if (shouldGenerate == isGenerator) if (shouldGenerate == isGenerator)
return; return;

View file

@ -158,8 +158,21 @@ public class NozzleTileEntity extends SmartTileEntity {
pushingEntities.add(entity); pushingEntities.add(entity);
} }
if (!pushing && pushingEntities.size() > 512 && !world.isRemote) for (Iterator<Entity> iterator = pushingEntities.iterator(); iterator.hasNext();) {
world.createExplosion(null, center.x, center.y, center.z, 6, Mode.BREAK); Entity entity = iterator.next();
if (entity.isAlive())
continue;
iterator.remove();
}
if (!pushing && pushingEntities.size() > 256 && !world.isRemote) {
world.createExplosion(null, center.x, center.y, center.z, 2, Mode.NONE);
for (Iterator<Entity> iterator = pushingEntities.iterator(); iterator.hasNext();) {
Entity entity = iterator.next();
entity.remove();
iterator.remove();
}
}
} }

View file

@ -43,7 +43,7 @@ public class FlywheelTileEntity extends GeneratingKineticTileEntity {
} }
@Override @Override
public float getAddedStressCapacity() { public float calculateAddedStressCapacity() {
return generatedCapacity; return generatedCapacity;
} }

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.contraptions.components.flywheel.engine;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import net.minecraft.block.AbstractFurnaceBlock; import net.minecraft.block.AbstractFurnaceBlock;
@ -23,7 +23,7 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber @EventBusSubscriber
public class FurnaceEngineBlock extends EngineBlock implements IWithTileEntity<FurnaceEngineTileEntity> { public class FurnaceEngineBlock extends EngineBlock implements ITE<FurnaceEngineTileEntity> {
public FurnaceEngineBlock() { public FurnaceEngineBlock() {
super(Properties.from(Blocks.GOLD_BLOCK)); super(Properties.from(Blocks.GOLD_BLOCK));
@ -76,4 +76,9 @@ public class FurnaceEngineBlock extends EngineBlock implements IWithTileEntity<F
event.setUseBlock(Result.DENY); event.setUseBlock(Result.DENY);
} }
@Override
public Class<FurnaceEngineTileEntity> getTileEntityClass() {
return FurnaceEngineTileEntity.class;
}
} }

View file

@ -1,6 +1,9 @@
package com.simibubi.create.modules.contraptions.components.millstone; package com.simibubi.create.modules.contraptions.components.millstone;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.modules.contraptions.base.KineticBlock; import com.simibubi.create.modules.contraptions.base.KineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -8,7 +11,6 @@ import net.minecraft.block.Blocks;
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.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
@ -28,7 +30,7 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
public class MillstoneBlock extends KineticBlock { public class MillstoneBlock extends KineticBlock implements ITE<MillstoneTileEntity> {
public MillstoneBlock() { public MillstoneBlock() {
super(Properties.from(Blocks.ANDESITE)); super(Properties.from(Blocks.ANDESITE));
@ -59,23 +61,32 @@ public class MillstoneBlock extends KineticBlock {
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
if (!player.getHeldItem(handIn).isEmpty()) if (!player.getHeldItem(handIn).isEmpty())
return ActionResultType.PASS; return ActionResultType.PASS;
if (worldIn.getTileEntity(pos) == null)
return ActionResultType.PASS;
if (worldIn.isRemote) if (worldIn.isRemote)
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
TileEntity tileEntity = worldIn.getTileEntity(pos); withTileEntityDo(worldIn, pos, millstone -> {
if (!(tileEntity instanceof MillstoneTileEntity)) boolean emptyOutput = true;
return ActionResultType.PASS; IItemHandlerModifiable inv = millstone.outputInv;
MillstoneTileEntity millstone = (MillstoneTileEntity) tileEntity; for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stackInSlot = inv.getStackInSlot(slot);
if (!stackInSlot.isEmpty())
emptyOutput = false;
player.inventory.placeItemBackInInventory(worldIn, stackInSlot);
inv.setStackInSlot(slot, ItemStack.EMPTY);
}
if (emptyOutput) {
inv = millstone.inputInv;
for (int slot = 0; slot < inv.getSlots(); slot++) {
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
inv.setStackInSlot(slot, ItemStack.EMPTY);
}
}
millstone.markDirty();
millstone.sendData();
});
IItemHandlerModifiable inv = millstone.outputInv;
for (int slot = 0; slot < inv.getSlots(); slot++) {
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
inv.setStackInSlot(slot, ItemStack.EMPTY);
}
millstone.markDirty();
millstone.sendData();
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
@ -88,15 +99,17 @@ public class MillstoneBlock extends KineticBlock {
if (!(entityIn instanceof ItemEntity)) if (!(entityIn instanceof ItemEntity))
return; return;
BlockPos pos = entityIn.getPosition(); MillstoneTileEntity millstone = null;
TileEntity tileEntity = worldIn.getTileEntity(pos); for (BlockPos pos : Iterate.hereAndBelow(entityIn.getPosition())) {
if (!(tileEntity instanceof MillstoneTileEntity)) { try {
tileEntity = worldIn.getTileEntity(pos.down()); millstone = getTileEntity(worldIn, pos);
if (!(tileEntity instanceof MillstoneTileEntity)) } catch (TileEntityException e) {
return; continue;
}
} }
if (millstone == null)
return;
MillstoneTileEntity millstone = (MillstoneTileEntity) tileEntity;
ItemEntity itemEntity = (ItemEntity) entityIn; ItemEntity itemEntity = (ItemEntity) entityIn;
LazyOptional<IItemHandler> capability = millstone.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); LazyOptional<IItemHandler> capability = millstone.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
if (!capability.isPresent()) if (!capability.isPresent())
@ -112,18 +125,10 @@ public class MillstoneBlock extends KineticBlock {
@Override @Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
TileEntity tileEntity = worldIn.getTileEntity(pos); withTileEntityDo(worldIn, pos, te -> {
if (!(tileEntity instanceof MillstoneTileEntity)) ItemHelper.dropContents(worldIn, pos, te.inputInv);
return; ItemHelper.dropContents(worldIn, pos, te.outputInv);
MillstoneTileEntity te = (MillstoneTileEntity) tileEntity; });
for (int slot = 0; slot < te.inputInv.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inputInv.getStackInSlot(slot));
}
for (int slot = 0; slot < te.outputInv.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.outputInv.getStackInSlot(slot));
}
worldIn.removeTileEntity(pos); worldIn.removeTileEntity(pos);
} }
@ -139,4 +144,9 @@ public class MillstoneBlock extends KineticBlock {
return Axis.Y; return Axis.Y;
} }
@Override
public Class<MillstoneTileEntity> getTileEntityClass() {
return MillstoneTileEntity.class;
}
} }

View file

@ -142,6 +142,16 @@ public class MillstoneTileEntity extends KineticTileEntity {
return super.getCapability(cap, side); return super.getCapability(cap, side);
} }
private boolean canProcess(ItemStack stack) {
ItemStackHandler tester = new ItemStackHandler(1);
tester.setStackInSlot(0, stack);
RecipeWrapper inventoryIn = new RecipeWrapper(tester);
if (lastRecipe != null && lastRecipe.matches(inventoryIn, world))
return true;
return world.getRecipeManager().getRecipe(AllRecipes.MILLING.getType(), inventoryIn, world).isPresent();
}
private class MillstoneInventoryHandler extends CombinedInvWrapper { private class MillstoneInventoryHandler extends CombinedInvWrapper {
public MillstoneInventoryHandler() { public MillstoneInventoryHandler() {
@ -152,13 +162,15 @@ public class MillstoneTileEntity extends KineticTileEntity {
public boolean isItemValid(int slot, ItemStack stack) { public boolean isItemValid(int slot, ItemStack stack) {
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot))) if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
return false; return false;
return super.isItemValid(slot, stack); return canProcess(stack) && super.isItemValid(slot, stack);
} }
@Override @Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (outputInv == getHandlerFromIndex(getIndexForSlot(slot))) if (outputInv == getHandlerFromIndex(getIndexForSlot(slot)))
return stack; return stack;
if (!isItemValid(slot, stack))
return stack;
return super.insertItem(slot, stack, simulate); return super.insertItem(slot, stack, simulate);
} }

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.contraptions.components.mixer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveCustomBlockItem; import com.simibubi.create.foundation.block.IHaveCustomBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.KineticBlock; import com.simibubi.create.modules.contraptions.base.KineticBlock;
@ -20,7 +20,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
public class MechanicalMixerBlock extends KineticBlock public class MechanicalMixerBlock extends KineticBlock
implements IWithTileEntity<MechanicalMixerTileEntity>, IHaveCustomBlockItem { implements ITE<MechanicalMixerTileEntity>, IHaveCustomBlockItem {
public MechanicalMixerBlock() { public MechanicalMixerBlock() {
super(Properties.from(Blocks.ANDESITE)); super(Properties.from(Blocks.ANDESITE));
@ -89,4 +89,9 @@ public class MechanicalMixerBlock extends KineticBlock
return new BasinOperatorBlockItem(AllBlocks.MECHANICAL_MIXER, properties); return new BasinOperatorBlockItem(AllBlocks.MECHANICAL_MIXER, properties);
} }
@Override
public Class<MechanicalMixerTileEntity> getTileEntityClass() {
return MechanicalMixerTileEntity.class;
}
} }

View file

@ -6,8 +6,7 @@ import java.util.Optional;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IHaveCustomBlockItem; import com.simibubi.create.foundation.block.IHaveCustomBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.block.SyncedTileEntity;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
@ -18,7 +17,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.I
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack; import com.simibubi.create.modules.contraptions.relays.belt.transport.TransportedItemStack;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -39,7 +38,7 @@ import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class MechanicalPressBlock extends HorizontalKineticBlock public class MechanicalPressBlock extends HorizontalKineticBlock
implements IWithTileEntity<MechanicalPressTileEntity>, IBeltAttachment, IHaveCustomBlockItem { implements ITE<MechanicalPressTileEntity>, IBeltAttachment, IHaveCustomBlockItem {
public MechanicalPressBlock() { public MechanicalPressBlock() {
super(Properties.from(Blocks.PISTON)); super(Properties.from(Blocks.PISTON));
@ -63,17 +62,15 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
boolean isMoving) { boolean isMoving) {
if (worldIn.isRemote) if (worldIn.isRemote)
return; return;
MechanicalPressTileEntity te = (MechanicalPressTileEntity) worldIn.getTileEntity(pos);
if (te == null)
return;
if (worldIn.isBlockPowered(pos)) { withTileEntityDo(worldIn, pos, te -> {
if (!worldIn.isBlockPowered(pos)) {
te.finished = false;
return;
}
if (!te.finished && !te.running && te.getSpeed() != 0) if (!te.finished && !te.running && te.getSpeed() != 0)
te.start(Mode.WORLD); te.start(Mode.WORLD);
} else { });
te.finished = false;
}
} }
@Override @Override
@ -134,54 +131,61 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
} }
@Override @Override
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { public boolean startProcessingItem(BeltTileEntity belt, TransportedItemStack transported,
MechanicalPressTileEntity pressTe = (MechanicalPressTileEntity) te.getWorld() BeltAttachmentState state) {
.getTileEntity(state.attachmentPos); try {
MechanicalPressTileEntity pressTe = getTileEntity(belt.getWorld(), state.attachmentPos);
if (pressTe.getSpeed() == 0)
return false;
if (pressTe.running)
return false;
if (!pressTe.getRecipe(transported.stack).isPresent())
return false;
if (pressTe == null || pressTe.getSpeed() == 0) state.processingDuration = 1;
return false; pressTe.start(Mode.BELT);
if (pressTe.running) return true;
return false;
if (!pressTe.getRecipe(transported.stack).isPresent())
return false;
state.processingDuration = 1; } catch (TileEntityException e) {}
pressTe.start(Mode.BELT); return false;
return true;
} }
@Override @Override
public boolean processItem(BeltTileEntity te, TransportedItemStack transportedStack, BeltAttachmentState state) { public boolean processItem(BeltTileEntity belt, TransportedItemStack transportedStack, BeltAttachmentState state) {
MechanicalPressTileEntity pressTe = (MechanicalPressTileEntity) te.getWorld() try {
.getTileEntity(state.attachmentPos); MechanicalPressTileEntity pressTe = getTileEntity(belt.getWorld(), state.attachmentPos);
// Not powered // Not powered
if (pressTe == null || pressTe.getSpeed() == 0) if (pressTe.getSpeed() == 0)
return false; return false;
// Running // Running
if (pressTe.running) { if (!pressTe.running)
if (pressTe.runningTicks == 30) { return false;
Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack); if (pressTe.runningTicks != 30)
return true;
pressTe.pressedItems.clear(); Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack);
pressTe.pressedItems.add(transportedStack.stack);
if (!recipe.isPresent()) pressTe.pressedItems.clear();
return false; pressTe.pressedItems.add(transportedStack.stack);
ItemStack out = recipe.get().getRecipeOutput().copy();
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
if (multipliedOutput.isEmpty())
transportedStack.stack = ItemStack.EMPTY;
transportedStack.stack = multipliedOutput.get(0);
TileEntity controllerTE = te.getWorld().getTileEntity(te.getController()); if (!recipe.isPresent())
if (controllerTE != null && controllerTE instanceof BeltTileEntity) return false;
((SyncedTileEntity) controllerTE).sendData();
pressTe.sendData(); ItemStack out = recipe.get().getRecipeOutput().copy();
} List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
if (multipliedOutput.isEmpty())
transportedStack.stack = ItemStack.EMPTY;
transportedStack.stack = multipliedOutput.get(0);
BeltTileEntity controllerTE = belt.getControllerTE();
if (controllerTE != null)
controllerTE.sendData();
pressTe.sendData();
return true; return true;
}
} catch (TileEntityException e) {}
return false; return false;
} }
@ -191,4 +195,9 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
return new BasinOperatorBlockItem(AllBlocks.MECHANICAL_PRESS, properties); return new BasinOperatorBlockItem(AllBlocks.MECHANICAL_PRESS, properties);
} }
@Override
public Class<MechanicalPressTileEntity> getTileEntityClass() {
return MechanicalPressTileEntity.class;
}
} }

View file

@ -2,7 +2,8 @@ package com.simibubi.create.modules.contraptions.components.saw;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.components.actors.SawMovementBehaviour; import com.simibubi.create.modules.contraptions.components.actors.SawMovementBehaviour;
@ -15,7 +16,6 @@ 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.Entity;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.inventory.InventoryHelper;
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;
@ -32,7 +32,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEntity<SawTileEntity>, IPortableBlock { public class SawBlock extends DirectionalAxisKineticBlock implements ITE<SawTileEntity>, IPortableBlock {
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 static DamageSource damageSourceSaw = new DamageSource("create.saw").setDamageBypassesArmor();
@ -96,12 +96,13 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
super.onLanded(worldIn, entityIn); super.onLanded(worldIn, entityIn);
if (!(entityIn instanceof ItemEntity)) if (!(entityIn instanceof ItemEntity))
return; return;
BlockPos pos = entityIn.getPosition();
if (!(worldIn.getTileEntity(pos) instanceof SawTileEntity))
return;
if (entityIn.world.isRemote) if (entityIn.world.isRemote)
return; return;
BlockPos pos = entityIn.getPosition();
withTileEntityDo(entityIn.world, pos, te -> { withTileEntityDo(entityIn.world, pos, te -> {
if (te.getSpeed() == 0)
return;
te.insertItem((ItemEntity) entityIn); te.insertItem((ItemEntity) entityIn);
}); });
} }
@ -128,19 +129,12 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
@Override @Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (worldIn.getTileEntity(pos) == null) if (!state.hasTileEntity() || state.getBlock() == newState.getBlock())
return; return;
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { withTileEntityDo(worldIn, pos, te -> ItemHelper.dropContents(worldIn, pos, te.inventory));
withTileEntityDo(worldIn, pos, te -> { TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
for (int slot = 0; slot < te.inventory.getSlots(); slot++) { worldIn.removeTileEntity(pos);
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
te.inventory.getStackInSlot(slot));
}
});
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeTileEntity(pos);
}
} }
@Override @Override
@ -148,4 +142,9 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IWithTileEn
return MOVEMENT; return MOVEMENT;
} }
@Override
public Class<SawTileEntity> getTileEntityClass() {
return SawTileEntity.class;
}
} }

View file

@ -55,6 +55,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
private int recipeIndex; private int recipeIndex;
private LazyOptional<IItemHandler> invProvider = LazyOptional.empty(); private LazyOptional<IItemHandler> invProvider = LazyOptional.empty();
private FilteringBehaviour filtering; private FilteringBehaviour filtering;
private boolean destroyed;
public SawTileEntity() { public SawTileEntity() {
super(AllTileEntities.SAW.type); super(AllTileEntities.SAW.type);
@ -81,7 +82,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
super.onSpeedChanged(prevSpeed); super.onSpeedChanged(prevSpeed);
boolean shouldRun = Math.abs(getSpeed()) > 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 && !destroyed)
world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun), 2 | 16); world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun), 2 | 16);
} }
@ -148,8 +149,6 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
if (stack.isEmpty()) if (stack.isEmpty())
continue; continue;
// if (itemMovementFacing.getAxis() == Axis.Z)
// itemMovementFacing = itemMovementFacing.getOpposite();
if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false)) if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false))
inventory.setStackInSlot(slot, ItemStack.EMPTY); inventory.setStackInSlot(slot, ItemStack.EMPTY);
else { else {
@ -214,8 +213,9 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
@Override @Override
public void remove() { public void remove() {
super.remove();
invProvider.invalidate(); invProvider.invalidate();
destroyed = true;
super.remove();
} }
@Override @Override

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.contraptions.components.turntable; package com.simibubi.create.modules.contraptions.components.turntable;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.KineticBlock; import com.simibubi.create.modules.contraptions.base.KineticBlock;
@ -22,7 +23,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class TurntableBlock extends KineticBlock { public class TurntableBlock extends KineticBlock implements ITE<TurntableTileEntity> {
public TurntableBlock() { public TurntableBlock() {
super(Properties.from(Blocks.STRIPPED_SPRUCE_LOG)); super(Properties.from(Blocks.STRIPPED_SPRUCE_LOG));
@ -40,51 +41,48 @@ public class TurntableBlock extends KineticBlock {
@Override @Override
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity e) { public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity e) {
TileEntity te = worldIn.getTileEntity(pos);
if (!(te instanceof KineticTileEntity))
return;
if (!e.onGround) if (!e.onGround)
return; return;
if (e.getMotion().y > 0) if (e.getMotion().y > 0)
return; return;
float speed = ((KineticTileEntity) te).getSpeed() * 3/10;
World world = e.getEntityWorld();
if (speed == 0)
return;
if (e.getY() < pos.getY() + .5f) if (e.getY() < pos.getY() + .5f)
return; return;
if (world.isRemote && (e instanceof PlayerEntity)) { withTileEntityDo(worldIn, pos, te -> {
if (worldIn.getBlockState(e.getPosition()) != state) { float speed = ((KineticTileEntity) te).getSpeed() * 3 / 10;
Vec3d origin = VecHelper.getCenterOf(pos); if (speed == 0)
Vec3d offset = e.getPositionVec().subtract(origin); return;
offset = VecHelper.rotate(offset, MathHelper.clamp(speed, -16, 16) / 1f, Axis.Y);
Vec3d movement = origin.add(offset).subtract(e.getPositionVec()); World world = e.getEntityWorld();
e.setMotion(e.getMotion().add(movement)); if (world.isRemote && (e instanceof PlayerEntity)) {
if (worldIn.getBlockState(e.getPosition()) != state) {
Vec3d origin = VecHelper.getCenterOf(pos);
Vec3d offset = e.getPositionVec().subtract(origin);
offset = VecHelper.rotate(offset, MathHelper.clamp(speed, -16, 16) / 1f, Axis.Y);
Vec3d movement = origin.add(offset).subtract(e.getPositionVec());
e.setMotion(e.getMotion().add(movement));
e.velocityChanged = true;
}
}
if ((e instanceof PlayerEntity))
return;
if (world.isRemote)
return;
if ((e instanceof LivingEntity)) {
float diff = e.getRotationYawHead() - speed;
((LivingEntity) e).setIdleTime(20);
e.setRenderYawOffset(diff);
e.setRotationYawHead(diff);
e.onGround = false;
e.velocityChanged = true; e.velocityChanged = true;
} }
}
if ((e instanceof PlayerEntity))
return;
if (world.isRemote)
return;
if ((e instanceof LivingEntity)) {
float diff = e.getRotationYawHead() - speed;
((LivingEntity) e).setIdleTime(20);
e.setRenderYawOffset(diff);
e.setRotationYawHead(diff);
e.onGround = false;
e.velocityChanged = true;
}
e.rotationYaw -= speed;
e.rotationYaw -= speed;
});
} }
// IRotate:
@Override @Override
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
return face == Direction.DOWN; return face == Direction.DOWN;
@ -100,4 +98,9 @@ public class TurntableBlock extends KineticBlock {
return false; return false;
} }
@Override
public Class<TurntableTileEntity> getTileEntityClass() {
return TurntableTileEntity.class;
}
} }

View file

@ -2,9 +2,9 @@ package com.simibubi.create.modules.contraptions.components.turntable;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -22,8 +22,12 @@ public class TurntableHandler {
if (mc.isGamePaused()) if (mc.isGamePaused())
return; return;
KineticTileEntity te = (KineticTileEntity) mc.world.getTileEntity(pos); TileEntity tileEntity = mc.world.getTileEntity(pos);
float speed = te.getSpeed() * 3/10; if (!(tileEntity instanceof TurntableTileEntity))
return;
TurntableTileEntity turnTable = (TurntableTileEntity) tileEntity;
float speed = turnTable.getSpeed() * 3/10;
if (speed == 0) if (speed == 0)
return; return;

View file

@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.components.waterwheel;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -19,7 +20,7 @@ import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class WaterWheelBlock extends HorizontalKineticBlock { public class WaterWheelBlock extends HorizontalKineticBlock implements ITE<WaterWheelTileEntity> {
public WaterWheelBlock() { public WaterWheelBlock() {
super(Properties.from(Blocks.STRIPPED_SPRUCE_WOOD)); super(Properties.from(Blocks.STRIPPED_SPRUCE_WOOD));
@ -78,46 +79,42 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
} }
private void updateFlowAt(BlockState state, World world, BlockPos pos, Direction f) { private void updateFlowAt(BlockState state, World world, BlockPos pos, Direction f) {
WaterWheelTileEntity te = (WaterWheelTileEntity) world.getTileEntity(pos);
if (te == null)
return;
if (f.getAxis() == state.get(HORIZONTAL_FACING).getAxis()) if (f.getAxis() == state.get(HORIZONTAL_FACING).getAxis())
return; return;
IFluidState fluid = world.getFluidState(pos.offset(f));
Vec3d flowVec = fluid.getFlow(world, pos.offset(f));
Direction wf = state.get(HORIZONTAL_FACING);
double flow = 0;
flowVec = flowVec.scale(f.getAxisDirection().getOffset()); IFluidState fluid = world.getFluidState(pos.offset(f));
Direction wf = state.get(HORIZONTAL_FACING);
boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE; boolean clockwise = wf.getAxisDirection() == AxisDirection.POSITIVE;
int clockwiseMultiplier = 2; int clockwiseMultiplier = 2;
flowVec = new Vec3d(Math.signum(flowVec.x), Math.signum(flowVec.y), Math.signum(flowVec.z));
if (wf.getAxis() == Axis.Z) { Vec3d vec = fluid.getFlow(world, pos.offset(f));
if (f.getAxis() == Axis.Y) vec = vec.scale(f.getAxisDirection().getOffset());
flow = flowVec.x > 0 ^ !clockwise ? -flowVec.x * clockwiseMultiplier : -flowVec.x; vec = new Vec3d(Math.signum(vec.x), Math.signum(vec.y), Math.signum(vec.z));
if (f.getAxis() == Axis.X) Vec3d flow = vec;
flow = flowVec.y < 0 ^ !clockwise ? flowVec.y * clockwiseMultiplier : flowVec.y;
}
if (wf.getAxis() == Axis.X) { withTileEntityDo(world, pos, te -> {
if (f.getAxis() == Axis.Y) double flowStrength = 0;
flow = flowVec.z < 0 ^ !clockwise ? flowVec.z * clockwiseMultiplier : flowVec.z;
if (f.getAxis() == Axis.Z)
flow = flowVec.y > 0 ^ !clockwise ? -flowVec.y * clockwiseMultiplier : -flowVec.y;
}
te.setFlow(f, (float) (flow * AllConfigs.SERVER.kinetics.waterWheelSpeed.get() / 2f)); if (wf.getAxis() == Axis.Z) {
if (f.getAxis() == Axis.Y)
flowStrength = flow.x > 0 ^ !clockwise ? -flow.x * clockwiseMultiplier : -flow.x;
if (f.getAxis() == Axis.X)
flowStrength = flow.y < 0 ^ !clockwise ? flow.y * clockwiseMultiplier : flow.y;
}
if (wf.getAxis() == Axis.X) {
if (f.getAxis() == Axis.Y)
flowStrength = flow.z < 0 ^ !clockwise ? flow.z * clockwiseMultiplier : flow.z;
if (f.getAxis() == Axis.Z)
flowStrength = flow.y > 0 ^ !clockwise ? -flow.y * clockwiseMultiplier : -flow.y;
}
te.setFlow(f, (float) (flowStrength * AllConfigs.SERVER.kinetics.waterWheelSpeed.get() / 2f));
});
} }
private void updateWheelSpeed(IWorld world, BlockPos pos) { private void updateWheelSpeed(IWorld world, BlockPos pos) {
if (world.isRemote()) withTileEntityDo(world, pos, WaterWheelTileEntity::updateGeneratedRotation);
return;
TileEntity tileEntity = world.getTileEntity(pos);
if (!(tileEntity instanceof WaterWheelTileEntity))
return;
WaterWheelTileEntity te = (WaterWheelTileEntity) tileEntity;
te.updateGeneratedRotation();
} }
@Override @Override
@ -158,4 +155,9 @@ public class WaterWheelBlock extends HorizontalKineticBlock {
return true; return true;
} }
@Override
public Class<WaterWheelTileEntity> getTileEntityClass() {
return WaterWheelTileEntity.class;
}
} }

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.contraptions.processing; package com.simibubi.create.modules.contraptions.processing;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AllShapes;
@ -12,7 +12,6 @@ import net.minecraft.block.material.PushReaction;
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.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
@ -27,7 +26,7 @@ import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity> { public class BasinBlock extends Block implements ITE<BasinTileEntity> {
public BasinBlock() { public BasinBlock() {
super(Properties.from(Blocks.ANDESITE)); super(Properties.from(Blocks.ANDESITE));
@ -53,16 +52,16 @@ public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
if (!player.getHeldItem(handIn).isEmpty()) if (!player.getHeldItem(handIn).isEmpty())
return ActionResultType.PASS; return ActionResultType.PASS;
if (worldIn.getTileEntity(pos) == null)
return ActionResultType.PASS;
BasinTileEntity te = (BasinTileEntity) worldIn.getTileEntity(pos); try {
IItemHandlerModifiable inv = te.inventory.orElse(new ItemStackHandler(1)); BasinTileEntity te = getTileEntity(worldIn, pos);
for (int slot = 0; slot < inv.getSlots(); slot++) { IItemHandlerModifiable inv = te.inventory.orElse(new ItemStackHandler(1));
player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot)); for (int slot = 0; slot < inv.getSlots(); slot++) {
inv.setStackInSlot(slot, ItemStack.EMPTY); player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot));
} inv.setStackInSlot(slot, ItemStack.EMPTY);
te.onEmptied(); }
te.onEmptied();
} catch (TileEntityException e) {}
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
@ -76,18 +75,17 @@ public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity
return; return;
if (!entityIn.isAlive()) if (!entityIn.isAlive())
return; return;
BasinTileEntity te = (BasinTileEntity) worldIn.getTileEntity(entityIn.getPosition());
ItemEntity itemEntity = (ItemEntity) entityIn; ItemEntity itemEntity = (ItemEntity) entityIn;
ItemStack insertItem = ItemHandlerHelper.insertItem(te.inputInventory, itemEntity.getItem().copy(), false); withTileEntityDo(worldIn, entityIn.getPosition(), te -> {
ItemStack insertItem = ItemHandlerHelper.insertItem(te.inputInventory, itemEntity.getItem().copy(), false);
if (insertItem.isEmpty()) { if (insertItem.isEmpty()) {
itemEntity.remove(); itemEntity.remove();
return; return;
} }
itemEntity.setItem(insertItem);
itemEntity.setItem(insertItem);
});
} }
@Override @Override
@ -97,19 +95,15 @@ public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity
@Override @Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (worldIn.getTileEntity(pos) == null) if (!state.hasTileEntity() || state.getBlock() == newState.getBlock()) {
return; return;
BasinTileEntity te = (BasinTileEntity) worldIn.getTileEntity(pos);
IItemHandlerModifiable inv = te.inventory.orElse(new ItemStackHandler(1));
for (int slot = 0; slot < inv.getSlots(); slot++) {
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), inv.getStackInSlot(slot));
}
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
worldIn.removeTileEntity(pos);
} }
withTileEntityDo(worldIn, pos, te -> {
ItemHelper.dropContents(worldIn, pos, te.inputInventory);
ItemHelper.dropContents(worldIn, pos, te.outputInventory);
});
worldIn.removeTileEntity(pos);
} }
@Override @Override
@ -119,12 +113,15 @@ public class BasinBlock extends Block implements IWithTileEntity<BasinTileEntity
@Override @Override
public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) {
TileEntity te = worldIn.getTileEntity(pos); try {
if (te instanceof BasinTileEntity) { return ItemHelper.calcRedstoneFromInventory(getTileEntity(worldIn, pos).inputInventory);
BasinTileEntity basinTileEntity = (BasinTileEntity) te; } catch (TileEntityException e) {}
return ItemHelper.calcRedstoneFromInventory(basinTileEntity.inputInventory);
}
return 0; return 0;
} }
@Override
public Class<BasinTileEntity> getTileEntityClass() {
return BasinTileEntity.class;
}
} }

View file

@ -2,6 +2,7 @@ package com.simibubi.create.modules.contraptions.processing;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
@ -84,11 +85,11 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
if (isRunning()) if (isRunning())
return false; return false;
TileEntity basinTE = world.getTileEntity(pos.down(2)); Optional<BasinTileEntity> basinTe = getBasin();
if (basinTE == null || !(basinTE instanceof BasinTileEntity)) if (!basinTe.isPresent())
return true; return true;
if (!basinInv.isPresent()) if (!basinInv.isPresent())
basinInv = basinTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); basinInv = basinTe.get().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
if (!basinInv.isPresent()) if (!basinInv.isPresent())
return true; return true;
@ -160,9 +161,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
sendData(); sendData();
} }
TileEntity basinTE = world.getTileEntity(pos.down(2)); getBasin().ifPresent(te -> te.contentsChanged = true);
if (basinTE instanceof BasinTileEntity)
((BasinTileEntity) basinTE).contentsChanged = false;
} }
protected List<IRecipe<?>> getMatchingRecipes() { protected List<IRecipe<?>> getMatchingRecipes() {
@ -176,6 +175,13 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
} }
protected Optional<BasinTileEntity> getBasin() {
TileEntity basinTE = world.getTileEntity(pos.down(2));
if (!(basinTE instanceof BasinTileEntity))
return Optional.empty();
return Optional.of((BasinTileEntity) basinTE);
}
protected abstract <C extends IInventory> boolean matchStaticFilters(IRecipe<C> recipe); protected abstract <C extends IInventory> boolean matchStaticFilters(IRecipe<C> recipe);
protected abstract <C extends IInventory> boolean matchBasinRecipe(IRecipe<C> recipe); protected abstract <C extends IInventory> boolean matchBasinRecipe(IRecipe<C> recipe);

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.processing; package com.simibubi.create.modules.contraptions.processing;
import java.util.Optional;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.block.SyncedTileEntity; import com.simibubi.create.foundation.block.SyncedTileEntity;
@ -111,11 +113,7 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
} }
public void onEmptied() { public void onEmptied() {
TileEntity te = world.getTileEntity(pos.up(2)); getOperator().ifPresent(te -> te.basinRemoved = true);
if (te == null)
return;
if (te instanceof BasinOperatingTileEntity)
((BasinOperatingTileEntity) te).basinRemoved = true;
} }
@Override @Override
@ -137,13 +135,14 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
if (!contentsChanged) if (!contentsChanged)
return; return;
contentsChanged = false; contentsChanged = false;
getOperator().ifPresent(te -> te.basinChecker.scheduleUpdate());
}
private Optional<BasinOperatingTileEntity> getOperator() {
TileEntity te = world.getTileEntity(pos.up(2)); TileEntity te = world.getTileEntity(pos.up(2));
if (te == null)
return;
if (te instanceof BasinOperatingTileEntity) if (te instanceof BasinOperatingTileEntity)
((BasinOperatingTileEntity) te).basinChecker.scheduleUpdate(); return Optional.of((BasinOperatingTileEntity) te);
return Optional.empty();
} }
} }

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.contraptions.redstone;
import java.util.Random; import java.util.Random;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -27,7 +27,7 @@ import net.minecraft.world.World;
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 AnalogLeverBlock extends HorizontalFaceBlock implements IWithTileEntity<AnalogLeverTileEntity> { public class AnalogLeverBlock extends HorizontalFaceBlock implements ITE<AnalogLeverTileEntity> {
public AnalogLeverBlock() { public AnalogLeverBlock() {
super(Properties.from(Blocks.LEVER)); super(Properties.from(Blocks.LEVER));
@ -51,23 +51,24 @@ public class AnalogLeverBlock extends HorizontalFaceBlock implements IWithTileEn
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
boolean sneak = player.isSneaking(); try {
AnalogLeverTileEntity te = getTileEntity(worldIn, pos); boolean sneak = player.isSneaking();
if (te == null) AnalogLeverTileEntity te = getTileEntity(worldIn, pos);
return ActionResultType.SUCCESS; te.changeState(sneak);
float f = .25f + ((te.state + 5) / 15f) * .5f;
worldIn.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.2F, f);
} catch (TileEntityException e) {}
te.changeState(sneak);
float f = .25f + ((te.state + 5) / 15f) * .5f;
worldIn.playSound(null, pos, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.2F, f);
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
@Override @Override
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) {
AnalogLeverTileEntity tileEntity = getTileEntity(blockAccess, pos); try {
if (tileEntity == null) return getTileEntity(blockAccess, pos).state;
} catch (TileEntityException e) {
return 0; return 0;
return tileEntity.state; }
} }
@Override @Override
@ -83,21 +84,23 @@ public class AnalogLeverBlock extends HorizontalFaceBlock implements IWithTileEn
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) { public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) {
AnalogLeverTileEntity tileEntity = getTileEntity(worldIn, pos); try {
if (tileEntity == null) AnalogLeverTileEntity tileEntity = getTileEntity(worldIn, pos);
return; if (tileEntity.state != 0 && rand.nextFloat() < 0.25F)
if (tileEntity.state != 0 && rand.nextFloat() < 0.25F) addParticles(stateIn, worldIn, pos, 0.5F);
addParticles(stateIn, worldIn, pos, 0.5F); } catch (TileEntityException e) {}
} }
@Override @Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
AnalogLeverTileEntity tileEntity = getTileEntity(worldIn, pos); try {
if (tileEntity != null && !isMoving && state.getBlock() != newState.getBlock()) { AnalogLeverTileEntity tileEntity = getTileEntity(worldIn, pos);
if (tileEntity.state != 0) if (!isMoving && state.getBlock() != newState.getBlock()) {
updateNeighbors(state, worldIn, pos); if (tileEntity.state != 0)
worldIn.removeTileEntity(pos); updateNeighbors(state, worldIn, pos);
} worldIn.removeTileEntity(pos);
}
} catch (TileEntityException e) {}
} }
private static void addParticles(BlockState state, IWorld worldIn, BlockPos pos, float alpha) { private static void addParticles(BlockState state, IWorld worldIn, BlockPos pos, float alpha) {
@ -128,4 +131,9 @@ public class AnalogLeverBlock extends HorizontalFaceBlock implements IWithTileEn
super.fillStateContainer(builder.add(HORIZONTAL_FACING, FACE)); super.fillStateContainer(builder.add(HORIZONTAL_FACING, FACE));
} }
@Override
public Class<AnalogLeverTileEntity> getTileEntityClass() {
return AnalogLeverTileEntity.class;
}
} }

View file

@ -1,16 +1,16 @@
package com.simibubi.create.modules.contraptions.relays.advanced.sequencer; package com.simibubi.create.modules.contraptions.relays.advanced.sequencer;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalAxisKineticBlock;
import com.simibubi.create.modules.contraptions.base.KineticBlock; import com.simibubi.create.modules.contraptions.base.KineticBlock;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.modules.contraptions.base.RotatedPillarKineticBlock;
import net.minecraft.block.Block; 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.client.entity.player.ClientPlayerEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.BlockItemUseContext;
@ -33,8 +33,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implements ITE<SequencedGearshiftTileEntity> {
implements IWithTileEntity<SequencedGearshiftTileEntity> {
public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical"); public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical");
public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5); public static final IntegerProperty STATE = IntegerProperty.create("state", 0, 5);
@ -88,9 +87,8 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock
return ActionResultType.PASS; return ActionResultType.PASS;
} }
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> { if (player instanceof ClientPlayerEntity)
displayScreen((SequencedGearshiftTileEntity) worldIn.getTileEntity(pos)); DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> withTileEntityDo(worldIn, pos, this::displayScreen));
});
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
@ -109,12 +107,13 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock
@Override @Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) { public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Direction facing = context.getFace(); BlockState newState = state;
if (facing.getAxis().isVertical() && !state.get(VERTICAL)) {
KineticTileEntity.switchToBlockState(context.getWorld(), context.getPos(), state.cycle(VERTICAL)); if (context.getFace().getAxis() != Axis.Y)
return ActionResultType.SUCCESS; if (newState.get(HORIZONTAL_AXIS) != context.getFace().getAxis())
} newState = newState.cycle(VERTICAL);
return super.onWrenched(state, context);
return super.onWrenched(newState, context);
} }
private BlockState withAxis(Axis axis, BlockItemUseContext context) { private BlockState withAxis(Axis axis, BlockItemUseContext context) {
@ -136,4 +135,9 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock
return true; return true;
} }
@Override
public Class<SequencedGearshiftTileEntity> getTileEntityClass() {
return SequencedGearshiftTileEntity.class;
}
} }

View file

@ -6,6 +6,7 @@ import java.util.function.Consumer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.modules.contraptions.relays.belt.transport.TransportedItemStack;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -13,7 +14,6 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT; import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -59,12 +59,13 @@ public enum AllBeltAttachments {
default void onAttachmentPlaced(IWorld world, BlockPos pos, BlockState state) { default void onAttachmentPlaced(IWorld world, BlockPos pos, BlockState state) {
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state); BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
TileEntity te = world.getTileEntity(beltPos); BeltTileEntity belt = BeltHelper.getSegmentTE(world, beltPos);
if (te == null || !(te instanceof BeltTileEntity))
if (belt == null)
return; return;
BeltTileEntity belt = (BeltTileEntity) te; if (!isAttachedCorrectly(world, pos, beltPos, state, world.getBlockState(beltPos)))
if (!isAttachedCorrectly(world, pos, belt.getPos(), state, belt.getBlockState()))
return; return;
belt.attachmentTracker.addAttachment(world, pos); belt.attachmentTracker.addAttachment(world, pos);
belt.markDirty(); belt.markDirty();
belt.sendData(); belt.sendData();
@ -72,16 +73,18 @@ public enum AllBeltAttachments {
default void onAttachmentRemoved(IWorld world, BlockPos pos, BlockState state) { default void onAttachmentRemoved(IWorld world, BlockPos pos, BlockState state) {
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state); BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
TileEntity te = world.getTileEntity(beltPos); BeltTileEntity belt = BeltHelper.getSegmentTE(world, beltPos);
if (te == null || !(te instanceof BeltTileEntity))
if (belt == null)
return; return;
BeltTileEntity belt = (BeltTileEntity) te; if (!isAttachedCorrectly(world, pos, beltPos, state, world.getBlockState(beltPos)))
if (!isAttachedCorrectly(world, pos, belt.getPos(), state, belt.getBlockState()))
return; return;
belt.attachmentTracker.removeAttachment(pos); belt.attachmentTracker.removeAttachment(pos);
belt.markDirty(); belt.markDirty();
belt.sendData(); belt.sendData();
} }
} }
public static class BeltAttachmentState { public static class BeltAttachmentState {
@ -112,8 +115,8 @@ public enum AllBeltAttachments {
World world = belt.getWorld(); World world = belt.getWorld();
BlockPos beltPos = belt.getPos(); BlockPos beltPos = belt.getPos();
BlockState beltState = belt.getBlockState(); BlockState beltState = belt.getBlockState();
List<BlockPos> attachmentPositions = ba.attachment.getPotentialAttachmentPositions(world, beltPos, List<BlockPos> attachmentPositions =
beltState); ba.attachment.getPotentialAttachmentPositions(world, beltPos, beltState);
for (BlockPos potentialPos : attachmentPositions) { for (BlockPos potentialPos : attachmentPositions) {
if (!world.isBlockPresent(potentialPos)) if (!world.isBlockPresent(potentialPos))

View file

@ -10,11 +10,12 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.block.IHaveColorHandler; import com.simibubi.create.foundation.block.IHaveColorHandler;
import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo; import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType; import net.minecraft.block.BlockRenderType;
@ -61,7 +62,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
public class BeltBlock extends HorizontalKineticBlock public class BeltBlock extends HorizontalKineticBlock
implements IHaveNoBlockItem, IWithTileEntity<BeltTileEntity>, IHaveColorHandler { implements IHaveNoBlockItem, ITE<BeltTileEntity>, IHaveColorHandler {
public static final IProperty<Slope> SLOPE = EnumProperty.create("slope", Slope.class); public static final IProperty<Slope> SLOPE = EnumProperty.create("slope", Slope.class);
public static final IProperty<Part> PART = EnumProperty.create("part", Part.class); public static final IProperty<Part> PART = EnumProperty.create("part", Part.class);
@ -76,8 +77,10 @@ public class BeltBlock extends HorizontalKineticBlock
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
if (face.getAxis() != getRotationAxis(state)) if (face.getAxis() != getRotationAxis(state))
return false; return false;
BeltTileEntity beltEntity = (BeltTileEntity) world.getTileEntity(pos); try {
return beltEntity != null && beltEntity.hasPulley(); return getTileEntity(world, pos).hasPulley();
} catch (TileEntityException e) {}
return false;
} }
@Override @Override
@ -110,15 +113,9 @@ public class BeltBlock extends HorizontalKineticBlock
@Override @Override
public void spawnAdditionalDrops(BlockState state, World worldIn, BlockPos pos, ItemStack stack) { public void spawnAdditionalDrops(BlockState state, World worldIn, BlockPos pos, ItemStack stack) {
withTileEntityDo(worldIn, pos, te -> { BeltTileEntity controllerTE = BeltHelper.getControllerTE(worldIn, pos);
if (worldIn.isRemote) if (controllerTE != null)
return; controllerTE.getInventory().ejectAll();
if (te.isController()) {
BeltInventory inv = te.getInventory();
for (TransportedItemStack s : inv.items)
inv.eject(s);
}
});
} }
@Override @Override
@ -146,9 +143,6 @@ public class BeltBlock extends HorizontalKineticBlock
@Override @Override
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
BeltTileEntity belt = null;
belt = (BeltTileEntity) worldIn.getTileEntity(pos);
if (state.get(SLOPE) == Slope.VERTICAL) if (state.get(SLOPE) == Slope.VERTICAL)
return; return;
if (entityIn instanceof PlayerEntity) { if (entityIn instanceof PlayerEntity) {
@ -158,6 +152,8 @@ public class BeltBlock extends HorizontalKineticBlock
if (player.abilities.isFlying) if (player.abilities.isFlying)
return; return;
} }
BeltTileEntity belt = BeltHelper.getSegmentTE(worldIn, pos);
if (belt == null || belt.getSpeed() == 0) if (belt == null || belt.getSpeed() == 0)
return; return;
if (entityIn instanceof ItemEntity && entityIn.isAlive()) { if (entityIn instanceof ItemEntity && entityIn.isAlive()) {
@ -177,12 +173,12 @@ public class BeltBlock extends HorizontalKineticBlock
return; return;
} }
BeltTileEntity controller = (BeltTileEntity) worldIn.getTileEntity(belt.getController()); BeltTileEntity controller = BeltHelper.getControllerTE(worldIn, pos);
if (controller == null || controller.passengers == null) if (controller == null || controller.passengers == null)
return; return;
if (controller.passengers.containsKey(entityIn)) { if (controller.passengers.containsKey(entityIn)) {
TransportedEntityInfo info = controller.passengers.get(entityIn); TransportedEntityInfo info = controller.passengers.get(entityIn);
if (info.ticksSinceLastCollision != 0 || pos.equals(entityIn.getPosition())) if (info.getTicksSinceLastCollision() != 0 || pos.equals(entityIn.getPosition()))
info.refresh(pos, state); info.refresh(pos, state);
} else { } else {
controller.passengers.put(entityIn, new TransportedEntityInfo(pos, state)); controller.passengers.put(entityIn, new TransportedEntityInfo(pos, state));
@ -223,10 +219,9 @@ public class BeltBlock extends HorizontalKineticBlock
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
} }
TileEntity te = worldIn.getTileEntity(pos); BeltTileEntity belt = BeltHelper.getSegmentTE(worldIn, pos);
if (te == null || !(te instanceof BeltTileEntity)) if (belt == null)
return ActionResultType.PASS; return ActionResultType.PASS;
BeltTileEntity belt = (BeltTileEntity) te;
if (isHand) { if (isHand) {
BeltTileEntity controllerBelt = belt.getControllerTE(); BeltTileEntity controllerBelt = belt.getControllerTE();
@ -269,10 +264,6 @@ public class BeltBlock extends HorizontalKineticBlock
@Override @Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) { public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
World world = context.getWorld(); World world = context.getWorld();
TileEntity te = world.getTileEntity(context.getPos());
if (te == null || !(te instanceof BeltTileEntity))
return ActionResultType.PASS;
BeltTileEntity belt = (BeltTileEntity) te;
PlayerEntity player = context.getPlayer(); PlayerEntity player = context.getPlayer();
if (state.get(CASING)) { if (state.get(CASING)) {
@ -288,8 +279,11 @@ public class BeltBlock extends HorizontalKineticBlock
if (world.isRemote) if (world.isRemote)
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
world.setBlockState(context.getPos(), state.with(PART, Part.MIDDLE), 2); world.setBlockState(context.getPos(), state.with(PART, Part.MIDDLE), 2);
belt.detachKinetics(); BeltTileEntity belt = BeltHelper.getSegmentTE(world, context.getPos());
belt.attachKinetics(); if (belt != null) {
belt.detachKinetics();
belt.attachKinetics();
}
if (!player.isCreative()) if (!player.isCreative())
player.inventory.placeItemBackInInventory(world, new ItemStack(AllBlocks.SHAFT.get())); player.inventory.placeItemBackInInventory(world, new ItemStack(AllBlocks.SHAFT.get()));
return ActionResultType.SUCCESS; return ActionResultType.SUCCESS;
@ -364,16 +358,20 @@ public class BeltBlock extends HorizontalKineticBlock
public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos,
ISelectionContext context) { ISelectionContext context) {
VoxelShape shape = getShape(state, worldIn, pos, context); VoxelShape shape = getShape(state, worldIn, pos, context);
BeltTileEntity belt = (BeltTileEntity) worldIn.getTileEntity(pos); try {
if (belt == null || context.getEntity() == null) if (context.getEntity() == null)
return shape; return shape;
BeltTileEntity controller = (BeltTileEntity) worldIn.getTileEntity(belt.getController());
if (controller == null)
return shape;
if (controller.passengers == null || !controller.passengers.containsKey(context.getEntity())) {
return BeltShapes.getCollisionShape(state);
}
BeltTileEntity belt = getTileEntity(worldIn, pos);
BeltTileEntity controller = belt.getControllerTE();
if (controller == null)
return shape;
if (controller.passengers == null || !controller.passengers.containsKey(context.getEntity())) {
return BeltShapes.getCollisionShape(state);
}
} catch (TileEntityException e) {}
return shape; return shape;
} }
@ -444,12 +442,8 @@ public class BeltBlock extends HorizontalKineticBlock
world.setBlockState(beltPos, currentState.with(CASING, false), 2); world.setBlockState(beltPos, currentState.with(CASING, false), 2);
} }
if (te.isController() && isVertical) { if (te.isController() && isVertical)
BeltInventory inventory = te.getInventory(); te.getInventory().ejectAll();
for (TransportedItemStack s : inventory.items)
inventory.eject(s);
inventory.items.clear();
}
} else { } else {
world.destroyBlock(pos, true); world.destroyBlock(pos, true);
return; return;
@ -489,11 +483,8 @@ public class BeltBlock extends HorizontalKineticBlock
TileEntity tileEntity = world.getTileEntity(currentPos); TileEntity tileEntity = world.getTileEntity(currentPos);
if (tileEntity instanceof BeltTileEntity) { if (tileEntity instanceof BeltTileEntity) {
BeltTileEntity te = (BeltTileEntity) tileEntity; BeltTileEntity te = (BeltTileEntity) tileEntity;
if (te.isController()) { if (te.isController())
BeltInventory inv = te.getInventory(); te.getInventory().ejectAll();
for (TransportedItemStack stack : inv.items)
inv.eject(stack);
}
te.remove(); te.remove();
hasPulley = te.hasPulley(); hasPulley = te.hasPulley();
@ -607,4 +598,9 @@ public class BeltBlock extends HorizontalKineticBlock
return new BeltColor(); return new BeltColor();
} }
@Override
public Class<BeltTileEntity> getTileEntityClass() {
return BeltTileEntity.class;
}
} }

View file

@ -0,0 +1,70 @@
package com.simibubi.create.modules.contraptions.relays.belt;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.IWorld;
public class BeltHelper {
public static BeltTileEntity getSegmentTE(IWorld world, BlockPos pos) {
if (!world.isAreaLoaded(pos, 0))
return null;
TileEntity tileEntity = world.getTileEntity(pos);
if (!(tileEntity instanceof BeltTileEntity))
return null;
return (BeltTileEntity) tileEntity;
}
public static BeltTileEntity getControllerTE(IWorld world, BlockPos pos) {
BeltTileEntity segment = getSegmentTE(world, pos);
if (segment == null)
return null;
BlockPos controllerPos = segment.controller;
if (controllerPos == null)
return null;
return getSegmentTE(world, controllerPos);
}
public static BeltTileEntity getBeltAtSegment(BeltTileEntity controller, int segment) {
BlockPos pos = getPositionForOffset(controller, segment);
TileEntity te = controller.getWorld().getTileEntity(pos);
if (te == null || !(te instanceof BeltTileEntity))
return null;
return (BeltTileEntity) te;
}
public static BlockPos getPositionForOffset(BeltTileEntity controller, int offset) {
BlockPos pos = controller.getPos();
Vec3i vec = controller.getBeltFacing().getDirectionVec();
Slope slope = controller.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
return pos.add(offset * vec.getX(), MathHelper.clamp(offset, 0, controller.beltLength - 1) * verticality,
offset * vec.getZ());
}
public static Vec3d getVectorForOffset(BeltTileEntity controller, float offset) {
Slope slope = controller.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
float verticalMovement = verticality;
if (offset < .5)
verticalMovement = 0;
verticalMovement = verticalMovement * (Math.min(offset, controller.beltLength - .5f) - .5f);
Vec3d vec = VecHelper.getCenterOf(controller.getPos());
Vec3d horizontalMovement = new Vec3d(controller.getBeltFacing().getDirectionVec()).scale(offset - .5f);
if (slope == Slope.VERTICAL)
horizontalMovement = Vec3d.ZERO;
vec = vec.add(horizontalMovement).add(0, verticalMovement, 0);
return vec;
}
}

View file

@ -20,7 +20,10 @@ import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.Tracker; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.Tracker;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.BeltMovementHandler.TransportedEntityInfo; import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltInventory;
import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltMovementHandler;
import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
import com.simibubi.create.modules.contraptions.relays.belt.transport.TransportedItemStack;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -53,7 +56,7 @@ public class BeltTileEntity extends KineticTileEntity {
protected BeltInventory inventory; protected BeltInventory inventory;
protected LazyOptional<IItemHandler> itemHandler; protected LazyOptional<IItemHandler> itemHandler;
private CompoundNBT trackerUpdateTag; public CompoundNBT trackerUpdateTag;
public BeltTileEntity() { public BeltTileEntity() {
super(AllTileEntities.BELT.type); super(AllTileEntities.BELT.type);
@ -99,7 +102,7 @@ public class BeltTileEntity extends KineticTileEntity {
passengers.forEach((entity, info) -> { passengers.forEach((entity, info) -> {
boolean canBeTransported = BeltMovementHandler.canBeTransported(entity); boolean canBeTransported = BeltMovementHandler.canBeTransported(entity);
boolean leftTheBelt = boolean leftTheBelt =
info.ticksSinceLastCollision > ((getBlockState().get(BeltBlock.SLOPE) != HORIZONTAL) ? 3 : 1); info.getTicksSinceLastCollision() > ((getBlockState().get(BeltBlock.SLOPE) != HORIZONTAL) ? 3 : 1);
if (!canBeTransported || leftTheBelt) { if (!canBeTransported || leftTheBelt) {
toRemove.add(entity); toRemove.add(entity);
return; return;
@ -112,10 +115,10 @@ public class BeltTileEntity extends KineticTileEntity {
} }
@Override @Override
public float getStressApplied() { public float calculateStressApplied() {
if (!isController()) if (!isController())
return 0; return 0;
return super.getStressApplied(); return super.calculateStressApplied();
} }
@Override @Override
@ -193,7 +196,7 @@ public class BeltTileEntity extends KineticTileEntity {
public void applyColor(DyeColor colorIn) { public void applyColor(DyeColor colorIn) {
int colorValue = colorIn.getMapColor().colorValue; int colorValue = colorIn.getMapColor().colorValue;
for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) { for (BlockPos blockPos : BeltBlock.getBeltChain(world, getController())) {
BeltTileEntity belt = (BeltTileEntity) world.getTileEntity(blockPos); BeltTileEntity belt = BeltHelper.getSegmentTE(world, blockPos);
if (belt == null) if (belt == null)
continue; continue;
belt.color = belt.color == -1 ? colorValue : ColorHelper.mixColors(belt.color, colorValue, .5f); belt.color = belt.color == -1 ? colorValue : ColorHelper.mixColors(belt.color, colorValue, .5f);

View file

@ -19,6 +19,7 @@ import com.simibubi.create.foundation.utility.TessellatorHelper;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.transport.TransportedItemStack;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -72,10 +73,9 @@ public class BeltTileEntityRenderer extends SafeTileEntityRenderer<BeltTileEntit
if (textureIndex < 0) if (textureIndex < 0)
textureIndex += 16; textureIndex += 16;
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), beltBuffer.shiftUVtoSheet(animatedTexture, (textureIndex % 4) / 4f, (textureIndex / 4) / 4f, 4);
(textureIndex % 4) * 16, (textureIndex / 4) * 16);
} else { } else {
beltBuffer.shiftUVtoSheet(animatedTexture.getOriginal(), animatedTexture.getTarget(), 0, 0); beltBuffer.dontShiftUV();
} }
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid()); IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
@ -115,7 +115,7 @@ public class BeltTileEntityRenderer extends SafeTileEntityRenderer<BeltTileEntit
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0; int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X; boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
for (TransportedItemStack transported : te.getInventory().items) { for (TransportedItemStack transported : te.getInventory().getItems()) {
ms.push(); ms.push();
TessellatorHelper.fightZFighting(transported.angle, ms); TessellatorHelper.fightZFighting(transported.angle, ms);
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition); float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.item;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -23,7 +23,7 @@ import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BeltConnectorItemHandler { public class BeltConnectorHandler {
private static Random r = new Random(); private static Random r = new Random();

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.item;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -7,6 +7,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs; import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.item.IAddedByOther; import com.simibubi.create.foundation.item.IAddedByOther;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock;
@ -17,6 +18,7 @@ import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
@ -184,8 +186,16 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
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)).getTheoreticalSpeed(); TileEntity tileEntity = world.getTileEntity(first);
float speed2 = ((KineticTileEntity) world.getTileEntity(second)).getTheoreticalSpeed(); TileEntity tileEntity2 = world.getTileEntity(second);
if (!(tileEntity instanceof KineticTileEntity))
return false;
if (!(tileEntity2 instanceof KineticTileEntity))
return false;
float speed1 = ((KineticTileEntity) tileEntity).getTheoreticalSpeed();
float speed2 = ((KineticTileEntity) tileEntity2).getTheoreticalSpeed();
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;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.transport;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -9,9 +9,13 @@ import java.util.function.Function;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -23,9 +27,7 @@ import net.minecraft.tileentity.TileEntity;
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.BlockPos; import net.minecraft.util.math.BlockPos;
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.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
@ -36,7 +38,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
public class BeltInventory { public class BeltInventory {
final BeltTileEntity belt; final BeltTileEntity belt;
final List<TransportedItemStack> items; private final List<TransportedItemStack> items;
final List<TransportedItemStack> toInsert; final List<TransportedItemStack> toInsert;
boolean beltMovementPositive; boolean beltMovementPositive;
final float SEGMENT_WINDOW = .75f; final float SEGMENT_WINDOW = .75f;
@ -52,7 +54,7 @@ public class BeltInventory {
// Reverse item collection if belt just reversed // Reverse item collection if belt just reversed
if (beltMovementPositive != movingPositive()) { if (beltMovementPositive != movingPositive()) {
beltMovementPositive = movingPositive(); beltMovementPositive = movingPositive();
Collections.reverse(items); Collections.reverse(getItems());
belt.markDirty(); belt.markDirty();
belt.sendData(); belt.sendData();
} }
@ -68,7 +70,7 @@ public class BeltInventory {
// Assuming the first entry is furthest on the belt // Assuming the first entry is furthest on the belt
TransportedItemStack stackInFront = null; TransportedItemStack stackInFront = null;
TransportedItemStack current = null; TransportedItemStack current = null;
Iterator<TransportedItemStack> iterator = items.iterator(); Iterator<TransportedItemStack> iterator = getItems().iterator();
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed(); float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
Direction movementFacing = belt.getMovementFacing(); Direction movementFacing = belt.getMovementFacing();
@ -121,9 +123,13 @@ public class BeltInventory {
if (!onClient) { if (!onClient) {
// Don't move if belt attachments want to continue processing // Don't move if belt attachments want to continue processing
if (segmentBefore != -1 && current.locked) { if (segmentBefore != -1 && current.locked) {
BeltTileEntity beltSegment = getBeltSegment(segmentBefore); BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
if (beltSegment != null) { if (beltSegment != null) {
// wait in case belt isnt initialized yet
if (current.locked && beltSegment.trackerUpdateTag != null)
continue;
current.locked = false; current.locked = false;
List<BeltAttachmentState> attachments = beltSegment.attachmentTracker.attachments; List<BeltAttachmentState> attachments = beltSegment.attachmentTracker.attachments;
for (BeltAttachmentState attachmentState : attachments) { for (BeltAttachmentState attachmentState : attachments) {
@ -143,7 +149,7 @@ public class BeltInventory {
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f)); int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
for (int segment = upcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset for (int segment = upcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) { : segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
BeltTileEntity beltSegment = getBeltSegment(segmentBefore); BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
if (beltSegment == null) if (beltSegment == null)
break; break;
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) { for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
@ -196,7 +202,7 @@ public class BeltInventory {
if (segment == -1) if (segment == -1)
continue; continue;
if (!world.isRemote) if (!world.isRemote)
world.updateComparatorOutputLevel(getPositionForOffset(segment), world.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment),
belt.getBlockState().getBlock()); belt.getBlockState().getBlock());
} }
} }
@ -207,7 +213,8 @@ public class BeltInventory {
continue; continue;
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0; int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
BlockPos nextPosition = getPositionForOffset(beltMovementPositive ? belt.beltLength : -1); BlockPos nextPosition =
BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
BlockState state = world.getBlockState(nextPosition); BlockState state = world.getBlockState(nextPosition);
// next block is a basin or a saw // next block is a basin or a saw
@ -238,7 +245,7 @@ public class BeltInventory {
} }
// next block is not a belt // next block is not a belt
if (!AllBlocks.BELT.typeOf(state)) { if (!AllBlocks.BELT.typeOf(state) || state.get(BeltBlock.SLOPE) == Slope.VERTICAL) {
if (!Block.hasSolidSide(state, world, nextPosition, movementFacing.getOpposite())) { if (!Block.hasSolidSide(state, world, nextPosition, movementFacing.getOpposite())) {
eject(current); eject(current);
iterator.remove(); iterator.remove();
@ -275,7 +282,7 @@ public class BeltInventory {
} }
private boolean stuckAtTunnel(int offset, ItemStack stack, Direction movementDirection) { private boolean stuckAtTunnel(int offset, ItemStack stack, Direction movementDirection) {
BlockPos pos = getPositionForOffset(offset).up(); BlockPos pos = BeltHelper.getPositionForOffset(belt, offset).up();
if (!AllBlocks.BELT_TUNNEL.typeOf(belt.getWorld().getBlockState(pos))) if (!AllBlocks.BELT_TUNNEL.typeOf(belt.getWorld().getBlockState(pos)))
return false; return false;
TileEntity te = belt.getWorld().getTileEntity(pos); TileEntity te = belt.getWorld().getTileEntity(pos);
@ -313,7 +320,7 @@ public class BeltInventory {
private void flapTunnel(int offset, Direction side, boolean inward) { private void flapTunnel(int offset, Direction side, boolean inward) {
if (belt.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL) if (belt.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
return; return;
BlockPos pos = getPositionForOffset(offset).up(); BlockPos pos = BeltHelper.getPositionForOffset(belt, offset).up();
if (!AllBlocks.BELT_TUNNEL.typeOf(belt.getWorld().getBlockState(pos))) if (!AllBlocks.BELT_TUNNEL.typeOf(belt.getWorld().getBlockState(pos)))
return; return;
TileEntity te = belt.getWorld().getTileEntity(pos); TileEntity te = belt.getWorld().getTileEntity(pos);
@ -335,7 +342,7 @@ public class BeltInventory {
else if (!beltMovementPositive) else if (!beltMovementPositive)
segmentPos += 1f; segmentPos += 1f;
for (TransportedItemStack stack : items) for (TransportedItemStack stack : getItems())
if (isBlocking(segment, side, segmentPos, stack)) if (isBlocking(segment, side, segmentPos, stack))
return false; return false;
for (TransportedItemStack stack : toInsert) for (TransportedItemStack stack : toInsert)
@ -358,25 +365,25 @@ public class BeltInventory {
} }
private void insert(TransportedItemStack newStack) { private void insert(TransportedItemStack newStack) {
if (items.isEmpty()) if (getItems().isEmpty())
items.add(newStack); getItems().add(newStack);
else { else {
int index = 0; int index = 0;
for (TransportedItemStack stack : items) { for (TransportedItemStack stack : getItems()) {
if (stack.compareTo(newStack) > 0 == beltMovementPositive) if (stack.compareTo(newStack) > 0 == beltMovementPositive)
break; break;
index++; index++;
} }
items.add(index, newStack); getItems().add(index, newStack);
} }
} }
public TransportedItemStack getStackAtOffset(int offset) { public TransportedItemStack getStackAtOffset(int offset) {
float min = offset + .5f - (SEGMENT_WINDOW / 2); float min = offset + .5f - (SEGMENT_WINDOW / 2);
float max = offset + .5f + (SEGMENT_WINDOW / 2); float max = offset + .5f + (SEGMENT_WINDOW / 2);
for (TransportedItemStack stack : items) { for (TransportedItemStack stack : getItems()) {
if (stack.beltPosition > max) if (stack.beltPosition > max)
break; continue;
if (stack.beltPosition > min) if (stack.beltPosition > min)
return stack; return stack;
} }
@ -384,16 +391,16 @@ public class BeltInventory {
} }
public void read(CompoundNBT nbt) { public void read(CompoundNBT nbt) {
items.clear(); getItems().clear();
nbt.getList("Items", NBT.TAG_COMPOUND) nbt.getList("Items", NBT.TAG_COMPOUND)
.forEach(inbt -> items.add(TransportedItemStack.read((CompoundNBT) inbt))); .forEach(inbt -> getItems().add(TransportedItemStack.read((CompoundNBT) inbt)));
beltMovementPositive = nbt.getBoolean("PositiveOrder"); beltMovementPositive = nbt.getBoolean("PositiveOrder");
} }
public CompoundNBT write() { public CompoundNBT write() {
CompoundNBT nbt = new CompoundNBT(); CompoundNBT nbt = new CompoundNBT();
ListNBT itemsNBT = new ListNBT(); ListNBT itemsNBT = new ListNBT();
items.forEach(stack -> itemsNBT.add(stack.serializeNBT())); getItems().forEach(stack -> itemsNBT.add(stack.serializeNBT()));
nbt.put("Items", itemsNBT); nbt.put("Items", itemsNBT);
nbt.putBoolean("PositiveOrder", beltMovementPositive); nbt.putBoolean("PositiveOrder", beltMovementPositive);
return nbt; return nbt;
@ -401,7 +408,7 @@ public class BeltInventory {
public void eject(TransportedItemStack stack) { public void eject(TransportedItemStack stack) {
ItemStack ejected = stack.stack; ItemStack ejected = stack.stack;
Vec3d outPos = getVectorForOffset(stack.beltPosition); Vec3d outPos = BeltHelper.getVectorForOffset(belt, stack.beltPosition);
float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f); float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f);
Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed).add(0, 1 / 8f, 0); Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed).add(0, 1 / 8f, 0);
outPos.add(outMotion.normalize()); outPos.add(outMotion.normalize());
@ -412,40 +419,9 @@ public class BeltInventory {
belt.getWorld().addEntity(entity); belt.getWorld().addEntity(entity);
} }
public Vec3d getVectorForOffset(float offset) { public void ejectAll() {
Slope slope = belt.getBlockState().get(BeltBlock.SLOPE); getItems().forEach(this::eject);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0; getItems().clear();
float verticalMovement = verticality;
if (offset < .5)
verticalMovement = 0;
verticalMovement = verticalMovement * (Math.min(offset, belt.beltLength - .5f) - .5f);
Vec3d vec = VecHelper.getCenterOf(belt.getPos());
Vec3d horizontalMovement = new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f);
if (slope == Slope.VERTICAL)
horizontalMovement = Vec3d.ZERO;
vec = vec.add(horizontalMovement).add(0, verticalMovement, 0);
return vec;
}
private BeltTileEntity getBeltSegment(int segment) {
BlockPos pos = getPositionForOffset(segment);
TileEntity te = belt.getWorld().getTileEntity(pos);
if (te == null || !(te instanceof BeltTileEntity))
return null;
return (BeltTileEntity) te;
}
private BlockPos getPositionForOffset(int offset) {
BlockPos pos = belt.getPos();
Vec3i vec = belt.getBeltFacing().getDirectionVec();
Slope slope = belt.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
return pos.add(offset * vec.getX(), MathHelper.clamp(offset, 0, belt.beltLength - 1) * verticality,
offset * vec.getZ());
} }
private boolean movingPositive() { private boolean movingPositive() {
@ -460,7 +436,7 @@ public class BeltInventory {
Function<TransportedItemStack, List<TransportedItemStack>> callback) { Function<TransportedItemStack, List<TransportedItemStack>> callback) {
List<TransportedItemStack> toBeAdded = new ArrayList<>(); List<TransportedItemStack> toBeAdded = new ArrayList<>();
boolean dirty = false; boolean dirty = false;
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) { for (Iterator<TransportedItemStack> iterator = getItems().iterator(); iterator.hasNext();) {
TransportedItemStack transportedItemStack = iterator.next(); TransportedItemStack transportedItemStack = iterator.next();
if (Math.abs(position - transportedItemStack.beltPosition) < distance) { if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
List<TransportedItemStack> apply = callback.apply(transportedItemStack); List<TransportedItemStack> apply = callback.apply(transportedItemStack);
@ -478,4 +454,8 @@ public class BeltInventory {
} }
} }
public List<TransportedItemStack> getItems() {
return items;
}
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.transport;
import static net.minecraft.entity.MoverType.SELF; import static net.minecraft.entity.MoverType.SELF;
import static net.minecraft.util.Direction.AxisDirection.NEGATIVE; import static net.minecraft.util.Direction.AxisDirection.NEGATIVE;
@ -9,8 +9,10 @@ import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -50,6 +52,10 @@ public class BeltMovementHandler {
ticksSinceLastCollision++; ticksSinceLastCollision++;
return this; return this;
} }
public int getTicksSinceLastCollision() {
return ticksSinceLastCollision;
}
} }
public static boolean canBeTransported(Entity entity) { public static boolean canBeTransported(Entity entity) {

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.transport;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt.transport;
import java.util.Random; import java.util.Random;

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.contraptions.relays.encased; package com.simibubi.create.modules.contraptions.relays.encased;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -14,7 +14,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
public class AdjustablePulleyBlock extends EncasedBeltBlock implements IWithTileEntity<AdjustablePulleyTileEntity> { public class AdjustablePulleyBlock extends EncasedBeltBlock implements ITE<AdjustablePulleyTileEntity> {
public static BooleanProperty POWERED = BlockStateProperties.POWERED; public static BooleanProperty POWERED = BlockStateProperties.POWERED;
@ -34,8 +34,9 @@ public class AdjustablePulleyBlock extends EncasedBeltBlock implements IWithTile
@Override @Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
if (oldState.getBlock() != state.getBlock()) if (oldState.getBlock() == state.getBlock())
withTileEntityDo(worldIn, pos, AdjustablePulleyTileEntity::neighborChanged); return;
withTileEntityDo(worldIn, pos, AdjustablePulleyTileEntity::neighborChanged);
} }
@Override @Override
@ -61,4 +62,9 @@ public class AdjustablePulleyBlock extends EncasedBeltBlock implements IWithTile
worldIn.setBlockState(pos, state.cycle(POWERED), 18); worldIn.setBlockState(pos, state.cycle(POWERED), 18);
} }
@Override
public Class<AdjustablePulleyTileEntity> getTileEntityClass() {
return AdjustablePulleyTileEntity.class;
}
} }

View file

@ -16,7 +16,6 @@ import net.minecraft.state.EnumProperty;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
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.ActionResultType;
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.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
@ -120,6 +119,22 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock {
return stateIn.with(PART, part).with(CONNECTED_ALONG_FIRST_COORDINATE, connectionAlongFirst); return stateIn.with(PART, part).with(CONNECTED_ALONG_FIRST_COORDINATE, connectionAlongFirst);
} }
@Override
public BlockState updateAfterWrenched(BlockState newState, ItemUseContext context) {
Blocks.AIR.getDefaultState().updateNeighbors(context.getWorld(), context.getPos(), 1);
Axis axis = newState.get(AXIS);
newState = getDefaultState().with(AXIS, axis);
for (Direction facing : Direction.values()) {
if (facing.getAxis() == axis)
continue;
BlockPos pos = context.getPos();
BlockPos offset = pos.offset(facing);
newState = updatePostPlacement(newState, facing, context.getWorld().getBlockState(offset), context.getWorld(),
pos, offset); }
newState.updateNeighbors(context.getWorld(), context.getPos(), 1 | 2);
return newState;
}
@Override @Override
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) { public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() == state.get(AXIS); return face.getAxis() == state.get(AXIS);
@ -169,19 +184,6 @@ public class EncasedBeltBlock extends RotatedPillarKineticBlock {
return new EncasedShaftTileEntity(); return new EncasedShaftTileEntity();
} }
@Override
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
Axis axis = state.get(AXIS);
boolean connectionAlongFirst = state.get(CONNECTED_ALONG_FIRST_COORDINATE);
Axis connectionAxis = connectionAlongFirst ? (axis == Axis.X ? Axis.Y : Axis.X)
: (axis == Axis.Z ? Axis.Y : Axis.Z);
if (context.getFace().getAxis() == connectionAxis)
return ActionResultType.PASS;
return super.onWrenched(state, context);
}
@Override @Override
protected boolean hasStaticPart() { protected boolean hasStaticPart() {
return true; return true;

View file

@ -1,7 +1,7 @@
package com.simibubi.create.modules.contraptions.relays.encased; package com.simibubi.create.modules.contraptions.relays.encased;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.modules.contraptions.RotationPropagator; import com.simibubi.create.modules.contraptions.RotationPropagator;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEntity; import com.simibubi.create.modules.contraptions.relays.gearbox.GearshiftTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -17,7 +17,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class GearshiftBlock extends EncasedShaftBlock { public class GearshiftBlock extends EncasedShaftBlock implements ITE<GearshiftTileEntity> {
public static final BooleanProperty POWERED = BlockStateProperties.POWERED; public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
@ -51,7 +51,7 @@ 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)) {
RotationPropagator.handleRemoved(worldIn, pos, (KineticTileEntity) worldIn.getTileEntity(pos)); withTileEntityDo(worldIn, pos, te -> RotationPropagator.handleRemoved(worldIn, pos, te));
worldIn.setBlockState(pos, state.cycle(POWERED), 2); worldIn.setBlockState(pos, state.cycle(POWERED), 2);
} }
} }
@ -60,4 +60,9 @@ public class GearshiftBlock extends EncasedShaftBlock {
return super.hasShaftTowards(world, pos, state, face); return super.hasShaftTowards(world, pos, state, face);
} }
@Override
public Class<GearshiftTileEntity> getTileEntityClass() {
return GearshiftTileEntity.class;
}
} }

View file

@ -6,10 +6,11 @@ import java.util.List;
import com.simibubi.create.foundation.block.IHaveCustomBlockModel; import com.simibubi.create.foundation.block.IHaveCustomBlockModel;
import com.simibubi.create.foundation.block.IHaveNoBlockItem; import com.simibubi.create.foundation.block.IHaveNoBlockItem;
import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.block.ITE;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.FourWayBlock; import net.minecraft.block.FourWayBlock;
import net.minecraft.block.PaneBlock; import net.minecraft.block.PaneBlock;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
@ -45,7 +46,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
public class WindowInABlockBlock extends PaneBlock public class WindowInABlockBlock extends PaneBlock
implements IWithTileEntity<WindowInABlockTileEntity>, IHaveNoBlockItem, IHaveCustomBlockModel { implements ITE<WindowInABlockTileEntity>, IHaveNoBlockItem, IHaveCustomBlockModel {
public WindowInABlockBlock() { public WindowInABlockBlock() {
super(Properties.create(Material.ROCK)); super(Properties.create(Material.ROCK));
@ -69,32 +70,32 @@ public class WindowInABlockBlock extends PaneBlock
Vec3d start = player.getEyePosition(1); Vec3d start = player.getEyePosition(1);
Vec3d end = start.add(player.getLookVec().scale(player.getAttribute(PlayerEntity.REACH_DISTANCE).getValue())); Vec3d end = start.add(player.getLookVec().scale(player.getAttribute(PlayerEntity.REACH_DISTANCE).getValue()));
BlockRayTraceResult target = world BlockRayTraceResult target =
.rayTraceBlocks(new RayTraceContext(start, end, BlockMode.OUTLINE, FluidMode.NONE, player)); world.rayTraceBlocks(new RayTraceContext(start, end, BlockMode.OUTLINE, FluidMode.NONE, player));
if (target == null || target.getHitVec() == null) if (target == null || target.getHitVec() == null)
return super.removedByPlayer(state, world, pos, player, willHarvest, fluid); return super.removedByPlayer(state, world, pos, player, willHarvest, fluid);
WindowInABlockTileEntity tileEntity = getTileEntity(world, pos); try {
if (tileEntity == null) WindowInABlockTileEntity tileEntity = getTileEntity(world, pos);
return super.removedByPlayer(state, world, pos, player, willHarvest, fluid); BlockState windowBlock = tileEntity.getWindowBlock();
BlockState windowBlock = tileEntity.getWindowBlock(); for (AxisAlignedBB bb : windowBlock.getShape(world, pos).toBoundingBoxList()) {
for (AxisAlignedBB bb : windowBlock.getShape(world, pos).toBoundingBoxList()) { if (bb.grow(.1d).contains(target.getHitVec().subtract(new Vec3d(pos)))) {
if (bb.grow(.1d).contains(target.getHitVec().subtract(new Vec3d(pos)))) { windowBlock.getBlock().onBlockHarvested(world, pos, windowBlock, player);
windowBlock.getBlock().onBlockHarvested(world, pos, windowBlock, player); Block.spawnDrops(windowBlock, world, pos, null, player, player.getHeldItemMainhand());
Block.spawnDrops(windowBlock, world, pos, null, player, player.getHeldItemMainhand()); BlockState partialBlock = tileEntity.getPartialBlock();
BlockState partialBlock = tileEntity.getPartialBlock();
world.setBlockState(pos, partialBlock);
for (Direction d : Direction.values()) {
BlockPos offset = pos.offset(d);
BlockState otherState = world.getBlockState(offset);
partialBlock = partialBlock.updatePostPlacement(d, otherState, world, pos, offset);
world.notifyBlockUpdate(offset, otherState, otherState, 2);
}
if (partialBlock != world.getBlockState(pos))
world.setBlockState(pos, partialBlock); world.setBlockState(pos, partialBlock);
return false; for (Direction d : Direction.values()) {
BlockPos offset = pos.offset(d);
BlockState otherState = world.getBlockState(offset);
partialBlock = partialBlock.updatePostPlacement(d, otherState, world, pos, offset);
world.notifyBlockUpdate(offset, otherState, otherState, 2);
}
if (partialBlock != world.getBlockState(pos))
world.setBlockState(pos, partialBlock);
return false;
}
} }
} } catch (TileEntityException e) {}
return super.removedByPlayer(state, world, pos, player, willHarvest, fluid); return super.removedByPlayer(state, world, pos, player, willHarvest, fluid);
} }
@ -111,49 +112,36 @@ public class WindowInABlockBlock extends PaneBlock
@Override @Override
public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) { public boolean propagatesSkylightDown(BlockState state, IBlockReader reader, BlockPos pos) {
WindowInABlockTileEntity tileEntity = getTileEntity(reader, pos); return getSurroundingBlockState(reader, pos).propagatesSkylightDown(reader, pos);
if (tileEntity == null)
return super.propagatesSkylightDown(state, reader, pos);
return tileEntity.getPartialBlock().propagatesSkylightDown(reader, pos);
} }
@Override @Override
public boolean collisionExtendsVertically(BlockState state, IBlockReader world, BlockPos pos, public boolean collisionExtendsVertically(BlockState state, IBlockReader world, BlockPos pos,
Entity collidingEntity) { Entity collidingEntity) {
WindowInABlockTileEntity tileEntity = getTileEntity(world, pos); return getSurroundingBlockState(world, pos).collisionExtendsVertically(world, pos, collidingEntity);
if (tileEntity == null)
return false;
return tileEntity.getPartialBlock().collisionExtendsVertically(world, pos, collidingEntity);
} }
@Override @Override
public float getBlockHardness(BlockState blockState, IBlockReader worldIn, BlockPos pos) { public float getBlockHardness(BlockState blockState, IBlockReader worldIn, BlockPos pos) {
WindowInABlockTileEntity tileEntity = getTileEntity(worldIn, pos); return getSurroundingBlockState(worldIn, pos).getBlockHardness(worldIn, pos);
if (tileEntity == null)
return 0;
return tileEntity.getPartialBlock().getBlockHardness(worldIn, pos);
} }
@Override @Override
public float getExplosionResistance(BlockState state, IWorldReader world, BlockPos pos, Entity exploder, public float getExplosionResistance(BlockState state, IWorldReader world, BlockPos pos, Entity exploder,
Explosion explosion) { Explosion explosion) {
WindowInABlockTileEntity tileEntity = getTileEntity(world, pos); return getSurroundingBlockState(world, pos).getExplosionResistance(world, pos, exploder, explosion);
if (tileEntity == null)
return 0;
return tileEntity.getPartialBlock().getExplosionResistance(world, pos, exploder, explosion);
} }
@Override @Override
public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos,
PlayerEntity player) { PlayerEntity player) {
WindowInABlockTileEntity tileEntity = getTileEntity(world, pos); BlockState window = getWindowBlockState(world, pos);
if (tileEntity == null) for (AxisAlignedBB bb : window.getShape(world, pos).toBoundingBoxList()) {
return ItemStack.EMPTY;
for (AxisAlignedBB bb : tileEntity.getWindowBlock().getShape(world, pos).toBoundingBoxList()) {
if (bb.grow(.1d).contains(target.getHitVec().subtract(new Vec3d(pos)))) if (bb.grow(.1d).contains(target.getHitVec().subtract(new Vec3d(pos))))
return tileEntity.getWindowBlock().getPickBlock(target, world, pos, player); return window.getPickBlock(target, world, pos, player);
} }
return tileEntity.getPartialBlock().getPickBlock(target, world, pos, player); BlockState surrounding = getSurroundingBlockState(world, pos);
return surrounding.getPickBlock(target, world, pos, player);
} }
@Override @Override
@ -170,11 +158,8 @@ public class WindowInABlockBlock extends PaneBlock
@Override @Override
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
WindowInABlockTileEntity tileEntity = getTileEntity(worldIn, pos); VoxelShape shape1 = getSurroundingBlockState(worldIn, pos).getShape(worldIn, pos, context);
if (tileEntity == null) VoxelShape shape2 = getWindowBlockState(worldIn, pos).getShape(worldIn, pos, context);
return makeCuboidShape(7, 0, 7, 9, 16, 9);
VoxelShape shape1 = tileEntity.getPartialBlock().getShape(worldIn, pos, context);
VoxelShape shape2 = tileEntity.getWindowBlock().getShape(worldIn, pos, context);
return VoxelShapes.or(shape1, shape2); return VoxelShapes.or(shape1, shape2);
} }
@ -187,10 +172,7 @@ public class WindowInABlockBlock extends PaneBlock
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public MaterialColor getMaterialColor(BlockState state, IBlockReader worldIn, BlockPos pos) { public MaterialColor getMaterialColor(BlockState state, IBlockReader worldIn, BlockPos pos) {
WindowInABlockTileEntity tileEntity = getTileEntity(worldIn, pos); return getSurroundingBlockState(worldIn, pos).getMaterialColor(worldIn, pos);
if (tileEntity == null)
return MaterialColor.AIR;
return tileEntity.getPartialBlock().getMaterialColor(worldIn, pos);
} }
@Override @Override
@ -199,8 +181,8 @@ public class WindowInABlockBlock extends PaneBlock
withTileEntityDo(worldIn, currentPos, te -> { withTileEntityDo(worldIn, currentPos, te -> {
te.setWindowBlock( te.setWindowBlock(
te.getWindowBlock().updatePostPlacement(facing, facingState, worldIn, currentPos, facingPos)); te.getWindowBlock().updatePostPlacement(facing, facingState, worldIn, currentPos, facingPos));
BlockState blockState = te.getPartialBlock().updatePostPlacement(facing, facingState, worldIn, currentPos, BlockState blockState =
facingPos); te.getPartialBlock().updatePostPlacement(facing, facingState, worldIn, currentPos, facingPos);
if (blockState.getBlock() instanceof FourWayBlock) { if (blockState.getBlock() instanceof FourWayBlock) {
for (BooleanProperty side : Arrays.asList(FourWayBlock.EAST, FourWayBlock.NORTH, FourWayBlock.SOUTH, for (BooleanProperty side : Arrays.asList(FourWayBlock.EAST, FourWayBlock.NORTH, FourWayBlock.SOUTH,
FourWayBlock.WEST)) FourWayBlock.WEST))
@ -213,6 +195,20 @@ public class WindowInABlockBlock extends PaneBlock
return stateIn; return stateIn;
} }
private BlockState getSurroundingBlockState(IBlockReader reader, BlockPos pos) {
try {
return getTileEntity(reader, pos).getPartialBlock();
} catch (TileEntityException e) {}
return Blocks.AIR.getDefaultState();
}
private BlockState getWindowBlockState(IBlockReader reader, BlockPos pos) {
try {
return getTileEntity(reader, pos).getWindowBlock();
} catch (TileEntityException e) {}
return Blocks.AIR.getDefaultState();
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) { public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
return false; return false;
@ -224,4 +220,9 @@ public class WindowInABlockBlock extends PaneBlock
return new WindowInABlockModel(original); return new WindowInABlockModel(original);
} }
@Override
public Class<WindowInABlockTileEntity> getTileEntityClass() {
return WindowInABlockTileEntity.class;
}
} }

View file

@ -28,6 +28,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
public class WindowInABlockModel extends WrappedBakedModel { public class WindowInABlockModel extends WrappedBakedModel {
@ -50,13 +51,20 @@ public class WindowInABlockModel extends WrappedBakedModel {
RenderType renderLayer = MinecraftForgeClient.getRenderLayer(); RenderType renderLayer = MinecraftForgeClient.getRenderLayer();
if (RenderTypeLookup.canRenderInLayer(partialState, renderLayer) && partialState != null) { if (RenderTypeLookup.canRenderInLayer(partialState, renderLayer) && partialState != null) {
quads.addAll(dispatcher.getModelForState(partialState).getQuads(partialState, side, rand, data)); IBakedModel partialModel = dispatcher.getModelForState(partialState);
IModelData modelData = partialModel.getModelData(Minecraft.getInstance().world, position, partialState,
EmptyModelData.INSTANCE);
quads.addAll(partialModel.getQuads(partialState, side, rand, modelData));
} }
if (RenderTypeLookup.canRenderInLayer(windowState, renderLayer) && windowState != null) { if (RenderTypeLookup.canRenderInLayer(windowState, renderLayer) && windowState != null) {
quads.addAll(dispatcher.getModelForState(windowState).getQuads(windowState, side, rand, data).stream() IBakedModel windowModel = dispatcher.getModelForState(windowState);
IModelData modelData =
windowModel.getModelData(Minecraft.getInstance().world, position, windowState, EmptyModelData.INSTANCE);
quads.addAll(dispatcher.getModelForState(windowState).getQuads(windowState, side, rand, modelData).stream()
.filter(q -> { .filter(q -> {
Direction face = q.getFace(); Direction face = q.getFace();
if (face != null && windowState.isSideInvisible(world.getBlockState(position), face)) if (face != null
&& world.getBlockState(position.offset(face)).isSideInvisible(windowState, face))
return false; return false;
if (face != null && Block.hasSolidSide(partialState, world, position, face)) if (face != null && Block.hasSolidSide(partialState, world, position, face))
return false; return false;

View file

@ -0,0 +1,84 @@
package com.simibubi.create.modules.curiosities.partialWindows;
import java.util.Arrays;
import com.simibubi.create.AllBlockTags;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.config.AllConfigs;
import net.minecraft.block.BlockState;
import net.minecraft.block.FourWayBlock;
import net.minecraft.block.WallBlock;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.state.BooleanProperty;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.Tags;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock;
import net.minecraftforge.eventbus.api.Event.Result;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus;
@EventBusSubscriber(bus = Bus.FORGE)
public class WindowLoggingHandler {
@SubscribeEvent
public static void rightClickPartialBlockWithPaneMakesItWindowLogged(RightClickBlock event) {
if (event.getUseItem() == Result.DENY)
return;
if (event.getEntityLiving().isSneaking())
return;
if (!event.getPlayer().isAllowEdit())
return;
if (!AllConfigs.SERVER.curiosities.allowGlassPanesInPartialBlocks.get())
return;
ItemStack stack = event.getItemStack();
if (stack.isEmpty())
return;
if (!(stack.getItem() instanceof BlockItem))
return;
BlockItem item = (BlockItem) stack.getItem();
if (!item.isIn(Tags.Items.GLASS_PANES)
&& (item.getBlock() == null || !item.getBlock().isIn(Tags.Blocks.GLASS_PANES)))
return;
BlockPos pos = event.getPos();
World world = event.getWorld();
BlockState blockState = world.getBlockState(pos);
if (!AllBlockTags.WINDOWABLE.matches(blockState))
return;
if (AllBlocks.WINDOW_IN_A_BLOCK.typeOf(blockState))
return;
BlockState defaultState = AllBlocks.WINDOW_IN_A_BLOCK.get().getDefaultState();
world.setBlockState(pos, defaultState);
TileEntity te = world.getTileEntity(pos);
if (te != null && te instanceof WindowInABlockTileEntity) {
WindowInABlockTileEntity wte = (WindowInABlockTileEntity) te;
wte.setWindowBlock(item.getBlock().getDefaultState());
wte.updateWindowConnections();
if (blockState.getBlock() instanceof FourWayBlock) {
for (BooleanProperty side : Arrays.asList(FourWayBlock.EAST, FourWayBlock.NORTH, FourWayBlock.SOUTH,
FourWayBlock.WEST))
blockState = blockState.with(side, false);
}
if (blockState.getBlock() instanceof WallBlock)
blockState = blockState.with(WallBlock.UP, true);
wte.setPartialBlock(blockState);
wte.requestModelDataUpdate();
if (!event.getPlayer().isCreative())
stack.shrink(1);
event.getPlayer().swingArm(event.getHand());
}
event.setCanceled(true);
}
}

View file

@ -9,7 +9,6 @@ import com.simibubi.create.modules.curiosities.tools.SandPaperItemRenderer.SandP
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -111,7 +110,7 @@ public class SandPaperItem extends Item implements IHaveCustomItemModel {
@Override @Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) { public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
return enchantment == Enchantments.FORTUNE || super.canApplyAtEnchantingTable(stack, enchantment); return super.canApplyAtEnchantingTable(stack, enchantment);
} }
@Override @Override

View file

@ -1,25 +1,18 @@
package com.simibubi.create.modules.curiosities.tools; package com.simibubi.create.modules.curiosities.tools;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import com.simibubi.create.AllRecipes; import com.simibubi.create.AllRecipes;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient; import com.simibubi.create.modules.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.modules.contraptions.processing.ProcessingOutput; import com.simibubi.create.modules.contraptions.processing.ProcessingOutput;
import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe; import com.simibubi.create.modules.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.modules.curiosities.tools.SandPaperPolishingRecipe.SandPaperInv; import com.simibubi.create.modules.curiosities.tools.SandPaperPolishingRecipe.SandPaperInv;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.DamageSource; import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.Explosion.Mode;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper; import net.minecraftforge.items.wrapper.RecipeWrapper;
@ -34,46 +27,13 @@ public class SandPaperPolishingRecipe extends ProcessingRecipe<SandPaperInv> {
} }
public static boolean canPolish(World world, ItemStack stack) { public static boolean canPolish(World world, ItemStack stack) {
return (stack.isDamageable() && isPolishingEnabled()) || !getMatchingRecipes(world, stack).isEmpty(); return !getMatchingRecipes(world, stack).isEmpty();
}
public static Boolean isPolishingEnabled() {
return AllConfigs.SERVER.curiosities.enableSandPaperToolPolishing.get();
} }
public static ItemStack applyPolish(World world, Vec3d position, ItemStack stack, ItemStack sandPaperStack) { public static ItemStack applyPolish(World world, Vec3d position, ItemStack stack, ItemStack sandPaperStack) {
List<IRecipe<SandPaperInv>> matchingRecipes = getMatchingRecipes(world, stack); List<IRecipe<SandPaperInv>> matchingRecipes = getMatchingRecipes(world, stack);
if (!matchingRecipes.isEmpty()) if (!matchingRecipes.isEmpty())
return matchingRecipes.get(0).getCraftingResult(new SandPaperInv(stack)).copy(); return matchingRecipes.get(0).getCraftingResult(new SandPaperInv(stack)).copy();
if (stack.isDamageable() && isPolishingEnabled()) {
stack.setDamage(stack.getDamage() / 2);
int fortuneLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, sandPaperStack);
float chanceToPunish = (float) (1 / Math.pow(2, fortuneLevel + 1));
if (world.rand.nextFloat() > chanceToPunish)
return stack;
if (stack.isEnchanted()) {
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
ArrayList<Enchantment> list = new ArrayList<>(enchantments.keySet());
Enchantment randomKey = list.get(world.rand.nextInt(list.size()));
int level = enchantments.get(randomKey);
if (level <= 1)
enchantments.remove(randomKey);
else
enchantments.put(randomKey, level - 1);
EnchantmentHelper.setEnchantments(enchantments, stack);
if (randomKey.isCurse())
if (!world.isRemote)
world.createExplosion(null, CURSED_POLISHING, position.x, position.y, position.z, 2, true,
Mode.DESTROY);
} else {
stack = ItemStack.EMPTY;
}
}
return stack; return stack;
} }

Some files were not shown because too many files have changed in this diff Show more