Use PersistentDataContainer for flying bows
This commit is contained in:
1 parent
cc1c71dad9
commit
3bedc7448c
4 files changed
+47
-43
No files matched your search
@@ -6,12 +6,12 @@ import java.util.Collections;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.trueog.flyingbowog.FlyingBowOG;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
@@ -38,9 +38,10 @@ public class GiveCommand implements CommandExecutor {
|
||||
ItemMeta bowMeta = flyingBowItem.getItemMeta();
|
||||
bowMeta.displayName(Component.text("Flying Bow").color(TextColor.color(0, 255, 255))
|
||||
.decorate(TextDecoration.ITALIC));
|
||||
bowMeta.lore(Collections.singletonList(Component.text("Shoot this bow to FLY")));
|
||||
bowMeta.lore(Collections.singletonList(Component.text(FlyingBowOG.LORE_MARKER)));
|
||||
// Tag as a Flying Bow via PersistentDataContainer (Panilla-legal NBT).
|
||||
FlyingBowOG.tagFlyingBow(bowMeta);
|
||||
flyingBowItem.setItemMeta(bowMeta);
|
||||
flyingBowItem.addItemFlags(ItemFlag.HIDE_DYE);
|
||||
|
||||
player.getInventory().addItem(flyingBowItem);
|
||||
|
||||
|
||||
@@ -17,37 +17,43 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public final class FlyingBowOG extends JavaPlugin implements Listener {
|
||||
|
||||
private static FlyingBowOG plugin;
|
||||
|
||||
// PersistentDataContainer key identifying a Flying Bow. Stored under the
|
||||
// vanilla-legal PublicBukkitValues NBT compound so anti-illegal-item plugins
|
||||
// (e.g. Panilla) do not strip it, unlike the old HideFlags-based marker.
|
||||
private static NamespacedKey flyingBowKey;
|
||||
|
||||
// Lore line shown on every Flying Bow (display only; identity is the PDC tag).
|
||||
public static final String LORE_MARKER = "Shoot this bow to FLY";
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
// Plugin startup logic
|
||||
plugin = this;
|
||||
flyingBowKey = new NamespacedKey(this, "flying_bow");
|
||||
|
||||
// create the flying bow item
|
||||
ItemStack flyingBowItem = new ItemStack(Material.BOW);
|
||||
ItemMeta bowMeta = flyingBowItem.getItemMeta();
|
||||
bowMeta.displayName(
|
||||
Component.text("Flying Bow").color(TextColor.color(0, 255, 255)).decorate(TextDecoration.ITALIC));
|
||||
bowMeta.lore(Collections.singletonList(Component.text("Shoot this bow to FLY")));
|
||||
bowMeta.lore(Collections.singletonList(Component.text(LORE_MARKER)));
|
||||
// Tag as a Flying Bow via PersistentDataContainer (Panilla-legal NBT).
|
||||
tagFlyingBow(bowMeta);
|
||||
flyingBowItem.setItemMeta(bowMeta);
|
||||
|
||||
// adding a useless itemFlag to identify this as a flying bow
|
||||
// this was easier for me than adding an attribute, and no other bow should have
|
||||
// this flag
|
||||
flyingBowItem.addItemFlags(ItemFlag.HIDE_DYE);
|
||||
|
||||
// add the recipe into the game
|
||||
ShapedRecipe flyingBowRecipe = new ShapedRecipe(new NamespacedKey(this, "flying_bow"), flyingBowItem);
|
||||
ShapedRecipe flyingBowRecipe = new ShapedRecipe(flyingBowKey, flyingBowItem);
|
||||
flyingBowRecipe.shape("sd ", "sed", "sd ");
|
||||
flyingBowRecipe.setIngredient('s', Material.STICK);
|
||||
flyingBowRecipe.setIngredient('e', Material.ELYTRA);
|
||||
@@ -72,6 +78,28 @@ public final class FlyingBowOG extends JavaPlugin implements Listener {
|
||||
|
||||
}
|
||||
|
||||
// Stamps a Flying Bow marker into an item's PersistentDataContainer.
|
||||
public static void tagFlyingBow(ItemMeta meta) {
|
||||
|
||||
meta.getPersistentDataContainer().set(flyingBowKey, PersistentDataType.BYTE, (byte) 1);
|
||||
|
||||
}
|
||||
|
||||
// Canonical Flying Bow identity check used by every listener. Identity lives in
|
||||
// the PDC marker only (Panilla-legal NBT).
|
||||
public static boolean isFlyingBow(ItemStack item) {
|
||||
|
||||
if (item == null || item.getType() != Material.BOW)
|
||||
return false;
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null)
|
||||
return false;
|
||||
|
||||
return meta.getPersistentDataContainer().has(flyingBowKey, PersistentDataType.BYTE);
|
||||
|
||||
}
|
||||
|
||||
public static String getPrefix() {
|
||||
|
||||
return "&7[&5FlyingBow&f-&4OG&7] ";
|
||||
|
||||
@@ -16,7 +16,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionType;
|
||||
@@ -32,19 +31,10 @@ public class OnEntityShootBowEvent implements Listener {
|
||||
// Only react to players shooting arrows with our Flying Bow.
|
||||
if (!(event.getEntity() instanceof Player player))
|
||||
return;
|
||||
FlyingBowOG.getPlugin().getLogger().info("[FB-DEBUG] shoot by player " + player.getName());
|
||||
if (!(event.getProjectile() instanceof Arrow arrow)) {
|
||||
|
||||
FlyingBowOG.getPlugin().getLogger()
|
||||
.info("[FB-DEBUG] projectile NOT Arrow: " + event.getProjectile().getType());
|
||||
if (!(event.getProjectile() instanceof Arrow arrow))
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
ItemStack bow = player.getInventory().getItemInMainHand();
|
||||
FlyingBowOG.getPlugin().getLogger().info("[FB-DEBUG] mainhand=" + bow.getType() + " flags=" + bow.getItemFlags()
|
||||
+ " isFlyingBow=" + isFlyingBow(bow));
|
||||
if (!isFlyingBow(bow))
|
||||
if (!FlyingBowOG.isFlyingBow(bow))
|
||||
return;
|
||||
|
||||
// Block flying bow usage while player is already wearing an elytra.
|
||||
@@ -80,15 +70,10 @@ public class OnEntityShootBowEvent implements Listener {
|
||||
|
||||
boolean sameWorld = shooter.getWorld().getKey().toString().equals(worldKey);
|
||||
|
||||
FlyingBowOG.getPlugin().getLogger().info("[FB-DEBUG] mount tick: sameWorld=" + sameWorld + " dead="
|
||||
+ rideArrow.isDead() + " valid=" + rideArrow.isValid());
|
||||
|
||||
if (!sameWorld || rideArrow.isDead() || !rideArrow.isValid())
|
||||
return;
|
||||
|
||||
boolean mounted = rideArrow.addPassenger(shooter);
|
||||
FlyingBowOG.getPlugin().getLogger()
|
||||
.info("[FB-DEBUG] addPassenger returned " + mounted + " passengers=" + rideArrow.getPassengers());
|
||||
rideArrow.addPassenger(shooter);
|
||||
|
||||
}, 1L);
|
||||
|
||||
@@ -142,7 +127,7 @@ public class OnEntityShootBowEvent implements Listener {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
boolean holdingFlyingBow = isFlyingBow(player.getInventory().getItemInMainHand());
|
||||
boolean holdingFlyingBow = FlyingBowOG.isFlyingBow(player.getInventory().getItemInMainHand());
|
||||
boolean ridingFlyingBowArrow = isRidingTaggedArrow(player);
|
||||
|
||||
if (!(holdingFlyingBow || ridingFlyingBowArrow))
|
||||
@@ -165,13 +150,6 @@ public class OnEntityShootBowEvent implements Listener {
|
||||
|
||||
}
|
||||
|
||||
// Identifies your custom “Flying Bow”.
|
||||
private boolean isFlyingBow(ItemStack item) {
|
||||
|
||||
return item != null && item.getType() == Material.BOW && item.getItemFlags().contains(ItemFlag.HIDE_DYE);
|
||||
|
||||
}
|
||||
|
||||
// True if the player is riding one of the cyan, UNCRAFTABLE arrows.
|
||||
private boolean isRidingTaggedArrow(Player player) {
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent;
|
||||
import org.bukkit.inventory.AnvilInventory;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
|
||||
@@ -31,7 +30,7 @@ public class OnPrepareAnvilEvent implements Listener {
|
||||
|
||||
if (secondItem != null) {
|
||||
|
||||
if (firstItem.getItemFlags().contains(ItemFlag.HIDE_DYE) && firstItem.getType().equals(Material.BOW)) {
|
||||
if (FlyingBowOG.isFlyingBow(firstItem)) {
|
||||
|
||||
if (secondItem.getType().equals(Material.PHANTOM_MEMBRANE)) {
|
||||
|
||||
@@ -104,10 +103,8 @@ public class OnPrepareAnvilEvent implements Listener {
|
||||
// if the second item is a bow
|
||||
if (secondItem.getType().equals(Material.BOW)) {
|
||||
|
||||
// if only one bow has the HIDE_DYE flag
|
||||
if (firstItem.getItemFlags().contains(ItemFlag.HIDE_DYE)
|
||||
^ secondItem.getItemFlags().contains(ItemFlag.HIDE_DYE))
|
||||
{
|
||||
// if only one of the two bows is a flying bow
|
||||
if (FlyingBowOG.isFlyingBow(firstItem) ^ FlyingBowOG.isFlyingBow(secondItem)) {
|
||||
|
||||
// set the result to null
|
||||
event.setResult(null);
|
||||
|
||||
Reference in new issue
Block a user