From 82202d13ef3eac106c309818d00ce10ffd4f8eb6 Mon Sep 17 00:00:00 2001 From: Coda Date: Mon, 18 Oct 2021 20:46:46 -0600 Subject: [PATCH 01/29] switch a switch to an if (see what i did there?) --- src/main/java/mod/teamdraco/bettas/Bettas.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/mod/teamdraco/bettas/Bettas.java b/src/main/java/mod/teamdraco/bettas/Bettas.java index 3527c1c..73150b6 100644 --- a/src/main/java/mod/teamdraco/bettas/Bettas.java +++ b/src/main/java/mod/teamdraco/bettas/Bettas.java @@ -59,10 +59,9 @@ public Bettas() { @SubscribeEvent(priority = EventPriority.LOWEST) public static void registerBiomes(BiomeLoadingEvent event) { - switch (event.getCategory()) { - case SWAMP: - event.getSpawns().getSpawner(EntityClassification.WATER_CREATURE).add(new MobSpawnInfo.Spawners(BettasEntities.BETTA_FISH.get(), 1, 1, 2));event.getGeneration().getFeatures(GenerationStage.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new FeatureSpreadConfig(5)).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).chance(16)); - break; + if (event.getCategory() == Biome.Category.SWAMP) { + event.getSpawns().getSpawner(EntityClassification.WATER_CREATURE).add(new MobSpawnInfo.Spawners(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); + event.getGeneration().getFeatures(GenerationStage.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new FeatureSpreadConfig(5)).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).chance(16)); } } From 1efd78a9e254825e99033df8185f5578648ddb81 Mon Sep 17 00:00:00 2001 From: Coda Date: Mon, 15 Nov 2021 07:09:29 -0700 Subject: [PATCH 02/29] \o/ --- build.gradle | 12 +- gradle/wrapper/gradle-wrapper.jar | Bin 54708 -> 59536 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- .../java/mod/teamdraco/bettas/Bettas.java | 103 -------------- .../bettas/ClientEventBusSubscriber.java | 35 ----- .../bettas/client/model/BettaFishModel.java | 87 ------------ .../bettas/feature/MossBallFeature.java | 40 ------ .../teamdraco/bettas/init/BettasBlocks.java | 33 ----- .../teamdraco/bettas/init/BettasEntities.java | 23 --- .../teamdraco/bettas/init/BettasFeatures.java | 19 --- .../bettas/item/BettasSpawnEggItem.java | 63 --------- src/main/java/teamdraco/bettas/Bettas.java | 95 +++++++++++++ .../bettas/block/DriedLeavesBlock.java | 67 ++++----- .../teamdraco/bettas/block/MossBallBlock.java | 69 ++++----- .../teamdraco/bettas/client/ClientEvents.java | 41 ++++++ .../bettas/client/model/BettaFishModel.java | 69 +++++++++ .../client/renderer/BettaFishRenderer.java | 38 ++--- .../bettas/entity/BettaFishEntity.java | 132 +++++++++--------- .../bettas/feature/MossBallFeature.java | 46 ++++++ .../teamdraco/bettas/init/BettasBlocks.java | 21 +++ .../teamdraco/bettas/init/BettasEntities.java | 21 +++ .../teamdraco/bettas/init/BettasFeatures.java | 15 ++ .../teamdraco/bettas/init/BettasItems.java | 32 ++--- .../bettas/item/BettasBucketItem.java | 104 ++++++++++++++ .../bettas/item/BettasSpawnEggItem.java | 26 ++++ src/main/resources/META-INF/mods.toml | 6 +- .../resources/assets/bettas/lang/en_us.json | 2 +- 27 files changed, 616 insertions(+), 585 deletions(-) delete mode 100644 src/main/java/mod/teamdraco/bettas/Bettas.java delete mode 100644 src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java delete mode 100644 src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java delete mode 100644 src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java delete mode 100644 src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java delete mode 100644 src/main/java/mod/teamdraco/bettas/init/BettasEntities.java delete mode 100644 src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java delete mode 100644 src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java create mode 100644 src/main/java/teamdraco/bettas/Bettas.java rename src/main/java/{mod => }/teamdraco/bettas/block/DriedLeavesBlock.java (55%) rename src/main/java/{mod => }/teamdraco/bettas/block/MossBallBlock.java (66%) create mode 100644 src/main/java/teamdraco/bettas/client/ClientEvents.java create mode 100644 src/main/java/teamdraco/bettas/client/model/BettaFishModel.java rename src/main/java/{mod => }/teamdraco/bettas/client/renderer/BettaFishRenderer.java (59%) rename src/main/java/{mod => }/teamdraco/bettas/entity/BettaFishEntity.java (55%) create mode 100644 src/main/java/teamdraco/bettas/feature/MossBallFeature.java create mode 100644 src/main/java/teamdraco/bettas/init/BettasBlocks.java create mode 100644 src/main/java/teamdraco/bettas/init/BettasEntities.java create mode 100644 src/main/java/teamdraco/bettas/init/BettasFeatures.java rename src/main/java/{mod => }/teamdraco/bettas/init/BettasItems.java (52%) create mode 100644 src/main/java/teamdraco/bettas/item/BettasBucketItem.java create mode 100644 src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java diff --git a/build.gradle b/build.gradle index 033b097..eaeb651 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1+', changing: true } } apply plugin: 'net.minecraftforge.gradle' @@ -13,11 +13,11 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.2.0' -group = 'mod.teamdraco.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +version = '1.17.1-1.0.0' +group = 'teamdraco.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'bettas' -sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +java.toolchain.languageVersion = JavaLanguageVersion.of(16) // Mojang ships Java 8 to end users, so your mod should target Java 8. println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) minecraft { @@ -26,7 +26,7 @@ minecraft { // stable_# Stables are built at the discretion of the MCP team. // Use non-default mappings at your own risk. they may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.16.5' + mappings channel: 'official', version: '1.17.1' // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') @@ -94,7 +94,7 @@ dependencies { // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.16.4-35.0.18' + minecraft 'net.minecraftforge:forge:1.17.1-37.0.109' // You may put jars on which you depend on in ./libs or you may define them like so.. // compile "some.group:artifact:version:classifier" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7a3265ee94c0ab25cf079ac8ccdf87f41d455d42..7454180f2ae8848c63b8b4dea2cb829da983f2fa 100644 GIT binary patch literal 59536 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 QuEJmfE|#`Dqx|px0L@K;Y5)KL literal 54708 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

