diff --git a/packages-user/client-modules/src/render/components/textbox.tsx b/packages-user/client-modules/src/render/components/textbox.tsx index 677a3fa..d1ec44d 100644 --- a/packages-user/client-modules/src/render/components/textbox.tsx +++ b/packages-user/client-modules/src/render/components/textbox.tsx @@ -31,6 +31,7 @@ import { TextAlign } from './textboxTyper'; import { SetupComponentOptions } from '@motajs/system-ui'; +import { texture } from '../elements'; //#region TextContent @@ -248,6 +249,8 @@ export interface TextboxProps extends TextContentProps, DefaultProps { titleStroke?: CanvasStyle; /** 标题文字与边框间的距离,默认为4 */ titlePadding?: number; + /** 图标 */ + icon?: AllIds; /** 最大宽度 */ width: number; } @@ -307,30 +310,10 @@ export const Textbox = defineComponent< keyof TextboxEmits, TextboxSlots >((props, { slots, expose, emit }) => { - const contentData = shallowReactive({ width: 200 }); const data = shallowReactive({ width: 200 }); - const setContentData = () => { - contentData.breakChars = props.breakChars ?? ''; - contentData.font = props.font ?? new Font(); - contentData.ignoreLineEnd = props.ignoreLineEnd ?? ''; - contentData.ignoreLineStart = props.ignoreLineStart ?? ''; - contentData.interval = props.interval ?? 0; - contentData.keepLast = props.keepLast ?? false; - contentData.lineHeight = props.lineHeight ?? 0; - contentData.text = props.text ?? ''; - contentData.textAlign = props.textAlign ?? TextAlign.Left; - contentData.wordBreak = props.wordBreak ?? WordBreak.Space; - contentData.fill = props.fill ?? true; - contentData.stroke = props.stroke ?? false; - contentData.fillStyle = props.fillStyle ?? '#fff'; - contentData.strokeStyle = props.strokeStyle ?? '#000'; - contentData.strokeWidth = props.strokeWidth ?? 2; - contentData.loc = props.loc; - contentData.width = props.width; - }; - const setTextboxData = () => { + // Textbox data.backColor = props.backColor ?? '#222'; data.winskin = props.winskin; data.padding = props.padding ?? 8; @@ -341,9 +324,28 @@ export const Textbox = defineComponent< data.width = props.width ?? props.loc?.[2] ?? 200; data.height = props.height ?? props.loc?.[3] ?? 200; data.title = props.title ?? ''; + data.icon = props.icon; + + // TextContent + data.breakChars = props.breakChars ?? ''; + data.font = props.font ?? new Font(); + data.ignoreLineEnd = props.ignoreLineEnd ?? ''; + data.ignoreLineStart = props.ignoreLineStart ?? ''; + data.interval = props.interval ?? 0; + data.keepLast = props.keepLast ?? false; + data.lineHeight = props.lineHeight ?? 0; + data.text = props.text ?? ''; + data.textAlign = props.textAlign ?? TextAlign.Left; + data.wordBreak = props.wordBreak ?? WordBreak.Space; + data.fill = props.fill ?? true; + data.stroke = props.stroke ?? false; + data.fillStyle = props.fillStyle ?? '#fff'; + data.strokeStyle = props.strokeStyle ?? '#000'; + data.strokeWidth = props.strokeWidth ?? 2; + data.loc = props.loc; + data.width = props.width; }; - setContentData(); setTextboxData(); watch(props, () => { @@ -361,15 +363,45 @@ export const Textbox = defineComponent< const tw = ref(data.titlePadding! * 2); /** 标题高度 */ const th = ref(data.titlePadding! * 2); + const contentX = computed(() => { + if (hasIcon.value) { + return data.padding! + 40; + } else { + return data.padding!; + } + }); const contentY = computed(() => { const height = th.value; return data.title ? height : 0; }); const backHeight = computed(() => data.height! - contentY.value); - const contentWidth = computed(() => data.width! - data.padding! * 2); + const contentWidth = computed(() => { + if (hasIcon.value) { + return data.width! - data.padding! * 2 - 40; + } else { + return data.width! - data.padding! * 2; + } + }); const contentHeight = computed( () => data.height! - data.padding! * 2 - contentY.value ); + const iconLoc = computed(() => { + const y = contentY.value; + const pad = data.padding!; + const icon = data.icon; + if (isNil(icon) || icon === 'none') { + return []; + } else { + const num = texture.idNumberMap[icon]; + const renderable = texture.getRenderable(num); + if (!renderable) return []; + const [, , w, h] = renderable.render[0]; + return [pad, pad + y, w, h]; + } + }); + const hasIcon = computed(() => { + return !isNil(data.icon) && data.icon !== 'none'; + }); const onSetText = () => { nextTick(() => { @@ -385,6 +417,8 @@ export const Textbox = defineComponent< //#region store + let lastTitle = data.title; + /** 结束打字机 */ const storeEmits: TextboxStoreEmits = { endType() { @@ -397,23 +431,23 @@ export const Textbox = defineComponent< hidden.value = false; }, update(value) { - if (data.title !== value.title) { - data.title = value.title; + if (value.title !== lastTitle) { onSetText(); + lastTitle = value.title; } }, setText(text) { - if (contentData.text === text) { + if (data.text === text) { content.value?.retype(); } else { - contentData.text = text; + data.text = text; } } }; const store = TextboxStore.use( props.id ?? getNextTextboxId(), - contentData, + data, storeEmits ); @@ -485,10 +519,23 @@ export const Textbox = defineComponent< fillStyle={data.backColor} > )} + {hasIcon.value && ( + + )} + {hasIcon.value && ( + + )} { typing: boolean = false; private constructor( - private readonly data: TextboxProps, + public readonly data: TextboxProps, private readonly emits: TextboxStoreEmits ) { super(); diff --git a/packages-user/client-modules/src/render/elements/misc.ts b/packages-user/client-modules/src/render/elements/misc.ts index 2dc13e1..548062f 100644 --- a/packages-user/client-modules/src/render/elements/misc.ts +++ b/packages-user/client-modules/src/render/elements/misc.ts @@ -67,7 +67,7 @@ export class Icon extends RenderItem implements IAnimateFrame { * @param id 图标id */ setIcon(id: AllIds | AllNumbers) { - if (id === 0) { + if (id === 0 || id === 'none') { this.renderable = void 0; return; } diff --git a/packages-user/client-modules/src/render/ui/main.tsx b/packages-user/client-modules/src/render/ui/main.tsx index fa059aa..0d16b86 100644 --- a/packages-user/client-modules/src/render/ui/main.tsx +++ b/packages-user/client-modules/src/render/ui/main.tsx @@ -76,7 +76,7 @@ const MainScene = defineComponent(() => { const mainTextboxProps: Props = { text: '', hidden: true, - loc: [0, MAP_HEIGHT - 150, MAIN_WIDTH, 150], + loc: [0, MAP_HEIGHT - 150, MAP_WIDTH, 150], zIndex: 30, fillStyle: '#fff', titleFill: 'gold', diff --git a/public/_server/MotaAction.g4 b/public/_server/MotaAction.g4 index 8e668e0..24d9735 100644 --- a/public/_server/MotaAction.g4 +++ b/public/_server/MotaAction.g4 @@ -810,7 +810,11 @@ action | comment_s | autoText_s | scrollText_s + | createTextbox_s + | deleteTextbox_s | setText_s + | createTip_s + | deleteTip_s | tip_s | setValue_s | setEquip_s @@ -940,30 +944,27 @@ action text_s - : '标题' EvalString? '图标' EvalString? '像素坐标 x' IntString? 'y' IntString? '宽' IntString? '高' IntString? '维持文本' Bool '打字间隔' IntString? '行高' IntString? BGNL? Newline + : '标题' EvalString? '图标' EvalString? '文本框id' EvalString? '像素坐标 x' IntString? 'y' IntString? '宽' IntString? '高' IntString? BGNL? Newline EvalString_Multi Newline /* text_s -tooltip : text:显示一段文字(剧情),选项较多请右键点击帮助 +tooltip : text:显示一段文字(剧情),文本框id 默认使用 main-textbox helpUrl : /_docs/#/instruction previewBlock : true allIds : ['EvalString_1'] -default : ["小妖精","fairy","","","","",false,"","","欢迎使用事件编辑器"] +default : ["","","","","","","","欢迎使用事件编辑器"] EvalString_0= EvalString_0 ? (', "title": "'+EvalString_0+'"') : ''; EvalString_1= EvalString_1 ? (', "icon": "'+EvalString_1+'"') : ''; +EvalString_2= EvalString_2 ? (', "textbox": "'+EvalString_2+'"') : ''; IntString_0= IntString_0 ? (', "x": '+IntString_0) : ''; IntString_1= IntString_1 ? (', "y": '+IntString_1) : ''; IntString_2= IntString_2 ? (', "width": '+IntString_2) : ''; IntString_3= IntString_3 ? (', "height": '+IntString_3) : ''; -IntString_4= IntString_4 ? (', "interval": '+IntString_4) : ''; -IntString_5= IntString_5 ? (', "lineHeight": '+IntString_5) : ''; -var code = '{"type": "text"'+EvalString_0+EvalString_1+IntString_0+IntString_1+IntString_2+IntString_3+',"keepLast":'+Bool_0+IntString_4+IntString_5+'"text":"'+EvalString_Multi_0+'"},\n'; +var code = '{"type": "text"'+EvalString_0+EvalString_1+EvalString_2+IntString_0+IntString_1+IntString_2+IntString_3+', "text": "'+EvalString_Multi_0+'"},\n'; return code */; - - comment_s : '添加注释' ':' EvalString_Multi Newline @@ -979,7 +980,7 @@ return code; */; autoText_s - : '自动剧情文本: 标题' EvalString? '图像' EvalString? '对话框效果' EvalString? '时间' Int BGNL? EvalString_Multi Newline + : '自动剧情文本: 标题' EvalString? '图标' EvalString? '文本框id' EvalString? '像素坐标 x' IntString? 'y' IntString? '宽' IntString? '高' IntString? '时间' Int BGNL? EvalString_Multi Newline /* autoText_s @@ -987,40 +988,54 @@ tooltip : autoText:自动剧情文本,用户无法跳过自动剧情文本,大 helpUrl : /_docs/#/instruction doubleclicktext : EvalString_Multi_0 allIds : ['EvalString_1'] -default : ["小妖精","fairy","",3000,"用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示"] -var title=''; -if (EvalString_0==''){ - if (EvalString_1=='' )title=''; - else title='\\t['+EvalString_1+']'; -} else { - if (EvalString_1=='')title='\\t['+EvalString_0+']'; - else title='\\t['+EvalString_0+','+EvalString_1+']'; -} -if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.test(EvalString_2))) { - throw new Error('对话框效果的用法请右键点击帮助'); -} -EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']'); -var code = '{"type": "autoText", "text": "'+title+EvalString_2+EvalString_Multi_0+'", "time": '+Int_0+'},\n'; +default : ["","","","","","","",3000,"用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示"] +EvalString_0= EvalString_0 ? (', "title": "'+EvalString_0+'"') : ''; +EvalString_1= EvalString_1 ? (', "icon": "'+EvalString_1+'"') : ''; +EvalString_2= EvalString_2 ? (', "textbox": "'+EvalString_2+'"') : ''; +IntString_0= IntString_0 ? (', "x": '+IntString_0) : ''; +IntString_1= IntString_1 ? (', "y": '+IntString_1) : ''; +IntString_2= IntString_2 ? (', "width": '+IntString_2) : ''; +IntString_3= IntString_3 ? (', "height": '+IntString_3) : ''; +Int_0= ', "time": '+Int_0; +var code = '{"type": "autoText"'+EvalString_0+EvalString_1+EvalString_2+IntString_0+IntString_1+IntString_2+IntString_3+Int0+', "text": "'+EvalString_Multi_0+'},\n'; return code; */; scrollText_s - : '滚动剧情文本:' '时间' Int '行距' Number '不等待执行完毕' Bool? BGNL? EvalString_Multi Newline + : '滚动剧情文本事件将在 2.B.1 实装' /* scrollText_s -tooltip : scrollText:滚动剧情文本,将从下到上进行滚动显示。 +tooltip : scrollText:滚动剧情文本事件将在 2.B.1 实装 helpUrl : /_docs/#/instruction -doubleclicktext : EvalString_Multi_0 -default : [5000,1.4,false,"时间是总时间,可以使用setText事件来控制字体、颜色、大小、偏移量等"] -Bool_0 = Bool_0?', "async": true':''; -var code = '{"type": "scrollText", "text": "'+EvalString_Multi_0+'"'+Bool_0+', "time" :'+Int_0+', "lineHeight": '+Number_0+'},\n'; -return code; +default : [] +return '{"type": "scrollText"}'; */; +createTextbox_s + : '创建文本框将在 2.B.1 实装' + +/* createTextbox_s +tooltip : createTextbox:创建文本框事件将在 2.B.1 实装 +helpUrl : /_docs/#/instruction +default : [] +return '{"type": "createTextbox"},\n' +*/; + +deleteTextbox_s + : '删除文本框将在 2.B.1 实装' + +/* deleteTextbox_s +tooltip : deleteTextbox:删除文本框事件将在 2.B.1 实装 +helpUrl : /_docs/#/instruction +default : [] +return '{"type": "deleteTextbox"},\n' +*/; + + setText_s - : '设置剧情文本的属性' '位置像素x' IntString? 'y' IntString? '宽' IntString? '高' IntString? '字体类型' EvalString? '字体大小' IntString? '字体线宽' IntString? BGNL? - '是否斜体' Bool? '维持文本' Bool? '打字间隔' IntString? '行高' IntString? '文字颜色' ColorString? Colour '文字描边颜色' ColorString? Colour '描边线宽' IntString? '是否填充' Bool '是否描边' Bool BGNL? + : '配置文本框' '文本框id'EvalString '位置像素x' IntString? 'y' IntString? '宽' IntString? '高' IntString? '字体类型' EvalString? '字体大小' IntString? '字体线宽' IntString? '是否斜体' Bool? BGNL? + '维持文本' Bool? '打字间隔' IntString? '行高' IntString? '文字颜色' ColorString? Colour '文字描边颜色' ColorString? Colour '描边线宽' IntString? '是否填充' Bool '是否描边' Bool BGNL? '背景色' ColorString? Colour '背景winskin' EvalString? '文字与边框距离' IntString? '标题是否填充' Bool '标题是否描边' Bool'标题与边框的距离' IntString? BGNL? '对齐方式' TextAlign_List '分词原则' WordBreak_List '行首禁则' EvalString? '行尾禁则' EvalString? '分词规则识别字符' EvalString? Newline @@ -1029,42 +1044,141 @@ setText_s tooltip : setText:设置文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填,字符间距为字符之间的距离,为整数或不填。 helpUrl : /_docs/#/instruction previewBlock : true -default : ["","","","","","","",false,false,"","","",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",true,false,"",'rgba(255,255,255,1)',"","",true,false,"",'null','space',"","",""] +default : ["main-textbox","","","","","","","",false,false,"","","",'rgba(255,255,255,1)',"",'rgba(255,255,255,1)',"",true,false,"",'rgba(255,255,255,1)',"","",true,false,"",'null','null',"","",""] +Bool_0 = Bool_0 ? (', "fontItalic": '+Bool_0) : ''; +Bool_1 = Bool_1 ? (', "keepLast": '+Bool_1) : ''; +Bool_2 = !Bool_2 ? (', "fill": '+Bool_2) : ''; +Bool_3 = Bool_3 ? (', "stroke": '+Bool_3) : ''; +Bool_4 = !Bool_4 ? (', "titleFill": '+Bool_4) : ''; +Bool_5 = Bool_5 ? (', "titleStroke": '+Bool_5) : ''; IntString_0= IntString_0 ? (', "x": '+IntString_0) : ''; IntString_1 = IntString_1 ? (', "y": '+IntString_1) : ''; IntString_2 = IntString_2 ? (', "width": '+IntString_2) : ''; IntString_3 = IntString_3 ? (', "height": '+IntString_3) : ''; -EvalString_0 = EvalString_0 ? (', "fontFamily": '+EvalString_0) : ''; IntString_4 = IntString_4 ? (', "fontSize": '+IntString_4) : ''; -IntString_5 = IntString_5 ? (', " interval": '+IntString_5) : ''; -IntString_6 = IntString_6 ? (', "lineHeight": ' + IntString_6) : ''; -IntString_7 = IntString_7? (', "strokeWidth": ' + IntString_7) : ''; -EvalString_1 = EvalString_1 ? (', "winskin": '+EvalString_1) : ''; -IntString_8 = IntString_8? (', "padding": ' + IntString_8) : ''; -IntString_9 = IntString_9? (', "titlePadding": ' + IntString_9) : ''; +IntString_5 = IntString_5? (', "fontWeight": ' + IntString_5) : ''; +IntString_6 = IntString_6 ? (', " interval": '+IntString_6) : ''; +IntString_7 = IntString_7 ? (', "lineHeight": ' + IntString_7) : ''; +IntString_8 = IntString_8? (', "strokeWidth": ' + IntString_8) : ''; +IntString_9 = IntString_9? (', "padding": ' + IntString_9) : ''; +IntString_10 = IntString_10? (', "titlePadding": ' + IntString_10) : ''; +EvalString_0 = EvalString_0 ? (', "textbox": "'+EvalString_0+'"') : ''; +EvalString_1 = EvalString_1 ? (', "fontFamily": "'+EvalString_1+'"') : ''; +EvalString_2 = EvalString_2 ? (', "winskin": "'+EvalString_2+'"') : ''; +EvalString_3 = EvalString_3? (', "ignoreLineStart": "'+EvalString_3+'"') : ''; +EvalString_4 = EvalString_4 ? (', "ignoreLineEnd": "'+EvalString_4+'"') : ''; +EvalString_5 = EvalString_5 ? (', "breakChars": "'+EvalString_5+'"') : ''; +ColorString_0=ColorString_0?(', "fillStyle": "rgba('+ColorString_0+')"'):''; +ColorString_1=ColorString_1?(', "strokeStyle": "rgba('+ColorString_1+')"'):''; +ColorString_2=ColorString_2?(', "backColor": "rgba('+ColorString_2+')"'):''; TextAlign_List_0 = TextAlign_List_0==='null'?'':', "textAlign": "'+TextAlign_List_0+'"'; WordBreak_List_0 = WordBreak_List_0==='null'?'':', "wordBreak": "'+WordBreak_List_0+'"'; -EvalString_2 = EvalString_2? (', "ignoreLineStart": '+EvalString_2) : ''; -EvalString_3 = EvalString_3 ? (', "ignoreLineEnd": '+EvalString_3) : ''; -EvalString_4 = EvalString_4 ? (', "breakChars": '+EvalString_4) : ''; -ColorString_0=ColorString_0?(', "fillStyle": ['+ColorString_0+']'):''; -ColorString_1=ColorString_1?(', "strokeStyle": ['+ColorString_1+']'):''; -ColorString_2=ColorString_2?(', "backColor": ['+ColorString_2+']'):''; -var code = '{"type": "setText"'+IntString_0+IntString_1+IntString_2+IntString_3+EvalString_0+IntString_4+', " fontItalic": '+Bool_0+', " keepLast": '+Bool_1+IntString_5+IntString_6+ColorString_0+ColorString_1+IntString_7 +',"fill":'+Bool_2+',"stroke":'+Bool_3+ColorString_2+EvalString_1+IntString_8+',"titleFill":'+Bool_4+',"titleStroke":'+Bool_5+IntString_9 +TextAlign_List_0+WordBreak_List_0+EvalString_2+EvalString_3+EvalString_4+'},\n'; +var code = + '{"type": "setText"'+ + EvalString_0+ IntString_0+ IntString_1+ IntString_2+ IntString_3+ EvalString_1+ IntString_4+ IntString_5+ Bool_0+ + Bool_1+ IntString_6+ IntString_7+ ColorString_0+ ColorString_1+ IntString_8+ Bool_2+ Bool_3+ + ColorString_2+ EvalString_2+ IntString_9+ Bool_4+ Bool_5+ IntString_10+ + TextAlign_List_0+ WordBreak_List_0+ EvalString_3+ EvalString_4+ EvalString_5+ +'},\n'; return code; */; +createTip_s + : '创建提示栏事件将在 2.B.1 实装' + +/* createTip_s +tooltip : createTip:创建提示栏事件将在 2.B.1 实装 +helpUrl : /_docs/#/instruction +default : [] +return '{"type": "createTip"}'; +*/; + +deleteTip_s + : '删除提示栏事件将在 2.B.1 实装' + +/* deleteTip_s +tooltip : createTip:删除提示栏事件将在 2.B.1 实装 +helpUrl : /_docs/#/instruction +default : [] +return '{"type": "deleteTip"}'; +*/; + tip_s - : '显示提示' ':' EvalString '图标ID' IdString? Newline + : '显示提示' '提示栏id' EvalString? '图标ID' IdString? BGNL? + '提示内容' EvalString Newline /* tip_s tooltip : tip:显示一段提示文字 helpUrl : /_docs/#/instruction allIds : ['IdString_0'] -default : ["这段话将在左上角以气泡形式显示",""] -IdString_0 = IdString_0 && (', "icon": "' + IdString_0 + '"'); -var code = '{"type": "tip", "text": "'+EvalString_0+'"'+IdString_0+'},\n'; +default : ["","","这段话将在左上角以气泡形式显示"] +EvalString_0 = EvalString_0 ? (', "tip": "' + EvalString_0 + '"') : ''; +IdString_0 = IdString_0 ? (', "icon": "' + IdString_0 + '"') : ''; +EvalString_1 = EvalString_1 ? (', "text": "' + EvalString_1 + '"') : ''; +var code = '{"type": "tip"'+EvalString_0+IdString_0+EvalString_1+'},\n'; +return code; +*/; + +confirm_s + : '显示确认框' ':' EvalString_Multi '超时毫秒数' Int BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline + +/* confirm_s +tooltip : 弹出确认框 +helpUrl : /_docs/#/instruction +default : ["确认要xxx吗?",0,false] +previewBlock : true +Bool_0 = Bool_0?', "default": true':'' +Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; +var code = ['{"type": "confirm"'+Int_0+Bool_0+', "text": "',EvalString_Multi_0,'",', + block.isCollapsed()?' "_collapsed": true,':'', + block.isEnabled()?'':' "_disabled": true,', + '\n"yes": [\n',action_0,'],\n', + '"no": [\n',action_1,']\n', +'},\n'].join(''); +return code; +*/; + +choices_s + : '选项' ':' EvalString_Multi? BGNL? '标题' EvalString? '图像' IdString? '超时毫秒数' Int BGNL? Newline choicesContext+ BEND Newline + + +/* choices_s +tooltip : choices: 给用户提供选项 +helpUrl : /_docs/#/instruction +previewBlock : true +default : ["","","",0] +allIds : ['IdString_0'] +EvalString_0 = EvalString_0 ? (', "title": "' + EvalString_0 + '"') : ''; +IdString_0 = IdString_0 ? (', "icon": "' + IdString_0 + '"') : ''; +EvalString_Multi_0 = EvalString_Multi_0 ?(', "text": "'+EvalString_Multi_0+'"'):''; +Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; +var code = ['{"type": "choices"',EvalString_0,IdString_0,EvalString_Multi_0,Int_0, + block.isCollapsed()?', "_collapsed": true':'', + block.isEnabled()?'':', "_disabled": true', + ', "choices": [\n', + choicesContext_0, +']},\n'].join(''); +return code; +*/; + +choicesContext + : '子选项' EvalString '图标' IdString? '颜色' ColorString? Colour '启用条件' EvalString? '出现条件' EvalString? BGNL? Newline action+ + + +/* choicesContext +tooltip : 选项的选择 +helpUrl : /_docs/#/instruction +default : ["提示文字:红钥匙","","","",""] +allIds : ['IdString_0'] +colour : this.subColor +ColorString_0 = ColorString_0 ? (', "color": ['+ColorString_0+']') : ''; +EvalString_1 = EvalString_1 && (', "need": "'+EvalString_1+'"'); +EvalString_2 = EvalString_2 && (', "condition": "'+EvalString_2+'"'); +IdString_0 = IdString_0?(', "icon": "'+IdString_0+'"'):''; +var collapsed=block.isCollapsed()?', "_collapsed": true':''; +var disabled=block.isEnabled()?'':', "_disabled": true'; +var code = '{"text": "'+EvalString_0+'"'+IdString_0+ColorString_0+EvalString_1+EvalString_2+collapsed+disabled+', "action": [\n'+action_0+']},\n'; return code; */; @@ -2470,76 +2584,6 @@ var code = '{"case": "'+expression_0+'"'+Bool_0+collapsed+disabled+', "action": return code; */; -choices_s - : '选项' ':' EvalString_Multi? BGNL? '标题' EvalString? '图像' IdString? '超时毫秒数' Int '宽度' IntString? BGNL? Newline choicesContext+ BEND Newline - - -/* choices_s -tooltip : choices: 给用户提供选项 -helpUrl : /_docs/#/instruction -previewBlock : true -default : ["","流浪者","trader",0,''] -allIds : ['IdString_0'] -var title=''; -if (EvalString_0==''){ - if (IdString_0=='')title=''; - else title='\\t['+IdString_0+']'; -} else { - if (IdString_0=='')title='\\t['+EvalString_0+']'; - else title='\\t['+EvalString_0+','+IdString_0+']'; -} -EvalString_Multi_0 = title+EvalString_Multi_0; -EvalString_Multi_0 = EvalString_Multi_0 ?(', "text": "'+EvalString_Multi_0+'"'):''; -Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; -IntString_0 = IntString_0 ? (', "width": ' + IntString_0) : ''; -var code = ['{"type": "choices"',EvalString_Multi_0,Int_0,IntString_0, - block.isCollapsed()?', "_collapsed": true':'', - block.isEnabled()?'':', "_disabled": true', - ', "choices": [\n', - choicesContext_0, -']},\n'].join(''); -return code; -*/; - -choicesContext - : '子选项' EvalString '图标' IdString? '颜色' ColorString? Colour '启用条件' EvalString? '出现条件' EvalString? BGNL? Newline action+ - - -/* choicesContext -tooltip : 选项的选择 -helpUrl : /_docs/#/instruction -default : ["提示文字:红钥匙","","","",""] -allIds : ['IdString_0'] -colour : this.subColor -ColorString_0 = ColorString_0 ? (', "color": ['+ColorString_0+']') : ''; -EvalString_1 = EvalString_1 && (', "need": "'+EvalString_1+'"'); -EvalString_2 = EvalString_2 && (', "condition": "'+EvalString_2+'"'); -IdString_0 = IdString_0?(', "icon": "'+IdString_0+'"'):''; -var collapsed=block.isCollapsed()?', "_collapsed": true':''; -var disabled=block.isEnabled()?'':', "_disabled": true'; -var code = '{"text": "'+EvalString_0+'"'+IdString_0+ColorString_0+EvalString_1+EvalString_2+collapsed+disabled+', "action": [\n'+action_0+']},\n'; -return code; -*/; - -confirm_s - : '显示确认框' ':' EvalString_Multi '超时毫秒数' Int BGNL? '确定的场合' ':' '(默认选中' Bool ')' BGNL? Newline action+ '取消的场合' ':' BGNL? Newline action+ BEND Newline - -/* confirm_s -tooltip : 弹出确认框 -helpUrl : /_docs/#/instruction -default : ["确认要xxx吗?",0,false] -previewBlock : true -Bool_0 = Bool_0?', "default": true':'' -Int_0 = Int_0 ? (', "timeout": '+Int_0) : ''; -var code = ['{"type": "confirm"'+Int_0+Bool_0+', "text": "',EvalString_Multi_0,'",', - block.isCollapsed()?' "_collapsed": true,':'', - block.isEnabled()?'':' "_disabled": true,', - '\n"yes": [\n',action_0,'],\n', - '"no": [\n',action_1,']\n', -'},\n'].join(''); -return code; -*/; - for_s : '循环遍历' ': ' expression '从' EvalString '到' EvalString '步增' EvalString BGNL? Newline action+ BEND Newline diff --git a/public/_server/MotaActionParser.js b/public/_server/MotaActionParser.js index 115e78e..b767d2e 100644 --- a/public/_server/MotaActionParser.js +++ b/public/_server/MotaActionParser.js @@ -257,33 +257,60 @@ ActionParser.prototype.parseAction = function() { return; case "text": // 文字/对话 this.next = MotaActionBlocks['text_s'].xmlText([ - data.title, data.icon, data.x, data.y, data.width, data.height, data.keepLast,data.interval,data.lineHeight, this.next]); + data.title,data.icon,data.textbox,data.x,data.y,data.width,data.height,data.text,this.next]); break; case "autoText": // 自动剧情文本 - var info = this.getTitleAndPosition(data.text); this.next = MotaActionBlocks['autoText_s'].xmlText([ - info[0],info[1],info[2],data.time,info[3],this.next]); + data.title,data.icon,data.textbox,data.x,data.y,data.width,data.height,data.time,data.text,this.next]); break; case "scrollText": - this.next = MotaActionBlocks['scrollText_s'].xmlText([ - data.time, data.lineHeight||1.4, data.async||false, this.EvalString_Multi(data.text), this.next]); + this.next = MotaActionBlocks['scrollText_s'].xmlText([this.next]); break; case "comment": // 注释 this.next = MotaActionBlocks['comment_s'].xmlText([this.EvalString_Multi(data.text),this.next]); break; + case "createTextbox": + this.next = MotaActionBlocks['createTextbox_s'].xmlText([this.next]); + case "createTextbox": + this.next = MotaActionBlocks['deleteTextbox_s'].xmlText([this.next]); case "setText": // 设置剧情文本的属性 - //data.backColor=this.Colour(data.backColor); - //data.fillStyle=this.Colour(data.fillStyle); - //data.strokeStyle=this.Colour(data.strokeStyle); + const parsedFillStyle = data.fillStyle ? data.fillStyle.slice(5, -1) : ''; + const parsedStrokeStyle = data.strokeStyle ? data.strokeStyle.slice(5, -1) : ''; + const parsedBackColor = data.backColor ? data.backColor.slice(5, -1) : ''; this.next = MotaActionBlocks['setText_s'].xmlText([ - data.x,data.y,data.width,data.height,data.fontFamily,data.fontSize,data.fontWeight, - data.fontItalic,data.keepLast,data.interval,data.lineHeight,,data.fillStyle,'rgba('+data.fillStyle+')', - data.strokeStyle,'rgba('+data.strokeStyle+')',data.strokeWidth,data.fill,data.stroke,data.backColor,'rgba('+data.backColor+')', - data.winskin,data.padding,data.titleFill,data.titleStroke,data.titlePadding,data.textAlign,data.wordBreak,data.ignoreLineStart,data.ignoreLineEnd,data.breakChars,this.next]); + data.textbox, data.x, data.y, data.width, data.height, data.fontFamily, data.fontSize, data.fontWeight, data.fontItalic, + data.keepLast, data.interval, data.lineHeight, parsedFillStyle, data.fillStyle, parsedStrokeStyle, data.strokeStyle, data.strokeWidth, data.fill, data.stroke, + parsedBackColor, data.backColor, data.winskin, data.padding, data.titleFill, data.titleStroke, data.titlePadding, + data.textAlign, data.wordBreak, data.ignoreLineStart, data.ignoreLineEnd, data.breakChars, this.next + ]); break; + case "createTip": + this.next = MotaActionBlocks['createTip_s'].xmlText([this.next]); + case "deleteTip": + this.next = MotaActionBlocks['deletetip_s'].xmlText([this.next]); case "tip": this.next = MotaActionBlocks['tip_s'].xmlText([ - data.text,data.icon||"",this.next]); + data.tip,data.icon||"",data.text,this.next]); + break; + case "confirm": // 显示确认框 + this.next = MotaActionFunctions.xmlText('confirm_s', [ + this.EvalString_Multi(data.text), data.timeout||0, data["default"], + this.insertActionList(data["yes"]), + this.insertActionList(data["no"]), + this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); + break; + case "choices": // 提供选项 + var text_choices = null; + for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) { + choice.color = this.Colour(choice.color); + text_choices=MotaActionFunctions.xmlText('choicesContext', [ + choice.text,choice.icon,choice.color,'rgba('+choice.color+')',choice.need||'',choice.condition||'',this.insertActionList(choice.action),text_choices], + /* isShadow */false, /*comment*/ null, /*collapsed*/ choice._collapsed, /*disabled*/ choice._disabled); + } + if (!this.isset(data.text)) data.text = ''; + var info = this.getTitleAndPosition(data.text); + this.next = MotaActionFunctions.xmlText('choices_s', [ + info[3],info[0],info[1],data.timeout||0,text_choices,this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); break; case "show": // 显示 data.loc=data.loc||[]; @@ -722,13 +749,6 @@ ActionParser.prototype.parseAction = function() { this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); } break; - case "confirm": // 显示确认框 - this.next = MotaActionFunctions.xmlText('confirm_s', [ - this.EvalString_Multi(data.text), data.timeout||0, data["default"], - this.insertActionList(data["yes"]), - this.insertActionList(data["no"]), - this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); - break; case "switch": // 多重条件分歧 var case_caseList = null; for(var ii=data.caseList.length-1,caseNow;caseNow=data.caseList[ii];ii--) { @@ -740,19 +760,6 @@ ActionParser.prototype.parseAction = function() { this.expandEvalBlock([data.condition]), case_caseList,this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); break; - case "choices": // 提供选项 - var text_choices = null; - for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) { - choice.color = this.Colour(choice.color); - text_choices=MotaActionFunctions.xmlText('choicesContext', [ - choice.text,choice.icon,choice.color,'rgba('+choice.color+')',choice.need||'',choice.condition||'',this.insertActionList(choice.action),text_choices], - /* isShadow */false, /*comment*/ null, /*collapsed*/ choice._collapsed, /*disabled*/ choice._disabled); - } - if (!this.isset(data.text)) data.text = ''; - var info = this.getTitleAndPosition(data.text); - this.next = MotaActionFunctions.xmlText('choices_s', [ - info[3],info[0],info[1],data.timeout||0,data.width,text_choices,this.next], /* isShadow */false, /*comment*/ null, /*collapsed*/ data._collapsed, /*disabled*/ data._disabled); - break; case "for": // 循环遍历 this.next = MotaActionFunctions.xmlText('for_s',[ this.expandEvalBlock([data.name]), diff --git a/public/_server/editor_blocklyconfig.js b/public/_server/editor_blocklyconfig.js index 5250b3f..4b72259 100644 --- a/public/_server/editor_blocklyconfig.js +++ b/public/_server/editor_blocklyconfig.js @@ -19,8 +19,8 @@ editor_blocklyconfig=(function(){ '入口方块':[ '', MotaActionFunctions.actionParser.parse([ - "欢迎使用事件编辑器", - "本事件触发一次后会消失", + {"type": "text", "text": "欢迎使用事件编辑器"}, + {"type": "text", "text": "本事件触发一次后会消失"}, {"type": "hide", "time": 500}, ],'event'), MotaActionFunctions.actionParser.parse({ @@ -96,16 +96,19 @@ editor_blocklyconfig=(function(){ ], 'splitImages'), ], '显示文字':[ - MotaActionBlocks['text_s'].xmlText(), - MotaActionBlocks['comment_s'].xmlText(), + MotaActionBlocks['text_s'].xmlText(), MotaActionBlocks['autoText_s'].xmlText(), MotaActionBlocks['scrollText_s'].xmlText(), + MotaActionBlocks['createTextbox_s'].xmlText(), + MotaActionBlocks['deleteTextbox_s'].xmlText(), MotaActionBlocks['setText_s'].xmlText(), + MotaActionBlocks['createTip_s'].xmlText(), + MotaActionBlocks['deleteTip_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(), MotaActionBlocks['confirm_s'].xmlText(), MotaActionBlocks['choices_s'].xmlText([ - '选择剑或者盾','流浪者','man',0,'',MotaActionBlocks['choicesContext'].xmlText([ + '选择剑或者盾','流浪者','man','',MotaActionBlocks['choicesContext'].xmlText([ '剑','','',null,'','',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), ]) ]), diff --git a/public/libs/actions.js b/public/libs/actions.js index f757724..e0056ed 100644 --- a/public/libs/actions.js +++ b/public/libs/actions.js @@ -1100,11 +1100,8 @@ actions.prototype._clickAction_text = function () { if (core.status.event.animateUI) return; const Store = Mota.require('@user/client-modules').TextboxStore; - const store = Store.get('main-textbox'); - - // var data = core.clone(core.status.event.data.current); - // if (typeof data == 'string') data = { type: 'text', text: data }; - + const id = core.events.nowTextbox ?? 'main-textbox'; + const store = Store.get(id); // 打字机效果显示全部文字 if (store.typing) { store.endType(); @@ -1112,19 +1109,8 @@ actions.prototype._clickAction_text = function () { } else { store.hide(); } - // if (core.status.event.interval != null) { - // data.showAll = true; - // core.insertAction(data); - // core.doAction(); - // return; - // } - if (!data.code) { - core.ui._animateUI('hide', null, core.doAction); - } else { - // 不清除对话框 - core.doAction(); - } + core.doAction(); }; ////// 自定义事件时的点击操作 ////// diff --git a/public/libs/control.js b/public/libs/control.js index 7fda678..eadfdf1 100644 --- a/public/libs/control.js +++ b/public/libs/control.js @@ -876,6 +876,22 @@ control.prototype.setHeroOpacity = function ( ////// 设置画布偏移 control.prototype.setGameCanvasTranslate = function (canvas, x, y) { // Deprecated. Use RenderItem.transform instead. + // For editor compatibility. + var c = core.dom.gameCanvas[canvas]; + x = x * core.domStyle.scale; + y = y * core.domStyle.scale; + c.style.transform = 'translate(' + x + 'px,' + y + 'px)'; + c.style.webkitTransform = 'translate(' + x + 'px,' + y + 'px)'; + c.style.OTransform = 'translate(' + x + 'px,' + y + 'px)'; + c.style.MozTransform = 'translate(' + x + 'px,' + y + 'px)'; + if (main.mode === 'editor' && editor.isMobile) { + c.style.transform = + 'translate(' + + (x / core._PX_) * 96 + + 'vw,' + + (y / core._PY_) * 96 + + 'vw)'; + } }; ////// 加减画布偏移 diff --git a/public/libs/events.js b/public/libs/events.js index 16c7369..1b77244 100644 --- a/public/libs/events.js +++ b/public/libs/events.js @@ -1563,109 +1563,55 @@ events.prototype.__action_doAsyncFunc = function (isAsync, func) { } }; -events.prototype._action_text = function (data, x, y, prefix) { +events.prototype._action_text = function (data) { if (this.__action_checkReplaying()) return; const Store = Mota.require('@user/client-modules').TextboxStore; - const store = Store.get('main-textbox'); - const { text } = data; - let title = ''; - let inTitle = false; - let titleStartIndex = 0; - let titleEndIndex = 0; - for (let i = 0; i < text.length; i++) { - const char = text[i]; - - if (inTitle) { - if (char === '\\' && text[i + 1] === ']') { - title += ']'; - i++; - } else if (char === ']') { - inTitle = false; - titleEndIndex = i + 1; - break; - } else { - title += char; - } - continue; - } - - if (char === '\t' && text[i + 1] === '[') { - inTitle = true; - titleStartIndex = i; - // 跳转至方括号内 - i++; - continue; - } - - if (char === '\\' && text[i + 1] === 't' && text[i + 2] === '[') { - inTitle = true; - titleStartIndex = i; - // 跳转至方括号内 - i += 2; - continue; - } + const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data; + const store = Store.get(textbox); + if (!store) { + core.doAction(); + return; } - - const showText = text.slice(0, titleStartIndex) + text.slice(titleEndIndex); + const loc = store.data.loc?.slice() ?? []; + loc[0] ??= 0; + loc[1] ??= 0; + loc[2] ??= 200; + loc[3] ??= 200; + const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data; store.show(); - store.modify({ title }); - store.setText(showText); - - // data.text = core.replaceText(data.text, prefix); - // var ctx = data.code ? '__text__' + data.code : null; - // data.ctx = ctx; - // if (core.getContextByName(ctx) && !data.showAll) { - // core.ui._animateUI('hide', ctx, function () { - // core.ui.drawTextBox(data.text, data); - // core.ui._animateUI('show', ctx, function () { - // if (data.async) core.doAction(); - // }); - // }); - // return; - // } - // core.ui.drawTextBox(data.text, data); - // if (!data.showAll) { - // core.ui._animateUI('show', ctx, function () { - // if (data.async) core.doAction(); - // }); - // } + store.modify({ title, icon, loc: [x, y, width, height], width }); + store.setText(text); + core.events.nowTextbox = textbox; }; -events.prototype._action_moveTextBox = function (data, x, y, prefix) { +events.prototype._action_autoText = function (data) { if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc( - data.async, - core.moveTextBox, - data.code, - this.__action_getLoc(data.loc, x, y, prefix), - data.relative, - data.moveMode, - data.time - ); -}; + const Store = Mota.require('@user/client-modules').TextboxStore; + const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data; + const store = Store.get(textbox); + if (!store) { + core.doAction(); + return; + } + const loc = store.data.loc?.slice() ?? []; + loc[0] ??= 0; + loc[1] ??= 0; + loc[2] ??= 200; + loc[3] ??= 200; + const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data; + store.show(); + store.modify({ title, icon, loc: [x, y, width, height], width }); + store.setText(text); -events.prototype._action_clearTextBox = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - core.clearTextBox(data.code, core.doAction); -}; - -events.prototype._action_autoText = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - data.text = core.replaceText(data.text, prefix); - core.ui.drawTextBox(data.text); - setTimeout(core.doAction, data.time || 3000); + setTimeout(() => { + store.hide(); + core.doAction(); + }, data.time ?? 3000); }; events.prototype._action_scrollText = function (data, x, y, prefix) { if (this.__action_checkReplaying()) return; - data.text = core.replaceText(data.text, prefix); - this.__action_doAsyncFunc( - data.async, - core.drawScrollText, - data.text, - data.time || 5000, - data.lineHeight || 1.4 - ); + // todo: 2.B.1 }; events.prototype._action_comment = function (data, x, y, prefix) { @@ -1676,8 +1622,59 @@ events.prototype._action__label = function (data, x, y, prefix) { core.doAction(); }; -events.prototype._action_setText = function (data, x, y, prefix) { - this.setTextAttribute(data); +events.prototype._action_setText = function (data) { + const isNil = value => value !== null && value !== void 0; + const { textbox = 'main-textbox' } = data; + const Store = Mota.require('@user/client-modules').TextboxStore; + const Font = Mota.require('@motajs/render-vue').Font; + const store = Store.get(textbox); + if (!store) { + core.doAction(); + return; + } + // loc + const loc = store.data.loc?.slice() ?? []; + loc[0] ??= 0; + loc[1] ??= 0; + loc[2] ??= 200; + loc[3] ??= 200; + const { x = loc[0], y = loc[1], width = loc[2], height = loc[3] } = data; + const newLoc = [x, y, width, height]; + // font + const { fontFamily, fontSize, fontWeight, fontItalic } = data; + const font = store.data.font ?? new Font(); + const newFont = Font.clone(font, { + family: fontFamily, + size: fontSize, + weight: fontWeight, + italic: fontItalic + }); + // config + const config = { + loc: newLoc, + font: newFont, + keepLast: data.keepLast, + interval: data.interval, + lineHeight: data.lineHeight, + fillStyle: data.fillStyle, + strokeStyle: data.strokeStyle, + strokeWidth: data.strokeWidth, + fill: isNil(data.fill), + stroke: !!data.stroke, + backColor: data.backColor, + winskin: data.winskin, + padding: data.padding, + titleFill: isNil(data.titleFill), + titleStroke: !!data.titleStroke, + titlePadding: data.titlePadding, + textAlign: data.textAlign, + wordBreak: data.wordBreak, + ignoreLineStart: data.ignoreLineStart, + ignoreLineEnd: data.ignoreLineEnd, + breakChars: data.breakChars + }; + store.modify(config); + core.doAction(); }; @@ -1686,6 +1683,29 @@ events.prototype._action_tip = function (data, x, y, prefix) { core.doAction(); }; +events.prototype._action_confirm = function (data, x, y, prefix) { + data.text = core.replaceText(data.text, prefix); + core.ui.drawConfirmBox( + data.text, + () => { + core.insertAction(data.yes ?? []); + core.doAction(); + }, + () => { + core.insertAction(data.no ?? []); + core.doAction(); + } + ); +}; + +events.prototype._action_choices = function (data, x, y, prefix) { + core.ui.drawChoices( + core.replaceText(data.text, prefix), + data.choices, + data.width + ); +}; + events.prototype._action_show = function (data, x, y, prefix) { data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); if (data.time > 0 && data.floorId == core.status.floorId) { @@ -2519,14 +2539,6 @@ events.prototype._precompile_switch = function (data) { return data; }; -events.prototype._action_choices = function (data, x, y, prefix) { - core.ui.drawChoices( - core.replaceText(data.text, prefix), - data.choices, - data.width - ); -}; - events.prototype.__action_choices_replaying = function (data, index) { var selection = index; if (index != 'none') { @@ -2580,21 +2592,6 @@ events.prototype._precompile_choices = function (data) { return data; }; -events.prototype._action_confirm = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - core.ui.drawConfirmBox( - data.text, - () => { - core.insertAction(data.yes ?? []); - core.doAction(); - }, - () => { - core.insertAction(data.no ?? []); - core.doAction(); - } - ); -}; - events.prototype.__action_confirm_replaying = function (data, index) { if (index != 'none') { var timeout = Math.floor(index / 100) || 0; diff --git a/public/main.js b/public/main.js index be9eea7..b6dc814 100644 --- a/public/main.js +++ b/public/main.js @@ -21,6 +21,7 @@ function main() { this.dom = { body: document.body, gameDraw: document.getElementById('game-draw'), + gameCanvas: document.getElementsByClassName('gameCanvas'), inputDiv: document.getElementById('inputDiv'), inputMessage: document.getElementById('inputMessage'), inputBox: document.getElementById('inputBox'), @@ -194,6 +195,10 @@ main.prototype.loadSync = function (mode, callback) { }; main.prototype.loadAsync = async function (mode, callback) { + for (var i = 0; i < main.dom.gameCanvas.length; i++) { + main.canvas[main.dom.gameCanvas[i].id] = + main.dom.gameCanvas[i].getContext('2d'); + } main.mode = mode; // 加载全塔属性代码 diff --git a/public/project/floors/MT14.js b/public/project/floors/MT14.js index eec45c9..779882c 100644 --- a/public/project/floors/MT14.js +++ b/public/project/floors/MT14.js @@ -226,8 +226,14 @@ main.floors.MT14= } ], "8,2": [ - "这一层有一个必须使用跳跃的地方,需要1个跳跃次数,你一共有3个跳跃次数,请规划好", - "不要吐槽为什么天气变化这么大(" + { + "type": "text", + "text": "这一层有一个必须使用跳跃的地方,需要1个跳跃次数,你一共有3个跳跃次数,请规划好" + }, + { + "type": "text", + "text": "不要吐槽为什么天气变化这么大(" + } ], "80,3": [ "你可以使用楼传传出去" diff --git a/src/types/declaration/source.d.ts b/src/types/declaration/source.d.ts index 8025676..60f71a2 100644 --- a/src/types/declaration/source.d.ts +++ b/src/types/declaration/source.d.ts @@ -25,7 +25,7 @@ type ItemCls = 'tools' | 'items' | 'equips' | 'constants'; /** * 所有的道具id */ -type AllIds = keyof IdToNumber; +type AllIds = keyof IdToNumber | 'none'; /** * 所有的道具数字