@occultus/block-api 0.18.2

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.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2025 CTN Studios
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
File without changes
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@occultus/block-api",
3
+ "version": "0.18.2",
4
+ "description": "Star Tenon block api",
5
+ "main": "src/index.ts",
6
+ "keywords": [
7
+ "Minecraft",
8
+ "Occultus SDK",
9
+ "Script API"
10
+ ],
11
+ "contributors": [
12
+ "FangLimao <mucigames@outlook.com>",
13
+ "RawDiamondMC <RawDiamondMC@outlook.com>"
14
+ ],
15
+ "license": "MIT",
16
+ "author": "CTN Studios",
17
+ "peerDependencies": {
18
+ "@occultus/core": ">=0.18.2 || <0.19.0",
19
+ "@minecraft/server": "2.3.0-beta.1.21.110-preview.20",
20
+ "@minecraft/server-ui": "2.1.0-beta.1.21.110-preview.20"
21
+ },
22
+ "dependencies": {
23
+ "@occultus/loot-api": "0.18.0",
24
+ "@occultus/entity-api": "0.18.1",
25
+ "@occultus/item-api": "0.18.2"
26
+ },
27
+ "type": "module",
28
+ "devDependencies": {
29
+ "typedoc": "^0.28.9"
30
+ }
31
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 设置方块的掉落条件
3
+ *
4
+ * @example
5
+ * new BlockWithDestroyCondition("destroy_condition");
6
+ *
7
+ * @example
8
+ * "destroy_condition": {
9
+ * "tag": "minecraft:is_pickaxe",
10
+ * "loot_table": "blocks/lab_table"
11
+ * }
12
+ */
13
+ export class BlockWithDestroyCondition {
14
+ constructor(readonly name: string) {}
15
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * 允许玩家与方块交互的组件
3
+ */
4
+ export class InteractableBlock {
5
+ /**
6
+ * @param name 可交互方块的名称,这个名称将会被注册为自定义组件
7
+ */
8
+ constructor(readonly name: string) {}
9
+ }
@@ -0,0 +1,12 @@
1
+ import { BlockComponentPlayerBreakEvent } from "@minecraft/server";
2
+
3
+ /**
4
+ * 表示自定义矿石方块的类
5
+ */
6
+ export class OreBlock {
7
+ /**
8
+ * @param name 矿石方块的名称,这个名称将会被注册为自定义组件
9
+ */
10
+ constructor(readonly name: string) {}
11
+ onBreak: (arg: BlockComponentPlayerBreakEvent) => void = () => {};
12
+ }
@@ -0,0 +1,49 @@
1
+ import { Registries } from "@occultus/core";
2
+ import { RegistryBlock } from "../../types/RegistryBlock";
3
+ import { InteractableBlock } from "../InteractableBlock";
4
+ import { BlockInternalUtils } from "../../utils/BlockInternalUtils";
5
+ import { OreBlock } from "../OreBlock";
6
+ import { BlockWithDestroyCondition } from "../BlockWithDestroyCondition";
7
+ import { system } from "@minecraft/server";
8
+
9
+ export class BlockRegistries extends Registries {
10
+ constructor() {
11
+ super();
12
+ }
13
+ private registry: Map<string, RegistryBlock> = new Map();
14
+ id: string = "BlockRegistries";
15
+ delete(id: string) {
16
+ return this.registry.delete(id);
17
+ }
18
+ get(id: string) {
19
+ return this.registry.get(id);
20
+ }
21
+ has(id: string): boolean {
22
+ return this.registry.has(id);
23
+ }
24
+ getAll() {
25
+ return Array.from(this.registry.values());
26
+ }
27
+ add(value: RegistryBlock | RegistryBlock[]): void {
28
+ if (Array.isArray(value)) {
29
+ value.forEach((v) => this.registry.set(v.name, v));
30
+ return;
31
+ }
32
+ this.registry.set(value.name, value);
33
+ }
34
+ register(): void {
35
+ system.beforeEvents.startup.subscribe((init) => {
36
+ this.registry.forEach((value) => {
37
+ if (value instanceof InteractableBlock) {
38
+ BlockInternalUtils.registryInteractableBlockComponent(value, init);
39
+ }
40
+ if (value instanceof OreBlock) {
41
+ BlockInternalUtils.registryOreBlockComponent(value, init);
42
+ }
43
+ if (value instanceof BlockWithDestroyCondition) {
44
+ BlockInternalUtils.registryDestroyCondition(value, init);
45
+ }
46
+ });
47
+ });
48
+ }
49
+ }
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./api/base/BlockRegistries"
2
+ export * from "./api/InteractableBlock"
3
+ export * from "./api/OreBlock"
4
+ export * from "./api/BlockWithDestroyCondition"
5
+ export * from "./types/OreBlockParams"
6
+ export * from "./types/BlockWithDestroyConditionParams"
7
+ export * from "./types/RegistryBlock"
@@ -0,0 +1,19 @@
1
+ export type BlockWithDestroyConditionParams = {
2
+ /**
3
+ * 方块被挖掘后掉落的战利品
4
+ * @example "block/ore/ruby_ore"
5
+ */
6
+ loot_table: string;
7
+ /**
8
+ * 挖掘矿石所需的物品标签
9
+ */
10
+ tag?: string;
11
+ /**
12
+ * 挖掘矿石所需最低工具等级
13
+ */
14
+ item_tier?: string;
15
+ /**
16
+ * 破坏矿石时给予玩家的经验值
17
+ */
18
+ item?: string;
19
+ };
@@ -0,0 +1,27 @@
1
+
2
+ /**
3
+ * 描述自定义矿石方块组件参数的类型
4
+ */
5
+ export type OreBlockParams = {
6
+ /**
7
+ * 方块被挖掘后掉落的战利品
8
+ * @example "block/ore/ruby_ore"
9
+ */
10
+ loot_table: string;
11
+ /**
12
+ * 挖掘矿石所需最低工具等级
13
+ */
14
+ item_tier?: string;
15
+ /**
16
+ * 挖掘矿石所需的物品标签
17
+ */
18
+ tag?: string;
19
+ /**
20
+ * 挖掘矿石所需的特定物品
21
+ */
22
+ item?: string;
23
+ /**
24
+ * 破坏矿石时给予玩家的经验值
25
+ */
26
+ exp?: number;
27
+ };
@@ -0,0 +1,8 @@
1
+ import { InteractableBlock } from "../api/InteractableBlock";
2
+ import { OreBlock } from "../api/OreBlock";
3
+ import { BlockRegistries } from "../api/base/BlockRegistries";
4
+
5
+ /**
6
+ * 需要通过 {@link BlockRegistries} 注册的方块类型
7
+ */
8
+ export type RegistryBlock = OreBlock | InteractableBlock;
@@ -0,0 +1,64 @@
1
+ import { GameMode, Player, system } from "@minecraft/server";
2
+ import { InteractableBlock } from "../api/InteractableBlock";
3
+ import { OreBlock } from "../api/OreBlock";
4
+ import { OreBlockParams } from "../types/OreBlockParams";
5
+ import { loot } from "@occultus/loot-api";
6
+ import { ItemTier } from "@occultus/item-api";
7
+ import { BlockWithDestroyCondition } from "../api/BlockWithDestroyCondition";
8
+ import { BlockWithDestroyConditionParams } from "../types/BlockWithDestroyConditionParams";
9
+ import { getEquipmentItem } from "@occultus/entity-api";
10
+ import { StartupEvent } from "@minecraft/server";
11
+
12
+ export class BlockInternalUtils {
13
+ static registryInteractableBlockComponent(
14
+ block: InteractableBlock,
15
+ arg: StartupEvent
16
+ ): void {
17
+ arg.blockComponentRegistry.registerCustomComponent(block.name, {
18
+ onPlayerInteract(arg) {},
19
+ });
20
+ }
21
+ static registryOreBlockComponent(block: OreBlock, arg: StartupEvent): void {
22
+ const that = this;
23
+ arg.blockComponentRegistry.registerCustomComponent(block.name, {
24
+ onPlayerBreak(callback, param) {
25
+ const p = param.params as OreBlockParams;
26
+ if (!callback.player) return;
27
+ if (block.onBreak) block.onBreak(callback);
28
+ if (callback.player.getGameMode() === GameMode.Creative) return;
29
+ if (that.checkCondition(callback.player, p)) {
30
+ loot(callback.dimension, callback.block.location, p.loot_table);
31
+ if (p.exp) callback.player.addExperience(p.exp);
32
+ }
33
+ },
34
+ });
35
+ }
36
+ static registryDestroyCondition(
37
+ block: BlockWithDestroyCondition,
38
+ arg: StartupEvent
39
+ ): void {
40
+ arg.blockComponentRegistry.registerCustomComponent(block.name, {
41
+ onPlayerBreak(callback, param) {
42
+ if (!callback.player) return;
43
+ const p = param.params as BlockWithDestroyConditionParams;
44
+ if (callback.player.getGameMode() === GameMode.Creative) return;
45
+ if (BlockInternalUtils.checkCondition(callback.player, p)) {
46
+ loot(callback.dimension, callback.block.location, p.loot_table);
47
+ return;
48
+ }
49
+ },
50
+ });
51
+ }
52
+ static checkCondition(
53
+ player: Player,
54
+ data: OreBlockParams | BlockWithDestroyConditionParams
55
+ ): boolean {
56
+ const item = getEquipmentItem(player);
57
+ if (!item) return false;
58
+ if (data.item) return item.typeId === data.item;
59
+ if (data.tag) return item.hasTag(data.tag);
60
+ if (data.item_tier)
61
+ return ItemTier.hasTier(ItemTier.stringfyTier(data.item_tier), item);
62
+ return false;
63
+ }
64
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "include": ["src/*"],
3
+ "exclude": ["./out"],
4
+ "Modules": {
5
+ "resolvePackageJsonExports": true
6
+ },
7
+ "compilerOptions": {
8
+ "noEmit": true,
9
+ "noEmitOnError": true,
10
+ "target": "es2022",
11
+ "lib": ["es2020", "dom"],
12
+ "strict": true,
13
+ "esModuleInterop": true,
14
+ "module": "es2022",
15
+ "moduleResolution": "bundler",
16
+ "outDir": ".",
17
+ "removeComments": true,
18
+ "newLine": "lf",
19
+ "resolveJsonModule": true
20
+ }
21
+ }