Jump to content

createTileEntity in Block [1.16.1] any way to auto from registry?


jackokring

Recommended Posts

@Nullable
@Override
public TileEntity createTileEntity(BlockState state,
                                   IBlockReader world) {
    //TODO: behaviour alteration
    ResourceLocation rl = getRegistryName();
    //RegistryManager.ACTIVE.getRegistry(TileEntityType.class) ->
    return new SigmaTileEntity();
}
Link to comment
Share on other sites

Hi,

 

Sorry for the GIGO. I wish to convert the Java "this" (which is a Block in context) into the TileEntity registered against the block with

 

tileEntitySigma = TileEntityType.Builder
        .create(SigmaTileEntity::new, sigma).build(null);
//technically type is null and used in constructor before assignment (pokey pointer variant generic?)
// you probably don't need a datafixer --> null should be fine
tileEntitySigma.setRegistryName("te_sigma");
event.getRegistry().register(tileEntitySigma);

 

It's not essential, but it would be nicer to not have to edit the method createTileEntity in sub-classes (mainly an automation error reduction process). From this registration I assume (perhaps in error) that an association is made that will be a reference to making a new SigmaTileEntity.

 

return ForgeRegistries.TILE_ENTITIES.getValue(this.getRegistryName())
    .create();

 

I assume this need identical ResourceLocation strings which I could do.

 

Cheers Jacko. 

 

Link to comment
Share on other sites

class Block {

... this ...

//turn a block into a new relevant TileEntity

 ... return new TileEntity();

}

 

So that the following becomes easy to have multiple TileEntity sub-classes without re-classing the basic Block logic, and just using ResourceLocation to change models.

 

@Mod("jacko")
public class Jacko {
    // Directly reference a log4j logger.
    private static final Logger LOGGER = LogManager.getLogger();

    public Jacko() {
        // Register the setup method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
        // Register the enqueueIMC method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC);
        // Register the processIMC method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC);
        // Register the doClientStuff method for modloading
        FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff);

