我正在尝试将Dye颜色应用到现有的ItemStack中,如何在不使用弃用方法和创建新堆栈的情况下执行此操作?
我尝试了以下代码,但这导致了正常的墨水袋.
ps:我只在第一行创建一个堆栈作为示例.
final ItemStack stack = new ItemStack(Material.INK_SACK);
Dye dye = new Dye();
dye.setColor(DyeColor.LIME);
stack.setData(dye);
编辑:添加最终到堆栈变量以显示它不能被新堆栈替换.
解决方法:
我找到了一种方法来实现这一点,但它远不如使用弃用方法那么高效.这是我自己的个人思考过程.
您当前尝试的问题是setData(MaterialData)方法的内部.
public void setData(MaterialData data) {
Material mat = getType();
if (data == null || mat == null || mat.getData() == null) {
this.data = data;
} else {
if ((data.getClass() == mat.getData()) || (data.getClass() == MaterialData.class)) {
this.data = data;
} else {
throw new IllegalArgumentException("Provided data is not of type " + mat.getData().getName() + ", found " + data.getClass().getName());
}
}
}
此方法用作处理空值并防止不正确数据类型的简单setter.这里的问题应该是非常明显的.羊毛和染料不会将它们的信息存储在MaterialData中,它们会将其存储在耐久性中.可着色物体的耐久性决定了它的颜色.因为这种情况,你需要修改耐久性,以便对颜色做任何事情.您可以在构造函数之外设置持久性的唯一位置是setDurability方法.这不是一个MaterialData,只是一个简短的.因此,我们的选项如下:构造新的ItemStack,或获得对可用短值的非弃用访问.根据您的标准,我们转向后者.
第一个入口点,DyeColor类.如果我们在这里找不到短值,它至少会从这里提供给另一个类.查看源代码,让我们对这个问题的根深蒂固提出了一个严峻的提醒.
有一个hacky解决方案单独使用DyeColor,但它不是版本证明的变化. Enum.ordinal()方法将返回枚举的序数值.这是它定义的顺序的数值.从索引零开始,它将匹配羊毛数据值,但需要针对染料进行反转,这是您试图普及的东西.但是选项就在那里.
所以DyeColor是不可能的,但它让我思考.使用toItemStack()方法时,作为MaterialData的Dye类工作得非常好.也许我们可以使用它.事实证明你可以!它需要创建一个新的Itemstack,但我们将使用新的ItemStack来访问原始的ItemStack数据.首先,我们像上面一样创建MaterialData.
Dye dye = new Dye();
dye.setColor(DyeColor.LIME);
接下来,使用toItemStack()方法将Dye转换为Itemstack.
ItemStack tempStack = dye.toItemStack();
现在坚持,为什么这样做?嗯,你看,Dye.setColor(DyeColor)方法有一个内部实现如下:
public void setColor(DyeColor color) {
setData(color.getDyeData());
}
它使用了一种不推荐使用的方法,但因为它包含在DyeColor调用中,所以它不会被弃用给插件用户.请注意:这是完全可以接受的!使用Material作为参数的许多Bukkit调用实际上只是调用与其关联的类型id的已弃用方法.尽管调用这些方法完全有效.另请注意,setData(byte)方法只是一个简单的setter.
接下来,使用toItemStack()方法.
public ItemStack toItemStack(int amount) {
return new ItemStack(type, amount, data);
}
我们在这里可以看到转换为字节的DyeColor现在作为持久性发送到ItemStack构造函数ItemStack(Material,int,short)(它会自动转换为short).这意味着,我们现在有我们要求的简短!它存储在tempStack的持久性中.最重要的是,我们采取以下措施.
stack.setDurability(tempStack.getDurability());
stack.setData(dye);
结束了.您有一个修改过的ItemStack,没有公开的弃用方法.您可能会问为什么我仍然调用ItemStack.setData(MaterialData).这只是确保如果有人试图从ItemStack的MaterialData访问DyeColor,它将与耐久性相匹配.
我希望你对这是可能的事实感到满意,但我仍然建议使用已弃用的方法,直到它们被列为已损坏(这通常不会发生在Bukkit中).