2022-03-11 17:37:08 +01:00
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
2022-11-20 00:53:20 +01:00
== AT ==
public net.minecraft.world.entity.projectile.FishingHook timeUntilLured
2024-05-29 23:45:01 +02:00
public net.minecraft.world.entity.projectile.FishingHook fishAngle
2022-11-20 00:53:20 +01:00
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
2024-10-21 18:17:45 +02:00
public net.minecraft.world.entity.projectile.AbstractArrow setPickupItemStack(Lnet/minecraft/world/item/ItemStack;)V
2022-11-20 00:53:20 +01:00
public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage
2024-06-04 22:55:29 +02:00
public net.minecraft.world.entity.projectile.Arrow NO_EFFECT_COLOR
2022-11-20 00:53:20 +01:00
public net.minecraft.world.entity.projectile.Projectile hasBeenShot
public net.minecraft.world.entity.projectile.Projectile leftOwner
2024-10-25 17:08:48 +02:00
public net.minecraft.world.entity.projectile.Projectile ownerUUID
2023-02-11 16:41:06 +01:00
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
2024-05-26 00:58:56 +02:00
public net.minecraft.world.entity.projectile.FireworkRocketEntity getDefaultItem()Lnet/minecraft/world/item/ItemStack;
2024-09-21 21:19:02 +02:00
public net.minecraft.world.item.CrossbowItem FIREWORK_POWER
2022-11-20 00:53:20 +01:00
2022-08-14 16:53:36 +02:00
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2024-05-29 23:45:01 +02:00
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
2024-09-21 21:19:02 +02:00
Co-authored-by: MelnCat <melncatuwu@gmail.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
2022-03-11 17:37:08 +01:00
2024-05-29 23:45:01 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
2024-12-03 19:54:10 +01:00
index 966ba1a9c2e7923a970ce3799a5e2ef6ca36bf84..a2487ca0d7794e58d9ede35d9be5a05a7ea7b03c 100644
2024-05-29 23:45:01 +02:00
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
2024-10-23 22:52:43 +02:00
@@ -419,13 +419,18 @@ public class FishingHook extends Projectile {
2024-05-29 23:45:01 +02:00
}
} else {
// CraftBukkit start - logic to modify fishing wait time
- this.timeUntilLured = Mth.nextInt(this.random, this.minWaitTime, this.maxWaitTime);
2024-06-14 03:30:23 +02:00
- 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
2024-05-29 23:45:01 +02:00
// 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);
2024-06-14 03:30:23 +02:00
+ this.timeUntilLured -= (this.applyLure) ? (this.lureSpeed >= this.maxWaitTime ? this.timeUntilLured - 1 : this.lureSpeed ) : 0; // Paper - Fix Lure infinite loop
2024-05-29 23:45:01 +02:00
+ }
+ // Paper end - more projectile api - extract time until lured reset logic
public boolean calculateOpenWater(BlockPos pos) {
FishingHook.OpenWaterType entityfishinghook_waterposition = FishingHook.OpenWaterType.INVALID;
2024-04-26 03:51:28 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
2024-12-03 19:54:10 +01:00
index 5cff58ab33657e7fb2642928e42b728e7b0b4689..f3781e37358f970b56e5b8de77ef224151270f1c 100644
2024-04-26 03:51:28 +02:00
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
2024-10-23 22:52:43 +02:00
@@ -288,7 +288,7 @@ public abstract class Projectile extends Entity implements TraceableEntity {
2024-04-26 03:51:28 +02:00
}
// 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) {
2022-08-14 16:53:36 +02:00
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
2024-10-23 22:52:43 +02:00
index d6ac07d9d5ee0430a1d91b7084b378aac1d047e5..a486466040a646b8a5a5ff2430cdd25b95b7e20f 100644
2022-08-14 16:53:36 +02:00
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
2024-10-23 22:52:43 +02:00
@@ -103,8 +103,12 @@ public class ThrownPotion extends ThrowableItemProjectile {
2022-08-14 16:53:36 +02:00
@Override
protected void onHit(HitResult hitResult) {
super.onHit(hitResult);
+ // Paper start - More projectile API
+ this.splash(hitResult);
+ }
2024-02-10 20:27:29 +01:00
+ public void splash(@Nullable HitResult hitResult) {
2022-08-14 16:53:36 +02:00
+ // Paper end - More projectile API
2024-10-23 22:52:43 +02:00
Level world = this.level();
-
if (world instanceof ServerLevel worldserver) {
2022-08-14 16:53:36 +02:00
ItemStack itemstack = this.getItem();
2024-04-24 22:05:42 +02:00
PotionContents potioncontents = (PotionContents) itemstack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY);
2024-10-23 22:52:43 +02:00
@@ -116,7 +120,7 @@ public class ThrownPotion extends ThrowableItemProjectile {
2022-08-14 16:53:36 +02:00
if (this.isLingering()) {
2024-04-25 01:25:57 +02:00
showParticles = this.makeAreaOfEffectCloud(potioncontents, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
2022-08-14 16:53:36 +02:00
} else {
2024-10-23 22:52:43 +02:00
- showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper
+ showParticles = this.applySplash(worldserver, potioncontents.getAllEffects(), hitResult != null && hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null, hitResult); // CraftBukkit - Pass MovingObjectPosition // Paper - More projectile API
2022-08-14 16:53:36 +02:00
}
}
2024-10-23 22:52:43 +02:00
@@ -178,7 +182,7 @@ public class ThrownPotion extends ThrowableItemProjectile {
2023-10-29 00:02:13 +02:00
}
2024-10-23 22:52:43 +02:00
- private boolean applySplash(ServerLevel worldserver, Iterable<MobEffectInstance> iterable, @Nullable Entity entity, HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events
+ private boolean applySplash(ServerLevel worldserver, Iterable<MobEffectInstance> iterable, @Nullable Entity entity, @Nullable HitResult position) { // CraftBukkit - Pass MovingObjectPosition // Paper - Fix potions splash events & More projectile API
2023-10-29 00:02:13 +02:00
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
2024-10-23 22:52:43 +02:00
List<net.minecraft.world.entity.LivingEntity> list = worldserver.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
2023-10-29 00:02:13 +02:00
Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
2024-10-23 22:52:43 +02:00
@@ -256,7 +260,7 @@ public class ThrownPotion extends ThrowableItemProjectile {
2023-10-29 00:02:13 +02:00
}
2024-04-24 22:05:42 +02:00
- 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
2023-10-29 00:02:13 +02:00
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
Entity entity = this.getOwner();
2022-10-11 23:04:26 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
2024-04-26 03:51:28 +02:00
index 91c2d0b40d3fca86938cd454e1415a4eea3df7c7..de4fb2654c7895cfd83ad694455ee56cb708c2f2 100644
2022-10-11 23:04:26 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
2023-09-29 02:28:26 +02:00
@@ -17,4 +17,65 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
@Override
public void setBounce(boolean doesBounce) {}
2024-01-18 18:52:00 +01:00
+ // Paper start - More projectile API
2022-10-11 23:04:26 +02:00
+ @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
2023-02-11 16:41:06 +01:00
+ public boolean canHitEntity(org.bukkit.entity.Entity entity) {
+ return this.getHandle().canHitEntity(((CraftEntity) entity).getHandle());
+ }
+
+ @Override
+ public void hitEntity(org.bukkit.entity.Entity entity) {
2024-04-26 03:51:28 +02:00
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle()));
2023-02-11 16:41:06 +01:00
+ }
+
+ @Override
+ public void hitEntity(org.bukkit.entity.Entity entity, org.bukkit.util.Vector vector) {
2024-04-26 03:51:28 +02:00
+ this.getHandle().preHitTargetOrDeflectSelf(new net.minecraft.world.phys.EntityHitResult(((CraftEntity) entity).getHandle(), new net.minecraft.world.phys.Vec3(vector.getX(), vector.getY(), vector.getZ())));
2023-02-11 16:41:06 +01:00
+ }
+
+ @Override
2022-10-11 23:04:26 +02:00
+ public net.minecraft.world.entity.projectile.Projectile getHandle() {
+ return (net.minecraft.world.entity.projectile.Projectile) entity;
+ }
2023-06-01 04:43:51 +02:00
+
+ @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;
+ }
2024-01-18 18:52:00 +01:00
+ // Paper end - More projectile API
2022-10-11 23:04:26 +02:00
}
2024-04-25 19:42:24 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
2024-10-23 22:52:43 +02:00
index 0f85c1f991469b277bba8b40b087f7224b4b3a85..1f30109abd86b76af343eb5eb75ec3db83ef9417 100644
2024-04-25 19:42:24 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractArrow.java
2024-10-23 22:52:43 +02:00
@@ -59,20 +59,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
2024-04-25 19:42:24 +02:00
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;
- }
2024-05-26 19:57:38 +02:00
+ // Paper - moved to AbstractProjectile
2024-04-25 19:42:24 +02:00
@Override
public boolean isInBlock() {
2024-10-23 22:52:43 +02:00
@@ -133,6 +120,7 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
2024-06-21 18:48:29 +02:00
@Override
public ItemStack getWeapon() {
+ if (this.getHandle().getWeaponItem() == null) return null; // Paper - fix NPE
return CraftItemStack.asBukkitCopy(this.getHandle().getWeaponItem());
}
2024-10-23 22:52:43 +02:00
@@ -152,4 +140,37 @@ public class CraftAbstractArrow extends AbstractProjectile implements AbstractAr
2024-04-26 03:51:28 +02:00
public String toString() {
return "CraftArrow";
2022-10-11 23:04:26 +02:00
}
2024-04-26 03:51:28 +02:00
+
2024-03-23 22:26:17 +01:00
+ // Paper start
+ @Override
2024-06-15 16:40:29 +02:00
+ 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));
2024-03-23 22:26:17 +01:00
+ }
+
2022-10-11 23:04:26 +02:00
+ @Override
+ public void setLifetimeTicks(int ticks) {
+ this.getHandle().life = ticks;
+ }
+
+ @Override
+ public int getLifetimeTicks() {
+ return this.getHandle().life;
+ }
+
+ @Override
+ public org.bukkit.Sound getHitSound() {
2023-09-23 04:06:03 +02:00
+ return org.bukkit.craftbukkit.CraftSound.minecraftToBukkit(this.getHandle().soundEvent);
2022-10-11 23:04:26 +02:00
+ }
+
+ @Override
2024-04-26 03:51:28 +02:00
+ public void setHitSound(org.bukkit.Sound sound) {
2023-09-23 04:06:03 +02:00
+ this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(sound));
2022-10-11 23:04:26 +02:00
+ }
2024-03-23 22:26:17 +01:00
+ // Paper end
2024-04-26 03:51:28 +02:00
}
2024-06-04 22:55:29 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java
2024-10-23 22:52:43 +02:00
index 6591513bb62226b6f85fd2ef9f6ebe376f0f7362..f9c113dc018702159345240d6d0de85767afa0c3 100644
2024-06-04 22:55:29 +02:00
--- 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;
2024-10-23 22:52:43 +02:00
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of(), old.customName()));
2024-06-04 22:55:29 +02:00
- 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
2024-10-23 22:52:43 +02:00
index 199d5836dc787cca54c6b653a4e67573f2f758a2..15d50a284cafc2eb59239ca00926836526f09e06 100644
2024-06-04 22:55:29 +02:00
--- 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();
2024-10-23 22:52:43 +02:00
this.getHandle().setPotionContents(new PotionContents(old.potion(), old.customColor(), List.of(), old.customName()));
2024-06-04 22:55:29 +02:00
- 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();
2024-10-23 22:52:43 +02:00
this.getHandle().setPotionContents(new PotionContents(old.potion(), Optional.of(colorRGB), old.customEffects(), old.customName()));
2024-06-04 22:55:29 +02:00
}
@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
}
}
2024-05-26 00:58:56 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
2024-12-03 19:54:10 +01:00
index f3ad9c57ce2fc06b90b7ab7e1f31ef0e1b564c9f..2a32f2aa3cb7395900cf2d06cc2dcd4ddacd4145 100644
2024-05-26 00:58:56 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java
2024-12-03 19:54:10 +01:00
@@ -440,7 +440,7 @@ public final class CraftEntityTypes {
2024-05-26 00:58:56 +02:00
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)));
2024-10-23 22:52:43 +02:00
register(new EntityTypeData<>(EntityType.COMMAND_BLOCK_MINECART, CommandMinecart.class, CraftMinecartCommand::new, createMinecart(net.minecraft.world.entity.EntityType.COMMAND_BLOCK_MINECART)));
register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, createMinecart(net.minecraft.world.entity.EntityType.MINECART)));
2023-06-01 04:43:51 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
2024-06-14 03:30:23 +02:00
index 1b084d63bdbb24dad45d28eed1693eb6e26e24dc..43d7bea201a52cfeacf60c75caa28dfd2c4ff164 100644
2023-06-01 04:43:51 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java
2024-06-14 03:30:23 +02:00
@@ -34,20 +34,7 @@ public class CraftFireball extends AbstractProjectile implements Fireball {
2023-06-01 04:43:51 +02:00
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() {
2022-03-11 17:37:08 +01:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
2024-06-15 18:28:18 +02:00
index c9e15a9d82dee935293b2e7e233f5b9b2d822448..2d54cf6f3d9696c55335f0a2057025e2034d4e13 100644
2022-03-11 17:37:08 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
2023-08-14 01:32:51 +02:00
@@ -15,24 +15,26 @@ import org.bukkit.inventory.meta.FireworkMeta;
2022-03-11 17:37:08 +01:00
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);
- }
2024-05-26 19:57:38 +02:00
+ // Paper start - Expose firework item directly
2022-03-11 17:37:08 +01:00
+// 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);
+// }
2024-01-19 22:13:42 +01:00
+ // Paper end - Expose firework item directly
2022-03-11 17:37:08 +01:00
}
@Override
2023-08-14 01:32:51 +02:00
@@ -47,12 +49,12 @@ public class CraftFirework extends CraftProjectile implements Firework {
2022-03-11 17:37:08 +01:00
@Override
public FireworkMeta getFireworkMeta() {
- return (FireworkMeta) this.item.getItemMeta();
2024-06-15 18:28:18 +02:00
+ return (FireworkMeta) CraftItemStack.getItemMeta(this.getHandle().getEntityData().get(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM), org.bukkit.inventory.ItemType.FIREWORK_ROCKET); // Paper - Expose firework item directly
2022-03-11 17:37:08 +01:00
}
@Override
public void setFireworkMeta(FireworkMeta meta) {
- this.item.setItemMeta(meta);
+ applyFireworkEffect(meta); // Paper - Expose firework item directly
2022-03-12 21:34:03 +01:00
2022-03-11 17:37:08 +01:00
// Copied from EntityFireworks constructor, update firework lifetime/power
this.getHandle().lifetime = 10 * (1 + meta.getPower()) + this.random.nextInt(6) + this.random.nextInt(7);
2023-08-14 01:32:51 +02:00
@@ -136,4 +138,46 @@ public class CraftFirework extends CraftProjectile implements Firework {
2022-09-12 13:31:45 +02:00
return getHandle().spawningEntity;
2022-03-11 17:37:08 +01:00
}
// 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();
2024-05-26 19:57:38 +02:00
+ ItemStack nmsItem = itemStack == null ? FireworkRocketEntity.getDefaultItem() : CraftItemStack.asNMSCopy(itemStack);
2022-03-11 17:37:08 +01:00
+ 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) {
2022-03-12 21:34:03 +01:00
+ ItemStack item = this.getHandle().getItem();
+ CraftItemStack.applyMetaToItem(item, meta);
+
+ this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_ID_FIREWORKS_ITEM, item);
2022-03-11 17:37:08 +01:00
+ }
+ // Paper end - Expose firework item directly + manually setting flight
}
2022-03-13 23:33:01 +01:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
2024-05-29 23:45:01 +02:00
index 6e2f91423371ead9890095cf4b1e2299c4dcba28..9d8f4b7176e60180565e3134a14ecf19060f2621 100644
2022-03-13 23:33:01 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFishHook.java
2024-05-29 23:45:01 +02:00
@@ -196,4 +196,42 @@ public class CraftFishHook extends CraftProjectile implements FishHook {
2022-03-13 23:33:01 +01:00
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;
+ }
2024-05-29 23:45:01 +02:00
+
+ @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.
+ }
2022-03-13 23:33:01 +01:00
+ // Paper end
}
2024-05-26 00:58:56 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
2024-12-03 19:54:10 +01:00
index 10a95c1a40597867ffd2974037bfed86dd6deda4..2028f9874e96a3b274528858d4149b04a075f256 100644
2024-05-26 00:58:56 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
2024-10-23 22:52:43 +02:00
@@ -579,8 +579,15 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
2024-09-21 21:19:02 +02:00
}
@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();
2024-10-23 22:52:43 +02:00
@@ -606,7 +613,7 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
2024-06-23 23:37:20 +02:00
} 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)) {
2024-10-23 22:52:43 +02:00
launch = new net.minecraft.world.entity.projectile.ThrownPotion(world, this.getHandle(), new net.minecraft.world.item.ItemStack(Items.LINGERING_POTION));
@@ -663,8 +670,26 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
2024-05-26 00:58:56 +02:00
} else if (Firework.class.isAssignableFrom(projectile)) {
Location location = this.getEyeLocation();
- launch = new FireworkRocketEntity(world, net.minecraft.world.item.ItemStack.EMPTY, this.getHandle());
2024-09-21 21:19:02 +02:00
- 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());
2024-10-23 22:52:43 +02:00
@@ -672,6 +697,11 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
2024-09-21 21:19:02 +02:00
if (velocity != null) {
((T) launch.getBukkitEntity()).setVelocity(velocity);
2024-05-26 00:58:56 +02:00
}
2024-09-21 21:19:02 +02:00
+ // Paper start - launchProjectile consumer
+ if (function != null) {
+ function.accept((T) launch.getBukkitEntity());
+ }
+ // Paper end - launchProjectile consumer
2024-05-26 00:58:56 +02:00
2024-09-21 21:19:02 +02:00
world.addFreshEntity(launch);
return (T) launch.getBukkitEntity();
2023-06-01 04:43:51 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
2023-08-14 01:32:51 +02:00
index 70cbc6c668c60e9d608ca7013b72f9b916c05c2d..47633f05b4fab1dcabc2117e7645fe6d6949622a 100644
2023-06-01 04:43:51 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlamaSpit.java
2023-08-14 01:32:51 +02:00
@@ -20,13 +20,5 @@ public class CraftLlamaSpit extends AbstractProjectile implements LlamaSpit {
return "CraftLlamaSpit";
2023-06-01 04:43:51 +02:00
}
- @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
2023-10-27 01:34:58 +02:00
index 696fdfa723aa896a67946f862d7c6890f7f7ab17..4f1fa7dec78970bdfc184d3c1f1632dc9d75a574 100644
2023-06-01 04:43:51 +02:00
--- 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() {
2022-10-11 23:04:26 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
2024-06-24 00:42:44 +02:00
index d685d09cae5f862c0004f148298c800736d2139e..b3797a43eeee11cb7ae0774d61bd5f195d0aa3ad 100644
2022-10-11 23:04:26 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
2024-06-24 00:42:44 +02:00
@@ -12,31 +12,56 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul
2023-06-01 04:43:51 +02:00
super(server, entity);
}
2024-06-24 00:42:44 +02:00
+ // Paper - moved to AbstractProjectile
+
+ @Override
+ public org.bukkit.entity.Entity getTarget() {
+ return this.getHandle().getTarget() != null ? this.getHandle().getTarget().getBukkitEntity() : null;
+ }
+
@Override
2023-06-01 04:43:51 +02:00
- public ProjectileSource getShooter() {
- return this.getHandle().projectileSource;
2024-06-24 00:42:44 +02:00
+ 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
2023-06-01 04:43:51 +02:00
- public void setShooter(ProjectileSource shooter) {
- if (shooter instanceof Entity) {
- this.getHandle().setOwner(((CraftEntity) shooter).getHandle());
- } else {
- this.getHandle().setOwner(null);
2022-10-11 23:04:26 +02:00
+ 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() {
2024-06-24 00:42:44 +02:00
+ 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;
2022-10-11 23:04:26 +02:00
+ public void setCurrentMovementDirection(org.bukkit.block.BlockFace movementDirection) {
+ this.getHandle().currentMoveDirection = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(movementDirection);
2024-06-24 00:42:44 +02:00
}
@Override
- public void setTarget(org.bukkit.entity.Entity target) {
- Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
2022-10-11 23:04:26 +02:00
+ public int getFlightSteps() {
+ return this.getHandle().flightSteps;
+ }
2024-06-24 00:42:44 +02:00
- this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
2022-10-11 23:04:26 +02:00
+ @Override
+ public void setFlightSteps(int steps) {
+ this.getHandle().flightSteps = steps;
2024-06-24 00:42:44 +02:00
}
2022-10-11 23:04:26 +02:00
@Override
2022-03-11 17:37:08 +01:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
2024-06-15 18:28:18 +02:00
index d67a80161b3e7c1fe02a6ed9d341c00dc7c2847a..f6fa6f1ac50b757dd3bc9a8dee9f6085446182c8 100644
2022-03-11 17:37:08 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
2024-04-24 22:05:42 +02:00
@@ -36,11 +36,31 @@ public class CraftThrownPotion extends CraftThrowableProjectile implements Throw
2023-06-13 01:51:45 +02:00
@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
2022-04-22 02:07:56 +02:00
+ org.bukkit.inventory.meta.PotionMeta meta = (item.getType() == Material.LINGERING_POTION || item.getType() == Material.SPLASH_POTION) ? null : this.getPotionMeta(); // Paper - Projectile API
2022-03-11 17:37:08 +01:00
this.getHandle().setItem(CraftItemStack.asNMSCopy(item));
2022-04-22 02:07:56 +02:00
+ if (meta != null) this.setPotionMeta(meta); // Paper - Projectile API
2022-03-11 17:37:08 +01:00
}
+ // Paper start - Projectile API
+ @Override
+ public org.bukkit.inventory.meta.PotionMeta getPotionMeta() {
2024-06-15 18:28:18 +02:00
+ return (org.bukkit.inventory.meta.PotionMeta) CraftItemStack.getItemMeta(this.getHandle().getItem(), org.bukkit.inventory.ItemType.SPLASH_POTION);
2022-03-11 17:37:08 +01:00
+ }
+
+ @Override
+ public void setPotionMeta(org.bukkit.inventory.meta.PotionMeta meta) {
2022-03-12 21:34:03 +01:00
+ net.minecraft.world.item.ItemStack item = this.getHandle().getItem();
+ CraftItemStack.applyMetaToItem(item, meta);
+ this.getHandle().setItem(item); // Reset item
2022-03-11 17:37:08 +01:00
+ }
2022-08-14 16:53:36 +02:00
+
+ @Override
+ public void splash() {
+ this.getHandle().splash(null);
+ }
2022-03-11 17:37:08 +01:00
+ // Paper end
@Override
public net.minecraft.world.entity.projectile.ThrownPotion getHandle() {
2023-10-27 01:34:58 +02:00
return (net.minecraft.world.entity.projectile.ThrownPotion) this.entity;
2022-10-11 23:04:26 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
2024-04-24 22:05:42 +02:00
index e374b9f40eddca13b30855d25a2030f8df98138f..4fc893378fb0568ddcffc7593d66df6bfe23f659 100644
2022-10-11 23:04:26 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
2024-04-24 22:05:42 +02:00
@@ -53,5 +53,15 @@ public class CraftTrident extends CraftAbstractArrow implements Trident {
2022-10-11 23:04:26 +02:00
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
}
2023-10-29 00:02:13 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
Rework async chunk api implementation
Firstly, the old methods all routed to the CompletableFuture method.
However, the CF method could not guarantee that if the caller
was off-main that the future would be "completed" on-main. Since
the callback methods used the CF one, this meant that the callback
methods did not guarantee that the callbacks were to be called on
the main thread.
Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb)
so that the methods with the callback are guaranteed to invoke
the callback on the main thread. The CF behavior remains unchanged;
it may still appear to complete on main if invoked off-main.
Secondly, remove the scheduleOnMain invocation in the async
chunk completion. This unnecessarily delays the callback
by 1 tick.
Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which
will load chunks within an area. This method is provided as a helper
as keeping all chunks loaded within an area can be complicated to
implement for plugins (due to the lacking ticket API), and is
already implemented internally anyways.
Fourthly, remove the ticket addition that occured with getChunkAt
and getChunkAtAsync. The ticket addition may delay the unloading
of the chunk unnecessarily. It also fixes a very rare timing bug
where the future/callback would be completed after the chunk
unloads.
2024-11-19 07:34:32 +01:00
index a5285a8952b2d99bfbb928b1bb31d3ddcf8ed57b..ca094e393de32b64db59c9fe906433761d70d29b 100644
2023-10-29 00:02:13 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
2024-10-23 22:52:43 +02:00
@@ -841,19 +841,19 @@ public class CraftEventFactory {
2023-10-29 00:02:13 +02:00
/**
* 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();
}
2024-10-23 22:52:43 +02:00
@@ -862,20 +862,20 @@ public class CraftEventFactory {
2023-10-29 00:02:13 +02:00
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();
}
2022-03-11 17:37:08 +01:00
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
2024-10-23 22:52:43 +02:00
index 60062ea5b18b95a14c459f2f3a0743c1e1ac0f12..502be683e8b04a9966043c9bee9d9fe793b12ef5 100644
2022-03-11 17:37:08 +01:00
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
2024-10-23 22:52:43 +02:00
@@ -341,12 +341,23 @@ public final class CraftItemStack extends ItemStack {
2022-03-11 17:37:08 +01:00
public ItemMeta getItemMeta() {
return CraftItemStack.getItemMeta(this.handle);
}
+ // Paper start
2024-04-25 21:40:53 +02:00
+ 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());
2022-03-11 17:37:08 +01:00
+ }
public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item) {
2024-06-15 18:28:18 +02:00
+ return getItemMeta(item, null);
2022-03-11 17:37:08 +01:00
+ }
2024-06-15 18:28:18 +02:00
+ public static ItemMeta getItemMeta(net.minecraft.world.item.ItemStack item, org.bukkit.inventory.ItemType metaForType) {
2022-03-11 17:37:08 +01:00
+ // Paper end
if (!CraftItemStack.hasItemMeta(item)) {
2024-06-15 18:28:18 +02:00
return CraftItemFactory.instance().getItemMeta(CraftItemStack.getType(item));
2022-03-11 17:37:08 +01:00
}
2024-06-15 18:28:18 +02:00
+ if (metaForType != null) { return ((CraftItemType<?>) metaForType).getItemMeta(item); } // Paper
return ((CraftItemType<?>) CraftItemType.minecraftToBukkitNew(item.getItem())).getItemMeta(item);
}
2024-09-21 21:19:02 +02:00
diff --git a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
2024-10-23 22:52:43 +02:00
index 642f5bf75661eb485558bc227f668e84416f3b5f..76fd4d27730d9139caa67099a6757ea33d681be9 100644
2024-09-21 21:19:02 +02:00
--- a/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
+++ b/src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java
2024-10-23 22:52:43 +02:00
@@ -56,7 +56,15 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-09-21 21:19:02 +02:00
@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");
2024-10-21 00:06:54 +02:00
+
// Copied from BlockDispenser.dispense()
BlockSource sourceblock = new BlockSource((ServerLevel) this.dispenserBlock.getLevel(), this.dispenserBlock.getBlockPos(), this.dispenserBlock.getBlockState(), this.dispenserBlock);
// Copied from DispenseBehaviorProjectile
2024-10-23 22:52:43 +02:00
@@ -68,7 +76,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-10-21 18:17:45 +02:00
item = Items.SNOWBALL;
} else if (Egg.class.isAssignableFrom(projectile)) {
item = Items.EGG;
- } else if (EnderPearl.class.isAssignableFrom(projectile)) {
+ } else if (false && EnderPearl.class.isAssignableFrom(projectile)) { // Paper - more projectile API - disallow enderpearl, it is not a projectile item
item = Items.ENDER_PEARL;
} else if (ThrownExpBottle.class.isAssignableFrom(projectile)) {
item = Items.EXPERIENCE_BOTTLE;
2024-10-23 22:52:43 +02:00
@@ -83,20 +91,20 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-10-21 18:17:45 +02:00
item = Items.TIPPED_ARROW;
} else if (SpectralArrow.class.isAssignableFrom(projectile)) {
item = Items.SPECTRAL_ARROW;
- } else {
+ } else if (org.bukkit.entity.Arrow.class.isAssignableFrom(projectile)) { // Paper - more projectile API - disallow trident
item = Items.ARROW;
}
2024-10-21 00:06:54 +02:00
} else if (Fireball.class.isAssignableFrom(projectile)) {
2024-10-21 18:17:45 +02:00
- if (AbstractWindCharge.class.isAssignableFrom(projectile)) {
+ if (org.bukkit.entity.WindCharge.class.isAssignableFrom(projectile)) { // Paper - more projectile API - only allow wind charge not breeze wind charge
2024-10-21 00:06:54 +02:00
item = Items.WIND_CHARGE;
2024-09-21 21:19:02 +02:00
- } else {
2024-10-21 00:06:54 +02:00
+ } 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)) {
2024-10-21 18:17:45 +02:00
item = Items.FIREWORK_ROCKET;
}
- Preconditions.checkArgument(item instanceof ProjectileItem, "Projectile not supported");
+ Preconditions.checkArgument(item instanceof ProjectileItem, "Projectile '%s' not supported", projectile.getSimpleName()); // Paper - more projectile API - include simple name in exception
ItemStack itemstack = new ItemStack(item);
ProjectileItem projectileItem = (ProjectileItem) item;
2024-10-23 22:52:43 +02:00
@@ -105,7 +113,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-10-21 00:06:54 +02:00
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)) {
2024-10-23 22:52:43 +02:00
launch = customFireball = EntityType.WITHER_SKULL.create(world, EntitySpawnReason.TRIGGERED);
@@ -130,7 +138,7 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-09-21 21:19:02 +02:00
}
}
2024-10-21 00:06:54 +02:00
- 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;
2024-10-23 22:52:43 +02:00
@@ -139,6 +147,11 @@ public class CraftBlockProjectileSource implements BlockProjectileSource {
2024-09-21 21:19:02 +02:00
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();