@occultus/toolkit 0.23.5 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,327 +1,327 @@
1
- import {
2
- Container,
3
- Effect,
4
- EffectType,
5
- Entity,
6
- EntityComponentTypes,
7
- EntityEffectOptions,
8
- EquipmentSlot,
9
- ItemStack,
10
- Player
11
- } from "@minecraft/server";
12
- import { EffectData, effectGroupMap, EffectGroups } from "@occultus/common";
13
- import { OccultusSDKError } from "@occultus/core";
14
- import { ensureNoNamespace } from "../identifier/namespace";
15
- import { EntityHealthUtils } from "./health";
16
-
17
- /**
18
- * 尝试对实体进行操作
19
- *
20
- * @param entity 要操作的实体
21
- * @param operate 操作函数,接受一个实体作为参数
22
- * @returns 操作是否成功
23
- * @since Starock 0.6.0 (0.1.0)
24
- */
25
- export function tryOperateEntity(
26
- entity: Entity,
27
- operate: (entity: Entity) => void
28
- ): boolean {
29
- if (entity.isValid) {
30
- operate(entity);
31
- return true;
32
- }
33
- return false;
34
- }
35
-
36
- /**
37
- * 获取给定**玩家**的指定装备槽物品 {@see EquipmentSlot}
38
- *
39
- * 注意:该方法仅适用于玩家实体
40
- *
41
- * @param entity 要获取槽位的实体
42
- * @param slot 要获取的槽位,默认为 {@link EquipmentSlot.Mainhand}
43
- * @return 槽位中的物品
44
- * @since Starock 0.6.0 (0.1.0)
45
- */
46
- export function getEquipmentItem(
47
- entity: Entity,
48
- slot = EquipmentSlot.Mainhand
49
- ): ItemStack | undefined {
50
- return entity
51
- ?.getComponent(EntityComponentTypes.Equippable)
52
- ?.getEquipment(slot);
53
- }
54
-
55
- /**
56
- * 设置给定**玩家**的指定装备槽物品 {@see EquipmentSlot}
57
- *
58
- * 注意:该方法仅适用于玩家实体
59
- *
60
- * @param entity 要设置槽位的实体
61
- * @param item 要设置的物品,如果为undefined则清空该槽位
62
- * @param slot 要设置的槽位,默认为 {@link EquipmentSlot.Mainhand}
63
- * @since Starock 0.6.0 (0.1.0)
64
- */
65
- export function setEquipmentItem(
66
- entity: Entity,
67
- item?: ItemStack,
68
- slot: EquipmentSlot = EquipmentSlot.Mainhand
69
- ): boolean {
70
- return (
71
- entity
72
- ?.getComponent(EntityComponentTypes.Equippable)
73
- ?.setEquipment(slot, item) ?? false
74
- );
75
- }
76
-
77
- /**
78
- * 获取实体的容器
79
- *
80
- * @param entity 要获取容器的实体
81
- * @return 实体的容器,如果没有则返回`undefined`
82
- * @since Starock 0.6.0 (0.1.0)
83
- */
84
- export function getContainer(entity: Entity): Container | undefined {
85
- return entity.getComponent(EntityComponentTypes.Inventory)?.container;
86
- }
87
-
88
- /**
89
- * 设置实体的槽位物品
90
- * @param entity 要设置槽位物品的实体
91
- * @param slot 槽位索引,从0开始依次递增
92
- * @param item 要设置的物品
93
- * @since Starock 0.6.0 (0.1.0)
94
- */
95
- export function setSlot(entity: Entity, slot: number, item?: ItemStack): void {
96
- getContainer(entity)?.setItem(slot, item);
97
- }
98
-
99
- /**
100
- * 给予实体物品
101
- * @param entity 要给予物品的实体
102
- * @param item 要给予的物品
103
- * @since Starock 0.6.0 (0.1.0)
104
- */
105
- export function giveItem(entity: Entity, item: ItemStack | ItemStack[]): void {
106
- const container = getContainer(entity);
107
- if (Array.isArray(item)) {
108
- for (const i of item) {
109
- giveItem(entity, i);
110
- }
111
- return;
112
- }
113
- if (container && container.emptySlotsCount > 0) {
114
- container.addItem(item);
115
- } else {
116
- entity.dimension.spawnItem(item, entity.location);
117
- }
118
- }
119
-
120
- /**
121
- * 清空实体的容器
122
- * @param entity 要清空容器的实体
123
- * @since Starock 0.6.0 (0.1.0)
124
- */
125
- export function clearSlot(entity: Entity): void {
126
- getContainer(entity)?.clearAll();
127
- }
128
-
129
- /**
130
- * 将 {@link EffectData} 应用到实体上
131
- * @param entity 要应用 {@link EffectData} 的实体
132
- * @param data 要应用的 {@link EffectData}
133
- * @returns 应用后的状态效果
134
- * @since Starock 0.6.0 (0.1.0)
135
- */
136
- export function applyEffectData(
137
- entity: Entity,
138
- data: EffectData | EffectData[]
139
- ): (Effect | undefined)[] {
140
- if (!Array.isArray(data)) {
141
- data = [data];
142
- }
143
- return data.flatMap((effectData) => {
144
- return entity.addEffect(effectData.effectType, effectData.duration, {
145
- amplifier: effectData.amplifier,
146
- showParticles: effectData.showParticles
147
- });
148
- });
149
- }
150
-
151
- /**
152
- * 向实体移除状态效果
153
- * @param entity 要清除效果的实体.
154
- * @param effectType 状态效果类型,可以是单个效果类型、效果类型数组、字符串、字符串数组或{@link EffectGroups}枚举值
155
- * @since Starock 0.6.0 (0.1.0)
156
- */
157
- export function clearEffect(
158
- entity: Entity,
159
- effectType: EffectType | EffectType[] | string | string[] | EffectGroups
160
- ): void {
161
- const effects =
162
- effectGroupMap[effectType as EffectGroups] ||
163
- (Array.isArray(effectType) ? effectType : [effectType]);
164
- for (const effect of effects) {
165
- entity.removeEffect(effect);
166
- }
167
- }
168
-
169
- /**
170
- * 向实体添加状态效果
171
- * @param entity 要添加状态效果实体对象
172
- * @param effectType 状态效果类型,可以是单个效果类型、效果类型数组、字符串、字符串数组或{@link EffectGroups}枚举值
173
- * @param duration
174
- * 状态效果持续时间,以刻为单位 *(20刻 = 1秒)*
175
- *
176
- * 其值必须在范围`[0, 20000000]`内
177
- *
178
- * 如果值为`"infinite"`,则状态效果将无限期持续
179
- * @param options 状态效果选项
180
- * @since Starock 0.6.0 (0.1.0)
181
- */
182
- export function addEffect(
183
- entity: Entity,
184
- effectType: EffectType | EffectType[] | string | string[] | EffectGroups,
185
- duration: number | "infinite",
186
- options?: EntityEffectOptions
187
- ): void {
188
- const effects =
189
- effectGroupMap[effectType as EffectGroups] ||
190
- (Array.isArray(effectType) ? effectType : [effectType]);
191
- for (const effect of effects) {
192
- if (duration === "infinite") {
193
- entity.runCommand(
194
- // @ts-ignore
195
- `effect @s ${ensureNoNamespace(effect)} infinite ${options?.amplifier ?? 0} ${options?.showParticles ?? false}`
196
- );
197
- return;
198
- }
199
- entity.addEffect(effect, duration, options);
200
- }
201
- }
202
-
203
- /**
204
- * 获取实体所有的族
205
- * @param entity 要获取族的实体
206
- * @return 实体的族数组,如果没有则返回`undefined`
207
- * @see https://zh.minecraft.wiki/w/族
208
- * @see https://minecraft.wiki/w/Family
209
- */
210
- export function getFamilies(entity: Entity): string[] | undefined {
211
- return entity.getComponent("minecraft:type_family")?.getTypeFamilies();
212
- }
213
-
214
- /**
215
- * 返回实体是否含有指定族
216
- * @param entity 要检查族的实体
217
- * @return 实体是否含有指定族
218
- * @see https://zh.minecraft.wiki/w/族
219
- * @see https://minecraft.wiki/w/Family
220
- */
221
- export function hasFamily(entity: Entity, family: string): boolean {
222
- return (
223
- entity.getComponent("minecraft:type_family")?.hasTypeFamily(family) ?? false
224
- );
225
- }
226
-
227
- /**
228
- * 根据玩家等级计算经验消耗
229
- * @param level 玩家等级
230
- */
231
- export function getExpCost(level: number): number {
232
- if (level >= 30) {
233
- return 62 + (level - 30) * 7;
234
- }
235
- if (level >= 15) {
236
- return 17 + (level - 15) * 3;
237
- }
238
- return 17;
239
- }
240
-
241
- /**
242
- * 获取玩家得到的所有经验值
243
- * @param player
244
- */
245
- export function getAllExp(player: Player): number {
246
- const level: number = player.level;
247
- let exp = 0;
248
- for (let i = 1; i <= level; i++) {
249
- exp += getExpCost(i);
250
- }
251
- return exp + player.xpEarnedAtCurrentLevel;
252
- }
253
-
254
- function consumeAmount(item: ItemStack, value: number): ItemStack | undefined {
255
- const amount: number = item.amount;
256
- if (amount === value) {
257
- return undefined;
258
- }
259
- if (amount - value < 0) {
260
- throw new OccultusSDKError(
261
- `The number of items is insufficient! Actual amount: ${amount} Consume amount: ${value}`,
262
- `${item.typeId}`
263
- );
264
- }
265
- if (amount - value > item.maxAmount) {
266
- throw new OccultusSDKError(
267
- `The max stack of items is insufficient!`,
268
- `${item.typeId}`
269
- );
270
- }
271
- const newItem: ItemStack = item.clone();
272
- newItem.amount = amount - value;
273
- return newItem;
274
- }
275
-
276
- /**
277
- * 消耗玩家装备物品的数量
278
- * @param player 要消耗物品的玩家
279
- * @param amount 消耗的数量
280
- * @returns 是否消耗成功
281
- */
282
- export function consumeEquipmentAmount(
283
- player: Player,
284
- amount: number = 1
285
- ): boolean {
286
- const item = getEquipmentItem(player);
287
- if (!item) return false;
288
- return setEquipmentItem(player, consumeAmount(item, amount));
289
- }
290
-
291
- /**
292
- * @deprecated 请使用 {@link EntityHealthUtils.heal}
293
- */
294
- export function heal(entity: Entity, amount: number): number {
295
- return new EntityHealthUtils(entity).heal(amount);
296
- }
297
-
298
- /**
299
- * @deprecated 请使用 {@link EntityHealthUtils.current}
300
- */
301
- export function getCurrentHealth(entity: Entity): number {
302
- return new EntityHealthUtils(entity).current;
303
- }
304
-
305
- /**
306
- * @deprecated 请使用 {@link EntityHealthUtils.current}
307
- */
308
- export function setCurrentHealth(entity: Entity, value: number): number {
309
- return (new EntityHealthUtils(entity).current = value);
310
- }
311
-
312
- /**
313
- * @deprecated 请使用 {@link EntityHealthUtils.damage}
314
- */
315
- export function consumeHealth(entity: Entity, amount: number): number {
316
- return new EntityHealthUtils(entity).damage(amount);
317
- }
318
-
319
- /**
320
- * @deprecated 请使用 {@link EntityHealthUtils.damageWithAmplifier}
321
- */
322
- export function consumeHealthAmplifier(
323
- entity: Entity,
324
- amplifier: number
325
- ): number {
326
- return new EntityHealthUtils(entity).damageWithAmplifier(amplifier);
327
- }
1
+ import {
2
+ Container,
3
+ Effect,
4
+ EffectType,
5
+ Entity,
6
+ EntityComponentTypes,
7
+ EntityEffectOptions,
8
+ EquipmentSlot,
9
+ ItemStack,
10
+ Player
11
+ } from "@minecraft/server";
12
+ import { EffectData, effectGroupMap, EffectGroups } from "@occultus/common";
13
+ import { OccultusSDKError } from "@occultus/core";
14
+ import { ensureNoNamespace } from "../identifier/namespace";
15
+ import { EntityHealthUtils } from "./health";
16
+
17
+ /**
18
+ * 尝试对实体进行操作
19
+ *
20
+ * @param entity 要操作的实体
21
+ * @param operate 操作函数,接受一个实体作为参数
22
+ * @returns 操作是否成功
23
+ * @since Starock 0.6.0 (0.1.0)
24
+ */
25
+ export function tryOperateEntity(
26
+ entity: Entity,
27
+ operate: (entity: Entity) => void
28
+ ): boolean {
29
+ if (entity.isValid) {
30
+ operate(entity);
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ /**
37
+ * 获取给定**玩家**的指定装备槽物品 {@see EquipmentSlot}
38
+ *
39
+ * 注意:该方法仅适用于玩家实体
40
+ *
41
+ * @param entity 要获取槽位的实体
42
+ * @param slot 要获取的槽位,默认为 {@link EquipmentSlot.Mainhand}
43
+ * @return 槽位中的物品
44
+ * @since Starock 0.6.0 (0.1.0)
45
+ */
46
+ export function getEquipmentItem(
47
+ entity: Entity,
48
+ slot = EquipmentSlot.Mainhand
49
+ ): ItemStack | undefined {
50
+ return entity
51
+ ?.getComponent(EntityComponentTypes.Equippable)
52
+ ?.getEquipment(slot);
53
+ }
54
+
55
+ /**
56
+ * 设置给定**玩家**的指定装备槽物品 {@see EquipmentSlot}
57
+ *
58
+ * 注意:该方法仅适用于玩家实体
59
+ *
60
+ * @param entity 要设置槽位的实体
61
+ * @param item 要设置的物品,如果为undefined则清空该槽位
62
+ * @param slot 要设置的槽位,默认为 {@link EquipmentSlot.Mainhand}
63
+ * @since Starock 0.6.0 (0.1.0)
64
+ */
65
+ export function setEquipmentItem(
66
+ entity: Entity,
67
+ item?: ItemStack,
68
+ slot: EquipmentSlot = EquipmentSlot.Mainhand
69
+ ): boolean {
70
+ return (
71
+ entity
72
+ ?.getComponent(EntityComponentTypes.Equippable)
73
+ ?.setEquipment(slot, item) ?? false
74
+ );
75
+ }
76
+
77
+ /**
78
+ * 获取实体的容器
79
+ *
80
+ * @param entity 要获取容器的实体
81
+ * @return 实体的容器,如果没有则返回`undefined`
82
+ * @since Starock 0.6.0 (0.1.0)
83
+ */
84
+ export function getContainer(entity: Entity): Container | undefined {
85
+ return entity.getComponent(EntityComponentTypes.Inventory)?.container;
86
+ }
87
+
88
+ /**
89
+ * 设置实体的槽位物品
90
+ * @param entity 要设置槽位物品的实体
91
+ * @param slot 槽位索引,从0开始依次递增
92
+ * @param item 要设置的物品
93
+ * @since Starock 0.6.0 (0.1.0)
94
+ */
95
+ export function setSlot(entity: Entity, slot: number, item?: ItemStack): void {
96
+ getContainer(entity)?.setItem(slot, item);
97
+ }
98
+
99
+ /**
100
+ * 给予实体物品
101
+ * @param entity 要给予物品的实体
102
+ * @param item 要给予的物品
103
+ * @since Starock 0.6.0 (0.1.0)
104
+ */
105
+ export function giveItem(entity: Entity, item: ItemStack | ItemStack[]): void {
106
+ const container = getContainer(entity);
107
+ if (Array.isArray(item)) {
108
+ for (const i of item) {
109
+ giveItem(entity, i);
110
+ }
111
+ return;
112
+ }
113
+ if (container && container.emptySlotsCount > 0) {
114
+ container.addItem(item);
115
+ } else {
116
+ entity.dimension.spawnItem(item, entity.location);
117
+ }
118
+ }
119
+
120
+ /**
121
+ * 清空实体的容器
122
+ * @param entity 要清空容器的实体
123
+ * @since Starock 0.6.0 (0.1.0)
124
+ */
125
+ export function clearSlot(entity: Entity): void {
126
+ getContainer(entity)?.clearAll();
127
+ }
128
+
129
+ /**
130
+ * 将 {@link EffectData} 应用到实体上
131
+ * @param entity 要应用 {@link EffectData} 的实体
132
+ * @param data 要应用的 {@link EffectData}
133
+ * @returns 应用后的状态效果
134
+ * @since Starock 0.6.0 (0.1.0)
135
+ */
136
+ export function applyEffectData(
137
+ entity: Entity,
138
+ data: EffectData | EffectData[]
139
+ ): (Effect | undefined)[] {
140
+ if (!Array.isArray(data)) {
141
+ data = [data];
142
+ }
143
+ return data.flatMap((effectData) => {
144
+ return entity.addEffect(effectData.effectType, effectData.duration, {
145
+ amplifier: effectData.amplifier,
146
+ showParticles: effectData.showParticles
147
+ });
148
+ });
149
+ }
150
+
151
+ /**
152
+ * 向实体移除状态效果
153
+ * @param entity 要清除效果的实体.
154
+ * @param effectType 状态效果类型,可以是单个效果类型、效果类型数组、字符串、字符串数组或{@link EffectGroups}枚举值
155
+ * @since Starock 0.6.0 (0.1.0)
156
+ */
157
+ export function clearEffect(
158
+ entity: Entity,
159
+ effectType: EffectType | EffectType[] | string | string[] | EffectGroups
160
+ ): void {
161
+ const effects =
162
+ effectGroupMap[effectType as EffectGroups] ||
163
+ (Array.isArray(effectType) ? effectType : [effectType]);
164
+ for (const effect of effects) {
165
+ entity.removeEffect(effect);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * 向实体添加状态效果
171
+ * @param entity 要添加状态效果实体对象
172
+ * @param effectType 状态效果类型,可以是单个效果类型、效果类型数组、字符串、字符串数组或{@link EffectGroups}枚举值
173
+ * @param duration
174
+ * 状态效果持续时间,以刻为单位 *(20刻 = 1秒)*
175
+ *
176
+ * 其值必须在范围`[0, 20000000]`内
177
+ *
178
+ * 如果值为`"infinite"`,则状态效果将无限期持续
179
+ * @param options 状态效果选项
180
+ * @since Starock 0.6.0 (0.1.0)
181
+ */
182
+ export function addEffect(
183
+ entity: Entity,
184
+ effectType: EffectType | EffectType[] | string | string[] | EffectGroups,
185
+ duration: number | "infinite",
186
+ options?: EntityEffectOptions
187
+ ): void {
188
+ const effects =
189
+ effectGroupMap[effectType as EffectGroups] ||
190
+ (Array.isArray(effectType) ? effectType : [effectType]);
191
+ for (const effect of effects) {
192
+ if (duration === "infinite") {
193
+ entity.runCommand(
194
+ // @ts-ignore
195
+ `effect @s ${ensureNoNamespace(effect)} infinite ${options?.amplifier ?? 0} ${options?.showParticles ?? false}`
196
+ );
197
+ return;
198
+ }
199
+ entity.addEffect(effect, duration, options);
200
+ }
201
+ }
202
+
203
+ /**
204
+ * 获取实体所有的族
205
+ * @param entity 要获取族的实体
206
+ * @return 实体的族数组,如果没有则返回`undefined`
207
+ * @see https://zh.minecraft.wiki/w/族
208
+ * @see https://minecraft.wiki/w/Family
209
+ */
210
+ export function getFamilies(entity: Entity): string[] | undefined {
211
+ return entity.getComponent("minecraft:type_family")?.getTypeFamilies();
212
+ }
213
+
214
+ /**
215
+ * 返回实体是否含有指定族
216
+ * @param entity 要检查族的实体
217
+ * @return 实体是否含有指定族
218
+ * @see https://zh.minecraft.wiki/w/族
219
+ * @see https://minecraft.wiki/w/Family
220
+ */
221
+ export function hasFamily(entity: Entity, family: string): boolean {
222
+ return (
223
+ entity.getComponent("minecraft:type_family")?.hasTypeFamily(family) ?? false
224
+ );
225
+ }
226
+
227
+ /**
228
+ * 根据玩家等级计算经验消耗
229
+ * @param level 玩家等级
230
+ */
231
+ export function getExpCost(level: number): number {
232
+ if (level >= 30) {
233
+ return 62 + (level - 30) * 7;
234
+ }
235
+ if (level >= 15) {
236
+ return 17 + (level - 15) * 3;
237
+ }
238
+ return 17;
239
+ }
240
+
241
+ /**
242
+ * 获取玩家得到的所有经验值
243
+ * @param player
244
+ */
245
+ export function getAllExp(player: Player): number {
246
+ const level: number = player.level;
247
+ let exp = 0;
248
+ for (let i = 1; i <= level; i++) {
249
+ exp += getExpCost(i);
250
+ }
251
+ return exp + player.xpEarnedAtCurrentLevel;
252
+ }
253
+
254
+ function consumeAmount(item: ItemStack, value: number): ItemStack | undefined {
255
+ const amount: number = item.amount;
256
+ if (amount === value) {
257
+ return undefined;
258
+ }
259
+ if (amount - value < 0) {
260
+ throw new OccultusSDKError(
261
+ `The number of items is insufficient! Actual amount: ${amount} Consume amount: ${value}`,
262
+ `${item.typeId}`
263
+ );
264
+ }
265
+ if (amount - value > item.maxAmount) {
266
+ throw new OccultusSDKError(
267
+ `The max stack of items is insufficient!`,
268
+ `${item.typeId}`
269
+ );
270
+ }
271
+ const newItem: ItemStack = item.clone();
272
+ newItem.amount = amount - value;
273
+ return newItem;
274
+ }
275
+
276
+ /**
277
+ * 消耗玩家装备物品的数量
278
+ * @param player 要消耗物品的玩家
279
+ * @param amount 消耗的数量
280
+ * @returns 是否消耗成功
281
+ */
282
+ export function consumeEquipmentAmount(
283
+ player: Player,
284
+ amount: number = 1
285
+ ): boolean {
286
+ const item = getEquipmentItem(player);
287
+ if (!item) return false;
288
+ return setEquipmentItem(player, consumeAmount(item, amount));
289
+ }
290
+
291
+ /**
292
+ * @deprecated 请使用 {@link EntityHealthUtils.heal}
293
+ */
294
+ export function heal(entity: Entity, amount: number): number {
295
+ return new EntityHealthUtils(entity).heal(amount);
296
+ }
297
+
298
+ /**
299
+ * @deprecated 请使用 {@link EntityHealthUtils.current}
300
+ */
301
+ export function getCurrentHealth(entity: Entity): number {
302
+ return new EntityHealthUtils(entity).current;
303
+ }
304
+
305
+ /**
306
+ * @deprecated 请使用 {@link EntityHealthUtils.current}
307
+ */
308
+ export function setCurrentHealth(entity: Entity, value: number): number {
309
+ return (new EntityHealthUtils(entity).current = value);
310
+ }
311
+
312
+ /**
313
+ * @deprecated 请使用 {@link EntityHealthUtils.damage}
314
+ */
315
+ export function consumeHealth(entity: Entity, amount: number): number {
316
+ return new EntityHealthUtils(entity).damage(amount);
317
+ }
318
+
319
+ /**
320
+ * @deprecated 请使用 {@link EntityHealthUtils.damageWithAmplifier}
321
+ */
322
+ export function consumeHealthAmplifier(
323
+ entity: Entity,
324
+ amplifier: number
325
+ ): number {
326
+ return new EntityHealthUtils(entity).damageWithAmplifier(amplifier);
327
+ }