mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 11:27:35 +01:00
3b9db2b194
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: bb4e97c6 Add support for Java 23 bc6874dd Bump asm to 9.7.1 50e8a00b PR-1064: Add specific getTopInventory methods for InventoryView derivatives 758b0a0f SPIGOT-7911: Fix Location#isWorldLoaded() for re-loaded worlds 133a64a7 Improve Registry#getOrThrow messages be0f5957 PR-1058: Add tests for Minecraft registry <-> Bukkit fields d1b31df2 PR-1062: Clarify BeaconView documentation 3fab4384 PR-1060: Cache Material to BlockType and ItemType conversion 967a7301 SPIGOT-7906: Increase YAML nesting limit to 100 6ecf033d SPIGOT-7899: Smithing recipes don't require inputs CraftBukkit Changes: 0a7bd6c81 PR-1493: Improve reroute performance and add some tests 54941524c Add support for Java 23 f4d957fff SPIGOT-7915: Fix World#getKeepSpawnInMemory() using Spawn Radius rather than Spawn Chunk Radius ded183674 Fix HIDE_ENCHANTS flag in items without enchantments 308785a0a Bump asm to 9.7.1 and re-add ClassReader to ClassWriter 72ce823cd PR-1487: Add specific getTopInventory methods for InventoryView derivatives 11a5e840c SPIGOT-7907, PR-1484: Improve merchant recipe item matching behavior to more closely align with older versions 45b66f7e4 SPIGOT-7909: Always set HIDE_ENCHANTS flag to item if flag is set 963459791 Increase outdated build delay fc5b2d75f SPIGOT-7910: Fix launching breeze wind charge from API and improve dispenser launch API c7d6428f2 SPIGOT-7856, PR-1483: End platform not dropping items after replacing blocks 2a5572b52 SPIGOT-7780, PR-1482: Cannot edit chunks during unload event 527041ab5 SPIGOT-7902, PR-1477: Fix CraftMetaPotion#hasCustomEffects() does not check if customEffects (List) is empty 5529a1769 Implement base methods for tags 30fbdbaaf Improve Registry#getOrThrow messages 6b71a7322 PR-1475: Add tests for Minecraft registry <-> Bukkit fields 5f24c255c SPIGOT-7908: Mark junit-platform-suite-engine as test scope e4c92ef65 PR-1473: Change tests to use suites, to run tests in different environments and feature flags d25e1e722 PR-1481: Fix BeaconView#set[X]Effect(null) d69a05362 PR-1480: Fix PerMaterialTest#isEdible test running for legacy materials bb3284a89 PR-1479: Use custom #isBlock method in legacy init instead of the one in Material, since it relies on legacy being init 98c57cbbe SPIGOT-7904: Fix NPE for PlayerItemBreakEvent f35bae9ec Fix missing hasJukeboxPlayable 8a6f8b6d8 SPIGOT-7881: CTRL+Pick Block saves position data into item 7913b3be7 SPIGOT-7899: Smithing recipes don't require inputs
905 lines
48 KiB
Diff
905 lines
48 KiB
Diff
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
|
|
|
|
== AT ==
|
|
public net.minecraft.world.entity.projectile.FishingHook timeUntilLured
|
|
public net.minecraft.world.entity.projectile.FishingHook fishAngle
|
|
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaX
|
|
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaY
|
|
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaZ
|
|
public net.minecraft.world.entity.projectile.ShulkerBullet currentMoveDirection
|
|
public net.minecraft.world.entity.projectile.ShulkerBullet flightSteps
|
|
public net.minecraft.world.entity.projectile.AbstractArrow soundEvent
|
|
public net/minecraft/world/entity/projectile/AbstractArrow setPickupItemStack(Lnet/minecraft/world/item/ItemStack;)V
|
|
public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage
|
|
public net.minecraft.world.entity.projectile.Arrow NO_EFFECT_COLOR
|
|
public net.minecraft.world.entity.projectile.Projectile hasBeenShot
|
|
public net.minecraft.world.entity.projectile.Projectile leftOwner
|
|
public net.minecraft.world.entity.projectile.Projectile preOnHit(Lnet/minecraft/world/phys/HitResult;)V
|
|
public net.minecraft.world.entity.projectile.Projectile canHitEntity(Lnet/minecraft/world/entity/Entity;)Z
|
|
public net.minecraft.world.entity.projectile.FireworkRocketEntity getDefaultItem()Lnet/minecraft/world/item/ItemStack;
|
|
public net.minecraft.world.item.CrossbowItem FIREWORK_POWER
|
|
|
|
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
|
|
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
|
Co-authored-by: MelnCat <melncatuwu@gmail.com>
|
|
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
|
index 5b7734020b496ade3740d92908ad2d399bfd55e6..e70ca1b2e6fbbc1f20e65429298d01b4ebd2dd29 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
|
@@ -414,13 +414,18 @@ public class FishingHook extends Projectile {
|
|
}
|
|
} else {
|
|
// CraftBukkit start - logic to modify fishing wait time
|
|
- this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
|
- this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
|
+ this.resetTimeUntilLured(); // Paper - more projectile api - extract time until lured reset logic
|
|
// CraftBukkit end
|
|
}
|
|
}
|
|
|
|
}
|
|
+ // Paper start - more projectile api - extract time until lured reset logic
|
|
+ public void resetTimeUntilLured() {
|
|
+ this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
|
|
+ this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
|
|
+ }
|
|
+ // Paper end - more projectile api - extract time until lured reset logic
|
|
|
|
public boolean calculateOpenWater(BlockPos pos) {
|
|
FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID;
|
|
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
|
index d27e17ebf25cd842a943cf82bde05b2248c74414..06ca07edef062f21c51860146086297ca345104d 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
|
@@ -190,7 +190,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
|
}
|
|
|
|
// CraftBukkit start - call projectile hit event
|
|
- protected ProjectileDeflection preHitTargetOrDeflectSelf(HitResult movingobjectposition) {
|
|
+ public ProjectileDeflection preHitTargetOrDeflectSelf(HitResult movingobjectposition) { // Paper - protected -> public
|
|
org.bukkit.event.entity.ProjectileHitEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this, movingobjectposition);
|
|
this.hitCancelled = event != null && event.isCancelled();
|
|
if (movingobjectposition.getType() == HitResult.Type.BLOCK || !this.hitCancelled) {
|
|
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 cb34cc9443da56c0497c7a0192c8b8363c3426fe..58dc69fe319027c2b9ecfb9caf272368e81081df 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
|
|
@@ -102,6 +102,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(@Nullable HitResult hitResult) {
|
|
+ // Paper end - More projectile API
|
|
if (!this.level().isClientSide) {
|
|
ItemStack itemstack = this.getItem();
|
|
PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
|
|
@@ -113,7 +118,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
|
if (this.isLingering()) {
|
|
showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
|
|
} else {
|
|
- showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
|
|
+ showParticles = this.applySplash(potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
|
}
|
|
}
|
|
|
|
@@ -175,7 +180,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
|
|
|
}
|
|
|
|
- private boolean applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
|
|
+ private boolean applySplash(Iterable<MobEffectInstance> iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
|
|
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
|
|
List<net.minecraft.world.entity.LivingEntity> list = this.level().getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
|
|
Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
|
|
@@ -253,7 +258,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
|
|
|
|
}
|
|
|
|
- private boolean makeAreaOfEffectCloud(PotionContents potioncontents, HitResult position) { // CraftBukkit - Pass MovingObjectPosition
|
|
+ private boolean makeAreaOfEffectCloud(PotionContents potioncontents, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
|
|
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
|
|
Entity entity = this.getOwner();
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
|
index 91c2d0b40d3fca86938cd454e1415a4eea3df7c7..de4fb2654c7895cfd83ad694455ee56cb708c2f2 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
|
|
@@ -17,4 +17,65 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
|
|
@Override
|
|
public void setBounce(boolean doesBounce) {}
|
|
|
|
+ // Paper start - More projectile API
|
|
+ @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 boolean canHitEntity(org.bukkit.entity.Entity entity) {
|
|
+ return this.getHandle().canHitEntity(((CraftEntity) entity).getHandle());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void hitEntity(org.bukkit.entity.Entity entity) {
|
|
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle()));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void hitEntity(org.bukkit.entity.Entity entity, org.bukkit.util.Vector vector) {
|
|
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle(), new net.minecraft.world.phys.Vec3(vector.getX(), vector.getY(), vector.getZ())));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public net.minecraft.world.entity.projectile.Projectile getHandle() {
|
|
+ return (net.minecraft.world.entity.projectile.Projectile) entity;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final org.bukkit.projectiles.ProjectileSource getShooter() {
|
|
+ return this.getHandle().projectileSource;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public final void setShooter(org.bukkit.projectiles.ProjectileSource shooter) {
|
|
+ if (shooter instanceof CraftEntity craftEntity) {
|
|
+ this.getHandle().setOwner(craftEntity.getHandle());
|
|
+ } else {
|
|
+ this.getHandle().setOwner(null);
|
|
+ }
|
|
+ this.getHandle().projectileSource = shooter;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public java.util.UUID getOwnerUniqueId() {
|
|
+ return this.getHandle().ownerUUID;
|
|
+ }
|
|
+ // Paper end - More projectile API
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
|
index 329ca9c743a7f2feeabbfb769ff9a71f60165006..faa08ad912fa43e7a6c5a2359e23c04c059c5edf 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
|
|
@@ -58,20 +58,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
|
this.getHandle().setCritArrow(critical);
|
|
}
|
|
|
|
- @Override
|
|
- public ProjectileSource getShooter() {
|
|
- return this.getHandle().projectileSource;
|
|
- }
|
|
-
|
|
- @Override
|
|
- public void setShooter(ProjectileSource shooter) {
|
|
- if (shooter instanceof Entity) {
|
|
- this.getHandle().setOwner(((CraftEntity) shooter).getHandle());
|
|
- } else {
|
|
- this.getHandle().setOwner(null);
|
|
- }
|
|
- this.getHandle().projectileSource = shooter;
|
|
- }
|
|
+ // Paper - moved to AbstractProjectile
|
|
|
|
@Override
|
|
public boolean isInBlock() {
|
|
@@ -130,6 +117,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
|
|
|
@Override
|
|
public ItemStack getWeapon() {
|
|
+ if (this.getHandle().getWeaponItem() == null) return null; // Paper - fix NPE
|
|
return CraftItemStack.asBukkitCopy(this.getHandle().getWeaponItem());
|
|
}
|
|
|
|
@@ -149,4 +137,37 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
|
|
public String toString() {
|
|
return "CraftArrow";
|
|
}
|
|
+
|
|
+ // Paper start
|
|
+ @Override
|
|
+ public CraftItemStack getItemStack() {
|
|
+ return CraftItemStack.asCraftMirror(this.getHandle().getPickupItem());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setItemStack(final ItemStack stack) {
|
|
+ Preconditions.checkArgument(stack != null, "ItemStack cannot be null");
|
|
+ this.getHandle().setPickupItemStack(CraftItemStack.asNMSCopy(stack));
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setLifetimeTicks(int ticks) {
|
|
+ this.getHandle().life = ticks;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getLifetimeTicks() {
|
|
+ return this.getHandle().life;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public org.bukkit.Sound getHitSound() {
|
|
+ return org.bukkit.craftbukkit.CraftSound.minecraftToBukkit(this.getHandle().soundEvent);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setHitSound(org.bukkit.Sound sound) {
|
|
+ this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(sound));
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
|
index 81f5e1d866128af8fb2acc13aca715580fdf9886..88f2a9f310f30a08893f3fa68af13a54cf72fa7f 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
|
|
@@ -125,7 +125,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
|
|
|
@Override
|
|
public Color getColor() {
|
|
- return Color.fromRGB(this.getHandle().potionContents.getColor());
|
|
+ return Color.fromRGB(this.getHandle().potionContents.getColor() & 0x00FFFFFF); // Paper - skip alpha channel
|
|
}
|
|
|
|
@Override
|
|
@@ -143,7 +143,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
|
this.removeCustomEffect(effect.getType());
|
|
}
|
|
this.getHandle().addEffect(CraftPotionUtil.fromBukkit(effect));
|
|
- this.getHandle().updateColor();
|
|
+ // this.getHandle().updateColor(); // Paper - already done above
|
|
return true;
|
|
}
|
|
|
|
@@ -151,7 +151,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud
|
|
public void clearCustomEffects() {
|
|
PotionContents old = this.getHandle().potionContents;
|
|
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of()));
|
|
- this.getHandle().updateColor();
|
|
+ // this.getHandle().updateColor(); // Paper - already done above
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
|
index 5232fbef0d014edd32a5d18d4a1500ab215313f5..071be344c3265a0cd52b31ffbb02ff7a70bdf231 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
|
|
@@ -43,7 +43,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
|
this.removeCustomEffect(effect.getType());
|
|
}
|
|
this.getHandle().addEffect(CraftPotionUtil.fromBukkit(effect));
|
|
- this.getHandle().updateColor();
|
|
+ // this.getHandle().updateColor(); // Paper - already done above
|
|
return true;
|
|
}
|
|
|
|
@@ -51,7 +51,7 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
|
public void clearCustomEffects() {
|
|
PotionContents old = this.getHandle().getPotionContents();
|
|
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of()));
|
|
- this.getHandle().updateColor();
|
|
+ // this.getHandle().updateColor(); // Paper - already done above
|
|
}
|
|
|
|
@Override
|
|
@@ -117,16 +117,17 @@ public class CraftArrow extends CraftAbstractArrow implements Arrow {
|
|
|
|
@Override
|
|
public void setColor(Color color) {
|
|
- int colorRGB = (color == null) ? -1 : color.asRGB();
|
|
+ int colorRGB = (color == null) ? net.minecraft.world.entity.projectile.Arrow.NO_EFFECT_COLOR : color.asARGB(); // Paper
|
|
PotionContents old = this.getHandle().getPotionContents();
|
|
this.getHandle().setPotionContents(new PotionContents(old.potion(), Optional.of(colorRGB), old.customEffects()));
|
|
}
|
|
|
|
@Override
|
|
public Color getColor() {
|
|
- if (this.getHandle().getColor() <= -1) {
|
|
+ int color = this.getHandle().getColor(); // Paper
|
|
+ if (color == net.minecraft.world.entity.projectile.Arrow.NO_EFFECT_COLOR) { // Paper
|
|
return null;
|
|
}
|
|
- return Color.fromRGB(this.getHandle().getColor());
|
|
+ return Color.fromARGB(color); // Paper
|
|
}
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
|
index 37527713b0afa6db19eefd57aaffcb2fe3544ce6..46a4f31e2b6eee6f8dc5f8fccd7de4c48a698b61 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
|
|
@@ -389,7 +389,7 @@ public final class CraftEntityTypes {
|
|
BlockPos pos = BlockPos.containing(spawnData.x(), spawnData.y(), spawnData.z());
|
|
return new FallingBlockEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), spawnData.world().getBlockState(pos)); // Paper - create falling block entities correctly
|
|
}));
|
|
- register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), net.minecraft.world.item.ItemStack.EMPTY)));
|
|
+ register(new EntityTypeData<>(EntityType.FIREWORK_ROCKET, Firework.class, CraftFirework::new, spawnData -> new FireworkRocketEntity(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), FireworkRocketEntity.getDefaultItem()))); // Paper - pass correct default to rocket for data storage
|
|
register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new net.minecraft.world.entity.projectile.EvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null)));
|
|
register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, spawnData -> new MinecartCommandBlock(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
|
|
register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, spawnData -> new Minecart(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
|
index 1b084d63bdbb24dad45d28eed1693eb6e26e24dc..43d7bea201a52cfeacf60c75caa28dfd2c4ff164 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
|
|
@@ -34,20 +34,7 @@ public class CraftFireball extends AbstractProjectile implements Fireball {
|
|
this.getHandle().bukkitYield = yield;
|
|
}
|
|
|
|
- @Override
|
|
- public ProjectileSource getShooter() {
|
|
- return this.getHandle().projectileSource;
|
|
- }
|
|
-
|
|
- @Override
|
|
- public void setShooter(ProjectileSource shooter) {
|
|
- if (shooter instanceof CraftLivingEntity) {
|
|
- this.getHandle().setOwner(((CraftLivingEntity) shooter).getHandle());
|
|
- } else {
|
|
- this.getHandle().setOwner(null);
|
|
- }
|
|
- this.getHandle().projectileSource = shooter;
|
|
- }
|
|
+ // Paper - moved to AbstractProjectile
|
|
|
|
@Override
|
|
public Vector getDirection() {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
|
index c9e15a9d82dee935293b2e7e233f5b9b2d822448..2d54cf6f3d9696c55335f0a2057025e2034d4e13 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
|
@@ -15,24 +15,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
|
|
@@ -47,12 +49,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), org.bukkit.inventory.ItemType.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);
|
|
@@ -136,4 +138,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 ? FireworkRocketEntity.getDefaultItem() : 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 6e2f91423371ead9890095cf4b1e2299c4dcba28..9d8f4b7176e60180565e3134a14ecf19060f2621 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
|
|
@@ -196,4 +196,42 @@ 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;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getTimeUntilBite() {
|
|
+ return this.getHandle().timeUntilHooked;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setTimeUntilBite(final int ticks) {
|
|
+ com.google.common.base.Preconditions.checkArgument(ticks >= 1, "Cannot set time until bite to less than 1 (%s<1)", ticks);
|
|
+ final FishingHook hook = this.getHandle();
|
|
+
|
|
+ // Reset the fish angle hook only when this call "enters" the fish into the lure stage.
|
|
+ final boolean alreadyInLuringPhase = hook.timeUntilHooked > 0 && hook.timeUntilLured <= 0;
|
|
+ if (!alreadyInLuringPhase) {
|
|
+ hook.fishAngle = net.minecraft.util.Mth.nextFloat(hook.random, hook.minLureAngle, hook.maxLureAngle);
|
|
+ hook.timeUntilLured = 0;
|
|
+ }
|
|
+
|
|
+ hook.timeUntilHooked = ticks;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void resetFishingState() {
|
|
+ final FishingHook hook = this.getHandle();
|
|
+ hook.resetTimeUntilLured();
|
|
+ hook.timeUntilHooked = 0; // Reset time until hooked, will be repopulated once lured time is ticked down.
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
|
index 0ed2910e64b6efdb4180c5bc23a146aced87c3d9..6350d4729fa3fbd9b15f1150cb4322f1c685044a 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
|
@@ -570,8 +570,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
|
}
|
|
|
|
@Override
|
|
- @SuppressWarnings("unchecked")
|
|
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
|
|
+ // Paper start - launchProjectile consumer
|
|
+ return this.launchProjectile(projectile, velocity, null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ @SuppressWarnings("unchecked")
|
|
+ public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity, java.util.function.Consumer<? super T> function) {
|
|
+ // Paper end - launchProjectile consumer
|
|
Preconditions.checkState(!this.getHandle().generation, "Cannot launch projectile during world generation");
|
|
|
|
net.minecraft.world.level.Level world = ((CraftWorld) this.getWorld()).getHandle();
|
|
@@ -597,7 +604,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
|
} else {
|
|
launch = new net.minecraft.world.entity.projectile.Arrow(world, this.getHandle(), new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ARROW), null);
|
|
}
|
|
- ((net.minecraft.world.entity.projectile.AbstractArrow) launch).shootFromRotation(this.getHandle(), this.getHandle().getXRot(), this.getHandle().getYRot(), 0.0F, 3.0F, 1.0F); // ItemBow
|
|
+ ((net.minecraft.world.entity.projectile.AbstractArrow) launch).shootFromRotation(this.getHandle(), this.getHandle().getXRot(), this.getHandle().getYRot(), 0.0F, Trident.class.isAssignableFrom(projectile) ? net.minecraft.world.item.TridentItem.SHOOT_POWER : 3.0F, 1.0F); // ItemBow // Paper - see TridentItem
|
|
} else if (ThrownPotion.class.isAssignableFrom(projectile)) {
|
|
if (LingeringPotion.class.isAssignableFrom(projectile)) {
|
|
launch = new net.minecraft.world.entity.projectile.ThrownPotion(world, this.getHandle());
|
|
@@ -656,8 +663,26 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
|
} else if (Firework.class.isAssignableFrom(projectile)) {
|
|
Location location = this.getEyeLocation();
|
|
|
|
- launch = new FireworkRocketEntity(world, net.minecraft.world.item.ItemStack.EMPTY, this.getHandle());
|
|
- launch.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
|
+ // Paper start - see CrossbowItem
|
|
+ launch = new FireworkRocketEntity(world, FireworkRocketEntity.getDefaultItem(), this.getHandle(), location.getX(), location.getY() - 0.15F, location.getZ(), true); // Paper - pass correct default to rocket for data storage & see CrossbowItem for regular launch without elytra boost
|
|
+
|
|
+ // Lifted from net.minecraft.world.item.ProjectileWeaponItem.shoot
|
|
+ float f2 = /* net.minecraft.world.item.enchantment.EnchantmentHelper.processProjectileSpread((ServerLevel) world, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.CROSSBOW), this.getHandle(), 0.0F); */ 0; // Just shortcut this to 0, no need to do any calculations on a non existing stack
|
|
+ int projectileSize = 1;
|
|
+ int i = 0;
|
|
+
|
|
+ float f3 = projectileSize == 1 ? 0.0F : 2.0F * f2 / (float) (projectileSize - 1);
|
|
+ float f4 = (float) ((projectileSize - 1) % 2) * f3 / 2.0F;
|
|
+ float f5 = 1.0F;
|
|
+ float yaw = f4 + f5 * (float) ((i + 1) / 2) * f3;
|
|
+
|
|
+ // Lifted from net.minecraft.world.item.CrossbowItem.shootProjectile
|
|
+ Vec3 vec3 = this.getHandle().getUpVector(1.0F);
|
|
+ org.joml.Quaternionf quaternionf = new org.joml.Quaternionf().setAngleAxis((double)(yaw * (float) (Math.PI / 180.0)), vec3.x, vec3.y, vec3.z);
|
|
+ Vec3 vec32 = this.getHandle().getViewVector(1.0F);
|
|
+ org.joml.Vector3f vector3f = vec32.toVector3f().rotate(quaternionf);
|
|
+ ((FireworkRocketEntity) launch).shoot((double)vector3f.x(), (double)vector3f.y(), (double)vector3f.z(), net.minecraft.world.item.CrossbowItem.FIREWORK_POWER, 1.0F);
|
|
+ // Paper end
|
|
}
|
|
|
|
Preconditions.checkArgument(launch != null, "Projectile (%s) not supported", projectile.getName());
|
|
@@ -665,6 +690,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
|
if (velocity != null) {
|
|
((T) launch.getBukkitEntity()).setVelocity(velocity);
|
|
}
|
|
+ // Paper start - launchProjectile consumer
|
|
+ if (function != null) {
|
|
+ function.accept((T) launch.getBukkitEntity());
|
|
+ }
|
|
+ // Paper end - launchProjectile consumer
|
|
|
|
world.addFreshEntity(launch);
|
|
return (T) launch.getBukkitEntity();
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
|
index 70cbc6c668c60e9d608ca7013b72f9b916c05c2d..47633f05b4fab1dcabc2117e7645fe6d6949622a 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
|
|
@@ -20,13 +20,5 @@ public class CraftLlamaSpit extends AbstractProjectile implements LlamaSpit {
|
|
return "CraftLlamaSpit";
|
|
}
|
|
|
|
- @Override
|
|
- public ProjectileSource getShooter() {
|
|
- return (this.getHandle().getOwner() != null) ? (ProjectileSource) this.getHandle().getOwner().getBukkitEntity() : null;
|
|
- }
|
|
-
|
|
- @Override
|
|
- public void setShooter(ProjectileSource source) {
|
|
- this.getHandle().setOwner((source != null) ? ((CraftLivingEntity) source).getHandle() : null);
|
|
- }
|
|
+ // Paper - moved to AbstractProjectile
|
|
}
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
|
index 696fdfa723aa896a67946f862d7c6890f7f7ab17..4f1fa7dec78970bdfc184d3c1f1632dc9d75a574 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java
|
|
@@ -10,20 +10,7 @@ public abstract class CraftProjectile extends AbstractProjectile implements Proj
|
|
super(server, entity);
|
|
}
|
|
|
|
- @Override
|
|
- public ProjectileSource getShooter() {
|
|
- return this.getHandle().projectileSource;
|
|
- }
|
|
-
|
|
- @Override
|
|
- public void setShooter(ProjectileSource shooter) {
|
|
- if (shooter instanceof CraftLivingEntity) {
|
|
- this.getHandle().setOwner((LivingEntity) ((CraftLivingEntity) shooter).entity);
|
|
- } else {
|
|
- this.getHandle().setOwner(null);
|
|
- }
|
|
- this.getHandle().projectileSource = shooter;
|
|
- }
|
|
+ // Paper - moved to AbstractProjectile
|
|
|
|
@Override
|
|
public net.minecraft.world.entity.projectile.Projectile getHandle() {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
|
index d685d09cae5f862c0004f148298c800736d2139e..b3797a43eeee11cb7ae0774d61bd5f195d0aa3ad 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
|
|
@@ -12,31 +12,56 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul
|
|
super(server, entity);
|
|
}
|
|
|
|
+ // Paper - moved to AbstractProjectile
|
|
+
|
|
+ @Override
|
|
+ public org.bukkit.entity.Entity getTarget() {
|
|
+ return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null;
|
|
+ }
|
|
+
|
|
@Override
|
|
- public ProjectileSource getShooter() {
|
|
- return this.getHandle().projectileSource;
|
|
+ public void setTarget(org.bukkit.entity.Entity target) {
|
|
+ Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
|
+
|
|
+ this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
|
|
}
|
|
|
|
@Override
|
|
- public void setShooter(ProjectileSource shooter) {
|
|
- if (shooter instanceof Entity) {
|
|
- this.getHandle().setOwner(((CraftEntity) shooter).getHandle());
|
|
- } else {
|
|
- this.getHandle().setOwner(null);
|
|
+ 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() {
|
|
+ net.minecraft.core.Direction dir = this.getHandle().currentMoveDirection;
|
|
+ if (dir == null) {
|
|
+ return null; // random dir
|
|
}
|
|
- this.getHandle().projectileSource = shooter;
|
|
+ return org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(dir);
|
|
}
|
|
|
|
@Override
|
|
- public org.bukkit.entity.Entity getTarget() {
|
|
- return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null;
|
|
+ public void setCurrentMovementDirection(org.bukkit.block.BlockFace movementDirection) {
|
|
+ this.getHandle().currentMoveDirection = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(movementDirection);
|
|
}
|
|
|
|
@Override
|
|
- public void setTarget(org.bukkit.entity.Entity target) {
|
|
- Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
|
+ public int getFlightSteps() {
|
|
+ return this.getHandle().flightSteps;
|
|
+ }
|
|
|
|
- this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
|
|
+ @Override
|
|
+ public void setFlightSteps(int steps) {
|
|
+ this.getHandle().flightSteps = steps;
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
|
index d67a80161b3e7c1fe02a6ed9d341c00dc7c2847a..f6fa6f1ac50b757dd3bc9a8dee9f6085446182c8 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
|
|
@@ -36,11 +36,31 @@ public class CraftThrownPotion extends CraftThrowableProjectile implements Throw
|
|
@Override
|
|
public void setItem(ItemStack item) {
|
|
Preconditions.checkArgument(item != null, "ItemStack cannot be null");
|
|
- Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", item.getType());
|
|
+ // Preconditions.checkArgument(item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION, "ItemStack material must be Material.LINGERING_POTION or Material.SPLASH_POTION but was Material.%s", 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().getItem(), org.bukkit.inventory.ItemType.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) this.entity;
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
|
index e374b9f40eddca13b30855d25a2030f8df98138f..4fc893378fb0568ddcffc7593d66df6bfe23f659 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
|
|
@@ -53,5 +53,15 @@ public class CraftTrident extends CraftAbstractArrow 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/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
index 5fc6ef13cdc9df11b0fd2b0baf3cec862ccb5e37..eeb326a115020f571e96f3ec85408950b5eb56fb 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
|
@@ -843,19 +843,19 @@ public class CraftEventFactory {
|
|
/**
|
|
* PotionSplashEvent
|
|
*/
|
|
- public static PotionSplashEvent callPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, HitResult position, Map<LivingEntity, Double> affectedEntities) {
|
|
+ public static PotionSplashEvent callPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, @Nullable HitResult position, Map<LivingEntity, Double> affectedEntities) { // Paper - nullable hitResult
|
|
ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity();
|
|
|
|
Block hitBlock = null;
|
|
BlockFace hitFace = null;
|
|
- if (position.getType() == HitResult.Type.BLOCK) {
|
|
+ if (position != null && position.getType() == HitResult.Type.BLOCK) { // Paper - nullable hitResult
|
|
BlockHitResult positionBlock = (BlockHitResult) position;
|
|
hitBlock = CraftBlock.at(potion.level(), positionBlock.getBlockPos());
|
|
hitFace = CraftBlock.notchToBlockFace(positionBlock.getDirection());
|
|
}
|
|
|
|
org.bukkit.entity.Entity hitEntity = null;
|
|
- if (position.getType() == HitResult.Type.ENTITY) {
|
|
+ if (position != null && position.getType() == HitResult.Type.ENTITY) { // Paper - nullable hitResult
|
|
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
|
}
|
|
|
|
@@ -864,20 +864,20 @@ public class CraftEventFactory {
|
|
return event;
|
|
}
|
|
|
|
- public static LingeringPotionSplashEvent callLingeringPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, HitResult position, net.minecraft.world.entity.AreaEffectCloud cloud) {
|
|
+ public static LingeringPotionSplashEvent callLingeringPotionSplashEvent(net.minecraft.world.entity.projectile.ThrownPotion potion, @Nullable HitResult position, net.minecraft.world.entity.AreaEffectCloud cloud) { // Paper - nullable hitResult
|
|
ThrownPotion thrownPotion = (ThrownPotion) potion.getBukkitEntity();
|
|
AreaEffectCloud effectCloud = (AreaEffectCloud) cloud.getBukkitEntity();
|
|
|
|
Block hitBlock = null;
|
|
BlockFace hitFace = null;
|
|
- if (position.getType() == HitResult.Type.BLOCK) {
|
|
+ if (position != null && position.getType() == HitResult.Type.BLOCK) { // Paper
|
|
BlockHitResult positionBlock = (BlockHitResult) position;
|
|
hitBlock = CraftBlock.at(potion.level(), positionBlock.getBlockPos());
|
|
hitFace = CraftBlock.notchToBlockFace(positionBlock.getDirection());
|
|
}
|
|
|
|
org.bukkit.entity.Entity hitEntity = null;
|
|
- if (position.getType() == HitResult.Type.ENTITY) {
|
|
+ if (position != null && position.getType() == HitResult.Type.ENTITY) { // Paper
|
|
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
|
}
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
index e8a455eb5e17bcfcae3f03664f2b47773fbdf37e..08178a88ba7d0881a6c2843eef24a846cf07adb4 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
|
@@ -329,12 +329,23 @@ 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 itemMeta) {
|
|
+ final CraftMetaItem.Applicator tag = new CraftMetaItem.Applicator();
|
|
+ ((CraftMetaItem) itemMeta).applyToItem(tag);
|
|
+ itemStack.applyComponents(tag.build());
|
|
+ }
|
|
|
|
public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item) {
|
|
+ return getItemMeta(item, null);
|
|
+ }
|
|
+ public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType) {
|
|
+ // Paper end
|
|
if (!CraftItemStack.hasItemMeta(item)) {
|
|
return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item));
|
|
}
|
|
|
|
+ if (metaForType != null) { return ((CraftItemType<?>) metaForType).getItemMeta(item); } // Paper
|
|
return ((CraftItemType<?>) CraftItemType.minecraftToBukkitNew(item.getItem())).getItemMeta(item);
|
|
}
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
|
index 93b9e6b32798e32026492fa3f80de9d4a7b3d9a5..baab2e097777a4295e7b14957304c927640a4a77 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
|
|
@@ -55,7 +55,15 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
|
|
|
@Override
|
|
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
|
|
+ // Paper start - launchProjectile consumer
|
|
+ return this.launchProjectile(projectile, velocity, null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity, java.util.function.Consumer<? super T> function) {
|
|
+ // Paper end - launchProjectile consumer
|
|
Preconditions.checkArgument(this.getBlock().getType() == Material.DISPENSER, "Block is no longer dispenser");
|
|
+
|
|
// Copied from BlockDispenser.dispense()
|
|
BlockSource sourceblock = new BlockSource((ServerLevel) this.dispenserBlock.getLevel(), this.dispenserBlock.getBlockPos(), this.dispenserBlock.getBlockState(), this.dispenserBlock);
|
|
// Copied from DispenseBehaviorProjectile
|
|
@@ -88,7 +96,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
|
} else if (Fireball.class.isAssignableFrom(projectile)) {
|
|
if (AbstractWindCharge.class.isAssignableFrom(projectile)) {
|
|
item = Items.WIND_CHARGE;
|
|
- } else {
|
|
+ } else if (org.bukkit.entity.SmallFireball.class.isAssignableFrom(projectile)) { // Paper - more projectile API - only allow firing fire charges.
|
|
item = Items.FIRE_CHARGE;
|
|
}
|
|
} else if (Firework.class.isAssignableFrom(projectile)) {
|
|
@@ -104,7 +112,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
|
Position iposition = dispenseConfig.positionFunction().getDispensePosition(sourceblock, enumdirection);
|
|
net.minecraft.world.entity.projectile.Projectile launch = projectileItem.asProjectile(world, iposition, itemstack, enumdirection);
|
|
|
|
- if (Fireball.class.isAssignableFrom(projectile)) {
|
|
+ if (false && Fireball.class.isAssignableFrom(projectile)) { // Paper - more project API - dispensers cannot launch anything but fire charges.
|
|
AbstractHurtingProjectile customFireball = null;
|
|
if (WitherSkull.class.isAssignableFrom(projectile)) {
|
|
launch = customFireball = EntityType.WITHER_SKULL.create(world);
|
|
@@ -129,7 +137,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
|
}
|
|
}
|
|
|
|
- if (launch instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) {
|
|
+ if (false && launch instanceof net.minecraft.world.entity.projectile.AbstractArrow arrow) { // Paper - more projectile API - this is set by the respective ArrowItem when constructing the projectile
|
|
arrow.pickup = net.minecraft.world.entity.projectile.AbstractArrow.Pickup.ALLOWED;
|
|
}
|
|
launch.projectileSource = this;
|
|
@@ -138,6 +146,11 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
|
|
if (velocity != null) {
|
|
((T) launch.getBukkitEntity()).setVelocity(velocity);
|
|
}
|
|
+ // Paper start
|
|
+ if (function != null) {
|
|
+ function.accept((T) launch.getBukkitEntity());
|
|
+ }
|
|
+ // Paper end
|
|
|
|
world.addFreshEntity(launch);
|
|
return (T) launch.getBukkitEntity();
|