        // Register ourselves for server and other game events we are interested in
        MinecraftForge.EVENT_BUS.register(this);
    }

    private void setup(final FMLCommonSetupEvent event) {
        // some preinit code
        LOGGER.info("HELLO FROM PREINIT");
        LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
    }

    private void doClientStuff(final FMLClientSetupEvent event) {
        // do something that can only be done on the client
        LOGGER.info("Got game settings {}",
                event.getMinecraftSupplier().get().gameSettings);
        //IMC supplier and field
    }

    private void enqueueIMC(final InterModEnqueueEvent event) {
        // some example code to dispatch IMC to another mod
        InterModComms.sendTo("jacko", "hello_world",
                () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";});
        //binding element manufacture to supply
    }

    private void processIMC(final InterModProcessEvent event) {
        // some example code to receive and process InterModComms from other mods
        LOGGER.info("Got IMC {}", event.getIMCStream().
                map(m -> m.getMessageSupplier().get()).
                collect(Collectors.toList()));
        //collect all supplied as a list
    }

    // You can use SubscribeEvent and let the Event Bus discover methods to call
    @SubscribeEvent
    public void onServerStarting(FMLServerStartingEvent event) {
        // do something when the server starts
        LOGGER.info("HELLO from server starting");
        event.getCommandDispatcher().register(
                Commands.literal("foo")
                        .requires(source -> source.hasPermissionLevel(4))
                        .then(
                                Commands.argument("bar", integer())
                                        .executes(context -> {
                                            System.out.println("Bar is " + getInteger(context, "bar"));
                                            return 1;
                                        })
                        )
                        .executes(context -> {
                            System.out.println("Called foo with no arguments");
                            return 1;
                        })
        );
    }

    public static class RangedRocker {
        public int count, bottomOffset, topOffset, max;
        public RangedRocker(int countSet, int bottomOffsetSet, int topOffsetSet, int maxSet) {
            count = countSet;
            bottomOffset = bottomOffsetSet;
            topOffset = topOffsetSet;
            max = maxSet;
        }
    }

    //count = iterative attempts to match random location with that to be replaced for spawn (commonality)
    //bottomOffset/topOffset = bottom and top offsets. 0 - 255 range squish
    //max = maximum cascade iterates
    public static RangedRocker[] ranges = {
        new RangedRocker(12, 5, 5, 80),
        new RangedRocker(18, 3, 5, 80),
        new RangedRocker(15, 8, 5, 50)
    };

    public static class BiomeRocker {
        Biome biome;
        OreFeatureConfig.FillerBlockType find;
        Block replace;
        RangedRocker range;
        Biome.Category subFilter;
        int size;
        boolean terminal;

        public BiomeRocker(OreFeatureConfig.FillerBlockType findSet, Block replaceSet, RangedRocker rangeSet,
                           int sizeSet, boolean terminalSet,
                           Biome.Category subFilterSet, Biome biomeSet) {
            biome = biomeSet;
            find = findSet;
            replace = replaceSet;
            range = rangeSet;
            subFilter = subFilterSet;
            size = sizeSet;
            terminal = terminalSet;
        }
    }

    //Seems to be no End Stone Ore type
    public static OreFeatureConfig.FillerBlockType END_STONE =
            OreFeatureConfig.FillerBlockType.create("END_STONE","end_stone",
                    new BlockMatcher(Blocks.END_STONE));

    //filters to iterate
    //more generic later as only applied per biome until terminalSet = true
    //sizeSet is vein size
    public static BiomeRocker[] biomes = {
        new BiomeRocker(OreFeatureConfig.FillerBlockType.NETHERRACK, unlock, ranges[0], 4, true,
                Biome.Category.NETHER, null),
        new BiomeRocker(END_STONE, unlock, ranges[1], 12, true,
                Biome.Category.THEEND, null),
        new BiomeRocker(OreFeatureConfig.FillerBlockType.NATURAL_STONE, unlock, ranges[2], 6, true,
                null, null)
    };

    @SubscribeEvent
    public static void generateOres(FMLLoadCompleteEvent event) {
        for (Biome biome : ForgeRegistries.BIOMES) {
            for(BiomeRocker br : biomes) {
                if(br.biome == null || biome == br.biome) {
                    if(br.subFilter == null || biome.getCategory() == br.subFilter) {
                        RangedRocker rr = br.range;
                        CountRangeConfig range = new CountRangeConfig(rr.count, rr.bottomOffset, rr.topOffset, rr.max);
                        OreFeatureConfig feature = new OreFeatureConfig(br.find, br.replace.getDefaultState(), br.size);
                        ConfiguredPlacement config = Placement.COUNT_RANGE.configure(range);
                        biome.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.
                                withConfiguration(feature).withPlacement(config));
                        if(br.terminal) break;//exit all applied per biome
                    }
                }
            }
        }
    }

    // You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD
    // Event bus for receiving Registry Events)
    @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
    public static class RegistryEvents {

        @SubscribeEvent
        public static void registerBlocks(RegistryEvent.Register<Block> event) {
            unlock = new Block(Block.Properties.create(Material.MISCELLANEOUS)
                    //.hardnessAndResistance(3f, 3f) //emerald level
                    .sound(SoundType.SCAFFOLDING)
                    //.slipperiness(0.5f)
            );
            unlock.setRegistryName("jacko", "unlock");
            //see @ObjectHolder in uk.co.kring.mc.Blocks field import static
            event.getRegistry().register(unlock);

            sigma = new CalculationProviderRedstoneBlock();//needs TileEntity registering with same "name"
            sigma.setRegistryName("jacko", "sigma");
            event.getRegistry().register(sigma);
        }

        @SubscribeEvent
        public static void registerItems(RegistryEvent.Register<Item> event) {
            final int MAXIMUM_STACK_SIZE = 64;
            final int POTION_STACK_SIZE = 1;
            final int BOOK_STACK_SIZE = 16;
            final ItemGroup customItemGroup = new ItemGroup("jacko_item_group") {
                @Override
                public ItemStack createIcon() {
                    return new ItemStack(Items.EMERALD);
                }
            };

            Item.Properties itemP = new BlockItem.Properties().group(customItemGroup)
                    .maxStackSize(MAXIMUM_STACK_SIZE);
            BlockItem unlockItem = new BlockItem(unlock, itemP);
            unlockItem.setRegistryName(unlock.getRegistryName());
            event.getRegistry().register(unlockItem);

            itemP = new BookItem.Properties().group(customItemGroup)
                    .maxStackSize(BOOK_STACK_SIZE);
            Item bookItem = new Item(itemP);
            bookItem.setRegistryName("jacko", "book");
            event.getRegistry().register(bookItem);

            itemP = new PotionItem.Properties().group(customItemGroup)
                    .maxStackSize(POTION_STACK_SIZE);
            Item potionItem = new PotionItem(itemP);
            potionItem.setRegistryName(zerog.getRegistryName());
            event.getRegistry().register(potionItem);

            itemP = new BlockItem.Properties().group(customItemGroup)
                    .maxStackSize(MAXIMUM_STACK_SIZE);
            BlockItem sigmaItem = new BlockItem(sigma, itemP);
            sigmaItem.setRegistryName(sigma.getRegistryName());
            event.getRegistry().register(sigmaItem);
        }

        @SubscribeEvent
        public static void registerTE(final RegistryEvent.Register<TileEntityType<?>> event) {
            tileEntitySigma = TileEntityType.Builder
                    .create(SigmaTileEntity::new, sigma).build(null);
            //technically type is null and used in constructor before assignment (pokey pointer variant generic?)
            // you probably don't need a datafixer --> null should be fine
            tileEntitySigma.setRegistryName(sigma.getRegistryName());
            event.getRegistry().register(tileEntitySigma);
        }

        @SubscribeEvent
        public static void registerEffects(final RegistryEvent.Register<Effect> event) {

        }

        @SubscribeEvent
        public static void registerPotions(final RegistryEvent.Register<Potion> event) {
            zerog = new Potion();
            zerog.setRegistryName("jacko", "zerog");
            event.getRegistry().register(zerog);//might need registering
        }
    }
}
Edited by jackokring
Link to comment
Share on other sites

