Item类
Item
用于进行与物品相关的操作。
前置知识
物品堆栈(ItemStack)
- 例如接下来谈到的Item.of(...args)函数会返回一个ItemStack对象,在Minecraft中,玩家手上,箱子,创造模式物品栏中等你所能见到的物品均为ItemStack的实例。
方法重载(Overload)
重载是指同一个方法(函数)名可以有多个不同的实现。例如下文提到的Item.of(...args);就有四种。特点如下:
同名但参数不同:重载的方法必须有不同的参数列表。可以通过改变参数的类型、数量或顺序来实现重载。
返回值不影响重载:返回值类型并不参与方法的重载。也就是说,两个方法即使返回值类型不同,如果它们的参数列表完全相同,也会导致编译错误。
可读性提高:通过重载,可以使用相同名称的方法处理不同类型的数据,这样可以提高代码的可读性。
编译时绑定:方法重载是在编译时通过静态类型检查决定调用哪个方法,与运行时绑定的动态多态性相对。
总结
函数名相同但参数(类型,顺序,数量)不同的函数,且与返回值类型无关。
同名不同参,返回值无关。
注意
KubeJS(JavaScript)的方法重载不能这样实现。
JavaScript(KubeJS)方法重载实现方式请查看(未完成,看到了请催一催)。
类型别名(Type Alias)
别名,指的是人或物除了自己本名以外的名字,而类型别名,则是指除了数据类型自身的类型名之外,新赋予的类型名称。
例:假设苹果树、梨树,现在是我们有的两个对象的类型,你有一个“摘”的动作(函数)可以从“果树”类型对象上获得果实,苹果树与梨树都属于果树,或者说苹果树与梨树都是果树这个类型的子类型,你很容易明白,这个“摘”函数的参数类型写“果树”。
但“摘”仅适用于果树吗?如果我把梨挂墙上能不能摘呢?很显然是能的,但这与前边定义的函数参数类型不符,“挂起来的梨”很显然不是果树,我们需要将所有可以被执行“摘”这个动作的类型归类到一个类型下,以便于使用。
在
Typescript
中:type 果树_= 果树 | 挂起来的梨; 这样就是一个类型别名声明。在KubeJS使用过程中,会经常看见这样形式的type_类型别名。
get与set属性
get
类型的属性,用于读取对象的属性值,更加详细的信息等待后续更新。
set
类型的属性,用于设置对象的属性值,更加详细的信息等待后续更新。
readonly属性
readonly
类型的属性,一旦初始化后不可更改,只能读取,更加详细的信息等待后续更新。
所有函数
Item.of(args)
可以返回一个ItemStack实例,共有4个重载方法。
Item.of(in_: Internal.ItemStack_): Internal.ItemStack;
表示接收
Internal.ItemStack_
类型参数in_,返回一个Internal.ItemStack
对象。
// 表示1个铁镐物品堆栈
Item.of('minecraft:iron_pickaxe');
Item.of(in_: Internal.ItemStack_, count: number, nbt: Internal.CompoundTag_): Internal.ItemStack;
表示接收
Internal.ItemStack_
参数in_,number
类型参数count,Internal.CompoundTag_
类型参数nbt,返回count个具有nbt标签的Internal.ItemStack
对象。
// 表示1个消耗100点耐久的铁镐物品堆栈
Item.of('minecraft:iron_pickaxe', 1, '{Damage:100}');
Item.of(in_: Internal.ItemStack_, count: number): Internal.ItemStack;
表示接收
Internal.ItemStack_
参数in_,number
类型参数count,返回count个Internal.ItemStack
对象。
// 表示1个铁镐物品堆栈
Item.of('minecraft:iron_pickaxe', 1);
Item.of(in_: Internal.ItemStack_, tag: Internal.CompoundTag_): Internal.ItemStack;
表示接收
Internal.ItemStack_
参数in_,Internal.CompoundTag_
类型参数nbt,返回1个具有nbt标签的Internal.ItemStack
对象。
// 表示1个消耗100点耐久的铁镐物品堆栈
Item.of('minecraft:iron_pickaxe', '{Damage:100}');
疑问,为什么Internal.ItemStack_类型的参数却传递了字符串?为什么Internal.CompoundTag_类的参数传递字符串或对象字面量?详情查看前置知识类型别名与下列对应类型别名解析。
Internal.ItemStack_类型解析
- 在Vscode中打开你的游戏根目录(就像平时编写kubejs做的那样),Ctrl+鼠标左键点击Item.of(...args);函数,可以看到这样一行of(in_: Internal.ItemStack_): Internal.ItemStack;
- Ctrl+鼠标左键点击Internal.ItemStack_来到Internal.ItemStack_类型别名的定义部分。在这里看到Internal.ItemStack_类型别名下都有什么类型。
- 它非常长,为了阅读方便,这里可以点击Alt+Z开启自动换行,不过请将关注点放在等号右边第二个类型别名Internal.Item_。
- Ctrl+鼠标左键点击Internal.Item_打开它的类型别名定义,type Item_ = Item | Special.Item;
- Item指代的是Minecraft的Item类的实例,不过现在将注意力转向Special.Item并Ctrl+鼠标左键点击。
- 在这里你可以发现,Special.Item是大量的物品id,而Special.Item是Internal.ItemStack_中引用的一个类型,因此你可以使用字符串来传递Internal.ItemStack_类型参数。
- 对于Internal.ItemStack_类型别名引用的其他类型,也可以使用,不过会不如字符串方便。
总结
Special.Item内每一个字符串,游戏内都有与之对应的物品id。
KubeJS内部会进行自动类型转换。
Internal.CompoundTag_类型解析
- 打开Internal.CompoundTag_类型别名定义,它只引用了Internal.CompoundTag类型,也就是说Internal.CompoundTag_与Internal.CompoundTag是等价的,没有像Special.Item这样的方便类型供我们使用。
- 对象字面量{key: value}或者字符串类型的对象字面量'{key: value}',会经由KubeJS内部的类型转换成Internal.CompoundTag。
- 打开Internal.CompoundTag类型声明,可以看到起其构造函数 constructor(arg0: Internal.Map_<string, Internal.Tag>); 也就是说它的实例化需要接收一个键值对,这与我们传递的参数具有形式上的相似性,出于经验,认为KubeJS内部进行了类型转换,此处没有再进行深究。
Item.withNBT(args)
返回输入的ItemStack,并包含给定的NBT数据。
Item.withNBT(in_: Internal.ItemStack_, nbt: Internal.CompoundTag_): Internal.ItemStack;
表示接收
Internal.ItemStack_
类型参数in_,Internal.CompoundTag_
类型参数nbt,返回带有指定NBT数据的ItemStack。
// 一个带有'{test: 6}'NBT的草方块物品
Item.withNBT(Item.of('grass_block'), '{test: 6}');
Item.getTypeToStackMap()
获取一个包含了物品id和存放其对应物品堆栈的集合的键值对。
Item.getTypeToStackMap(): Internal.Map<ResourceLocation, Internal.Collection<Internal.ItemStack>>;
返回一个Map键值对<物品id,Set集合>,这个Map是
java.util.HashMap
类型,这个Set集合是java.util.ImmutableCollections$Set
类型,大小size为1,内含1个对应物品id的ItemStack实例。
// 示例
PlayerEvents.chat(event => {
const { message } = event;
if (message !== 'test') return;
Item.getTypeToStackMap().forEach(
/**
*
* @param {ResourceLocation} key
* @param {Internal.Set} value
*/
(key, value) => {
if (key.namespace === 'minecraft') {
console.log(`键值对值<${key},${value}>`);
console.log(`键值对类型<${key.getClass()},${value.getClass()}>`);
}
}
);
})
Item.playerHeadFromSkinHash(args)
从hash获取玩家头颅物品堆栈实例。
playerHeadFromSkinHash(hash: string): Internal.ItemStack;
从玩家皮肤的哈希值获取玩家头颅物品
ItemStack
,目前还未得知皮肤哈希值的具体获取来源。
// 暂无示例
Item.getEmpty()
返回空气/空槽物品堆栈实例。
Item.getEmpty()
返回一个空气/空槽物品堆栈实例
ItemStack
// 将一个空气/空槽物品堆栈给予玩家,这什么也不会发生。
// 即使玩家背包为满也不会有槽被替换为空气。
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
player.give(Item.getEmpty());
});
Item.getItem(args)
从物品id(ResourceLocation)获取Item实例。
Item.getItem(id: ResourceLocation_): Internal.Item;
接收一个id
ResourceLocation_
返回物品实例Internal.Item
// 一个草方块的Item实例
Item.getItem('minecraft:grass_block');
Item.getVariants(args)
返回一个物品(ItemStack)的变种集合。
Item.getVariants(item: Internal.ItemStack_): Internal.Collection<Internal.ItemStack>;
接收一个物品堆栈实例
Internal.ItemStack_
返回一个集合Internal.Collection<Internal.ItemStack>
// 结论:经过对原版物品的遍历,这个函数目前并没有什么用,所获取的变种物品(ItemStack)与输入物品(ItemStack)完全相同,引用也相同。
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
// 这个函数是上文所提及的用于获取物品Id与装有物品(ItemStack)集合的键值对Map的函数。
// 这里为了探究getVariants究竟有什么用,拿来用用。
// 演示时游戏里物品有些多,这里过滤一下只查看原版。
Item.getTypeToStackMap().forEach((k, v) => {
if (k.getNamespace() === 'minecraft') {
/**@type {Internal.ItemStack} */
let itemStack = v.toArray()[0];
Item.getVariants(itemStack).forEach(e => {
console.log(`原物品: ${itemStack.getIdLocation()} 变种物品: ${e.getIdLocation()} 判断一下引用: ${itemStack.getIdLocation() === e.getIdLocation()}`);
})
}
})
});
Item.getList()
返回所有处在创造模式物品栏中的物品(ItemStack)列表。
Item.getList(): Internal.List<Internal.ItemStack>;
返回一个物品堆栈列表
Internal.List<Internal.ItemStack>
// 遍历了全部在创造模式物品栏中的物品
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
Item.getList().forEach(e => {
console.log(`物品id:${e.getIdLocation()}`);
})
});
Item.fireworks(args)
返回具有输入属性的烟花,返回类型为Internal.FireworksJS,目前尚未明晰。
Item.fireworks(properties: Internal.Map_<string, any>): Internal.FireworksJS;
接收属性键值对
Internal.Map_<string, any>
,允许对象字面量{string, any}
,允许字符串形式对象字面量'{string, any}'
,返回烟花JSInternal.FireworksJS
// 不可用的示例 只是作为研究进度备份留存,等待后续。
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
// 此处返回了Internal.FireworkRocketEntity类型,还未研究明白。
let entity = Item.fireworks('{Fireworks:{Flight:1b}}').createFireworkRocket(level, player.block.pos.x, player.block.pos.y, player.block.pos.z)
// 尝试生成 但是生成是失败的,未能理解。
entity.spawn();
player.tell(`是否加入世界: ${entity.isAddedToWorld()}`);
// 重复给予会报错
player.give(entity.getItem());
//[10:49:56] [ERROR] ! Error in 'PlayerEvents.chat': Could not find platform implementation for LevelPlatformHelper!
//[10:49:56] [ERROR] ! java.lang.RuntimeException: Could not find platform implementation for LevelPlatformHelper!
});
Item.playerHead(args)
返回玩家头颅ItemStack实例,具有两个方法重载。
Item.playerHead(name: string): Internal.ItemStack;
接收玩家名称
string
,返回玩家头颅物品堆栈实例ItemStack
// 获取了玩家的头
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
player.give(Item.playerHead(player.name.getString()));
});
Item.playerHead(uuid: Internal.UUID_, textureBase64: string): Internal.ItemStack;
接收玩家uuid
Internal.UUID_
,经Base64编码的纹理图片string
尚未明确此处的uuid的含义,已知的是textureBase64是纹理图片经Base64编码后得到的字符串。
// 暂无示例
Item.isItem(args)
判断传递的参数类型是否为ItemStack,返回布尔值。
isItem(o: any): boolean;
接收任意参数
any
,返回物品实例判断结果boolean
// 判断对象的类型是否为ItemStack
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
// 很显然不是 因为传入的是player
console.log(`是不是ItemStack: ${Item.isItem(player)}`);
});
Item.getId(args)
从Item实例(并非ItemStack实例)获取其id。
getId(item: Internal.Item_): ResourceLocation;
接收物品实例
Internal.Item_
,返回物品idResourceLocation
// 从一个Item对象获取其id
PlayerEvents.chat(event => {
const { message, level, server, player } = event;
if (message !== 'test') return;
player.give(Item.playerHead(player.name.getString()));
// 假设现在有一个item 只是为了演示,这里从id获取了item实例
let item = Item.getItem('minecraft:grass_block');
console.log(`是不是ItemStack: ${Item.getId()}`);
});
所有属性
typeToStackMap
get
属性,同Item.getTypeToStackMap()函数,返回映射java.util.HashMap
,其中键为物品idResourceLocation
,值为集合java.util.ImmutableCollections$Set
其大小size为1,内含对应物品id的物品实例Internal.ItemStack
empty
get
属性,同Item.getEmpty()函数,返回空气/空槽物品堆栈实例Internal.ItemStack
list
get
属性,同Item.getList()函数,返回物品堆栈实例列表,Internal.List<Internal.ItemStack>
typeList
get
属性,获取游戏内的物品id(string)列表,Internal.List<string>
KJS_ARMOR_MODIFIER_UUID_PER_SLOT
readonly
属性,返回uuid数组Internal.UUID[]
,含义等待研究,目前认为是物品在每个槽位的护甲值属性修饰符uuid列表。
KJS_BASE_ATTACK_SPEED_UUID
readonly
属性,返回一个交叉类型
(Internal.UUID) & (Internal.UUID)
,含义等待研究,目前认为是基础攻击速度值属性修饰符的uuid。
KJS_BASE_ATTACK_DAMAGE_UUID
readonly
属性,返回一个交叉类型
(Internal.UUID) & (Internal.UUID)
,含义等待研究,目前认为是基础攻击伤害值属性修饰符的uuid。