diff options
author | MiniDigger | Martin <[email protected]> | 2024-01-14 11:04:49 +0100 |
---|---|---|
committer | MiniDigger | Martin <[email protected]> | 2024-01-14 11:04:49 +0100 |
commit | bee74680e607c2e29b038329f62181238911cd83 (patch) | |
tree | 708fd1a4a0227d9071243adf2a42d5e9e96cde4a /patch-remap/mache-vineflower/net/minecraft/world/item | |
parent | 0a44692ef6ff6e255d48eb3ba1bb114166eafda9 (diff) | |
download | Paper-softspoon.tar.gz Paper-softspoon.zip |
add remapped patches as a testsoftspoon
Diffstat (limited to 'patch-remap/mache-vineflower/net/minecraft/world/item')
49 files changed, 8672 insertions, 0 deletions
diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorItem.java.patch new file mode 100644 index 0000000000..8e4d6b77b1 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorItem.java.patch @@ -0,0 +1,176 @@ +--- a/net/minecraft/world/item/ArmorItem.java ++++ b/net/minecraft/world/item/ArmorItem.java +@@ -1,18 +1,19 @@ + package net.minecraft.world.item; + + import com.google.common.collect.ImmutableMultimap; +-import com.google.common.collect.Multimap; + import com.google.common.collect.ImmutableMultimap.Builder; ++import com.google.common.collect.Multimap; + import java.util.EnumMap; + import java.util.List; + import java.util.UUID; + import net.minecraft.Util; + import net.minecraft.core.BlockPos; +-import net.minecraft.core.dispenser.BlockSource; ++import net.minecraft.core.Direction; + import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; + import net.minecraft.core.dispenser.DispenseItemBehavior; ++import net.minecraft.core.dispenser.SourceBlock; + import net.minecraft.sounds.SoundEvent; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.EntitySelector; + import net.minecraft.world.entity.EquipmentSlot; +@@ -25,18 +26,24 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.DispenserBlock; + import net.minecraft.world.phys.AABB; ++// CraftBukkit start ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseArmorEvent; ++// CraftBukkit end + + public class ArmorItem extends Item implements Equipable { +- private static final EnumMap<ArmorItem.Type, UUID> ARMOR_MODIFIER_UUID_PER_TYPE = Util.make(new EnumMap<>(ArmorItem.Type.class), map -> { +- map.put(ArmorItem.Type.BOOTS, UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B")); +- map.put(ArmorItem.Type.LEGGINGS, UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D")); +- map.put(ArmorItem.Type.CHESTPLATE, UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E")); +- map.put(ArmorItem.Type.HELMET, UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")); ++ ++ private static final EnumMap<ArmorItem.Type, UUID> ARMOR_MODIFIER_UUID_PER_TYPE = (EnumMap) Util.make(new EnumMap(ArmorItem.Type.class), (enummap) -> { ++ enummap.put(ArmorItem.Type.BOOTS, UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B")); ++ enummap.put(ArmorItem.Type.LEGGINGS, UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D")); ++ enummap.put(ArmorItem.Type.CHESTPLATE, UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E")); ++ enummap.put(ArmorItem.Type.HELMET, UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")); + }); + public static final DispenseItemBehavior DISPENSE_ITEM_BEHAVIOR = new DefaultDispenseItemBehavior() { + @Override +- protected ItemStack execute(BlockSource blockSource, ItemStack itemStack) { +- return ArmorItem.dispenseArmor(blockSource, itemStack) ? itemStack : super.execute(blockSource, itemStack); ++ protected ItemStack execute(SourceBlock sourceblock, ItemStack itemstack) { ++ return ArmorItem.dispenseArmor(sourceblock, itemstack) ? itemstack : super.execute(sourceblock, itemstack); + } + }; + protected final ArmorItem.Type type; +@@ -46,24 +53,49 @@ + protected final ArmorMaterial material; + private final Multimap<Attribute, AttributeModifier> defaultModifiers; + +- public static boolean dispenseArmor(BlockSource blockSource, ItemStack itemStack) { +- BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING)); +- List<LivingEntity> entitiesOfClass = blockSource.level() +- .getEntitiesOfClass( +- LivingEntity.class, new AABB(blockPos), EntitySelector.NO_SPECTATORS.and(new EntitySelector.MobCanWearArmorEntitySelector(itemStack)) +- ); +- if (entitiesOfClass.isEmpty()) { ++ public static boolean dispenseArmor(SourceBlock sourceblock, ItemStack itemstack) { ++ BlockPos blockposition = sourceblock.pos().relative((Direction) sourceblock.state().getValue(DispenserBlock.FACING)); ++ List<LivingEntity> list = sourceblock.level().getEntitiesOfClass(LivingEntity.class, new AABB(blockposition), EntitySelector.NO_SPECTATORS.and(new EntitySelector.MobCanWearArmorEntitySelector(itemstack))); ++ ++ if (list.isEmpty()) { + return false; + } else { +- LivingEntity livingEntity = entitiesOfClass.get(0); +- EquipmentSlot equipmentSlotForItem = Mob.getEquipmentSlotForItem(itemStack); +- ItemStack itemStack1 = itemStack.split(1); +- livingEntity.setItemSlot(equipmentSlotForItem, itemStack1); +- if (livingEntity instanceof Mob) { +- ((Mob)livingEntity).setDropChance(equipmentSlotForItem, 2.0F); +- ((Mob)livingEntity).setPersistenceRequired(); ++ LivingEntity entityliving = (LivingEntity) list.get(0); ++ EquipmentSlot enumitemslot = Mob.getEquipmentSlotForItem(itemstack); ++ ItemStack itemstack1 = itemstack.split(1); ++ // CraftBukkit start ++ Level world = sourceblock.level(); ++ org.bukkit.block.Block block = CraftBlock.at(world, sourceblock.pos()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseArmorEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) entityliving.getBukkitEntity()); ++ if (!DispenserBlock.eventFired) { ++ world.getCraftServer().getPluginManager().callEvent(event); + } + ++ if (event.isCancelled()) { ++ itemstack.grow(1); ++ return false; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.grow(1); ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != ArmorItem.DISPENSE_ITEM_BEHAVIOR) { ++ idispensebehavior.dispense(sourceblock, eventStack); ++ return true; ++ } ++ } ++ ++ entityliving.setItemSlot(enumitemslot, CraftItemStack.asNMSCopy(event.getItem())); ++ // CraftBukkit end ++ if (entityliving instanceof Mob) { ++ ((Mob) entityliving).setDropChance(enumitemslot, 2.0F); ++ ((Mob) entityliving).setPersistenceRequired(); ++ } ++ + return true; + } + } +@@ -75,16 +107,14 @@ + this.defense = material.getDefenseForType(type); + this.toughness = material.getToughness(); + this.knockbackResistance = material.getKnockbackResistance(); +- DispenserBlock.registerBehavior(this, DISPENSE_ITEM_BEHAVIOR); ++ DispenserBlock.registerBehavior(this, ArmorItem.DISPENSE_ITEM_BEHAVIOR); + Builder<Attribute, AttributeModifier> builder = ImmutableMultimap.builder(); +- UUID uUID = ARMOR_MODIFIER_UUID_PER_TYPE.get(type); +- builder.put(Attributes.ARMOR, new AttributeModifier(uUID, "Armor modifier", (double)this.defense, AttributeModifier.Operation.ADDITION)); +- builder.put(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(uUID, "Armor toughness", (double)this.toughness, AttributeModifier.Operation.ADDITION)); ++ UUID uuid = (UUID) ArmorItem.ARMOR_MODIFIER_UUID_PER_TYPE.get(type); ++ ++ builder.put(Attributes.ARMOR, new AttributeModifier(uuid, "Armor modifier", (double) this.defense, AttributeModifier.Operation.ADDITION)); ++ builder.put(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(uuid, "Armor toughness", (double) this.toughness, AttributeModifier.Operation.ADDITION)); + if (material == ArmorMaterials.NETHERITE) { +- builder.put( +- Attributes.KNOCKBACK_RESISTANCE, +- new AttributeModifier(uUID, "Armor knockback resistance", (double)this.knockbackResistance, AttributeModifier.Operation.ADDITION) +- ); ++ builder.put(Attributes.KNOCKBACK_RESISTANCE, new AttributeModifier(uuid, "Armor knockback resistance", (double) this.knockbackResistance, AttributeModifier.Operation.ADDITION)); + } + + this.defaultModifiers = builder.build(); +@@ -109,7 +139,7 @@ + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { + return this.swapWithEquipmentSlot(this, level, player, hand); + } + +@@ -137,17 +167,15 @@ + } + + public static enum Type { +- HELMET(EquipmentSlot.HEAD, "helmet"), +- CHESTPLATE(EquipmentSlot.CHEST, "chestplate"), +- LEGGINGS(EquipmentSlot.LEGS, "leggings"), +- BOOTS(EquipmentSlot.FEET, "boots"); + ++ HELMET(EquipmentSlot.HEAD, "helmet"), CHESTPLATE(EquipmentSlot.CHEST, "chestplate"), LEGGINGS(EquipmentSlot.LEGS, "leggings"), BOOTS(EquipmentSlot.FEET, "boots"); ++ + private final EquipmentSlot slot; + private final String name; + +- private Type(EquipmentSlot slot, String name) { +- this.slot = slot; +- this.name = name; ++ private Type(EquipmentSlot enumitemslot, String s) { ++ this.slot = enumitemslot; ++ this.name = s; + } + + public EquipmentSlot getSlot() { diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorStandItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorStandItem.java.patch new file mode 100644 index 0000000000..1b400dd595 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/ArmorStandItem.java.patch @@ -0,0 +1,89 @@ +--- a/net/minecraft/world/item/ArmorStandItem.java ++++ b/net/minecraft/world/item/ArmorStandItem.java +@@ -8,9 +8,11 @@ + import net.minecraft.sounds.SoundSource; + import net.minecraft.util.Mth; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; +-import net.minecraft.world.entity.MobSpawnType; ++import net.minecraft.world.entity.EnumMobSpawn; + import net.minecraft.world.entity.decoration.ArmorStand; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.context.BlockPlaceContext; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; +@@ -19,42 +21,50 @@ + import net.minecraft.world.phys.Vec3; + + public class ArmorStandItem extends Item { ++ + public ArmorStandItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Direction clickedFace = context.getClickedFace(); +- if (clickedFace == Direction.DOWN) { ++ Direction enumdirection = context.getClickedFace(); ++ ++ if (enumdirection == Direction.DOWN) { + return InteractionResult.FAIL; + } else { +- Level level = context.getLevel(); +- BlockPlaceContext blockPlaceContext = new BlockPlaceContext(context); +- BlockPos clickedPos = blockPlaceContext.getClickedPos(); +- ItemStack itemInHand = context.getItemInHand(); +- Vec3 vec3 = Vec3.atBottomCenterOf(clickedPos); +- AABB aABB = EntityType.ARMOR_STAND.getDimensions().makeBoundingBox(vec3.x(), vec3.y(), vec3.z()); +- if (level.noCollision(null, aABB) && level.getEntities(null, aABB).isEmpty()) { +- if (level instanceof ServerLevel serverLevel) { +- Consumer<ArmorStand> consumer = EntityType.createDefaultStackConfig(serverLevel, itemInHand, context.getPlayer()); +- ArmorStand armorStand = EntityType.ARMOR_STAND +- .create(serverLevel, itemInHand.getTag(), consumer, clickedPos, MobSpawnType.SPAWN_EGG, true, true); +- if (armorStand == null) { ++ Level world = context.getLevel(); ++ BlockPlaceContext blockactioncontext = new BlockPlaceContext(context); ++ BlockPos blockposition = blockactioncontext.getClickedPos(); ++ ItemStack itemstack = context.getItemInHand(); ++ Vec3 vec3d = Vec3.atBottomCenterOf(blockposition); ++ AABB axisalignedbb = EntityType.ARMOR_STAND.getDimensions().makeBoundingBox(vec3d.x(), vec3d.y(), vec3d.z()); ++ ++ if (world.noCollision((Entity) null, axisalignedbb) && world.getEntities((Entity) null, axisalignedbb).isEmpty()) { ++ if (world instanceof ServerLevel) { ++ ServerLevel worldserver = (ServerLevel) world; ++ Consumer<ArmorStand> consumer = EntityType.createDefaultStackConfig(worldserver, itemstack, context.getPlayer()); ++ ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.create(worldserver, itemstack.getTag(), consumer, blockposition, EnumMobSpawn.SPAWN_EGG, true, true); ++ ++ if (entityarmorstand == null) { + return InteractionResult.FAIL; + } + +- float f = (float)Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F; +- armorStand.moveTo(armorStand.getX(), armorStand.getY(), armorStand.getZ(), f, 0.0F); +- serverLevel.addFreshEntityWithPassengers(armorStand); +- level.playSound( +- null, armorStand.getX(), armorStand.getY(), armorStand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F +- ); +- armorStand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer()); ++ float f = (float) Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F; ++ ++ entityarmorstand.moveTo(entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), f, 0.0F); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityarmorstand).isCancelled()) { ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end ++ worldserver.addFreshEntityWithPassengers(entityarmorstand); ++ world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F); ++ entityarmorstand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer()); + } + +- itemInHand.shrink(1); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ itemstack.shrink(1); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.FAIL; + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/BlockItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/BlockItem.java.patch new file mode 100644 index 0000000000..5230934354 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/BlockItem.java.patch @@ -0,0 +1,345 @@ +--- a/net/minecraft/world/item/BlockItem.java ++++ b/net/minecraft/world/item/BlockItem.java +@@ -1,7 +1,10 @@ + package net.minecraft.world.item; + ++import java.util.Iterator; + import java.util.List; + import java.util.Map; ++import java.util.Objects; ++import java.util.stream.Stream; + import javax.annotation.Nullable; + import net.minecraft.advancements.CriteriaTriggers; + import net.minecraft.core.BlockPos; +@@ -9,9 +12,9 @@ + import net.minecraft.nbt.ListTag; + import net.minecraft.network.chat.Component; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; +-import net.minecraft.sounds.SoundSource; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.player.Player; +@@ -24,15 +27,21 @@ + import net.minecraft.world.level.block.SoundType; + import net.minecraft.world.level.block.entity.BlockEntity; + import net.minecraft.world.level.block.entity.BlockEntityType; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.StateDefinition; + import net.minecraft.world.level.block.state.properties.Property; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.shapes.CollisionContext; ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.craftbukkit.block.data.CraftBlockData; ++import org.bukkit.event.block.BlockCanBuildEvent; ++// CraftBukkit end + + public class BlockItem extends Item { ++ + public static final String BLOCK_ENTITY_TAG = "BlockEntityTag"; + public static final String BLOCK_STATE_TAG = "BlockStateTag"; ++ /** @deprecated */ + @Deprecated + private final Block block; + +@@ -43,12 +52,14 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- InteractionResult interactionResult = this.place(new BlockPlaceContext(context)); +- if (!interactionResult.consumesAction() && this.isEdible()) { +- InteractionResult result = this.use(context.getLevel(), context.getPlayer(), context.getHand()).getResult(); +- return result == InteractionResult.CONSUME ? InteractionResult.CONSUME_PARTIAL : result; ++ InteractionResult enuminteractionresult = this.place(new BlockPlaceContext(context)); ++ ++ if (!enuminteractionresult.consumesAction() && this.isEdible()) { ++ InteractionResult enuminteractionresult1 = this.use(context.getLevel(), context.getPlayer(), context.getHand()).getResult(); ++ ++ return enuminteractionresult1 == InteractionResult.CONSUME ? InteractionResult.CONSUME_PARTIAL : enuminteractionresult1; + } else { +- return interactionResult; ++ return enuminteractionresult; + } + } + +@@ -58,51 +69,67 @@ + } else if (!context.canPlace()) { + return InteractionResult.FAIL; + } else { +- BlockPlaceContext blockPlaceContext = this.updatePlacementContext(context); +- if (blockPlaceContext == null) { ++ BlockPlaceContext blockactioncontext1 = this.updatePlacementContext(context); ++ ++ if (blockactioncontext1 == null) { + return InteractionResult.FAIL; + } else { +- BlockState placementState = this.getPlacementState(blockPlaceContext); +- if (placementState == null) { ++ IBlockData iblockdata = this.getPlacementState(blockactioncontext1); ++ // CraftBukkit start - special case for handling block placement with water lilies and snow buckets ++ org.bukkit.block.BlockState blockstate = null; ++ if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) { ++ blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); ++ } ++ // CraftBukkit end ++ ++ if (iblockdata == null) { + return InteractionResult.FAIL; +- } else if (!this.placeBlock(blockPlaceContext, placementState)) { ++ } else if (!this.placeBlock(blockactioncontext1, iblockdata)) { + return InteractionResult.FAIL; + } else { +- BlockPos clickedPos = blockPlaceContext.getClickedPos(); +- Level level = blockPlaceContext.getLevel(); +- Player player = blockPlaceContext.getPlayer(); +- ItemStack itemInHand = blockPlaceContext.getItemInHand(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (blockState.is(placementState.getBlock())) { +- blockState = this.updateBlockStateFromTag(clickedPos, level, itemInHand, blockState); +- this.updateCustomBlockEntityTag(clickedPos, level, player, itemInHand, blockState); +- blockState.getBlock().setPlacedBy(level, clickedPos, blockState, player, itemInHand); +- if (player instanceof ServerPlayer) { +- CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, clickedPos, itemInHand); ++ BlockPos blockposition = blockactioncontext1.getClickedPos(); ++ Level world = blockactioncontext1.getLevel(); ++ Player entityhuman = blockactioncontext1.getPlayer(); ++ ItemStack itemstack = blockactioncontext1.getItemInHand(); ++ IBlockData iblockdata1 = world.getBlockState(blockposition); ++ ++ if (iblockdata1.is(iblockdata.getBlock())) { ++ iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1); ++ this.updateCustomBlockEntityTag(blockposition, world, entityhuman, itemstack, iblockdata1); ++ iblockdata1.getBlock().setPlacedBy(world, blockposition, iblockdata1, entityhuman, itemstack); ++ // CraftBukkit start ++ if (blockstate != null) { ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent((ServerLevel) world, entityhuman, blockactioncontext1.getHand(), blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ blockstate.update(true, false); ++ ++ if (this instanceof SolidBucketItem) { ++ ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 ++ } ++ return InteractionResult.FAIL; ++ } + } ++ // CraftBukkit end ++ if (entityhuman instanceof ServerPlayer) { ++ CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) entityhuman, blockposition, itemstack); ++ } + } + +- SoundType soundType = blockState.getSoundType(); +- level.playSound( +- player, +- clickedPos, +- this.getPlaceSound(blockState), +- SoundSource.BLOCKS, +- (soundType.getVolume() + 1.0F) / 2.0F, +- soundType.getPitch() * 0.8F +- ); +- level.gameEvent(GameEvent.BLOCK_PLACE, clickedPos, GameEvent.Context.of(player, blockState)); +- if (player == null || !player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ SoundType soundeffecttype = iblockdata1.getSoundType(); ++ ++ // world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundCategory.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); ++ world.gameEvent(GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1)); ++ if ((entityhuman == null || !entityhuman.getAbilities().instabuild) && itemstack != ItemStack.EMPTY) { // CraftBukkit ++ itemstack.shrink(1); + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } + } + } + } + +- protected SoundEvent getPlaceSound(BlockState state) { ++ protected SoundEvent getPlaceSound(IBlockData state) { + return state.getSoundType().getPlaceSound(); + } + +@@ -111,77 +138,106 @@ + return context; + } + +- protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, @Nullable Player player, ItemStack stack, BlockState state) { ++ protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, @Nullable Player player, ItemStack stack, IBlockData state) { + return updateCustomBlockEntityTag(level, player, pos, stack); + } + + @Nullable +- protected BlockState getPlacementState(BlockPlaceContext context) { +- BlockState stateForPlacement = this.getBlock().getStateForPlacement(context); +- return stateForPlacement != null && this.canPlace(context, stateForPlacement) ? stateForPlacement : null; ++ protected IBlockData getPlacementState(BlockPlaceContext context) { ++ IBlockData iblockdata = this.getBlock().getStateForPlacement(context); ++ ++ return iblockdata != null && this.canPlace(context, iblockdata) ? iblockdata : null; + } + +- private BlockState updateBlockStateFromTag(BlockPos pos, Level level, ItemStack stack, BlockState state) { +- BlockState blockState = state; +- CompoundTag tag = stack.getTag(); +- if (tag != null) { +- CompoundTag compound = tag.getCompound("BlockStateTag"); +- StateDefinition<Block, BlockState> stateDefinition = state.getBlock().getStateDefinition(); ++ private IBlockData updateBlockStateFromTag(BlockPos pos, Level level, ItemStack stack, IBlockData state) { ++ IBlockData iblockdata1 = state; ++ CompoundTag nbttagcompound = stack.getTag(); + +- for (String string : compound.getAllKeys()) { +- Property<?> property = stateDefinition.getProperty(string); +- if (property != null) { +- String asString = compound.get(string).getAsString(); +- blockState = updateState(blockState, property, asString); +- } +- } ++ if (nbttagcompound != null) { ++ CompoundTag nbttagcompound1 = nbttagcompound.getCompound("BlockStateTag"); ++ // CraftBukkit start ++ iblockdata1 = getBlockState(iblockdata1, nbttagcompound1); + } + +- if (blockState != state) { +- level.setBlock(pos, blockState, 2); ++ if (iblockdata1 != state) { ++ level.setBlock(pos, iblockdata1, 2); + } + +- return blockState; ++ return iblockdata1; + } + +- private static <T extends Comparable<T>> BlockState updateState(BlockState state, Property<T> property, String valueIdentifier) { +- return property.getValue(valueIdentifier).map(comparable -> state.setValue(property, comparable)).orElse(state); ++ public static IBlockData getBlockState(IBlockData iblockdata, CompoundTag nbttagcompound1) { ++ IBlockData iblockdata1 = iblockdata; ++ { ++ // CraftBukkit end ++ StateDefinition<Block, IBlockData> blockstatelist = iblockdata.getBlock().getStateDefinition(); ++ Iterator iterator = nbttagcompound1.getAllKeys().iterator(); ++ ++ while (iterator.hasNext()) { ++ String s = (String) iterator.next(); ++ Property<?> iblockstate = blockstatelist.getProperty(s); ++ ++ if (iblockstate != null) { ++ String s1 = nbttagcompound1.get(s).getAsString(); ++ ++ iblockdata1 = updateState(iblockdata1, iblockstate, s1); ++ } ++ } ++ } ++ return iblockdata1; + } + +- protected boolean canPlace(BlockPlaceContext context, BlockState state) { +- Player player = context.getPlayer(); +- CollisionContext collisionContext = player == null ? CollisionContext.empty() : CollisionContext.of(player); +- return (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) +- && context.getLevel().isUnobstructed(state, context.getClickedPos(), collisionContext); ++ private static <T extends Comparable<T>> IBlockData updateState(IBlockData state, Property<T> property, String valueIdentifier) { ++ return (IBlockData) property.getValue(valueIdentifier).map((comparable) -> { ++ return (IBlockData) state.setValue(property, comparable); ++ }).orElse(state); + } + ++ protected boolean canPlace(BlockPlaceContext context, IBlockData state) { ++ Player entityhuman = context.getPlayer(); ++ CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman); ++ // CraftBukkit start - store default return ++ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().isUnobstructed(state, context.getClickedPos(), voxelshapecollision); ++ org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; ++ ++ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn); ++ context.getLevel().getCraftServer().getPluginManager().callEvent(event); ++ ++ return event.isBuildable(); ++ // CraftBukkit end ++ } ++ + protected boolean mustSurvive() { + return true; + } + +- protected boolean placeBlock(BlockPlaceContext context, BlockState state) { ++ protected boolean placeBlock(BlockPlaceContext context, IBlockData state) { + return context.getLevel().setBlock(context.getClickedPos(), state, 11); + } + + public static boolean updateCustomBlockEntityTag(Level level, @Nullable Player player, BlockPos pos, ItemStack stack) { +- MinecraftServer server = level.getServer(); +- if (server == null) { ++ MinecraftServer minecraftserver = level.getServer(); ++ ++ if (minecraftserver == null) { + return false; + } else { +- CompoundTag blockEntityData = getBlockEntityData(stack); +- if (blockEntityData != null) { +- BlockEntity blockEntity = level.getBlockEntity(pos); +- if (blockEntity != null) { +- if (!level.isClientSide && blockEntity.onlyOpCanSetNbt() && (player == null || !player.canUseGameMasterBlocks())) { ++ CompoundTag nbttagcompound = getBlockEntityData(stack); ++ ++ if (nbttagcompound != null) { ++ BlockEntity tileentity = level.getBlockEntity(pos); ++ ++ if (tileentity != null) { ++ if (!level.isClientSide && tileentity.onlyOpCanSetNbt() && (player == null || !player.canUseGameMasterBlocks())) { + return false; + } + +- CompoundTag compoundTag = blockEntity.saveWithoutMetadata(); +- CompoundTag compoundTag1 = compoundTag.copy(); +- compoundTag.merge(blockEntityData); +- if (!compoundTag.equals(compoundTag1)) { +- blockEntity.load(compoundTag); +- blockEntity.setChanged(); ++ CompoundTag nbttagcompound1 = tileentity.saveWithoutMetadata(); ++ CompoundTag nbttagcompound2 = nbttagcompound1.copy(); ++ ++ nbttagcompound1.merge(nbttagcompound); ++ if (!nbttagcompound1.equals(nbttagcompound2)) { ++ tileentity.load(nbttagcompound1); ++ tileentity.setChanged(); + return true; + } + } +@@ -218,13 +274,18 @@ + @Override + public void onDestroyed(ItemEntity itemEntity) { + if (this.block instanceof ShulkerBoxBlock) { +- ItemStack item = itemEntity.getItem(); +- CompoundTag blockEntityData = getBlockEntityData(item); +- if (blockEntityData != null && blockEntityData.contains("Items", 9)) { +- ListTag list = blockEntityData.getList("Items", 10); +- ItemUtils.onContainerDestroyed(itemEntity, list.stream().map(CompoundTag.class::cast).map(ItemStack::of)); ++ ItemStack itemstack = itemEntity.getItem(); ++ CompoundTag nbttagcompound = getBlockEntityData(itemstack); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("Items", 9)) { ++ ListTag nbttaglist = nbttagcompound.getList("Items", 10); ++ Stream<net.minecraft.nbt.Tag> stream = nbttaglist.stream(); // CraftBukkit - decompile error ++ ++ Objects.requireNonNull(CompoundTag.class); ++ ItemUtils.onContainerDestroyed(itemEntity, stream.map(CompoundTag.class::cast).map(ItemStack::of)); + } + } ++ + } + + @Nullable +@@ -239,6 +300,7 @@ + BlockEntity.addEntityType(blockEntityData, blockEntityType); + stack.addTagElement("BlockEntityTag", blockEntityData); + } ++ + } + + @Override diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/BoatItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/BoatItem.java.patch new file mode 100644 index 0000000000..62e5ee2651 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/BoatItem.java.patch @@ -0,0 +1,141 @@ +--- a/net/minecraft/world/item/BoatItem.java ++++ b/net/minecraft/world/item/BoatItem.java +@@ -1,10 +1,11 @@ + package net.minecraft.world.item; + ++import java.util.Iterator; + import java.util.List; + import java.util.function.Predicate; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntitySelector; +@@ -16,10 +17,12 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.AABB; ++import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.HitResult; + import net.minecraft.world.phys.Vec3; + + public class BoatItem extends Item { ++ + private static final Predicate<Entity> ENTITY_PREDICATE = EntitySelector.NO_SPECTATORS.and(Entity::isPickable); + private final Boat.Type type; + private final boolean hasChest; +@@ -31,57 +34,81 @@ + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- HitResult playerPOVHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); +- if (playerPOVHitResult.getType() == HitResult.Type.MISS) { +- return InteractionResultHolder.pass(itemInHand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ BlockHitResult movingobjectpositionblock = getPlayerPOVHitResult(level, player, ClipContext.Fluid.ANY); ++ ++ if (movingobjectpositionblock.getType() == HitResult.EnumMovingObjectType.MISS) { ++ return InteractionResultHolder.pass(itemstack); + } else { +- Vec3 viewVector = player.getViewVector(1.0F); +- double d = 5.0; +- List<Entity> entities = level.getEntities(player, player.getBoundingBox().expandTowards(viewVector.scale(5.0)).inflate(1.0), ENTITY_PREDICATE); +- if (!entities.isEmpty()) { +- Vec3 eyePosition = player.getEyePosition(); ++ Vec3 vec3d = player.getViewVector(1.0F); ++ double d0 = 5.0D; ++ List<Entity> list = level.getEntities((Entity) player, player.getBoundingBox().expandTowards(vec3d.scale(5.0D)).inflate(1.0D), BoatItem.ENTITY_PREDICATE); + +- for (Entity entity : entities) { +- AABB aABB = entity.getBoundingBox().inflate((double)entity.getPickRadius()); +- if (aABB.contains(eyePosition)) { +- return InteractionResultHolder.pass(itemInHand); ++ if (!list.isEmpty()) { ++ Vec3 vec3d1 = player.getEyePosition(); ++ Iterator iterator = list.iterator(); ++ ++ while (iterator.hasNext()) { ++ Entity entity = (Entity) iterator.next(); ++ AABB axisalignedbb = entity.getBoundingBox().inflate((double) entity.getPickRadius()); ++ ++ if (axisalignedbb.contains(vec3d1)) { ++ return InteractionResultHolder.pass(itemstack); + } + } + } + +- if (playerPOVHitResult.getType() == HitResult.Type.BLOCK) { +- Boat boat = this.getBoat(level, playerPOVHitResult, itemInHand, player); +- boat.setVariant(this.type); +- boat.setYRot(player.getYRot()); +- if (!level.noCollision(boat, boat.getBoundingBox())) { +- return InteractionResultHolder.fail(itemInHand); ++ if (movingobjectpositionblock.getType() == HitResult.EnumMovingObjectType.BLOCK) { ++ // CraftBukkit start - Boat placement ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), itemstack, false, hand, movingobjectpositionblock.getLocation()); ++ ++ if (event.isCancelled()) { ++ return InteractionResultHolder.pass(itemstack); ++ } ++ // CraftBukkit end ++ Boat entityboat = this.getBoat(level, movingobjectpositionblock, itemstack, player); ++ ++ entityboat.setVariant(this.type); ++ entityboat.setYRot(player.getYRot()); ++ if (!level.noCollision(entityboat, entityboat.getBoundingBox())) { ++ return InteractionResultHolder.fail(itemstack); + } else { + if (!level.isClientSide) { +- level.addFreshEntity(boat); +- level.gameEvent(player, GameEvent.ENTITY_PLACE, playerPOVHitResult.getLocation()); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(level, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), player, entityboat, hand).isCancelled()) { ++ return InteractionResultHolder.fail(itemstack); ++ } ++ ++ if (!level.addFreshEntity(entityboat)) { ++ return InteractionResultHolder.pass(itemstack); ++ } ++ // CraftBukkit end ++ level.gameEvent((Entity) player, GameEvent.ENTITY_PLACE, movingobjectpositionblock.getLocation()); + if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ itemstack.shrink(1); + } + } + + player.awardStat(Stats.ITEM_USED.get(this)); +- return InteractionResultHolder.sidedSuccess(itemInHand, level.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + } else { +- return InteractionResultHolder.pass(itemInHand); ++ return InteractionResultHolder.pass(itemstack); + } + } + } + +- private Boat getBoat(Level level, HitResult hitResult, ItemStack itemStack, Player player) { +- Vec3 location = hitResult.getLocation(); +- Boat boat = (Boat)(this.hasChest ? new ChestBoat(level, location.x, location.y, location.z) : new Boat(level, location.x, location.y, location.z)); +- if (level instanceof ServerLevel serverLevel) { +- EntityType.<Boat>createDefaultStackConfig(serverLevel, itemStack, player).accept(boat); ++ private Boat getBoat(Level world, HitResult movingobjectposition, ItemStack itemstack, Player entityhuman) { ++ Vec3 vec3d = movingobjectposition.getLocation(); ++ Boat object = this.hasChest ? new ChestBoat(world, vec3d.x, vec3d.y, vec3d.z) : new Boat(world, vec3d.x, vec3d.y, vec3d.z); // CraftBukkit - decompile error ++ ++ if (world instanceof ServerLevel) { ++ ServerLevel worldserver = (ServerLevel) world; ++ ++ EntityType.createDefaultStackConfig(worldserver, itemstack, entityhuman).accept(object); + } + +- return boat; ++ return (Boat) object; + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/BoneMealItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/BoneMealItem.java.patch new file mode 100644 index 0000000000..1d357a7708 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/BoneMealItem.java.patch @@ -0,0 +1,277 @@ +--- a/net/minecraft/world/item/BoneMealItem.java ++++ b/net/minecraft/world/item/BoneMealItem.java +@@ -4,7 +4,6 @@ + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.Holder; +-import net.minecraft.core.HolderSet; + import net.minecraft.core.particles.ParticleTypes; + import net.minecraft.core.registries.BuiltInRegistries; + import net.minecraft.server.level.ServerLevel; +@@ -17,13 +16,14 @@ + import net.minecraft.world.level.LevelAccessor; + import net.minecraft.world.level.biome.Biome; + import net.minecraft.world.level.block.BaseCoralWallFanBlock; ++import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.BonemealableBlock; +-import net.minecraft.world.level.block.state.BlockBehaviour; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + + public class BoneMealItem extends Item { ++ + public static final int GRASS_SPREAD_WIDTH = 3; + public static final int GRASS_SPREAD_HEIGHT = 1; + public static final int GRASS_COUNT_MULTIPLIER = 3; +@@ -34,26 +34,34 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockPos blockPos = clickedPos.relative(context.getClickedFace()); +- if (growCrop(context.getItemInHand(), level, clickedPos)) { +- if (!level.isClientSide) { +- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); +- level.levelEvent(1505, clickedPos, 0); ++ // CraftBukkit start - extract bonemeal application logic to separate, static method ++ return applyBonemeal(context); ++ } ++ ++ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) { ++ // CraftBukkit end ++ Level world = itemactioncontext.getLevel(); ++ BlockPos blockposition = itemactioncontext.getClickedPos(); ++ BlockPos blockposition1 = blockposition.relative(itemactioncontext.getClickedFace()); ++ ++ if (growCrop(itemactioncontext.getItemInHand(), world, blockposition)) { ++ if (!world.isClientSide) { ++ if (itemactioncontext.getPlayer() != null) itemactioncontext.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 ++ world.levelEvent(1505, blockposition, 0); + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { +- BlockState blockState = level.getBlockState(clickedPos); +- boolean isFaceSturdy = blockState.isFaceSturdy(level, clickedPos, context.getClickedFace()); +- if (isFaceSturdy && growWaterPlant(context.getItemInHand(), level, blockPos, context.getClickedFace())) { +- if (!level.isClientSide) { +- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); +- level.levelEvent(1505, blockPos, 0); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ boolean flag = iblockdata.isFaceSturdy(world, blockposition, itemactioncontext.getClickedFace()); ++ ++ if (flag && growWaterPlant(itemactioncontext.getItemInHand(), world, blockposition1, itemactioncontext.getClickedFace())) { ++ if (!world.isClientSide) { ++ if (itemactioncontext.getPlayer() != null) itemactioncontext.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 ++ world.levelEvent(1505, blockposition1, 0); + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.PASS; + } +@@ -61,17 +69,23 @@ + } + + public static boolean growCrop(ItemStack stack, Level level, BlockPos pos) { +- BlockState blockState = level.getBlockState(pos); +- if (blockState.getBlock() instanceof BonemealableBlock bonemealableBlock && bonemealableBlock.isValidBonemealTarget(level, pos, blockState)) { +- if (level instanceof ServerLevel) { +- if (bonemealableBlock.isBonemealSuccess(level, level.random, pos, blockState)) { +- bonemealableBlock.performBonemeal((ServerLevel)level, level.random, pos, blockState); ++ IBlockData iblockdata = level.getBlockState(pos); ++ Block block = iblockdata.getBlock(); ++ ++ if (block instanceof BonemealableBlock) { ++ BonemealableBlock iblockfragileplantelement = (BonemealableBlock) block; ++ ++ if (iblockfragileplantelement.isValidBonemealTarget(level, pos, iblockdata)) { ++ if (level instanceof ServerLevel) { ++ if (iblockfragileplantelement.isBonemealSuccess(level, level.random, pos, iblockdata)) { ++ iblockfragileplantelement.performBonemeal((ServerLevel) level, level.random, pos, iblockdata); ++ } ++ ++ stack.shrink(1); + } + +- stack.shrink(1); ++ return true; + } +- +- return true; + } + + return false; +@@ -82,53 +96,64 @@ + if (!(level instanceof ServerLevel)) { + return true; + } else { +- RandomSource random = level.getRandom(); ++ RandomSource randomsource = level.getRandom(); ++ int i = 0; + +- label78: +- for (int i = 0; i < 128; i++) { +- BlockPos blockPos = pos; +- BlockState blockState = Blocks.SEAGRASS.defaultBlockState(); ++ while (i < 128) { ++ BlockPos blockposition1 = pos; ++ IBlockData iblockdata = Blocks.SEAGRASS.defaultBlockState(); ++ int j = 0; + +- for (int i1 = 0; i1 < i / 16; i1++) { +- blockPos = blockPos.offset(random.nextInt(3) - 1, (random.nextInt(3) - 1) * random.nextInt(3) / 2, random.nextInt(3) - 1); +- if (level.getBlockState(blockPos).isCollisionShapeFullBlock(level, blockPos)) { +- continue label78; +- } +- } ++ while (true) { ++ if (j < i / 16) { ++ blockposition1 = blockposition1.offset(randomsource.nextInt(3) - 1, (randomsource.nextInt(3) - 1) * randomsource.nextInt(3) / 2, randomsource.nextInt(3) - 1); ++ if (!level.getBlockState(blockposition1).isCollisionShapeFullBlock(level, blockposition1)) { ++ ++j; ++ continue; ++ } ++ } else { ++ Holder<Biome> holder = level.getBiome(blockposition1); + +- Holder<Biome> biome = level.getBiome(blockPos); +- if (biome.is(BiomeTags.PRODUCES_CORALS_FROM_BONEMEAL)) { +- if (i == 0 && clickedSide != null && clickedSide.getAxis().isHorizontal()) { +- blockState = BuiltInRegistries.BLOCK +- .getTag(BlockTags.WALL_CORALS) +- .flatMap(set -> set.getRandomElement(level.random)) +- .map(holder -> holder.value().defaultBlockState()) +- .orElse(blockState); +- if (blockState.hasProperty(BaseCoralWallFanBlock.FACING)) { +- blockState = blockState.setValue(BaseCoralWallFanBlock.FACING, clickedSide); ++ if (holder.is(BiomeTags.PRODUCES_CORALS_FROM_BONEMEAL)) { ++ if (i == 0 && clickedSide != null && clickedSide.getAxis().isHorizontal()) { ++ iblockdata = (IBlockData) BuiltInRegistries.BLOCK.getTag(BlockTags.WALL_CORALS).flatMap((holderset_named) -> { ++ return holderset_named.getRandomElement(level.random); ++ }).map((holder1) -> { ++ return ((Block) holder1.value()).defaultBlockState(); ++ }).orElse(iblockdata); ++ if (iblockdata.hasProperty(BaseCoralWallFanBlock.FACING)) { ++ iblockdata = (IBlockData) iblockdata.setValue(BaseCoralWallFanBlock.FACING, clickedSide); ++ } ++ } else if (randomsource.nextInt(4) == 0) { ++ iblockdata = (IBlockData) BuiltInRegistries.BLOCK.getTag(BlockTags.UNDERWATER_BONEMEALS).flatMap((holderset_named) -> { ++ return holderset_named.getRandomElement(level.random); ++ }).map((holder1) -> { ++ return ((Block) holder1.value()).defaultBlockState(); ++ }).orElse(iblockdata); ++ } + } +- } else if (random.nextInt(4) == 0) { +- blockState = BuiltInRegistries.BLOCK +- .getTag(BlockTags.UNDERWATER_BONEMEALS) +- .flatMap(set -> set.getRandomElement(level.random)) +- .map(holder -> holder.value().defaultBlockState()) +- .orElse(blockState); +- } +- } + +- if (blockState.is(BlockTags.WALL_CORALS, state -> state.hasProperty(BaseCoralWallFanBlock.FACING))) { +- for (int i2 = 0; !blockState.canSurvive(level, blockPos) && i2 < 4; i2++) { +- blockState = blockState.setValue(BaseCoralWallFanBlock.FACING, Direction.Plane.HORIZONTAL.getRandomDirection(random)); +- } +- } ++ if (iblockdata.is(BlockTags.WALL_CORALS, (blockbase_blockdata) -> { ++ return blockbase_blockdata.hasProperty(BaseCoralWallFanBlock.FACING); ++ })) { ++ for (int k = 0; !iblockdata.canSurvive(level, blockposition1) && k < 4; ++k) { ++ iblockdata = (IBlockData) iblockdata.setValue(BaseCoralWallFanBlock.FACING, Direction.Plane.HORIZONTAL.getRandomDirection(randomsource)); ++ } ++ } + +- if (blockState.canSurvive(level, blockPos)) { +- BlockState blockState1 = level.getBlockState(blockPos); +- if (blockState1.is(Blocks.WATER) && level.getFluidState(blockPos).getAmount() == 8) { +- level.setBlock(blockPos, blockState, 3); +- } else if (blockState1.is(Blocks.SEAGRASS) && random.nextInt(10) == 0) { +- ((BonemealableBlock)Blocks.SEAGRASS).performBonemeal((ServerLevel)level, random, blockPos, blockState1); ++ if (iblockdata.canSurvive(level, blockposition1)) { ++ IBlockData iblockdata1 = level.getBlockState(blockposition1); ++ ++ if (iblockdata1.is(Blocks.WATER) && level.getFluidState(blockposition1).getAmount() == 8) { ++ level.setBlock(blockposition1, iblockdata, 3); ++ } else if (iblockdata1.is(Blocks.SEAGRASS) && randomsource.nextInt(10) == 0) { ++ ((BonemealableBlock) Blocks.SEAGRASS).performBonemeal((ServerLevel) level, randomsource, blockposition1, iblockdata1); ++ } ++ } + } ++ ++ ++i; ++ break; + } + } + +@@ -145,38 +170,42 @@ + data = 15; + } + +- BlockState blockState = level.getBlockState(pos); +- if (!blockState.isAir()) { +- double d = 0.5; ++ IBlockData iblockdata = level.getBlockState(pos); ++ ++ if (!iblockdata.isAir()) { ++ double d0 = 0.5D; + double d1; +- if (blockState.is(Blocks.WATER)) { ++ ++ if (iblockdata.is(Blocks.WATER)) { + data *= 3; +- d1 = 1.0; +- d = 3.0; +- } else if (blockState.isSolidRender(level, pos)) { ++ d1 = 1.0D; ++ d0 = 3.0D; ++ } else if (iblockdata.isSolidRender(level, pos)) { + pos = pos.above(); + data *= 3; +- d = 3.0; +- d1 = 1.0; ++ d0 = 3.0D; ++ d1 = 1.0D; + } else { +- d1 = blockState.getShape(level, pos).max(Direction.Axis.Y); ++ d1 = iblockdata.getShape(level, pos).max(Direction.Axis.Y); + } + +- level.addParticle(ParticleTypes.HAPPY_VILLAGER, (double)pos.getX() + 0.5, (double)pos.getY() + 0.5, (double)pos.getZ() + 0.5, 0.0, 0.0, 0.0); +- RandomSource random = level.getRandom(); ++ level.addParticle(ParticleTypes.HAPPY_VILLAGER, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 0.0D, 0.0D, 0.0D); ++ RandomSource randomsource = level.getRandom(); + +- for (int i = 0; i < data; i++) { +- double d2 = random.nextGaussian() * 0.02; +- double d3 = random.nextGaussian() * 0.02; +- double d4 = random.nextGaussian() * 0.02; +- double d5 = 0.5 - d; +- double d6 = (double)pos.getX() + d5 + random.nextDouble() * d * 2.0; +- double d7 = (double)pos.getY() + random.nextDouble() * d1; +- double d8 = (double)pos.getZ() + d5 + random.nextDouble() * d * 2.0; ++ for (int j = 0; j < data; ++j) { ++ double d2 = randomsource.nextGaussian() * 0.02D; ++ double d3 = randomsource.nextGaussian() * 0.02D; ++ double d4 = randomsource.nextGaussian() * 0.02D; ++ double d5 = 0.5D - d0; ++ double d6 = (double) pos.getX() + d5 + randomsource.nextDouble() * d0 * 2.0D; ++ double d7 = (double) pos.getY() + randomsource.nextDouble() * d1; ++ double d8 = (double) pos.getZ() + d5 + randomsource.nextDouble() * d0 * 2.0D; ++ + if (!level.getBlockState(BlockPos.containing(d6, d7, d8).below()).isAir()) { + level.addParticle(ParticleTypes.HAPPY_VILLAGER, d6, d7, d8, d2, d3, d4); + } + } ++ + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/BowItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/BowItem.java.patch new file mode 100644 index 0000000000..4607fa28b2 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/BowItem.java.patch @@ -0,0 +1,200 @@ +--- a/net/minecraft/world/item/BowItem.java ++++ b/net/minecraft/world/item/BowItem.java +@@ -4,7 +4,7 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.player.Player; +@@ -13,7 +13,8 @@ + import net.minecraft.world.item.enchantment.Enchantments; + import net.minecraft.world.level.Level; + +-public class BowItem extends ProjectileWeaponItem implements Vanishable { ++public class BowItem extends ProjectileWeaponItem implements ItemVanishable { ++ + public static final int MAX_DRAW_DURATION = 20; + public static final int DEFAULT_RANGE = 15; + +@@ -23,79 +24,97 @@ + + @Override + public void releaseUsing(ItemStack stack, Level level, LivingEntity entityLiving, int timeLeft) { +- if (entityLiving instanceof Player player) { +- boolean flag = player.getAbilities().instabuild || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0; +- ItemStack projectile = player.getProjectile(stack); +- if (!projectile.isEmpty() || flag) { +- if (projectile.isEmpty()) { +- projectile = new ItemStack(Items.ARROW); ++ if (entityLiving instanceof Player) { ++ Player entityhuman = (Player) entityLiving; ++ boolean flag = entityhuman.getAbilities().instabuild || EnchantmentHelper.getItemEnchantmentLevel(Enchantments.INFINITY_ARROWS, stack) > 0; ++ ItemStack itemstack1 = entityhuman.getProjectile(stack); ++ ++ if (!itemstack1.isEmpty() || flag) { ++ if (itemstack1.isEmpty()) { ++ itemstack1 = new ItemStack(Items.ARROW); + } + +- int i = this.getUseDuration(stack) - timeLeft; +- float powerForTime = getPowerForTime(i); +- if (!((double)powerForTime < 0.1)) { +- boolean flag1 = flag && projectile.is(Items.ARROW); ++ int j = this.getUseDuration(stack) - timeLeft; ++ float f = getPowerForTime(j); ++ ++ if ((double) f >= 0.1D) { ++ boolean flag1 = flag && itemstack1.is(Items.ARROW); ++ + if (!level.isClientSide) { +- ArrowItem arrowItem = (ArrowItem)(projectile.getItem() instanceof ArrowItem ? projectile.getItem() : Items.ARROW); +- AbstractArrow abstractArrow = arrowItem.createArrow(level, projectile, player); +- abstractArrow.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, powerForTime * 3.0F, 1.0F); +- if (powerForTime == 1.0F) { +- abstractArrow.setCritArrow(true); ++ ArrowItem itemarrow = (ArrowItem) (itemstack1.getItem() instanceof ArrowItem ? itemstack1.getItem() : Items.ARROW); ++ AbstractArrow entityarrow = itemarrow.createArrow(level, itemstack1, entityhuman); ++ ++ entityarrow.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, f * 3.0F, 1.0F); ++ if (f == 1.0F) { ++ entityarrow.setCritArrow(true); + } + +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.POWER_ARROWS, stack); +- if (itemEnchantmentLevel > 0) { +- abstractArrow.setBaseDamage(abstractArrow.getBaseDamage() + (double)itemEnchantmentLevel * 0.5 + 0.5); ++ int k = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.POWER_ARROWS, stack); ++ ++ if (k > 0) { ++ entityarrow.setBaseDamage(entityarrow.getBaseDamage() + (double) k * 0.5D + 0.5D); + } + +- int itemEnchantmentLevel1 = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.PUNCH_ARROWS, stack); +- if (itemEnchantmentLevel1 > 0) { +- abstractArrow.setKnockback(itemEnchantmentLevel1); ++ int l = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.PUNCH_ARROWS, stack); ++ ++ if (l > 0) { ++ entityarrow.setKnockback(l); + } + + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.FLAMING_ARROWS, stack) > 0) { +- abstractArrow.setSecondsOnFire(100); ++ entityarrow.setSecondsOnFire(100); + } ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(entityhuman, stack, itemstack1, entityarrow, entityhuman.getUsedItemHand(), f, !flag1); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; ++ } ++ flag1 = !event.shouldConsumeItem(); ++ // CraftBukkit end + +- stack.hurtAndBreak(1, player, player1 -> player1.broadcastBreakEvent(player.getUsedItemHand())); +- if (flag1 || player.getAbilities().instabuild && (projectile.is(Items.SPECTRAL_ARROW) || projectile.is(Items.TIPPED_ARROW))) { +- abstractArrow.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; ++ stack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(entityhuman.getUsedItemHand()); ++ }); ++ if (flag1 || entityhuman.getAbilities().instabuild && (itemstack1.is(Items.SPECTRAL_ARROW) || itemstack1.is(Items.TIPPED_ARROW))) { ++ entityarrow.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; + } + +- level.addFreshEntity(abstractArrow); ++ // CraftBukkit start ++ if (event.getProjectile() == entityarrow.getBukkitEntity()) { ++ if (!level.addFreshEntity(entityarrow)) { ++ if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); ++ } ++ return; ++ } ++ } ++ // CraftBukkit end + } + +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.ARROW_SHOOT, +- SoundSource.PLAYERS, +- 1.0F, +- 1.0F / (level.getRandom().nextFloat() * 0.4F + 1.2F) + powerForTime * 0.5F +- ); +- if (!flag1 && !player.getAbilities().instabuild) { +- projectile.shrink(1); +- if (projectile.isEmpty()) { +- player.getInventory().removeItem(projectile); ++ level.playSound((Player) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEvents.ARROW_SHOOT, SoundSource.PLAYERS, 1.0F, 1.0F / (level.getRandom().nextFloat() * 0.4F + 1.2F) + f * 0.5F); ++ if (!flag1 && !entityhuman.getAbilities().instabuild) { ++ itemstack1.shrink(1); ++ if (itemstack1.isEmpty()) { ++ entityhuman.getInventory().removeItem(itemstack1); + } + } + +- player.awardStat(Stats.ITEM_USED.get(this)); ++ entityhuman.awardStat(Stats.ITEM_USED.get(this)); + } + } + } + } + + public static float getPowerForTime(int charge) { +- float f = (float)charge / 20.0F; +- float var2 = (f * f + f * 2.0F) / 3.0F; +- if (var2 > 1.0F) { +- var2 = 1.0F; ++ float f = (float) charge / 20.0F; ++ ++ f = (f * f + f * 2.0F) / 3.0F; ++ if (f > 1.0F) { ++ f = 1.0F; + } + +- return var2; ++ return f; + } + + @Override +@@ -104,25 +123,26 @@ + } + + @Override +- public UseAnim getUseAnimation(ItemStack stack) { +- return UseAnim.BOW; ++ public EnumAnimation getUseAnimation(ItemStack stack) { ++ return EnumAnimation.BOW; + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- boolean flag = !player.getProjectile(itemInHand).isEmpty(); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ boolean flag = !player.getProjectile(itemstack).isEmpty(); ++ + if (!player.getAbilities().instabuild && !flag) { +- return InteractionResultHolder.fail(itemInHand); ++ return InteractionResultHolder.fail(itemstack); + } else { + player.startUsingItem(hand); +- return InteractionResultHolder.consume(itemInHand); ++ return InteractionResultHolder.consume(itemstack); + } + } + + @Override + public Predicate<ItemStack> getAllSupportedProjectiles() { +- return ARROW_ONLY; ++ return BowItem.ARROW_ONLY; + } + + @Override diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/BucketItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/BucketItem.java.patch new file mode 100644 index 0000000000..fad620d749 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/BucketItem.java.patch @@ -0,0 +1,310 @@ +--- a/net/minecraft/world/item/BucketItem.java ++++ b/net/minecraft/world/item/BucketItem.java +@@ -5,14 +5,17 @@ + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; + import net.minecraft.core.particles.ParticleTypes; ++import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; ++import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.tags.FluidTags; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.level.ClipContext; + import net.minecraft.world.level.Level; +@@ -20,70 +23,100 @@ + import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.BucketPickup; + import net.minecraft.world.level.block.LiquidBlockContainer; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.level.material.FlowingFluid; + import net.minecraft.world.level.material.Fluid; + import net.minecraft.world.level.material.Fluids; + import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.HitResult; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.DummyGeneratorAccess; ++import org.bukkit.event.player.PlayerBucketEmptyEvent; ++import org.bukkit.event.player.PlayerBucketFillEvent; ++// CraftBukkit end + + public class BucketItem extends Item implements DispensibleContainerItem { +- private final Fluid content; + ++ public final Fluid content; ++ + public BucketItem(Fluid content, Item.Properties properties) { + super(properties); + this.content = content; + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- BlockHitResult playerPOVHitResult = getPlayerPOVHitResult( +- level, player, this.content == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE +- ); +- if (playerPOVHitResult.getType() == HitResult.Type.MISS) { +- return InteractionResultHolder.pass(itemInHand); +- } else if (playerPOVHitResult.getType() != HitResult.Type.BLOCK) { +- return InteractionResultHolder.pass(itemInHand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ BlockHitResult movingobjectpositionblock = getPlayerPOVHitResult(level, player, this.content == Fluids.EMPTY ? ClipContext.Fluid.SOURCE_ONLY : ClipContext.Fluid.NONE); ++ ++ if (movingobjectpositionblock.getType() == HitResult.EnumMovingObjectType.MISS) { ++ return InteractionResultHolder.pass(itemstack); ++ } else if (movingobjectpositionblock.getType() != HitResult.EnumMovingObjectType.BLOCK) { ++ return InteractionResultHolder.pass(itemstack); + } else { +- BlockPos blockPos = playerPOVHitResult.getBlockPos(); +- Direction direction = playerPOVHitResult.getDirection(); +- BlockPos blockPos1 = blockPos.relative(direction); +- if (!level.mayInteract(player, blockPos) || !player.mayUseItemAt(blockPos1, direction, itemInHand)) { +- return InteractionResultHolder.fail(itemInHand); +- } else if (this.content == Fluids.EMPTY) { +- BlockState blockState = level.getBlockState(blockPos); +- if (blockState.getBlock() instanceof BucketPickup bucketPickup) { +- ItemStack itemStack = bucketPickup.pickupBlock(player, level, blockPos, blockState); +- if (!itemStack.isEmpty()) { +- player.awardStat(Stats.ITEM_USED.get(this)); +- bucketPickup.getPickupSound().ifPresent(soundEvent -> player.playSound(soundEvent, 1.0F, 1.0F)); +- level.gameEvent(player, GameEvent.FLUID_PICKUP, blockPos); +- ItemStack itemStack1 = ItemUtils.createFilledResult(itemInHand, player, itemStack); +- if (!level.isClientSide) { +- CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, itemStack); ++ BlockPos blockposition = movingobjectpositionblock.getBlockPos(); ++ Direction enumdirection = movingobjectpositionblock.getDirection(); ++ BlockPos blockposition1 = blockposition.relative(enumdirection); ++ ++ if (level.mayInteract(player, blockposition) && player.mayUseItemAt(blockposition1, enumdirection, itemstack)) { ++ IBlockData iblockdata; ++ ++ if (this.content == Fluids.EMPTY) { ++ iblockdata = level.getBlockState(blockposition); ++ Block block = iblockdata.getBlock(); ++ ++ if (block instanceof BucketPickup) { ++ BucketPickup ifluidsource = (BucketPickup) block; ++ // CraftBukkit start ++ ItemStack dummyFluid = ifluidsource.pickupBlock(player, DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); ++ if (dummyFluid.isEmpty()) return InteractionResultHolder.fail(itemstack); // Don't fire event if the bucket won't be filled. ++ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) level, player, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand); ++ ++ if (event.isCancelled()) { ++ ((ServerPlayer) player).connection.send(new ClientboundBlockUpdatePacket(level, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) ++ ((ServerPlayer) player).getBukkitEntity().updateInventory(); // SPIGOT-4541 ++ return InteractionResultHolder.fail(itemstack); + } ++ // CraftBukkit end ++ ItemStack itemstack1 = ifluidsource.pickupBlock(player, level, blockposition, iblockdata); + +- return InteractionResultHolder.sidedSuccess(itemStack1, level.isClientSide()); +- } +- } ++ if (!itemstack1.isEmpty()) { ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ ifluidsource.getPickupSound().ifPresent((soundeffect) -> { ++ player.playSound(soundeffect, 1.0F, 1.0F); ++ }); ++ level.gameEvent((Entity) player, GameEvent.FLUID_PICKUP, blockposition); ++ ItemStack itemstack2 = ItemUtils.createFilledResult(itemstack, player, CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit + +- return InteractionResultHolder.fail(itemInHand); +- } else { +- BlockState blockState = level.getBlockState(blockPos); +- BlockPos blockPos2 = blockState.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockPos : blockPos1; +- if (this.emptyContents(player, level, blockPos2, playerPOVHitResult)) { +- this.checkExtraContent(player, level, itemInHand, blockPos2); +- if (player instanceof ServerPlayer) { +- CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, blockPos2, itemInHand); ++ if (!level.isClientSide) { ++ CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer) player, itemstack1); ++ } ++ ++ return InteractionResultHolder.sidedSuccess(itemstack2, level.isClientSide()); ++ } + } + +- player.awardStat(Stats.ITEM_USED.get(this)); +- return InteractionResultHolder.sidedSuccess(getEmptySuccessItem(itemInHand, player), level.isClientSide()); ++ return InteractionResultHolder.fail(itemstack); + } else { +- return InteractionResultHolder.fail(itemInHand); ++ iblockdata = level.getBlockState(blockposition); ++ BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1; ++ ++ if (this.emptyContents(player, level, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit ++ this.checkExtraContent(player, level, itemstack, blockposition2); ++ if (player instanceof ServerPlayer) { ++ CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) player, blockposition2, itemstack); ++ } ++ ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ return InteractionResultHolder.sidedSuccess(getEmptySuccessItem(itemstack, player), level.isClientSide()); ++ } else { ++ return InteractionResultHolder.fail(itemstack); ++ } + } ++ } else { ++ return InteractionResultHolder.fail(itemstack); + } + } + } +@@ -93,67 +126,95 @@ + } + + @Override +- public void checkExtraContent(@Nullable Player player, Level level, ItemStack containerStack, BlockPos pos) { +- } ++ public void checkExtraContent(@Nullable Player player, Level level, ItemStack containerStack, BlockPos pos) {} + + @Override + public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, @Nullable BlockHitResult result) { +- if (!(this.content instanceof FlowingFluid flowingFluid)) { ++ // CraftBukkit start ++ return emptyContents(player, level, pos, result, null, null, null, EnumHand.MAIN_HAND); ++ } ++ ++ public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, EnumHand enumhand) { ++ // CraftBukkit end ++ Fluid fluidtype = this.content; ++ ++ if (!(fluidtype instanceof FlowingFluid)) { + return false; + } else { ++ FlowingFluid fluidtypeflowing; ++ IBlockData iblockdata; + Block block; +- boolean canBeReplaced; +- BlockState blockState; +- boolean var10000; +- label82: { +- blockState = level.getBlockState(pos); +- block = blockState.getBlock(); +- canBeReplaced = blockState.canBeReplaced(this.content); +- label70: +- if (!blockState.isAir() && !canBeReplaced) { +- if (block instanceof LiquidBlockContainer liquidBlockContainer +- && liquidBlockContainer.canPlaceLiquid(player, level, pos, blockState, this.content)) { ++ boolean flag; ++ LiquidBlockContainer ifluidcontainer; ++ boolean flag1; ++ label70: ++ { ++ fluidtypeflowing = (FlowingFluid) fluidtype; ++ iblockdata = world.getBlockState(blockposition); ++ block = iblockdata.getBlock(); ++ flag = iblockdata.canBeReplaced(this.content); ++ if (!iblockdata.isAir() && !flag) { ++ label67: ++ { ++ if (block instanceof LiquidBlockContainer) { ++ ifluidcontainer = (LiquidBlockContainer) block; ++ if (ifluidcontainer.canPlaceLiquid(entityhuman, world, blockposition, iblockdata, this.content)) { ++ break label67; ++ } ++ } ++ ++ flag1 = false; + break label70; + } +- +- var10000 = false; +- break label82; + } + +- var10000 = true; ++ flag1 = true; + } + +- boolean flag = var10000; +- if (!flag) { +- return result != null && this.emptyContents(player, level, result.getBlockPos().relative(result.getDirection()), null); +- } else if (level.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) { +- int x = pos.getX(); +- int y = pos.getY(); +- int z = pos.getZ(); +- level.playSound( +- player, pos, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (level.random.nextFloat() - level.random.nextFloat()) * 0.8F +- ); ++ boolean flag2 = flag1; + +- for (int i = 0; i < 8; i++) { +- level.addParticle(ParticleTypes.LARGE_SMOKE, (double)x + Math.random(), (double)y + Math.random(), (double)z + Math.random(), 0.0, 0.0, 0.0); ++ // CraftBukkit start ++ if (flag2 && entityhuman != null) { ++ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); ++ if (event.isCancelled()) { ++ ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity ++ ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 ++ return false; + } ++ } ++ // CraftBukkit end ++ if (!flag2) { ++ return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit ++ } else if (world.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) { ++ int i = blockposition.getX(); ++ int j = blockposition.getY(); ++ int k = blockposition.getZ(); + ++ world.playSound(entityhuman, blockposition, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); ++ ++ for (int l = 0; l < 8; ++l) { ++ world.addParticle(ParticleTypes.LARGE_SMOKE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D); ++ } ++ + return true; + } else { +- if (block instanceof LiquidBlockContainer liquidBlockContainer && this.content == Fluids.WATER) { +- liquidBlockContainer.placeLiquid(level, pos, blockState, flowingFluid.getSource(false)); +- this.playEmptySound(player, level, pos); +- return true; ++ if (block instanceof LiquidBlockContainer) { ++ ifluidcontainer = (LiquidBlockContainer) block; ++ if (this.content == Fluids.WATER) { ++ ifluidcontainer.placeLiquid(world, blockposition, iblockdata, fluidtypeflowing.getSource(false)); ++ this.playEmptySound(entityhuman, world, blockposition); ++ return true; ++ } + } + +- if (!level.isClientSide && canBeReplaced && !blockState.liquid()) { +- level.destroyBlock(pos, true); ++ if (!world.isClientSide && flag && !iblockdata.liquid()) { ++ world.destroyBlock(blockposition, true); + } + +- if (!level.setBlock(pos, this.content.defaultFluidState().createLegacyBlock(), 11) && !blockState.getFluidState().isSource()) { ++ if (!world.setBlock(blockposition, this.content.defaultFluidState().createLegacyBlock(), 11) && !iblockdata.getFluidState().isSource()) { + return false; + } else { +- this.playEmptySound(player, level, pos); ++ this.playEmptySound(entityhuman, world, blockposition); + return true; + } + } +@@ -161,8 +222,9 @@ + } + + protected void playEmptySound(@Nullable Player player, LevelAccessor level, BlockPos pos) { +- SoundEvent soundEvent = this.content.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY; +- level.playSound(player, pos, soundEvent, SoundSource.BLOCKS, 1.0F, 1.0F); +- level.gameEvent(player, GameEvent.FLUID_PLACE, pos); ++ SoundEvent soundeffect = this.content.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY; ++ ++ level.playSound(player, pos, soundeffect, SoundSource.BLOCKS, 1.0F, 1.0F); ++ level.gameEvent((Entity) player, GameEvent.FLUID_PLACE, pos); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/ChorusFruitItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/ChorusFruitItem.java.patch new file mode 100644 index 0000000000..8f1c09e300 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/ChorusFruitItem.java.patch @@ -0,0 +1,95 @@ +--- a/net/minecraft/world/item/ChorusFruitItem.java ++++ b/net/minecraft/world/item/ChorusFruitItem.java +@@ -5,6 +5,7 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.util.Mth; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.animal.Fox; + import net.minecraft.world.entity.player.Player; +@@ -13,50 +14,62 @@ + import net.minecraft.world.phys.Vec3; + + public class ChorusFruitItem extends Item { ++ + public ChorusFruitItem(Item.Properties properties) { + super(properties); + } + + @Override + public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity entityLiving) { +- ItemStack itemStack = super.finishUsingItem(stack, level, entityLiving); ++ ItemStack itemstack1 = super.finishUsingItem(stack, level, entityLiving); ++ + if (!level.isClientSide) { +- for (int i = 0; i < 16; i++) { +- double d = entityLiving.getX() + (entityLiving.getRandom().nextDouble() - 0.5) * 16.0; +- double d1 = Mth.clamp( +- entityLiving.getY() + (double)(entityLiving.getRandom().nextInt(16) - 8), +- (double)level.getMinBuildHeight(), +- (double)(level.getMinBuildHeight() + ((ServerLevel)level).getLogicalHeight() - 1) +- ); +- double d2 = entityLiving.getZ() + (entityLiving.getRandom().nextDouble() - 0.5) * 16.0; ++ for (int i = 0; i < 16; ++i) { ++ double d0 = entityLiving.getX() + (entityLiving.getRandom().nextDouble() - 0.5D) * 16.0D; ++ double d1 = Mth.clamp(entityLiving.getY() + (double) (entityLiving.getRandom().nextInt(16) - 8), (double) level.getMinBuildHeight(), (double) (level.getMinBuildHeight() + ((ServerLevel) level).getLogicalHeight() - 1)); ++ double d2 = entityLiving.getZ() + (entityLiving.getRandom().nextDouble() - 0.5D) * 16.0D; ++ + if (entityLiving.isPassenger()) { + entityLiving.stopRiding(); + } + +- Vec3 vec3 = entityLiving.position(); +- if (entityLiving.randomTeleport(d, d1, d2, true)) { +- level.gameEvent(GameEvent.TELEPORT, vec3, GameEvent.Context.of(entityLiving)); +- SoundSource soundSource; +- SoundEvent soundEvent; ++ Vec3 vec3d = entityLiving.position(); ++ ++ // CraftBukkit start - handle canceled status of teleport event ++ java.util.Optional<Boolean> status = entityLiving.randomTeleport(d0, d1, d2, true, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.CHORUS_FRUIT); ++ ++ if (!status.isPresent()) { ++ // teleport event was canceled, no more tries ++ break; ++ } ++ ++ if (status.get()) { ++ // CraftBukkit end ++ level.gameEvent(GameEvent.TELEPORT, vec3d, GameEvent.Context.of((Entity) entityLiving)); ++ SoundEvent soundeffect; ++ SoundSource soundcategory; ++ + if (entityLiving instanceof Fox) { +- soundEvent = SoundEvents.FOX_TELEPORT; +- soundSource = SoundSource.NEUTRAL; ++ soundeffect = SoundEvents.FOX_TELEPORT; ++ soundcategory = SoundSource.NEUTRAL; + } else { +- soundEvent = SoundEvents.CHORUS_FRUIT_TELEPORT; +- soundSource = SoundSource.PLAYERS; ++ soundeffect = SoundEvents.CHORUS_FRUIT_TELEPORT; ++ soundcategory = SoundSource.PLAYERS; + } + +- level.playSound(null, entityLiving.getX(), entityLiving.getY(), entityLiving.getZ(), soundEvent, soundSource); ++ level.playSound((Player) null, entityLiving.getX(), entityLiving.getY(), entityLiving.getZ(), soundeffect, soundcategory); + entityLiving.resetFallDistance(); + break; + } + } + +- if (entityLiving instanceof Player player) { +- player.getCooldowns().addCooldown(this, 20); ++ if (entityLiving instanceof Player) { ++ Player entityhuman = (Player) entityLiving; ++ ++ entityhuman.getCooldowns().addCooldown(this, 20); + } + } + +- return itemStack; ++ return itemstack1; + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/CrossbowItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/CrossbowItem.java.patch new file mode 100644 index 0000000000..482db78cd4 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/CrossbowItem.java.patch @@ -0,0 +1,526 @@ +--- a/net/minecraft/world/item/CrossbowItem.java ++++ b/net/minecraft/world/item/CrossbowItem.java +@@ -16,8 +16,9 @@ + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.util.RandomSource; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.monster.CrossbowAttackMob; + import net.minecraft.world.entity.player.Player; +@@ -31,7 +32,8 @@ + import org.joml.Quaternionf; + import org.joml.Vector3f; + +-public class CrossbowItem extends ProjectileWeaponItem implements Vanishable { ++public class CrossbowItem extends ProjectileWeaponItem implements ItemVanishable { ++ + private static final String TAG_CHARGED = "Charged"; + private static final String TAG_CHARGED_PROJECTILES = "ChargedProjectiles"; + private static final int MAX_CHARGE_DURATION = 25; +@@ -49,31 +51,32 @@ + + @Override + public Predicate<ItemStack> getSupportedHeldProjectiles() { +- return ARROW_OR_FIREWORK; ++ return CrossbowItem.ARROW_OR_FIREWORK; + } + + @Override + public Predicate<ItemStack> getAllSupportedProjectiles() { +- return ARROW_ONLY; ++ return CrossbowItem.ARROW_ONLY; + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- if (isCharged(itemInHand)) { +- performShooting(level, player, hand, itemInHand, getShootingPower(itemInHand), 1.0F); +- setCharged(itemInHand, false); +- return InteractionResultHolder.consume(itemInHand); +- } else if (!player.getProjectile(itemInHand).isEmpty()) { +- if (!isCharged(itemInHand)) { ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ ++ if (isCharged(itemstack)) { ++ performShooting(level, player, hand, itemstack, getShootingPower(itemstack), 1.0F); ++ setCharged(itemstack, false); ++ return InteractionResultHolder.consume(itemstack); ++ } else if (!player.getProjectile(itemstack).isEmpty()) { ++ if (!isCharged(itemstack)) { + this.startSoundPlayed = false; + this.midLoadSoundPlayed = false; + player.startUsingItem(hand); + } + +- return InteractionResultHolder.consume(itemInHand); ++ return InteractionResultHolder.consume(itemstack); + } else { +- return InteractionResultHolder.fail(itemInHand); ++ return InteractionResultHolder.fail(itemstack); + } + } + +@@ -83,42 +86,36 @@ + + @Override + public void releaseUsing(ItemStack stack, Level level, LivingEntity entityLiving, int timeLeft) { +- int i = this.getUseDuration(stack) - timeLeft; +- float powerForTime = getPowerForTime(i, stack); +- if (powerForTime >= 1.0F && !isCharged(stack) && tryLoadProjectiles(entityLiving, stack)) { ++ int j = this.getUseDuration(stack) - timeLeft; ++ float f = getPowerForTime(j, stack); ++ ++ if (f >= 1.0F && !isCharged(stack) && tryLoadProjectiles(entityLiving, stack)) { + setCharged(stack, true); +- SoundSource soundSource = entityLiving instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE; +- level.playSound( +- null, +- entityLiving.getX(), +- entityLiving.getY(), +- entityLiving.getZ(), +- SoundEvents.CROSSBOW_LOADING_END, +- soundSource, +- 1.0F, +- 1.0F / (level.getRandom().nextFloat() * 0.5F + 1.0F) + 0.2F +- ); ++ SoundSource soundcategory = entityLiving instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE; ++ ++ level.playSound((Player) null, entityLiving.getX(), entityLiving.getY(), entityLiving.getZ(), SoundEvents.CROSSBOW_LOADING_END, soundcategory, 1.0F, 1.0F / (level.getRandom().nextFloat() * 0.5F + 1.0F) + 0.2F); + } ++ + } + + private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack) { +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, crossbowStack); +- int i = itemEnchantmentLevel == 0 ? 1 : 3; +- boolean flag = shooter instanceof Player && ((Player)shooter).getAbilities().instabuild; +- ItemStack projectile = shooter.getProjectile(crossbowStack); +- ItemStack itemStack = projectile.copy(); ++ int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.MULTISHOT, crossbowStack); ++ int j = i == 0 ? 1 : 3; ++ boolean flag = shooter instanceof Player && ((Player) shooter).getAbilities().instabuild; ++ ItemStack itemstack1 = shooter.getProjectile(crossbowStack); ++ ItemStack itemstack2 = itemstack1.copy(); + +- for (int i1 = 0; i1 < i; i1++) { +- if (i1 > 0) { +- projectile = itemStack.copy(); ++ for (int k = 0; k < j; ++k) { ++ if (k > 0) { ++ itemstack1 = itemstack2.copy(); + } + +- if (projectile.isEmpty() && flag) { +- projectile = new ItemStack(Items.ARROW); +- itemStack = projectile.copy(); ++ if (itemstack1.isEmpty() && flag) { ++ itemstack1 = new ItemStack(Items.ARROW); ++ itemstack2 = itemstack1.copy(); + } + +- if (!loadProjectile(shooter, crossbowStack, projectile, i1 > 0, flag)) { ++ if (!loadProjectile(shooter, crossbowStack, itemstack1, k > 0, flag)) { + return false; + } + } +@@ -130,56 +127,64 @@ + if (ammoStack.isEmpty()) { + return false; + } else { +- boolean flag = isCreative && ammoStack.getItem() instanceof ArrowItem; +- ItemStack itemStack; +- if (!flag && !isCreative && !hasAmmo) { +- itemStack = ammoStack.split(1); ++ boolean flag2 = isCreative && ammoStack.getItem() instanceof ArrowItem; ++ ItemStack itemstack2; ++ ++ if (!flag2 && !isCreative && !hasAmmo) { ++ itemstack2 = ammoStack.split(1); + if (ammoStack.isEmpty() && shooter instanceof Player) { +- ((Player)shooter).getInventory().removeItem(ammoStack); ++ ((Player) shooter).getInventory().removeItem(ammoStack); + } + } else { +- itemStack = ammoStack.copy(); ++ itemstack2 = ammoStack.copy(); + } + +- addChargedProjectile(crossbowStack, itemStack); ++ addChargedProjectile(crossbowStack, itemstack2); + return true; + } + } + + public static boolean isCharged(ItemStack crossbowStack) { +- CompoundTag tag = crossbowStack.getTag(); +- return tag != null && tag.getBoolean("Charged"); ++ CompoundTag nbttagcompound = crossbowStack.getTag(); ++ ++ return nbttagcompound != null && nbttagcompound.getBoolean("Charged"); + } + + public static void setCharged(ItemStack crossbowStack, boolean isCharged) { +- CompoundTag tag = crossbowStack.getOrCreateTag(); +- tag.putBoolean("Charged", isCharged); ++ CompoundTag nbttagcompound = crossbowStack.getOrCreateTag(); ++ ++ nbttagcompound.putBoolean("Charged", isCharged); + } + + private static void addChargedProjectile(ItemStack crossbowStack, ItemStack ammoStack) { +- CompoundTag tag = crossbowStack.getOrCreateTag(); +- ListTag list; +- if (tag.contains("ChargedProjectiles", 9)) { +- list = tag.getList("ChargedProjectiles", 10); ++ CompoundTag nbttagcompound = crossbowStack.getOrCreateTag(); ++ ListTag nbttaglist; ++ ++ if (nbttagcompound.contains("ChargedProjectiles", 9)) { ++ nbttaglist = nbttagcompound.getList("ChargedProjectiles", 10); + } else { +- list = new ListTag(); ++ nbttaglist = new ListTag(); + } + +- CompoundTag compoundTag = new CompoundTag(); +- ammoStack.save(compoundTag); +- list.add(compoundTag); +- tag.put("ChargedProjectiles", list); ++ CompoundTag nbttagcompound1 = new CompoundTag(); ++ ++ ammoStack.save(nbttagcompound1); ++ nbttaglist.add(nbttagcompound1); ++ nbttagcompound.put("ChargedProjectiles", nbttaglist); + } + + private static List<ItemStack> getChargedProjectiles(ItemStack crossbowStack) { + List<ItemStack> list = Lists.newArrayList(); +- CompoundTag tag = crossbowStack.getTag(); +- if (tag != null && tag.contains("ChargedProjectiles", 9)) { +- ListTag list1 = tag.getList("ChargedProjectiles", 10); +- if (list1 != null) { +- for (int i = 0; i < list1.size(); i++) { +- CompoundTag compound = list1.getCompound(i); +- list.add(ItemStack.of(compound)); ++ CompoundTag nbttagcompound = crossbowStack.getTag(); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("ChargedProjectiles", 9)) { ++ ListTag nbttaglist = nbttagcompound.getList("ChargedProjectiles", 10); ++ ++ if (nbttaglist != null) { ++ for (int i = 0; i < nbttaglist.size(); ++i) { ++ CompoundTag nbttagcompound1 = nbttaglist.getCompound(i); ++ ++ list.add(ItemStack.of(nbttagcompound1)); + } + } + } +@@ -188,90 +193,108 @@ + } + + private static void clearChargedProjectiles(ItemStack crossbowStack) { +- CompoundTag tag = crossbowStack.getTag(); +- if (tag != null) { +- ListTag list = tag.getList("ChargedProjectiles", 9); +- list.clear(); +- tag.put("ChargedProjectiles", list); ++ CompoundTag nbttagcompound = crossbowStack.getTag(); ++ ++ if (nbttagcompound != null) { ++ ListTag nbttaglist = nbttagcompound.getList("ChargedProjectiles", 9); ++ ++ nbttaglist.clear(); ++ nbttagcompound.put("ChargedProjectiles", nbttaglist); + } ++ + } + + public static boolean containsChargedProjectile(ItemStack crossbowStack, Item ammoItem) { +- return getChargedProjectiles(crossbowStack).stream().anyMatch(stackToCheck -> stackToCheck.is(ammoItem)); ++ return getChargedProjectiles(crossbowStack).stream().anyMatch((itemstack1) -> { ++ return itemstack1.is(ammoItem); ++ }); + } + +- private static void shootProjectile( +- Level level, +- LivingEntity shooter, +- InteractionHand hand, +- ItemStack crossbowStack, +- ItemStack ammoStack, +- float soundPitch, +- boolean isCreativeMode, +- float velocity, +- float inaccuracy, +- float projectileAngle +- ) { ++ private static void shootProjectile(Level level, LivingEntity shooter, EnumHand hand, ItemStack crossbowStack, ItemStack ammoStack, float soundPitch, boolean isCreativeMode, float velocity, float inaccuracy, float projectileAngle) { + if (!level.isClientSide) { +- boolean isFireworkRocket = ammoStack.is(Items.FIREWORK_ROCKET); +- Projectile projectile; +- if (isFireworkRocket) { +- projectile = new FireworkRocketEntity(level, ammoStack, shooter, shooter.getX(), shooter.getEyeY() - 0.15F, shooter.getZ(), true); ++ boolean flag1 = ammoStack.is(Items.FIREWORK_ROCKET); ++ Object object; ++ ++ if (flag1) { ++ object = new FireworkRocketEntity(level, ammoStack, shooter, shooter.getX(), shooter.getEyeY() - 0.15000000596046448D, shooter.getZ(), true); + } else { +- projectile = getArrow(level, shooter, crossbowStack, ammoStack); ++ object = getArrow(level, shooter, crossbowStack, ammoStack); + if (isCreativeMode || projectileAngle != 0.0F) { +- ((AbstractArrow)projectile).pickup = AbstractArrow.Pickup.CREATIVE_ONLY; ++ ((AbstractArrow) object).pickup = AbstractArrow.Pickup.CREATIVE_ONLY; + } + } + +- if (shooter instanceof CrossbowAttackMob crossbowAttackMob) { +- crossbowAttackMob.shootCrossbowProjectile(crossbowAttackMob.getTarget(), crossbowStack, projectile, projectileAngle); ++ if (shooter instanceof CrossbowAttackMob) { ++ CrossbowAttackMob icrossbow = (CrossbowAttackMob) shooter; ++ ++ icrossbow.shootCrossbowProjectile(icrossbow.getTarget(), crossbowStack, (Projectile) object, projectileAngle); + } else { +- Vec3 upVector = shooter.getUpVector(1.0F); +- Quaternionf quaternionf = new Quaternionf() +- .setAngleAxis((double)(projectileAngle * (float) (Math.PI / 180.0)), upVector.x, upVector.y, upVector.z); +- Vec3 viewVector = shooter.getViewVector(1.0F); +- Vector3f vector3f = viewVector.toVector3f().rotate(quaternionf); +- projectile.shoot((double)vector3f.x(), (double)vector3f.y(), (double)vector3f.z(), velocity, inaccuracy); ++ Vec3 vec3d = shooter.getUpVector(1.0F); ++ Quaternionf quaternionf = (new Quaternionf()).setAngleAxis((double) (projectileAngle * 0.017453292F), vec3d.x, vec3d.y, vec3d.z); ++ Vec3 vec3d1 = shooter.getViewVector(1.0F); ++ Vector3f vector3f = vec3d1.toVector3f().rotate(quaternionf); ++ ++ ((Projectile) object).shoot((double) vector3f.x(), (double) vector3f.y(), (double) vector3f.z(), velocity, inaccuracy); + } ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, crossbowStack, ammoStack, (Entity) object, shooter.getUsedItemHand(), soundPitch, true); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; ++ } ++ // CraftBukkit end + +- crossbowStack.hurtAndBreak(isFireworkRocket ? 3 : 1, shooter, contextEntity -> contextEntity.broadcastBreakEvent(hand)); +- level.addFreshEntity(projectile); +- level.playSound(null, shooter.getX(), shooter.getY(), shooter.getZ(), SoundEvents.CROSSBOW_SHOOT, SoundSource.PLAYERS, 1.0F, soundPitch); ++ crossbowStack.hurtAndBreak(flag1 ? 3 : 1, shooter, (entityliving1) -> { ++ entityliving1.broadcastBreakEvent(hand); ++ }); ++ // CraftBukkit start ++ if (event.getProjectile() == ((Entity) object).getBukkitEntity()) { ++ if (!level.addFreshEntity((Entity) object)) { ++ if (shooter instanceof ServerPlayer) { ++ ((ServerPlayer) shooter).getBukkitEntity().updateInventory(); ++ } ++ return; ++ } ++ } ++ // CraftBukkit end ++ level.playSound((Player) null, shooter.getX(), shooter.getY(), shooter.getZ(), SoundEvents.CROSSBOW_SHOOT, SoundSource.PLAYERS, 1.0F, soundPitch); + } + } + + private static AbstractArrow getArrow(Level level, LivingEntity livingEntity, ItemStack crossbowStack, ItemStack ammoStack) { +- ArrowItem arrowItem = (ArrowItem)(ammoStack.getItem() instanceof ArrowItem ? ammoStack.getItem() : Items.ARROW); +- AbstractArrow abstractArrow = arrowItem.createArrow(level, ammoStack, livingEntity); ++ ArrowItem itemarrow = (ArrowItem) (ammoStack.getItem() instanceof ArrowItem ? ammoStack.getItem() : Items.ARROW); ++ AbstractArrow entityarrow = itemarrow.createArrow(level, ammoStack, livingEntity); ++ + if (livingEntity instanceof Player) { +- abstractArrow.setCritArrow(true); ++ entityarrow.setCritArrow(true); + } + +- abstractArrow.setSoundEvent(SoundEvents.CROSSBOW_HIT); +- abstractArrow.setShotFromCrossbow(true); +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.PIERCING, crossbowStack); +- if (itemEnchantmentLevel > 0) { +- abstractArrow.setPierceLevel((byte)itemEnchantmentLevel); ++ entityarrow.setSoundEvent(SoundEvents.CROSSBOW_HIT); ++ entityarrow.setShotFromCrossbow(true); ++ int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.PIERCING, crossbowStack); ++ ++ if (i > 0) { ++ entityarrow.setPierceLevel((byte) i); + } + +- return abstractArrow; ++ return entityarrow; + } + +- public static void performShooting(Level level, LivingEntity shooter, InteractionHand usedHand, ItemStack crossbowStack, float velocity, float inaccuracy) { +- List<ItemStack> chargedProjectiles = getChargedProjectiles(crossbowStack); +- float[] shotPitches = getShotPitches(shooter.getRandom()); ++ public static void performShooting(Level level, LivingEntity shooter, EnumHand usedHand, ItemStack crossbowStack, float velocity, float inaccuracy) { ++ List<ItemStack> list = getChargedProjectiles(crossbowStack); ++ float[] afloat = getShotPitches(shooter.getRandom()); + +- for (int i = 0; i < chargedProjectiles.size(); i++) { +- ItemStack itemStack = chargedProjectiles.get(i); +- boolean flag = shooter instanceof Player && ((Player)shooter).getAbilities().instabuild; +- if (!itemStack.isEmpty()) { ++ for (int i = 0; i < list.size(); ++i) { ++ ItemStack itemstack1 = (ItemStack) list.get(i); ++ boolean flag = shooter instanceof Player && ((Player) shooter).getAbilities().instabuild; ++ ++ if (!itemstack1.isEmpty()) { + if (i == 0) { +- shootProjectile(level, shooter, usedHand, crossbowStack, itemStack, shotPitches[i], flag, velocity, inaccuracy, 0.0F); ++ shootProjectile(level, shooter, usedHand, crossbowStack, itemstack1, afloat[i], flag, velocity, inaccuracy, 0.0F); + } else if (i == 1) { +- shootProjectile(level, shooter, usedHand, crossbowStack, itemStack, shotPitches[i], flag, velocity, inaccuracy, -10.0F); ++ shootProjectile(level, shooter, usedHand, crossbowStack, itemstack1, afloat[i], flag, velocity, inaccuracy, -10.0F); + } else if (i == 2) { +- shootProjectile(level, shooter, usedHand, crossbowStack, itemStack, shotPitches[i], flag, velocity, inaccuracy, 10.0F); ++ shootProjectile(level, shooter, usedHand, crossbowStack, itemstack1, afloat[i], flag, velocity, inaccuracy, 10.0F); + } + } + } +@@ -280,22 +303,26 @@ + } + + private static float[] getShotPitches(RandomSource random) { +- boolean randomBoolean = random.nextBoolean(); +- return new float[]{1.0F, getRandomShotPitch(randomBoolean, random), getRandomShotPitch(!randomBoolean, random)}; ++ boolean flag = random.nextBoolean(); ++ ++ return new float[]{1.0F, getRandomShotPitch(flag, random), getRandomShotPitch(!flag, random)}; + } + + private static float getRandomShotPitch(boolean isHighPitched, RandomSource random) { + float f = isHighPitched ? 0.63F : 0.43F; ++ + return 1.0F / (random.nextFloat() * 0.5F + 1.8F) + f; + } + + private static void onCrossbowShot(Level level, LivingEntity shooter, ItemStack crossbowStack) { +- if (shooter instanceof ServerPlayer serverPlayer) { ++ if (shooter instanceof ServerPlayer) { ++ ServerPlayer entityplayer = (ServerPlayer) shooter; ++ + if (!level.isClientSide) { +- CriteriaTriggers.SHOT_CROSSBOW.trigger(serverPlayer, crossbowStack); ++ CriteriaTriggers.SHOT_CROSSBOW.trigger(entityplayer, crossbowStack); + } + +- serverPlayer.awardStat(Stats.ITEM_USED.get(crossbowStack.getItem())); ++ entityplayer.awardStat(Stats.ITEM_USED.get(crossbowStack.getItem())); + } + + clearChargedProjectiles(crossbowStack); +@@ -304,10 +331,11 @@ + @Override + public void onUseTick(Level level, LivingEntity livingEntity, ItemStack stack, int count) { + if (!level.isClientSide) { +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.QUICK_CHARGE, stack); +- SoundEvent startSound = this.getStartSound(itemEnchantmentLevel); +- SoundEvent soundEvent = itemEnchantmentLevel == 0 ? SoundEvents.CROSSBOW_LOADING_MIDDLE : null; +- float f = (float)(stack.getUseDuration() - count) / (float)getChargeDuration(stack); ++ int j = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.QUICK_CHARGE, stack); ++ SoundEvent soundeffect = this.getStartSound(j); ++ SoundEvent soundeffect1 = j == 0 ? SoundEvents.CROSSBOW_LOADING_MIDDLE : null; ++ float f = (float) (stack.getUseDuration() - count) / (float) getChargeDuration(stack); ++ + if (f < 0.2F) { + this.startSoundPlayed = false; + this.midLoadSoundPlayed = false; +@@ -315,14 +343,15 @@ + + if (f >= 0.2F && !this.startSoundPlayed) { + this.startSoundPlayed = true; +- level.playSound(null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), startSound, SoundSource.PLAYERS, 0.5F, 1.0F); ++ level.playSound((Player) null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), soundeffect, SoundSource.PLAYERS, 0.5F, 1.0F); + } + +- if (f >= 0.5F && soundEvent != null && !this.midLoadSoundPlayed) { ++ if (f >= 0.5F && soundeffect1 != null && !this.midLoadSoundPlayed) { + this.midLoadSoundPlayed = true; +- level.playSound(null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), soundEvent, SoundSource.PLAYERS, 0.5F, 1.0F); ++ level.playSound((Player) null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), soundeffect1, SoundSource.PLAYERS, 0.5F, 1.0F); + } + } ++ + } + + @Override +@@ -331,13 +360,14 @@ + } + + public static int getChargeDuration(ItemStack crossbowStack) { +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.QUICK_CHARGE, crossbowStack); +- return itemEnchantmentLevel == 0 ? 25 : 25 - 5 * itemEnchantmentLevel; ++ int i = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.QUICK_CHARGE, crossbowStack); ++ ++ return i == 0 ? 25 : 25 - 5 * i; + } + + @Override +- public UseAnim getUseAnimation(ItemStack stack) { +- return UseAnim.CROSSBOW; ++ public EnumAnimation getUseAnimation(ItemStack stack) { ++ return EnumAnimation.CROSSBOW; + } + + private SoundEvent getStartSound(int enchantmentLevel) { +@@ -354,7 +384,8 @@ + } + + private static float getPowerForTime(int useTime, ItemStack crossbowStack) { +- float f = (float)useTime / (float)getChargeDuration(crossbowStack); ++ float f = (float) useTime / (float) getChargeDuration(crossbowStack); ++ + if (f > 1.0F) { + f = 1.0F; + } +@@ -364,27 +395,31 @@ + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) { +- List<ItemStack> chargedProjectiles = getChargedProjectiles(stack); +- if (isCharged(stack) && !chargedProjectiles.isEmpty()) { +- ItemStack itemStack = chargedProjectiles.get(0); +- tooltip.add(Component.translatable("item.minecraft.crossbow.projectile").append(CommonComponents.SPACE).append(itemStack.getDisplayName())); +- if (flag.isAdvanced() && itemStack.is(Items.FIREWORK_ROCKET)) { +- List<Component> list = Lists.newArrayList(); +- Items.FIREWORK_ROCKET.appendHoverText(itemStack, level, list, flag); +- if (!list.isEmpty()) { +- for (int i = 0; i < list.size(); i++) { +- list.set(i, Component.literal(" ").append(list.get(i)).withStyle(ChatFormatting.GRAY)); ++ List<ItemStack> list1 = getChargedProjectiles(stack); ++ ++ if (isCharged(stack) && !list1.isEmpty()) { ++ ItemStack itemstack1 = (ItemStack) list1.get(0); ++ ++ tooltip.add(Component.translatable("item.minecraft.crossbow.projectile").append(CommonComponents.SPACE).append(itemstack1.getDisplayName())); ++ if (flag.isAdvanced() && itemstack1.is(Items.FIREWORK_ROCKET)) { ++ List<Component> list2 = Lists.newArrayList(); ++ ++ Items.FIREWORK_ROCKET.appendHoverText(itemstack1, level, list2, flag); ++ if (!list2.isEmpty()) { ++ for (int i = 0; i < list2.size(); ++i) { ++ list2.set(i, Component.literal(" ").append((Component) list2.get(i)).withStyle(ChatFormatting.GRAY)); + } + +- tooltip.addAll(list); ++ tooltip.addAll(list2); + } + } ++ + } + } + + @Override + public boolean useOnRelease(ItemStack stack) { +- return stack.is(this); ++ return stack.is((Item) this); + } + + @Override diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/DebugStickItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/DebugStickItem.java.patch new file mode 100644 index 0000000000..9933f93c07 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/DebugStickItem.java.patch @@ -0,0 +1,144 @@ +--- a/net/minecraft/world/item/DebugStickItem.java ++++ b/net/minecraft/world/item/DebugStickItem.java +@@ -1,3 +1,4 @@ ++// mc-dev import + package net.minecraft.world.item; + + import java.util.Collection; +@@ -8,18 +9,19 @@ + import net.minecraft.nbt.CompoundTag; + import net.minecraft.network.chat.Component; + import net.minecraft.server.level.ServerPlayer; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.LevelAccessor; + import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.StateDefinition; + import net.minecraft.world.level.block.state.properties.Property; + + public class DebugStickItem extends Item { ++ + public DebugStickItem(Item.Properties properties) { + super(properties); + } +@@ -30,9 +32,9 @@ + } + + @Override +- public boolean canAttackBlock(BlockState state, Level level, BlockPos pos, Player player) { ++ public boolean canAttackBlock(IBlockData state, Level level, BlockPos pos, Player player) { + if (!level.isClientSide) { +- this.handleInteraction(player, state, level, pos, false, player.getItemInHand(InteractionHand.MAIN_HAND)); ++ this.handleInteraction(player, state, level, pos, false, player.getItemInHand(EnumHand.MAIN_HAND)); + } + + return false; +@@ -40,48 +42,52 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- Player player = context.getPlayer(); +- Level level = context.getLevel(); +- if (!level.isClientSide && player != null) { +- BlockPos clickedPos = context.getClickedPos(); +- if (!this.handleInteraction(player, level.getBlockState(clickedPos), level, clickedPos, true, context.getItemInHand())) { ++ Player entityhuman = context.getPlayer(); ++ Level world = context.getLevel(); ++ ++ if (!world.isClientSide && entityhuman != null) { ++ BlockPos blockposition = context.getClickedPos(); ++ ++ if (!this.handleInteraction(entityhuman, world.getBlockState(blockposition), world, blockposition, true, context.getItemInHand())) { + return InteractionResult.FAIL; + } + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } + +- private boolean handleInteraction( +- Player player, BlockState stateClicked, LevelAccessor accessor, BlockPos pos, boolean shouldCycleState, ItemStack debugStack +- ) { ++ public boolean handleInteraction(Player player, IBlockData stateClicked, LevelAccessor accessor, BlockPos pos, boolean shouldCycleState, ItemStack debugStack) { + if (!player.canUseGameMasterBlocks()) { + return false; + } else { + Block block = stateClicked.getBlock(); +- StateDefinition<Block, BlockState> stateDefinition = block.getStateDefinition(); +- Collection<Property<?>> properties = stateDefinition.getProperties(); +- String string = BuiltInRegistries.BLOCK.getKey(block).toString(); +- if (properties.isEmpty()) { +- message(player, Component.translatable(this.getDescriptionId() + ".empty", string)); ++ StateDefinition<Block, IBlockData> blockstatelist = block.getStateDefinition(); ++ Collection<Property<?>> collection = blockstatelist.getProperties(); ++ String s = BuiltInRegistries.BLOCK.getKey(block).toString(); ++ ++ if (collection.isEmpty()) { ++ message(player, Component.translatable(this.getDescriptionId() + ".empty", s)); + return false; + } else { +- CompoundTag tagElement = debugStack.getOrCreateTagElement("DebugProperty"); +- String string1 = tagElement.getString(string); +- Property<?> property = stateDefinition.getProperty(string1); ++ CompoundTag nbttagcompound = debugStack.getOrCreateTagElement("DebugProperty"); ++ String s1 = nbttagcompound.getString(s); ++ Property<?> iblockstate = blockstatelist.getProperty(s1); ++ + if (shouldCycleState) { +- if (property == null) { +- property = properties.iterator().next(); ++ if (iblockstate == null) { ++ iblockstate = (Property) collection.iterator().next(); + } + +- BlockState blockState = cycleState(stateClicked, property, player.isSecondaryUseActive()); +- accessor.setBlock(pos, blockState, 18); +- message(player, Component.translatable(this.getDescriptionId() + ".update", property.getName(), getNameHelper(blockState, property))); ++ IBlockData iblockdata1 = cycleState(stateClicked, iblockstate, player.isSecondaryUseActive()); ++ ++ accessor.setBlock(pos, iblockdata1, 18); ++ message(player, Component.translatable(this.getDescriptionId() + ".update", iblockstate.getName(), getNameHelper(iblockdata1, iblockstate))); + } else { +- property = getRelative(properties, property, player.isSecondaryUseActive()); +- String name = property.getName(); +- tagElement.putString(string, name); +- message(player, Component.translatable(this.getDescriptionId() + ".select", name, getNameHelper(stateClicked, property))); ++ iblockstate = (Property) getRelative(collection, iblockstate, player.isSecondaryUseActive()); ++ String s2 = iblockstate.getName(); ++ ++ nbttagcompound.putString(s, s2); ++ message(player, Component.translatable(this.getDescriptionId() + ".select", s2, getNameHelper(stateClicked, iblockstate))); + } + + return true; +@@ -89,8 +95,8 @@ + } + } + +- private static <T extends Comparable<T>> BlockState cycleState(BlockState state, Property<T> property, boolean backwards) { +- return state.setValue(property, getRelative(property.getPossibleValues(), state.getValue(property), backwards)); ++ private static <T extends Comparable<T>> IBlockData cycleState(IBlockData state, Property<T> property, boolean backwards) { ++ return (IBlockData) state.setValue(property, getRelative(property.getPossibleValues(), state.getValue(property), backwards)); // CraftBukkit - decompile error + } + + private static <T> T getRelative(Iterable<T> allowedValues, @Nullable T currentValue, boolean backwards) { +@@ -98,10 +104,10 @@ + } + + private static void message(Player player, Component messageComponent) { +- ((ServerPlayer)player).sendSystemMessage(messageComponent, true); ++ ((ServerPlayer) player).sendSystemMessage(messageComponent, true); + } + +- private static <T extends Comparable<T>> String getNameHelper(BlockState state, Property<T> property) { ++ private static <T extends Comparable<T>> String getNameHelper(IBlockData state, Property<T> property) { + return property.getName(state.getValue(property)); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/DyeItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/DyeItem.java.patch new file mode 100644 index 0000000000..7d57bbc525 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/DyeItem.java.patch @@ -0,0 +1,84 @@ +--- a/net/minecraft/world/item/DyeItem.java ++++ b/net/minecraft/world/item/DyeItem.java +@@ -4,35 +4,51 @@ + import java.util.Map; + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.animal.Sheep; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.entity.SignBlockEntity; +-import net.minecraft.world.level.block.entity.SignText; ++import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit + + public class DyeItem extends Item implements SignApplicator { ++ + private static final Map<DyeColor, DyeItem> ITEM_BY_COLOR = Maps.newEnumMap(DyeColor.class); + private final DyeColor dyeColor; + + public DyeItem(DyeColor dyeColor, Item.Properties properties) { + super(properties); + this.dyeColor = dyeColor; +- ITEM_BY_COLOR.put(dyeColor, this); ++ DyeItem.ITEM_BY_COLOR.put(dyeColor, this); + } + + @Override +- public InteractionResult interactLivingEntity(ItemStack stack, Player player, LivingEntity target, InteractionHand hand) { +- if (target instanceof Sheep sheep && sheep.isAlive() && !sheep.isSheared() && sheep.getColor() != this.dyeColor) { +- sheep.level().playSound(player, sheep, SoundEvents.DYE_USE, SoundSource.PLAYERS, 1.0F, 1.0F); +- if (!player.level().isClientSide) { +- sheep.setColor(this.dyeColor); +- stack.shrink(1); +- } ++ public InteractionResult interactLivingEntity(ItemStack stack, Player player, LivingEntity target, EnumHand hand) { ++ if (target instanceof Sheep) { ++ Sheep entitysheep = (Sheep) target; + +- return InteractionResult.sidedSuccess(player.level().isClientSide); ++ if (entitysheep.isAlive() && !entitysheep.isSheared() && entitysheep.getColor() != this.dyeColor) { ++ entitysheep.level().playSound(player, (Entity) entitysheep, SoundEvents.DYE_USE, SoundSource.PLAYERS, 1.0F, 1.0F); ++ if (!player.level().isClientSide) { ++ // CraftBukkit start ++ byte bColor = (byte) this.dyeColor.getId(); ++ SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor), (org.bukkit.entity.Player) player.getBukkitEntity()); ++ entitysheep.level().getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return InteractionResult.PASS; ++ } ++ ++ entitysheep.setColor(DyeColor.byId((byte) event.getColor().getWoolData())); ++ // CraftBukkit end ++ stack.shrink(1); ++ } ++ ++ return InteractionResult.sidedSuccess(player.level().isClientSide); ++ } + } + + return InteractionResult.PASS; +@@ -43,13 +59,15 @@ + } + + public static DyeItem byColor(DyeColor color) { +- return ITEM_BY_COLOR.get(color); ++ return (DyeItem) DyeItem.ITEM_BY_COLOR.get(color); + } + + @Override + public boolean tryApplyToSign(Level level, SignBlockEntity sign, boolean isFront, Player player) { +- if (sign.updateText(signText -> signText.setColor(this.getDyeColor()), isFront)) { +- level.playSound(null, sign.getBlockPos(), SoundEvents.DYE_USE, SoundSource.BLOCKS, 1.0F, 1.0F); ++ if (sign.updateText((signtext) -> { ++ return signtext.setColor(this.getDyeColor()); ++ }, isFront)) { ++ level.playSound((Player) null, sign.getBlockPos(), SoundEvents.DYE_USE, SoundSource.BLOCKS, 1.0F, 1.0F); + return true; + } else { + return false; diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/EggItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/EggItem.java.patch new file mode 100644 index 0000000000..ed27a63783 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/EggItem.java.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/world/item/EggItem.java ++++ b/net/minecraft/world/item/EggItem.java +@@ -3,42 +3,44 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.projectile.ThrownEgg; + import net.minecraft.world.level.Level; + + public class EggItem extends Item { ++ + public EggItem(Item.Properties properties) { + super(properties); + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.EGG_THROW, +- SoundSource.PLAYERS, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ ++ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // CraftBukkit - moved down + if (!level.isClientSide) { +- ThrownEgg thrownEgg = new ThrownEgg(level, player); +- thrownEgg.setItem(itemInHand); +- thrownEgg.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); +- level.addFreshEntity(thrownEgg); ++ ThrownEgg entityegg = new ThrownEgg(level, player); ++ ++ entityegg.setItem(itemstack); ++ entityegg.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); ++ // CraftBukkit start ++ if (!level.addFreshEntity(entityegg)) { ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResultHolder.fail(itemstack); ++ } ++ // CraftBukkit end + } ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); + + player.awardStat(Stats.ITEM_USED.get(this)); + if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ itemstack.shrink(1); + } + +- return InteractionResultHolder.sidedSuccess(itemInHand, level.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/EndCrystalItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/EndCrystalItem.java.patch new file mode 100644 index 0000000000..dbe8d5b5fc --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/EndCrystalItem.java.patch @@ -0,0 +1,83 @@ +--- a/net/minecraft/world/item/EndCrystalItem.java ++++ b/net/minecraft/world/item/EndCrystalItem.java +@@ -9,48 +9,59 @@ + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.dimension.end.EndDragonFight; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.AABB; + + public class EndCrystalItem extends Item { ++ + public EndCrystalItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (!blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) { ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ ++ if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { + return InteractionResult.FAIL; + } else { +- BlockPos blockPos = clickedPos.above(); +- if (!level.isEmptyBlock(blockPos)) { ++ BlockPos blockposition1 = blockposition.above(); ++ ++ if (!world.isEmptyBlock(blockposition1)) { + return InteractionResult.FAIL; + } else { +- double d = (double)blockPos.getX(); +- double d1 = (double)blockPos.getY(); +- double d2 = (double)blockPos.getZ(); +- List<Entity> entities = level.getEntities(null, new AABB(d, d1, d2, d + 1.0, d1 + 2.0, d2 + 1.0)); +- if (!entities.isEmpty()) { ++ double d0 = (double) blockposition1.getX(); ++ double d1 = (double) blockposition1.getY(); ++ double d2 = (double) blockposition1.getZ(); ++ List<Entity> list = world.getEntities((Entity) null, new AABB(d0, d1, d2, d0 + 1.0D, d1 + 2.0D, d2 + 1.0D)); ++ ++ if (!list.isEmpty()) { + return InteractionResult.FAIL; + } else { +- if (level instanceof ServerLevel) { +- EndCrystal endCrystal = new EndCrystal(level, d + 0.5, d1, d2 + 0.5); +- endCrystal.setShowBottom(false); +- level.addFreshEntity(endCrystal); +- level.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, blockPos); +- EndDragonFight dragonFight = ((ServerLevel)level).getDragonFight(); +- if (dragonFight != null) { +- dragonFight.tryRespawn(); ++ if (world instanceof ServerLevel) { ++ EndCrystal entityendercrystal = new EndCrystal(world, d0 + 0.5D, d1, d2 + 0.5D); ++ ++ entityendercrystal.setShowBottom(false); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityendercrystal).isCancelled()) { ++ return InteractionResult.FAIL; + } ++ // CraftBukkit end ++ world.addFreshEntity(entityendercrystal); ++ world.gameEvent((Entity) context.getPlayer(), GameEvent.ENTITY_PLACE, blockposition1); ++ EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight(); ++ ++ if (enderdragonbattle != null) { ++ enderdragonbattle.tryRespawn(); ++ } + } + + context.getItemInHand().shrink(1); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/EnderEyeItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/EnderEyeItem.java.patch new file mode 100644 index 0000000000..23e574aaab --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/EnderEyeItem.java.patch @@ -0,0 +1,164 @@ +--- a/net/minecraft/world/item/EnderEyeItem.java ++++ b/net/minecraft/world/item/EnderEyeItem.java +@@ -8,9 +8,10 @@ + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.tags.StructureTags; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.InteractionResultHolder; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.projectile.EyeOfEnder; + import net.minecraft.world.item.context.UseOnContext; +@@ -19,92 +20,97 @@ + import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.EndPortalFrameBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.pattern.BlockPattern; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.HitResult; + + public class EnderEyeItem extends Item { ++ + public EnderEyeItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (!blockState.is(Blocks.END_PORTAL_FRAME) || blockState.getValue(EndPortalFrameBlock.HAS_EYE)) { +- return InteractionResult.PASS; +- } else if (level.isClientSide) { +- return InteractionResult.SUCCESS; +- } else { +- BlockState blockState1 = blockState.setValue(EndPortalFrameBlock.HAS_EYE, Boolean.valueOf(true)); +- Block.pushEntitiesUp(blockState, blockState1, level, clickedPos); +- level.setBlock(clickedPos, blockState1, 2); +- level.updateNeighbourForOutputSignal(clickedPos, Blocks.END_PORTAL_FRAME); +- context.getItemInHand().shrink(1); +- level.levelEvent(1503, clickedPos, 0); +- BlockPattern.BlockPatternMatch blockPatternMatch = EndPortalFrameBlock.getOrCreatePortalShape().find(level, clickedPos); +- if (blockPatternMatch != null) { +- BlockPos blockPos = blockPatternMatch.getFrontTopLeft().offset(-3, 0, -3); ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); + +- for (int i = 0; i < 3; i++) { +- for (int i1 = 0; i1 < 3; i1++) { +- level.setBlock(blockPos.offset(i, 0, i1), Blocks.END_PORTAL.defaultBlockState(), 2); ++ if (iblockdata.is(Blocks.END_PORTAL_FRAME) && !(Boolean) iblockdata.getValue(EndPortalFrameBlock.HAS_EYE)) { ++ if (world.isClientSide) { ++ return InteractionResult.SUCCESS; ++ } else { ++ IBlockData iblockdata1 = (IBlockData) iblockdata.setValue(EndPortalFrameBlock.HAS_EYE, true); ++ ++ Block.pushEntitiesUp(iblockdata, iblockdata1, world, blockposition); ++ world.setBlock(blockposition, iblockdata1, 2); ++ world.updateNeighbourForOutputSignal(blockposition, Blocks.END_PORTAL_FRAME); ++ context.getItemInHand().shrink(1); ++ world.levelEvent(1503, blockposition, 0); ++ BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection = EndPortalFrameBlock.getOrCreatePortalShape().find(world, blockposition); ++ ++ if (shapedetector_shapedetectorcollection != null) { ++ BlockPos blockposition1 = shapedetector_shapedetectorcollection.getFrontTopLeft().offset(-3, 0, -3); ++ ++ for (int i = 0; i < 3; ++i) { ++ for (int j = 0; j < 3; ++j) { ++ world.setBlock(blockposition1.offset(i, 0, j), Blocks.END_PORTAL.defaultBlockState(), 2); ++ } + } ++ ++ world.globalLevelEvent(1038, blockposition1.offset(1, 0, 1), 0); + } + +- level.globalLevelEvent(1038, blockPos.offset(1, 0, 1), 0); ++ return InteractionResult.CONSUME; + } +- +- return InteractionResult.CONSUME; ++ } else { ++ return InteractionResult.PASS; + } + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- BlockHitResult playerPOVHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.NONE); +- if (playerPOVHitResult.getType() == HitResult.Type.BLOCK && level.getBlockState(playerPOVHitResult.getBlockPos()).is(Blocks.END_PORTAL_FRAME)) { +- return InteractionResultHolder.pass(itemInHand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ BlockHitResult movingobjectpositionblock = getPlayerPOVHitResult(level, player, ClipContext.Fluid.NONE); ++ ++ if (movingobjectpositionblock.getType() == HitResult.EnumMovingObjectType.BLOCK && level.getBlockState(movingobjectpositionblock.getBlockPos()).is(Blocks.END_PORTAL_FRAME)) { ++ return InteractionResultHolder.pass(itemstack); + } else { + player.startUsingItem(hand); +- if (level instanceof ServerLevel serverLevel) { +- BlockPos blockPos = serverLevel.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false); +- if (blockPos != null) { +- EyeOfEnder eyeOfEnder = new EyeOfEnder(level, player.getX(), player.getY(0.5), player.getZ()); +- eyeOfEnder.setItem(itemInHand); +- eyeOfEnder.signalTo(blockPos); +- level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player)); +- level.addFreshEntity(eyeOfEnder); ++ if (level instanceof ServerLevel) { ++ ServerLevel worldserver = (ServerLevel) level; ++ BlockPos blockposition = worldserver.findNearestMapStructure(StructureTags.EYE_OF_ENDER_LOCATED, player.blockPosition(), 100, false); ++ ++ if (blockposition != null) { ++ EyeOfEnder entityendersignal = new EyeOfEnder(level, player.getX(), player.getY(0.5D), player.getZ()); ++ ++ entityendersignal.setItem(itemstack); ++ entityendersignal.signalTo(blockposition); ++ level.gameEvent(GameEvent.PROJECTILE_SHOOT, entityendersignal.position(), GameEvent.Context.of((Entity) player)); ++ // CraftBukkit start ++ if (!level.addFreshEntity(entityendersignal)) { ++ return new InteractionResultHolder(InteractionResult.FAIL, itemstack); ++ } ++ // CraftBukkit end + if (player instanceof ServerPlayer) { +- CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer)player, blockPos); ++ CriteriaTriggers.USED_ENDER_EYE.trigger((ServerPlayer) player, blockposition); + } + +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.ENDER_EYE_LAUNCH, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); +- level.levelEvent(null, 1003, player.blockPosition(), 0); ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_EYE_LAUNCH, SoundSource.NEUTRAL, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ level.levelEvent((Player) null, 1003, player.blockPosition(), 0); + if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ itemstack.shrink(1); + } + + player.awardStat(Stats.ITEM_USED.get(this)); + player.swing(hand, true); +- return InteractionResultHolder.success(itemInHand); ++ return InteractionResultHolder.success(itemstack); + } + } + +- return InteractionResultHolder.consume(itemInHand); ++ return InteractionResultHolder.consume(itemstack); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/EnderpearlItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/EnderpearlItem.java.patch new file mode 100644 index 0000000000..09162a980d --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/EnderpearlItem.java.patch @@ -0,0 +1,68 @@ +--- a/net/minecraft/world/item/EnderpearlItem.java ++++ b/net/minecraft/world/item/EnderpearlItem.java +@@ -3,43 +3,45 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.projectile.ThrownEnderpearl; + import net.minecraft.world.level.Level; + + public class EnderpearlItem extends Item { ++ + public EnderpearlItem(Item.Properties properties) { + super(properties); + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.ENDER_PEARL_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); +- player.getCooldowns().addCooldown(this, 20); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ ++ // CraftBukkit start - change order + if (!level.isClientSide) { +- ThrownEnderpearl thrownEnderpearl = new ThrownEnderpearl(level, player); +- thrownEnderpearl.setItem(itemInHand); +- thrownEnderpearl.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); +- level.addFreshEntity(thrownEnderpearl); ++ ThrownEnderpearl entityenderpearl = new ThrownEnderpearl(level, player); ++ ++ entityenderpearl.setItem(itemstack); ++ entityenderpearl.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); ++ if (!level.addFreshEntity(entityenderpearl)) { ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResultHolder.fail(itemstack); ++ } + } + ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ player.getCooldowns().addCooldown(this, 20); ++ // CraftBukkit end ++ + player.awardStat(Stats.ITEM_USED.get(this)); + if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ itemstack.shrink(1); + } + +- return InteractionResultHolder.sidedSuccess(itemInHand, level.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/FireChargeItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/FireChargeItem.java.patch new file mode 100644 index 0000000000..25fe364878 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/FireChargeItem.java.patch @@ -0,0 +1,92 @@ +--- a/net/minecraft/world/item/FireChargeItem.java ++++ b/net/minecraft/world/item/FireChargeItem.java +@@ -5,52 +5,73 @@ + import net.minecraft.sounds.SoundSource; + import net.minecraft.util.RandomSource; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.BaseFireBlock; + import net.minecraft.world.level.block.CampfireBlock; + import net.minecraft.world.level.block.CandleBlock; + import net.minecraft.world.level.block.CandleCakeBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.properties.BlockStateProperties; + import net.minecraft.world.level.gameevent.GameEvent; + + public class FireChargeItem extends Item { ++ + public FireChargeItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); + boolean flag = false; +- if (!CampfireBlock.canLight(blockState) && !CandleBlock.canLight(blockState) && !CandleCakeBlock.canLight(blockState)) { +- BlockPos var6 = clickedPos.relative(context.getClickedFace()); +- if (BaseFireBlock.canBePlacedAt(level, var6, context.getHorizontalDirection())) { +- this.playSound(level, var6); +- level.setBlockAndUpdate(var6, BaseFireBlock.getState(level, var6)); +- level.gameEvent(context.getPlayer(), GameEvent.BLOCK_PLACE, var6); ++ ++ if (!CampfireBlock.canLight(iblockdata) && !CandleBlock.canLight(iblockdata) && !CandleCakeBlock.canLight(iblockdata)) { ++ blockposition = blockposition.relative(context.getClickedFace()); ++ if (BaseFireBlock.canBePlacedAt(world, blockposition, context.getHorizontalDirection())) { ++ // CraftBukkit start - fire BlockIgniteEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { ++ if (!context.getPlayer().getAbilities().instabuild) { ++ context.getItemInHand().shrink(1); ++ } ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end ++ this.playSound(world, blockposition); ++ world.setBlockAndUpdate(blockposition, BaseFireBlock.getState(world, blockposition)); ++ world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_PLACE, blockposition); + flag = true; + } + } else { +- this.playSound(level, clickedPos); +- level.setBlockAndUpdate(clickedPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true))); +- level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos); ++ // CraftBukkit start - fire BlockIgniteEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { ++ if (!context.getPlayer().getAbilities().instabuild) { ++ context.getItemInHand().shrink(1); ++ } ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end ++ this.playSound(world, blockposition); ++ world.setBlockAndUpdate(blockposition, (IBlockData) iblockdata.setValue(BlockStateProperties.LIT, true)); ++ world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_CHANGE, blockposition); + flag = true; + } + + if (flag) { + context.getItemInHand().shrink(1); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.FAIL; + } + } + + private void playSound(Level level, BlockPos pos) { +- RandomSource random = level.getRandom(); +- level.playSound(null, pos, SoundEvents.FIRECHARGE_USE, SoundSource.BLOCKS, 1.0F, (random.nextFloat() - random.nextFloat()) * 0.2F + 1.0F); ++ RandomSource randomsource = level.getRandom(); ++ ++ level.playSound((Player) null, pos, SoundEvents.FIRECHARGE_USE, SoundSource.BLOCKS, 1.0F, (randomsource.nextFloat() - randomsource.nextFloat()) * 0.2F + 1.0F); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/FishingRodItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/FishingRodItem.java.patch new file mode 100644 index 0000000000..b426cb8fe7 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/FishingRodItem.java.patch @@ -0,0 +1,98 @@ +--- a/net/minecraft/world/item/FishingRodItem.java ++++ b/net/minecraft/world/item/FishingRodItem.java +@@ -3,7 +3,7 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.projectile.FishingHook; +@@ -11,53 +11,57 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.gameevent.GameEvent; + +-public class FishingRodItem extends Item implements Vanishable { ++// CraftBukkit start ++import org.bukkit.event.player.PlayerFishEvent; ++import org.bukkit.craftbukkit.CraftEquipmentSlot; ++// CraftBukkit end ++ ++public class FishingRodItem extends Item implements ItemVanishable { ++ + public FishingRodItem(Item.Properties properties) { + super(properties); + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ int i; ++ + if (player.fishing != null) { + if (!level.isClientSide) { +- int i = player.fishing.retrieve(itemInHand); +- itemInHand.hurtAndBreak(i, player, contextEntity -> contextEntity.broadcastBreakEvent(hand)); ++ i = player.fishing.retrieve(itemstack); ++ itemstack.hurtAndBreak(i, player, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(hand); ++ }); + } + +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.FISHING_BOBBER_RETRIEVE, +- SoundSource.NEUTRAL, +- 1.0F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.FISHING_BOBBER_RETRIEVE, SoundSource.NEUTRAL, 1.0F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); + player.gameEvent(GameEvent.ITEM_INTERACT_FINISH); + } else { +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.FISHING_BOBBER_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); + if (!level.isClientSide) { +- int i = EnchantmentHelper.getFishingSpeedBonus(itemInHand); +- int fishingLuckBonus = EnchantmentHelper.getFishingLuckBonus(itemInHand); +- level.addFreshEntity(new FishingHook(player, level, fishingLuckBonus, i)); ++ i = EnchantmentHelper.getFishingSpeedBonus(itemstack); ++ int j = EnchantmentHelper.getFishingLuckBonus(itemstack); ++ ++ // CraftBukkit start ++ FishingHook entityfishinghook = new FishingHook(player, level, j, i); ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) player.getBukkitEntity(), null, (org.bukkit.entity.FishHook) entityfishinghook.getBukkitEntity(), CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.FISHING); ++ level.getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ player.fishing = null; ++ return InteractionResultHolder.pass(itemstack); ++ } ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.FISHING_BOBBER_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ level.addFreshEntity(entityfishinghook); ++ // CraftBukkit end + } + + player.awardStat(Stats.ITEM_USED.get(this)); + player.gameEvent(GameEvent.ITEM_INTERACT_START); + } + +- return InteractionResultHolder.sidedSuccess(itemInHand, level.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + + @Override diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/FlintAndSteelItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/FlintAndSteelItem.java.patch new file mode 100644 index 0000000000..37ab07b16e --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/FlintAndSteelItem.java.patch @@ -0,0 +1,106 @@ +--- a/net/minecraft/world/item/FlintAndSteelItem.java ++++ b/net/minecraft/world/item/FlintAndSteelItem.java +@@ -6,6 +6,7 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; +@@ -13,47 +14,72 @@ + import net.minecraft.world.level.block.CampfireBlock; + import net.minecraft.world.level.block.CandleBlock; + import net.minecraft.world.level.block.CandleCakeBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.properties.BlockStateProperties; + import net.minecraft.world.level.gameevent.GameEvent; + + public class FlintAndSteelItem extends Item { ++ + public FlintAndSteelItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Player player = context.getPlayer(); +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (!CampfireBlock.canLight(blockState) && !CandleBlock.canLight(blockState) && !CandleCakeBlock.canLight(blockState)) { +- BlockPos blockPos = clickedPos.relative(context.getClickedFace()); +- if (BaseFireBlock.canBePlacedAt(level, blockPos, context.getHorizontalDirection())) { +- level.playSound(player, blockPos, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, level.getRandom().nextFloat() * 0.4F + 0.8F); +- BlockState state = BaseFireBlock.getState(level, blockPos); +- level.setBlock(blockPos, state, 11); +- level.gameEvent(player, GameEvent.BLOCK_PLACE, clickedPos); +- ItemStack itemInHand = context.getItemInHand(); +- if (player instanceof ServerPlayer) { +- CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, blockPos, itemInHand); +- itemInHand.hurtAndBreak(1, player, contextPlayer -> contextPlayer.broadcastBreakEvent(context.getHand())); ++ Player entityhuman = context.getPlayer(); ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ ++ if (!CampfireBlock.canLight(iblockdata) && !CandleBlock.canLight(iblockdata) && !CandleCakeBlock.canLight(iblockdata)) { ++ BlockPos blockposition1 = blockposition.relative(context.getClickedFace()); ++ ++ if (BaseFireBlock.canBePlacedAt(world, blockposition1, context.getHorizontalDirection())) { ++ // CraftBukkit start - Store the clicked block ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition1, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { ++ context.getItemInHand().hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(context.getHand()); ++ }); ++ return InteractionResult.PASS; + } ++ // CraftBukkit end ++ world.playSound(entityhuman, blockposition1, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.4F + 0.8F); ++ IBlockData iblockdata1 = BaseFireBlock.getState(world, blockposition1); + +- return InteractionResult.sidedSuccess(level.isClientSide()); ++ world.setBlock(blockposition1, iblockdata1, 11); ++ world.gameEvent((Entity) entityhuman, GameEvent.BLOCK_PLACE, blockposition); ++ ItemStack itemstack = context.getItemInHand(); ++ ++ if (entityhuman instanceof ServerPlayer) { ++ CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) entityhuman, blockposition1, itemstack); ++ itemstack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(context.getHand()); ++ }); ++ } ++ ++ return InteractionResult.sidedSuccess(world.isClientSide()); + } else { + return InteractionResult.FAIL; + } + } else { +- level.playSound(player, clickedPos, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, level.getRandom().nextFloat() * 0.4F + 0.8F); +- level.setBlock(clickedPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)), 11); +- level.gameEvent(player, GameEvent.BLOCK_CHANGE, clickedPos); +- if (player != null) { +- context.getItemInHand().hurtAndBreak(1, player, contextPlayer -> contextPlayer.broadcastBreakEvent(context.getHand())); ++ // CraftBukkit start - Store the clicked block ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { ++ context.getItemInHand().hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(context.getHand()); ++ }); ++ return InteractionResult.PASS; + } ++ // CraftBukkit end ++ world.playSound(entityhuman, blockposition, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.4F + 0.8F); ++ world.setBlock(blockposition, (IBlockData) iblockdata.setValue(BlockStateProperties.LIT, true), 11); ++ world.gameEvent((Entity) entityhuman, GameEvent.BLOCK_CHANGE, blockposition); ++ if (entityhuman != null) { ++ context.getItemInHand().hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(context.getHand()); ++ }); ++ } + +- return InteractionResult.sidedSuccess(level.isClientSide()); ++ return InteractionResult.sidedSuccess(world.isClientSide()); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/HangingEntityItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/HangingEntityItem.java.patch new file mode 100644 index 0000000000..f19767ab05 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/HangingEntityItem.java.patch @@ -0,0 +1,183 @@ +--- a/net/minecraft/world/item/HangingEntityItem.java ++++ b/net/minecraft/world/item/HangingEntityItem.java +@@ -6,23 +6,28 @@ + import net.minecraft.ChatFormatting; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; +-import net.minecraft.core.Holder; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.network.chat.Component; +-import net.minecraft.resources.ResourceKey; + import net.minecraft.util.Mth; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; + import net.minecraft.world.entity.decoration.GlowItemFrame; + import net.minecraft.world.entity.decoration.HangingEntity; + import net.minecraft.world.entity.decoration.ItemFrame; + import net.minecraft.world.entity.decoration.Painting; +-import net.minecraft.world.entity.player.Player; ++import net.minecraft.world.entity.decoration.PaintingVariant; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.gameevent.GameEvent; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.hanging.HangingPlaceEvent; ++// CraftBukkit end ++ + public class HangingEntityItem extends Item { ++ + private static final Component TOOLTIP_RANDOM_VARIANT = Component.translatable("painting.random").withStyle(ChatFormatting.GRAY); + private final EntityType<? extends HangingEntity> type; + +@@ -33,54 +38,71 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- BlockPos clickedPos = context.getClickedPos(); +- Direction clickedFace = context.getClickedFace(); +- BlockPos blockPos = clickedPos.relative(clickedFace); +- Player player = context.getPlayer(); +- ItemStack itemInHand = context.getItemInHand(); +- if (player != null && !this.mayPlace(player, clickedFace, itemInHand, blockPos)) { ++ BlockPos blockposition = context.getClickedPos(); ++ Direction enumdirection = context.getClickedFace(); ++ BlockPos blockposition1 = blockposition.relative(enumdirection); ++ net.minecraft.world.entity.player.Player entityhuman = context.getPlayer(); ++ ItemStack itemstack = context.getItemInHand(); ++ ++ if (entityhuman != null && !this.mayPlace(entityhuman, enumdirection, itemstack, blockposition1)) { + return InteractionResult.FAIL; + } else { +- Level level = context.getLevel(); +- HangingEntity hangingEntity; ++ Level world = context.getLevel(); ++ Object object; ++ + if (this.type == EntityType.PAINTING) { +- Optional<Painting> optional = Painting.create(level, blockPos, clickedFace); ++ Optional<Painting> optional = Painting.create(world, blockposition1, enumdirection); ++ + if (optional.isEmpty()) { + return InteractionResult.CONSUME; + } + +- hangingEntity = optional.get(); ++ object = (HangingEntity) optional.get(); + } else if (this.type == EntityType.ITEM_FRAME) { +- hangingEntity = new ItemFrame(level, blockPos, clickedFace); ++ object = new ItemFrame(world, blockposition1, enumdirection); + } else { + if (this.type != EntityType.GLOW_ITEM_FRAME) { +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } + +- hangingEntity = new GlowItemFrame(level, blockPos, clickedFace); ++ object = new GlowItemFrame(world, blockposition1, enumdirection); + } + +- CompoundTag tag = itemInHand.getTag(); +- if (tag != null) { +- EntityType.updateCustomEntityTag(level, player, hangingEntity, tag); ++ CompoundTag nbttagcompound = itemstack.getTag(); ++ ++ if (nbttagcompound != null) { ++ EntityType.updateCustomEntityTag(world, entityhuman, (Entity) object, nbttagcompound); + } + +- if (hangingEntity.survives()) { +- if (!level.isClientSide) { +- hangingEntity.playPlacementSound(); +- level.gameEvent(player, GameEvent.ENTITY_PLACE, hangingEntity.position()); +- level.addFreshEntity(hangingEntity); ++ if (((HangingEntity) object).survives()) { ++ if (!world.isClientSide) { ++ // CraftBukkit start - fire HangingPlaceEvent ++ Player who = (context.getPlayer() == null) ? null : (Player) context.getPlayer().getBukkitEntity(); ++ org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection); ++ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand()); ++ ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) ((HangingEntity) object).getBukkitEntity(), who, blockClicked, blockFace, hand, org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); ++ world.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end ++ ((HangingEntity) object).playPlacementSound(); ++ world.gameEvent((Entity) entityhuman, GameEvent.ENTITY_PLACE, ((HangingEntity) object).position()); ++ world.addFreshEntity((Entity) object); + } + +- itemInHand.shrink(1); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ itemstack.shrink(1); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.CONSUME; + } + } + } + +- protected boolean mayPlace(Player player, Direction direction, ItemStack hangingEntityStack, BlockPos pos) { ++ protected boolean mayPlace(net.minecraft.world.entity.player.Player player, Direction direction, ItemStack hangingEntityStack, BlockPos pos) { + return !direction.getAxis().isVertical() && player.mayUseItemAt(pos, direction, hangingEntityStack); + } + +@@ -88,36 +110,24 @@ + public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltipComponents, TooltipFlag isAdvanced) { + super.appendHoverText(stack, level, tooltipComponents, isAdvanced); + if (this.type == EntityType.PAINTING) { +- CompoundTag tag = stack.getTag(); +- if (tag != null && tag.contains("EntityTag", 10)) { +- CompoundTag compound = tag.getCompound("EntityTag"); +- Painting.loadVariant(compound) +- .ifPresentOrElse( +- holder -> { +- holder.unwrapKey() +- .ifPresent( +- resourceKey -> { +- tooltipComponents.add( +- Component.translatable(resourceKey.location().toLanguageKey("painting", "title")).withStyle(ChatFormatting.YELLOW) +- ); +- tooltipComponents.add( +- Component.translatable(resourceKey.location().toLanguageKey("painting", "author")).withStyle(ChatFormatting.GRAY) +- ); +- } +- ); +- tooltipComponents.add( +- Component.translatable( +- "painting.dimensions", +- Mth.positiveCeilDiv(holder.value().getWidth(), 16), +- Mth.positiveCeilDiv(holder.value().getHeight(), 16) +- ) +- ); +- }, +- () -> tooltipComponents.add(TOOLTIP_RANDOM_VARIANT) +- ); ++ CompoundTag nbttagcompound = stack.getTag(); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("EntityTag", 10)) { ++ CompoundTag nbttagcompound1 = nbttagcompound.getCompound("EntityTag"); ++ ++ Painting.loadVariant(nbttagcompound1).ifPresentOrElse((holder) -> { ++ holder.unwrapKey().ifPresent((resourcekey) -> { ++ tooltipComponents.add(Component.translatable(resourcekey.location().toLanguageKey("painting", "title")).withStyle(ChatFormatting.YELLOW)); ++ tooltipComponents.add(Component.translatable(resourcekey.location().toLanguageKey("painting", "author")).withStyle(ChatFormatting.GRAY)); ++ }); ++ tooltipComponents.add(Component.translatable("painting.dimensions", Mth.positiveCeilDiv(((PaintingVariant) holder.value()).getWidth(), 16), Mth.positiveCeilDiv(((PaintingVariant) holder.value()).getHeight(), 16))); ++ }, () -> { ++ tooltipComponents.add(HangingEntityItem.TOOLTIP_RANDOM_VARIANT); ++ }); + } else if (isAdvanced.isCreative()) { +- tooltipComponents.add(TOOLTIP_RANDOM_VARIANT); ++ tooltipComponents.add(HangingEntityItem.TOOLTIP_RANDOM_VARIANT); + } + } ++ + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch new file mode 100644 index 0000000000..8f2b7a5500 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/ItemStack.java.patch @@ -0,0 +1,1384 @@ +--- a/net/minecraft/world/item/ItemStack.java ++++ b/net/minecraft/world/item/ItemStack.java +@@ -9,15 +9,15 @@ + import com.mojang.serialization.DataResult; + import com.mojang.serialization.MapCodec; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; + import java.text.DecimalFormat; + import java.text.DecimalFormatSymbols; + import java.util.Collection; ++import java.util.Iterator; + import java.util.List; + import java.util.Locale; ++import java.util.Map.Entry; + import java.util.Objects; + import java.util.Optional; +-import java.util.Map.Entry; + import java.util.function.Consumer; + import java.util.function.Predicate; + import java.util.stream.Collectors; +@@ -28,6 +28,7 @@ + import net.minecraft.advancements.CriteriaTriggers; + import net.minecraft.commands.arguments.blocks.BlockStateParser; + import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; + import net.minecraft.core.Holder; + import net.minecraft.core.HolderSet; + import net.minecraft.core.Registry; +@@ -35,6 +36,7 @@ + import net.minecraft.core.registries.Registries; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.NbtOps; + import net.minecraft.nbt.Tag; + import net.minecraft.nbt.TagParser; + import net.minecraft.network.chat.CommonComponents; +@@ -43,27 +45,24 @@ + import net.minecraft.network.chat.HoverEvent; + import net.minecraft.network.chat.MutableComponent; + import net.minecraft.network.chat.Style; ++import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; + import net.minecraft.resources.ResourceLocation; +-import net.minecraft.server.level.ServerPlayer; +-import net.minecraft.sounds.SoundEvent; +-import net.minecraft.stats.Stats; + import net.minecraft.tags.TagKey; + import net.minecraft.util.ExtraCodecs; + import net.minecraft.util.RandomSource; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EnumMonsterType; + import net.minecraft.world.entity.EquipmentSlot; + import net.minecraft.world.entity.LivingEntity; +-import net.minecraft.world.entity.MobType; + import net.minecraft.world.entity.SlotAccess; + import net.minecraft.world.entity.ai.attributes.Attribute; + import net.minecraft.world.entity.ai.attributes.AttributeModifier; + import net.minecraft.world.entity.ai.attributes.Attributes; + import net.minecraft.world.entity.decoration.ItemFrame; + import net.minecraft.world.entity.item.ItemEntity; +-import net.minecraft.world.entity.player.Player; + import net.minecraft.world.flag.FeatureFlagSet; + import net.minecraft.world.inventory.ClickAction; + import net.minecraft.world.inventory.Slot; +@@ -74,52 +73,81 @@ + import net.minecraft.world.item.enchantment.Enchantment; + import net.minecraft.world.item.enchantment.EnchantmentHelper; + import net.minecraft.world.item.enchantment.Enchantments; +-import net.minecraft.world.level.ItemLike; ++import net.minecraft.world.level.IMaterial; + import net.minecraft.world.level.Level; ++import net.minecraft.world.level.block.BaseEntityBlock; ++import net.minecraft.world.level.block.BedBlock; + import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.pattern.BlockInWorld; + import org.slf4j.Logger; + ++// CraftBukkit start ++import com.mojang.serialization.Dynamic; ++import java.util.Map; ++import java.util.Objects; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerLevel; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.sounds.SoundEvent; ++import net.minecraft.sounds.SoundSource; ++import net.minecraft.stats.Stats; ++import net.minecraft.util.datafix.fixes.DataConverterTypes; ++import net.minecraft.world.level.block.Blocks; ++import net.minecraft.world.level.block.SaplingBlock; ++import net.minecraft.world.level.block.SignBlock; ++import net.minecraft.world.level.block.SoundType; ++import net.minecraft.world.level.block.WitherSkullBlock; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.entity.JukeboxBlockEntity; ++import net.minecraft.world.level.block.entity.SignBlockEntity; ++import net.minecraft.world.level.block.entity.SkullBlockEntity; ++import net.minecraft.world.level.gameevent.GameEvent; ++import org.bukkit.Location; ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.craftbukkit.block.CraftBlockState; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.CraftLocation; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.entity.Player; ++import org.bukkit.event.block.BlockFertilizeEvent; ++import org.bukkit.event.player.PlayerItemDamageEvent; ++import org.bukkit.event.world.StructureGrowEvent; ++// CraftBukkit end ++ + public final class ItemStack { +- public static final Codec<ItemStack> CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("id").forGetter(ItemStack::getItemHolder), +- Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount), +- CompoundTag.CODEC.optionalFieldOf("tag").forGetter(itemStack -> Optional.ofNullable(itemStack.getTag())) +- ) +- .apply(instance, ItemStack::new) +- ); +- private static final Codec<Item> ITEM_NON_AIR_CODEC = ExtraCodecs.validate( +- BuiltInRegistries.ITEM.byNameCodec(), item -> item == Items.AIR ? DataResult.error(() -> "Item must not be minecraft:air") : DataResult.success(item) +- ); +- public static final Codec<ItemStack> ADVANCEMENT_ICON_CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("item").forGetter(ItemStack::getItemHolder), +- ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter(itemStack -> Optional.ofNullable(itemStack.getTag())) +- ) +- .apply(instance, (holder, optional) -> new ItemStack(holder, 1, optional)) +- ); +- public static final Codec<ItemStack> ITEM_WITH_COUNT_CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- ITEM_NON_AIR_CODEC.fieldOf("item").forGetter(ItemStack::getItem), +- ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount) +- ) +- .apply(instance, ItemStack::new) +- ); +- public static final Codec<ItemStack> SINGLE_ITEM_CODEC = ITEM_NON_AIR_CODEC.xmap(ItemStack::new, ItemStack::getItem); +- public static final MapCodec<ItemStack> RESULT_CODEC = RecordCodecBuilder.mapCodec( +- instance -> instance.group( +- BuiltInRegistries.ITEM.byNameCodec().fieldOf("result").forGetter(ItemStack::getItem), +- Codec.INT.fieldOf("count").forGetter(ItemStack::getCount) +- ) +- .apply(instance, ItemStack::new) +- ); ++ ++ public static final Codec<ItemStack> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("id").forGetter(ItemStack::getItemHolder), Codec.INT.fieldOf("Count").forGetter(ItemStack::getCount), CompoundTag.CODEC.optionalFieldOf("tag").forGetter((itemstack) -> { ++ return Optional.ofNullable(itemstack.getTag()); ++ })).apply(instance, ItemStack::new); ++ }); ++ private static final Codec<Item> ITEM_NON_AIR_CODEC = ExtraCodecs.validate(BuiltInRegistries.ITEM.byNameCodec(), (item) -> { ++ return item == Items.AIR ? DataResult.error(() -> { ++ return "Item must not be minecraft:air"; ++ }) : DataResult.success(item); ++ }); ++ public static final Codec<ItemStack> ADVANCEMENT_ICON_CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(BuiltInRegistries.ITEM.holderByNameCodec().fieldOf("item").forGetter(ItemStack::getItemHolder), ExtraCodecs.strictOptionalField(TagParser.AS_CODEC, "nbt").forGetter((itemstack) -> { ++ return Optional.ofNullable(itemstack.getTag()); ++ })).apply(instance, (holder, optional) -> { ++ return new ItemStack(holder, 1, optional); ++ }); ++ }); ++ public static final Codec<ItemStack> ITEM_WITH_COUNT_CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(ItemStack.ITEM_NON_AIR_CODEC.fieldOf("item").forGetter(ItemStack::getItem), ExtraCodecs.strictOptionalField(ExtraCodecs.POSITIVE_INT, "count", 1).forGetter(ItemStack::getCount)).apply(instance, ItemStack::new); ++ }); ++ public static final Codec<ItemStack> SINGLE_ITEM_CODEC = ItemStack.ITEM_NON_AIR_CODEC.xmap(ItemStack::new, ItemStack::getItem); ++ public static final MapCodec<ItemStack> RESULT_CODEC = RecordCodecBuilder.mapCodec((instance) -> { ++ return instance.group(BuiltInRegistries.ITEM.byNameCodec().fieldOf("result").forGetter(ItemStack::getItem), Codec.INT.fieldOf("count").forGetter(ItemStack::getCount)).apply(instance, ItemStack::new); ++ }); + private static final Logger LOGGER = LogUtils.getLogger(); +- public static final ItemStack EMPTY = new ItemStack((Void)null); +- public static final DecimalFormat ATTRIBUTE_MODIFIER_FORMAT = Util.make( +- new DecimalFormat("#.##"), decimalFormat -> decimalFormat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)) +- ); ++ public static final ItemStack EMPTY = new ItemStack((Void) null); ++ public static final DecimalFormat ATTRIBUTE_MODIFIER_FORMAT = (DecimalFormat) Util.make(new DecimalFormat("#.##"), (decimalformat) -> { ++ decimalformat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)); ++ }); + public static final String TAG_ENCH = "Enchantments"; + public static final String TAG_DISPLAY = "display"; + public static final String TAG_DISPLAY_NAME = "Name"; +@@ -136,9 +164,10 @@ + private static final Style LORE_STYLE = Style.EMPTY.withColor(ChatFormatting.DARK_PURPLE).withItalic(true); + private int count; + private int popTime; ++ /** @deprecated */ + @Deprecated + @Nullable +- private final Item item; ++ private Item item; + @Nullable + private CompoundTag tag; + @Nullable +@@ -152,12 +181,12 @@ + return this.getItem().getTooltipImage(this); + } + +- public ItemStack(ItemLike item) { ++ public ItemStack(IMaterial item) { + this(item, 1); + } + + public ItemStack(Holder<Item> tag) { +- this(tag.value(), 1); ++ this((IMaterial) tag.value(), 1); + } + + public ItemStack(Holder<Item> item, int count, Optional<CompoundTag> optional) { +@@ -166,45 +195,63 @@ + } + + public ItemStack(Holder<Item> item, int count) { +- this(item.value(), count); ++ this((IMaterial) item.value(), count); + } + +- public ItemStack(ItemLike item, int count) { ++ public ItemStack(IMaterial item, int count) { + this.item = item.asItem(); + this.count = count; + if (this.item.canBeDepleted()) { + this.setDamageValue(this.getDamageValue()); + } ++ + } + +- private ItemStack(@Nullable Void _void) { ++ private ItemStack(@Nullable Void ovoid) { + this.item = null; + } + +- private ItemStack(CompoundTag compoundTag) { +- this.item = BuiltInRegistries.ITEM.get(new ResourceLocation(compoundTag.getString("id"))); +- this.count = compoundTag.getByte("Count"); +- if (compoundTag.contains("tag", 10)) { +- this.tag = compoundTag.getCompound("tag").copy(); ++ // Called to run this stack through the data converter to handle older storage methods and serialized items ++ public void convertStack(int version) { ++ if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion()) { ++ CompoundTag savedStack = new CompoundTag(); ++ this.save(savedStack); ++ savedStack = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(DataConverterTypes.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue(); ++ this.load(savedStack); ++ } ++ } ++ ++ // CraftBukkit - break into own method ++ private void load(CompoundTag nbttagcompound) { ++ this.item = (Item) BuiltInRegistries.ITEM.get(new ResourceLocation(nbttagcompound.getString("id"))); ++ this.count = nbttagcompound.getByte("Count"); ++ if (nbttagcompound.contains("tag", 10)) { ++ this.tag = nbttagcompound.getCompound("tag").copy(); + this.getItem().verifyTagAfterLoad(this.tag); + } + + if (this.getItem().canBeDepleted()) { + this.setDamageValue(this.getDamageValue()); + } ++ + } + ++ private ItemStack(CompoundTag compoundTag) { ++ this.load(compoundTag); ++ // CraftBukkit end ++ } ++ + public static ItemStack of(CompoundTag compoundTag) { + try { + return new ItemStack(compoundTag); +- } catch (RuntimeException var2) { +- LOGGER.debug("Tried to load invalid item: {}", compoundTag, var2); +- return EMPTY; ++ } catch (RuntimeException runtimeexception) { ++ ItemStack.LOGGER.debug("Tried to load invalid item: {}", compoundTag, runtimeexception); ++ return ItemStack.EMPTY; + } + } + + public boolean isEmpty() { +- return this == EMPTY || this.item == Items.AIR || this.count <= 0; ++ return this == ItemStack.EMPTY || this.item == Items.AIR || this.count <= 0; + } + + public boolean isItemEnabled(FeatureFlagSet enabledFlags) { +@@ -212,19 +259,21 @@ + } + + public ItemStack split(int amount) { +- int min = Math.min(amount, this.getCount()); +- ItemStack itemStack = this.copyWithCount(min); +- this.shrink(min); +- return itemStack; ++ int j = Math.min(amount, this.getCount()); ++ ItemStack itemstack = this.copyWithCount(j); ++ ++ this.shrink(j); ++ return itemstack; + } + + public ItemStack copyAndClear() { + if (this.isEmpty()) { +- return EMPTY; ++ return ItemStack.EMPTY; + } else { +- ItemStack itemStack = this.copy(); ++ ItemStack itemstack = this.copy(); ++ + this.setCount(0); +- return itemStack; ++ return itemstack; + } + } + +@@ -252,8 +301,8 @@ + return this.getItem().builtInRegistryHolder() == item; + } + +- public boolean is(HolderSet<Item> holderSet) { +- return holderSet.contains(this.getItemHolder()); ++ public boolean is(HolderSet<Item> holderset) { ++ return holderset.contains(this.getItemHolder()); + } + + public Stream<TagKey<Item>> getTags() { +@@ -261,29 +310,208 @@ + } + + public InteractionResult useOn(UseOnContext context) { +- Player player = context.getPlayer(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockInWorld blockInWorld = new BlockInWorld(context.getLevel(), clickedPos, false); +- if (player != null +- && !player.getAbilities().mayBuild +- && !this.hasAdventureModePlaceTagForBlock(context.getLevel().registryAccess().registryOrThrow(Registries.BLOCK), blockInWorld)) { ++ net.minecraft.world.entity.player.Player entityhuman = context.getPlayer(); ++ BlockPos blockposition = context.getClickedPos(); ++ BlockInWorld shapedetectorblock = new BlockInWorld(context.getLevel(), blockposition, false); ++ ++ if (entityhuman != null && !entityhuman.getAbilities().mayBuild && !this.hasAdventureModePlaceTagForBlock(context.getLevel().registryAccess().registryOrThrow(Registries.BLOCK), shapedetectorblock)) { + return InteractionResult.PASS; + } else { + Item item = this.getItem(); +- InteractionResult interactionResult = item.useOn(context); +- if (player != null && interactionResult.shouldAwardStats()) { +- player.awardStat(Stats.ITEM_USED.get(item)); ++ // CraftBukkit start - handle all block place event logic here ++ CompoundTag oldData = this.getTagClone(); ++ int oldCount = this.getCount(); ++ ServerLevel world = (ServerLevel) context.getLevel(); ++ ++ if (!(item instanceof BucketItem || item instanceof SolidBucketItem)) { // if not bucket ++ world.captureBlockStates = true; ++ // special case bonemeal ++ if (item == Items.BONE_MEAL) { ++ world.captureTreeGeneration = true; ++ } + } ++ InteractionResult enuminteractionresult; ++ try { ++ enuminteractionresult = item.useOn(context); ++ } finally { ++ world.captureBlockStates = false; ++ } ++ CompoundTag newData = this.getTagClone(); ++ int newCount = this.getCount(); ++ this.setCount(oldCount); ++ this.setTagClone(oldData); ++ if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { ++ world.captureTreeGeneration = false; ++ Location location = CraftLocation.toBukkit(blockposition, world.getWorld()); ++ TreeType treeType = SaplingBlock.treeType; ++ SaplingBlock.treeType = null; ++ List<CraftBlockState> blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); ++ world.capturedBlockStates.clear(); ++ StructureGrowEvent structureEvent = null; ++ if (treeType != null) { ++ boolean isBonemeal = getItem() == Items.BONE_MEAL; ++ structureEvent = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List<? extends BlockState>) blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); ++ } + +- return interactionResult; ++ BlockFertilizeEvent fertilizeEvent = new BlockFertilizeEvent(CraftBlock.at(world, blockposition), (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List<? extends BlockState>) blocks); ++ fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled()); ++ org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent); ++ ++ if (!fertilizeEvent.isCancelled()) { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) { ++ this.setTag(newData); ++ this.setCount(newCount); ++ } ++ for (CraftBlockState blockstate : blocks) { ++ world.setBlock(blockstate.getPosition(),blockstate.getHandle(), blockstate.getFlag()); // SPIGOT-7248 - manual update to avoid physics where appropriate ++ } ++ entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat ++ } ++ ++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return ++ return enuminteractionresult; ++ } ++ world.captureTreeGeneration = false; ++ ++ if (entityhuman != null && enuminteractionresult.shouldAwardStats()) { ++ EnumHand enumhand = context.getHand(); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = null; ++ List<BlockState> blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); ++ world.capturedBlockStates.clear(); ++ if (blocks.size() > 1) { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ } else if (blocks.size() == 1) { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ } ++ ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ enuminteractionresult = InteractionResult.FAIL; // cancel placement ++ // PAIL: Remove this when MC-99075 fixed ++ placeEvent.getPlayer().updateInventory(); ++ // revert back all captured blocks ++ world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 ++ for (BlockState blockstate : blocks) { ++ blockstate.update(true, false); ++ } ++ world.preventPoiUpdated = false; ++ ++ // Brute force all possible updates ++ BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); ++ for (Direction dir : Direction.values()) { ++ ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); ++ } ++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return ++ } else { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.getCount() == oldCount && Objects.equals(this.tag, oldData)) { ++ this.setTag(newData); ++ this.setCount(newCount); ++ } ++ ++ for (Map.Entry<BlockPos, BlockEntity> e : world.capturedTileEntities.entrySet()) { ++ world.setBlockEntity(e.getValue()); ++ } ++ ++ for (BlockState blockstate : blocks) { ++ int updateFlag = ((CraftBlockState) blockstate).getFlag(); ++ IBlockData oldBlock = ((CraftBlockState) blockstate).getHandle(); ++ BlockPos newblockposition = ((CraftBlockState) blockstate).getPosition(); ++ IBlockData block = world.getBlockState(newblockposition); ++ ++ if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically ++ block.getBlock().onPlace(block, world, newblockposition, oldBlock, true); ++ } ++ ++ world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point ++ } ++ ++ // Special case juke boxes as they update their tile entity. Copied from ItemRecord. ++ // PAIL: checkme on updates. ++ if (this.item instanceof RecordItem) { ++ BlockEntity tileentity = world.getBlockEntity(blockposition); ++ ++ if (tileentity instanceof JukeboxBlockEntity) { ++ JukeboxBlockEntity tileentityjukebox = (JukeboxBlockEntity) tileentity; ++ ++ // There can only be one ++ ItemStack record = this.copy(); ++ if (!record.isEmpty()) { ++ record.setCount(1); ++ } ++ ++ tileentityjukebox.setTheItem(record); ++ world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, world.getBlockState(blockposition))); ++ } ++ ++ this.shrink(1); ++ entityhuman.awardStat(Stats.PLAY_RECORD); ++ } ++ ++ if (this.item == Items.WITHER_SKELETON_SKULL) { // Special case skulls to allow wither spawns to be cancelled ++ BlockPos bp = blockposition; ++ if (!world.getBlockState(blockposition).canBeReplaced()) { ++ if (!world.getBlockState(blockposition).isSolid()) { ++ bp = null; ++ } else { ++ bp = bp.relative(context.getClickedFace()); ++ } ++ } ++ if (bp != null) { ++ BlockEntity te = world.getBlockEntity(bp); ++ if (te instanceof SkullBlockEntity) { ++ WitherSkullBlock.checkSpawn(world, bp, (SkullBlockEntity) te); ++ } ++ } ++ } ++ ++ // SPIGOT-4678 ++ if (this.item instanceof SignItem && SignItem.openSign != null) { ++ try { ++ if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) { ++ if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) { ++ blocksign.openTextEdit(entityhuman, tileentitysign, true, org.bukkit.event.player.PlayerSignOpenEvent.Cause.PLACE); // Craftbukkit ++ } ++ } ++ } finally { ++ SignItem.openSign = null; ++ } ++ } ++ ++ // SPIGOT-7315: Moved from BlockBed#setPlacedBy ++ if (placeEvent != null && this.item instanceof BedItem) { ++ BlockPos position = ((CraftBlock) placeEvent.getBlock()).getPosition(); ++ IBlockData blockData = world.getBlockState(position); ++ ++ if (blockData.getBlock() instanceof BedBlock) { ++ world.blockUpdated(position, Blocks.AIR); ++ blockData.updateNeighbourShapes(world, position, 3); ++ } ++ } ++ ++ // SPIGOT-1288 - play sound stripped from ItemBlock ++ if (this.item instanceof BlockItem) { ++ SoundType soundeffecttype = ((BlockItem) this.item).getBlock().defaultBlockState().getSoundType(); // TODO: not strictly correct, however currently only affects decorated pots ++ world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); ++ } ++ ++ entityhuman.awardStat(Stats.ITEM_USED.get(item)); ++ } ++ } ++ world.capturedTileEntities.clear(); ++ world.capturedBlockStates.clear(); ++ // CraftBukkit end ++ ++ return enuminteractionresult; + } + } + +- public float getDestroySpeed(BlockState state) { ++ public float getDestroySpeed(IBlockData state) { + return this.getItem().getDestroySpeed(this, state); + } + +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) { ++ public InteractionResultHolder<ItemStack> use(Level level, net.minecraft.world.entity.player.Player player, EnumHand usedHand) { + return this.getItem().use(level, player, usedHand); + } + +@@ -292,9 +520,10 @@ + } + + public CompoundTag save(CompoundTag compoundTag) { +- ResourceLocation key = BuiltInRegistries.ITEM.getKey(this.getItem()); +- compoundTag.putString("id", key == null ? "minecraft:air" : key.toString()); +- compoundTag.putByte("Count", (byte)this.count); ++ ResourceLocation minecraftkey = BuiltInRegistries.ITEM.getKey(this.getItem()); ++ ++ compoundTag.putString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString()); ++ compoundTag.putByte("Count", (byte) this.count); + if (this.tag != null) { + compoundTag.put("tag", this.tag.copy()); + } +@@ -312,8 +541,9 @@ + + public boolean isDamageableItem() { + if (!this.isEmpty() && this.getItem().getMaxDamage() > 0) { +- CompoundTag tag = this.getTag(); +- return tag == null || !tag.getBoolean("Unbreakable"); ++ CompoundTag nbttagcompound = this.getTag(); ++ ++ return nbttagcompound == null || !nbttagcompound.getBoolean("Unbreakable"); + } else { + return false; + } +@@ -339,17 +569,34 @@ + if (!this.isDamageableItem()) { + return false; + } else { ++ int j; ++ + if (amount > 0) { +- int itemEnchantmentLevel = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this); +- int i = 0; ++ j = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.UNBREAKING, this); ++ int k = 0; + +- for (int i1 = 0; itemEnchantmentLevel > 0 && i1 < amount; i1++) { +- if (DigDurabilityEnchantment.shouldIgnoreDurabilityDrop(this, itemEnchantmentLevel, random)) { +- i++; ++ for (int l = 0; j > 0 && l < amount; ++l) { ++ if (DigDurabilityEnchantment.shouldIgnoreDurabilityDrop(this, j, random)) { ++ ++k; + } + } + +- amount -= i; ++ amount -= k; ++ // CraftBukkit start ++ if (user != null) { ++ PlayerItemDamageEvent event = new PlayerItemDamageEvent(user.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); ++ event.getPlayer().getServer().getPluginManager().callEvent(event); ++ ++ if (amount != event.getDamage() || event.isCancelled()) { ++ event.getPlayer().updateInventory(); ++ } ++ if (event.isCancelled()) { ++ return false; ++ } ++ ++ amount = event.getDamage(); ++ } ++ // CraftBukkit end + if (amount <= 0) { + return false; + } +@@ -359,25 +606,32 @@ + CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(user, this, this.getDamageValue() + amount); + } + +- int itemEnchantmentLevel = this.getDamageValue() + amount; +- this.setDamageValue(itemEnchantmentLevel); +- return itemEnchantmentLevel >= this.getMaxDamage(); ++ j = this.getDamageValue() + amount; ++ this.setDamageValue(j); ++ return j >= this.getMaxDamage(); + } + } + + public <T extends LivingEntity> void hurtAndBreak(int amount, T entity, Consumer<T> onBroken) { +- if (!entity.level().isClientSide && (!(entity instanceof Player) || !((Player)entity).getAbilities().instabuild)) { ++ if (!entity.level().isClientSide && (!(entity instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) entity).getAbilities().instabuild)) { + if (this.isDamageableItem()) { +- if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer)entity : null)) { ++ if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer) entity : null)) { + onBroken.accept(entity); + Item item = this.getItem(); ++ // CraftBukkit start - Check for item breaking ++ if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this); ++ } ++ // CraftBukkit end ++ + this.shrink(1); +- if (entity instanceof Player) { +- ((Player)entity).awardStat(Stats.ITEM_BROKEN.get(item)); ++ if (entity instanceof net.minecraft.world.entity.player.Player) { ++ ((net.minecraft.world.entity.player.Player) entity).awardStat(Stats.ITEM_BROKEN.get(item)); + } + + this.setDamageValue(0); + } ++ + } + } + } +@@ -394,62 +648,68 @@ + return this.getItem().getBarColor(this); + } + +- public boolean overrideStackedOnOther(Slot slot, ClickAction action, Player player) { ++ public boolean overrideStackedOnOther(Slot slot, ClickAction action, net.minecraft.world.entity.player.Player player) { + return this.getItem().overrideStackedOnOther(this, slot, action, player); + } + +- public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction action, Player player, SlotAccess access) { ++ public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction action, net.minecraft.world.entity.player.Player player, SlotAccess access) { + return this.getItem().overrideOtherStackedOnMe(this, stack, slot, action, player, access); + } + +- public void hurtEnemy(LivingEntity entity, Player player) { ++ public void hurtEnemy(LivingEntity entity, net.minecraft.world.entity.player.Player player) { + Item item = this.getItem(); ++ + if (item.hurtEnemy(this, entity, player)) { + player.awardStat(Stats.ITEM_USED.get(item)); + } ++ + } + +- public void mineBlock(Level level, BlockState state, BlockPos pos, Player player) { ++ public void mineBlock(Level level, IBlockData state, BlockPos pos, net.minecraft.world.entity.player.Player player) { + Item item = this.getItem(); ++ + if (item.mineBlock(this, level, state, pos, player)) { + player.awardStat(Stats.ITEM_USED.get(item)); + } ++ + } + +- public boolean isCorrectToolForDrops(BlockState state) { ++ public boolean isCorrectToolForDrops(IBlockData state) { + return this.getItem().isCorrectToolForDrops(state); + } + +- public InteractionResult interactLivingEntity(Player player, LivingEntity entity, InteractionHand usedHand) { ++ public InteractionResult interactLivingEntity(net.minecraft.world.entity.player.Player player, LivingEntity entity, EnumHand usedHand) { + return this.getItem().interactLivingEntity(this, player, entity, usedHand); + } + + public ItemStack copy() { + if (this.isEmpty()) { +- return EMPTY; ++ return ItemStack.EMPTY; + } else { +- ItemStack itemStack = new ItemStack(this.getItem(), this.count); +- itemStack.setPopTime(this.getPopTime()); ++ ItemStack itemstack = new ItemStack(this.getItem(), this.count); ++ ++ itemstack.setPopTime(this.getPopTime()); + if (this.tag != null) { +- itemStack.tag = this.tag.copy(); ++ itemstack.tag = this.tag.copy(); + } + +- return itemStack; ++ return itemstack; + } + } + + public ItemStack copyWithCount(int count) { + if (this.isEmpty()) { +- return EMPTY; ++ return ItemStack.EMPTY; + } else { +- ItemStack itemStack = this.copy(); +- itemStack.setCount(count); +- return itemStack; ++ ItemStack itemstack = this.copy(); ++ ++ itemstack.setCount(count); ++ return itemstack; + } + } + + public static boolean matches(ItemStack stack, ItemStack other) { +- return stack == other || stack.getCount() == other.getCount() && isSameItemSameTags(stack, other); ++ return stack == other ? true : (stack.getCount() != other.getCount() ? false : isSameItemSameTags(stack, other)); + } + + public static boolean isSameItem(ItemStack stack, ItemStack other) { +@@ -457,42 +717,44 @@ + } + + public static boolean isSameItemSameTags(ItemStack stack, ItemStack other) { +- return stack.is(other.getItem()) && (stack.isEmpty() && other.isEmpty() || Objects.equals(stack.tag, other.tag)); ++ return !stack.is(other.getItem()) ? false : (stack.isEmpty() && other.isEmpty() ? true : Objects.equals(stack.tag, other.tag)); + } + + public String getDescriptionId() { + return this.getItem().getDescriptionId(this); + } + +- @Override + public String toString() { +- return this.getCount() + " " + this.getItem(); ++ int i = this.getCount(); ++ ++ return i + " " + this.getItem(); + } + + public void inventoryTick(Level level, Entity entity, int inventorySlot, boolean isCurrentItem) { + if (this.popTime > 0) { +- this.popTime--; ++ --this.popTime; + } + + if (this.getItem() != null) { + this.getItem().inventoryTick(this, level, entity, inventorySlot, isCurrentItem); + } ++ + } + +- public void onCraftedBy(Level level, Player player, int amount) { ++ public void onCraftedBy(Level level, net.minecraft.world.entity.player.Player player, int amount) { + player.awardStat(Stats.ITEM_CRAFTED.get(this.getItem()), amount); + this.getItem().onCraftedBy(this, level, player); + } + +- public void onCraftedBySystem(Level level) { +- this.getItem().onCraftedPostProcess(this, level); ++ public void onCraftedBySystem(Level world) { ++ this.getItem().onCraftedPostProcess(this, world); + } + + public int getUseDuration() { + return this.getItem().getUseDuration(this); + } + +- public UseAnim getUseAnimation() { ++ public EnumAnimation getUseAnimation() { + return this.getItem().getUseAnimation(this); + } + +@@ -513,6 +775,17 @@ + return this.tag; + } + ++ // CraftBukkit start ++ @Nullable ++ private CompoundTag getTagClone() { ++ return this.tag == null ? null : this.tag.copy(); ++ } ++ ++ private void setTagClone(@Nullable CompoundTag nbtttagcompound) { ++ this.setTag(nbtttagcompound == null ? null : nbtttagcompound.copy()); ++ } ++ // CraftBukkit end ++ + public CompoundTag getOrCreateTag() { + if (this.tag == null) { + this.setTag(new CompoundTag()); +@@ -525,9 +798,10 @@ + if (this.tag != null && this.tag.contains(key, 10)) { + return this.tag.getCompound(key); + } else { +- CompoundTag compoundTag = new CompoundTag(); +- this.addTagElement(key, compoundTag); +- return compoundTag; ++ CompoundTag nbttagcompound = new CompoundTag(); ++ ++ this.addTagElement(key, nbttagcompound); ++ return nbttagcompound; + } + } + +@@ -543,6 +817,7 @@ + this.tag = null; + } + } ++ + } + + public ListTag getEnchantmentTags() { +@@ -558,20 +833,23 @@ + if (compoundTag != null) { + this.getItem().verifyTagAfterLoad(compoundTag); + } ++ + } + + public Component getHoverName() { +- CompoundTag tagElement = this.getTagElement("display"); +- if (tagElement != null && tagElement.contains("Name", 8)) { ++ CompoundTag nbttagcompound = this.getTagElement("display"); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("Name", 8)) { + try { +- Component component = Component.Serializer.fromJson(tagElement.getString("Name")); +- if (component != null) { +- return component; ++ MutableComponent ichatmutablecomponent = Component.Serializer.fromJson(nbttagcompound.getString("Name")); ++ ++ if (ichatmutablecomponent != null) { ++ return ichatmutablecomponent; + } + +- tagElement.remove("Name"); +- } catch (Exception var3) { +- tagElement.remove("Name"); ++ nbttagcompound.remove("Name"); ++ } catch (Exception exception) { ++ nbttagcompound.remove("Name"); + } + } + +@@ -579,21 +857,23 @@ + } + + public ItemStack setHoverName(@Nullable Component nameComponent) { +- CompoundTag tagElement = this.getOrCreateTagElement("display"); ++ CompoundTag nbttagcompound = this.getOrCreateTagElement("display"); ++ + if (nameComponent != null) { +- tagElement.putString("Name", Component.Serializer.toJson(nameComponent)); ++ nbttagcompound.putString("Name", Component.Serializer.toJson(nameComponent)); + } else { +- tagElement.remove("Name"); ++ nbttagcompound.remove("Name"); + } + + return this; + } + + public void resetHoverName() { +- CompoundTag tagElement = this.getTagElement("display"); +- if (tagElement != null) { +- tagElement.remove("Name"); +- if (tagElement.isEmpty()) { ++ CompoundTag nbttagcompound = this.getTagElement("display"); ++ ++ if (nbttagcompound != null) { ++ nbttagcompound.remove("Name"); ++ if (nbttagcompound.isEmpty()) { + this.removeTagKey("display"); + } + } +@@ -601,136 +881,132 @@ + if (this.tag != null && this.tag.isEmpty()) { + this.tag = null; + } ++ + } + + public boolean hasCustomHoverName() { +- CompoundTag tagElement = this.getTagElement("display"); +- return tagElement != null && tagElement.contains("Name", 8); ++ CompoundTag nbttagcompound = this.getTagElement("display"); ++ ++ return nbttagcompound != null && nbttagcompound.contains("Name", 8); + } + +- public List<Component> getTooltipLines(@Nullable Player player, TooltipFlag isAdvanced) { ++ public List<Component> getTooltipLines(@Nullable net.minecraft.world.entity.player.Player player, TooltipFlag isAdvanced) { + List<Component> list = Lists.newArrayList(); +- MutableComponent mutableComponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color); ++ MutableComponent ichatmutablecomponent = Component.empty().append(this.getHoverName()).withStyle(this.getRarity().color); ++ + if (this.hasCustomHoverName()) { +- mutableComponent.withStyle(ChatFormatting.ITALIC); ++ ichatmutablecomponent.withStyle(ChatFormatting.ITALIC); + } + +- list.add(mutableComponent); ++ list.add(ichatmutablecomponent); + if (!isAdvanced.isAdvanced() && !this.hasCustomHoverName() && this.is(Items.FILLED_MAP)) { +- Integer mapId = MapItem.getMapId(this); +- if (mapId != null) { ++ Integer integer = MapItem.getMapId(this); ++ ++ if (integer != null) { + list.add(MapItem.getTooltipForId(this)); + } + } + +- int hideFlags = this.getHideFlags(); +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.ADDITIONAL)) { ++ int i = this.getHideFlags(); ++ ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.ADDITIONAL)) { + this.getItem().appendHoverText(this, player == null ? null : player.level(), list, isAdvanced); + } + ++ int j; ++ + if (this.hasTag()) { +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.UPGRADES) && player != null) { ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.UPGRADES) && player != null) { + ArmorTrim.appendUpgradeHoverText(this, player.level().registryAccess(), list); + } + +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.ENCHANTMENTS)) { ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.ENCHANTMENTS)) { + appendEnchantmentNames(list, this.getEnchantmentTags()); + } + + if (this.tag.contains("display", 10)) { +- CompoundTag compound = this.tag.getCompound("display"); +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.DYE) && compound.contains("color", 99)) { ++ CompoundTag nbttagcompound = this.tag.getCompound("display"); ++ ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.DYE) && nbttagcompound.contains("color", 99)) { + if (isAdvanced.isAdvanced()) { +- list.add( +- Component.translatable("item.color", String.format(Locale.ROOT, "#%06X", compound.getInt("color"))).withStyle(ChatFormatting.GRAY) +- ); ++ list.add(Component.translatable("item.color", String.format(Locale.ROOT, "#%06X", nbttagcompound.getInt("color"))).withStyle(ChatFormatting.GRAY)); + } else { + list.add(Component.translatable("item.dyed").withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC)); + } + } + +- if (compound.getTagType("Lore") == 9) { +- ListTag list1 = compound.getList("Lore", 8); ++ if (nbttagcompound.getTagType("Lore") == 9) { ++ ListTag nbttaglist = nbttagcompound.getList("Lore", 8); + +- for (int i = 0; i < list1.size(); i++) { +- String string = list1.getString(i); ++ for (j = 0; j < nbttaglist.size(); ++j) { ++ String s = nbttaglist.getString(j); + + try { +- MutableComponent mutableComponent1 = Component.Serializer.fromJson(string); +- if (mutableComponent1 != null) { +- list.add(ComponentUtils.mergeStyles(mutableComponent1, LORE_STYLE)); ++ MutableComponent ichatmutablecomponent1 = Component.Serializer.fromJson(s); ++ ++ if (ichatmutablecomponent1 != null) { ++ list.add(ComponentUtils.mergeStyles(ichatmutablecomponent1, ItemStack.LORE_STYLE)); + } +- } catch (Exception var19) { +- compound.remove("Lore"); ++ } catch (Exception exception) { ++ nbttagcompound.remove("Lore"); + } + } + } + } + } + +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.MODIFIERS)) { +- for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) { +- Multimap<Attribute, AttributeModifier> attributeModifiers = this.getAttributeModifiers(equipmentSlot); +- if (!attributeModifiers.isEmpty()) { ++ int k; ++ ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.MODIFIERS)) { ++ EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); ++ ++ k = aenumitemslot.length; ++ ++ for (j = 0; j < k; ++j) { ++ EquipmentSlot enumitemslot = aenumitemslot[j]; ++ Multimap<Attribute, AttributeModifier> multimap = this.getAttributeModifiers(enumitemslot); ++ ++ if (!multimap.isEmpty()) { + list.add(CommonComponents.EMPTY); +- list.add(Component.translatable("item.modifiers." + equipmentSlot.getName()).withStyle(ChatFormatting.GRAY)); ++ list.add(Component.translatable("item.modifiers." + enumitemslot.getName()).withStyle(ChatFormatting.GRAY)); ++ Iterator iterator = multimap.entries().iterator(); + +- for (Entry<Attribute, AttributeModifier> entry : attributeModifiers.entries()) { +- AttributeModifier attributeModifier = entry.getValue(); +- double amount = attributeModifier.getAmount(); ++ while (iterator.hasNext()) { ++ Entry<Attribute, AttributeModifier> entry = (Entry) iterator.next(); ++ AttributeModifier attributemodifier = (AttributeModifier) entry.getValue(); ++ double d0 = attributemodifier.getAmount(); + boolean flag = false; ++ + if (player != null) { +- if (attributeModifier.getId() == Item.BASE_ATTACK_DAMAGE_UUID) { +- amount += player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE); +- amount += (double)EnchantmentHelper.getDamageBonus(this, MobType.UNDEFINED); ++ if (attributemodifier.getId() == Item.BASE_ATTACK_DAMAGE_UUID) { ++ d0 += player.getAttributeBaseValue(Attributes.ATTACK_DAMAGE); ++ d0 += (double) EnchantmentHelper.getDamageBonus(this, EnumMonsterType.UNDEFINED); + flag = true; +- } else if (attributeModifier.getId() == Item.BASE_ATTACK_SPEED_UUID) { +- amount += player.getAttributeBaseValue(Attributes.ATTACK_SPEED); ++ } else if (attributemodifier.getId() == Item.BASE_ATTACK_SPEED_UUID) { ++ d0 += player.getAttributeBaseValue(Attributes.ATTACK_SPEED); + flag = true; + } + } + +- double d; +- if (attributeModifier.getOperation() == AttributeModifier.Operation.MULTIPLY_BASE +- || attributeModifier.getOperation() == AttributeModifier.Operation.MULTIPLY_TOTAL) { +- d = amount * 100.0; +- } else if (entry.getKey().equals(Attributes.KNOCKBACK_RESISTANCE)) { +- d = amount * 10.0; ++ double d1; ++ ++ if (attributemodifier.getOperation() != AttributeModifier.Operation.MULTIPLY_BASE && attributemodifier.getOperation() != AttributeModifier.Operation.MULTIPLY_TOTAL) { ++ if (((Attribute) entry.getKey()).equals(Attributes.KNOCKBACK_RESISTANCE)) { ++ d1 = d0 * 10.0D; ++ } else { ++ d1 = d0; ++ } + } else { +- d = amount; ++ d1 = d0 * 100.0D; + } + + if (flag) { +- list.add( +- CommonComponents.space() +- .append( +- Component.translatable( +- "attribute.modifier.equals." + attributeModifier.getOperation().toValue(), +- ATTRIBUTE_MODIFIER_FORMAT.format(d), +- Component.translatable(entry.getKey().getDescriptionId()) +- ) +- ) +- .withStyle(ChatFormatting.DARK_GREEN) +- ); +- } else if (amount > 0.0) { +- list.add( +- Component.translatable( +- "attribute.modifier.plus." + attributeModifier.getOperation().toValue(), +- ATTRIBUTE_MODIFIER_FORMAT.format(d), +- Component.translatable(entry.getKey().getDescriptionId()) +- ) +- .withStyle(ChatFormatting.BLUE) +- ); +- } else if (amount < 0.0) { +- d *= -1.0; +- list.add( +- Component.translatable( +- "attribute.modifier.take." + attributeModifier.getOperation().toValue(), +- ATTRIBUTE_MODIFIER_FORMAT.format(d), +- Component.translatable(entry.getKey().getDescriptionId()) +- ) +- .withStyle(ChatFormatting.RED) +- ); ++ list.add(CommonComponents.space().append((Component) Component.translatable("attribute.modifier.equals." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId()))).withStyle(ChatFormatting.DARK_GREEN)); ++ } else if (d0 > 0.0D) { ++ list.add(Component.translatable("attribute.modifier.plus." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId())).withStyle(ChatFormatting.BLUE)); ++ } else if (d0 < 0.0D) { ++ d1 *= -1.0D; ++ list.add(Component.translatable("attribute.modifier.take." + attributemodifier.getOperation().toValue(), ItemStack.ATTRIBUTE_MODIFIER_FORMAT.format(d1), Component.translatable(((Attribute) entry.getKey()).getDescriptionId())).withStyle(ChatFormatting.RED)); + } + } + } +@@ -738,30 +1014,32 @@ + } + + if (this.hasTag()) { +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.UNBREAKABLE) && this.tag.getBoolean("Unbreakable")) { ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.UNBREAKABLE) && this.tag.getBoolean("Unbreakable")) { + list.add(Component.translatable("item.unbreakable").withStyle(ChatFormatting.BLUE)); + } + +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.CAN_DESTROY) && this.tag.contains("CanDestroy", 9)) { +- ListTag list2 = this.tag.getList("CanDestroy", 8); +- if (!list2.isEmpty()) { ++ ListTag nbttaglist1; ++ ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.CAN_DESTROY) && this.tag.contains("CanDestroy", 9)) { ++ nbttaglist1 = this.tag.getList("CanDestroy", 8); ++ if (!nbttaglist1.isEmpty()) { + list.add(CommonComponents.EMPTY); + list.add(Component.translatable("item.canBreak").withStyle(ChatFormatting.GRAY)); + +- for (int i1 = 0; i1 < list2.size(); i1++) { +- list.addAll(expandBlockState(list2.getString(i1))); ++ for (k = 0; k < nbttaglist1.size(); ++k) { ++ list.addAll(expandBlockState(nbttaglist1.getString(k))); + } + } + } + +- if (shouldShowInTooltip(hideFlags, ItemStack.TooltipPart.CAN_PLACE) && this.tag.contains("CanPlaceOn", 9)) { +- ListTag list2 = this.tag.getList("CanPlaceOn", 8); +- if (!list2.isEmpty()) { ++ if (shouldShowInTooltip(i, ItemStack.HideFlags.CAN_PLACE) && this.tag.contains("CanPlaceOn", 9)) { ++ nbttaglist1 = this.tag.getList("CanPlaceOn", 8); ++ if (!nbttaglist1.isEmpty()) { + list.add(CommonComponents.EMPTY); + list.add(Component.translatable("item.canPlace").withStyle(ChatFormatting.GRAY)); + +- for (int i1 = 0; i1 < list2.size(); i1++) { +- list.addAll(expandBlockState(list2.getString(i1))); ++ for (k = 0; k < nbttaglist1.size(); ++k) { ++ list.addAll(expandBlockState(nbttaglist1.getString(k))); + } + } + } +@@ -779,13 +1057,13 @@ + } + + if (player != null && !this.getItem().isEnabled(player.level().enabledFeatures())) { +- list.add(DISABLED_ITEM_TOOLTIP); ++ list.add(ItemStack.DISABLED_ITEM_TOOLTIP); + } + + return list; + } + +- private static boolean shouldShowInTooltip(int hideFlags, ItemStack.TooltipPart part) { ++ private static boolean shouldShowInTooltip(int hideFlags, ItemStack.HideFlags part) { + return (hideFlags & part.getMask()) == 0; + } + +@@ -793,32 +1071,34 @@ + return this.hasTag() && this.tag.contains("HideFlags", 99) ? this.tag.getInt("HideFlags") : 0; + } + +- public void hideTooltipPart(ItemStack.TooltipPart part) { +- CompoundTag tag = this.getOrCreateTag(); +- tag.putInt("HideFlags", tag.getInt("HideFlags") | part.getMask()); ++ public void hideTooltipPart(ItemStack.HideFlags part) { ++ CompoundTag nbttagcompound = this.getOrCreateTag(); ++ ++ nbttagcompound.putInt("HideFlags", nbttagcompound.getInt("HideFlags") | part.getMask()); + } + + public static void appendEnchantmentNames(List<Component> tooltipComponents, ListTag storedEnchantments) { +- for (int i = 0; i < storedEnchantments.size(); i++) { +- CompoundTag compound = storedEnchantments.getCompound(i); +- BuiltInRegistries.ENCHANTMENT +- .getOptional(EnchantmentHelper.getEnchantmentId(compound)) +- .ifPresent(enchantment -> tooltipComponents.add(enchantment.getFullname(EnchantmentHelper.getEnchantmentLevel(compound)))); ++ for (int i = 0; i < storedEnchantments.size(); ++i) { ++ CompoundTag nbttagcompound = storedEnchantments.getCompound(i); ++ ++ BuiltInRegistries.ENCHANTMENT.getOptional(EnchantmentHelper.getEnchantmentId(nbttagcompound)).ifPresent((enchantment) -> { ++ tooltipComponents.add(enchantment.getFullname(EnchantmentHelper.getEnchantmentLevel(nbttagcompound))); ++ }); + } ++ + } + + private static Collection<Component> expandBlockState(String stateString) { + try { +- return BlockStateParser.parseForTesting(BuiltInRegistries.BLOCK.asLookup(), stateString, true) +- .map( +- blockResult -> Lists.newArrayList(blockResult.blockState().getBlock().getName().withStyle(ChatFormatting.DARK_GRAY)), +- tagResult -> tagResult.tag() +- .stream() +- .map(holder -> holder.value().getName().withStyle(ChatFormatting.DARK_GRAY)) +- .collect(Collectors.toList()) +- ); +- } catch (CommandSyntaxException var2) { +- return Lists.newArrayList(Component.literal("missingno").withStyle(ChatFormatting.DARK_GRAY)); ++ return (Collection) BlockStateParser.parseForTesting(BuiltInRegistries.BLOCK.asLookup(), stateString, true).map((argumentblock_a) -> { ++ return Lists.newArrayList(new Component[]{argumentblock_a.blockState().getBlock().getName().withStyle(ChatFormatting.DARK_GRAY)}); ++ }, (argumentblock_b) -> { ++ return (List) argumentblock_b.tag().stream().map((holder) -> { ++ return ((Block) holder.value()).getName().withStyle(ChatFormatting.DARK_GRAY); ++ }).collect(Collectors.toList()); ++ }); ++ } catch (CommandSyntaxException commandsyntaxexception) { ++ return Lists.newArrayList(new Component[]{Component.literal("missingno").withStyle(ChatFormatting.DARK_GRAY)}); + } + } + +@@ -831,7 +1111,7 @@ + } + + public boolean isEnchantable() { +- return this.getItem().isEnchantable(this) && !this.isEnchanted(); ++ return !this.getItem().isEnchantable(this) ? false : !this.isEnchanted(); + } + + public void enchant(Enchantment enchantment, int level) { +@@ -840,12 +1120,13 @@ + this.tag.put("Enchantments", new ListTag()); + } + +- ListTag list = this.tag.getList("Enchantments", 10); +- list.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte)level)); ++ ListTag nbttaglist = this.tag.getList("Enchantments", 10); ++ ++ nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte) level)); + } + + public boolean isEnchanted() { +- return this.tag != null && this.tag.contains("Enchantments", 9) && !this.tag.getList("Enchantments", 10).isEmpty(); ++ return this.tag != null && this.tag.contains("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; + } + + public void addTagElement(String key, Tag tag) { +@@ -862,7 +1143,7 @@ + + @Nullable + public ItemFrame getFrame() { +- return this.entityRepresentation instanceof ItemFrame ? (ItemFrame)this.getEntityRepresentation() : null; ++ return this.entityRepresentation instanceof ItemFrame ? (ItemFrame) this.getEntityRepresentation() : null; + } + + @Nullable +@@ -880,33 +1161,36 @@ + } else { + this.removeTagKey("RepairCost"); + } ++ + } + + public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot) { +- Multimap<Attribute, AttributeModifier> multimap; ++ Object object; ++ + if (this.hasTag() && this.tag.contains("AttributeModifiers", 9)) { +- multimap = HashMultimap.create(); +- ListTag list = this.tag.getList("AttributeModifiers", 10); ++ object = HashMultimap.create(); ++ ListTag nbttaglist = this.tag.getList("AttributeModifiers", 10); + +- for (int i = 0; i < list.size(); i++) { +- CompoundTag compound = list.getCompound(i); +- if (!compound.contains("Slot", 8) || compound.getString("Slot").equals(slot.getName())) { +- Optional<Attribute> optional = BuiltInRegistries.ATTRIBUTE.getOptional(ResourceLocation.tryParse(compound.getString("AttributeName"))); ++ for (int i = 0; i < nbttaglist.size(); ++i) { ++ CompoundTag nbttagcompound = nbttaglist.getCompound(i); ++ ++ if (!nbttagcompound.contains("Slot", 8) || nbttagcompound.getString("Slot").equals(slot.getName())) { ++ Optional<Attribute> optional = BuiltInRegistries.ATTRIBUTE.getOptional(ResourceLocation.tryParse(nbttagcompound.getString("AttributeName"))); ++ + if (!optional.isEmpty()) { +- AttributeModifier attributeModifier = AttributeModifier.load(compound); +- if (attributeModifier != null +- && attributeModifier.getId().getLeastSignificantBits() != 0L +- && attributeModifier.getId().getMostSignificantBits() != 0L) { +- multimap.put(optional.get(), attributeModifier); ++ AttributeModifier attributemodifier = AttributeModifier.load(nbttagcompound); ++ ++ if (attributemodifier != null && attributemodifier.getId().getLeastSignificantBits() != 0L && attributemodifier.getId().getMostSignificantBits() != 0L) { ++ ((Multimap) object).put((Attribute) optional.get(), attributemodifier); + } + } + } + } + } else { +- multimap = this.getItem().getDefaultAttributeModifiers(slot); ++ object = this.getItem().getDefaultAttributeModifiers(slot); + } + +- return multimap; ++ return (Multimap) object; + } + + public void addAttributeModifier(Attribute attribute, AttributeModifier modifier, @Nullable EquipmentSlot slot) { +@@ -915,29 +1199,40 @@ + this.tag.put("AttributeModifiers", new ListTag()); + } + +- ListTag list = this.tag.getList("AttributeModifiers", 10); +- CompoundTag compoundTag = modifier.save(); +- compoundTag.putString("AttributeName", BuiltInRegistries.ATTRIBUTE.getKey(attribute).toString()); ++ ListTag nbttaglist = this.tag.getList("AttributeModifiers", 10); ++ CompoundTag nbttagcompound = modifier.save(); ++ ++ nbttagcompound.putString("AttributeName", BuiltInRegistries.ATTRIBUTE.getKey(attribute).toString()); + if (slot != null) { +- compoundTag.putString("Slot", slot.getName()); ++ nbttagcompound.putString("Slot", slot.getName()); + } + +- list.add(compoundTag); ++ nbttaglist.add(nbttagcompound); + } + ++ // CraftBukkit start ++ @Deprecated ++ public void setItem(Item item) { ++ this.item = item; ++ } ++ // CraftBukkit end ++ + public Component getDisplayName() { +- MutableComponent mutableComponent = Component.empty().append(this.getHoverName()); ++ MutableComponent ichatmutablecomponent = Component.empty().append(this.getHoverName()); ++ + if (this.hasCustomHoverName()) { +- mutableComponent.withStyle(ChatFormatting.ITALIC); ++ ichatmutablecomponent.withStyle(ChatFormatting.ITALIC); + } + +- MutableComponent mutableComponent1 = ComponentUtils.wrapInSquareBrackets(mutableComponent); ++ MutableComponent ichatmutablecomponent1 = ComponentUtils.wrapInSquareBrackets(ichatmutablecomponent); ++ + if (!this.isEmpty()) { +- mutableComponent1.withStyle(this.getRarity().color) +- .withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this)))); ++ ichatmutablecomponent1.withStyle(this.getRarity().color).withStyle((chatmodifier) -> { ++ return chatmodifier.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new HoverEvent.ItemStackInfo(this))); ++ }); + } + +- return mutableComponent1; ++ return ichatmutablecomponent1; + } + + public boolean hasAdventureModePlaceTagForBlock(Registry<Block> blockRegistry, BlockInWorld block) { +@@ -1000,18 +1295,14 @@ + return this.getItem().getEatingSound(); + } + +- public static enum TooltipPart { +- ENCHANTMENTS, +- MODIFIERS, +- UNBREAKABLE, +- CAN_DESTROY, +- CAN_PLACE, +- ADDITIONAL, +- DYE, +- UPGRADES; ++ public static enum HideFlags { + ++ ENCHANTMENTS, MODIFIERS, UNBREAKABLE, CAN_DESTROY, CAN_PLACE, ADDITIONAL, DYE, UPGRADES; ++ + private final int mask = 1 << this.ordinal(); + ++ private HideFlags() {} ++ + public int getMask() { + return this.mask; + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/LeadItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/LeadItem.java.patch new file mode 100644 index 0000000000..c5ea6ddded --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/LeadItem.java.patch @@ -0,0 +1,127 @@ +--- a/net/minecraft/world/item/LeadItem.java ++++ b/net/minecraft/world/item/LeadItem.java +@@ -1,65 +1,100 @@ + package net.minecraft.world.item; + ++import java.util.Iterator; ++import java.util.List; + import net.minecraft.core.BlockPos; + import net.minecraft.tags.BlockTags; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.Mob; + import net.minecraft.world.entity.decoration.LeashFenceKnotEntity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.AABB; ++// CraftBukkit start ++import org.bukkit.craftbukkit.CraftEquipmentSlot; ++import org.bukkit.event.hanging.HangingPlaceEvent; ++// CraftBukkit end + + public class LeadItem extends Item { ++ + public LeadItem(Item.Properties properties) { + super(properties); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (blockState.is(BlockTags.FENCES)) { +- Player player = context.getPlayer(); +- if (!level.isClientSide && player != null) { +- bindPlayerMobs(player, level, clickedPos); ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ ++ if (iblockdata.is(BlockTags.FENCES)) { ++ Player entityhuman = context.getPlayer(); ++ ++ if (!world.isClientSide && entityhuman != null) { ++ bindPlayerMobs(entityhuman, world, blockposition, context.getHand()); // CraftBukkit - Pass hand + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.PASS; + } + } + +- public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) { +- LeashFenceKnotEntity leashFenceKnotEntity = null; ++ public static InteractionResult bindPlayerMobs(Player entityhuman, Level world, BlockPos blockposition, net.minecraft.world.EnumHand enumhand) { // CraftBukkit - Add EnumHand ++ LeashFenceKnotEntity entityleash = null; + boolean flag = false; +- double d = 7.0; +- int x = pos.getX(); +- int y = pos.getY(); +- int z = pos.getZ(); ++ double d0 = 7.0D; ++ int i = blockposition.getX(); ++ int j = blockposition.getY(); ++ int k = blockposition.getZ(); ++ List<Mob> list = world.getEntitiesOfClass(Mob.class, new AABB((double) i - 7.0D, (double) j - 7.0D, (double) k - 7.0D, (double) i + 7.0D, (double) j + 7.0D, (double) k + 7.0D)); ++ Iterator iterator = list.iterator(); + +- for (Mob mob : level.getEntitiesOfClass( +- Mob.class, new AABB((double)x - 7.0, (double)y - 7.0, (double)z - 7.0, (double)x + 7.0, (double)y + 7.0, (double)z + 7.0) +- )) { +- if (mob.getLeashHolder() == player) { +- if (leashFenceKnotEntity == null) { +- leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos); +- leashFenceKnotEntity.playPlacementSound(); ++ while (iterator.hasNext()) { ++ Mob entityinsentient = (Mob) iterator.next(); ++ ++ if (entityinsentient.getLeashHolder() == entityhuman) { ++ if (entityleash == null) { ++ entityleash = LeashFenceKnotEntity.getOrCreateKnot(world, blockposition); ++ ++ // CraftBukkit start - fire HangingPlaceEvent ++ org.bukkit.inventory.EquipmentSlot hand = CraftEquipmentSlot.getHand(enumhand); ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, world.getWorld().getBlockAt(i, j, k), org.bukkit.block.BlockFace.SELF, hand); ++ world.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ entityleash.discard(); ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end ++ entityleash.playPlacementSound(); + } + +- mob.setLeashedTo(leashFenceKnotEntity, true); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, entityleash, entityhuman, enumhand).isCancelled()) { ++ continue; ++ } ++ // CraftBukkit end ++ ++ entityinsentient.setLeashedTo(entityleash, true); + flag = true; + } + } + + if (flag) { +- level.gameEvent(GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of(player)); ++ world.gameEvent(GameEvent.BLOCK_ATTACH, blockposition, GameEvent.Context.of((Entity) entityhuman)); + } + + return flag ? InteractionResult.SUCCESS : InteractionResult.PASS; + } ++ ++ // CraftBukkit start ++ public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) { ++ return bindPlayerMobs(player, level, pos, net.minecraft.world.EnumHand.MAIN_HAND); ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/MapItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/MapItem.java.patch new file mode 100644 index 0000000000..6556502cec --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/MapItem.java.patch @@ -0,0 +1,615 @@ +--- a/net/minecraft/world/item/MapItem.java ++++ b/net/minecraft/world/item/MapItem.java +@@ -26,7 +26,7 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.biome.Biome; + import net.minecraft.world.level.block.Blocks; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.chunk.LevelChunk; + import net.minecraft.world.level.levelgen.Heightmap; + import net.minecraft.world.level.material.FluidState; +@@ -34,6 +34,7 @@ + import net.minecraft.world.level.saveddata.maps.MapItemSavedData; + + public class MapItem extends ComplexItem { ++ + public static final int IMAGE_WIDTH = 128; + public static final int IMAGE_HEIGHT = 128; + private static final int DEFAULT_MAP_COLOR = -12173266; +@@ -46,9 +47,10 @@ + } + + public static ItemStack create(Level level, int levelX, int levelZ, byte scale, boolean trackingPosition, boolean unlimitedTracking) { +- ItemStack itemStack = new ItemStack(Items.FILLED_MAP); +- createAndStoreSavedData(itemStack, level, levelX, levelZ, scale, trackingPosition, unlimitedTracking, level.dimension()); +- return itemStack; ++ ItemStack itemstack = new ItemStack(Items.FILLED_MAP); ++ ++ createAndStoreSavedData(itemstack, level, levelX, levelZ, scale, trackingPosition, unlimitedTracking, level.dimension()); ++ return itemstack; + } + + @Nullable +@@ -58,34 +60,34 @@ + + @Nullable + public static MapItemSavedData getSavedData(ItemStack stack, Level level) { +- Integer mapId = getMapId(stack); +- return getSavedData(mapId, level); ++ Integer integer = getMapId(stack); ++ ++ return getSavedData(integer, level); + } + + @Nullable + public static Integer getMapId(ItemStack stack) { +- CompoundTag tag = stack.getTag(); +- return tag != null && tag.contains("map", 99) ? tag.getInt("map") : null; ++ CompoundTag nbttagcompound = stack.getTag(); ++ ++ return nbttagcompound != null && nbttagcompound.contains("map", 99) ? nbttagcompound.getInt("map") : -1; // CraftBukkit - make new maps for no tag + } + +- private static int createNewSavedData( +- Level level, int x, int z, int scale, boolean trackingPosition, boolean unlimitedTracking, ResourceKey<Level> dimension +- ) { +- MapItemSavedData mapItemSavedData = MapItemSavedData.createFresh((double)x, (double)z, (byte)scale, trackingPosition, unlimitedTracking, dimension); +- int freeMapId = level.getFreeMapId(); +- level.setMapData(makeKey(freeMapId), mapItemSavedData); +- return freeMapId; ++ public static int createNewSavedData(Level level, int x, int z, int scale, boolean trackingPosition, boolean unlimitedTracking, ResourceKey<Level> dimension) { ++ MapItemSavedData worldmap = MapItemSavedData.createFresh((double) x, (double) z, (byte) scale, trackingPosition, unlimitedTracking, dimension); ++ int l = level.getFreeMapId(); ++ ++ level.setMapData(makeKey(l), worldmap); ++ return l; + } + + private static void storeMapData(ItemStack stack, int mapId) { + stack.getOrCreateTag().putInt("map", mapId); + } + +- private static void createAndStoreSavedData( +- ItemStack stack, Level level, int x, int z, int scale, boolean trackingPosition, boolean unlimitedTracking, ResourceKey<Level> dimension +- ) { +- int i = createNewSavedData(level, x, z, scale, trackingPosition, unlimitedTracking, dimension); +- storeMapData(stack, i); ++ private static void createAndStoreSavedData(ItemStack stack, Level level, int x, int z, int scale, boolean trackingPosition, boolean unlimitedTracking, ResourceKey<Level> dimension) { ++ int l = createNewSavedData(level, x, z, scale, trackingPosition, unlimitedTracking, dimension); ++ ++ storeMapData(stack, l); + } + + public static String makeKey(int mapId) { +@@ -95,121 +97,134 @@ + public void update(Level level, Entity viewer, MapItemSavedData data) { + if (level.dimension() == data.dimension && viewer instanceof Player) { + int i = 1 << data.scale; +- int i1 = data.centerX; +- int i2 = data.centerZ; +- int i3 = Mth.floor(viewer.getX() - (double)i1) / i + 64; +- int i4 = Mth.floor(viewer.getZ() - (double)i2) / i + 64; +- int i5 = 128 / i; ++ int j = data.centerX; ++ int k = data.centerZ; ++ int l = Mth.floor(viewer.getX() - (double) j) / i + 64; ++ int i1 = Mth.floor(viewer.getZ() - (double) k) / i + 64; ++ int j1 = 128 / i; ++ + if (level.dimensionType().hasCeiling()) { +- i5 /= 2; ++ j1 /= 2; + } + +- MapItemSavedData.HoldingPlayer holdingPlayer = data.getHoldingPlayer((Player)viewer); +- holdingPlayer.step++; +- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); +- BlockPos.MutableBlockPos mutableBlockPos1 = new BlockPos.MutableBlockPos(); ++ MapItemSavedData.HoldingPlayer worldmap_worldmaphumantracker = data.getHoldingPlayer((Player) viewer); ++ ++ ++worldmap_worldmaphumantracker.step; ++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); ++ BlockPos.MutableBlockPos blockposition_mutableblockposition1 = new BlockPos.MutableBlockPos(); + boolean flag = false; + +- for (int i6 = i3 - i5 + 1; i6 < i3 + i5; i6++) { +- if ((i6 & 15) == (holdingPlayer.step & 15) || flag) { ++ for (int k1 = l - j1 + 1; k1 < l + j1; ++k1) { ++ if ((k1 & 15) == (worldmap_worldmaphumantracker.step & 15) || flag) { + flag = false; +- double d = 0.0; ++ double d0 = 0.0D; + +- for (int i7 = i4 - i5 - 1; i7 < i4 + i5; i7++) { +- if (i6 >= 0 && i7 >= -1 && i6 < 128 && i7 < 128) { +- int i8 = Mth.square(i6 - i3) + Mth.square(i7 - i4); +- boolean flag1 = i8 > (i5 - 2) * (i5 - 2); +- int i9 = (i1 / i + i6 - 64) * i; +- int i10 = (i2 / i + i7 - 64) * i; ++ for (int l1 = i1 - j1 - 1; l1 < i1 + j1; ++l1) { ++ if (k1 >= 0 && l1 >= -1 && k1 < 128 && l1 < 128) { ++ int i2 = Mth.square(k1 - l) + Mth.square(l1 - i1); ++ boolean flag1 = i2 > (j1 - 2) * (j1 - 2); ++ int j2 = (j / i + k1 - 64) * i; ++ int k2 = (k / i + l1 - 64) * i; + Multiset<MapColor> multiset = LinkedHashMultiset.create(); +- LevelChunk chunk = level.getChunk(SectionPos.blockToSectionCoord(i9), SectionPos.blockToSectionCoord(i10)); ++ LevelChunk chunk = level.getChunk(SectionPos.blockToSectionCoord(j2), SectionPos.blockToSectionCoord(k2)); ++ + if (!chunk.isEmpty()) { +- int i11 = 0; +- double d1 = 0.0; ++ int l2 = 0; ++ double d1 = 0.0D; ++ int i3; ++ + if (level.dimensionType().hasCeiling()) { +- int i12 = i9 + i10 * 231871; +- i12 = i12 * i12 * 31287121 + i12 * 11; +- if ((i12 >> 20 & 1) == 0) { ++ i3 = j2 + k2 * 231871; ++ i3 = i3 * i3 * 31287121 + i3 * 11; ++ if ((i3 >> 20 & 1) == 0) { + multiset.add(Blocks.DIRT.defaultBlockState().getMapColor(level, BlockPos.ZERO), 10); + } else { + multiset.add(Blocks.STONE.defaultBlockState().getMapColor(level, BlockPos.ZERO), 100); + } + +- d1 = 100.0; ++ d1 = 100.0D; + } else { +- for (int i12 = 0; i12 < i; i12++) { +- for (int i13 = 0; i13 < i; i13++) { +- mutableBlockPos.set(i9 + i12, 0, i10 + i13); +- int i14 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, mutableBlockPos.getX(), mutableBlockPos.getZ()) + 1; +- BlockState blockState; +- if (i14 <= level.getMinBuildHeight() + 1) { +- blockState = Blocks.BEDROCK.defaultBlockState(); +- } else { ++ for (i3 = 0; i3 < i; ++i3) { ++ for (int j3 = 0; j3 < i; ++j3) { ++ blockposition_mutableblockposition.set(j2 + i3, 0, k2 + j3); ++ int k3 = chunk.getHeight(Heightmap.Types.WORLD_SURFACE, blockposition_mutableblockposition.getX(), blockposition_mutableblockposition.getZ()) + 1; ++ IBlockData iblockdata; ++ ++ if (k3 > level.getMinBuildHeight() + 1) { + do { +- mutableBlockPos.setY(--i14); +- blockState = chunk.getBlockState(mutableBlockPos); +- } while (blockState.getMapColor(level, mutableBlockPos) == MapColor.NONE && i14 > level.getMinBuildHeight()); ++ --k3; ++ blockposition_mutableblockposition.setY(k3); ++ iblockdata = chunk.getBlockState(blockposition_mutableblockposition); ++ } while (iblockdata.getMapColor(level, blockposition_mutableblockposition) == MapColor.NONE && k3 > level.getMinBuildHeight()); + +- if (i14 > level.getMinBuildHeight() && !blockState.getFluidState().isEmpty()) { +- int i15 = i14 - 1; +- mutableBlockPos1.set(mutableBlockPos); ++ if (k3 > level.getMinBuildHeight() && !iblockdata.getFluidState().isEmpty()) { ++ int l3 = k3 - 1; + +- BlockState blockState1; ++ blockposition_mutableblockposition1.set(blockposition_mutableblockposition); ++ ++ IBlockData iblockdata1; ++ + do { +- mutableBlockPos1.setY(i15--); +- blockState1 = chunk.getBlockState(mutableBlockPos1); +- i11++; +- } while (i15 > level.getMinBuildHeight() && !blockState1.getFluidState().isEmpty()); ++ blockposition_mutableblockposition1.setY(l3--); ++ iblockdata1 = chunk.getBlockState(blockposition_mutableblockposition1); ++ ++l2; ++ } while (l3 > level.getMinBuildHeight() && !iblockdata1.getFluidState().isEmpty()); + +- blockState = this.getCorrectStateForFluidBlock(level, blockState, mutableBlockPos); ++ iblockdata = this.getCorrectStateForFluidBlock(level, iblockdata, blockposition_mutableblockposition); + } ++ } else { ++ iblockdata = Blocks.BEDROCK.defaultBlockState(); + } + +- data.checkBanners(level, mutableBlockPos.getX(), mutableBlockPos.getZ()); +- d1 += (double)i14 / (double)(i * i); +- multiset.add(blockState.getMapColor(level, mutableBlockPos)); ++ data.checkBanners(level, blockposition_mutableblockposition.getX(), blockposition_mutableblockposition.getZ()); ++ d1 += (double) k3 / (double) (i * i); ++ multiset.add(iblockdata.getMapColor(level, blockposition_mutableblockposition)); + } + } + } + +- int var33 = i11 / (i * i); +- MapColor mapColor = Iterables.getFirst(Multisets.copyHighestCountFirst(multiset), MapColor.NONE); +- MapColor.Brightness brightness; +- if (mapColor == MapColor.WATER) { +- double d2 = (double)var33 * 0.1 + (double)(i6 + i7 & 1) * 0.2; +- if (d2 < 0.5) { +- brightness = MapColor.Brightness.HIGH; +- } else if (d2 > 0.9) { +- brightness = MapColor.Brightness.LOW; ++ l2 /= i * i; ++ MapColor materialmapcolor = (MapColor) Iterables.getFirst(Multisets.copyHighestCountFirst(multiset), MapColor.NONE); ++ double d2; ++ MapColor.Brightness materialmapcolor_a; ++ ++ if (materialmapcolor == MapColor.WATER) { ++ d2 = (double) l2 * 0.1D + (double) (k1 + l1 & 1) * 0.2D; ++ if (d2 < 0.5D) { ++ materialmapcolor_a = MapColor.Brightness.HIGH; ++ } else if (d2 > 0.9D) { ++ materialmapcolor_a = MapColor.Brightness.LOW; + } else { +- brightness = MapColor.Brightness.NORMAL; ++ materialmapcolor_a = MapColor.Brightness.NORMAL; + } + } else { +- double d2 = (d1 - d) * 4.0 / (double)(i + 4) + ((double)(i6 + i7 & 1) - 0.5) * 0.4; +- if (d2 > 0.6) { +- brightness = MapColor.Brightness.HIGH; +- } else if (d2 < -0.6) { +- brightness = MapColor.Brightness.LOW; ++ d2 = (d1 - d0) * 4.0D / (double) (i + 4) + ((double) (k1 + l1 & 1) - 0.5D) * 0.4D; ++ if (d2 > 0.6D) { ++ materialmapcolor_a = MapColor.Brightness.HIGH; ++ } else if (d2 < -0.6D) { ++ materialmapcolor_a = MapColor.Brightness.LOW; + } else { +- brightness = MapColor.Brightness.NORMAL; ++ materialmapcolor_a = MapColor.Brightness.NORMAL; + } + } + +- d = d1; +- if (i7 >= 0 && i8 < i5 * i5 && (!flag1 || (i6 + i7 & 1) != 0)) { +- flag |= data.updateColor(i6, i7, mapColor.getPackedId(brightness)); ++ d0 = d1; ++ if (l1 >= 0 && i2 < j1 * j1 && (!flag1 || (k1 + l1 & 1) != 0)) { ++ flag |= data.updateColor(k1, l1, materialmapcolor.getPackedId(materialmapcolor_a)); + } + } + } + } + } + } ++ + } + } + +- private BlockState getCorrectStateForFluidBlock(Level level, BlockState state, BlockPos pos) { +- FluidState fluidState = state.getFluidState(); +- return !fluidState.isEmpty() && !state.isFaceSturdy(level, pos, Direction.UP) ? fluidState.createLegacyBlock() : state; ++ private IBlockData getCorrectStateForFluidBlock(Level level, IBlockData state, BlockPos pos) { ++ FluidState fluid = state.getFluidState(); ++ ++ return !fluid.isEmpty() && !state.isFaceSturdy(level, pos, Direction.UP) ? fluid.createLegacyBlock() : state; + } + + private static boolean isBiomeWatery(boolean[] wateryMap, int xSample, int zSample) { +@@ -217,76 +232,83 @@ + } + + public static void renderBiomePreviewMap(ServerLevel serverLevel, ItemStack stack) { +- MapItemSavedData savedData = getSavedData(stack, serverLevel); +- if (savedData != null) { +- if (serverLevel.dimension() == savedData.dimension) { +- int i = 1 << savedData.scale; +- int i1 = savedData.centerX; +- int i2 = savedData.centerZ; +- boolean[] flags = new boolean[16384]; +- int i3 = i1 / i - 64; +- int i4 = i2 / i - 64; +- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ++ MapItemSavedData worldmap = getSavedData(stack, serverLevel); + +- for (int i5 = 0; i5 < 128; i5++) { +- for (int i6 = 0; i6 < 128; i6++) { +- Holder<Biome> biome = serverLevel.getBiome(mutableBlockPos.set((i3 + i6) * i, 0, (i4 + i5) * i)); +- flags[i5 * 128 + i6] = biome.is(BiomeTags.WATER_ON_MAP_OUTLINES); ++ if (worldmap != null) { ++ if (serverLevel.dimension() == worldmap.dimension) { ++ int i = 1 << worldmap.scale; ++ int j = worldmap.centerX; ++ int k = worldmap.centerZ; ++ boolean[] aboolean = new boolean[16384]; ++ int l = j / i - 64; ++ int i1 = k / i - 64; ++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); ++ ++ int j1; ++ int k1; ++ ++ for (j1 = 0; j1 < 128; ++j1) { ++ for (k1 = 0; k1 < 128; ++k1) { ++ Holder<Biome> holder = serverLevel.getBiome(blockposition_mutableblockposition.set((l + k1) * i, 0, (i1 + j1) * i)); ++ ++ aboolean[j1 * 128 + k1] = holder.is(BiomeTags.WATER_ON_MAP_OUTLINES); + } + } + +- for (int i5 = 1; i5 < 127; i5++) { +- for (int i6 = 1; i6 < 127; i6++) { +- int i7 = 0; ++ for (j1 = 1; j1 < 127; ++j1) { ++ for (k1 = 1; k1 < 127; ++k1) { ++ int l1 = 0; + +- for (int i8 = -1; i8 < 2; i8++) { +- for (int i9 = -1; i9 < 2; i9++) { +- if ((i8 != 0 || i9 != 0) && isBiomeWatery(flags, i5 + i8, i6 + i9)) { +- i7++; ++ for (int i2 = -1; i2 < 2; ++i2) { ++ for (int j2 = -1; j2 < 2; ++j2) { ++ if ((i2 != 0 || j2 != 0) && isBiomeWatery(aboolean, j1 + i2, k1 + j2)) { ++ ++l1; + } + } + } + +- MapColor.Brightness brightness = MapColor.Brightness.LOWEST; +- MapColor mapColor = MapColor.NONE; +- if (isBiomeWatery(flags, i5, i6)) { +- mapColor = MapColor.COLOR_ORANGE; +- if (i7 > 7 && i6 % 2 == 0) { +- switch ((i5 + (int)(Mth.sin((float)i6 + 0.0F) * 7.0F)) / 8 % 5) { ++ MapColor.Brightness materialmapcolor_a = MapColor.Brightness.LOWEST; ++ MapColor materialmapcolor = MapColor.NONE; ++ ++ if (isBiomeWatery(aboolean, j1, k1)) { ++ materialmapcolor = MapColor.COLOR_ORANGE; ++ if (l1 > 7 && k1 % 2 == 0) { ++ switch ((j1 + (int) (Mth.sin((float) k1 + 0.0F) * 7.0F)) / 8 % 5) { + case 0: + case 4: +- brightness = MapColor.Brightness.LOW; ++ materialmapcolor_a = MapColor.Brightness.LOW; + break; + case 1: + case 3: +- brightness = MapColor.Brightness.NORMAL; ++ materialmapcolor_a = MapColor.Brightness.NORMAL; + break; + case 2: +- brightness = MapColor.Brightness.HIGH; ++ materialmapcolor_a = MapColor.Brightness.HIGH; + } +- } else if (i7 > 7) { +- mapColor = MapColor.NONE; +- } else if (i7 > 5) { +- brightness = MapColor.Brightness.NORMAL; +- } else if (i7 > 3) { +- brightness = MapColor.Brightness.LOW; +- } else if (i7 > 1) { +- brightness = MapColor.Brightness.LOW; ++ } else if (l1 > 7) { ++ materialmapcolor = MapColor.NONE; ++ } else if (l1 > 5) { ++ materialmapcolor_a = MapColor.Brightness.NORMAL; ++ } else if (l1 > 3) { ++ materialmapcolor_a = MapColor.Brightness.LOW; ++ } else if (l1 > 1) { ++ materialmapcolor_a = MapColor.Brightness.LOW; + } +- } else if (i7 > 0) { +- mapColor = MapColor.COLOR_BROWN; +- if (i7 > 3) { +- brightness = MapColor.Brightness.NORMAL; ++ } else if (l1 > 0) { ++ materialmapcolor = MapColor.COLOR_BROWN; ++ if (l1 > 3) { ++ materialmapcolor_a = MapColor.Brightness.NORMAL; + } else { +- brightness = MapColor.Brightness.LOWEST; ++ materialmapcolor_a = MapColor.Brightness.LOWEST; + } + } + +- if (mapColor != MapColor.NONE) { +- savedData.setColor(i5, i6, mapColor.getPackedId(brightness)); ++ if (materialmapcolor != MapColor.NONE) { ++ worldmap.setColor(j1, k1, materialmapcolor.getPackedId(materialmapcolor_a)); + } + } + } ++ + } + } + } +@@ -294,15 +316,19 @@ + @Override + public void inventoryTick(ItemStack stack, Level level, Entity entity, int itemSlot, boolean isSelected) { + if (!level.isClientSide) { +- MapItemSavedData savedData = getSavedData(stack, level); +- if (savedData != null) { +- if (entity instanceof Player player) { +- savedData.tickCarriedBy(player, stack); ++ MapItemSavedData worldmap = getSavedData(stack, level); ++ ++ if (worldmap != null) { ++ if (entity instanceof Player) { ++ Player entityhuman = (Player) entity; ++ ++ worldmap.tickCarriedBy(entityhuman, stack); + } + +- if (!savedData.locked && (isSelected || entity instanceof Player && ((Player)entity).getOffhandItem() == stack)) { +- this.update(level, entity, savedData); ++ if (!worldmap.locked && (isSelected || entity instanceof Player && ((Player) entity).getOffhandItem() == stack)) { ++ this.update(level, entity, worldmap); + } ++ + } + } + } +@@ -310,90 +336,104 @@ + @Nullable + @Override + public Packet<?> getUpdatePacket(ItemStack stack, Level level, Player player) { +- Integer mapId = getMapId(stack); +- MapItemSavedData savedData = getSavedData(mapId, level); +- return savedData != null ? savedData.getUpdatePacket(mapId, player) : null; ++ Integer integer = getMapId(stack); ++ MapItemSavedData worldmap = getSavedData(integer, level); ++ ++ return worldmap != null ? worldmap.getUpdatePacket(integer, player) : null; + } + + @Override +- public void onCraftedPostProcess(ItemStack itemStack, Level level) { +- CompoundTag tag = itemStack.getTag(); +- if (tag != null && tag.contains("map_scale_direction", 99)) { +- scaleMap(itemStack, level, tag.getInt("map_scale_direction")); +- tag.remove("map_scale_direction"); +- } else if (tag != null && tag.contains("map_to_lock", 1) && tag.getBoolean("map_to_lock")) { +- lockMap(level, itemStack); +- tag.remove("map_to_lock"); ++ public void onCraftedPostProcess(ItemStack itemstack, Level world) { ++ CompoundTag nbttagcompound = itemstack.getTag(); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("map_scale_direction", 99)) { ++ scaleMap(itemstack, world, nbttagcompound.getInt("map_scale_direction")); ++ nbttagcompound.remove("map_scale_direction"); ++ } else if (nbttagcompound != null && nbttagcompound.contains("map_to_lock", 1) && nbttagcompound.getBoolean("map_to_lock")) { ++ lockMap(world, itemstack); ++ nbttagcompound.remove("map_to_lock"); + } ++ + } + + private static void scaleMap(ItemStack stack, Level level, int scale) { +- MapItemSavedData savedData = getSavedData(stack, level); +- if (savedData != null) { +- int freeMapId = level.getFreeMapId(); +- level.setMapData(makeKey(freeMapId), savedData.scaled(scale)); +- storeMapData(stack, freeMapId); ++ MapItemSavedData worldmap = getSavedData(stack, level); ++ ++ if (worldmap != null) { ++ int j = level.getFreeMapId(); ++ ++ level.setMapData(makeKey(j), worldmap.scaled(scale)); ++ storeMapData(stack, j); + } ++ + } + + public static void lockMap(Level level, ItemStack stack) { +- MapItemSavedData savedData = getSavedData(stack, level); +- if (savedData != null) { +- int freeMapId = level.getFreeMapId(); +- String string = makeKey(freeMapId); +- MapItemSavedData mapItemSavedData = savedData.locked(); +- level.setMapData(string, mapItemSavedData); +- storeMapData(stack, freeMapId); ++ MapItemSavedData worldmap = getSavedData(stack, level); ++ ++ if (worldmap != null) { ++ int i = level.getFreeMapId(); ++ String s = makeKey(i); ++ MapItemSavedData worldmap1 = worldmap.locked(); ++ ++ level.setMapData(s, worldmap1); ++ storeMapData(stack, i); + } ++ + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) { +- Integer mapId = getMapId(stack); +- MapItemSavedData mapItemSavedData = level == null ? null : getSavedData(mapId, level); +- CompoundTag tag = stack.getTag(); +- boolean _boolean; +- byte _byte; +- if (tag != null) { +- _boolean = tag.getBoolean("map_to_lock"); +- _byte = tag.getByte("map_scale_direction"); ++ Integer integer = getMapId(stack); ++ MapItemSavedData worldmap = level == null ? null : getSavedData(integer, level); ++ CompoundTag nbttagcompound = stack.getTag(); ++ boolean flag; ++ byte b0; ++ ++ if (nbttagcompound != null) { ++ flag = nbttagcompound.getBoolean("map_to_lock"); ++ b0 = nbttagcompound.getByte("map_scale_direction"); + } else { +- _boolean = false; +- _byte = 0; ++ flag = false; ++ b0 = 0; + } + +- if (mapItemSavedData != null && (mapItemSavedData.locked || _boolean)) { +- tooltip.add(Component.translatable("filled_map.locked", mapId).withStyle(ChatFormatting.GRAY)); ++ if (worldmap != null && (worldmap.locked || flag)) { ++ tooltip.add(Component.translatable("filled_map.locked", integer).withStyle(ChatFormatting.GRAY)); + } + + if (flag.isAdvanced()) { +- if (mapItemSavedData != null) { +- if (!_boolean && _byte == 0) { +- tooltip.add(getTooltipForId(mapId)); ++ if (worldmap != null) { ++ if (!flag && b0 == 0) { ++ tooltip.add(getTooltipForId(integer)); + } + +- int min = Math.min(mapItemSavedData.scale + _byte, 4); +- tooltip.add(Component.translatable("filled_map.scale", 1 << min).withStyle(ChatFormatting.GRAY)); +- tooltip.add(Component.translatable("filled_map.level", min, 4).withStyle(ChatFormatting.GRAY)); ++ int i = Math.min(worldmap.scale + b0, 4); ++ ++ tooltip.add(Component.translatable("filled_map.scale", 1 << i).withStyle(ChatFormatting.GRAY)); ++ tooltip.add(Component.translatable("filled_map.level", i, 4).withStyle(ChatFormatting.GRAY)); + } else { + tooltip.add(Component.translatable("filled_map.unknown").withStyle(ChatFormatting.GRAY)); + } + } ++ + } + + private static Component getTooltipForId(int i) { + return Component.translatable("filled_map.id", i).withStyle(ChatFormatting.GRAY); + } + +- public static Component getTooltipForId(ItemStack itemStack) { +- return getTooltipForId(getMapId(itemStack)); ++ public static Component getTooltipForId(ItemStack itemstack) { ++ return getTooltipForId(getMapId(itemstack)); + } + + public static int getColor(ItemStack stack) { +- CompoundTag tagElement = stack.getTagElement("display"); +- if (tagElement != null && tagElement.contains("MapColor", 99)) { +- int _int = tagElement.getInt("MapColor"); +- return 0xFF000000 | _int & 16777215; ++ CompoundTag nbttagcompound = stack.getTagElement("display"); ++ ++ if (nbttagcompound != null && nbttagcompound.contains("MapColor", 99)) { ++ int i = nbttagcompound.getInt("MapColor"); ++ ++ return -16777216 | i & 16777215; + } else { + return -12173266; + } +@@ -401,11 +441,13 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- BlockState blockState = context.getLevel().getBlockState(context.getClickedPos()); +- if (blockState.is(BlockTags.BANNERS)) { ++ IBlockData iblockdata = context.getLevel().getBlockState(context.getClickedPos()); ++ ++ if (iblockdata.is(BlockTags.BANNERS)) { + if (!context.getLevel().isClientSide) { +- MapItemSavedData savedData = getSavedData(context.getItemInHand(), context.getLevel()); +- if (savedData != null && !savedData.toggleBanner(context.getLevel(), context.getClickedPos())) { ++ MapItemSavedData worldmap = getSavedData(context.getItemInHand(), context.getLevel()); ++ ++ if (worldmap != null && !worldmap.toggleBanner(context.getLevel(), context.getClickedPos())) { + return InteractionResult.FAIL; + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/MilkBucketItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/MilkBucketItem.java.patch new file mode 100644 index 0000000000..2e929e5667 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/MilkBucketItem.java.patch @@ -0,0 +1,59 @@ +--- a/net/minecraft/world/item/MilkBucketItem.java ++++ b/net/minecraft/world/item/MilkBucketItem.java +@@ -3,13 +3,14 @@ + import net.minecraft.advancements.CriteriaTriggers; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.level.Level; + + public class MilkBucketItem extends Item { ++ + private static final int DRINK_DURATION = 32; + + public MilkBucketItem(Item.Properties properties) { +@@ -18,17 +19,19 @@ + + @Override + public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity entityLiving) { +- if (entityLiving instanceof ServerPlayer serverPlayer) { +- CriteriaTriggers.CONSUME_ITEM.trigger(serverPlayer, stack); +- serverPlayer.awardStat(Stats.ITEM_USED.get(this)); ++ if (entityLiving instanceof ServerPlayer) { ++ ServerPlayer entityplayer = (ServerPlayer) entityLiving; ++ ++ CriteriaTriggers.CONSUME_ITEM.trigger(entityplayer, stack); ++ entityplayer.awardStat(Stats.ITEM_USED.get(this)); + } + +- if (entityLiving instanceof Player && !((Player)entityLiving).getAbilities().instabuild) { ++ if (entityLiving instanceof Player && !((Player) entityLiving).getAbilities().instabuild) { + stack.shrink(1); + } + + if (!level.isClientSide) { +- entityLiving.removeAllEffects(); ++ entityLiving.removeAllEffects(org.bukkit.event.entity.EntityPotionEffectEvent.Cause.MILK); // CraftBukkit + } + + return stack.isEmpty() ? new ItemStack(Items.BUCKET) : stack; +@@ -40,12 +43,12 @@ + } + + @Override +- public UseAnim getUseAnimation(ItemStack stack) { +- return UseAnim.DRINK; ++ public EnumAnimation getUseAnimation(ItemStack stack) { ++ return EnumAnimation.DRINK; + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { + return ItemUtils.startUsingInstantly(level, player, hand); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/MinecartItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/MinecartItem.java.patch new file mode 100644 index 0000000000..a46e0e5dde --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/MinecartItem.java.patch @@ -0,0 +1,217 @@ +--- a/net/minecraft/world/item/MinecartItem.java ++++ b/net/minecraft/world/item/MinecartItem.java +@@ -2,118 +2,149 @@ + + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; +-import net.minecraft.core.dispenser.BlockSource; + import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; + import net.minecraft.core.dispenser.DispenseItemBehavior; ++import net.minecraft.core.dispenser.SourceBlock; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.tags.BlockTags; + import net.minecraft.world.InteractionResult; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.vehicle.AbstractMinecart; + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.BaseRailBlock; + import net.minecraft.world.level.block.DispenserBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.block.state.properties.RailShape; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.Vec3; ++// CraftBukkit start ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end + + public class MinecartItem extends Item { ++ + private static final DispenseItemBehavior DISPENSE_ITEM_BEHAVIOR = new DefaultDispenseItemBehavior() { + private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior(); + + @Override +- public ItemStack execute(BlockSource blockSource, ItemStack itemStack) { +- Direction direction = blockSource.state().getValue(DispenserBlock.FACING); +- ServerLevel serverLevel = blockSource.level(); +- Vec3 vec3 = blockSource.center(); +- double d = vec3.x() + (double)direction.getStepX() * 1.125; +- double d1 = Math.floor(vec3.y()) + (double)direction.getStepY(); +- double d2 = vec3.z() + (double)direction.getStepZ() * 1.125; +- BlockPos blockPos = blockSource.pos().relative(direction); +- BlockState blockState = serverLevel.getBlockState(blockPos); +- RailShape railShape = blockState.getBlock() instanceof BaseRailBlock +- ? blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty()) +- : RailShape.NORTH_SOUTH; ++ public ItemStack execute(SourceBlock sourceblock, ItemStack itemstack) { ++ Direction enumdirection = (Direction) sourceblock.state().getValue(DispenserBlock.FACING); ++ ServerLevel worldserver = sourceblock.level(); ++ Vec3 vec3d = sourceblock.center(); ++ double d0 = vec3d.x() + (double) enumdirection.getStepX() * 1.125D; ++ double d1 = Math.floor(vec3d.y()) + (double) enumdirection.getStepY(); ++ double d2 = vec3d.z() + (double) enumdirection.getStepZ() * 1.125D; ++ BlockPos blockposition = sourceblock.pos().relative(enumdirection); ++ IBlockData iblockdata = worldserver.getBlockState(blockposition); ++ RailShape blockpropertytrackposition = iblockdata.getBlock() instanceof BaseRailBlock ? (RailShape) iblockdata.getValue(((BaseRailBlock) iblockdata.getBlock()).getShapeProperty()) : RailShape.NORTH_SOUTH; + double d3; +- if (blockState.is(BlockTags.RAILS)) { +- if (railShape.isAscending()) { +- d3 = 0.6; ++ ++ if (iblockdata.is(BlockTags.RAILS)) { ++ if (blockpropertytrackposition.isAscending()) { ++ d3 = 0.6D; + } else { +- d3 = 0.1; ++ d3 = 0.1D; + } + } else { +- if (!blockState.isAir() || !serverLevel.getBlockState(blockPos.below()).is(BlockTags.RAILS)) { +- return this.defaultDispenseItemBehavior.dispense(blockSource, itemStack); ++ if (!iblockdata.isAir() || !worldserver.getBlockState(blockposition.below()).is(BlockTags.RAILS)) { ++ return this.defaultDispenseItemBehavior.dispense(sourceblock, itemstack); + } + +- BlockState blockState1 = serverLevel.getBlockState(blockPos.below()); +- RailShape railShape1 = blockState1.getBlock() instanceof BaseRailBlock +- ? blockState1.getValue(((BaseRailBlock)blockState1.getBlock()).getShapeProperty()) +- : RailShape.NORTH_SOUTH; +- if (direction != Direction.DOWN && railShape1.isAscending()) { +- d3 = -0.4; ++ IBlockData iblockdata1 = worldserver.getBlockState(blockposition.below()); ++ RailShape blockpropertytrackposition1 = iblockdata1.getBlock() instanceof BaseRailBlock ? (RailShape) iblockdata1.getValue(((BaseRailBlock) iblockdata1.getBlock()).getShapeProperty()) : RailShape.NORTH_SOUTH; ++ ++ if (enumdirection != Direction.DOWN && blockpropertytrackposition1.isAscending()) { ++ d3 = -0.4D; + } else { +- d3 = -0.9; ++ d3 = -0.9D; + } + } + +- AbstractMinecart abstractMinecart = AbstractMinecart.createMinecart( +- serverLevel, d, d1 + d3, d2, ((MinecartItem)itemStack.getItem()).type, itemStack, null +- ); +- serverLevel.addFreshEntity(abstractMinecart); +- itemStack.shrink(1); +- return itemStack; ++ // CraftBukkit start ++ // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.createMinecart(worldserver, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).type); ++ ItemStack itemstack1 = itemstack.split(1); ++ org.bukkit.block.Block block2 = CraftBlock.at(worldserver, sourceblock.pos()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ ++ BlockDispenseEvent event = new BlockDispenseEvent(block2, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); ++ if (!DispenserBlock.eventFired) { ++ worldserver.getCraftServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) { ++ itemstack.grow(1); ++ return itemstack; ++ } ++ ++ if (!event.getItem().equals(craftItem)) { ++ itemstack.grow(1); ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); ++ if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior != this) { ++ idispensebehavior.dispense(sourceblock, eventStack); ++ return itemstack; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ AbstractMinecart entityminecartabstract = AbstractMinecart.createMinecart(worldserver, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), ((MinecartItem) itemstack1.getItem()).type, itemstack1, (Player) null); ++ ++ if (!worldserver.addFreshEntity(entityminecartabstract)) itemstack.grow(1); ++ // itemstack.shrink(1); // CraftBukkit - handled during event processing ++ // CraftBukkit end ++ return itemstack; + } + + @Override +- protected void playSound(BlockSource blockSource) { +- blockSource.level().levelEvent(1000, blockSource.pos(), 0); ++ protected void playSound(SourceBlock sourceblock) { ++ sourceblock.level().levelEvent(1000, sourceblock.pos(), 0); + } + }; +- final AbstractMinecart.Type type; ++ final AbstractMinecart.EnumMinecartType type; + +- public MinecartItem(AbstractMinecart.Type type, Item.Properties properties) { ++ public MinecartItem(AbstractMinecart.EnumMinecartType type, Item.Properties properties) { + super(properties); + this.type = type; +- DispenserBlock.registerBehavior(this, DISPENSE_ITEM_BEHAVIOR); ++ DispenserBlock.registerBehavior(this, MinecartItem.DISPENSE_ITEM_BEHAVIOR); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (!blockState.is(BlockTags.RAILS)) { ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ ++ if (!iblockdata.is(BlockTags.RAILS)) { + return InteractionResult.FAIL; + } else { +- ItemStack itemInHand = context.getItemInHand(); +- if (level instanceof ServerLevel serverLevel) { +- RailShape railShape = blockState.getBlock() instanceof BaseRailBlock +- ? blockState.getValue(((BaseRailBlock)blockState.getBlock()).getShapeProperty()) +- : RailShape.NORTH_SOUTH; +- double d = 0.0; +- if (railShape.isAscending()) { +- d = 0.5; ++ ItemStack itemstack = context.getItemInHand(); ++ ++ if (world instanceof ServerLevel) { ++ ServerLevel worldserver = (ServerLevel) world; ++ RailShape blockpropertytrackposition = iblockdata.getBlock() instanceof BaseRailBlock ? (RailShape) iblockdata.getValue(((BaseRailBlock) iblockdata.getBlock()).getShapeProperty()) : RailShape.NORTH_SOUTH; ++ double d0 = 0.0D; ++ ++ if (blockpropertytrackposition.isAscending()) { ++ d0 = 0.5D; + } + +- AbstractMinecart abstractMinecart = AbstractMinecart.createMinecart( +- serverLevel, +- (double)clickedPos.getX() + 0.5, +- (double)clickedPos.getY() + 0.0625 + d, +- (double)clickedPos.getZ() + 0.5, +- this.type, +- itemInHand, +- context.getPlayer() +- ); +- serverLevel.addFreshEntity(abstractMinecart); +- serverLevel.gameEvent( +- GameEvent.ENTITY_PLACE, clickedPos, GameEvent.Context.of(context.getPlayer(), serverLevel.getBlockState(clickedPos.below())) +- ); ++ AbstractMinecart entityminecartabstract = AbstractMinecart.createMinecart(worldserver, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.0625D + d0, (double) blockposition.getZ() + 0.5D, this.type, itemstack, context.getPlayer()); ++ ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end ++ if (!worldserver.addFreshEntity(entityminecartabstract)) return InteractionResult.PASS; // CraftBukkit ++ worldserver.gameEvent(GameEvent.ENTITY_PLACE, blockposition, GameEvent.Context.of(context.getPlayer(), worldserver.getBlockState(blockposition.below()))); + } + +- itemInHand.shrink(1); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ itemstack.shrink(1); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/PotionItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/PotionItem.java.patch new file mode 100644 index 0000000000..a1fac302b7 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/PotionItem.java.patch @@ -0,0 +1,162 @@ +--- a/net/minecraft/world/item/PotionItem.java ++++ b/net/minecraft/world/item/PotionItem.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.item; + ++import java.util.Iterator; + import java.util.List; + import javax.annotation.Nullable; + import net.minecraft.advancements.CriteriaTriggers; +@@ -13,10 +14,11 @@ + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.tags.BlockTags; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.effect.MobEffectInstance; ++import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.LivingEntity; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.alchemy.PotionUtils; +@@ -24,10 +26,11 @@ + import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + + public class PotionItem extends Item { ++ + private static final int DRINK_DURATION = 32; + + public PotionItem(Item.Properties properties) { +@@ -41,35 +44,41 @@ + + @Override + public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity entityLiving) { +- Player player = entityLiving instanceof Player ? (Player)entityLiving : null; +- if (player instanceof ServerPlayer) { +- CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer)player, stack); ++ Player entityhuman = entityLiving instanceof Player ? (Player) entityLiving : null; ++ ++ if (entityhuman instanceof ServerPlayer) { ++ CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayer) entityhuman, stack); + } + + if (!level.isClientSide) { +- for (MobEffectInstance mobEffectInstance : PotionUtils.getMobEffects(stack)) { +- if (mobEffectInstance.getEffect().isInstantenous()) { +- mobEffectInstance.getEffect().applyInstantenousEffect(player, player, entityLiving, mobEffectInstance.getAmplifier(), 1.0); ++ List<MobEffectInstance> list = PotionUtils.getMobEffects(stack); ++ Iterator iterator = list.iterator(); ++ ++ while (iterator.hasNext()) { ++ MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); ++ ++ if (mobeffect.getEffect().isInstantenous()) { ++ mobeffect.getEffect().applyInstantenousEffect(entityhuman, entityhuman, entityLiving, mobeffect.getAmplifier(), 1.0D); + } else { +- entityLiving.addEffect(new MobEffectInstance(mobEffectInstance)); ++ entityLiving.addEffect(new MobEffectInstance(mobeffect), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_DRINK); // CraftBukkit + } + } + } + +- if (player != null) { +- player.awardStat(Stats.ITEM_USED.get(this)); +- if (!player.getAbilities().instabuild) { ++ if (entityhuman != null) { ++ entityhuman.awardStat(Stats.ITEM_USED.get(this)); ++ if (!entityhuman.getAbilities().instabuild) { + stack.shrink(1); + } + } + +- if (player == null || !player.getAbilities().instabuild) { ++ if (entityhuman == null || !entityhuman.getAbilities().instabuild) { + if (stack.isEmpty()) { + return new ItemStack(Items.GLASS_BOTTLE); + } + +- if (player != null) { +- player.getInventory().add(new ItemStack(Items.GLASS_BOTTLE)); ++ if (entityhuman != null) { ++ entityhuman.getInventory().add(new ItemStack(Items.GLASS_BOTTLE)); + } + } + +@@ -79,37 +88,28 @@ + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- Player player = context.getPlayer(); +- ItemStack itemInHand = context.getItemInHand(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (context.getClickedFace() != Direction.DOWN && blockState.is(BlockTags.CONVERTABLE_TO_MUD) && PotionUtils.getPotion(itemInHand) == Potions.WATER) { +- level.playSound(null, clickedPos, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); +- player.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemInHand, player, new ItemStack(Items.GLASS_BOTTLE))); +- player.awardStat(Stats.ITEM_USED.get(itemInHand.getItem())); +- if (!level.isClientSide) { +- ServerLevel serverLevel = (ServerLevel)level; ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ Player entityhuman = context.getPlayer(); ++ ItemStack itemstack = context.getItemInHand(); ++ IBlockData iblockdata = world.getBlockState(blockposition); + +- for (int i = 0; i < 5; i++) { +- serverLevel.sendParticles( +- ParticleTypes.SPLASH, +- (double)clickedPos.getX() + level.random.nextDouble(), +- (double)(clickedPos.getY() + 1), +- (double)clickedPos.getZ() + level.random.nextDouble(), +- 1, +- 0.0, +- 0.0, +- 0.0, +- 1.0 +- ); ++ if (context.getClickedFace() != Direction.DOWN && iblockdata.is(BlockTags.CONVERTABLE_TO_MUD) && PotionUtils.getPotion(itemstack) == Potions.WATER) { ++ world.playSound((Player) null, blockposition, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); ++ entityhuman.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemstack, entityhuman, new ItemStack(Items.GLASS_BOTTLE))); ++ entityhuman.awardStat(Stats.ITEM_USED.get(itemstack.getItem())); ++ if (!world.isClientSide) { ++ ServerLevel worldserver = (ServerLevel) world; ++ ++ for (int i = 0; i < 5; ++i) { ++ worldserver.sendParticles(ParticleTypes.SPLASH, (double) blockposition.getX() + world.random.nextDouble(), (double) (blockposition.getY() + 1), (double) blockposition.getZ() + world.random.nextDouble(), 1, 0.0D, 0.0D, 0.0D, 1.0D); + } + } + +- level.playSound(null, clickedPos, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); +- level.gameEvent(null, GameEvent.FLUID_PLACE, clickedPos); +- level.setBlockAndUpdate(clickedPos, Blocks.MUD.defaultBlockState()); +- return InteractionResult.sidedSuccess(level.isClientSide); ++ world.playSound((Player) null, blockposition, SoundEvents.BOTTLE_EMPTY, SoundSource.BLOCKS, 1.0F, 1.0F); ++ world.gameEvent((Entity) null, GameEvent.FLUID_PLACE, blockposition); ++ world.setBlockAndUpdate(blockposition, Blocks.MUD.defaultBlockState()); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.PASS; + } +@@ -121,12 +121,12 @@ + } + + @Override +- public UseAnim getUseAnimation(ItemStack stack) { +- return UseAnim.DRINK; ++ public EnumAnimation getUseAnimation(ItemStack stack) { ++ return EnumAnimation.DRINK; + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { + return ItemUtils.startUsingInstantly(level, player, hand); + } + diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/RecordItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/RecordItem.java.patch new file mode 100644 index 0000000000..c9f63ee89d --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/RecordItem.java.patch @@ -0,0 +1,79 @@ +--- a/net/minecraft/world/item/RecordItem.java ++++ b/net/minecraft/world/item/RecordItem.java +@@ -16,11 +16,13 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.JukeboxBlock; ++import net.minecraft.world.level.block.entity.BlockEntity; + import net.minecraft.world.level.block.entity.JukeboxBlockEntity; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + + public class RecordItem extends Item { ++ + private static final Map<SoundEvent, RecordItem> BY_NAME = Maps.newHashMap(); + private final int analogOutput; + private final SoundEvent sound; +@@ -31,30 +33,37 @@ + this.analogOutput = analogOutput; + this.sound = sound; + this.lengthInTicks = lengthInSeconds * 20; +- BY_NAME.put(this.sound, this); ++ RecordItem.BY_NAME.put(this.sound, this); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (blockState.is(Blocks.JUKEBOX) && !blockState.getValue(JukeboxBlock.HAS_RECORD)) { +- ItemStack itemInHand = context.getItemInHand(); +- if (!level.isClientSide) { +- Player player = context.getPlayer(); +- if (level.getBlockEntity(clickedPos) instanceof JukeboxBlockEntity jukeboxBlockEntity) { +- jukeboxBlockEntity.setTheItem(itemInHand.copy()); +- level.gameEvent(GameEvent.BLOCK_CHANGE, clickedPos, GameEvent.Context.of(player, blockState)); ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ ++ if (iblockdata.is(Blocks.JUKEBOX) && !(Boolean) iblockdata.getValue(JukeboxBlock.HAS_RECORD)) { ++ ItemStack itemstack = context.getItemInHand(); ++ ++ if (!world.isClientSide) { ++ if (true) return InteractionResult.SUCCESS; // CraftBukkit - handled in ItemStack ++ Player entityhuman = context.getPlayer(); ++ BlockEntity tileentity = world.getBlockEntity(blockposition); ++ ++ if (tileentity instanceof JukeboxBlockEntity) { ++ JukeboxBlockEntity tileentityjukebox = (JukeboxBlockEntity) tileentity; ++ ++ tileentityjukebox.setTheItem(itemstack.copy()); ++ world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entityhuman, iblockdata)); + } + +- itemInHand.shrink(1); +- if (player != null) { +- player.awardStat(Stats.PLAY_RECORD); ++ itemstack.shrink(1); ++ if (entityhuman != null) { ++ entityhuman.awardStat(Stats.PLAY_RECORD); + } + } + +- return InteractionResult.sidedSuccess(level.isClientSide); ++ return InteractionResult.sidedSuccess(world.isClientSide); + } else { + return InteractionResult.PASS; + } +@@ -75,7 +84,7 @@ + + @Nullable + public static RecordItem getBySound(SoundEvent sound) { +- return BY_NAME.get(sound); ++ return (RecordItem) RecordItem.BY_NAME.get(sound); + } + + public SoundEvent getSound() { diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/SignItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/SignItem.java.patch new file mode 100644 index 0000000000..ccb176dc5c --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/SignItem.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/world/item/SignItem.java ++++ b/net/minecraft/world/item/SignItem.java +@@ -7,10 +7,14 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Block; + import net.minecraft.world.level.block.SignBlock; ++import net.minecraft.world.level.block.entity.BlockEntity; + import net.minecraft.world.level.block.entity.SignBlockEntity; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + + public class SignItem extends StandingAndWallBlockItem { ++ ++ public static BlockPos openSign; // CraftBukkit ++ + public SignItem(Item.Properties properties, Block standingBlock, Block wallBlock) { + super(standingBlock, wallBlock, properties, Direction.DOWN); + } +@@ -20,14 +24,25 @@ + } + + @Override +- protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, @Nullable Player player, ItemStack stack, BlockState state) { ++ protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, @Nullable Player player, ItemStack stack, IBlockData state) { + boolean flag = super.updateCustomBlockEntityTag(pos, level, player, stack, state); +- if (!level.isClientSide +- && !flag +- && player != null +- && level.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity +- && level.getBlockState(pos).getBlock() instanceof SignBlock signBlock) { +- signBlock.openTextEdit(player, signBlockEntity, true); ++ ++ if (!level.isClientSide && !flag && player != null) { ++ BlockEntity tileentity = level.getBlockEntity(pos); ++ ++ if (tileentity instanceof SignBlockEntity) { ++ SignBlockEntity tileentitysign = (SignBlockEntity) tileentity; ++ Block block = level.getBlockState(pos).getBlock(); ++ ++ if (block instanceof SignBlock) { ++ SignBlock blocksign = (SignBlock) block; ++ ++ // CraftBukkit start - SPIGOT-4678 ++ // blocksign.openTextEdit(entityhuman, tileentitysign, true); ++ SignItem.openSign = pos; ++ // CraftBukkit end ++ } ++ } + } + + return flag; diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/SnowballItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/SnowballItem.java.patch new file mode 100644 index 0000000000..e7a11c6556 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/SnowballItem.java.patch @@ -0,0 +1,72 @@ +--- a/net/minecraft/world/item/SnowballItem.java ++++ b/net/minecraft/world/item/SnowballItem.java +@@ -3,42 +3,49 @@ + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.entity.projectile.Snowball; + import net.minecraft.world.level.Level; + + public class SnowballItem extends Item { ++ + public SnowballItem(Item.Properties properties) { + super(properties); + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.SNOWBALL_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ ++ // CraftBukkit - moved down ++ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); + if (!level.isClientSide) { +- Snowball snowball = new Snowball(level, player); +- snowball.setItem(itemInHand); +- snowball.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); +- level.addFreshEntity(snowball); ++ Snowball entitysnowball = new Snowball(level, player); ++ ++ entitysnowball.setItem(itemstack); ++ entitysnowball.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 1.5F, 1.0F); ++ if (level.addFreshEntity(entitysnowball)) { ++ if (!player.getAbilities().instabuild) { ++ itemstack.shrink(1); ++ } ++ ++ level.playSound((Player) null, player.getX(), player.getY(), player.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } + } ++ // CraftBukkit end + + player.awardStat(Stats.ITEM_USED.get(this)); +- if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ // CraftBukkit start - moved up ++ /* ++ if (!entityhuman.getAbilities().instabuild) { ++ itemstack.shrink(1); + } ++ */ + +- return InteractionResultHolder.sidedSuccess(itemInHand, level.isClientSide()); ++ return InteractionResultHolder.sidedSuccess(itemstack, level.isClientSide()); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/SpawnEggItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/SpawnEggItem.java.patch new file mode 100644 index 0000000000..e55ed2d4a1 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/SpawnEggItem.java.patch @@ -0,0 +1,241 @@ +--- a/net/minecraft/world/item/SpawnEggItem.java ++++ b/net/minecraft/world/item/SpawnEggItem.java +@@ -11,14 +11,14 @@ + import net.minecraft.nbt.CompoundTag; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.stats.Stats; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.InteractionResultHolder; + import net.minecraft.world.entity.AgeableMob; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntityType; ++import net.minecraft.world.entity.EnumMobSpawn; + import net.minecraft.world.entity.Mob; +-import net.minecraft.world.entity.MobSpawnType; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.flag.FeatureFlagSet; + import net.minecraft.world.item.context.UseOnContext; +@@ -26,13 +26,15 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.Spawner; + import net.minecraft.world.level.block.LiquidBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.level.gameevent.GameEvent; + import net.minecraft.world.phys.BlockHitResult; + import net.minecraft.world.phys.HitResult; + import net.minecraft.world.phys.Vec3; + + public class SpawnEggItem extends Item { ++ + private static final Map<EntityType<? extends Mob>, SpawnEggItem> BY_ID = Maps.newIdentityHashMap(); + private final int backgroundColor; + private final int highlightColor; +@@ -43,47 +45,45 @@ + this.defaultType = defaultType; + this.backgroundColor = backgroundColor; + this.highlightColor = highlightColor; +- BY_ID.put(defaultType, this); ++ SpawnEggItem.BY_ID.put(defaultType, this); + } + + @Override + public InteractionResult useOn(UseOnContext context) { +- Level level = context.getLevel(); +- if (!(level instanceof ServerLevel)) { ++ Level world = context.getLevel(); ++ ++ if (!(world instanceof ServerLevel)) { + return InteractionResult.SUCCESS; + } else { +- ItemStack itemInHand = context.getItemInHand(); +- BlockPos clickedPos = context.getClickedPos(); +- Direction clickedFace = context.getClickedFace(); +- BlockState blockState = level.getBlockState(clickedPos); +- if (level.getBlockEntity(clickedPos) instanceof Spawner spawner) { +- EntityType<?> type = this.getType(itemInHand.getTag()); +- spawner.setEntityId(type, level.getRandom()); +- level.sendBlockUpdated(clickedPos, blockState, blockState, 3); +- level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos); +- itemInHand.shrink(1); ++ ItemStack itemstack = context.getItemInHand(); ++ BlockPos blockposition = context.getClickedPos(); ++ Direction enumdirection = context.getClickedFace(); ++ IBlockData iblockdata = world.getBlockState(blockposition); ++ BlockEntity tileentity = world.getBlockEntity(blockposition); ++ EntityType entitytypes; ++ ++ if (tileentity instanceof Spawner) { ++ Spawner spawner = (Spawner) tileentity; ++ ++ entitytypes = this.getType(itemstack.getTag()); ++ spawner.setEntityId(entitytypes, world.getRandom()); ++ world.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3); ++ world.gameEvent((Entity) context.getPlayer(), GameEvent.BLOCK_CHANGE, blockposition); ++ itemstack.shrink(1); + return InteractionResult.CONSUME; + } else { +- BlockPos blockPos; +- if (blockState.getCollisionShape(level, clickedPos).isEmpty()) { +- blockPos = clickedPos; ++ BlockPos blockposition1; ++ ++ if (iblockdata.getCollisionShape(world, blockposition).isEmpty()) { ++ blockposition1 = blockposition; + } else { +- blockPos = clickedPos.relative(clickedFace); ++ blockposition1 = blockposition.relative(enumdirection); + } + +- EntityType<?> type = this.getType(itemInHand.getTag()); +- if (type.spawn( +- (ServerLevel)level, +- itemInHand, +- context.getPlayer(), +- blockPos, +- MobSpawnType.SPAWN_EGG, +- true, +- !Objects.equals(clickedPos, blockPos) && clickedFace == Direction.UP +- ) +- != null) { +- itemInHand.shrink(1); +- level.gameEvent(context.getPlayer(), GameEvent.ENTITY_PLACE, clickedPos); ++ entitytypes = this.getType(itemstack.getTag()); ++ if (entitytypes.spawn((ServerLevel) world, itemstack, context.getPlayer(), blockposition1, EnumMobSpawn.SPAWN_EGG, true, !Objects.equals(blockposition, blockposition1) && enumdirection == Direction.UP) != null) { ++ itemstack.shrink(1); ++ world.gameEvent((Entity) context.getPlayer(), GameEvent.ENTITY_PLACE, blockposition); + } + + return InteractionResult.CONSUME; +@@ -92,33 +92,36 @@ + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- BlockHitResult playerPOVHitResult = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY); +- if (playerPOVHitResult.getType() != HitResult.Type.BLOCK) { +- return InteractionResultHolder.pass(itemInHand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ BlockHitResult movingobjectpositionblock = getPlayerPOVHitResult(level, player, ClipContext.Fluid.SOURCE_ONLY); ++ ++ if (movingobjectpositionblock.getType() != HitResult.EnumMovingObjectType.BLOCK) { ++ return InteractionResultHolder.pass(itemstack); + } else if (!(level instanceof ServerLevel)) { +- return InteractionResultHolder.success(itemInHand); ++ return InteractionResultHolder.success(itemstack); + } else { +- BlockPos blockPos = playerPOVHitResult.getBlockPos(); +- if (!(level.getBlockState(blockPos).getBlock() instanceof LiquidBlock)) { +- return InteractionResultHolder.pass(itemInHand); +- } else if (level.mayInteract(player, blockPos) && player.mayUseItemAt(blockPos, playerPOVHitResult.getDirection(), itemInHand)) { +- EntityType<?> type = this.getType(itemInHand.getTag()); +- Entity entity = type.spawn((ServerLevel)level, itemInHand, player, blockPos, MobSpawnType.SPAWN_EGG, false, false); ++ BlockPos blockposition = movingobjectpositionblock.getBlockPos(); ++ ++ if (!(level.getBlockState(blockposition).getBlock() instanceof LiquidBlock)) { ++ return InteractionResultHolder.pass(itemstack); ++ } else if (level.mayInteract(player, blockposition) && player.mayUseItemAt(blockposition, movingobjectpositionblock.getDirection(), itemstack)) { ++ EntityType<?> entitytypes = this.getType(itemstack.getTag()); ++ Entity entity = entitytypes.spawn((ServerLevel) level, itemstack, player, blockposition, EnumMobSpawn.SPAWN_EGG, false, false); ++ + if (entity == null) { +- return InteractionResultHolder.pass(itemInHand); ++ return InteractionResultHolder.pass(itemstack); + } else { + if (!player.getAbilities().instabuild) { +- itemInHand.shrink(1); ++ itemstack.shrink(1); + } + + player.awardStat(Stats.ITEM_USED.get(this)); +- level.gameEvent(player, GameEvent.ENTITY_PLACE, entity.position()); +- return InteractionResultHolder.consume(itemInHand); ++ level.gameEvent((Entity) player, GameEvent.ENTITY_PLACE, entity.position()); ++ return InteractionResultHolder.consume(itemstack); + } + } else { +- return InteractionResultHolder.fail(itemInHand); ++ return InteractionResultHolder.fail(itemstack); + } + } + } +@@ -133,18 +136,19 @@ + + @Nullable + public static SpawnEggItem byId(@Nullable EntityType<?> type) { +- return BY_ID.get(type); ++ return (SpawnEggItem) SpawnEggItem.BY_ID.get(type); + } + + public static Iterable<SpawnEggItem> eggs() { +- return Iterables.unmodifiableIterable(BY_ID.values()); ++ return Iterables.unmodifiableIterable(SpawnEggItem.BY_ID.values()); + } + + public EntityType<?> getType(@Nullable CompoundTag nbt) { + if (nbt != null && nbt.contains("EntityTag", 10)) { +- CompoundTag compound = nbt.getCompound("EntityTag"); +- if (compound.contains("id", 8)) { +- return EntityType.byString(compound.getString("id")).orElse(this.defaultType); ++ CompoundTag nbttagcompound1 = nbt.getCompound("EntityTag"); ++ ++ if (nbttagcompound1.contains("id", 8)) { ++ return (EntityType) EntityType.byString(nbttagcompound1.getString("id")).orElse(this.defaultType); + } + } + +@@ -156,37 +160,36 @@ + return this.defaultType.requiredFeatures(); + } + +- public Optional<Mob> spawnOffspringFromSpawnEgg( +- Player player, Mob mob, EntityType<? extends Mob> entityType, ServerLevel serverLevel, Vec3 pos, ItemStack stack +- ) { ++ public Optional<Mob> spawnOffspringFromSpawnEgg(Player player, Mob mob, EntityType<? extends Mob> entityType, ServerLevel serverLevel, Vec3 pos, ItemStack stack) { + if (!this.spawnsEntity(stack.getTag(), entityType)) { + return Optional.empty(); + } else { +- Mob breedOffspring; ++ Object object; ++ + if (mob instanceof AgeableMob) { +- breedOffspring = ((AgeableMob)mob).getBreedOffspring(serverLevel, (AgeableMob)mob); ++ object = ((AgeableMob) mob).getBreedOffspring(serverLevel, (AgeableMob) mob); + } else { +- breedOffspring = entityType.create(serverLevel); ++ object = (Mob) entityType.create(serverLevel); + } + +- if (breedOffspring == null) { ++ if (object == null) { + return Optional.empty(); + } else { +- breedOffspring.setBaby(true); +- if (!breedOffspring.isBaby()) { ++ ((Mob) object).setBaby(true); ++ if (!((Mob) object).isBaby()) { + return Optional.empty(); + } else { +- breedOffspring.moveTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F); +- serverLevel.addFreshEntityWithPassengers(breedOffspring); ++ ((Mob) object).moveTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F); ++ serverLevel.addFreshEntityWithPassengers((Entity) object, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + if (stack.hasCustomHoverName()) { +- breedOffspring.setCustomName(stack.getHoverName()); ++ ((Mob) object).setCustomName(stack.getHoverName()); + } + + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } + +- return Optional.of(breedOffspring); ++ return Optional.of((Mob) object); // CraftBukkit - decompile error + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/StandingAndWallBlockItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/StandingAndWallBlockItem.java.patch new file mode 100644 index 0000000000..2b71c68f68 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/StandingAndWallBlockItem.java.patch @@ -0,0 +1,85 @@ +--- a/net/minecraft/world/item/StandingAndWallBlockItem.java ++++ b/net/minecraft/world/item/StandingAndWallBlockItem.java +@@ -4,14 +4,21 @@ + import javax.annotation.Nullable; + import net.minecraft.core.BlockPos; + import net.minecraft.core.Direction; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.world.item.context.BlockPlaceContext; ++import net.minecraft.world.level.Level; + import net.minecraft.world.level.LevelReader; + import net.minecraft.world.level.block.Block; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.phys.shapes.CollisionContext; ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.craftbukkit.block.data.CraftBlockData; ++import org.bukkit.event.block.BlockCanBuildEvent; ++// CraftBukkit end + + public class StandingAndWallBlockItem extends BlockItem { +- protected final Block wallBlock; ++ ++ public final Block wallBlock; + private final Direction attachmentDirection; + + public StandingAndWallBlockItem(Block block, Block wallBlock, Item.Properties properties, Direction attachmentDirection) { +@@ -20,29 +27,46 @@ + this.attachmentDirection = attachmentDirection; + } + +- protected boolean canPlace(LevelReader level, BlockState state, BlockPos pos) { ++ protected boolean canPlace(LevelReader level, IBlockData state, BlockPos pos) { + return state.canSurvive(level, pos); + } + + @Nullable + @Override +- protected BlockState getPlacementState(BlockPlaceContext context) { +- BlockState stateForPlacement = this.wallBlock.getStateForPlacement(context); +- BlockState blockState = null; +- LevelReader level = context.getLevel(); +- BlockPos clickedPos = context.getClickedPos(); ++ protected IBlockData getPlacementState(BlockPlaceContext context) { ++ IBlockData iblockdata = this.wallBlock.getStateForPlacement(context); ++ IBlockData iblockdata1 = null; ++ Level world = context.getLevel(); ++ BlockPos blockposition = context.getClickedPos(); ++ Direction[] aenumdirection = context.getNearestLookingDirections(); ++ int i = aenumdirection.length; + +- for (Direction direction : context.getNearestLookingDirections()) { +- if (direction != this.attachmentDirection.getOpposite()) { +- BlockState blockState1 = direction == this.attachmentDirection ? this.getBlock().getStateForPlacement(context) : stateForPlacement; +- if (blockState1 != null && this.canPlace(level, blockState1, clickedPos)) { +- blockState = blockState1; ++ for (int j = 0; j < i; ++j) { ++ Direction enumdirection = aenumdirection[j]; ++ ++ if (enumdirection != this.attachmentDirection.getOpposite()) { ++ IBlockData iblockdata2 = enumdirection == this.attachmentDirection ? this.getBlock().getStateForPlacement(context) : iblockdata; ++ ++ if (iblockdata2 != null && this.canPlace(world, iblockdata2, blockposition)) { ++ iblockdata1 = iblockdata2; + break; + } + } + } + +- return blockState != null && level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()) ? blockState : null; ++ // CraftBukkit start ++ if (iblockdata1 != null) { ++ boolean defaultReturn = world.isUnobstructed(iblockdata1, blockposition, CollisionContext.empty()); ++ org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; ++ ++ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn); ++ context.getLevel().getCraftServer().getPluginManager().callEvent(event); ++ ++ return (event.isBuildable()) ? iblockdata1 : null; ++ } else { ++ return null; ++ } ++ // CraftBukkit end + } + + @Override diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/TridentItem.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/TridentItem.java.patch new file mode 100644 index 0000000000..36f0180224 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/TridentItem.java.patch @@ -0,0 +1,244 @@ +--- a/net/minecraft/world/item/TridentItem.java ++++ b/net/minecraft/world/item/TridentItem.java +@@ -1,19 +1,20 @@ + package net.minecraft.world.item; + + import com.google.common.collect.ImmutableMultimap; +-import com.google.common.collect.Multimap; + import com.google.common.collect.ImmutableMultimap.Builder; ++import com.google.common.collect.Multimap; + import net.minecraft.core.BlockPos; + import net.minecraft.sounds.SoundEvent; + import net.minecraft.sounds.SoundEvents; + import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.util.Mth; +-import net.minecraft.world.InteractionHand; ++import net.minecraft.world.EnumHand; + import net.minecraft.world.InteractionResultHolder; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EnumMoveType; + import net.minecraft.world.entity.EquipmentSlot; + import net.minecraft.world.entity.LivingEntity; +-import net.minecraft.world.entity.MoverType; + import net.minecraft.world.entity.ai.attributes.Attribute; + import net.minecraft.world.entity.ai.attributes.AttributeModifier; + import net.minecraft.world.entity.ai.attributes.Attributes; +@@ -22,10 +23,11 @@ + import net.minecraft.world.entity.projectile.ThrownTrident; + import net.minecraft.world.item.enchantment.EnchantmentHelper; + import net.minecraft.world.level.Level; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.phys.Vec3; + +-public class TridentItem extends Item implements Vanishable { ++public class TridentItem extends Item implements ItemVanishable { ++ + public static final int THROW_THRESHOLD_TIME = 10; + public static final float BASE_DAMAGE = 8.0F; + public static final float SHOOT_POWER = 2.5F; +@@ -34,19 +36,20 @@ + public TridentItem(Item.Properties properties) { + super(properties); + Builder<Attribute, AttributeModifier> builder = ImmutableMultimap.builder(); +- builder.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(BASE_ATTACK_DAMAGE_UUID, "Tool modifier", 8.0, AttributeModifier.Operation.ADDITION)); +- builder.put(Attributes.ATTACK_SPEED, new AttributeModifier(BASE_ATTACK_SPEED_UUID, "Tool modifier", -2.9F, AttributeModifier.Operation.ADDITION)); ++ ++ builder.put(Attributes.ATTACK_DAMAGE, new AttributeModifier(TridentItem.BASE_ATTACK_DAMAGE_UUID, "Tool modifier", 8.0D, AttributeModifier.Operation.ADDITION)); ++ builder.put(Attributes.ATTACK_SPEED, new AttributeModifier(TridentItem.BASE_ATTACK_SPEED_UUID, "Tool modifier", -2.9000000953674316D, AttributeModifier.Operation.ADDITION)); + this.defaultModifiers = builder.build(); + } + + @Override +- public boolean canAttackBlock(BlockState state, Level level, BlockPos pos, Player player) { ++ public boolean canAttackBlock(IBlockData state, Level level, BlockPos pos, Player player) { + return !player.isCreative(); + } + + @Override +- public UseAnim getUseAnimation(ItemStack stack) { +- return UseAnim.SPEAR; ++ public EnumAnimation getUseAnimation(ItemStack stack) { ++ return EnumAnimation.SPEAR; + } + + @Override +@@ -56,86 +59,127 @@ + + @Override + public void releaseUsing(ItemStack stack, Level level, LivingEntity entityLiving, int timeLeft) { +- if (entityLiving instanceof Player player) { +- int i = this.getUseDuration(stack) - timeLeft; +- if (i >= 10) { +- int riptide = EnchantmentHelper.getRiptide(stack); +- if (riptide <= 0 || player.isInWaterOrRain()) { ++ if (entityLiving instanceof Player) { ++ Player entityhuman = (Player) entityLiving; ++ int j = this.getUseDuration(stack) - timeLeft; ++ ++ if (j >= 10) { ++ int k = EnchantmentHelper.getRiptide(stack); ++ ++ if (k <= 0 || entityhuman.isInWaterOrRain()) { + if (!level.isClientSide) { +- stack.hurtAndBreak(1, player, contextEntity -> contextEntity.broadcastBreakEvent(entityLiving.getUsedItemHand())); +- if (riptide == 0) { +- ThrownTrident thrownTrident = new ThrownTrident(level, player, stack); +- thrownTrident.shootFromRotation(player, player.getXRot(), player.getYRot(), 0.0F, 2.5F + (float)riptide * 0.5F, 1.0F); +- if (player.getAbilities().instabuild) { +- thrownTrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; ++ // CraftBukkit - moved down ++ /* ++ itemstack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(entityliving.getUsedItemHand()); ++ }); ++ */ ++ if (k == 0) { ++ ThrownTrident entitythrowntrident = new ThrownTrident(level, entityhuman, stack); ++ ++ entitythrowntrident.shootFromRotation(entityhuman, entityhuman.getXRot(), entityhuman.getYRot(), 0.0F, 2.5F + (float) k * 0.5F, 1.0F); ++ if (entityhuman.getAbilities().instabuild) { ++ entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; + } + +- level.addFreshEntity(thrownTrident); +- level.playSound(null, thrownTrident, SoundEvents.TRIDENT_THROW, SoundSource.PLAYERS, 1.0F, 1.0F); +- if (!player.getAbilities().instabuild) { +- player.getInventory().removeItem(stack); ++ // CraftBukkit start ++ if (!level.addFreshEntity(entitythrowntrident)) { ++ if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); ++ } ++ return; + } ++ ++ stack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(entityLiving.getUsedItemHand()); ++ }); ++ entitythrowntrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved ++ // CraftBukkit end ++ ++ level.playSound((Player) null, (Entity) entitythrowntrident, SoundEvents.TRIDENT_THROW, SoundSource.PLAYERS, 1.0F, 1.0F); ++ if (!entityhuman.getAbilities().instabuild) { ++ entityhuman.getInventory().removeItem(stack); ++ } ++ // CraftBukkit start - SPIGOT-5458 also need in this branch :( ++ } else { ++ stack.hurtAndBreak(1, entityhuman, (entityhuman1) -> { ++ entityhuman1.broadcastBreakEvent(entityLiving.getUsedItemHand()); ++ }); ++ // CraftBukkkit end + } + } + +- player.awardStat(Stats.ITEM_USED.get(this)); +- if (riptide > 0) { +- float yRot = player.getYRot(); +- float xRot = player.getXRot(); +- float f = -Mth.sin(yRot * (float) (Math.PI / 180.0)) * Mth.cos(xRot * (float) (Math.PI / 180.0)); +- float f1 = -Mth.sin(xRot * (float) (Math.PI / 180.0)); +- float f2 = Mth.cos(yRot * (float) (Math.PI / 180.0)) * Mth.cos(xRot * (float) (Math.PI / 180.0)); +- float squareRoot = Mth.sqrt(f * f + f1 * f1 + f2 * f2); +- float f3 = 3.0F * ((1.0F + (float)riptide) / 4.0F); +- f *= f3 / squareRoot; +- f1 *= f3 / squareRoot; +- f2 *= f3 / squareRoot; +- player.push((double)f, (double)f1, (double)f2); +- player.startAutoSpinAttack(20); +- if (player.onGround()) { +- float f4 = 1.1999999F; +- player.move(MoverType.SELF, new Vec3(0.0, 1.1999999F, 0.0)); ++ entityhuman.awardStat(Stats.ITEM_USED.get(this)); ++ if (k > 0) { ++ // CraftBukkit start ++ org.bukkit.event.player.PlayerRiptideEvent event = new org.bukkit.event.player.PlayerRiptideEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); ++ event.getPlayer().getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end ++ float f = entityhuman.getYRot(); ++ float f1 = entityhuman.getXRot(); ++ float f2 = -Mth.sin(f * 0.017453292F) * Mth.cos(f1 * 0.017453292F); ++ float f3 = -Mth.sin(f1 * 0.017453292F); ++ float f4 = Mth.cos(f * 0.017453292F) * Mth.cos(f1 * 0.017453292F); ++ float f5 = Mth.sqrt(f2 * f2 + f3 * f3 + f4 * f4); ++ float f6 = 3.0F * ((1.0F + (float) k) / 4.0F); ++ ++ f2 *= f6 / f5; ++ f3 *= f6 / f5; ++ f4 *= f6 / f5; ++ entityhuman.push((double) f2, (double) f3, (double) f4); ++ entityhuman.startAutoSpinAttack(20); ++ if (entityhuman.onGround()) { ++ float f7 = 1.1999999F; ++ ++ entityhuman.move(EnumMoveType.SELF, new Vec3(0.0D, 1.1999999284744263D, 0.0D)); + } + +- SoundEvent soundEvent; +- if (riptide >= 3) { +- soundEvent = SoundEvents.TRIDENT_RIPTIDE_3; +- } else if (riptide == 2) { +- soundEvent = SoundEvents.TRIDENT_RIPTIDE_2; ++ SoundEvent soundeffect; ++ ++ if (k >= 3) { ++ soundeffect = SoundEvents.TRIDENT_RIPTIDE_3; ++ } else if (k == 2) { ++ soundeffect = SoundEvents.TRIDENT_RIPTIDE_2; + } else { +- soundEvent = SoundEvents.TRIDENT_RIPTIDE_1; ++ soundeffect = SoundEvents.TRIDENT_RIPTIDE_1; + } + +- level.playSound(null, player, soundEvent, SoundSource.PLAYERS, 1.0F, 1.0F); ++ level.playSound((Player) null, (Entity) entityhuman, soundeffect, SoundSource.PLAYERS, 1.0F, 1.0F); + } ++ + } + } + } + } + + @Override +- public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) { +- ItemStack itemInHand = player.getItemInHand(hand); +- if (itemInHand.getDamageValue() >= itemInHand.getMaxDamage() - 1) { +- return InteractionResultHolder.fail(itemInHand); +- } else if (EnchantmentHelper.getRiptide(itemInHand) > 0 && !player.isInWaterOrRain()) { +- return InteractionResultHolder.fail(itemInHand); ++ public InteractionResultHolder<ItemStack> use(Level level, Player player, EnumHand hand) { ++ ItemStack itemstack = player.getItemInHand(hand); ++ ++ if (itemstack.getDamageValue() >= itemstack.getMaxDamage() - 1) { ++ return InteractionResultHolder.fail(itemstack); ++ } else if (EnchantmentHelper.getRiptide(itemstack) > 0 && !player.isInWaterOrRain()) { ++ return InteractionResultHolder.fail(itemstack); + } else { + player.startUsingItem(hand); +- return InteractionResultHolder.consume(itemInHand); ++ return InteractionResultHolder.consume(itemstack); + } + } + + @Override + public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) { +- stack.hurtAndBreak(1, attacker, contextEntity -> contextEntity.broadcastBreakEvent(EquipmentSlot.MAINHAND)); ++ stack.hurtAndBreak(1, attacker, (entityliving2) -> { ++ entityliving2.broadcastBreakEvent(EquipmentSlot.MAINHAND); ++ }); + return true; + } + + @Override +- public boolean mineBlock(ItemStack stack, Level level, BlockState state, BlockPos pos, LivingEntity entityLiving) { +- if ((double)state.getDestroySpeed(level, pos) != 0.0) { +- stack.hurtAndBreak(2, entityLiving, contextEntity -> contextEntity.broadcastBreakEvent(EquipmentSlot.MAINHAND)); ++ public boolean mineBlock(ItemStack stack, Level level, IBlockData state, BlockPos pos, LivingEntity entityLiving) { ++ if ((double) state.getDestroySpeed(level, pos) != 0.0D) { ++ stack.hurtAndBreak(2, entityLiving, (entityliving1) -> { ++ entityliving1.broadcastBreakEvent(EquipmentSlot.MAINHAND); ++ }); + } + + return true; diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/BlastingRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/BlastingRecipe.java.patch new file mode 100644 index 0000000000..b1903d9db4 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/BlastingRecipe.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/item/crafting/BlastingRecipe.java ++++ b/net/minecraft/world/item/crafting/BlastingRecipe.java +@@ -3,9 +3,18 @@ + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.block.Blocks; + ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftBlastingRecipe; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ + public class BlastingRecipe extends AbstractCookingRecipe { +- public BlastingRecipe(String string, CookingBookCategory cookingBookCategory, Ingredient ingredient, ItemStack itemStack, float f, int i) { +- super(RecipeType.BLASTING, string, cookingBookCategory, ingredient, itemStack, f, i); ++ ++ public BlastingRecipe(String s, CookingBookCategory cookingbookcategory, Ingredient recipeitemstack, ItemStack itemstack, float f, int i) { ++ super(RecipeType.BLASTING, s, cookingbookcategory, recipeitemstack, itemstack, f, i); + } + + @Override +@@ -17,4 +26,17 @@ + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.BLASTING_RECIPE; + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ ++ CraftBlastingRecipe recipe = new CraftBlastingRecipe(id, result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ return recipe; ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CampfireCookingRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CampfireCookingRecipe.java.patch new file mode 100644 index 0000000000..c92ff1542f --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CampfireCookingRecipe.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/item/crafting/CampfireCookingRecipe.java ++++ b/net/minecraft/world/item/crafting/CampfireCookingRecipe.java +@@ -3,9 +3,18 @@ + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.block.Blocks; + ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftCampfireRecipe; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ + public class CampfireCookingRecipe extends AbstractCookingRecipe { +- public CampfireCookingRecipe(String string, CookingBookCategory cookingBookCategory, Ingredient ingredient, ItemStack itemStack, float f, int i) { +- super(RecipeType.CAMPFIRE_COOKING, string, cookingBookCategory, ingredient, itemStack, f, i); ++ ++ public CampfireCookingRecipe(String s, CookingBookCategory cookingbookcategory, Ingredient recipeitemstack, ItemStack itemstack, float f, int i) { ++ super(RecipeType.CAMPFIRE_COOKING, s, cookingbookcategory, recipeitemstack, itemstack, f, i); + } + + @Override +@@ -17,4 +26,17 @@ + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.CAMPFIRE_COOKING_RECIPE; + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ ++ CraftCampfireRecipe recipe = new CraftCampfireRecipe(id, result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ return recipe; ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CustomRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CustomRecipe.java.patch new file mode 100644 index 0000000000..16057f8555 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/CustomRecipe.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/world/item/crafting/CustomRecipe.java ++++ b/net/minecraft/world/item/crafting/CustomRecipe.java +@@ -3,11 +3,17 @@ + import net.minecraft.core.RegistryAccess; + import net.minecraft.world.item.ItemStack; + +-public abstract class CustomRecipe implements CraftingRecipe { ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ ++public abstract class CustomRecipe implements RecipeCrafting { ++ + private final CraftingBookCategory category; + +- public CustomRecipe(CraftingBookCategory craftingBookCategory) { +- this.category = craftingBookCategory; ++ public CustomRecipe(CraftingBookCategory craftingbookcategory) { ++ this.category = craftingbookcategory; + } + + @Override +@@ -24,4 +30,11 @@ + public CraftingBookCategory category() { + return this.category; + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ return new org.bukkit.craftbukkit.inventory.CraftComplexRecipe(id, this); ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Ingredient.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Ingredient.java.patch new file mode 100644 index 0000000000..a4e23f27af --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Ingredient.java.patch @@ -0,0 +1,323 @@ +--- a/net/minecraft/world/item/crafting/Ingredient.java ++++ b/net/minecraft/world/item/crafting/Ingredient.java +@@ -5,13 +5,13 @@ + import com.mojang.serialization.Codec; + import com.mojang.serialization.DataResult; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; + import it.unimi.dsi.fastutil.ints.IntArrayList; + import it.unimi.dsi.fastutil.ints.IntComparators; + import it.unimi.dsi.fastutil.ints.IntList; + import java.util.Arrays; + import java.util.Collection; + import java.util.Collections; ++import java.util.Iterator; + import java.util.List; + import java.util.function.Predicate; + import java.util.stream.Stream; +@@ -25,43 +25,64 @@ + import net.minecraft.world.entity.player.StackedContents; + import net.minecraft.world.item.Item; + import net.minecraft.world.item.ItemStack; +-import net.minecraft.world.level.ItemLike; ++import net.minecraft.world.level.IMaterial; + + public final class Ingredient implements Predicate<ItemStack> { ++ + public static final Ingredient EMPTY = new Ingredient(Stream.empty()); +- private final Ingredient.Value[] values; ++ private final Ingredient.Provider[] values; + @Nullable +- private ItemStack[] itemStacks; ++ public ItemStack[] itemStacks; + @Nullable + private IntList stackingIds; ++ public boolean exact; // CraftBukkit + public static final Codec<Ingredient> CODEC = codec(true); + public static final Codec<Ingredient> CODEC_NONEMPTY = codec(false); + +- private Ingredient(Stream<? extends Ingredient.Value> values) { +- this.values = values.toArray(Ingredient.Value[]::new); ++ public Ingredient(Stream<? extends Ingredient.Provider> values) { ++ this.values = (Ingredient.Provider[]) values.toArray((i) -> { ++ return new Ingredient.Provider[i]; ++ }); + } + +- private Ingredient(Ingredient.Value[] values) { +- this.values = values; ++ private Ingredient(Ingredient.Provider[] arecipeitemstack_provider) { ++ this.values = arecipeitemstack_provider; + } + + public ItemStack[] getItems() { + if (this.itemStacks == null) { +- this.itemStacks = Arrays.stream(this.values).flatMap(value -> value.getItems().stream()).distinct().toArray(ItemStack[]::new); ++ this.itemStacks = (ItemStack[]) Arrays.stream(this.values).flatMap((recipeitemstack_provider) -> { ++ return recipeitemstack_provider.getItems().stream(); ++ }).distinct().toArray((i) -> { ++ return new ItemStack[i]; ++ }); + } + + return this.itemStacks; + } + +- @Override + public boolean test(@Nullable ItemStack stack) { + if (stack == null) { + return false; + } else if (this.isEmpty()) { + return stack.isEmpty(); + } else { +- for (ItemStack itemStack : this.getItems()) { +- if (itemStack.is(stack.getItem())) { ++ ItemStack[] aitemstack = this.getItems(); ++ int i = aitemstack.length; ++ ++ for (int j = 0; j < i; ++j) { ++ ItemStack itemstack1 = aitemstack[j]; ++ ++ // CraftBukkit start ++ if (exact) { ++ if (itemstack1.getItem() == stack.getItem() && ItemStack.isSameItemSameTags(stack, itemstack1)) { ++ return true; ++ } ++ ++ continue; ++ } ++ // CraftBukkit end ++ if (itemstack1.is(stack.getItem())) { + return true; + } + } +@@ -72,11 +93,16 @@ + + public IntList getStackingIds() { + if (this.stackingIds == null) { +- ItemStack[] items = this.getItems(); +- this.stackingIds = new IntArrayList(items.length); ++ ItemStack[] aitemstack = this.getItems(); + +- for (ItemStack itemStack : items) { +- this.stackingIds.add(StackedContents.getStackingIndex(itemStack)); ++ this.stackingIds = new IntArrayList(aitemstack.length); ++ ItemStack[] aitemstack1 = aitemstack; ++ int i = aitemstack.length; ++ ++ for (int j = 0; j < i; ++j) { ++ ItemStack itemstack = aitemstack1[j]; ++ ++ this.stackingIds.add(StackedContents.getStackingIndex(itemstack)); + } + + this.stackingIds.sort(IntComparators.NATURAL_COMPARATOR); +@@ -93,21 +119,27 @@ + return this.values.length == 0; + } + +- @Override + public boolean equals(Object object) { +- return object instanceof Ingredient ingredient && Arrays.equals((Object[])this.values, (Object[])ingredient.values); ++ if (object instanceof Ingredient) { ++ Ingredient recipeitemstack = (Ingredient) object; ++ ++ return Arrays.equals(this.values, recipeitemstack.values); ++ } else { ++ return false; ++ } + } + +- private static Ingredient fromValues(Stream<? extends Ingredient.Value> stream) { +- Ingredient ingredient = new Ingredient(stream); +- return ingredient.isEmpty() ? EMPTY : ingredient; ++ private static Ingredient fromValues(Stream<? extends Ingredient.Provider> stream) { ++ Ingredient recipeitemstack = new Ingredient(stream); ++ ++ return recipeitemstack.isEmpty() ? Ingredient.EMPTY : recipeitemstack; + } + + public static Ingredient of() { +- return EMPTY; ++ return Ingredient.EMPTY; + } + +- public static Ingredient of(ItemLike... items) { ++ public static Ingredient of(IMaterial... items) { + return of(Arrays.stream(items).map(ItemStack::new)); + } + +@@ -116,7 +148,9 @@ + } + + public static Ingredient of(Stream<ItemStack> stacks) { +- return fromValues(stacks.filter(stack -> !stack.isEmpty()).map(Ingredient.ItemValue::new)); ++ return fromValues(stacks.filter((itemstack) -> { ++ return !itemstack.isEmpty(); ++ }).map(Ingredient.ItemValue::new)); + } + + public static Ingredient of(TagKey<Item> tag) { +@@ -124,67 +158,78 @@ + } + + public static Ingredient fromNetwork(FriendlyByteBuf buffer) { +- return fromValues(buffer.<ItemStack>readList(FriendlyByteBuf::readItem).stream().map(Ingredient.ItemValue::new)); ++ return fromValues(buffer.readList(FriendlyByteBuf::readItem).stream().map(Ingredient.ItemValue::new)); + } + + private static Codec<Ingredient> codec(boolean flag) { +- Codec<Ingredient.Value[]> codec = Codec.list(Ingredient.Value.CODEC) +- .comapFlatMap( +- list -> !flag && list.size() < 1 +- ? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined") +- : DataResult.success(list.toArray(new Ingredient.Value[0])), +- List::of +- ); +- return ExtraCodecs.either(codec, Ingredient.Value.CODEC) +- .flatComapMap( +- either -> either.map(Ingredient::new, value -> new Ingredient(new Ingredient.Value[]{value})), +- ingredient -> { +- if (ingredient.values.length == 1) { +- return DataResult.success(Either.right(ingredient.values[0])); +- } else { +- return ingredient.values.length == 0 && !flag +- ? DataResult.error(() -> "Item array cannot be empty, at least one item must be defined") +- : DataResult.success(Either.left(ingredient.values)); +- } +- } +- ); ++ Codec<Ingredient.Provider[]> codec = Codec.list(Ingredient.Provider.CODEC).comapFlatMap((list) -> { ++ return !flag && list.size() < 1 ? DataResult.error(() -> { ++ return "Item array cannot be empty, at least one item must be defined"; ++ }) : DataResult.success((Ingredient.Provider[]) list.toArray(new Ingredient.Provider[0])); ++ }, List::of); ++ ++ return ExtraCodecs.either(codec, Ingredient.Provider.CODEC).flatComapMap((either) -> { ++ return (Ingredient) either.map(Ingredient::new, (recipeitemstack_provider) -> { ++ return new Ingredient(new Ingredient.Provider[]{recipeitemstack_provider}); ++ }); ++ }, (recipeitemstack) -> { ++ return recipeitemstack.values.length == 1 ? DataResult.success(Either.right(recipeitemstack.values[0])) : (recipeitemstack.values.length == 0 && !flag ? DataResult.error(() -> { ++ return "Item array cannot be empty, at least one item must be defined"; ++ }) : DataResult.success(Either.left(recipeitemstack.values))); ++ }); + } + +- static record ItemValue(ItemStack item) implements Ingredient.Value { +- static final Codec<Ingredient.ItemValue> CODEC = RecordCodecBuilder.create( +- instance -> instance.group(ItemStack.SINGLE_ITEM_CODEC.fieldOf("item").forGetter(itemValue -> itemValue.item)) +- .apply(instance, Ingredient.ItemValue::new) +- ); ++ public interface Provider { + +- @Override +- public boolean equals(Object object) { +- return object instanceof Ingredient.ItemValue itemValue +- && itemValue.item.getItem().equals(this.item.getItem()) +- && itemValue.item.getCount() == this.item.getCount(); +- } ++ Codec<Ingredient.Provider> CODEC = ExtraCodecs.xor(Ingredient.ItemValue.CODEC, Ingredient.TagValue.CODEC).xmap((either) -> { ++ return (Ingredient.Provider) either.map((recipeitemstack_stackprovider) -> { ++ return recipeitemstack_stackprovider; ++ }, (recipeitemstack_b) -> { ++ return recipeitemstack_b; ++ }); ++ }, (recipeitemstack_provider) -> { ++ if (recipeitemstack_provider instanceof Ingredient.TagValue) { ++ Ingredient.TagValue recipeitemstack_b = (Ingredient.TagValue) recipeitemstack_provider; + +- @Override +- public Collection<ItemStack> getItems() { +- return Collections.singleton(this.item); +- } ++ return Either.right(recipeitemstack_b); ++ } else if (recipeitemstack_provider instanceof Ingredient.ItemValue) { ++ Ingredient.ItemValue recipeitemstack_stackprovider = (Ingredient.ItemValue) recipeitemstack_provider; ++ ++ return Either.left(recipeitemstack_stackprovider); ++ } else { ++ throw new UnsupportedOperationException("This is neither an item value nor a tag value."); ++ } ++ }); ++ ++ Collection<ItemStack> getItems(); + } + +- static record TagValue(TagKey<Item> tag) implements Ingredient.Value { +- static final Codec<Ingredient.TagValue> CODEC = RecordCodecBuilder.create( +- instance -> instance.group(TagKey.codec(Registries.ITEM).fieldOf("tag").forGetter(tagValue -> tagValue.tag)) +- .apply(instance, Ingredient.TagValue::new) +- ); ++ private static record TagValue(TagKey<Item> tag) implements Ingredient.Provider { + +- @Override ++ static final Codec<Ingredient.TagValue> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(TagKey.codec(Registries.ITEM).fieldOf("tag").forGetter((recipeitemstack_b) -> { ++ return recipeitemstack_b.tag; ++ })).apply(instance, Ingredient.TagValue::new); ++ }); ++ + public boolean equals(Object object) { +- return object instanceof Ingredient.TagValue tagValue && tagValue.tag.location().equals(this.tag.location()); ++ if (object instanceof Ingredient.TagValue) { ++ Ingredient.TagValue recipeitemstack_b = (Ingredient.TagValue) object; ++ ++ return recipeitemstack_b.tag.location().equals(this.tag.location()); ++ } else { ++ return false; ++ } + } + + @Override + public Collection<ItemStack> getItems() { + List<ItemStack> list = Lists.newArrayList(); ++ Iterator iterator = BuiltInRegistries.ITEM.getTagOrEmpty(this.tag).iterator(); + +- for (Holder<Item> holder : BuiltInRegistries.ITEM.getTagOrEmpty(this.tag)) { ++ while (iterator.hasNext()) { ++ Holder<Item> holder = (Holder) iterator.next(); ++ + list.add(new ItemStack(holder)); + } + +@@ -192,18 +237,27 @@ + } + } + +- interface Value { +- Codec<Ingredient.Value> CODEC = ExtraCodecs.xor(Ingredient.ItemValue.CODEC, Ingredient.TagValue.CODEC) +- .xmap(either -> either.map(itemValue -> itemValue, tagValue -> tagValue), value -> { +- if (value instanceof Ingredient.TagValue tagValue) { +- return Either.right(tagValue); +- } else if (value instanceof Ingredient.ItemValue itemValue) { +- return Either.left(itemValue); +- } else { +- throw new UnsupportedOperationException("This is neither an item value nor a tag value."); +- } +- }); ++ public static record ItemValue(ItemStack item) implements Ingredient.Provider { + +- Collection<ItemStack> getItems(); ++ static final Codec<Ingredient.ItemValue> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(ItemStack.SINGLE_ITEM_CODEC.fieldOf("item").forGetter((recipeitemstack_stackprovider) -> { ++ return recipeitemstack_stackprovider.item; ++ })).apply(instance, Ingredient.ItemValue::new); ++ }); ++ ++ public boolean equals(Object object) { ++ if (!(object instanceof Ingredient.ItemValue)) { ++ return false; ++ } else { ++ Ingredient.ItemValue recipeitemstack_stackprovider = (Ingredient.ItemValue) object; ++ ++ return recipeitemstack_stackprovider.item.getItem().equals(this.item.getItem()) && recipeitemstack_stackprovider.item.getCount() == this.item.getCount(); ++ } ++ } ++ ++ @Override ++ public Collection<ItemStack> getItems() { ++ return Collections.singleton(this.item); ++ } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Recipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Recipe.java.patch new file mode 100644 index 0000000000..0d6b152103 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/Recipe.java.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/world/item/crafting/Recipe.java ++++ b/net/minecraft/world/item/crafting/Recipe.java +@@ -11,6 +11,7 @@ + import net.minecraft.world.level.block.Blocks; + + public interface Recipe<C extends Container> { ++ + Codec<Recipe<?>> CODEC = BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec); + + boolean matches(C container, Level level); +@@ -22,16 +23,17 @@ + ItemStack getResultItem(RegistryAccess registryAccess); + + default NonNullList<ItemStack> getRemainingItems(C container) { +- NonNullList<ItemStack> list = NonNullList.withSize(container.getContainerSize(), ItemStack.EMPTY); ++ NonNullList<ItemStack> nonnulllist = NonNullList.withSize(container.getContainerSize(), ItemStack.EMPTY); + +- for (int i = 0; i < list.size(); i++) { ++ for (int i = 0; i < nonnulllist.size(); ++i) { + Item item = container.getItem(i).getItem(); ++ + if (item.hasCraftingRemainingItem()) { +- list.set(i, new ItemStack(item.getCraftingRemainingItem())); ++ nonnulllist.set(i, new ItemStack(item.getCraftingRemainingItem())); + } + } + +- return list; ++ return nonnulllist; + } + + default NonNullList<Ingredient> getIngredients() { +@@ -59,7 +61,12 @@ + RecipeType<?> getType(); + + default boolean isIncomplete() { +- NonNullList<Ingredient> ingredients = this.getIngredients(); +- return ingredients.isEmpty() || ingredients.stream().anyMatch(ingredient -> ingredient.getItems().length == 0); ++ NonNullList<Ingredient> nonnulllist = this.getIngredients(); ++ ++ return nonnulllist.isEmpty() || nonnulllist.stream().anyMatch((recipeitemstack) -> { ++ return recipeitemstack.getItems().length == 0; ++ }); + } ++ ++ org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id); // CraftBukkit + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeHolder.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeHolder.java.patch new file mode 100644 index 0000000000..b9dcb13846 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeHolder.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/world/item/crafting/RecipeHolder.java ++++ b/net/minecraft/world/item/crafting/RecipeHolder.java +@@ -1,27 +1,41 @@ + package net.minecraft.world.item.crafting; + + import net.minecraft.resources.ResourceLocation; ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.CraftNamespacedKey; ++import org.bukkit.inventory.Recipe; + +-public record RecipeHolder<T extends Recipe<?>>(ResourceLocation id, T value) { +- @Override ++public record RecipeHolder<T extends net.minecraft.world.item.crafting.Recipe<?>>(ResourceLocation id, T value) { ++ ++ public final Recipe toBukkitRecipe() { ++ return this.value.toBukkitRecipe(CraftNamespacedKey.fromMinecraft(this.id)); ++ } ++ // CraftBukkit end ++ + public boolean equals(Object object) { + if (this == object) { + return true; + } else { +- if (object instanceof RecipeHolder<?> recipeHolder && this.id.equals(recipeHolder.id)) { +- return true; ++ boolean flag; ++ ++ if (object instanceof RecipeHolder) { ++ RecipeHolder<?> recipeholder = (RecipeHolder) object; ++ ++ if (this.id.equals(recipeholder.id)) { ++ flag = true; ++ return flag; ++ } + } + +- return false; ++ flag = false; ++ return flag; + } + } + +- @Override + public int hashCode() { + return this.id.hashCode(); + } + +- @Override + public String toString() { + return this.id.toString(); + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeManager.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeManager.java.patch new file mode 100644 index 0000000000..bef8eeac66 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -0,0 +1,322 @@ +--- a/net/minecraft/world/item/crafting/RecipeManager.java ++++ b/net/minecraft/world/item/crafting/RecipeManager.java +@@ -1,8 +1,8 @@ + package net.minecraft.world.item.crafting; + + import com.google.common.collect.ImmutableMap; +-import com.google.common.collect.Maps; + import com.google.common.collect.ImmutableMap.Builder; ++import com.google.common.collect.Maps; + import com.google.gson.Gson; + import com.google.gson.GsonBuilder; + import com.google.gson.JsonElement; +@@ -14,83 +14,122 @@ + import java.util.Collection; + import java.util.Collections; + import java.util.Comparator; ++import java.util.Iterator; + import java.util.List; + import java.util.Map; +-import java.util.Optional; + import java.util.Map.Entry; ++import java.util.Optional; + import java.util.stream.Collectors; + import java.util.stream.Stream; + import javax.annotation.Nullable; + import net.minecraft.Util; + import net.minecraft.core.NonNullList; ++import net.minecraft.world.Container; ++import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.level.Level; ++import org.slf4j.Logger; ++ ++// CraftBukkit start ++import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; ++import net.minecraft.core.registries.BuiltInRegistries; ++// CraftBukkit end + import net.minecraft.resources.ResourceLocation; + import net.minecraft.server.packs.resources.ResourceManager; + import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; + import net.minecraft.util.GsonHelper; + import net.minecraft.util.profiling.ProfilerFiller; +-import net.minecraft.world.Container; +-import net.minecraft.world.item.ItemStack; +-import net.minecraft.world.level.Level; +-import org.slf4j.Logger; + + public class RecipeManager extends SimpleJsonResourceReloadListener { +- private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); ++ ++ private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().disableHtmlEscaping().create(); + private static final Logger LOGGER = LogUtils.getLogger(); +- private Map<RecipeType<?>, Map<ResourceLocation, RecipeHolder<?>>> recipes = ImmutableMap.of(); ++ public Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> recipes = ImmutableMap.of(); // CraftBukkit + private Map<ResourceLocation, RecipeHolder<?>> byName = ImmutableMap.of(); + private boolean hasErrors; + + public RecipeManager() { +- super(GSON, "recipes"); ++ super(RecipeManager.GSON, "recipes"); + } + +- @Override + protected void apply(Map<ResourceLocation, JsonElement> object, ResourceManager resourceManager, ProfilerFiller profiler) { + this.hasErrors = false; +- Map<RecipeType<?>, Builder<ResourceLocation, RecipeHolder<?>>> map = Maps.newHashMap(); ++ // CraftBukkit start - SPIGOT-5667 make sure all types are populated and mutable ++ Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> map1 = Maps.newHashMap(); ++ for (RecipeType<?> recipeType : BuiltInRegistries.RECIPE_TYPE) { ++ map1.put(recipeType, new Object2ObjectLinkedOpenHashMap<>()); ++ } ++ // CraftBukkit end + Builder<ResourceLocation, RecipeHolder<?>> builder = ImmutableMap.builder(); ++ Iterator iterator = object.entrySet().iterator(); + +- for (Entry<ResourceLocation, JsonElement> entry : object.entrySet()) { +- ResourceLocation resourceLocation = entry.getKey(); ++ while (iterator.hasNext()) { ++ Entry<ResourceLocation, JsonElement> entry = (Entry) iterator.next(); ++ ResourceLocation minecraftkey = (ResourceLocation) entry.getKey(); + + try { +- RecipeHolder<?> recipeHolder = fromJson(resourceLocation, GsonHelper.convertToJsonObject(entry.getValue(), "top element")); +- map.computeIfAbsent(recipeHolder.value().getType(), type -> ImmutableMap.builder()).put(resourceLocation, recipeHolder); +- builder.put(resourceLocation, recipeHolder); +- } catch (IllegalArgumentException | JsonParseException var10) { +- LOGGER.error("Parsing error loading recipe {}", resourceLocation, var10); ++ RecipeHolder<?> recipeholder = fromJson(minecraftkey, GsonHelper.convertToJsonObject((JsonElement) entry.getValue(), "top element")); ++ ++ // CraftBukkit start ++ (map1.computeIfAbsent(recipeholder.value().getType(), (recipes) -> { ++ return new Object2ObjectLinkedOpenHashMap<>(); ++ // CraftBukkit end ++ })).put(minecraftkey, recipeholder); ++ builder.put(minecraftkey, recipeholder); ++ } catch (IllegalArgumentException | JsonParseException jsonparseexception) { ++ RecipeManager.LOGGER.error("Parsing error loading recipe {}", minecraftkey, jsonparseexception); + } + } + +- this.recipes = map.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, entry1 -> entry1.getValue().build())); +- this.byName = builder.build(); +- LOGGER.info("Loaded {} recipes", map.size()); ++ this.recipes = (Map) map1.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, (entry1) -> { ++ return (entry1.getValue()); // CraftBukkit ++ })); ++ this.byName = Maps.newHashMap(builder.build()); // CraftBukkit ++ RecipeManager.LOGGER.info("Loaded {} recipes", map1.size()); + } + ++ // CraftBukkit start ++ public void addRecipe(RecipeHolder<?> irecipe) { ++ Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>> map = this.recipes.get(irecipe.value().getType()); // CraftBukkit ++ ++ if (byName.containsKey(irecipe.id()) || map.containsKey(irecipe.id())) { ++ throw new IllegalStateException("Duplicate recipe ignored with ID " + irecipe.id()); ++ } else { ++ map.putAndMoveToFirst(irecipe.id(), irecipe); // CraftBukkit - SPIGOT-4638: last recipe gets priority ++ byName.put(irecipe.id(), irecipe); ++ } ++ } ++ // CraftBukkit end ++ + public boolean hadErrorsLoading() { + return this.hasErrors; + } + + public <C extends Container, T extends Recipe<C>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> recipeType, C inventory, Level level) { +- return this.byType(recipeType).values().stream().filter(recipeHolder -> recipeHolder.value().matches(inventory, level)).findFirst(); ++ // CraftBukkit start ++ Optional<RecipeHolder<T>> recipe = this.byType(recipeType).values().stream().filter((recipeholder) -> { ++ return recipeholder.value().matches(inventory, level); ++ }).findFirst(); ++ inventory.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found ++ return recipe; ++ // CraftBukkit end + } + +- public <C extends Container, T extends Recipe<C>> Optional<Pair<ResourceLocation, RecipeHolder<T>>> getRecipeFor( +- RecipeType<T> recipeType, C inventory, Level level, @Nullable ResourceLocation lastRecipe +- ) { ++ public <C extends Container, T extends Recipe<C>> Optional<Pair<ResourceLocation, RecipeHolder<T>>> getRecipeFor(RecipeType<T> recipeType, C inventory, Level level, @Nullable ResourceLocation lastRecipe) { + Map<ResourceLocation, RecipeHolder<T>> map = this.byType(recipeType); ++ + if (lastRecipe != null) { +- RecipeHolder<T> recipeHolder = map.get(lastRecipe); +- if (recipeHolder != null && recipeHolder.value().matches(inventory, level)) { +- return Optional.of(Pair.of(lastRecipe, recipeHolder)); ++ RecipeHolder<T> recipeholder = (RecipeHolder) map.get(lastRecipe); ++ ++ if (recipeholder != null && recipeholder.value().matches(inventory, level)) { ++ return Optional.of(Pair.of(lastRecipe, recipeholder)); + } + } + +- return map.entrySet() +- .stream() +- .filter(entry -> entry.getValue().value().matches(inventory, level)) +- .findFirst() +- .map(entry -> Pair.of(entry.getKey(), entry.getValue())); ++ return map.entrySet().stream().filter((entry) -> { ++ return ((RecipeHolder) entry.getValue()).value().matches(inventory, level); ++ }).findFirst().map((entry) -> { ++ return Pair.of((ResourceLocation) entry.getKey(), (RecipeHolder) entry.getValue()); ++ }); + } + + public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> recipeType) { +@@ -98,67 +137,96 @@ + } + + public <C extends Container, T extends Recipe<C>> List<RecipeHolder<T>> getRecipesFor(RecipeType<T> recipeType, C inventory, Level level) { +- return this.byType(recipeType) +- .values() +- .stream() +- .filter(recipeHolder -> recipeHolder.value().matches(inventory, level)) +- .sorted(Comparator.comparing(recipeHolder -> recipeHolder.value().getResultItem(level.registryAccess()).getDescriptionId())) +- .collect(Collectors.toList()); ++ return (List) this.byType(recipeType).values().stream().filter((recipeholder) -> { ++ return recipeholder.value().matches(inventory, level); ++ }).sorted(Comparator.comparing((recipeholder) -> { ++ return recipeholder.value().getResultItem(level.registryAccess()).getDescriptionId(); ++ })).collect(Collectors.toList()); + } + + private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, RecipeHolder<T>> byType(RecipeType<T> recipeType) { +- return (Map<ResourceLocation, RecipeHolder<T>>) ((Map<ResourceLocation, ?>) this.recipes.getOrDefault(recipeType, Collections.emptyMap())); ++ return (Map) this.recipes.getOrDefault(recipeType, new Object2ObjectLinkedOpenHashMap<>()); // CraftBukkit + } + + public <C extends Container, T extends Recipe<C>> NonNullList<ItemStack> getRemainingItemsFor(RecipeType<T> recipeType, C inventory, Level level) { +- Optional<RecipeHolder<T>> recipeFor = this.getRecipeFor(recipeType, inventory, level); +- if (recipeFor.isPresent()) { +- return recipeFor.get().value().getRemainingItems(inventory); ++ Optional<RecipeHolder<T>> optional = this.getRecipeFor(recipeType, inventory, level); ++ ++ if (optional.isPresent()) { ++ return ((RecipeHolder) optional.get()).value().getRemainingItems(inventory); + } else { +- NonNullList<ItemStack> list = NonNullList.withSize(inventory.getContainerSize(), ItemStack.EMPTY); ++ NonNullList<ItemStack> nonnulllist = NonNullList.withSize(inventory.getContainerSize(), ItemStack.EMPTY); + +- for (int i = 0; i < list.size(); i++) { +- list.set(i, inventory.getItem(i)); ++ for (int i = 0; i < nonnulllist.size(); ++i) { ++ nonnulllist.set(i, inventory.getItem(i)); + } + +- return list; ++ return nonnulllist; + } + } + + public Optional<RecipeHolder<?>> byKey(ResourceLocation recipeId) { +- return Optional.ofNullable(this.byName.get(recipeId)); ++ return Optional.ofNullable((RecipeHolder) this.byName.get(recipeId)); + } + + public Collection<RecipeHolder<?>> getRecipes() { +- return this.recipes.values().stream().flatMap(map -> map.values().stream()).collect(Collectors.toSet()); ++ return (Collection) this.recipes.values().stream().flatMap((map) -> { ++ return map.values().stream(); ++ }).collect(Collectors.toSet()); + } + + public Stream<ResourceLocation> getRecipeIds() { +- return this.recipes.values().stream().flatMap(map -> map.keySet().stream()); ++ return this.recipes.values().stream().flatMap((map) -> { ++ return map.keySet().stream(); ++ }); + } + +- protected static RecipeHolder<?> fromJson(ResourceLocation resourceLocation, JsonObject jsonObject) { +- Recipe<?> recipe = Util.getOrThrow(Recipe.CODEC.parse(JsonOps.INSTANCE, jsonObject), JsonParseException::new); +- return new RecipeHolder<>(resourceLocation, recipe); ++ protected static RecipeHolder<?> fromJson(ResourceLocation minecraftkey, JsonObject jsonobject) { ++ Recipe<?> irecipe = (Recipe) Util.getOrThrow(Recipe.CODEC.parse(JsonOps.INSTANCE, jsonobject), JsonParseException::new); ++ ++ return new RecipeHolder<>(minecraftkey, irecipe); + } + + public void replaceRecipes(Iterable<RecipeHolder<?>> recipes) { + this.hasErrors = false; +- Map<RecipeType<?>, Map<ResourceLocation, RecipeHolder<?>>> map = Maps.newHashMap(); ++ Map<RecipeType<?>, Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>>> map = Maps.newHashMap(); // CraftBukkit + Builder<ResourceLocation, RecipeHolder<?>> builder = ImmutableMap.builder(); +- recipes.forEach(recipeHolder -> { +- Map<ResourceLocation, RecipeHolder<?>> map1 = map.computeIfAbsent(recipeHolder.value().getType(), recipeType -> Maps.newHashMap()); +- ResourceLocation resourceLocation = recipeHolder.id(); +- RecipeHolder<?> recipeHolder1 = map1.put(resourceLocation, (RecipeHolder<?>)recipeHolder); +- builder.put(resourceLocation, (RecipeHolder<?>)recipeHolder); +- if (recipeHolder1 != null) { +- throw new IllegalStateException("Duplicate recipe ignored with ID " + resourceLocation); ++ ++ recipes.forEach((recipeholder) -> { ++ Map<ResourceLocation, RecipeHolder<?>> map1 = (Map) map.computeIfAbsent(recipeholder.value().getType(), (recipes) -> { ++ return new Object2ObjectLinkedOpenHashMap<>(); // CraftBukkit ++ }); ++ ResourceLocation minecraftkey = recipeholder.id(); ++ RecipeHolder<?> recipeholder1 = (RecipeHolder) map1.put(minecraftkey, recipeholder); ++ ++ builder.put(minecraftkey, recipeholder); ++ if (recipeholder1 != null) { ++ throw new IllegalStateException("Duplicate recipe ignored with ID " + minecraftkey); + } + }); + this.recipes = ImmutableMap.copyOf(map); +- this.byName = builder.build(); ++ this.byName = Maps.newHashMap(builder.build()); // CraftBukkit + } + ++ // CraftBukkit start ++ public boolean removeRecipe(ResourceLocation mcKey) { ++ for (Object2ObjectLinkedOpenHashMap<ResourceLocation, RecipeHolder<?>> recipes : recipes.values()) { ++ recipes.remove(mcKey); ++ } ++ ++ return byName.remove(mcKey) != null; ++ } ++ ++ public void clearRecipes() { ++ this.recipes = Maps.newHashMap(); ++ ++ for (RecipeType<?> recipeType : BuiltInRegistries.RECIPE_TYPE) { ++ this.recipes.put(recipeType, new Object2ObjectLinkedOpenHashMap<>()); ++ } ++ ++ this.byName = Maps.newHashMap(); ++ } ++ // CraftBukkit end ++ + public static <C extends Container, T extends Recipe<C>> RecipeManager.CachedCheck<C, T> createCheck(final RecipeType<T> recipeType) { + return new RecipeManager.CachedCheck<C, T>() { + @Nullable +@@ -166,12 +234,14 @@ + + @Override + public Optional<RecipeHolder<T>> getRecipeFor(C container, Level level) { +- RecipeManager recipeManager = level.getRecipeManager(); +- Optional<Pair<ResourceLocation, RecipeHolder<T>>> recipeFor = recipeManager.getRecipeFor(recipeType, container, level, this.lastRecipe); +- if (recipeFor.isPresent()) { +- Pair<ResourceLocation, RecipeHolder<T>> pair = recipeFor.get(); +- this.lastRecipe = pair.getFirst(); +- return Optional.of(pair.getSecond()); ++ RecipeManager craftingmanager = level.getRecipeManager(); ++ Optional<Pair<ResourceLocation, RecipeHolder<T>>> optional = craftingmanager.getRecipeFor(recipeType, container, level, this.lastRecipe); ++ ++ if (optional.isPresent()) { ++ Pair<ResourceLocation, RecipeHolder<T>> pair = (Pair) optional.get(); ++ ++ this.lastRecipe = (ResourceLocation) pair.getFirst(); ++ return Optional.of((RecipeHolder) pair.getSecond()); + } else { + return Optional.empty(); + } +@@ -180,6 +250,7 @@ + } + + public interface CachedCheck<C extends Container, T extends Recipe<C>> { ++ + Optional<RecipeHolder<T>> getRecipeFor(C container, Level level); + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapedRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapedRecipe.java.patch new file mode 100644 index 0000000000..bf7e64ba97 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapedRecipe.java.patch @@ -0,0 +1,205 @@ +--- a/net/minecraft/world/item/crafting/ShapedRecipe.java ++++ b/net/minecraft/world/item/crafting/ShapedRecipe.java +@@ -2,35 +2,104 @@ + + import com.mojang.serialization.Codec; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; + import net.minecraft.core.NonNullList; + import net.minecraft.core.RegistryAccess; + import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.util.ExtraCodecs; +-import net.minecraft.world.inventory.CraftingContainer; ++import net.minecraft.world.inventory.InventoryCrafting; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.Level; ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; ++import org.bukkit.inventory.RecipeChoice; ++// CraftBukkit end + +-public class ShapedRecipe implements CraftingRecipe { ++public class ShapedRecipe implements RecipeCrafting { ++ + final ShapedRecipePattern pattern; + final ItemStack result; + final String group; + final CraftingBookCategory category; + final boolean showNotification; + +- public ShapedRecipe(String string, CraftingBookCategory craftingBookCategory, ShapedRecipePattern shapedRecipePattern, ItemStack itemStack, boolean flag) { +- this.group = string; +- this.category = craftingBookCategory; +- this.pattern = shapedRecipePattern; +- this.result = itemStack; ++ public ShapedRecipe(String s, CraftingBookCategory craftingbookcategory, ShapedRecipePattern shapedrecipepattern, ItemStack itemstack, boolean flag) { ++ this.group = s; ++ this.category = craftingbookcategory; ++ this.pattern = shapedrecipepattern; ++ this.result = itemstack; + this.showNotification = flag; + } + +- public ShapedRecipe(String string, CraftingBookCategory craftingBookCategory, ShapedRecipePattern shapedRecipePattern, ItemStack itemStack) { +- this(string, craftingBookCategory, shapedRecipePattern, itemStack, true); ++ public ShapedRecipe(String s, CraftingBookCategory craftingbookcategory, ShapedRecipePattern shapedrecipepattern, ItemStack itemstack) { ++ this(s, craftingbookcategory, shapedrecipepattern, itemstack, true); + } + ++ // CraftBukkit start + @Override ++ public org.bukkit.inventory.ShapedRecipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ CraftShapedRecipe recipe = new CraftShapedRecipe(id, result, this); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ switch (this.pattern.height()) { ++ case 1: ++ switch (this.pattern.width()) { ++ case 1: ++ recipe.shape("a"); ++ break; ++ case 2: ++ recipe.shape("ab"); ++ break; ++ case 3: ++ recipe.shape("abc"); ++ break; ++ } ++ break; ++ case 2: ++ switch (this.pattern.width()) { ++ case 1: ++ recipe.shape("a","b"); ++ break; ++ case 2: ++ recipe.shape("ab","cd"); ++ break; ++ case 3: ++ recipe.shape("abc","def"); ++ break; ++ } ++ break; ++ case 3: ++ switch (this.pattern.width()) { ++ case 1: ++ recipe.shape("a","b","c"); ++ break; ++ case 2: ++ recipe.shape("ab","cd","ef"); ++ break; ++ case 3: ++ recipe.shape("abc","def","ghi"); ++ break; ++ } ++ break; ++ } ++ char c = 'a'; ++ for (Ingredient list : this.pattern.ingredients()) { ++ RecipeChoice choice = CraftRecipe.toBukkit(list); ++ if (choice != null) { ++ recipe.setIngredient(c, choice); ++ } ++ ++ c++; ++ } ++ return recipe; ++ } ++ // CraftBukkit end ++ ++ @Override + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.SHAPED_RECIPE; + } +@@ -65,13 +134,11 @@ + return width >= this.pattern.width() && height >= this.pattern.height(); + } + +- @Override +- public boolean matches(CraftingContainer inv, Level level) { ++ public boolean matches(InventoryCrafting inv, Level level) { + return this.pattern.matches(inv); + } + +- @Override +- public ItemStack assemble(CraftingContainer container, RegistryAccess registryAccess) { ++ public ItemStack assemble(InventoryCrafting container, RegistryAccess registryAccess) { + return this.getResultItem(registryAccess).copy(); + } + +@@ -85,39 +152,49 @@ + + @Override + public boolean isIncomplete() { +- NonNullList<Ingredient> ingredients = this.getIngredients(); +- return ingredients.isEmpty() +- || ingredients.stream().filter(ingredient -> !ingredient.isEmpty()).anyMatch(filteredIngredients -> filteredIngredients.getItems().length == 0); ++ NonNullList<Ingredient> nonnulllist = this.getIngredients(); ++ ++ return nonnulllist.isEmpty() || nonnulllist.stream().filter((recipeitemstack) -> { ++ return !recipeitemstack.isEmpty(); ++ }).anyMatch((recipeitemstack) -> { ++ return recipeitemstack.getItems().length == 0; ++ }); + } + + public static class Serializer implements RecipeSerializer<ShapedRecipe> { +- public static final Codec<ShapedRecipe> CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter(shapedRecipe -> shapedRecipe.group), +- CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(shapedRecipe -> shapedRecipe.category), +- ShapedRecipePattern.MAP_CODEC.forGetter(shapedRecipe -> shapedRecipe.pattern), +- ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter(shapedRecipe -> shapedRecipe.result), +- ExtraCodecs.strictOptionalField(Codec.BOOL, "show_notification", true).forGetter(shapedRecipe -> shapedRecipe.showNotification) +- ) +- .apply(instance, ShapedRecipe::new) +- ); + ++ public static final Codec<ShapedRecipe> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter((shapedrecipes) -> { ++ return shapedrecipes.group; ++ }), CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter((shapedrecipes) -> { ++ return shapedrecipes.category; ++ }), ShapedRecipePattern.MAP_CODEC.forGetter((shapedrecipes) -> { ++ return shapedrecipes.pattern; ++ }), ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter((shapedrecipes) -> { ++ return shapedrecipes.result; ++ }), ExtraCodecs.strictOptionalField(Codec.BOOL, "show_notification", true).forGetter((shapedrecipes) -> { ++ return shapedrecipes.showNotification; ++ })).apply(instance, ShapedRecipe::new); ++ }); ++ ++ public Serializer() {} ++ + @Override + public Codec<ShapedRecipe> codec() { +- return CODEC; ++ return ShapedRecipe.Serializer.CODEC; + } + + @Override +- public ShapedRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) { +- String utf = friendlyByteBuf.readUtf(); +- CraftingBookCategory craftingBookCategory = friendlyByteBuf.readEnum(CraftingBookCategory.class); +- ShapedRecipePattern shapedRecipePattern = ShapedRecipePattern.fromNetwork(friendlyByteBuf); +- ItemStack item = friendlyByteBuf.readItem(); +- boolean _boolean = friendlyByteBuf.readBoolean(); +- return new ShapedRecipe(utf, craftingBookCategory, shapedRecipePattern, item, _boolean); ++ public ShapedRecipe fromNetwork(FriendlyByteBuf packetdataserializer) { ++ String s = packetdataserializer.readUtf(); ++ CraftingBookCategory craftingbookcategory = (CraftingBookCategory) packetdataserializer.readEnum(CraftingBookCategory.class); ++ ShapedRecipePattern shapedrecipepattern = ShapedRecipePattern.fromNetwork(packetdataserializer); ++ ItemStack itemstack = packetdataserializer.readItem(); ++ boolean flag = packetdataserializer.readBoolean(); ++ ++ return new ShapedRecipe(s, craftingbookcategory, shapedrecipepattern, itemstack, flag); + } + +- @Override + public void toNetwork(FriendlyByteBuf buffer, ShapedRecipe recipe) { + buffer.writeUtf(recipe.group); + buffer.writeEnum(recipe.category); diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch new file mode 100644 index 0000000000..0434c3100b --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/ShapelessRecipe.java.patch @@ -0,0 +1,204 @@ +--- a/net/minecraft/world/item/crafting/ShapelessRecipe.java ++++ b/net/minecraft/world/item/crafting/ShapelessRecipe.java +@@ -3,31 +3,54 @@ + import com.mojang.serialization.Codec; + import com.mojang.serialization.DataResult; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; +-import java.util.List; ++import it.unimi.dsi.fastutil.ints.IntList; ++import java.util.Iterator; + import net.minecraft.core.NonNullList; + import net.minecraft.core.RegistryAccess; + import net.minecraft.network.FriendlyByteBuf; + import net.minecraft.util.ExtraCodecs; + import net.minecraft.world.entity.player.StackedContents; +-import net.minecraft.world.inventory.CraftingContainer; ++import net.minecraft.world.inventory.InventoryCrafting; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.Level; ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; ++// CraftBukkit end + +-public class ShapelessRecipe implements CraftingRecipe { ++public class ShapelessRecipe implements RecipeCrafting { ++ + final String group; + final CraftingBookCategory category; + final ItemStack result; + final NonNullList<Ingredient> ingredients; + +- public ShapelessRecipe(String string, CraftingBookCategory craftingBookCategory, ItemStack itemStack, NonNullList<Ingredient> list) { +- this.group = string; +- this.category = craftingBookCategory; +- this.result = itemStack; +- this.ingredients = list; ++ public ShapelessRecipe(String s, CraftingBookCategory craftingbookcategory, ItemStack itemstack, NonNullList<Ingredient> nonnulllist) { ++ this.group = s; ++ this.category = craftingbookcategory; ++ this.result = itemstack; ++ this.ingredients = nonnulllist; + } + ++ // CraftBukkit start ++ @SuppressWarnings("unchecked") + @Override ++ public org.bukkit.inventory.ShapelessRecipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ CraftShapelessRecipe recipe = new CraftShapelessRecipe(id, result, this); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ for (Ingredient list : this.ingredients) { ++ recipe.addIngredient(CraftRecipe.toBukkit(list)); ++ } ++ return recipe; ++ } ++ // CraftBukkit end ++ ++ @Override + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.SHAPELESS_RECIPE; + } +@@ -52,24 +75,23 @@ + return this.ingredients; + } + +- @Override +- public boolean matches(CraftingContainer inv, Level level) { +- StackedContents stackedContents = new StackedContents(); ++ public boolean matches(InventoryCrafting inv, Level level) { ++ StackedContents autorecipestackmanager = new StackedContents(); + int i = 0; + +- for (int i1 = 0; i1 < inv.getContainerSize(); i1++) { +- ItemStack item = inv.getItem(i1); +- if (!item.isEmpty()) { +- i++; +- stackedContents.accountStack(item, 1); ++ for (int j = 0; j < inv.getContainerSize(); ++j) { ++ ItemStack itemstack = inv.getItem(j); ++ ++ if (!itemstack.isEmpty()) { ++ ++i; ++ autorecipestackmanager.accountStack(itemstack, 1); + } + } + +- return i == this.ingredients.size() && stackedContents.canCraft(this, null); ++ return i == this.ingredients.size() && autorecipestackmanager.canCraft(this, (IntList) null); + } + +- @Override +- public ItemStack assemble(CraftingContainer container, RegistryAccess registryAccess) { ++ public ItemStack assemble(InventoryCrafting container, RegistryAccess registryAccess) { + return this.result.copy(); + } + +@@ -79,60 +101,64 @@ + } + + public static class Serializer implements RecipeSerializer<ShapelessRecipe> { +- private static final Codec<ShapelessRecipe> CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter(shapelessRecipe -> shapelessRecipe.group), +- CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter(shapelessRecipe -> shapelessRecipe.category), +- ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter(shapelessRecipe -> shapelessRecipe.result), +- Ingredient.CODEC_NONEMPTY +- .listOf() +- .fieldOf("ingredients") +- .flatXmap( +- list -> { +- Ingredient[] ingredients = list.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new); +- if (ingredients.length == 0) { +- return DataResult.error(() -> "No ingredients for shapeless recipe"); +- } else { +- return ingredients.length > 9 +- ? DataResult.error(() -> "Too many ingredients for shapeless recipe") +- : DataResult.success(NonNullList.of(Ingredient.EMPTY, ingredients)); +- } +- }, +- DataResult::success +- ) +- .forGetter(shapelessRecipe -> shapelessRecipe.ingredients) +- ) +- .apply(instance, ShapelessRecipe::new) +- ); + ++ private static final Codec<ShapelessRecipe> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(ExtraCodecs.strictOptionalField(Codec.STRING, "group", "").forGetter((shapelessrecipes) -> { ++ return shapelessrecipes.group; ++ }), CraftingBookCategory.CODEC.fieldOf("category").orElse(CraftingBookCategory.MISC).forGetter((shapelessrecipes) -> { ++ return shapelessrecipes.category; ++ }), ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter((shapelessrecipes) -> { ++ return shapelessrecipes.result; ++ }), Ingredient.CODEC_NONEMPTY.listOf().fieldOf("ingredients").flatXmap((list) -> { ++ Ingredient[] arecipeitemstack = (Ingredient[]) list.stream().filter((recipeitemstack) -> { ++ return !recipeitemstack.isEmpty(); ++ }).toArray((i) -> { ++ return new Ingredient[i]; ++ }); ++ ++ return arecipeitemstack.length == 0 ? DataResult.error(() -> { ++ return "No ingredients for shapeless recipe"; ++ }) : (arecipeitemstack.length > 9 ? DataResult.error(() -> { ++ return "Too many ingredients for shapeless recipe"; ++ }) : DataResult.success(NonNullList.of(Ingredient.EMPTY, arecipeitemstack))); ++ }, DataResult::success).forGetter((shapelessrecipes) -> { ++ return shapelessrecipes.ingredients; ++ })).apply(instance, ShapelessRecipe::new); ++ }); ++ ++ public Serializer() {} ++ + @Override + public Codec<ShapelessRecipe> codec() { +- return CODEC; ++ return ShapelessRecipe.Serializer.CODEC; + } + + @Override +- public ShapelessRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) { +- String utf = friendlyByteBuf.readUtf(); +- CraftingBookCategory craftingBookCategory = friendlyByteBuf.readEnum(CraftingBookCategory.class); +- int varInt = friendlyByteBuf.readVarInt(); +- NonNullList<Ingredient> list = NonNullList.withSize(varInt, Ingredient.EMPTY); ++ public ShapelessRecipe fromNetwork(FriendlyByteBuf packetdataserializer) { ++ String s = packetdataserializer.readUtf(); ++ CraftingBookCategory craftingbookcategory = (CraftingBookCategory) packetdataserializer.readEnum(CraftingBookCategory.class); ++ int i = packetdataserializer.readVarInt(); ++ NonNullList<Ingredient> nonnulllist = NonNullList.withSize(i, Ingredient.EMPTY); + +- for (int i = 0; i < list.size(); i++) { +- list.set(i, Ingredient.fromNetwork(friendlyByteBuf)); ++ for (int j = 0; j < nonnulllist.size(); ++j) { ++ nonnulllist.set(j, Ingredient.fromNetwork(packetdataserializer)); + } + +- ItemStack item = friendlyByteBuf.readItem(); +- return new ShapelessRecipe(utf, craftingBookCategory, item, list); ++ ItemStack itemstack = packetdataserializer.readItem(); ++ ++ return new ShapelessRecipe(s, craftingbookcategory, itemstack, nonnulllist); + } + +- @Override + public void toNetwork(FriendlyByteBuf buffer, ShapelessRecipe recipe) { + buffer.writeUtf(recipe.group); + buffer.writeEnum(recipe.category); + buffer.writeVarInt(recipe.ingredients.size()); ++ Iterator iterator = recipe.ingredients.iterator(); + +- for (Ingredient ingredient : recipe.ingredients) { +- ingredient.toNetwork(buffer); ++ while (iterator.hasNext()) { ++ Ingredient recipeitemstack = (Ingredient) iterator.next(); ++ ++ recipeitemstack.toNetwork(buffer); + } + + buffer.writeItem(recipe.result); diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmeltingRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmeltingRecipe.java.patch new file mode 100644 index 0000000000..69d9e9092e --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmeltingRecipe.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/item/crafting/SmeltingRecipe.java ++++ b/net/minecraft/world/item/crafting/SmeltingRecipe.java +@@ -3,9 +3,18 @@ + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.block.Blocks; + ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ + public class SmeltingRecipe extends AbstractCookingRecipe { +- public SmeltingRecipe(String string, CookingBookCategory cookingBookCategory, Ingredient ingredient, ItemStack itemStack, float f, int i) { +- super(RecipeType.SMELTING, string, cookingBookCategory, ingredient, itemStack, f, i); ++ ++ public SmeltingRecipe(String s, CookingBookCategory cookingbookcategory, Ingredient recipeitemstack, ItemStack itemstack, float f, int i) { ++ super(RecipeType.SMELTING, s, cookingbookcategory, recipeitemstack, itemstack, f, i); + } + + @Override +@@ -17,4 +26,17 @@ + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.SMELTING_RECIPE; + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ ++ CraftFurnaceRecipe recipe = new CraftFurnaceRecipe(id, result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ return recipe; ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch new file mode 100644 index 0000000000..da1e2ac7d4 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTransformRecipe.java.patch @@ -0,0 +1,139 @@ +--- a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java ++++ b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java +@@ -2,7 +2,6 @@ + + import com.mojang.serialization.Codec; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; + import java.util.stream.Stream; + import net.minecraft.core.RegistryAccess; + import net.minecraft.nbt.CompoundTag; +@@ -10,18 +9,26 @@ + import net.minecraft.world.Container; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.Level; ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftSmithingTransformRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end + + public class SmithingTransformRecipe implements SmithingRecipe { ++ + final Ingredient template; + final Ingredient base; + final Ingredient addition; + final ItemStack result; + +- public SmithingTransformRecipe(Ingredient ingredient, Ingredient ingredient1, Ingredient ingredient2, ItemStack itemStack) { +- this.template = ingredient; +- this.base = ingredient1; +- this.addition = ingredient2; +- this.result = itemStack; ++ public SmithingTransformRecipe(Ingredient recipeitemstack, Ingredient recipeitemstack1, Ingredient recipeitemstack2, ItemStack itemstack) { ++ this.template = recipeitemstack; ++ this.base = recipeitemstack1; ++ this.addition = recipeitemstack2; ++ this.result = itemstack; + } + + @Override +@@ -31,13 +38,14 @@ + + @Override + public ItemStack assemble(Container container, RegistryAccess registryAccess) { +- ItemStack itemStack = this.result.copy(); +- CompoundTag tag = container.getItem(1).getTag(); +- if (tag != null) { +- itemStack.setTag(tag.copy()); ++ ItemStack itemstack = this.result.copy(); ++ CompoundTag nbttagcompound = container.getItem(1).getTag(); ++ ++ if (nbttagcompound != null) { ++ itemstack.setTag(nbttagcompound.copy()); + } + +- return itemStack; ++ return itemstack; + } + + @Override +@@ -70,37 +78,53 @@ + return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::isEmpty); + } + +- public static class Serializer implements RecipeSerializer<SmithingTransformRecipe> { +- private static final Codec<SmithingTransformRecipe> CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- Ingredient.CODEC.fieldOf("template").forGetter(smithingTransformRecipe -> smithingTransformRecipe.template), +- Ingredient.CODEC.fieldOf("base").forGetter(smithingTransformRecipe -> smithingTransformRecipe.base), +- Ingredient.CODEC.fieldOf("addition").forGetter(smithingTransformRecipe -> smithingTransformRecipe.addition), +- ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter(smithingTransformRecipe -> smithingTransformRecipe.result) +- ) +- .apply(instance, SmithingTransformRecipe::new) +- ); ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); + ++ CraftSmithingTransformRecipe recipe = new CraftSmithingTransformRecipe(id, result, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition)); ++ ++ return recipe; ++ } ++ // CraftBukkit end ++ ++ public static class a implements RecipeSerializer<SmithingTransformRecipe> { ++ ++ private static final Codec<SmithingTransformRecipe> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(Ingredient.CODEC.fieldOf("template").forGetter((smithingtransformrecipe) -> { ++ return smithingtransformrecipe.template; ++ }), Ingredient.CODEC.fieldOf("base").forGetter((smithingtransformrecipe) -> { ++ return smithingtransformrecipe.base; ++ }), Ingredient.CODEC.fieldOf("addition").forGetter((smithingtransformrecipe) -> { ++ return smithingtransformrecipe.addition; ++ }), ItemStack.ITEM_WITH_COUNT_CODEC.fieldOf("result").forGetter((smithingtransformrecipe) -> { ++ return smithingtransformrecipe.result; ++ })).apply(instance, SmithingTransformRecipe::new); ++ }); ++ ++ public a() {} ++ + @Override + public Codec<SmithingTransformRecipe> codec() { +- return CODEC; ++ return SmithingTransformRecipe.a.CODEC; + } + + @Override +- public SmithingTransformRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) { +- Ingredient ingredient = Ingredient.fromNetwork(friendlyByteBuf); +- Ingredient ingredient1 = Ingredient.fromNetwork(friendlyByteBuf); +- Ingredient ingredient2 = Ingredient.fromNetwork(friendlyByteBuf); +- ItemStack item = friendlyByteBuf.readItem(); +- return new SmithingTransformRecipe(ingredient, ingredient1, ingredient2, item); ++ public SmithingTransformRecipe fromNetwork(FriendlyByteBuf packetdataserializer) { ++ Ingredient recipeitemstack = Ingredient.fromNetwork(packetdataserializer); ++ Ingredient recipeitemstack1 = Ingredient.fromNetwork(packetdataserializer); ++ Ingredient recipeitemstack2 = Ingredient.fromNetwork(packetdataserializer); ++ ItemStack itemstack = packetdataserializer.readItem(); ++ ++ return new SmithingTransformRecipe(recipeitemstack, recipeitemstack1, recipeitemstack2, itemstack); + } + +- @Override +- public void toNetwork(FriendlyByteBuf buffer, SmithingTransformRecipe recipe) { +- recipe.template.toNetwork(buffer); +- recipe.base.toNetwork(buffer); +- recipe.addition.toNetwork(buffer); +- buffer.writeItem(recipe.result); ++ public void toNetwork(FriendlyByteBuf packetdataserializer, SmithingTransformRecipe smithingtransformrecipe) { ++ smithingtransformrecipe.template.toNetwork(packetdataserializer); ++ smithingtransformrecipe.base.toNetwork(packetdataserializer); ++ smithingtransformrecipe.addition.toNetwork(packetdataserializer); ++ packetdataserializer.writeItem(smithingtransformrecipe.result); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch new file mode 100644 index 0000000000..ef758f8657 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmithingTrimRecipe.java.patch @@ -0,0 +1,170 @@ +--- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java ++++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java +@@ -2,7 +2,6 @@ + + import com.mojang.serialization.Codec; + import com.mojang.serialization.codecs.RecordCodecBuilder; +-import com.mojang.serialization.codecs.RecordCodecBuilder.Instance; + import java.util.Optional; + import java.util.stream.Stream; + import net.minecraft.core.Holder; +@@ -18,16 +17,23 @@ + import net.minecraft.world.item.armortrim.TrimPattern; + import net.minecraft.world.item.armortrim.TrimPatterns; + import net.minecraft.world.level.Level; ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftSmithingTrimRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end + + public class SmithingTrimRecipe implements SmithingRecipe { ++ + final Ingredient template; + final Ingredient base; + final Ingredient addition; + +- public SmithingTrimRecipe(Ingredient ingredient, Ingredient ingredient1, Ingredient ingredient2) { +- this.template = ingredient; +- this.base = ingredient1; +- this.addition = ingredient2; ++ public SmithingTrimRecipe(Ingredient recipeitemstack, Ingredient recipeitemstack1, Ingredient recipeitemstack2) { ++ this.template = recipeitemstack; ++ this.base = recipeitemstack1; ++ this.addition = recipeitemstack2; + } + + @Override +@@ -37,21 +43,26 @@ + + @Override + public ItemStack assemble(Container container, RegistryAccess registryAccess) { +- ItemStack item = container.getItem(1); +- if (this.base.test(item)) { +- Optional<Holder.Reference<TrimMaterial>> fromIngredient = TrimMaterials.getFromIngredient(registryAccess, container.getItem(2)); +- Optional<Holder.Reference<TrimPattern>> fromTemplate = TrimPatterns.getFromTemplate(registryAccess, container.getItem(0)); +- if (fromIngredient.isPresent() && fromTemplate.isPresent()) { +- Optional<ArmorTrim> trim = ArmorTrim.getTrim(registryAccess, item, false); +- if (trim.isPresent() && trim.get().hasPatternAndMaterial(fromTemplate.get(), fromIngredient.get())) { ++ ItemStack itemstack = container.getItem(1); ++ ++ if (this.base.test(itemstack)) { ++ Optional<Holder.Reference<TrimMaterial>> optional = TrimMaterials.getFromIngredient(registryAccess, container.getItem(2)); ++ Optional<Holder.Reference<TrimPattern>> optional1 = TrimPatterns.getFromTemplate(registryAccess, container.getItem(0)); ++ ++ if (optional.isPresent() && optional1.isPresent()) { ++ Optional<ArmorTrim> optional2 = ArmorTrim.getTrim(registryAccess, itemstack, false); ++ ++ if (optional2.isPresent() && ((ArmorTrim) optional2.get()).hasPatternAndMaterial((Holder) optional1.get(), (Holder) optional.get())) { + return ItemStack.EMPTY; + } + +- ItemStack itemStack = item.copy(); +- itemStack.setCount(1); +- ArmorTrim armorTrim = new ArmorTrim(fromIngredient.get(), fromTemplate.get()); +- if (ArmorTrim.setTrim(registryAccess, itemStack, armorTrim)) { +- return itemStack; ++ ItemStack itemstack1 = itemstack.copy(); ++ ++ itemstack1.setCount(1); ++ ArmorTrim armortrim = new ArmorTrim((Holder) optional.get(), (Holder) optional1.get()); ++ ++ if (ArmorTrim.setTrim(registryAccess, itemstack1, armortrim)) { ++ return itemstack1; + } + } + } +@@ -61,17 +72,20 @@ + + @Override + public ItemStack getResultItem(RegistryAccess registryAccess) { +- ItemStack itemStack = new ItemStack(Items.IRON_CHESTPLATE); ++ ItemStack itemstack = new ItemStack(Items.IRON_CHESTPLATE); + Optional<Holder.Reference<TrimPattern>> optional = registryAccess.registryOrThrow(Registries.TRIM_PATTERN).holders().findFirst(); ++ + if (optional.isPresent()) { +- Optional<Holder.Reference<TrimMaterial>> holder = registryAccess.registryOrThrow(Registries.TRIM_MATERIAL).getHolder(TrimMaterials.REDSTONE); +- if (holder.isPresent()) { +- ArmorTrim armorTrim = new ArmorTrim(holder.get(), optional.get()); +- ArmorTrim.setTrim(registryAccess, itemStack, armorTrim); ++ Optional<Holder.Reference<TrimMaterial>> optional1 = registryAccess.registryOrThrow(Registries.TRIM_MATERIAL).getHolder(TrimMaterials.REDSTONE); ++ ++ if (optional1.isPresent()) { ++ ArmorTrim armortrim = new ArmorTrim((Holder) optional1.get(), (Holder) optional.get()); ++ ++ ArmorTrim.setTrim(registryAccess, itemstack, armortrim); + } + } + +- return itemStack; ++ return itemstack; + } + + @Override +@@ -99,34 +113,45 @@ + return Stream.of(this.template, this.base, this.addition).anyMatch(Ingredient::isEmpty); + } + +- public static class Serializer implements RecipeSerializer<SmithingTrimRecipe> { +- private static final Codec<SmithingTrimRecipe> CODEC = RecordCodecBuilder.create( +- instance -> instance.group( +- Ingredient.CODEC.fieldOf("template").forGetter(smithingTrimRecipe -> smithingTrimRecipe.template), +- Ingredient.CODEC.fieldOf("base").forGetter(smithingTrimRecipe -> smithingTrimRecipe.base), +- Ingredient.CODEC.fieldOf("addition").forGetter(smithingTrimRecipe -> smithingTrimRecipe.addition) +- ) +- .apply(instance, SmithingTrimRecipe::new) +- ); ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ return new CraftSmithingTrimRecipe(id, CraftRecipe.toBukkit(this.template), CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition)); ++ } ++ // CraftBukkit end + ++ public static class a implements RecipeSerializer<SmithingTrimRecipe> { ++ ++ private static final Codec<SmithingTrimRecipe> CODEC = RecordCodecBuilder.create((instance) -> { ++ return instance.group(Ingredient.CODEC.fieldOf("template").forGetter((smithingtrimrecipe) -> { ++ return smithingtrimrecipe.template; ++ }), Ingredient.CODEC.fieldOf("base").forGetter((smithingtrimrecipe) -> { ++ return smithingtrimrecipe.base; ++ }), Ingredient.CODEC.fieldOf("addition").forGetter((smithingtrimrecipe) -> { ++ return smithingtrimrecipe.addition; ++ })).apply(instance, SmithingTrimRecipe::new); ++ }); ++ ++ public a() {} ++ + @Override + public Codec<SmithingTrimRecipe> codec() { +- return CODEC; ++ return SmithingTrimRecipe.a.CODEC; + } + + @Override +- public SmithingTrimRecipe fromNetwork(FriendlyByteBuf friendlyByteBuf) { +- Ingredient ingredient = Ingredient.fromNetwork(friendlyByteBuf); +- Ingredient ingredient1 = Ingredient.fromNetwork(friendlyByteBuf); +- Ingredient ingredient2 = Ingredient.fromNetwork(friendlyByteBuf); +- return new SmithingTrimRecipe(ingredient, ingredient1, ingredient2); ++ public SmithingTrimRecipe fromNetwork(FriendlyByteBuf packetdataserializer) { ++ Ingredient recipeitemstack = Ingredient.fromNetwork(packetdataserializer); ++ Ingredient recipeitemstack1 = Ingredient.fromNetwork(packetdataserializer); ++ Ingredient recipeitemstack2 = Ingredient.fromNetwork(packetdataserializer); ++ ++ return new SmithingTrimRecipe(recipeitemstack, recipeitemstack1, recipeitemstack2); + } + +- @Override +- public void toNetwork(FriendlyByteBuf buffer, SmithingTrimRecipe recipe) { +- recipe.template.toNetwork(buffer); +- recipe.base.toNetwork(buffer); +- recipe.addition.toNetwork(buffer); ++ public void toNetwork(FriendlyByteBuf packetdataserializer, SmithingTrimRecipe smithingtrimrecipe) { ++ smithingtrimrecipe.template.toNetwork(packetdataserializer); ++ smithingtrimrecipe.base.toNetwork(packetdataserializer); ++ smithingtrimrecipe.addition.toNetwork(packetdataserializer); + } + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmokingRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmokingRecipe.java.patch new file mode 100644 index 0000000000..125f7896db --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/SmokingRecipe.java.patch @@ -0,0 +1,41 @@ +--- a/net/minecraft/world/item/crafting/SmokingRecipe.java ++++ b/net/minecraft/world/item/crafting/SmokingRecipe.java +@@ -3,9 +3,18 @@ + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.block.Blocks; + ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftSmokingRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ + public class SmokingRecipe extends AbstractCookingRecipe { +- public SmokingRecipe(String string, CookingBookCategory cookingBookCategory, Ingredient ingredient, ItemStack itemStack, float f, int i) { +- super(RecipeType.SMOKING, string, cookingBookCategory, ingredient, itemStack, f, i); ++ ++ public SmokingRecipe(String s, CookingBookCategory cookingbookcategory, Ingredient recipeitemstack, ItemStack itemstack, float f, int i) { ++ super(RecipeType.SMOKING, s, cookingbookcategory, recipeitemstack, itemstack, f, i); + } + + @Override +@@ -17,4 +26,17 @@ + public RecipeSerializer<?> getSerializer() { + return RecipeSerializer.SMOKING_RECIPE; + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ ++ CraftSmokingRecipe recipe = new CraftSmokingRecipe(id, result, CraftRecipe.toBukkit(this.ingredient), this.experience, this.cookingTime); ++ recipe.setGroup(this.group); ++ recipe.setCategory(CraftRecipe.getCategory(this.category())); ++ ++ return recipe; ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/StonecutterRecipe.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/StonecutterRecipe.java.patch new file mode 100644 index 0000000000..47fa959efd --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/crafting/StonecutterRecipe.java.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/world/item/crafting/StonecutterRecipe.java ++++ b/net/minecraft/world/item/crafting/StonecutterRecipe.java +@@ -5,9 +5,18 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; + ++// CraftBukkit start ++import org.bukkit.NamespacedKey; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftRecipe; ++import org.bukkit.craftbukkit.inventory.CraftStonecuttingRecipe; ++import org.bukkit.inventory.Recipe; ++// CraftBukkit end ++ + public class StonecutterRecipe extends SingleItemRecipe { +- public StonecutterRecipe(String string, Ingredient ingredient, ItemStack itemStack) { +- super(RecipeType.STONECUTTING, RecipeSerializer.STONECUTTER, string, ingredient, itemStack); ++ ++ public StonecutterRecipe(String s, Ingredient recipeitemstack, ItemStack itemstack) { ++ super(RecipeType.STONECUTTING, RecipeSerializer.STONECUTTER, s, recipeitemstack, itemstack); + } + + @Override +@@ -19,4 +28,16 @@ + public ItemStack getToastSymbol() { + return new ItemStack(Blocks.STONECUTTER); + } ++ ++ // CraftBukkit start ++ @Override ++ public Recipe toBukkitRecipe(NamespacedKey id) { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.result); ++ ++ CraftStonecuttingRecipe recipe = new CraftStonecuttingRecipe(id, result, CraftRecipe.toBukkit(this.ingredient)); ++ recipe.setGroup(this.group); ++ ++ return recipe; ++ } ++ // CraftBukkit end + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/DamageEnchantment.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/DamageEnchantment.java.patch new file mode 100644 index 0000000000..e5cb62c89f --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/DamageEnchantment.java.patch @@ -0,0 +1,75 @@ +--- a/net/minecraft/world/item/enchantment/DamageEnchantment.java ++++ b/net/minecraft/world/item/enchantment/DamageEnchantment.java +@@ -3,13 +3,14 @@ + import net.minecraft.world.effect.MobEffectInstance; + import net.minecraft.world.effect.MobEffects; + import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EnumMonsterType; + import net.minecraft.world.entity.EquipmentSlot; + import net.minecraft.world.entity.LivingEntity; +-import net.minecraft.world.entity.MobType; + import net.minecraft.world.item.AxeItem; + import net.minecraft.world.item.ItemStack; + + public class DamageEnchantment extends Enchantment { ++ + public static final int ALL = 0; + public static final int UNDEAD = 1; + public static final int ARTHROPODS = 2; +@@ -26,12 +27,12 @@ + + @Override + public int getMinCost(int enchantmentLevel) { +- return MIN_COST[this.type] + (enchantmentLevel - 1) * LEVEL_COST[this.type]; ++ return DamageEnchantment.MIN_COST[this.type] + (enchantmentLevel - 1) * DamageEnchantment.LEVEL_COST[this.type]; + } + + @Override + public int getMaxCost(int enchantmentLevel) { +- return this.getMinCost(enchantmentLevel) + LEVEL_COST_SPAN[this.type]; ++ return this.getMinCost(enchantmentLevel) + DamageEnchantment.LEVEL_COST_SPAN[this.type]; + } + + @Override +@@ -40,14 +41,8 @@ + } + + @Override +- public float getDamageBonus(int level, MobType creatureType) { +- if (this.type == 0) { +- return 1.0F + (float)Math.max(0, level - 1) * 0.5F; +- } else if (this.type == 1 && creatureType == MobType.UNDEAD) { +- return (float)level * 2.5F; +- } else { +- return this.type == 2 && creatureType == MobType.ARTHROPOD ? (float)level * 2.5F : 0.0F; +- } ++ public float getDamageBonus(int level, EnumMonsterType creatureType) { ++ return this.type == 0 ? 1.0F + (float) Math.max(0, level - 1) * 0.5F : (this.type == 1 && creatureType == EnumMonsterType.UNDEAD ? (float) level * 2.5F : (this.type == 2 && creatureType == EnumMonsterType.ARTHROPOD ? (float) level * 2.5F : 0.0F)); + } + + @Override +@@ -57,14 +52,20 @@ + + @Override + public boolean canEnchant(ItemStack stack) { +- return stack.getItem() instanceof AxeItem || super.canEnchant(stack); ++ return stack.getItem() instanceof AxeItem ? true : super.canEnchant(stack); + } + + @Override + public void doPostAttack(LivingEntity user, Entity target, int level) { +- if (target instanceof LivingEntity livingEntity && this.type == 2 && level > 0 && livingEntity.getMobType() == MobType.ARTHROPOD) { +- int i = 20 + user.getRandom().nextInt(10 * level); +- livingEntity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, i, 3)); ++ if (target instanceof LivingEntity) { ++ LivingEntity entityliving1 = (LivingEntity) target; ++ ++ if (this.type == 2 && level > 0 && entityliving1.getMobType() == EnumMonsterType.ARTHROPOD) { ++ int j = 20 + user.getRandom().nextInt(10 * level); ++ ++ entityliving1.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, j, 3), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit ++ } + } ++ + } + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/FrostWalkerEnchantment.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/FrostWalkerEnchantment.java.patch new file mode 100644 index 0000000000..9fc59385d6 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/enchantment/FrostWalkerEnchantment.java.patch @@ -0,0 +1,69 @@ +--- a/net/minecraft/world/item/enchantment/FrostWalkerEnchantment.java ++++ b/net/minecraft/world/item/enchantment/FrostWalkerEnchantment.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.item.enchantment; + ++import java.util.Iterator; + import net.minecraft.core.BlockPos; + import net.minecraft.util.Mth; + import net.minecraft.world.entity.EquipmentSlot; +@@ -7,10 +8,11 @@ + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.Blocks; + import net.minecraft.world.level.block.FrostedIceBlock; +-import net.minecraft.world.level.block.state.BlockState; ++import net.minecraft.world.level.block.state.IBlockData; + import net.minecraft.world.phys.shapes.CollisionContext; + + public class FrostWalkerEnchantment extends Enchantment { ++ + public FrostWalkerEnchantment(Enchantment.Rarity rarity, EquipmentSlot... applicableSlots) { + super(rarity, EnchantmentCategory.ARMOR_FEET, applicableSlots); + } +@@ -37,25 +39,32 @@ + + public static void onEntityMoved(LivingEntity living, Level level, BlockPos pos, int levelConflicting) { + if (living.onGround()) { +- BlockState blockState = Blocks.FROSTED_ICE.defaultBlockState(); +- int min = Math.min(16, 2 + levelConflicting); +- BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); ++ IBlockData iblockdata = Blocks.FROSTED_ICE.defaultBlockState(); ++ int j = Math.min(16, 2 + levelConflicting); ++ BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); ++ Iterator iterator = BlockPos.betweenClosed(pos.offset(-j, -1, -j), pos.offset(j, -1, j)).iterator(); + +- for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-min, -1, -min), pos.offset(min, -1, min))) { +- if (blockPos.closerToCenterThan(living.position(), (double)min)) { +- mutableBlockPos.set(blockPos.getX(), blockPos.getY() + 1, blockPos.getZ()); +- BlockState blockState1 = level.getBlockState(mutableBlockPos); +- if (blockState1.isAir()) { +- BlockState blockState2 = level.getBlockState(blockPos); +- if (blockState2 == FrostedIceBlock.meltsInto() +- && blockState.canSurvive(level, blockPos) +- && level.isUnobstructed(blockState, blockPos, CollisionContext.empty())) { +- level.setBlockAndUpdate(blockPos, blockState); +- level.scheduleTick(blockPos, Blocks.FROSTED_ICE, Mth.nextInt(living.getRandom(), 60, 120)); ++ while (iterator.hasNext()) { ++ BlockPos blockposition1 = (BlockPos) iterator.next(); ++ ++ if (blockposition1.closerToCenterThan(living.position(), (double) j)) { ++ blockposition_mutableblockposition.set(blockposition1.getX(), blockposition1.getY() + 1, blockposition1.getZ()); ++ IBlockData iblockdata1 = level.getBlockState(blockposition_mutableblockposition); ++ ++ if (iblockdata1.isAir()) { ++ IBlockData iblockdata2 = level.getBlockState(blockposition1); ++ ++ if (iblockdata2 == FrostedIceBlock.meltsInto() && iblockdata.canSurvive(level, blockposition1) && level.isUnobstructed(iblockdata, blockposition1, CollisionContext.empty())) { ++ // CraftBukkit Start - Call EntityBlockFormEvent for Frost Walker ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockposition1, iblockdata, living)) { ++ level.scheduleTick(blockposition1, Blocks.FROSTED_ICE, Mth.nextInt(living.getRandom(), 60, 120)); ++ } ++ // CraftBukkit End + } + } + } + } ++ + } + } + diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/trading/Merchant.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/trading/Merchant.java.patch new file mode 100644 index 0000000000..f4aecf8456 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/trading/Merchant.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/world/item/trading/Merchant.java ++++ b/net/minecraft/world/item/trading/Merchant.java +@@ -5,12 +5,12 @@ + import net.minecraft.network.chat.Component; + import net.minecraft.sounds.SoundEvent; + import net.minecraft.world.SimpleMenuProvider; +-import net.minecraft.world.entity.player.Inventory; + import net.minecraft.world.entity.player.Player; + import net.minecraft.world.inventory.MerchantMenu; + import net.minecraft.world.item.ItemStack; + + public interface Merchant { ++ + void setTradingPlayer(@Nullable Player tradingPlayer); + + @Nullable +@@ -37,16 +37,21 @@ + } + + default void openTradingScreen(Player player, Component displayName, int level) { +- OptionalInt optionalInt = player.openMenu( +- new SimpleMenuProvider((containerId, inventory, player1) -> new MerchantMenu(containerId, inventory, this), displayName) +- ); +- if (optionalInt.isPresent()) { +- MerchantOffers offers = this.getOffers(); +- if (!offers.isEmpty()) { +- player.sendMerchantOffers(optionalInt.getAsInt(), offers, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock()); ++ OptionalInt optionalint = player.openMenu(new SimpleMenuProvider((j, playerinventory, entityhuman1) -> { ++ return new MerchantMenu(j, playerinventory, this); ++ }, displayName)); ++ ++ if (optionalint.isPresent()) { ++ MerchantOffers merchantrecipelist = this.getOffers(); ++ ++ if (!merchantrecipelist.isEmpty()) { ++ player.sendMerchantOffers(optionalint.getAsInt(), merchantrecipelist, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock()); + } + } ++ + } + + boolean isClientSide(); ++ ++ org.bukkit.craftbukkit.inventory.CraftMerchant getCraftMerchant(); // CraftBukkit + } diff --git a/patch-remap/mache-vineflower/net/minecraft/world/item/trading/MerchantOffer.java.patch b/patch-remap/mache-vineflower/net/minecraft/world/item/trading/MerchantOffer.java.patch new file mode 100644 index 0000000000..b95fea8462 --- /dev/null +++ b/patch-remap/mache-vineflower/net/minecraft/world/item/trading/MerchantOffer.java.patch @@ -0,0 +1,200 @@ +--- a/net/minecraft/world/item/trading/MerchantOffer.java ++++ b/net/minecraft/world/item/trading/MerchantOffer.java +@@ -5,19 +5,40 @@ + import net.minecraft.util.Mth; + import net.minecraft.world.item.ItemStack; + ++import org.bukkit.craftbukkit.inventory.CraftMerchantRecipe; // CraftBukkit ++ + public class MerchantOffer { +- private final ItemStack baseCostA; +- private final ItemStack costB; +- private final ItemStack result; +- private int uses; +- private final int maxUses; +- private boolean rewardExp = true; +- private int specialPriceDiff; +- private int demand; +- private float priceMultiplier; +- private int xp = 1; + ++ public ItemStack baseCostA; ++ public ItemStack costB; ++ public final ItemStack result; ++ public int uses; ++ public int maxUses; ++ public boolean rewardExp; ++ public int specialPriceDiff; ++ public int demand; ++ public float priceMultiplier; ++ public int xp; ++ // CraftBukkit start ++ private CraftMerchantRecipe bukkitHandle; ++ ++ public CraftMerchantRecipe asBukkit() { ++ return (bukkitHandle == null) ? bukkitHandle = new CraftMerchantRecipe(this) : bukkitHandle; ++ } ++ ++ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, CraftMerchantRecipe bukkit) { ++ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, 0, bukkit); ++ } ++ ++ public MerchantOffer(ItemStack itemstack, ItemStack itemstack1, ItemStack itemstack2, int uses, int maxUses, int experience, float priceMultiplier, int demand, CraftMerchantRecipe bukkit) { ++ this(itemstack, itemstack1, itemstack2, uses, maxUses, experience, priceMultiplier, demand); ++ this.bukkitHandle = bukkit; ++ } ++ // CraftBukkit end ++ + public MerchantOffer(CompoundTag compoundTag) { ++ this.rewardExp = true; ++ this.xp = 1; + this.baseCostA = ItemStack.of(compoundTag.getCompound("buy")); + this.costB = ItemStack.of(compoundTag.getCompound("buyB")); + this.result = ItemStack.of(compoundTag.getCompound("sell")); +@@ -52,32 +73,36 @@ + this(baseCostA, costB, result, 0, maxUses, xp, priceMultiplier); + } + +- public MerchantOffer(ItemStack baseCostA, ItemStack costB, ItemStack result, int _uses, int maxUses, int xp, float priceMultiplier) { +- this(baseCostA, costB, result, _uses, maxUses, xp, priceMultiplier, 0); ++ public MerchantOffer(ItemStack baseCostA, ItemStack costB, ItemStack result, int uses, int maxUses, int xp, float priceMultiplier) { ++ this(baseCostA, costB, result, uses, maxUses, xp, priceMultiplier, 0); + } + +- public MerchantOffer(ItemStack baseCostA, ItemStack costB, ItemStack result, int _uses, int maxUses, int xp, float priceMultiplier, int demand) { ++ public MerchantOffer(ItemStack baseCostA, ItemStack costB, ItemStack result, int uses, int maxUses, int xp, float priceMultiplier, int demand) { ++ this.rewardExp = true; ++ this.xp = 1; + this.baseCostA = baseCostA; + this.costB = costB; + this.result = result; +- this.uses = _uses; ++ this.uses = uses; + this.maxUses = maxUses; + this.xp = xp; + this.priceMultiplier = priceMultiplier; + this.demand = demand; + } + +- private MerchantOffer(MerchantOffer merchantOffer) { +- this.baseCostA = merchantOffer.baseCostA.copy(); +- this.costB = merchantOffer.costB.copy(); +- this.result = merchantOffer.result.copy(); +- this.uses = merchantOffer.uses; +- this.maxUses = merchantOffer.maxUses; +- this.rewardExp = merchantOffer.rewardExp; +- this.specialPriceDiff = merchantOffer.specialPriceDiff; +- this.demand = merchantOffer.demand; +- this.priceMultiplier = merchantOffer.priceMultiplier; +- this.xp = merchantOffer.xp; ++ private MerchantOffer(MerchantOffer merchantrecipe) { ++ this.rewardExp = true; ++ this.xp = 1; ++ this.baseCostA = merchantrecipe.baseCostA.copy(); ++ this.costB = merchantrecipe.costB.copy(); ++ this.result = merchantrecipe.result.copy(); ++ this.uses = merchantrecipe.uses; ++ this.maxUses = merchantrecipe.maxUses; ++ this.rewardExp = merchantrecipe.rewardExp; ++ this.specialPriceDiff = merchantrecipe.specialPriceDiff; ++ this.demand = merchantrecipe.demand; ++ this.priceMultiplier = merchantrecipe.priceMultiplier; ++ this.xp = merchantrecipe.xp; + } + + public ItemStack getBaseCostA() { +@@ -88,9 +113,11 @@ + if (this.baseCostA.isEmpty()) { + return ItemStack.EMPTY; + } else { +- int count = this.baseCostA.getCount(); +- int max = Math.max(0, Mth.floor((float)(count * this.demand) * this.priceMultiplier)); +- return this.baseCostA.copyWithCount(Mth.clamp(count + max + this.specialPriceDiff, 1, this.baseCostA.getItem().getMaxStackSize())); ++ int i = this.baseCostA.getCount(); ++ if (i <= 0) return ItemStack.EMPTY; // CraftBukkit - SPIGOT-5476 ++ int j = Math.max(0, Mth.floor((float) (i * this.demand) * this.priceMultiplier)); ++ ++ return this.baseCostA.copyWithCount(Mth.clamp(i + j + this.specialPriceDiff, 1, this.baseCostA.getItem().getMaxStackSize())); + } + } + +@@ -123,7 +150,7 @@ + } + + public void increaseUses() { +- this.uses++; ++ ++this.uses; + } + + public int getDemand() { +@@ -171,38 +198,36 @@ + } + + public CompoundTag createTag() { +- CompoundTag compoundTag = new CompoundTag(); +- compoundTag.put("buy", this.baseCostA.save(new CompoundTag())); +- compoundTag.put("sell", this.result.save(new CompoundTag())); +- compoundTag.put("buyB", this.costB.save(new CompoundTag())); +- compoundTag.putInt("uses", this.uses); +- compoundTag.putInt("maxUses", this.maxUses); +- compoundTag.putBoolean("rewardExp", this.rewardExp); +- compoundTag.putInt("xp", this.xp); +- compoundTag.putFloat("priceMultiplier", this.priceMultiplier); +- compoundTag.putInt("specialPrice", this.specialPriceDiff); +- compoundTag.putInt("demand", this.demand); +- return compoundTag; ++ CompoundTag nbttagcompound = new CompoundTag(); ++ ++ nbttagcompound.put("buy", this.baseCostA.save(new CompoundTag())); ++ nbttagcompound.put("sell", this.result.save(new CompoundTag())); ++ nbttagcompound.put("buyB", this.costB.save(new CompoundTag())); ++ nbttagcompound.putInt("uses", this.uses); ++ nbttagcompound.putInt("maxUses", this.maxUses); ++ nbttagcompound.putBoolean("rewardExp", this.rewardExp); ++ nbttagcompound.putInt("xp", this.xp); ++ nbttagcompound.putFloat("priceMultiplier", this.priceMultiplier); ++ nbttagcompound.putInt("specialPrice", this.specialPriceDiff); ++ nbttagcompound.putInt("demand", this.demand); ++ return nbttagcompound; + } + + public boolean satisfiedBy(ItemStack playerOfferA, ItemStack playerOfferB) { +- return this.isRequiredItem(playerOfferA, this.getCostA()) +- && playerOfferA.getCount() >= this.getCostA().getCount() +- && this.isRequiredItem(playerOfferB, this.costB) +- && playerOfferB.getCount() >= this.costB.getCount(); ++ return this.isRequiredItem(playerOfferA, this.getCostA()) && playerOfferA.getCount() >= this.getCostA().getCount() && this.isRequiredItem(playerOfferB, this.costB) && playerOfferB.getCount() >= this.costB.getCount(); + } + + private boolean isRequiredItem(ItemStack offer, ItemStack cost) { + if (cost.isEmpty() && offer.isEmpty()) { + return true; + } else { +- ItemStack itemStack = offer.copy(); +- if (itemStack.getItem().canBeDepleted()) { +- itemStack.setDamageValue(itemStack.getDamageValue()); ++ ItemStack itemstack2 = offer.copy(); ++ ++ if (itemstack2.getItem().canBeDepleted()) { ++ itemstack2.setDamageValue(itemstack2.getDamageValue()); + } + +- return ItemStack.isSameItem(itemStack, cost) +- && (!cost.hasTag() || itemStack.hasTag() && NbtUtils.compareNbt(cost.getTag(), itemStack.getTag(), false)); ++ return ItemStack.isSameItem(itemstack2, cost) && (!cost.hasTag() || itemstack2.hasTag() && NbtUtils.compareNbt(cost.getTag(), itemstack2.getTag(), false)); + } + } + +@@ -210,7 +235,11 @@ + if (!this.satisfiedBy(playerOfferA, playerOfferB)) { + return false; + } else { +- playerOfferA.shrink(this.getCostA().getCount()); ++ // CraftBukkit start ++ if (!this.getCostA().isEmpty()) { ++ playerOfferA.shrink(this.getCostA().getCount()); ++ } ++ // CraftBukkit end + if (!this.getCostB().isEmpty()) { + playerOfferB.shrink(this.getCostB().getCount()); + } |