40 minutes ago, jackokring said:

I wish to convert the Java "this" (which is a Block in context) into the TileEntity registered against the block with

This statement makes no sense. You can't "convert" a block to a TileEntity. You can't even assume that a block only has one TE it supplies.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

Hi,

 

I wish to instance a tile entity from a block object (i.e. convert one into the other). This might not exactly imply the finality of this, but when I convert from centigrade to Fahrenheit, I do not alter either). I know I can't assume other people would only have one tile entity, but I can design to the principal and so not be inconsistent in my design. I could handle any situation where I'd need a multiple tile entity (as the function itself  (Block.createTileEntity) does not return an array of tile entities) by making a class CompoundTileEntity<A, B> if the need arises.

Link to comment
Share on other sites

1 hour ago, jackokring said:

This might not exactly imply the finality of this, but when I convert from centigrade to Fahrenheit, I do not alter either)

You're asking to convert from centigrade to pounds.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

8 minutes ago, jackokring said:

More of a not centigrade to kelvin. 🥳 As it's both an associated scale and offset. Likely have to store that just in case it varies with the map co-ordinates.

No.

 

I'm saying that the two things are fundamentally unrelated: like temperature and weight.

 

They appear to have a relationship (after all, objects have both temperature and weight...) in that a given block that has a tile entity will have createTileEntity called and it will return a value, but you can't 1:1 map those two things together in any meaningful sense.

 

For example this:

https://github.com/Draco18s/ReasonableRealism/blob/1.14.4/src/main/java/com/draco18s/harderores/block/AxelBlock.java#L66-L77

Sometimes the block has a TE, sometimes it does not.

Writing a condition that says "when the block has X state, it return TE_X, when it has Y state it returns TE_Y, when it is in Z state, it returns null."

It is even possible to write two different blocks to have the same TE. The vanilla furnace for example: at one time the lit furnace and the unlit furnace were two, completely separate, blocks that the game would switch between in order to handle lighting.

 

You simply cannot convert from one to the other because it does not make sense to even ask the question.

Edited by Draco18s

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

OK, I got it. It will not however stop me as I am quite prepared to operate within the constraint of making my variants per resource named block occur within a unified tile entity within my mod.  As my code stands at the moment I have 4 blocks all using the same class, but each loads a unique tile entity based on resource name. They will all be redstone components, and the only behaviour difference is the output calculation and hence stored data. As the texture is loaded via resource name, this allows individual textures. They have individual block state assets for example.

 

In this sense I already have 4 tile entities fro one block class, but as the variant is based on the resource name, then the right tile entity is used for the right CalculationProvider interface in my tile entities which all extend DelayTileEntity (to prevent update feedback loops) which implements CalculationProvider but abstract so not really and it causes a forced implementation requirement in the sub-class which is itself registered under the resource name.

 

Jacko

Link to comment
Share on other sites

if(this == MyBlocks.BlockA) {
	return new TileEntityA();
}
if(this == MyBlocks.BlockB) {
	return new TileEntityB();
}
...

?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

You could probably pass a Supplier/RegistryObject of the TileEntityType to the Block's constructor, then use that to create the TileEntity.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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