Jump to content

Matryoshika

Forge Modder
  • Posts

    523
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by Matryoshika

  1. Inside your IDE, lookup the Entity class.
    Look for the rayTrace method.
    The code can run on both Client & Server side, it's merely been forced to one side by human intervention.

    You can copy it and put it wherever, and it should work. However, you'll need to know blockReachDistance & partialTicks. At least in Eclipse, you can highlight a method/class name, and press Ctrl+Shift+G to find what calls it. I suggest you use that or any equivalent methods in other IDE's to figure out those values.

  2. I am calling MapGenBase::generate inside provideChunk ( this.villageGenerator.generate(this.world, x, z, chunkprimer); )

    And I will update, as soon as I work out these issues. And yes, I hate these names as well, but 1.10 was the version to code in when I started this.

    Personally, I see no point in updating faulty code. You're just dragging broken things into a new environment. It's for the best to fix it all before a major change occurs.

  3. So, for quite some time now, villages have not been generating through my custom ChunkProvider.

     

    I've been debugging, and I've managed to track down where the structure-generation fails ( MapGenVillage ::generateStructure call in my ChunkProvider::populate method)
    In MapGenStructure::generateStructure, I've placed a breakpoint inside the for-loop (StructureStart : structureMap.values)

    Nothing happens. The breakpoint is never reached, which points towards that there are no values inside the structureMap, leading to the for-loop being skipped.

     

    Does anyone know why this is?
    Relevant ChunkProvider code: 91, 312 & 432

  4. 38 minutes ago, funsize888 said:

    Put, @SideOnly(Side.CLIENT) above, public class ClientProxy extends CommonProxy {

    What? The ClientProxy is automatically stripped away from Server-Side by the proxy-injector. 

     

    @Blitex post your main class. Likely you have accidentally misspelled the path to the client-proxy, resulting in the proxy-injector not finding it.

  5. 1 minute ago, V0idWa1k3r said:

    Entity::getCapability allows you to get a specified capability data. As EntityPlayer(and EntityPlayerSP) are child classes of Entity you can use this method just fine.

     

    Minecraft.player was never EntityPlayerMP as EntityPlayerMP is a multiplayer player entity.

     

    NBT has nothing to do with getting the data of a capability.

     

    Capabilities are common and are present on both client and server. What exactly have you tried?

     

    You can simply check that the active itemstack contains the desired item(if the item has a use duration) or if the currently selected itemstack contains the desired item and the right mouse button is pressed down.

    Capabilities are common yes, aka both on the server and client, however, the capability data is only saved on the server. As per official documentation.

    1. You need to put @EventBusSubscriber above the public class Register
    2. The methods (registerBlocks & registerItems) need to be static
    3. You still need to have reference points for your blocks and items
      1. Create a static field in the Register class called OBSIDIAN_INGOT or similar.
      2. Inside the registerAll method, make OBSIDIAN_INGOT = new ItemObsidianIngot(). This way you can use your items in code by calling Register.OBSIDIAN_INGOT.

    The @EventBusSubscriber annotation makes sure that Forge knows that this class contains methods that rely on events. You have to use the annotation because these events are fired before preInit.

     

  6. Create a new class.

    Annotate this new class with @EventBusSubscriber

    Create two public static void methods with Register<Block> and Register<Item> parameters respectively.

    Either manually call event.registry::registerAll(), adding all blocks inside of the method call, or if you have a collection of blocks/items, for that collection call forEach(event.registry::register)

     

  7. For categories, you need to create static inner classes.

    @Config(modid = Echo.MODID, name = "Echo/" + Echo.NAME)
    public class ConfigHandler {
    
    	public static Compat compat = new Compat();
    
    	public static class Compat {
    		@Config.LangKey("config.echo:botania")
    		@Config.Comment("Should Echo add any interactions at all with Botania?")
    		public boolean botania = true;
    
    		@Config.LangKey("config.echo:botania.pool")
    		@Config.Comment("Should Echo add interactions with Botania's pools")
    		public boolean botania_pool = true;
    
    		@Config.LangKey("config.echo:botania.spreader")
    		@Config.Comment("Should Echo add interactions with Botania's Spreader")
    		public boolean botania_spreader = true;
    
    	}
    }

    The configuration code above will contain a sub-category called "compat" that houses the 3 configs pertaining to that category.

    To access for example the botania_spreader config, I call ConfigHandler.compat.botania_spreader.

    I would recommend that you create individual classes for each file.

    • Like 1
  8. 27 minutes ago, Kander16 said:

    By the way, could it be that it's still not fast enough?

    Hmm?
    This way of caching IBakedModels is done on the fly. It cannot be any faster. It literally checks "Do I have this? If yes, reuse. No? Ok, calculating it now, and now I got it"
     

    How are you determining the "speed" of the caching?

     

    Oh, and with you should be able to store quite the amount of different List<BakedQuad>'s in memory. The way it is being rendered now, explicitly only puts them in memory if they have to be drawn. So unless the player goes through each single permutation in a single sitting, the client will never have all the models in memory.

  9. Applying textures is done through JSON files ever since Minecraft 1.8

     

    Normally, for blocks with specific "front" sides, you want your block to dynamically rotate depending on it's relative position to the player (most commonly face the player when placed).
    For that, you need to work with BlockState's. The vanilla furnace is a good example, and the BlockFurnace class should show you how to use PropertyDirection to alter the BlockState.

     

    As for the textures, you can look at the furnace.json located in forgeSrc-<mc.version>-<forge.version>.jar/assets/minecraft/models/block. Use your IDE to find that file.

     

    This model.JSON file has to exist inside src/main/resources/assets/modid/models/block, and if needed, a blockstate.JSON has to exist inside src/main/resources/assets/modid/blockstates

     

    The JSON files have to be completely lowercase in 1.11, and their names have to be identical to your block's RegistryName.

  10. That's because this class is never ever even "seen" by Minecraft.

    (You HAVE to call setRegistryName(string) in your block. Either directly in the constructor or later down the road when you register it. (setRegistryName returns the block itself, with the registryName set))

     

    Create a new class, which you will be using for registration of blocks (and items (held blocks & blocks stored in inventories etc are item (technically ItemBlocks)))
    Annotate this class with @EventBusSubscriber
    Create a public static void method, and subscribe it to the Register<Block> event.

     

    Now, I like to put all my blocks in a list/set collection, and for that collection, call forEach(event.getRegistry::register).

    Of course, you can always just use a for-each loop and call event.getRegistry().register(block).

     

    If you do not want to use a collection, use event.getRegistry().registerAll(), and supply the registerAll all your blocks. (block1, block2... blockn)

    Now, create another public static void method, but subscribe to the Register<Item> event instead.
    For each block you registered in just now, you will need to create a corresponding ItemBlock (so that it can exist in inventories & your hand etc)
    Either for-each loop over the collection, create a new ItemBlock(block) & set it's RegistryName to the block's RegistryName and register it in the event, OR use another lambda expression:

    blockCollection.stream().map(block -> new ItemBlock(block).setRegistryName(block.getRegistryName())).collect(Collectors.toList()).forEach(event.getRegistry()::register);

    Wee bit messier than before. (for each block in this collection(that contains blocks!), create a new ItemBlock, and set it's RegistryName to the block's RegistryName. Put this new ItemBlock into a new list, and for each thing in this new list, register).

    if you have any normal items, you can simply do the same thing we did with blocks, and call forEach(event.getRegistry::register) on the item-list.
    (or as said stick to a simple for-each loop)

    • Like 2
  11. By default, the config file will use the modid as the file-name if no name parameter is given to the annotation.
    Extending from that, if you provide a name that contains file-separators, the folder-structure will be auto-magically built for you.
    For example, I use:

    @Config(modid = Echo.MODID, name = "Echo/"+Echo.NAME)

    where Echo.NAME is the mod's name parameter, per Forge's @Mod annotation.

     

    This creates a sub-folder called "Echo" in the config folder, and a config-file named "Echo" in the mentioned sub-folder.

  12. 14 hours ago, Zealock said:

    core mod and modify the BlockBarrier.class

    You might have missed a pillar of Forge ideology: simply extend the class, override what methods you want to change, and use this new class...

    You don't HAVE to use Barrier blocks, you WANT to use something that works like Barrier blocks.
    ASM is incredibly bad if you don't know what you are doing, and as time and time again has been proven by countless users in the MC modding community, unless you have a few years of expertise, chances are that you do not.
    In fact, countless core-mods could do what was stated above, and look at that, no ASM needed at all.
     

    To make something go invisible, a FastTESR could be used. Override getMaxRenderDistanceSquared in the TE to return the cutoff-point for (rendering->not-rendering)². Default is 4096 (64 block / 4 chunks distance)

    Simple, yet effective way of turning invisible, with minimal code required.

    • Like 1
  13. You can make an ICustomModelLoader.

    Point the ResourceLocation to a custom IModel, that points to a custom IBakedModel.

    In the IBakedModel's getQuads method, provide the list of BakedQuad's to render for the given side.

    Do note, only calculate the BakedQuad's once, and store them somewhere. It's quite expensive to re-calculate every frame.

    • Like 1
  14. You should not store the part integer in the block.

    Blocks are singletons. This means, that there is only 1 of each type, that exists in multiple locations when placed. You change the data in one block, you change the data in all blocks of that type.

     

    Non-final information should be stored in the BlockState directly, or in a TileEntity.

     

    You also have to override shouldRefresh in the TileEntity. By default, the tile is replaced with a new instance if the blockstate changes. Common fix is to return newBlockstate.getBlock() != oldBlockstate.getBlock().

     

    Oh, and the more-than-16-states... Lookup IExtendedBlockState. It can hold more information than normal blockstates (so more than 16 possible states) but the additional data can not actively affect the world like normal blockstates. Extended blockstates are used mostly for storing information that affects rendering etc.

×
×
  • Create New...

Important Information

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