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

Commit 679f81b

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 3f64cef commit 679f81b

File tree

13 files changed

+728
-36
lines changed

13 files changed

+728
-36
lines changed
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/Registry.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.squiddev.plethora.gameplay.neural.ItemNeuralConnector;
1515
import org.squiddev.plethora.gameplay.neural.ItemNeuralInterface;
1616
import org.squiddev.plethora.gameplay.redstone.BlockRedstoneIntegrator;
17+
import org.squiddev.plethora.gameplay.tiny.BlockTinyTurtle;
1718

1819
import java.util.HashSet;
1920
import java.util.Set;
@@ -34,6 +35,7 @@ public final class Registry {
3435
public static ItemKeyboard itemKeyboard;
3536
public static BlockManipulator blockManipulator;
3637
public static BlockRedstoneIntegrator blockRedstoneIntegrator;
38+
public static BlockTinyTurtle blockTinyTurtle;
3739

3840
private static void addModule(IModule module) {
3941
if (module instanceof IClientModule) {
@@ -72,6 +74,8 @@ public static void setup() {
7274
addModule(blockRedstoneIntegrator = new BlockRedstoneIntegrator());
7375

7476
addModule(new RenderSquidOverlay());
77+
78+
addModule(blockTinyTurtle = new BlockTinyTurtle());
7579
}
7680

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

0 commit comments

Comments
 (0)