More Projectile API

Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
Co-authored-by: MelnCat <melncatuwu@gmail.com>
This commit is contained in:
Owen1212055 2021-05-26 19:34:43 -04:00
parent 84be1c082d
commit b0e4de9c20
8 changed files with 366 additions and 4 deletions

View File

@ -139,17 +139,21 @@ public interface AbstractArrow extends Projectile {
* Gets the ItemStack which will be picked up from this arrow.
*
* @return The picked up ItemStack
* @deprecated use {@link #getItemStack()}
*/
@NotNull
@ApiStatus.Experimental
@Deprecated(forRemoval = true, since = "1.20.4") // Paper
public ItemStack getItem();
/**
* Sets the ItemStack which will be picked up from this arrow.
*
* @param item ItemStack set to be picked up
* @deprecated use {@link #getItemStack()}
*/
@ApiStatus.Experimental
@Deprecated(forRemoval = true, since = "1.20.4") // Paper
public void setItem(@NotNull ItemStack item);
/**
@ -220,4 +224,52 @@ public interface AbstractArrow extends Projectile {
CREATIVE_ONLY;
}
// Paper end
// Paper start - more projectile API
/**
* Gets the {@link ItemStack} for this arrow. This stack is used
* for both visuals on the arrow and the stack that could be picked up.
*
* @return The ItemStack, as if a player picked up the arrow
*/
@NotNull ItemStack getItemStack();
/**
* Sets the {@link ItemStack} for this arrow. This stack is used for both
* visuals on the arrow and the stack that could be picked up.
*
* @param stack the arrow stack
*/
void setItemStack(@NotNull ItemStack stack);
/**
* Sets the amount of ticks this arrow has been alive in the world
* This is used to determine when the arrow should be automatically despawned.
*
* @param ticks lifetime ticks
*/
void setLifetimeTicks(int ticks);
/**
* Gets how many ticks this arrow has been in the world for.
*
* @return ticks this arrow has been in the world
*/
int getLifetimeTicks();
/**
* Gets the sound that is played when this arrow hits an entity.
*
* @return sound that plays
*/
@NotNull
org.bukkit.Sound getHitSound();
/**
* Sets the sound that is played when this arrow hits an entity.
*
* @param sound sound that is played
*/
void setHitSound(@NotNull org.bukkit.Sound sound);
// Paper end - more projectile API
}

View File

@ -16,6 +16,8 @@ public interface Firework extends Projectile {
/**
* Apply the provided meta to the fireworks
* <p>
* Adjusts detonation ticks automatically.
*
* @param meta The FireworkMeta to apply
*/
@ -54,31 +56,39 @@ public interface Firework extends Projectile {
* {@link #getMaxLife()}, the firework will detonate.
*
* @param ticks the ticks to set. Must be greater than or equal to 0
* @deprecated use {@link #setTicksFlown(int)}
* @return true if the life was set, false if this firework has already detonated
*/
@Deprecated(forRemoval = true) // Paper
boolean setLife(int ticks);
/**
* Get the ticks that this firework has been alive. When this value reaches
* {@link #getMaxLife()}, the firework will detonate.
*
* @deprecated use {@link #getTicksFlown()}
* @return the life ticks
*/
@Deprecated(forRemoval = true) // Paper
int getLife();
/**
* Set the time in ticks this firework will exist until it is detonated.
*
* @param ticks the ticks to set. Must be greater than 0
* @deprecated use {@link #setTicksToDetonate(int)}
* @return true if the time was set, false if this firework has already detonated
*/
@Deprecated(forRemoval = true) // Paper
boolean setMaxLife(int ticks);
/**
* Get the time in ticks this firework will exist until it is detonated.
*
* @deprecated use {@link #getTicksToDetonate()}
* @return the maximum life in ticks
*/
@Deprecated(forRemoval = true) // Paper
int getMaxLife();
/**
@ -127,4 +137,52 @@ public interface Firework extends Projectile {
return getAttachedTo();
}
// Paper end
// Paper start - Firework API
/**
* Gets the item used in the firework.
*
* @return firework item
*/
@NotNull
public org.bukkit.inventory.ItemStack getItem();
/**
* Sets the item used in the firework.
* <p>
* Firework explosion effects are used from this item.
*
* @param itemStack item to set
*/
void setItem(@org.jetbrains.annotations.Nullable org.bukkit.inventory.ItemStack itemStack);
/**
* Gets the number of ticks the firework has flown.
*
* @return ticks flown
*/
int getTicksFlown();
/**
* Sets the number of ticks the firework has flown.
* Setting this greater than detonation ticks will cause the firework to explode.
*
* @param ticks ticks flown
*/
void setTicksFlown(int ticks);
/**
* Gets the number of ticks the firework will detonate on.
*
* @return the tick to detonate on
*/
int getTicksToDetonate();
/**
* Set the amount of ticks the firework will detonate on.
*
* @param ticks ticks to detonate on
*/
void setTicksToDetonate(int ticks);
// Paper end
}

View File

@ -322,4 +322,50 @@ public interface FishHook extends Projectile {
*/
BOBBING;
}
// Paper start - More FishHook API
/**
* Get the number of ticks the hook needs to wait for a fish to bite.
*
* @return Number of ticks
*/
int getWaitTime();
/**
* Sets the number of ticks the hook needs to wait for a fish to bite.
*
* @param ticks Number of ticks
*/
void setWaitTime(int ticks);
/**
* Get the number of ticks the fish has to swim until biting the hook.
* The {@link #getWaitTime()} has to be zero or below for the fish to start the time until bite timer.
*
* @return number of ticks.
* A value of one indicates that the fish bites the very next time the fish hook is ticked
* while a value of zero represents a fish that has already bitten the hook.
* @see #getWaitTime()
*/
@org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE)
int getTimeUntilBite();
/**
* Sets the number of ticks the fish has to swim until biting the hook.
*
* @param ticks number of ticks.
* One is the minimum that can be passed to this method and instructs the fish to bite the very next tick.
* @throws IllegalArgumentException if the passed tick value is less than one.
*/
void setTimeUntilBite(@org.jetbrains.annotations.Range(from = 1, to = Integer.MAX_VALUE) int ticks) throws IllegalArgumentException;
/**
* Completely resets this fishing hook's fishing state, re-randomizing the time needed until a fish is lured and
* bites the hook.
* <p>
* This method takes all properties of the fishing hook into account when resetting said values, such as a lure
* enchantment.
*/
void resetFishingState();
// Paper end
}

View File

@ -12,6 +12,7 @@ public interface Projectile extends Entity {
* Retrieve the shooter of this projectile.
*
* @return the {@link ProjectileSource} that shot this projectile
* @see #getOwnerUniqueId()
*/
@Nullable
public ProjectileSource getShooter();
@ -41,4 +42,89 @@ public interface Projectile extends Entity {
*/
@Deprecated(since = "1.20.2", forRemoval = true)
public void setBounce(boolean doesBounce);
// Paper start
/**
* Gets whether the projectile has left the
* hitbox of their shooter and can now hit entities.
*
* @return has left shooter's hitbox
*/
boolean hasLeftShooter();
/**
* Sets whether the projectile has left the
* hitbox of their shooter and can now hit entities.
*
* This is recalculated each tick if the projectile has a shooter.
*
* @param leftShooter has left shooter's hitbox
*/
void setHasLeftShooter(boolean leftShooter);
/**
* Gets whether the projectile has been
* shot into the world and has sent a projectile
* shot game event.
*
* @return has been shot into the world
*/
boolean hasBeenShot();
/**
* Sets whether the projectile has been
* shot into the world and has sent a projectile
* shot game event in the next tick.
*
* Setting this to false will cause a game event
* to fire and the value to be set back to true.
*
* @param beenShot has been in shot into the world
*/
void setHasBeenShot(boolean beenShot);
/**
* Gets whether this projectile can hit an entity.
* <p>
* This method returns true under the following conditions:
* <p>
* - The shooter can see the entity ({@link Player#canSee(Entity)}) <p>
* - The entity is alive and not a spectator <p>
* - The projectile has left the hitbox of the shooter ({@link #hasLeftShooter()})<p>
* - If this is an arrow with piercing, it has not pierced the entity already
*
* @param entity the entity to check if this projectile can hit
* @return true if this projectile can damage the entity, false otherwise
*/
boolean canHitEntity(@org.jetbrains.annotations.NotNull Entity entity);
/**
* Makes this projectile hit a specific entity.
* This uses the current position of the projectile for the hit point.
* Using this method will result in {@link org.bukkit.event.entity.ProjectileHitEvent} being called.
* @param entity the entity to hit
* @see #hitEntity(Entity, org.bukkit.util.Vector)
* @see #canHitEntity(Entity)
*/
void hitEntity(@org.jetbrains.annotations.NotNull Entity entity);
/**
* Makes this projectile hit a specific entity from a specific point.
* Using this method will result in {@link org.bukkit.event.entity.ProjectileHitEvent} being called.
* @param entity the entity to hit
* @param vector the direction to hit from
* @see #hitEntity(Entity)
* @see #canHitEntity(Entity)
*/
void hitEntity(@org.jetbrains.annotations.NotNull Entity entity, @org.jetbrains.annotations.NotNull org.bukkit.util.Vector vector);
/**
* Gets the owner's UUID
*
* @return the owner's UUID, or null if not owned
* @see #getShooter()
*/
@Nullable
java.util.UUID getOwnerUniqueId();
// Paper end
}

View File

@ -18,4 +18,61 @@ public interface ShulkerBullet extends Projectile {
* @param target the entity to target
*/
void setTarget(@Nullable Entity target);
// Paper start
/**
* Gets the relative offset that this shulker bullet should move towards,
* note that this will change each tick as the skulker bullet approaches the target.
*
* @return target delta offset
*/
@org.jetbrains.annotations.NotNull
org.bukkit.util.Vector getTargetDelta();
/**
* Sets the relative offset that this shulker bullet should move towards,
* note that this will change each tick as the skulker bullet approaches the target.
* This is usually relative towards their target.
*
* @param vector target
*/
void setTargetDelta(@org.jetbrains.annotations.NotNull org.bukkit.util.Vector vector);
/**
* Gets the current movement direction.
* This is used to determine the next movement direction to ensure
* that the bullet does not move in the same direction.
*
* @return null or their current direction
*/
@Nullable
org.bukkit.block.BlockFace getCurrentMovementDirection();
/**
* Set the current movement direction.
* This is used to determine the next movement direction to ensure
* that the bullet does not move in the same direction.
*
* Set to null to simply pick a random direction.
*
* @param movementDirection null or a direction
*/
void setCurrentMovementDirection(@Nullable org.bukkit.block.BlockFace movementDirection);
/**
* Gets how many ticks this shulker bullet
* will attempt to move in its current direction.
*
* @return number of steps
*/
int getFlightSteps();
/**
* Sets how many ticks this shulker bullet
* will attempt to move in its current direction.
*
* @param steps number of steps
*/
void setFlightSteps(int steps);
// Paper end
}

View File

@ -32,12 +32,34 @@ public interface ThrownPotion extends ThrowableProjectile {
/**
* Set the ItemStack for this thrown potion.
* <p>
* The ItemStack must be of type {@link org.bukkit.Material#SPLASH_POTION}
* or {@link org.bukkit.Material#LINGERING_POTION}, otherwise an exception
* is thrown.
*
* @param item New ItemStack
*/
public void setItem(@NotNull ItemStack item);
// Paper start - Projectile API
/**
* Gets a copy of the PotionMeta for this thrown potion.
* This includes what effects will be applied by this potion.
*
* @return potion meta
*/
@NotNull
org.bukkit.inventory.meta.PotionMeta getPotionMeta();
/**
* Sets the PotionMeta of this thrown potion.
* This will modify the effects applied by this potion.
* <p>
* Note that the type of {@link #getItem()} is irrelevant
*
* @param meta potion meta
*/
void setPotionMeta(@NotNull org.bukkit.inventory.meta.PotionMeta meta);
/**
* Splashes the potion at its current location.
*/
void splash();
// Paper end
}

View File

@ -38,5 +38,24 @@ public interface Trident extends AbstractArrow, ThrowableProjectile {
* @throws IllegalArgumentException if the loyalty level is lower than 0 or greater than 127
*/
void setLoyaltyLevel(int loyaltyLevel);
/**
* Gets if this trident has dealt damage to an
* entity yet or has hit the floor.
*
* If neither of these events have occurred yet, this will
* return false.
*
* @return has dealt damage
*/
boolean hasDealtDamage();
/**
* Sets if this trident has dealt damage to an entity
* yet or has hit the floor.
*
* @param hasDealtDamage has dealt damage or hit the floor
*/
void setHasDealtDamage(boolean hasDealtDamage);
}
// Paper end

View File

@ -39,4 +39,26 @@ public interface ProjectileSource {
*/
@NotNull
public <T extends Projectile> T launchProjectile(@NotNull Class<? extends T> projectile, @Nullable Vector velocity);
// Paper start - add consumer to launchProjectile
/**
* Launches a {@link Projectile} from the ProjectileSource with an
* initial velocity, with the supplied function run before the
* entity is added to the world.
* <br>
* Note that when the function is run, the entity will not be actually in
* the world. Any operation involving such as teleporting the entity is undefined
* until after this function returns.
* <p>
* The family of launchProjectile methods only promise the ability to launch projectile types
* that the {@link ProjectileSource} is capable of firing in vanilla.
* Any other types of projectiles *may* be implemented but are not part of the method contract.
* @param <T> a projectile subclass
* @param projectile class of the projectile to launch
* @param velocity the velocity with which to launch
* @param function the function to be run before the entity is spawned
* @return the launched projectile
*/
<T extends Projectile> @NotNull T launchProjectile(@NotNull Class<? extends T> projectile, @Nullable Vector velocity, java.util.function.@Nullable Consumer<? super T> function);
// Paper end - add consumer to launchProjectile
}