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..5500c0569120 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/event/entity/CopperGolemWeatheringEvent.java @@ -0,0 +1,106 @@ +package io.papermc.paper.event.entity; + +import io.papermc.paper.world.WeatheringCopperState; +import org.bukkit.entity.CopperGolem; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Called when a Copper Golem's Weathering State changes. + */ +public class CopperGolemWeatheringEvent extends EntityEvent implements Cancellable { + + private static final HandlerList HANDLER_LIST = new HandlerList(); + private final WeatheringCopperState weatheringCopperState; + private final WeatheringCopperState previousWeatheringCopperState; + private final Reason reason; + private final Player player; + private boolean cancelled; + + public CopperGolemWeatheringEvent(final @NotNull Entity entity, final @NotNull WeatheringCopperState weatheringCopperState, final @NotNull WeatheringCopperState previousWeatheringCopperState, final @NotNull Reason reason, final @Nullable Player player) { + super(entity); + this.weatheringCopperState = weatheringCopperState; + this.previousWeatheringCopperState = previousWeatheringCopperState; + this.reason = reason; + this.player = player; + } + + /** + * Gets the new copper golem's weathering state + * @return new weathering state + * @see CopperGolem#getWeatheringState() + */ + @NotNull + public WeatheringCopperState getWeatheringCopperState() { + return this.weatheringCopperState; + } + + /** + * Gets the previous copper golem's weathering state + * @return previous weathering state + * @see CopperGolem#getWeatheringState() + */ + @NotNull + public WeatheringCopperState getPreviousWeatheringCopperState() { + return this.previousWeatheringCopperState; + } + + /** + * Gets the reason for the weathering change. + * + * @return the reason + */ + @NotNull + public Reason getReason() { + return this.reason; + } + + /** + * Gets the player involved in the weathering change, if applicable. + * + * @return the player or null + */ + @Nullable + public Player getPlayer() { + return this.player; + } + + @Override + @NotNull + public CopperGolem getEntity() { + return (CopperGolem) super.getEntity(); + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } + + @Override + @NotNull + public HandlerList getHandlers() { + return HANDLER_LIST; + } + + @NotNull + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + public enum Reason { + NATURAL, + AXE, + LIGHTNING, + OTHER + } +} diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/golem/CopperGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/golem/CopperGolem.java.patch index 51f378361e74..85d76f3735fa 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/golem/CopperGolem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/golem/CopperGolem.java.patch @@ -37,6 +37,40 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, hand); } +@@ -242,6 +_,14 @@ + if (itemInHand.is(ItemTags.AXES)) { + WeatheringCopper.WeatherState weatherState = this.getWeatherState(); + if (weatherState != WeatheringCopper.WeatherState.UNAFFECTED) { ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.world.WeatheringCopperState currentState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()); ++ io.papermc.paper.world.WeatheringCopperState nextState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.previous().name()); ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent(this.getBukkitEntity(), nextState, currentState, io.papermc.paper.event.entity.CopperGolemWeatheringEvent.Reason.AXE, (org.bukkit.entity.Player) player.getBukkitEntity()); if (!event.callEvent()) { ++ return InteractionResult.PASS; ++ } ++ // 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; +@@ -264,6 +_,18 @@ + boolean flag = weatherState.equals(WeatheringCopper.WeatherState.OXIDIZED); + if (gameTime >= this.nextWeatheringTick && !flag) { + WeatheringCopper.WeatherState weatherState1 = weatherState.next(); ++ ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.world.WeatheringCopperState currentState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()); ++ io.papermc.paper.world.WeatheringCopperState nextState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState1.name()); ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent(this.getBukkitEntity(), nextState, currentState, io.papermc.paper.event.entity.CopperGolemWeatheringEvent.Reason.NATURAL, null); ++ ++ if (!event.callEvent()) { ++ this.nextWeatheringTick = gameTime + random.nextIntBetweenInclusive(504000, 552000); ++ return; ++ } ++ // Paper end - CopperGolemWeatheringEvent ++ + boolean flag1 = weatherState1.equals(WeatheringCopper.WeatherState.OXIDIZED); + this.setWeatherState(weatherState1); + this.nextWeatheringTick = flag1 ? 0L : this.nextWeatheringTick + random.nextIntBetweenInclusive(504000, 552000); @@ -282,20 +_,27 @@ private void turnToStatue(ServerLevel level) { @@ -124,3 +158,18 @@ } @Override +@@ -457,6 +_,14 @@ + this.lastLightningBoltUUID = uuid; + WeatheringCopper.WeatherState weatherState = this.getWeatherState(); + if (weatherState != WeatheringCopper.WeatherState.UNAFFECTED) { ++ // Paper start - CopperGolemWeatheringEvent ++ io.papermc.paper.world.WeatheringCopperState currentState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.name()); ++ io.papermc.paper.world.WeatheringCopperState nextState = io.papermc.paper.world.WeatheringCopperState.valueOf(weatherState.previous().name()); ++ io.papermc.paper.event.entity.CopperGolemWeatheringEvent event = new io.papermc.paper.event.entity.CopperGolemWeatheringEvent(this.getBukkitEntity(), nextState, currentState, io.papermc.paper.event.entity.CopperGolemWeatheringEvent.Reason.LIGHTNING, null); ++ if (!event.callEvent()) { ++ return; ++ } ++ // Paper end - CopperGolemWeatheringEvent + this.nextWeatheringTick = -1L; + this.entityData.set(DATA_WEATHER_STATE, weatherState.previous(), true); + }