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

Commit a5621e8

Browse files
committed
Initial tiny turtle implementation
This currently can be labelled and have upgrades attached on the left and right hand side.
1 parent df371ff commit a5621e8

File tree

14 files changed

+726
-38
lines changed

14 files changed

+726
-38
lines changed

src/main/java/org/squiddev/plethora/gameplay/client/ClientRegistration.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.squiddev.plethora.gameplay.client;
22

33
import net.minecraft.item.Item;
4+
import net.minecraftforge.client.event.ColorHandlerEvent;
45
import net.minecraftforge.client.event.ModelRegistryEvent;
56
import net.minecraftforge.fml.client.registry.ClientRegistry;
67
import net.minecraftforge.fml.client.registry.RenderingRegistry;
@@ -12,11 +13,14 @@
1213
import org.squiddev.plethora.gameplay.client.entity.RenderLaser;
1314
import org.squiddev.plethora.gameplay.client.entity.RenderMinecartComputer;
1415
import org.squiddev.plethora.gameplay.client.tile.RenderManipulator;
16+
import org.squiddev.plethora.gameplay.client.tile.RenderTinyTurtle;
1517
import org.squiddev.plethora.gameplay.minecart.EntityMinecartComputer;
1618
import org.squiddev.plethora.gameplay.modules.EntityLaser;
1719
import org.squiddev.plethora.gameplay.modules.ManipulatorType;
1820
import org.squiddev.plethora.gameplay.modules.PlethoraModules;
1921
import org.squiddev.plethora.gameplay.modules.TileManipulator;
22+
import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle;
23+
import org.squiddev.plethora.gameplay.tiny.TileTinyTurtle;
2024
import org.squiddev.plethora.utils.Helpers;
2125