_x$+l{{cH8$W#CT diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1d5b29f..ffed3a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip diff --git a/src/main/java/mod/teamdraco/bettas/Bettas.java b/src/main/java/mod/teamdraco/bettas/Bettas.java deleted file mode 100644 index 73150b6..0000000 --- a/src/main/java/mod/teamdraco/bettas/Bettas.java +++ /dev/null @@ -1,103 +0,0 @@ -package mod.teamdraco.bettas; - -import mod.teamdraco.bettas.entity.BettaFishEntity; -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasEntities; -import mod.teamdraco.bettas.init.BettasFeatures; -import mod.teamdraco.bettas.init.BettasItems; -import net.minecraft.entity.EntityClassification; -import net.minecraft.entity.EntitySpawnPlacementRegistry; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes; -import net.minecraft.entity.passive.fish.AbstractFishEntity; -import net.minecraft.loot.LootEntry; -import net.minecraft.loot.LootPool; -import net.minecraft.loot.LootTables; -import net.minecraft.loot.TableLootEntry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.MobSpawnInfo; -import net.minecraft.world.gen.GenerationStage; -import net.minecraft.world.gen.Heightmap; -import net.minecraft.world.gen.feature.*; -import net.minecraft.world.gen.placement.ChanceConfig; -import net.minecraft.world.gen.placement.Placement; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.LootTableLoadEvent; -import net.minecraftforge.event.world.BiomeLoadingEvent; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; - -import java.util.List; -import java.util.Random; - -@Mod(Bettas.MOD_ID) -@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) -public class Bettas { - public static final String MOD_ID = "bettas"; - public static Bettas instance; - - public Bettas() { - IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); - bus.addListener(this::registerCommon); - - BettasItems.ITEMS.register(bus); - BettasBlocks.BLOCKS.register(bus); - BettasEntities.ENTITIES.register(bus); - BettasFeatures.FEATURES.register(bus); - - bus.addGenericListener(EntityType.class, BettasEntities::init); - - instance = this; - MinecraftForge.EVENT_BUS.register(this); - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - public static void registerBiomes(BiomeLoadingEvent event) { - if (event.getCategory() == Biome.Category.SWAMP) { - event.getSpawns().getSpawner(EntityClassification.WATER_CREATURE).add(new MobSpawnInfo.Spawners(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); - event.getGeneration().getFeatures(GenerationStage.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new FeatureSpreadConfig(5)).decorated(Features.Placements.TOP_SOLID_HEIGHTMAP_SQUARE).chance(16)); - } - } - - private void registerCommon(FMLCommonSetupEvent event) { - registerEntityAttributes(); - EntitySpawnPlacementRegistry.register(BettasEntities.BETTA_FISH.get(), EntitySpawnPlacementRegistry.PlacementType.IN_WATER, Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkFishSpawnRules); - } - - private void registerEntityAttributes() { - GlobalEntityTypeAttributes.put(BettasEntities.BETTA_FISH.get(), BettaFishEntity.createAttributes().build()); - } - - //Thanks to BlueDuck for the help with the loot table code :) - @Mod.EventBusSubscriber(modid = Bettas.MOD_ID) - public static class LootEvents { - @SubscribeEvent - public static void onLootLoad(LootTableLoadEvent event) throws IllegalAccessException { - ResourceLocation name = event.getName(); - if (name.equals(LootTables.FISHING)) { - LootPool pool = event.getTable().getPool("main"); - if (pool != null) { - addEntry(pool, getInjectEntry(new ResourceLocation("bettas:inject/fishing"), 10, 1)); - } - } - } - } - - private static LootEntry getInjectEntry(ResourceLocation location, int weight, int quality) { - return TableLootEntry.lootTableReference(location).setWeight(weight).setQuality(quality).build(); - } - - private static void addEntry(LootPool pool, LootEntry entry) throws IllegalAccessException { - List lootEntries = (List) ObfuscationReflectionHelper.findField(LootPool.class, "entries").get(pool); - if (lootEntries.stream().anyMatch(e -> e == entry)) { - throw new RuntimeException("Attempted to add a duplicate entry to pool: " + entry); - } - lootEntries.add(entry); - } -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java b/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java deleted file mode 100644 index 821e0e9..0000000 --- a/src/main/java/mod/teamdraco/bettas/ClientEventBusSubscriber.java +++ /dev/null @@ -1,35 +0,0 @@ -package mod.teamdraco.bettas; - - -import mod.teamdraco.bettas.client.renderer.BettaFishRenderer; -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasEntities; -import mod.teamdraco.bettas.item.BettasSpawnEggItem; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.RenderTypeLookup; -import net.minecraft.client.renderer.color.IItemColor; -import net.minecraft.client.renderer.color.ItemColors; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.ColorHandlerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; - -@OnlyIn(Dist.CLIENT) -@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) -public class ClientEventBusSubscriber { - @SubscribeEvent - public static void clientSetup(FMLClientSetupEvent event) { - RenderingRegistry.registerEntityRenderingHandler(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); - RenderTypeLookup.setRenderLayer(BettasBlocks.DRIED_LEAVES.get(), RenderType.getCutout()); - } - - @SubscribeEvent - public static void itemColors(ColorHandlerEvent.Item event) { - ItemColors handler = event.getItemColors(); - IItemColor eggColor = (stack, tintIndex) -> ((BettasSpawnEggItem) stack.getItem()).getColor(tintIndex); - for (BettasSpawnEggItem e : BettasSpawnEggItem.UNADDED_EGGS) handler.register(eggColor, e); - } -} diff --git a/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java b/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java deleted file mode 100644 index d9eecb1..0000000 --- a/src/main/java/mod/teamdraco/bettas/client/model/BettaFishModel.java +++ /dev/null @@ -1,87 +0,0 @@ -package mod.teamdraco.bettas.client.model; - -import com.google.common.collect.ImmutableList; -import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.vertex.IVertexBuilder; -import net.minecraft.client.renderer.entity.model.EntityModel; -import net.minecraft.client.renderer.model.ModelRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -@OnlyIn(Dist.CLIENT) -public class BettaFishModel extends EntityModel { - public ModelRenderer body; - public ModelRenderer tail; - public ModelRenderer finTop; - public ModelRenderer finBottom; - public ModelRenderer finLeftBottom; - public ModelRenderer finRightBottom; - public ModelRenderer finLeft; - public ModelRenderer finRight; - - public BettaFishModel() { - this.texWidth = 32; - this.texHeight = 16; - this.finLeftBottom = new ModelRenderer(this, 11, 9); - this.finLeftBottom.setPos(0.5F, 1.5F, -0.5F); - this.finLeftBottom.addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finLeftBottom, 0.0F, 0.0F, -0.3490658503988659F); - this.tail = new ModelRenderer(this, 0, 6); - this.tail.setPos(0.0F, 0.0F, 3.5F); - this.tail.addBox(0.0F, -3.0F, 0.0F, 0.0F, 6.0F, 4.0F, 0.0F, 0.0F, 0.0F); - this.finRight = new ModelRenderer(this, -1, 1); - this.finRight.setPos(-1.0F, 0.5F, -0.5F); - this.finRight.addBox(-2.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finRight, 0.0F, 0.0F, -0.7853981633974483F); - this.body = new ModelRenderer(this, 0, 0); - this.body.setPos(0.0F, 22.5F, -0.5F); - this.body.addBox(-1.0F, -1.5F, -3.5F, 2.0F, 3.0F, 7.0F, 0.0F, 0.0F, 0.0F); - this.finTop = new ModelRenderer(this, 0, 1); - this.finTop.setPos(0.0F, -1.5F, 2.0F); - this.finTop.addBox(0.0F, -3.0F, -1.5F, 0.0F, 3.0F, 3.0F, 0.0F, 0.0F, 0.0F); - this.finRightBottom = new ModelRenderer(this, 11, 9); - this.finRightBottom.setPos(-0.5F, 1.5F, -0.5F); - this.finRightBottom.addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finRightBottom, 0.0F, 0.0F, 0.3490658503988659F); - this.finBottom = new ModelRenderer(this, 11, -6); - this.finBottom.setPos(0.0F, 1.5F, 0.5F); - this.finBottom.addBox(0.0F, 0.0F, -3.0F, 0.0F, 2.0F, 6.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finBottom, 0.0F, 3.141592653589793F, 0.0F); - this.finLeft = new ModelRenderer(this, -1, 1); - this.finLeft.mirror = true; - this.finLeft.setPos(1.0F, 0.5F, -0.5F); - this.finLeft.addBox(0.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, 0.0F, 0.0F, 0.0F); - this.setRotateAngle(finLeft, 0.0F, 0.0F, 0.7853981633974483F); - this.body.addChild(this.finLeftBottom); - this.body.addChild(this.tail); - this.body.addChild(this.finRight); - this.body.addChild(this.finTop); - this.body.addChild(this.finRightBottom); - this.body.addChild(this.finBottom); - this.body.addChild(this.finLeft); - } - - @Override - public void renderToBuffer(MatrixStack matrixStackIn, IVertexBuilder bufferIn, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float alpha) { - ImmutableList.of(this.body).forEach((modelRenderer) -> { - modelRenderer.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, red, green, blue, alpha); - }); - } - - @Override - public void setupAnim(T entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { - float f = 1.0F; - if (!entityIn.isInWater()) { - f = 1.5F; - } - this.tail.yRot = -f * 0.45F * MathHelper.sin(0.6F * ageInTicks); - } - - public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) { - modelRenderer.xRot = x; - modelRenderer.yRot = y; - modelRenderer.zRot = z; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java b/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java deleted file mode 100644 index bd216a3..0000000 --- a/src/main/java/mod/teamdraco/bettas/feature/MossBallFeature.java +++ /dev/null @@ -1,40 +0,0 @@ -package mod.teamdraco.bettas.feature; - -import com.mojang.serialization.Codec; -import mod.teamdraco.bettas.init.BettasBlocks; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.SeaPickleBlock; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.ISeedReader; -import net.minecraft.world.gen.ChunkGenerator; -import net.minecraft.world.gen.Heightmap; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.FeatureSpreadConfig; - -import java.util.Random; - -public class MossBallFeature extends Feature { - public MossBallFeature(Codec p_i231987_1_) { - super(p_i231987_1_); - } - - public boolean place(ISeedReader reader, ChunkGenerator generator, Random rand, BlockPos pos, FeatureSpreadConfig config) { - int i = 0; - int j = config.count().sample(rand); - - for(int k = 0; k < j; ++k) { - int l = rand.nextInt(8) - rand.nextInt(8); - int i1 = rand.nextInt(8) - rand.nextInt(8); - int j1 = reader.getHeight(Heightmap.Type.OCEAN_FLOOR, pos.getX() + l, pos.getZ() + i1); - BlockPos blockpos = new BlockPos(pos.getX() + l, j1, pos.getZ() + i1); - BlockState blockstate = BettasBlocks.MOSS_BALL.get().defaultBlockState().setValue(SeaPickleBlock.PICKLES, Integer.valueOf(rand.nextInt(4) + 1)); - if (reader.getBlockState(blockpos).is(Blocks.WATER) && blockstate.canSurvive(reader, blockpos)) { - reader.setBlock(blockpos, blockstate, 2); - ++i; - } - } - - return i > 0; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java b/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java deleted file mode 100644 index 050238a..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasBlocks.java +++ /dev/null @@ -1,33 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.block.DriedLeavesBlock; -import mod.teamdraco.bettas.block.MossBallBlock; -import net.minecraft.block.Block; -import net.minecraft.block.SoundType; -import net.minecraft.block.material.Material; -import net.minecraft.block.material.MaterialColor; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -import java.util.function.Supplier; - -import net.minecraft.block.AbstractBlock; - -public class BettasBlocks { - public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Bettas.MOD_ID); - - public static final RegistryObject MOSS_BALL = BLOCKS.register("moss_ball", () -> new MossBallBlock(AbstractBlock.Properties.of(Material.DECORATION, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0).noOcclusion())); - public static final RegistryObject MOSS_BALL_BLOCK = BLOCKS.register("moss_ball_block", () -> new Block(AbstractBlock.Properties.of(Material.GRASS, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0.5f))); - public static final RegistryObject DRIED_LEAVES = BLOCKS.register("dried_leaves", () -> new DriedLeavesBlock(AbstractBlock.Properties.of(Material.DECORATION, MaterialColor.COLOR_ORANGE).sound(SoundType.GRASS).strength(0).noOcclusion())); - - private static RegistryObject register(String name, Supplier block) { - RegistryObject object = BLOCKS.register(name, block); - BettasItems.ITEMS.register(name, () -> new BlockItem(object.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - return object; - } -} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java b/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java deleted file mode 100644 index 583ba49..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasEntities.java +++ /dev/null @@ -1,23 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.entity.BettaFishEntity; -import net.minecraft.entity.*; -import net.minecraft.entity.ai.attributes.GlobalEntityTypeAttributes; -import net.minecraft.item.Item; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -public class BettasEntities { - public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Bettas.MOD_ID); - - public static final RegistryObject> BETTA_FISH = ENTITIES.register("betta_fish", () -> EntityType.Builder.of(BettaFishEntity::new, EntityClassification.WATER_AMBIENT).sized(0.3f, 0.3f).build(new ResourceLocation(Bettas.MOD_ID, "betta_fish").toString())); - - public static void init(RegistryEvent.Register> event) { - } -} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java deleted file mode 100644 index 52e86fc..0000000 --- a/src/main/java/mod/teamdraco/bettas/init/BettasFeatures.java +++ /dev/null @@ -1,19 +0,0 @@ -package mod.teamdraco.bettas.init; - -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.feature.MossBallFeature; -import net.minecraft.entity.EntityType; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.FeatureSpreadConfig; -import net.minecraft.world.gen.feature.IFeatureConfig; -import net.minecraft.world.gen.feature.SeaPickleFeature; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; - -public class BettasFeatures { - public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); - - public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(FeatureSpreadConfig.CODEC)); -} diff --git a/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java b/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java deleted file mode 100644 index 813c0c6..0000000 --- a/src/main/java/mod/teamdraco/bettas/item/BettasSpawnEggItem.java +++ /dev/null @@ -1,63 +0,0 @@ -package mod.teamdraco.bettas.item; - -import net.minecraft.block.DispenserBlock; -import net.minecraft.dispenser.DefaultDispenseItemBehavior; -import net.minecraft.dispenser.IBlockSource; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnReason; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.item.SpawnEggItem; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.Direction; -import net.minecraftforge.common.util.Lazy; -import net.minecraftforge.common.util.NonNullSupplier; -import net.minecraftforge.fml.RegistryObject; -import net.minecraftforge.fml.common.ObfuscationReflectionHelper; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -public class BettasSpawnEggItem extends SpawnEggItem { - - public static final List UNADDED_EGGS = new ArrayList(); - private final Lazy> entityTypeSupplier; - - public BettasSpawnEggItem(final NonNullSupplier> entityTypeSupplier, final int primaryColour, final int secondaryColour, final Item.Properties properties) { - super(null, primaryColour, secondaryColour, properties); - this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); - UNADDED_EGGS.add(this); - } - - public BettasSpawnEggItem(final RegistryObject> entityTypeSupplier, final int primaryColour, final int secondaryColour, final Item.Properties properties) { - super(null, primaryColour, secondaryColour, properties); - this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); - UNADDED_EGGS.add(this); - } - - public static void initSpawnEggs() { - final Map, SpawnEggItem> EGGS = ObfuscationReflectionHelper.getPrivateValue(SpawnEggItem.class, null, "BY_ID"); - DefaultDispenseItemBehavior dispenseBehaviour = new DefaultDispenseItemBehavior() { - @Override - protected ItemStack execute(IBlockSource source, ItemStack stack) { - Direction direction = source.getBlockState().getValue(DispenserBlock.FACING); - EntityType type = ((SpawnEggItem) stack.getItem()).getType(stack.getTag()); - type.spawn(source.getLevel(), stack, null, source.getPos().relative(direction), SpawnReason.DISPENSER, direction != Direction.UP, false); - stack.shrink(1); - return stack; - } - }; - - for (final SpawnEggItem spawnEgg : UNADDED_EGGS) { - EGGS.put(spawnEgg.getType(null), spawnEgg); - DispenserBlock.registerBehavior(spawnEgg, dispenseBehaviour); - } - UNADDED_EGGS.clear(); - } - - @Override - public EntityType getType(CompoundNBT nbt) { - return this.entityTypeSupplier.get(); - } -} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/Bettas.java b/src/main/java/teamdraco/bettas/Bettas.java new file mode 100644 index 0000000..f407c1f --- /dev/null +++ b/src/main/java/teamdraco/bettas/Bettas.java @@ -0,0 +1,95 @@ +package teamdraco.bettas; + +import net.minecraft.data.worldgen.Features; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.entity.SpawnPlacements; +import net.minecraft.world.level.SpawnData; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.entries.LootTableReference; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.LootTableLoadEvent; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; +import net.minecraftforge.event.world.BiomeLoadingEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import net.minecraftforge.fml.util.ObfuscationReflectionHelper; +import teamdraco.bettas.entity.BettaFishEntity; +import teamdraco.bettas.init.BettasBlocks; +import teamdraco.bettas.init.BettasEntities; +import teamdraco.bettas.init.BettasFeatures; +import teamdraco.bettas.init.BettasItems; + +import java.util.List; + +@Mod(Bettas.MOD_ID) +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) +public class Bettas { + public static final String MOD_ID = "bettas"; + + public Bettas() { + IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); + bus.addListener(this::registerCommon); + + BettasItems.ITEMS.register(bus); + BettasBlocks.BLOCKS.register(bus); + BettasEntities.ENTITIES.register(bus); + BettasFeatures.FEATURES.register(bus); + + bus.addListener(this::registerEntityAttributes); + + MinecraftForge.EVENT_BUS.register(this); + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + public static void registerBiomes(BiomeLoadingEvent event) { + if (event.getCategory() == Biome.BiomeCategory.SWAMP) { + event.getSpawns().getSpawner(MobCategory.WATER_CREATURE).add(new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); + event.getGeneration().getFeatures(GenerationStep.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new CountConfiguration(5)).decorated(Features.Decorators.TOP_SOLID_HEIGHTMAP_SQUARE).count(1)); + } + } + + private void registerCommon(FMLCommonSetupEvent event) { + SpawnPlacements.register(BettasEntities.BETTA_FISH.get(), SpawnPlacements.Type.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkBettaFishSpawnRules); + } + + private void registerEntityAttributes(EntityAttributeCreationEvent event) { + event.put(BettasEntities.BETTA_FISH.get(), BettaFishEntity.createAttributes().build()); + } + + //Thanks to BlueDuck for the help with the loot table code :) + @Mod.EventBusSubscriber(modid = Bettas.MOD_ID) + public static class LootEvents { + @SubscribeEvent + public static void onLootLoad(LootTableLoadEvent event) throws IllegalAccessException { + ResourceLocation name = event.getName(); + if (name.equals(LootContextParamSets.FISHING)) { + LootPool pool = event.getTable().getPool("main"); + addEntry(pool, getInjectEntry(new ResourceLocation("bettas:inject/fishing"), 10, 1)); + } + } + } + + private static LootPoolEntryContainer getInjectEntry(ResourceLocation location, int weight, int quality) { + return LootTableReference.lootTableReference(location).setWeight(weight).setQuality(quality).build(); + } + + private static void addEntry(LootPool pool, LootPoolEntryContainer entry) throws IllegalAccessException { + List lootEntries = (List) ObfuscationReflectionHelper.findField(LootPool.class, "entries").get(pool); + if (lootEntries.stream().anyMatch(e -> e == entry)) { + throw new RuntimeException("Attempted to add a duplicate entry to pool: " + entry); + } + lootEntries.add(entry); + } +} \ No newline at end of file diff --git a/src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java similarity index 55% rename from src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java rename to src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java index ff03f68..c005a7b 100644 --- a/src/main/java/mod/teamdraco/bettas/block/DriedLeavesBlock.java +++ b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java @@ -1,37 +1,42 @@ -package mod.teamdraco.bettas.block; +package teamdraco.bettas.block; -import net.minecraft.block.*; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.IntegerProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; -import net.minecraft.world.IWorldReader; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BushBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; import javax.annotation.Nullable; -public class DriedLeavesBlock extends BushBlock implements IWaterLoggable { +public class DriedLeavesBlock extends BushBlock implements SimpleWaterloggedBlock { public static final IntegerProperty LEAVES = BlockStateProperties.PICKLES; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; protected static final VoxelShape ONE_SHAPE = Block.box(0, 0, 0, 16, 2, 16); protected static final VoxelShape TWO_SHAPE = Block.box(0, 0, 0, 16, 3, 16); protected static final VoxelShape THREE_SHAPE = Block.box(0, 0, 0, 16, 5, 16); - public DriedLeavesBlock(AbstractBlock.Properties properties) { + public DriedLeavesBlock(BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState(this.stateDefinition.any().setValue(LEAVES, Integer.valueOf(1)).setValue(WATERLOGGED, Boolean.valueOf(true))); } @Nullable - public BlockState getStateForPlacement(BlockItemUseContext context) { + public BlockState getStateForPlacement(BlockPlaceContext context) { BlockState blockstate = context.getLevel().getBlockState(context.getClickedPos()); if (blockstate.is(this)) { return blockstate.setValue(LEAVES, Integer.valueOf(Math.min(3, blockstate.getValue(LEAVES) + 1))); @@ -47,26 +52,16 @@ public boolean useShapeForLightOcclusion(BlockState state) { return true; } - public static boolean isInBadEnvironment(BlockState p_204901_0_) { - return !p_204901_0_.getValue(WATERLOGGED); - } - - protected boolean mayPlaceOn(BlockState state, IBlockReader worldIn, BlockPos pos) { + protected boolean mayPlaceOn(BlockState state, LevelReader worldIn, BlockPos pos) { return !state.getCollisionShape(worldIn, pos).getFaceShape(Direction.UP).isEmpty() || state.isFaceSturdy(worldIn, pos, Direction.UP); } - public boolean canSurvive(BlockState state, IWorldReader worldIn, BlockPos pos) { + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { BlockPos blockpos = pos.below(); return this.mayPlaceOn(worldIn.getBlockState(blockpos), worldIn, blockpos); } - /** - * Update the provided state given the provided neighbor facing and neighbor state, returning a new state. - * For example, fences make their connections to the passed in state if possible, and wet concrete powder immediately - * returns its solidified counterpart. - * Note that this method should ideally consider only the specific face passed in. - */ - public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) { + public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, BlockPos currentPos, BlockPos facingPos) { if (!stateIn.canSurvive(worldIn, currentPos)) { return Blocks.AIR.defaultBlockState(); } else { @@ -78,11 +73,11 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f } } - public boolean canBeReplaced(BlockState state, BlockItemUseContext useContext) { - return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(LEAVES) < 3 ? true : super.canBeReplaced(state, useContext); + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(LEAVES) < 3 || super.canBeReplaced(state, useContext); } - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { switch (state.getValue(LEAVES)) { case 1: default: @@ -98,7 +93,7 @@ public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } - protected void createBlockStateDefinition(StateContainer.Builder builder) { + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(LEAVES, WATERLOGGED); } } diff --git a/src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java b/src/main/java/teamdraco/bettas/block/MossBallBlock.java similarity index 66% rename from src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java rename to src/main/java/teamdraco/bettas/block/MossBallBlock.java index ac67483..6e797fe 100644 --- a/src/main/java/mod/teamdraco/bettas/block/MossBallBlock.java +++ b/src/main/java/teamdraco/bettas/block/MossBallBlock.java @@ -1,29 +1,30 @@ -package mod.teamdraco.bettas.block; - -import mod.teamdraco.bettas.init.BettasBlocks; -import net.minecraft.block.*; -import net.minecraft.fluid.FluidState; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.BlockItemUseContext; -import net.minecraft.state.BooleanProperty; -import net.minecraft.state.IntegerProperty; -import net.minecraft.state.StateContainer; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.tags.BlockTags; -import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.shapes.ISelectionContext; -import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; -import net.minecraft.world.IWorldReader; -import net.minecraft.world.World; -import net.minecraft.world.server.ServerWorld; +package teamdraco.bettas.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import teamdraco.bettas.init.BettasBlocks; import javax.annotation.Nullable; import java.util.Random; -public class MossBallBlock extends BushBlock implements IWaterLoggable, IGrowable { +public class MossBallBlock extends BushBlock implements SimpleWaterloggedBlock, BonemealableBlock { public static final IntegerProperty BALLS = BlockStateProperties.PICKLES; public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; protected static final VoxelShape ONE_SHAPE = Block.box(0, 0, 0, 16, 7, 16); @@ -31,13 +32,13 @@ public class MossBallBlock extends BushBlock implements IWaterLoggable, IGrowabl protected static final VoxelShape THREE_SHAPE = Block.box(0, 0, 0, 16, 7, 16); protected static final VoxelShape FOUR_SHAPE = Block.box(0, 0, 0, 16, 8, 16); - public MossBallBlock(AbstractBlock.Properties properties) { + public MossBallBlock(BlockBehaviour.Properties properties) { super(properties); this.registerDefaultState(this.stateDefinition.any().setValue(BALLS, Integer.valueOf(1)).setValue(WATERLOGGED, Boolean.valueOf(true))); } @Nullable - public BlockState getStateForPlacement(BlockItemUseContext context) { + public BlockState getStateForPlacement(BlockPlaceContext context) { BlockState blockstate = context.getLevel().getBlockState(context.getClickedPos()); if (blockstate.is(this)) { return blockstate.setValue(BALLS, Integer.valueOf(Math.min(4, blockstate.getValue(BALLS) + 1))); @@ -52,16 +53,16 @@ public static boolean isInBadEnvironment(BlockState p_204901_0_) { return !p_204901_0_.getValue(WATERLOGGED); } - protected boolean mayPlaceOn(BlockState state, IBlockReader worldIn, BlockPos pos) { + protected boolean mayPlaceOn(BlockState state, LevelReader worldIn, BlockPos pos) { return !state.getCollisionShape(worldIn, pos).getFaceShape(Direction.UP).isEmpty() || state.isFaceSturdy(worldIn, pos, Direction.UP); } - public boolean canSurvive(BlockState state, IWorldReader worldIn, BlockPos pos) { + public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) { BlockPos blockpos = pos.below(); return this.mayPlaceOn(worldIn.getBlockState(blockpos), worldIn, blockpos); } - public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, BlockPos currentPos, BlockPos facingPos) { + public BlockState updateShape(BlockState stateIn, Direction facing, BlockState facingState, LevelAccessor worldIn, BlockPos currentPos, BlockPos facingPos) { if (!stateIn.canSurvive(worldIn, currentPos)) { return Blocks.AIR.defaultBlockState(); } else { @@ -73,11 +74,11 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f } } - public boolean canBeReplaced(BlockState state, BlockItemUseContext useContext) { - return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(BALLS) < 4 ? true : super.canBeReplaced(state, useContext); + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(BALLS) < 4 || super.canBeReplaced(state, useContext); } - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { switch (state.getValue(BALLS)) { case 1: default: @@ -95,19 +96,19 @@ public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } - protected void createBlockStateDefinition(StateContainer.Builder builder) { + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(BALLS, WATERLOGGED); } - public boolean isValidBonemealTarget(IBlockReader worldIn, BlockPos pos, BlockState state, boolean isClient) { + public boolean isValidBonemealTarget(BlockGetter worldIn, BlockPos pos, BlockState state, boolean isClient) { return true; } - public boolean isBonemealSuccess(World worldIn, Random rand, BlockPos pos, BlockState state) { + public boolean isBonemealSuccess(Level worldIn, Random rand, BlockPos pos, BlockState state) { return true; } - public void performBonemeal(ServerWorld worldIn, Random rand, BlockPos pos, BlockState state) { + public void performBonemeal(ServerLevel worldIn, Random rand, BlockPos pos, BlockState state) { if (!isInBadEnvironment(state) && worldIn.getBlockState(pos.below()).getBlock() == BettasBlocks.MOSS_BALL_BLOCK.get()) { int i = 5; int j = 1; diff --git a/src/main/java/teamdraco/bettas/client/ClientEvents.java b/src/main/java/teamdraco/bettas/client/ClientEvents.java new file mode 100644 index 0000000..b444185 --- /dev/null +++ b/src/main/java/teamdraco/bettas/client/ClientEvents.java @@ -0,0 +1,41 @@ +package teamdraco.bettas.client; + +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.client.color.item.ItemColors; +import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.entity.EntityRenderers; +import net.minecraftforge.client.ForgeHooksClient; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.client.model.BettaFishModel; +import teamdraco.bettas.client.renderer.BettaFishRenderer; +import teamdraco.bettas.init.BettasBlocks; +import teamdraco.bettas.init.BettasEntities; +import teamdraco.bettas.item.BettasSpawnEggItem; +import net.minecraft.client.renderer.RenderType; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.ColorHandlerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +@OnlyIn(Dist.CLIENT) +@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +public class ClientEvents { + + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent event) { + EntityRenderers.register(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); + ItemBlockRenderTypes.setRenderLayer(BettasBlocks.DRIED_LEAVES.get(), RenderType.cutout()); + + ForgeHooksClient.registerLayerDefinition(BettaFishRenderer.MODEL_LAYER, BettaFishModel::createLayerDefinition); + + } + + @SubscribeEvent + public static void itemColors(ColorHandlerEvent.Item event) { + ItemColors handler = event.getItemColors(); + ItemColor eggColor = (stack, tintIndex) -> ((BettasSpawnEggItem) stack.getItem()).getColor(tintIndex); + for (BettasSpawnEggItem e : BettasSpawnEggItem.UNADDED_EGGS) handler.register(eggColor, e); + } +} diff --git a/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java b/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java new file mode 100644 index 0000000..57b2c5f --- /dev/null +++ b/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java @@ -0,0 +1,69 @@ +package teamdraco.bettas.client.model; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.model.EntityModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.model.geom.PartPose; +import net.minecraft.client.model.geom.builders.CubeListBuilder; +import net.minecraft.client.model.geom.builders.LayerDefinition; +import net.minecraft.client.model.geom.builders.MeshDefinition; +import net.minecraft.client.model.geom.builders.PartDefinition; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class BettaFishModel extends EntityModel { + public ModelPart body; + public ModelPart tail; + public ModelPart finTop; + public ModelPart finBottom; + public ModelPart finLeftBottom; + public ModelPart finRightBottom; + public ModelPart finLeft; + public ModelPart finRight; + + //Constructor + public BettaFishModel(ModelPart root) { + this.body = root.getChild("body"); + this.finLeftBottom = this.body.getChild("finLeftBottom"); + this.tail = this.body.getChild("tail"); + this.finRight = this.body.getChild("finRight"); + this.finTop = this.body.getChild("finTop"); + this.finRightBottom = this.body.getChild("finRightBottom"); + this.finBottom = this.body.getChild("finBottom"); + this.finLeft = this.body.getChild("finLeft"); + } + + //Layer Definition + public static LayerDefinition createLayerDefinition() { + MeshDefinition meshdefinition = new MeshDefinition(); + PartDefinition root = meshdefinition.getRoot(); + PartDefinition body = root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -1.5F, -3.5F, 2.0F, 3.0F, 7.0F, false), PartPose.offsetAndRotation(0.0F, 22.5F, -0.5F, 0.0F, 0.0F, 0.0F)); + PartDefinition finLeftBottom = body.addOrReplaceChild("finLeftBottom", CubeListBuilder.create().texOffs(11, 9).addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, false), PartPose.offsetAndRotation(0.5F, 1.5F, -0.5F, 0.0F, 0.0F, -0.34906584F)); + PartDefinition tail = body.addOrReplaceChild("tail", CubeListBuilder.create().texOffs(0, 6).addBox(0.0F, -3.0F, 0.0F, 0.0F, 6.0F, 4.0F, false), PartPose.offsetAndRotation(0.0F, 0.0F, 3.5F, 0.0F, 0.0F, 0.0F)); + PartDefinition finRight = body.addOrReplaceChild("finRight", CubeListBuilder.create().texOffs(-1, 1).addBox(-2.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, false), PartPose.offsetAndRotation(-1.0F, 0.5F, -0.5F, 0.0F, 0.0F, -0.7853982F)); + PartDefinition finTop = body.addOrReplaceChild("finTop", CubeListBuilder.create().texOffs(0, 1).addBox(0.0F, -3.0F, -1.5F, 0.0F, 3.0F, 3.0F, false), PartPose.offsetAndRotation(0.0F, -1.5F, 2.0F, 0.0F, 0.0F, 0.0F)); + PartDefinition finRightBottom = body.addOrReplaceChild("finRightBottom", CubeListBuilder.create().texOffs(11, 9).addBox(0.0F, 0.0F, -1.0F, 0.0F, 3.0F, 2.0F, false), PartPose.offsetAndRotation(-0.5F, 1.5F, -0.5F, 0.0F, 0.0F, 0.34906584F)); + PartDefinition finBottom = body.addOrReplaceChild("finBottom", CubeListBuilder.create().texOffs(11, -6).addBox(0.0F, 0.0F, -3.0F, 0.0F, 2.0F, 6.0F, false), PartPose.offsetAndRotation(0.0F, 1.5F, 0.5F, 0.0F, 3.1415927F, 0.0F)); + PartDefinition finLeft = body.addOrReplaceChild("finLeft", CubeListBuilder.create().texOffs(-1, 3).addBox(0.0F, 0.0F, -1.0F, 2.0F, 0.0F, 2.0F, true), PartPose.offsetAndRotation(1.0F, 0.5F, -0.5F, 0.0F, 0.0F, 0.7853982F)); + return LayerDefinition.create(meshdefinition, 32, 16); + } + + @Override + public void setupAnim(T entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch) { + float f = 1.0F; + if (!entityIn.isInWater()) { + f = 1.5F; + } + this.tail.yRot = -f * 0.45F * Mth.sin(0.6F * ageInTicks); + } + + @Override + public void renderToBuffer(PoseStack matrixStackIn, VertexConsumer bufferIn, int packedLightIn, int packedOverlayIn, float p_103115_, float p_103116_, float p_103117_, float p_103118_) { + body.render(matrixStackIn, bufferIn, packedLightIn, packedOverlayIn, p_103115_, p_103116_, p_103117_, p_103118_); + + } +} diff --git a/src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java b/src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java similarity index 59% rename from src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java rename to src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java index acff614..c8c7185 100644 --- a/src/main/java/mod/teamdraco/bettas/client/renderer/BettaFishRenderer.java +++ b/src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java @@ -1,34 +1,35 @@ -package mod.teamdraco.bettas.client.renderer; +package teamdraco.bettas.client.renderer; -import com.mojang.blaze3d.matrix.MatrixStack; -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.client.model.BettaFishModel; -import mod.teamdraco.bettas.entity.BettaFishEntity; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.entity.EntityRendererManager; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import net.minecraft.client.model.geom.ModelLayerLocation; +import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.MobRenderer; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.vector.Vector3f; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.client.model.BettaFishModel; +import teamdraco.bettas.entity.BettaFishEntity; +import net.minecraft.client.Minecraft; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @OnlyIn(Dist.CLIENT) public class BettaFishRenderer extends MobRenderer> { + public static final ModelLayerLocation MODEL_LAYER = new ModelLayerLocation(new ResourceLocation(Bettas.MOD_ID, "betta"), "main"); private static final ResourceLocation[] TEXTURES = new ResourceLocation[BettaFishEntity.MAX_VARIANTS]; - public BettaFishRenderer(EntityRendererManager manager) { - super(manager, new BettaFishModel<>(), 0.2f); + public BettaFishRenderer(EntityRendererProvider.Context manager) { + super(manager, new BettaFishModel<>(manager.bakeLayer(MODEL_LAYER)), 0.2F); + this.shadowRadius = 0.2F; } @Override public ResourceLocation getTextureLocation(BettaFishEntity entity) { int variant = entity.getVariant(); - if (TEXTURES[variant] == null) - { + if (TEXTURES[variant] == null) { ResourceLocation loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_" + variant + ".png"); - if (!Minecraft.getInstance().getResourceManager().hasResource(loc)) // todo: remove this block in 1.17, since variants won't matter on an update! - { + if (!Minecraft.getInstance().getResourceManager().hasResource(loc)) { System.out.println("Found Unknown variant " + variant + ", using default"); loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_0.png"); } @@ -39,10 +40,11 @@ public ResourceLocation getTextureLocation(BettaFishEntity entity) { return TEXTURES[variant]; } + @Override - protected void setupRotations(BettaFishEntity entityLiving, MatrixStack matrixStackIn, float ageInTicks, float rotationYaw, float partialTicks) { + protected void setupRotations(BettaFishEntity entityLiving, PoseStack matrixStackIn, float ageInTicks, float rotationYaw, float partialTicks) { super.setupRotations(entityLiving, matrixStackIn, ageInTicks, rotationYaw, partialTicks); - float f = 4.3F * MathHelper.sin(0.6F * ageInTicks); + float f = 4.3F * Mth.sin(0.6F * ageInTicks); matrixStackIn.mulPose(Vector3f.YP.rotationDegrees(f)); if (!entityLiving.isInWater()) { matrixStackIn.translate(0.2d, 0.1d, 0); diff --git a/src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java b/src/main/java/teamdraco/bettas/entity/BettaFishEntity.java similarity index 55% rename from src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java rename to src/main/java/teamdraco/bettas/entity/BettaFishEntity.java index fcb2d82..48689b8 100644 --- a/src/main/java/mod/teamdraco/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamdraco/bettas/entity/BettaFishEntity.java @@ -1,47 +1,59 @@ -package mod.teamdraco.bettas.entity; - -import mod.teamdraco.bettas.init.BettasBlocks; -import mod.teamdraco.bettas.init.BettasItems; -import net.minecraft.block.Blocks; -import net.minecraft.entity.*; -import net.minecraft.entity.ai.attributes.AttributeModifierMap; -import net.minecraft.entity.ai.attributes.Attributes; -import net.minecraft.entity.ai.goal.*; -import net.minecraft.entity.passive.fish.AbstractFishEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.projectile.AbstractArrowEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.particles.ParticleTypes; -import net.minecraft.util.*; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.vector.Vector3d; +package teamdraco.bettas.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.EntityDataSerializers; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.SpawnGroupData; +import net.minecraft.world.entity.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.goal.MeleeAttackGoal; +import net.minecraft.world.entity.ai.goal.RandomSwimmingGoal; +import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal; +import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.animal.Bucketable; +import net.minecraft.world.entity.monster.Monster; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.AbstractArrow; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.ServerLevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import teamdraco.bettas.init.BettasBlocks; +import teamdraco.bettas.init.BettasItems; import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.IServerWorld; -import net.minecraft.world.IWorld; -import net.minecraft.world.World; import javax.annotation.Nullable; import java.util.Random; -public class BettaFishEntity extends AbstractFishEntity { +public class BettaFishEntity extends AbstractFish implements Bucketable { public static final int MAX_VARIANTS = 120; - private static final DataParameter VARIANT = EntityDataManager.defineId(BettaFishEntity.class, DataSerializers.INT); - private static final DataParameter FROM_BUCKET = EntityDataManager.defineId(BettaFishEntity.class, DataSerializers.BOOLEAN); + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor FROM_BUCKET = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); - public BettaFishEntity(EntityType type, World worldIn) { + public BettaFishEntity(EntityType type, Level worldIn) { super(type, worldIn); } protected void registerGoals() { this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); - this.goalSelector.addGoal(1, new SwimGoal(this)); - this.targetSelector.addGoal(3, new HurtByTargetGoal(this)); + this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); } private boolean isFromBucket() { @@ -59,11 +71,11 @@ protected void defineSynchedData() { this.entityData.define(FROM_BUCKET, false); } - public static AttributeModifierMap.MutableAttribute createAttributes() { - return MobEntity.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); + public static AttributeSupplier.Builder createAttributes() { + return Monster.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); } - public static boolean checkFishSpawnRules(EntityType type, IWorld worldIn, SpawnReason reason, BlockPos p_223363_3_, Random randomIn) { + public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, Random randomIn) { return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; } @@ -72,7 +84,7 @@ public boolean hurt(DamageSource source, float amount) { return false; } else { Entity entity = source.getEntity(); - if (entity != null && !(entity instanceof PlayerEntity) && !(entity instanceof AbstractArrowEntity)) { + if (entity != null && !(entity instanceof Player) && !(entity instanceof AbstractArrow)) { amount = (amount + 1.0F) / 2.0F; } @@ -81,7 +93,7 @@ public boolean hurt(DamageSource source, float amount) { } public boolean doHurtTarget(Entity entityIn) { - boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float)((int)this.getAttributeValue(Attributes.ATTACK_DAMAGE))); + boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float) ((int) this.getAttributeValue(Attributes.ATTACK_DAMAGE))); if (flag) { this.doEnchantDamageEffects(this, entityIn); } @@ -116,12 +128,12 @@ public void tick() { private boolean isMossBallNearby() { BlockPos blockpos = this.blockPosition(); - BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable(); + BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); - for(int i = 0; i < 8; ++i) { - for(int j = 0; j < 8; ++j) { - for(int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { - for(int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { + for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { blockpos$mutable.setWithOffset(blockpos, k, i, l); if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL_BLOCK.get())) { return true; @@ -135,29 +147,28 @@ private boolean isMossBallNearby() { } @Override - public void addAdditionalSaveData(CompoundNBT compound) { + public void addAdditionalSaveData(CompoundTag compound) { super.addAdditionalSaveData(compound); compound.putInt("Variant", getVariant()); compound.putBoolean("FromBucket", this.isFromBucket()); } @Override - public void readAdditionalSaveData(CompoundNBT compound) { + public void readAdditionalSaveData(CompoundTag compound) { super.readAdditionalSaveData(compound); - setVariant(MathHelper.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); + setVariant(Mth.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); this.setFromBucket(compound.getBoolean("FromBucket")); } @Nullable @Override - public ILivingEntityData finalizeSpawn(IServerWorld worldIn, DifficultyInstance difficultyIn, SpawnReason reason, @Nullable ILivingEntityData spawnDataIn, @Nullable CompoundNBT dataTag) { + public SpawnGroupData finalizeSpawn(ServerLevelAccessor worldIn, DifficultyInstance difficultyIn, MobSpawnType reason, @Nullable SpawnGroupData spawnDataIn, @Nullable CompoundTag dataTag) { if (dataTag == null) { double chance = getRandom().nextDouble(); if (chance <= 0.45) setVariant(getRandom().nextInt(MAX_VARIANTS)); else if (chance <= 0.7) setVariant(24); else setVariant(100); - } - else { + } else { if (dataTag.contains("Variant", 3)) { this.setVariant(dataTag.getInt("Variant")); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false)); @@ -169,14 +180,14 @@ public ILivingEntityData finalizeSpawn(IServerWorld worldIn, DifficultyInstance return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); } - protected void saveToBucketTag(ItemStack bucket) { - CompoundNBT compoundnbt = bucket.getOrCreateTag(); + public void saveToBucketTag(ItemStack bucket) { + CompoundTag compoundnbt = bucket.getOrCreateTag(); compoundnbt.putInt("Variant", this.getVariant()); compoundnbt.putFloat("Health", this.getHealth()); } @Override - protected ItemStack getBucketItemStack() { + public ItemStack getBucketItemStack() { return new ItemStack(BettasItems.BETTA_FISH_BUCKET.get()); } @@ -194,12 +205,12 @@ protected SoundEvent getHurtSound(DamageSource damageSourceIn) { } @Override - public ItemStack getPickedResult(RayTraceResult result) { + public ItemStack getPickedResult(HitResult result) { return new ItemStack(BettasItems.BETTA_FISH_SPAWN_EGG.get()); } @Override - public ActionResultType interactAt(PlayerEntity player, Vector3d vec, Hand hand) { + public InteractionResult interactAt(Player player, Vec3 vec, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); float maxHealth = this.getMaxHealth(); float health = this.getHealth(); @@ -212,21 +223,8 @@ public ActionResultType interactAt(PlayerEntity player, Vector3d vec, Hand hand) double d1 = this.random.nextGaussian() * 0.02D; double d2 = this.random.nextGaussian() * 0.02D; this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2); - return ActionResultType.PASS; + return InteractionResult.PASS; } return super.interactAt(player, vec, hand); } - - static class SwimGoal extends RandomSwimmingGoal { - private final BettaFishEntity fish; - - public SwimGoal(BettaFishEntity fish) { - super(fish, 1.0D, 40); - this.fish = fish; - } - - public boolean canUse() { - return this.fish.canRandomSwim() && super.canUse(); - } - } } \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/feature/MossBallFeature.java b/src/main/java/teamdraco/bettas/feature/MossBallFeature.java new file mode 100644 index 0000000..385fc28 --- /dev/null +++ b/src/main/java/teamdraco/bettas/feature/MossBallFeature.java @@ -0,0 +1,46 @@ +package teamdraco.bettas.feature; + +import com.mojang.serialization.Codec; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SeaPickleBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import teamdraco.bettas.init.BettasBlocks; + +import java.util.Random; + +public class MossBallFeature extends Feature { + + public MossBallFeature(Codec p_i231987_1_) { + super(p_i231987_1_); + } + + public boolean place(FeaturePlaceContext context) { + WorldGenLevel reader = context.level(); + Random rand = context.random(); + CountConfiguration config = context.config(); + BlockPos pos = context.origin(); + + int i = 0; + int j = config.count().sample(rand); + + for(int k = 0; k < j; ++k) { + int l = rand.nextInt(8) - rand.nextInt(8); + int i1 = rand.nextInt(8) - rand.nextInt(8); + int j1 = reader.getHeight(Heightmap.Types.OCEAN_FLOOR, pos.getX() + l, pos.getZ() + i1); + BlockPos blockpos = new BlockPos(pos.getX() + l, j1, pos.getZ() + i1); + BlockState blockstate = BettasBlocks.MOSS_BALL.get().defaultBlockState().setValue(SeaPickleBlock.PICKLES, Integer.valueOf(rand.nextInt(4) + 1)); + if (reader.getBlockState(blockpos).is(Blocks.WATER) && blockstate.canSurvive(reader, blockpos)) { + reader.setBlock(blockpos, blockstate, 2); + ++i; + } + } + + return i > 0; + } +} diff --git a/src/main/java/teamdraco/bettas/init/BettasBlocks.java b/src/main/java/teamdraco/bettas/init/BettasBlocks.java new file mode 100644 index 0000000..ed1f43e --- /dev/null +++ b/src/main/java/teamdraco/bettas/init/BettasBlocks.java @@ -0,0 +1,21 @@ +package teamdraco.bettas.init; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.MaterialColor; +import net.minecraftforge.fmllegacy.RegistryObject; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.block.DriedLeavesBlock; +import teamdraco.bettas.block.MossBallBlock; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class BettasBlocks { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Bettas.MOD_ID); + + public static final RegistryObject MOSS_BALL = BLOCKS.register("moss_ball", () -> new MossBallBlock(BlockBehaviour.Properties.of(Material.DECORATION, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0).noOcclusion())); + public static final RegistryObject MOSS_BALL_BLOCK = BLOCKS.register("moss_ball_block", () -> new Block(BlockBehaviour.Properties.of(Material.GRASS, MaterialColor.COLOR_GREEN).sound(SoundType.WET_GRASS).strength(0.5f))); + public static final RegistryObject DRIED_LEAVES = BLOCKS.register("dried_leaves", () -> new DriedLeavesBlock(BlockBehaviour.Properties.of(Material.DECORATION, MaterialColor.COLOR_ORANGE).sound(SoundType.GRASS).strength(0).noOcclusion())); +} diff --git a/src/main/java/teamdraco/bettas/init/BettasEntities.java b/src/main/java/teamdraco/bettas/init/BettasEntities.java new file mode 100644 index 0000000..297bcb3 --- /dev/null +++ b/src/main/java/teamdraco/bettas/init/BettasEntities.java @@ -0,0 +1,21 @@ +package teamdraco.bettas.init; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraftforge.fmllegacy.RegistryObject; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.entity.BettaFishEntity; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class BettasEntities { + public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Bettas.MOD_ID); + + public static final RegistryObject> BETTA_FISH = create("betta_fish", EntityType.Builder.of(BettaFishEntity::new, MobCategory.WATER_AMBIENT).sized(0.3f, 0.3f)); + + private static RegistryObject> create(String name, EntityType.Builder builder) { + return ENTITIES.register(name, () -> builder.build(Bettas.MOD_ID + "." + name)); + } +} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/teamdraco/bettas/init/BettasFeatures.java new file mode 100644 index 0000000..4036e84 --- /dev/null +++ b/src/main/java/teamdraco/bettas/init/BettasFeatures.java @@ -0,0 +1,15 @@ +package teamdraco.bettas.init; + +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraftforge.fmllegacy.RegistryObject; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.feature.MossBallFeature; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class BettasFeatures { + public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); + + public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(CountConfiguration.CODEC)); +} diff --git a/src/main/java/mod/teamdraco/bettas/init/BettasItems.java b/src/main/java/teamdraco/bettas/init/BettasItems.java similarity index 52% rename from src/main/java/mod/teamdraco/bettas/init/BettasItems.java rename to src/main/java/teamdraco/bettas/init/BettasItems.java index 059a19b..d372502 100644 --- a/src/main/java/mod/teamdraco/bettas/init/BettasItems.java +++ b/src/main/java/teamdraco/bettas/init/BettasItems.java @@ -1,26 +1,26 @@ -package mod.teamdraco.bettas.init; +package teamdraco.bettas.init; -import mod.teamdraco.bettas.Bettas; -import mod.teamdraco.bettas.item.BettasSpawnEggItem; -import net.minecraft.fluid.Fluid; -import net.minecraft.fluid.Fluids; -import net.minecraft.item.*; -import net.minecraftforge.fml.RegistryObject; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.food.FoodProperties; +import net.minecraft.world.item.*; +import net.minecraft.world.level.material.Fluids; +import net.minecraftforge.fmllegacy.RegistryObject; +import teamdraco.bettas.Bettas; +import teamdraco.bettas.item.BettasBucketItem; +import teamdraco.bettas.item.BettasSpawnEggItem; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; -import java.util.function.Supplier; - public class BettasItems { public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Bettas.MOD_ID); - public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(ItemGroup.TAB_FOOD).food(new Food.Builder().nutrition(1).saturationMod(0.1F).build()))); - public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new FishBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, new Item.Properties().tab(ItemGroup.TAB_MISC).stacksTo(1))); - public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(ItemGroup.TAB_MISC).stacksTo(1))); + public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_FOOD).food(new FoodProperties.Builder().nutrition(1).saturationMod(0.1F).build()))); + public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new BettasBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, Items.BUCKET, false, new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); + public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); - public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new BettasSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(ItemGroup.TAB_MISC))); + public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new BettasSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(CreativeModeTab.TAB_MISC))); - public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); - public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(ItemGroup.TAB_DECORATIONS))); + public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); + public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); + public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); } \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/item/BettasBucketItem.java b/src/main/java/teamdraco/bettas/item/BettasBucketItem.java new file mode 100644 index 0000000..c042d03 --- /dev/null +++ b/src/main/java/teamdraco/bettas/item/BettasBucketItem.java @@ -0,0 +1,104 @@ +package teamdraco.bettas.item; + +import net.minecraft.ChatFormatting; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stats; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobSpawnType; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BucketItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.ForgeEventFactory; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.function.Supplier; + +public class BettasBucketItem extends BucketItem { + private final boolean hasTooltip; + private final Supplier fluid; + private final Item item; + + public BettasBucketItem(Supplier> entityType, Supplier fluid, Item item, boolean hasTooltip, Properties builder) { + super(fluid, builder); + this.fluid = fluid; + this.hasTooltip = hasTooltip; + this.entityTypeSupplier = entityType; + this.item = item; + } + + @Override + public InteractionResultHolder use(Level worldIn, Player playerIn, InteractionHand handIn) { + ItemStack itemstack = playerIn.getItemInHand(handIn); + BlockHitResult raytraceresult = getPlayerPOVHitResult(worldIn, playerIn, ClipContext.Fluid.NONE); + InteractionResultHolder ret = ForgeEventFactory.onBucketUse(playerIn, worldIn, itemstack, raytraceresult); + if (ret != null) return ret; + if (raytraceresult.getType() == BlockHitResult.Type.MISS) { + return InteractionResultHolder.pass(itemstack); + } else if (raytraceresult.getType() != BlockHitResult.Type.BLOCK) { + return InteractionResultHolder.pass(itemstack); + } else { + BlockPos blockpos = raytraceresult.getBlockPos(); + Direction direction = raytraceresult.getDirection(); + BlockPos blockpos1 = blockpos.relative(direction); + if (worldIn.mayInteract(playerIn, blockpos) && playerIn.mayUseItemAt(blockpos1, direction, itemstack)) { + BlockState blockstate = worldIn.getBlockState(blockpos); + BlockPos blockpos2 = blockstate.getBlock() instanceof LiquidBlockContainer && ((LiquidBlockContainer) blockstate.getBlock()).canPlaceLiquid(worldIn, blockpos, blockstate, fluid.get()) ? blockpos : blockpos1; + this.emptyContents(playerIn, worldIn, blockpos2, raytraceresult); + if (worldIn instanceof ServerLevel) this.placeEntity((ServerLevel)worldIn, itemstack, blockpos2); + if (playerIn instanceof ServerPlayer) { + CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) playerIn, blockpos2, itemstack); + } + + playerIn.awardStat(Stats.ITEM_USED.get(this)); + return InteractionResultHolder.sidedSuccess(this.getEmptySuccessItem(itemstack, playerIn), worldIn.isClientSide()); + } else { + return InteractionResultHolder.fail(itemstack); + } + } + } + + @OnlyIn(Dist.CLIENT) + @Override + public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { + super.appendHoverText(stack, world, tooltip, flag); + if (hasTooltip && stack.hasTag()) { + tooltip.add(new TranslatableComponent(getEntityType().getDescriptionId() + "." + stack.getTag().getInt("Variant")).withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.ITALIC)); + } + } + + private void placeEntity(ServerLevel worldIn, ItemStack stack, BlockPos pos) { + Entity entity = this.entityTypeSupplier.get().spawn(worldIn, stack, null, pos, MobSpawnType.BUCKET, true, false); + if (entity != null) { + if (entity instanceof AbstractFish) { + ((AbstractFish)entity).setFromBucket(true); + } + } + } + + private final Supplier> entityTypeSupplier; + + protected EntityType getEntityType() { + return entityTypeSupplier.get(); + } +} diff --git a/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java b/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java new file mode 100644 index 0000000..92d1e14 --- /dev/null +++ b/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java @@ -0,0 +1,26 @@ +package teamdraco.bettas.item; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.SpawnEggItem; +import net.minecraftforge.common.util.Lazy; +import net.minecraftforge.fmllegacy.RegistryObject; + +import java.util.ArrayList; +import java.util.List; + +public class BettasSpawnEggItem extends SpawnEggItem { + public static final List UNADDED_EGGS = new ArrayList(); + private final Lazy> entityTypeSupplier; + + public BettasSpawnEggItem(final RegistryObject> entityTypeSupplier, final int primaryColor, final int secondaryColor, final Properties properties) { + super(null, primaryColor, secondaryColor, properties); + this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); + UNADDED_EGGS.add(this); + } + + @Override + public EntityType getType(CompoundTag nbt) { + return this.entityTypeSupplier.get(); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 19bde7d..446b9e1 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,10 +1,10 @@ modLoader="javafml" #mandatory -loaderVersion="[35,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion="[37,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. license="All rights reserved" [[mods]] #mandatory modId="bettas" #mandatory version="${file.jarVersion}" #mandatory displayName="Bettas" #mandatory -credits="Coda (code), Tazz (art) & Ninni (art)" #optional -authors="Team Draco" #optional +credits="Tazz, Ninni" #optional +authors="Coda" #optional description='''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' diff --git a/src/main/resources/assets/bettas/lang/en_us.json b/src/main/resources/assets/bettas/lang/en_us.json index 2d123b8..6437083 100644 --- a/src/main/resources/assets/bettas/lang/en_us.json +++ b/src/main/resources/assets/bettas/lang/en_us.json @@ -2,7 +2,7 @@ "entity.bettas.betta_fish": "Betta Fish", "item.bettas.betta_fish": "Betta Fish", - "item.bettas.betta_fish_bucket": "Betta Fish Bucket", + "item.bettas.betta_fish_bucket": "Bucket of Betta Fish", "item.bettas.betta_fish_spawn_egg": "Betta Fish Spawn Egg", "item.bettas.blackwater_bottle": "Blackwater Bottle", From 8961909bc281dbe2177589da09295065d91ecb59 Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 18 Jul 2022 20:59:11 -0600 Subject: [PATCH 03/29] most of 1.18.2, missing moss ball gen --- build.gradle | 6 ++--- src/main/java/teamdraco/bettas/Bettas.java | 5 +--- .../bettas/block/DriedLeavesBlock.java | 2 +- .../teamdraco/bettas/block/MossBallBlock.java | 8 +++--- .../teamdraco/bettas/client/ClientEvents.java | 11 +------- .../teamdraco/bettas/init/BettasBlocks.java | 2 +- .../teamdraco/bettas/init/BettasEntities.java | 3 +-- .../teamdraco/bettas/init/BettasFeatures.java | 4 +-- .../teamdraco/bettas/init/BettasItems.java | 7 +++-- .../bettas/item/BettasSpawnEggItem.java | 26 ------------------- src/main/resources/META-INF/mods.toml | 2 +- .../configured_feature/moss_ball.json | 6 +++++ .../worldgen/placed_feature/moss_ball.json | 19 ++++++++++++++ src/main/resources/pack.mcmeta | 2 +- 14 files changed, 44 insertions(+), 59 deletions(-) delete mode 100644 src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java create mode 100644 src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json create mode 100644 src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json diff --git a/build.gradle b/build.gradle index eaeb651..697ae48 100644 --- a/build.gradle +++ b/build.gradle @@ -13,11 +13,11 @@ apply plugin: 'net.minecraftforge.gradle' apply plugin: 'eclipse' apply plugin: 'maven-publish' -version = '1.17.1-1.0.0' +version = '1.18.2-1.0.0' group = 'teamdraco.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'bettas' -java.toolchain.languageVersion = JavaLanguageVersion.of(16) // Mojang ships Java 8 to end users, so your mod should target Java 8. +java.toolchain.languageVersion = JavaLanguageVersion.of(17) // Mojang ships Java 8 to end users, so your mod should target Java 8. println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) minecraft { @@ -94,7 +94,7 @@ dependencies { // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.17.1-37.0.109' + minecraft 'net.minecraftforge:forge:1.18.2-40.0.1' // You may put jars on which you depend on in ./libs or you may define them like so.. // compile "some.group:artifact:version:classifier" diff --git a/src/main/java/teamdraco/bettas/Bettas.java b/src/main/java/teamdraco/bettas/Bettas.java index f407c1f..07c64f6 100644 --- a/src/main/java/teamdraco/bettas/Bettas.java +++ b/src/main/java/teamdraco/bettas/Bettas.java @@ -1,15 +1,12 @@ package teamdraco.bettas; -import net.minecraft.data.worldgen.Features; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.level.SpawnData; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; import net.minecraft.world.level.storage.loot.entries.LootTableReference; @@ -56,7 +53,7 @@ public Bettas() { public static void registerBiomes(BiomeLoadingEvent event) { if (event.getCategory() == Biome.BiomeCategory.SWAMP) { event.getSpawns().getSpawner(MobCategory.WATER_CREATURE).add(new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); - event.getGeneration().getFeatures(GenerationStep.Decoration.SURFACE_STRUCTURES).add(() -> BettasFeatures.MOSS_BALL.get().configured(new CountConfiguration(5)).decorated(Features.Decorators.TOP_SOLID_HEIGHTMAP_SQUARE).count(1)); + } } diff --git a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java index c005a7b..f36dd1d 100644 --- a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java +++ b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java @@ -66,7 +66,7 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.getLiquidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); + worldIn.m_183324_().m_183588_(currentPos, Fluids.WATER); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); diff --git a/src/main/java/teamdraco/bettas/block/MossBallBlock.java b/src/main/java/teamdraco/bettas/block/MossBallBlock.java index 6e797fe..9f1b872 100644 --- a/src/main/java/teamdraco/bettas/block/MossBallBlock.java +++ b/src/main/java/teamdraco/bettas/block/MossBallBlock.java @@ -34,18 +34,18 @@ public class MossBallBlock extends BushBlock implements SimpleWaterloggedBlock, public MossBallBlock(BlockBehaviour.Properties properties) { super(properties); - this.registerDefaultState(this.stateDefinition.any().setValue(BALLS, Integer.valueOf(1)).setValue(WATERLOGGED, Boolean.valueOf(true))); + this.registerDefaultState(this.stateDefinition.any().setValue(BALLS, 1).setValue(WATERLOGGED, Boolean.TRUE)); } @Nullable public BlockState getStateForPlacement(BlockPlaceContext context) { BlockState blockstate = context.getLevel().getBlockState(context.getClickedPos()); if (blockstate.is(this)) { - return blockstate.setValue(BALLS, Integer.valueOf(Math.min(4, blockstate.getValue(BALLS) + 1))); + return blockstate.setValue(BALLS, Math.min(4, blockstate.getValue(BALLS) + 1)); } else { FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos()); boolean flag = fluidstate.getType() == Fluids.WATER; - return super.getStateForPlacement(context).setValue(WATERLOGGED, Boolean.valueOf(flag)); + return super.getStateForPlacement(context).setValue(WATERLOGGED, flag); } } @@ -67,7 +67,7 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.getLiquidTicks().scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); + worldIn.m_183324_().m_183588_(currentPos, Fluids.WATER); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); diff --git a/src/main/java/teamdraco/bettas/client/ClientEvents.java b/src/main/java/teamdraco/bettas/client/ClientEvents.java index b444185..fb7b8bb 100644 --- a/src/main/java/teamdraco/bettas/client/ClientEvents.java +++ b/src/main/java/teamdraco/bettas/client/ClientEvents.java @@ -10,7 +10,6 @@ import teamdraco.bettas.client.renderer.BettaFishRenderer; import teamdraco.bettas.init.BettasBlocks; import teamdraco.bettas.init.BettasEntities; -import teamdraco.bettas.item.BettasSpawnEggItem; import net.minecraft.client.renderer.RenderType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -29,13 +28,5 @@ public static void clientSetup(FMLClientSetupEvent event) { ItemBlockRenderTypes.setRenderLayer(BettasBlocks.DRIED_LEAVES.get(), RenderType.cutout()); ForgeHooksClient.registerLayerDefinition(BettaFishRenderer.MODEL_LAYER, BettaFishModel::createLayerDefinition); - - } - - @SubscribeEvent - public static void itemColors(ColorHandlerEvent.Item event) { - ItemColors handler = event.getItemColors(); - ItemColor eggColor = (stack, tintIndex) -> ((BettasSpawnEggItem) stack.getItem()).getColor(tintIndex); - for (BettasSpawnEggItem e : BettasSpawnEggItem.UNADDED_EGGS) handler.register(eggColor, e); } -} +} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/init/BettasBlocks.java b/src/main/java/teamdraco/bettas/init/BettasBlocks.java index ed1f43e..f0e05e9 100644 --- a/src/main/java/teamdraco/bettas/init/BettasBlocks.java +++ b/src/main/java/teamdraco/bettas/init/BettasBlocks.java @@ -5,7 +5,7 @@ import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.MaterialColor; -import net.minecraftforge.fmllegacy.RegistryObject; +import net.minecraftforge.registries.RegistryObject; import teamdraco.bettas.Bettas; import teamdraco.bettas.block.DriedLeavesBlock; import teamdraco.bettas.block.MossBallBlock; diff --git a/src/main/java/teamdraco/bettas/init/BettasEntities.java b/src/main/java/teamdraco/bettas/init/BettasEntities.java index 297bcb3..09f14dd 100644 --- a/src/main/java/teamdraco/bettas/init/BettasEntities.java +++ b/src/main/java/teamdraco/bettas/init/BettasEntities.java @@ -1,10 +1,9 @@ package teamdraco.bettas.init; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraftforge.fmllegacy.RegistryObject; +import net.minecraftforge.registries.RegistryObject; import teamdraco.bettas.Bettas; import teamdraco.bettas.entity.BettaFishEntity; import net.minecraftforge.registries.DeferredRegister; diff --git a/src/main/java/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/teamdraco/bettas/init/BettasFeatures.java index 4036e84..acb48cd 100644 --- a/src/main/java/teamdraco/bettas/init/BettasFeatures.java +++ b/src/main/java/teamdraco/bettas/init/BettasFeatures.java @@ -2,7 +2,7 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; -import net.minecraftforge.fmllegacy.RegistryObject; +import net.minecraftforge.registries.RegistryObject; import teamdraco.bettas.Bettas; import teamdraco.bettas.feature.MossBallFeature; import net.minecraftforge.registries.DeferredRegister; @@ -12,4 +12,4 @@ public class BettasFeatures { public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(CountConfiguration.CODEC)); -} +} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/init/BettasItems.java b/src/main/java/teamdraco/bettas/init/BettasItems.java index d372502..1f8f5f9 100644 --- a/src/main/java/teamdraco/bettas/init/BettasItems.java +++ b/src/main/java/teamdraco/bettas/init/BettasItems.java @@ -1,13 +1,12 @@ package teamdraco.bettas.init; -import net.minecraft.sounds.SoundEvents; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.*; import net.minecraft.world.level.material.Fluids; -import net.minecraftforge.fmllegacy.RegistryObject; +import net.minecraftforge.common.ForgeSpawnEggItem; +import net.minecraftforge.registries.RegistryObject; import teamdraco.bettas.Bettas; import teamdraco.bettas.item.BettasBucketItem; -import teamdraco.bettas.item.BettasSpawnEggItem; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; @@ -18,7 +17,7 @@ public class BettasItems { public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new BettasBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, Items.BUCKET, false, new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); - public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new BettasSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(CreativeModeTab.TAB_MISC))); + public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new ForgeSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(CreativeModeTab.TAB_MISC))); public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); diff --git a/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java b/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java deleted file mode 100644 index 92d1e14..0000000 --- a/src/main/java/teamdraco/bettas/item/BettasSpawnEggItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package teamdraco.bettas.item; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.SpawnEggItem; -import net.minecraftforge.common.util.Lazy; -import net.minecraftforge.fmllegacy.RegistryObject; - -import java.util.ArrayList; -import java.util.List; - -public class BettasSpawnEggItem extends SpawnEggItem { - public static final List UNADDED_EGGS = new ArrayList(); - private final Lazy> entityTypeSupplier; - - public BettasSpawnEggItem(final RegistryObject> entityTypeSupplier, final int primaryColor, final int secondaryColor, final Properties properties) { - super(null, primaryColor, secondaryColor, properties); - this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get); - UNADDED_EGGS.add(this); - } - - @Override - public EntityType getType(CompoundTag nbt) { - return this.entityTypeSupplier.get(); - } -} \ No newline at end of file diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 446b9e1..7adb930 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,5 +1,5 @@ modLoader="javafml" #mandatory -loaderVersion="[37,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +loaderVersion="[40,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. license="All rights reserved" [[mods]] #mandatory modId="bettas" #mandatory diff --git a/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json b/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json new file mode 100644 index 0000000..bbcb19d --- /dev/null +++ b/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json @@ -0,0 +1,6 @@ +{ + "type": "minecraft:sea_pickle", + "config": { + "count": 20 + } +} diff --git a/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json b/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json new file mode 100644 index 0000000..5f30ade --- /dev/null +++ b/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json @@ -0,0 +1,19 @@ +{ + "feature": "minecraft:sea_pickle", + "placement": [ + { + "type": "minecraft:rarity_filter", + "chance": 16 + }, + { + "type": "minecraft:in_square" + }, + { + "type": "minecraft:heightmap", + "heightmap": "OCEAN_FLOOR_WG" + }, + { + "type": "minecraft:biome" + } + ] +} diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta index d530cd9..ce05012 100644 --- a/src/main/resources/pack.mcmeta +++ b/src/main/resources/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "bettas resources", - "pack_format": 6 + "pack_format": 8 } } From c0c2a005da5ee7e0d93279d926f5b8cb6cb388a9 Mon Sep 17 00:00:00 2001 From: Cody Date: Mon, 18 Jul 2022 21:18:42 -0600 Subject: [PATCH 04/29] add new textures, temp moss ball crafting recipe --- .../bettas/models/block/moss_balls_four.json | 69 ++++++++---------- .../models/block/moss_balls_four_alter.json | 56 ++++++++++++++ .../bettas/models/block/moss_balls_one.json | 18 ++--- .../models/block/moss_balls_one_alter.json | 20 +++++ .../bettas/models/block/moss_balls_three.json | 52 ++++++------- .../models/block/moss_balls_three_alter.json | 44 +++++++++++ .../bettas/models/block/moss_balls_two.json | 35 ++++----- .../models/block/moss_balls_two_alter.json | 32 ++++++++ .../block/heavily_piled_dried_leaves.png | Bin 601 -> 530 bytes .../block/loosely_piled_dried_leaves.png | Bin 610 -> 392 bytes .../bettas/textures/block/moss_ball.png | Bin 432 -> 167 bytes .../bettas/textures/block/moss_ball_block.png | Bin 544 -> 522 bytes .../textures/block/piled_dried_leaves.png | Bin 519 -> 609 bytes .../bettas/textures/item/betta_fish.png | Bin 541 -> 417 bytes .../textures/item/betta_fish_bucket.png | Bin 498 -> 475 bytes .../textures/item/blackwater_bottle.png | Bin 364 -> 372 bytes .../bettas/textures/item/dried_leaves.png | Bin 518 -> 371 bytes .../assets/bettas/textures/item/moss_ball.png | Bin 342 -> 301 bytes .../bettas/recipes/moss_ball_from_moss.json | 12 +++ .../configured_feature/moss_ball.json | 6 -- .../worldgen/placed_feature/moss_ball.json | 19 ----- 21 files changed, 244 insertions(+), 119 deletions(-) create mode 100644 src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json create mode 100644 src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json create mode 100644 src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json create mode 100644 src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json create mode 100644 src/main/resources/data/bettas/recipes/moss_ball_from_moss.json delete mode 100644 src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json delete mode 100644 src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_four.json b/src/main/resources/assets/bettas/models/block/moss_balls_four.json index 77d3fca..f2558b9 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_four.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_four.json @@ -1,60 +1,55 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [2, 0, 3], + "to": [8, 6, 9], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [9, 0, 1], - "to": [15, 6, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 9]}, + "from": [9, 0, 9], + "to": [15, 6, 15], "faces": { - "north": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "east": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "south": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "west": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "up": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "down": {"uv": [0, 0, 6, 6], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [1, 0, 5], - "to": [9, 8, 13], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 14]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "east": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "south": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "west": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "up": {"uv": [8, 0, 16, 8], "texture": "#0"}, - "down": {"uv": [8, 0, 16, 8], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json new file mode 100644 index 0000000..3d4fbd1 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_four_alter.json @@ -0,0 +1,56 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 8], + "to": [7, 6, 14], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 3], + "to": [15, 6, 9], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_one.json b/src/main/resources/assets/bettas/models/block/moss_balls_one.json index 59d51a3..ea28ba2 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_one.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_one.json @@ -1,21 +1,19 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json new file mode 100644 index 0000000..ab3a0b6 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_one_alter.json @@ -0,0 +1,20 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_three.json b/src/main/resources/assets/bettas/models/block/moss_balls_three.json index 2b0d6bd..8a42b97 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_three.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_three.json @@ -1,47 +1,43 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [2, 0, 3], + "to": [8, 6, 9], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} } }, { - "from": [9, 0, 1], - "to": [15, 6, 7], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 9]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "east": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "south": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "west": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "up": {"uv": [0, 0, 6, 6], "texture": "#0"}, - "down": {"uv": [0, 0, 6, 6], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json new file mode 100644 index 0000000..8d9969c --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_three_alter.json @@ -0,0 +1,44 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 8], + "to": [7, 6, 14], + "faces": { + "north": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "east": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "south": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "west": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "up": {"uv": [0, 10, 6, 16], "texture": "#0"}, + "down": {"uv": [0, 10, 6, 16], "texture": "#0"} + } + }, + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_two.json b/src/main/resources/assets/bettas/models/block/moss_balls_two.json index e813f68..03e6481 100644 --- a/src/main/resources/assets/bettas/models/block/moss_balls_two.json +++ b/src/main/resources/assets/bettas/models/block/moss_balls_two.json @@ -1,34 +1,31 @@ { - "ambientocclusion": false, "textures": { "0": "bettas:block/moss_ball", "particle": "bettas:block/moss_ball" }, "elements": [ { - "from": [9, 0, 9], - "to": [16, 7, 16], - "rotation": {"angle": 0, "axis": "y", "origin": [17, 8, 17]}, + "from": [1, 0, 10], + "to": [6, 5, 15], "faces": { - "north": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "east": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "south": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "west": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "up": {"uv": [9, 9, 16, 16], "texture": "#0"}, - "down": {"uv": [9, 9, 16, 16], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } }, { - "from": [2, 0, 0], - "to": [6, 4, 4], - "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "from": [9, 0, 2], + "to": [14, 5, 7], "faces": { - "north": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "east": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "south": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "west": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "up": {"uv": [0, 7, 4, 11], "texture": "#0"}, - "down": {"uv": [0, 7, 4, 11], "texture": "#0"} + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} } } ] diff --git a/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json b/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json new file mode 100644 index 0000000..73824f4 --- /dev/null +++ b/src/main/resources/assets/bettas/models/block/moss_balls_two_alter.json @@ -0,0 +1,32 @@ +{ + "textures": { + "0": "bettas:block/moss_ball", + "particle": "bettas:block/moss_ball" + }, + "elements": [ + { + "from": [1, 0, 2], + "to": [6, 5, 7], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + }, + { + "from": [9, 0, 10], + "to": [14, 5, 15], + "faces": { + "north": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "east": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "south": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "west": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "up": {"uv": [7, 11, 12, 16], "texture": "#0"}, + "down": {"uv": [7, 11, 12, 16], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png b/src/main/resources/assets/bettas/textures/block/heavily_piled_dried_leaves.png index 1d5b69bf9f5f4aed77b5399039dba54739ecb5cd..ba76badfc961a9dd2015633465e1e12f248859ab 100644 GIT binary patch delta 492 zcmV0L}-dxuH2<0SMAzv`W~K z(TZCe64<(c(JB$+{qyQE4G+=*u&QQ^;-pBhE+hba4SCR--G8xVyIx>L_^404f@(fV zWaoP&n{~y5*1WxcV%-IRWm&K+3wFmA=L5M`)Xjw~%C4IWUOIli{7Neg&)fSaR)le3 zc=|cRx*jv~cT<9NY}boKup-H@ARX0w!mSO-OaP-5S&)t(9jj`F72$7vU|ALkFmydi zujUgTroA`WFn^N6{?Z#M!eM`*nolrVv0X1%mc_SJrnw<>zLIP8O-X)# ix#PmHJGM0EEB^sRQ!%LJ87q?j0000m5P5QRUR7{_A0URg@x2q>s7AYDO2q^s}G z+&{efq@+nlk}3s8&>$hR-e`j@L<(nDhqC2pcILhBP4MTZIv>oLOav$yvD!8OWFlZV z64cd^)wW@~|KP_c;b6{;i$0ZZ8IAs$$L zu-$*4?aBLg^Z_29_FW2#c}`s&d01+A>23f(BoWiefakY&L=v&tHHf5xTIm*TPaOj{ z{eC9NMBtfZBJe!iz)S>eb{$xm^ay|dy75`3D)yeWJ%4$qb#-K1bSZ3h4ceZ(tt;mz zRWZw#noI;_qR;Jr)LrK81^|lu8e?0+howfzh{vZr#>9>JpKx6C0nqm3rKT!I+Y?28&1&1l=J>dH7xSD-w_K$v zMkYNL^DW#T$+|S$&!p$_u++$;$L&oYh?w1_zV{Qdr#}Pu%;KI)%lNG)y-omTeYpoSrW-cv|0yGuOAjCg2!AeFVDKDgFMPLuLL~iYI#kt)gg^T z$%*j&QzG!$Up!p^0Lr4qeCC1^4cxONGX9AM^)X{)NhH%aG>Qy5nA!nO)J>p2LQP-_ z{W#+ZO$vb@>1L6dbFn zhza9mAdrb}O;WjHB2o!{ZI0ON{^0RF5gpH=s(S+!o=~os(0{Vc9nT>iFq$i|@?%)i z!2K619XwtJ;^*==-nK{drfZ>PH&@*o3|l42B3bz{B9-9rJrRtoQ7>S!*$V*BIN5I& zNrfi>K-sT7TL)n0KRIfSJ=%D%{Lbu9yG-&CXq6ybQ$RB}xmJ_jnly7FLBPL@L3` zkJDyL8qin_9#XEDkhY#ecg(ZKul@llJYh6fB2oze;OTh>(RTCHs232a1V0ub+`=a~ zrod>f((AO{Jn^EePhR~4wD9m34DsRK#&{VB)`Z1t)PD;X9^nhwxhrVjzZS9b;|tjF z;e3sLvq-E*)xAN#S-coB+3dwN^T{ea+3ZEPCW&)=-Yl(-=TLk&K^x4rLfSfd)Aa>M z0O(EE!jeX+`mj|ZM&XzOW=_Y4rfyAAc2mDuBug5IR00*AE~o;)2W9#FwmqhP=OK%i zDE)ZDRyK)Nehh8cDiM1h`0ubg?-s*Wi8`J`gV|O*J?}2QJR9mC)sQ0#x&X6<00000 LNkvXXu0mjf(>Dn~ diff --git a/src/main/resources/assets/bettas/textures/block/moss_ball.png b/src/main/resources/assets/bettas/textures/block/moss_ball.png index b0170b529ea299755683dfd53b57a56587979082..7da6af66e7925775df21c1e1e5be97d2b70658f9 100644 GIT binary patch delta 139 zcmV;60CfMb1E&FyB!6y6L_t(|USnVw1*2e4fVc{~|0!*@|Iul5bvOaCrj!|0VA?y+ z3~T_hp*Rf&DF#WxXpkWw8YBld9L-=901|XbHbAinrVvEK3`Q150mwFk3;`JiQwU-s tdjqQhAVn}u$TouHV6KCSgV^Z$0n)I0!Yt3@!2kdN07*qoL_79*WE3wa z?bY=K(aZrL%Nw?4$LpgR0mREm3*d(?fgTgh92*npG0G2Jwtr>^beG-d@rpqb=ds6B zcLW>L0C0CZVPhJUyxI>)(h5PK$7FezG}VqhZ%jj$Hz;8jWO+kb)Yjgb9rM@&V4d!d zT6H8iNh|9-M3#4K{YnMO4_)5hKCPqAE_PYe_@PTQ^H`^QOHvj!qa(Tl#LG$RhpyE_ zT1e80vZzsum49yg<9T`bIC@m7DvO$}aR)xtAJK0}pT7RAQYC4{JoZis2(Vb`w%>xp zmPL&!i<(R~10fF)=rK33vi4LvY>Y=j^}mP!_s^H@FuAb{rA}t`Ai>e>Ct0R(TD=}b z8(B74s3fh^G9A`Jsnyh8GT#zD6h^)Lc3^_ufB zmbxxnY*R3+idS@Np$iv)dKgK=0Q0GM-8PLwJ&f3C7~n?=fPcB0DZc*6!?K!WZ$M04 zw-x|yJ&a^0AH9#RTZ`+x6+}N$OuZ)m`~aY=CTRlTW+xw#2MUL>nn=Td{PRP&8{Q-f zG!EIx2Yjj9hHqI-WItS)LdC0auZIyDXM;>0QWpw_AC3PMj(~a?nY$T3Qi7Pa+d0Ed zAq@iv1FrX0gnvoH;7z#h)-xS6ex$?|m2Z?>l`oW+MUcB&4}f>@@FPY3D?}F?HE{^Y z_Gw)jhp8W)0XaPd%1%BsU_j2tnCrdWTx%^7cDAc;5@`T*;bI$` zOvm!FkcI(sH>2WJ9+5oWTroP?uNQUUO2LH2AeNT}63 delta 505 zcmVk|Osz@w*q zUZ#qpsoCypGELuG|#*RJzJML6)dbth+AeRb7|zC1Mmqj{H}_8CUbok)bY=Rbe^wr5Ig z&8A)Y+Tr>IWTqrt6nyyfj$!1`*A7QhGoA!&)+fxaLW!*v1wGyNEtSA0r64mU;M=}4 zQxXom*1>IWw|_h`)9!Wbksm60+Gmv%mW`z1=-6X4?=qeQ_NQDT`}V@}u82gcZZpk{ zXQ7Eu;7QLq_AFG}f&lvb@tLEkStW(d{mLU?!^w&Tx{`?l?Bq%B;lSf%s;u?Qc-EOD zrbN6<&Ncz*aXbk)nwq|D9nPj*@?tke{0G=HBVuO%f-c2 zP?QbZeNE#w?0&uS@AXXMHmFG}3D33@e3waT&l6J@* vV+2q#QF6g}64+GWnPqZjvp(5W9*g`3hABxo;?i_}00000NkvXXu0mjfoQMFk diff --git a/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png b/src/main/resources/assets/bettas/textures/block/piled_dried_leaves.png index f6193b0ee6aca2d30907dfddd46ccbac54346df3..f1b7d4aa6d3d86a6dd121bc31d9e2c9a0e83cd1d 100644 GIT binary patch delta 585 zcmV-P0=E5!1mOgbBYyw^b5ch_0Itp)=>Px%8%ab#R5*=QlRa-5K@f(Y1>bRSCVbdP zM`5`_rg9Y_S(NV6xTd6bmtWv2ooh<|L3)=oD3vQLs>lUMm~Yl_w~98!WmcE1XWn_| zd1qCx)3VK|LiWw(Tk7Q^0M9S43ZU0%S%90XOWxi;Tx|{@)_)1HPFODw{P_7x0eqek zSJdyeZ8NISj4Hgne-L1!PxyW@?K8i!DynscpkA% zxVgHdc5%+h`~l#sUM{-kbZST;^xbq>0iaP0S!^_)r-Z=E^ZfFva-XM!!DylYryA?j zzU&R~_Wr@n7=H?(PwnE|^_&ex6O{!dZ)Xg{@l^FXEqily$zr34b;4?Y{112zU^t#C zY5F~1)2N2d!EiiPLS3xa%SHO#wgouLs;!p?N`cSL7}m=J^>Pt$0I=AkBErl$$iiCf zkF1vmCmMM9f6bakHKY{y3`P?rG3WZ-wtc+6wE|Jrk$+Ugkt9$EeR`di72wW+u;_Q& zwsvvOYJYShv-#H5#5!R(o~mY4;qm^~=42Our-wUR3Vdest;=~ZnyA3bvopqB=l5@4 zZLCukIoZG8ZClwh`!{->mK}^HN?fe=M`rV_y9f7CgtR0e_Oo2%UYb#bSSK{9Vd@|| zG1dv!Q9=!YDk%t~Z1c{TRN#x}vDj!A)y^1J`y+vurxf_^X!_l@jdemH^jT~)v-y_4 X+Zi$e=RQf000000NkvXXu0mjfK20VY delta 494 zcmVGGakCI}%=0ZnoaF58nR(~ueP_1WdD?3)Ms2Ki zn&@@s;>YoIFz*i^b>i}T61$&H8otD?59Z^1cvIsw@Op5s1%K!)&BbVZQ@{TQiM{>s z>kgZ^CmYLA1m7S3sX<9w&(>;@mEM9-{5%@fDYD6f{(NjcUJ1$H4zH#KjK*QCwEct2 zIwD%>f3vaLdS`qZ-*LlNx8$w*aQrtuo=qCvb(U;0IOe@lAYwWMfl%o#%~XF>**5__G%7wA$Mel@J)qRYF{K_blKB+!(5Sq6(XXne z!jfsCFkk9n5|2bN4~>e^nNBp&!ChD%pCUPO1xD1>if4N-cmolH9)9b>oUbCeGQS-h z(}YH4u(miAFQNu@OAugAm~{B8UK5mx4~COurW4b_zf%!D`s8|T4!#Iblb9?|`rUTF kbrTFtbm(IflJlVc0h^jO)akWx!TrlCYaf@vwZNJ_y~n;?dM zK%4ppf%PA9+onyMg4PkVaT~cxXz4DHGBXDQCtWz)7I81?Sj*__?%_SpeL45SU+U6H zimZDk2EB=&hKq4qWZg57+Bgw1>_q!i^BJV~BjD0Wiu^*9YJWa6^TA5d#`RM@iS z(5I&H{NQ(hn{r+g3DY298pQMno*!UYa{$y@9Th0X?ce{wY3Tugm>!|o{Gj^eeM4T~ zIW%TN8>m9$22!$l8LsbMvsk(3v3#VB1*Dfvky^D?4>AZ4tQ-S`!b1QF89a|Z+5glR XF^+=9F3h|e00000NkvXXu0mjfoQSk? delta 502 zcmVB*+ChPV28aV_qf)tX3FYvMjQ32x3Nk?wRw zvRV`Ie<|5c6WeJ(!NuJPIR_%U8c=aC2pW=5F0CePVa0swz9 z2jFTnCYUaH@hHcMcNv3?2nS|Hgv!Be1wd~wlw_u^5lojHD+vl&084B|2yOe5Ieph- z&o(F((*S(y{p46#J39NDA0Qs8KdU^Jc>(rpgTCt#%x_i#p-@UJu-t(`Q_7+92&sa%pnh7)lmWW&1-raU`Y^6myv1rT@PTruFffd sa6iJY&S?Y;8*ALvRQbC$_x!*511*KwLi#ItIRF3v07*qoM6N<$g7W0)asU7T diff --git a/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png b/src/main/resources/assets/bettas/textures/item/betta_fish_bucket.png index ec830ba24ecabf1ff4897debabad9a7a818d5732..3199b58c91bc1bf1aedc1c6cfde429a51a1d06b3 100644 GIT binary patch delta 450 zcmV;z0X_cm1KR_TBYyw^b5ch_0Itp)=>Px$l}SWFR5*>LlRZl#Q51%s*@zfNG&>3t zb!EW~25gLhG(t$RhzJYoUq~aQT(H~HQU{yuQw$<@7D^DoCRVv9SFj08A;`up)^Q?^ zS{TMc9Fn<-ji)Y5PcC5qoUy~f*=^?B@W%bs&0xSNTuSNK+wh3h zXJNSVK@9u6%muljAV;*X-rXbi(S+E-0p54lAvqxO?R|n33rkl7Mm* zWjJ%`5T}6Tr#Io`#J_{t#bv7* z{CNdU(_kbu=#dBm()U0v>SOzu=}rPr{}-TcAP|6&oI|Np!pdI!hhRRiRZ$d4K$-y& z>@h!e43DP^GXq=p7Rx1pVzKB5GR@ytsMTr`MhF;&;ZiCT3anW!mnG2bc$Vd=sv@0E zgRmSR1bD%I4f}~4$5%;!loN>r8y*MHTB%gvbUO8f6)VC1Pw<}AI0`vlqF@G*eL_t(Ijm46`OT$1M#XpKoYonrQHwP!z;^gMgMIAaRI7R6n zprAMwbkMnLQNf{$IEau*aFBKrM8w!Zg(4WlqE^NHFd5D*P%mi}1mAXi-+TAI?+*SO z9j%7O;76Sj*00000K{l+|K&%wAWKD%2V z>;Ne*CXGiHydXz01Hs{^QG1!!&#O(Y`23I`B*2{g$c$Z(@l3>VgM_P%**y7nf0K3; zzGt>QV#=gb@U7SV{sv14;UnMVf4x^dyh&cH;cmA6A9X8%iM)>D&U`kj7#aGc%6)jw R3jJaL0#8>zmvv4FO#sq1l1~5t diff --git a/src/main/resources/assets/bettas/textures/item/dried_leaves.png b/src/main/resources/assets/bettas/textures/item/dried_leaves.png index 25945705b7848c7d8ef0c4fa0dbe98c1e177d6d4..f2e5bf36c41a470e2ee5ef80aa032f3a53b21c96 100644 GIT binary patch delta 331 zcmV-R0kr;x1oHxrF@G&dL_t(Ijn$DcYlA=-h9A?KTo6nplnx0l2^lhG%D>2(F+Z(i zSN}z)j)KKPa0%6+RyeA6h@BL#wsdV@IJghK@8Q1Z;NQpU7pMKE0Vq|?!_$lP{m2i1 z(|*&e7jpm#t%>54AWW5q^qkd6nO_ob;Z=7!D^Cf30Y{d8q&lLlR@e65M zFmcA6xF}A$;Y3o^%pB8?0chn!aY_`YoG&>+m{=dBX66X|rN_H02LMB2sp^5KAWW+ag)axkx~BjD002ovPDHLkV1o9-m?QuI delta 479 zcmV<50U-YK0)_;TF@L~GL_t(IjeV0%i{d~KhM%nQBbb;lsFx7g(}0Ngz+Utp>`(O{ ztd{}r5`;O)1TVWXwCP9^bxJp>x88cH+TcMfhF0a-CIG9wG#>qk18mf=WUKNM;letvf<0Fhpq`F~x!K^u{jc!M@$-yu6+ z*lbS?k#D!j;oM~w^Z@V%Z5*%5^YjUklw{`%R=>kC9O**Zfl7|wQoKPMfR|m$kEzYr zcK~?Zy#o+TY@{fN;+)l98m6)=MS(YH6UBM$z&45ET%Q$-*WG*FT6%3l6iLb9^!Jv& zj^78#ugxE3L4S{6ViUim%_*#pnc>-H70z9xD3GE+BqhPb#_D$%`wnB@sYSj_%v20! zK~GoSY)^F?q5#l>BE9mmtE;b%nV|(ldPO89AQ4H)G8~beFGx{nyV0Rw=65wnZ+ogV zL={n-6V6>-HHvc$%d<^ATKVbhj)6*4mVLJcpm!sRb6EVO}@QDR`vBxF8St! diff --git a/src/main/resources/assets/bettas/textures/item/moss_ball.png b/src/main/resources/assets/bettas/textures/item/moss_ball.png index b9bb1ca3fb6dc2911923f129b081ac5f1e0edd14..33f46048590f5bec9b74baa99c0e48ba7dbe92f7 100644 GIT binary patch delta 261 zcmV+g0s8*d0<8j&Fn<8&NklmRrlJ`jEZIDB0&BMRHU00000 LNkvXXu0mjfW94>D delta 303 zcmV+~0nq-f0@ebMFn<9MNklVp+8oJMPZDfcaRfg(VHg=(|Q7 z>eJZp&j@iUti7^oDRe`wF93Egrp|LvzxB3m@2)6xLn0$S*Sjc*&~cVjJ$LoWaT002ovPDHLkV1jNC Bl_~%L diff --git a/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json b/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json new file mode 100644 index 0000000..568a6c6 --- /dev/null +++ b/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json @@ -0,0 +1,12 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:moss_block" + } + ], + "result": { + "item": "bettas:moss_ball", + "count": 4 + } +} \ No newline at end of file diff --git a/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json b/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json deleted file mode 100644 index bbcb19d..0000000 --- a/src/main/resources/data/bettas/worldgen/configured_feature/moss_ball.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "minecraft:sea_pickle", - "config": { - "count": 20 - } -} diff --git a/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json b/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json deleted file mode 100644 index 5f30ade..0000000 --- a/src/main/resources/data/bettas/worldgen/placed_feature/moss_ball.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "feature": "minecraft:sea_pickle", - "placement": [ - { - "type": "minecraft:rarity_filter", - "chance": 16 - }, - { - "type": "minecraft:in_square" - }, - { - "type": "minecraft:heightmap", - "heightmap": "OCEAN_FLOOR_WG" - }, - { - "type": "minecraft:biome" - } - ] -} From 59e5b3da822904670aa2a41be185c4515d1f7766 Mon Sep 17 00:00:00 2001 From: Cody Date: Thu, 21 Jul 2022 01:44:24 -0600 Subject: [PATCH 05/29] remove moss_ball_from_moss.json --- .../data/bettas/recipes/moss_ball_from_moss.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/main/resources/data/bettas/recipes/moss_ball_from_moss.json diff --git a/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json b/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json deleted file mode 100644 index 568a6c6..0000000 --- a/src/main/resources/data/bettas/recipes/moss_ball_from_moss.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "minecraft:crafting_shapeless", - "ingredients": [ - { - "item": "minecraft:moss_block" - } - ], - "result": { - "item": "bettas:moss_ball", - "count": 4 - } -} \ No newline at end of file From 3c93388e36ad1c5200af2b920ca107b91d256ae7 Mon Sep 17 00:00:00 2001 From: superlord9362 <33046398+superlord9362@users.noreply.github.com> Date: Fri, 22 Jul 2022 18:54:37 -0700 Subject: [PATCH 06/29] Moss Ball Generation Added Moss Ball generation as well as updated all mappings --- build.gradle | 160 ++++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 282 +++++++++++------- gradlew.bat | 43 +-- src/main/java/teamdraco/bettas/Bettas.java | 23 +- .../bettas/block/DriedLeavesBlock.java | 8 +- .../teamdraco/bettas/block/MossBallBlock.java | 11 +- .../teamdraco/bettas/client/ClientEvents.java | 15 +- .../bettas/client/model/BettaFishModel.java | 3 +- .../bettas/init/BettasConfiguredFeatures.java | 16 + .../teamdraco/bettas/init/BettasFeatures.java | 9 +- .../bettas/init/BettasPlacedFeatures.java | 16 + .../bettas/item/BettasBucketItem.java | 6 +- 13 files changed, 384 insertions(+), 210 deletions(-) create mode 100644 src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java create mode 100644 src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java diff --git a/build.gradle b/build.gradle index 697ae48..fb21944 100644 --- a/build.gradle +++ b/build.gradle @@ -1,35 +1,46 @@ buildscript { repositories { - maven { url = 'https://files.minecraftforge.net/maven' } - jcenter() + // These repositories are only for Gradle plugins, put any other repositories in the repository block further below + maven { url = 'https://maven.minecraftforge.net' } mavenCentral() } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1+', changing: true + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true } } -apply plugin: 'net.minecraftforge.gradle' // Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -apply plugin: 'eclipse' -apply plugin: 'maven-publish' +plugins { + id 'eclipse' + id 'maven-publish' +} +apply plugin: 'net.minecraftforge.gradle' + -version = '1.18.2-1.0.0' -group = 'teamdraco.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'bettas' +version = '1.0' +group = 'com.yourname.modid' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'modid' -java.toolchain.languageVersion = JavaLanguageVersion.of(17) // Mojang ships Java 8 to end users, so your mod should target Java 8. +// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. +java.toolchain.languageVersion = JavaLanguageVersion.of(17) -println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) +println "Java: ${System.getProperty 'java.version'}, JVM: ${System.getProperty 'java.vm.version'} (${System.getProperty 'java.vendor'}), Arch: ${System.getProperty 'os.arch'}" minecraft { - // The mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD Snapshot are built nightly. - // stable_# Stables are built at the discretion of the MCP team. - // Use non-default mappings at your own risk. they may not always work. + // The mappings can be changed at any time and must be in the following format. + // Channel: Version: + // official MCVersion Official field/method names from Mojang mapping files + // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official + // + // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge + // Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started + // + // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.17.1' - // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. - - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + mappings channel: 'official', version: '1.18.2' + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. // Default run configurations. // These can be tweaked, removed, or duplicated as needed. @@ -38,11 +49,20 @@ minecraft { workingDirectory project.file('run') // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + mods { examplemod { source sourceSets.main @@ -53,12 +73,41 @@ minecraft { server { workingDirectory project.file('run') + property 'forge.logging.markers', 'REGISTRIES' + + property 'forge.logging.console.level', 'debug' + + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + + mods { + examplemod { + source sourceSets.main + } + } + } + + // This run config launches GameTestServer and runs all registered gametests, then exits. + // By default, the server will crash when no gametests are provided. + // The gametest system is also enabled by default for other run configs under the /test command. + gameTestServer { + workingDirectory project.file('run') + // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + // The markers can be added/remove as needed separated by commas. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels property 'forge.logging.console.level', 'debug' + // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. + property 'forge.enabledGameTestNamespaces', 'examplemod' + mods { examplemod { source sourceSets.main @@ -69,10 +118,8 @@ minecraft { data { workingDirectory project.file('run') - // Recommended logging data for a userdev environment - property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' + property 'forge.logging.markers', 'REGISTRIES' - // 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. @@ -90,52 +137,55 @@ minecraft { // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } -dependencies { - // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed - // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. - // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.18.2-40.0.1' +repositories { + // Put repositories for dependencies here + // ForgeGradle automatically adds the Forge maven and Maven Central for you - // You may put jars on which you depend on in ./libs or you may define them like so.. - // compile "some.group:artifact:version:classifier" - // compile "some.group:artifact:version" + // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: + // flatDir { + // dir 'libs' + // } +} - // Real examples - // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env - // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env +dependencies { + // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed + // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.18.2-40.1.68' - // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. - // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + // Real mod deobf dependency examples - these get remapped to your current mappings + // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency + // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency + // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency - // These dependencies get remapped to your current MCP mappings - // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' + // Examples using mod jars from ./libs + // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") // For more info... // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html - } -// Example for how to get properties into the manifest for reading by the runtime.. +// Example for how to get properties into the manifest for reading at runtime. jar { manifest { attributes([ - "Specification-Title": "examplemod", - "Specification-Vendor": "examplemodsareus", - "Specification-Version": "1", // We are version 1 of ourselves - "Implementation-Title": project.name, - "Implementation-Version": "${version}", - "Implementation-Vendor" :"examplemodsareus", - "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + "Specification-Title" : "examplemod", + "Specification-Vendor" : "examplemodsareus", + "Specification-Version" : "1", // We are version 1 of ourselves + "Implementation-Title" : project.name, + "Implementation-Version" : project.jar.archiveVersion, + "Implementation-Vendor" : "examplemodsareus", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } } -// Example configuration to allow publishing using the maven-publish task +// Example configuration to allow publishing using the maven-publish plugin // This is the preferred method to reobfuscate your jar file -jar.finalizedBy('reobfJar') +jar.finalizedBy('reobfJar') // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing -//publish.dependsOn('reobfJar') +// publish.dependsOn('reobfJar') publishing { publications { @@ -145,7 +195,11 @@ publishing { } repositories { maven { - url "file:///${project.projectDir}/mcmodsrepo" + url "file://${project.projectDir}/mcmodsrepo" } } -} \ No newline at end of file +} + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ffed3a2..41dfb87 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d..c53aefa 100644 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f955316..107acd3 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/teamdraco/bettas/Bettas.java b/src/main/java/teamdraco/bettas/Bettas.java index 07c64f6..9c84ae7 100644 --- a/src/main/java/teamdraco/bettas/Bettas.java +++ b/src/main/java/teamdraco/bettas/Bettas.java @@ -1,5 +1,7 @@ package teamdraco.bettas; +import java.util.List; + import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.SpawnPlacements; @@ -12,6 +14,7 @@ import net.minecraft.world.level.storage.loot.entries.LootTableReference; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; import net.minecraftforge.event.LootTableLoadEvent; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.event.world.BiomeLoadingEvent; @@ -24,11 +27,11 @@ import net.minecraftforge.fml.util.ObfuscationReflectionHelper; import teamdraco.bettas.entity.BettaFishEntity; import teamdraco.bettas.init.BettasBlocks; +import teamdraco.bettas.init.BettasConfiguredFeatures; import teamdraco.bettas.init.BettasEntities; import teamdraco.bettas.init.BettasFeatures; import teamdraco.bettas.init.BettasItems; - -import java.util.List; +import teamdraco.bettas.init.BettasPlacedFeatures; @Mod(Bettas.MOD_ID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) @@ -43,6 +46,8 @@ public Bettas() { BettasBlocks.BLOCKS.register(bus); BettasEntities.ENTITIES.register(bus); BettasFeatures.FEATURES.register(bus); + BettasConfiguredFeatures.CONFIGURED_FEATURES.register(bus); + BettasPlacedFeatures.PLACED_FEATURES.register(bus); bus.addListener(this::registerEntityAttributes); @@ -56,6 +61,14 @@ public static void registerBiomes(BiomeLoadingEvent event) { } } + + @SubscribeEvent + public static void onBiomeLoad(BiomeLoadingEvent event) { + BiomeGenerationSettingsBuilder builder = event.getGeneration(); + if (event.getCategory() == Biome.BiomeCategory.SWAMP) { + builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, BettasPlacedFeatures.PLACED_MOSS_BALLS.getHolder().orElseThrow()); + } + } private void registerCommon(FMLCommonSetupEvent event) { SpawnPlacements.register(BettasEntities.BETTA_FISH.get(), SpawnPlacements.Type.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkBettaFishSpawnRules); @@ -68,7 +81,8 @@ private void registerEntityAttributes(EntityAttributeCreationEvent event) { //Thanks to BlueDuck for the help with the loot table code :) @Mod.EventBusSubscriber(modid = Bettas.MOD_ID) public static class LootEvents { - @SubscribeEvent + @SuppressWarnings("unlikely-arg-type") + @SubscribeEvent public static void onLootLoad(LootTableLoadEvent event) throws IllegalAccessException { ResourceLocation name = event.getName(); if (name.equals(LootContextParamSets.FISHING)) { @@ -82,7 +96,8 @@ private static LootPoolEntryContainer getInjectEntry(ResourceLocation location, return LootTableReference.lootTableReference(location).setWeight(weight).setQuality(quality).build(); } - private static void addEntry(LootPool pool, LootPoolEntryContainer entry) throws IllegalAccessException { + @SuppressWarnings("unchecked") + private static void addEntry(LootPool pool, LootPoolEntryContainer entry) throws IllegalAccessException { List lootEntries = (List) ObfuscationReflectionHelper.findField(LootPool.class, "entries").get(pool); if (lootEntries.stream().anyMatch(e -> e == entry)) { throw new RuntimeException("Attempted to add a duplicate entry to pool: " + entry); diff --git a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java index f36dd1d..23dfa99 100644 --- a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java +++ b/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java @@ -66,14 +66,15 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.m_183324_().m_183588_(currentPos, Fluids.WATER); + worldIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); } } - public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + @SuppressWarnings("deprecation") + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(LEAVES) < 3 || super.canBeReplaced(state, useContext); } @@ -89,7 +90,8 @@ public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, } } - public FluidState getFluidState(BlockState state) { + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } diff --git a/src/main/java/teamdraco/bettas/block/MossBallBlock.java b/src/main/java/teamdraco/bettas/block/MossBallBlock.java index 9f1b872..75609b6 100644 --- a/src/main/java/teamdraco/bettas/block/MossBallBlock.java +++ b/src/main/java/teamdraco/bettas/block/MossBallBlock.java @@ -67,14 +67,15 @@ public BlockState updateShape(BlockState stateIn, Direction facing, BlockState f return Blocks.AIR.defaultBlockState(); } else { if (stateIn.getValue(WATERLOGGED)) { - worldIn.m_183324_().m_183588_(currentPos, Fluids.WATER); + worldIn.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(worldIn)); } return super.updateShape(stateIn, facing, facingState, worldIn, currentPos, facingPos); } } - public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { + @SuppressWarnings("deprecation") + public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) { return useContext.getItemInHand().getItem() == this.asItem() && state.getValue(BALLS) < 4 || super.canBeReplaced(state, useContext); } @@ -92,7 +93,8 @@ public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, } } - public FluidState getFluidState(BlockState state) { + @SuppressWarnings("deprecation") + public FluidState getFluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); } @@ -108,7 +110,8 @@ public boolean isBonemealSuccess(Level worldIn, Random rand, BlockPos pos, Block return true; } - public void performBonemeal(ServerLevel worldIn, Random rand, BlockPos pos, BlockState state) { + @SuppressWarnings("unused") + public void performBonemeal(ServerLevel worldIn, Random rand, BlockPos pos, BlockState state) { if (!isInBadEnvironment(state) && worldIn.getBlockState(pos.below()).getBlock() == BettasBlocks.MOSS_BALL_BLOCK.get()) { int i = 5; int j = 1; diff --git a/src/main/java/teamdraco/bettas/client/ClientEvents.java b/src/main/java/teamdraco/bettas/client/ClientEvents.java index fb7b8bb..3a415c3 100644 --- a/src/main/java/teamdraco/bettas/client/ClientEvents.java +++ b/src/main/java/teamdraco/bettas/client/ClientEvents.java @@ -1,22 +1,19 @@ package teamdraco.bettas.client; -import net.minecraft.client.color.item.ItemColor; -import net.minecraft.client.color.item.ItemColors; import net.minecraft.client.renderer.ItemBlockRenderTypes; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.entity.EntityRenderers; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import teamdraco.bettas.Bettas; import teamdraco.bettas.client.model.BettaFishModel; import teamdraco.bettas.client.renderer.BettaFishRenderer; import teamdraco.bettas.init.BettasBlocks; import teamdraco.bettas.init.BettasEntities; -import net.minecraft.client.renderer.RenderType; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.ColorHandlerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; @OnlyIn(Dist.CLIENT) @Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) diff --git a/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java b/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java index 57b2c5f..b52b7dc 100644 --- a/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java +++ b/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java @@ -38,7 +38,8 @@ public BettaFishModel(ModelPart root) { } //Layer Definition - public static LayerDefinition createLayerDefinition() { + @SuppressWarnings("unused") + public static LayerDefinition createLayerDefinition() { MeshDefinition meshdefinition = new MeshDefinition(); PartDefinition root = meshdefinition.getRoot(); PartDefinition body = root.addOrReplaceChild("body", CubeListBuilder.create().texOffs(0, 0).addBox(-1.0F, -1.5F, -3.5F, 2.0F, 3.0F, 7.0F, false), PartPose.offsetAndRotation(0.0F, 22.5F, -0.5F, 0.0F, 0.0F, 0.0F)); diff --git a/src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java b/src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java new file mode 100644 index 0000000..057de50 --- /dev/null +++ b/src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java @@ -0,0 +1,16 @@ +package teamdraco.bettas.init; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import teamdraco.bettas.Bettas; + +public class BettasConfiguredFeatures { + + public static final DeferredRegister> CONFIGURED_FEATURES = DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Bettas.MOD_ID); + + public static final RegistryObject> CONFIGURED_MOSS_BALLS = CONFIGURED_FEATURES.register("moss_balls", () -> new ConfiguredFeature<>(BettasFeatures.MOSS_BALL.get(), new CountConfiguration(4))); + +} diff --git a/src/main/java/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/teamdraco/bettas/init/BettasFeatures.java index acb48cd..bb59e45 100644 --- a/src/main/java/teamdraco/bettas/init/BettasFeatures.java +++ b/src/main/java/teamdraco/bettas/init/BettasFeatures.java @@ -2,14 +2,15 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; import teamdraco.bettas.Bettas; import teamdraco.bettas.feature.MossBallFeature; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; public class BettasFeatures { - public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); + public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); + + public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(CountConfiguration.CODEC)); - public static final RegistryObject> MOSS_BALL = FEATURES.register("moss_ball", () -> new MossBallFeature(CountConfiguration.CODEC)); } \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java b/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java new file mode 100644 index 0000000..1bd2633 --- /dev/null +++ b/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java @@ -0,0 +1,16 @@ +package teamdraco.bettas.init; + +import net.minecraft.core.Registry; +import net.minecraft.data.worldgen.placement.VegetationPlacements; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import teamdraco.bettas.Bettas; + +public class BettasPlacedFeatures { + + public static final DeferredRegister PLACED_FEATURES = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Bettas.MOD_ID); + + public static final RegistryObject PLACED_MOSS_BALLS = PLACED_FEATURES.register("placed_moss_balls", () -> new PlacedFeature(BettasConfiguredFeatures.CONFIGURED_MOSS_BALLS.getHolder().orElseThrow(), VegetationPlacements.worldSurfaceSquaredWithCount(4))); + +} diff --git a/src/main/java/teamdraco/bettas/item/BettasBucketItem.java b/src/main/java/teamdraco/bettas/item/BettasBucketItem.java index c042d03..357857b 100644 --- a/src/main/java/teamdraco/bettas/item/BettasBucketItem.java +++ b/src/main/java/teamdraco/bettas/item/BettasBucketItem.java @@ -37,7 +37,8 @@ public class BettasBucketItem extends BucketItem { private final boolean hasTooltip; private final Supplier fluid; - private final Item item; + @SuppressWarnings("unused") + private final Item item; public BettasBucketItem(Supplier> entityType, Supplier fluid, Item item, boolean hasTooltip, Properties builder) { super(fluid, builder); @@ -47,7 +48,8 @@ public BettasBucketItem(Supplier> entityType, Supplier use(Level worldIn, Player playerIn, InteractionHand handIn) { ItemStack itemstack = playerIn.getItemInHand(handIn); BlockHitResult raytraceresult = getPlayerPOVHitResult(worldIn, playerIn, ClipContext.Fluid.NONE); From 997b842147d0f855729e04f47967990637119537 Mon Sep 17 00:00:00 2001 From: superlord9362 <33046398+superlord9362@users.noreply.github.com> Date: Fri, 22 Jul 2022 19:29:36 -0700 Subject: [PATCH 07/29] Tweaked Moss Ball Generation Tweaked Moss Ball generation --- src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java | 2 +- src/main/resources/META-INF/mods.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java b/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java index 1bd2633..3908c32 100644 --- a/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java +++ b/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java @@ -11,6 +11,6 @@ public class BettasPlacedFeatures { public static final DeferredRegister PLACED_FEATURES = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Bettas.MOD_ID); - public static final RegistryObject PLACED_MOSS_BALLS = PLACED_FEATURES.register("placed_moss_balls", () -> new PlacedFeature(BettasConfiguredFeatures.CONFIGURED_MOSS_BALLS.getHolder().orElseThrow(), VegetationPlacements.worldSurfaceSquaredWithCount(4))); + public static final RegistryObject PLACED_MOSS_BALLS = PLACED_FEATURES.register("placed_moss_balls", () -> new PlacedFeature(BettasConfiguredFeatures.CONFIGURED_MOSS_BALLS.getHolder().orElseThrow(), VegetationPlacements.worldSurfaceSquaredWithCount(2))); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 7adb930..693d43a 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -3,8 +3,8 @@ loaderVersion="[40,)" #mandatory This is typically bumped every Minecraft versio license="All rights reserved" [[mods]] #mandatory modId="bettas" #mandatory -version="${file.jarVersion}" #mandatory +version="1.0.0" #mandatory displayName="Bettas" #mandatory credits="Tazz, Ninni" #optional -authors="Coda" #optional +authors="Coda, superlord9362" #optional description='''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' From b16d632f46ca239fd2e0991751420ac8d0c2f359 Mon Sep 17 00:00:00 2001 From: andantet Date: Tue, 27 Sep 2022 17:29:23 +0100 Subject: [PATCH 08/29] build workflow --- .github/workflows/build.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..b3e26b2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: build +on: [ push, pull_request ] +jobs: + build: + strategy: + matrix: + java: [ 17-jdk ] + runs-on: ubuntu-20.04 + container: + image: eclipse-temurin:${{ matrix.java }} + options: --user root + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Publish to Maven local + run: ./gradlew check build publishToMavenLocal --stacktrace --parallel --warning-mode=fail + + - name: Upload artifacts (Artifacts, for root project) + uses: actions/upload-artifact@v2 + with: + name: Artifacts + path: build/libs/ + + - name: Upload artifacts (Maven Local) + uses: actions/upload-artifact@v2 + with: + name: Maven Local + path: /root/.m2/repository From 062829b0a063e0b6835c6b690ed82a9e0e80b30f Mon Sep 17 00:00:00 2001 From: andante Date: Tue, 27 Sep 2022 17:39:14 +0100 Subject: [PATCH 09/29] remove maven publishing from workflow --- .github/workflows/build.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b3e26b2..078a65e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,17 +20,8 @@ jobs: - name: Make Gradle wrapper executable run: chmod +x ./gradlew - - name: Publish to Maven local - run: ./gradlew check build publishToMavenLocal --stacktrace --parallel --warning-mode=fail - - name: Upload artifacts (Artifacts, for root project) uses: actions/upload-artifact@v2 with: name: Artifacts path: build/libs/ - - - name: Upload artifacts (Maven Local) - uses: actions/upload-artifact@v2 - with: - name: Maven Local - path: /root/.m2/repository From c79024d34cc96ee5dac243113610529e08919b42 Mon Sep 17 00:00:00 2001 From: andante Date: Tue, 27 Sep 2022 17:46:01 +0100 Subject: [PATCH 10/29] for god's sake --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 078a65e..f4b9d0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,10 @@ jobs: - name: Make Gradle wrapper executable run: chmod +x ./gradlew - - name: Upload artifacts (Artifacts, for root project) + - name: Build + run: ./gradlew build --stacktrace --parallel + + - name: Upload artifacts uses: actions/upload-artifact@v2 with: name: Artifacts From 98c44d99331ce4699a15cd7c364bb24b40818bde Mon Sep 17 00:00:00 2001 From: baguchan Date: Thu, 29 Sep 2022 20:13:14 +0900 Subject: [PATCH 11/29] 1.19 port and group name changed --- build.gradle | 8 ++-- .../teamdraco/bettas/client/ClientEvents.java | 29 ------------ .../bettas/Bettas.java | 45 +++++-------------- .../bettas/biome/BettaBiomeModifier.java | 34 ++++++++++++++ .../bettas/block/DriedLeavesBlock.java | 2 +- .../bettas/block/MossBallBlock.java | 20 +++++---- .../bettas/client/ClientEvents.java | 27 +++++++++++ .../bettas/client/model/BettaFishModel.java | 2 +- .../client/renderer/BettaFishRenderer.java | 12 ++--- .../bettas/entity/BettaFishEntity.java | 12 ++--- .../bettas/feature/MossBallFeature.java | 9 ++-- .../bettas/init/BettaBiomeModifiers.java | 16 +++++++ .../bettas/init/BettasBlocks.java | 10 ++--- .../bettas/init/BettasConfiguredFeatures.java | 4 +- .../bettas/init/BettasEntities.java | 10 ++--- .../bettas/init/BettasFeatures.java | 6 +-- .../bettas/init/BettasItems.java | 13 +++--- .../bettas/init/BettasPlacedFeatures.java | 4 +- .../bettas/item/BettasBucketItem.java | 5 +-- src/main/resources/META-INF/mods.toml | 18 ++++---- .../block/heavily_piled_dried_leaves.json | 38 +++++++++++----- .../block/loosely_piled_dried_leaves.json | 38 +++++++++++----- .../biome_modifier/betta_biome_spawn.json | 3 ++ 23 files changed, 218 insertions(+), 147 deletions(-) delete mode 100644 src/main/java/teamdraco/bettas/client/ClientEvents.java rename src/main/java/{teamdraco => teamfusion}/bettas/Bettas.java (70%) create mode 100644 src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java rename src/main/java/{teamdraco => teamfusion}/bettas/block/DriedLeavesBlock.java (99%) rename src/main/java/{teamdraco => teamfusion}/bettas/block/MossBallBlock.java (89%) create mode 100644 src/main/java/teamfusion/bettas/client/ClientEvents.java rename src/main/java/{teamdraco => teamfusion}/bettas/client/model/BettaFishModel.java (99%) rename src/main/java/{teamdraco => teamfusion}/bettas/client/renderer/BettaFishRenderer.java (88%) rename src/main/java/{teamdraco => teamfusion}/bettas/entity/BettaFishEntity.java (97%) rename src/main/java/{teamdraco => teamfusion}/bettas/feature/MossBallFeature.java (91%) create mode 100644 src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasBlocks.java (89%) rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasConfiguredFeatures.java (91%) rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasEntities.java (81%) rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasFeatures.java (84%) rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasItems.java (87%) rename src/main/java/{teamdraco => teamfusion}/bettas/init/BettasPlacedFeatures.java (91%) rename src/main/java/{teamdraco => teamfusion}/bettas/item/BettasBucketItem.java (94%) create mode 100644 src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json diff --git a/build.gradle b/build.gradle index fb21944..c008ada 100644 --- a/build.gradle +++ b/build.gradle @@ -17,8 +17,8 @@ apply plugin: 'net.minecraftforge.gradle' version = '1.0' -group = 'com.yourname.modid' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'modid' +group = 'teamfusion.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'bettas' // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) @@ -38,7 +38,7 @@ minecraft { // // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'official', version: '1.18.2' + mappings channel: 'official', version: '1.19.2' // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. @@ -151,7 +151,7 @@ dependencies { // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.18.2-40.1.68' + minecraft 'net.minecraftforge:forge:1.19.2-43.1.23' // Real mod deobf dependency examples - these get remapped to your current mappings // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency diff --git a/src/main/java/teamdraco/bettas/client/ClientEvents.java b/src/main/java/teamdraco/bettas/client/ClientEvents.java deleted file mode 100644 index 3a415c3..0000000 --- a/src/main/java/teamdraco/bettas/client/ClientEvents.java +++ /dev/null @@ -1,29 +0,0 @@ -package teamdraco.bettas.client; - -import net.minecraft.client.renderer.ItemBlockRenderTypes; -import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.entity.EntityRenderers; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.ForgeHooksClient; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.client.model.BettaFishModel; -import teamdraco.bettas.client.renderer.BettaFishRenderer; -import teamdraco.bettas.init.BettasBlocks; -import teamdraco.bettas.init.BettasEntities; - -@OnlyIn(Dist.CLIENT) -@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) -public class ClientEvents { - - @SubscribeEvent - public static void clientSetup(FMLClientSetupEvent event) { - EntityRenderers.register(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); - ItemBlockRenderTypes.setRenderLayer(BettasBlocks.DRIED_LEAVES.get(), RenderType.cutout()); - - ForgeHooksClient.registerLayerDefinition(BettaFishRenderer.MODEL_LAYER, BettaFishModel::createLayerDefinition); - } -} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/Bettas.java b/src/main/java/teamfusion/bettas/Bettas.java similarity index 70% rename from src/main/java/teamdraco/bettas/Bettas.java rename to src/main/java/teamfusion/bettas/Bettas.java index 9c84ae7..ba192d6 100644 --- a/src/main/java/teamdraco/bettas/Bettas.java +++ b/src/main/java/teamfusion/bettas/Bettas.java @@ -1,37 +1,31 @@ -package teamdraco.bettas; - -import java.util.List; +package teamfusion.bettas; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.MobSpawnSettings; -import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; import net.minecraft.world.level.storage.loot.entries.LootTableReference; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; import net.minecraftforge.event.LootTableLoadEvent; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; -import net.minecraftforge.event.world.BiomeLoadingEvent; -import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.util.ObfuscationReflectionHelper; -import teamdraco.bettas.entity.BettaFishEntity; -import teamdraco.bettas.init.BettasBlocks; -import teamdraco.bettas.init.BettasConfiguredFeatures; -import teamdraco.bettas.init.BettasEntities; -import teamdraco.bettas.init.BettasFeatures; -import teamdraco.bettas.init.BettasItems; -import teamdraco.bettas.init.BettasPlacedFeatures; +import teamfusion.bettas.entity.BettaFishEntity; +import teamfusion.bettas.init.BettaBiomeModifiers; +import teamfusion.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasConfiguredFeatures; +import teamfusion.bettas.init.BettasEntities; +import teamfusion.bettas.init.BettasFeatures; +import teamfusion.bettas.init.BettasItems; +import teamfusion.bettas.init.BettasPlacedFeatures; + +import java.util.List; @Mod(Bettas.MOD_ID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bettas.MOD_ID) @@ -42,6 +36,7 @@ public Bettas() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener(this::registerCommon); + BettaBiomeModifiers.BIOME_MODIFIER_SERIALIZERS.register(bus); BettasItems.ITEMS.register(bus); BettasBlocks.BLOCKS.register(bus); BettasEntities.ENTITIES.register(bus); @@ -54,22 +49,6 @@ public Bettas() { MinecraftForge.EVENT_BUS.register(this); } - @SubscribeEvent(priority = EventPriority.LOWEST) - public static void registerBiomes(BiomeLoadingEvent event) { - if (event.getCategory() == Biome.BiomeCategory.SWAMP) { - event.getSpawns().getSpawner(MobCategory.WATER_CREATURE).add(new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); - - } - } - - @SubscribeEvent - public static void onBiomeLoad(BiomeLoadingEvent event) { - BiomeGenerationSettingsBuilder builder = event.getGeneration(); - if (event.getCategory() == Biome.BiomeCategory.SWAMP) { - builder.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, BettasPlacedFeatures.PLACED_MOSS_BALLS.getHolder().orElseThrow()); - } - } - private void registerCommon(FMLCommonSetupEvent event) { SpawnPlacements.register(BettasEntities.BETTA_FISH.get(), SpawnPlacements.Type.IN_WATER, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, BettaFishEntity::checkBettaFishSpawnRules); } diff --git a/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java new file mode 100644 index 0000000..59e720e --- /dev/null +++ b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java @@ -0,0 +1,34 @@ +package teamfusion.bettas.biome; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.MobSpawnSettings; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraftforge.common.Tags; +import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.common.world.ModifiableBiomeInfo; +import teamfusion.bettas.init.BettaBiomeModifiers; +import teamfusion.bettas.init.BettasEntities; +import teamfusion.bettas.init.BettasPlacedFeatures; + +public class BettaBiomeModifier implements BiomeModifier { + public static final BettaBiomeModifier INSTANCE = new BettaBiomeModifier(); + + @Override + public void modify(Holder biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { + if (phase == Phase.ADD) { + if (biome.is(BiomeTags.IS_OVERWORLD) && biome.is(Tags.Biomes.IS_SWAMP)) { + builder.getMobSpawnSettings().addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); + builder.getGenerationSettings().addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, BettasPlacedFeatures.PLACED_MOSS_BALLS.getHolder().get()); + } + } + } + + @Override + public Codec codec() { + return BettaBiomeModifiers.BETTA_BIOME_MODIFIER_TYPE.get(); + } +} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java b/src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java similarity index 99% rename from src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java rename to src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java index 23dfa99..9ae0228 100644 --- a/src/main/java/teamdraco/bettas/block/DriedLeavesBlock.java +++ b/src/main/java/teamfusion/bettas/block/DriedLeavesBlock.java @@ -1,4 +1,4 @@ -package teamdraco.bettas.block; +package teamfusion.bettas.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; diff --git a/src/main/java/teamdraco/bettas/block/MossBallBlock.java b/src/main/java/teamfusion/bettas/block/MossBallBlock.java similarity index 89% rename from src/main/java/teamdraco/bettas/block/MossBallBlock.java rename to src/main/java/teamfusion/bettas/block/MossBallBlock.java index 75609b6..86282fa 100644 --- a/src/main/java/teamdraco/bettas/block/MossBallBlock.java +++ b/src/main/java/teamfusion/bettas/block/MossBallBlock.java @@ -1,14 +1,19 @@ -package teamdraco.bettas.block; +package teamfusion.bettas.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.BushBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; @@ -19,10 +24,9 @@ import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -import teamdraco.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasBlocks; import javax.annotation.Nullable; -import java.util.Random; public class MossBallBlock extends BushBlock implements SimpleWaterloggedBlock, BonemealableBlock { public static final IntegerProperty BALLS = BlockStateProperties.PICKLES; @@ -106,12 +110,12 @@ public boolean isValidBonemealTarget(BlockGetter worldIn, BlockPos pos, BlockSta return true; } - public boolean isBonemealSuccess(Level worldIn, Random rand, BlockPos pos, BlockState state) { + public boolean isBonemealSuccess(Level worldIn, RandomSource rand, BlockPos pos, BlockState state) { return true; } @SuppressWarnings("unused") - public void performBonemeal(ServerLevel worldIn, Random rand, BlockPos pos, BlockState state) { + public void performBonemeal(ServerLevel worldIn, RandomSource rand, BlockPos pos, BlockState state) { if (!isInBadEnvironment(state) && worldIn.getBlockState(pos.below()).getBlock() == BettasBlocks.MOSS_BALL_BLOCK.get()) { int i = 5; int j = 1; @@ -120,8 +124,8 @@ public void performBonemeal(ServerLevel worldIn, Random rand, BlockPos pos, Bloc int i1 = pos.getX() - 2; int j1 = 0; - for(int k1 = 0; k1 < 5; ++k1) { - for(int l1 = 0; l1 < j; ++l1) { + for (int k1 = 0; k1 < 5; ++k1) { + for (int l1 = 0; l1 < j; ++l1) { int i2 = 2 + pos.getY() - 1; for(int j2 = i2 - 2; j2 < i2; ++j2) { diff --git a/src/main/java/teamfusion/bettas/client/ClientEvents.java b/src/main/java/teamfusion/bettas/client/ClientEvents.java new file mode 100644 index 0000000..a34b31a --- /dev/null +++ b/src/main/java/teamfusion/bettas/client/ClientEvents.java @@ -0,0 +1,27 @@ +package teamfusion.bettas.client; + +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.EntityRenderersEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.client.model.BettaFishModel; +import teamfusion.bettas.client.renderer.BettaFishRenderer; +import teamfusion.bettas.init.BettasEntities; + +@OnlyIn(Dist.CLIENT) +@Mod.EventBusSubscriber(modid = Bettas.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +public class ClientEvents { + + @SubscribeEvent + public static void registerLayerDefinition(EntityRenderersEvent.RegisterLayerDefinitions event) { + event.registerLayerDefinition(BettaFishRenderer.MODEL_LAYER, BettaFishModel::createLayerDefinition); + } + + + @SubscribeEvent + public static void registerEntityRenders(EntityRenderersEvent.RegisterRenderers event) { + event.registerEntityRenderer(BettasEntities.BETTA_FISH.get(), BettaFishRenderer::new); + } +} \ No newline at end of file diff --git a/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java b/src/main/java/teamfusion/bettas/client/model/BettaFishModel.java similarity index 99% rename from src/main/java/teamdraco/bettas/client/model/BettaFishModel.java rename to src/main/java/teamfusion/bettas/client/model/BettaFishModel.java index b52b7dc..1359a00 100644 --- a/src/main/java/teamdraco/bettas/client/model/BettaFishModel.java +++ b/src/main/java/teamfusion/bettas/client/model/BettaFishModel.java @@ -1,4 +1,4 @@ -package teamdraco.bettas.client.model; +package teamfusion.bettas.client.model; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; diff --git a/src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java similarity index 88% rename from src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java rename to src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java index c8c7185..16e67e7 100644 --- a/src/main/java/teamdraco/bettas/client/renderer/BettaFishRenderer.java +++ b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java @@ -1,18 +1,18 @@ -package teamdraco.bettas.client.renderer; +package teamfusion.bettas.client.renderer; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.MobRenderer; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.client.model.BettaFishModel; -import teamdraco.bettas.entity.BettaFishEntity; -import net.minecraft.client.Minecraft; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.client.model.BettaFishModel; +import teamfusion.bettas.entity.BettaFishEntity; @OnlyIn(Dist.CLIENT) public class BettaFishRenderer extends MobRenderer> { @@ -29,7 +29,7 @@ public ResourceLocation getTextureLocation(BettaFishEntity entity) { int variant = entity.getVariant(); if (TEXTURES[variant] == null) { ResourceLocation loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_" + variant + ".png"); - if (!Minecraft.getInstance().getResourceManager().hasResource(loc)) { + if (!Minecraft.getInstance().getResourceManager().getResource(loc).isPresent()) { System.out.println("Found Unknown variant " + variant + ", using default"); loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_0.png"); } diff --git a/src/main/java/teamdraco/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java similarity index 97% rename from src/main/java/teamdraco/bettas/entity/BettaFishEntity.java rename to src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 48689b8..b7df616 100644 --- a/src/main/java/teamdraco/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -1,4 +1,4 @@ -package teamdraco.bettas.entity; +package teamfusion.bettas.entity; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -9,6 +9,8 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; +import net.minecraft.world.DifficultyInstance; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; @@ -34,12 +36,10 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import teamdraco.bettas.init.BettasBlocks; -import teamdraco.bettas.init.BettasItems; -import net.minecraft.world.DifficultyInstance; +import teamfusion.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasItems; import javax.annotation.Nullable; -import java.util.Random; public class BettaFishEntity extends AbstractFish implements Bucketable { public static final int MAX_VARIANTS = 120; @@ -75,7 +75,7 @@ public static AttributeSupplier.Builder createAttributes() { return Monster.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); } - public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, Random randomIn) { + public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, RandomSource randomIn) { return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; } diff --git a/src/main/java/teamdraco/bettas/feature/MossBallFeature.java b/src/main/java/teamfusion/bettas/feature/MossBallFeature.java similarity index 91% rename from src/main/java/teamdraco/bettas/feature/MossBallFeature.java rename to src/main/java/teamfusion/bettas/feature/MossBallFeature.java index 385fc28..bd5dcba 100644 --- a/src/main/java/teamdraco/bettas/feature/MossBallFeature.java +++ b/src/main/java/teamfusion/bettas/feature/MossBallFeature.java @@ -1,7 +1,8 @@ -package teamdraco.bettas.feature; +package teamfusion.bettas.feature; import com.mojang.serialization.Codec; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SeaPickleBlock; @@ -10,9 +11,7 @@ import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; -import teamdraco.bettas.init.BettasBlocks; - -import java.util.Random; +import teamfusion.bettas.init.BettasBlocks; public class MossBallFeature extends Feature { @@ -22,7 +21,7 @@ public MossBallFeature(Codec p_i231987_1_) { public boolean place(FeaturePlaceContext context) { WorldGenLevel reader = context.level(); - Random rand = context.random(); + RandomSource rand = context.random(); CountConfiguration config = context.config(); BlockPos pos = context.origin(); diff --git a/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java b/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java new file mode 100644 index 0000000..360d4dd --- /dev/null +++ b/src/main/java/teamfusion/bettas/init/BettaBiomeModifiers.java @@ -0,0 +1,16 @@ +package teamfusion.bettas.init; + +import com.mojang.serialization.Codec; +import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.biome.BettaBiomeModifier; + +public class BettaBiomeModifiers { + public static final DeferredRegister> BIOME_MODIFIER_SERIALIZERS = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIER_SERIALIZERS, Bettas.MOD_ID); + + public static final RegistryObject> BETTA_BIOME_MODIFIER_TYPE = BIOME_MODIFIER_SERIALIZERS.register("betta_biome_modifier", () -> Codec.unit(BettaBiomeModifier.INSTANCE)); + +} diff --git a/src/main/java/teamdraco/bettas/init/BettasBlocks.java b/src/main/java/teamfusion/bettas/init/BettasBlocks.java similarity index 89% rename from src/main/java/teamdraco/bettas/init/BettasBlocks.java rename to src/main/java/teamfusion/bettas/init/BettasBlocks.java index f0e05e9..560062e 100644 --- a/src/main/java/teamdraco/bettas/init/BettasBlocks.java +++ b/src/main/java/teamfusion/bettas/init/BettasBlocks.java @@ -1,16 +1,16 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SoundType; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.MaterialColor; -import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.block.DriedLeavesBlock; -import teamdraco.bettas.block.MossBallBlock; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.block.DriedLeavesBlock; +import teamfusion.bettas.block.MossBallBlock; public class BettasBlocks { public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Bettas.MOD_ID); diff --git a/src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java b/src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java similarity index 91% rename from src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java rename to src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java index 057de50..f419fe9 100644 --- a/src/main/java/teamdraco/bettas/init/BettasConfiguredFeatures.java +++ b/src/main/java/teamfusion/bettas/init/BettasConfiguredFeatures.java @@ -1,11 +1,11 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.core.Registry; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; +import teamfusion.bettas.Bettas; public class BettasConfiguredFeatures { diff --git a/src/main/java/teamdraco/bettas/init/BettasEntities.java b/src/main/java/teamfusion/bettas/init/BettasEntities.java similarity index 81% rename from src/main/java/teamdraco/bettas/init/BettasEntities.java rename to src/main/java/teamfusion/bettas/init/BettasEntities.java index 09f14dd..6751f05 100644 --- a/src/main/java/teamdraco/bettas/init/BettasEntities.java +++ b/src/main/java/teamfusion/bettas/init/BettasEntities.java @@ -1,16 +1,16 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.entity.BettaFishEntity; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.entity.BettaFishEntity; public class BettasEntities { - public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITIES, Bettas.MOD_ID); + public static final DeferredRegister> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, Bettas.MOD_ID); public static final RegistryObject> BETTA_FISH = create("betta_fish", EntityType.Builder.of(BettaFishEntity::new, MobCategory.WATER_AMBIENT).sized(0.3f, 0.3f)); diff --git a/src/main/java/teamdraco/bettas/init/BettasFeatures.java b/src/main/java/teamfusion/bettas/init/BettasFeatures.java similarity index 84% rename from src/main/java/teamdraco/bettas/init/BettasFeatures.java rename to src/main/java/teamfusion/bettas/init/BettasFeatures.java index bb59e45..5ff93fc 100644 --- a/src/main/java/teamdraco/bettas/init/BettasFeatures.java +++ b/src/main/java/teamfusion/bettas/init/BettasFeatures.java @@ -1,12 +1,12 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraft.world.level.levelgen.feature.configurations.CountConfiguration; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.feature.MossBallFeature; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.feature.MossBallFeature; public class BettasFeatures { public static final DeferredRegister> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, Bettas.MOD_ID); diff --git a/src/main/java/teamdraco/bettas/init/BettasItems.java b/src/main/java/teamfusion/bettas/init/BettasItems.java similarity index 87% rename from src/main/java/teamdraco/bettas/init/BettasItems.java rename to src/main/java/teamfusion/bettas/init/BettasItems.java index 1f8f5f9..8af4872 100644 --- a/src/main/java/teamdraco/bettas/init/BettasItems.java +++ b/src/main/java/teamfusion/bettas/init/BettasItems.java @@ -1,14 +1,17 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.*; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; import net.minecraft.world.level.material.Fluids; import net.minecraftforge.common.ForgeSpawnEggItem; -import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; -import teamdraco.bettas.item.BettasBucketItem; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import teamfusion.bettas.Bettas; +import teamfusion.bettas.item.BettasBucketItem; public class BettasItems { public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Bettas.MOD_ID); diff --git a/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java b/src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java similarity index 91% rename from src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java rename to src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java index 3908c32..4d59b64 100644 --- a/src/main/java/teamdraco/bettas/init/BettasPlacedFeatures.java +++ b/src/main/java/teamfusion/bettas/init/BettasPlacedFeatures.java @@ -1,11 +1,11 @@ -package teamdraco.bettas.init; +package teamfusion.bettas.init; import net.minecraft.core.Registry; import net.minecraft.data.worldgen.placement.VegetationPlacements; import net.minecraft.world.level.levelgen.placement.PlacedFeature; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.RegistryObject; -import teamdraco.bettas.Bettas; +import teamfusion.bettas.Bettas; public class BettasPlacedFeatures { diff --git a/src/main/java/teamdraco/bettas/item/BettasBucketItem.java b/src/main/java/teamfusion/bettas/item/BettasBucketItem.java similarity index 94% rename from src/main/java/teamdraco/bettas/item/BettasBucketItem.java rename to src/main/java/teamfusion/bettas/item/BettasBucketItem.java index 357857b..fd1d4db 100644 --- a/src/main/java/teamdraco/bettas/item/BettasBucketItem.java +++ b/src/main/java/teamfusion/bettas/item/BettasBucketItem.java @@ -1,11 +1,10 @@ -package teamdraco.bettas.item; +package teamfusion.bettas.item; import net.minecraft.ChatFormatting; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stats; @@ -85,7 +84,7 @@ public InteractionResultHolder use(Level worldIn, Player playerIn, In public void appendHoverText(ItemStack stack, @Nullable Level world, List tooltip, TooltipFlag flag) { super.appendHoverText(stack, world, tooltip, flag); if (hasTooltip && stack.hasTag()) { - tooltip.add(new TranslatableComponent(getEntityType().getDescriptionId() + "." + stack.getTag().getInt("Variant")).withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.ITALIC)); + tooltip.add(Component.translatable(getEntityType().getDescriptionId() + "." + stack.getTag().getInt("Variant")).withStyle(ChatFormatting.GRAY).withStyle(ChatFormatting.ITALIC)); } } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 693d43a..0752e36 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -1,10 +1,10 @@ -modLoader="javafml" #mandatory -loaderVersion="[40,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. -license="All rights reserved" +modLoader = "javafml" #mandatory +loaderVersion = "[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +license = "All rights reserved" [[mods]] #mandatory -modId="bettas" #mandatory -version="1.0.0" #mandatory -displayName="Bettas" #mandatory -credits="Tazz, Ninni" #optional -authors="Coda, superlord9362" #optional -description='''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' +modId = "bettas" #mandatory +version = "1.0.0" #mandatory +displayName = "Bettas" #mandatory +credits = "Tazz, Ninni" #optional +authors = "Coda, superlord9362, bagu_chan, Team Fusion" #optional +description = '''A small mod containing a new fish: the betta! Bettas can be bucketed just like normal fish and will fight and kill eachother.''' diff --git a/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json index 0a22525..1f2f5f1 100644 --- a/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/heavily_piled_dried_leaves.json @@ -1,14 +1,32 @@ { - "textures": { - "dried": "bettas:block/heavily_piled_dried_leaves", - "particle": "bettas:block/heavily_piled_dried_leaves" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 5, 16], - "faces": { - "north": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "north" }, + "render_type": "cutout", + "textures": { + "dried": "bettas:block/heavily_piled_dried_leaves", + "particle": "bettas:block/heavily_piled_dried_leaves" + }, + "elements": [ + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 5, + 16 + ], + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 5 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 5], "texture": "#dried", "cullface": "west"}, diff --git a/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json index 9ec3dfb..fbeb6ae 100644 --- a/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/loosely_piled_dried_leaves.json @@ -1,14 +1,32 @@ { - "textures": { - "particle": "bettas:block/loosely_piled_dried_leaves", - "dried": "bettas:block/loosely_piled_dried_leaves" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 2, 16], - "faces": { - "north": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "north" }, + "render_type": "cutout", + "textures": { + "particle": "bettas:block/loosely_piled_dried_leaves", + "dried": "bettas:block/loosely_piled_dried_leaves" + }, + "elements": [ + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 2, + 16 + ], + "faces": { + "north": { + "uv": [ + 0, + 0, + 16, + 2 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 2], "texture": "#dried", "cullface": "west"}, diff --git a/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json b/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json new file mode 100644 index 0000000..b5b61cf --- /dev/null +++ b/src/main/resources/data/bettas/forge/biome_modifier/betta_biome_spawn.json @@ -0,0 +1,3 @@ +{ + "type": "bettas:betta_biome_modifier" +} \ No newline at end of file From c1acd981f2f926079adcef1c01dceeb574ad62ee Mon Sep 17 00:00:00 2001 From: baguchan Date: Fri, 30 Sep 2022 19:57:54 +0900 Subject: [PATCH 12/29] betta when from bucket. attack another betta --- .../teamfusion/bettas/entity/BettaFishEntity.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index b7df616..1e24a74 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -16,6 +16,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MobSpawnType; import net.minecraft.world.entity.SpawnGroupData; import net.minecraft.world.entity.ai.attributes.AttributeSupplier; @@ -26,7 +27,6 @@ import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.Bucketable; -import net.minecraft.world.entity.monster.Monster; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.item.ItemStack; @@ -54,6 +54,13 @@ protected void registerGoals() { this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); + this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { + @Override + public boolean canUse() { + return isFromBucket() && super.canUse(); + } + }); + } private boolean isFromBucket() { @@ -72,7 +79,7 @@ protected void defineSynchedData() { } public static AttributeSupplier.Builder createAttributes() { - return Monster.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); } public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, RandomSource randomIn) { @@ -171,7 +178,6 @@ public SpawnGroupData finalizeSpawn(ServerLevelAccessor worldIn, DifficultyInsta } else { if (dataTag.contains("Variant", 3)) { this.setVariant(dataTag.getInt("Variant")); - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false)); } if (dataTag.contains("Health", 99)) { this.setHealth(dataTag.getFloat("Health")); From 68ea658b538e91e758c62097198f1981b9af0330 Mon Sep 17 00:00:00 2001 From: baguchan Date: Sat, 1 Oct 2022 08:42:40 +0900 Subject: [PATCH 13/29] add creative tab and dried leaves render fixed --- .../teamfusion/bettas/init/BettasItems.java | 22 +++++++++++------ .../models/block/piled_dried_leaves.json | 24 ++++++++++++++++--- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/main/java/teamfusion/bettas/init/BettasItems.java b/src/main/java/teamfusion/bettas/init/BettasItems.java index 8af4872..69ba26f 100644 --- a/src/main/java/teamfusion/bettas/init/BettasItems.java +++ b/src/main/java/teamfusion/bettas/init/BettasItems.java @@ -4,6 +4,7 @@ import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.level.material.Fluids; import net.minecraftforge.common.ForgeSpawnEggItem; @@ -16,13 +17,20 @@ public class BettasItems { public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Bettas.MOD_ID); - public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_FOOD).food(new FoodProperties.Builder().nutrition(1).saturationMod(0.1F).build()))); - public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new BettasBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, Items.BUCKET, false, new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); - public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(CreativeModeTab.TAB_MISC).stacksTo(1))); + public static final CreativeModeTab BETTA_TAB = new CreativeModeTab(Bettas.MOD_ID) { + @Override + public ItemStack makeIcon() { + return new ItemStack(BettasItems.BETTA_FISH.get()); + } + }; - public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new ForgeSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(CreativeModeTab.TAB_MISC))); + public static final RegistryObject BETTA_FISH = ITEMS.register("betta_fish", () -> new Item(new Item.Properties().tab(BETTA_TAB).food(new FoodProperties.Builder().nutrition(1).saturationMod(0.1F).build()))); + public static final RegistryObject BETTA_FISH_BUCKET = ITEMS.register("betta_fish_bucket", () -> new BettasBucketItem(BettasEntities.BETTA_FISH, () -> Fluids.WATER, Items.BUCKET, false, new Item.Properties().tab(BETTA_TAB).stacksTo(1))); + public static final RegistryObject BLACKWATER_BOTTLE = ITEMS.register("blackwater_bottle", () -> new Item(new Item.Properties().tab(BETTA_TAB).stacksTo(1))); - public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); - public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); - public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(CreativeModeTab.TAB_DECORATIONS))); + public static final RegistryObject BETTA_FISH_SPAWN_EGG = ITEMS.register("betta_fish_spawn_egg", () -> new ForgeSpawnEggItem(BettasEntities.BETTA_FISH, 0x613d2a, 0x2dceff, new Item.Properties().tab(BETTA_TAB))); + + public static final RegistryObject MOSS_BALL = ITEMS.register("moss_ball", () -> new BlockItem(BettasBlocks.MOSS_BALL.get(), new Item.Properties().tab(BETTA_TAB))); + public static final RegistryObject MOSS_BALL_BLOCK = ITEMS.register("moss_ball_block", () -> new BlockItem(BettasBlocks.MOSS_BALL_BLOCK.get(), new Item.Properties().tab(BETTA_TAB))); + public static final RegistryObject DRIED_LEAVES = ITEMS.register("dried_leaves", () -> new BlockItem(BettasBlocks.DRIED_LEAVES.get(), new Item.Properties().tab(BETTA_TAB))); } \ No newline at end of file diff --git a/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json b/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json index cbb1e3b..c94867d 100644 --- a/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json +++ b/src/main/resources/assets/bettas/models/block/piled_dried_leaves.json @@ -1,14 +1,32 @@ { + "render_type": "cutout", "textures": { "dried": "bettas:block/piled_dried_leaves", "particle": "bettas:block/piled_dried_leaves" }, "elements": [ { - "from": [0, 0, 0], - "to": [16, 3, 16], + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 3, + 16 + ], "faces": { - "north": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "north" }, + "north": { + "uv": [ + 0, + 0, + 16, + 3 + ], + "texture": "#dried", + "cullface": "north" + }, "east": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "east"}, "south": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "south"}, "west": {"uv": [0, 0, 16, 3], "texture": "#dried", "cullface": "west"}, From 635c754dbd6f73af5d8fc65137e8371499797304 Mon Sep 17 00:00:00 2001 From: baguchan Date: Sat, 1 Oct 2022 08:43:52 +0900 Subject: [PATCH 14/29] hm --- src/main/resources/assets/bettas/lang/en_us.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/bettas/lang/en_us.json b/src/main/resources/assets/bettas/lang/en_us.json index 6437083..48ca62f 100644 --- a/src/main/resources/assets/bettas/lang/en_us.json +++ b/src/main/resources/assets/bettas/lang/en_us.json @@ -8,5 +8,7 @@ "block.bettas.moss_ball": "Moss Ball", "block.bettas.moss_ball_block": "Block of Moss Balls", - "block.bettas.dried_leaves": "Dried Leaves" + "block.bettas.dried_leaves": "Dried Leaves", + + "itemGroup.bettas": "Bettas" } \ No newline at end of file From a9d436697b7efd9ba7c1219bf767b5757ac349e0 Mon Sep 17 00:00:00 2001 From: baguchan Date: Thu, 6 Oct 2022 13:00:22 +0900 Subject: [PATCH 15/29] betta is coming to spawn(also tropical fish no longer spawn in mangrove swamp) --- .../bettas/biome/BettaBiomeModifier.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java index 59e720e..204feb3 100644 --- a/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java +++ b/src/main/java/teamfusion/bettas/biome/BettaBiomeModifier.java @@ -3,17 +3,23 @@ import com.mojang.serialization.Codec; import net.minecraft.core.Holder; import net.minecraft.tags.BiomeTags; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biomes; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.levelgen.GenerationStep; import net.minecraftforge.common.Tags; import net.minecraftforge.common.world.BiomeModifier; +import net.minecraftforge.common.world.MobSpawnSettingsBuilder; import net.minecraftforge.common.world.ModifiableBiomeInfo; +import net.minecraftforge.registries.ForgeRegistries; import teamfusion.bettas.init.BettaBiomeModifiers; import teamfusion.bettas.init.BettasEntities; import teamfusion.bettas.init.BettasPlacedFeatures; +import java.util.List; + public class BettaBiomeModifier implements BiomeModifier { public static final BettaBiomeModifier INSTANCE = new BettaBiomeModifier(); @@ -21,10 +27,20 @@ public class BettaBiomeModifier implements BiomeModifier { public void modify(Holder biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder) { if (phase == Phase.ADD) { if (biome.is(BiomeTags.IS_OVERWORLD) && biome.is(Tags.Biomes.IS_SWAMP)) { - builder.getMobSpawnSettings().addSpawn(MobCategory.WATER_CREATURE, new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 1, 1, 2)); + builder.getMobSpawnSettings().addSpawn(MobCategory.WATER_AMBIENT, new MobSpawnSettings.SpawnerData(BettasEntities.BETTA_FISH.get(), 15, 4, 6)); builder.getGenerationSettings().addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, BettasPlacedFeatures.PLACED_MOSS_BALLS.getHolder().get()); } } + + if (phase == Phase.REMOVE) { + if (biome.is(Biomes.MANGROVE_SWAMP)) { + MobSpawnSettingsBuilder spawnBuilder = builder.getMobSpawnSettings(); + for (MobCategory category : MobCategory.values()) { + List spawns = spawnBuilder.getSpawner(category); + spawns.removeIf(spawnerData -> EntityType.TROPICAL_FISH == ForgeRegistries.ENTITY_TYPES.getHolder(spawnerData.type).get().get()); + } + } + } } @Override From 79ba8677e30b95a7f97e66b9d50a9c2b70c39659 Mon Sep 17 00:00:00 2001 From: baguchan Date: Sat, 22 Oct 2022 07:54:20 +0900 Subject: [PATCH 16/29] build name is changed --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c008ada..e5e3e41 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ plugins { apply plugin: 'net.minecraftforge.gradle' -version = '1.0' +version = 'forge-1.19.2-1.0.0' group = 'teamfusion.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'bettas' From cbd139cddda8f8a0c433a232963874425bfb984a Mon Sep 17 00:00:00 2001 From: baguchan Date: Sat, 22 Oct 2022 15:00:11 +0900 Subject: [PATCH 17/29] add easter egg --- .../bettas/client/renderer/BettaFishRenderer.java | 7 +++++++ .../assets/bettas/textures/entity/betta/beto.png | Bin 0 -> 467 bytes 2 files changed, 7 insertions(+) create mode 100644 src/main/resources/assets/bettas/textures/entity/betta/beto.png diff --git a/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java index 16e67e7..82cc857 100644 --- a/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java +++ b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java @@ -2,6 +2,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; +import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.model.geom.ModelLayerLocation; import net.minecraft.client.renderer.entity.EntityRendererProvider; @@ -19,6 +20,8 @@ public class BettaFishRenderer extends MobRenderer(manager.bakeLayer(MODEL_LAYER)), 0.2F); this.shadowRadius = 0.2F; @@ -26,6 +29,10 @@ public BettaFishRenderer(EntityRendererProvider.Context manager) { @Override public ResourceLocation getTextureLocation(BettaFishEntity entity) { + String s = ChatFormatting.stripFormatting(entity.getName().getString()); + if (s != null && ("beto".equals(s) || "Beto".equals(s))) { + return BETO; + } int variant = entity.getVariant(); if (TEXTURES[variant] == null) { ResourceLocation loc = new ResourceLocation(Bettas.MOD_ID, "textures/entity/betta/body_" + variant + ".png"); diff --git a/src/main/resources/assets/bettas/textures/entity/betta/beto.png b/src/main/resources/assets/bettas/textures/entity/betta/beto.png new file mode 100644 index 0000000000000000000000000000000000000000..c879b6adf7e747221d68aa86f474c385f5feb582 GIT binary patch literal 467 zcmV;^0WAKBP){xWrNpN*&b&!IS?VyX) zIyzJvmqrN$OBNAw4kaOJLXeR7n{qFA?|ql|Cj1~PVZHe4XzhG@~HEdj)sYydtDAS=bzELur0s#E@99+5F z3w`TA0akD)43`-{C{cuT<4M7S)S-SGpAT-%)I6Dk`NuIu+Ap*V_^~XJ4a? z?-jss8JMDMSNbGT%zr1I!m(1oa2Xhy8f|g?m8?*vlfUA)_ytc&h!3e28*%^u002ov JPDHLkV1lJo%t-(M literal 0 HcmV?d00001 From 3401014e705e92c37e298c756f7f0cdda0dac8a0 Mon Sep 17 00:00:00 2001 From: baguchan Date: Sat, 22 Oct 2022 15:04:02 +0900 Subject: [PATCH 18/29] oops --- .../teamfusion/bettas/client/renderer/BettaFishRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java index 82cc857..3bfb6e3 100644 --- a/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java +++ b/src/main/java/teamfusion/bettas/client/renderer/BettaFishRenderer.java @@ -20,7 +20,7 @@ public class BettaFishRenderer extends MobRenderer(manager.bakeLayer(MODEL_LAYER)), 0.2F); From e8436534872a3995767a007095809739f328d075 Mon Sep 17 00:00:00 2001 From: baguchan Date: Mon, 24 Oct 2022 05:55:44 +0900 Subject: [PATCH 19/29] my bad --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index e5e3e41..826e804 100644 --- a/build.gradle +++ b/build.gradle @@ -16,9 +16,9 @@ plugins { apply plugin: 'net.minecraftforge.gradle' -version = 'forge-1.19.2-1.0.0' +version = '1.19.2-1.0.0' group = 'teamfusion.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'bettas' +archivesBaseName = 'bettas-forge' // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) From 4f6c4e6f09da67d5cb87f3ee1a12b78c65ac4c07 Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 08:19:42 +0900 Subject: [PATCH 20/29] moss balls will pacify 2 bucketed bettas in an area --- .../bettas/entity/BettaFishEntity.java | 432 ++++++++++-------- 1 file changed, 243 insertions(+), 189 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 1e24a74..3e0fdb0 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -37,200 +37,254 @@ import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import teamfusion.bettas.init.BettasBlocks; +import teamfusion.bettas.init.BettasEntities; import teamfusion.bettas.init.BettasItems; import javax.annotation.Nullable; +import java.util.List; +import java.util.function.Predicate; public class BettaFishEntity extends AbstractFish implements Bucketable { - public static final int MAX_VARIANTS = 120; - private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.INT); - private static final EntityDataAccessor FROM_BUCKET = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); - - public BettaFishEntity(EntityType type, Level worldIn) { - super(type, worldIn); - } - - protected void registerGoals() { - this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); - this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); - this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { - @Override - public boolean canUse() { - return isFromBucket() && super.canUse(); - } - }); - - } - - private boolean isFromBucket() { - return this.entityData.get(FROM_BUCKET); - } - - public void setFromBucket(boolean p_203706_1_) { - this.entityData.set(FROM_BUCKET, p_203706_1_); - } - - @Override - protected void defineSynchedData() { - super.defineSynchedData(); - this.entityData.define(VARIANT, 0); - this.entityData.define(FROM_BUCKET, false); - } - - public static AttributeSupplier.Builder createAttributes() { - return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); - } - - public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, RandomSource randomIn) { - return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; - } - - public boolean hurt(DamageSource source, float amount) { - if (this.isInvulnerableTo(source)) { - return false; - } else { - Entity entity = source.getEntity(); - if (entity != null && !(entity instanceof Player) && !(entity instanceof AbstractArrow)) { - amount = (amount + 1.0F) / 2.0F; - } - - return super.hurt(source, amount); - } - } - - public boolean doHurtTarget(Entity entityIn) { - boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float) ((int) this.getAttributeValue(Attributes.ATTACK_DAMAGE))); - if (flag) { - this.doEnchantDamageEffects(this, entityIn); - } - - return flag; - } - - public int getVariant() { - return this.entityData.get(VARIANT); - } - - private void setVariant(int variant) { - this.entityData.set(VARIANT, variant); - } - - public boolean removeWhenFarAway(double distanceToClosestPlayer) { - return !this.isFromBucket() && !this.hasCustomName(); - } - - public boolean requiresCustomPersistence() { - return super.requiresCustomPersistence() || this.isFromBucket(); - } - - @Override - public void tick() { - super.tick(); - - if (isMossBallNearby()) { - this.setTarget(null); - } - } + public static final int MAX_VARIANTS = 120; + private static final EntityDataAccessor VARIANT = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.INT); + private static final EntityDataAccessor FROM_BUCKET = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); + private static final EntityDataAccessor CALMED = SynchedEntityData.defineId(BettaFishEntity.class, EntityDataSerializers.BOOLEAN); + + static final Predicate CALMED_ENTITY = (p_28528_) -> { + return p_28528_.isCalmed() && p_28528_.isAlive(); + }; + + public BettaFishEntity(EntityType type, Level worldIn) { + super(type, worldIn); + } + + protected void registerGoals() { + this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true) { + @Override + public boolean canUse() { + return !isCalmed() && super.canUse(); + } + + @Override + public boolean canContinueToUse() { + return !isCalmed() && super.canContinueToUse(); + } + }); + this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class) { + @Override + public boolean canUse() { + return !isCalmed() && super.canUse(); + } + + @Override + public boolean canContinueToUse() { + return !isCalmed() && super.canContinueToUse(); + } + }); + this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { + @Override + public boolean canUse() { + return isFromBucket() && !isCalmed() && super.canUse(); + } + + + @Override + public boolean canContinueToUse() { + return !isCalmed() && super.canContinueToUse(); + } + }); + + } + + private boolean isFromBucket() { + return this.entityData.get(FROM_BUCKET); + } + + public void setFromBucket(boolean p_203706_1_) { + this.entityData.set(FROM_BUCKET, p_203706_1_); + } + + public boolean isCalmed() { + return this.entityData.get(CALMED); + } + + public void setCalmed(boolean calmed) { + this.entityData.set(CALMED, calmed); + } + + + @Override + protected void defineSynchedData() { + super.defineSynchedData(); + this.entityData.define(VARIANT, 0); + this.entityData.define(FROM_BUCKET, false); + this.entityData.define(CALMED, false); + } + + public static AttributeSupplier.Builder createAttributes() { + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.ATTACK_DAMAGE, 1.0D); + } + + public static boolean checkBettaFishSpawnRules(EntityType type, BlockGetter worldIn, MobSpawnType reason, BlockPos p_223363_3_, RandomSource randomIn) { + return worldIn.getBlockState(p_223363_3_).is(Blocks.WATER) && worldIn.getBlockState(p_223363_3_.above()).is(Blocks.WATER) && randomIn.nextFloat() > 0.9; + } + + public boolean hurt(DamageSource source, float amount) { + if (this.isInvulnerableTo(source)) { + return false; + } else { + Entity entity = source.getEntity(); + if (entity != null && !(entity instanceof Player) && !(entity instanceof AbstractArrow)) { + amount = (amount + 1.0F) / 2.0F; + } + + return super.hurt(source, amount); + } + } + + public boolean doHurtTarget(Entity entityIn) { + boolean flag = entityIn.hurt(DamageSource.mobAttack(this), (float) ((int) this.getAttributeValue(Attributes.ATTACK_DAMAGE))); + if (flag) { + this.doEnchantDamageEffects(this, entityIn); + } + + return flag; + } + + public int getVariant() { + return this.entityData.get(VARIANT); + } + + private void setVariant(int variant) { + this.entityData.set(VARIANT, variant); + } + + public boolean removeWhenFarAway(double distanceToClosestPlayer) { + return !this.isFromBucket() && !this.hasCustomName(); + } + + public boolean requiresCustomPersistence() { + return super.requiresCustomPersistence() || this.isFromBucket(); + } + + @Override + public void tick() { + super.tick(); + + if (!this.level.isClientSide()) { + if (isMossBallNearby() && !isCalmed()) { + List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); + + if (list.isEmpty() || list.size() < 2) { + this.setCalmed(true); + } + } else if (isCalmed() && !isMossBallNearby()) { + this.setCalmed(false); + } + } + } private boolean isMossBallNearby() { - BlockPos blockpos = this.blockPosition(); - BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); - - for (int i = 0; i < 8; ++i) { - for (int j = 0; j < 8; ++j) { - for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { - for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { - blockpos$mutable.setWithOffset(blockpos, k, i, l); - if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL_BLOCK.get())) { - return true; - } - } - } - } - } - - return false; - } - - @Override - public void addAdditionalSaveData(CompoundTag compound) { - super.addAdditionalSaveData(compound); - compound.putInt("Variant", getVariant()); - compound.putBoolean("FromBucket", this.isFromBucket()); - } - - @Override - public void readAdditionalSaveData(CompoundTag compound) { - super.readAdditionalSaveData(compound); - setVariant(Mth.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); - this.setFromBucket(compound.getBoolean("FromBucket")); - } - - @Nullable - @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor worldIn, DifficultyInstance difficultyIn, MobSpawnType reason, @Nullable SpawnGroupData spawnDataIn, @Nullable CompoundTag dataTag) { - if (dataTag == null) { - double chance = getRandom().nextDouble(); - if (chance <= 0.45) setVariant(getRandom().nextInt(MAX_VARIANTS)); - else if (chance <= 0.7) setVariant(24); - else setVariant(100); - } else { - if (dataTag.contains("Variant", 3)) { - this.setVariant(dataTag.getInt("Variant")); - } - if (dataTag.contains("Health", 99)) { - this.setHealth(dataTag.getFloat("Health")); - } - } - return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); - } - - public void saveToBucketTag(ItemStack bucket) { - CompoundTag compoundnbt = bucket.getOrCreateTag(); - compoundnbt.putInt("Variant", this.getVariant()); - compoundnbt.putFloat("Health", this.getHealth()); - } - - @Override - public ItemStack getBucketItemStack() { - return new ItemStack(BettasItems.BETTA_FISH_BUCKET.get()); - } - - @Override - protected SoundEvent getFlopSound() { - return SoundEvents.COD_FLOP; - } - - protected SoundEvent getDeathSound() { - return SoundEvents.COD_DEATH; - } - - protected SoundEvent getHurtSound(DamageSource damageSourceIn) { - return SoundEvents.COD_HURT; - } - - @Override - public ItemStack getPickedResult(HitResult result) { - return new ItemStack(BettasItems.BETTA_FISH_SPAWN_EGG.get()); - } - - @Override - public InteractionResult interactAt(Player player, Vec3 vec, InteractionHand hand) { - ItemStack stack = player.getItemInHand(hand); - float maxHealth = this.getMaxHealth(); - float health = this.getHealth(); - if (stack.getItem() == BettasItems.BLACKWATER_BOTTLE.get() && health < maxHealth) { - if (!player.isCreative()) { - stack.shrink(1); - } - heal(3); - double d0 = this.random.nextGaussian() * 0.02D; - double d1 = this.random.nextGaussian() * 0.02D; - double d2 = this.random.nextGaussian() * 0.02D; - this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2); - return InteractionResult.PASS; - } - return super.interactAt(player, vec, hand); - } + BlockPos blockpos = this.blockPosition(); + BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); + + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 8; ++j) { + for (int k = 0; k <= j; k = k > 0 ? -k : 1 - k) { + for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { + blockpos$mutable.setWithOffset(blockpos, k, i, l); + if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL.get())) { + return true; + } + } + } + } + } + + return false; + } + + @Override + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); + compound.putInt("Variant", getVariant()); + compound.putBoolean("FromBucket", this.isFromBucket()); + compound.putBoolean("Calmed", this.isCalmed()); + } + + @Override + public void readAdditionalSaveData(CompoundTag compound) { + super.readAdditionalSaveData(compound); + setVariant(Mth.clamp(compound.getInt("Variant"), 0, MAX_VARIANTS - 1)); + this.setFromBucket(compound.getBoolean("FromBucket")); + this.setCalmed(compound.getBoolean("Calmed")); + } + + @Nullable + @Override + public SpawnGroupData finalizeSpawn(ServerLevelAccessor worldIn, DifficultyInstance difficultyIn, MobSpawnType reason, @Nullable SpawnGroupData spawnDataIn, @Nullable CompoundTag dataTag) { + if (dataTag == null) { + double chance = getRandom().nextDouble(); + if (chance <= 0.45) setVariant(getRandom().nextInt(MAX_VARIANTS)); + else if (chance <= 0.7) setVariant(24); + else setVariant(100); + } else { + if (dataTag.contains("Variant", 3)) { + this.setVariant(dataTag.getInt("Variant")); + } + if (dataTag.contains("Health", 99)) { + this.setHealth(dataTag.getFloat("Health")); + } + } + return super.finalizeSpawn(worldIn, difficultyIn, reason, spawnDataIn, dataTag); + } + + public void saveToBucketTag(ItemStack bucket) { + CompoundTag compoundnbt = bucket.getOrCreateTag(); + compoundnbt.putInt("Variant", this.getVariant()); + compoundnbt.putFloat("Health", this.getHealth()); + } + + @Override + public ItemStack getBucketItemStack() { + return new ItemStack(BettasItems.BETTA_FISH_BUCKET.get()); + } + + @Override + protected SoundEvent getFlopSound() { + return SoundEvents.COD_FLOP; + } + + protected SoundEvent getDeathSound() { + return SoundEvents.COD_DEATH; + } + + protected SoundEvent getHurtSound(DamageSource damageSourceIn) { + return SoundEvents.COD_HURT; + } + + @Override + public ItemStack getPickedResult(HitResult result) { + return new ItemStack(BettasItems.BETTA_FISH_SPAWN_EGG.get()); + } + + @Override + public InteractionResult interactAt(Player player, Vec3 vec, InteractionHand hand) { + ItemStack stack = player.getItemInHand(hand); + float maxHealth = this.getMaxHealth(); + float health = this.getHealth(); + if (stack.getItem() == BettasItems.BLACKWATER_BOTTLE.get() && health < maxHealth) { + if (!player.isCreative()) { + stack.shrink(1); + } + heal(3); + double d0 = this.random.nextGaussian() * 0.02D; + double d1 = this.random.nextGaussian() * 0.02D; + double d2 = this.random.nextGaussian() * 0.02D; + this.level.addParticle(ParticleTypes.HEART, this.getRandomX(1.0D), this.getRandomY() + 0.5D, this.getRandomZ(1.0D), d0, d1, d2); + return InteractionResult.PASS; + } + return super.interactAt(player, vec, hand); + } } \ No newline at end of file From 64e16fe7f780d77f765fa80aec7697c43b0c7820 Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 08:54:24 +0900 Subject: [PATCH 21/29] 1.19.2-1.1.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 826e804..ba14a8d 100644 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ plugins { apply plugin: 'net.minecraftforge.gradle' -version = '1.19.2-1.0.0' +version = '1.19.2-1.1.0' group = 'teamfusion.bettas' // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = 'bettas-forge' From d0fd3af5d1abe29eb039a93672e5adec3ad86e86 Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:02:50 +0900 Subject: [PATCH 22/29] fixed pacifies mechanic --- .../bettas/entity/BettaFishEntity.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 3e0fdb0..800046f 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -36,6 +36,7 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; +import teamfusion.bettas.block.MossBallBlock; import teamfusion.bettas.init.BettasBlocks; import teamfusion.bettas.init.BettasEntities; import teamfusion.bettas.init.BettasItems; @@ -173,19 +174,16 @@ public void tick() { super.tick(); if (!this.level.isClientSide()) { - if (isMossBallNearby() && !isCalmed()) { - List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); + if (isMossBallNearby(true) && !isCalmed()) { - if (list.isEmpty() || list.size() < 2) { - this.setCalmed(true); - } - } else if (isCalmed() && !isMossBallNearby()) { + this.setCalmed(true); + } else if (isCalmed() && !isMossBallNearby(false)) { this.setCalmed(false); } } } - private boolean isMossBallNearby() { + private boolean isMossBallNearby(boolean checkEntity) { BlockPos blockpos = this.blockPosition(); BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); @@ -195,7 +193,17 @@ private boolean isMossBallNearby() { for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { blockpos$mutable.setWithOffset(blockpos, k, i, l); if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL.get())) { - return true; + if (checkEntity) { + List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); + + if (list.isEmpty() || list.size() < 2 * this.level.getBlockState(blockpos$mutable).getValue(MossBallBlock.BALLS)) { + return true; + } else { + return false; + } + } else { + return true; + } } } } From 8197a43f347da9ace81c4ceb3e07f7ac2a04dd9f Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:20:56 +0900 Subject: [PATCH 23/29] fixed pacifies mechanic --- .../bettas/entity/BettaFishEntity.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 800046f..0af2d9b 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -174,16 +174,18 @@ public void tick() { super.tick(); if (!this.level.isClientSide()) { - if (isMossBallNearby(true) && !isCalmed()) { + if (isMossBallNearby() && !isCalmed()) { this.setCalmed(true); - } else if (isCalmed() && !isMossBallNearby(false)) { + } else if (isCalmed() && !isMossBallNearby()) { this.setCalmed(false); } } } - private boolean isMossBallNearby(boolean checkEntity) { + private boolean isMossBallNearby() { + boolean flag = false; + int mossCount = 0; BlockPos blockpos = this.blockPosition(); BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); @@ -193,23 +195,20 @@ private boolean isMossBallNearby(boolean checkEntity) { for (int l = k < j && k > -j ? j : 0; l <= j; l = l > 0 ? -l : 1 - l) { blockpos$mutable.setWithOffset(blockpos, k, i, l); if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL.get())) { - if (checkEntity) { - List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); - - if (list.isEmpty() || list.size() < 2 * this.level.getBlockState(blockpos$mutable).getValue(MossBallBlock.BALLS)) { - return true; - } else { - return false; - } - } else { - return true; - } + flag = true; + mossCount += this.level.getBlockState(blockpos$mutable).getValue(MossBallBlock.BALLS); } } } } } + if (flag) { + List list = this.level.getEntities(BettasEntities.BETTA_FISH.get(), this.getBoundingBox().inflate(8.0D), CALMED_ENTITY); + if (list.isEmpty() || list.size() < 2 * mossCount) { + return true; + } + } return false; } From 38ca1ce6e13bef00481612b630f66b1d7bfd739b Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:23:31 +0900 Subject: [PATCH 24/29] moss ball block too! --- src/main/java/teamfusion/bettas/entity/BettaFishEntity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 0af2d9b..52678dd 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -197,6 +197,9 @@ private boolean isMossBallNearby() { if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL.get())) { flag = true; mossCount += this.level.getBlockState(blockpos$mutable).getValue(MossBallBlock.BALLS); + } else if (this.level.getBlockState(blockpos$mutable).is(BettasBlocks.MOSS_BALL_BLOCK.get())) { + flag = true; + mossCount += 8; } } } From d62dd9d1e79de13041ee35487a95379c32101e72 Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:39:59 +0900 Subject: [PATCH 25/29] oops --- .../java/teamfusion/bettas/entity/BettaFishEntity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 52678dd..40c3402 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -174,18 +174,18 @@ public void tick() { super.tick(); if (!this.level.isClientSide()) { - if (isMossBallNearby() && !isCalmed()) { + if (isMossBallNearby(true) && !isCalmed()) { this.setCalmed(true); - } else if (isCalmed() && !isMossBallNearby()) { + } else if (isCalmed() && !isMossBallNearby(false)) { this.setCalmed(false); } } } - private boolean isMossBallNearby() { + private boolean isMossBallNearby(boolean checkEntity) { boolean flag = false; - int mossCount = 0; + int mossCount = checkEntity ? 0 : 1; BlockPos blockpos = this.blockPosition(); BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); From a3af1a31beeeb354f285fa6eecc75675a453abeb Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:41:24 +0900 Subject: [PATCH 26/29] oops --- src/main/java/teamfusion/bettas/entity/BettaFishEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 40c3402..78101e5 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -183,9 +183,9 @@ public void tick() { } } - private boolean isMossBallNearby(boolean checkEntity) { + private boolean isMossBallNearby(boolean afterCheck) { boolean flag = false; - int mossCount = checkEntity ? 0 : 1; + int mossCount = afterCheck ? 0 : 1; BlockPos blockpos = this.blockPosition(); BlockPos.MutableBlockPos blockpos$mutable = new BlockPos.MutableBlockPos(); From c1b67808e2f04c29a5922a734a88d930eb10c75a Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 10:56:41 +0900 Subject: [PATCH 27/29] bettas actually defend themselves when attacked by other bettas --- .../teamfusion/bettas/entity/BettaFishEntity.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 78101e5..0e8e161 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -72,17 +72,7 @@ public boolean canContinueToUse() { } }); this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); - this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class) { - @Override - public boolean canUse() { - return !isCalmed() && super.canUse(); - } - - @Override - public boolean canContinueToUse() { - return !isCalmed() && super.canContinueToUse(); - } - }); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { @Override public boolean canUse() { From 647f0042635f7ab94ff2e3151395f9e06df038bd Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 11:05:14 +0900 Subject: [PATCH 28/29] bettas actually defend themselves when attacked by other bettas --- .../teamfusion/bettas/entity/BettaFishEntity.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 0e8e161..8bfe9e6 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -60,17 +60,7 @@ public BettaFishEntity(EntityType type, Level worldIn } protected void registerGoals() { - this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true) { - @Override - public boolean canUse() { - return !isCalmed() && super.canUse(); - } - - @Override - public boolean canContinueToUse() { - return !isCalmed() && super.canContinueToUse(); - } - }); + this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { From 98a8017d5e92f950cfbbfcaa804a21c93dbd17a9 Mon Sep 17 00:00:00 2001 From: baguchan Date: Wed, 26 Oct 2022 11:17:55 +0900 Subject: [PATCH 29/29] oops --- src/main/java/teamfusion/bettas/entity/BettaFishEntity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java index 8bfe9e6..dca3fbb 100644 --- a/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java +++ b/src/main/java/teamfusion/bettas/entity/BettaFishEntity.java @@ -62,7 +62,7 @@ public BettaFishEntity(EntityType type, Level worldIn protected void registerGoals() { this.goalSelector.addGoal(0, new MeleeAttackGoal(this, 2.0D, true)); this.goalSelector.addGoal(1, new RandomSwimmingGoal(this, 1.0D, 20)); - this.targetSelector.addGoal(0, new HurtByTargetGoal(this, BettaFishEntity.class)); + this.targetSelector.addGoal(0, new HurtByTargetGoal(this)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, BettaFishEntity.class, false) { @Override public boolean canUse() { @@ -154,7 +154,7 @@ public void tick() { super.tick(); if (!this.level.isClientSide()) { - if (isMossBallNearby(true) && !isCalmed()) { + if (isFromBucket() && isMossBallNearby(true) && !isCalmed()) { this.setCalmed(true); } else if (isCalmed() && !isMossBallNearby(false)) {