diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java index 5bcc8f5b..98671c2b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java @@ -44,9 +44,10 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ExperienceOrb; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MoverType; -import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.animal.Bucketable; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.ChatVisiblity; import net.minecraft.world.entity.projectile.AbstractArrow; @@ -1174,8 +1175,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB cserver.getPluginManager().callEvent(event); // Fish bucket - SPIGOT-4048 - if ((entity instanceof AbstractFish && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) { - send(new ClientboundAddMobPacket((AbstractFish) entity)); + if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) { + send(new ClientboundAddMobPacket((LivingEntity) entity)); player.containerMenu.sendAllDataToRemote(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java index 6160908f..409d01fc 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java @@ -278,6 +278,16 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri this.forceDrops = true; } + @Inject(method = "restoreLeashFromSave", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Mob;spawnAtLocation(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/entity/item/ItemEntity;")) + private void arclight$leashRestorePost(CallbackInfo ci) { + this.forceDrops = false; + } + + @Inject(method = "restoreLeashFromSave", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;spawnAtLocation(Lnet/minecraft/world/level/ItemLike;)Lnet/minecraft/world/entity/item/ItemEntity;")) + private void arclight$leashRestorePre(CallbackInfo ci) { + this.forceDrops = true; + } + @Inject(method = "startRiding", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;dropLeash(ZZ)V")) private void arclight$unleashRide(Entity entityIn, boolean force, CallbackInfoReturnable cir) { Bukkit.getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.UNKNOWN)); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java index 1b8a9f6a..1e2385ef 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java @@ -30,12 +30,21 @@ public abstract class VillagerMixin extends AbstractVillagerMixin { bridge$pushEffectCause(EntityPotionEffectEvent.Cause.VILLAGER_TRADE); } - @Redirect(method = "updateSpecialPrices", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/item/trading/MerchantOffer;addToSpecialPriceDiff(I)V")) - private void arclight$replenish(MerchantOffer merchantOffer, int add) { - VillagerReplenishTradeEvent event = new VillagerReplenishTradeEvent((Villager) this.getBukkitEntity(), ((MerchantOfferBridge) merchantOffer).bridge$asBukkit(), add); + @Redirect(method = "restock", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/trading/MerchantOffer;resetUses()V")) + private void arclight$restock(MerchantOffer instance) { + VillagerReplenishTradeEvent event = new VillagerReplenishTradeEvent((Villager) this.getBukkitEntity(), ((MerchantOfferBridge) instance).bridge$asBukkit()); Bukkit.getPluginManager().callEvent(event); if (!event.isCancelled()) { - merchantOffer.addToSpecialPriceDiff(event.getBonus()); + instance.resetUses(); + } + } + + @Redirect(method = "updateSpecialPrices", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/item/trading/MerchantOffer;addToSpecialPriceDiff(I)V")) + private void arclight$replenish(MerchantOffer merchantOffer, int add) { + VillagerReplenishTradeEvent event = new VillagerReplenishTradeEvent((Villager) this.getBukkitEntity(), ((MerchantOfferBridge) merchantOffer).bridge$asBukkit()); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + merchantOffer.resetUses(); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java new file mode 100644 index 00000000..8cc2567f --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java @@ -0,0 +1,64 @@ +package io.izzel.arclight.common.mixin.core.world.level.gameevent.vibrations; + +import io.izzel.arclight.common.bridge.core.entity.EntityBridge; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.level.gameevent.PositionSource; +import net.minecraft.world.level.gameevent.vibrations.VibrationListener; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.util.CraftNamespacedKey; +import org.bukkit.event.block.BlockReceiveGameEvent; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; +import java.util.Optional; + +@Mixin(VibrationListener.class) +public abstract class VibrationListenerMixin { + + // @formatter:off + @Shadow protected abstract boolean isValidVibration(GameEvent p_157917_, @org.jetbrains.annotations.Nullable Entity p_157918_); + @Shadow @Final protected PositionSource listenerSource; + @Shadow @Final protected VibrationListener.VibrationListenerConfig config; + @Shadow protected abstract boolean isOccluded(Level p_157911_, BlockPos p_157912_, BlockPos p_157913_); + @Shadow protected abstract void sendSignal(Level p_157906_, GameEvent p_157907_, BlockPos p_157908_, BlockPos p_157909_); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public boolean handleGameEvent(Level level, GameEvent gameEvent, @Nullable Entity entity, BlockPos pos) { + if (!this.isValidVibration(gameEvent, entity)) { + return false; + } else { + Optional optional = this.listenerSource.getPosition(level); + if (!optional.isPresent()) { + return false; + } else { + BlockPos blockpos = optional.get(); + var cancelled = !this.config.shouldListen(level, (VibrationListener) (Object) this, pos, gameEvent, entity); + BlockReceiveGameEvent event = new BlockReceiveGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), + CraftBlock.at(level, blockpos), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity()); + event.setCancelled(cancelled); + Bukkit.getPluginManager().callEvent(event); + if (cancelled) { + return false; + } else if (this.isOccluded(level, pos, blockpos)) { + return false; + } else { + this.sendSignal(level, gameEvent, pos, blockpos); + return true; + } + } + } + } +} diff --git a/arclight-common/src/main/resources/mixins.arclight.core.json b/arclight-common/src/main/resources/mixins.arclight.core.json index d79160ba..6802eb6a 100644 --- a/arclight-common/src/main/resources/mixins.arclight.core.json +++ b/arclight-common/src/main/resources/mixins.arclight.core.json @@ -429,6 +429,7 @@ "world.level.chunk.storage.ChunkSerializerMixin", "world.level.chunk.storage.RegionFileCacheMixin", "world.level.entity.PersistentEntitySectionManagerMixin", + "world.level.gameevent.vibrations.VibrationListenerMixin", "world.level.levelgen.ChunkGeneratorMixin", "world.level.portal.PortalForcerMixin", "world.level.saveddata.maps.MapDataMixin",