start of upgrading

This commit is contained in:
Ellpeck 2020-04-14 01:38:48 +02:00
parent 46ef0ef0a9
commit ad92be8d7b
16 changed files with 384 additions and 52 deletions

View file

@ -1,14 +1,23 @@
package de.ellpeck.prettypipes;
import de.ellpeck.prettypipes.blocks.PipeBlock;
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
import de.ellpeck.prettypipes.blocks.pipe.PipeContainer;
import de.ellpeck.prettypipes.blocks.pipe.PipeGui;
import de.ellpeck.prettypipes.blocks.pipe.PipeTileEntity;
import de.ellpeck.prettypipes.items.ExtractionUpgradeItem;
import de.ellpeck.prettypipes.items.WrenchItem;
import net.minecraft.block.Block;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@ -23,24 +32,29 @@ public final class Registry {
public static final ItemGroup GROUP = new ItemGroup(PrettyPipes.ID) {
@Override
public ItemStack createIcon() {
return new ItemStack(wrench);
return new ItemStack(wrenchItem);
}
};
public static Item wrench;
public static Block pipe;
public static Item wrenchItem;
public static Item extractionUpgradeItem;
public static Block pipeBlock;
public static TileEntityType<PipeTileEntity> pipeTileEntity;
public static ContainerType<PipeContainer> pipeContainer;
@SubscribeEvent
public static void registerBlocks(RegistryEvent.Register<Block> event) {
event.getRegistry().registerAll(
pipe = new PipeBlock().setRegistryName("pipe")
pipeBlock = new PipeBlock().setRegistryName("pipe")
);
}
@SubscribeEvent
public static void registerItems(RegistryEvent.Register<Item> event) {
event.getRegistry().registerAll(
wrench = new WrenchItem().setRegistryName("wrench")
wrenchItem = new WrenchItem().setRegistryName("wrench"),
extractionUpgradeItem = new ExtractionUpgradeItem().setRegistryName("extraction_upgrade")
);
ForgeRegistries.BLOCKS.getValues().stream()
@ -48,11 +62,29 @@ public final class Registry {
.forEach(b -> event.getRegistry().register(new BlockItem(b, new Item.Properties().group(GROUP)).setRegistryName(b.getRegistryName())));
}
@SubscribeEvent
public static void registerTiles(RegistryEvent.Register<TileEntityType<?>> event) {
event.getRegistry().registerAll(
pipeTileEntity = (TileEntityType<PipeTileEntity>) TileEntityType.Builder.create(PipeTileEntity::new, pipeBlock).build(null).setRegistryName("pipe")
);
}
@SubscribeEvent
public static void registerContainer(RegistryEvent.Register<ContainerType<?>> event) {
event.getRegistry().registerAll(
pipeContainer = (ContainerType<PipeContainer>) IForgeContainerType.create((windowId, inv, data) -> {
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, inv.player.world, data.readBlockPos());
return tile != null ? new PipeContainer(pipeContainer, windowId, inv.player, tile) : null;
}).setRegistryName("pipe")
);
}
public static void setup(FMLCommonSetupEvent event) {
}
public static void setupClient(FMLClientSetupEvent event) {
RenderTypeLookup.setRenderLayer(pipe, RenderType.cutout());
RenderTypeLookup.setRenderLayer(pipeBlock, RenderType.cutout());
ScreenManager.registerFactory(pipeContainer, PipeGui::new);
}
}

View file

@ -0,0 +1,25 @@
package de.ellpeck.prettypipes;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.items.IItemHandler;
public final class Utility {
public static <T extends TileEntity> T getTileEntity(Class<T> type, World world, BlockPos pos) {
TileEntity tile = world.getTileEntity(pos);
return type.isInstance(tile) ? (T) tile : null;
}
public static void dropInventory(TileEntity tile, IItemHandler inventory) {
BlockPos pos = tile.getPos();
for (int i = 0; i < inventory.getSlots(); i++) {
ItemStack stack = inventory.getStackInSlot(i);
if (!stack.isEmpty())
InventoryHelper.spawnItemStack(tile.getWorld(), pos.getX(), pos.getY(), pos.getZ(), stack);
}
}
}

View file

@ -0,0 +1,29 @@
package de.ellpeck.prettypipes.blocks.pipe;
import net.minecraft.util.IStringSerializable;
import java.util.Locale;
public enum ConnectionType implements IStringSerializable {
CONNECTED_PIPE(true),
CONNECTED_INVENTORY(true),
DISCONNECTED(false),
BLOCKED(false);
private final String name;
private final boolean isConnected;
ConnectionType(boolean isConnected) {
this.name = this.name().toLowerCase(Locale.ROOT);
this.isConnected = isConnected;
}
public boolean isConnected() {
return this.isConnected;
}
@Override
public String getName() {
return this.name;
}
}

