From 50290a0339131f02a143ee9b07ad1299b82b1db8 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 30 Oct 2023 14:51:37 +0300 Subject: [PATCH 1/6] Bonemeal API --- .../sltest/bonemeal/BonemealListener.java | 14 +++ .../sltest/mixin/MixinObsidian.java | 29 +++++ src/test/resources/fabric.mod.json | 3 +- src/test/resources/sltest.mixins.json | 41 +++---- .../api/util/collection/WeightedList.java | 35 ++++++ .../stationapi/api/block/StationBlock.java | 5 + .../stationapi/api/bonemeal/BonemealAPI.java | 101 ++++++++++++++++++ .../stationapi/mixin/item/MixinDye.java | 35 ++++++ .../resources/station-items-v0.mixins.json | 63 +++++------ 9 files changed, 274 insertions(+), 52 deletions(-) create mode 100644 src/test/java/net/modificationstation/sltest/bonemeal/BonemealListener.java create mode 100644 src/test/java/net/modificationstation/sltest/mixin/MixinObsidian.java create mode 100644 station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java create mode 100644 station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java create mode 100644 station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java diff --git a/src/test/java/net/modificationstation/sltest/bonemeal/BonemealListener.java b/src/test/java/net/modificationstation/sltest/bonemeal/BonemealListener.java new file mode 100644 index 000000000..5f80064b1 --- /dev/null +++ b/src/test/java/net/modificationstation/sltest/bonemeal/BonemealListener.java @@ -0,0 +1,14 @@ +package net.modificationstation.sltest.bonemeal; + +import net.mine_diver.unsafeevents.listener.EventListener; +import net.mine_diver.unsafeevents.listener.ListenerPriority; +import net.minecraft.block.BlockBase; +import net.modificationstation.stationapi.api.bonemeal.BonemealAPI; +import net.modificationstation.stationapi.api.event.registry.BlockRegistryEvent; + +public class BonemealListener { + @EventListener(priority = ListenerPriority.LOW) + public void registerItems(BlockRegistryEvent event) { + BonemealAPI.addPlant(BlockBase.SAND.getDefaultState(), BlockBase.BOOKSHELF.getDefaultState(), 1); + } +} diff --git a/src/test/java/net/modificationstation/sltest/mixin/MixinObsidian.java b/src/test/java/net/modificationstation/sltest/mixin/MixinObsidian.java new file mode 100644 index 000000000..36e176aaa --- /dev/null +++ b/src/test/java/net/modificationstation/sltest/mixin/MixinObsidian.java @@ -0,0 +1,29 @@ +package net.modificationstation.sltest.mixin; + +import net.minecraft.block.BlockBase; +import net.minecraft.block.Obsidian; +import net.minecraft.level.Level; +import net.minecraft.level.biome.Biome; +import net.minecraft.level.dimension.DimensionData; +import net.minecraft.level.gen.BiomeSource; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.block.StationBlock; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; + +@Mixin(Obsidian.class) +public abstract class MixinObsidian implements StationBlock { + @Override + public boolean onBonemealUse(Level level, int x, int y, int z, BlockState state) { + level.setBlockState(x, y, z, BlockBase.LOG.getDefaultState()); + System.out.println(x + " " + y + " " + z); + return true; + } +} diff --git a/src/test/resources/fabric.mod.json b/src/test/resources/fabric.mod.json index 6e93b5531..e25a35906 100644 --- a/src/test/resources/fabric.mod.json +++ b/src/test/resources/fabric.mod.json @@ -31,7 +31,8 @@ "net.modificationstation.sltest.tileentity.TileEntityListener", "net.modificationstation.sltest.item.tool.ToolListener", "net.modificationstation.sltest.datafixer.DataFixerListener", - "net.modificationstation.sltest.worldgen.TestWorldgenListener" + "net.modificationstation.sltest.worldgen.TestWorldgenListener", + "net.modificationstation.sltest.bonemeal.BonemealListener" ], "stationapi:event_bus_client": [ "net.modificationstation.sltest.gui.GuiListener", diff --git a/src/test/resources/sltest.mixins.json b/src/test/resources/sltest.mixins.json index d077e2988..bea083cad 100644 --- a/src/test/resources/sltest.mixins.json +++ b/src/test/resources/sltest.mixins.json @@ -1,22 +1,23 @@ { - "required": true, - "minVersion": "0.8", - "package": "net.modificationstation.sltest.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - "BlockBaseAccessor", - "MixinLevel", - "MixinNetherLevelSource", - "OverworldTestMixin" - ], - "server": [ - ], - "client": [ - "MixinScreenBase", - "MixinScrollableBase", - "MixinWorldRenderer" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "minVersion": "0.8", + "package": "net.modificationstation.sltest.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "BlockBaseAccessor", + "MixinLevel", + "MixinNetherLevelSource", + "MixinObsidian", + "OverworldTestMixin" + ], + "server": [ + ], + "client": [ + "MixinScreenBase", + "MixinScrollableBase", + "MixinWorldRenderer" + ], + "injectors": { + "defaultRequire": 1 + } } diff --git a/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java new file mode 100644 index 000000000..d533055b0 --- /dev/null +++ b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java @@ -0,0 +1,35 @@ +package net.modificationstation.stationapi.api.util.collection; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class WeightedList { + private final List objects = new ArrayList<>(); + private final IntList weights = new IntArrayList(); + private int maxWeight; + + public void add(T object, int weight) { + objects.add(object); + maxWeight += weight; + weights.add(maxWeight); + } + + public void clear() { + objects.clear(); + weights.clear(); + maxWeight = 0; + } + + public T get(Random random) { + if (maxWeight == 0 || objects.isEmpty()) return null; + int weight = random.nextInt(maxWeight); + for (int i = 0; i < objects.size(); i++) { + if (weight < weights.getInt(i)) return objects.get(i); + } + return objects.get(0); + } +} diff --git a/station-blocks-v0/src/main/java/net/modificationstation/stationapi/api/block/StationBlock.java b/station-blocks-v0/src/main/java/net/modificationstation/stationapi/api/block/StationBlock.java index 0c36b17e9..880ff0c8d 100644 --- a/station-blocks-v0/src/main/java/net/modificationstation/stationapi/api/block/StationBlock.java +++ b/station-blocks-v0/src/main/java/net/modificationstation/stationapi/api/block/StationBlock.java @@ -1,6 +1,7 @@ package net.modificationstation.stationapi.api.block; import net.minecraft.block.BlockBase; +import net.minecraft.level.Level; import net.modificationstation.stationapi.api.registry.Identifier; import net.modificationstation.stationapi.api.registry.ModID; import net.modificationstation.stationapi.api.registry.RemappableRawIdHolder; @@ -15,4 +16,8 @@ default BlockBase setTranslationKey(ModID modID, String translationKey) { default BlockBase setTranslationKey(Identifier translationKey) { return Util.assertImpl(); } + + default boolean onBonemealUse(Level level, int x, int y, int z, BlockState state) { + return false; + } } diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java new file mode 100644 index 000000000..a0bf098e8 --- /dev/null +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java @@ -0,0 +1,101 @@ +package net.modificationstation.stationapi.api.bonemeal; + +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import net.minecraft.block.BlockBase; +import net.minecraft.level.Level; +import net.minecraft.level.structure.Structure; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.registry.BlockRegistry; +import net.modificationstation.stationapi.api.tag.TagKey; +import net.modificationstation.stationapi.api.util.collection.WeightedList; +import net.modificationstation.stationapi.api.util.math.Direction; + +import java.util.Map; +import java.util.Random; + +public class BonemealAPI { + private static final Map> PLACERS = new Reference2ObjectOpenHashMap<>(); + + public static void addPlant(BlockState ground, BlockState plant, int weight) { + addPlant(ground, new SimpleStateStructure(plant), weight); + } + + public static void addPlant(BlockState ground, Structure plant, int weight) { + PLACERS.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); + } + + public static void addPlant(TagKey ground, BlockState plant, int weight) { + BlockRegistry.INSTANCE.forEach(blockBase -> + blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) + ); + } + + public static void addPlant(TagKey ground, Structure plant, int weight) { + BlockRegistry.INSTANCE.forEach(blockBase -> + blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) + ); + } + + public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { + WeightedList structures = PLACERS.get(state); + if (structures == null) return false; + Random random = level.rand; + Direction offset = Direction.byId(side); + structures.get(random).generate( + level, + random, + x + offset.getOffsetX(), + y + offset.getOffsetY(), + z + offset.getOffsetZ() + ); + for (byte i = 0; i < 127; i++) { + int px = x + random.nextInt(7) - 3; + int py = y + random.nextInt(5) - 2; + int pz = z + random.nextInt(7) - 3; + state = level.getBlockState(px, py, pz); + structures = PLACERS.get(state); + if (structures == null) continue; + structures.get(random).generate(level, random, px, py + 1, pz); + } + return true; + } + + private static class SimpleStateStructure extends Structure { + private final BlockState state; + + private SimpleStateStructure(BlockState state) { + this.state = state; + } + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (state.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, state); + return true; + } + return false; + } + } + + private static class GrassStructure extends Structure { + private static final BlockState STATE = BlockBase.TALLGRASS.getDefaultState(); + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (STATE.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, STATE); + level.setTileMeta(x, y, z, 1); + return true; + } + return false; + } + } + + static { + addPlant(BlockBase.GRASS.getDefaultState(), new GrassStructure(), 1); + } +} diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java new file mode 100644 index 000000000..9b8ee0d9d --- /dev/null +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java @@ -0,0 +1,35 @@ +package net.modificationstation.stationapi.mixin.item; + +import net.minecraft.entity.player.PlayerBase; +import net.minecraft.item.Dye; +import net.minecraft.item.ItemInstance; +import net.minecraft.level.Level; +import net.modificationstation.stationapi.api.block.BlockState; +import net.modificationstation.stationapi.api.bonemeal.BonemealAPI; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Dye.class) +public class MixinDye { + @Inject(method = "useOnTile", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/level/Level;getTileId(III)I", + ordinal = 0 + ), cancellable = true) + private void onBonemealUse(ItemInstance item, PlayerBase player, Level level, int x, int y, int z, int side, CallbackInfoReturnable info) { + BlockState state = level.getBlockState(x, y, z); + if (state.getBlock().onBonemealUse(level, x, y, z, state)) { + level.method_202(x, y, z, x, y, z); + info.setReturnValue(true); + item.count--; + return; + } + if (BonemealAPI.generate(level, x, y, z, state, side)) { + level.method_202(x - 8, y - 8, z - 8, x + 8, y + 8, z + 8); + info.setReturnValue(true); + item.count--; + } + } +} diff --git a/station-items-v0/src/main/resources/station-items-v0.mixins.json b/station-items-v0/src/main/resources/station-items-v0.mixins.json index d84fd96ea..1e3598784 100644 --- a/station-items-v0/src/main/resources/station-items-v0.mixins.json +++ b/station-items-v0/src/main/resources/station-items-v0.mixins.json @@ -1,33 +1,34 @@ { - "required": true, - "minVersion": "0.8", - "package": "net.modificationstation.stationapi.mixin.item", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "MixinBlockBase", - "MixinContainerBase", - "MixinInventoryUpdate0x68S2CPacket", - "MixinItemBase", - "MixinItemInstance", - "MixinPlayerBase", - "MixinPlayerInventory", - "MixinStats" - ], - "server": [ - "server.Mixinclass_70", - "server.MixinServerPlayerPacketHandler" - ], - "client": [ - "client.DrawableHelperInvoker", - "client.Mixinclass_608", - "client.MixinClientInteractionManager", - "client.MixinContainerBase", - "client.MixinGameRenderer", - "client.MixinItemRenderer", - "client.MixinMultiPlayerClientInteractionManager", - "client.MixinSinglePlayerClientInteractionManager" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "minVersion": "0.8", + "package": "net.modificationstation.stationapi.mixin.item", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "MixinBlockBase", + "MixinContainerBase", + "MixinDye", + "MixinInventoryUpdate0x68S2CPacket", + "MixinItemBase", + "MixinItemInstance", + "MixinPlayerBase", + "MixinPlayerInventory", + "MixinStats" + ], + "server": [ + "server.Mixinclass_70", + "server.MixinServerPlayerPacketHandler" + ], + "client": [ + "client.DrawableHelperInvoker", + "client.Mixinclass_608", + "client.MixinClientInteractionManager", + "client.MixinContainerBase", + "client.MixinGameRenderer", + "client.MixinItemRenderer", + "client.MixinMultiPlayerClientInteractionManager", + "client.MixinSinglePlayerClientInteractionManager" + ], + "injectors": { + "defaultRequire": 1 + } } From 4193406017b5ab4e8dbc40933d9729ef669084ce Mon Sep 17 00:00:00 2001 From: mineLdiver Date: Mon, 30 Oct 2023 17:24:44 +0500 Subject: [PATCH 2/6] Reindented code. Fixed missing station-maths-v0 dependency --- src/test/resources/sltest.mixins.json | 42 ++--- .../api/util/collection/WeightedList.java | 48 ++--- station-items-v0/build.gradle | 1 + .../stationapi/api/bonemeal/BonemealAPI.java | 168 +++++++++--------- .../stationapi/mixin/item/MixinDye.java | 38 ++-- .../resources/station-items-v0.mixins.json | 64 +++---- 6 files changed, 181 insertions(+), 180 deletions(-) diff --git a/src/test/resources/sltest.mixins.json b/src/test/resources/sltest.mixins.json index bea083cad..483f20575 100644 --- a/src/test/resources/sltest.mixins.json +++ b/src/test/resources/sltest.mixins.json @@ -1,23 +1,23 @@ { - "required": true, - "minVersion": "0.8", - "package": "net.modificationstation.sltest.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - "BlockBaseAccessor", - "MixinLevel", - "MixinNetherLevelSource", - "MixinObsidian", - "OverworldTestMixin" - ], - "server": [ - ], - "client": [ - "MixinScreenBase", - "MixinScrollableBase", - "MixinWorldRenderer" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "minVersion": "0.8", + "package": "net.modificationstation.sltest.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "BlockBaseAccessor", + "MixinLevel", + "MixinNetherLevelSource", + "MixinObsidian", + "OverworldTestMixin" + ], + "server": [ + ], + "client": [ + "MixinScreenBase", + "MixinScrollableBase", + "MixinWorldRenderer" + ], + "injectors": { + "defaultRequire": 1 + } } diff --git a/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java index d533055b0..1651814fd 100644 --- a/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java +++ b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java @@ -8,28 +8,28 @@ import java.util.Random; public class WeightedList { - private final List objects = new ArrayList<>(); - private final IntList weights = new IntArrayList(); - private int maxWeight; - - public void add(T object, int weight) { - objects.add(object); - maxWeight += weight; - weights.add(maxWeight); - } - - public void clear() { - objects.clear(); - weights.clear(); - maxWeight = 0; - } - - public T get(Random random) { - if (maxWeight == 0 || objects.isEmpty()) return null; - int weight = random.nextInt(maxWeight); - for (int i = 0; i < objects.size(); i++) { - if (weight < weights.getInt(i)) return objects.get(i); - } - return objects.get(0); - } + private final List objects = new ArrayList<>(); + private final IntList weights = new IntArrayList(); + private int maxWeight; + + public void add(T object, int weight) { + objects.add(object); + maxWeight += weight; + weights.add(maxWeight); + } + + public void clear() { + objects.clear(); + weights.clear(); + maxWeight = 0; + } + + public T get(Random random) { + if (maxWeight == 0 || objects.isEmpty()) return null; + int weight = random.nextInt(maxWeight); + for (int i = 0; i < objects.size(); i++) { + if (weight < weights.getInt(i)) return objects.get(i); + } + return objects.get(0); + } } diff --git a/station-items-v0/build.gradle b/station-items-v0/build.gradle index ba7e5f2b9..03e57bdb1 100644 --- a/station-items-v0/build.gradle +++ b/station-items-v0/build.gradle @@ -3,6 +3,7 @@ version = getSubprojectVersion(project, "1.0.0") moduleDependencies(project, 'station-api-base', + 'station-maths-v0', 'station-registry-api-v0', 'station-flattening-v0', 'station-blocks-v0', diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java index a0bf098e8..2b9cc9418 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java @@ -14,88 +14,88 @@ import java.util.Random; public class BonemealAPI { - private static final Map> PLACERS = new Reference2ObjectOpenHashMap<>(); - - public static void addPlant(BlockState ground, BlockState plant, int weight) { - addPlant(ground, new SimpleStateStructure(plant), weight); - } - - public static void addPlant(BlockState ground, Structure plant, int weight) { - PLACERS.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); - } - - public static void addPlant(TagKey ground, BlockState plant, int weight) { - BlockRegistry.INSTANCE.forEach(blockBase -> - blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) - ); - } - - public static void addPlant(TagKey ground, Structure plant, int weight) { - BlockRegistry.INSTANCE.forEach(blockBase -> - blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) - ); - } - - public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { - WeightedList structures = PLACERS.get(state); - if (structures == null) return false; - Random random = level.rand; - Direction offset = Direction.byId(side); - structures.get(random).generate( - level, - random, - x + offset.getOffsetX(), - y + offset.getOffsetY(), - z + offset.getOffsetZ() - ); - for (byte i = 0; i < 127; i++) { - int px = x + random.nextInt(7) - 3; - int py = y + random.nextInt(5) - 2; - int pz = z + random.nextInt(7) - 3; - state = level.getBlockState(px, py, pz); - structures = PLACERS.get(state); - if (structures == null) continue; - structures.get(random).generate(level, random, px, py + 1, pz); - } - return true; - } - - private static class SimpleStateStructure extends Structure { - private final BlockState state; - - private SimpleStateStructure(BlockState state) { - this.state = state; - } - - @Override - public boolean generate(Level level, Random random, int x, int y, int z) { - BlockState levelState = level.getBlockState(x, y, z); - if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; - if (state.getBlock().canPlaceAt(level, x, y, z)) { - level.setBlockState(x, y, z, state); - return true; - } - return false; - } - } - - private static class GrassStructure extends Structure { - private static final BlockState STATE = BlockBase.TALLGRASS.getDefaultState(); - - @Override - public boolean generate(Level level, Random random, int x, int y, int z) { - BlockState levelState = level.getBlockState(x, y, z); - if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; - if (STATE.getBlock().canPlaceAt(level, x, y, z)) { - level.setBlockState(x, y, z, STATE); - level.setTileMeta(x, y, z, 1); - return true; - } - return false; - } - } - - static { - addPlant(BlockBase.GRASS.getDefaultState(), new GrassStructure(), 1); - } + private static final Map> PLACERS = new Reference2ObjectOpenHashMap<>(); + + public static void addPlant(BlockState ground, BlockState plant, int weight) { + addPlant(ground, new SimpleStateStructure(plant), weight); + } + + public static void addPlant(BlockState ground, Structure plant, int weight) { + PLACERS.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); + } + + public static void addPlant(TagKey ground, BlockState plant, int weight) { + BlockRegistry.INSTANCE.forEach(blockBase -> + blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) + ); + } + + public static void addPlant(TagKey ground, Structure plant, int weight) { + BlockRegistry.INSTANCE.forEach(blockBase -> + blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) + ); + } + + public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { + WeightedList structures = PLACERS.get(state); + if (structures == null) return false; + Random random = level.rand; + Direction offset = Direction.byId(side); + structures.get(random).generate( + level, + random, + x + offset.getOffsetX(), + y + offset.getOffsetY(), + z + offset.getOffsetZ() + ); + for (byte i = 0; i < 127; i++) { + int px = x + random.nextInt(7) - 3; + int py = y + random.nextInt(5) - 2; + int pz = z + random.nextInt(7) - 3; + state = level.getBlockState(px, py, pz); + structures = PLACERS.get(state); + if (structures == null) continue; + structures.get(random).generate(level, random, px, py + 1, pz); + } + return true; + } + + private static class SimpleStateStructure extends Structure { + private final BlockState state; + + private SimpleStateStructure(BlockState state) { + this.state = state; + } + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (state.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, state); + return true; + } + return false; + } + } + + private static class GrassStructure extends Structure { + private static final BlockState STATE = BlockBase.TALLGRASS.getDefaultState(); + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (STATE.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, STATE); + level.setTileMeta(x, y, z, 1); + return true; + } + return false; + } + } + + static { + addPlant(BlockBase.GRASS.getDefaultState(), new GrassStructure(), 1); + } } diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java index 9b8ee0d9d..95a1d1aa9 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/mixin/item/MixinDye.java @@ -13,23 +13,23 @@ @Mixin(Dye.class) public class MixinDye { - @Inject(method = "useOnTile", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/level/Level;getTileId(III)I", - ordinal = 0 - ), cancellable = true) - private void onBonemealUse(ItemInstance item, PlayerBase player, Level level, int x, int y, int z, int side, CallbackInfoReturnable info) { - BlockState state = level.getBlockState(x, y, z); - if (state.getBlock().onBonemealUse(level, x, y, z, state)) { - level.method_202(x, y, z, x, y, z); - info.setReturnValue(true); - item.count--; - return; - } - if (BonemealAPI.generate(level, x, y, z, state, side)) { - level.method_202(x - 8, y - 8, z - 8, x + 8, y + 8, z + 8); - info.setReturnValue(true); - item.count--; - } - } + @Inject(method = "useOnTile", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/level/Level;getTileId(III)I", + ordinal = 0 + ), cancellable = true) + private void onBonemealUse(ItemInstance item, PlayerBase player, Level level, int x, int y, int z, int side, CallbackInfoReturnable info) { + BlockState state = level.getBlockState(x, y, z); + if (state.getBlock().onBonemealUse(level, x, y, z, state)) { + level.method_202(x, y, z, x, y, z); + info.setReturnValue(true); + item.count--; + return; + } + if (BonemealAPI.generate(level, x, y, z, state, side)) { + level.method_202(x - 8, y - 8, z - 8, x + 8, y + 8, z + 8); + info.setReturnValue(true); + item.count--; + } + } } diff --git a/station-items-v0/src/main/resources/station-items-v0.mixins.json b/station-items-v0/src/main/resources/station-items-v0.mixins.json index 1e3598784..44f2e43c8 100644 --- a/station-items-v0/src/main/resources/station-items-v0.mixins.json +++ b/station-items-v0/src/main/resources/station-items-v0.mixins.json @@ -1,34 +1,34 @@ { - "required": true, - "minVersion": "0.8", - "package": "net.modificationstation.stationapi.mixin.item", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "MixinBlockBase", - "MixinContainerBase", - "MixinDye", - "MixinInventoryUpdate0x68S2CPacket", - "MixinItemBase", - "MixinItemInstance", - "MixinPlayerBase", - "MixinPlayerInventory", - "MixinStats" - ], - "server": [ - "server.Mixinclass_70", - "server.MixinServerPlayerPacketHandler" - ], - "client": [ - "client.DrawableHelperInvoker", - "client.Mixinclass_608", - "client.MixinClientInteractionManager", - "client.MixinContainerBase", - "client.MixinGameRenderer", - "client.MixinItemRenderer", - "client.MixinMultiPlayerClientInteractionManager", - "client.MixinSinglePlayerClientInteractionManager" - ], - "injectors": { - "defaultRequire": 1 - } + "required": true, + "minVersion": "0.8", + "package": "net.modificationstation.stationapi.mixin.item", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "MixinBlockBase", + "MixinContainerBase", + "MixinDye", + "MixinInventoryUpdate0x68S2CPacket", + "MixinItemBase", + "MixinItemInstance", + "MixinPlayerBase", + "MixinPlayerInventory", + "MixinStats" + ], + "server": [ + "server.Mixinclass_70", + "server.MixinServerPlayerPacketHandler" + ], + "client": [ + "client.DrawableHelperInvoker", + "client.Mixinclass_608", + "client.MixinClientInteractionManager", + "client.MixinContainerBase", + "client.MixinGameRenderer", + "client.MixinItemRenderer", + "client.MixinMultiPlayerClientInteractionManager", + "client.MixinSinglePlayerClientInteractionManager" + ], + "injectors": { + "defaultRequire": 1 + } } From 301d4da3c92d8bae85fdc44d239d5077aaec49ba Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Mon, 30 Oct 2023 16:15:31 +0300 Subject: [PATCH 3/6] Fixed missing flowers --- .../stationapi/api/bonemeal/BonemealAPI.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java index a0bf098e8..cd83ec7da 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java @@ -96,6 +96,9 @@ public boolean generate(Level level, Random random, int x, int y, int z) { } static { - addPlant(BlockBase.GRASS.getDefaultState(), new GrassStructure(), 1); + BlockState grass = BlockBase.GRASS.getDefaultState(); + addPlant(grass, new GrassStructure(), 10); + addPlant(grass, BlockBase.DANDELION.getDefaultState(), 1); + addPlant(grass, BlockBase.ROSE.getDefaultState(), 1); } } From bb75d751d907d584282fe9359d9379720ee0c614 Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Wed, 1 Nov 2023 19:33:18 +0300 Subject: [PATCH 4/6] Added missing overworld biomes --- .../worldgen/OverworldBiomeProviderImpl.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/station-worldgen-api-v0/src/main/java/net/modificationstation/stationapi/impl/worldgen/OverworldBiomeProviderImpl.java b/station-worldgen-api-v0/src/main/java/net/modificationstation/stationapi/impl/worldgen/OverworldBiomeProviderImpl.java index 026f1c0a7..c60bdefed 100644 --- a/station-worldgen-api-v0/src/main/java/net/modificationstation/stationapi/impl/worldgen/OverworldBiomeProviderImpl.java +++ b/station-worldgen-api-v0/src/main/java/net/modificationstation/stationapi/impl/worldgen/OverworldBiomeProviderImpl.java @@ -1,8 +1,19 @@ package net.modificationstation.stationapi.impl.worldgen; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import net.minecraft.level.biome.Biome; +import net.minecraft.level.biome.Forest; +import net.minecraft.level.biome.Hell; +import net.minecraft.level.biome.Rainforest; +import net.minecraft.level.biome.Sky; +import net.minecraft.level.biome.SparseBiome; +import net.minecraft.level.biome.Swampland; +import net.minecraft.level.biome.Taiga; import net.modificationstation.stationapi.api.worldgen.biome.ClimateBiomeProvider; +import java.util.Collection; +import java.util.Set; + public class OverworldBiomeProviderImpl extends ClimateBiomeProvider { private static final OverworldBiomeProviderImpl INSTANCE = new OverworldBiomeProviderImpl(); @@ -20,6 +31,23 @@ protected Biome getBiome(float temperature, float wetness) { Biome biome = super.getBiome(temperature, wetness); return biome == null ? Biome.getBiome(temperature, wetness) : biome; } + + @Override + public Collection getBiomes() { + Collection biomes = super.getBiomes(); + biomes.add(Biome.RAINFOREST); + biomes.add(Biome.SWAMPLAND); + biomes.add(Biome.SEASONAL_FOREST); + biomes.add(Biome.FOREST); + biomes.add(Biome.SAVANNA); + biomes.add(Biome.SHRUBLAND); + biomes.add(Biome.TAIGA); + biomes.add(Biome.DESERT); + biomes.add(Biome.PLAINS); + biomes.add(Biome.ICE_DESERT); + biomes.add(Biome.TUNDRA); + return biomes; + } public static OverworldBiomeProviderImpl getInstance() { return INSTANCE; From a8f82dc7f0d30c4389113d52072ea042cd38281e Mon Sep 17 00:00:00 2001 From: paulevsGitch Date: Fri, 3 Nov 2023 18:53:28 +0300 Subject: [PATCH 5/6] Reloadable tag support --- .../api/util/collection/WeightedList.java | 14 ++++++++ .../stationapi/api/bonemeal/BonemealAPI.java | 36 +++++++++++-------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java index 1651814fd..214796c1c 100644 --- a/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java +++ b/station-api-base/src/main/java/net/modificationstation/stationapi/api/util/collection/WeightedList.java @@ -17,6 +17,16 @@ public void add(T object, int weight) { maxWeight += weight; weights.add(maxWeight); } + + public void addAll(WeightedList list) { + objects.addAll(list.objects); + int start = weights.size(); + weights.addAll(list.weights); + for (int i = start; i < weights.size(); i++) { + weights.set(i, weights.getInt(i) + maxWeight); + } + maxWeight += list.maxWeight; + } public void clear() { objects.clear(); @@ -32,4 +42,8 @@ public T get(Random random) { } return objects.get(0); } + + public boolean isEmpty() { + return maxWeight == 0; + } } diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java index cd83ec7da..75330f6f2 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java @@ -14,34 +14,32 @@ import java.util.Random; public class BonemealAPI { - private static final Map> PLACERS = new Reference2ObjectOpenHashMap<>(); + private static final Map, WeightedList> PLACERS_TAG = new Reference2ObjectOpenHashMap<>(); + private static final Map> PLACERS_BLOCK = new Reference2ObjectOpenHashMap<>(); + private static final WeightedList CACHE = new WeightedList<>(); public static void addPlant(BlockState ground, BlockState plant, int weight) { addPlant(ground, new SimpleStateStructure(plant), weight); } public static void addPlant(BlockState ground, Structure plant, int weight) { - PLACERS.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); + PLACERS_BLOCK.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); } public static void addPlant(TagKey ground, BlockState plant, int weight) { - BlockRegistry.INSTANCE.forEach(blockBase -> - blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) - ); + addPlant(ground, new SimpleStateStructure(plant), weight); } public static void addPlant(TagKey ground, Structure plant, int weight) { - BlockRegistry.INSTANCE.forEach(blockBase -> - blockBase.getStateManager().getStates().stream().filter(state -> state.isIn(ground)).forEach(state -> addPlant(state, plant, weight)) - ); + PLACERS_TAG.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); } public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { - WeightedList structures = PLACERS.get(state); - if (structures == null) return false; + updateCache(state); + if (CACHE.isEmpty()) return false; Random random = level.rand; Direction offset = Direction.byId(side); - structures.get(random).generate( + CACHE.get(random).generate( level, random, x + offset.getOffsetX(), @@ -53,13 +51,23 @@ public static boolean generate(Level level, int x, int y, int z, BlockState stat int py = y + random.nextInt(5) - 2; int pz = z + random.nextInt(7) - 3; state = level.getBlockState(px, py, pz); - structures = PLACERS.get(state); - if (structures == null) continue; - structures.get(random).generate(level, random, px, py + 1, pz); + updateCache(state); + if (CACHE.isEmpty()) continue; + CACHE.get(random).generate(level, random, px, py + 1, pz); } return true; } + private static void updateCache(BlockState state) { + CACHE.clear(); + WeightedList structures = PLACERS_BLOCK.get(state); + if (structures != null) CACHE.addAll(structures); + state.streamTags().forEach(tag -> { + WeightedList tagStructures = PLACERS_TAG.get(tag); + if (tagStructures != null) CACHE.addAll(tagStructures); + }); + } + private static class SimpleStateStructure extends Structure { private final BlockState state; From a82d8f5d1c0b3f71916acd2813dddf3b2282cf5b Mon Sep 17 00:00:00 2001 From: mineLdiver Date: Sat, 4 Nov 2023 02:02:16 +0500 Subject: [PATCH 6/6] Reindented code --- .../stationapi/api/bonemeal/BonemealAPI.java | 190 +++++++++--------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java index 75330f6f2..c75fa8448 100644 --- a/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java +++ b/station-items-v0/src/main/java/net/modificationstation/stationapi/api/bonemeal/BonemealAPI.java @@ -14,99 +14,99 @@ import java.util.Random; public class BonemealAPI { - private static final Map, WeightedList> PLACERS_TAG = new Reference2ObjectOpenHashMap<>(); - private static final Map> PLACERS_BLOCK = new Reference2ObjectOpenHashMap<>(); - private static final WeightedList CACHE = new WeightedList<>(); - - public static void addPlant(BlockState ground, BlockState plant, int weight) { - addPlant(ground, new SimpleStateStructure(plant), weight); - } - - public static void addPlant(BlockState ground, Structure plant, int weight) { - PLACERS_BLOCK.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); - } - - public static void addPlant(TagKey ground, BlockState plant, int weight) { - addPlant(ground, new SimpleStateStructure(plant), weight); - } - - public static void addPlant(TagKey ground, Structure plant, int weight) { - PLACERS_TAG.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); - } - - public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { - updateCache(state); - if (CACHE.isEmpty()) return false; - Random random = level.rand; - Direction offset = Direction.byId(side); - CACHE.get(random).generate( - level, - random, - x + offset.getOffsetX(), - y + offset.getOffsetY(), - z + offset.getOffsetZ() - ); - for (byte i = 0; i < 127; i++) { - int px = x + random.nextInt(7) - 3; - int py = y + random.nextInt(5) - 2; - int pz = z + random.nextInt(7) - 3; - state = level.getBlockState(px, py, pz); - updateCache(state); - if (CACHE.isEmpty()) continue; - CACHE.get(random).generate(level, random, px, py + 1, pz); - } - return true; - } - - private static void updateCache(BlockState state) { - CACHE.clear(); - WeightedList structures = PLACERS_BLOCK.get(state); - if (structures != null) CACHE.addAll(structures); - state.streamTags().forEach(tag -> { - WeightedList tagStructures = PLACERS_TAG.get(tag); - if (tagStructures != null) CACHE.addAll(tagStructures); - }); - } - - private static class SimpleStateStructure extends Structure { - private final BlockState state; - - private SimpleStateStructure(BlockState state) { - this.state = state; - } - - @Override - public boolean generate(Level level, Random random, int x, int y, int z) { - BlockState levelState = level.getBlockState(x, y, z); - if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; - if (state.getBlock().canPlaceAt(level, x, y, z)) { - level.setBlockState(x, y, z, state); - return true; - } - return false; - } - } - - private static class GrassStructure extends Structure { - private static final BlockState STATE = BlockBase.TALLGRASS.getDefaultState(); - - @Override - public boolean generate(Level level, Random random, int x, int y, int z) { - BlockState levelState = level.getBlockState(x, y, z); - if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; - if (STATE.getBlock().canPlaceAt(level, x, y, z)) { - level.setBlockState(x, y, z, STATE); - level.setTileMeta(x, y, z, 1); - return true; - } - return false; - } - } - - static { - BlockState grass = BlockBase.GRASS.getDefaultState(); - addPlant(grass, new GrassStructure(), 10); - addPlant(grass, BlockBase.DANDELION.getDefaultState(), 1); - addPlant(grass, BlockBase.ROSE.getDefaultState(), 1); - } + private static final Map, WeightedList> PLACERS_TAG = new Reference2ObjectOpenHashMap<>(); + private static final Map> PLACERS_BLOCK = new Reference2ObjectOpenHashMap<>(); + private static final WeightedList CACHE = new WeightedList<>(); + + public static void addPlant(BlockState ground, BlockState plant, int weight) { + addPlant(ground, new SimpleStateStructure(plant), weight); + } + + public static void addPlant(BlockState ground, Structure plant, int weight) { + PLACERS_BLOCK.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); + } + + public static void addPlant(TagKey ground, BlockState plant, int weight) { + addPlant(ground, new SimpleStateStructure(plant), weight); + } + + public static void addPlant(TagKey ground, Structure plant, int weight) { + PLACERS_TAG.computeIfAbsent(ground, g -> new WeightedList<>()).add(plant, weight); + } + + public static boolean generate(Level level, int x, int y, int z, BlockState state, int side) { + updateCache(state); + if (CACHE.isEmpty()) return false; + Random random = level.rand; + Direction offset = Direction.byId(side); + CACHE.get(random).generate( + level, + random, + x + offset.getOffsetX(), + y + offset.getOffsetY(), + z + offset.getOffsetZ() + ); + for (byte i = 0; i < 127; i++) { + int px = x + random.nextInt(7) - 3; + int py = y + random.nextInt(5) - 2; + int pz = z + random.nextInt(7) - 3; + state = level.getBlockState(px, py, pz); + updateCache(state); + if (CACHE.isEmpty()) continue; + CACHE.get(random).generate(level, random, px, py + 1, pz); + } + return true; + } + + private static void updateCache(BlockState state) { + CACHE.clear(); + WeightedList structures = PLACERS_BLOCK.get(state); + if (structures != null) CACHE.addAll(structures); + state.streamTags().forEach(tag -> { + WeightedList tagStructures = PLACERS_TAG.get(tag); + if (tagStructures != null) CACHE.addAll(tagStructures); + }); + } + + private static class SimpleStateStructure extends Structure { + private final BlockState state; + + private SimpleStateStructure(BlockState state) { + this.state = state; + } + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (state.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, state); + return true; + } + return false; + } + } + + private static class GrassStructure extends Structure { + private static final BlockState STATE = BlockBase.TALLGRASS.getDefaultState(); + + @Override + public boolean generate(Level level, Random random, int x, int y, int z) { + BlockState levelState = level.getBlockState(x, y, z); + if (!levelState.isAir() && !levelState.getMaterial().isLiquid()) return false; + if (STATE.getBlock().canPlaceAt(level, x, y, z)) { + level.setBlockState(x, y, z, STATE); + level.setTileMeta(x, y, z, 1); + return true; + } + return false; + } + } + + static { + BlockState grass = BlockBase.GRASS.getDefaultState(); + addPlant(grass, new GrassStructure(), 10); + addPlant(grass, BlockBase.DANDELION.getDefaultState(), 1); + addPlant(grass, BlockBase.ROSE.getDefaultState(), 1); + } }