diff --git a/paper-api/src/main/java/io/papermc/paper/event/entity/CopperGolemWeatheringEvent.java b/paper-api/src/main/java/io/papermc/paper/event/entity/CopperGolemWeatheringEvent.java new file mode 100644 index 000000000000..ca6e3bc62547 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/CopperGolemWeatheringEvent.java @@ -0,0 +1,77 @@ +package io.papermc.paper.event.entity; + +import io.papermc.paper.world.WeatheringCopperState; +import org.bukkit.entity.CopperGolem; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Called when a {@link CopperGolem} transitions from one {@link WeatheringCopperState} to another. + */ +@NullMarked +public class CopperGolemWeatheringEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + + private final WeatheringCopperState currentWeatherState; + private final WeatheringCopperState nextWeatherState; + + private boolean cancelled; + + @ApiStatus.Internal + public CopperGolemWeatheringEvent(final CopperGolem golem, final WeatheringCopperState currentWeatherState, final WeatheringCopperState nextWeatherState) { + super(golem); + this.currentWeatherState = currentWeatherState; + this.nextWeatherState = nextWeatherState; + } + + /** + * Gets the copper golem entity that is about to weather. + * + * @return The copper golem entity about to weather. + */ + @Override + public CopperGolem getEntity() { + return (CopperGolem) super.getEntity(); + } + + /** + * Gets the current weathering state of the copper golem. + * + * @return The current weathering state. + */ + public WeatheringCopperState getCurrentWeatheringState() { + return currentWeatherState; + } + + /** + * Gets the next weathering state the copper golem will transition to. + * + * @return The next weathering state. + */ + public WeatheringCopperState getNextWeatheringState() { + return nextWeatherState; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java.patch index 67806aa82794..0692e975493f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java.patch @@ -37,6 +37,41 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, hand); } +@@ -245,6 +_,14 @@ + if (itemInHand.is(ItemTags.AXES)) { + WeatheringCopper.WeatherState weatherState = this.getWeatherState(); + if (weatherState != WeatheringCopper.WeatherState.UNAFFECTED) { ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent( ++ (org.bukkit.entity.CopperGolem) this.getBukkitEntity(), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.previous().name()) ++ ); ++ if (!event.callEvent()) return InteractionResult.FAIL; ++ // Paper end - CopperGolemWeatheringEvent + level.playSound(null, this, SoundEvents.AXE_SCRAPE, this.getSoundSource(), 1.0F, 1.0F); + level.levelEvent(this, LevelEvent.PARTICLES_SCRAPE, this.blockPosition(), 0); + this.nextWeatheringTick = -1L; +@@ -267,9 +_,18 @@ + boolean flag = weatherState.equals(WeatheringCopper.WeatherState.OXIDIZED); + if (gameTime >= this.nextWeatheringTick && !flag) { + WeatheringCopper.WeatherState weatherState1 = weatherState.next(); ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent( ++ (org.bukkit.entity.CopperGolem) this.getBukkitEntity(), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState1.name()) ++ ); ++ event.callEvent(); ++ // Paper end - CopperGolemWeatheringEvent + boolean flag1 = weatherState1.equals(WeatheringCopper.WeatherState.OXIDIZED); +- this.setWeatherState(weatherState1); ++ if (!event.isCancelled()) this.setWeatherState(weatherState1); // Paper - CopperGolemWeatheringEvent + this.nextWeatheringTick = flag1 ? 0L : this.nextWeatheringTick + random.nextIntBetweenInclusive(504000, 552000); ++ if (event.isCancelled()) return; // Paper - CopperGolemWeatheringEvent + } + + if (flag && this.canTurnToStatue(level)) { @@ -285,20 +_,27 @@ private void turnToStatue(ServerLevel level) { @@ -124,3 +159,18 @@ } @Override +@@ -461,6 +_,14 @@ + this.lastLightningBoltUUID = uuid; + WeatheringCopper.WeatherState weatherState = this.getWeatherState(); + if (weatherState != WeatheringCopper.WeatherState.UNAFFECTED) { ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent( ++ (org.bukkit.entity.CopperGolem) this.getBukkitEntity(), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()), ++ io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.previous().name()) ++ ); ++ if (!event.callEvent()) return; ++ // Paper end - CopperGolemWeatheringEvent + this.nextWeatheringTick = -1L; + this.entityData.set(DATA_WEATHER_STATE, weatherState.previous(), true); + }