我正在尝试将Dye颜色应用到现有的ItemStack中,如何在不使用不推荐使用的方法和创建新堆栈的情况下执行此操作?
我尝试了以下代码,但导致正常的墨水袋。
ps:我仅在第一行中创建一个堆栈作为示例。
final ItemStack stack = new ItemStack(Material.INK_SACK);
Dye dye = new Dye();
dye.setColor(DyeColor.LIME);
stack.setData(dye);
编辑:将final添加到堆栈变量以显示它不能被新堆栈替换。
最佳答案
我找到了一种方法来执行此操作,但是它远不如使用不推荐使用的方法有效。这就是我个人的思考过程。
您当前尝试的问题在于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());
}
}
}
此方法用作处理空值并防止错误数据类型的简单设置器。虽然这里的问题应该很明显。羊毛和染料不会将其信息存储在
MaterialData
中,而是将其存储在持久性中。 Colorable
对象的持久性决定了它的颜色。既然是这种情况,您将需要修改耐久性才能对颜色进行任何处理。可以在构造函数之外设置持久性的唯一地方是setDurability
方法。这不需要MaterialData
,只需要short
。因此,我们的选择如下:构造一个新的ItemStack,或获得对不可用的short
值的不建议使用的访问。根据您的标准,我们转向后者。第一个入口点是
DyeColor
类。如果我们在这里找不到short
值,那么它将至少从此处提供给另一个类。查看源代码可以使我们对问题的根源有一个严峻的提醒。有一种仅使用
DyeColor
的hacky解决方案,但如果发生更改,则不能提供版本证明。 Enum.ordinal()
方法将返回枚举的序数值。这是定义顺序的数值。从索引零开始,它将与羊毛数据值匹配,但是对于染料,需要反转,这是您要尝试实现的通用性。选项在那里。所以
DyeColor
没问题,但这让我思考。使用Dye
方法时,将MaterialData
类作为toItemStack()
可以很好地工作。也许我们可以使用它。原来你可以!这将需要创建一个新的Itemstack
,但是我们将使用新的ItemStack
来访问原始代码。首先,我们像上面一样创建MaterialData
。Dye dye = new Dye();
dye.setColor(DyeColor.LIME);
接下来,使用
Dye
方法将Itemstack
转换为toItemStack()
。ItemStack tempStack = dye.toItemStack();
现在,为什么要这样做?很好,您知道
Dye.setColor(DyeColor)
方法具有以下内部实现:public void setColor(DyeColor color) {
setData(color.getDyeData());
}
它使用了不推荐使用的方法,但是由于它包装在DyeColor调用中,因此不建议插件用户使用。请注意:这完全可以接受! Bukkit的许多使用
Material
作为参数的调用实际上只是调用了与该ID相关联的不赞成使用的方法。不过,调用这些方法是完全有效的。还要注意,setData(byte)
方法只是一个简单的设置方法。接下来,使用
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的DyeColor
中访问MaterialData
,它将与耐久性相匹配。我希望您对可能的事实感到满意,但是我仍然建议您使用不推荐使用的方法,直到它们被列为已损坏(Bukkit通常不会发生)为止。