sapdon 3.0.2 → 3.0.3
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/dist/cli/build.d.ts +7 -0
- package/dist/cli/build.js +234 -0
- package/dist/cli/dev-server/client.d.ts +2 -0
- package/dist/cli/dev-server/client.js +21 -0
- package/dist/cli/dev-server/config.d.ts +3 -0
- package/dist/cli/dev-server/config.js +3 -0
- package/dist/cli/dev-server/handles.d.ts +4 -0
- package/dist/cli/dev-server/handles.js +5 -0
- package/dist/cli/dev-server/hmr.d.ts +1 -0
- package/dist/cli/dev-server/hmr.js +13 -0
- package/dist/cli/dev-server/index.d.ts +4 -0
- package/dist/cli/dev-server/index.js +17 -0
- package/dist/cli/dev-server/server.d.ts +14 -0
- package/dist/cli/dev-server/server.js +59 -0
- package/dist/cli/dev-server/syncFiles.d.ts +3 -0
- package/dist/cli/dev-server/syncFiles.js +37 -0
- package/dist/cli/index.d.ts +23 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/init.d.ts +9 -0
- package/dist/cli/init.js +80 -0
- package/dist/cli/load.d.ts +3 -0
- package/dist/cli/load.js +94 -0
- package/dist/cli/start.d.ts +2 -0
- package/dist/cli/start.js +2 -0
- package/dist/cli/tools/textureSet.d.ts +13 -0
- package/dist/cli/tools/textureSet.js +103 -0
- package/dist/cli/utils.d.ts +13 -0
- package/dist/cli/utils.js +89 -0
- package/dist/core/addon/biome.d.ts +22 -0
- package/dist/core/addon/biome.js +27 -0
- package/dist/core/addon/block/block.d.ts +41 -0
- package/dist/core/addon/block/block.js +46 -0
- package/dist/core/addon/controllers/animationController.d.ts +43 -0
- package/dist/core/addon/controllers/animationController.js +73 -0
- package/dist/core/addon/entity/clientEntity.d.ts +107 -0
- package/dist/core/addon/entity/clientEntity.js +149 -0
- package/dist/core/addon/entity/entity.d.ts +42 -0
- package/dist/core/addon/entity/entity.js +50 -0
- package/dist/core/addon/feature/oreFeature.d.ts +19 -0
- package/dist/core/addon/feature/oreFeature.js +24 -0
- package/dist/core/addon/featureRule.d.ts +20 -0
- package/dist/core/addon/featureRule.js +25 -0
- package/dist/core/addon/item/attachable.d.ts +94 -0
- package/dist/core/addon/item/attachable.js +134 -0
- package/dist/core/addon/item/item.d.ts +19 -0
- package/dist/core/addon/item/item.js +26 -0
- package/dist/core/addon/manifest.d.ts +49 -0
- package/dist/core/addon/manifest.js +65 -0
- package/dist/core/addon/menuCategory.d.ts +6 -0
- package/dist/core/addon/menuCategory.js +7 -0
- package/dist/core/addon/recipe/baseRecipe.d.ts +12 -0
- package/dist/core/addon/recipe/baseRecipe.js +23 -0
- package/dist/core/addon/recipe/data.d.ts +66 -0
- package/dist/core/addon/recipe/data.js +74 -0
- package/dist/core/addon/recipe/furnace.d.ts +17 -0
- package/dist/core/addon/recipe/furnace.js +43 -0
- package/dist/core/addon/recipe/shaped.d.ts +26 -0
- package/dist/core/addon/recipe/shaped.js +53 -0
- package/dist/core/addon/recipe/shapeless.d.ts +18 -0
- package/dist/core/addon/recipe/shapeless.js +36 -0
- package/dist/core/biome/biome.d.ts +14 -0
- package/dist/core/biome/biome.js +23 -0
- package/dist/core/biome/biomeComponent.d.ts +46 -0
- package/dist/core/biome/biomeComponent.js +77 -0
- package/dist/core/block/basicBlock.d.ts +48 -0
- package/dist/core/block/basicBlock.js +105 -0
- package/dist/core/block/block.d.ts +32 -0
- package/dist/core/block/block.js +92 -0
- package/dist/core/block/blockComponent.d.ts +187 -0
- package/dist/core/block/blockComponent.js +500 -0
- package/dist/core/block/cropBlock.d.ts +4 -0
- package/dist/core/block/cropBlock.js +27 -0
- package/dist/core/block/geometryBlock.d.ts +12 -0
- package/dist/core/block/geometryBlock.js +16 -0
- package/dist/core/block/oreBlock.d.ts +9 -0
- package/dist/core/block/oreBlock.js +25 -0
- package/dist/core/block/rotatableBlock.d.ts +27 -0
- package/dist/core/block/rotatableBlock.js +107 -0
- package/dist/core/block/tileBlock.d.ts +17 -0
- package/dist/core/block/tileBlock.js +125 -0
- package/dist/core/entity/basicEntity.d.ts +111 -0
- package/dist/core/entity/basicEntity.js +170 -0
- package/dist/core/entity/behavior/followMob.d.ts +12 -0
- package/dist/core/entity/behavior/followMob.js +35 -0
- package/dist/core/entity/behavior/followParent.d.ts +7 -0
- package/dist/core/entity/behavior/followParent.js +15 -0
- package/dist/core/entity/behavior/randomStroll.d.ts +31 -0
- package/dist/core/entity/behavior/randomStroll.js +63 -0
- package/dist/core/entity/behavior/tempt.d.ts +73 -0
- package/dist/core/entity/behavior/tempt.js +134 -0
- package/dist/core/entity/bundles/basicBundle.d.ts +13 -0
- package/dist/core/entity/bundles/basicBundle.js +45 -0
- package/dist/core/entity/clientEntity.d.ts +20 -0
- package/dist/core/entity/clientEntity.js +37 -0
- package/dist/core/entity/componets/entityComponet.d.ts +202 -0
- package/dist/core/entity/componets/entityComponet.js +347 -0
- package/dist/core/entity/data/nativeEntityData.d.ts +9 -0
- package/dist/core/entity/data/nativeEntityData.js +38 -0
- package/dist/core/entity/entity.d.ts +15 -0
- package/dist/core/entity/entity.js +18 -0
- package/dist/core/entity/nativeEntity.d.ts +8 -0
- package/dist/core/entity/nativeEntity.js +28 -0
- package/dist/core/entity/navigation/walk.d.ts +23 -0
- package/dist/core/entity/navigation/walk.js +56 -0
- package/dist/core/entity/projectile.d.ts +3 -0
- package/dist/core/entity/projectile.js +7 -0
- package/dist/core/factory/biomeFactory.d.ts +4 -0
- package/dist/core/factory/biomeFactory.js +13 -0
- package/dist/core/factory/blockFactory.d.ts +34 -0
- package/dist/core/factory/blockFactory.js +143 -0
- package/dist/core/factory/entityFactory.d.ts +17 -0
- package/dist/core/factory/entityFactory.js +75 -0
- package/dist/core/factory/featureFactory.d.ts +6 -0
- package/dist/core/factory/featureFactory.js +23 -0
- package/dist/core/factory/itemExtra.d.ts +8 -0
- package/dist/core/factory/itemExtra.js +9 -0
- package/dist/core/factory/itemFactory.d.ts +27 -0
- package/dist/core/factory/itemFactory.js +112 -0
- package/dist/core/factory/recipeFactory.d.ts +18 -0
- package/dist/core/factory/recipeFactory.js +39 -0
- package/dist/core/factory/uiFactory.d.ts +12 -0
- package/dist/core/factory/uiFactory.js +32 -0
- package/dist/core/feature/oreFeature.d.ts +10 -0
- package/dist/core/feature/oreFeature.js +11 -0
- package/dist/core/feature-rule/condition/biomeFilter.d.ts +26 -0
- package/dist/core/feature-rule/condition/biomeFilter.js +36 -0
- package/dist/core/feature-rule/condition/featureConditions.d.ts +27 -0
- package/dist/core/feature-rule/condition/featureConditions.js +37 -0
- package/dist/core/feature-rule/distribution/coordinateDistribution.d.ts +17 -0
- package/dist/core/feature-rule/distribution/coordinateDistribution.js +23 -0
- package/dist/core/feature-rule/distribution/featureDistribution.d.ts +31 -0
- package/dist/core/feature-rule/distribution/featureDistribution.js +41 -0
- package/dist/core/feature-rule/featureRule.d.ts +17 -0
- package/dist/core/feature-rule/featureRule.js +26 -0
- package/dist/core/index.d.ts +2062 -0
- package/dist/core/index.js +1 -0
- package/dist/core/item/armor.d.ts +21 -0
- package/dist/core/item/armor.js +90 -0
- package/dist/core/item/attachable.d.ts +6 -0
- package/dist/core/item/attachable.js +26 -0
- package/dist/core/item/food.d.ts +24 -0
- package/dist/core/item/food.js +38 -0
- package/dist/core/item/item.d.ts +36 -0
- package/dist/core/item/item.js +69 -0
- package/dist/core/item/itemComponents.d.ts +113 -0
- package/dist/core/item/itemComponents.js +225 -0
- package/dist/core/registry.d.ts +12 -0
- package/dist/core/registry.js +16 -0
- package/dist/core/texture.d.ts +18 -0
- package/dist/core/texture.js +38 -0
- package/dist/core/ui/buttonMapping.d.ts +97 -0
- package/dist/core/ui/buttonMapping.js +132 -0
- package/dist/core/ui/dataBindingObject.d.ts +97 -0
- package/dist/core/ui/dataBindingObject.js +134 -0
- package/dist/core/ui/elements/button.d.ts +21 -0
- package/dist/core/ui/elements/button.js +101 -0
- package/dist/core/ui/elements/collectionPanel.d.ts +12 -0
- package/dist/core/ui/elements/collectionPanel.js +53 -0
- package/dist/core/ui/elements/grid.d.ts +8 -0
- package/dist/core/ui/elements/grid.js +33 -0
- package/dist/core/ui/elements/image.d.ts +13 -0
- package/dist/core/ui/elements/image.js +55 -0
- package/dist/core/ui/elements/label.d.ts +14 -0
- package/dist/core/ui/elements/label.js +61 -0
- package/dist/core/ui/elements/panel.d.ts +11 -0
- package/dist/core/ui/elements/panel.js +49 -0
- package/dist/core/ui/elements/scrollingPanel.d.ts +14 -0
- package/dist/core/ui/elements/scrollingPanel.js +59 -0
- package/dist/core/ui/elements/stackPanel.d.ts +14 -0
- package/dist/core/ui/elements/stackPanel.js +37 -0
- package/dist/core/ui/elements/uiElement.d.ts +53 -0
- package/dist/core/ui/elements/uiElement.js +129 -0
- package/dist/core/ui/properties/control.d.ts +214 -0
- package/dist/core/ui/properties/control.js +286 -0
- package/dist/core/ui/properties/dataBinding.d.ts +6 -0
- package/dist/core/ui/properties/dataBinding.js +16 -0
- package/dist/core/ui/properties/factory.d.ts +37 -0
- package/dist/core/ui/properties/factory.js +62 -0
- package/dist/core/ui/properties/gridProp.d.ts +65 -0
- package/dist/core/ui/properties/gridProp.js +90 -0
- package/dist/core/ui/properties/input.d.ts +97 -0
- package/dist/core/ui/properties/input.js +134 -0
- package/dist/core/ui/properties/layout.d.ts +105 -0
- package/dist/core/ui/properties/layout.js +145 -0
- package/dist/core/ui/properties/scrollView.d.ts +105 -0
- package/dist/core/ui/properties/scrollView.js +145 -0
- package/dist/core/ui/properties/sound.d.ts +47 -0
- package/dist/core/ui/properties/sound.js +66 -0
- package/dist/core/ui/properties/sprite.d.ts +161 -0
- package/dist/core/ui/properties/sprite.js +222 -0
- package/dist/core/ui/properties/text.d.ts +135 -0
- package/dist/core/ui/properties/text.js +187 -0
- package/dist/core/ui/registry/uiSystemRegistry.d.ts +8 -0
- package/dist/core/ui/registry/uiSystemRegistry.js +26 -0
- package/dist/core/ui/systems/chest.d.ts +5 -0
- package/dist/core/ui/systems/chest.js +21 -0
- package/dist/core/ui/systems/containerUISystem.d.ts +67 -0
- package/dist/core/ui/systems/containerUISystem.js +214 -0
- package/dist/core/ui/systems/guidebook.d.ts +9 -0
- package/dist/core/ui/systems/guidebook.js +206 -0
- package/dist/core/ui/systems/serverForm.d.ts +13 -0
- package/dist/core/ui/systems/serverForm.js +116 -0
- package/dist/core/ui/systems/system.d.ts +16 -0
- package/dist/core/ui/systems/system.js +37 -0
- package/dist/oc/index.d.ts +142 -0
- package/dist/oc/index.js +1 -0
- package/doc/sapdon-ts.md +35 -1
- package/package.json +6 -8
package/dist/cli/load.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { saveFile } from "./utils.js";
|
|
3
|
+
import { generateBlockTextureJson, generateItemTextureJson } from "./tools/textureSet.js";
|
|
4
|
+
import { FlipbookTextures, ItemTextureManager, terrainTextureManager } from "../core/texture.js";
|
|
5
|
+
import { writeAddon } from './dev-server/client.js';
|
|
6
|
+
/**
|
|
7
|
+
* 处理 blocks.json 数据
|
|
8
|
+
* @param {Object} data blocks.json 数据
|
|
9
|
+
* @returns {Object} 处理后的 blocks 数据
|
|
10
|
+
*/
|
|
11
|
+
export const processBlocksData = (data) => {
|
|
12
|
+
const textures_arr = data.textures;
|
|
13
|
+
// 检查 textures 数组长度
|
|
14
|
+
if (textures_arr.length !== 6) {
|
|
15
|
+
console.warn(`blocks.json 的 textures 数组长度不为 6,实际长度: ${textures_arr.length}`);
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
// 构建 blocks 数据
|
|
19
|
+
const blocks = {};
|
|
20
|
+
blocks[data.identifier] = {
|
|
21
|
+
textures: {
|
|
22
|
+
up: textures_arr[0],
|
|
23
|
+
down: textures_arr[1],
|
|
24
|
+
east: textures_arr[2],
|
|
25
|
+
west: textures_arr[3],
|
|
26
|
+
south: textures_arr[4],
|
|
27
|
+
north: textures_arr[5]
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
return blocks;
|
|
31
|
+
};
|
|
32
|
+
export const generateAddonClient = async (modPath, buildPath, projectName) => {
|
|
33
|
+
writeAddon(modPath, buildPath, projectName);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Server
|
|
37
|
+
* 加载并执行模组文件
|
|
38
|
+
* @param {string} modPath 模组文件路径
|
|
39
|
+
* @param {string} buildPath 构建目录路径
|
|
40
|
+
* @param {string} projectName 项目名
|
|
41
|
+
*/
|
|
42
|
+
export const generateAddon = (GRegistry, UISystemRegistry) => async (modPath, buildPath, projectName) => {
|
|
43
|
+
try {
|
|
44
|
+
const buildBehDirPath = path.join(buildPath, `${projectName}_BP`);
|
|
45
|
+
const buildResDirPath = path.join(buildPath, `${projectName}_RP`);
|
|
46
|
+
const resDir = name => path.join(buildResDirPath, name);
|
|
47
|
+
// 初始化 blocks.json 数据
|
|
48
|
+
const blocksJsonPath = path.join(buildBehDirPath, "blocks.json");
|
|
49
|
+
const blocks = { "format_version": "1.20.20" };
|
|
50
|
+
//生成item_texture.json
|
|
51
|
+
const item_texture_dir = resDir("textures/items");
|
|
52
|
+
const item_texture_json_path = resDir("textures/item_texture.json");
|
|
53
|
+
generateItemTextureJson(item_texture_dir, item_texture_json_path, projectName, ItemTextureManager.getItemTextures());
|
|
54
|
+
//生成terrain_texture.json
|
|
55
|
+
const terrain_texture_dir = resDir("textures/blocks");
|
|
56
|
+
const terrain_texture_json_path = resDir("textures/terrain_texture.json");
|
|
57
|
+
generateBlockTextureJson(terrain_texture_dir, terrain_texture_json_path, projectName, terrainTextureManager.getTerrainTextures());
|
|
58
|
+
//生成flipbook_textures.json
|
|
59
|
+
const flipbook_textures_path = resDir("textures/flipbook_textures.json");
|
|
60
|
+
saveFile(flipbook_textures_path, JSON.stringify(FlipbookTextures.flipbook_textures, null, 2));
|
|
61
|
+
//_ui_defs.json
|
|
62
|
+
const ui_def = UISystemRegistry.getUIdefList();
|
|
63
|
+
saveFile(resDir("ui/_ui_defs.json"), JSON.stringify({ "ui_defs": ui_def }, null, 2));
|
|
64
|
+
UISystemRegistry.getUISystemList().forEach((ui_system) => {
|
|
65
|
+
saveFile(resDir(ui_system.path, `${ui_system.name}.json`), JSON.stringify(ui_system.toJson(), null, 2));
|
|
66
|
+
});
|
|
67
|
+
// 从全局注册表中获取数据
|
|
68
|
+
const dataList = GRegistry.getDataList();
|
|
69
|
+
// console.log("dataList:", dataList)
|
|
70
|
+
// 遍历数据并保存到相应的目录
|
|
71
|
+
dataList.forEach(({ name, root, path: dataPath, data }) => {
|
|
72
|
+
// 处理 blocks.json 数据
|
|
73
|
+
if (dataPath === "blocks/") {
|
|
74
|
+
const processedBlocks = processBlocksData(data);
|
|
75
|
+
Object.assign(blocks, processedBlocks);
|
|
76
|
+
}
|
|
77
|
+
// 根据数据类型确定根目录
|
|
78
|
+
const rootPath = root === "behavior" ? `${projectName}_BP` : `${projectName}_RP`;
|
|
79
|
+
const buildRootPath = path.join(buildPath, rootPath);
|
|
80
|
+
// 拼接文件路径
|
|
81
|
+
const filePath = path.join(buildRootPath, dataPath, `${name}.json`);
|
|
82
|
+
// 保存文件
|
|
83
|
+
saveFile(filePath, JSON.stringify(data.toJson(), null, 2));
|
|
84
|
+
});
|
|
85
|
+
// 保存 blocks.json
|
|
86
|
+
console.log("保存 blocks.json 文件:", blocksJsonPath);
|
|
87
|
+
saveFile(blocksJsonPath, JSON.stringify(blocks, null, 2));
|
|
88
|
+
console.log(`已加载并执行 ${modPath} 文件!`);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
console.error(`加载或执行 ${modPath} 失败:${err.message}`);
|
|
92
|
+
console.error(err.stack); // 打印堆栈跟踪以便调试
|
|
93
|
+
}
|
|
94
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import{program as n}from"commander";import o from"inquirer";import e from"path";import i from"os";import{fileURLToPath as t}from"url";import s from"fs";import{randomUUID as r}from"crypto";import{fileURLToPath as c}from"node:url";import a from"child_process";import"fs/promises";import{rollup as p}from"rollup";import l from"@rollup/plugin-commonjs";import{nodeResolve as m}from"@rollup/plugin-node-resolve";import d from"@rollup/plugin-typescript";import{typescriptPaths as u}from"rollup-plugin-typescript-paths";import f from"@rollup/plugin-json";import"rollup-plugin-visualizer";import g from"lodash";const j=()=>r();function y(n,o){try{s.copyFileSync(n,o)}catch(n){console.error("文件复制失败:",n)}}const h=n=>!s.existsSync(n),S=n=>{try{return s.readFileSync(n,"utf8")}catch(n){console.log(n)}return null},_=(n,o)=>{s.mkdirSync(e.dirname(n),{recursive:!0}),s.writeFile(n,o,(n=>{if(n)return console.error(n)}))},w=(n,o)=>{if(s.mkdirSync(e.dirname(o),{recursive:!0}),!s.existsSync(n))return void console.log(`Source path ${n} does not exist.`);s.existsSync(o)||s.mkdirSync(o);s.readdirSync(n).forEach((i=>{const t=e.join(n,i),r=e.join(o,i);s.lstatSync(t).isDirectory()?w(t,r):s.copyFileSync(t,r)}))};const v=t(import.meta.url),b=e.dirname(v),k={js:"test_sapdon",ts:"ts_sapdon"};const P=n=>{const o=e.join(n,"package.json");if(!s.existsSync(o))return null;try{const i=JSON.parse(s.readFileSync(o,"utf-8"));return{name:e.basename(n),description:i.description||"A new sapdon project",author:i.author||"Sapdon",version:i.version||"1.0.0"}}catch(n){return console.error("读取package.json文件时出错:",n),null}};var N;!function(n){n.WRITE_ADDON="write-addon",n.WRITE_GAME_DEV="write-dev"}(N||(N={}));const{port:O}={port:49037};async function D(n,...o){try{await fetch(`http://localhost:${O}/${n}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)})}catch(n){console.error(n),console.error("尝试在构建脚本中使用 server.startDevServer() 启动开发服务器")}}const J=async(n,o,e)=>{!async function(n,o,e){await D(N.WRITE_ADDON,n,o,e)}(n,o,e)};class M{constructor(n,o,e,i,t={}){this.name=n,this.description=o,this.version=e,this.uuid=i,this.allow_random_seed=t.allow_random_seed,this.lock_template_options=t.lock_template_options,this.pack_scope=t.pack_scope,this.base_game_version=t.base_game_version,this.min_engine_version=t.min_engine_version}}class E{constructor(n,o,e,i){this.description=n,this.type=o,this.uuid=e,this.version=i}}class x{constructor(n,o,e,i,t){this.authors=n,this.license=o,this.generated_with=e,this.product_type=i,this.url=t}}class F{constructor(n,o,e,i,t=null,s=null){this.format_version=n,this.header=o,this.modules=e,this.dependencies=i,null!=t&&(this.capabilities=t),null!=s&&(this.metadata=s)}}async function L(n){const o=e.join(n,"node_modules"),i=e.join(function(n){const o=c(n.url);return e.dirname(o)}(import.meta),"../"),t=e.join(i,"core"),r=e.join(i,"cli"),a=e.join(i,"oc"),p=e.join(o,"@sapdon/core"),l=e.join(o,"@sapdon/cli"),m=e.join(o,"@sapdon/oc");s.cpSync(t,p,{recursive:!0,force:!0}),s.cpSync(r,l,{recursive:!0,force:!0}),s.cpSync(a,m,{recursive:!0,force:!0}),s.writeFileSync(e.join(p,"package.json"),JSON.stringify({name:"@sapdon/core",main:"index.js",version:"1.0.0"})),s.writeFileSync(e.join(l,"package.json"),JSON.stringify({name:"@sapdon/cli",main:"index.js",version:"1.0.0"})),s.writeFileSync(e.join(m,"package.json"),JSON.stringify({name:"@sapdon/oc",main:"index.js",version:"1.0.0"}))}g.debounce;const R=t(import.meta.url),A=e.dirname(R),U=["rollup","typescript","@sapdon/core","@sapdon/cli","@minecraft"],I={__projectPath:e.join(A,"../../"),js:(n,o)=>{w(n,o)},ts:async(n,o,i="index.js",t="index.ts")=>{const r=e.join(I.__projectPath,".tmp",`sapdon-${crypto.randomUUID()}.js`);try{const c=await p({input:e.join(n,t),plugins:[u(),m({preferBuiltins:!0}),d({tsconfig:e.join(I.__projectPath,"tsconfig.json")}),l(),f()],external(n){for(const o of U)if(n.includes(o))return!0;return!1}});await c.write({file:r,format:"esm"}),c.close(),s.cpSync(r,e.join(o,i))}catch(n){console.error(n)}finally{s.rmSync(r,{recursive:!0,force:!0})}}};async function T(n,o,i){const t=e.join(n,i.path),s=i.type||"js";I.__projectPath=n,I[s](t,o)}async function W(n){const{promise:o,resolve:e}=Promise.withResolvers(),i=a.fork(n,{stdio:"inherit"});i.once("message",(n=>{"initialized"!==n&&i.kill(),e()})),await o}async function C(n){if(n.endsWith(".ts")){const i=crypto.randomUUID()+".js",t=e.dirname(n),r=n.replace(t,""),c=e.join(t,i);await I.ts(t,t,i,r),o=c,s.appendFileSync(o,"\n ;(async () => {\n const { startDevServer } = await import('@sapdon/cli')\n const { GRegistry, UISystemRegistry } = await import('@sapdon/core')\n startDevServer(GRegistry, UISystemRegistry)\n })();\n ");try{await W(c)}finally{s.rmSync(c,{force:!0})}}else{var o;await W(n)}}function B(n,o){return console.log("开始构建项目"),console.log("项目路径:"+n),h(n)?(console.log("项目不存在"),!1):!h(e.join(n,"build.config"))||(console.log("项目没有build.config文件"),!1)}const $=async(n,o)=>{const i=e.join(n,"build.config"),t=JSON.parse(S(i)),s=e.join(n,"mod.info"),r=JSON.parse(S(s)),c=G(r.min_engine_version),a=e.join(n,t.defaultConfig.buildDir),p=e.join(a,`${o}_BP/`),l=e.join(a,`${o}_RP/`),m=e.join(p,"manifest.json");if(h(m)){const n=V(r.name,r.description,r.version,{min_engine_version:c},t.defaultConfig.dependencies,t.defaultConfig.scriptEntry),o=z(r.name,r.description,r.version,{min_engine_version:c},[]);_(e.join(p,"manifest.json"),n),_(e.join(l,"manifest.json"),o)}const d=e.join(n,"pack_icon.png");y(d,e.join(p,"pack_icon.png")),y(d,e.join(l,"pack_icon.png"));t.resources.forEach((o=>{const i=e.join(n,o.path);w(i,l)}));const u=t.scripts,f=e.join(p,"scripts/");for(const o of u)await T(n,f,o);const g=e.join(n,t.defaultConfig.buildEntry);await C(g),"development"===t.defaultConfig.buildMode&&await J(g,a,o),async function(n,o){await D(N.WRITE_GAME_DEV,n,o)}(n,o),t.useHMR};function G(n){return n.split(".").map((n=>Number(n)))}const V=(n,o,e,i={},t=[],s)=>{console.log("开始生成behavior_packs/manifest.json"),console.log("Entry:",s);const r=new M(n+"_BP",o,G(e),j(),i),c=new E("行为模块","data",j(),G(e)),a=new E("脚本模块","script",j(),G(e));s&&(a.entry=s);const p=new x(["@sapdon"],"MIT",{sapdon:["1.0.0"]},"addon","https://github.com/junjun260/sapdon"),l=new F(2,r,[c,a],t,null,p);return JSON.stringify(l,null,2)},z=(n,o,e,i={},t=[])=>{const s=new M(n+"_RP",o,G(e),j(),i),r=new E("资源模块","resources",j(),G(e)),c=new x(["@sapdon"],"MIT",{sapdon:["1.0.0"]},"addon","https://github.com/junjun260/sapdon"),a=new F(2,s,[r],[],null,c);return JSON.stringify(a,null,2)},q=t(import.meta.url),H=e.dirname(q);process.removeAllListeners("warning"),n.command("init").description("初始化一个基于NodeJS的项目").action((()=>{const n=process.cwd(),i=e.join(n,"package.json");let t;if(s.existsSync(i)){try{t=JSON.parse(s.readFileSync(i,"utf-8"))}catch(n){return console.error("读取package.json文件时出错:",n),void console.log("请使改用create命令进行创建。")}t.scripts={...t.scripts,init:"sapdon init",pack:"sapdon pack",config:"sapdon config"};try{s.writeFileSync(i,JSON.stringify(t,null,2),"utf-8")}catch(n){return void console.error("写入package.json文件时出错:",n)}o.prompt([{type:"input",name:"min_engine_version",message:"最低引擎版本:",default:"1.19.50"}]).then((o=>{((n,o)=>{if(!(h(e.join(n,"mod.info"))&&h(e.join(n,"main.mjs"))&&h(e.join(n,"scripts"))&&h(e.join(n,"build.config"))))return void console.log("项目已存在...");const i=e.join(b,"../templates/test_sapdon");w(i,n),_(e.join(n,"mod.info"),JSON.stringify(o,null,2))})(n,{...P(n),...o}),console.log("请使用命令sapdon config配置框架的build.config文件。")}))}else console.error("没有找到package.json文件,请使改用create命令进行创建。")})),n.command("create <project-name>").description("Create a new project").action((n=>{o.prompt([{type:"input",name:"name",message:"Project Name:",default:e.basename(n)},{type:"input",name:"description",message:"Project Description:",default:"A new sapdon project"},{type:"input",name:"author",message:"Author Name:",default:"Sapdon"},{type:"input",name:"version",message:"Project Version:",default:"1.0.0"},{type:"input",name:"min_engine_version",message:"Minimum Engine Version:",default:"1.19.50"},{type:"input",name:"language",message:"Language:(js/ts)",default:"ts"}]).then((o=>{const t=e.join(process.cwd(),n);console.log("项目路径:",t),((n,o)=>{if(console.log(1,o),!h(n))return void console.log("项目名称已存在,创建项目目录失败");const i=e.join(b,`../../src/templates/${k[o.language||"js"]}`);w(i,n),_(e.join(n,"mod.info"),JSON.stringify(o,null,2)),a.execSync("npm i",{cwd:n,stdio:"inherit"})})(t,o),function(n){const o=e.join(i.homedir(),"AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/"),t=e.join(i.homedir(),"AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/"),r=e.join(n,"./build.config"),c=JSON.parse(s.readFileSync(r));c.mojangPath=o,c.betaPath=t,_(r,JSON.stringify(c,null,2))}(t),L(t)}))})),n.command("build <project-name>").description("Build the project").action((n=>{console.log("Building the project...");const o=e.join(process.cwd(),n);B(o)&&$(o,e.basename(o))})),n.command("pack").description("Pack the current project").action((()=>{console.log("Packing the current project...");const n=process.cwd();B(n)&&$(n,e.basename(n))})),n.command("lib").description("Generate lib files for development server.").action((()=>{L(process.cwd())})),n.command("config").description("Configure build.config file").action((()=>{const n=e.join(H,"./build.config");let t;try{t=JSON.parse(S(n))}catch(n){return void console.error("读取build.config文件时出错:",n)}o.prompt([{type:"input",name:"mojangPath",message:"Mojang Path (must end with LocalState/games/com.mojang/):",default:e.join(i.homedir(),"AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/")},{type:"input",name:"mojangBetaPath",message:"Mojang Beta Path (must end with LocalState/games/com.mojang/):",default:e.join(i.homedir(),"AppData/Local/Packages/Microsoft.MinecraftUWP_8wekyb3d8bbwe/LocalState/games/com.mojang/")}]).then((o=>{try{s.writeFileSync(n,JSON.stringify({...t,...o},null,2),"utf-8"),console.log("build.config文件已更新。")}catch(n){console.error("写入build.config文件时出错:",n)}}))})),n.parse(n.argv);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 生成 block_texture.json 文件
|
|
3
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
4
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
5
|
+
* @param {string} projectName - 项目名称
|
|
6
|
+
*/
|
|
7
|
+
export function generateBlockTextureJson(itemTexturesPath: string, outputPath: string, projectName: string, userTerrainTextures: any): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* 生成 item_texture.json 文件
|
|
10
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
11
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
12
|
+
*/
|
|
13
|
+
export function generateItemTextureJson(itemTexturesPath: string, outputPath: string, projectName: any, userItemTextures: any): Promise<void>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* 递归遍历目录,收集所有 PNG 文件的路径
|
|
5
|
+
* @param {string} directory - 要遍历的目录
|
|
6
|
+
* @param {string} basePath - 基础路径(用于计算相对路径)
|
|
7
|
+
* @param {string} prefix - 路径前缀(如 "textures/items/")
|
|
8
|
+
* @returns {Promise<Object>} - 返回一个对象,键为文件名,值为相对路径(不带 .png 后缀)
|
|
9
|
+
*/
|
|
10
|
+
const traverseDirectory = async (directory, basePath, prefix = "") => {
|
|
11
|
+
const texturesSet = {};
|
|
12
|
+
const files = await fs.readdir(directory);
|
|
13
|
+
for (const file of files) {
|
|
14
|
+
const filePath = path.join(directory, file);
|
|
15
|
+
const fileStats = await fs.stat(filePath);
|
|
16
|
+
if (fileStats.isDirectory()) {
|
|
17
|
+
// 如果是目录,递归遍历
|
|
18
|
+
const subDirectoryTextures = await traverseDirectory(filePath, basePath, prefix);
|
|
19
|
+
Object.assign(texturesSet, subDirectoryTextures);
|
|
20
|
+
}
|
|
21
|
+
else if (file.endsWith(".png")) {
|
|
22
|
+
// 如果是 PNG 文件,提取文件名并生成 texture_data
|
|
23
|
+
const fileName = path.basename(file, ".png"); // 去掉 .png 后缀
|
|
24
|
+
const relativePath = path.relative(basePath, filePath).replace(/\.png$/, ""); // 去掉 .png 后缀
|
|
25
|
+
const normalizedPath = `${prefix}${relativePath.replace(/\\/g, "/")}`; // 确保路径使用正斜杠
|
|
26
|
+
texturesSet[fileName] = {
|
|
27
|
+
textures: normalizedPath,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return texturesSet;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* 生成 JSON 文件
|
|
35
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
36
|
+
* @param {Object} jsonData - 要写入的 JSON 数据
|
|
37
|
+
* @param {string} successMessage - 成功时的日志消息
|
|
38
|
+
*/
|
|
39
|
+
const generateJsonFile = async (outputPath, jsonData, successMessage) => {
|
|
40
|
+
try {
|
|
41
|
+
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
42
|
+
await fs.writeFile(outputPath, jsonString);
|
|
43
|
+
console.log(successMessage);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error("Error writing JSON file:", err);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* 生成 block_texture.json 文件
|
|
51
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
52
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
53
|
+
* @param {string} projectName - 项目名称
|
|
54
|
+
*/
|
|
55
|
+
export async function generateBlockTextureJson(itemTexturesPath, outputPath, projectName, userTerrainTextures) {
|
|
56
|
+
try {
|
|
57
|
+
// 递归遍历目录,获取所有 PNG 文件的路径
|
|
58
|
+
const itemTexturesSet = await traverseDirectory(itemTexturesPath, itemTexturesPath, "textures/blocks/");
|
|
59
|
+
// 合并用户自定义的texture_data
|
|
60
|
+
if (userTerrainTextures) {
|
|
61
|
+
Object.assign(itemTexturesSet, userTerrainTextures);
|
|
62
|
+
}
|
|
63
|
+
// 生成 JSON 数据
|
|
64
|
+
const jsonData = {
|
|
65
|
+
texture_name: "atlas.terrain",
|
|
66
|
+
resource_pack_name: projectName,
|
|
67
|
+
padding: 8,
|
|
68
|
+
num_mip_levels: 4,
|
|
69
|
+
texture_data: itemTexturesSet,
|
|
70
|
+
};
|
|
71
|
+
// 写入文件
|
|
72
|
+
await generateJsonFile(outputPath, jsonData, "Block texture JSON file generated successfully.");
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
console.error("Error generating block texture JSON:", err);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 生成 item_texture.json 文件
|
|
80
|
+
* @param {string} itemTexturesPath - 包含 PNG 文件的根目录
|
|
81
|
+
* @param {string} outputPath - 输出的 JSON 文件路径
|
|
82
|
+
*/
|
|
83
|
+
export async function generateItemTextureJson(itemTexturesPath, outputPath, projectName, userItemTextures) {
|
|
84
|
+
try {
|
|
85
|
+
// 递归遍历目录,获取所有 PNG 文件的路径
|
|
86
|
+
const itemTexturesSet = await traverseDirectory(itemTexturesPath, itemTexturesPath, "textures/items/");
|
|
87
|
+
// 合并用户自定义的texture_data
|
|
88
|
+
if (userItemTextures) {
|
|
89
|
+
Object.assign(itemTexturesSet, userItemTextures);
|
|
90
|
+
}
|
|
91
|
+
// 生成 JSON 数据
|
|
92
|
+
const jsonData = {
|
|
93
|
+
resource_pack_name: projectName,
|
|
94
|
+
texture_name: "atlas.items",
|
|
95
|
+
texture_data: itemTexturesSet,
|
|
96
|
+
};
|
|
97
|
+
// 写入文件
|
|
98
|
+
await generateJsonFile(outputPath, jsonData, "Item texture JSON file generated successfully.");
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
console.error("Error generating item texture JSON:", err);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 同步复制文件
|
|
3
|
+
* @param {string} src 源文件路径
|
|
4
|
+
* @param {string} dest 目标文件路径
|
|
5
|
+
*/
|
|
6
|
+
export function copyFileSync(src: string, dest: string): void;
|
|
7
|
+
export function dirname(importMeta: any): string;
|
|
8
|
+
export function asyncImport(path: any): Promise<any>;
|
|
9
|
+
export function generateUUID(): `${string}-${string}-${string}-${string}-${string}`;
|
|
10
|
+
export function pathNotExist(filePath: any): boolean;
|
|
11
|
+
export function readFile(filePath: any): string | null;
|
|
12
|
+
export function saveFile(filePath: string, data: string): void;
|
|
13
|
+
export function copyFolder(sourcePath: any, destinationPath: any): void;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { randomUUID } from "crypto";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
export const generateUUID = () => {
|
|
6
|
+
return randomUUID();
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* 同步复制文件
|
|
10
|
+
* @param {string} src 源文件路径
|
|
11
|
+
* @param {string} dest 目标文件路径
|
|
12
|
+
*/
|
|
13
|
+
export function copyFileSync(src, dest) {
|
|
14
|
+
try {
|
|
15
|
+
fs.copyFileSync(src, dest);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error("文件复制失败:", err);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//检查路径
|
|
22
|
+
export const pathNotExist = filePath => {
|
|
23
|
+
return !fs.existsSync(filePath);
|
|
24
|
+
};
|
|
25
|
+
//读取文件
|
|
26
|
+
export const readFile = filePath => {
|
|
27
|
+
try {
|
|
28
|
+
return fs.readFileSync(filePath, "utf8");
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.log(error);
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* 保存文件
|
|
37
|
+
* @param {string} filePath 绝对路径
|
|
38
|
+
* @param {string} data 数据
|
|
39
|
+
*/
|
|
40
|
+
export const saveFile = (filePath, data) => {
|
|
41
|
+
// 确保目录存在
|
|
42
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
43
|
+
// 创建文件并写入内容
|
|
44
|
+
fs.writeFile(filePath, data, err => {
|
|
45
|
+
if (err) {
|
|
46
|
+
return console.error(err);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
export const copyFolder = (sourcePath, destinationPath) => {
|
|
51
|
+
// 确保目录存在
|
|
52
|
+
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
53
|
+
// 检查源路径是否存在
|
|
54
|
+
if (!fs.existsSync(sourcePath)) {
|
|
55
|
+
console.log(`Source path ${sourcePath} does not exist.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// 检查目标路径是否存在,如果不存在则创建它
|
|
59
|
+
if (!fs.existsSync(destinationPath)) {
|
|
60
|
+
fs.mkdirSync(destinationPath);
|
|
61
|
+
}
|
|
62
|
+
// 获取源路径下的所有文件和文件夹
|
|
63
|
+
const files = fs.readdirSync(sourcePath);
|
|
64
|
+
// 遍历文件和文件夹
|
|
65
|
+
files.forEach(file => {
|
|
66
|
+
const sourceFile = path.join(sourcePath, file);
|
|
67
|
+
const destinationFile = path.join(destinationPath, file);
|
|
68
|
+
// 判断是文件还是文件夹
|
|
69
|
+
if (fs.lstatSync(sourceFile).isDirectory()) {
|
|
70
|
+
// 如果是文件夹,则递归调用copyFolder函数
|
|
71
|
+
copyFolder(sourceFile, destinationFile);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// 如果是文件,则直接复制到目标路径
|
|
75
|
+
fs.copyFileSync(sourceFile, destinationFile);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
export function dirname(importMeta) {
|
|
80
|
+
const __filename = fileURLToPath(importMeta.url);
|
|
81
|
+
const __dirname = path.dirname(__filename);
|
|
82
|
+
return __dirname;
|
|
83
|
+
}
|
|
84
|
+
export function asyncImport(path) {
|
|
85
|
+
if (!path.startsWith('.')) {
|
|
86
|
+
return import('file://' + path);
|
|
87
|
+
}
|
|
88
|
+
return import(path);
|
|
89
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class AddonBiome {
|
|
2
|
+
constructor(format_version: any, definition: any);
|
|
3
|
+
format_version: any;
|
|
4
|
+
definition: any;
|
|
5
|
+
toJson(): {
|
|
6
|
+
format_version: any;
|
|
7
|
+
"minecraft:biome": any;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export class AddonBiomeDescription {
|
|
11
|
+
constructor(identifier: any);
|
|
12
|
+
identifier: any;
|
|
13
|
+
}
|
|
14
|
+
export class AddonBiomeDefinition {
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {AddonBiomeDescription} description
|
|
18
|
+
*/
|
|
19
|
+
constructor(description: AddonBiomeDescription, components: any);
|
|
20
|
+
description: AddonBiomeDescription;
|
|
21
|
+
components: any;
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class AddonBiome {
|
|
2
|
+
constructor(format_version, definition) {
|
|
3
|
+
this.format_version = format_version;
|
|
4
|
+
this.definition = definition;
|
|
5
|
+
}
|
|
6
|
+
toJson() {
|
|
7
|
+
return {
|
|
8
|
+
format_version: this.format_version,
|
|
9
|
+
["minecraft:biome"]: this.definition
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class AddonBiomeDescription {
|
|
14
|
+
constructor(identifier) {
|
|
15
|
+
this.identifier = identifier;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class AddonBiomeDefinition {
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {AddonBiomeDescription} description
|
|
22
|
+
*/
|
|
23
|
+
constructor(description, components) {
|
|
24
|
+
this.description = description;
|
|
25
|
+
this.components = components;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class AddonBlock {
|
|
2
|
+
/**
|
|
3
|
+
* Addon方块类
|
|
4
|
+
* @param {string} format_version 格式版本
|
|
5
|
+
* @param {AddonBlockDefinition} definitions 方块定义
|
|
6
|
+
*/
|
|
7
|
+
constructor(format_version: string, definitions: AddonBlockDefinition);
|
|
8
|
+
format_version: string;
|
|
9
|
+
definitions: AddonBlockDefinition;
|
|
10
|
+
toJson(): {
|
|
11
|
+
format_version: string;
|
|
12
|
+
"minecraft:block": AddonBlockDefinition;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export class AddonBlockDefinition {
|
|
16
|
+
/**
|
|
17
|
+
* 方块定义类
|
|
18
|
+
* @param {AddonBlockDescription} description 方块描述
|
|
19
|
+
* @param {Object} components 方块组件
|
|
20
|
+
* @param {Array} permutations 方块变体
|
|
21
|
+
*/
|
|
22
|
+
constructor(description: AddonBlockDescription, components: Object, permutations?: any[]);
|
|
23
|
+
description: AddonBlockDescription;
|
|
24
|
+
components: Object;
|
|
25
|
+
permutations: any[];
|
|
26
|
+
}
|
|
27
|
+
export class AddonBlockDescription {
|
|
28
|
+
/**
|
|
29
|
+
* 方块描述类
|
|
30
|
+
* @param {string} identifier 唯一标识符
|
|
31
|
+
* @param {map} traits 方块特性
|
|
32
|
+
* @param {map} states 方块状态
|
|
33
|
+
* @param {AddonMenuCategory} menu_category
|
|
34
|
+
*/
|
|
35
|
+
constructor(identifier: string, traits: map, states: map, menu_category: AddonMenuCategory);
|
|
36
|
+
identifier: string;
|
|
37
|
+
traits: map;
|
|
38
|
+
states: map;
|
|
39
|
+
menu_category: AddonMenuCategory;
|
|
40
|
+
}
|
|
41
|
+
import { AddonMenuCategory } from "../menuCategory.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AddonMenuCategory } from "../menuCategory.js";
|
|
2
|
+
export class AddonBlock {
|
|
3
|
+
/**
|
|
4
|
+
* Addon方块类
|
|
5
|
+
* @param {string} format_version 格式版本
|
|
6
|
+
* @param {AddonBlockDefinition} definitions 方块定义
|
|
7
|
+
*/
|
|
8
|
+
constructor(format_version, definitions) {
|
|
9
|
+
this.format_version = format_version;
|
|
10
|
+
this.definitions = definitions;
|
|
11
|
+
}
|
|
12
|
+
toJson() {
|
|
13
|
+
return {
|
|
14
|
+
format_version: this.format_version,
|
|
15
|
+
["minecraft:block"]: this.definitions
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class AddonBlockDefinition {
|
|
20
|
+
/**
|
|
21
|
+
* 方块定义类
|
|
22
|
+
* @param {AddonBlockDescription} description 方块描述
|
|
23
|
+
* @param {Object} components 方块组件
|
|
24
|
+
* @param {Array} permutations 方块变体
|
|
25
|
+
*/
|
|
26
|
+
constructor(description, components, permutations = []) {
|
|
27
|
+
this.description = description;
|
|
28
|
+
this.components = components;
|
|
29
|
+
this.permutations = permutations;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class AddonBlockDescription {
|
|
33
|
+
/**
|
|
34
|
+
* 方块描述类
|
|
35
|
+
* @param {string} identifier 唯一标识符
|
|
36
|
+
* @param {map} traits 方块特性
|
|
37
|
+
* @param {map} states 方块状态
|
|
38
|
+
* @param {AddonMenuCategory} menu_category
|
|
39
|
+
*/
|
|
40
|
+
constructor(identifier, traits, states, menu_category) {
|
|
41
|
+
this.identifier = identifier;
|
|
42
|
+
this.traits = traits;
|
|
43
|
+
this.states = states;
|
|
44
|
+
this.menu_category = menu_category;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export class AddonAnimationController {
|
|
2
|
+
constructor(format_version: any, definition: any);
|
|
3
|
+
format_version: any;
|
|
4
|
+
definition: any;
|
|
5
|
+
toJson(): {
|
|
6
|
+
format_version: any;
|
|
7
|
+
animation_controllers: any;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export class AddonAnimationStateMachine {
|
|
11
|
+
constructor(identifier: any);
|
|
12
|
+
identifier: any;
|
|
13
|
+
namespace: any;
|
|
14
|
+
name: any;
|
|
15
|
+
initialState: string | null;
|
|
16
|
+
states: Map<any, any>;
|
|
17
|
+
/**
|
|
18
|
+
* 设置状态机的初始状态。
|
|
19
|
+
* @param {string} stateName - 初始状态的名称。
|
|
20
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
21
|
+
*/
|
|
22
|
+
setInitialState(stateName: string): AddonAnimationStateMachine;
|
|
23
|
+
/**
|
|
24
|
+
* 添加一个新状态到状态机。
|
|
25
|
+
* @param {string} stateName - 状态的名称。
|
|
26
|
+
* @param {string[]} animations - 该状态播放的动画列表。
|
|
27
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
28
|
+
*/
|
|
29
|
+
addState(stateName: string, animations?: string[]): AddonAnimationStateMachine;
|
|
30
|
+
/**
|
|
31
|
+
* 添加一个状态之间的过渡条件。
|
|
32
|
+
* @param {string} fromState - 过渡的起始状态名称。
|
|
33
|
+
* @param {string} toState - 过渡的目标状态名称。
|
|
34
|
+
* @param {string} condition - 触发过渡的条件(例如 "q.is_on_ground")。
|
|
35
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
36
|
+
*/
|
|
37
|
+
addTransition(fromState: string, toState: string, condition: string): AddonAnimationStateMachine;
|
|
38
|
+
/**
|
|
39
|
+
* 将整个状态机转换为 JSON 兼容的对象。
|
|
40
|
+
* @returns {object} - 包含格式版本的完整动画控制器定义。
|
|
41
|
+
*/
|
|
42
|
+
toJson(): object;
|
|
43
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export class AddonAnimationController {
|
|
2
|
+
constructor(format_version, definition) {
|
|
3
|
+
this.format_version = format_version;
|
|
4
|
+
this.definition = definition;
|
|
5
|
+
}
|
|
6
|
+
toJson() {
|
|
7
|
+
return {
|
|
8
|
+
format_version: this.format_version,
|
|
9
|
+
["animation_controllers"]: this.definition
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class AddonAnimationStateMachine {
|
|
14
|
+
constructor(identifier) {
|
|
15
|
+
this.identifier = identifier; // 状态机的唯一标识符(例如 "helicopter.blade")
|
|
16
|
+
this.namespace = identifier.split(":")[0]; // 标识符的命名空间部分(冒号前的部分)
|
|
17
|
+
this.name = identifier.split(":")[1]; // 标识符的名称部分(冒号后的部分)
|
|
18
|
+
// 状态机属性
|
|
19
|
+
this.initialState = null; // 状态机的初始状态
|
|
20
|
+
this.states = new Map(); // 使用 Map 存储所有状态,键为状态名,值为状态数据
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 设置状态机的初始状态。
|
|
24
|
+
* @param {string} stateName - 初始状态的名称。
|
|
25
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
26
|
+
*/
|
|
27
|
+
setInitialState(stateName) {
|
|
28
|
+
this.initialState = stateName;
|
|
29
|
+
return this; // 支持链式调用
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 添加一个新状态到状态机。
|
|
33
|
+
* @param {string} stateName - 状态的名称。
|
|
34
|
+
* @param {string[]} animations - 该状态播放的动画列表。
|
|
35
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
36
|
+
*/
|
|
37
|
+
addState(stateName, animations = []) {
|
|
38
|
+
this.states.set(stateName, {
|
|
39
|
+
animations: animations, // 该状态的动画列表
|
|
40
|
+
transitions: [] // 该状态的过渡条件列表
|
|
41
|
+
});
|
|
42
|
+
return this; // 支持链式调用
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 添加一个状态之间的过渡条件。
|
|
46
|
+
* @param {string} fromState - 过渡的起始状态名称。
|
|
47
|
+
* @param {string} toState - 过渡的目标状态名称。
|
|
48
|
+
* @param {string} condition - 触发过渡的条件(例如 "q.is_on_ground")。
|
|
49
|
+
* @returns {AddonAnimationStateMachine} - 返回实例以支持链式调用。
|
|
50
|
+
*/
|
|
51
|
+
addTransition(fromState, toState, condition) {
|
|
52
|
+
if (!this.states.has(fromState)) {
|
|
53
|
+
throw new Error(`状态 "${fromState}" 不存在。`);
|
|
54
|
+
}
|
|
55
|
+
const state = this.states.get(fromState);
|
|
56
|
+
state.transitions.push({
|
|
57
|
+
[toState]: condition // 添加过渡条件
|
|
58
|
+
});
|
|
59
|
+
return this; // 支持链式调用
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 将整个状态机转换为 JSON 兼容的对象。
|
|
63
|
+
* @returns {object} - 包含格式版本的完整动画控制器定义。
|
|
64
|
+
*/
|
|
65
|
+
toJson() {
|
|
66
|
+
return {
|
|
67
|
+
[`controller.animation.${this.namespace}.${this.name}`]: {
|
|
68
|
+
initial_state: this.initialState,
|
|
69
|
+
states: Object.fromEntries(this.states)
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|