Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Commit

Permalink
Initial tiny turtle implementation
Browse files Browse the repository at this point in the history
This currently can be labelled and have upgrades attached on the left
and right hand side.
  • Loading branch information
SquidDev committed May 13, 2019
1 parent df371ff commit a5621e8
Show file tree
Hide file tree
Showing 14 changed files with 726 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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.*;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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<TileTinyTurtle> {
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<IBakedModel, Matrix4f> 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<BakedQuad> 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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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() {
}
Expand All @@ -48,7 +52,8 @@ private Registration() {
public static void registerBlocks(RegistryEvent.Register<Block> event) {
event.getRegistry().registerAll(
blockManipulator = new BlockManipulator(),
blockRedstoneIntegrator = new BlockRedstoneIntegrator()
blockRedstoneIntegrator = new BlockRedstoneIntegrator(),
blockTinyTurtle = new BlockTinyTurtle()
);

registerTiles();
Expand All @@ -72,7 +77,8 @@ public static void registerItems(RegistryEvent.Register<Item> event) {
itemModule = new ItemModule(),
itemKeyboard = new ItemKeyboard(),
new ItemBlockBase(blockManipulator),
new ItemBlockBase(blockRedstoneIntegrator)
new ItemBlockBase(blockRedstoneIntegrator),
itemTinyTurtle = new ItemTinyTurtle(blockTinyTurtle)
);

registerUpgrades();
Expand Down
161 changes: 161 additions & 0 deletions src/main/java/org/squiddev/plethora/gameplay/tiny/BlockTinyTurtle.java
Original file line number Diff line number Diff line change
@@ -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<TileTinyTurtle> {
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<ItemStack> 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
}
Loading

0 comments on commit a5621e8

Please sign in to comment.