From a5621e8fc9a4e0ef5e30e62011865c05d84586b7 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Fri, 4 Jan 2019 19:20:25 +0000 Subject: [PATCH] Initial tiny turtle implementation This currently can be labelled and have upgrades attached on the left and right hand side. --- .../gameplay/client/ClientRegistration.java | 19 ++ .../client/tile/RenderTinyTurtle.java | 133 ++++++++++ .../gameplay/registry/Registration.java | 10 +- .../gameplay/tiny/BlockTinyTurtle.java | 161 ++++++++++++ .../gameplay/tiny/ItemTinyTurtle.java | 92 +++++++ .../gameplay/tiny/TileTinyTurtle.java | 234 ++++++++++++++++++ .../plethora/blockstates/tiny_turtle.json | 8 + .../resources/assets/plethora/lang/en_us.lang | 4 + .../plethora/models/block/tiny_turtle.json | 61 +++++ .../models/item/manipulator.mark_1.json | 9 +- .../models/item/manipulator.mark_2.json | 21 +- .../models/item/redstone_integrator.json | 9 +- .../plethora/models/item/tiny_turtle.json | 3 + .../plethora/textures/blocks/tiny_turtle.png | Bin 0 -> 512 bytes 14 files changed, 726 insertions(+), 38 deletions(-) create mode 100644 src/main/java/org/squiddev/plethora/gameplay/client/tile/RenderTinyTurtle.java create mode 100644 src/main/java/org/squiddev/plethora/gameplay/tiny/BlockTinyTurtle.java create mode 100644 src/main/java/org/squiddev/plethora/gameplay/tiny/ItemTinyTurtle.java create mode 100644 src/main/java/org/squiddev/plethora/gameplay/tiny/TileTinyTurtle.java create mode 100644 src/main/resources/assets/plethora/blockstates/tiny_turtle.json create mode 100644 src/main/resources/assets/plethora/models/block/tiny_turtle.json create mode 100644 src/main/resources/assets/plethora/models/item/tiny_turtle.json create mode 100644 src/main/resources/assets/plethora/textures/blocks/tiny_turtle.png diff --git a/src/main/java/org/squiddev/plethora/gameplay/client/ClientRegistration.java b/src/main/java/org/squiddev/plethora/gameplay/client/ClientRegistration.java index d15ee435..43029ee5 100644 --- a/src/main/java/org/squiddev/plethora/gameplay/client/ClientRegistration.java +++ b/src/main/java/org/squiddev/plethora/gameplay/client/ClientRegistration.java @@ -1,6 +1,7 @@ package org.squiddev.plethora.gameplay.client; import net.minecraft.item.Item; +import net.minecraftforge.client.event.ColorHandlerEvent; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.RenderingRegistry; @@ -12,11 +13,14 @@ import org.squiddev.plethora.gameplay.client.entity.RenderLaser; import org.squiddev.plethora.gameplay.client.entity.RenderMinecartComputer; import org.squiddev.plethora.gameplay.client.tile.RenderManipulator; +import org.squiddev.plethora.gameplay.client.tile.RenderTinyTurtle; import org.squiddev.plethora.gameplay.minecart.EntityMinecartComputer; import org.squiddev.plethora.gameplay.modules.EntityLaser; import org.squiddev.plethora.gameplay.modules.ManipulatorType; import org.squiddev.plethora.gameplay.modules.PlethoraModules; import org.squiddev.plethora.gameplay.modules.TileManipulator; +import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle; +import org.squiddev.plethora.gameplay.tiny.TileTinyTurtle; import org.squiddev.plethora.utils.Helpers; import static org.squiddev.plethora.gameplay.registry.Registration.*; @@ -47,6 +51,8 @@ public static void registerModels(ModelRegistryEvent event) { @SideOnly(Side.CLIENT) public static void preInit() { ClientRegistry.bindTileEntitySpecialRenderer(TileManipulator.class, new RenderManipulator()); + ClientRegistry.bindTileEntitySpecialRenderer(TileTinyTurtle.class, new RenderTinyTurtle()); + RenderingRegistry.registerEntityRenderingHandler(EntityMinecartComputer.class, RenderMinecartComputer::new); RenderingRegistry.registerEntityRenderingHandler(EntityLaser.class, RenderLaser::new); } @@ -56,4 +62,17 @@ public static void init() { RenderSquidOverlay.init(); RenderInterfaceLiving.init(); } + + @SubscribeEvent + @SideOnly(Side.CLIENT) + public static void registerColour(ColorHandlerEvent.Item event) { + event.getItemColors().registerItemColorHandler((stack, tintIndex) -> { + if (tintIndex == 0) { + int colour = itemTinyTurtle.getColour(stack); + return colour == -1 ? BlockTinyTurtle.DEFAULT_COLOUR : colour; + } + + return 0xFFFFFF; + }, itemTinyTurtle); + } } diff --git a/src/main/java/org/squiddev/plethora/gameplay/client/tile/RenderTinyTurtle.java b/src/main/java/org/squiddev/plethora/gameplay/client/tile/RenderTinyTurtle.java new file mode 100644 index 00000000..10426340 --- /dev/null +++ b/src/main/java/org/squiddev/plethora/gameplay/client/tile/RenderTinyTurtle.java @@ -0,0 +1,133 @@ +package org.squiddev.plethora.gameplay.client.tile; + +import dan200.computercraft.api.turtle.ITurtleUpgrade; +import dan200.computercraft.api.turtle.TurtleSide; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.EntityRenderer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ModelManager; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.entity.Entity; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.pipeline.LightUtil; +import org.apache.commons.lang3.tuple.Pair; +import org.lwjgl.opengl.GL11; +import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle; +import org.squiddev.plethora.gameplay.tiny.TileTinyTurtle; + +import javax.annotation.Nonnull; +import javax.vecmath.Matrix4f; +import java.util.List; + +public class RenderTinyTurtle extends TileEntitySpecialRenderer { + private static final ModelResourceLocation MODEL = new ModelResourceLocation("plethora:tiny_turtle", "facing=north"); + + @Override + public void render(TileTinyTurtle te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) { + renderTurtleAt(te, x, y, z, partialTicks); + super.render(te, x, y, z, partialTicks, destroyStage, alpha); + } + + private void renderTurtleAt(TileTinyTurtle turtle, double x, double y, double z, float partialTicks) { + IBlockState state = turtle.getWorld().getBlockState(turtle.getPos()); + GlStateManager.pushMatrix(); + + String label = turtle.getLabel(); + + GlStateManager.translate(x, y, z); + GlStateManager.translate(0.5f, 0.5f, 0.5f); + GlStateManager.rotate(180.0f - turtle.getFacing().getHorizontalAngle(), 0.0f, 1.0f, 0.0f); + if (label != null && (label.equals("Dinnerbone") || label.equals("Grumm"))) { + // Flip the model and swap the cull face as winding order will have changed. + GlStateManager.scale(1.0f, -1.0f, 1.0f); + GlStateManager.cullFace(GlStateManager.CullFace.FRONT); + } + GlStateManager.translate(-0.5f, -0.5f, -0.5f); + + int colour = turtle.getColour(); + + renderModel(state, MODEL, new int[]{colour == -1 ? BlockTinyTurtle.DEFAULT_COLOUR : colour}); + renderUpgrade(state, turtle, TurtleSide.Left, partialTicks); + renderUpgrade(state, turtle, TurtleSide.Right, partialTicks); + + GlStateManager.cullFace(GlStateManager.CullFace.BACK); + + GlStateManager.popMatrix(); + } + + private void renderUpgrade(IBlockState state, TileTinyTurtle turtle, TurtleSide side, float partialTicks) { + ITurtleUpgrade upgrade = turtle.getUpgrade(side); + if (upgrade == null) return; + GlStateManager.pushMatrix(); + + GlStateManager.translate(0.5f, 0.0f, 0.5f); + GlStateManager.scale(0.5f, 0.5f, 0.5f); + GlStateManager.translate(-0.5f, 0.5f, -0.5f); + + Pair pair = upgrade.getModel(null, side); + if (pair != null) { + if (pair.getRight() != null) ForgeHooksClient.multiplyCurrentGlMatrix(pair.getRight()); + if (pair.getLeft() != null) renderModel(state, pair.getLeft(), null); + } + + GlStateManager.popMatrix(); + } + + private void renderModel(IBlockState state, ModelResourceLocation model, int[] tints) { + Minecraft mc = Minecraft.getMinecraft(); + ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager(); + renderModel(state, modelManager.getModel(model), tints); + } + + private void renderModel(IBlockState state, IBakedModel model, int[] tints) { + Tessellator tessellator = Tessellator.getInstance(); + bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); + renderQuads(tessellator, model.getQuads(state, null, 0), tints); + for (EnumFacing facing : EnumFacing.VALUES) { + renderQuads(tessellator, model.getQuads(state, facing, 0), tints); + } + } + + private void renderQuads(Tessellator tessellator, List quads, int[] tints) { + BufferBuilder buffer = tessellator.getBuffer(); + VertexFormat format = DefaultVertexFormats.ITEM; + buffer.begin(GL11.GL_QUADS, format); + + for (BakedQuad quad : quads) { + VertexFormat quadFormat = quad.getFormat(); + if (quadFormat != format) { + tessellator.draw(); + format = quadFormat; + buffer.begin(GL11.GL_QUADS, quadFormat); + } + + int index = quad.getTintIndex(); + int colour = tints != null && index >= 0 && index < tints.length ? tints[index] | -16777216 : -1; + LightUtil.renderQuadColor(buffer, quad, colour); + } + + tessellator.draw(); + } + + @Override + protected void drawNameplate(TileTinyTurtle te, @Nonnull String label, double x, double y, double z, int maxDistance) { + Entity entity = rendererDispatcher.entity; + double distance = te.getDistanceSq(entity.posX, entity.posY, entity.posZ); + + if (distance <= (double) (maxDistance * maxDistance)) { + float yaw = rendererDispatcher.entityYaw; + float pitch = rendererDispatcher.entityPitch; + EntityRenderer.drawNameplate(this.getFontRenderer(), label, (float) x + 0.5f, (float) y + 1f, (float) z + 0.5f, 0, yaw, pitch, false, false); + } + } +} diff --git a/src/main/java/org/squiddev/plethora/gameplay/registry/Registration.java b/src/main/java/org/squiddev/plethora/gameplay/registry/Registration.java index 1d60aa86..55cc4941 100644 --- a/src/main/java/org/squiddev/plethora/gameplay/registry/Registration.java +++ b/src/main/java/org/squiddev/plethora/gameplay/registry/Registration.java @@ -24,6 +24,8 @@ import org.squiddev.plethora.gameplay.neural.ItemNeuralInterface; import org.squiddev.plethora.gameplay.redstone.BlockRedstoneIntegrator; import org.squiddev.plethora.gameplay.redstone.TileRedstoneIntegrator; +import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle; +import org.squiddev.plethora.gameplay.tiny.ItemTinyTurtle; import java.util.Objects; @@ -38,8 +40,10 @@ public final class Registration { public static ItemNeuralConnector itemNeuralConnector; public static ItemModule itemModule; public static ItemKeyboard itemKeyboard; + public static ItemTinyTurtle itemTinyTurtle; public static BlockManipulator blockManipulator; public static BlockRedstoneIntegrator blockRedstoneIntegrator; + public static BlockTinyTurtle blockTinyTurtle; private Registration() { } @@ -48,7 +52,8 @@ private Registration() { public static void registerBlocks(RegistryEvent.Register event) { event.getRegistry().registerAll( blockManipulator = new BlockManipulator(), - blockRedstoneIntegrator = new BlockRedstoneIntegrator() + blockRedstoneIntegrator = new BlockRedstoneIntegrator(), + blockTinyTurtle = new BlockTinyTurtle() ); registerTiles(); @@ -72,7 +77,8 @@ public static void registerItems(RegistryEvent.Register event) { itemModule = new ItemModule(), itemKeyboard = new ItemKeyboard(), new ItemBlockBase(blockManipulator), - new ItemBlockBase(blockRedstoneIntegrator) + new ItemBlockBase(blockRedstoneIntegrator), + itemTinyTurtle = new ItemTinyTurtle(blockTinyTurtle) ); registerUpgrades(); diff --git a/src/main/java/org/squiddev/plethora/gameplay/tiny/BlockTinyTurtle.java b/src/main/java/org/squiddev/plethora/gameplay/tiny/BlockTinyTurtle.java new file mode 100644 index 00000000..fb8c173e --- /dev/null +++ b/src/main/java/org/squiddev/plethora/gameplay/tiny/BlockTinyTurtle.java @@ -0,0 +1,161 @@ +package org.squiddev.plethora.gameplay.tiny; + +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumBlockRenderType; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumParticleTypes; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.squiddev.plethora.gameplay.BlockBase; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class BlockTinyTurtle extends BlockBase { + private static final AxisAlignedBB BOX = new AxisAlignedBB( + 0.3125, 0.3125, 0.3125, + 0.6875, 0.6875, 0.6875 + ); + static final PropertyDirection FACING = BlockHorizontal.FACING; + public static final int DEFAULT_COLOUR = 0xC6C6C6; + + private static final String NAME = "tiny_turtle"; + + public BlockTinyTurtle() { + super(NAME, Material.IRON, TileTinyTurtle.class); + setDefaultState(getBlockState().getBaseState().withProperty(FACING, EnumFacing.NORTH)); + } + + @Override + public void harvestBlock(@Nonnull World world, EntityPlayer player, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nullable TileEntity te, @Nonnull ItemStack stack) { + List items = Collections.singletonList(getItem(te instanceof TileTinyTurtle ? (TileTinyTurtle) te : null)); + ForgeEventFactory.fireBlockHarvesting(items, world, pos, state, 0, 1, true, player); + for (ItemStack item : items) spawnAsEntity(world, pos, item); + } + + @Nonnull + @Override + @Deprecated + public ItemStack getItem(World world, BlockPos pos, @Nonnull IBlockState state) { + return getItem(getTile(world, pos)); + } + + @Nonnull + private ItemStack getItem(@Nullable TileTinyTurtle tile) { + + ItemStack stack = new ItemStack(Item.getItemFromBlock(this)); + if (tile != null) ItemTinyTurtle.setup(stack, tile.getId(), tile.getLabel(), tile.getColour()); + return stack; + } + + @Override + public int damageDropped(IBlockState state) { + return 0; + } + + @Override + @SideOnly(Side.CLIENT) + public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random rand) { + if (rand.nextInt(30) != 0) return; + + for (int i = 0; i < 1 + rand.nextInt(5); i++) { + world.spawnParticle( + EnumParticleTypes.HEART, + pos.getX() + rand.nextFloat(), + pos.getY() + 0.5 + rand.nextFloat() * 0.5, + pos.getZ() + rand.nextFloat(), + rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.02 + ); + } + } + + //region Properties + @Nullable + @Override + public TileEntity createNewTileEntity(@Nonnull World world, int meta) { + return new TileTinyTurtle(); + } + + @Nonnull + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING); + } + + @Nonnull + @Override + @Deprecated + public IBlockState getStateFromMeta(int meta) { + return getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta)); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(FACING).getHorizontalIndex(); + } + + @Nonnull + @Override + @Deprecated + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return getDefaultState().withProperty(FACING, placer.getHorizontalFacing()); + } + + @Override + @Deprecated + public boolean isOpaqueCube(IBlockState state) { + return false; + } + + @Override + @Deprecated + public boolean isFullCube(IBlockState state) { + return false; + } + + @Override + @Nonnull + @Deprecated + public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing side) { + return BlockFaceShape.UNDEFINED; + } + + @Override + @Deprecated + public boolean isSideSolid(IBlockState base_state, @Nonnull IBlockAccess world, @Nonnull BlockPos pos, EnumFacing side) { + return false; + } + + @Nonnull + @Override + @Deprecated + public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) { + return BOX; + } + + @Override + @Nonnull + @Deprecated + public EnumBlockRenderType getRenderType(IBlockState state) { + return EnumBlockRenderType.INVISIBLE; + } + //endregion +} diff --git a/src/main/java/org/squiddev/plethora/gameplay/tiny/ItemTinyTurtle.java b/src/main/java/org/squiddev/plethora/gameplay/tiny/ItemTinyTurtle.java new file mode 100644 index 00000000..7f2e9fb0 --- /dev/null +++ b/src/main/java/org/squiddev/plethora/gameplay/tiny/ItemTinyTurtle.java @@ -0,0 +1,92 @@ +package org.squiddev.plethora.gameplay.tiny; + +import dan200.computercraft.shared.common.IColouredItem; +import dan200.computercraft.shared.computer.core.ComputerFamily; +import dan200.computercraft.shared.computer.items.IComputerItem; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.squiddev.plethora.gameplay.ItemBlockBase; + +import javax.annotation.Nonnull; + +public class ItemTinyTurtle extends ItemBlockBase implements IComputerItem, IColouredItem { + private static final String TAG_COLOUR = "colour"; + private static final String TAG_ID = "computer_id"; + + public ItemTinyTurtle(BlockTinyTurtle turtle) { + super(turtle); + } + + @Override + public int getColour(ItemStack stack) { + NBTTagCompound nbt = stack.getTagCompound(); + return nbt != null && nbt.hasKey(TAG_COLOUR) ? nbt.getInteger(TAG_COLOUR) : -1; + } + + @Override + public ItemStack withColour(ItemStack stack, int colour) { + ItemStack copy = stack.copy(); + setColourDirect(copy, colour); + return copy; + } + + @Override + public ItemStack withFamily(@Nonnull ItemStack stack, @Nonnull ComputerFamily computerFamily) { + return computerFamily == ComputerFamily.Advanced ? stack : ItemStack.EMPTY; + } + + @Override + public int getComputerID(@Nonnull ItemStack stack) { + NBTTagCompound nbt = stack.getTagCompound(); + return nbt != null && nbt.hasKey(TAG_ID) ? nbt.getInteger(TAG_ID) : -1; + } + + @Override + public String getLabel(@Nonnull ItemStack stack) { + return stack.hasDisplayName() ? stack.getDisplayName() : null; + } + + @Override + public ComputerFamily getFamily(@Nonnull ItemStack itemStack) { + return ComputerFamily.Advanced; + } + + public static void setup(ItemStack stack, int computerId, String label, int colour) { + if (computerId >= 0) { + NBTTagCompound tag = stack.getTagCompound(); + if (tag == null) stack.setTagCompound(tag = new NBTTagCompound()); + tag.setInteger(TAG_ID, computerId); + } + + if (label != null) stack.setStackDisplayName(label); + + setColourDirect(stack, colour); + } + + private static void setColourDirect(ItemStack stack, int colour) { + NBTTagCompound tag = stack.getTagCompound(); + if (colour == -1) { + if (tag != null) tag.removeTag("colour"); + } else { + if (tag == null) stack.setTagCompound(tag = new NBTTagCompound()); + tag.setInteger("colour", colour); + } + } + + @Override + public boolean placeBlockAt(@Nonnull ItemStack stack, @Nonnull EntityPlayer player, World world, @Nonnull BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ, @Nonnull IBlockState newState) { + if (!super.placeBlockAt(stack, player, world, pos, side, hitX, hitY, hitZ, newState)) return false; + TileEntity tile = world.getTileEntity(pos); + if (!(tile instanceof TileTinyTurtle)) return false; + + TileTinyTurtle computer = (TileTinyTurtle) tile; + computer.setup(getComputerID(stack), getLabel(stack), getColour(stack)); + return true; + } +} diff --git a/src/main/java/org/squiddev/plethora/gameplay/tiny/TileTinyTurtle.java b/src/main/java/org/squiddev/plethora/gameplay/tiny/TileTinyTurtle.java new file mode 100644 index 00000000..4e159c4e --- /dev/null +++ b/src/main/java/org/squiddev/plethora/gameplay/tiny/TileTinyTurtle.java @@ -0,0 +1,234 @@ +package org.squiddev.plethora.gameplay.tiny; + +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.turtle.ITurtleUpgrade; +import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.shared.util.Colour; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; +import org.squiddev.plethora.gameplay.TileBase; +import org.squiddev.plethora.utils.Helpers; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.EnumMap; + +public class TileTinyTurtle extends TileBase { + private static final String TAG_COLOUR = "Colour"; + private static final String TAG_ID = "ComputerId"; + private static final String TAG_LABEL = "Label"; + + private static final String TAG_UPGRADE_LEFT = "UpgradeLeft"; + private static final String TAG_UPGRADE_RIGHT = "UpgradeRight"; + + private int colour; + private String label; + private int id; + + private EnumMap upgrades = new EnumMap<>(TurtleSide.class); + + public void setup(int id, String label, int colour) { + this.id = id; + this.label = label; + this.colour = colour; + + markDirty(); + } + + public int getId() { + return id; + } + + public int getColour() { + return colour; + } + + public ITurtleUpgrade getUpgrade(TurtleSide side) { + return upgrades.get(side); + } + + public String getLabel() { + return label; + } + + public EnumFacing getFacing() { + IBlockState state = world.getBlockState(pos); + return state.getBlock() instanceof BlockTinyTurtle ? state.getValue(BlockTinyTurtle.FACING) : EnumFacing.NORTH; + } + + private EnumFacing getRelative(EnumFacing side) { + return EnumFacing.byHorizontalIndex(side.getHorizontalIndex() + getFacing().getHorizontalIndex()); + } + + @Override + public boolean onActivated(EntityPlayer player, EnumHand hand, EnumFacing side, Vec3d hit) { + ItemStack stack = player.getHeldItem(hand); + + // Try to dye a turtle + if (stack.getItem() == Items.DYE) { + // Dye to change turtle colour + if (!world.isRemote) { + int dye = stack.getItemDamage() & 0xf; + Colour currentDye = colour == -1 ? null : Colour.fromHex(colour); + if (currentDye == null || dye != currentDye.ordinal()) { + colour = Colour.values()[dye].getHex(); + markForUpdate(); + + if (!player.isCreative()) stack.shrink(1); + } + } + + return true; + } else if (stack.getItem() == Items.WATER_BUCKET && colour != -1) { + // Water to remove turtle colour + if (!world.isRemote) { + colour = -1; + markForUpdate(); + + if (!player.isCreative()) { + player.setHeldItem(hand, new ItemStack(Items.BUCKET)); + player.inventory.markDirty(); + } + } + + return true; + } else if (stack.getItem() == Items.NAME_TAG) { + if (!world.isRemote) { + label = stack.hasDisplayName() ? stack.getDisplayName() : null; + markForUpdate(); + + if (!player.isCreative()) stack.shrink(1); + } + + return true; + } + + // Try to set an upgrade. + EnumFacing facing = getRelative(side); + TurtleSide turtleSide = null; + if (facing == EnumFacing.EAST) turtleSide = TurtleSide.Left; + if (facing == EnumFacing.WEST) turtleSide = TurtleSide.Right; + + if (turtleSide != null) { + if (!world.isRemote) { + if (stack.isEmpty()) { + removeUpgrade(turtleSide, side); + } else { + ITurtleUpgrade upgrade = ComputerCraft.getTurtleUpgrade(stack); + if (upgrade != null) { + removeUpgrade(turtleSide, side); + upgrades.put(turtleSide, upgrade); + markForUpdate(); + + if (!player.isCreative()) stack.shrink(1); + } + } + } + + return true; + } + + return false; + } + + @Override + public void broken() { + super.broken(); + + EnumFacing facing = getFacing(); + dropUpgrade(upgrades.get(TurtleSide.Left), facing.rotateY()); + dropUpgrade(upgrades.get(TurtleSide.Right), facing.rotateYCCW()); + } + + private void removeUpgrade(TurtleSide side, EnumFacing actualSide) { + ITurtleUpgrade existing = upgrades.remove(side); + if (existing == null) return; + + markForUpdate(); + dropUpgrade(existing, actualSide); + } + + private void dropUpgrade(ITurtleUpgrade upgrade, EnumFacing actualSide) { + if (upgrade == null) return; + + ItemStack dropStack = upgrade.getCraftingItem(); + if (dropStack.isEmpty()) return; + + Vec3d itemPos = new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5) + .add(new Vec3d(actualSide.getDirectionVec()).scale(0.75)); + + Helpers.spawnItemStack(world, itemPos.x, itemPos.y, itemPos.z, dropStack.copy()); + } + + private void readCommon(NBTTagCompound nbt) { + id = nbt.hasKey(TAG_ID) ? nbt.getInteger(TAG_ID) : -1; + label = nbt.hasKey(TAG_LABEL) ? nbt.getString(TAG_LABEL) : null; + colour = nbt.hasKey(TAG_COLOUR) ? nbt.getInteger(TAG_COLOUR) : -1; + + ITurtleUpgrade leftUpgrade = nbt.hasKey(TAG_UPGRADE_LEFT) ? ComputerCraft.getTurtleUpgrade(nbt.getString(TAG_UPGRADE_LEFT)) : null; + if (leftUpgrade == null) { + upgrades.remove(TurtleSide.Left); + } else { + upgrades.put(TurtleSide.Left, leftUpgrade); + } + + ITurtleUpgrade rightUpgrade = nbt.hasKey(TAG_UPGRADE_RIGHT) ? ComputerCraft.getTurtleUpgrade(nbt.getString(TAG_UPGRADE_RIGHT)) : null; + if (rightUpgrade == null) { + upgrades.remove(TurtleSide.Right); + } else { + upgrades.put(TurtleSide.Right, rightUpgrade); + } + } + + private void writeCommon(NBTTagCompound nbt) { + if (id >= 0) nbt.setInteger(TAG_ID, id); + if (label != null) nbt.setString(TAG_LABEL, label); + if (colour != -1) nbt.setInteger(TAG_COLOUR, colour); + + ITurtleUpgrade left = upgrades.get(TurtleSide.Left); + if (left != null) nbt.setString(TAG_UPGRADE_LEFT, left.getUpgradeID().toString()); + + ITurtleUpgrade right = upgrades.get(TurtleSide.Right); + if (right != null) nbt.setString(TAG_UPGRADE_RIGHT, right.getUpgradeID().toString()); + } + + @Override + protected void readDescription(NBTTagCompound tag) { + super.readDescription(tag); + readCommon(tag); + } + + @Override + protected void writeDescription(NBTTagCompound tag) { + super.writeDescription(tag); + writeCommon(tag); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + readCommon(nbt); + } + + @Nonnull + @Override + public NBTTagCompound writeToNBT(NBTTagCompound nbt) { + writeCommon(nbt); + + return super.writeToNBT(nbt); + } + + @Nullable + @Override + public ITextComponent getDisplayName() { + return label == null ? null : new TextComponentString(label); + } +} diff --git a/src/main/resources/assets/plethora/blockstates/tiny_turtle.json b/src/main/resources/assets/plethora/blockstates/tiny_turtle.json new file mode 100644 index 00000000..b053c07c --- /dev/null +++ b/src/main/resources/assets/plethora/blockstates/tiny_turtle.json @@ -0,0 +1,8 @@ +{ + "variants": { + "facing=north": { "model": "plethora:tiny_turtle" }, + "facing=south": { "model": "plethora:tiny_turtle", "y": 180 }, + "facing=west": { "model": "plethora:tiny_turtle", "y": 270 }, + "facing=east": { "model": "plethora:tiny_turtle", "y": 90 } + } +} diff --git a/src/main/resources/assets/plethora/lang/en_us.lang b/src/main/resources/assets/plethora/lang/en_us.lang index 1a1daac8..441c773c 100644 --- a/src/main/resources/assets/plethora/lang/en_us.lang +++ b/src/main/resources/assets/plethora/lang/en_us.lang @@ -86,6 +86,10 @@ adjective.plethora.clock=Chronal adjective.plethora.daylight_detector=Photosensitive adjective.plethora.note_block=Acoustic +# Tiny turtle +tile.plethora.tiny_turtle.name=Tiny Turtle +tile.plethora.tiny_turtle.desc=It loves you, and would never stab you. + # Minecart entity.plethora.plethora:minecartComputer.name=Minecart computer diff --git a/src/main/resources/assets/plethora/models/block/tiny_turtle.json b/src/main/resources/assets/plethora/models/block/tiny_turtle.json new file mode 100644 index 00000000..960dabde --- /dev/null +++ b/src/main/resources/assets/plethora/models/block/tiny_turtle.json @@ -0,0 +1,61 @@ +{ + "parent": "block/block", + "textures": { + "texture": "plethora:blocks/tiny_turtle", + "particle": "plethora:blocks/tiny_turtle" + }, + "elements": [ + { + "name": "main_body", + "from": [ 5, 5, 5 ], + "to": [ 11, 11, 10.5 ], + "faces": { + "north": { "uv": [ 3.5, 0, 6.5, 3 ], "texture": "#texture", "tintindex": 0 }, + "east": { "uv": [ 0, 0, 3, 3 ], "texture": "#texture", "tintindex": 0 }, + "south": { "uv": [ 3.5, 3.5, 6.5, 6.5 ], "texture": "#texture", "tintindex": 0 }, + "west": { "uv": [ 7, 0, 10, 3 ], "texture": "#texture", "tintindex": 0 }, + "up": { "uv": [ 0, 3.5, 3, 6.5 ], "texture": "#texture", "tintindex": 0 }, + "down": { "uv": [ 7, 3.5, 10, 6.25 ], "texture": "#texture", "tintindex": 0 } + } + }, + { + "name": "grid_body", + "from": [ 5, 5, 5 ], + "to": [ 11, 11, 10.5 ], + "faces": { + "north": { "uv": [ 3.5, 6.5, 6.5, 9.5 ], "texture": "#texture" }, + "east": { "uv": [ 0, 6.5, 3, 9.5 ], "texture": "#texture" }, + "south": { "uv": [ 3.5, 10, 6.5, 13 ], "texture": "#texture" }, + "west": { "uv": [ 7, 6.5, 10, 9.5 ], "texture": "#texture" }, + "up": { "uv": [ 0, 10, 3, 13 ], "texture": "#texture" }, + "down": { "uv": [ 7, 10, 10, 12.75 ], "texture": "#texture" } + } + }, + { + "name": "main_back", + "from": [ 6, 7, 10.5 ], + "to": [ 10, 10, 11.5 ], + "faces": { + "north": { "uv": [ 11, 1, 13, 2.5 ], "texture": "#texture", "tintindex": 0 }, + "east": { "uv": [ 10.5, 1, 11, 2.5 ], "texture": "#texture", "tintindex": 0 }, + "south": { "uv": [ 11, 1, 13, 2.5 ], "texture": "#texture", "tintindex": 0 }, + "west": { "uv": [ 13, 1, 13.5, 2.5 ], "texture": "#texture", "tintindex": 0 }, + "up": { "uv": [ 11, 0.5, 13, 1 ], "texture": "#texture", "tintindex": 0 }, + "down": { "uv": [ 11, 2.5, 13, 3 ], "texture": "#texture", "tintindex": 0 } + } + }, + { + "name": "grid_back", + "from": [ 6, 7, 10.5 ], + "to": [ 10, 10, 11.5 ], + "faces": { + "north": { "uv": [ 11, 7.5, 13, 9 ], "texture": "#texture" }, + "east": { "uv": [ 10.5, 7.5, 11, 9 ], "texture": "#texture" }, + "south": { "uv": [ 11, 7.5, 13, 9 ], "texture": "#texture" }, + "west": { "uv": [ 13, 7.5, 13.5, 9 ], "texture": "#texture" }, + "up": { "uv": [ 11, 7, 13, 7.5 ], "texture": "#texture" }, + "down": { "uv": [ 11, 9, 13, 9.5 ], "texture": "#texture" } + } + } + ] +} diff --git a/src/main/resources/assets/plethora/models/item/manipulator.mark_1.json b/src/main/resources/assets/plethora/models/item/manipulator.mark_1.json index 94ae5306..700a9f29 100644 --- a/src/main/resources/assets/plethora/models/item/manipulator.mark_1.json +++ b/src/main/resources/assets/plethora/models/item/manipulator.mark_1.json @@ -1,10 +1,3 @@ { - "parent": "plethora:block/manipulator.mark_1", - "display": { - "thirdperson": { - "rotation": [ 10, -45, 170 ], - "translation": [ 0, 1.5, -2.75 ], - "scale": [ 0.375, 0.375, 0.375 ] - } - } + "parent": "plethora:block/manipulator.mark_1" } diff --git a/src/main/resources/assets/plethora/models/item/manipulator.mark_2.json b/src/main/resources/assets/plethora/models/item/manipulator.mark_2.json index 7ee7327c..a559720c 100644 --- a/src/main/resources/assets/plethora/models/item/manipulator.mark_2.json +++ b/src/main/resources/assets/plethora/models/item/manipulator.mark_2.json @@ -1,22 +1,3 @@ { - "parent": "plethora:block/manipulator.mark_2", - "display": { - "thirdperson": { - "rotation": [ - 10, - -45, - 170 - ], - "translation": [ - 0, - 1.5, - -2.75 - ], - "scale": [ - 0.375, - 0.375, - 0.375 - ] - } - } + "parent": "plethora:block/manipulator.mark_2" } diff --git a/src/main/resources/assets/plethora/models/item/redstone_integrator.json b/src/main/resources/assets/plethora/models/item/redstone_integrator.json index 7f6f9718..72a2b21f 100644 --- a/src/main/resources/assets/plethora/models/item/redstone_integrator.json +++ b/src/main/resources/assets/plethora/models/item/redstone_integrator.json @@ -1,10 +1,3 @@ { - "parent": "plethora:block/redstone_integrator", - "display": { - "thirdperson": { - "rotation": [ 10, -45, 170 ], - "translation": [ 0, 1.5, -2.75 ], - "scale": [ 0.375, 0.375, 0.375 ] - } - } + "parent": "plethora:block/redstone_integrator" } diff --git a/src/main/resources/assets/plethora/models/item/tiny_turtle.json b/src/main/resources/assets/plethora/models/item/tiny_turtle.json new file mode 100644 index 00000000..749c89a6 --- /dev/null +++ b/src/main/resources/assets/plethora/models/item/tiny_turtle.json @@ -0,0 +1,3 @@ +{ + "parent": "plethora:block/tiny_turtle" +} diff --git a/src/main/resources/assets/plethora/textures/blocks/tiny_turtle.png b/src/main/resources/assets/plethora/textures/blocks/tiny_turtle.png new file mode 100644 index 0000000000000000000000000000000000000000..018d6b738ef88b4344d08e08f409fa66eb8cd88f GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6;>1s;*b3=DjSL74G){)!Z!pk#?_L`iUdT1k0gQ7S`0VrE{6US4X6f{C7i zo{`~4h0LiyQwuy@977`9_fEOp*KEM!^85e&W6Y20CjQ`gpnE!E$80NRmTl7B>VD~u zZcJ^MUi@yg!i>5Woz%!(``*Xi-nMStYu{hC4flO7??{wjdA*Qr>kj5yix~?7ua~wn zI~*6db);&=RV!Hr=cko=r8k_DPb}iy^MU^+hs~8oeY$pR8eNA{Bh{Fll3yHat3PpU z<#T?93pQyD>lZQ~aXLCBz)*G5gO~G`dCn{Py`=x~k85kU|DU!YPG{2siS>fBZe9=A z&v?O8*!=wF=|wx#xwMtXkFe&pWry@3wa{KmquL-*} zR?HBp%$3|N`QpK;-ONd+8#QhP`+v7v6)h0W=W_AS8IzRx66cGmeyo?MT47u%m}%8)`30zo-A0$ysC1Gy)Ralw_olCX_j9WTUd25_&s0H sksAM_owRCANO!5LV5AUsG(8w22*_0Y%0*oLAPgg&ebxsLQ0ImPpw*UYD literal 0 HcmV?d00001