From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Tue, 22 Jun 2021 23:41:11 -0400 Subject: [PATCH] More Projectile API Co-authored-by: Nassim Jahnke diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java index fee09e6ff72cf1da389d5811dd005642cd50a5b4..4f276b2a86735a2c664738450ae0fbdd82031d4e 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java @@ -98,6 +98,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie @Override protected void onHit(HitResult hitResult) { super.onHit(hitResult); + // Paper start - More projectile API + this.splash(hitResult); + } + public void splash(@org.jetbrains.annotations.Nullable HitResult hitResult) { + // Paper end - More projectile API if (!this.level.isClientSide) { ItemStack itemstack = this.getItem(); Potion potionregistry = PotionUtils.getPotion(itemstack); @@ -110,7 +115,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie if (this.isLingering()) { this.makeAreaOfEffectCloud(itemstack, potionregistry); } else { - this.applySplash(list, hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null); + this.applySplash(list, hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null); // Paper - nullable hitResult } } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index 40e5b19bc8fa3de3b3d54da0762aee5bd7bb8d7b..825fdc6162797ade8e76e1ca3a863ed5fb48f936 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -21,5 +21,31 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti public void setBounce(boolean doesBounce) { this.doesBounce = doesBounce; } + // Paper start + @Override + public boolean hasLeftShooter() { + return this.getHandle().leftOwner; + } + + @Override + public void setHasLeftShooter(boolean leftShooter) { + this.getHandle().leftOwner = leftShooter; + } + + @Override + public boolean hasBeenShot() { + return this.getHandle().hasBeenShot; + } + + @Override + public void setHasBeenShot(boolean beenShot) { + this.getHandle().hasBeenShot = beenShot; + } + + @Override + public net.minecraft.world.entity.projectile.Projectile getHandle() { + return (net.minecraft.world.entity.projectile.Projectile) entity; + } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java index 15abd085eeb0a31a925c1a8d6de903c9d4625a29..40ae8e43f40f9bf457d2917ac4f131b21e4f8dd2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java @@ -108,6 +108,27 @@ public class CraftArrow extends AbstractProjectile implements AbstractArrow { return org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(getHandle().getPickupItem()); } + @Override + public void setLifetimeTicks(int ticks) { + this.getHandle().life = ticks; + } + + @Override + public int getLifetimeTicks() { + return this.getHandle().life; + } + + @org.jetbrains.annotations.NotNull + @Override + public org.bukkit.Sound getHitSound() { + return org.bukkit.craftbukkit.CraftSound.getBukkit(this.getHandle().soundEvent); + } + + @Override + public void setHitSound(@org.jetbrains.annotations.NotNull org.bukkit.Sound sound) { + this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.getSoundEffect(sound)); + } + @Override public void setNoPhysics(boolean noPhysics) { this.getHandle().setNoPhysics(noPhysics); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java index c242f654c88ca1773429348939d3bb2ffae3768c..d1c7ab67cba881d96b7a5e9220130d86d0514304 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java @@ -16,24 +16,26 @@ import org.bukkit.inventory.meta.FireworkMeta; public class CraftFirework extends CraftProjectile implements Firework { private final Random random = new Random(); - private final CraftItemStack item; + //private CraftItemStack item; // Paper - Remove usage, not accurate representation of current item. public CraftFirework(CraftServer server, FireworkRocketEntity entity) { super(server, entity); - ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM); - - if (item.isEmpty()) { - item = new ItemStack(Items.FIREWORK_ROCKET); - this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item); - } - - this.item = CraftItemStack.asCraftMirror(item); - - // Ensure the item is a firework... - if (this.item.getType() != Material.FIREWORK_ROCKET) { - this.item.setType(Material.FIREWORK_ROCKET); - } +// Paper Start - Expose firework item directly +// ItemStack item = this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM); +// +// if (item.isEmpty()) { +// item = new ItemStack(Items.FIREWORK_ROCKET); +// this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item); +// } +// +// this.item = CraftItemStack.asCraftMirror(item); +// +// // Ensure the item is a firework... +// if (this.item.getType() != Material.FIREWORK_ROCKET) { +// this.item.setType(Material.FIREWORK_ROCKET); +// } + // Paper End - Expose firework item directly } @Override @@ -53,12 +55,12 @@ public class CraftFirework extends CraftProjectile implements Firework { @Override public FireworkMeta getFireworkMeta() { - return (FireworkMeta) this.item.getItemMeta(); + return (FireworkMeta) CraftItemStack.getItemMeta(this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM), Material.FIREWORK_ROCKET); // Paper - Expose firework item directly } @Override public void setFireworkMeta(FireworkMeta meta) { - this.item.setItemMeta(meta); + applyFireworkEffect(meta); // Paper - Expose firework item directly // Copied from EntityFireworks constructor, update firework lifetime/power this.getHandle().lifetime = 10 * (1 + meta.getPower()) + this.random.nextInt(6) + this.random.nextInt(7); @@ -142,4 +144,46 @@ public class CraftFirework extends CraftProjectile implements Firework { return getHandle().spawningEntity; } // Paper end + // Paper start - Expose firework item directly + manually setting flight + @Override + public org.bukkit.inventory.ItemStack getItem() { + return CraftItemStack.asBukkitCopy(this.getHandle().getItem()); + } + + @Override + public void setItem(org.bukkit.inventory.ItemStack itemStack) { + FireworkMeta meta = getFireworkMeta(); + ItemStack nmsItem = itemStack == null ? ItemStack.EMPTY : CraftItemStack.asNMSCopy(itemStack); + this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, nmsItem); + + applyFireworkEffect(meta); + } + + @Override + public int getTicksFlown() { + return this.getHandle().life; + } + + @Override + public void setTicksFlown(int ticks) { + this.getHandle().life = ticks; + } + + @Override + public int getTicksToDetonate() { + return this.getHandle().lifetime; + } + + @Override + public void setTicksToDetonate(int ticks) { + this.getHandle().lifetime = ticks; + } + + void applyFireworkEffect(FireworkMeta meta) { + ItemStack item = this.getHandle().getItem(); + CraftItemStack.applyMetaToItem(item, meta); + + this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item); + } + // Paper end - Expose firework item directly + manually setting flight } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java index 6bfa984781a483d048ef4318761203c701d8a632..5e0c2c5094e1578162d1a50d50701fbd25e6d961 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java @@ -119,4 +119,15 @@ public class CraftFishHook extends CraftProjectile implements FishHook { public HookState getState() { return HookState.values()[this.getHandle().currentState.ordinal()]; } + // Paper start - More FishHook API + @Override + public int getWaitTime() { + return this.getHandle().timeUntilLured; + } + + @Override + public void setWaitTime(int ticks) { + this.getHandle().timeUntilLured = ticks; + } + // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java index 20b54f8896be1f8744a29e1d0205e58d27049f1f..ca8a9b2773d70a8800b2179b164ce33d7e2bdc5e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java @@ -40,6 +40,40 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle()); } + @Override + public org.bukkit.util.Vector getTargetDelta() { + net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle(); + return new org.bukkit.util.Vector(bullet.targetDeltaX, bullet.targetDeltaY, bullet.targetDeltaZ); + } + + @Override + public void setTargetDelta(org.bukkit.util.Vector vector) { + net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle(); + bullet.targetDeltaX = vector.getX(); + bullet.targetDeltaY = vector.getY(); + bullet.targetDeltaZ = vector.getZ(); + } + + @Override + public org.bukkit.block.BlockFace getCurrentMovementDirection() { + return org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(this.getHandle().currentMoveDirection); + } + + @Override + public void setCurrentMovementDirection(org.bukkit.block.BlockFace movementDirection) { + this.getHandle().currentMoveDirection = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(movementDirection); + } + + @Override + public int getFlightSteps() { + return this.getHandle().flightSteps; + } + + @Override + public void setFlightSteps(int steps) { + this.getHandle().flightSteps = steps; + } + @Override public String toString() { return "CraftShulkerBullet"; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java index 0db8aa840ea026d48215ac5dc80ffde5f12725b1..397e0df15a0e64e5bc522f62f3b327a5039ec4c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java @@ -39,11 +39,31 @@ public class CraftThrownPotion extends CraftThrowableProjectile implements Throw Validate.notNull(item, "ItemStack cannot be null."); // The ItemStack must be a potion. - Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + "."); + //Validate.isTrue(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack must be a lingering or splash potion. This item stack was " + item.getType() + "."); // Paper - Projectile API + org.bukkit.inventory.meta.PotionMeta meta = (item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION) ? null : this.getPotionMeta(); // Paper - Projectile API this.getHandle().setItem(CraftItemStack.asNMSCopy(item)); + if (meta != null) this.setPotionMeta(meta); // Paper - Projectile API } + // Paper start - Projectile API + @Override + public org.bukkit.inventory.meta.PotionMeta getPotionMeta() { + return (org.bukkit.inventory.meta.PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItemRaw(), Material.SPLASH_POTION); + } + + @Override + public void setPotionMeta(org.bukkit.inventory.meta.PotionMeta meta) { + net.minecraft.world.item.ItemStack item = this.getHandle().getItem(); + CraftItemStack.applyMetaToItem(item, meta); + this.getHandle().setItem(item); // Reset item + } + + @Override + public void splash() { + this.getHandle().splash(null); + } + // Paper end @Override public net.minecraft.world.entity.projectile.ThrownPotion getHandle() { return (net.minecraft.world.entity.projectile.ThrownPotion) entity; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java index 832981b07ef5c633ef00a382f56798ee87eec0df..faf071201b7c1414225a33fe9641eac9477d53c7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java @@ -59,5 +59,15 @@ public class CraftTrident extends CraftArrow implements Trident { com.google.common.base.Preconditions.checkArgument(loyaltyLevel >= 0 && loyaltyLevel <= 127, "The loyalty level has to be between 0 and 127"); this.getHandle().setLoyalty((byte) loyaltyLevel); } + + @Override + public boolean hasDealtDamage() { + return this.getHandle().dealtDamage; + } + + @Override + public void setHasDealtDamage(boolean hasDealtDamage) { + this.getHandle().dealtDamage = hasDealtDamage; + } // Paper end } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index f3abcd5949011eaef3d1ba68f4cc0751042d2834..bfb1ad0b6e20e10fee53f94a3e6c4f8aad7aae7d 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -278,12 +278,20 @@ public final class CraftItemStack extends ItemStack { public ItemMeta getItemMeta() { return CraftItemStack.getItemMeta(this.handle); } + // Paper start + public static void applyMetaToItem(net.minecraft.world.item.ItemStack itemStack, ItemMeta meta) { + ((org.bukkit.craftbukkit.inventory.CraftMetaItem) meta).applyToItem(itemStack.getOrCreateTag()); + } public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item) { + return getItemMeta(item, CraftItemStack.getType(item)); + } + public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, Material material) { + // Paper end if (!CraftItemStack.hasItemMeta(item)) { - return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item)); + return CraftItemFactory.instance().getItemMeta(material); // Paper } - switch (CraftItemStack.getType(item)) { + switch (material) { // Paper case WRITTEN_BOOK: return new CraftMetaBookSigned(item.getTag()); case WRITABLE_BOOK: