Jump to content

ChampionAsh5357

Members
  • Posts

    3284
  • Joined

  • Last visited

  • Days Won

    62

Everything posted by ChampionAsh5357

  1. I feel like you just ignored what I wrote. Go back and reread. Don't show me some youtube video. As a person who makes videos on youtube, its terrible most of the time, including my own.
  2. I need a facepalm emoji so badly. I use the double colon operator to specify the location of a function. Let's break down what you wrote. First, you tried calling a static method using the double colon operator. Please learn some basic java and don't just follow some youtube tutorial. If you want a hint, a dot helps. Second, you called new on a method. You can only call new on constructors to create objects. A method is not a constructor. In this case, DeferredRegister::create is a static method for a constructor initialization circumventing the new operator (its called inside). And the easiest way you could've found this out is by reading the docs.
  3. A warning is not an error. An error is an error. It's letting you know that this method of calling the constructor is deprecated and should be replaced with DeferredRegister::create. However, you could of found this out by hovering over the strike-through.
  4. Wherever you want. I structure files in places for organizational purposes. Put it where you please. I feel as though Novârch said it best:
  5. Um. So you're basically asking for F3 except with no rendering behind it? Why don't you just draw a more opaque box behind the text so you can show the information better. If you could give more context as to why you are trying to accomplish this, it would be helpful.
  6. Oh wait. You have to call setRequiresTool or func_235861_h_ in your block properties depending on your mapping version.
  7. Well assuming its a modded entity, it would be in File -> Export -> Export Java Entity
  8. What version of forge are you using? This did not work up until 32.0.55 I believe.
  9. No. Food specifically has a method for applying effects. Use the supplier version of the it. Do not override a method for an already implemented purpose.
  10. I agree. Trying to set something as accessible when ObfuscationReflectionHelper::findField already does that for you makes no sense. Also casting an object to another with no relation also is bonkers. Just remove you trying to set accessible. Also, if you want to remove individual vanilla brewing recipes, you will need to access the data in PotionBrewing.
  11. I want to do a verification check on my two custom providers before I go and write a tutorial on their implementation. The first one is an advancements provider that takes in a FinishedAdvancement (basically an advancement still as a builder and its location. It's almost exactly similar to the Minecraft implementation. public abstract class AdvancementsProvider implements IDataProvider { private static final Logger LOGGER = LogManager.getLogger(); private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().create(); private final DataGenerator generator; public AdvancementsProvider(DataGenerator generatorIn) { this.generator = generatorIn; } @Override public void act(DirectoryCache cache) throws IOException { Path path = this.generator.getOutputFolder(); Set<ResourceLocation> set = Sets.newHashSet(); Consumer<FinishedAdvancement> consumer = (advancementIn) -> { if (!set.add(advancementIn.getId())) { throw new IllegalStateException("Duplicate advancement " + advancementIn.getId()); } else { Path path1 = getPath(path, advancementIn); try { IDataProvider.save(GSON, cache, advancementIn.serialize(), path1); } catch (IOException ioexception) { LOGGER.error("Couldn't save advancement {}", path1, ioexception); } } }; for(Consumer<Consumer<FinishedAdvancement>> consumer1 : this.getAdvancements()) { consumer1.accept(consumer); } } public abstract List<Consumer<Consumer<FinishedAdvancement>>> getAdvancements(); private static Path getPath(Path pathIn, FinishedAdvancement advancementIn) { return pathIn.resolve("data/" + advancementIn.getId().getNamespace() + "/advancements/" + advancementIn.getId().getPath() + ".json"); } @Override public String getName() { return "Advancements"; } } public class FinishedAdvancement { private final ResourceLocation id; private final Advancement.Builder builder; private FinishedAdvancement(ResourceLocation idIn, Advancement.Builder builderIn) { this.id = idIn; this.builder = builderIn; } public JsonObject serialize() { return this.builder.serialize(); } public ResourceLocation getId() { return id; } public static class Builder { private Advancement.Builder builder; private Builder() {} public static FinishedAdvancement.Builder builder() { return new FinishedAdvancement.Builder(); } public FinishedAdvancement.Builder advancement(Advancement.Builder builderIn) { this.builder = builderIn; return this; } public FinishedAdvancement build(Consumer<FinishedAdvancement> consumer, ResourceLocation id) { FinishedAdvancement advancement = new FinishedAdvancement(id, builder); consumer.accept(advancement); return advancement; } } } The second one is a basic provider for a sounds.json file. The only parameter it doesn't take into account is its type since that is automatically set for its usage. public abstract class SoundsProvider implements IDataProvider { private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); private final DataGenerator gen; private final String modid; public SoundsProvider(DataGenerator gen, String modid) { this.gen = gen; this.modid = modid; } protected abstract void addSounds(Consumer<SoundBuilder> consumer); @Override public void act(DirectoryCache cache) throws IOException { JsonObject object = new JsonObject(); addSounds(builder -> builder.serialize(object)); IDataProvider.save(GSON, cache, object, this.gen.getOutputFolder().resolve("assets/" + modid + "/sounds.json")); } @Override public String getName() { return "Sounds"; } } public class SoundBuilder { private ResourceLocation name; private boolean replace; @Nullable private String subtitleTranslationKey; private final List<SoundExtension> sounds = new ArrayList<>(); private SoundBuilder(ResourceLocation location) { this.name = location; } public static SoundBuilder builder(SoundEvent sound) { return builder(sound.getRegistryName()); } public static SoundBuilder builder(Supplier<? extends SoundEvent> soundSupplier) { return builder(soundSupplier.get()); } public static SoundBuilder builder(ResourceLocation location) { return new SoundBuilder(location); } public SoundBuilder replace() { this.replace = true; return this; } public SoundBuilder subtitle() { return subtitle("subtitle." + name.getNamespace() + "." + name.getPath()); } public SoundBuilder subtitle(String translationKey) { this.subtitleTranslationKey = translationKey; return this; } private SoundBuilder defaultSound() { return sound(this.name); } public SoundBuilder sound(ResourceLocation name) { this.sounds.add(new SoundExtension(name)); return this; } public SoundBuilder sound(SoundExtension soundIn) { this.sounds.add(soundIn); return this; } public void build(Consumer<SoundBuilder> consumer) { this.validate(); consumer.accept(this); } private void validate() { if(this.sounds.isEmpty()) { this.defaultSound(); } this.sounds.forEach(SoundExtension::validate); } public void serialize(JsonObject parentObject) { JsonObject object = new JsonObject(); object.addProperty("replace", this.replace); if(subtitleTranslationKey != null) { object.addProperty("subtitle", this.subtitleTranslationKey); } JsonArray array = new JsonArray(); this.sounds.forEach(sound -> array.add(sound.serialize())); object.add("sounds", array); parentObject.add(this.name.getPath(), object); } public static class SoundExtension { private final String name; private float volume = 1.0f, pitch = 1.0f; private int weight = 1, attenuation_distance = 16; private boolean stream, preload; private SoundExtension(ResourceLocation name) { this.name = name.toString().replaceAll("[.]", "/"); } public static SoundExtension builder(ResourceLocation name) { return new SoundExtension(name); } public SoundExtension volume(float volumeIn) { this.volume = volumeIn; return this; } public SoundExtension pitch(float pitchIn) { this.pitch = pitchIn; return this; } public SoundExtension weight(int weightIn) { this.weight = weightIn; return this; } public SoundExtension stream() { this.stream = true; return this; } public SoundExtension attenuationDistance(int attenuationDistanceIn) { this.attenuation_distance = attenuationDistanceIn; return this; } public SoundExtension preload() { this.preload = true; return this; } private void validate() { if(this.volume != MathHelper.clamp(this.volume, 0, 1.0)) { throw new IllegalArgumentException("Sound " + name + " has a volume not between 0 and 1."); } else if(this.pitch != MathHelper.clamp(this.pitch, 0, 2.0)) { throw new IllegalArgumentException("Sound " + name + " has a pitch not between 0 and 2."); } else if(this.weight <= 0) { throw new IllegalArgumentException("Sound " + name + " has a negative or zero weight."); } else if(this.attenuation_distance <= 0) { throw new IllegalArgumentException("Sound " + name + " has a negative or zero attenuation distance."); } } private JsonObject serialize() { JsonObject object = new JsonObject(); object.addProperty("name", this.name); object.addProperty("volume", this.volume); object.addProperty("pitch", this.pitch); object.addProperty("weight", this.weight); object.addProperty("weight", this.weight); object.addProperty("stream", this.stream); object.addProperty("attenuation_distance", this.attenuation_distance); object.addProperty("preload", this.preload); return object; } } } Please let me know if there is anything I can do to improve the quality of this code.
  12. Gravity is a myth for the basic Entity class. Give it some velocity and it'll start moving in the direction you want. Probably should use Entity::setMotion and some Vector3d::add. You also might want to override the tick method.
  13. You've already asked that in a different post and I already gave you a reference in that one.
  14. There is an overlay layer however that is used specifically for dyeable armor. You'll probably have to create a custom armor model.
  15. Brewing recipes are hooked in via BrewingRecipeRegistry::addRecipe. Also, are you seriously calling the brewing recipes in your constructor before the potions are even registered? This should be done within FMLCommonSetupEvent surrounded by a DeferredWorkQueue.
  16. Ahem. I absolutely hate having to watch a youtube video to find out a mistake. And I mean wow. Its the mistake I guessed it would be. You should probably check out the mods.toml and correctly update it to the loader version and dependencies inside. Next time just give us your code.
  17. Feel free to read through this. I also posted it in user submitted tutorials because of the giant problems in understanding how ModelRenderer works.
  18. Yes, calling the method to add particles on the server would be pointless as the method does nothing. So it should be checked and called on the client.
  19. You should really read the source information provided with it. Pass in a TileEntityType and a Function that takes in a dispatcher and returns a TER (double colon operators are helpful). You can call it within FMLClientSetupEvent. If it doesn't work, then you probably haven't specified any blocks that can use your tileentity in the builder.
  20. You would need to call a event that is handled in Minecraft's constructor. Do note that forge's event bus doesn't start until mod loading is completed meaning that it has to be called from somewhere on the mod event bus. The Lifecycle Events for creating and loading registries would work, but then we have to deal with it being fired specifically for the client. The easiest event to use is actually ParticleFactoryRegisterEvent. Do remember this is on your mod's event bus and only on the client side.
  21. https://mcforge.readthedocs.io/en/latest/blocks/interaction/#onblockactivated
  22. WorldSavedData in the docs is ridiculously outdated due to a lack of information and just pure complexity. As for capabilities, I'm not sure if they fixed world capabilities yet due to the rework of the world and dimension system.
×
×
  • Create New...

Important Information

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