From 2c965fac902fa0e4c092cc5331b658df637637e4 Mon Sep 17 00:00:00 2001 From: bconlon <67203206+bconlon1@users.noreply.github.com> Date: Thu, 13 Jul 2023 17:29:03 -0700 Subject: [PATCH] AlterGroundEvent for modifying block placement performed by AlterGroundDecorator (#9637) --- .../AlterGroundDecorator.java.patch | 11 +++ .../event/ForgeEventFactory.java | 9 +++ .../event/level/AlterGroundEvent.java | 79 +++++++++++++++++++ .../debug/AlterGroundEventTest.java | 27 +++++++ src/test/resources/META-INF/mods.toml | 2 + 5 files changed, 128 insertions(+) create mode 100644 patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch create mode 100644 src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java create mode 100644 src/test/java/net/minecraftforge/debug/AlterGroundEventTest.java diff --git a/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch b/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch new file mode 100644 index 0000000000..00200b48fe --- /dev/null +++ b/patches/minecraft/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java ++++ b/net/minecraft/world/level/levelgen/feature/treedecorators/AlterGroundDecorator.java +@@ -72,7 +_,7 @@ + for(int i = 2; i >= -3; --i) { + BlockPos blockpos = p_225975_.m_6630_(i); + if (Feature.m_65788_(p_225974_.m_226058_(), blockpos)) { +- p_225974_.m_226061_(blockpos, this.f_69303_.m_213972_(p_225974_.m_226067_(), p_225975_)); ++ p_225974_.m_226061_(blockpos, net.minecraftforge.event.ForgeEventFactory.alterGround(p_225974_.m_226058_(), p_225974_.m_226067_(), blockpos, this.f_69303_.m_213972_(p_225974_.m_226067_(), p_225975_))); + break; + } + diff --git a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java index ce71e67150..c11d66123c 100644 --- a/src/main/java/net/minecraftforge/event/ForgeEventFactory.java +++ b/src/main/java/net/minecraftforge/event/ForgeEventFactory.java @@ -30,6 +30,7 @@ import net.minecraft.world.DifficultyInstance; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.ThrownEnderpearl; +import net.minecraft.world.level.LevelSimulatedReader; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; @@ -128,6 +129,7 @@ import net.minecraftforge.event.entity.player.PlayerWakeUpEvent; import net.minecraftforge.event.entity.player.SleepingLocationCheckEvent; import net.minecraftforge.event.entity.player.SleepingTimeCheckEvent; import net.minecraftforge.event.furnace.FurnaceFuelBurnTimeEvent; +import net.minecraftforge.event.level.AlterGroundEvent; import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.event.level.BlockEvent.BlockToolModificationEvent; import net.minecraftforge.event.level.BlockEvent.CreateFluidSourceEvent; @@ -737,6 +739,13 @@ public class ForgeEventFactory return event; } + public static BlockState alterGround(LevelSimulatedReader level, RandomSource random, BlockPos pos, BlockState altered) + { + AlterGroundEvent event = new AlterGroundEvent(level, random, pos, altered); + MinecraftForge.EVENT_BUS.post(event); + return event.getNewAlteredState(); + } + public static void fireChunkTicketLevelUpdated(ServerLevel level, long chunkPos, int oldTicketLevel, int newTicketLevel, @Nullable ChunkHolder chunkHolder) { if (oldTicketLevel != newTicketLevel) diff --git a/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java b/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java new file mode 100644 index 0000000000..5c4d60599e --- /dev/null +++ b/src/main/java/net/minecraftforge/event/level/AlterGroundEvent.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.event.level; + +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LevelSimulatedReader; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.feature.treedecorators.TreeDecorator; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; +import org.jetbrains.annotations.ApiStatus; + +/** + * This event is fired when {@link net.minecraft.world.level.levelgen.feature.treedecorators.AlterGroundDecorator#placeBlockAt(TreeDecorator.Context, BlockPos)} + * attempts to alter a ground block when generating a feature. An example of this would be large spruce trees converting grass blocks into podzol. + *
+ * This event is not {@linkplain Cancelable cancellable}. + *
+ * This event is fired on the {@linkplain MinecraftForge#EVENT_BUS main Forge event bus} + * only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}. + */ +public class AlterGroundEvent extends Event { + private final LevelSimulatedReader level; + private final RandomSource random; + private final BlockPos pos; + private final BlockState originalAltered; + private BlockState newAltered; + + @ApiStatus.Internal + public AlterGroundEvent(LevelSimulatedReader level, RandomSource random, BlockPos pos, BlockState altered) { + super(); + this.level = level; + this.random = random; + this.pos = pos; + this.originalAltered = altered; + this.newAltered = altered; + } + + public LevelSimulatedReader getLevel() { + return this.level; + } + + public RandomSource getRandom() { + return this.random; + } + + /** + * {@return the position of the block that will be altered} + */ + public BlockPos getPos() { + return this.pos; + } + + /** + * {@return the original block state that would be placed by the ground decorator} + */ + public BlockState getOriginalAlteredState() { + return this.originalAltered; + } + + /** + * {@return the new block state to be placed by the ground decorator} + */ + public BlockState getNewAlteredState() { + return this.newAltered; + } + + /** + * @param newAltered the new block state to be placed by the ground decorator + */ + public void setNewAlteredState(BlockState newAltered) { + this.newAltered = newAltered; + } +} \ No newline at end of file diff --git a/src/test/java/net/minecraftforge/debug/AlterGroundEventTest.java b/src/test/java/net/minecraftforge/debug/AlterGroundEventTest.java new file mode 100644 index 0000000000..e733b010ab --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/AlterGroundEventTest.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.debug; + +import net.minecraft.world.level.block.Blocks; +import net.minecraftforge.event.level.AlterGroundEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod("alter_ground_event_test") +@Mod.EventBusSubscriber +public class AlterGroundEventTest { + public static final boolean ENABLE = true; + + @SubscribeEvent + public static void onAlterGround(AlterGroundEvent event) + { + if (ENABLE) { + if (event.getOriginalAlteredState().is(Blocks.PODZOL)) { + event.setNewAlteredState(Blocks.REDSTONE_BLOCK.defaultBlockState()); + } + } + } +} \ No newline at end of file diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index 751ba90319..ca5d5a1a94 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -295,5 +295,7 @@ modId="trade_with_villager_event_test" modId="chunk_event_load_new_chunk_test" [[mods]] modId="custom_fluid_container_test" +[[mods]] +modId="alter_ground_event_test" # ADD ABOVE THIS LINE