mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-25 22:10:21 +01:00
Fix EntityShootBowEvent with crossbows
This commit is contained in:
parent
e7d928a8e1
commit
92fc3bb251
2 changed files with 194 additions and 0 deletions
20
patches/api/0377-Fix-shouldConsumeItem-for-crossbows.patch
Normal file
20
patches/api/0377-Fix-shouldConsumeItem-for-crossbows.patch
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Tue, 22 Mar 2022 01:05:38 -0700
|
||||||
|
Subject: [PATCH] Fix shouldConsumeItem for crossbows
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java b/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||||
|
index 719d0d878320c1903b44076053989ba99fa0e92a..1f131a14e2d3f16c1ef11b9849dc1b6746947fa0 100644
|
||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityShootBowEvent.java
|
||||||
|
@@ -133,8 +133,7 @@ public class EntityShootBowEvent extends EntityEvent implements Cancellable {
|
||||||
|
* the server's decision to not consume a consumable item.
|
||||||
|
* <p>
|
||||||
|
* This value is ignored for entities where items are not required
|
||||||
|
- * (skeletons, pillagers, etc.) or with crossbows (as no item is being
|
||||||
|
- * consumed).
|
||||||
|
+ * (skeletons, pillagers, etc.).
|
||||||
|
*
|
||||||
|
* @param consumeItem whether or not to consume the item
|
||||||
|
*/
|
174
patches/server/0887-Fix-bow-shoot-event-for-crossbows.patch
Normal file
174
patches/server/0887-Fix-bow-shoot-event-for-crossbows.patch
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||||
|
Date: Tue, 22 Mar 2022 01:04:20 -0700
|
||||||
|
Subject: [PATCH] Fix bow shoot event for crossbows
|
||||||
|
|
||||||
|
Cancelling the EntityShootBowEvent now leaves the crossbow
|
||||||
|
charged. Also the shouldConsumeItem now has an effect of
|
||||||
|
consuming the item if true, and not if false.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||||
|
index c0c211c7227f4ce5d1e0e433419425e6bb13046f..027c54b3bff2d46b7ff902b2a7835d86c2db8878 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||||
|
@@ -65,8 +65,9 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
ItemStack itemstack = user.getItemInHand(hand);
|
||||||
|
|
||||||
|
if (CrossbowItem.isCharged(itemstack)) {
|
||||||
|
- CrossbowItem.performShooting(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), 1.0F);
|
||||||
|
+ if (CrossbowItem.performShooting0(world, user, hand, itemstack, CrossbowItem.getShootingPower(itemstack), 1.0F)) { // Paper
|
||||||
|
CrossbowItem.setCharged(itemstack, false);
|
||||||
|
+ } // Paper
|
||||||
|
return InteractionResultHolder.consume(itemstack);
|
||||||
|
} else if (!user.getProjectile(itemstack).isEmpty()) {
|
||||||
|
if (!CrossbowItem.isCharged(itemstack)) {
|
||||||
|
@@ -174,6 +175,11 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addChargedProjectile(ItemStack crossbow, ItemStack projectile) {
|
||||||
|
+ // Paper start
|
||||||
|
+ addChargedProjectiles(crossbow, java.util.Collections.singletonList(projectile), false);
|
||||||
|
+ }
|
||||||
|
+ private static void addChargedProjectiles(ItemStack crossbow, List<ItemStack> projectiles, boolean filterEmpty) {
|
||||||
|
+ // Paper end
|
||||||
|
CompoundTag nbttagcompound = crossbow.getOrCreateTag();
|
||||||
|
ListTag nbttaglist;
|
||||||
|
|
||||||
|
@@ -183,10 +189,15 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
nbttaglist = new ListTag();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ for (ItemStack projectile : projectiles) {
|
||||||
|
+ if (projectile.isEmpty()) continue;
|
||||||
|
+ // Paper end
|
||||||
|
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||||
|
|
||||||
|
projectile.save(nbttagcompound1);
|
||||||
|
nbttaglist.add(nbttagcompound1);
|
||||||
|
+ } // Paper
|
||||||
|
nbttagcompound.put("ChargedProjectiles", nbttaglist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -227,7 +238,8 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static void shootProjectile(Level world, LivingEntity shooter, InteractionHand hand, ItemStack crossbow, ItemStack projectile, float soundPitch, boolean creative, float speed, float divergence, float simulated) {
|
||||||
|
+ private static ItemStack shootProjectile(Level world, LivingEntity shooter, InteractionHand hand, ItemStack crossbow, ItemStack projectile, float soundPitch, boolean creative, float speed, float divergence, float simulated) { // Paper - return leftover stack, or empty if used
|
||||||
|
+ ItemStack newProjectile = ItemStack.EMPTY; // Paper
|
||||||
|
if (!world.isClientSide) {
|
||||||
|
boolean flag1 = projectile.is(Items.FIREWORK_ROCKET);
|
||||||
|
Object object;
|
||||||
|
@@ -259,8 +271,13 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, crossbow, projectile, (Entity) object, shooter.getUsedItemHand(), soundPitch, true);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
event.getProjectile().remove();
|
||||||
|
- return;
|
||||||
|
+ return org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getConsumable()); // Paper
|
||||||
|
+ }
|
||||||
|
+ // Paper start
|
||||||
|
+ if (!event.shouldConsumeItem()) {
|
||||||
|
+ newProjectile = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getConsumable());
|
||||||
|
}
|
||||||
|
+ // Paper end
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
crossbow.hurtAndBreak(flag1 ? 3 : 1, shooter, (entityliving1) -> {
|
||||||
|
@@ -272,12 +289,13 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
if (shooter instanceof ServerPlayer) {
|
||||||
|
((ServerPlayer) shooter).getBukkitEntity().updateInventory();
|
||||||
|
}
|
||||||
|
- return;
|
||||||
|
+ return newProjectile; // Paper - the entity spawn cancelled doesn't cancel the shot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
world.playSound((Player) null, shooter.getX(), shooter.getY(), shooter.getZ(), SoundEvents.CROSSBOW_SHOOT, SoundSource.PLAYERS, 1.0F, soundPitch);
|
||||||
|
}
|
||||||
|
+ return newProjectile; // Paper
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AbstractArrow getArrow(Level world, LivingEntity entity, ItemStack crossbow, ItemStack arrow) {
|
||||||
|
@@ -300,25 +318,52 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performShooting(Level world, LivingEntity entity, InteractionHand hand, ItemStack stack, float speed, float divergence) {
|
||||||
|
+ // Paper start
|
||||||
|
+ performShooting0(world, entity, hand, stack, speed, divergence);
|
||||||
|
+ }
|
||||||
|
+ public static boolean performShooting0(Level world, LivingEntity entity, InteractionHand hand, ItemStack stack, float speed, float divergence) {
|
||||||
|
+ // Paper end
|
||||||
|
List<ItemStack> list = CrossbowItem.getChargedProjectiles(stack);
|
||||||
|
float[] afloat = CrossbowItem.getShotPitches(entity.getRandom());
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ final List<ItemStack> newProjectiles = new java.util.ArrayList<>(3);
|
||||||
|
+ boolean noneCancelled = true;
|
||||||
|
+ boolean allCancelled = true;
|
||||||
|
+ // Paper end
|
||||||
|
for (int i = 0; i < list.size(); ++i) {
|
||||||
|
ItemStack itemstack1 = (ItemStack) list.get(i);
|
||||||
|
boolean flag = entity instanceof Player && ((Player) entity).getAbilities().instabuild;
|
||||||
|
|
||||||
|
if (!itemstack1.isEmpty()) {
|
||||||
|
if (i == 0) {
|
||||||
|
- CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, 0.0F);
|
||||||
|
+ itemstack1 = CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, 0.0F); // Paper
|
||||||
|
} else if (i == 1) {
|
||||||
|
- CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, -10.0F);
|
||||||
|
+ itemstack1 = CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, -10.0F); // Paper
|
||||||
|
} else if (i == 2) {
|
||||||
|
- CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, 10.0F);
|
||||||
|
+ // Paper start
|
||||||
|
+ itemstack1 = CrossbowItem.shootProjectile(world, entity, hand, stack, itemstack1, afloat[i], flag, speed, divergence, 10.0F);
|
||||||
|
+ }
|
||||||
|
+ if (i < 3) {
|
||||||
|
+ newProjectiles.add(itemstack1);
|
||||||
|
+ if (!itemstack1.isEmpty()) {
|
||||||
|
+ noneCancelled = false;
|
||||||
|
+ } else {
|
||||||
|
+ allCancelled = false;
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (noneCancelled || !(entity instanceof Player)) { // Paper
|
||||||
|
CrossbowItem.onCrossbowShot(world, entity, stack);
|
||||||
|
+ // Paper start
|
||||||
|
+ } else {
|
||||||
|
+ CrossbowItem.onCrossbowShot(world, entity, stack, allCancelled, newProjectiles);
|
||||||
|
+ }
|
||||||
|
+ return noneCancelled;
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float[] getShotPitches(Random random) {
|
||||||
|
@@ -334,7 +379,12 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onCrossbowShot(Level world, LivingEntity entity, ItemStack stack) {
|
||||||
|
- if (entity instanceof ServerPlayer) {
|
||||||
|
+ // Paper start
|
||||||
|
+ onCrossbowShot(world, entity, stack, false, null);
|
||||||
|
+ }
|
||||||
|
+ private static void onCrossbowShot(Level world, LivingEntity entity, ItemStack stack, boolean allCancelled, @Nullable List<ItemStack> projectiles) {
|
||||||
|
+ if (entity instanceof ServerPlayer && !allCancelled) {
|
||||||
|
+ // Paper end
|
||||||
|
ServerPlayer entityplayer = (ServerPlayer) entity;
|
||||||
|
|
||||||
|
if (!world.isClientSide) {
|
||||||
|
@@ -345,6 +395,11 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||||
|
}
|
||||||
|
|
||||||
|
CrossbowItem.clearChargedProjectiles(stack);
|
||||||
|
+ // Paper start
|
||||||
|
+ if (projectiles != null) {
|
||||||
|
+ CrossbowItem.addChargedProjectiles(stack, projectiles, true);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
Loading…
Reference in a new issue