Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by kiou.23

  1. This problem is related to Java, not forge nor optifine I don't think. try updating the java version on your pc
  2. well obviously, Enchantment#canApply(), calls ItemStack#CanApplyAtEnchantingTable(), which calls Item#canApplyAtEnchantingTable. Therefore, you got yourself an infinite loop...
  3. That's odd, I couldn't find anything wrong with the code. could you describe exactly what steps you are taking to run the mod? also: your group in build.gradle and your main path doesn't follow the convention, seeing that you have a github, you could use that http://maven.apache.org/guides/mini/guide-naming-conventions.html EDIT: Ideally I would pull the repo to my machine and try running the mod myself, but my weak computer takes 4 hours to decompile mc, So... sorry I can't do that
  4. you don't need the existing damage, you can call ItemStack#damage() on the stack
  5. make sure you are in the latest version of IntelliJ, if that doesn't fix it, you could you post the build.gradle file.
  6. https://link.springer.com/referenceworkentry/10.1007%2F978-3-319-08234-9_272-1 It's the architecture, the server does all the logical shenanigans, and the client is only a viewport, an interface to the state that's managed in the server side
  7. did you refresh the project after you made changes to build.gradle?
  8. This forum isn't for annoying people asking for mods, go do that somewhere else
  9. You need to update the build.gradle to have your modid instead of the default examplemod you'll want to modify the group, the modid and pretty much everywhere where "examplemod" is shown, you'll want to replace with your own modid note: you have a static field in your main mod class (Warwolves.java) called MOD_ID, whenever you need the mod id, you should be referencing this field, instead of typing the string every time note 2: don't create an ItemBase class https://championash5357.github.io/ChampionAsh5357/tutorial/minecraft/ciar#code-style-5
  10. the whole point of the Data Generators is for the dev to not waste time writing (copying and pasting) repetitive json it automates the whole process of generating data. sometimes it is better to write the json by hand, but if the project is quite big, looking into Data Generators is definetelly the way to go, not only for loot tables, but for everything that uses json erally, such as block and item models, blockstates, lang files, recipe files and tags. it does save a lot of time, I can guarantee that
  11. If all you want is to change the screen, not the block itself, you can create your own ContainerScreen, and than bind that to the vanilla Containers
  12. you could write the loot tables by hand, but forge provides a more developer friendly way of adding loot tables through data generators. here's the docs for data generation: https://mcforge.readthedocs.io/en/1.16.x/datagen/intro/ but basically what you'll want to do is: 1- Subscribe to the GatherDataEvent in the Mod Event bus, there you can get the DataGenerator from the event parameter 2- You can register your Data Providers to the DataGenerator using DataGenerator#addProvider(), passing a new instance of your data Provider 3- Then you'll need a Data Provider for the mod's loot tables. You can create a new class that extends LootTableProvider. 3.1- in your LootTableProvider, add a constructor that takes a Data Generator and simply calls super, passing the data generator 3.2- You'll want to override the getTables methods, to return your instance of lootTables. all you need to do is return an ImmutableList of Pairs. the Pairs are composed of the LootTable constructor (We'll look at how to create the lootTables in a few steps), and the corresponding LootParameterSet (e.g.: for items that drops when you break a block: LootParameterSets.BLOCK) 3.3- You'll need to override the validate method, and honestly, the code for this is only boilerplate, so you can copy it like I did: @Override protected void validate(Map<ResourceLocation, LootTable> map, ValidationTracker validationtracker) { final Set<ResourceLocation> modLootTableIds = LootTables .getReadOnlyLootTables() .stream() .filter(lootTable -> lootTable.getNamespace().equals(Main.MOD_ID)) .collect(Collectors.toSet()); for (ResourceLocation id : Sets.difference(modLootTableIds, map.keySet())) validationtracker.addProblem("Missing mod loot table: " + id); map.forEach((id, lootTable) -> LootTableManager.validateLootTable(validationtracker, id, lootTable)); } 3.4- Finally, override getName() and simply return your modid suffixed with "_lootTables" 4- Okay, now to writing the actual loot tables: you can create a class that overrides BlockLootTables (call it ModBlockLootTables for instance) 4.1- override addTables(), and in here you register the lootTables, the superclass has a lot of usefull helper methods, such as registerDropSelfLootTable, which makes the block drop itself as an item when broken. 4.2- override the getKnownBlocks() method, the code is also very boilerplatey, so here it is: @Override protected Iterable<Block> getKnownBlocks() { return StreamSupport .stream(ForgeRegistries.BLOCKS.spliterator(), false) .filter( entry -> entry.getRegistryName() != null && entry.getRegistryName().getNamespace().equals(Main.MOD_ID) ).collect(Collectors.toSet()); } 5- Don't forget to add the construcor of this class to the List you're returning in the LootTablesProvider, in getTables Regarding folder structure: create a data package under your main src path, where you'd keep the init, block, and items folder under I like to create a class DataGenerators, which handles the gatherData event. then inside the data package, add two packages, one "client", and one "server" in client you'd add any dataProvider that's client specific: such as a model provider, or a localization provider in server you'd keep the common data providers: such as recipes, tags, and lootTables the Custom LootTablesProvider class should go inside the data.server package inside server add a loot package, whre you'll kep different lootTables, such as the Custom BlockLootTables class EDIT: oh, and after you're done with the data folder, and after every change you make to it, you need to run the runData task, to actually generate the data, any data that is generated will be under the generated [main] folder if you'd like some example code, take a look at my repo: https://github.com/jvcmarcenes/effetewood Hope I've helped, if you still have any questions, please ask them
  13. Wow that's alot, I was trying to do the brute force way of simply reimplementing all the classes over, but it didn't quite work. I'll take a look at your solution and try doing that. Thank you a lot for taking the time to help me with this! (is it fine for me to dm you on discord if I face a roadblock again? relevant to adding this signs of course)
  14. Did the classes, now the edit screen shows up, and if I use a vanilla WoodType for the sign, the texture shows up in the edit screen (not in the actual block tho, it still won't render) the changes are on github. How should I go about rendering the Sign again? I'll need to write my own TileEntityRenderer?
  15. Okay, so my Custom Sign Tile Entity has to extend SignTileEntity, because PlayerEntity#openSignEditor() expects a SignTileEntity. but from there I can't call super() and pass in my custom Tile Entity Type, because the TileEntityType for SignTileEntity is hardcoded in the constructor. How to proceed?
  16. so I also need to write my own Sign blocks? and can I just make them a subclass of the vanilla classes?
  17. git repo: https://github.com/jvcmarcenes/effetewood
  18. I'll try it (Edit: nvm, no idea how to try it, and it may not even work) there seems to be another problem tho: I changed the wood type of the sign to OAK, just to see if it rendered with a vanilla wood type, and nope. it's still invisible. however, the edit screen has the oak sign texture (it still only stays up for milliseconds) this has to be related to something else, right?
  19. Alright, where can I learn about the ObsfuscationReflectionHelper and SRG names? (and by register, you mean registering to the VALUES field from the WoodType class?) doesn't this do it? Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete"))); if it doesn't, can you point me towards how I would write my own renderer?
  20. I had asked on discord and someone suggested using reflection. but yeah, a subclass is way better This is correct? public class ModWoodType extends WoodType { public static final WoodType EFFETE = new ModWoodType("effete"); protected ModWoodType(String name) { super(name); } } Yeah, you told me that in another thread. But since I don't need to use reflection, I'm going to postpone studying error handling to another week And how should I go about doing that? I tried: @SubscribeEvent public static void modelRegistryEvent(ModelRegistryEvent e) { Atlases.SIGN_MATERIALS.put(ModWoodType.EFFETE, new RenderMaterial(Atlases.SIGN_ATLAS, new ResourceLocation("effetewood:entity/signs/effete"))); } It still doesn't work (The edit screen pops up for less than a second, and appear to have the missing pink/black texture), and the actual block just is invisible (dumb question: I don't need to specify "textures/entity/..." in the resouce location, right?)
  21. I have registered blocks for both a Standing Sign, and Wall Sign and I have registered an item for the sign. I did reflection for registering a wood type, and am using this wood type in the signs I have the texture for the wood type under textures/entity/signs and I have created the blockstate and model files, copying the vanilla ones (where the blockstates point to a model file that only has a texture for particles) However, the Sign still won't render, and the edit sign screen won't show up. Sometimes the game crashes when I place a sign, with a NPE, but it isn't consistent. Sign block registration: EFFETE_SIGN = registerNoItem("effete_sign", () -> new StandingSignBlock( AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME) .doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD), Main.EFFETE_WOOD_TYPE)); EFFETE_WALL_SIGN = registerNoItem("effete_wall_sign", () -> new WallSignBlock( AbstractBlock.Properties.create(Material.NETHER_WOOD, MaterialColor.LIME) .doesNotBlockMovement().hardnessAndResistance(1.0F).sound(SoundType.WOOD).lootFrom(EFFETE_SIGN.get()), Main.EFFETE_WOOD_TYPE)); Blockstate and model files: { "textures": { "particle": "effetewood:block/effete_planks" } } { "variants": { "": { "model": "effetewood:block/effete_sign" } } } Wood Type registration and Reflection code: private void setup(final FMLCommonSetupEvent event) { reflectionSetup(); try { EFFETE_WOOD_TYPE = (WoodType) registerWoodTypeMethod.invoke(null, woodTypeConstructor.newInstance("effete")); } catch (Exception e) { LOGGER.error("Error registering wood type"); e.printStackTrace(); } } private void reflectionSetup() { if (woodTypeConstructor != null) woodTypeConstructor.setAccessible(true); if (registerWoodTypeMethod != null) registerWoodTypeMethod.setAccessible(true); } private static final Constructor<WoodType> woodTypeConstructor; private static final Method registerWoodTypeMethod; private static Constructor<WoodType> getWoodTypeConstructor() { try { return WoodType.class.getDeclaredConstructor(String.class); } catch (Exception e) { LOGGER.error("Exception in getWoodTypeConstructor: " + e.getMessage()); e.printStackTrace(); return null; } } private static Method getRegisterWoodTypeMethod(){ try { return WoodType.class.getDeclaredMethod("register", WoodType.class); } catch (Exception e) { LOGGER.error("Exception in getRegisterWoodTypeMethod: " + e.getMessage()); e.printStackTrace(); return null; } } static { woodTypeConstructor = getWoodTypeConstructor(); registerWoodTypeMethod = getRegisterWoodTypeMethod(); }
  22. I'm using Data Generators to generate the models and block states files, however, when I run runData, it errors with IllegalArgumentException, "Texture effetewood:block/effete_planks does not exist in any know resource pack". Even tho there's a png with the correct name in the textures/block folder. this is the registerStatesAndModel: @Override protected void registerStatesAndModels() { ResourceLocation name = ModBlocks.EFFETE_PLANKS.get().getRegistryName(); Main.LOGGER.info(name.getNamespace() + ":" + ModelProvider.BLOCK_FOLDER + "/" + name.getPath()); simpleBlock(ModBlocks.EFFETE_PLANKS.get()); logBlock(ModBlocks.EFFETE_STEM.get()); logBlock(ModBlocks.STRIPPED_EFFETE_STEM.get()); } and this is the data section in the build.gradle: data { workingDirectory project.file('run') // Recommended logging data for a userdev environment property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' // Recommended logging level for the console property 'forge.logging.console.level', 'debug' // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. args '--mod', 'effetewood', '--all', '--existing', file('src/main/resources/').toString(), '--existing', file('src/generated/resources/').toString(), '--output', file('src/generated/resources/') mods { effetewood { source sourceSets.main } } }
  23. YEAH, I guessed the fault it was taking so long would be my pc didn't imagine it would take 4 hours and a half tho It did work, after painful waiting, so it's fine now
  24. Intel E5400, with 3GB of ram, running Windows 8.1. with a Nvidia GeForce 210. it's a pretty old machine However, I let the IDE import the project over night, it did take 4 and a half hours... but it did import
  • Create New...

Important Information

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