Jump to content


Forge Modder
  • Posts

  • Joined

  • Last visited

Posts posted by gcewing

  1. For a long time I've been using a little script that greps the .srg files to find a mapping for a name. But I've just set up a decomp workspace for 1.10.2, and I can't find the .srg files anywhere, not even in the gradle cache.


    Does anyone know where they've been hidden? Are .srg files even being used still, or have they been replaced by something else?

  2. having difficulty hooking the new 1.8.9 builds up with computer craft

    There are no power or computer interfaces in the 1.8 version yet. I'll tackle that when I finish revamping the 1.7 code.


    the base of the stargate does not seem to be acting as a peripheral is there an extra step needed now?

    The base itself has never acted as a computer peripheral. You need to use an interface block in 1.7, and it will be the same in 1.8.

  3. We have an issue with the Stargates where anyone connecting to my private server will crash once they step through the stargate.


    [20/1/2016 00:03:04 AM] java.lang.NullPointerException

    [20/1/2016 00:03:04 AM] at gcewing.sg.SGAddressing.getWorld(SGAddressing.java:229) ~[sGAddressing.class:?]


    Does this still happen with the latest version (1.9.5)?

  4. According to DefaultVertexFormats.ITEM, the layout of the bytes in a normal should be


      x  y  z  pad


    But I'm finding I need to lay them out this way:


      pad  x  y  z


    All the other code I can find in MC and Forge that deals with normals seems to use the ITEM layout, so I'm confused. Anyone know what's going on?


    I'm using Forge 1.8.9-

  5. I'm trying to add a TextureAtlasSprite by calling event.map.registerSprite() in a TextureStitchEvent.Pre handler.


    It's not working properly. I get a TextureAtlasSprite with valid-looking texture coords, but the position in the texture that they refer to is occupied by a different sprite. Looking at the dump of the stitched texture map, my texture doesn't seem to appear in it anywhere.


    Am I going about this the right way? Is TextureStitchEvent.Pre the right time to do this? Am I calling the right method? The equivalent thing used to work in 1.7.

  6. You might be able to do something in multiple rendering layers using this forge extension - i.e. Render your AO in the CUTOUT and the non-AO in the CUTOUT MIPPED,

    I thought about that, but the layer is ultimately going to be dictated by the base material, e.g. if the block is made from tinted glass, it's going to have to be rendered in the alpha transparency layer. So I'm not really free to (ab)use the layers that way.

  7. I'm porting my roof blocks from Greg's Blocks to 1.8, and I'm having trouble with ambient occlusion. It doesn't seem to be possible to get it to work correctly for faces that are not axis-aligned.


    In this screenshot, you can see places where the lower edges of roof blocks are incorrectly shaded, because the rendering system thinks that the cobblestone block below the roof block is casting a shadow on it. This happens because the roof block is not opaque, so it includes the block below in AO calculations rather than the block below and in front. The same thing causes the ridge blocks on top to be shaded too darkly, because they have opaque blocks underneath them.




    In my 1.7 rendering code, I dealt with this by only using AO for the exterior axis-aligned faces and not the sloping ones. But the 1.8 rendering system only allows AO to be turned on or off for the whole model, not individual faces, and unless I'm missing something, only allows one BakedModel to be rendered per block.


    Anyone have any suggestions?

  8. Don't get me wrong, I don't object to the model-based system. For mostly-static rendering, it's fine, and a great improvement. But I don't like being forced to use it, and having to use ugly workarounds to make it more dynamic when needed.


    The frustrating thing is that it doesn't need to be that hard. There's a place in BlockRendererDispatcher that switches on the block's renderType to choose between model rendering and fluid rendering. If there were a Forge hook in there to allow you to plug in a custom renderer at that point, like there used to be, all would be well.


    Is there an official place to make Forge feature requests?

  9. It still seems like terribly convoluted way of going about things. Seemingly I have to extract all the information out of my tile entity and encode it as Properties, only to immediately decode it again in my model. It would be much easier if I just got the world and position passed in directly.


    Then in the model, instead of just rendering things using the tessellator, I have to construct a list of quads in a screwy low level format that involves shoehorning floats into ints? Really?


    The whole thing feels like a massive kludge. The old way may not have been ideal, but it was easy to do unusual things with it. This seems very constraining.


    I hate to think how mods such as Forge Multipart will deal with this. It's not going to be fun for them.

  10. Someone please tell me this is all a bad dream...


    It seems that to use ISmartModel I need to pass information from the tile entity to the model via an IBlockState.


    That's not going to work. There are far too many possible states to encode that way. Plus I need information from adjacent blocks as well.

  11. Is there any way to register a custom block renderer in 1.8?


    In Greg's Blocks for 1.7 I have a block renderer that dynamically computes what to render based on information in the block's tile entity and those of surrounding blocks. There are too many variations on the shape to use a separate model for each one. The textures to be used also depend on the tile entity. I don't want to use a TESR because these blocks are typically used in large numbers, and re-rendered on every frame would be very inefficient.


    I can't see how to handle this with the new rendering system in 1.8.

  12. Project Blue


    This is the beginnings of an add-on for Project Red. I hope to add a lot more content.


    Control Panels




    If your contraption requires more than a couple of buttons or levers to operate, the controls can take up a lot of room and leave you puffed out running back and forth between them. A Control Panel lets you fit up to 16 levers, buttons and indicator lamps into one block space for the ultimate in compactness and ease of use.


    You can make a Control Panel out of any material that a Cover can be made from. Controls for use on the panel can be left plain or painted any of 16 colours. Individual labels can be placed above and below each control.


    The control panel can be mounted on a surface as shown here, or it can be placed flush in a wall with the cable connecting from behind, so that all the wiring is hidden.


    Bundled Cable to RedNet Adaptor




    Relays signals between a Project Red Bundled Cable and a MineFactory Reloaded RedNet cable.




    Version 1.1.6

        Fixed controls reverting to white when removed from a control panel.


    Version 1.1.5

        Fixed crash when spawning a control panel using the /give command.


    Version 1.1.4

    Now works in multiplayer again.


    Version 1.1.3

    Control panels may be rotated by right-clicking on an empty cell with a screwdriver, and the initial orientation of a horizontal control panel is determined by the direction the player is facing when placed.

    Control panels can be placed side by side without connecting to each other, allowing larger control panels to be assembled.

    Control panel related recipes appear in NEI.

    Control panels retain their controls when broken and placed down again.

    Shift-left-click on a control panel with a screwdriver to pick it up instantly.

    Breaking a control panel in creative mode does not destroy it.


    Version 1.1.2

    Fixed breakage of MFR 2.8.0 RC3. Names used to find blocks and items from other mods are now configurable to allow any future incidents of this kind to be worked around.


    Version 1.1.1

    Fixed crash with MFR 2.8.0 RC4.


    Version 1.1.0

    Added Bundled Cable to RedNet Adaptor.


    Version 1.0.1

    Now works on server.

    Fixed display of colour names in tooltips.

    Added more miniature control creative items.





  13. Does any one know of any open source mod that has a tile entity implemented with a forge multi part, so I can have a better understanding of how to efficiently do stuff.

    Project Red makes extensive use of multiparts.


    Also Forge Multipart itself includes multipart versions of some vanilla items such as torches and levers.


    Finally, for what it's worth, here's some code of my own (incomplete) implementing a pipe part. The canConnectToTube() method contains an example of looking at a tile entity to see whether it contains another pipe part. It's a bit specialised, because my pipes are always centre parts and therefore can only appear in slot 6 of the part list. In the general case you would have to iterate over partMap.



    //   Project Blue - Pneumatic Tube Part
    package gcewing.projectblue;
    import java.util.*;
    import net.minecraft.inventory.*;
    import net.minecraft.nbt.*;
    import net.minecraft.tileentity.*;
    import net.minecraft.util.*;
    import net.minecraftforge.common.util.*;
    import codechicken.microblock.*;
    import codechicken.multipart.*;
    import codechicken.multipart.MultiPartRegistry.IPartFactory;
    import codechicken.lib.data.*;
    import codechicken.lib.lighting.*;
    import codechicken.lib.raytracer.*;
    import codechicken.lib.vec.*;
    public class PneumaticTubePart extends JCenterPart implements IHollowConnect {
    final static int tubeWidth = 6; // sixteenths
    final static double h = 0.5 * (tubeWidth / 16.0);
    static Cuboid6 centerBox = new Cuboid6(0.5 - h, 0.5 - h, 0.5 - h, 0.5 + h, 0.5 + h, 0.5 + h);
    static Cuboid6[] sideBoxes = new Cuboid6[6];
    static {
    	for (int i = 0; i < 6; i++) {
    		Transformation t = Rotation.sideRotations[i].at(codechicken.lib.vec.Vector3.center);
    		sideBoxes[i] = new Cuboid6(0.5 - h, 0, 0.5 - h, 0.5 + h, 0.5 - h, 0.5 + h).apply(t);
    public int connections = 0;
    public Collection<TubePayload> payloads;
    public boolean isConnectedOnSide(int i) {
    	return (connections & (1 << i)) != 0;
    public String getType() {
    	return "pb_pneumatictube";
    public int getHollowSize() {
    	return tubeWidth;
    public Iterable<Cuboid6> getCollisionBoxes() {
    	List<Cuboid6> result = new ArrayList<Cuboid6>();
    	for (int i = 0; i < 6; i++)
    		if (isConnectedOnSide(i))
    	return result;
    public Iterable<IndexedCuboid6> getSubParts() {
    	List<IndexedCuboid6> result = new ArrayList<IndexedCuboid6>();
    	result.add(new IndexedCuboid6(6, centerBox));
    	for (int i = 0; i < 6; i++)
    		if (isConnectedOnSide(i))
    			result.add(new IndexedCuboid6(i, sideBoxes[i]));
    	return result;
    public void writeDesc(MCDataOutput data) {
    	data.writeByte(connections & 0xff);
    public void readDesc(MCDataInput data) {
    	connections = data.readByte();
    public void save(NBTTagCompound nbt) {
    	nbt.setInteger("connections", connections);
    public void load(NBTTagCompound nbt) {
    	connections = nbt.getInteger("connections");
    public void renderStatic(codechicken.lib.vec.Vector3 pos, LazyLightMatrix olm, int pass) {
    	if (pass == 0)
    		PneumaticTubeRenderer.renderStaticInWorld(this, pos.x, pos.y, pos.z);
    //	@Override
    //	public void renderDynamic(codechicken.lib.vec.Vector3 pos, float frame, int pass) {
    //	}
    //	@Override
    //	public void drawBreaking(RenderBlocks rb) {
    //	}
    public void onAdded() {
    	if (!world().isRemote)
    public void onPartChanged(TMultiPart part) {
    	if (!world().isRemote)
    public void onNeighborChanged() {
    	if (!world().isRemote)
    void updateConnections() {
    	int mask = 0;
    	for (int i = 0; i < 6; i++) {
    		ForgeDirection d = ForgeDirection.getOrientation(i);
    		TileEntity te = world().getTileEntity(x() + d.offsetX, y() + d.offsetY, z() + d.offsetZ);
    		if (canConnectToTube(te, i ^ 1)) {
    			if (tubeCanConnect(this, i))
    				mask |= 1 << i;
    	if (connections != mask) {
    		connections = mask;
    static boolean canConnectToTube(TileEntity te, int side) {
    	if (te instanceof IInventory)
    		return true;
    	if (te instanceof TileMultipart) {
    		TileMultipart tmp = (TileMultipart)te;
    		TMultiPart part = tmp.partMap(6);
    		if (part instanceof PneumaticTubePart)
    			return tubeCanConnect(part, side);
    	return false;
    static boolean tubeCanConnect(TMultiPart tube, int side) {
    	TMultiPart part = tube.tile().partMap(side);
    	if (part == null)
    		return true;
    	if (part instanceof TFacePart) {
    		TFacePart f = (TFacePart)part;
    		return (f.redstoneConductionMap() & (1 << side)) != 0;
    	return false;
    public static class Factory implements IPartFactory {
    	public TMultiPart createPart(String name, boolean client) {
    		return new PneumaticTubePart();


  14. You need to all markDirty() whenever something in your tile entity changes, so that it will be written out when the world is saved.


    Also, you need to implement getDescriptionPacket() and onDescriptionPacket() even for a single-player environment. There is still a server and a client in single player (they just exist in the same process) and they need to be kept in sync.

  15. Something like


       NBTTagCompound nbt = stack.getTagCompound();
       if (nbt != null) {
          NBTTagCompound disp = nbt.getCompoundTag("display");
          if (disp != null) {
             NBTTagList lore = disp.getTagList("Lore", ;
             if (lore != null) {
                // lore is now a list of NBTTagStrings


  • Create New...

Important Information

By using this site, you agree to our Terms of Use.