mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-23 21:46:40 +01:00
Cutting Edge
- Fixed Entity Types not registering correctly - Fixed WorldRenderer being loaded server side - Fixed the Tree Cutter search used by the Deforester - Fixed Crushing wheel controller not dropping contents when removed - Mechanical Saw can now process Cutting and Stonecutting Recipes
This commit is contained in:
parent
6f185d4540
commit
c2814f8ad2
25 changed files with 625 additions and 66 deletions
|
@ -20,7 +20,7 @@ archivesBaseName = 'create'
|
|||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8'
|
||||
|
||||
minecraft {
|
||||
mappings channel: 'snapshot', version: '20191021-1.14.3'
|
||||
mappings channel: 'snapshot', version: '20191107-1.14.3'
|
||||
|
||||
runs {
|
||||
client {
|
||||
|
@ -71,7 +71,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.61'
|
||||
minecraft 'net.minecraftforge:forge:1.14.4-28.1.85'
|
||||
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api")
|
||||
|
|
|
@ -56,6 +56,9 @@ public class Create {
|
|||
modEventBus.addGenericListener(IRecipeSerializer.class, Create::registerRecipes);
|
||||
modEventBus.addGenericListener(TileEntityType.class, Create::registerTileEntities);
|
||||
modEventBus.addGenericListener(ContainerType.class, Create::registerContainers);
|
||||
modEventBus.addGenericListener(VillagerProfession.class, Create::registerVillagerProfessions);
|
||||
modEventBus.addGenericListener(PointOfInterestType.class, Create::registerPointsOfInterest);
|
||||
modEventBus.addGenericListener(EntityType.class, Create::registerEntities);
|
||||
modEventBus.addListener(Create::createConfigs);
|
||||
CreateClient.addListeners(modEventBus);
|
||||
|
||||
|
@ -95,12 +98,10 @@ public class Create {
|
|||
AllRecipes.register(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerEntities(final RegistryEvent.Register<EntityType<?>> event) {
|
||||
AllEntities.register(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerVillagerProfessions(RegistryEvent.Register<VillagerProfession> event) {
|
||||
LogisticianHandler.registerVillagerProfessions(event);
|
||||
}
|
||||
|
@ -110,7 +111,6 @@ public class Create {
|
|||
LogisticianHandler.registerPointsOfInterest(event);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void createConfigs(ModConfig.ModConfigEvent event) {
|
||||
if (event.getConfig().getSpec() == CreateConfig.specification)
|
||||
config = event.getConfig();
|
||||
|
|
|
@ -66,8 +66,8 @@ public class TreeCutter {
|
|||
visited.add(currentPos);
|
||||
|
||||
BlockState blockState = reader.getBlockState(currentPos);
|
||||
boolean isLog = !isLog(blockState);
|
||||
boolean isLeaf = !isLeaf(blockState);
|
||||
boolean isLog = isLog(blockState);
|
||||
boolean isLeaf = isLeaf(blockState);
|
||||
|
||||
if (!isLog && !isLeaf)
|
||||
continue;
|
||||
|
@ -108,7 +108,7 @@ public class TreeCutter {
|
|||
|
||||
if (!isLog(reader.getBlockState(currentPos)))
|
||||
continue;
|
||||
if (isLog(reader.getBlockState(currentPos.down())))
|
||||
if (!pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down())))
|
||||
return false;
|
||||
|
||||
for (Direction direction : Direction.values()) {
|
||||
|
@ -127,7 +127,7 @@ public class TreeCutter {
|
|||
|
||||
private static void addNeighbours(BlockPos pos, List<BlockPos> frontier, Set<BlockPos> visited) {
|
||||
BlockPos.getAllInBox(pos.add(-1, -1, -1), pos.add(1, 1, 1)).filter(Predicates.not(visited::contains))
|
||||
.forEach(frontier::add);
|
||||
.forEach(p -> frontier.add(new BlockPos(p)));
|
||||
}
|
||||
|
||||
private static boolean isLog(BlockState state) {
|
||||
|
|
|
@ -37,7 +37,7 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
protected static Map<BlockState, BufferManipulator> cachedBuffers;
|
||||
public static boolean rainbowMode = false;
|
||||
|
||||
protected static class BlockModelSpinner extends BufferManipulator {
|
||||
public static class BlockModelSpinner extends BufferManipulator {
|
||||
|
||||
public BlockModelSpinner(ByteBuffer original) {
|
||||
super(original);
|
||||
|
@ -78,14 +78,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = (float) (((time * te.getSpeed() + offset) % 360) / 180 * (float) Math.PI);
|
||||
float angle = getAngleForTe(te, pos, axis);
|
||||
|
||||
renderFromCache(buffer, state, getWorld(), (float) x, (float) y, (float) z, pos, axis, angle);
|
||||
}
|
||||
|
||||
protected static void renderFromCache(BufferBuilder buffer, BlockState state, World world, float x, float y,
|
||||
public static float getAngleForTe(KineticTileEntity te, final BlockPos pos, Axis axis) {
|
||||
float time = AnimationTickHolder.getRenderTick();
|
||||
float offset = getRotationOffsetForPosition(te, pos, axis);
|
||||
float angle = (float) (((time * te.getSpeed() + offset) % 360) / 180 * (float) Math.PI);
|
||||
return angle;
|
||||
}
|
||||
|
||||
public static void renderFromCache(BufferBuilder buffer, BlockState state, World world, float x, float y,
|
||||
float z, BlockPos pos, Axis axis, float angle) {
|
||||
int packedLightmapCoords = state.getPackedLightmapCoords(world, pos);
|
||||
ByteBuffer transformed = ((BlockModelSpinner) getBuffer(state)).getTransformed(x, y, z, angle, axis,
|
||||
|
@ -126,7 +131,7 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast<KineticTil
|
|||
}
|
||||
}
|
||||
|
||||
protected float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Axis axis) {
|
||||
protected static float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Axis axis) {
|
||||
float offset = AllBlocks.LARGE_COGWHEEL.typeOf(te.getBlockState()) ? 11.25f : 0;
|
||||
double d = (((axis == Axis.X) ? 0 : pos.getX()) + ((axis == Axis.Y) ? 0 : pos.getY())
|
||||
+ ((axis == Axis.Z) ? 0 : pos.getZ())) % 2;
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.block.Block;
|
|||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
|
@ -39,7 +40,7 @@ public class CrushingWheelControllerBlock extends Block implements IWithoutBlock
|
|||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isReplaceable(BlockState state, BlockItemUseContext useContext) {
|
||||
return false;
|
||||
|
@ -150,4 +151,21 @@ public class CrushingWheelControllerBlock extends Block implements IWithoutBlock
|
|||
return VoxelShapes.fullCube();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
if (worldIn.getTileEntity(pos) == null)
|
||||
return;
|
||||
|
||||
CrushingWheelControllerTileEntity te = (CrushingWheelControllerTileEntity) worldIn.getTileEntity(pos);
|
||||
for (int slot = 0; slot < te.inventory.getSizeInventory(); slot++) {
|
||||
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
|
||||
te.inventory.getStackInSlot(slot));
|
||||
}
|
||||
|
||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||
worldIn.removeTileEntity(pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
private UUID entityUUID;
|
||||
protected boolean searchForEntity;
|
||||
|
||||
private ProcessingInventory contents;
|
||||
public ProcessingInventory inventory;
|
||||
public float crushingspeed;
|
||||
|
||||
public CrushingWheelControllerTileEntity() {
|
||||
super(AllTileEntities.CRUSHING_WHEEL_CONTROLLER.type);
|
||||
contents = new ProcessingInventory();
|
||||
inventory = new ProcessingInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,31 +65,31 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
if (!hasEntity()) {
|
||||
|
||||
float processingSpeed = speed / (!contents.appliedRecipe ? contents.getStackInSlot(0).getCount() : 1);
|
||||
contents.processingDuration -= processingSpeed;
|
||||
spawnParticles(contents.getStackInSlot(0));
|
||||
float processingSpeed = speed / (!inventory.appliedRecipe ? inventory.getStackInSlot(0).getCount() : 1);
|
||||
inventory.remainingTime -= processingSpeed;
|
||||
spawnParticles(inventory.getStackInSlot(0));
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (contents.processingDuration < 20 && !contents.appliedRecipe) {
|
||||
if (inventory.remainingTime < 20 && !inventory.appliedRecipe) {
|
||||
applyRecipe();
|
||||
contents.appliedRecipe = true;
|
||||
inventory.appliedRecipe = true;
|
||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3d outPos = new Vec3d(pos).add(.5, -.5, .5);
|
||||
if (contents.processingDuration <= 0) {
|
||||
for (int slot = 0; slot < contents.getSizeInventory(); slot++) {
|
||||
ItemStack stack = contents.getStackInSlot(slot);
|
||||
if (inventory.remainingTime <= 0) {
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
world.addEntity(entityIn);
|
||||
}
|
||||
contents.clear();
|
||||
inventory.clear();
|
||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
|
||||
return;
|
||||
}
|
||||
|
@ -140,12 +140,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
}
|
||||
|
||||
private void applyRecipe() {
|
||||
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, contents,
|
||||
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, inventory,
|
||||
world);
|
||||
|
||||
if (recipe.isPresent()) {
|
||||
int rolls = contents.getStackInSlot(0).getCount();
|
||||
contents.clear();
|
||||
int rolls = inventory.getStackInSlot(0).getCount();
|
||||
inventory.clear();
|
||||
|
||||
for (int roll = 0; roll < rolls; roll++) {
|
||||
List<ItemStack> rolledResults = recipe.get().rollResults();
|
||||
|
@ -153,8 +153,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
for (int i = 0; i < rolledResults.size(); i++) {
|
||||
ItemStack stack = rolledResults.get(i);
|
||||
|
||||
for (int slot = 0; slot < contents.getSizeInventory(); slot++) {
|
||||
stack = contents.getItems().insertItem(slot, stack, false);
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
stack = inventory.getItems().insertItem(slot, stack, false);
|
||||
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
|
@ -163,7 +163,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
}
|
||||
|
||||
} else {
|
||||
contents.clear();
|
||||
inventory.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
public CompoundNBT write(CompoundNBT compound) {
|
||||
if (hasEntity() && !isFrozen())
|
||||
compound.put("Entity", NBTUtil.writeUniqueId(entityUUID));
|
||||
contents.write(compound);
|
||||
inventory.write(compound);
|
||||
compound.putFloat("Speed", crushingspeed);
|
||||
|
||||
return super.write(compound);
|
||||
|
@ -187,7 +187,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
this.searchForEntity = true;
|
||||
}
|
||||
crushingspeed = compound.getFloat("Speed");
|
||||
contents = ProcessingInventory.read(compound);
|
||||
inventory = ProcessingInventory.read(compound);
|
||||
|
||||
}
|
||||
|
||||
|
@ -197,13 +197,13 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
}
|
||||
|
||||
private void insertItem(ItemEntity entity) {
|
||||
contents.clear();
|
||||
contents.setInventorySlotContents(0, entity.getItem());
|
||||
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, contents,
|
||||
inventory.clear();
|
||||
inventory.setInventorySlotContents(0, entity.getItem());
|
||||
Optional<CrushingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, inventory,
|
||||
world);
|
||||
|
||||
contents.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
||||
contents.appliedRecipe = false;
|
||||
inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
||||
inventory.appliedRecipe = false;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
@ -212,7 +212,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
}
|
||||
|
||||
public boolean isOccupied() {
|
||||
return hasEntity() || !contents.isEmpty();
|
||||
return hasEntity() || !inventory.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasEntity() {
|
||||
|
|
|
@ -8,7 +8,8 @@ import net.minecraftforge.items.ItemStackHandler;
|
|||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
public class ProcessingInventory extends RecipeWrapper {
|
||||
protected int processingDuration;
|
||||
protected int remainingTime;
|
||||
protected int recipeDuration;
|
||||
protected boolean appliedRecipe;
|
||||
|
||||
public ProcessingInventory() {
|
||||
|
@ -18,7 +19,8 @@ public class ProcessingInventory extends RecipeWrapper {
|
|||
@Override
|
||||
public void clear() {
|
||||
super.clear();
|
||||
processingDuration = 0;
|
||||
remainingTime = 0;
|
||||
recipeDuration = 0;
|
||||
appliedRecipe = false;
|
||||
}
|
||||
|
||||
|
@ -29,7 +31,8 @@ public class ProcessingInventory extends RecipeWrapper {
|
|||
stacks.add(stack);
|
||||
}
|
||||
ItemStackHelper.saveAllItems(nbt, stacks);
|
||||
nbt.putInt("ProcessingTime", processingDuration);
|
||||
nbt.putInt("ProcessingTime", remainingTime);
|
||||
nbt.putInt("RecipeTime", recipeDuration);
|
||||
nbt.putBoolean("AppliedRecipe", appliedRecipe);
|
||||
}
|
||||
|
||||
|
@ -40,7 +43,8 @@ public class ProcessingInventory extends RecipeWrapper {
|
|||
|
||||
for (int slot = 0; slot < stacks.size(); slot++)
|
||||
inventory.setInventorySlotContents(slot, stacks.get(slot));
|
||||
inventory.processingDuration = nbt.getInt("ProcessingTime");
|
||||
inventory.remainingTime = nbt.getInt("ProcessingTime");
|
||||
inventory.recipeDuration = nbt.getInt("RecipeTime");
|
||||
inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe");
|
||||
|
||||
return inventory;
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.foundation.block.IWithTileEntity;
|
|||
import com.simibubi.create.foundation.utility.VoxelShapers;
|
||||
import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock;
|
||||
import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -11,6 +12,8 @@ import net.minecraft.block.Blocks;
|
|||
import net.minecraft.block.material.PushReaction;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
|
@ -18,17 +21,20 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SawBlock extends DirectionalAxisKineticBlock
|
||||
implements IWithTileEntity<SawTileEntity>, IHaveMovementBehavior {
|
||||
implements IWithTileEntity<SawTileEntity>, IHaveMovementBehavior, IBlockWithFilter {
|
||||
|
||||
public static final BooleanProperty RUNNING = BooleanProperty.create("running");
|
||||
public static DamageSource damageSourceSaw = new DamageSource("create.saw").setDamageBypassesArmor();
|
||||
|
@ -38,6 +44,12 @@ public class SawBlock extends DirectionalAxisKineticBlock
|
|||
setDefaultState(getDefaultState().with(RUNNING, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT_MIPPED;
|
||||
|
@ -92,7 +104,7 @@ public class SawBlock extends DirectionalAxisKineticBlock
|
|||
if (!(entityIn instanceof ItemEntity))
|
||||
return;
|
||||
withTileEntityDo(entityIn.world, entityIn.getPosition(), te -> {
|
||||
|
||||
te.insertItem((ItemEntity) entityIn);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -116,4 +128,44 @@ public class SawBlock extends DirectionalAxisKineticBlock
|
|||
: super.hasShaftTowards(world, pos, state, face);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||
if (worldIn.getTileEntity(pos) == null)
|
||||
return;
|
||||
|
||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
for (int slot = 0; slot < te.inventory.getSizeInventory(); slot++) {
|
||||
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(),
|
||||
te.inventory.getStackInSlot(slot));
|
||||
}
|
||||
});
|
||||
|
||||
worldIn.removeTileEntity(pos);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d getFilterPosition(BlockState state) {
|
||||
Vec3d x = new Vec3d(8f / 16f, 12.5f / 16f + 1f/256f, 12.25f / 16f);
|
||||
Vec3d z = new Vec3d(12.25f / 16f, 12.5f / 16f + 1f/256f, 8f / 16f);
|
||||
return state.get(AXIS_ALONG_FIRST_COORDINATE) ? z : x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFilterAngle(BlockState state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFilterVisible(BlockState state) {
|
||||
return state.get(FACING) == Direction.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getFilterFacing(BlockState state) {
|
||||
return state.get(AXIS_ALONG_FIRST_COORDINATE) ? Direction.EAST : Direction.SOUTH;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,21 +2,49 @@ package com.simibubi.create.modules.contraptions.receivers;
|
|||
|
||||
import static com.simibubi.create.modules.contraptions.receivers.SawBlock.RUNNING;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllRecipes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.item.crafting.StonecuttingRecipe;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.BlockParticleData;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class SawTileEntity extends KineticTileEntity {
|
||||
public class SawTileEntity extends KineticTileEntity implements IHaveFilter {
|
||||
|
||||
public ProcessingInventory inventory;
|
||||
private int recipeIndex;
|
||||
private ItemStack filter;
|
||||
|
||||
public SawTileEntity() {
|
||||
super(AllTileEntities.SAW.type);
|
||||
inventory = new ProcessingInventory();
|
||||
inventory.remainingTime = -1;
|
||||
filter = ItemStack.EMPTY;
|
||||
recipeIndex = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFastRenderer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,26 +52,198 @@ public class SawTileEntity extends KineticTileEntity {
|
|||
boolean shouldRun = Math.abs(getSpeed()) > 1 / 64f;
|
||||
boolean running = getBlockState().get(RUNNING);
|
||||
if (shouldRun != running)
|
||||
world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun));
|
||||
world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun), 2 | 16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
inventory.write(compound);
|
||||
compound.put("Filter", filter.write(new CompoundNBT()));
|
||||
compound.putInt("RecipeIndex", recipeIndex);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
super.read(compound);
|
||||
inventory = ProcessingInventory.read(compound);
|
||||
recipeIndex = compound.getInt("RecipeIndex");
|
||||
filter = ItemStack.read(compound.getCompound("Filter"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!canProcess())
|
||||
return;
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
if (inventory.remainingTime == -1)
|
||||
return;
|
||||
|
||||
float processingSpeed = MathHelper.clamp(Math.abs(getSpeed()) / 32, 1, 128);
|
||||
inventory.remainingTime -= processingSpeed;
|
||||
spawnParticles(inventory.getStackInSlot(0));
|
||||
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (inventory.remainingTime < 20 && !inventory.appliedRecipe) {
|
||||
applyRecipe();
|
||||
inventory.appliedRecipe = true;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3d outPos = VecHelper.getCenterOf(pos).add(getItemMovementVec().scale(.5f).add(0, .5, 0));
|
||||
Vec3d outMotion = getItemMovementVec().scale(.0625).add(0, .125, 0);
|
||||
|
||||
if (inventory.remainingTime <= 0) {
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||
entityIn.setMotion(outMotion);
|
||||
world.addEntity(entityIn);
|
||||
}
|
||||
inventory.clear();
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
protected void spawnParticles(ItemStack stack) {
|
||||
if (stack == null || stack.isEmpty())
|
||||
return;
|
||||
|
||||
IParticleData particleData = null;
|
||||
float speed = 1;
|
||||
if (stack.getItem() instanceof BlockItem)
|
||||
particleData = new BlockParticleData(ParticleTypes.BLOCK,
|
||||
((BlockItem) stack.getItem()).getBlock().getDefaultState());
|
||||
else {
|
||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||
speed = .125f;
|
||||
}
|
||||
|
||||
Random r = world.rand;
|
||||
Vec3d vec = getItemMovementVec();
|
||||
Vec3d pos = VecHelper.getCenterOf(this.pos);
|
||||
float offset = inventory.recipeDuration != 0 ? (float) (inventory.remainingTime) / inventory.recipeDuration : 0;
|
||||
offset -= .5f;
|
||||
world.addParticle(particleData, pos.getX() + -vec.x * offset, pos.getY() + .45f, pos.getZ() + -vec.z * offset,
|
||||
vec.x * speed, r.nextFloat() * speed, vec.z * speed);
|
||||
}
|
||||
|
||||
public Vec3d getItemMovementVec() {
|
||||
boolean alongX = !getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
int offset = getSpeed() < 0 ? -1 : 1;
|
||||
return new Vec3d(offset * (alongX ? 1 : 0), 0, offset * (alongX ? 0 : -1));
|
||||
}
|
||||
|
||||
private void applyRecipe() {
|
||||
List<IRecipe<?>> recipes = getRecipes();
|
||||
if (recipes.isEmpty())
|
||||
return;
|
||||
if (recipeIndex >= recipes.size())
|
||||
recipeIndex = 0;
|
||||
|
||||
IRecipe<?> recipe = recipes.get(recipeIndex);
|
||||
|
||||
int rolls = inventory.getStackInSlot(0).getCount();
|
||||
inventory.clear();
|
||||
|
||||
for (int roll = 0; roll < rolls; roll++) {
|
||||
List<ItemStack> results = new LinkedList<ItemStack>();
|
||||
if (recipe instanceof CuttingRecipe)
|
||||
results = ((CuttingRecipe) recipe).rollResults();
|
||||
else if (recipe instanceof StonecuttingRecipe)
|
||||
results.add(recipe.getRecipeOutput().copy());
|
||||
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
ItemStack stack = results.get(i);
|
||||
|
||||
for (int slot = 0; slot < inventory.getSizeInventory(); slot++) {
|
||||
stack = inventory.getItems().insertItem(slot, stack, false);
|
||||
|
||||
if (stack.isEmpty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<IRecipe<?>> getRecipes() {
|
||||
List<IRecipe<?>> recipes = world.getRecipeManager().getRecipes().parallelStream()
|
||||
.filter(r -> r.getType() == IRecipeType.STONECUTTING || r.getType() == AllRecipes.Types.CUTTING)
|
||||
.filter(r -> filter.isEmpty() || ItemStack.areItemsEqual(filter, r.getRecipeOutput()))
|
||||
.filter(r -> !r.getIngredients().isEmpty()
|
||||
&& r.getIngredients().get(0).test(inventory.getStackInSlot(0)))
|
||||
.collect(Collectors.toList());
|
||||
return recipes;
|
||||
}
|
||||
|
||||
public void insertItem(ItemEntity entity) {
|
||||
if (!canProcess())
|
||||
return;
|
||||
if (!inventory.isEmpty())
|
||||
return;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
inventory.clear();
|
||||
inventory.setInventorySlotContents(0, entity.getItem().copy());
|
||||
Optional<CuttingRecipe> recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CUTTING, inventory, world);
|
||||
|
||||
inventory.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
||||
List<IRecipe<?>> recipes = getRecipes();
|
||||
boolean valid = !recipes.isEmpty();
|
||||
int time = 100;
|
||||
|
||||
if (recipes.isEmpty()) {
|
||||
inventory.remainingTime = inventory.recipeDuration = 10;
|
||||
inventory.appliedRecipe = false;
|
||||
entity.remove();
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
recipeIndex++;
|
||||
if (recipeIndex >= recipes.size())
|
||||
recipeIndex = 0;
|
||||
}
|
||||
|
||||
IRecipe<?> recipe = recipes.get(recipeIndex);
|
||||
if (recipe instanceof CuttingRecipe) {
|
||||
time = ((CuttingRecipe) recipe).getProcessingDuration();
|
||||
}
|
||||
|
||||
inventory.remainingTime = time * Math.max(1, (entity.getItem().getCount() / 5));
|
||||
inventory.recipeDuration = inventory.remainingTime;
|
||||
inventory.appliedRecipe = false;
|
||||
entity.remove();
|
||||
|
||||
sendData();
|
||||
}
|
||||
|
||||
protected boolean canProcess() {
|
||||
return getBlockState().get(SawBlock.FACING) == Direction.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(ItemStack stack) {
|
||||
filter = stack.copy();
|
||||
markDirty();
|
||||
sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,16 +3,87 @@ package com.simibubi.create.modules.contraptions.receivers;
|
|||
import static net.minecraft.state.properties.BlockStateProperties.AXIS;
|
||||
import static net.minecraft.state.properties.BlockStateProperties.FACING;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||
import com.simibubi.create.modules.contraptions.base.IRotate;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner;
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
public class SawTileEntityRenderer extends KineticTileEntityRenderer {
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SawTileEntityRenderer extends TileEntityRenderer<SawTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public SawTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(SawTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) {
|
||||
super.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
||||
boolean processingMode = te.getBlockState().get(SawBlock.FACING) == Direction.UP;
|
||||
if (processingMode && !te.inventory.isEmpty()) {
|
||||
boolean alongZ = !te.getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE);
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
float offset = te.inventory.recipeDuration != 0
|
||||
? (float) (te.inventory.remainingTime) / te.inventory.recipeDuration
|
||||
: 0;
|
||||
if (te.getSpeed() == 0)
|
||||
offset = .5f;
|
||||
if (te.getSpeed() < 0 ^ alongZ)
|
||||
offset = 1 - offset;
|
||||
|
||||
ItemStack stack = te.inventory.getStackInSlot(0);
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack);
|
||||
boolean blockItem = modelWithOverrides.isGui3d();
|
||||
|
||||
GlStateManager.translated(x + (alongZ ? offset : .5), y + (blockItem ? .925f : 13f / 16f),
|
||||
z + (alongZ ? .5 : offset));
|
||||
|
||||
GlStateManager.scaled(.5, .5, .5);
|
||||
if (alongZ)
|
||||
GlStateManager.rotated(90, 0, 1, 0);
|
||||
GlStateManager.rotated(90, 1, 0, 0);
|
||||
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
// Filter
|
||||
filterRenderer.render(te, x, y, z, partialTicks, destroyStage);
|
||||
|
||||
// Kinetic renders
|
||||
final BlockState state = getRenderedBlockState(te);
|
||||
KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new);
|
||||
final BlockPos pos = te.getPos();
|
||||
Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState());
|
||||
float angle = KineticTileEntityRenderer.getAngleForTe(te, pos, axis);
|
||||
|
||||
TessellatorHelper.prepareFastRender();
|
||||
TessellatorHelper.begin(DefaultVertexFormats.BLOCK);
|
||||
KineticTileEntityRenderer.renderFromCache(Tessellator.getInstance().getBuffer(), state, getWorld(), (float) x,
|
||||
(float) y, (float) z, pos, axis, angle);
|
||||
TessellatorHelper.draw();
|
||||
}
|
||||
|
||||
protected BlockState getRenderedBlockState(KineticTileEntity te) {
|
||||
BlockState state = te.getBlockState();
|
||||
if (state.get(FACING).getAxis().isHorizontal()) {
|
||||
|
|
|
@ -26,8 +26,6 @@ import net.minecraft.util.math.shapes.ISelectionContext;
|
|||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
||||
@EventBusSubscriber
|
||||
|
@ -166,8 +164,9 @@ public class MovingConstructHandler {
|
|||
return movingPistons.get(mechanicalPistonTileEntity.getWorld());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||
// @SubscribeEvent
|
||||
// @OnlyIn(value = Dist.CLIENT)
|
||||
// public static void onRenderWorld(RenderWorldLastEvent event) {
|
||||
// for (AxisAlignedBB bb : renderedBBs) {
|
||||
// TessellatorHelper.prepareForDrawing();
|
||||
// GlStateManager.disableTexture();
|
||||
|
@ -179,6 +178,6 @@ public class MovingConstructHandler {
|
|||
// GlStateManager.enableTexture();
|
||||
// TessellatorHelper.cleanUpAfterDrawing();
|
||||
// }
|
||||
}
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,10 @@ public class FilteredTileEntityRenderer {
|
|||
float partialTicks, int destroyStage) {
|
||||
BlockState state = tileEntityIn.getBlockState();
|
||||
IBlockWithFilter block = (IBlockWithFilter) state.getBlock();
|
||||
|
||||
if (!block.isFilterVisible(state))
|
||||
return;
|
||||
|
||||
Direction facing = block.getFilterFacing(state);
|
||||
float scale = block.getItemHitboxScale();
|
||||
|
||||
|
@ -31,13 +35,13 @@ public class FilteredTileEntityRenderer {
|
|||
BlockPos pos = tileEntityIn.getPos();
|
||||
GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ());
|
||||
|
||||
renderFilterItem(tileEntityIn.getFilter(), position, facing, scale - 2 / 16f);
|
||||
renderFilterItem(tileEntityIn.getFilter(), position, facing, scale - 2 / 16f, block.getFilterAngle(state));
|
||||
|
||||
TessellatorHelper.cleanUpAfterDrawing();
|
||||
|
||||
}
|
||||
|
||||
private void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff) {
|
||||
private void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff, float angle) {
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
boolean vertical = facing.getAxis().isVertical();
|
||||
|
||||
|
@ -46,11 +50,11 @@ public class FilteredTileEntityRenderer {
|
|||
|
||||
float offX = 0;
|
||||
float offY = 0;
|
||||
float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff - 1/16f : 1/16f;
|
||||
float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff - 1 / 16f : 1 / 16f;
|
||||
if (vertical)
|
||||
offZ = -offZ;
|
||||
|
||||
float rotX = vertical ? 90 : 0 - (blockItem ? -67.5f : 67.5f);
|
||||
float rotX = vertical ? 90 : 0 - (blockItem ? -90f + angle : 90 - angle);
|
||||
float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0);
|
||||
float rotZ = vertical && facing == Direction.DOWN ? 180 : 0;
|
||||
if (facing.getAxis() == Axis.X) {
|
||||
|
|
|
@ -41,6 +41,14 @@ public interface IBlockWithFilter {
|
|||
return 2 / 16f;
|
||||
}
|
||||
|
||||
public default float getFilterAngle(BlockState state) {
|
||||
return 22.5f;
|
||||
}
|
||||
|
||||
public default boolean isFilterVisible(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public default boolean showsCount() {
|
||||
return false;
|
||||
}
|
||||
|
@ -50,8 +58,10 @@ public interface IBlockWithFilter {
|
|||
TileEntity te = worldIn.getTileEntity(pos);
|
||||
if (te == null || !(te instanceof IHaveFilter))
|
||||
return false;
|
||||
IHaveFilter actor = (IHaveFilter) te;
|
||||
if (!isFilterVisible(state))
|
||||
return false;
|
||||
|
||||
IHaveFilter actor = (IHaveFilter) te;
|
||||
Vec3d vec = new Vec3d(pos);
|
||||
Vec3d position = vec.add(getFilterPosition(state));
|
||||
ItemStack stack = player.getHeldItem(handIn);
|
||||
|
@ -86,6 +96,9 @@ public interface IBlockWithFilter {
|
|||
IHaveFilter actor = (IHaveFilter) te;
|
||||
|
||||
IBlockWithFilter filterBlock = (IBlockWithFilter) state.getBlock();
|
||||
if (!filterBlock.isFilterVisible(state))
|
||||
return;
|
||||
|
||||
Vec3d vec = new Vec3d(pos);
|
||||
Vec3d position = filterBlock.getFilterPosition(state).add(vec);
|
||||
float scale = filterBlock.getItemHitboxScale();
|
||||
|
@ -112,7 +125,8 @@ public interface IBlockWithFilter {
|
|||
Vec3i direction = facing.getDirectionVec();
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.translated(position.x, position.y, position.z);
|
||||
GlStateManager.rotated(22.5f, direction.getZ(), 0, -direction.getX());
|
||||
float filterAngle = filterBlock.getFilterAngle(state);
|
||||
GlStateManager.rotated(filterAngle, direction.getZ(), 0, -direction.getX());
|
||||
GlStateManager.translated(-center.x, -center.y, -center.z);
|
||||
GlStateManager.translated(-position.x, -position.y, -position.z);
|
||||
|
||||
|
@ -138,7 +152,7 @@ public interface IBlockWithFilter {
|
|||
GlStateManager.rotated(facing.getHorizontalAngle() * (facing.getAxis() == Axis.X ? -1 : 1), 0, 1, 0);
|
||||
GlStateManager.scaled(textScale, -textScale, textScale);
|
||||
GlStateManager.translated(17.5f, -5f, -5f);
|
||||
GlStateManager.rotated(67.5f, 1, 0, 0);
|
||||
GlStateManager.rotated(90 - filterAngle, 1, 0, 0);
|
||||
|
||||
String text = Lang.translate("logistics.filter");
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
|
@ -149,7 +163,7 @@ public interface IBlockWithFilter {
|
|||
if (filterBlock.showsCount() && !actor.getFilter().isEmpty()) {
|
||||
String count = actor.getFilter().getCount() + "";
|
||||
GlStateManager.translated(-7 - font.getStringWidth(count), 10, 10 + 1 / 4f);
|
||||
GlStateManager.scaled(1.5,1.5, 1.5);
|
||||
GlStateManager.scaled(1.5, 1.5, 1.5);
|
||||
font.drawString(count, 0, 0, 0xEDEDED);
|
||||
GlStateManager.translated(0, 0, -1 / 4f);
|
||||
font.drawString(count, 1, 1, 0x4F4F4F);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:acacia_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_acacia_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:birch_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_birch_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:dark_oak_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_dark_oak_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:jungle_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_jungle_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
16
src/main/resources/data/create/recipes/cutting/oak_log.json
Normal file
16
src/main/resources/data/create/recipes/cutting/oak_log.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:oak_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_oak_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:spruce_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:stripped_spruce_log",
|
||||
"count": 1
|
||||
}
|
||||
],
|
||||
"processingTime": 50
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_acacia_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:acacia_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_birch_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:birch_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_dark_oak_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:dark_oak_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_jungle_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:jungle_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_oak_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:oak_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "create:cutting",
|
||||
"group": "minecraft:misc",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:stripped_spruce_log"
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"item": "minecraft:spruce_planks",
|
||||
"count": 5
|
||||
}
|
||||
],
|
||||
"processingTime": 100
|
||||
}
|
Loading…
Reference in a new issue