mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 23:33:40 +01:00
Schematics and Entities
- Fixed sidedness issue with glue effect packets - Fixed duplication issue with Schematic tables - Schematics can now include entities - Schematicannons can now print: - superglue - (filled) item frames - (equipped) armor stands - end crystals - boats and minecarts - paintings - Special blocks/entities placed by a schematicannon can now specify custom item requirements (used currently for belts & superglue) - Fixed superglue not being rotated/mirrored correctly
This commit is contained in:
parent
8bfc4445b0
commit
c4513020df
23 changed files with 696 additions and 242 deletions
|
@ -127,17 +127,27 @@ public class ItemHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum ExtractionCountMode {
|
||||||
|
EXACTLY, UPTO
|
||||||
|
}
|
||||||
|
|
||||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, boolean simulate) {
|
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, boolean simulate) {
|
||||||
return extract(inv, test, -1, simulate);
|
return extract(inv, test, ExtractionCountMode.UPTO, AllConfigs.SERVER.logistics.extractorAmount.get(),
|
||||||
|
simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, int exactAmount, boolean simulate) {
|
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, int exactAmount, boolean simulate) {
|
||||||
|
return extract(inv, test, ExtractionCountMode.EXACTLY, exactAmount, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, ExtractionCountMode mode, int amount,
|
||||||
|
boolean simulate) {
|
||||||
ItemStack extracting = ItemStack.EMPTY;
|
ItemStack extracting = ItemStack.EMPTY;
|
||||||
boolean amountRequired = exactAmount != -1;
|
boolean amountRequired = mode == ExtractionCountMode.EXACTLY;
|
||||||
boolean checkHasEnoughItems = amountRequired;
|
boolean checkHasEnoughItems = amountRequired;
|
||||||
boolean hasEnoughItems = !checkHasEnoughItems;
|
boolean hasEnoughItems = !checkHasEnoughItems;
|
||||||
int maxExtractionCount = hasEnoughItems ? AllConfigs.SERVER.logistics.extractorAmount.get() : exactAmount;
|
|
||||||
boolean potentialOtherMatch = false;
|
boolean potentialOtherMatch = false;
|
||||||
|
int maxExtractionCount = amount;
|
||||||
|
|
||||||
Extraction: do {
|
Extraction: do {
|
||||||
extracting = ItemStack.EMPTY;
|
extracting = ItemStack.EMPTY;
|
||||||
|
@ -186,7 +196,7 @@ public class ItemHelper {
|
||||||
|
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
if (amountRequired && extracting.getCount() < exactAmount)
|
if (amountRequired && extracting.getCount() < amount)
|
||||||
return ItemStack.EMPTY;
|
return ItemStack.EMPTY;
|
||||||
|
|
||||||
return extracting;
|
return extracting;
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
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.foundation.utility.Debug;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
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.block.FallingBlock;
|
import net.minecraft.block.FallingBlock;
|
||||||
import net.minecraft.block.material.Material;
|
|
||||||
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.entity.item.minecart.AbstractMinecartEntity;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ public class GlueEffectPacket extends SimplePacketBase {
|
||||||
buffer.writeBoolean(fullBlock);
|
buffer.writeBoolean(fullBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
public void handle(Supplier<Context> context) {
|
public void handle(Supplier<Context> context) {
|
||||||
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
Minecraft mc = Minecraft.getInstance();
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
|
|
@ -8,6 +8,9 @@ import com.simibubi.create.AllEntities;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
|
import com.simibubi.create.modules.schematics.ISpecialEntityItemRequirement;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
@ -46,7 +49,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
import net.minecraftforge.fml.network.PacketDistributor;
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData {
|
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement {
|
||||||
|
|
||||||
private int validationTimer;
|
private int validationTimer;
|
||||||
protected BlockPos hangingPosition;
|
protected BlockPos hangingPosition;
|
||||||
|
@ -64,7 +67,8 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void registerData() {}
|
protected void registerData() {
|
||||||
|
}
|
||||||
|
|
||||||
public int getWidthPixels() {
|
public int getWidthPixels() {
|
||||||
return 12;
|
return 12;
|
||||||
|
@ -104,34 +108,32 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
||||||
|
|
||||||
protected void updateBoundingBox() {
|
protected void updateBoundingBox() {
|
||||||
if (this.getFacingDirection() != null) {
|
if (this.getFacingDirection() != null) {
|
||||||
this.posX =
|
double offset = 0.5 - 1 / 256d;
|
||||||
(double) this.hangingPosition.getX() + 0.5 - (double) this.getFacingDirection().getXOffset() * 0.5;
|
this.posX = hangingPosition.getX() + 0.5 - facingDirection.getXOffset() * offset;
|
||||||
this.posY =
|
this.posY = hangingPosition.getY() + 0.5 - facingDirection.getYOffset() * offset;
|
||||||
(double) this.hangingPosition.getY() + 0.5 - (double) this.getFacingDirection().getYOffset() * 0.5;
|
this.posZ = hangingPosition.getZ() + 0.5 - facingDirection.getZOffset() * offset;
|
||||||
this.posZ =
|
double w = getWidthPixels();
|
||||||
(double) this.hangingPosition.getZ() + 0.5 - (double) this.getFacingDirection().getZOffset() * 0.5;
|
double h = getHeightPixels();
|
||||||
double d1 = (double) this.getWidthPixels();
|
double l = getWidthPixels();
|
||||||
double d2 = (double) this.getHeightPixels();
|
|
||||||
double d3 = (double) this.getWidthPixels();
|
|
||||||
Axis axis = this.getFacingDirection().getAxis();
|
Axis axis = this.getFacingDirection().getAxis();
|
||||||
double depth = 2 - 1 / 128f;
|
double depth = 2 - 1 / 128f;
|
||||||
|
|
||||||
switch (axis) {
|
switch (axis) {
|
||||||
case X:
|
case X:
|
||||||
d1 = depth;
|
w = depth;
|
||||||
break;
|
break;
|
||||||
case Y:
|
case Y:
|
||||||
d2 = depth;
|
h = depth;
|
||||||
break;
|
break;
|
||||||
case Z:
|
case Z:
|
||||||
d3 = depth;
|
l = depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
d1 = d1 / 32.0D;
|
w = w / 32.0D;
|
||||||
d2 = d2 / 32.0D;
|
h = h / 32.0D;
|
||||||
d3 = d3 / 32.0D;
|
l = l / 32.0D;
|
||||||
this.setBoundingBox(new AxisAlignedBB(this.posX - d1, this.posY - d2, this.posZ - d3, this.posX + d1,
|
this.setBoundingBox(new AxisAlignedBB(this.posX - w, this.posY - h, this.posZ - l, this.posX + w,
|
||||||
this.posY + d2, this.posZ + d3));
|
this.posY + h, this.posZ + l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,13 +319,13 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
||||||
if (this.getFacingDirection().getAxis() != Direction.Axis.Y) {
|
if (this.getFacingDirection().getAxis() != Direction.Axis.Y) {
|
||||||
switch (transformRotation) {
|
switch (transformRotation) {
|
||||||
case CLOCKWISE_180:
|
case CLOCKWISE_180:
|
||||||
this.facingDirection = this.getFacingDirection().getOpposite();
|
facingDirection = facingDirection.getOpposite();
|
||||||
break;
|
break;
|
||||||
case COUNTERCLOCKWISE_90:
|
case COUNTERCLOCKWISE_90:
|
||||||
this.facingDirection = this.getFacingDirection().rotateYCCW();
|
facingDirection = facingDirection.rotateYCCW();
|
||||||
break;
|
break;
|
||||||
case CLOCKWISE_90:
|
case CLOCKWISE_90:
|
||||||
this.facingDirection = this.getFacingDirection().rotateY();
|
facingDirection = facingDirection.rotateY();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -356,10 +358,12 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStruckByLightning(LightningBoltEntity lightningBolt) {}
|
public void onStruckByLightning(LightningBoltEntity lightningBolt) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculateSize() {}
|
public void recalculateSize() {
|
||||||
|
}
|
||||||
|
|
||||||
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -387,4 +391,10 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat
|
||||||
public Direction getFacingDirection() {
|
public Direction getFacingDirection() {
|
||||||
return facingDirection;
|
return facingDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemRequirement getRequiredItems() {
|
||||||
|
return new ItemRequirement(ItemUseType.DAMAGE, AllItems.SUPER_GLUE.get());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.modules.contraptions.relays.belt;
|
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -16,6 +17,9 @@ 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.transport.BeltMovementHandler.TransportedEntityInfo;
|
import com.simibubi.create.modules.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
|
||||||
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
|
import com.simibubi.create.modules.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||||
|
import com.simibubi.create.modules.schematics.ISpecialBlockItemRequirement;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockRenderType;
|
import net.minecraft.block.BlockRenderType;
|
||||||
|
@ -63,7 +67,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, ITE<BeltTileEntity>, IHaveColorHandler {
|
implements IHaveNoBlockItem, ITE<BeltTileEntity>, IHaveColorHandler, ISpecialBlockItemRequirement {
|
||||||
|
|
||||||
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);
|
||||||
|
@ -603,5 +607,19 @@ public class BeltBlock extends HorizontalKineticBlock
|
||||||
public Class<BeltTileEntity> getTileEntityClass() {
|
public Class<BeltTileEntity> getTileEntityClass() {
|
||||||
return BeltTileEntity.class;
|
return BeltTileEntity.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemRequirement getRequiredItems(BlockState state) {
|
||||||
|
List<ItemStack> required = new ArrayList<>();
|
||||||
|
if (state.get(PART) != Part.MIDDLE)
|
||||||
|
required.add(new ItemStack(AllBlocks.SHAFT.get()));
|
||||||
|
if (state.get(CASING))
|
||||||
|
required.add(new ItemStack(AllBlocks.BRASS_CASING.get()));
|
||||||
|
if (state.get(PART) == Part.START)
|
||||||
|
required.add(AllItems.BELT_CONNECTOR.asStack());
|
||||||
|
if (required.isEmpty())
|
||||||
|
return ItemRequirement.NONE;
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, required);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.simibubi.create.modules.schematics;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
|
||||||
|
public interface ISpecialBlockItemRequirement {
|
||||||
|
|
||||||
|
default ItemRequirement getRequiredItems(BlockState state) {
|
||||||
|
return ItemRequirement.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.simibubi.create.modules.schematics;
|
||||||
|
|
||||||
|
public interface ISpecialEntityItemRequirement {
|
||||||
|
|
||||||
|
default ItemRequirement getRequiredItems() {
|
||||||
|
return ItemRequirement.INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.simibubi.create.modules.schematics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.item.ArmorStandEntity;
|
||||||
|
import net.minecraft.entity.item.BoatEntity;
|
||||||
|
import net.minecraft.entity.item.ItemFrameEntity;
|
||||||
|
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
|
||||||
|
import net.minecraft.item.BlockItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.state.properties.SlabType;
|
||||||
|
|
||||||
|
public class ItemRequirement {
|
||||||
|
|
||||||
|
public enum ItemUseType {
|
||||||
|
CONSUME, DAMAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemUseType usage;
|
||||||
|
List<ItemStack> requiredItems;
|
||||||
|
|
||||||
|
public static ItemRequirement INVALID = new ItemRequirement();
|
||||||
|
public static ItemRequirement NONE = new ItemRequirement();
|
||||||
|
|
||||||
|
private ItemRequirement() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRequirement(ItemUseType usage, Item item) {
|
||||||
|
this(usage, Arrays.asList(new ItemStack(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemRequirement(ItemUseType usage, List<ItemStack> requiredItems) {
|
||||||
|
this.usage = usage;
|
||||||
|
this.requiredItems = requiredItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemRequirement of(BlockState state) {
|
||||||
|
Block block = state.getBlock();
|
||||||
|
if (block == Blocks.AIR)
|
||||||
|
return NONE;
|
||||||
|
if (block instanceof ISpecialBlockItemRequirement)
|
||||||
|
return ((ISpecialBlockItemRequirement) block).getRequiredItems(state);
|
||||||
|
|
||||||
|
Item item = BlockItem.BLOCK_TO_ITEM.getOrDefault(state.getBlock(), Items.AIR);
|
||||||
|
|
||||||
|
// double slab needs two items
|
||||||
|
if (state.has(BlockStateProperties.SLAB_TYPE) && state.get(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE)
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(new ItemStack(item, 2)));
|
||||||
|
|
||||||
|
return item == Items.AIR ? INVALID : new ItemRequirement(ItemUseType.CONSUME, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ItemRequirement of(Entity entity) {
|
||||||
|
EntityType<?> type = entity.getType();
|
||||||
|
|
||||||
|
if (entity instanceof ISpecialEntityItemRequirement)
|
||||||
|
return ((ISpecialEntityItemRequirement) entity).getRequiredItems();
|
||||||
|
|
||||||
|
if (type == EntityType.ITEM_FRAME) {
|
||||||
|
ItemFrameEntity ife = (ItemFrameEntity) entity;
|
||||||
|
ItemStack frame = new ItemStack(Items.ITEM_FRAME);
|
||||||
|
ItemStack displayedItem = ife.getDisplayedItem();
|
||||||
|
if (displayedItem.isEmpty())
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, Items.ITEM_FRAME);
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, Arrays.asList(frame, displayedItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == EntityType.PAINTING)
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, Items.PAINTING);
|
||||||
|
|
||||||
|
if (type == EntityType.ARMOR_STAND) {
|
||||||
|
List<ItemStack> requirements = new ArrayList<>();
|
||||||
|
ArmorStandEntity armorStandEntity = (ArmorStandEntity) entity;
|
||||||
|
armorStandEntity.getEquipmentAndArmor().forEach(requirements::add);
|
||||||
|
requirements.add(new ItemStack(Items.ARMOR_STAND));
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, requirements);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity instanceof AbstractMinecartEntity) {
|
||||||
|
AbstractMinecartEntity minecartEntity = (AbstractMinecartEntity) entity;
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, minecartEntity.getCartItem().getItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity instanceof BoatEntity) {
|
||||||
|
BoatEntity boatEntity = (BoatEntity) entity;
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, boatEntity.getItemBoat().getItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == EntityType.END_CRYSTAL)
|
||||||
|
return new ItemRequirement(ItemUseType.CONSUME, Items.END_CRYSTAL);
|
||||||
|
|
||||||
|
return INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return NONE == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInvalid() {
|
||||||
|
return INVALID == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ItemStack> getRequiredItems() {
|
||||||
|
return requiredItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemUseType getUsage() {
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean validate(ItemStack required, ItemStack present) {
|
||||||
|
return required.isEmpty() || required.getItem() == present.getItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,9 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.Items;
|
import net.minecraft.item.Items;
|
||||||
|
@ -21,10 +24,12 @@ public class MaterialChecklist {
|
||||||
|
|
||||||
public Map<Item, Integer> gathered;
|
public Map<Item, Integer> gathered;
|
||||||
public Map<Item, Integer> required;
|
public Map<Item, Integer> required;
|
||||||
|
public Map<Item, Integer> damageRequired;
|
||||||
public boolean blocksNotLoaded;
|
public boolean blocksNotLoaded;
|
||||||
|
|
||||||
public MaterialChecklist() {
|
public MaterialChecklist() {
|
||||||
required = new HashMap<>();
|
required = new HashMap<>();
|
||||||
|
damageRequired = new HashMap<>();
|
||||||
gathered = new HashMap<>();
|
gathered = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,16 +37,33 @@ public class MaterialChecklist {
|
||||||
blocksNotLoaded = true;
|
blocksNotLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void require(Item item) {
|
public void require(ItemRequirement requirement) {
|
||||||
if (required.containsKey(item))
|
if (requirement.isEmpty())
|
||||||
required.put(item, required.get(item) + 1);
|
return;
|
||||||
|
if (requirement.isInvalid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (ItemStack stack : requirement.requiredItems) {
|
||||||
|
if (requirement.getUsage() == ItemUseType.DAMAGE)
|
||||||
|
putOrIncrement(damageRequired, stack);
|
||||||
|
if (requirement.getUsage() == ItemUseType.CONSUME)
|
||||||
|
putOrIncrement(required, stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putOrIncrement(Map<Item, Integer> map, ItemStack stack) {
|
||||||
|
Item item = stack.getItem();
|
||||||
|
if (item == Items.AIR)
|
||||||
|
return;
|
||||||
|
if (map.containsKey(item))
|
||||||
|
map.put(item, map.get(item) + stack.getCount());
|
||||||
else
|
else
|
||||||
required.put(item, 1);
|
map.put(item, stack.getCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collect(ItemStack stack) {
|
public void collect(ItemStack stack) {
|
||||||
Item item = stack.getItem();
|
Item item = stack.getItem();
|
||||||
if (required.containsKey(item))
|
if (required.containsKey(item) || damageRequired.containsKey(item))
|
||||||
if (gathered.containsKey(item))
|
if (gathered.containsKey(item))
|
||||||
gathered.put(item, gathered.get(item) + stack.getCount());
|
gathered.put(item, gathered.get(item) + stack.getCount());
|
||||||
else
|
else
|
||||||
|
@ -65,19 +87,19 @@ public class MaterialChecklist {
|
||||||
string = new StringBuilder("{\"text\":\"");
|
string = new StringBuilder("{\"text\":\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Item> keys = new ArrayList<>(required.keySet());
|
List<Item> keys = new ArrayList<>(Sets.union(required.keySet(), damageRequired.keySet()));
|
||||||
Collections.sort(keys, (item1, item2) -> {
|
Collections.sort(keys, (item1, item2) -> {
|
||||||
Locale locale = Locale.ENGLISH;
|
Locale locale = Locale.ENGLISH;
|
||||||
String name1 = new TranslationTextComponent(((Item) item1).getTranslationKey()).getFormattedText()
|
String name1 =
|
||||||
.toLowerCase(locale);
|
new TranslationTextComponent(((Item) item1).getTranslationKey()).getFormattedText().toLowerCase(locale);
|
||||||
String name2 = new TranslationTextComponent(((Item) item2).getTranslationKey()).getFormattedText()
|
String name2 =
|
||||||
.toLowerCase(locale);
|
new TranslationTextComponent(((Item) item2).getTranslationKey()).getFormattedText().toLowerCase(locale);
|
||||||
return name1.compareTo(name2);
|
return name1.compareTo(name2);
|
||||||
});
|
});
|
||||||
|
|
||||||
List<Item> completed = new ArrayList<>();
|
List<Item> completed = new ArrayList<>();
|
||||||
for (Item item : keys) {
|
for (Item item : keys) {
|
||||||
int amount = required.get(item);
|
int amount = getRequiredAmount(item);
|
||||||
if (gathered.containsKey(item))
|
if (gathered.containsKey(item))
|
||||||
amount -= gathered.get(item);
|
amount -= gathered.get(item);
|
||||||
|
|
||||||
|
@ -106,7 +128,7 @@ public class MaterialChecklist {
|
||||||
}
|
}
|
||||||
|
|
||||||
itemsWritten++;
|
itemsWritten++;
|
||||||
string.append(gatheredEntry(new ItemStack(item), required.get(item)));
|
string.append(gatheredEntry(new ItemStack(item), getRequiredAmount(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
string.append("\"}");
|
string.append("\"}");
|
||||||
|
@ -120,6 +142,13 @@ public class MaterialChecklist {
|
||||||
return book;
|
return book;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getRequiredAmount(Item item) {
|
||||||
|
int amount = required.getOrDefault(item, 0);
|
||||||
|
if (damageRequired.containsKey(item))
|
||||||
|
amount += Math.ceil(damageRequired.get(item) / (float) new ItemStack(item).getMaxDamage());
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
private String gatheredEntry(ItemStack item, int amount) {
|
private String gatheredEntry(ItemStack item, int amount) {
|
||||||
int stacks = amount / 64;
|
int stacks = amount / 64;
|
||||||
int remainder = amount % 64;
|
int remainder = amount % 64;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.modules.schematics;
|
package com.simibubi.create.modules.schematics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -14,6 +15,8 @@ import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.item.ArmorStandEntity;
|
||||||
|
import net.minecraft.entity.item.ItemFrameEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.fluid.Fluid;
|
import net.minecraft.fluid.Fluid;
|
||||||
import net.minecraft.fluid.IFluidState;
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
@ -31,6 +34,7 @@ public class SchematicWorld extends WrappedWorld {
|
||||||
|
|
||||||
private Map<BlockPos, BlockState> blocks;
|
private Map<BlockPos, BlockState> blocks;
|
||||||
private Map<BlockPos, TileEntity> tileEntities;
|
private Map<BlockPos, TileEntity> tileEntities;
|
||||||
|
private List<Entity> entities;
|
||||||
private Cuboid bounds;
|
private Cuboid bounds;
|
||||||
public BlockPos anchor;
|
public BlockPos anchor;
|
||||||
public boolean renderMode;
|
public boolean renderMode;
|
||||||
|
@ -41,11 +45,28 @@ public class SchematicWorld extends WrappedWorld {
|
||||||
this.tileEntities = new HashMap<>();
|
this.tileEntities = new HashMap<>();
|
||||||
this.bounds = new Cuboid();
|
this.bounds = new Cuboid();
|
||||||
this.anchor = anchor;
|
this.anchor = anchor;
|
||||||
|
this.entities = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<BlockPos> getAllPositions() {
|
public Set<BlockPos> getAllPositions() {
|
||||||
return blocks.keySet();
|
return blocks.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addEntity(Entity entityIn) {
|
||||||
|
if (entityIn instanceof ItemFrameEntity)
|
||||||
|
((ItemFrameEntity) entityIn).getDisplayedItem().setTag(null);
|
||||||
|
if (entityIn instanceof ArmorStandEntity) {
|
||||||
|
ArmorStandEntity armorStandEntity = (ArmorStandEntity) entityIn;
|
||||||
|
armorStandEntity.getEquipmentAndArmor().forEach(stack -> stack.setTag(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
return entities.add(entityIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Entity> getEntities() {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileEntity getTileEntity(BlockPos pos) {
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
|
|
@ -25,7 +25,6 @@ import com.simibubi.create.modules.schematics.item.SchematicItem;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
import net.minecraft.util.text.TranslationTextComponent;
|
import net.minecraft.util.text.TranslationTextComponent;
|
||||||
|
@ -234,7 +233,6 @@ public class ServerSchematicLoader {
|
||||||
if (table == null)
|
if (table == null)
|
||||||
return;
|
return;
|
||||||
table.finishUpload();
|
table.finishUpload();
|
||||||
table.inventory.setStackInSlot(0, ItemStack.EMPTY);
|
|
||||||
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName().getFormattedText()));
|
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName().getFormattedText()));
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.simibubi.create.modules.schematics.block;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
|
|
||||||
public class LaunchedBlock {
|
|
||||||
|
|
||||||
private final SchematicannonTileEntity te;
|
|
||||||
public int totalTicks;
|
|
||||||
public int ticksRemaining;
|
|
||||||
public BlockPos target;
|
|
||||||
public BlockState state;
|
|
||||||
|
|
||||||
public LaunchedBlock(SchematicannonTileEntity schematicannonTileEntity, BlockPos target, BlockState state) {
|
|
||||||
te = schematicannonTileEntity;
|
|
||||||
this.target = target;
|
|
||||||
this.state = state;
|
|
||||||
totalTicks = (int) (Math.max(10, MathHelper.sqrt(MathHelper.sqrt(target.distanceSq(te.getPos()))) * 4f));
|
|
||||||
ticksRemaining = totalTicks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaunchedBlock(SchematicannonTileEntity schematicannonTileEntity, BlockPos target, BlockState state,
|
|
||||||
int ticksLeft, int total) {
|
|
||||||
te = schematicannonTileEntity;
|
|
||||||
this.target = target;
|
|
||||||
this.state = state;
|
|
||||||
this.totalTicks = total;
|
|
||||||
this.ticksRemaining = ticksLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
if (ticksRemaining > 0)
|
|
||||||
ticksRemaining--;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
package com.simibubi.create.modules.schematics.block;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.nbt.NBTUtil;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public abstract class LaunchedItem {
|
||||||
|
|
||||||
|
public int totalTicks;
|
||||||
|
public int ticksRemaining;
|
||||||
|
public BlockPos target;
|
||||||
|
public ItemStack stack;
|
||||||
|
|
||||||
|
private LaunchedItem(BlockPos start, BlockPos target, ItemStack stack) {
|
||||||
|
this(target, stack, ticksForDistance(start, target), ticksForDistance(start, target));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ticksForDistance(BlockPos start, BlockPos target) {
|
||||||
|
return (int) (Math.max(10, MathHelper.sqrt(MathHelper.sqrt(target.distanceSq(start))) * 4f));
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedItem() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private LaunchedItem(BlockPos target, ItemStack stack, int ticksLeft, int total) {
|
||||||
|
this.target = target;
|
||||||
|
this.stack = stack;
|
||||||
|
this.totalTicks = total;
|
||||||
|
this.ticksRemaining = ticksLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean update(World world) {
|
||||||
|
if (ticksRemaining > 0) {
|
||||||
|
ticksRemaining--;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (world.isRemote)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
place(world);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundNBT serializeNBT() {
|
||||||
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
c.putInt("TotalTicks", totalTicks);
|
||||||
|
c.putInt("TicksLeft", ticksRemaining);
|
||||||
|
c.put("Stack", stack.serializeNBT());
|
||||||
|
c.put("Target", NBTUtil.writeBlockPos(target));
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LaunchedItem fromNBT(CompoundNBT c) {
|
||||||
|
LaunchedItem launched =
|
||||||
|
c.contains("BlockState") ? new LaunchedItem.ForBlockState() : new LaunchedItem.ForEntity();
|
||||||
|
launched.readNBT(c);
|
||||||
|
return launched;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void place(World world);
|
||||||
|
|
||||||
|
void readNBT(CompoundNBT c) {
|
||||||
|
target = NBTUtil.readBlockPos(c.getCompound("Target"));
|
||||||
|
ticksRemaining = c.getInt("TicksLeft");
|
||||||
|
totalTicks = c.getInt("TotalTicks");
|
||||||
|
stack = ItemStack.read(c.getCompound("Stack"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ForBlockState extends LaunchedItem {
|
||||||
|
public BlockState state;
|
||||||
|
|
||||||
|
ForBlockState() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForBlockState(BlockPos start, BlockPos target, ItemStack stack, BlockState state) {
|
||||||
|
super(start, target, stack);
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT serializeNBT() {
|
||||||
|
CompoundNBT serializeNBT = super.serializeNBT();
|
||||||
|
serializeNBT.put("BlockState", NBTUtil.writeBlockState(state));
|
||||||
|
return serializeNBT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void readNBT(CompoundNBT nbt) {
|
||||||
|
super.readNBT(nbt);
|
||||||
|
state = NBTUtil.readBlockState(nbt.getCompound("BlockState"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void place(World world) {
|
||||||
|
// Piston
|
||||||
|
if (state.has(BlockStateProperties.EXTENDED))
|
||||||
|
state = state.with(BlockStateProperties.EXTENDED, false);
|
||||||
|
|
||||||
|
world.setBlockState(target, state, 18);
|
||||||
|
state.getBlock().onBlockPlacedBy(world, target, state, null, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ForEntity extends LaunchedItem {
|
||||||
|
public Entity entity;
|
||||||
|
private CompoundNBT deferredTag;
|
||||||
|
|
||||||
|
ForEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForEntity(BlockPos start, BlockPos target, ItemStack stack, Entity entity) {
|
||||||
|
super(start, target, stack);
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean update(World world) {
|
||||||
|
if (deferredTag != null && entity == null) {
|
||||||
|
try {
|
||||||
|
Optional<Entity> loadEntityUnchecked = EntityType.loadEntityUnchecked(deferredTag, world);
|
||||||
|
if (!loadEntityUnchecked.isPresent())
|
||||||
|
return true;
|
||||||
|
entity = loadEntityUnchecked.get();
|
||||||
|
} catch (Exception var3) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
deferredTag = null;
|
||||||
|
}
|
||||||
|
return super.update(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT serializeNBT() {
|
||||||
|
CompoundNBT serializeNBT = super.serializeNBT();
|
||||||
|
if (entity != null)
|
||||||
|
serializeNBT.put("Entity", entity.serializeNBT());
|
||||||
|
return serializeNBT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void readNBT(CompoundNBT nbt) {
|
||||||
|
super.readNBT(nbt);
|
||||||
|
if (nbt.contains("Entity"))
|
||||||
|
deferredTag = nbt.getCompound("Entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void place(World world) {
|
||||||
|
world.addEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
@ -102,6 +103,7 @@ public class SchematicTableTileEntity extends SyncedTileEntity implements ITicka
|
||||||
uploadingProgress = 0;
|
uploadingProgress = 0;
|
||||||
uploadingSchematic = schematic;
|
uploadingSchematic = schematic;
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
|
inventory.setStackInSlot(0, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishUpload() {
|
public void finishUpload() {
|
||||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorldReader;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.fml.network.NetworkHooks;
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
|
||||||
|
@ -52,11 +51,6 @@ public class SchematicannonBlock extends Block implements ITE<SchematicannonTile
|
||||||
return AllShapes.SCHEMATICANNON_SHAPE;
|
return AllShapes.SCHEMATICANNON_SHAPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) {
|
|
||||||
withTileEntityDo(world, pos, SchematicannonTileEntity::findInventories);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
|
|
|
@ -7,11 +7,14 @@ import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
import com.simibubi.create.foundation.block.SafeTileEntityRenderer;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
import com.simibubi.create.foundation.utility.TessellatorHelper;
|
||||||
|
import com.simibubi.create.modules.schematics.block.LaunchedItem.ForBlockState;
|
||||||
|
import com.simibubi.create.modules.schematics.block.LaunchedItem.ForEntity;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
|
@ -20,6 +23,7 @@ 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;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public class SchematicannonRenderer extends SafeTileEntityRenderer<SchematicannonTileEntity> {
|
public class SchematicannonRenderer extends SafeTileEntityRenderer<SchematicannonTileEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,14 +60,14 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tileEntityIn.flyingBlocks.isEmpty()) {
|
if (!tileEntityIn.flyingBlocks.isEmpty()) {
|
||||||
for (LaunchedBlock block : tileEntityIn.flyingBlocks) {
|
for (LaunchedItem launched : tileEntityIn.flyingBlocks) {
|
||||||
|
|
||||||
if (block.ticksRemaining == 0)
|
if (launched.ticksRemaining == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Calculate position of flying block
|
// Calculate position of flying block
|
||||||
Vec3d start = new Vec3d(tileEntityIn.getPos().add(.5f, 1, .5f));
|
Vec3d start = new Vec3d(tileEntityIn.getPos().add(.5f, 1, .5f));
|
||||||
Vec3d target = new Vec3d(block.target).add(-.5, 0, 1);
|
Vec3d target = new Vec3d(launched.target).add(-.5, 0, 1);
|
||||||
Vec3d distance = target.subtract(start);
|
Vec3d distance = target.subtract(start);
|
||||||
|
|
||||||
double targetY = target.y - start.y;
|
double targetY = target.y - start.y;
|
||||||
|
@ -71,10 +75,10 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
||||||
Vec3d cannonOffset = distance.add(0, throwHeight, 0).normalize().scale(2);
|
Vec3d cannonOffset = distance.add(0, throwHeight, 0).normalize().scale(2);
|
||||||
start = start.add(cannonOffset);
|
start = start.add(cannonOffset);
|
||||||
|
|
||||||
double progress = ((double) block.totalTicks - (block.ticksRemaining + 1 - partialTicks))
|
double progress =
|
||||||
/ block.totalTicks;
|
((double) launched.totalTicks - (launched.ticksRemaining + 1 - partialTicks)) / launched.totalTicks;
|
||||||
Vec3d blockLocationXZ = new Vec3d(x + .5, y + .5, z + .5)
|
Vec3d blockLocationXZ =
|
||||||
.add(target.subtract(start).scale(progress).mul(1, 0, 1));
|
new Vec3d(x + .5, y + .5, z + .5).add(target.subtract(start).scale(progress).mul(1, 0, 1));
|
||||||
|
|
||||||
// Height is determined through a bezier curve
|
// Height is determined through a bezier curve
|
||||||
double t = progress;
|
double t = progress;
|
||||||
|
@ -86,21 +90,32 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer<Schematicanno
|
||||||
GlStateManager.translated(blockLocation.x, blockLocation.y, blockLocation.z);
|
GlStateManager.translated(blockLocation.x, blockLocation.y, blockLocation.z);
|
||||||
|
|
||||||
// Rotation and Scaling effects
|
// Rotation and Scaling effects
|
||||||
double scale = .3f;
|
|
||||||
GlStateManager.rotated(360 * t * 2, 1, 1, 0);
|
GlStateManager.rotated(360 * t * 2, 1, 1, 0);
|
||||||
GlStateManager.scaled(scale, scale, scale);
|
|
||||||
|
|
||||||
// Render the Block
|
// Render the Block
|
||||||
Minecraft.getInstance().getBlockRendererDispatcher().renderBlockBrightness(block.state, 1);
|
if (launched instanceof ForBlockState) {
|
||||||
|
double scale = .3f;
|
||||||
|
GlStateManager.scaled(scale, scale, scale);
|
||||||
|
Minecraft.getInstance().getBlockRendererDispatcher()
|
||||||
|
.renderBlockBrightness(((ForBlockState) launched).state, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the item
|
||||||
|
if (launched instanceof ForEntity) {
|
||||||
|
double scale = 1.2f;
|
||||||
|
GlStateManager.scaled(scale, scale, scale);
|
||||||
|
Minecraft.getInstance().getItemRenderer().renderItem(launched.stack, TransformType.GROUND);
|
||||||
|
}
|
||||||
|
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
|
|
||||||
// Apply Recoil if block was just launched
|
// Apply Recoil if block was just launched
|
||||||
if ((block.ticksRemaining + 1 - partialTicks) > block.totalTicks - 10) {
|
if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10) {
|
||||||
recoil = Math.max(recoil, (block.ticksRemaining + 1 - partialTicks) - block.totalTicks + 10);
|
recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render particles for launch
|
// Render particles for launch
|
||||||
if (block.ticksRemaining == block.totalTicks && tileEntityIn.firstRenderTick) {
|
if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) {
|
||||||
tileEntityIn.firstRenderTick = false;
|
tileEntityIn.firstRenderTick = false;
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
Random r = tileEntityIn.getWorld().getRandom();
|
Random r = tileEntityIn.getWorld().getRandom();
|
||||||
|
|
|
@ -26,7 +26,6 @@ import net.minecraft.client.gui.widget.Widget;
|
||||||
import net.minecraft.client.renderer.Rectangle2d;
|
import net.minecraft.client.renderer.Rectangle2d;
|
||||||
import net.minecraft.client.renderer.RenderHelper;
|
import net.minecraft.client.renderer.RenderHelper;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.item.BlockItem;
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
@ -89,9 +88,8 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
||||||
// Replace settings
|
// Replace settings
|
||||||
replaceLevelButtons = new Vector<>(4);
|
replaceLevelButtons = new Vector<>(4);
|
||||||
replaceLevelIndicators = new Vector<>(4);
|
replaceLevelIndicators = new Vector<>(4);
|
||||||
List<ScreenResources> icons = ImmutableList.of(ScreenResources.I_DONT_REPLACE,
|
List<ScreenResources> icons = ImmutableList.of(ScreenResources.I_DONT_REPLACE, ScreenResources.I_REPLACE_SOLID,
|
||||||
ScreenResources.I_REPLACE_SOLID, ScreenResources.I_REPLACE_ANY,
|
ScreenResources.I_REPLACE_ANY, ScreenResources.I_REPLACE_EMPTY);
|
||||||
ScreenResources.I_REPLACE_EMPTY);
|
|
||||||
List<String> toolTips = ImmutableList.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"),
|
List<String> toolTips = ImmutableList.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"),
|
||||||
Lang.translate("gui.schematicannon.option.replaceWithSolid"),
|
Lang.translate("gui.schematicannon.option.replaceWithSolid"),
|
||||||
Lang.translate("gui.schematicannon.option.replaceWithAny"),
|
Lang.translate("gui.schematicannon.option.replaceWithAny"),
|
||||||
|
@ -215,10 +213,9 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
||||||
String msg = Lang.translate("schematicannon.status." + te.statusMsg);
|
String msg = Lang.translate("schematicannon.status." + te.statusMsg);
|
||||||
int stringWidth = font.getStringWidth(msg);
|
int stringWidth = font.getStringWidth(msg);
|
||||||
|
|
||||||
if (te.missingBlock != null) {
|
if (te.missingItem != null) {
|
||||||
stringWidth += 15;
|
stringWidth += 15;
|
||||||
itemRenderer.renderItemIntoGUI(new ItemStack(BlockItem.BLOCK_TO_ITEM.get(te.missingBlock.getBlock())),
|
itemRenderer.renderItemIntoGUI(te.missingItem, guiLeft + 145, guiTop + 25);
|
||||||
guiLeft + 145, guiTop + 25);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
font.drawStringWithShadow(msg, guiLeft + 20 + 96 - stringWidth / 2, guiTop + 30, 0xCCDDFF);
|
font.drawStringWithShadow(msg, guiLeft + 20 + 96 - stringWidth / 2, guiTop + 30, 0xCCDDFF);
|
||||||
|
@ -227,9 +224,10 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
||||||
font.drawString(playerInventory.getDisplayName().getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6,
|
font.drawString(playerInventory.getDisplayName().getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6,
|
||||||
0x666666);
|
0x666666);
|
||||||
|
|
||||||
//to see or debug the bounds of the extra area uncomment the following lines
|
// to see or debug the bounds of the extra area uncomment the following lines
|
||||||
//Rectangle2d r = extraAreas.get(0);
|
// Rectangle2d r = extraAreas.get(0);
|
||||||
//fill(r.getX() + r.getWidth(), r.getY() + r.getHeight(), r.getX(), r.getY(), 0xd3d3d3d3);
|
// fill(r.getX() + r.getWidth(), r.getY() + r.getHeight(), r.getX(), r.getY(),
|
||||||
|
// 0xd3d3d3d3);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void renderCannon() {
|
protected void renderCannon() {
|
||||||
|
@ -282,21 +280,27 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
||||||
if (mouseX >= fuelX && mouseY >= fuelY && mouseX <= fuelX + ScreenResources.SCHEMATICANNON_FUEL.width
|
if (mouseX >= fuelX && mouseY >= fuelY && mouseX <= fuelX + ScreenResources.SCHEMATICANNON_FUEL.width
|
||||||
&& mouseY <= fuelY + ScreenResources.SCHEMATICANNON_FUEL.height) {
|
&& mouseY <= fuelY + ScreenResources.SCHEMATICANNON_FUEL.height) {
|
||||||
container.getTileEntity();
|
container.getTileEntity();
|
||||||
|
|
||||||
double fuelUsageRate = te.getFuelUsageRate();
|
double fuelUsageRate = te.getFuelUsageRate();
|
||||||
int shotsLeft = (int) (te.fuelLevel / fuelUsageRate);
|
int shotsLeft = (int) (te.fuelLevel / fuelUsageRate);
|
||||||
int shotsLeftWithItems = (int) (shotsLeft
|
int shotsLeftWithItems = (int) (shotsLeft
|
||||||
+ te.inventory.getStackInSlot(4).getCount() * (te.getFuelAddedByGunPowder() / fuelUsageRate));
|
+ te.inventory.getStackInSlot(4).getCount() * (te.getFuelAddedByGunPowder() / fuelUsageRate));
|
||||||
renderTooltip(ImmutableList.of(Lang.translate(_gunpowderLevel, "" + (int) (te.fuelLevel * 100)),
|
|
||||||
GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft),
|
List<String> tooltip = new ArrayList<>();
|
||||||
GRAY + Lang.translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems)),
|
tooltip.add(Lang.translate(_gunpowderLevel, "" + (int) (te.fuelLevel * 100)));
|
||||||
mouseX, mouseY);
|
tooltip.add(GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft));
|
||||||
|
if (shotsLeftWithItems != shotsLeft)
|
||||||
|
tooltip.add(GRAY
|
||||||
|
+ Lang.translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems));
|
||||||
|
|
||||||
|
renderTooltip(tooltip, mouseX, mouseY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (te.missingBlock != null) {
|
if (te.missingItem != null) {
|
||||||
int missingBlockX = guiLeft + 145, missingBlockY = guiTop + 25;
|
int missingBlockX = guiLeft + 145, missingBlockY = guiTop + 25;
|
||||||
if (mouseX >= missingBlockX && mouseY >= missingBlockY && mouseX <= missingBlockX + 16
|
if (mouseX >= missingBlockX && mouseY >= missingBlockY && mouseX <= missingBlockX + 16
|
||||||
&& mouseY <= missingBlockY + 16) {
|
&& mouseY <= missingBlockY + 16) {
|
||||||
renderTooltip(new ItemStack(BlockItem.BLOCK_TO_ITEM.get(te.missingBlock.getBlock())), mouseX, mouseY);
|
renderTooltip(te.missingItem, mouseX, mouseY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@ import com.simibubi.create.config.AllConfigs;
|
||||||
import com.simibubi.create.config.CSchematics;
|
import com.simibubi.create.config.CSchematics;
|
||||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
|
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement;
|
||||||
|
import com.simibubi.create.modules.schematics.ItemRequirement.ItemUseType;
|
||||||
import com.simibubi.create.modules.schematics.MaterialChecklist;
|
import com.simibubi.create.modules.schematics.MaterialChecklist;
|
||||||
import com.simibubi.create.modules.schematics.SchematicWorld;
|
import com.simibubi.create.modules.schematics.SchematicWorld;
|
||||||
import com.simibubi.create.modules.schematics.item.SchematicItem;
|
import com.simibubi.create.modules.schematics.item.SchematicItem;
|
||||||
|
@ -18,6 +22,7 @@ import com.simibubi.create.modules.schematics.item.SchematicItem;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.PistonHeadBlock;
|
import net.minecraft.block.PistonHeadBlock;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.container.Container;
|
import net.minecraft.inventory.container.Container;
|
||||||
|
@ -33,7 +38,6 @@ import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.state.properties.BedPart;
|
import net.minecraft.state.properties.BedPart;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.state.properties.DoubleBlockHalf;
|
import net.minecraft.state.properties.DoubleBlockHalf;
|
||||||
import net.minecraft.state.properties.SlabType;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -48,6 +52,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider {
|
public class SchematicannonTileEntity extends SmartTileEntity implements INamedContainerProvider {
|
||||||
|
|
||||||
|
@ -71,17 +76,18 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
public BlockPos currentPos;
|
public BlockPos currentPos;
|
||||||
public BlockPos schematicAnchor;
|
public BlockPos schematicAnchor;
|
||||||
public boolean schematicLoaded;
|
public boolean schematicLoaded;
|
||||||
public BlockState missingBlock;
|
public ItemStack missingItem;
|
||||||
public boolean blockNotLoaded;
|
public boolean positionNotLoaded;
|
||||||
public boolean hasCreativeCrate;
|
public boolean hasCreativeCrate;
|
||||||
private int printerCooldown;
|
private int printerCooldown;
|
||||||
private int skipsLeft;
|
private int skipsLeft;
|
||||||
private boolean blockSkipped;
|
private boolean blockSkipped;
|
||||||
|
private int printingEntityIndex;
|
||||||
|
|
||||||
public BlockPos target;
|
public BlockPos target;
|
||||||
public BlockPos previousTarget;
|
public BlockPos previousTarget;
|
||||||
public List<IItemHandler> attachedInventories;
|
public List<IItemHandler> attachedInventories;
|
||||||
public List<LaunchedBlock> flyingBlocks;
|
public List<LaunchedItem> flyingBlocks;
|
||||||
public MaterialChecklist checklist;
|
public MaterialChecklist checklist;
|
||||||
|
|
||||||
// Gui information
|
// Gui information
|
||||||
|
@ -124,6 +130,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
inventory = new SchematicannonInventory(this);
|
inventory = new SchematicannonInventory(this);
|
||||||
statusMsg = "idle";
|
statusMsg = "idle";
|
||||||
state = State.STOPPED;
|
state = State.STOPPED;
|
||||||
|
printingEntityIndex = -1;
|
||||||
replaceMode = 2;
|
replaceMode = 2;
|
||||||
neighbourCheckCooldown = NEIGHBOUR_CHECKING;
|
neighbourCheckCooldown = NEIGHBOUR_CHECKING;
|
||||||
checklist = new MaterialChecklist();
|
checklist = new MaterialChecklist();
|
||||||
|
@ -143,8 +150,8 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
TileEntity tileEntity = world.getTileEntity(pos.offset(facing));
|
TileEntity tileEntity = world.getTileEntity(pos.offset(facing));
|
||||||
if (tileEntity != null) {
|
if (tileEntity != null) {
|
||||||
LazyOptional<IItemHandler> capability = tileEntity
|
LazyOptional<IItemHandler> capability =
|
||||||
.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite());
|
tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite());
|
||||||
if (capability.isPresent()) {
|
if (capability.isPresent()) {
|
||||||
attachedInventories.add(capability.orElse(null));
|
attachedInventories.add(capability.orElse(null));
|
||||||
}
|
}
|
||||||
|
@ -174,11 +181,11 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
state = State.valueOf(compound.getString("State"));
|
state = State.valueOf(compound.getString("State"));
|
||||||
blocksPlaced = compound.getInt("AmountPlaced");
|
blocksPlaced = compound.getInt("AmountPlaced");
|
||||||
blocksToPlace = compound.getInt("AmountToPlace");
|
blocksToPlace = compound.getInt("AmountToPlace");
|
||||||
|
printingEntityIndex = compound.getInt("EntityProgress");
|
||||||
|
|
||||||
if (compound.contains("MissingBlock"))
|
missingItem = null;
|
||||||
missingBlock = NBTUtil.readBlockState(compound.getCompound("MissingBlock"));
|
if (compound.contains("MissingItem"))
|
||||||
else
|
missingItem = ItemStack.read(compound.getCompound("MissingItem"));
|
||||||
missingBlock = null;
|
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
CompoundNBT options = compound.getCompound("Options");
|
CompoundNBT options = compound.getCompound("Options");
|
||||||
|
@ -203,15 +210,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
for (int i = 0; i < tagBlocks.size(); i++) {
|
for (int i = 0; i < tagBlocks.size(); i++) {
|
||||||
CompoundNBT c = tagBlocks.getCompound(i);
|
CompoundNBT c = tagBlocks.getCompound(i);
|
||||||
|
LaunchedItem launched = LaunchedItem.fromNBT(c);
|
||||||
BlockPos readBlockPos = NBTUtil.readBlockPos(c.getCompound("Target"));
|
BlockPos readBlockPos = launched.target;
|
||||||
BlockState readBlockState = NBTUtil.readBlockState(c.getCompound("Block"));
|
|
||||||
int int1 = c.getInt("TicksLeft");
|
|
||||||
int int2 = c.getInt("TotalTicks");
|
|
||||||
|
|
||||||
// Always write to Server tile
|
// Always write to Server tile
|
||||||
if (world == null || !world.isRemote) {
|
if (world == null || !world.isRemote) {
|
||||||
flyingBlocks.add(new LaunchedBlock(this, readBlockPos, readBlockState, int1, int2));
|
flyingBlocks.add(launched);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +228,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
// Add new server side blocks
|
// Add new server side blocks
|
||||||
if (i >= flyingBlocks.size()) {
|
if (i >= flyingBlocks.size()) {
|
||||||
flyingBlocks.add(new LaunchedBlock(this, readBlockPos, readBlockState, int1, int2));
|
flyingBlocks.add(launched);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,9 +260,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
compound.putString("State", state.name());
|
compound.putString("State", state.name());
|
||||||
compound.putInt("AmountPlaced", blocksPlaced);
|
compound.putInt("AmountPlaced", blocksPlaced);
|
||||||
compound.putInt("AmountToPlace", blocksToPlace);
|
compound.putInt("AmountToPlace", blocksToPlace);
|
||||||
|
compound.putInt("EntityProgress", printingEntityIndex);
|
||||||
|
|
||||||
if (missingBlock != null)
|
if (missingItem != null)
|
||||||
compound.put("MissingBlock", NBTUtil.writeBlockState(missingBlock));
|
compound.put("MissingItem", missingItem.serializeNBT());
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
CompoundNBT options = new CompoundNBT();
|
CompoundNBT options = new CompoundNBT();
|
||||||
|
@ -271,14 +276,8 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
if (target != null)
|
if (target != null)
|
||||||
compound.put("Target", NBTUtil.writeBlockPos(target));
|
compound.put("Target", NBTUtil.writeBlockPos(target));
|
||||||
ListNBT tagBlocks = new ListNBT();
|
ListNBT tagBlocks = new ListNBT();
|
||||||
for (LaunchedBlock b : flyingBlocks) {
|
for (LaunchedItem b : flyingBlocks)
|
||||||
CompoundNBT c = new CompoundNBT();
|
tagBlocks.add(b.serializeNBT());
|
||||||
c.putInt("TotalTicks", b.totalTicks);
|
|
||||||
c.putInt("TicksLeft", b.ticksRemaining);
|
|
||||||
c.put("Target", NBTUtil.writeBlockPos(b.target));
|
|
||||||
c.put("Block", NBTUtil.writeBlockState(b.state));
|
|
||||||
tagBlocks.add(c);
|
|
||||||
}
|
|
||||||
compound.put("FlyingBlocks", tagBlocks);
|
compound.put("FlyingBlocks", tagBlocks);
|
||||||
|
|
||||||
return compound;
|
return compound;
|
||||||
|
@ -287,7 +286,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
|
||||||
if (neighbourCheckCooldown-- <= 0) {
|
if (neighbourCheckCooldown-- <= 0) {
|
||||||
neighbourCheckCooldown = NEIGHBOUR_CHECKING;
|
neighbourCheckCooldown = NEIGHBOUR_CHECKING;
|
||||||
findInventories();
|
findInventories();
|
||||||
|
@ -344,7 +343,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.PAUSED && !blockNotLoaded && missingBlock == null && fuelLevel > getFuelUsageRate())
|
if (state == State.PAUSED && !positionNotLoaded && missingItem == null && fuelLevel > getFuelUsageRate())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Initialize Printer
|
// Initialize Printer
|
||||||
|
@ -370,13 +369,13 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
// Update Target
|
// Update Target
|
||||||
if (hasCreativeCrate) {
|
if (hasCreativeCrate) {
|
||||||
if (missingBlock != null) {
|
if (missingItem != null) {
|
||||||
missingBlock = null;
|
missingItem = null;
|
||||||
state = State.RUNNING;
|
state = State.RUNNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (missingBlock == null && !blockNotLoaded) {
|
if (missingItem == null && !positionNotLoaded) {
|
||||||
advanceCurrentPos();
|
advanceCurrentPos();
|
||||||
|
|
||||||
// End reached
|
// End reached
|
||||||
|
@ -387,61 +386,83 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
target = schematicAnchor.add(currentPos);
|
target = schematicAnchor.add(currentPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean entityMode = printingEntityIndex >= 0;
|
||||||
|
|
||||||
// Check block
|
// Check block
|
||||||
if (!getWorld().isAreaLoaded(target, 0)) {
|
if (!getWorld().isAreaLoaded(target, 0)) {
|
||||||
blockNotLoaded = true;
|
positionNotLoaded = true;
|
||||||
statusMsg = "targetNotLoaded";
|
statusMsg = "targetNotLoaded";
|
||||||
state = State.PAUSED;
|
state = State.PAUSED;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (blockNotLoaded) {
|
if (positionNotLoaded) {
|
||||||
blockNotLoaded = false;
|
positionNotLoaded = false;
|
||||||
state = State.RUNNING;
|
state = State.RUNNING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockState blockState = blockReader.getBlockState(target);
|
boolean shouldSkip = false;
|
||||||
ItemStack requiredItem = getItemForBlock(blockState);
|
BlockState blockState = Blocks.AIR.getDefaultState();
|
||||||
|
ItemRequirement requirement;
|
||||||
|
|
||||||
if (!shouldPlace(target, blockState) || requiredItem.isEmpty()) {
|
if (entityMode) {
|
||||||
|
requirement = ItemRequirement.of(blockReader.getEntities().get(printingEntityIndex));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
blockState = blockReader.getBlockState(target);
|
||||||
|
requirement = ItemRequirement.of(blockState);
|
||||||
|
shouldSkip = !shouldPlace(target, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSkip || requirement.isInvalid()) {
|
||||||
statusMsg = "searching";
|
statusMsg = "searching";
|
||||||
blockSkipped = true;
|
blockSkipped = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find item
|
// Find item
|
||||||
if (blockState.has(BlockStateProperties.SLAB_TYPE)
|
List<ItemStack> requiredItems = requirement.getRequiredItems();
|
||||||
&& blockState.get(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE)
|
if (!requirement.isEmpty()) {
|
||||||
requiredItem.setCount(2);
|
for (ItemStack required : requiredItems) {
|
||||||
|
if (!grabItemsFromAttachedInventories(required, requirement.getUsage(), true)) {
|
||||||
|
if (skipMissing) {
|
||||||
|
statusMsg = "skipping";
|
||||||
|
blockSkipped = true;
|
||||||
|
if (missingItem != null) {
|
||||||
|
missingItem = null;
|
||||||
|
state = State.RUNNING;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!findItemInAttachedInventories(requiredItem)) {
|
missingItem = required;
|
||||||
if (skipMissing) {
|
state = State.PAUSED;
|
||||||
statusMsg = "skipping";
|
statusMsg = "missingBlock";
|
||||||
blockSkipped = true;
|
return;
|
||||||
if (missingBlock != null) {
|
|
||||||
missingBlock = null;
|
|
||||||
state = State.RUNNING;
|
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
missingBlock = blockState;
|
for (ItemStack required : requiredItems)
|
||||||
state = State.PAUSED;
|
grabItemsFromAttachedInventories(required, requirement.getUsage(), false);
|
||||||
statusMsg = "missingBlock";
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
state = State.RUNNING;
|
state = State.RUNNING;
|
||||||
if (blockState.getBlock() != Blocks.AIR)
|
if (blockState.getBlock() != Blocks.AIR || entityMode)
|
||||||
statusMsg = "placing";
|
statusMsg = "placing";
|
||||||
else
|
else
|
||||||
statusMsg = "clearing";
|
statusMsg = "clearing";
|
||||||
launchBlock(target, blockState);
|
|
||||||
|
ItemStack icon = requirement.isEmpty() || requiredItems.isEmpty() ? ItemStack.EMPTY : requiredItems.get(0);
|
||||||
|
if (entityMode)
|
||||||
|
launchEntity(target, icon, blockReader.getEntities().get(printingEntityIndex));
|
||||||
|
else
|
||||||
|
launchBlock(target, icon, blockState);
|
||||||
|
|
||||||
printerCooldown = config().schematicannonDelay.get();
|
printerCooldown = config().schematicannonDelay.get();
|
||||||
fuelLevel -= getFuelUsageRate();
|
fuelLevel -= getFuelUsageRate();
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
missingBlock = null;
|
missingItem = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getFuelUsageRate() {
|
public double getFuelUsageRate() {
|
||||||
|
@ -487,6 +508,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
schematicLoaded = true;
|
schematicLoaded = true;
|
||||||
state = State.PAUSED;
|
state = State.PAUSED;
|
||||||
statusMsg = "ready";
|
statusMsg = "ready";
|
||||||
|
printingEntityIndex = -1;
|
||||||
updateChecklist();
|
updateChecklist();
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
blocksToPlace += blocksPlaced;
|
blocksToPlace += blocksPlaced;
|
||||||
|
@ -498,44 +520,82 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
return item == Items.AIR ? ItemStack.EMPTY : new ItemStack(item);
|
return item == Items.AIR ? ItemStack.EMPTY : new ItemStack(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean findItemInAttachedInventories(ItemStack requiredItem) {
|
protected boolean grabItemsFromAttachedInventories(ItemStack required, ItemUseType usage, boolean simulate) {
|
||||||
if (hasCreativeCrate)
|
if (hasCreativeCrate)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
boolean two = requiredItem.getCount() == 2;
|
// Find and apply damage
|
||||||
int lastSlot = -1;
|
if (usage == ItemUseType.DAMAGE) {
|
||||||
|
for (IItemHandler iItemHandler : attachedInventories) {
|
||||||
|
for (int slot = 0; slot < iItemHandler.getSlots(); slot++) {
|
||||||
|
ItemStack extractItem = iItemHandler.extractItem(slot, 1, true);
|
||||||
|
if (!ItemRequirement.validate(required, extractItem))
|
||||||
|
continue;
|
||||||
|
if (!extractItem.isDamageable())
|
||||||
|
continue;
|
||||||
|
|
||||||
for (IItemHandler iItemHandler : attachedInventories) {
|
if (!simulate) {
|
||||||
for (int slot = 0; slot < iItemHandler.getSlots(); slot++) {
|
ItemStack stack = iItemHandler.extractItem(slot, 1, false);
|
||||||
ItemStack stackInSlot = iItemHandler.getStackInSlot(slot);
|
stack.setDamage(stack.getDamage() + 1);
|
||||||
if (!stackInSlot.isItemEqual(requiredItem))
|
if (stack.getDamage() <= stack.getMaxDamage()) {
|
||||||
continue;
|
if (iItemHandler.getStackInSlot(slot).isEmpty())
|
||||||
if (!two && !iItemHandler.extractItem(slot, 1, false).isEmpty())
|
iItemHandler.insertItem(slot, stack, false);
|
||||||
return true;
|
else
|
||||||
|
ItemHandlerHelper.insertItem(iItemHandler, stack, false);
|
||||||
// Two Items required (Double slabs)
|
|
||||||
if (two) {
|
|
||||||
int count = iItemHandler.extractItem(slot, 2, true).getCount();
|
|
||||||
if (count == 2) {
|
|
||||||
iItemHandler.extractItem(slot, 2, false);
|
|
||||||
return true;
|
|
||||||
} else if (count == 1) {
|
|
||||||
if (lastSlot == -1)
|
|
||||||
lastSlot = slot;
|
|
||||||
else {
|
|
||||||
iItemHandler.extractItem(lastSlot, 1, false);
|
|
||||||
iItemHandler.extractItem(slot, 1, false);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// Find and remove
|
||||||
|
boolean success = false;
|
||||||
|
if (usage == ItemUseType.CONSUME) {
|
||||||
|
int amountFound = 0;
|
||||||
|
for (IItemHandler iItemHandler : attachedInventories) {
|
||||||
|
|
||||||
|
amountFound += ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required, s),
|
||||||
|
ExtractionCountMode.UPTO, required.getCount(), true).getCount();
|
||||||
|
|
||||||
|
if (amountFound < required.getCount())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!simulate && success) {
|
||||||
|
int amountFound = 0;
|
||||||
|
for (IItemHandler iItemHandler : attachedInventories) {
|
||||||
|
amountFound += ItemHelper.extract(iItemHandler, s -> ItemRequirement.validate(required, s),
|
||||||
|
ExtractionCountMode.UPTO, required.getCount(), false).getCount();
|
||||||
|
if (amountFound < required.getCount())
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void advanceCurrentPos() {
|
protected void advanceCurrentPos() {
|
||||||
|
List<Entity> entities = blockReader.getEntities();
|
||||||
|
if (printingEntityIndex != -1) {
|
||||||
|
printingEntityIndex++;
|
||||||
|
|
||||||
|
// End of entities reached
|
||||||
|
if (printingEntityIndex >= entities.size()) {
|
||||||
|
finishedPrinting();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentPos = entities.get(printingEntityIndex).getPosition().subtract(schematicAnchor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BlockPos size = blockReader.getBounds().getSize();
|
BlockPos size = blockReader.getBounds().getSize();
|
||||||
currentPos = currentPos.offset(Direction.EAST);
|
currentPos = currentPos.offset(Direction.EAST);
|
||||||
BlockPos posInBounds = currentPos.subtract(blockReader.getBounds().getOrigin());
|
BlockPos posInBounds = currentPos.subtract(blockReader.getBounds().getOrigin());
|
||||||
|
@ -545,29 +605,38 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
if (posInBounds.getZ() > size.getZ())
|
if (posInBounds.getZ() > size.getZ())
|
||||||
currentPos = new BlockPos(currentPos.getX(), currentPos.getY() + 1, blockReader.getBounds().z).west();
|
currentPos = new BlockPos(currentPos.getX(), currentPos.getY() + 1, blockReader.getBounds().z).west();
|
||||||
|
|
||||||
// End reached
|
// End of blocks reached
|
||||||
if (currentPos.getY() > size.getY()) {
|
if (currentPos.getY() > size.getY()) {
|
||||||
inventory.setStackInSlot(0, ItemStack.EMPTY);
|
printingEntityIndex = 0;
|
||||||
inventory.setStackInSlot(1,
|
if (entities.isEmpty()) {
|
||||||
new ItemStack(AllItems.EMPTY_BLUEPRINT.get(), inventory.getStackInSlot(1).getCount() + 1));
|
finishedPrinting();
|
||||||
state = State.STOPPED;
|
return;
|
||||||
statusMsg = "finished";
|
}
|
||||||
resetPrinter();
|
currentPos = entities.get(0).getPosition().subtract(schematicAnchor);
|
||||||
target = getPos().add(1, 0, 0);
|
|
||||||
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), AllSoundEvents.SCHEMATICANNON_FINISH.get(),
|
|
||||||
SoundCategory.BLOCKS, 1, .7f);
|
|
||||||
sendUpdate = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void finishedPrinting() {
|
||||||
|
inventory.setStackInSlot(0, ItemStack.EMPTY);
|
||||||
|
inventory.setStackInSlot(1,
|
||||||
|
new ItemStack(AllItems.EMPTY_BLUEPRINT.get(), inventory.getStackInSlot(1).getCount() + 1));
|
||||||
|
state = State.STOPPED;
|
||||||
|
statusMsg = "finished";
|
||||||
|
resetPrinter();
|
||||||
|
target = getPos().add(1, 0, 0);
|
||||||
|
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), AllSoundEvents.SCHEMATICANNON_FINISH.get(),
|
||||||
|
SoundCategory.BLOCKS, 1, .7f);
|
||||||
|
sendUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
protected void resetPrinter() {
|
protected void resetPrinter() {
|
||||||
schematicLoaded = false;
|
schematicLoaded = false;
|
||||||
schematicAnchor = null;
|
schematicAnchor = null;
|
||||||
currentPos = null;
|
currentPos = null;
|
||||||
blockReader = null;
|
blockReader = null;
|
||||||
missingBlock = null;
|
missingItem = null;
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
|
printingEntityIndex = -1;
|
||||||
schematicProgress = 0;
|
schematicProgress = 0;
|
||||||
blocksPlaced = 0;
|
blocksPlaced = 0;
|
||||||
blocksToPlace = 0;
|
blocksToPlace = 0;
|
||||||
|
@ -577,6 +646,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
BlockState toReplace = world.getBlockState(pos);
|
BlockState toReplace = world.getBlockState(pos);
|
||||||
boolean placingAir = state.getBlock() == Blocks.AIR;
|
boolean placingAir = state.getBlock() == Blocks.AIR;
|
||||||
|
|
||||||
|
if (!world.isBlockPresent(pos))
|
||||||
|
return false;
|
||||||
|
if (!world.getWorldBorder().contains(pos))
|
||||||
|
return false;
|
||||||
if (toReplace == state)
|
if (toReplace == state)
|
||||||
return false;
|
return false;
|
||||||
if (toReplace.getBlockHardness(world, pos) == -1)
|
if (toReplace.getBlockHardness(world, pos) == -1)
|
||||||
|
@ -622,21 +695,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void tickFlyingBlocks() {
|
protected void tickFlyingBlocks() {
|
||||||
List<LaunchedBlock> toRemove = new LinkedList<>();
|
List<LaunchedItem> toRemove = new LinkedList<>();
|
||||||
for (LaunchedBlock b : flyingBlocks) {
|
for (LaunchedItem b : flyingBlocks)
|
||||||
b.update();
|
if (b.update(world))
|
||||||
if (b.ticksRemaining <= 0 && !world.isRemote) {
|
|
||||||
|
|
||||||
// Piston
|
|
||||||
if (b.state.has(BlockStateProperties.EXTENDED)) {
|
|
||||||
b.state = b.state.with(BlockStateProperties.EXTENDED, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
world.setBlockState(b.target, b.state, 18);
|
|
||||||
b.state.getBlock().onBlockPlacedBy(world, b.target, b.state, null, getItemForBlock(b.state));
|
|
||||||
toRemove.add(b);
|
toRemove.add(b);
|
||||||
}
|
|
||||||
}
|
|
||||||
flyingBlocks.removeAll(toRemove);
|
flyingBlocks.removeAll(toRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,10 +758,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void launchBlock(BlockPos target, BlockState state) {
|
protected void launchBlock(BlockPos target, ItemStack stack, BlockState state) {
|
||||||
if (state.getBlock() != Blocks.AIR)
|
if (state.getBlock() != Blocks.AIR)
|
||||||
blocksPlaced++;
|
blocksPlaced++;
|
||||||
flyingBlocks.add(new LaunchedBlock(this, target, state));
|
flyingBlocks.add(new LaunchedItem.ForBlockState(this.getPos(), target, stack, state));
|
||||||
|
playFiringSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void launchEntity(BlockPos target, ItemStack stack, Entity entity) {
|
||||||
|
blocksPlaced++;
|
||||||
|
flyingBlocks.add(new LaunchedItem.ForEntity(this.getPos(), target, stack, entity));
|
||||||
|
playFiringSound();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playFiringSound() {
|
||||||
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), AllSoundEvents.SCHEMATICANNON_LAUNCH_BLOCK.get(),
|
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), AllSoundEvents.SCHEMATICANNON_LAUNCH_BLOCK.get(),
|
||||||
SoundCategory.BLOCKS, .1f, 1.1f);
|
SoundCategory.BLOCKS, .1f, 1.1f);
|
||||||
}
|
}
|
||||||
|
@ -721,6 +793,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
public void updateChecklist() {
|
public void updateChecklist() {
|
||||||
checklist.required.clear();
|
checklist.required.clear();
|
||||||
|
checklist.damageRequired.clear();
|
||||||
checklist.blocksNotLoaded = false;
|
checklist.blocksNotLoaded = false;
|
||||||
|
|
||||||
if (schematicLoaded) {
|
if (schematicLoaded) {
|
||||||
|
@ -734,18 +807,22 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
}
|
}
|
||||||
if (!shouldPlace(pos.add(schematicAnchor), required))
|
if (!shouldPlace(pos.add(schematicAnchor), required))
|
||||||
continue;
|
continue;
|
||||||
ItemStack requiredItem = getItemForBlock(required);
|
ItemRequirement requirement = ItemRequirement.of(required);
|
||||||
if (requiredItem.isEmpty())
|
if (requirement.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
if (requirement.isInvalid())
|
||||||
// Two items for double slabs
|
continue;
|
||||||
if (required.has(BlockStateProperties.SLAB_TYPE)
|
checklist.require(requirement);
|
||||||
&& required.get(BlockStateProperties.SLAB_TYPE) == SlabType.DOUBLE)
|
|
||||||
checklist.require(requiredItem.getItem());
|
|
||||||
|
|
||||||
checklist.require(requiredItem.getItem());
|
|
||||||
blocksToPlace++;
|
blocksToPlace++;
|
||||||
}
|
}
|
||||||
|
for (Entity entity : blockReader.getEntities()) {
|
||||||
|
ItemRequirement requirement = ItemRequirement.of(entity);
|
||||||
|
if (requirement.isEmpty())
|
||||||
|
continue;
|
||||||
|
if (requirement.isInvalid())
|
||||||
|
continue;
|
||||||
|
checklist.require(requirement);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
checklist.gathered.clear();
|
checklist.gathered.clear();
|
||||||
for (IItemHandler inventory : attachedInventories) {
|
for (IItemHandler inventory : attachedInventories) {
|
||||||
|
@ -762,7 +839,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void lazyTick() {
|
public void lazyTick() {
|
||||||
super.lazyTick();
|
super.lazyTick();
|
||||||
|
|
|
@ -225,7 +225,7 @@ public class SchematicAndQuillHandler {
|
||||||
Template t = new Template();
|
Template t = new Template();
|
||||||
MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos);
|
MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos);
|
||||||
t.takeBlocksFromWorld(Minecraft.getInstance().world, new BlockPos(bb.minX, bb.minY, bb.minZ),
|
t.takeBlocksFromWorld(Minecraft.getInstance().world, new BlockPos(bb.minX, bb.minY, bb.minZ),
|
||||||
new BlockPos(bb.getXSize(), bb.getYSize(), bb.getZSize()), false, Blocks.AIR);
|
new BlockPos(bb.getXSize(), bb.getYSize(), bb.getZSize()), true, Blocks.AIR);
|
||||||
|
|
||||||
if (string.isEmpty())
|
if (string.isEmpty())
|
||||||
string = Lang.translate("schematicAndQuill.fallbackName");
|
string = Lang.translate("schematicAndQuill.fallbackName");
|
||||||
|
|
|
@ -9,6 +9,7 @@ import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.world.gen.feature.template.PlacementSettings;
|
||||||
import net.minecraft.world.gen.feature.template.Template;
|
import net.minecraft.world.gen.feature.template.Template;
|
||||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
@ -32,8 +33,10 @@ public class SchematicPlacePacket extends SimplePacketBase {
|
||||||
context.get().enqueueWork(() -> {
|
context.get().enqueueWork(() -> {
|
||||||
ServerPlayerEntity player = context.get().getSender();
|
ServerPlayerEntity player = context.get().getSender();
|
||||||
Template t = SchematicItem.loadSchematic(stack);
|
Template t = SchematicItem.loadSchematic(stack);
|
||||||
|
PlacementSettings settings = SchematicItem.getSettings(stack);
|
||||||
|
settings.setIgnoreEntities(false);
|
||||||
t.addBlocksToWorld(player.getServerWorld(), NBTUtil.readBlockPos(stack.getTag().getCompound("Anchor")),
|
t.addBlocksToWorld(player.getServerWorld(), NBTUtil.readBlockPos(stack.getTag().getCompound("Anchor")),
|
||||||
SchematicItem.getSettings(stack));
|
settings);
|
||||||
});
|
});
|
||||||
context.get().setPacketHandled(true);
|
context.get().setPacketHandled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -534,11 +534,11 @@
|
||||||
"create.schematicannon.status.paused": "Paused",
|
"create.schematicannon.status.paused": "Paused",
|
||||||
"create.schematicannon.status.stopped": "Stopped",
|
"create.schematicannon.status.stopped": "Stopped",
|
||||||
"create.schematicannon.status.noGunpowder": "Out of Gunpowder",
|
"create.schematicannon.status.noGunpowder": "Out of Gunpowder",
|
||||||
"create.schematicannon.status.targetNotLoaded": "Block is Not Loaded",
|
"create.schematicannon.status.targetNotLoaded": "Target is not loaded",
|
||||||
"create.schematicannon.status.targetOutsideRange": "Target too Far Away",
|
"create.schematicannon.status.targetOutsideRange": "Target too far away",
|
||||||
"create.schematicannon.status.searching": "Searching",
|
"create.schematicannon.status.searching": "Searching",
|
||||||
"create.schematicannon.status.skipping": "Skipping",
|
"create.schematicannon.status.skipping": "Skipping",
|
||||||
"create.schematicannon.status.missingBlock": "Missing Block:",
|
"create.schematicannon.status.missingBlock": "Missing Item:",
|
||||||
"create.schematicannon.status.placing": "Placing",
|
"create.schematicannon.status.placing": "Placing",
|
||||||
"create.schematicannon.status.clearing": "Clearing Blocks",
|
"create.schematicannon.status.clearing": "Clearing Blocks",
|
||||||
"create.schematicannon.status.schematicInvalid": "Schematic Invalid",
|
"create.schematicannon.status.schematicInvalid": "Schematic Invalid",
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 401 B |
Binary file not shown.
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 444 B |
Loading…
Reference in a new issue