View file

@ -1,31 +1,38 @@
package de.ellpeck.prettypipes.blocks;
package de.ellpeck.prettypipes.blocks.pipe;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.SoundType;
import de.ellpeck.prettypipes.Utility;
import net.minecraft.block.*;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.item.ItemStack;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.tileentity.AbstractFurnaceTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.datafix.fixes.BlockEntityKeepPacked;
import net.minecraft.util.Hand;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class PipeBlock extends Block {
public class PipeBlock extends ContainerBlock {
public static final Map<Direction, EnumProperty<ConnectionType>> DIRECTIONS = new HashMap<>();
private static final Map<BlockState, VoxelShape> SHAPE_CACHE = new HashMap<>();
@ -53,6 +60,20 @@ public class PipeBlock extends Block {
this.setDefaultState(state);
}
@Override
public ActionResultType onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult p_225533_6_) {
if (!player.getHeldItem(handIn).isEmpty())
return ActionResultType.PASS;
if (DIRECTIONS.values().stream().noneMatch(d -> state.get(d) == ConnectionType.CONNECTED_INVENTORY))
return ActionResultType.PASS;
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos);
if (tile == null)
return ActionResultType.PASS;
if (!worldIn.isRemote)
NetworkHooks.openGui((ServerPlayerEntity) player, tile, pos);
return ActionResultType.SUCCESS;
}
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
builder.add(DIRECTIONS.values().toArray(new EnumProperty[0]));
@ -61,8 +82,10 @@ public class PipeBlock extends Block {
@Override
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
BlockState newState = this.createState(worldIn, pos, state);
if (newState != state)
if (newState != state) {
worldIn.setBlockState(pos, newState);
onStateChanged(worldIn, pos, newState);
}
}
@Nullable
@ -84,7 +107,7 @@ public class PipeBlock extends Block {
shape = CENTER_SHAPE;
for (Map.Entry<Direction, EnumProperty<ConnectionType>> entry : DIRECTIONS.entrySet()) {
if (state.get(entry.getValue()) == ConnectionType.CONNECTED)
if (state.get(entry.getValue()).isConnected())
shape = VoxelShapes.or(shape, DIR_SHAPES.get(entry.getKey()));
}
SHAPE_CACHE.put(state, shape);
@ -95,7 +118,7 @@ public class PipeBlock extends Block {
BlockState state = this.getDefaultState();
for (Map.Entry<Direction, EnumProperty<ConnectionType>> entry : DIRECTIONS.entrySet()) {
ConnectionType type = getConnectionType(world, pos, entry.getKey());
if (type == ConnectionType.CONNECTED && current.get(entry.getValue()) == ConnectionType.BLOCKED)
if (type.isConnected() && current.get(entry.getValue()) == ConnectionType.BLOCKED)
type = ConnectionType.BLOCKED;
state = state.with(entry.getValue(), type);
}
@ -107,27 +130,46 @@ public class PipeBlock extends Block {
if (!world.isBlockLoaded(offset))
return ConnectionType.DISCONNECTED;
BlockState state = world.getBlockState(offset);
if (!(state.getBlock() instanceof PipeBlock))
return ConnectionType.DISCONNECTED;
if (state.get(DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
return ConnectionType.BLOCKED;
return ConnectionType.CONNECTED;
if (state.getBlock() instanceof PipeBlock) {
if (state.get(DIRECTIONS.get(direction.getOpposite())) == ConnectionType.BLOCKED)
return ConnectionType.BLOCKED;
return ConnectionType.CONNECTED_PIPE;
} else {
TileEntity tile = world.getTileEntity(offset);
if (tile == null)
return ConnectionType.DISCONNECTED;
IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite()).orElse(null);
return handler == null ? ConnectionType.DISCONNECTED : ConnectionType.CONNECTED_INVENTORY;
}
}
public enum ConnectionType implements IStringSerializable {
CONNECTED,
DISCONNECTED,
BLOCKED;
private final String name;
ConnectionType() {
this.name = this.name().toLowerCase(Locale.ROOT);
public static void onStateChanged(World world, BlockPos pos, BlockState newState) {
if (DIRECTIONS.values().stream().noneMatch(d -> newState.get(d) == ConnectionType.CONNECTED_INVENTORY)) {
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, world, pos);
if (tile != null)
Utility.dropInventory(tile, tile.upgrades);
}
}
@Override
public String getName() {
return this.name;
@Override
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.getBlock() != newState.getBlock()) {
PipeTileEntity tile = Utility.getTileEntity(PipeTileEntity.class, worldIn, pos);
if (tile != null)
Utility.dropInventory(tile, tile.upgrades);
super.onReplaced(state, worldIn, pos, newState, isMoving);
}
}
@Nullable
@Override
public TileEntity createNewTileEntity(IBlockReader worldIn) {
return new PipeTileEntity();
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
}

View file

@ -0,0 +1,77 @@
package de.ellpeck.prettypipes.blocks.pipe;
import de.ellpeck.prettypipes.items.UpgradeItem;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.inventory.container.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import javax.annotation.Nullable;
public class PipeContainer extends Container {
public PipeContainer(@Nullable ContainerType<?> type, int id, PlayerEntity player, PipeTileEntity tile) {
super(type, id);
for (int i = 0; i < 3; i++)
this.addSlot(new SlotItemHandler(tile.upgrades, i, 62 + i * 18, 17));
for (int l = 0; l < 3; ++l)
for (int j1 = 0; j1 < 9; ++j1)
this.addSlot(new Slot(player.inventory, j1 + l * 9 + 9, 8 + j1 * 18, 89 + l * 18));
for (int i1 = 0; i1 < 9; ++i1)
this.addSlot(new Slot(player.inventory, i1, 8 + i1 * 18, 147));
}
@Override
public boolean canInteractWith(PlayerEntity playerIn) {
return true;
}
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int slotIndex) {
// change this to the amount of slots that we have
int inventoryStart = 3;
int inventoryEnd = inventoryStart + 26;
int hotbarStart = inventoryEnd + 1;
int hotbarEnd = hotbarStart + 8;
Slot slot = this.inventorySlots.get(slotIndex);
if (slot != null && slot.getHasStack()) {
ItemStack newStack = slot.getStack();
ItemStack currentStack = newStack.copy();
if (slotIndex >= inventoryStart) {
// shift into this container here
// mergeItemStack with the slots that newStack should go into
// return an empty stack if mergeItemStack fails
if (newStack.getItem() instanceof UpgradeItem) {
if (!this.mergeItemStack(newStack, 0, 3, false))
return ItemStack.EMPTY;
}
// end custom code
else if (slotIndex >= inventoryStart && slotIndex <= inventoryEnd) {
if (!this.mergeItemStack(newStack, hotbarStart, hotbarEnd + 1, false))
return ItemStack.EMPTY;
} else if (slotIndex >= inventoryEnd + 1 && slotIndex < hotbarEnd + 1 && !this.mergeItemStack(newStack, inventoryStart, inventoryEnd + 1, false)) {
return ItemStack.EMPTY;
}
} else if (!this.mergeItemStack(newStack, inventoryStart, hotbarEnd + 1, false)) {
return ItemStack.EMPTY;
}
if (newStack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if (newStack.getCount() == currentStack.getCount())
return ItemStack.EMPTY;
slot.onTake(player, newStack);
return currentStack;
}
return ItemStack.EMPTY;
}
}

View file

@ -0,0 +1,42 @@
package de.ellpeck.prettypipes.blocks.pipe;
import com.mojang.blaze3d.platform.GlStateManager;
import de.ellpeck.prettypipes.PrettyPipes;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
public class PipeGui extends ContainerScreen<PipeContainer> {
private static final ResourceLocation TEXTURE = new ResourceLocation(PrettyPipes.ID, "textures/gui/pipe.png");
public PipeGui(PipeContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) {
super(screenContainer, inv, titleIn);
this.xSize = 176;
this.ySize = 171;
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
this.renderBackground();
super.render(mouseX, mouseY, partialTicks);
this.renderHoveredToolTip(mouseX, mouseY);
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
this.font.drawString(this.title.getFormattedText(), 8, 6, 4210752);
this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8, this.ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
this.getMinecraft().getTextureManager().bindTexture(TEXTURE);
this.blit(this.guiLeft, this.guiTop, 0, 0, 176, 171);
for (int i = 0; i < 3; i++)
this.blit(this.guiLeft + 61 + i * 18, this.guiTop + 16, 176, 62, 18, 18);
}
}

View file

@ -0,0 +1,55 @@
package de.ellpeck.prettypipes.blocks.pipe;
import de.ellpeck.prettypipes.PrettyPipes;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.items.UpgradeItem;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TranslationTextComponent;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class PipeTileEntity extends TileEntity implements INamedContainerProvider {
public final ItemStackHandler upgrades = new ItemStackHandler(3) {
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
return stack.getItem() instanceof UpgradeItem;
}
};
public PipeTileEntity() {
super(Registry.pipeTileEntity);
}
@Override
public ITextComponent getDisplayName() {
return new TranslationTextComponent("container." + PrettyPipes.ID + ".pipe");
}
@Nullable
@Override
public Container createMenu(int window, PlayerInventory inv, PlayerEntity player) {
return new PipeContainer(Registry.pipeContainer, window, player, this);
}
@Override
public CompoundNBT write(CompoundNBT compound) {
compound.put("upgrades", this.upgrades.serializeNBT());
return super.write(compound);
}
@Override
public void read(CompoundNBT compound) {
this.upgrades.deserializeNBT(compound.getCompound("upgrades"));
super.read(compound);
}
}

View file

@ -0,0 +1,5 @@
package de.ellpeck.prettypipes.items;
public class ExtractionUpgradeItem extends UpgradeItem {
}

View file

@ -0,0 +1,10 @@
package de.ellpeck.prettypipes.items;
import de.ellpeck.prettypipes.Registry;
import net.minecraft.item.Item;
public class UpgradeItem extends Item {
public UpgradeItem() {
super(new Properties().group(Registry.GROUP).maxStackSize(16));
}
}

View file

@ -1,15 +1,14 @@
package de.ellpeck.prettypipes.items;
import de.ellpeck.prettypipes.Registry;
import de.ellpeck.prettypipes.blocks.PipeBlock;
import de.ellpeck.prettypipes.blocks.PipeBlock.ConnectionType;
import de.ellpeck.prettypipes.blocks.pipe.PipeBlock;
import de.ellpeck.prettypipes.blocks.pipe.ConnectionType;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.state.EnumProperty;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.SoundCategory;
@ -17,7 +16,6 @@ import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.world.World;
import java.util.Map;
@ -55,12 +53,20 @@ public class WrenchItem extends Item {
continue;
if (!world.isRemote) {
ConnectionType newType = curr == ConnectionType.BLOCKED ? ConnectionType.CONNECTED : ConnectionType.BLOCKED;
ConnectionType newType = curr == ConnectionType.BLOCKED ? ConnectionType.CONNECTED_PIPE : ConnectionType.BLOCKED;
BlockPos otherPos = pos.offset(entry.getKey());
BlockState otherState = world.getBlockState(otherPos);
if (otherState.getBlock() instanceof PipeBlock) {
otherState = otherState.with(PipeBlock.DIRECTIONS.get(entry.getKey().getOpposite()), newType);
world.setBlockState(otherPos, otherState);
PipeBlock.onStateChanged(world, otherPos, otherState);
} else if (newType == ConnectionType.CONNECTED_PIPE) {
newType = ConnectionType.CONNECTED_INVENTORY;
}
BlockState newState = state.with(prop, newType);
world.setBlockState(pos, newState);
BlockPos otherPos = pos.offset(entry.getKey());
world.setBlockState(otherPos, world.getBlockState(otherPos).with(PipeBlock.DIRECTIONS.get(entry.getKey().getOpposite()), newType));
PipeBlock.onStateChanged(world, pos, newState);
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_FRAME_ROTATE_ITEM, SoundCategory.PLAYERS, 1, 1);
}
return ActionResultType.SUCCESS;
}

View file

@ -7,7 +7,7 @@
},
{
"when": {
"north": "connected"
"north": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end"
@ -15,7 +15,7 @@
},
{
"when": {
"south": "connected"
"south": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end",
@ -24,7 +24,7 @@
},
{
"when": {
"east": "connected"
"east": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end",
@ -33,7 +33,7 @@
},
{
"when": {
"west": "connected"
"west": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end",
@ -42,7 +42,7 @@
},
{
"when": {
"down": "connected"
"down": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end",
@ -51,7 +51,7 @@
},
{
"when": {
"up": "connected"
"up": "connected_pipe|connected_inventory"
},
"apply": {
"model": "prettypipes:block/pipe_end",

View file

@ -1,5 +1,7 @@
{
"item.prettypipes.wrench": "Pipe Wrench",
"item.prettypipes.extraction_upgrade": "Extraction Upgrade",
"block.prettypipes.pipe": "Pipe",
"itemGroup.prettypipes": "Pretty Pipes"
"itemGroup.prettypipes": "Pretty Pipes",
"container.prettypipes.pipe": "Pipe"
}

View file

@ -1,5 +1,6 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "prettypipes:block/pipe",
"particle": "prettypipes:block/pipe"

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "prettypipes:item/extraction_upgrade"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B