2226
import static org.squiddev.plethora.gameplay.registry.Registration.*;
@@ -47,6 +51,8 @@ public static void registerModels(ModelRegistryEvent event) {
4751
@SideOnly(Side.CLIENT)
4852
public static void preInit() {
4953
ClientRegistry.bindTileEntitySpecialRenderer(TileManipulator.class, new RenderManipulator());
54+
ClientRegistry.bindTileEntitySpecialRenderer(TileTinyTurtle.class, new RenderTinyTurtle());
55+
5056
RenderingRegistry.registerEntityRenderingHandler(EntityMinecartComputer.class, RenderMinecartComputer::new);
5157
RenderingRegistry.registerEntityRenderingHandler(EntityLaser.class, RenderLaser::new);
5258
}
@@ -56,4 +62,17 @@ public static void init() {
5662
RenderSquidOverlay.init();
5763
RenderInterfaceLiving.init();
5864
}
65+
66+
@SubscribeEvent
67+
@SideOnly(Side.CLIENT)
68+
public static void registerColour(ColorHandlerEvent.Item event) {
69+
event.getItemColors().registerItemColorHandler((stack, tintIndex) -> {
70+
if (tintIndex == 0) {
71+
int colour = itemTinyTurtle.getColour(stack);
72+
return colour == -1 ? BlockTinyTurtle.DEFAULT_COLOUR : colour;
73+
}
74+
75+
return 0xFFFFFF;
76+
}, itemTinyTurtle);
77+
}
5978
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package org.squiddev.plethora.gameplay.client.tile;
2+
3+
import dan200.computercraft.api.turtle.ITurtleUpgrade;
4+
import dan200.computercraft.api.turtle.TurtleSide;
5+
import net.minecraft.block.state.IBlockState;
6+
import net.minecraft.client.Minecraft;
7+
import net.minecraft.client.renderer.BufferBuilder;
8+
import net.minecraft.client.renderer.EntityRenderer;
9+
import net.minecraft.client.renderer.GlStateManager;
10+
import net.minecraft.client.renderer.Tessellator;
11+
import net.minecraft.client.renderer.block.model.BakedQuad;
12+
import net.minecraft.client.renderer.block.model.IBakedModel;
13+
import net.minecraft.client.renderer.block.model.ModelManager;
14+
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
15+
import net.minecraft.client.renderer.texture.TextureMap;
16+
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
17+
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
18+
import net.minecraft.client.renderer.vertex.VertexFormat;
19+
import net.minecraft.entity.Entity;
20+
import net.minecraft.util.EnumFacing;
21+
import net.minecraftforge.client.ForgeHooksClient;
22+
import net.minecraftforge.client.model.pipeline.LightUtil;
23+
import org.apache.commons.lang3.tuple.Pair;
24+
import org.lwjgl.opengl.GL11;
25+
import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle;
26+
import org.squiddev.plethora.gameplay.tiny.TileTinyTurtle;
27+
28+
import javax.annotation.Nonnull;
29+
import javax.vecmath.Matrix4f;
30+
import java.util.List;
31+
32+
public class RenderTinyTurtle extends TileEntitySpecialRenderer<TileTinyTurtle> {
33+
private static final ModelResourceLocation MODEL = new ModelResourceLocation("plethora:tiny_turtle", "facing=north");
34+
35+
@Override
36+
public void render(TileTinyTurtle te, double x, double y, double z, float partialTicks, int destroyStage, float alpha) {
37+
renderTurtleAt(te, x, y, z, partialTicks);
38+
super.render(te, x, y, z, partialTicks, destroyStage, alpha);
39+
}
40+
41+
private void renderTurtleAt(TileTinyTurtle turtle, double x, double y, double z, float partialTicks) {
42+
IBlockState state = turtle.getWorld().getBlockState(turtle.getPos());
43+
GlStateManager.pushMatrix();
44+
45+
String label = turtle.getLabel();
46+
47+
GlStateManager.translate(x, y, z);
48+
GlStateManager.translate(0.5f, 0.5f, 0.5f);
49+
GlStateManager.rotate(180.0f - turtle.getFacing().getHorizontalAngle(), 0.0f, 1.0f, 0.0f);
50+
if (label != null && (label.equals("Dinnerbone") || label.equals("Grumm"))) {
51+
// Flip the model and swap the cull face as winding order will have changed.
52+
GlStateManager.scale(1.0f, -1.0f, 1.0f);
53+
GlStateManager.cullFace(GlStateManager.CullFace.FRONT);
54+
}
55+
GlStateManager.translate(-0.5f, -0.5f, -0.5f);
56+
57+
int colour = turtle.getColour();
58+
59+
renderModel(state, MODEL, new int[]{colour == -1 ? BlockTinyTurtle.DEFAULT_COLOUR : colour});
60+
renderUpgrade(state, turtle, TurtleSide.Left, partialTicks);
61+
renderUpgrade(state, turtle, TurtleSide.Right, partialTicks);
62+
63+
GlStateManager.cullFace(GlStateManager.CullFace.BACK);
64+
65+
GlStateManager.popMatrix();
66+
}
67+
68+
private void renderUpgrade(IBlockState state, TileTinyTurtle turtle, TurtleSide side, float partialTicks) {
69+
ITurtleUpgrade upgrade = turtle.getUpgrade(side);
70+
if (upgrade == null) return;
71+
GlStateManager.pushMatrix();
72+
73+
GlStateManager.translate(0.5f, 0.0f, 0.5f);
74+
GlStateManager.scale(0.5f, 0.5f, 0.5f);
75+
GlStateManager.translate(-0.5f, 0.5f, -0.5f);
76+
77+
Pair<IBakedModel, Matrix4f> pair = upgrade.getModel(null, side);
78+
if (pair != null) {
79+
if (pair.getRight() != null) ForgeHooksClient.multiplyCurrentGlMatrix(pair.getRight());
80+
if (pair.getLeft() != null) renderModel(state, pair.getLeft(), null);
81+
}
82+
83+
GlStateManager.popMatrix();
84+
}
85+
86+
private void renderModel(IBlockState state, ModelResourceLocation model, int[] tints) {
87+
Minecraft mc = Minecraft.getMinecraft();
88+
ModelManager modelManager = mc.getRenderItem().getItemModelMesher().getModelManager();
89+
renderModel(state, modelManager.getModel(model), tints);
90+
}
91+
92+
private void renderModel(IBlockState state, IBakedModel model, int[] tints) {
93+
Tessellator tessellator = Tessellator.getInstance();
94+
bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
95+
renderQuads(tessellator, model.getQuads(state, null, 0), tints);
96+
for (EnumFacing facing : EnumFacing.VALUES) {
97+
renderQuads(tessellator, model.getQuads(state, facing, 0), tints);
98+
}
99+
}
100+
101+
private void renderQuads(Tessellator tessellator, List<BakedQuad> quads, int[] tints) {
102+
BufferBuilder buffer = tessellator.getBuffer();
103+
VertexFormat format = DefaultVertexFormats.ITEM;
104+
buffer.begin(GL11.GL_QUADS, format);
105+
106+
for (BakedQuad quad : quads) {
107+
VertexFormat quadFormat = quad.getFormat();
108+
if (quadFormat != format) {
109+
tessellator.draw();
110+
format = quadFormat;
111+
buffer.begin(GL11.GL_QUADS, quadFormat);
112+
}
113+
114+
int index = quad.getTintIndex();
115+
int colour = tints != null && index >= 0 && index < tints.length ? tints[index] | -16777216 : -1;
116+
LightUtil.renderQuadColor(buffer, quad, colour);
117+
}
118+
119+
tessellator.draw();
120+
}
121+
122+
@Override
123+
protected void drawNameplate(TileTinyTurtle te, @Nonnull String label, double x, double y, double z, int maxDistance) {
124+
Entity entity = rendererDispatcher.entity;
125+
double distance = te.getDistanceSq(entity.posX, entity.posY, entity.posZ);
126+
127+
if (distance <= (double) (maxDistance * maxDistance)) {
128+
float yaw = rendererDispatcher.entityYaw;
129+
float pitch = rendererDispatcher.entityPitch;
130+
EntityRenderer.drawNameplate(this.getFontRenderer(), label, (float) x + 0.5f, (float) y + 1f, (float) z + 0.5f, 0, yaw, pitch, false, false);
131+
}
132+
}
133+
}

src/main/java/org/squiddev/plethora/gameplay/registry/Registration.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.squiddev.plethora.gameplay.neural.ItemNeuralInterface;
2525
import org.squiddev.plethora.gameplay.redstone.BlockRedstoneIntegrator;
2626
import org.squiddev.plethora.gameplay.redstone.TileRedstoneIntegrator;
27+
import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle;
28+
import org.squiddev.plethora.gameplay.tiny.ItemTinyTurtle;
2729

2830
import java.util.Objects;
2931

@@ -38,8 +40,10 @@ public final class Registration {
3840
public static ItemNeuralConnector itemNeuralConnector;
3941
public static ItemModule itemModule;
4042
public static ItemKeyboard itemKeyboard;
43+
public static ItemTinyTurtle itemTinyTurtle;
4144
public static BlockManipulator blockManipulator;
4245
public static BlockRedstoneIntegrator blockRedstoneIntegrator;
46+
public static BlockTinyTurtle blockTinyTurtle;
4347

4448
private Registration() {
4549
}
@@ -48,7 +52,8 @@ private Registration() {
4852
public static void registerBlocks(RegistryEvent.Register<Block> event) {
4953
event.getRegistry().registerAll(
5054
blockManipulator = new BlockManipulator(),
51-
blockRedstoneIntegrator = new BlockRedstoneIntegrator()
55+
blockRedstoneIntegrator = new BlockRedstoneIntegrator(),
56+
blockTinyTurtle = new BlockTinyTurtle()
5257
);
5358

5459
registerTiles();
@@ -72,7 +77,8 @@ public static void registerItems(RegistryEvent.Register<Item> event) {
7277
itemModule = new ItemModule(),
7378
itemKeyboard = new ItemKeyboard(),
7479
new ItemBlockBase(blockManipulator),
75-
new ItemBlockBase(blockRedstoneIntegrator)
80+
new ItemBlockBase(blockRedstoneIntegrator),
81+
itemTinyTurtle = new ItemTinyTurtle(blockTinyTurtle)
7682
);
7783

7884
registerUpgrades();
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package org.squiddev.plethora.gameplay.tiny;
2+
3+
import net.minecraft.block.BlockHorizontal;
4+
import net.minecraft.block.material.Material;
5+
import net.minecraft.block.properties.PropertyDirection;
6+
import net.minecraft.block.state.BlockFaceShape;
7+
import net.minecraft.block.state.BlockStateContainer;
8+
import net.minecraft.block.state.IBlockState;
9+
import net.minecraft.entity.EntityLivingBase;
10+
import net.minecraft.entity.player.EntityPlayer;
11+
import net.minecraft.item.Item;
12+
import net.minecraft.item.ItemStack;
13+
import net.minecraft.tileentity.TileEntity;
14+
import net.minecraft.util.EnumBlockRenderType;
15+
import net.minecraft.util.EnumFacing;
16+
import net.minecraft.util.EnumParticleTypes;
17+
import net.minecraft.util.math.AxisAlignedBB;
18+
import net.minecraft.util.math.BlockPos;
19+
import net.minecraft.world.IBlockAccess;
20+
import net.minecraft.world.World;
21+
import net.minecraftforge.event.ForgeEventFactory;
22+
import net.minecraftforge.fml.relauncher.Side;
23+
import net.minecraftforge.fml.relauncher.SideOnly;
24+
import org.squiddev.plethora.gameplay.BlockBase;
25+
26+
import javax.annotation.Nonnull;
27+
import javax.annotation.Nullable;
28+
import java.util.Collections;
29+
import java.util.List;
30+
import java.util.Random;
31+
32+
public class BlockTinyTurtle extends BlockBase<TileTinyTurtle> {
33+
private static final AxisAlignedBB BOX = new AxisAlignedBB(
34+
0.3125, 0.3125, 0.3125,
35+
0.6875, 0.6875, 0.6875
36+
);
37+
static final PropertyDirection FACING = BlockHorizontal.FACING;
38+
public static final int DEFAULT_COLOUR = 0xC6C6C6;
39+
40+
private static final String NAME = "tiny_turtle";
41+
42+
public BlockTinyTurtle() {
43+
super(NAME, Material.IRON, TileTinyTurtle.class);
44+
setDefaultState(getBlockState().getBaseState().withProperty(FACING, EnumFacing.NORTH));
45+
}
46+
47+
@Override
48+
public void harvestBlock(@Nonnull World world, EntityPlayer player, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nullable TileEntity te, @Nonnull ItemStack stack) {
49+
List<ItemStack> items = Collections.singletonList(getItem(te instanceof TileTinyTurtle ? (TileTinyTurtle) te : null));
50+
ForgeEventFactory.fireBlockHarvesting(items, world, pos, state, 0, 1, true, player);
51+
for (ItemStack item : items) spawnAsEntity(world, pos, item);
52+
}
53+
54+
@Nonnull
55+
@Override
56+
@Deprecated
57+
public ItemStack getItem(World world, BlockPos pos, @Nonnull IBlockState state) {
58+
return getItem(getTile(world, pos));
59+
}
60+
61+
@Nonnull
62+
private ItemStack getItem(@Nullable TileTinyTurtle tile) {
63+
64+
ItemStack stack = new ItemStack(Item.getItemFromBlock(this));
65+
if (tile != null) ItemTinyTurtle.setup(stack, tile.getId(), tile.getLabel(), tile.getColour());
66+
return stack;
67+
}
68+
69+
@Override
70+
public int damageDropped(IBlockState state) {
71+
return 0;
72+
}
73+
74+
@Override
75+
@SideOnly(Side.CLIENT)
76+
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random rand) {
77+
if (rand.nextInt(30) != 0) return;
78+
79+
for (int i = 0; i < 1 + rand.nextInt(5); i++) {
80+
world.spawnParticle(
81+
EnumParticleTypes.HEART,
82+
pos.getX() + rand.nextFloat(),
83+
pos.getY() + 0.5 + rand.nextFloat() * 0.5,
84+
pos.getZ() + rand.nextFloat(),
85+
rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.02, rand.nextGaussian() * 0.02
86+
);
87+
}
88+
}
89+
90+
//region Properties
91+
@Nullable
92+
@Override
93+
public TileEntity createNewTileEntity(@Nonnull World world, int meta) {
94+
return new TileTinyTurtle();
95+
}
96+
97+
@Nonnull
98+
@Override
99+
protected BlockStateContainer createBlockState() {
100+
return new BlockStateContainer(this, FACING);
101+
}
102+
103+
@Nonnull
104+
@Override
105+
@Deprecated
106+
public IBlockState getStateFromMeta(int meta) {
107+
return getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta));
108+
}
109+
110+
@Override
111+
public int getMetaFromState(IBlockState state) {
112+
return state.getValue(FACING).getHorizontalIndex();
113+
}
114+
115+
@Nonnull
116+
@Override
117+
@Deprecated
118+
public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) {
119+
return getDefaultState().withProperty(FACING, placer.getHorizontalFacing());
120+
}
121+
122+
@Override
123+
@Deprecated
124+
public boolean isOpaqueCube(IBlockState state) {
125+
return false;
126+
}
127+
128+
@Override
129+
@Deprecated
130+
public boolean isFullCube(IBlockState state) {
131+
return false;
132+
}
133+
134+
@Override
135+
@Nonnull
136+
@Deprecated
137+
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing side) {
138+
return BlockFaceShape.UNDEFINED;
139+
}
140+
141+
@Override
142+
@Deprecated
143+
public boolean isSideSolid(IBlockState base_state, @Nonnull IBlockAccess world, @Nonnull BlockPos pos, EnumFacing side) {
144+
return false;
145+
}
146+
147+
@Nonnull
148+
@Override
149+
@Deprecated
150+
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) {
151+
return BOX;
152+
}
153+
154+
@Override
155+
@Nonnull
156+
@Deprecated
157+
public EnumBlockRenderType getRenderType(IBlockState state) {
158+
return EnumBlockRenderType.INVISIBLE;
159+
}
160+
//endregion
161+
}

0 commit comments

Comments
 (0)