diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60839c7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_saves/ +_server/config.json \ No newline at end of file diff --git a/_saves/.exported b/_saves/.exported deleted file mode 100644 index 56a6051..0000000 --- a/_saves/.exported +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/_saves/Eustia_autoSave b/_saves/Eustia_autoSave deleted file mode 100644 index c063af7..0000000 --- a/_saves/Eustia_autoSave +++ /dev/null @@ -1 +0,0 @@ -N4IgZgNg9lBOCSATEAuEBPAlgRwK4CYQAaEACwFNYpVRMBbAQwHNzUzKoA6Ad3ICMADsRAMAdvQYAXVijAMIAZ3IlRDOjJABhBvWEQAbqgCMJUgMYAPYwAZbpoSiO3rJRqss3XYhqhcjJANaeIIjkYMF0oeGOfnRQouToviTkFg5+5HiY5uSikqgA2gC6JJjSdAo0IADG8QqSYpKVKKB8MEGOJJBJjgC+JJIwilXo5BDQ3ADSiagALCR8ELjk0z1G/SCZuNnNwL0b0NVVVigAnCQ98yGYsOTVkpjxbLhCG5DMuyBl5HQAIuQNTAQVCSWDLEi4JQAIQBvFyABlMExSPkUKDwSAAPqYpTkRDY4z4ADMRlmADZ8GSyQB2EjY2BifGYwkk8mUmkkBi3BjNAqgdwaAA6uFm5GsfGFAFZqrNCF4BLytDo6KQoOoQEV+vy1EKRWKJbhpbLhIwFYUQAArTC4Ji4MQarUgAVsYWi8VSmVykCmxWTAAqADUHURteq0MLqZT8BH8GAjCaGGaUAUQP6AwAxQiakNOnUu3CRikxuMJpMpphQCCIAIzbOh3Vug1Gr0+818TCkSG4ah13NhkCusUMD3G+WKq0MKANURMYP1/Nu4eGz2lxUKCgz0T6VXq3vO8N66xL5ur83rzBbnesPd5g+F6MF2Pxsfmq14ydzvu6+/F5/exNrqC5AAtYf71LcIFeraYhMNUpAwcI0EznBMFehYmCTuhMGgcIWFQFhM7WGhGH4RhM5EsIWB4H+VEEJ++6iLg4wvsmGA4LgFE3mGjHMf+ZZsXgsz0bePEQCxKa0ZKwncUxYl8YqtFktJMiieJAkFspqCqfJ5q0QAHJpKDaa2rG0achnGQBunsU4DolCACgBNkqByIoyhkFyyAoH42LwbAiCaJWcAEmgtzIHSmLfHQAASF6SCFxQRRA5AMPo5DwlA1QhaAtHxi01y3PcjyiM8QgkCcfg9NS+wRfomAKN8TIjDZIJgu5tGEGibUbHwsLAaIACCkgNNUAS/FIPhGbJEWIPVDCLHi2XqZ1BQFEYRiSkQ63zE4LjrUSRBkiY1KzCUxTZh5QFefgJCOUCwLebdTnjAAcreA64GSkpiiAbyVhMlC8vZ9TkEmZJeIEyQOQIwFeU4t2gsEzCYMEcXBLUJUxF4TCYEcsjyEoCNSPVDzVJ8gwNBAfr0DIkbWFSpycKczMs8zsybTUuCwLA1NhgzjN6c4Qu2LMtJkOkCxSJIyXGK48QzI9mxpFDfBS8l42MCwUMCFA9XxBrzAyBkFiggwBta4rcRpb8Nx3NLPTg18TCiHA5AAMrSEm+Bi/UXKolSkqzKcZKcLMNUef5bCnvlHVVKahQuInRAuAUAC0Jjp0QmfZxnudZ3nLg5/nZ1F6Xedl8n+dV+nJQpxX9flyYheNyXjfV23RdJ83teV4nmobFQuDSGw8LwFCTAABoDdFA3YAomgALKSEwADy3BQgAogN6ADQGK+SgA4rgAYKAN8KTKfABS6DppKARb7gACqACaACKA0ALxf8I+jyMsuwbDSrABqTwDynHIESRAUo+CSmsBGBgpwoG4FOEROBho9KBw9NYMAwpg5GHCCQW0mAvIgBpHwWYswjD4ElJiIk5B8D4ExLMBBNCYGIHxNScgkoA5EgYEaAhIAHhhiMNSIkZI9JfVONSawelqR6V6EAA= \ No newline at end of file diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js index 1c16b25..ee517af 100644 --- a/_server/CodeMirror/defs.js +++ b/_server/CodeMirror/defs.js @@ -1,4130 +1,4526 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ { "!name": "browser", - "Node": { + Node: { "!type": "fn()", - "prototype": { - "nextSibling": { + prototype: { + nextSibling: { "!type": "+Element", - "!doc": "返回紧接其父节点的childNodes列表中指定节点之后的节点;如果指定节点是该列表中的最后一个节点,则返回null.", + "!doc": + "返回紧接其父节点的childNodes列表中指定节点之后的节点;如果指定节点是该列表中的最后一个节点,则返回null.", }, - "previousSibling": { + previousSibling: { "!type": "+Element", - "!doc": "返回紧接其父节点的childNodes列表中指定节点之前的节点,如果指定节点是该列表中的第一个节点,则返回null.", + "!doc": + "返回紧接其父节点的childNodes列表中指定节点之前的节点,如果指定节点是该列表中的第一个节点,则返回null.", }, - "lastChild": { + lastChild: { "!type": "+Element", - "!doc": "返回节点的最后一个孩子." + "!doc": "返回节点的最后一个孩子.", }, - "firstChild": { + firstChild: { "!type": "+Element", - "!doc": "返回树中该节点的第一个子节点;如果该节点为无子节点,则返回null.如果该节点是Document,则返回其直接子节点列表中的第一个节点.", + "!doc": + "返回树中该节点的第一个子节点;如果该节点为无子节点,则返回null.如果该节点是Document,则返回其直接子节点列表中的第一个节点.", }, - "childNodes": { + childNodes: { "!type": "+NodeList", - "!doc": "返回给定元素的子节点的集合." + "!doc": "返回给定元素的子节点的集合.", }, - "parentNode": { + parentNode: { "!type": "+Element", - "!doc": "返回DOM树中指定节点的父级." + "!doc": "返回DOM树中指定节点的父级.", }, - "tagName": { + tagName: { "!type": "string", - "!doc": "将当前节点的名称作为字符串返回." + "!doc": "将当前节点的名称作为字符串返回.", }, - "insertBefore": { + insertBefore: { "!type": "fn(newElt: +Element, before: +Element) -> +Element", "!doc": "将指定的节点插入到参考元素之前,作为当前节点的子级.", }, - "removeChild": { + removeChild: { "!type": "fn(oldNode: +Element) -> +Element", "!doc": "从DOM中删除一个子节点.返回已删除的节点.", }, - "appendChild": { + appendChild: { "!type": "fn(newNode: +Element) -> +Element", - "!doc": "将一个节点添加到指定父节点的子节点列表的末尾.如果该节点已经存在,则将其从当前父节点中删除,然后添加到新的父节点中.", + "!doc": + "将一个节点添加到指定父节点的子节点列表的末尾.如果该节点已经存在,则将其从当前父节点中删除,然后添加到新的父节点中.", }, - "cloneNode": { + cloneNode: { "!type": "fn(deep: bool) -> +Element", - "!doc": "返回在其上调用此方法的节点的副本." + "!doc": "返回在其上调用此方法的节点的副本.", }, - "addEventListener": { + addEventListener: { "!type": "fn(type: string, listener: fn(e: +Event), capture: bool)", - "!doc": "在单个目标上注册单个事件侦听器.事件目标可以是文档中的单个元素,文档本身,窗口或XMLHttpRequest.", + "!doc": + "在单个目标上注册单个事件侦听器.事件目标可以是文档中的单个元素,文档本身,窗口或XMLHttpRequest.", }, - "removeEventListener": { + removeEventListener: { "!type": "fn(type: string, listener: fn(), capture: bool)", "!doc": "允许从事件目标中删除事件侦听器.", }, - "innerText": { + innerText: { "!type": "string", - "!doc": "获取或设置节点及其后代的文本内容." - } - }, - "!doc": "节点是一个接口,许多DOM类型都从该接口继承,并允许类似地对待(或测试)这些各种类型.", - }, - "Element": { - "!type": "fn()", - "prototype": { - "!proto": "Node.prototype", - "getAttribute": { - "!type": "fn(name: string) -> string", - "!doc": "返回指定元素上的命名属性的值.如果命名属性不存在,则返回的值将为null或\" \"(空字符串).", + "!doc": "获取或设置节点及其后代的文本内容.", }, - "setAttribute": { + }, + "!doc": + "节点是一个接口,许多DOM类型都从该接口继承,并允许类似地对待(或测试)这些各种类型.", + }, + Element: { + "!type": "fn()", + prototype: { + "!proto": "Node.prototype", + getAttribute: { + "!type": "fn(name: string) -> string", + "!doc": + '返回指定元素上的命名属性的值.如果命名属性不存在,则返回的值将为null或" "(空字符串).', + }, + setAttribute: { "!type": "fn(name: string, value: string)", "!doc": "在指定元素上添加新属性或更改现有属性的值.", }, - "removeAttribute": { + removeAttribute: { "!type": "fn(name: string)", "!doc": "从指定元素中删除属性.", }, - "getElementsByTagName": { + getElementsByTagName: { "!type": "fn(tagName: string) -> +NodeList", - "!doc": "返回具有给定标签名的元素列表.搜索指定元素下面的子树,不包括元素本身.返回的列表是活动的,这意味着它将自动使用DOM树进行更新.因此,无需使用相同的元素和参数多次调用element.getElementsByTagName." + "!doc": + "返回具有给定标签名的元素列表.搜索指定元素下面的子树,不包括元素本身.返回的列表是活动的,这意味着它将自动使用DOM树进行更新.因此,无需使用相同的元素和参数多次调用element.getElementsByTagName.", }, - "getElementsByClassName": { + getElementsByClassName: { "!type": "fn(name: string) -> +NodeList", - "!doc": "返回具有所有给定类名称的一组元素.在文档对象上调用时,将搜索整个文档,包括根节点.您还可以在任何元素上调用getElementsByClassName;它将仅返回元素,它们是具有给定类名的指定根元素的后代." + "!doc": + "返回具有所有给定类名称的一组元素.在文档对象上调用时,将搜索整个文档,包括根节点.您还可以在任何元素上调用getElementsByClassName;它将仅返回元素,它们是具有给定类名的指定根元素的后代.", }, - "children": { + children: { "!type": "+HTMLCollection", - "!doc": "返回给定元素的子元素的集合." + "!doc": "返回给定元素的子元素的集合.", }, - "className": { + className: { "!type": "string", "!doc": "获取并设置指定元素的class属性的值.", }, - "style": { - "cssText": "string", - "alignmentBaseline": "string", - "background": "string", - "backgroundAttachment": "string", - "backgroundClip": "string", - "backgroundColor": "string", - "backgroundImage": "string", - "backgroundOrigin": "string", - "backgroundPosition": "string", - "backgroundPositionX": "string", - "backgroundPositionY": "string", - "backgroundRepeat": "string", - "backgroundRepeatX": "string", - "backgroundRepeatY": "string", - "backgroundSize": "string", - "baselineShift": "string", - "border": "string", - "borderBottom": "string", - "borderBottomColor": "string", - "borderBottomLeftRadius": "string", - "borderBottomRightRadius": "string", - "borderBottomStyle": "string", - "borderBottomWidth": "string", - "borderCollapse": "string", - "borderColor": "string", - "borderImage": "string", - "borderImageOutset": "string", - "borderImageRepeat": "string", - "borderImageSlice": "string", - "borderImageSource": "string", - "borderImageWidth": "string", - "borderLeft": "string", - "borderLeftColor": "string", - "borderLeftStyle": "string", - "borderLeftWidth": "string", - "borderRadius": "string", - "borderRight": "string", - "borderRightColor": "string", - "borderRightStyle": "string", - "borderRightWidth": "string", - "borderSpacing": "string", - "borderStyle": "string", - "borderTop": "string", - "borderTopColor": "string", - "borderTopLeftRadius": "string", - "borderTopRightRadius": "string", - "borderTopStyle": "string", - "borderTopWidth": "string", - "borderWidth": "string", - "bottom": "string", - "boxShadow": "string", - "boxSizing": "string", - "captionSide": "string", - "clear": "string", - "clip": "string", - "clipPath": "string", - "clipRule": "string", - "color": "string", - "colorInterpolation": "string", - "colorInterpolationFilters": "string", - "colorProfile": "string", - "colorRendering": "string", - "content": "string", - "counterIncrement": "string", - "counterReset": "string", - "cursor": "string", - "direction": "string", - "display": "string", - "dominantBaseline": "string", - "emptyCells": "string", - "enableBackground": "string", - "fill": "string", - "fillOpacity": "string", - "fillRule": "string", - "filter": "string", - "float": "string", - "floodColor": "string", - "floodOpacity": "string", - "font": "string", - "fontFamily": "string", - "fontSize": "string", - "fontStretch": "string", - "fontStyle": "string", - "fontVariant": "string", - "fontWeight": "string", - "glyphOrientationHorizontal": "string", - "glyphOrientationVertical": "string", - "height": "string", - "imageRendering": "string", - "kerning": "string", - "left": "string", - "letterSpacing": "string", - "lightingColor": "string", - "lineHeight": "string", - "listStyle": "string", - "listStyleImage": "string", - "listStylePosition": "string", - "listStyleType": "string", - "margin": "string", - "marginBottom": "string", - "marginLeft": "string", - "marginRight": "string", - "marginTop": "string", - "marker": "string", - "markerEnd": "string", - "markerMid": "string", - "markerStart": "string", - "mask": "string", - "maxHeight": "string", - "maxWidth": "string", - "minHeight": "string", - "minWidth": "string", - "opacity": "string", - "orphans": "string", - "outline": "string", - "outlineColor": "string", - "outlineOffset": "string", - "outlineStyle": "string", - "outlineWidth": "string", - "overflow": "string", - "overflowWrap": "string", - "overflowX": "string", - "overflowY": "string", - "padding": "string", - "paddingBottom": "string", - "paddingLeft": "string", - "paddingRight": "string", - "paddingTop": "string", - "page": "string", - "pageBreakAfter": "string", - "pageBreakBefore": "string", - "pageBreakInside": "string", - "pointerEvents": "string", - "position": "string", - "quotes": "string", - "resize": "string", - "right": "string", - "shapeRendering": "string", - "size": "string", - "speak": "string", - "src": "string", - "stopColor": "string", - "stopOpacity": "string", - "stroke": "string", - "strokeDasharray": "string", - "strokeDashoffset": "string", - "strokeLinecap": "string", - "strokeLinejoin": "string", - "strokeMiterlimit": "string", - "strokeOpacity": "string", - "strokeWidth": "string", - "tabSize": "string", - "tableLayout": "string", - "textAlign": "string", - "textAnchor": "string", - "textDecoration": "string", - "textIndent": "string", - "textLineThrough": "string", - "textLineThroughColor": "string", - "textLineThroughMode": "string", - "textLineThroughStyle": "string", - "textLineThroughWidth": "string", - "textOverflow": "string", - "textOverline": "string", - "textOverlineColor": "string", - "textOverlineMode": "string", - "textOverlineStyle": "string", - "textOverlineWidth": "string", - "textRendering": "string", - "textShadow": "string", - "textTransform": "string", - "textUnderline": "string", - "textUnderlineColor": "string", - "textUnderlineMode": "string", - "textUnderlineStyle": "string", - "textUnderlineWidth": "string", - "top": "string", - "unicodeBidi": "string", - "unicodeRange": "string", - "vectorEffect": "string", - "verticalAlign": "string", - "visibility": "string", - "whiteSpace": "string", - "width": "string", - "wordBreak": "string", - "wordSpacing": "string", - "wordWrap": "string", - "writingMode": "string", - "zIndex": "string", - "zoom": "string", - "!doc": "返回一个表示元素的style属性的对象." + style: { + cssText: "string", + alignmentBaseline: "string", + background: "string", + backgroundAttachment: "string", + backgroundClip: "string", + backgroundColor: "string", + backgroundImage: "string", + backgroundOrigin: "string", + backgroundPosition: "string", + backgroundPositionX: "string", + backgroundPositionY: "string", + backgroundRepeat: "string", + backgroundRepeatX: "string", + backgroundRepeatY: "string", + backgroundSize: "string", + baselineShift: "string", + border: "string", + borderBottom: "string", + borderBottomColor: "string", + borderBottomLeftRadius: "string", + borderBottomRightRadius: "string", + borderBottomStyle: "string", + borderBottomWidth: "string", + borderCollapse: "string", + borderColor: "string", + borderImage: "string", + borderImageOutset: "string", + borderImageRepeat: "string", + borderImageSlice: "string", + borderImageSource: "string", + borderImageWidth: "string", + borderLeft: "string", + borderLeftColor: "string", + borderLeftStyle: "string", + borderLeftWidth: "string", + borderRadius: "string", + borderRight: "string", + borderRightColor: "string", + borderRightStyle: "string", + borderRightWidth: "string", + borderSpacing: "string", + borderStyle: "string", + borderTop: "string", + borderTopColor: "string", + borderTopLeftRadius: "string", + borderTopRightRadius: "string", + borderTopStyle: "string", + borderTopWidth: "string", + borderWidth: "string", + bottom: "string", + boxShadow: "string", + boxSizing: "string", + captionSide: "string", + clear: "string", + clip: "string", + clipPath: "string", + clipRule: "string", + color: "string", + colorInterpolation: "string", + colorInterpolationFilters: "string", + colorProfile: "string", + colorRendering: "string", + content: "string", + counterIncrement: "string", + counterReset: "string", + cursor: "string", + direction: "string", + display: "string", + dominantBaseline: "string", + emptyCells: "string", + enableBackground: "string", + fill: "string", + fillOpacity: "string", + fillRule: "string", + filter: "string", + float: "string", + floodColor: "string", + floodOpacity: "string", + font: "string", + fontFamily: "string", + fontSize: "string", + fontStretch: "string", + fontStyle: "string", + fontVariant: "string", + fontWeight: "string", + glyphOrientationHorizontal: "string", + glyphOrientationVertical: "string", + height: "string", + imageRendering: "string", + kerning: "string", + left: "string", + letterSpacing: "string", + lightingColor: "string", + lineHeight: "string", + listStyle: "string", + listStyleImage: "string", + listStylePosition: "string", + listStyleType: "string", + margin: "string", + marginBottom: "string", + marginLeft: "string", + marginRight: "string", + marginTop: "string", + marker: "string", + markerEnd: "string", + markerMid: "string", + markerStart: "string", + mask: "string", + maxHeight: "string", + maxWidth: "string", + minHeight: "string", + minWidth: "string", + opacity: "string", + orphans: "string", + outline: "string", + outlineColor: "string", + outlineOffset: "string", + outlineStyle: "string", + outlineWidth: "string", + overflow: "string", + overflowWrap: "string", + overflowX: "string", + overflowY: "string", + padding: "string", + paddingBottom: "string", + paddingLeft: "string", + paddingRight: "string", + paddingTop: "string", + page: "string", + pageBreakAfter: "string", + pageBreakBefore: "string", + pageBreakInside: "string", + pointerEvents: "string", + position: "string", + quotes: "string", + resize: "string", + right: "string", + shapeRendering: "string", + size: "string", + speak: "string", + src: "string", + stopColor: "string", + stopOpacity: "string", + stroke: "string", + strokeDasharray: "string", + strokeDashoffset: "string", + strokeLinecap: "string", + strokeLinejoin: "string", + strokeMiterlimit: "string", + strokeOpacity: "string", + strokeWidth: "string", + tabSize: "string", + tableLayout: "string", + textAlign: "string", + textAnchor: "string", + textDecoration: "string", + textIndent: "string", + textLineThrough: "string", + textLineThroughColor: "string", + textLineThroughMode: "string", + textLineThroughStyle: "string", + textLineThroughWidth: "string", + textOverflow: "string", + textOverline: "string", + textOverlineColor: "string", + textOverlineMode: "string", + textOverlineStyle: "string", + textOverlineWidth: "string", + textRendering: "string", + textShadow: "string", + textTransform: "string", + textUnderline: "string", + textUnderlineColor: "string", + textUnderlineMode: "string", + textUnderlineStyle: "string", + textUnderlineWidth: "string", + top: "string", + unicodeBidi: "string", + unicodeRange: "string", + vectorEffect: "string", + verticalAlign: "string", + visibility: "string", + whiteSpace: "string", + width: "string", + wordBreak: "string", + wordSpacing: "string", + wordWrap: "string", + writingMode: "string", + zIndex: "string", + zoom: "string", + "!doc": "返回一个表示元素的style属性的对象.", }, - "classList": { + classList: { "!type": "+DOMTokenList", - "!doc": "返回元素的class属性的标记列表." + "!doc": "返回元素的class属性的标记列表.", }, - "title": { + title: { "!type": "string", - "!doc": " \"\u5efa\u7acb\u5f53\u9f20\u6807\u60ac\u505c\u5728\u663e\u793a\u7684\u8282\u70b9\u4e0a\u65f6\u5728\"\u5de5\u5177\u63d0\u793a\"\u5f39\u51fa\u7a97\u53e3\u4e2d\u663e\u793a\u7684\u6587\u672c.\"," + "!doc": + ' "\u5efa\u7acb\u5f53\u9f20\u6807\u60ac\u505c\u5728\u663e\u793a\u7684\u8282\u70b9\u4e0a\u65f6\u5728"\u5de5\u5177\u63d0\u793a"\u5f39\u51fa\u7a97\u53e3\u4e2d\u663e\u793a\u7684\u6587\u672c.",', }, - "width": { + width: { "!type": "number", - "!doc": "返回元素的布局宽度." + "!doc": "返回元素的布局宽度.", }, - "height": { + height: { "!type": "number", - "!doc": "元素相对于元素的offsetParent的高度." + "!doc": "元素相对于元素的offsetParent的高度.", }, - "getContext": { + getContext: { "!type": "fn(id: string) -> CanvasRenderingContext2D", - "!doc": " DOM画布元素公开了HTMLCanvasElement接口,该接口提供了用于操纵画布元素的布局和表示的属性和方法.HTMLCanvasElement接口继承了元素对象接口的属性和方法.", + "!doc": + " DOM画布元素公开了HTMLCanvasElement接口,该接口提供了用于操纵画布元素的布局和表示的属性和方法.HTMLCanvasElement接口继承了元素对象接口的属性和方法.", }, - "innerHTML": { + innerHTML: { "!type": "string", "!doc": "设置或获取描述元素后代的HTML语法.", - } + }, }, "!doc": "表示HTML或XML文档中的元素.", }, - "Document": { + Document: { "!type": "fn()", - "prototype": { + prototype: { "!proto": "Node.prototype", - "height": { + height: { "!type": "number", "!doc": "返回当前文档的元素的高度.", }, - "width": { + width: { "!type": "number", "!doc": "以像素为单位返回当前文档的元素的宽度.", }, - "body": { + body: { "!type": "+Element", "!doc": "返回当前文档的或节点.", }, - "cookie": { + cookie: { "!type": "string", "!doc": "获取并设置与当前文档关联的cookie.", }, - "URL": "string", - "title": { + URL: "string", + title: { "!type": "string", - "!doc": "获取或设置文档的标题." + "!doc": "获取或设置文档的标题.", }, - "getElementById": { + getElementById: { "!type": "fn(id: string) -> +Element", - "!doc": "通过元素ID返回对该元素的引用." + "!doc": "通过元素ID返回对该元素的引用.", }, - "getElementsByTagName": { + getElementsByTagName: { "!type": "fn(tagName: string) -> +NodeList", - "!doc": "返回具有给定标签名称的元素的NodeList.将搜索整个文档,包括根节点.返回的NodeList处于活动状态,这意味着它会自动更新自身以与DOM树保持同步,而无需再次调用document.getElementsByTagName." + "!doc": + "返回具有给定标签名称的元素的NodeList.将搜索整个文档,包括根节点.返回的NodeList处于活动状态,这意味着它会自动更新自身以与DOM树保持同步,而无需再次调用document.getElementsByTagName.", }, - "getElementsByName": { + getElementsByName: { "!type": "fn(name: string) -> +HTMLCollection", "!doc": "返回HTML文档中具有给定名称的元素列表.", }, - "getElementsByClassName": "Element.prototype.getElementsByClassName" + getElementsByClassName: "Element.prototype.getElementsByClassName", }, - "!doc": "浏览器中加载的每个网页都有其自己的文档对象.此对象用作网页内容(DOM树,包括诸如和之类的元素)的入口点,并提供文档的全局功能(例如获取页面的URL和在文档中创建新元素)." + "!doc": + "浏览器中加载的每个网页都有其自己的文档对象.此对象用作网页内容(DOM树,包括诸如和
之类的元素)的入口点,并提供文档的全局功能(例如获取页面的URL和在文档中创建新元素).", }, - "document": { + document: { "!type": "+Document", - "!doc": "浏览器中加载的每个网页都有其自己的文档对象.此对象用作网页内容(DOM树,包括诸如和
之类的元素)的入口点,并提供文档的全局功能(例如获取页面的URL和在文档中创建新元素)." + "!doc": + "浏览器中加载的每个网页都有其自己的文档对象.此对象用作网页内容(DOM树,包括诸如和
之类的元素)的入口点,并提供文档的全局功能(例如获取页面的URL和在文档中创建新元素).", }, - "Event": { + Event: { "!type": "fn()", - "prototype": { - "stopPropagation": { + prototype: { + stopPropagation: { "!type": "fn()", - "!doc": "防止当前事件进一步传播." + "!doc": "防止当前事件进一步传播.", }, - "preventDefault": { + preventDefault: { "!type": "fn()", - "!doc": "如果可以取消事件,则取消该事件,而不停止事件的进一步传播." + "!doc": "如果可以取消事件,则取消该事件,而不停止事件的进一步传播.", }, - "stopImmediatePropagation": { + stopImmediatePropagation: { "!type": "fn()", - "!doc": "防止同一事件的其他侦听器被调用." + "!doc": "防止同一事件的其他侦听器被调用.", }, - "type": { + type: { "!type": "string", - "!doc": "返回包含事件类型的字符串." + "!doc": "返回包含事件类型的字符串.", }, - "target": { + target: { "!type": "+Element", - "!doc": " EventTarget是由对象实现的DOM接口,这些对象可以接收DOM事件并具有侦听器.最常见的EventTarget是DOM元素,尽管其他对象也可以是EventTarget,例如文档,窗口,XMLHttpRequest,和别的." + "!doc": + " EventTarget是由对象实现的DOM接口,这些对象可以接收DOM事件并具有侦听器.最常见的EventTarget是DOM元素,尽管其他对象也可以是EventTarget,例如文档,窗口,XMLHttpRequest,和别的.", }, - "clientX": { + clientX: { "!type": "number", - "!doc": "返回事件发生的应用程序客户区域内的水平坐标(与页面内的坐标相反).例如,单击客户区域左上角将始终显示clientX值为0的鼠标事件,无论页面是否水平滚动." + "!doc": + "返回事件发生的应用程序客户区域内的水平坐标(与页面内的坐标相反).例如,单击客户区域左上角将始终显示clientX值为0的鼠标事件,无论页面是否水平滚动.", }, - "clientY": { + clientY: { "!type": "number", - "!doc": "返回事件发生在应用程序客户区中的垂直坐标(与页面中的坐标相反).例如,单击客户区左上角将始终显示不管页面是否垂直滚动,clientY值为0的鼠标事件." + "!doc": + "返回事件发生在应用程序客户区中的垂直坐标(与页面中的坐标相反).例如,单击客户区左上角将始终显示不管页面是否垂直滚动,clientY值为0的鼠标事件.", }, - "keyCode": { + keyCode: { "!type": "number", - "!doc": "返回按键事件中的非字符键或任何其他类型的键盘事件中的任何键的Unicode值.", + "!doc": + "返回按键事件中的非字符键或任何其他类型的键盘事件中的任何键的Unicode值.", }, - "charCode": { + charCode: { "!type": "number", - "!doc": "返回在按键事件期间按下的字符键的Unicode值." + "!doc": "返回在按键事件期间按下的字符键的Unicode值.", }, - "which": { + which: { "!type": "number", - "!doc": "返回所按下键的数字keyCode或所按下字母数字键的字符代码(charCode)." + "!doc": + "返回所按下键的数字keyCode或所按下字母数字键的字符代码(charCode).", }, - "button": { + button: { "!type": "number", - "!doc": "指示导致事件的鼠标按钮." + "!doc": "指示导致事件的鼠标按钮.", }, - "shiftKey": { + shiftKey: { "!type": "bool", "!doc": "指示事件触发时是否按下SHIFT键.", }, - "ctrlKey": { + ctrlKey: { "!type": "bool", "!doc": "指示事件触发时是否按下了CTRL键.", }, - "altKey": { + altKey: { "!type": "bool", "!doc": "指示事件触发时是否按下ALT键.", - } - } + }, + }, }, - "Storage": { - "length": { + Storage: { + length: { "!type": "number", - "!doc": "存储接口的length只读属性返回一个整数,该整数表示存储在存储对象中的数据项的数量.", + "!doc": + "存储接口的length只读属性返回一个整数,该整数表示存储在存储对象中的数据项的数量.", }, - "setItem": { + setItem: { "!type": "fn(name: string, value: string)", - "!doc": "存储接口的setItem()方法在传递键名称和值时,会将该键添加到存储中,或者更新该键的值(如果已存在).", + "!doc": + "存储接口的setItem()方法在传递键名称和值时,会将该键添加到存储中,或者更新该键的值(如果已存在).", }, - "getItem": { + getItem: { "!type": "fn(name: string) -> string", "!doc": "存储接口的getItem()方法在传递键名时将返回该键的值.", }, - "key": { + key: { "!type": "fn(index: number) -> string", - "!doc": "存储接口的key()方法传递数字n时,返回存储中第n个键的名称.键的顺序是用户代理定义的,因此您不应依赖它." + "!doc": + "存储接口的key()方法传递数字n时,返回存储中第n个键的名称.键的顺序是用户代理定义的,因此您不应依赖它.", }, - "removeItem": { + removeItem: { "!type": "fn(key: string)", "!doc": "存储接口的removeItem()方法在传递了键名后,将从存储中删除该键.", }, - "clear": { + clear: { "!type": "fn()", - "!doc": "存储接口的clear()方法在被调用时将从存储中清空所有键." - } + "!doc": "存储接口的clear()方法在被调用时将从存储中清空所有键.", + }, }, - "localStorage": { + localStorage: { "!type": "Storage", - "!doc": " localStorage属性允许您访问本地存储对象.localStorage与sessionStorage类似.唯一的区别是,虽然存储在localStorage中的数据没有到期时间,但是浏览会话时存储在sessionStorage中的数据将被清除.结束-也就是说,当浏览器关闭时.\ n \ n请注意,存储在localStorage或sessionStorage中的数据特定于页面协议." + "!doc": + " localStorage属性允许您访问本地存储对象.localStorage与sessionStorage类似.唯一的区别是,虽然存储在localStorage中的数据没有到期时间,但是浏览会话时存储在sessionStorage中的数据将被清除.结束-也就是说,当浏览器关闭时. n n请注意,存储在localStorage或sessionStorage中的数据特定于页面协议.", }, - "console": { - "assert": { + console: { + assert: { "!type": "fn(assertion: bool, text: string)", "!doc": "如果断言为false,则将错误消息写入控制台.", }, - "error": { + error: { "!type": "fn(...msg: ?)", "!doc": "将错误消息输出到Web控制台.", }, - "info": { + info: { "!type": "fn(...msg: ?)", "!doc": "将参考消息输出到Web控制台.", }, - "log": { + log: { "!type": "fn(...msg: ?)", "!doc": "将消息输出到Web控制台.", }, - "time": { + time: { "!type": "fn(label: string)", "!doc": "启动计时器,您可以使用该计时器来跟踪操作需要多长时间.", }, - "timeEnd": { + timeEnd: { "!type": "fn(label: string)", "!doc": "停止以前通过调用console.time()启动的计时器.", }, - "trace": { + trace: { "!type": "fn()", "!doc": "将堆栈跟踪输出到Web控制台.", }, - "warn": { + warn: { "!type": "fn(...msg: ?)", "!doc": "将警告消息输出到Web控制台.", }, - "!doc": "控制台对象提供对浏览器调试控制台的访问.其工作方式的细节因浏览器而异,但实际上提供了一组事实上的功能.", + "!doc": + "控制台对象提供对浏览器调试控制台的访问.其工作方式的细节因浏览器而异,但实际上提供了一组事实上的功能.", }, - "window": { + window: { "!type": "", "!doc": "窗口对象代表一个包含DOM文档的窗口.", }, - "self": { + self: { "!type": "", "!doc": "将对象引用返回到窗口对象.", }, - "devicePixelRatio": "number", - "requestAnimationFrame": { + devicePixelRatio: "number", + requestAnimationFrame: { "!type": "fn(callback: fn(timestamp: number)) -> number", - "!doc": " Window.requestAnimationFrame()方法告诉浏览器您希望执行动画,并请求浏览器在下一次重绘之前调用指定的函数来更新动画.该方法将回调作为参数在重新粉刷之前被调用." + "!doc": + " Window.requestAnimationFrame()方法告诉浏览器您希望执行动画,并请求浏览器在下一次重绘之前调用指定的函数来更新动画.该方法将回调作为参数在重新粉刷之前被调用.", }, - "cancelAnimationFrame": { + cancelAnimationFrame: { "!type": "fn(number)n", "!doc": "取消先前安排的动画帧请求.", }, - "alert": { + alert: { "!type": "fn(message: string)", - "!doc": "显示具有指定内容和确定按钮的警报对话框." + "!doc": "显示具有指定内容和确定按钮的警报对话框.", }, - "confirm": { + confirm: { "!type": "fn(message: string) -> bool", "!doc": "显示带有消息和两个按钮(确定和取消)的模式对话框.", }, - "prompt": { + prompt: { "!type": "fn(message: string, value: string) -> string", "!doc": "显示一个对话框,提示用户输入一些文本.", }, - "setTimeout": { + setTimeout: { "!type": "fn(f: fn(), ms: number) -> number", - "!doc": "在指定的延迟后调用函数或执行代码段." + "!doc": "在指定的延迟后调用函数或执行代码段.", }, - "clearTimeout": { + clearTimeout: { "!type": "fn(timeout: number)", "!doc": "清除window.setTimeout()设置的延迟.", }, - "setInterval": { + setInterval: { "!type": "fn(f: fn(), ms: number) -> number", - "!doc": "反复调用一个函数或执行代码段,每次调用该函数之间有固定的时间延迟.", + "!doc": + "反复调用一个函数或执行代码段,每次调用该函数之间有固定的时间延迟.", }, - "clearInterval": { + clearInterval: { "!type": "fn(interval: number)", "!doc": "取消使用setInterval设置的重复操作.", }, - "atob": { + atob: { "!type": "fn(encoded: string) -> string", - "!doc": "解码使用base-64编码编码的数据字符串." + "!doc": "解码使用base-64编码编码的数据字符串.", }, - "btoa": { + btoa: { "!type": "fn(data: string) -> string", "!doc": "从一串二进制数据创建一个base-64编码的ASCII字符串.", }, - "getComputedStyle": { + getComputedStyle: { "!type": "fn(node: +Element, pseudo?: string) -> Element.prototype.style", "!doc": "给出元素的所有CSS属性的最终使用值.", }, - "CanvasRenderingContext2D": { - "canvas": "+Element", - "width": "number", - "height": "number", - "commit": "fn()", - "save": "fn()", - "restore": "fn()", - "currentTransform": "?", - "scale": "fn(x: number, y: number)", - "rotate": "fn(angle: number)", - "translate": "fn(x: number, y: number)", - "transform": "fn(a: number, b: number, c: number, d: number, e: number, f: number)", - "setTransform": "fn(a: number, b: number, c: number, d: number, e: number, f: number)", - "resetTransform": "fn()", - "globalAlpha": "number", - "globalCompositeOperation": "string", - "imageSmoothingEnabled": "bool", - "strokeStyle": "string", - "fillStyle": "string", - "createLinearGradient": "fn(x0: number, y0: number, x1: number, y1: number) -> ?", - "createPattern": "fn(image: ?, repetition: string) -> ?", - "shadowOffsetX": "number", - "shadowOffsetY": "number", - "shadowBlur": "number", - "shadowColor": "string", - "clearRect": "fn(x: number, y: number, w: number, h: number)", - "fillRect": "fn(x: number, y: number, w: number, h: number)", - "strokeRect": "fn(x: number, y: number, w: number, h: number)", - "fillRule": "string", - "fill": "fn()", - "beginPath": "fn()", - "stroke": "fn()", - "clip": "fn()", - "resetClip": "fn()", - "fillText": "fn(text: string, x: number, y: number, maxWidth: number)", - "strokeText": "fn(text: string, x: number, y: number, maxWidth: number)", - "measureText": "fn(text: string) -> ?", - "drawImage": "fn(image: ?, dx: number, dy: number)", - "createImageData": "fn(sw: number, sh: number) -> ?", - "getImageData": "fn(sx: number, sy: number, sw: number, sh: number) -> ?", - "putImageData": "fn(imagedata: ?, dx: number, dy: number)", - "lineWidth": "number", - "lineCap": "string", - "lineJoin": "string", - "miterLimit": "number", - "setLineDash": "fn(segments: [number])", - "getLineDash": "fn() -> [number]", - "lineDashOffset": "number", - "font": "string", - "textAlign": "string", - "textBaseline": "string", - "direction": "string", - "closePath": "fn()", - "moveTo": "fn(x: number, y: number)", - "lineTo": "fn(x: number, y: number)", - "quadraticCurveTo": "fn(cpx: number, cpy: number, x: number, y: number)", - "bezierCurveTo": "fn(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number)", - "arcTo": "fn(x1: number, y1: number, x2: number, y2: number, radius: number)", - "rect": "fn(x: number, y: number, w: number, h: number)", - "arc": "fn(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: bool)", - "ellipse": "fn(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise: bool)" - } + CanvasRenderingContext2D: { + canvas: "+Element", + width: "number", + height: "number", + commit: "fn()", + save: "fn()", + restore: "fn()", + currentTransform: "?", + scale: "fn(x: number, y: number)", + rotate: "fn(angle: number)", + translate: "fn(x: number, y: number)", + transform: + "fn(a: number, b: number, c: number, d: number, e: number, f: number)", + setTransform: + "fn(a: number, b: number, c: number, d: number, e: number, f: number)", + resetTransform: "fn()", + globalAlpha: "number", + globalCompositeOperation: "string", + imageSmoothingEnabled: "bool", + strokeStyle: "string", + fillStyle: "string", + createLinearGradient: + "fn(x0: number, y0: number, x1: number, y1: number) -> ?", + createPattern: "fn(image: ?, repetition: string) -> ?", + shadowOffsetX: "number", + shadowOffsetY: "number", + shadowBlur: "number", + shadowColor: "string", + clearRect: "fn(x: number, y: number, w: number, h: number)", + fillRect: "fn(x: number, y: number, w: number, h: number)", + strokeRect: "fn(x: number, y: number, w: number, h: number)", + fillRule: "string", + fill: "fn()", + beginPath: "fn()", + stroke: "fn()", + clip: "fn()", + resetClip: "fn()", + fillText: "fn(text: string, x: number, y: number, maxWidth: number)", + strokeText: "fn(text: string, x: number, y: number, maxWidth: number)", + measureText: "fn(text: string) -> ?", + drawImage: "fn(image: ?, dx: number, dy: number)", + createImageData: "fn(sw: number, sh: number) -> ?", + getImageData: "fn(sx: number, sy: number, sw: number, sh: number) -> ?", + putImageData: "fn(imagedata: ?, dx: number, dy: number)", + lineWidth: "number", + lineCap: "string", + lineJoin: "string", + miterLimit: "number", + setLineDash: "fn(segments: [number])", + getLineDash: "fn() -> [number]", + lineDashOffset: "number", + font: "string", + textAlign: "string", + textBaseline: "string", + direction: "string", + closePath: "fn()", + moveTo: "fn(x: number, y: number)", + lineTo: "fn(x: number, y: number)", + quadraticCurveTo: "fn(cpx: number, cpy: number, x: number, y: number)", + bezierCurveTo: + "fn(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number)", + arcTo: + "fn(x1: number, y1: number, x2: number, y2: number, radius: number)", + rect: "fn(x: number, y: number, w: number, h: number)", + arc: "fn(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: bool)", + ellipse: + "fn(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, anticlockwise: bool)", + }, }, { "!name": "ecmascript", - "Infinity": { + Infinity: { "!type": "number", - "!doc": "代表无穷大的数值." + "!doc": "代表无穷大的数值.", }, - "undefined": { + undefined: { "!type": "?", "!doc": "该值未定义.", }, - "NaN": { + NaN: { "!type": "number", - "!doc": "代表非数字的值." + "!doc": "代表非数字的值.", }, - "Object": { + Object: { "!type": "fn()", - "create": { + create: { "!type": "fn(proto: ?) -> !custom:Object_create", "!doc": "使用指定的原型对象和属性创建一个新对象.", }, - "defineProperty": { - "!type": "fn(obj: ?, prop: string, desc: propertyDescriptor) -> !custom:Object_defineProperty", - "!doc": "直接在对象上定义新属性,或修改对象上的现有属性,然后返回对象.如果想了解如何将Object.defineProperty方法与类似二进制标志的语法一起使用,请参阅本文." + defineProperty: { + "!type": + "fn(obj: ?, prop: string, desc: propertyDescriptor) -> !custom:Object_defineProperty", + "!doc": + "直接在对象上定义新属性,或修改对象上的现有属性,然后返回对象.如果想了解如何将Object.defineProperty方法与类似二进制标志的语法一起使用,请参阅本文.", }, - "keys": { + keys: { "!type": "fn(obj: ?) -> [string]", - "!doc": "返回一个给定对象自己的可枚举属性的数组,其顺序与for-in循环所提供的顺序相同(不同之处在于for-in循环也枚举了原型链中的属性). " + "!doc": + "返回一个给定对象自己的可枚举属性的数组,其顺序与for-in循环所提供的顺序相同(不同之处在于for-in循环也枚举了原型链中的属性). ", }, - "assign": { + assign: { "!type": "fn(target: ?, source: ?, source?: ?) -> !0", "!effects": ["copy !1 !0", "copy !2 !0", "copy !3 !0"], - "!doc": " Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象.它将返回目标对象.,", + "!doc": + " Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象.它将返回目标对象.,", }, - "prototype": { + prototype: { "!stdProto": "Object", - "toString": { + toString: { "!type": "fn() -> string", - "!doc": "返回表示对象的字符串." + "!doc": "返回表示对象的字符串.", }, - "hasOwnProperty": { + hasOwnProperty: { "!type": "fn(prop: string) -> bool", "!doc": "返回一个布尔值,指示对象是否具有指定的属性.", - } + }, }, }, - "Function": { + Function: { "!type": "fn(body: string) -> fn()", - "prototype": { + prototype: { "!stdProto": "Function", - "apply": { + apply: { "!type": "fn(this: ?, args: [?])", - "!effects": [ - "call and return !this this=!0 !1. !1. !1." - ], - "!doc": "调用具有给定值的函数,并以数组(或类似对象的数组)形式提供参数.", + "!effects": ["call and return !this this=!0 !1. !1. !1."], + "!doc": + "调用具有给定值的函数,并以数组(或类似对象的数组)形式提供参数.", }, - "call": { + call: { "!type": "fn(this: ?, args?: ?) -> !this.!ret", - "!effects": [ - "call and return !this this=!0 !1 !2 !3 !4" - ], + "!effects": ["call and return !this this=!0 !1 !2 !3 !4"], "!doc": "调用具有给定值和单独提供的参数的函数.", }, - "bind": { + bind: { "!type": "fn(this: ?, args?: ?) -> !custom:Function_bind", - "!doc": "创建一个新函数,该函数在被调用时将其this关键字设置为提供的值,并在调用新函数时提供给定的参数序列.", + "!doc": + "创建一个新函数,该函数在被调用时将其this关键字设置为提供的值,并在调用新函数时提供给定的参数序列.", }, - "prototype": "?" + prototype: "?", }, }, - "Array": { + Array: { "!type": "fn(size: number) -> !custom:Array_ctor", - "isArray": { + isArray: { "!type": "fn(value: ?) -> bool", "!doc": "如果对象是数组,则返回true,否则返回false.", }, - "from": { - "!type": "fn(arrayLike: ?, mapFn?: fn(elt: ?, i: number) -> ?, thisArg?: ?) -> [!0.]", - "!effects": [ - "call !1 this=!2 !0. number" - ], - "!doc": " Array.from()方法从类似数组或可迭代的对象创建一个新的Array实例.,", + from: { + "!type": + "fn(arrayLike: ?, mapFn?: fn(elt: ?, i: number) -> ?, thisArg?: ?) -> [!0.]", + "!effects": ["call !1 this=!2 !0. number"], + "!doc": + " Array.from()方法从类似数组或可迭代的对象创建一个新的Array实例.,", }, - "of": { + of: { "!type": "fn(elementN: ?) -> [!0]", - "!doc": " Array.of()方法创建一个新的Array实例,该实例具有可变数量的参数,而不考虑参数的数量或类型.,", + "!doc": + " Array.of()方法创建一个新的Array实例,该实例具有可变数量的参数,而不考虑参数的数量或类型.,", }, - "prototype": { + prototype: { "!stdProto": "Array", - "length": { + length: { "!type": "number", "!doc": "一个无符号的32位整数,指定数组中的元素数.", }, - "concat": { + concat: { "!type": "fn(other: [?]) -> !this", "!doc": "返回一个新数组,该数组由该数组与其他数组和/或值组成.", }, - "join": { + join: { "!type": "fn(separator?: string) -> string", - "!doc": "将数组的所有元素连接到字符串中." + "!doc": "将数组的所有元素连接到字符串中.", }, - "splice": { + splice: { "!type": "fn(pos: number, amount: number, newelt?: ?) -> [?]", "!doc": "更改数组的内容,在删除旧元素的同时添加新元素.", }, - "pop": { + pop: { "!type": "fn() -> !this.", "!doc": "从数组中删除最后一个元素并返回该元素.", }, - "push": { + push: { "!type": "fn(newelt: ?) -> number", - "!effects": [ - "propagate !0 !this." - ], + "!effects": ["propagate !0 !this."], "!doc": "通过添加给定元素并返回数组的新长度来更改数组.", }, - "shift": { + shift: { "!type": "fn() -> !this.", "!doc": "从数组中删除第一个元素并返回该元素.此方法更改数组的长度.", }, - "unshift": { + unshift: { "!type": "fn(newelt: ?) -> number", - "!effects": [ - "propagate !0 !this." - ], + "!effects": ["propagate !0 !this."], "!doc": "将一个或多个元素添加到数组的开头,并返回数组的新长度.", }, - "slice": { + slice: { "!type": "fn(from?: number, to?: number) -> !this", - "!doc": "返回数组一部分的浅表副本." + "!doc": "返回数组一部分的浅表副本.", }, - "reverse": { + reverse: { "!type": "fn()", - "!doc": "就地反转数组.第一个数组元素变为最后一个,而最后一个数组变为第一个.", + "!doc": + "就地反转数组.第一个数组元素变为最后一个,而最后一个数组变为第一个.", }, - "sort": { + sort: { "!type": "fn(compare?: fn(a: ?, b: ?) -> number)", - "!effects": [ - "call !0 !this. !this." - ], - "!doc": "将数组中的元素排序并返回数组." + "!effects": ["call !0 !this. !this."], + "!doc": "将数组中的元素排序并返回数组.", }, - "indexOf": { + indexOf: { "!type": "fn(elt: ?, from?: number) -> number", - "!doc": "返回在数组中可以找到给定元素的第一个索引;如果不存在,则返回-1.", + "!doc": + "返回在数组中可以找到给定元素的第一个索引;如果不存在,则返回-1.", }, - "lastIndexOf": { + lastIndexOf: { "!type": "fn(elt: ?, from?: number) -> number", - "!doc": "返回在数组中找到给定元素的最后一个索引,如果不存在则返回-1.从fromIndex开始向后搜索数组.", + "!doc": + "返回在数组中找到给定元素的最后一个索引,如果不存在则返回-1.从fromIndex开始向后搜索数组.", }, - "filter": { - "!type": "fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> !this", - "!effects": [ - "call !0 this=!1 !this. number !this" - ], + filter: { + "!type": + "fn(test: fn(elt: ?, i: number, array: +Array) -> bool, context?: ?) -> !this", + "!effects": ["call !0 this=!1 !this. number !this"], "!doc": "创建一个新数组,其中包含所有通过提供的功能实现的测试的元素.", }, - "forEach": { + forEach: { "!type": "fn(f: fn(elt: ?, i: number, array: +Array), context?: ?)", - "!effects": [ - "call !0 this=!1 !this. number !this" - ], - "!doc": "每个数组元素执行一次提供的功能." + "!effects": ["call !0 this=!1 !this. number !this"], + "!doc": "每个数组元素执行一次提供的功能.", }, - "map": { - "!type": "fn(f: fn(elt: ?, i: number, array: +Array) -> ?, context?: ?) -> [!0.!ret]", - "!effects": [ - "call !0 this=!1 !this. number !this" - ], + map: { + "!type": + "fn(f: fn(elt: ?, i: number, array: +Array) -> ?, context?: ?) -> [!0.!ret]", + "!effects": ["call !0 this=!1 !this. number !this"], "!doc": "创建一个新数组,其结果是对该数组中的每个元素调用提供的函数.", }, - "reduce": { - "!type": "fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret", - "!effects": [ - "call !0 !1 !this. number !this" - ], - "!doc": "对一个累加器和数组的每个值(从左到右)应用一个函数,以将其减小为单个值.", + reduce: { + "!type": + "fn(combine: fn(sum: ?, elt: ?, i: number, array: +Array) -> ?, init?: ?) -> !0.!ret", + "!effects": ["call !0 !1 !this. number !this"], + "!doc": + "对一个累加器和数组的每个值(从左到右)应用一个函数,以将其减小为单个值.", }, - "fill": { + fill: { "!type": "fn(value: ?, start?: number, end?: number) -> !this", - "!doc": " fill()方法使用静态值填充数组的所有元素,从开始索引到结束索引.,", + "!doc": + " fill()方法使用静态值填充数组的所有元素,从开始索引到结束索引.,", }, - "find": { - "!type": "fn(callback: fn(element: ?, index: number, array: [?]) -> bool, thisArg?: ?) -> !this.", + find: { + "!type": + "fn(callback: fn(element: ?, index: number, array: [?]) -> bool, thisArg?: ?) -> !this.", "!effects": ["call !0 this=!2 !this. number"], - "!doc": "如果数组中的元素满足提供的测试功能,则find()方法将在数组中返回一个值.否则,返回undefined.,", + "!doc": + "如果数组中的元素满足提供的测试功能,则find()方法将在数组中返回一个值.否则,返回undefined.,", }, - "findIndex": { - "!type": "fn(callback: fn(element: ?, index: number, array: [?]), thisArg?: ?) -> number", + findIndex: { + "!type": + "fn(callback: fn(element: ?, index: number, array: [?]), thisArg?: ?) -> number", "!effects": ["call !0 this=!2 !this. number"], - "!doc": "如果数组中的元素满足提供的测试功能,则findIndex()方法将返回数组中的索引.否则返回-1.,", + "!doc": + "如果数组中的元素满足提供的测试功能,则findIndex()方法将返回数组中的索引.否则返回-1.,", }, - "keys": { + keys: { "!type": "fn() -> +iter[:t=number]", - "!doc": " keys()方法返回一个新的数组迭代器,其中包含数组中每个索引的键.,", + "!doc": + " keys()方法返回一个新的数组迭代器,其中包含数组中每个索引的键.,", }, - "values": { + values: { "!type": "fn() -> +iter[:t=!this.]", - "!doc": " values()方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的值.,", + "!doc": + " values()方法返回一个新的Array Iterator对象,该对象包含数组中每个索引的值.,", }, - "includes": { + includes: { "!type": "fn(value: ?, fromIndex?: number) -> bool", "!doc": "确定数组是否包含某个元素,并根据需要返回true或false.,", - } + }, }, }, - "String": { + String: { "!type": "fn(value: ?) -> string", - "prototype": { + prototype: { "!stdProto": "String", - "length": { + length: { "!type": "number", - "!doc": "表示字符串的长度." + "!doc": "表示字符串的长度.", }, "": "string", - "charAt": { + charAt: { "!type": "fn(i: number) -> string", "!doc": "从字符串中返回指定的字符.", }, - "charCodeAt": { + charCodeAt: { "!type": "fn(i: number) -> number", - "!doc": "返回给定索引处字符的数字Unicode值(Unicode代码点> 0x10000除外).", + "!doc": + "返回给定索引处字符的数字Unicode值(Unicode代码点> 0x10000除外).", }, - "indexOf": { + indexOf: { "!type": "fn(char: string, from?: number) -> number", - "!doc": "返回指定值首次出现的调用String对象中的索引,从fromIndex开始搜索,\ n如果未找到该值,则返回-1.", + "!doc": + "返回指定值首次出现的调用String对象中的索引,从fromIndex开始搜索, n如果未找到该值,则返回-1.", }, - "lastIndexOf": { + lastIndexOf: { "!type": "fn(char: string, from?: number) -> number", - "!doc": "返回指定值最后一次出现的调用String对象内的索引,如果未找到则返回-1.从fromIndex开始向后搜索调用字符串.", + "!doc": + "返回指定值最后一次出现的调用String对象内的索引,如果未找到则返回-1.从fromIndex开始向后搜索调用字符串.", }, - "substring": { + substring: { "!type": "fn(from: number, to?: number) -> string", - "!doc": "返回一个索引与另一个索引之间或字符串末尾的字符串子集.
from为起始位置,to为终止位置.", + "!doc": + "返回一个索引与另一个索引之间或字符串末尾的字符串子集.
from为起始位置,to为终止位置.", }, - "substr": { + substr: { "!type": "fn(from: number, length?: number) -> string", - "!doc": "以指定的字符数返回从指定位置开始的字符串中的字符.
from为起始位置,length为长度", + "!doc": + "以指定的字符数返回从指定位置开始的字符串中的字符.
from为起始位置,length为长度", }, - "slice": { + slice: { "!type": "fn(from: number, to?: number) -> string", "!doc": "提取字符串的一部分并返回新的字符串.", }, - "padStart": { + padStart: { "!type": "fn(targetLength: number, padString?: string) -> string", - "!doc": "用另一个字符串(如果需要,重复)填充当前字符串,以使结果字符串达到给定的长度.", + "!doc": + "用另一个字符串(如果需要,重复)填充当前字符串,以使结果字符串达到给定的长度.", }, - "padEnd": { + padEnd: { "!type": "fn(targetLength: number, padString?: string) -> string", - "!doc": "用给定的字符串(如果需要,重复)填充当前字符串,以使结果字符串达到给定的长度.", + "!doc": + "用给定的字符串(如果需要,重复)填充当前字符串,以使结果字符串达到给定的长度.", }, - "trim": { + trim: { "!type": "fn() -> string", "!doc": "从字符串的两端删除空格.", }, - "trimStart": { + trimStart: { "!type": "fn() -> string", "!doc": "从字符串的开头删除空格.", }, - "trimEnd": { + trimEnd: { "!type": "fn() -> string", "!doc": "从字符串末尾删除空格.", }, - "toUpperCase": { + toUpperCase: { "!type": "fn() -> string", - "!doc": "返回转换为大写的调用字符串值." + "!doc": "返回转换为大写的调用字符串值.", }, - "toLowerCase": { + toLowerCase: { "!type": "fn() -> string", - "!doc": "返回转换为小写的调用字符串值." + "!doc": "返回转换为小写的调用字符串值.", }, - "split": { + split: { "!type": "fn(pattern?: string|+RegExp, limit?: number) -> [string]", "!doc": "通过将字符串分成子字符串,将String对象拆分为字符串数组.", }, - "concat": { + concat: { "!type": "fn(other: string) -> string", - "!doc": "将两个或多个字符串的文本合并,并返回一个新字符串." + "!doc": "将两个或多个字符串的文本合并,并返回一个新字符串.", }, - "match": { + match: { "!type": "fn(pattern: +RegExp) -> [string]", "!doc": "用于将字符串与正则表达式匹配时用于检索匹配.", }, - "replace": { + replace: { "!type": "fn(pattern: string|+RegExp, replacement: string) -> string", - "!doc": "返回一个新字符串,该字符串的某个或所有匹配项都由替换项替换.该模式可以是字符串或RegExp,并且替换项可以是字符串或每个匹配项将调用的函数. " + "!doc": + "返回一个新字符串,该字符串的某个或所有匹配项都由替换项替换.该模式可以是字符串或RegExp,并且替换项可以是字符串或每个匹配项将调用的函数. ", }, - "endsWith": { + endsWith: { "!type": "fn(searchString: string, position?: number) -> bool", - "!doc": " endsWith()方法确定一个字符串是否以另一个字符串的字符结尾,并根据需要返回true或false.,", + "!doc": + " endsWith()方法确定一个字符串是否以另一个字符串的字符结尾,并根据需要返回true或false.,", }, - "startsWith": { + startsWith: { "!type": "fn(searchString: string, position?: number) -> bool", - "!doc": " startsWith()方法确定一个字符串是否以另一个字符串的字符开头,并根据需要返回true或false.,", - } + "!doc": + " startsWith()方法确定一个字符串是否以另一个字符串的字符开头,并根据需要返回true或false.,", + }, }, }, - "Number": { + Number: { "!type": "fn(value: ?) -> number", - "MAX_VALUE": { + MAX_VALUE: { "!type": "number", - "!doc": " JavaScript中可表示的最大数值." + "!doc": " JavaScript中可表示的最大数值.", }, - "MIN_VALUE": { + MIN_VALUE: { "!type": "number", - "!doc": " JavaScript中可表示的最小正数值." + "!doc": " JavaScript中可表示的最小正数值.", }, - "POSITIVE_INFINITY": { + POSITIVE_INFINITY: { "!type": "number", - "!doc": "代表正无穷大值的值." + "!doc": "代表正无穷大值的值.", }, - "NEGATIVE_INFINITY": { + NEGATIVE_INFINITY: { "!type": "number", - "!doc": "代表负无穷大值的值." + "!doc": "代表负无穷大值的值.", }, - "prototype": { + prototype: { "!stdProto": "Number", - "toString": { + toString: { "!type": "fn(radix?: number) -> string", - "!doc": "返回代表指定Number对象的字符串" + "!doc": "返回代表指定Number对象的字符串", }, - "toFixed": { + toFixed: { "!type": "fn(digits: number) -> string", - "!doc": "使用定点符号格式化数字" + "!doc": "使用定点符号格式化数字", }, - "toExponential": { + toExponential: { "!type": "fn(digits: number) -> string", - "!doc": "返回以指数表示形式表示Number对象的字符串" + "!doc": "返回以指数表示形式表示Number对象的字符串", }, - "toPrecision": { + toPrecision: { "!type": "fn(digits: number) -> string", "!doc": " toPrecision()方法返回一个字符串,该数字表示指定精度的数字.", - } + }, }, - "EPSILON": { + EPSILON: { "!type": "number", - "!doc": " Number.EPSILON属性表示一个数值与可以表示为Number的最小值之间的差异.,", + "!doc": + " Number.EPSILON属性表示一个数值与可以表示为Number的最小值之间的差异.,", }, - "MAX_SAFE_INTEGER": { + MAX_SAFE_INTEGER: { "!type": "number", - "!doc": " Number.MAX_SAFE_INTEGER常量表示JavaScript中的最大安全整数(2 ^ 53-1).,", + "!doc": + " Number.MAX_SAFE_INTEGER常量表示JavaScript中的最大安全整数(2 ^ 53-1).,", }, - "MIN_SAFE_INTEGER": { + MIN_SAFE_INTEGER: { "!type": "number", - "!doc": " Number.MIN_SAFE_INTEGER常量表示JavaScript(-(2 ^ 53-1))中的最小安全整数.,", + "!doc": + " Number.MIN_SAFE_INTEGER常量表示JavaScript(-(2 ^ 53-1))中的最小安全整数.,", }, - "isFinite": { + isFinite: { "!type": "fn(testValue: ?) -> bool", "!doc": " Number.isFinite()方法确定传递的值是否为有限值.,", }, - "isInteger": { + isInteger: { "!type": "fn(testValue: ?) -> bool", "!doc": " Number.isInteger()方法确定传递的值是否为整数.,", }, - "isNaN": { + isNaN: { "!type": "fn(testValue: ?) -> bool", - "!doc": " Number.isNaN()方法确定传递的值是否为NaN.原始全局isNaN()的更可靠的版本.,", + "!doc": + " Number.isNaN()方法确定传递的值是否为NaN.原始全局isNaN()的更可靠的版本.,", }, - "isSafeInteger": { + isSafeInteger: { "!type": "fn(testValue: ?) -> bool", - "!doc": " Number.isSafeInteger()方法确定所提供的值是否是一个安全整数的数字.安全整数是该数字的整数.", + "!doc": + " Number.isSafeInteger()方法确定所提供的值是否是一个安全整数的数字.安全整数是该数字的整数.", }, - "parseFloat": { + parseFloat: { "!type": "fn(string: string) -> number", "!doc": " Number.parseFloat()方法解析字符串参数并返回浮点数.,", }, - "parseInt": { + parseInt: { "!type": "fn(string: string, radix?: number) -> number", - "!doc": " Number.parseInt()方法解析字符串参数并返回指定基数或基数的整数.,", + "!doc": + " Number.parseInt()方法解析字符串参数并返回指定基数或基数的整数.,", }, }, - "Boolean": { + Boolean: { "!type": "fn(value: ?) -> bool", - "prototype": { - "!stdProto": "Boolean" + prototype: { + "!stdProto": "Boolean", }, }, - "abstract": "?", - "arguments": "?", - "boolean": "?", - "break": "?", - "byte": "?", - "case": "?", - "catch": "?", - "char": "?", - "const": "?", - "continue": "?", - "debugger": "?", - "default": "?", - "delete": "?", - "do": "?", - "double": "?", - "else": "?", - "eval": "?", - "false": "bool", - "final": "?", - "finally": "?", - "float": "?", - "for": "?", - "function": "?", - "goto": "?", - "if": "?", - "implements": "?", - "in": "?", - "instanceof": "?", - "int": "?", - "interface": "?", - "long": "?", - "native": "?", - "new": "?", - "null": "?", - "package": "?", - "private": "?", - "protected": "?", - "public": "?", - "return": "?", - "short": "?", - "static": "?", - "switch": "?", - "synchronized": "?", - "this": "?", - "throw": "?", - "throws": "?", - "transient": "?", - "true": "bool", - "try": "?", - "typeof": "?", - "var": "?", - "void": "?", - "volatile": "?", - "while": "?", - "with": "?", - "yield": "?", - "RegExp": { + abstract: "?", + arguments: "?", + boolean: "?", + break: "?", + byte: "?", + case: "?", + catch: "?", + char: "?", + const: "?", + continue: "?", + debugger: "?", + default: "?", + delete: "?", + do: "?", + double: "?", + else: "?", + eval: "?", + false: "bool", + final: "?", + finally: "?", + float: "?", + for: "?", + function: "?", + goto: "?", + if: "?", + implements: "?", + in: "?", + instanceof: "?", + int: "?", + interface: "?", + long: "?", + native: "?", + new: "?", + null: "?", + package: "?", + private: "?", + protected: "?", + public: "?", + return: "?", + short: "?", + static: "?", + switch: "?", + synchronized: "?", + this: "?", + throw: "?", + throws: "?", + transient: "?", + true: "bool", + try: "?", + typeof: "?", + var: "?", + void: "?", + volatile: "?", + while: "?", + with: "?", + yield: "?", + RegExp: { "!type": "fn(source: string, flags?: string)", - "prototype": { + prototype: { "!stdProto": "RegExp", - "exec": { + exec: { "!type": "fn(input: string) -> [string]", "!doc": "搜索指定字符串中的匹配项.返回结果数组,或者为null.", }, - "test": { + test: { "!type": "fn(input: string) -> bool", "!doc": "执行正则表达式和指定字符串之间的匹配搜索.返回true或false.", - } + }, }, "!doc": "创建正则表达式对象以将文本与模式匹配.", }, - "parseInt": { + parseInt: { "!type": "fn(string: string, radix?: number) -> number", - "!doc": "解析字符串参数并返回指定基数或基数的整数." + "!doc": "解析字符串参数并返回指定基数或基数的整数.", }, - "parseFloat": { + parseFloat: { "!type": "fn(string: string) -> number", - "!doc": "解析字符串参数并返回浮点数." + "!doc": "解析字符串参数并返回浮点数.", }, - "isNaN": { + isNaN: { "!type": "fn(value: number) -> bool", - "!doc": "确定值是否为NaN.请注意,此函数已损坏.您可能对ECMAScript 6 Number.isNaN感兴趣.", + "!doc": + "确定值是否为NaN.请注意,此函数已损坏.您可能对ECMAScript 6 Number.isNaN感兴趣.", }, - "isFinite": { + isFinite: { "!type": "fn(value: number) -> bool", - "!doc": "确定传递的值是否为有限数字." + "!doc": "确定传递的值是否为有限数字.", }, - "eval": { + eval: { "!type": "fn(code: string) -> ?", - "!doc": "评估以字符串形式表示的JavaScript代码." + "!doc": "评估以字符串形式表示的JavaScript代码.", }, - "encodeURI": { + encodeURI: { "!type": "fn(uri: string) -> string", - "!doc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例来编码统一资源标识符(URI)(对于字符而言将仅是四个转义序列由两个\"代理\"字符组成).", + "!doc": + '通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例来编码统一资源标识符(URI)(对于字符而言将仅是四个转义序列由两个"代理"字符组成).', }, - "encodeURIComponent": { + encodeURIComponent: { "!type": "fn(uri: string) -> string", - "!doc": "通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例来编码统一资源标识符(URI)组件(对于由两个\"代理\"字符组成的字符).", + "!doc": + '通过用表示字符的UTF-8编码的一个,两个,三个或四个转义序列替换某些字符的每个实例来编码统一资源标识符(URI)组件(对于由两个"代理"字符组成的字符).', }, - "decodeURI": { + decodeURI: { "!type": "fn(uri: string) -> string", "!doc": "解码以前由encodeURI或类似例程创建的统一资源标识符(URI).", }, - "decodeURIComponent": { + decodeURIComponent: { "!type": "fn(uri: string) -> string", - "!doc": "解码以前由encodeURIComponent或类似例程创建的统一资源标识符(URI)组件.", + "!doc": + "解码以前由encodeURIComponent或类似例程创建的统一资源标识符(URI)组件.", }, - "Math": { - "E": { + Math: { + E: { "!type": "number", - "!doc": "自然对数的底数,e约为2.718." + "!doc": "自然对数的底数,e约为2.718.", }, - "LN2": { + LN2: { "!type": "number", - "!doc": " 2的自然对数,大约为0.693." + "!doc": " 2的自然对数,大约为0.693.", }, - "LN10": { + LN10: { "!type": "number", - "!doc": " 10的自然对数,大约为2.302." + "!doc": " 10的自然对数,大约为2.302.", }, - "LOG2E": { + LOG2E: { "!type": "number", "!doc": " E的以2为底的对数(大约1.442).", }, - "LOG10E": { + LOG10E: { "!type": "number", - "!doc": " E的以10为底的对数(约0.434)." + "!doc": " E的以10为底的对数(约0.434).", }, - "SQRT1_2": { + SQRT1_2: { "!type": "number", - "!doc": " 1/2的平方根;等效于2的平方根上的1,大约为0.707." + "!doc": " 1/2的平方根;等效于2的平方根上的1,大约为0.707.", }, - "SQRT2": { + SQRT2: { "!type": "number", - "!doc": " 2的平方根,大约为1.414." + "!doc": " 2的平方根,大约为1.414.", }, - "PI": { + PI: { "!type": "number", - "!doc": "圆的周长与其直径之比,大约为3.14159." + "!doc": "圆的周长与其直径之比,大约为3.14159.", }, - "abs": { + abs: { "!type": "fn(number) -> number", - "!doc": "返回数字的绝对值." + "!doc": "返回数字的绝对值.", }, - "cos": { + cos: { "!type": "fn(number) -> number", - "!doc": "返回数字的余弦." + "!doc": "返回数字的余弦.", }, - "sin": { + sin: { "!type": "fn(number) -> number", - "!doc": "返回数字的正弦." + "!doc": "返回数字的正弦.", }, - "tan": { + tan: { "!type": "fn(number) -> number", - "!doc": "返回数字的正切值." + "!doc": "返回数字的正切值.", }, - "acos": { + acos: { "!type": "fn(number) -> number", - "!doc": "返回数字的反余弦(以弧度为单位)." + "!doc": "返回数字的反余弦(以弧度为单位).", }, - "asin": { + asin: { "!type": "fn(number) -> number", - "!doc": "返回数字的反正弦(以弧度为单位)." + "!doc": "返回数字的反正弦(以弧度为单位).", }, - "atan": { + atan: { "!type": "fn(number) -> number", - "!doc": "返回数字的反正切(以弧度为单位)." + "!doc": "返回数字的反正切(以弧度为单位).", }, - "atan2": { + atan2: { "!type": "fn(y: number, x: number) -> number", - "!doc": "返回其参数商的反正切值." + "!doc": "返回其参数商的反正切值.", }, - "ceil": { + ceil: { "!type": "fn(number) -> number", - "!doc": "返回大于或等于数字的最小整数." + "!doc": "返回大于或等于数字的最小整数.", }, - "floor": { + floor: { "!type": "fn(number) -> number", - "!doc": "返回小于或等于数字的最大整数." + "!doc": "返回小于或等于数字的最大整数.", }, - "round": { + round: { "!type": "fn(number) -> number", - "!doc": "返回四舍五入到最接近整数的数字的值." + "!doc": "返回四舍五入到最接近整数的数字的值.", }, - "exp": { + exp: { "!type": "fn(number) -> number", - "!doc": "返回E ^ x,其中x是自变量,E是欧拉常数,自然对数的底." + "!doc": "返回E ^ x,其中x是自变量,E是欧拉常数,自然对数的底.", }, - "log": { + log: { "!type": "fn(number) -> number", "!doc": "返回数字的自然对数(以E为底).", }, - "sqrt": { + sqrt: { "!type": "fn(number) -> number", - "!doc": "返回数字的平方根." + "!doc": "返回数字的平方根.", }, - "pow": { + pow: { "!type": "fn(number, number) -> number", - "!doc": "将基数返回指数幂,即baseexponent." + "!doc": "将基数返回指数幂,即baseexponent.", }, - "max": { + max: { "!type": "fn(number, number) -> number", - "!doc": "返回零个或多个数字中的最大值." + "!doc": "返回零个或多个数字中的最大值.", }, - "min": { + min: { "!type": "fn(number, number) -> number", - "!doc": "返回零个或多个数字中的最小值." + "!doc": "返回零个或多个数字中的最小值.", }, - "random": { + random: { "!type": "fn() -> number", - "!doc": "返回一个浮点伪随机数,范围为[0,1),即从0(包括)到不包括1(排除),然后您可以缩放到所需的值范围." + "!doc": + "返回一个浮点伪随机数,范围为[0,1),即从0(包括)到不包括1(排除),然后您可以缩放到所需的值范围.", }, - "log10": { + log10: { "!type": "fn(x: number) -> number", "!doc": " Math.log10()函数返回数字的以10为底的对数.", }, - "log2": { + log2: { "!type": "fn(x: number) -> number", "!doc": " Math.log2()函数返回数字的以2为底的对数.", }, - "sign": { + sign: { "!type": "fn(x: number) -> number", "!doc": " Math.sign()函数返回数字的符号,指示数字是正数,负数还是零.,", }, - "trunc": { + trunc: { "!type": "fn(x: number) -> number", - "!doc": " Math.trunc()函数通过删除任何小数位来返回数字的整数部分.它不舍入任何数字.该函数可以用floor()和ceil()函数表示: ,", + "!doc": + " Math.trunc()函数通过删除任何小数位来返回数字的整数部分.它不舍入任何数字.该函数可以用floor()和ceil()函数表示: ,", }, "!doc": "一个内置对象,具有用于数学常数和函数的属性和方法.", }, - "JSON": { - "parse": { - "!type": "fn(json: string, reviver?: fn(key: string, value: ?) -> ?) -> ?", + JSON: { + parse: { + "!type": + "fn(json: string, reviver?: fn(key: string, value: ?) -> ?) -> ?", "!doc": "将字符串解析为JSON,可以选择转换解析产生的值.", }, - "stringify": { - "!type": "fn(value: ?, replacer?: fn(key: string, value: ?) -> ?, space?: string|number) -> string", - "!doc": "将值转换为JSON,如果指定了replacer函数,则可以选择替换值,如果指定了replacer数组,则可以选择仅包括指定的属性.", + stringify: { + "!type": + "fn(value: ?, replacer?: fn(key: string, value: ?) -> ?, space?: string|number) -> string", + "!doc": + "将值转换为JSON,如果指定了replacer函数,则可以选择替换值,如果指定了replacer数组,则可以选择仅包括指定的属性.", }, - "!doc": " JSON(JavaScript对象表示法)是一种数据交换格式.尽管它不是严格的子集,但它非常类似于JavaScript语法的子集.(有关详细信息,请参见JavaScript参考中的JSON.)在编写任何类型的基于JavaScript的应用程序(包括网站和浏览器扩展程序)时非常有用.例如,您可以将JSON格式的用户信息存储在cookie中,或者可以将扩展名首选项以JSON形式存储在字符串值的浏览器首选项中." - } + "!doc": + " JSON(JavaScript对象表示法)是一种数据交换格式.尽管它不是严格的子集,但它非常类似于JavaScript语法的子集.(有关详细信息,请参见JavaScript参考中的JSON.)在编写任何类型的基于JavaScript的应用程序(包括网站和浏览器扩展程序)时非常有用.例如,您可以将JSON格式的用户信息存储在cookie中,或者可以将扩展名首选项以JSON形式存储在字符串值的浏览器首选项中.", + }, }, { "!name": "core", "!define": { - "image": { + image: { "!doc": "图片信息", - "width": "number", - "height": "number", - "src": "string" + width: "number", + height: "number", + src: "string", }, - "audio": { + audio: { "!doc": "音乐音效信息", - "currentTime": "number", - "play": "fn()", - "pause": "fn()", - "paused": "bool", - "duration": "number", - "volume": "number", + currentTime: "number", + play: "fn()", + pause: "fn()", + paused: "bool", + duration: "number", + volume: "number", }, - "flag": { + flag: { "!doc": "当前变量", - "hard": { + hard: { "!type": "number", - "!doc": "当前难度编号" + "!doc": "当前难度编号", }, - "hatred": { + hatred: { "!type": "number", - "!doc": "当前仇恨值" + "!doc": "当前仇恨值", }, - "poison": { + poison: { "!type": "bool", - "!doc": "是否处于中毒状态" + "!doc": "是否处于中毒状态", }, - "weak": { + weak: { "!type": "number", - "!doc": "是否处于衰弱状态" + "!doc": "是否处于衰弱状态", }, - "curse": { + curse: { "!type": "number", - "!doc": "是否处于诅咒状态" + "!doc": "是否处于诅咒状态", }, - "no_zone": { + no_zone: { "!type": "bool", - "!doc": "无视领域伤害" + "!doc": "无视领域伤害", }, - "no_repulse": { + no_repulse: { "!type": "bool", - "!doc": "无视阻击伤害" + "!doc": "无视阻击伤害", }, - "no_lasel": { + no_lasel: { "!type": "bool", - "!doc": "无视激光伤害" + "!doc": "无视激光伤害", }, - "no_ambush": { + no_ambush: { "!type": "bool", - "!doc": "无视捕捉" + "!doc": "无视捕捉", }, - "__bgm__": { + __bgm__: { "!type": "string", - "!doc": "背景音乐" + "!doc": "背景音乐", }, - "__weather__": { - "!doc": "天气" + __weather__: { + "!doc": "天气", }, - "__color__": { - "!doc": "色调" + __color__: { + "!doc": "色调", }, - "__volume__": { + __volume__: { "!type": "number", - "!doc": "音量" + "!doc": "音量", }, - "skill": { + skill: { "!type": "number", - "!doc": "当前开启的技能编号" + "!doc": "当前开启的技能编号", }, - "skillName": { + skillName: { "!type": "string", - "!doc": "当前开启的技能名" + "!doc": "当前开启的技能名", }, - "input": { + input: { "!type": "string|number", - "!doc": "等待用户输入后的存放值" + "!doc": "等待用户输入后的存放值", }, - "type": { + type: { "!type": "number", - "!doc": "等待用户操作后获得的操作类型" + "!doc": "等待用户操作后获得的操作类型", }, - "keycode": { + keycode: { "!type": "number", - "!doc": "等待用户操作后用户按键的键值" + "!doc": "等待用户操作后用户按键的键值", }, - "x": { + x: { "!type": "number", - "!doc": "等待用户操作后用户点击的网格横坐标" + "!doc": "等待用户操作后用户点击的网格横坐标", }, - "y": { + y: { "!type": "number", - "!doc": "等待用户操作后用户点击的网格纵坐标" + "!doc": "等待用户操作后用户点击的网格纵坐标", }, - "px": { + px: { "!type": "number", - "!doc": "等待用户操作后用户点击的像素横坐标" + "!doc": "等待用户操作后用户点击的像素横坐标", }, - "py": { + py: { "!type": "number", - "!doc": "等待用户操作后用户点击的像素纵坐标" + "!doc": "等待用户操作后用户点击的像素纵坐标", }, - "__visited__": { - "!doc": "当前访问过的楼层" + __visited__: { + "!doc": "当前访问过的楼层", }, - "__leaveLoc__": { - "!doc": "每个楼层的离开位置,用于楼传平面塔模式" + __leaveLoc__: { + "!doc": "每个楼层的离开位置,用于楼传平面塔模式", }, - "cannotMoveDirectly": { + cannotMoveDirectly: { "!type": "bool", - "!doc": "当前是否全局不可瞬移" + "!doc": "当前是否全局不可瞬移", }, }, - "hero": { + hero: { "!doc": "勇士当前属性", - "image": { + image: { "!type": "string", - "!doc": "行走图" + "!doc": "行走图", }, - "animate": { + animate: { "!type": "bool", - "!doc": "是否开启帧动画" + "!doc": "是否开启帧动画", }, - "name": { + name: { "!type": "string", - "!doc": "勇士名" + "!doc": "勇士名", }, - "lv": { + lv: { "!type": "number", - "!doc": "勇士等级" + "!doc": "勇士等级", }, - "hpmax": { + hpmax: { "!type": "number", - "!doc": "勇士生命上限" + "!doc": "勇士生命上限", }, - "hp": { + hp: { "!type": "number", - "!doc": "勇士当前生命值" + "!doc": "勇士当前生命值", }, - "atk": { + atk: { "!type": "number", - "!doc": "勇士当前攻击力" + "!doc": "勇士当前攻击力", }, - "def": { + def: { "!type": "number", - "!doc": "勇士当前防御力" + "!doc": "勇士当前防御力", }, - "manamax": { + manamax: { "!type": "number", - "!doc": "勇士当前魔力上限,负数无效" + "!doc": "勇士当前魔力上限,负数无效", }, - "mana": { + mana: { "!type": "number", - "!doc": "勇士当前魔力值" + "!doc": "勇士当前魔力值", }, - "mdef": { + mdef: { "!type": "number", - "!doc": "勇士当前护盾值" + "!doc": "勇士当前护盾值", }, - "money": { + money: { "!type": "number", - "!doc": "勇士当前金币" + "!doc": "勇士当前金币", }, - "exp": { + exp: { "!type": "number", - "!doc": "勇士当前经验" + "!doc": "勇士当前经验", }, - "equipment": { + equipment: { "!type": "[string]", - "!doc": "勇士当前装备" + "!doc": "勇士当前装备", }, - "items": { + items: { "!doc": "勇士当前道具", - "constants": { - "!doc": "永久道具" + constants: { + "!doc": "永久道具", }, - "tools": { + tools: { "!doc": "消耗道具", - "yellowKey": { + yellowKey: { "!type": "number", - "!doc": "黄钥匙个数" + "!doc": "黄钥匙个数", }, - "blueKey": { + blueKey: { "!type": "number", - "!doc": "蓝钥匙个数" + "!doc": "蓝钥匙个数", }, - "redKey": { + redKey: { "!type": "number", - "!doc": "红钥匙个数" + "!doc": "红钥匙个数", }, - "greenKey": { + greenKey: { "!type": "number", - "!doc": "绿钥匙个数" + "!doc": "绿钥匙个数", }, - "steelKey": { + steelKey: { "!type": "number", - "!doc": "铁门钥匙个数" + "!doc": "铁门钥匙个数", }, }, - "equips": { - "!doc": "在背包中未装备上的装备" + equips: { + "!doc": "在背包中未装备上的装备", }, }, - "loc": { + loc: { "!doc": "勇士当前坐标和朝向", - "x": "number", - "y": "number", - "direction": { + x: "number", + y: "number", + direction: { "!doc": "朝向,只能为 up,down,left,right 之一", - "!type": "string" + "!type": "string", }, }, - "flags": { + flags: { "!type": "flag", - "!doc": "当前游戏中用到的变量" + "!doc": "当前游戏中用到的变量", }, - "followers": { + followers: { "!type": "[?]", - "!doc": "跟随者信息" + "!doc": "跟随者信息", }, - "steps": { + steps: { "!type": "number", - "!doc": "当前步数" - } + "!doc": "当前步数", + }, }, - "block": { + block: { "!doc": "地图图块信息", - "x": { + x: { "!type": "number", - "!doc": "图块的x坐标" + "!doc": "图块的x坐标", }, - "y": { + y: { "!type": "number", - "!doc": "图块的y坐标" + "!doc": "图块的y坐标", }, - "id": { + id: { "!type": "number", - "!doc": "图块的数字" + "!doc": "图块的数字", }, - "event": { + event: { "!doc": "图块上的事件信息", - "id": { + id: { "!type": "string", - "!doc": "图块的ID" + "!doc": "图块的ID", }, - "cls": { + cls: { "!type": "string", - "!doc": "图块的类别,一般为所在图片名去掉后缀" + "!doc": "图块的类别,一般为所在图片名去掉后缀", }, - "disabled": { + disabled: { "!type": "bool", - "!doc": "启用状态" - } - } + "!doc": "启用状态", + }, + }, }, - "blockInfo": { + blockInfo: { "!doc": "图块的更多信息", - "animate": { + animate: { "!type": "number", - "!doc": "动画帧数" + "!doc": "动画帧数", }, - "cls": { + cls: { "!type": "string", - "!doc": "图块类别" + "!doc": "图块类别", }, - "faceIds": { + faceIds: { "!doc": "行走图朝向", - "up": "string", - "down": "string", - "left": "string", - "right": "string" + up: "string", + down: "string", + left: "string", + right: "string", }, - "height": { + height: { "!type": "number", - "!doc": "图块高度" + "!doc": "图块高度", }, - "id": { + id: { "!type": "string", - "!doc": "图块ID" + "!doc": "图块ID", }, - "image": { + image: { "!type": "image", - "!doc": "图块所在的图片" + "!doc": "图块所在的图片", }, - "name": { + name: { "!type": "string", - "!doc": "图块名称" + "!doc": "图块名称", }, - "number": { + number: { "!type": "number", - "!doc": "图块使用的数字" + "!doc": "图块使用的数字", }, - "posX": { + posX: { "!type": "number", - "!doc": "图块在图片上的横坐标" + "!doc": "图块在图片上的横坐标", }, - "posY": { + posY: { "!type": "number", - "!doc": "图块在图片上的纵坐标" + "!doc": "图块在图片上的纵坐标", }, }, - "enemy": { + enemy: { "!doc": "怪物信息", - "id": { + id: { "!type": "string", - "!doc": "怪物ID" + "!doc": "怪物ID", }, - "name": { + name: { "!type": "string", - "!doc": "怪物名称" + "!doc": "怪物名称", }, - "displayIdInBook": { + displayIdInBook: { "!type": "string", - "!doc": "在怪物手册映射ID" + "!doc": "在怪物手册映射ID", }, - "hp": { + hp: { "!type": "number", - "!doc": "怪物生命值" + "!doc": "怪物生命值", }, - "atk": { + atk: { "!type": "number", - "!doc": "怪物攻击" + "!doc": "怪物攻击", }, - "def": { + def: { "!type": "number", - "!doc": "怪物防御" + "!doc": "怪物防御", }, - "money": { + money: { "!type": "number", - "!doc": "怪物金币" + "!doc": "怪物金币", }, - "exp": { + exp: { "!type": "number", - "!doc": "怪物经验" + "!doc": "怪物经验", }, - "special": { + special: { "!type": "[number]", - "!doc": "怪物特殊属性" + "!doc": "怪物特殊属性", }, - "point": { + point: { "!type": "number", - "!doc": "怪物加点" + "!doc": "怪物加点", }, - "value": { + value: { "!type": "number", - "!doc": "怪物特殊属性值:阻激夹域伤害值;吸血比例;光环增加生命比例" + "!doc": "怪物特殊属性值:阻激夹域伤害值;吸血比例;光环增加生命比例", }, - "zoneSquare": { + zoneSquare: { "!type": "bool", - "!doc": "领域怪是否九宫格伤害;区域光环是否九宫格范围" + "!doc": "领域怪是否九宫格伤害;区域光环是否九宫格范围", }, - "range": { + range: { "!type": "number", - "!doc": "领域伤害的范围;区域光环范围" + "!doc": "领域伤害的范围;区域光环范围", }, - "notBomb": { + notBomb: { "!type": "bool", - "!doc": "怪物不可炸" + "!doc": "怪物不可炸", }, - "n": { + n: { "!type": "number", - "!doc": "多连击的连击数;净化比例" + "!doc": "多连击的连击数;净化比例", }, - "add": { + add: { "!type": "bool", - "!doc": "吸血是否加到自身;光环是否叠加" + "!doc": "吸血是否加到自身;光环是否叠加", }, - "atkValue": { + atkValue: { "!type": "number", - "!doc": "反击比例;退化扣除攻击;光环增加攻击;" + "!doc": "反击比例;退化扣除攻击;光环增加攻击;", }, - "defValue": { + defValue: { "!type": "number", - "!doc": "破甲比例;退化扣除防御;光环增加防御" + "!doc": "破甲比例;退化扣除防御;光环增加防御", }, - "damage": { + damage: { "!type": "number", - "!doc": "固伤值" + "!doc": "固伤值", }, }, - "item": { + item: { "!doc": "道具信息", - "id": { + id: { "!type": "string", - "!doc": "道具ID" + "!doc": "道具ID", }, - "cls": { + cls: { "!type": "string", - "!doc": "道具类型" + "!doc": "道具类型", }, - "name": { + name: { "!type": "string", - "!doc": "道具名称" + "!doc": "道具名称", }, - "text": { + text: { "!type": "string", - "!doc": "道具描述" + "!doc": "道具描述", }, - "hideInToolbox": { + hideInToolbox: { "!type": "bool", - "!doc": "不显示在道具栏" + "!doc": "不显示在道具栏", }, - "equip": { + equip: { "!doc": "装备属性", - "type": { + type: { "!type": "number|string", - "!doc": "装备类型" + "!doc": "装备类型", }, - "animate": { + animate: { "!type": "string", - "!doc": "装备动画" + "!doc": "装备动画", }, - "value": { - "!doc": "数值加成" + value: { + "!doc": "数值加成", + }, + percentage: { + "!doc": "比例加成", }, - "percentage": { - "!doc": "比例加成" - } }, - "hideInReplay": { + hideInReplay: { "!type": "bool", - "!doc": "回放不绘制道具栏" + "!doc": "回放不绘制道具栏", }, }, - "floor": { + floor: { "!doc": "楼层信息", - "floorId": { + floorId: { "!type": "string", - "!doc": "楼层ID" + "!doc": "楼层ID", }, - "title": { + title: { "!type": "string", - "!doc": "楼层中文名" + "!doc": "楼层中文名", }, - "name": { + name: { "!type": "string", - "!doc": "状态栏显示值" + "!doc": "状态栏显示值", }, - "width": { + width: { "!type": "number", - "!doc": "地图宽" + "!doc": "地图宽", }, - "height": { + height: { "!type": "number", - "!doc": "地图高" + "!doc": "地图高", }, - "canFlyTo": { + canFlyTo: { "!type": "bool", - "!doc": "该楼是否可以楼传飞到" + "!doc": "该楼是否可以楼传飞到", }, - "canFlyFrom": { + canFlyFrom: { "!type": "bool", - "!doc": "该楼是否可以楼传飞出" + "!doc": "该楼是否可以楼传飞出", }, - "canUseQuickShop": { + canUseQuickShop: { "!type": "bool", - "!doc": "该楼是否可快捷商店" + "!doc": "该楼是否可快捷商店", }, - "cannotViewMap": { + cannotViewMap: { "!type": "bool", - "!doc": "该层是否不允许被浏览地图看到,也不统计" + "!doc": "该层是否不允许被浏览地图看到,也不统计", }, - "cannotMoveDirectly": { + cannotMoveDirectly: { "!type": "bool", - "!doc": "该层是否不允许瞬间移动" + "!doc": "该层是否不允许瞬间移动", }, - "upFloor": { + upFloor: { "!type": "[number]", - "!doc": "上楼点" + "!doc": "上楼点", }, - "downFloor": { + downFloor: { "!type": "[number]", - "!doc": "下楼点" + "!doc": "下楼点", }, - "flyPoint": { + flyPoint: { "!type": "[number]", - "!doc": "楼传落点" + "!doc": "楼传落点", }, - "color": { - "!doc": "楼层色调" + color: { + "!doc": "楼层色调", }, - "weather": { - "!doc": "楼层天气" + weather: { + "!doc": "楼层天气", }, - "bgm": { + bgm: { "!type": "string", - "!doc": "楼层背景音乐" + "!doc": "楼层背景音乐", }, - "ratio": { + ratio: { "!type": "number", - "!doc": "宝石/血瓶效果" + "!doc": "宝石/血瓶效果", }, - "map": { + map: { "!type": "[[number]]", - "!doc": "地图数据" + "!doc": "地图数据", }, - "blocks": { + blocks: { "!type": "[block]", - "!doc": "本层图块信息" - } + "!doc": "本层图块信息", + }, }, - "animate": { + animate: { "!doc": "动画信息", - "se": { + se: { "!type": "string", - "!doc": "动画音效" - } - } + "!doc": "动画音效", + }, + }, }, - "core": { + core: { "!doc": "核心游戏控制", - "__SIZE__": { + __SIZE__: { "!type": "number", - "!doc": "窗口宽度,为13或15" + "!doc": "窗口宽度,为13或15", }, - "__PIXELS__": { + __PIXELS__: { "!type": "number", - "!doc": "窗口像素宽度,为416或480" + "!doc": "窗口像素宽度,为416或480", }, - "__HALF_SIZE__": { + __HALF_SIZE__: { "!type": "number", - "!doc": "窗口宽度的一半,为6或7" + "!doc": "窗口宽度的一半,为6或7", }, - "floorIds": { + floorIds: { "!type": "[string]", - "!doc": "全部楼层ID列表" + "!doc": "全部楼层ID列表", }, - "floors": { - "!doc": "全部楼层信息" + floors: { + "!doc": "全部楼层信息", }, - "floorPartitions": { + floorPartitions: { "!type": "[[string]]", - "!doc": "楼层分区信息" + "!doc": "楼层分区信息", }, - "material": { + material: { "!doc": "游戏所用到的资源", - "animates": { - "!doc": "注册的动画" + animates: { + "!doc": "注册的动画", }, - "images": { - "!doc": "注册的图片" + images: { + "!doc": "注册的图片", }, - "bgms": { - "!doc": "注册的背景音乐" + bgms: { + "!doc": "注册的背景音乐", }, - "sounds": { - "!doc": "注册的音效" + sounds: { + "!doc": "注册的音效", }, - "enemys": { + enemys: { "!doc": "怪物定义", }, - "items": { - "!doc": "道具定义" - } + items: { + "!doc": "道具定义", + }, }, - "timeout": { - "!doc": "当前异步事件句柄" + timeout: { + "!doc": "当前异步事件句柄", }, - "interval": { - "!doc": "当前异步事件延时" + interval: { + "!doc": "当前异步事件延时", }, - "animateFrame": { - "!doc": "当前各个帧动画" + animateFrame: { + "!doc": "当前各个帧动画", }, - "musicStatus": { + musicStatus: { "!doc": "音乐音效状态", - "bgmStatus": { + bgmStatus: { "!type": "bool", - "!doc": "是否播放BGM" + "!doc": "是否播放BGM", }, - "soundStatus": { + soundStatus: { "!type": "bool", - "!doc": "是否播放SE" + "!doc": "是否播放SE", }, - "playingBgm": { + playingBgm: { "!type": "string", - "!doc": "正在播放的bgm" + "!doc": "正在播放的bgm", }, - "lastBgm": { + lastBgm: { "!type": "string", - "!doc": "上次播放的bgm" + "!doc": "上次播放的bgm", }, - "playingSounds": { - "!doc": "正在播放的SE" + playingSounds: { + "!doc": "正在播放的SE", }, - "volume": { + volume: { "!type": "number", - "!doc": "当前bgm音量" - } + "!doc": "当前bgm音量", + }, }, - "platform": { + platform: { "!doc": "平台信息", - "isPC": "bool", - "isAndroid": "bool", - "isIOS": "bool", + isPC: "bool", + isAndroid: "bool", + isIOS: "bool", }, - "domStyle": { + domStyle: { "!doc": "界面样式", - "scale": { + scale: { "!type": "number", "!doc": "当前界面放缩比例", }, - "ratio": { + ratio: { "!type": "number", - "!doc": "高清UI放缩比例" + "!doc": "高清UI放缩比例", }, - "hdCanvas": { + hdCanvas: { "!type": "[string]", - "!doc": "高清UI的系统画布" + "!doc": "高清UI的系统画布", }, - "availableScale": { + availableScale: { "!type": "[number]", - "!doc": "当前界面支持的放缩比例" + "!doc": "当前界面支持的放缩比例", }, - "isVertical": { + isVertical: { "!type": "bool", - "!doc": "当前是否是竖屏" + "!doc": "当前是否是竖屏", }, - "showStatusBar": { + showStatusBar: { "!type": "bool", - "!doc": "当前是否显示状态栏" + "!doc": "当前是否显示状态栏", }, - "toolbarBtn": { + toolbarBtn: { "!type": "bool", - "!doc": "当前工具栏是否是1-8的按钮" + "!doc": "当前工具栏是否是1-8的按钮", }, }, - "bigmap": { + bigmap: { "!doc": "大地图信息", - "canvas": { + canvas: { "!type": "[string]", - "!doc": "大地图的画布" + "!doc": "大地图的画布", }, - "width": { + width: { "!type": "number", - "!doc": "大地图高度" + "!doc": "大地图高度", }, - "height": { + height: { "!type": "number", - "!doc": "大地图宽度" + "!doc": "大地图宽度", }, - "offsetX": { + offsetX: { "!type": "number", - "!doc": "大地图视角横向偏移量" + "!doc": "大地图视角横向偏移量", }, - "offsetY": { + offsetY: { "!type": "number", - "!doc": "大地图视角纵向偏移量" + "!doc": "大地图视角纵向偏移量", }, - "posX": { + posX: { "!type": "number", - "!doc": "大地图视角横向基准格" + "!doc": "大地图视角横向基准格", }, - "posY": { + posY: { "!type": "number", - "!doc": "大地图视角纵向基准格" + "!doc": "大地图视角纵向基准格", }, - "v2": { + v2: { "!type": "bool", - "!doc": "是否是新版大地图绘制方式" + "!doc": "是否是新版大地图绘制方式", }, - "threshold": { + threshold: { "!type": "number", - "!doc": "新版大地图绘制方式的分界线" + "!doc": "新版大地图绘制方式的分界线", }, - "extend": { + extend: { "!type": "number", - "!doc": "新版大地图模式下向每一侧额外计算的数量" + "!doc": "新版大地图模式下向每一侧额外计算的数量", }, - "scale": { + scale: { "!type": "number", - "!doc": "缩略图的比例放缩" + "!doc": "缩略图的比例放缩", }, - "tempCanvas": { + tempCanvas: { "!type": "CanvasRenderingContext2D", - "!doc": "临时画布" - } + "!doc": "临时画布", + }, }, - "saves": { - "!doc": "当前存档信息" + saves: { + "!doc": "当前存档信息", }, - "dymCanvas": { - "!doc": "各个自定义画布" + dymCanvas: { + "!doc": "各个自定义画布", }, - "statusBar": { - "!doc": "状态栏信息" + statusBar: { + "!doc": "状态栏信息", }, - "canvas": { - "!doc": "系统画布" + canvas: { + "!doc": "系统画布", }, - "flags": { - "!doc": "系统开关" + flags: { + "!doc": "系统开关", }, - "values": { - "!doc": "全局数值,如毒衰效果" + values: { + "!doc": "全局数值,如毒衰效果", }, - "firstData": { - "!doc": "初始属性,如出生点" + firstData: { + "!doc": "初始属性,如出生点", }, - "status": { + status: { "!doc": "状态信息", - "hero": { + hero: { "!type": "hero", - "!doc": "勇士信息" + "!doc": "勇士信息", }, - "automaticRoute": { - "!doc": "自动寻路信息" + automaticRoute: { + "!doc": "自动寻路信息", }, - "bgmaps": { - "!doc": "各地图背景层" + bgmaps: { + "!doc": "各地图背景层", }, - "fgmaps": { - "!doc": "各地图前景层" + fgmaps: { + "!doc": "各地图前景层", }, - "mapBlockObjs": { - "!doc": "以<位置,block>存放的各地图图块信息" + mapBlockObjs: { + "!doc": "以<位置,block>存放的各地图图块信息", }, - "boxAnimateObjs": { - "!doc": "(手册和剧情文本的)帧动画对象" + boxAnimateObjs: { + "!doc": "(手册和剧情文本的)帧动画对象", }, - "checkBlock": { + checkBlock: { "!doc": "阻激夹域捕捉信息", - "damage": { - "!doc": "每个点的伤害信息" + damage: { + "!doc": "每个点的伤害信息", }, - "type": { - "!doc": "每个点的伤害类型" + type: { + "!doc": "每个点的伤害类型", }, - "repluse": { - "!doc": "每个点的阻击信息" + repluse: { + "!doc": "每个点的阻击信息", }, - "ambush": { - "!doc": "每个点的捕捉信息" + ambush: { + "!doc": "每个点的捕捉信息", }, - "needCache": { + needCache: { "!type": "bool", - "!doc": "该楼层是否需要计算缓存" + "!doc": "该楼层是否需要计算缓存", }, - "cache": { - "!doc": "每个点的光环缓存" + cache: { + "!doc": "每个点的光环缓存", }, }, - "damage": { + damage: { "!doc": "每个点的显伤信息", }, - "ctrlDown": { + ctrlDown: { "!type": "bool", - "!doc": "Ctrl键是否被按下" + "!doc": "Ctrl键是否被按下", }, - "curtainColor": { - "!doc": "当前画面色调" + curtainColor: { + "!doc": "当前画面色调", }, - "event": { + event: { "!doc": "当前事件", - "data": { - "!doc": "事件信息,如坐标等" + data: { + "!doc": "事件信息,如坐标等", }, - "id": { + id: { "!type": "string", - "!doc": "事件类型,如选择项/确认框" + "!doc": "事件类型,如选择项/确认框", }, - "interval": { + interval: { "!type": "number", - "!doc": "打字机效果的定时器" + "!doc": "打字机效果的定时器", }, - "selection": { + selection: { "!type": "number", - "!doc": "选择项和确认框的当前选中项" + "!doc": "选择项和确认框的当前选中项", + }, + ui: { + "!doc": "当前事件的界面信息,如楼传/手册/SL", }, - "ui": { - "!doc": "当前事件的界面信息,如楼传/手册/SL" - } }, - "floorAnimateObjs": { - "!doc": "楼层贴图的帧动画" + floorAnimateObjs: { + "!doc": "楼层贴图的帧动画", }, - "floorId": { + floorId: { "!type": "string", - "!doc": "当前楼层ID" + "!doc": "当前楼层ID", }, - "gameOver": { + gameOver: { "!type": "bool", - "!doc": "游戏是否已结束" + "!doc": "游戏是否已结束", }, - "globalAnimateObjs": { - "!doc": "各全局动画" + globalAnimateObjs: { + "!doc": "各全局动画", }, - "globalAnimateStatus": { + globalAnimateStatus: { "!type": "number", - "!doc": "全局动画的帧状态" + "!doc": "全局动画的帧状态", }, - "globalAttribute": { - "!doc": "全局css属性" + globalAttribute: { + "!doc": "全局css属性", }, - "hard": { + hard: { "!type": "string", - "!doc": "状态栏一角的难度名" + "!doc": "状态栏一角的难度名", }, - "downTime": { + downTime: { "!type": "number", - "!doc": "方向键已按下的时间" + "!doc": "方向键已按下的时间", }, - "heroCenter": { + heroCenter: { "!doc": "勇士中心像素坐标", - "px": { + px: { "!type": "number", - "!doc": "勇士中心的横坐标" + "!doc": "勇士中心的横坐标", }, - "py": { + py: { "!type": "number", - "!doc": "勇士中心的纵坐标" + "!doc": "勇士中心的纵坐标", }, }, - "heroMoving": { + heroMoving: { "!type": "number", - "!doc": "勇士行走的状态值" + "!doc": "勇士行走的状态值", }, - "heroStop": { + heroStop: { "!type": "bool", - "!doc": "勇士是否已停下" + "!doc": "勇士是否已停下", }, - "holdingKeys": { + holdingKeys: { "!type": "[number]", - "!doc": "当前按下的键" + "!doc": "当前按下的键", }, - "id2number": { - "!doc": "图块ID到数字的对应关系" + id2number: { + "!doc": "图块ID到数字的对应关系", }, - "lockControl": { + lockControl: { "!type": "bool", - "!doc": "当前是否是锁定操作状态" + "!doc": "当前是否是锁定操作状态", }, - "maps": { - "!doc": "当前各地图信息" + maps: { + "!doc": "当前各地图信息", }, - "number2Block": { - "!doc": "数字到图块对象的对应关系" + number2Block: { + "!doc": "数字到图块对象的对应关系", }, - "played": { + played: { "!type": "bool", - "!doc": "当前是否游戏中(不包括标题画面和录像回放)" + "!doc": "当前是否游戏中(不包括标题画面和录像回放)", }, - "replay": { + replay: { "!doc": "当前录像回放信息", - "animate": { + animate: { "!type": "bool", - "!doc": "回放是否正处于动画中" + "!doc": "回放是否正处于动画中", }, - "pausing": { + pausing: { "!type": "bool", - "!doc": "回放是否暂停中" + "!doc": "回放是否暂停中", }, - "replaying": { + replaying: { "!type": "bool", - "!doc": "当前是否回放中" + "!doc": "当前是否回放中", }, - "save": { + save: { "!type": "[]", - "!doc": "录像中的存档" + "!doc": "录像中的存档", }, - "speed": { + speed: { "!type": "number", - "!doc": "回放速度" + "!doc": "回放速度", }, - "steps": { + steps: { "!type": "number", - "!doc": "回放步数" + "!doc": "回放步数", }, - "toReplay": { + toReplay: { "!type": "[string]", - "!doc": "待回放的列表" + "!doc": "待回放的列表", }, - "totalList": { + totalList: { "!type": "[string]", - "!doc": "回放总列表" - } + "!doc": "回放总列表", + }, }, - "route": { + route: { "!type": "[string]", - "!doc": "当前录像内容" + "!doc": "当前录像内容", }, - "shops": { - "!doc": "全局商店列表" + shops: { + "!doc": "全局商店列表", }, - "textAttribute": { - "!doc": "当前剧情文本属性" + textAttribute: { + "!doc": "当前剧情文本属性", }, - "thisMap": { + thisMap: { "!type": "floor", - "!doc": "当前地图信息" - } + "!doc": "当前地图信息", + }, }, - "init": { + init: { "!doc": "初始化core", - "!type": "fn(coreData: ?, callback: fn())" + "!type": "fn(coreData: ?, callback: fn())", }, - "doFunc": { + doFunc: { "!doc": "执行一个函数;如果函数名是字符串则转发到插件中", - "!type": "fn(func: name|fn(), _this?: ?)" + "!type": "fn(func: name|fn(), _this?: ?)", }, - "control": { - "!doc": "负责整个游戏的核心控制系统,分为如下几个部分:
- requestAnimationFrame相关
- 标题界面,开始和重新开始游戏
- 自动寻路和人物行走相关
- 画布、位置、阻激夹域、显伤等相关
- 录像的回放相关
- 存读档,自动存档,同步存档等相关
- 人物属性和状态、位置、变量等相关
- 天气、色调、音乐和音效的播放
- 状态栏和工具栏相关
- 界面resize相关", - "showStatusBar": { + control: { + "!doc": + "负责整个游戏的核心控制系统,分为如下几个部分:
- requestAnimationFrame相关
- 标题界面,开始和重新开始游戏
- 自动寻路和人物行走相关
- 画布、位置、阻激夹域、显伤等相关
- 录像的回放相关
- 存读档,自动存档,同步存档等相关
- 人物属性和状态、位置、变量等相关
- 天气、色调、音乐和音效的播放
- 状态栏和工具栏相关
- 界面resize相关", + showStatusBar: { "!doc": "显示状态栏", - "!type": "fn()" + "!type": "fn()", }, - "startReplay": { + startReplay: { "!doc": "开始播放录像", - "!type": "fn(list: [string])" + "!type": "fn(list: [string])", }, - "triggerReplay": { + triggerReplay: { "!doc": "播放或暂停录像回放", - "!type": "fn()" + "!type": "fn()", }, - "screenFlash": { - "!doc": "画面闪烁
例如:core.screenFlash([255, 0, 0, 1], 3); // 红屏一闪而过
color: 一行三列(第四列视为1)或一行四列(第四列若大于1则会被视为1,第四列若填负数则会被视为0)的颜色数组,必填
time: 单次闪烁时长,实际闪烁效果为先花其三分之一的时间渐变到目标色调,再花剩余三分之二的时间渐变回去
times: 闪烁的总次数,不填或填0都视为1
moveMode: 渐变方式
callback: 闪烁全部完毕后的回调函数,可选", - "!type": "fn(color: [number], time: number, times?: number, moveMode?: string, callback?: fn())" + screenFlash: { + "!doc": + "画面闪烁
例如:core.screenFlash([255, 0, 0, 1], 3); // 红屏一闪而过
color: 一行三列(第四列视为1)或一行四列(第四列若大于1则会被视为1,第四列若填负数则会被视为0)的颜色数组,必填
time: 单次闪烁时长,实际闪烁效果为先花其三分之一的时间渐变到目标色调,再花剩余三分之二的时间渐变回去
times: 闪烁的总次数,不填或填0都视为1
moveMode: 渐变方式
callback: 闪烁全部完毕后的回调函数,可选", + "!type": + "fn(color: [number], time: number, times?: number, moveMode?: string, callback?: fn())", }, - "setCurtain": { - "!doc": "更改画面色调,不计入存档。如需长期生效请使用core.events._action_setCurtain()函数
例如:core.setCurtain(); // 恢复画面色调,用时四分之三秒
color: 一行三列(第四列视为1)或一行四列(第四列若大于1则会被视为1,第四列若为负数则会被视为0)的颜色数组,不填视为[0, 0, 0, 0]
time: 渐变时间,单位为毫秒。不填视为750ms,负数视为0(无渐变,立即更改)
moveMode: 渐变方式
callback: 更改完毕后的回调函数,可选。事件流中常取core.doAction", - "!type": "fn(color?: [number], time?: number, moveMode?: string, callback?: fn())" + setCurtain: { + "!doc": + "更改画面色调,不计入存档。如需长期生效请使用core.events._action_setCurtain()函数
例如:core.setCurtain(); // 恢复画面色调,用时四分之三秒
color: 一行三列(第四列视为1)或一行四列(第四列若大于1则会被视为1,第四列若为负数则会被视为0)的颜色数组,不填视为[0, 0, 0, 0]
time: 渐变时间,单位为毫秒。不填视为750ms,负数视为0(无渐变,立即更改)
moveMode: 渐变方式
callback: 更改完毕后的回调函数,可选。事件流中常取core.doAction", + "!type": + "fn(color?: [number], time?: number, moveMode?: string, callback?: fn())", }, - "updateDamage": { - "!doc": "注意!请勿使用该函数!请使用core.updateStatusBar()代替!!重算并绘制地图显伤
例如:core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话)
floorId: 地图id,不填视为当前地图。预览地图时填写
ctx: 绘制到的画布,如果填写了就会画在该画布而不是显伤层", - "!type": "fn(floorId?: string, ctx?: string|CanvasRenderingContext2D)" + updateDamage: { + "!doc": + "注意!请勿使用该函数!请使用core.updateStatusBar()代替!!重算并绘制地图显伤
例如:core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话)
floorId: 地图id,不填视为当前地图。预览地图时填写
ctx: 绘制到的画布,如果填写了就会画在该画布而不是显伤层", + "!type": + "fn(floorId?: string, ctx?: string|CanvasRenderingContext2D)", }, - "drawDamage": { + drawDamage: { "!doc": "仅绘制地图显伤", - "!type": "fn(string|CanvasRenderingContext2D)" + "!type": "fn(string|CanvasRenderingContext2D)", }, - "nextX": { - "!doc": "获取主角面前第n格的横坐标
例如:core.closeDoor(core.nextX(), core.nextY(), 'yellowDoor', core.turnHero); // 在主角面前关上一扇黄门,然后主角顺时针旋转90°
n: 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1", - "!type": "fn(n?: number) -> number" + nextX: { + "!doc": + "获取主角面前第n格的横坐标
例如:core.closeDoor(core.nextX(), core.nextY(), 'yellowDoor', core.turnHero); // 在主角面前关上一扇黄门,然后主角顺时针旋转90°
n: 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1", + "!type": "fn(n?: number) -> number", }, - "nextY": { - "!doc": "获取主角面前第n格的纵坐标
例如:core.jumpHero(core.nextX(2), core.nextY(2)); // 主角向前跃过一格,即跳跃靴道具的使用效果
n: 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1", - "!type": "fn(n?: number) -> number" + nextY: { + "!doc": + "获取主角面前第n格的纵坐标
例如:core.jumpHero(core.nextX(2), core.nextY(2)); // 主角向前跃过一格,即跳跃靴道具的使用效果
n: 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1", + "!type": "fn(n?: number) -> number", }, - "clearContinueAutomaticRoute": { + clearContinueAutomaticRoute: { "!doc": "清空剩下的自动寻路列表", - "!type": "fn(callback?: fn())" + "!type": "fn(callback?: fn())", }, - "updateViewport": { + updateViewport: { "!doc": "更新大地图的可见区域", - "!type": "fn()" + "!type": "fn()", }, - "getMappedName": { + getMappedName: { "!doc": "获得映射文件名", - "!type": "fn(name: string) -> string" + "!type": "fn(name: string) -> string", }, - "addFlag": { - "!doc": "增减一个flag变量,等价于 core.setFlag(name, core.getFlag(name, 0) + value)
例如:core.addFlag('hatred', 1); // 增加1点仇恨值
name: 变量名,支持中文
value: 变量的增量", - "!type": "fn(name: string, value: number)" + addFlag: { + "!doc": + "增减一个flag变量,等价于 core.setFlag(name, core.getFlag(name, 0) + value)
例如:core.addFlag('hatred', 1); // 增加1点仇恨值
name: 变量名,支持中文
value: 变量的增量", + "!type": "fn(name: string, value: number)", }, - "setFlag": { - "!doc": "设置一个flag变量
例如:core.setFlag('poison', true); // 令主角中毒
name: 变量名,支持中文
value: 变量的新值,不填或填null视为删除", - "!type": "fn(name: string, value: ?)" + setFlag: { + "!doc": + "设置一个flag变量
例如:core.setFlag('poison', true); // 令主角中毒
name: 变量名,支持中文
value: 变量的新值,不填或填null视为删除", + "!type": "fn(name: string, value: ?)", }, - "playSound": { - "!doc": "播放一个音效
sound: 音效名;可以使用文件别名。
pitch: 播放的音调;可选,如果设置则为30-300之间的数值。
callback: 可选,播放完毕后执行的回调函数。
返回:一个数字,可用于core.stopSound的参数来只停止该音效。", - "!type": "fn(sound: string, pitch?: number, callback?: fn()) -> number" + playSound: { + "!doc": + "播放一个音效
sound: 音效名;可以使用文件别名。
pitch: 播放的音调;可选,如果设置则为30-300之间的数值。
callback: 可选,播放完毕后执行的回调函数。
返回:一个数字,可用于core.stopSound的参数来只停止该音效。", + "!type": + "fn(sound: string, pitch?: number, callback?: fn()) -> number", }, - "stopSound": { - "!doc": "停止播放音效。如果未指定id则停止所有音效,否则只停止指定的音效。", - "!type": "fn(id?: number)" + stopSound: { + "!doc": + "停止播放音效。如果未指定id则停止所有音效,否则只停止指定的音效。", + "!type": "fn(id?: number)", }, - "getPlayingSounds": { - "!doc": "获得当前正在播放的所有(指定)音效的id列表
name: 音效名,可用别名;不填代表返回正在播放的全部音效
返回值: 一个列表,每一项为一个正在播放的音效id;可用core.stopSound立刻停止播放", - "!type": "fn(name?: string) -> [number]" + getPlayingSounds: { + "!doc": + "获得当前正在播放的所有(指定)音效的id列表
name: 音效名,可用别名;不填代表返回正在播放的全部音效
返回值: 一个列表,每一项为一个正在播放的音效id;可用core.stopSound立刻停止播放", + "!type": "fn(name?: string) -> [number]", }, - "addGameCanvasTranslate": { + addGameCanvasTranslate: { "!doc": "加减画布偏移", - "!type": "fn(x?: number, y?: number)" + "!type": "fn(x?: number, y?: number)", }, - "addBuff": { - "!doc": "增减主角某个属性的百分比修正倍率,加减法叠加和抵消。等价于 core.setBuff(name, core.getBuff(name) + value)
例如:core.addBuff('atk', -0.1); // 主角获得一层“攻击力减一成”的负面效果
name: 属性的英文名,请注意只能用于数值类属性哦,否则随后的乘法会得到NaN
value: 倍率的增量", - "!type": "fn(name: string, value: number)" + addBuff: { + "!doc": + "增减主角某个属性的百分比修正倍率,加减法叠加和抵消。等价于 core.setBuff(name, core.getBuff(name) + value)
例如:core.addBuff('atk', -0.1); // 主角获得一层“攻击力减一成”的负面效果
name: 属性的英文名,请注意只能用于数值类属性哦,否则随后的乘法会得到NaN
value: 倍率的增量", + "!type": "fn(name: string, value: number)", }, - "drawHero": { - "!doc": "绘制主角和跟随者并重置视野到以主角为中心
例如:core.drawHero(); // 原地绘制主角的静止帧并重置视野野
status: 只能为 stop, leftFoot 和 rightFoot,不填用stop。
offset: 相对主角逻辑位置的偏移量,不填视为无偏移。
frame: 绘制的第几帧", - "!type": "fn(status?: string, offset?: number, frame?: number)" + drawHero: { + "!doc": + "绘制主角和跟随者并重置视野到以主角为中心
例如:core.drawHero(); // 原地绘制主角的静止帧并重置视野野
status: 只能为 stop, leftFoot 和 rightFoot,不填用stop。
offset: 相对主角逻辑位置的偏移量,不填视为无偏移。
frame: 绘制的第几帧", + "!type": "fn(status?: string, offset?: number, frame?: number)", }, - "pauseBgm": { + pauseBgm: { "!doc": "暂停背景音乐的播放", - "!type": "fn()" + "!type": "fn()", }, - "setBgmSpeed": { - "!doc": "设置背景音乐的播放速度和音调
speed: 播放速度,必须为30-300中间的值。100为正常速度。
usePitch: 是否同时改变音调(部分设备可能不支持)", - "!type": "fn(speed: number, usePitch?: bool)" + setBgmSpeed: { + "!doc": + "设置背景音乐的播放速度和音调
speed: 播放速度,必须为30-300中间的值。100为正常速度。
usePitch: 是否同时改变音调(部分设备可能不支持)", + "!type": "fn(speed: number, usePitch?: bool)", }, - "setReplaySpeed": { + setReplaySpeed: { "!doc": "设置播放速度", - "!type": "fn(speed: number)" + "!type": "fn(speed: number)", }, - "pauseReplay": { + pauseReplay: { "!doc": "暂停播放", - "!type": "fn()" + "!type": "fn()", }, - "doSL": { + doSL: { "!doc": "实际进行存读档事件", - "!type": "fn(id?: string, type?: string)" + "!type": "fn(id?: string, type?: string)", }, - "setStatus": { - "!doc": "设置主角的某个属性
例如:core.setStatus('atk', 100); // 设置攻击力为100
name: 属性的英文名,其中'x'、'y'和'direction'会被特殊处理为 core.setHeroLoc(name, value),其他的会直接对 core.status.hero[name] 赋值
value: 属性的新值", - "!type": "fn(name: string, value: number)" + setStatus: { + "!doc": + "设置主角的某个属性
例如:core.setStatus('atk', 100); // 设置攻击力为100
name: 属性的英文名,其中'x'、'y'和'direction'会被特殊处理为 core.setHeroLoc(name, value),其他的会直接对 core.status.hero[name] 赋值
value: 属性的新值", + "!type": "fn(name: string, value: number)", }, - "setAutomaticRoute": { - "!doc": "半自动寻路,用于鼠标或手指拖动
例如:core.setAutomaticRoute(0, 0, [{direction: \"right\", x: 4, y: 9}, {direction: \"right\", x: 5, y: 9}]);
destX: 鼠标或手指的起拖点横坐标
destY: 鼠标或手指的起拖点纵坐标
stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。", - "!type": "fn(destX: number, destY: number, stepPostfix: [{x: number, y: number, direction: string}])" + setAutomaticRoute: { + "!doc": + '半自动寻路,用于鼠标或手指拖动
例如:core.setAutomaticRoute(0, 0, [{direction: "right", x: 4, y: 9}, {direction: "right", x: 5, y: 9}]);
destX: 鼠标或手指的起拖点横坐标
destY: 鼠标或手指的起拖点纵坐标
stepPostfix: 拖动轨迹的数组表示,每项为一步的方向和目标点。', + "!type": + "fn(destX: number, destY: number, stepPostfix: [{x: number, y: number, direction: string}])", }, - "setHeroOpacity": { + setHeroOpacity: { "!doc": "改变勇士的不透明度", - "!type": "fn(opacity?: number, moveMode?: string, time?: number, callback?: fn())" + "!type": + "fn(opacity?: number, moveMode?: string, time?: number, callback?: fn())", }, - "gatherFollowers": { + gatherFollowers: { "!doc": "立刻聚集所有的跟随者", - "!type": "fn()" + "!type": "fn()", }, - "getStatus": { - "!doc": "读取主角的某个属性,不包括百分比修正
例如:core.getStatus('atk'); // 读取主角的攻击力
name: 属性的英文名,其中'x'、'y'和'direction'会被特殊处理为 core.getHeroLoc(name),其他的会直接读取 core.status.hero[name]", - "!type": "fn(name: string) -> number" + getStatus: { + "!doc": + "读取主角的某个属性,不包括百分比修正
例如:core.getStatus('atk'); // 读取主角的攻击力
name: 属性的英文名,其中'x'、'y'和'direction'会被特殊处理为 core.getHeroLoc(name),其他的会直接读取 core.status.hero[name]", + "!type": "fn(name: string) -> number", }, - "setHeroLoc": { - "!doc": "设置勇士位置
值得注意的是,这句话虽然会使勇士改变位置,但并不会使界面重新绘制;
如需立刻重新绘制地图还需调用:core.clearMap('hero'); core.drawHero(); 来对界面进行更新。
例如:core.setHeroLoc('x', 5) // 将勇士当前位置的横坐标设置为5。
name: 要设置的坐标属性
value: 新值
noGather: 是否聚集跟随者", - "!type": "fn(name: string, value: string|number, noGather?: bool)" + setHeroLoc: { + "!doc": + "设置勇士位置
值得注意的是,这句话虽然会使勇士改变位置,但并不会使界面重新绘制;
如需立刻重新绘制地图还需调用:core.clearMap('hero'); core.drawHero(); 来对界面进行更新。
例如:core.setHeroLoc('x', 5) // 将勇士当前位置的横坐标设置为5。
name: 要设置的坐标属性
value: 新值
noGather: 是否聚集跟随者", + "!type": "fn(name: string, value: string|number, noGather?: bool)", }, - "getLvName": { - "!doc": "根据级别的数字获取对应的名称,后者定义在全塔属性
例如:core.getLvName(); // 获取主角当前级别的名称,如“下级佣兵”
lv: 级别的数字,不填则视为主角当前的级别
返回值:级别的名称,如果不存在就还是返回数字", - "!type": "fn(lv?: number) -> string|number" + getLvName: { + "!doc": + "根据级别的数字获取对应的名称,后者定义在全塔属性
例如:core.getLvName(); // 获取主角当前级别的名称,如“下级佣兵”
lv: 级别的数字,不填则视为主角当前的级别
返回值:级别的名称,如果不存在就还是返回数字", + "!type": "fn(lv?: number) -> string|number", }, - "getNextLvUpNeed": { - "!doc": "获得下次升级需要的经验值。
升级扣除模式下会返回经验差值;非扣除模式下会返回总共需要的经验值。
如果无法进行下次升级,返回null。", - "!type": "fn() -> number" + getNextLvUpNeed: { + "!doc": + "获得下次升级需要的经验值。
升级扣除模式下会返回经验差值;非扣除模式下会返回总共需要的经验值。
如果无法进行下次升级,返回null。", + "!type": "fn() -> number", }, - "addStatus": { - "!doc": "增减主角的某个属性,等价于core.setStatus(name, core.getStatus(name) + value)
例如:core.addStatus('atk', 100'); // 给主角攻击力加100
name: 属性的英文名
value: 属性的增量", - "!type": "fn(name: string, value: number)" + addStatus: { + "!doc": + "增减主角的某个属性,等价于core.setStatus(name, core.getStatus(name) + value)
例如:core.addStatus('atk', 100'); // 给主角攻击力加100
name: 属性的英文名
value: 属性的增量", + "!type": "fn(name: string, value: number)", }, - "speedUpReplay": { + speedUpReplay: { "!doc": "加速播放", - "!type": "fn()" + "!type": "fn()", }, - "loadData": { + loadData: { "!doc": "从本地读档", - "!type": "fn(data?: ?, callback?: fn())" + "!type": "fn(data?: ?, callback?: fn())", }, - "debug": { - "!doc": "开启调试模式, 此模式下可以按Ctrl键进行穿墙, 并忽略一切事件。
此模式下不可回放录像和上传成绩。", - "!type": "fn()" + debug: { + "!doc": + "开启调试模式, 此模式下可以按Ctrl键进行穿墙, 并忽略一切事件。
此模式下不可回放录像和上传成绩。", + "!type": "fn()", }, - "moveOneStep": { - "!doc": "每移动一格后执行的事件
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(callback?: fn())" + moveOneStep: { + "!doc": + "每移动一格后执行的事件
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(callback?: fn())", }, - "clearStatus": { + clearStatus: { "!doc": "清除游戏状态和数据", - "!type": "fn()" + "!type": "fn()", }, - "updateFollowers": { + updateFollowers: { "!doc": "更新跟随者坐标", - "!type": "fn()" + "!type": "fn()", }, - "waitHeroToStop": { - "!doc": "等待主角停下
例如:core.waitHeroToStop(core.vibrate); // 等待主角停下,然后视野左右抖动1秒
callback: 主角停止后的回调函数", - "!type": "fn(callback?: fn())" + waitHeroToStop: { + "!doc": + "等待主角停下
例如:core.waitHeroToStop(core.vibrate); // 等待主角停下,然后视野左右抖动1秒
callback: 主角停止后的回调函数", + "!type": "fn(callback?: fn())", }, - "hideStatusBar": { + hideStatusBar: { "!doc": "隐藏状态栏
showToolbox: 是否不隐藏竖屏工具栏", - "!type": "fn(showToolbox?: bool)" + "!type": "fn(showToolbox?: bool)", }, - "getBuff": { - "!doc": "读取主角某个属性的百分比修正倍率,初始值为1
例如:core.getBuff('atk'); // 主角当前能发挥出多大比例的攻击力
name: 属性的英文名", - "!type": "fn(name: string) -> number" + getBuff: { + "!doc": + "读取主角某个属性的百分比修正倍率,初始值为1
例如:core.getBuff('atk'); // 主角当前能发挥出多大比例的攻击力
name: 属性的英文名", + "!type": "fn(name: string) -> number", }, - "triggerDebuff": { - "!doc": "获得或移除毒衰咒效果
action: 要获得还是移除,'get'为获得,'remove'为移除
type: 获得或移除的内容(poison/weak/curse),可以为字符串或数组", - "!type": "fn(action: string, type: string|[string])" + triggerDebuff: { + "!doc": + "获得或移除毒衰咒效果
action: 要获得还是移除,'get'为获得,'remove'为移除
type: 获得或移除的内容(poison/weak/curse),可以为字符串或数组", + "!type": "fn(action: string, type: string|[string])", }, - "setToolbarButton": { + setToolbarButton: { "!doc": "改变工具栏为按钮1-8", - "!type": "fn(useButton?: bool)" + "!type": "fn(useButton?: bool)", }, - "getSaves": { + getSaves: { "!doc": "获得某些存档内容", - "!type": "fn(ids?: ?, callback?: fn())" + "!type": "fn(ids?: ?, callback?: fn())", }, - "replay": { + replay: { "!doc": "回放下一个操作", - "!type": "fn()" + "!type": "fn()", }, - "getStatusOrDefault": { + getStatusOrDefault: { "!doc": "从status中获得属性,如果不存在则从勇士属性中获取", - "!type": "fn(status?: ?, name?: string)" + "!type": "fn(status?: ?, name?: string)", }, - "unregisterReplayAction": { + unregisterReplayAction: { "!doc": "注销一个录像行为", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "unregisterWeather": { + unregisterWeather: { "!doc": "注销一个天气", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "setBuff": { - "!doc": "设置主角某个属性的百分比修正倍率,初始值为1,
倍率存放在flag: '__'+name+'_buff__' 中
例如:core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半
name: 属性的英文名,请注意只能用于数值类属性哦,否则随后的乘法会得到NaN
value: 新的百分比修正倍率,不填(效果上)视为1", - "!type": "fn(name: string, value: number)" + setBuff: { + "!doc": + "设置主角某个属性的百分比修正倍率,初始值为1,
倍率存放在flag: '__'+name+'_buff__' 中
例如:core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半
name: 属性的英文名,请注意只能用于数值类属性哦,否则随后的乘法会得到NaN
value: 新的百分比修正倍率,不填(效果上)视为1", + "!type": "fn(name: string, value: number)", }, - "continueAutomaticRoute": { + continueAutomaticRoute: { "!doc": "继续剩下的自动寻路操作", - "!type": "fn()" + "!type": "fn()", }, - "setAutoHeroMove": { - "!doc": "连续行走
例如:core.setAutoHeroMove([{direction: \"up\", step: 1}, {direction: \"left\", step: 3}]); // 上左左左
steps: 压缩的步伐数组,每项表示朝某方向走多少步", - "!type": "fn(steps: [?])" + setAutoHeroMove: { + "!doc": + '连续行走
例如:core.setAutoHeroMove([{direction: "up", step: 1}, {direction: "left", step: 3}]); // 上左左左
steps: 压缩的步伐数组,每项表示朝某方向走多少步', + "!type": "fn(steps: [?])", }, - "unregisterResize": { + unregisterResize: { "!doc": "注销一个resize函数", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "saveAndStopAutomaticRoute": { + saveAndStopAutomaticRoute: { "!doc": "保存剩下的寻路,并停止", - "!type": "fn()" + "!type": "fn()", }, - "hideStartAnimate": { - "!doc": "淡出标题画面
例如:core.hideStartAnimate(core.startGame); // 淡出标题画面并开始新游戏,跳过难度选择
callback: 标题画面完全淡出后的回调函数", - "!type": "fn(callback?: fn())" + hideStartAnimate: { + "!doc": + "淡出标题画面
例如:core.hideStartAnimate(core.startGame); // 淡出标题画面并开始新游戏,跳过难度选择
callback: 标题画面完全淡出后的回调函数", + "!type": "fn(callback?: fn())", }, - "getAllSaves": { + getAllSaves: { "!doc": "获得所有存档内容", - "!type": "fn(callback?: fn())" + "!type": "fn(callback?: fn())", }, - "updateHeroIcon": { + updateHeroIcon: { "!doc": "更新状态栏的勇士图标", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "setMusicBtn": { + setMusicBtn: { "!doc": "设置音乐图标的显隐状态", - "!type": "fn()" + "!type": "fn()", }, - "isPlaying": { + isPlaying: { "!doc": "游戏是否已经开始", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "triggerBgm": { + triggerBgm: { "!doc": "开启或关闭背景音乐的播放", - "!type": "fn()" + "!type": "fn()", }, - "moveHero": { - "!doc": "连续前进,不撞南墙不回头
例如:core.moveHero(); // 连续前进
direction: 可选,如果设置了就会先转身到该方向
callback: 可选,如果设置了就只走一步
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(direction?: string, callback?: fn())" + moveHero: { + "!doc": + "连续前进,不撞南墙不回头
例如:core.moveHero(); // 连续前进
direction: 可选,如果设置了就会先转身到该方向
callback: 可选,如果设置了就只走一步
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(direction?: string, callback?: fn())", }, - "getRealStatusOrDefault": { - "!doc": "从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取", - "!type": "fn(status?: ?, name?: string)" + getRealStatusOrDefault: { + "!doc": + "从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取", + "!type": "fn(status?: ?, name?: string)", }, - "getStatusLabel": { + getStatusLabel: { "!doc": "获得某个状态的名字,如atk->攻击,def->防御等", - "!type": "fn(name: string) -> string" + "!type": "fn(name: string) -> string", }, - "removeSave": { + removeSave: { "!doc": "删除某个存档", - "!type": "fn(index?: number, callback?: fn())" + "!type": "fn(index?: number, callback?: fn())", }, - "registerAnimationFrame": { - "!doc": "注册一个 animationFrame
name: 名称,可用来作为注销使用
needPlaying: 是否只在游戏运行时才执行(在标题界面不执行)
func: 要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数", - "!type": "fn(name: string, needPlaying: bool, func?: fn(timestamp: number))" + registerAnimationFrame: { + "!doc": + "注册一个 animationFrame
name: 名称,可用来作为注销使用
needPlaying: 是否只在游戏运行时才执行(在标题界面不执行)
func: 要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数", + "!type": + "fn(name: string, needPlaying: bool, func?: fn(timestamp: number))", }, - "getHeroLoc": { - "!doc": "读取主角的位置和/或朝向
例如:core.getHeroLoc(); // 读取主角的位置和朝向
name: 要读取横坐标还是纵坐标还是朝向还是都读取
返回值:name ? core.status.hero.loc[name] : core.status.hero.loc", - "!type": "fn(name: string) -> string|number" + getHeroLoc: { + "!doc": + "读取主角的位置和/或朝向
例如:core.getHeroLoc(); // 读取主角的位置和朝向
name: 要读取横坐标还是纵坐标还是朝向还是都读取
返回值:name ? core.status.hero.loc[name] : core.status.hero.loc", + "!type": "fn(name: string) -> string|number", }, - "stopAutomaticRoute": { + stopAutomaticRoute: { "!doc": "停止自动寻路操作", - "!type": "fn()" + "!type": "fn()", }, - "setWeather": { - "!doc": "设置天气,不计入存档。如需长期生效请使用core.events._action_setWeather()函数
例如:core.setWeather('fog', 10); // 设置十级大雾天
type: 新天气的类型,不填视为晴天
level: 新天气(晴天除外)的级别,必须为不大于10的正整数,不填视为5", - "!type": "fn(type?: string, level?: number)" + setWeather: { + "!doc": + "设置天气,不计入存档。如需长期生效请使用core.events._action_setWeather()函数
例如:core.setWeather('fog', 10); // 设置十级大雾天
type: 新天气的类型,不填视为晴天
level: 新天气(晴天除外)的级别,必须为不大于10的正整数,不填视为5", + "!type": "fn(type?: string, level?: number)", }, - "updateStatusBar": { - "!doc": "刷新状态栏和地图显伤
doNotCheckAutoEvents: 是否不检查自动事件", - "!type": "fn(doNotCheckAutoEvents?: bool, immediate?: bool)" + updateStatusBar: { + "!doc": + "刷新状态栏和地图显伤
doNotCheckAutoEvents: 是否不检查自动事件", + "!type": "fn(doNotCheckAutoEvents?: bool, immediate?: bool)", }, - "autosave": { + autosave: { "!doc": "自动存档", - "!type": "fn(removeLast?: bool)" + "!type": "fn(removeLast?: bool)", }, - "clearStatusBar": { + clearStatusBar: { "!doc": "清空状态栏", - "!type": "fn()" + "!type": "fn()", }, - "moveAction": { - "!doc": "尝试前进一步,如果面前不可被踏入就会直接触发该点事件
请勿直接使用此函数,如有需要请使用「勇士前进一步或撞击」事件
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(callback?: fn())" + moveAction: { + "!doc": + "尝试前进一步,如果面前不可被踏入就会直接触发该点事件
请勿直接使用此函数,如有需要请使用「勇士前进一步或撞击」事件
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(callback?: fn())", }, - "hasFlag": { - "!doc": "判定一个flag变量是否存在且不为false、0、''、null、undefined和NaN
例如:core.hasFlag('poison'); // 判断主角当前是否中毒
name: 变量名,支持中文
此函数等价于 !!core.getFlag(name)", - "!type": "fn(name: string) -> bool" + hasFlag: { + "!doc": + "判定一个flag变量是否存在且不为false、0、''、null、undefined和NaN
例如:core.hasFlag('poison'); // 判断主角当前是否中毒
name: 变量名,支持中文
此函数等价于 !!core.getFlag(name)", + "!type": "fn(name: string) -> bool", }, - "rewindReplay": { + rewindReplay: { "!doc": "回退到上一个录像节点", - "!type": "fn()" + "!type": "fn()", }, - "playBgm": { - "!doc": "播放背景音乐,中途开播但不计入存档且只会持续到下次场景切换。如需长期生效请将背景音乐的文件名赋值给flags.__bgm__
例如:core.playBgm('bgm.mp3', 30); // 播放bgm.mp3,并跳过前半分钟
bgm: 背景音乐的文件名,支持全塔属性中映射前的中文名
startTime: 跳过前多少秒,不填则不跳过", - "!type": "fn(bgm: string, startTime?: number)" + playBgm: { + "!doc": + "播放背景音乐,中途开播但不计入存档且只会持续到下次场景切换。如需长期生效请将背景音乐的文件名赋值给flags.__bgm__
例如:core.playBgm('bgm.mp3', 30); // 播放bgm.mp3,并跳过前半分钟
bgm: 背景音乐的文件名,支持全塔属性中映射前的中文名
startTime: 跳过前多少秒,不填则不跳过", + "!type": "fn(bgm: string, startTime?: number)", }, - "isReplaying": { + isReplaying: { "!doc": "是否正在播放录像", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "isMoving": { + isMoving: { "!doc": "当前是否正在移动", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "getSaveIndexes": { + getSaveIndexes: { "!doc": "获得所有存在存档的存档位", - "!type": "fn(callback?: fn())" + "!type": "fn(callback?: fn())", }, - "unlockControl": { + unlockControl: { "!doc": "解锁用户控制行为", - "!type": "fn()" + "!type": "fn()", }, - "syncSave": { + syncSave: { "!doc": "同步存档到服务器", - "!type": "fn(type?: string)" + "!type": "fn(type?: string)", }, - "removeFlag": { + removeFlag: { "!doc": "删除某个flag/变量", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "registerResize": { - "!doc": "注册一个resize函数
name: 名称,可供注销使用
func: 可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。", - "!type": "fn(name: string, func: fn(obj: ?))" + registerResize: { + "!doc": + "注册一个resize函数
name: 名称,可供注销使用
func: 可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。", + "!type": "fn(name: string, func: fn(obj: ?))", }, - "registerWeather": { - "!doc": "注册一个天气
name: 要注册的天气名
initFunc: 当切换到此天气时的初始化;接受level(天气等级)为参数;可用于创建多个节点(如初始化雪花)
frameFunc: 每帧的天气效果变化;可接受timestamp(从页面加载完毕到当前所经过的时间)和level(天气等级)作为参数
天气应当仅在weather层进行绘制,推荐使用core.animateFrame.weather.nodes用于节点信息。", - "!type": "fn(name: string, initFunc: fn(level: number), frameFunc?: fn(timestamp: number, level: number))" + registerWeather: { + "!doc": + "注册一个天气
name: 要注册的天气名
initFunc: 当切换到此天气时的初始化;接受level(天气等级)为参数;可用于创建多个节点(如初始化雪花)
frameFunc: 每帧的天气效果变化;可接受timestamp(从页面加载完毕到当前所经过的时间)和level(天气等级)作为参数
天气应当仅在weather层进行绘制,推荐使用core.animateFrame.weather.nodes用于节点信息。", + "!type": + "fn(name: string, initFunc: fn(level: number), frameFunc?: fn(timestamp: number, level: number))", }, - "stopReplay": { + stopReplay: { "!doc": "停止播放", - "!type": "fn(force?: bool)" + "!type": "fn(force?: bool)", }, - "turnHero": { - "!doc": "主角转向并计入录像,不会导致跟随者聚集,会导致视野重置到以主角为中心
例如:core.turnHero(); // 主角顺时针旋转90°,即单击主角或按下Z键的效果
direction: 主角的新朝向,可为 up, down, left, right, :left, :right, :back 七种之一", - "!type": "fn(direction?: string)" + turnHero: { + "!doc": + "主角转向并计入录像,不会导致跟随者聚集,会导致视野重置到以主角为中心
例如:core.turnHero(); // 主角顺时针旋转90°,即单击主角或按下Z键的效果
direction: 主角的新朝向,可为 up, down, left, right, :left, :right, :back 七种之一", + "!type": "fn(direction?: string)", }, - "resumeReplay": { + resumeReplay: { "!doc": "恢复播放", - "!type": "fn()" + "!type": "fn()", }, - "resize": { + resize: { "!doc": "屏幕分辨率改变后重新自适应", - "!type": "fn()" + "!type": "fn()", }, - "getSave": { + getSave: { "!doc": "获得某个存档内容", - "!type": "fn(index?: number, callback?: fn(data: ?))" + "!type": "fn(index?: number, callback?: fn(data: ?))", }, - "setViewport": { - "!doc": "设置视野范围
px,py: 左上角相对大地图的像素坐标,不需要为32倍数", - "!type": "fn(px?: number, py?: number)" + setViewport: { + "!doc": + "设置视野范围
px,py: 左上角相对大地图的像素坐标,不需要为32倍数", + "!type": "fn(px?: number, py?: number)", }, - "chooseReplayFile": { + chooseReplayFile: { "!doc": "选择录像文件", - "!type": "fn()" + "!type": "fn()", }, - "lockControl": { + lockControl: { "!doc": "锁定用户控制,常常用于事件处理", - "!type": "fn()" + "!type": "fn()", }, - "updateCheckBlock": { + updateCheckBlock: { "!doc": "更新领域、夹击、阻击的伤害地图", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "checkBlock": { + checkBlock: { "!doc": "检查并执行领域、夹击、阻击事件", - "!type": "fn()" + "!type": "fn()", }, - "clearAutomaticRouteNode": { + clearAutomaticRouteNode: { "!doc": "清除自动寻路路线", - "!type": "fn(x?: number, y?: number)" + "!type": "fn(x?: number, y?: number)", }, - "getFlag": { - "!doc": "读取一个flag变量
name: 变量名,支持中文
defaultValue: 当变量不存在时的返回值,可选(事件流中默认填0)。", - "!type": "fn(name: string, defaultValue?: ?)" + getFlag: { + "!doc": + "读取一个flag变量
name: 变量名,支持中文
defaultValue: 当变量不存在时的返回值,可选(事件流中默认填0)。", + "!type": "fn(name: string, defaultValue?: ?)", }, - "getNakedStatus": { + getNakedStatus: { "!doc": "获得勇士原始属性(无装备和衰弱影响)", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "nearHero": { - "!doc": "判定主角是否身处某个点的锯齿领域(取曼哈顿距离)
例如:core.nearHero(6, 6, 6); // 判定主角是否身处点(6,6)的半径为6的锯齿领域
x: 领域的中心横坐标
y: 领域的中心纵坐标
n: 领域的半径,不填视为1", - "!type": "fn(x: number, y: number, n?: number) -> bool" + nearHero: { + "!doc": + "判定主角是否身处某个点的锯齿领域(取曼哈顿距离)
例如:core.nearHero(6, 6, 6); // 判定主角是否身处点(6,6)的半径为6的锯齿领域
x: 领域的中心横坐标
y: 领域的中心纵坐标
n: 领域的半径,不填视为1", + "!type": "fn(x: number, y: number, n?: number) -> bool", }, - "stepReplay": { + stepReplay: { "!doc": "单步播放", - "!type": "fn()" + "!type": "fn()", }, - "hasSave": { + hasSave: { "!doc": "判断某个存档位是否存在存档", - "!type": "fn(index?: number) -> bool" + "!type": "fn(index?: number) -> bool", }, - "showStartAnimate": { - "!doc": "进入标题画面
例如:core.showStartAnimate(); // 重启游戏但不重置bgm
noAnimate: 可选,true表示不由黑屏淡入而是立即亮屏
callback: 可选,完全亮屏后的回调函数", - "!type": "fn(noAnimate?: bool, callback?: fn())" + showStartAnimate: { + "!doc": + "进入标题画面
例如:core.showStartAnimate(); // 重启游戏但不重置bgm
noAnimate: 可选,true表示不由黑屏淡入而是立即亮屏
callback: 可选,完全亮屏后的回调函数", + "!type": "fn(noAnimate?: bool, callback?: fn())", }, - "moveViewport": { + moveViewport: { "!doc": "移动视野范围", - "!type": "fn(x: number, y: number, moveMode?: string, time?: number, callback?: fn())" + "!type": + "fn(x: number, y: number, moveMode?: string, time?: number, callback?: fn())", }, - "syncLoad": { + syncLoad: { "!doc": "从服务器加载存档", - "!type": "fn()" + "!type": "fn()", }, - "setHeroMoveInterval": { + setHeroMoveInterval: { "!doc": "设置行走的效果动画", - "!type": "fn(callback?: fn())" + "!type": "fn(callback?: fn())", }, - "registerReplayAction": { - "!doc": "注册一个录像行为
name: 自定义名称,可用于注销使用
func: 具体执行录像的函数,可为一个函数或插件中的函数名;
需要接受一个action参数,代表录像回放时的下一个操作
func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。", - "!type": "fn(name: string, func: fn(action?: string) -> bool)" + registerReplayAction: { + "!doc": + "注册一个录像行为
name: 自定义名称,可用于注销使用
func: 具体执行录像的函数,可为一个函数或插件中的函数名;
需要接受一个action参数,代表录像回放时的下一个操作
func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。", + "!type": "fn(name: string, func: fn(action?: string) -> bool)", }, - "checkAutosave": { + checkAutosave: { "!doc": "实际将自动存档写入存储", - "!type": "fn()" + "!type": "fn()", }, - "resumeBgm": { + resumeBgm: { "!doc": "恢复背景音乐的播放
resumeTime: 从哪一秒开始恢复播放", - "!type": "fn(resumeTime?: number)" + "!type": "fn(resumeTime?: number)", }, - "setGameCanvasTranslate": { + setGameCanvasTranslate: { "!doc": "设置大地图的偏移量", - "!type": "fn(ctx: string|CanvasRenderingContext2D, x: number, y: number)" + "!type": + "fn(ctx: string|CanvasRenderingContext2D, x: number, y: number)", }, - "checkBgm": { + checkBgm: { "!doc": "检查bgm状态", - "!type": "fn()" + "!type": "fn()", }, - "setDisplayScale": { + setDisplayScale: { "!doc": "设置屏幕放缩", - "!type": "fn(delta: number)" + "!type": "fn(delta: number)", }, - "speedDownReplay": { + speedDownReplay: { "!doc": "减速播放", - "!type": "fn()" + "!type": "fn()", }, - "getRealStatus": { - "!doc": "计算主角的某个属性,包括百分比修正
例如:core.getRealStatus('atk'); // 计算主角的攻击力,包括百分比修正。战斗使用的就是这个值
name: 属性的英文名,请注意只能用于数值类属性哦,否则乘法会得到NaN", - "!type": "fn(name: string)" + getRealStatus: { + "!doc": + "计算主角的某个属性,包括百分比修正
例如:core.getRealStatus('atk'); // 计算主角的攻击力,包括百分比修正。战斗使用的就是这个值
name: 属性的英文名,请注意只能用于数值类属性哦,否则乘法会得到NaN", + "!type": "fn(name: string)", }, - "saveData": { + saveData: { "!doc": "存档到本地", - "!type": "fn()" + "!type": "fn()", }, - "unregisterAnimationFrame": { + unregisterAnimationFrame: { "!doc": "注销一个animationFrame", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "tryMoveDirectly": { - "!doc": "尝试瞬移,如果该点有图块/事件/阻激夹域捕则会瞬移到它旁边再走一步(不可踏入的话当然还是触发该点事件),这一步的方向优先和瞬移前主角的朝向一致
例如:core.tryMoveDirectly(6, 0); // 尝试瞬移到地图顶部的正中央,以样板0层为例,实际效果是瞬移到了上楼梯下面一格然后向上走一步并触发上楼事件
destX: 目标点的横坐标
destY: 目标点的纵坐标", - "!type": "fn(destX: number, destY: number)" + tryMoveDirectly: { + "!doc": + "尝试瞬移,如果该点有图块/事件/阻激夹域捕则会瞬移到它旁边再走一步(不可踏入的话当然还是触发该点事件),这一步的方向优先和瞬移前主角的朝向一致
例如:core.tryMoveDirectly(6, 0); // 尝试瞬移到地图顶部的正中央,以样板0层为例,实际效果是瞬移到了上楼梯下面一格然后向上走一步并触发上楼事件
destX: 目标点的横坐标
destY: 目标点的纵坐标", + "!type": "fn(destX: number, destY: number)", }, - "moveDirectly": { + moveDirectly: { "!doc": "瞬间移动", - "!type": "fn(destX?: number, destY?: number, ignoreSteps?: number)" + "!type": "fn(destX?: number, destY?: number, ignoreSteps?: number)", }, - "clearRouteFolding": { + clearRouteFolding: { "!doc": "清空录像折叠信息", - "!type": "fn()" + "!type": "fn()", }, - "checkRouteFolding": { + checkRouteFolding: { "!doc": "检查录像折叠信息", - "!type": "fn()" + "!type": "fn()", }, - "setSwitch": { + setSwitch: { "!doc": "设置某个独立开关", - "!type": "fn(x: number, y: number, floorId: string, name: string, value: ?)" + "!type": + "fn(x: number, y: number, floorId: string, name: string, value: ?)", }, - "getSwitch": { + getSwitch: { "!doc": "获得某个独立开关", - "!type": "fn(x: number, y: number, floorId: string, name: string, defaultValue?: ?)" + "!type": + "fn(x: number, y: number, floorId: string, name: string, defaultValue?: ?)", }, - "addSwitch": { + addSwitch: { "!doc": "增加某个独立开关", - "!type": "fn(x: number, y: number, floorId: string, name: string, value: number)" + "!type": + "fn(x: number, y: number, floorId: string, name: string, value: number)", }, - "removeSwitch": { + removeSwitch: { "!doc": "删除某个独立开关", - "!type": "fn(x: number, y: number, floorId: string, name: string)" + "!type": "fn(x: number, y: number, floorId: string, name: string)", }, - "removeSwitch": { + removeSwitch: { "!doc": "判定某个独立开关", - "!type": "fn(x: number, y: number, floorId: string, name: string) -> bool" - } + "!type": + "fn(x: number, y: number, floorId: string, name: string) -> bool", + }, }, - "icons": { + icons: { "!doc": "图标信息", - "getTilesetOffset": { + getTilesetOffset: { "!doc": "根据图块数字或ID获得所在的tileset和坐标信息", - "!type": "fn(id?: string) -> {image: ?, x: number, y: number}" + "!type": "fn(id?: string) -> {image: ?, x: number, y: number}", }, - "getClsFromId": { + getClsFromId: { "!doc": "根据ID获得其图标类型", - "!type": "fn(id?: string) -> string" + "!type": "fn(id?: string) -> string", }, - "getAllIconIds": { + getAllIconIds: { "!doc": "获得所有图标的ID", - "!type": "fn() -> [string]" + "!type": "fn() -> [string]", }, - "getIcons": { + getIcons: { "!doc": "获得所有图标类型", - "!type": "fn()" - } + "!type": "fn()", + }, }, - "items": { + items: { "!doc": "道具相关的函数", - "getEquip": { - "!doc": "检查主角某种类型的装备目前是什么
例如:core.getEquip(1) // 主角目前装备了什么盾牌
equipType: 装备类型,自然数
返回值:装备id,null表示未穿戴", - "!type": "fn(equipType: number) -> string" + getEquip: { + "!doc": + "检查主角某种类型的装备目前是什么
例如:core.getEquip(1) // 主角目前装备了什么盾牌
equipType: 装备类型,自然数
返回值:装备id,null表示未穿戴", + "!type": "fn(equipType: number) -> string", }, - "loadEquip": { - "!doc": "尝试穿上某件背包里面的装备并提示
例如:core.loadEquip('sword5') // 尝试装备上背包里面的神圣剑,无回调
equipId: 装备id
callback: 穿戴成功或失败后的回调函数", - "!type": "fn(equipId: string, callback?: fn())" + loadEquip: { + "!doc": + "尝试穿上某件背包里面的装备并提示
例如:core.loadEquip('sword5') // 尝试装备上背包里面的神圣剑,无回调
equipId: 装备id
callback: 穿戴成功或失败后的回调函数", + "!type": "fn(equipId: string, callback?: fn())", }, - "itemCount": { - "!doc": "统计某种道具的持有量
例如:core.itemCount('yellowKey') // 持有多少把黄钥匙
itemId: 道具id
返回值:该种道具的持有量,不包括已穿戴的装备", - "!type": "fn(itemId: string) -> number" + itemCount: { + "!doc": + "统计某种道具的持有量
例如:core.itemCount('yellowKey') // 持有多少把黄钥匙
itemId: 道具id
返回值:该种道具的持有量,不包括已穿戴的装备", + "!type": "fn(itemId: string) -> number", }, - "getItems": { + getItems: { "!doc": "获得所有道具", - "!type": "fn()" + "!type": "fn()", }, - "canUseItem": { - "!doc": "检查能否使用某种道具
例如:core.canUseItem('pickaxe') // 能否使用破墙镐
itemId: 道具id
返回值:true表示可以使用", - "!type": "fn(itemId: string) -> bool" + canUseItem: { + "!doc": + "检查能否使用某种道具
例如:core.canUseItem('pickaxe') // 能否使用破墙镐
itemId: 道具id
返回值:true表示可以使用", + "!type": "fn(itemId: string) -> bool", }, - "hasItem": { - "!doc": "检查主角是否持有某种道具(不包括已穿戴的装备)
例如:core.hasItem('yellowKey') // 主角是否持有黄钥匙
itemId: 道具id
返回值:true表示持有", - "!type": "fn(itemId: string) -> bool" + hasItem: { + "!doc": + "检查主角是否持有某种道具(不包括已穿戴的装备)
例如:core.hasItem('yellowKey') // 主角是否持有黄钥匙
itemId: 道具id
返回值:true表示持有", + "!type": "fn(itemId: string) -> bool", }, - "addItem": { - "!doc": "静默增减某种道具的持有量 不会更新游戏画面或是显示提示
例如:core.addItem('yellowKey', -2) // 没收两把黄钥匙
itemId: 道具id
itemNum: 增加量,负数表示没收", - "!type": "fn(itemId: string, itemNum?: number)" + addItem: { + "!doc": + "静默增减某种道具的持有量 不会更新游戏画面或是显示提示
例如:core.addItem('yellowKey', -2) // 没收两把黄钥匙
itemId: 道具id
itemNum: 增加量,负数表示没收", + "!type": "fn(itemId: string, itemNum?: number)", }, - "unloadEquip": { - "!doc": "脱下某个类型的装备
例如:core.unloadEquip(1) // 卸下盾牌,无回调
equipType: 装备类型编号,自然数
callback: 卸下装备后的回调函数", - "!type": "fn(equipType: number, callback?: fn())" + unloadEquip: { + "!doc": + "脱下某个类型的装备
例如:core.unloadEquip(1) // 卸下盾牌,无回调
equipType: 装备类型编号,自然数
callback: 卸下装备后的回调函数", + "!type": "fn(equipType: number, callback?: fn())", }, - "quickLoadEquip": { - "!doc": "快速换装
例如:core.quickLoadEquip(1) // 快速换上1号套装
index: 套装编号,自然数", - "!type": "fn(index: number)" + quickLoadEquip: { + "!doc": + "快速换装
例如:core.quickLoadEquip(1) // 快速换上1号套装
index: 套装编号,自然数", + "!type": "fn(index: number)", }, - "getItemEffect": { - "!doc": "即捡即用类的道具获得时的效果
例如:core.getItemEffect('redPotion', 10) // 执行获得10瓶红血的效果
itemId: 道具id
itemNum: 道具数量,可选,默认为1", - "!type": "fn(itemId: string, itemNum?: number)" + getItemEffect: { + "!doc": + "即捡即用类的道具获得时的效果
例如:core.getItemEffect('redPotion', 10) // 执行获得10瓶红血的效果
itemId: 道具id
itemNum: 道具数量,可选,默认为1", + "!type": "fn(itemId: string, itemNum?: number)", }, - "quickSaveEquip": { - "!doc": "保存当前套装
例如:core.quickSaveEquip(1) // 将当前套装保存为1号套装
index: 套装编号,自然数", - "!type": "fn(index: number)" + quickSaveEquip: { + "!doc": + "保存当前套装
例如:core.quickSaveEquip(1) // 将当前套装保存为1号套装
index: 套装编号,自然数", + "!type": "fn(index: number)", }, - "setItem": { - "!doc": "设置某种道具的持有量
例如:core.setItem('yellowKey', 3) // 设置黄钥匙为3把
itemId: 道具id
itemNum: 新的持有量,可选,自然数,默认为0", - "!type": "fn(itemId: string, itemNum?: number)" + setItem: { + "!doc": + "设置某种道具的持有量
例如:core.setItem('yellowKey', 3) // 设置黄钥匙为3把
itemId: 道具id
itemNum: 新的持有量,可选,自然数,默认为0", + "!type": "fn(itemId: string, itemNum?: number)", }, - "compareEquipment": { - "!doc": "比较两件(类型可不同)装备的优劣
例如:core.compareEquipment('sword5', 'shield5') // 比较神圣剑和神圣盾的优劣
compareEquipId: 装备甲的id
beComparedEquipId: 装备乙的id
返回值:两装备的各属性差,甲减乙,0省略", - "!type": "fn(compareEquipId: string, beComparedEquipId: string) -> {value: ?, percentage: ?}" + compareEquipment: { + "!doc": + "比较两件(类型可不同)装备的优劣
例如:core.compareEquipment('sword5', 'shield5') // 比较神圣剑和神圣盾的优劣
compareEquipId: 装备甲的id
beComparedEquipId: 装备乙的id
返回值:两装备的各属性差,甲减乙,0省略", + "!type": + "fn(compareEquipId: string, beComparedEquipId: string) -> {value: ?, percentage: ?}", }, - "removeItem": { + removeItem: { "!doc": "删除某个物品", - "!type": "fn(itemId?: string, itemNum?: number)" + "!type": "fn(itemId?: string, itemNum?: number)", }, - "getEquipTypeById": { - "!doc": "判定某件装备的类型
例如:core.getEquipTypeById('shield5') // 1(盾牌)
equipId: 装备id
返回值:类型编号,自然数", - "!type": "fn(equipId: string) -> number" + getEquipTypeById: { + "!doc": + "判定某件装备的类型
例如:core.getEquipTypeById('shield5') // 1(盾牌)
equipId: 装备id
返回值:类型编号,自然数", + "!type": "fn(equipId: string) -> number", }, - "getEquipTypeByName": { + getEquipTypeByName: { "!doc": "根据类型获得一个可用的装备孔", - "!type": "fn(name?: string)" + "!type": "fn(name?: string)", }, - "useItem": { - "!doc": "使用一个道具
例如:core.useItem('pickaxe', true) // 使用破墙镐,不计入录像,无回调
itemId: 道具id
noRoute: 是否不计入录像,快捷键使用的请填true,否则可省略
callback: 道具使用完毕或使用失败后的回调函数", - "!type": "fn(itemId: string, noRoute?: bool, callback?: fn())" + useItem: { + "!doc": + "使用一个道具
例如:core.useItem('pickaxe', true) // 使用破墙镐,不计入录像,无回调
itemId: 道具id
noRoute: 是否不计入录像,快捷键使用的请填true,否则可省略
callback: 道具使用完毕或使用失败后的回调函数", + "!type": "fn(itemId: string, noRoute?: bool, callback?: fn())", }, - "hasEquip": { - "!doc": "检查主角是否穿戴着某件装备
例如:core.hasEquip('sword5') // 主角是否装备了神圣剑
itemId: 装备id
返回值:true表示已装备", - "!type": "fn(itemId: string) -> bool" + hasEquip: { + "!doc": + "检查主角是否穿戴着某件装备
例如:core.hasEquip('sword5') // 主角是否装备了神圣剑
itemId: 装备id
返回值:true表示已装备", + "!type": "fn(itemId: string) -> bool", }, - "getItemEffectTip": { - "!doc": "即捡即用类的道具获得时的额外提示
例如:core.getItemEffectTip(redPotion) // (获得 红血瓶)',生命+100'
itemId: 道具id
返回值:图块属性itemEffectTip的内容", - "!type": "fn(itemId: string) -> string" + getItemEffectTip: { + "!doc": + "即捡即用类的道具获得时的额外提示
例如:core.getItemEffectTip(redPotion) // (获得 红血瓶)',生命+100'
itemId: 道具id
返回值:图块属性itemEffectTip的内容", + "!type": "fn(itemId: string) -> string", }, - "canEquip": { - "!doc": "检查能否穿上某件装备
例如:core.canEquip('sword5', true) // 主角可以装备神圣剑吗,如果不能会有提示
equipId: 装备id
hint: 无法穿上时是否提示(比如是因为未持有还是别的什么原因)
返回值:true表示可以穿上,false表示无法穿上", - "!type": "fn(equipId: string, hint?: bool) -> bool" + canEquip: { + "!doc": + "检查能否穿上某件装备
例如:core.canEquip('sword5', true) // 主角可以装备神圣剑吗,如果不能会有提示
equipId: 装备id
hint: 无法穿上时是否提示(比如是因为未持有还是别的什么原因)
返回值:true表示可以穿上,false表示无法穿上", + "!type": "fn(equipId: string, hint?: bool) -> bool", + }, + setEquip: { + "!doc": + "设置某个装备的属性并计入存档
例如:core.setEquip('sword1', 'value', 'atk', 300, '+='); // 设置铁剑的攻击力数值再加300
equipId: 装备id
valueType: 增幅类型,只能是value(数值)或percentage(百分比)
name: 要修改的属性名称,如atk
value: 要修改到的属性数值
operator: 操作符,可选,如+=表示在原始值上增加
prefix: 独立开关前缀,一般不需要", + "!type": + "fn(equipId: string, valueType: string, name: string, value: ?, operator?: string, prefix?: string)", }, - "setEquip": { - "!doc": "设置某个装备的属性并计入存档
例如:core.setEquip('sword1', 'value', 'atk', 300, '+='); // 设置铁剑的攻击力数值再加300
equipId: 装备id
valueType: 增幅类型,只能是value(数值)或percentage(百分比)
name: 要修改的属性名称,如atk
value: 要修改到的属性数值
operator: 操作符,可选,如+=表示在原始值上增加
prefix: 独立开关前缀,一般不需要", - "!type": "fn(equipId: string, valueType: string, name: string, value: ?, operator?: string, prefix?: string)" - } }, - "utils": { + utils: { "!doc": "工具函数库,里面有各个样板中使用到的工具函数。", - "scan": { + scan: { "!doc": "朝向到x,y映射", - "up": { - "x": "number", - "y": "number" + up: { + x: "number", + y: "number", }, - "down": { - "x": "number", - "y": "number" + down: { + x: "number", + y: "number", }, - "left": { - "x": "number", - "y": "number" + left: { + x: "number", + y: "number", + }, + right: { + x: "number", + y: "number", }, - "right": { - "x": "number", - "y": "number" - } }, - "applyEasing": { + applyEasing: { "!doc": "获得变速移动曲线", - "!type": "fn(mode?: string) -> fn(t: number) -> number" + "!type": "fn(mode?: string) -> fn(t: number) -> number", }, - "clamp": { - "!doc": "将x限定在[a,b]区间内,注意a和b可交换
例如:core.clamp(1200, 1, 1000); // 1000
x: 原始值,!x为true时x一律视为0
a: 下限值,大于b将导致与b交换
b: 上限值,小于a将导致与a交换", - "!type": "fn(x: number, a: number, b: number) -> number" + clamp: { + "!doc": + "将x限定在[a,b]区间内,注意a和b可交换
例如:core.clamp(1200, 1, 1000); // 1000
x: 原始值,!x为true时x一律视为0
a: 下限值,大于b将导致与b交换
b: 上限值,小于a将导致与a交换", + "!type": "fn(x: number, a: number, b: number) -> number", }, - "rand": { - "!doc": "不支持SL的随机数
例如:1 + core.rand(6); // 随机生成一个小于7的正整数,模拟骰子的效果
num: 填正数表示生成小于num的随机自然数,否则生成小于1的随机正数
返回值:随机数,即使读档也不会改变结果", - "!type": "fn(num?: number) -> number" + rand: { + "!doc": + "不支持SL的随机数
例如:1 + core.rand(6); // 随机生成一个小于7的正整数,模拟骰子的效果
num: 填正数表示生成小于num的随机自然数,否则生成小于1的随机正数
返回值:随机数,即使读档也不会改变结果", + "!type": "fn(num?: number) -> number", }, - "clone": { - "!doc": "深拷贝一个对象(函数将原样返回)
例如:core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具
data: 待拷贝对象
filter: 过滤器,可选,表示data为数组或对象时拷贝哪些项或属性,true表示拷贝
recursion: 过滤器是否递归,可选。true表示过滤器也被递归
返回值:拷贝的结果,注意函数将原样返回", - "!type": "fn(data?: ?, filter?: fn(name: string, value: ?) -> bool, recursion?: bool)" + clone: { + "!doc": + "深拷贝一个对象(函数将原样返回)
例如:core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具
data: 待拷贝对象
filter: 过滤器,可选,表示data为数组或对象时拷贝哪些项或属性,true表示拷贝
recursion: 过滤器是否递归,可选。true表示过滤器也被递归
返回值:拷贝的结果,注意函数将原样返回", + "!type": + "fn(data?: ?, filter?: fn(name: string, value: ?) -> bool, recursion?: bool)", }, - "cloneArray": { - "!doc": "深拷贝一个1D或2D数组对象
例如:core.cloneArray(core.status.thisMap.map)", - "!type": "fn(data?: [number]|[[number]]) -> [number]|[[number]]" + cloneArray: { + "!doc": + "深拷贝一个1D或2D数组对象
例如:core.cloneArray(core.status.thisMap.map)", + "!type": "fn(data?: [number]|[[number]]) -> [number]|[[number]]", }, - "setLocalForage": { + setLocalForage: { "!doc": "往数据库写入一段数据", - "!type": "fn(key: string, value?: ?, successCallback?: fn(), errorCallback?: fn())" + "!type": + "fn(key: string, value?: ?, successCallback?: fn(), errorCallback?: fn())", }, - "getGlobal": { - "!doc": "读取一个全局存储,适用于global:xxx,支持录像。
例如:if (core.getGlobal('一周目已通关', false) === true) core.getItem('dagger'); // 二周目游戏进行到此处时会获得一把屠龙匕首
key: 全局变量名称,支持中文
defaultValue: 可选,当此全局变量不存在或值为null、undefined时,用此值代替
返回值:全局变量的值", - "!type": "fn(key: string, defaultValue?: ?)" + getGlobal: { + "!doc": + "读取一个全局存储,适用于global:xxx,支持录像。
例如:if (core.getGlobal('一周目已通关', false) === true) core.getItem('dagger'); // 二周目游戏进行到此处时会获得一把屠龙匕首
key: 全局变量名称,支持中文
defaultValue: 可选,当此全局变量不存在或值为null、undefined时,用此值代替
返回值:全局变量的值", + "!type": "fn(key: string, defaultValue?: ?)", }, - "replaceText": { - "!doc": "将一段文字中的${}(表达式)进行替换。
例如:core.replaceText('衬衫的价格是${status:hp}镑${item:yellowKey}便士。'); // 把主角的生命值和持有的黄钥匙数量代入这句话
text: 模板字符串,可以使用${}计算js表达式,支持“状态、物品、变量、独立开关、全局存储、图块id、图块类型、敌人数据、装备id”等量参与运算
返回值:替换完毕后的字符串", - "!type": "fn(text: string, prefix?: string) -> string" + replaceText: { + "!doc": + "将一段文字中的${}(表达式)进行替换。
例如:core.replaceText('衬衫的价格是${status:hp}镑${item:yellowKey}便士。'); // 把主角的生命值和持有的黄钥匙数量代入这句话
text: 模板字符串,可以使用${}计算js表达式,支持“状态、物品、变量、独立开关、全局存储、图块id、图块类型、敌人数据、装备id”等量参与运算
返回值:替换完毕后的字符串", + "!type": "fn(text: string, prefix?: string) -> string", }, - "removeLocalStorage": { + removeLocalStorage: { "!doc": "移除本地存储", - "!type": "fn(key: string)" + "!type": "fn(key: string)", }, - "unzip": { + unzip: { "!doc": "解压一段内容", - "!type": "fn(blobOrUrl?: ?, success?: fn(data: ?), error?: fn(error: string), convertToText?: bool, onprogress?: fn(loaded: number, total: number))" + "!type": + "fn(blobOrUrl?: ?, success?: fn(data: ?), error?: fn(error: string), convertToText?: bool, onprogress?: fn(loaded: number, total: number))", }, - "formatTime": { + formatTime: { "!doc": "格式化时间", - "!type": "fn(time: number) -> string" + "!type": "fn(time: number) -> string", }, - "readFile": { - "!doc": "尝试请求读取一个本地文件内容 [异步]
success: 成功后的回调
error: 失败后的回调
readType: 不设置则以文本读取,否则以DataUrl形式读取", - "!type": "fn(success?: fn(data: string), error?: fn(message: string), readType?: bool)" + readFile: { + "!doc": + "尝试请求读取一个本地文件内容 [异步]
success: 成功后的回调
error: 失败后的回调
readType: 不设置则以文本读取,否则以DataUrl形式读取", + "!type": + "fn(success?: fn(data: string), error?: fn(message: string), readType?: bool)", }, - "readFileContent": { + readFileContent: { "!doc": "文件读取完毕后的内容处理 [异步]", - "!type": "fn(content: string)" + "!type": "fn(content: string)", }, - "formatDate": { + formatDate: { "!doc": "格式化日期为字符串", - "!type": "fn(date: ?) -> string" + "!type": "fn(date: ?) -> string", }, - "download": { - "!doc": "弹窗请求下载一个文本文件
例如:core.download('route.txt', JSON.stringify(core.status.route)); // 弹窗请求下载录像
filename: 文件名
content: 文件内容", - "!type": "fn(filename: string, content: string)" + download: { + "!doc": + "弹窗请求下载一个文本文件
例如:core.download('route.txt', JSON.stringify(core.status.route)); // 弹窗请求下载录像
filename: 文件名
content: 文件内容", + "!type": "fn(filename: string, content: string)", }, - "encodeBase64": { - "!doc": "base64加密
例如:core.encodeBase64('abcd'); // 'YWJjZA=='
str: 明文
返回值:密文", - "!type": "fn(str: string) -> string" + encodeBase64: { + "!doc": + "base64加密
例如:core.encodeBase64('abcd'); // 'YWJjZA=='
str: 明文
返回值:密文", + "!type": "fn(str: string) -> string", }, - "strlen": { - "!doc": "求字符串的国标码字节数,也可用于等宽字体下文本的宽度测算。请注意样板的默认字体Verdana不是等宽字体
例如:core.strlen('无敌ad'); // 6
str: 待测字符串
返回值:字符串的国标码字节数,每个汉字为2,每个ASCII字符为1", - "!type": "fn(str: string) -> number" + strlen: { + "!doc": + "求字符串的国标码字节数,也可用于等宽字体下文本的宽度测算。请注意样板的默认字体Verdana不是等宽字体
例如:core.strlen('无敌ad'); // 6
str: 待测字符串
返回值:字符串的国标码字节数,每个汉字为2,每个ASCII字符为1", + "!type": "fn(str: string) -> number", }, - "myprompt": { + myprompt: { "!doc": "让用户输入一段文字", - "!type": "fn(hint: string, value: string, callback?: fn(data?: string))" + "!type": + "fn(hint: string, value: string, callback?: fn(data?: string))", }, - "getCookie": { + getCookie: { "!doc": "访问浏览器cookie", - "!type": "fn(name: string) -> string" + "!type": "fn(name: string) -> string", }, - "decodeRoute": { - "!doc": "录像解压的最后一步,即一压的逆过程
例如:core.decodeRoute(core.encodeRoute(core.status.route)); // 一压当前录像再解压-_-|
route: 录像解压倒数第二步的结果,即一压的结果
返回值:原始录像", - "!type": "fn(route: string) -> [string]" + decodeRoute: { + "!doc": + "录像解压的最后一步,即一压的逆过程
例如:core.decodeRoute(core.encodeRoute(core.status.route)); // 一压当前录像再解压-_-|
route: 录像解压倒数第二步的结果,即一压的结果
返回值:原始录像", + "!type": "fn(route: string) -> [string]", }, - "formatDate2": { + formatDate2: { "!doc": "格式化日期为最简字符串", - "!type": "fn(date: ?) -> string" + "!type": "fn(date: ?) -> string", }, - "unshift": { - "!doc": "将b(可以是另一个数组)插入数组a的开头,此函数用于弥补a.unshift(b)中b只能是单项的不足。
例如:core.unshift(todo, {type: 'unfollow'}); // 在事件指令数组todo的开头插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新首项或前缀数组
返回值:插入完毕后的新数组,它是改变原数组a本身得到的", - "!type": "fn(a: [?], b: ?) -> [?]" + unshift: { + "!doc": + "将b(可以是另一个数组)插入数组a的开头,此函数用于弥补a.unshift(b)中b只能是单项的不足。
例如:core.unshift(todo, {type: 'unfollow'}); // 在事件指令数组todo的开头插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新首项或前缀数组
返回值:插入完毕后的新数组,它是改变原数组a本身得到的", + "!type": "fn(a: [?], b: ?) -> [?]", }, - "same": { - "!doc": "判定深层相等, 会逐层比较每个元素
例如:core.same(['1', 2], ['1', 2]); // true", - "!type": "fn(a?: ?, b?: ?) -> bool" + same: { + "!doc": + "判定深层相等, 会逐层比较每个元素
例如:core.same(['1', 2], ['1', 2]); // true", + "!type": "fn(a?: ?, b?: ?) -> bool", }, - "setTwoDigits": { + setTwoDigits: { "!doc": "两位数显示", - "!type": "fn(x: number) -> string" + "!type": "fn(x: number) -> string", }, - "splitImage": { - "!doc": "等比例切分一张图片
例如:core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人
image: 图片名(支持映射前的中文名)或图片对象(参见上面的例子),获取不到时返回[]
width: 子图的宽度,单位为像素。原图总宽度必须是其倍数,不填视为32
height: 子图的高度,单位为像素。原图总高度必须是其倍数,不填视为正方形
返回值:子图组成的数组,在原图中呈先行后列,从左到右、从上到下排列。", - "!type": "fn(image?: string|image, width?: number, height?: number) -> [image]" + splitImage: { + "!doc": + "等比例切分一张图片
例如:core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人
image: 图片名(支持映射前的中文名)或图片对象(参见上面的例子),获取不到时返回[]
width: 子图的宽度,单位为像素。原图总宽度必须是其倍数,不填视为32
height: 子图的高度,单位为像素。原图总高度必须是其倍数,不填视为正方形
返回值:子图组成的数组,在原图中呈先行后列,从左到右、从上到下排列。", + "!type": + "fn(image?: string|image, width?: number, height?: number) -> [image]", }, - "decompress": { + decompress: { "!doc": "解压缩一个数据", - "!type": "fn(value: ?)" + "!type": "fn(value: ?)", }, - "showWithAnimate": { + showWithAnimate: { "!doc": "动画显示某对象", - "!type": "fn(obj?: ?, speed?: number, callback?: fn())" + "!type": "fn(obj?: ?, speed?: number, callback?: fn())", }, - "subarray": { - "!doc": "判定一个数组是否为另一个数组的前缀,用于录像接续播放。请注意函数名没有大写字母
例如:core.subarray(['ad', '米库', '小精灵', '小破草', '小艾'], ['ad', '米库', '小精灵']); // ['小破草', '小艾']
a: 可能的母数组,不填或比b短将返回null
b: 可能的前缀,不填或比a长将返回null
返回值:如果b不是a的前缀将返回null,否则将返回a去掉此前缀后的剩余数组", - "!type": "fn(a?: [?], b?: [?]) -> [?]|null" + subarray: { + "!doc": + "判定一个数组是否为另一个数组的前缀,用于录像接续播放。请注意函数名没有大写字母
例如:core.subarray(['ad', '米库', '小精灵', '小破草', '小艾'], ['ad', '米库', '小精灵']); // ['小破草', '小艾']
a: 可能的母数组,不填或比b短将返回null
b: 可能的前缀,不填或比a长将返回null
返回值:如果b不是a的前缀将返回null,否则将返回a去掉此前缀后的剩余数组", + "!type": "fn(a?: [?], b?: [?]) -> [?]|null", }, - "turnDirection": { - "!doc": "计算应当转向某个方向
turn: 转向的方向,可为 up,down,left,right,:left,:right,:back 七种
direction: 当前方向", - "!type": "fn(turn: string, direction?: string) -> string" + turnDirection: { + "!doc": + "计算应当转向某个方向
turn: 转向的方向,可为 up,down,left,right,:left,:right,:back 七种
direction: 当前方向", + "!type": "fn(turn: string, direction?: string) -> string", }, - "myconfirm": { - "!doc": "显示确认框,类似core.drawConfirmBox(),但不打断事件流
例如:core.myconfirm('重启游戏?', core.restart); // 弹窗询问玩家是否重启游戏
hint: 弹窗的内容,支持 ${} 语法
yesCallback: 确定后的回调函数
noCallback: 取消后的回调函数,可选", - "!type": "fn(hint: string, yesCallback?: fn(), noCallback?: fn())" + myconfirm: { + "!doc": + "显示确认框,类似core.drawConfirmBox(),但不打断事件流
例如:core.myconfirm('重启游戏?', core.restart); // 弹窗询问玩家是否重启游戏
hint: 弹窗的内容,支持 ${} 语法
yesCallback: 确定后的回调函数
noCallback: 取消后的回调函数,可选", + "!type": "fn(hint: string, yesCallback?: fn(), noCallback?: fn())", }, - "calValue": { - "!doc": "计算一个表达式的值,支持status:xxx等的计算。
例如:core.calValue('status:hp + status:def'); // 计算主角的生命值加防御力
value: 待求值的表达式
prefix: 独立开关前缀,一般可省略
返回值:求出的值", - "!type": "fn(value: string, prefix?: string)" + calValue: { + "!doc": + "计算一个表达式的值,支持status:xxx等的计算。
例如:core.calValue('status:hp + status:def'); // 计算主角的生命值加防御力
value: 待求值的表达式
prefix: 独立开关前缀,一般可省略
返回值:求出的值", + "!type": "fn(value: string, prefix?: string)", }, - "encodeRoute": { - "!doc": "录像压缩缩
例如:core.encodeRoute(core.status.route); // 压缩当前录像
route: 原始录像,自定义内容(不予压缩,原样写入)必须由0-9A-Za-z和下划线、冒号组成,所以中文和数组需要用JSON.stringify预处理再base64压缩才能交由一压
返回值:一压的结果", - "!type": "fn(route: [string]) -> string" + encodeRoute: { + "!doc": + "录像压缩缩
例如:core.encodeRoute(core.status.route); // 压缩当前录像
route: 原始录像,自定义内容(不予压缩,原样写入)必须由0-9A-Za-z和下划线、冒号组成,所以中文和数组需要用JSON.stringify预处理再base64压缩才能交由一压
返回值:一压的结果", + "!type": "fn(route: [string]) -> string", }, - "decodeBase64": { - "!doc": "base64解密
例如:core.decodeBase64('YWJjZA=='); // \"abcd\"
str: 密文
返回值:明文", - "!type": "fn(str: string) -> string" + decodeBase64: { + "!doc": + "base64解密
例如:core.decodeBase64('YWJjZA=='); // \"abcd\"
str: 密文
返回值:明文", + "!type": "fn(str: string) -> string", }, - "http": { - "!doc": "发送一个HTTP请求 [异步]
type: 请求类型,只能为GET或POST
url: 目标地址
formData: 如果是POST请求则为表单数据
success: 成功后的回调
error: 失败后的回调", - "!type": "fn(type: string, url: string, formData: ?, success?: fn(data: string), error?: fn(message: string), mimeType?: string, responseType?: string, onprogress?: fn(loaded: number, total: number))" + http: { + "!doc": + "发送一个HTTP请求 [异步]
type: 请求类型,只能为GET或POST
url: 目标地址
formData: 如果是POST请求则为表单数据
success: 成功后的回调
error: 失败后的回调", + "!type": + "fn(type: string, url: string, formData: ?, success?: fn(data: string), error?: fn(message: string), mimeType?: string, responseType?: string, onprogress?: fn(loaded: number, total: number))", }, - "getGuid": { + getGuid: { "!doc": "获得或生成浏览器唯一的guid", - "!type": "fn() -> string" + "!type": "fn() -> string", }, - "getLocalStorage": { + getLocalStorage: { "!doc": "获得本地存储", - "!type": "fn(key: string, defaultValue?: ?)" + "!type": "fn(key: string, defaultValue?: ?)", }, - "arrayToRGB": { - "!doc": "颜色数组转字符串
例如:core.arrayToRGB([102, 204, 255]); // \"#66ccff\"
color: 一行三列的数组,必须为不大于255的自然数
返回值:该颜色的#xxxxxx字符串表示", - "!type": "fn(color: [number]) -> string" + arrayToRGB: { + "!doc": + '颜色数组转字符串
例如:core.arrayToRGB([102, 204, 255]); // "#66ccff"
color: 一行三列的数组,必须为不大于255的自然数
返回值:该颜色的#xxxxxx字符串表示', + "!type": "fn(color: [number]) -> string", }, - "arrayToRGBA": { - "!doc": "颜色数组转字符串
例如:core.arrayToRGBA([102, 204, 255, 0.3]); // \"rgba(102,204,255,0.3)\"
color: 一行三列或一行四列的数组,前三个元素必须为不大于255的自然数。第四个元素(如果有)必须为0或不大于1的数字,第四个元素不填视为1
返回值:该颜色的rgba(...)字符串表示", - "!type": "fn(color: [number]) -> string" + arrayToRGBA: { + "!doc": + '颜色数组转字符串
例如:core.arrayToRGBA([102, 204, 255, 0.3]); // "rgba(102,204,255,0.3)"
color: 一行三列或一行四列的数组,前三个元素必须为不大于255的自然数。第四个元素(如果有)必须为0或不大于1的数字,第四个元素不填视为1
返回值:该颜色的rgba(...)字符串表示', + "!type": "fn(color: [number]) -> string", }, - "formatBigNumber": { - "!doc": "大数字格式化,单位为10000的倍数(w,e,z,j,g),末尾四舍五入
例如:core.formatBigNumber(123456789, false); // \"12346w\"
x: 原数字
onMap: 可选,true表示用于地图显伤,结果总字符数最多为5,否则最多为6
返回值:格式化结果", - "!type": "fn(x: number, onMap?: bool) -> string" + formatBigNumber: { + "!doc": + '大数字格式化,单位为10000的倍数(w,e,z,j,g),末尾四舍五入
例如:core.formatBigNumber(123456789, false); // "12346w"
x: 原数字
onMap: 可选,true表示用于地图显伤,结果总字符数最多为5,否则最多为6
返回值:格式化结果', + "!type": "fn(x: number, onMap?: bool) -> string", }, - "removeLocalForage": { + removeLocalForage: { "!doc": "移除本地数据库的数据", - "!type": "fn(key: string, successCallback?: fn(), errorCallback?: fn())" + "!type": + "fn(key: string, successCallback?: fn(), errorCallback?: fn())", }, - "matchWildcard": { - "!doc": "通配符匹配,用于搜索图块等批量处理。
例如:core.playSound(core.matchWildcard('*Key', itemId) ? 'item.mp3' : 'door.mp3'); // 判断捡到的是钥匙还是别的道具,从而播放不同的音效
pattern: 模式串,每个星号表示任意多个(0个起)字符
string: 待测串
返回值:true表示匹配成功,false表示匹配失败", - "!type": "fn(pattern: string, string: string) -> bool" + matchWildcard: { + "!doc": + "通配符匹配,用于搜索图块等批量处理。
例如:core.playSound(core.matchWildcard('*Key', itemId) ? 'item.opus' : 'door.opus'); // 判断捡到的是钥匙还是别的道具,从而播放不同的音效
pattern: 模式串,每个星号表示任意多个(0个起)字符
string: 待测串
返回值:true表示匹配成功,false表示匹配失败", + "!type": "fn(pattern: string, string: string) -> bool", }, - "setLocalStorage": { + setLocalStorage: { "!doc": "设置本地存储", - "!type": "fn(key: string, value?: ?)" + "!type": "fn(key: string, value?: ?)", }, - "hideWithAnimate": { + hideWithAnimate: { "!doc": "动画使某对象消失", - "!type": "fn(obj?: ?, speed?: number, callback?: fn())" + "!type": "fn(obj?: ?, speed?: number, callback?: fn())", }, - "copy": { + copy: { "!doc": "尝试复制一段文本到剪切板。", - "!type": "fn(data: string) -> bool" + "!type": "fn(data: string) -> bool", }, - "isset": { - "!doc": "判断一个值是否不为null,undefined和NaN
例如:core.isset(0/0); // false,因为0/0等于NaN
v: 待测值,可选
返回值:false表示待测值为null、undefined、NaN或未填写,true表示为其他值。", - "!type": "fn(v?: ?) -> bool" + isset: { + "!doc": + "判断一个值是否不为null,undefined和NaN
例如:core.isset(0/0); // false,因为0/0等于NaN
v: 待测值,可选
返回值:false表示待测值为null、undefined、NaN或未填写,true表示为其他值。", + "!type": "fn(v?: ?) -> bool", }, - "replaceValue": { - "!doc": "对一个表达式中的特殊规则进行替换,如status:xxx等。
例如:core.replaceValue('status:atk+item:yellowKey'); // 把这两个冒号表达式替换为core.getStatus('hp')和core.itemCount('yellowKey')这样的函数调用
value: 模板字符串,注意独立开关不会被替换
返回值:替换完毕后的字符串", - "!type": "fn(value: string) -> string" + replaceValue: { + "!doc": + "对一个表达式中的特殊规则进行替换,如status:xxx等。
例如:core.replaceValue('status:atk+item:yellowKey'); // 把这两个冒号表达式替换为core.getStatus('hp')和core.itemCount('yellowKey')这样的函数调用
value: 模板字符串,注意独立开关不会被替换
返回值:替换完毕后的字符串", + "!type": "fn(value: string) -> string", }, - "getLocalForage": { + getLocalForage: { "!doc": "从本地数据库读出一段数据", - "!type": "fn(key: string, defaultValue?: ?, successCallback?: fn(data: ?), errorCallback?: fn())" + "!type": + "fn(key: string, defaultValue?: ?, successCallback?: fn(data: ?), errorCallback?: fn())", }, - "inArray": { - "!doc": "判定array是不是一个数组,以及element是否在该数组中。
array: 可能的数组,不为数组或不填将导致返回值为false
element: 待查找的元素
返回值:如果array为数组且具有element这项,就返回true,否则返回false", - "!type": "fn(array?: ?, element?: ?) -> bool" + inArray: { + "!doc": + "判定array是不是一个数组,以及element是否在该数组中。
array: 可能的数组,不为数组或不填将导致返回值为false
element: 待查找的元素
返回值:如果array为数组且具有element这项,就返回true,否则返回false", + "!type": "fn(array?: ?, element?: ?) -> bool", }, - "setGlobal": { - "!doc": "设置一个全局存储,适用于global:xxx,录像播放时将忽略此函数。
例如:core.setBlobal('一周目已通关', true); // 设置全局存储“一周目已通关”为true,方便二周目游戏中的新要素。
key: 全局变量名称,支持中文
value: 全局变量的新值,不填或null表示清除此全局存储", - "!type": "fn(key: string, value?: ?)" + setGlobal: { + "!doc": + "设置一个全局存储,适用于global:xxx,录像播放时将忽略此函数。
例如:core.setBlobal('一周目已通关', true); // 设置全局存储“一周目已通关”为true,方便二周目游戏中的新要素。
key: 全局变量名称,支持中文
value: 全局变量的新值,不填或null表示清除此全局存储", + "!type": "fn(key: string, value?: ?)", }, - "rand2": { - "!doc": "支持SL的随机数,并计入录像
例如:1 + core.rand2(6); // 随机生成一个小于7的正整数,模拟骰子的效果
num: 正整数,0或不填会被视为2147483648
返回值:属于 [0, num) 的随机数", - "!type": "fn(num?: number) -> number" + rand2: { + "!doc": + "支持SL的随机数,并计入录像
例如:1 + core.rand2(6); // 随机生成一个小于7的正整数,模拟骰子的效果
num: 正整数,0或不填会被视为2147483648
返回值:属于 [0, num) 的随机数", + "!type": "fn(num?: number) -> number", }, - "setStatusBarInnerHTML": { - "!doc": "填写非自绘状态栏
例如:core.setStatusBarInnerHTML('hp', core.status.hero.hp, 'color: #66CCFF'); // 更新状态栏中的主角生命,使用加载画面的宣传色
name: 状态栏项的名称,如'hp', 'atk', 'def'等。必须是core.statusBar中的一个合法项
value: 要填写的内容,大数字会被格式化为至多6个字符,无中文的内容会被自动设为斜体
css: 额外的css样式,可选。如更改颜色等", - "!type": "fn(name: string, value: ?, css?: string)" + setStatusBarInnerHTML: { + "!doc": + "填写非自绘状态栏
例如:core.setStatusBarInnerHTML('hp', core.status.hero.hp, 'color: #66CCFF'); // 更新状态栏中的主角生命,使用加载画面的宣传色
name: 状态栏项的名称,如'hp', 'atk', 'def'等。必须是core.statusBar中的一个合法项
value: 要填写的内容,大数字会被格式化为至多6个字符,无中文的内容会被自动设为斜体
css: 额外的css样式,可选。如更改颜色等", + "!type": "fn(name: string, value: ?, css?: string)", }, - "matchRegex": { + matchRegex: { "!doc": "是否满足正则表达式", - "!type": "fn(pattern: string, string: string) -> string" + "!type": "fn(pattern: string, string: string) -> string", }, - "push": { - "!doc": "将b(可以是另一个数组)插入数组a的末尾,此函数用于弥补a.push(b)中b只能是单项的不足。
例如:core.push(todo, {type: 'unfollow'}); // 在事件指令数组todo的末尾插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新末项或后缀数组
返回值:插入完毕后的新数组,它是改变原数组a本身得到的", - "!type": "fn(a: [?], b: ?) -> [?]" + push: { + "!doc": + "将b(可以是另一个数组)插入数组a的末尾,此函数用于弥补a.push(b)中b只能是单项的不足。
例如:core.push(todo, {type: 'unfollow'}); // 在事件指令数组todo的末尾插入“取消所有跟随者”指令
a: 原数组
b: 待插入的新末项或后缀数组
返回值:插入完毕后的新数组,它是改变原数组a本身得到的", + "!type": "fn(a: [?], b: ?) -> [?]", }, - "formatSize": { + formatSize: { "!doc": "格式化文件大小", - "!type": "fn(size: number) -> string" - } + "!type": "fn(size: number) -> string", + }, }, - "actions": { + actions: { "!doc": "主要是处理一些和用户交互相关的内容。", - "onup": { + onup: { "!doc": "当点击(触摸)事件放开时", - "!type": "fn(loc: {x: number, y: number, size: number})" + "!type": "fn(loc: {x: number, y: number, size: number})", }, - "pressKey": { + pressKey: { "!doc": "按住某个键时", - "!type": "fn(keyCode: number)" + "!type": "fn(keyCode: number)", }, - "keyUp": { + keyUp: { "!doc": "根据放开键的code来执行一系列操作", - "!type": "fn(keyCode: number, altKey?: bool, fromReplay?: bool)" + "!type": "fn(keyCode: number, altKey?: bool, fromReplay?: bool)", }, - "ondown": { + ondown: { "!doc": "点击(触摸)事件按下时", - "!type": "fn(loc: {x: number, y: number, size: number})" + "!type": "fn(loc: {x: number, y: number, size: number})", }, - "registerAction": { - "!doc": "此函数将注册一个用户交互行为。
action: 要注册的交互类型,如 ondown, onclick, keyDown 等等。
name: 你的自定义名称,可被注销使用;同名重复注册将后者覆盖前者。
func: 执行函数。
如果func返回true,则不会再继续执行其他的交互函数;否则会继续执行其他的交互函数。
priority: 优先级;优先级高的将会被执行。此项可不填,默认为0", - "!type": "fn(action: string, name: string, func: string|fn(params: ?), priority?: number)" + registerAction: { + "!doc": + "此函数将注册一个用户交互行为。
action: 要注册的交互类型,如 ondown, onclick, keyDown 等等。
name: 你的自定义名称,可被注销使用;同名重复注册将后者覆盖前者。
func: 执行函数。
如果func返回true,则不会再继续执行其他的交互函数;否则会继续执行其他的交互函数。
priority: 优先级;优先级高的将会被执行。此项可不填,默认为0", + "!type": + "fn(action: string, name: string, func: string|fn(params: ?), priority?: number)", }, - "onkeyDown": { + onkeyDown: { "!doc": "按下某个键时", - "!type": "fn(e: Event)" + "!type": "fn(e: Event)", }, - "keyDown": { + keyDown: { "!doc": "根据按下键的code来执行一系列操作", - "!type": "fn(keyCode: number)" + "!type": "fn(keyCode: number)", }, - "onStatusBarClick": { + onStatusBarClick: { "!doc": "点击自绘状态栏时", - "!type": "fn(e?: Event)" + "!type": "fn(e?: Event)", }, - "longClick": { + longClick: { "!doc": "长按", - "!type": "fn(x: number, y: number, px: number, py: number, fromEvent?: bool)" + "!type": + "fn(x: number, y: number, px: number, py: number, fromEvent?: bool)", }, - "unregisterAction": { + unregisterAction: { "!doc": "注销一个用户交互行为", - "!type": "fn(action: string, name: string)" + "!type": "fn(action: string, name: string)", }, - "keyDownCtrl": { + keyDownCtrl: { "!doc": "长按Ctrl键时", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "onclick": { + onclick: { "!doc": "具体点击屏幕上(x,y)点时,执行的操作", - "!type": "fn(x: number, y: number, px: number, py: number, stepPostfix?: [?])" + "!type": + "fn(x: number, y: number, px: number, py: number, stepPostfix?: [?])", }, - "doRegisteredAction": { + doRegisteredAction: { "!doc": "执行一个用户交互行为", - "!type": "fn(action: string, params: ?)" + "!type": "fn(action: string, params: ?)", }, - "onkeyUp": { + onkeyUp: { "!doc": "放开某个键时", - "!type": "fn(e: Event)" + "!type": "fn(e: Event)", }, - "onmousewheel": { + onmousewheel: { "!doc": "滑动鼠标滚轮时的操作", - "!type": "fn(direct: number)" + "!type": "fn(direct: number)", }, - "onmove": { + onmove: { "!doc": "当在触摸屏上滑动时", - "!type": "fn(loc: {x: number, y: number, size: number})" - } + "!type": "fn(loc: {x: number, y: number, size: number})", + }, }, - "loader": { + loader: { "!doc": "资源加载相关的函数", - "loadImages": { + loadImages: { "!doc": "加载一系列图片", - "!type": "fn(dir: string, names: [string], toSave: ?, callback?: fn()) " + "!type": + "fn(dir: string, names: [string], toSave: ?, callback?: fn()) ", }, - "loadImagesFromZip": { + loadImagesFromZip: { "!doc": "从zip中加载一系列图片", - "!type": "fn(url: string, names: [string], toSave?: ?, onprogress?: ?, onfinished?: ?)" + "!type": + "fn(url: string, names: [string], toSave?: ?, onprogress?: ?, onfinished?: ?)", }, - "loadBgm": { + loadBgm: { "!doc": "加载一个bgm", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "loadOneMusic": { + loadOneMusic: { "!doc": "加载一个音乐或音效", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "freeBgm": { + freeBgm: { "!doc": "释放一个bgm的缓存", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "loadOneSound": { + loadOneSound: { "!doc": "加载一个音效", - "!type": "fn(name: string)" + "!type": "fn(name: string)", }, - "loadImage": { + loadImage: { "!doc": "加载某一张图片", - "!type": "fn(dir: name, imgName: name, callback?: fn())" - } + "!type": "fn(dir: name, imgName: name, callback?: fn())", + }, }, - "maps": { - "!doc": "负责一切和地图相关的处理内容,包括如下几个方面:
- 地图的初始化,保存和读取,地图数组的生成
- 是否可移动或瞬间移动的判定
- 地图的绘制
- 获得某个点的图块信息
- 启用和禁用图块,改变图块
- 移动/跳跃图块,淡入淡出图块
- 全局动画控制,动画的绘制", - "noPass": { - "!doc": "判定某个点是否不可被踏入(不基于主角生命值和图块cannotIn属性)
例如:core.noPass(0, 0); // 判断地图左上角能否被踏入
x: 目标点的横坐标
y: 目标点的纵坐标
floorId: 目标点所在的地图id,不填视为当前地图
返回值:true表示可踏入", - "!type": "fn(x: number, y: number, floorId?: string) -> bool" + maps: { + "!doc": + "负责一切和地图相关的处理内容,包括如下几个方面:
- 地图的初始化,保存和读取,地图数组的生成
- 是否可移动或瞬间移动的判定
- 地图的绘制
- 获得某个点的图块信息
- 启用和禁用图块,改变图块
- 移动/跳跃图块,淡入淡出图块
- 全局动画控制,动画的绘制", + noPass: { + "!doc": + "判定某个点是否不可被踏入(不基于主角生命值和图块cannotIn属性)
例如:core.noPass(0, 0); // 判断地图左上角能否被踏入
x: 目标点的横坐标
y: 目标点的纵坐标
floorId: 目标点所在的地图id,不填视为当前地图
返回值:true表示可踏入", + "!type": "fn(x: number, y: number, floorId?: string) -> bool", }, - "drawAnimate": { - "!doc": "播放动画,注意即使指定了主角的坐标也不会跟随主角移动,如有需要请使用core.drawHeroAnimate(name, callback)函数
例如:core.drawAnimate('attack', core.nextX(), core.nextY(), false, core.vibrate); // 在主角面前一格播放普攻动画,动画停止后视野左右抖动1秒
name: 动画文件名,不含后缀
x: 横坐标
y: 纵坐标
alignWindow: 是否是相对窗口的坐标
callback: 动画停止后的回调函数,可选
返回值:一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数)", - "!type": "fn(name: string, x: number, y: number, alignWindow: bool, callback?: fn()) -> number" + drawAnimate: { + "!doc": + "播放动画,注意即使指定了主角的坐标也不会跟随主角移动,如有需要请使用core.drawHeroAnimate(name, callback)函数
例如:core.drawAnimate('attack', core.nextX(), core.nextY(), false, core.vibrate); // 在主角面前一格播放普攻动画,动画停止后视野左右抖动1秒
name: 动画文件名,不含后缀
x: 横坐标
y: 纵坐标
alignWindow: 是否是相对窗口的坐标
callback: 动画停止后的回调函数,可选
返回值:一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数)", + "!type": + "fn(name: string, x: number, y: number, alignWindow: bool, callback?: fn()) -> number", }, - "drawHeroAnimate": { - "!doc": "播放跟随勇士的动画
name: 动画名
callback: 动画停止后的回调函数,可选
返回值:一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数)", - "!type": "fn(name: string, callback?: fn()) -> number" + drawHeroAnimate: { + "!doc": + "播放跟随勇士的动画
name: 动画名
callback: 动画停止后的回调函数,可选
返回值:一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数)", + "!type": "fn(name: string, callback?: fn()) -> number", }, - "stopAnimate": { - "!doc": "立刻停止一个动画播放
id: 播放动画的编号,即drawAnimate或drawHeroAnimate的返回值;不填视为所有动画br/>doCallback: 是否执行该动画的回调函数", - "!type": "fn(id?: number, doCallback?: bool)" + stopAnimate: { + "!doc": + "立刻停止一个动画播放
id: 播放动画的编号,即drawAnimate或drawHeroAnimate的返回值;不填视为所有动画br/>doCallback: 是否执行该动画的回调函数", + "!type": "fn(id?: number, doCallback?: bool)", }, - "getPlayingAnimates": { - "!doc": "获得当前正在播放的所有(指定)动画的id列表
name: 动画名;不填代表返回全部正在播放的动画
返回值: 一个数组,每一项为一个正在播放的动画;可用core.stopAnimate停止播放。", - "!type": "fn(name?: string) -> [number]" + getPlayingAnimates: { + "!doc": + "获得当前正在播放的所有(指定)动画的id列表
name: 动画名;不填代表返回全部正在播放的动画
返回值: 一个数组,每一项为一个正在播放的动画;可用core.stopAnimate停止播放。", + "!type": "fn(name?: string) -> [number]", }, - "getBlockCls": { - "!doc": "判定某个点的图块类型
例如:if(core.getBlockCls(x1, y1) != 'enemys' && core.getBlockCls(x2, y2) != 'enemy48') core.openDoor(x3, y3); // 另一个简单的机关门事件,打败或炸掉这一对不同身高的敌人就开门
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块类型,即“地形、四帧动画、矮敌人、高敌人、道具、矮npc、高npc、自动元件、额外地形”之一", - "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string" + getBlockCls: { + "!doc": + "判定某个点的图块类型
例如:if(core.getBlockCls(x1, y1) != 'enemys' && core.getBlockCls(x2, y2) != 'enemy48') core.openDoor(x3, y3); // 另一个简单的机关门事件,打败或炸掉这一对不同身高的敌人就开门
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块类型,即“地形、四帧动画、矮敌人、高敌人、道具、矮npc、高npc、自动元件、额外地形”之一", + "!type": + "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string", }, - "drawMap": { - "!doc": "地图重绘
例如:core.drawMap(); // 重绘当前地图,常用于更改贴图或改变自动元件后的刷新
floorId: 地图id,可省略表示当前楼层
callback: 重绘完毕后的回调函数,可选", - "!type": "fn(floorId?: string)" + drawMap: { + "!doc": + "地图重绘
例如:core.drawMap(); // 重绘当前地图,常用于更改贴图或改变自动元件后的刷新
floorId: 地图id,可省略表示当前楼层
callback: 重绘完毕后的回调函数,可选", + "!type": "fn(floorId?: string)", }, - "nearStair": { + nearStair: { "!doc": "当前位置是否在楼梯边;在楼传平面塔模式下对箭头也有效", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "turnBlock": { + turnBlock: { "!doc": "事件转向", - "!type": "fn(direction?: string, x?: number, y?: number, floorId?: string)" + "!type": + "fn(direction?: string, x?: number, y?: number, floorId?: string)", }, - "getMapArray": { - "!doc": "生成事件层矩阵
例如:core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵,隐藏的图块视为0
floorId: 地图id,不填视为当前地图
showDisable: 可选,true表示隐藏的图块也会被表示出来
返回值:事件层矩阵,注意对其阵元的访问是[y][x]", - "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]" + getMapArray: { + "!doc": + "生成事件层矩阵
例如:core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵,隐藏的图块视为0
floorId: 地图id,不填视为当前地图
showDisable: 可选,true表示隐藏的图块也会被表示出来
返回值:事件层矩阵,注意对其阵元的访问是[y][x]", + "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]", }, - "getMapNumber": { + getMapNumber: { "!doc": "获得事件层某个点的数字", - "!type": "fn(x: number, y: number, floorId?: string, noCache?: bool) -> number" + "!type": + "fn(x: number, y: number, floorId?: string, noCache?: bool) -> number", }, - "jumpBlock": { - "!doc": "跳跃图块;从V2.7开始不再有音效
例如:core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒,再花半秒淡出
sx: 起点的横坐标
sy: 起点的纵坐标
ex: 终点的横坐标
ey: 终点的纵坐标
time: 单步和淡出用时,单位为毫秒。不填视为半秒
keep: 是否不淡出,true表示不淡出
callback: 落地或淡出后的回调函数,可选", - "!type": "fn(sx: number, sy: number, ex: number, ey: number, time?: number, keep?: bool, callback?: fn())" + jumpBlock: { + "!doc": + "跳跃图块;从V2.7开始不再有音效
例如:core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒,再花半秒淡出
sx: 起点的横坐标
sy: 起点的纵坐标
ex: 终点的横坐标
ey: 终点的纵坐标
time: 单步和淡出用时,单位为毫秒。不填视为半秒
keep: 是否不淡出,true表示不淡出
callback: 落地或淡出后的回调函数,可选", + "!type": + "fn(sx: number, sy: number, ex: number, ey: number, time?: number, keep?: bool, callback?: fn())", }, - "replaceBlock": { - "!doc": "批量替换图块
例如:core.replaceBlock(21, 22, core.floorIds); // 把游戏中地上当前所有的黄钥匙都变成蓝钥匙
fromNumber: 旧图块的数字
toNumber: 新图块的数字
floorId: 地图id或其数组,不填视为当前地图", - "!type": "fn(fromNumber: number, toNumber: number, floorId?: string|[string])" + replaceBlock: { + "!doc": + "批量替换图块
例如:core.replaceBlock(21, 22, core.floorIds); // 把游戏中地上当前所有的黄钥匙都变成蓝钥匙
fromNumber: 旧图块的数字
toNumber: 新图块的数字
floorId: 地图id或其数组,不填视为当前地图", + "!type": + "fn(fromNumber: number, toNumber: number, floorId?: string|[string])", }, - "drawBlock": { + drawBlock: { "!doc": "绘制一个图块", - "!type": "fn(block?: block, animate?: number)" + "!type": "fn(block?: block, animate?: number)", }, - "resetMap": { + resetMap: { "!doc": "重置地图", - "!type": "fn(floorId?: string|[string])" + "!type": "fn(floorId?: string|[string])", }, - "animateSetBlock": { + animateSetBlock: { "!doc": "动画形式转变某点图块", - "!type": "fn(number: number|string, x: number, y: number, floorId?: string, time?: number, callback?: fn())" + "!type": + "fn(number: number|string, x: number, y: number, floorId?: string, time?: number, callback?: fn())", }, - "animateSetBlocks": { + animateSetBlocks: { "!doc": "动画形式同时转变若干点图块", - "!type": "fn(number: number|string, locs: [?], floorId?: string, time?: number, callback?: fn())" + "!type": + "fn(number: number|string, locs: [?], floorId?: string, time?: number, callback?: fn())", }, - "compressMap": { + compressMap: { "!doc": "压缩地图", - "!type": "fn(mapArr: [[number]], floorId?: string) -> [[number]]" + "!type": "fn(mapArr: [[number]], floorId?: string) -> [[number]]", }, - "enemyExists": { + enemyExists: { "!doc": "某个点是否存在(指定的)怪物", - "!type": "fn(x: number, y: number, id?: string, floorId?: string) -> bool" + "!type": + "fn(x: number, y: number, id?: string, floorId?: string) -> bool", }, - "npcExists": { + npcExists: { "!doc": "某个点是否存在NPC", - "!type": "fn(x: number, y: number, floorId?: string) -> bool" + "!type": "fn(x: number, y: number, floorId?: string) -> bool", }, - "getBlockByNumber": { + getBlockByNumber: { "!doc": "根据数字获得图块", - "!type": "fn(number: number) -> block" + "!type": "fn(number: number) -> block", }, - "removeBlock": { - "!doc": "删除一个图块,对应于「隐藏事件」并同时删除
例如:core.removeBlock(0, 0); // 尝试删除地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", - "!type": "fn(x: number, y: number, floorId?: string)" + removeBlock: { + "!doc": + "删除一个图块,对应于「隐藏事件」并同时删除
例如:core.removeBlock(0, 0); // 尝试删除地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", + "!type": "fn(x: number, y: number, floorId?: string)", }, - "hideBlock": { - "!doc": "隐藏一个图块,对应于「隐藏事件」且不删除
例如:core.hideBlock(0, 0); // 隐藏地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", - "!type": "fn(x: number, y: number, floorId?: string)" + hideBlock: { + "!doc": + "隐藏一个图块,对应于「隐藏事件」且不删除
例如:core.hideBlock(0, 0); // 隐藏地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", + "!type": "fn(x: number, y: number, floorId?: string)", }, - "removeBlockByIndex": { + removeBlockByIndex: { "!doc": "根据block的索引删除该块", - "!type": "fn(index: number, floorId?: string)" + "!type": "fn(index: number, floorId?: string)", }, - "stairExists": { + stairExists: { "!doc": "某个点是否存在楼梯", - "!type": "fn(x: number, y: number, floorId?: string) -> bool" + "!type": "fn(x: number, y: number, floorId?: string) -> bool", }, - "isMapBlockDisabled": { + isMapBlockDisabled: { "!doc": "某个点图块是否被强制启用或禁用", - "!type": "fn(floorId?: string, x?: number, y?: number, flags?: ?) -> bool" + "!type": + "fn(floorId?: string, x?: number, y?: number, flags?: ?) -> bool", }, - "setMapBlockDisabled": { + setMapBlockDisabled: { "!doc": "设置某个点图块的强制启用或禁用状态", - "!type": "fn(floorId?: string, x?: number, y?: number, disabled?: bool)" + "!type": + "fn(floorId?: string, x?: number, y?: number, disabled?: bool)", }, - "setBlockOpacity": { + setBlockOpacity: { "!doc": "设置某个点图块的不透明度", - "!type": "fn(opacity?: number, x?: number, y?: number, floorId?: string)" + "!type": + "fn(opacity?: number, x?: number, y?: number, floorId?: string)", }, - "setBlockFilter": { + setBlockFilter: { "!doc": "设置某个点图块的特效", - "!type": "fn(filter?: ?, x?: number, y?: number, floorId?: string)" + "!type": "fn(filter?: ?, x?: number, y?: number, floorId?: string)", }, - "decompressMap": { + decompressMap: { "!doc": "解压缩地图", - "!type": "fn(mapArr: [[number]], floorId?: string) -> [[number]]" + "!type": "fn(mapArr: [[number]], floorId?: string) -> [[number]]", }, - "automaticRoute": { - "!doc": "自动寻路
例如:core.automaticRoute(0, 0); // 自动寻路到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值:每步走完后主角的loc属性组成的一维数组", - "!type": "fn(destX: number, destY: number) -> [{x: number, y: number, direction: string}]" + automaticRoute: { + "!doc": + "自动寻路
例如:core.automaticRoute(0, 0); // 自动寻路到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值:每步走完后主角的loc属性组成的一维数组", + "!type": + "fn(destX: number, destY: number) -> [{x: number, y: number, direction: string}]", }, - "resizeMap": { + resizeMap: { "!doc": "更改地图画布的尺寸", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "getFgNumber": { - "!doc": "判定某点的前景层的数字
例如:core.getFgNumber(); // 判断主角脚下的前景层图块的数字
x: 横坐标,不填为勇士坐标
y: 纵坐标,不填为勇士坐标floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存而强制重算", - "!type": "fn(x: number, y: number, floorId?: string, noCache?: bool) -> number" + getFgNumber: { + "!doc": + "判定某点的前景层的数字
例如:core.getFgNumber(); // 判断主角脚下的前景层图块的数字
x: 横坐标,不填为勇士坐标
y: 纵坐标,不填为勇士坐标floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存而强制重算", + "!type": + "fn(x: number, y: number, floorId?: string, noCache?: bool) -> number", }, - "moveBlock": { - "!doc": "移动图块
例如:core.moveBlock(0, 0, ['down']); // 令地图左上角的图块下移一格
x: 起点的横坐标
y: 起点的纵坐标
steps: 步伐数组
time: 单步和淡出用时,单位为毫秒。不填视为半秒
keep: 是否不淡出,true表示不淡出
callback: 移动或淡出后的回调函数,可选", - "!type": "fn(x: number, y: number, steps: [string], time?: number, keep?: bool, callback?: fn())" + moveBlock: { + "!doc": + "移动图块
例如:core.moveBlock(0, 0, ['down']); // 令地图左上角的图块下移一格
x: 起点的横坐标
y: 起点的纵坐标
steps: 步伐数组
time: 单步和淡出用时,单位为毫秒。不填视为半秒
keep: 是否不淡出,true表示不淡出
callback: 移动或淡出后的回调函数,可选", + "!type": + "fn(x: number, y: number, steps: [string], time?: number, keep?: bool, callback?: fn())", }, - "getBgNumber": { - "!doc": "判定某点的背景层的数字
例如:core.getBgNumber(); // 判断主角脚下的背景层图块的数字
x: 横坐标,不填为勇士坐标
y: 纵坐标,不填为勇士坐标
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存而强制重算", - "!type": "fn(x?: number, y?: number, floorId?: string, noCache?: bool) -> number" + getBgNumber: { + "!doc": + "判定某点的背景层的数字
例如:core.getBgNumber(); // 判断主角脚下的背景层图块的数字
x: 横坐标,不填为勇士坐标
y: 纵坐标,不填为勇士坐标
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存而强制重算", + "!type": + "fn(x?: number, y?: number, floorId?: string, noCache?: bool) -> number", }, - "getIdOfThis": { + getIdOfThis: { "!doc": "获得当前事件点的ID", - "!type": "fn(id?: string) -> string" + "!type": "fn(id?: string) -> string", }, - "searchBlock": { - "!doc": "搜索图块, 支持通配符和正则表达式
例如:core.searchBlock('*Door'); // 搜索当前地图的所有门
id: 图块id,支持星号表示任意多个(0个起)字符
floorId: 地图id或数组,不填视为当前地图
showDisable: 隐藏点是否计入,true表示计入
返回值:一个详尽的数组,一般只用到其长度", - "!type": "fn(id: string, floorId?: string|[string], showDisable?: bool) -> [{floorId: string, index: number, x: number, y: number, block: block}]" + searchBlock: { + "!doc": + "搜索图块, 支持通配符和正则表达式
例如:core.searchBlock('*Door'); // 搜索当前地图的所有门
id: 图块id,支持星号表示任意多个(0个起)字符
floorId: 地图id或数组,不填视为当前地图
showDisable: 隐藏点是否计入,true表示计入
返回值:一个详尽的数组,一般只用到其长度", + "!type": + "fn(id: string, floorId?: string|[string], showDisable?: bool) -> [{floorId: string, index: number, x: number, y: number, block: block}]", }, - "searchBlockWithFilter": { - "!doc": "根据给定的筛选函数搜索全部满足条件的图块
例如:core.searchBlockWithFilter(function (block) { return block.event.id.endsWith('Door'); }); // 搜索当前地图的所有门
blockFilter: 筛选函数,可接受block输入,应当返回一个boolean值
floorId: 地图id或数组,不填视为当前地图
showDisable: 隐藏点是否计入,true表示计入
返回值:一个详尽的数组", - "!type": "fn(blockFilter: fn(block: block) -> bool, floorId?: string|[string], showDisable?: bool): [{floorId: string, index: number, x: number, y: number, block: block}]" + searchBlockWithFilter: { + "!doc": + "根据给定的筛选函数搜索全部满足条件的图块
例如:core.searchBlockWithFilter(function (block) { return block.event.id.endsWith('Door'); }); // 搜索当前地图的所有门
blockFilter: 筛选函数,可接受block输入,应当返回一个boolean值
floorId: 地图id或数组,不填视为当前地图
showDisable: 隐藏点是否计入,true表示计入
返回值:一个详尽的数组", + "!type": + "fn(blockFilter: fn(block: block) -> bool, floorId?: string|[string], showDisable?: bool): [{floorId: string, index: number, x: number, y: number, block: block}]", }, - "hideBgFgMap": { + hideBgFgMap: { "!doc": "隐藏前景/背景地图", - "!type": "fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())" + "!type": + "fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())", }, - "getBlockInfo": { - "!doc": "获得某个图块或素材的信息,包括ID,cls,图片,坐标,faceIds等等", - "!type": "fn(block?: number|string|block) -> blockInfo" + getBlockInfo: { + "!doc": + "获得某个图块或素材的信息,包括ID,cls,图片,坐标,faceIds等等", + "!type": "fn(block?: number|string|block) -> blockInfo", }, - "getFaceDownId": { - "!doc": "获得某个图块对应行走图朝向向下的那一项的id;如果不存在行走图绑定则返回自身id。", - "!type": "fn(block?: string|number|block) -> string" + getFaceDownId: { + "!doc": + "获得某个图块对应行走图朝向向下的那一项的id;如果不存在行走图绑定则返回自身id。", + "!type": "fn(block?: string|number|block) -> string", }, - "canMoveDirectlyArray": { + canMoveDirectlyArray: { "!doc": "获得某些点可否通行的信息", - "!type": "fn(locs?: [[number]])" + "!type": "fn(locs?: [[number]])", }, - "hideFloorImage": { + hideFloorImage: { "!doc": "隐藏一个楼层贴图", - "!type": "fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())" + "!type": + "fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())", }, - "extractBlocks": { + extractBlocks: { "!doc": "根据需求解析出blocks", - "!type": "fn(map?: ?)" + "!type": "fn(map?: ?)", }, - "extractBlocksForUI": { + extractBlocksForUI: { "!doc": "根据需求为UI解析出blocks", - "!type": "fn(map?: ?, flags?: ?)" + "!type": "fn(map?: ?, flags?: ?)", }, - "getBlockId": { - "!doc": "判定某个点的图块id
例如:if(core.getBlockId(x1, y1) != 'greenSlime' && core.getBlockId(x2, y2) != 'redSlime') core.openDoor(x3, y3); // 一个简单的机关门事件,打败或炸掉这一对绿头怪和红头怪就开门
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块id,该点无图块则返回null", - "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string" + getBlockId: { + "!doc": + "判定某个点的图块id
例如:if(core.getBlockId(x1, y1) != 'greenSlime' && core.getBlockId(x2, y2) != 'redSlime') core.openDoor(x3, y3); // 一个简单的机关门事件,打败或炸掉这一对绿头怪和红头怪就开门
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块id,该点无图块则返回null", + "!type": + "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> string", }, - "getBlockNumber": { - "!doc": "判定某个点的图块数字
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块数字,该点无图块则返回null", - "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> number" + getBlockNumber: { + "!doc": + "判定某个点的图块数字
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图
showDisable: 隐藏点是否不返回null,true表示不返回null
返回值:图块数字,该点无图块则返回null", + "!type": + "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> number", }, - "getBlockOpacity": { + getBlockOpacity: { "!doc": "获得某个点图块的不透明度", - "!type": "fn(x?: number, y?: number, floorId?: string, showDisable?: bool) -> number" + "!type": + "fn(x?: number, y?: number, floorId?: string, showDisable?: bool) -> number", }, - "getBlockFilter": { + getBlockFilter: { "!doc": "获得某个点图块的特效", - "!type": "fn(x?: number, y?: number, floorId?: string, showDisable?: bool) -> ?" + "!type": + "fn(x?: number, y?: number, floorId?: string, showDisable?: bool) -> ?", }, - "loadFloor": { + loadFloor: { "!doc": "从文件或存档中加载某个楼层", - "!type": "fn(floorId?: string, map?: ?)" + "!type": "fn(floorId?: string, map?: ?)", }, - "generateMovableArray": { - "!doc": "可通行性判定
例如:core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id,不填视为当前地图
返回值:从各点可移动方向的三维数组", - "!type": "fn(floorId?: string) -> [[[string]]]" + generateMovableArray: { + "!doc": + "可通行性判定
例如:core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动
floorId: 地图id,不填视为当前地图
返回值:从各点可移动方向的三维数组", + "!type": "fn(floorId?: string) -> [[[string]]]", }, - "terrainExists": { + terrainExists: { "!doc": "某个点是否存在(指定的)地形", - "!type": "fn(x: number, y: number, id?: string, floorId?: string) -> bool" + "!type": + "fn(x: number, y: number, id?: string, floorId?: string) -> bool", }, - "getBlockById": { + getBlockById: { "!doc": "根据ID获得图块", - "!type": "fn(id: string) -> block" + "!type": "fn(id: string) -> block", }, - "drawBg": { - "!doc": "绘制背景层(含贴图,其与背景层矩阵的绘制顺序可通过复写此函数来改变)
例如:core.drawBg(); // 绘制当前地图的背景层
floorId: 地图id,不填视为当前地图
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", - "!type": "fn(floorId?: string, ctx?: CanvasRenderingContext2D)" + drawBg: { + "!doc": + "绘制背景层(含贴图,其与背景层矩阵的绘制顺序可通过复写此函数来改变)
例如:core.drawBg(); // 绘制当前地图的背景层
floorId: 地图id,不填视为当前地图
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", + "!type": "fn(floorId?: string, ctx?: CanvasRenderingContext2D)", }, - "showBlock": { - "!doc": "显示(隐藏或显示的)图块,此函数将被“显示事件”指令和勾选了“不消失”的“移动/跳跃事件”指令(如阻击怪)的终点调用
例如:core.showBlock(0, 0); // 显示地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", - "!type": "fn(x: number, y: number, floorId?: string)" + showBlock: { + "!doc": + "显示(隐藏或显示的)图块,此函数将被“显示事件”指令和勾选了“不消失”的“移动/跳跃事件”指令(如阻击怪)的终点调用
例如:core.showBlock(0, 0); // 显示地图左上角的图块
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", + "!type": "fn(x: number, y: number, floorId?: string)", }, - "getMapBlocksObj": { + getMapBlocksObj: { "!doc": "以x,y的形式返回每个点的事件", - "!type": "fn(floorId?: string, noCache?: bool)" + "!type": "fn(floorId?: string, noCache?: bool)", }, - "removeGlobalAnimate": { + removeGlobalAnimate: { "!doc": "删除一个或所有全局动画", - "!type": "fn(x?: number, y?: number, name?: string)" + "!type": "fn(x?: number, y?: number, name?: string)", }, - "drawEvents": { - "!doc": "绘制事件层
例如:core.drawEvents(); // 绘制当前地图的事件层
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", - "!type": "fn(floorId?: string, blocks?: [block], ctx?: CanvasRenderingContext2D)" + drawEvents: { + "!doc": + "绘制事件层
例如:core.drawEvents(); // 绘制当前地图的事件层
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", + "!type": + "fn(floorId?: string, blocks?: [block], ctx?: CanvasRenderingContext2D)", }, - "canMoveDirectly": { - "!doc": "能否瞬移到某点,并求出节约的步数。
例如:core.canMoveDirectly(0, 0); // 能否瞬移到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值:正数表示节约的步数,-1表示不可瞬移", - "!type": "fn(destX: number, destY: number) -> number" + canMoveDirectly: { + "!doc": + "能否瞬移到某点,并求出节约的步数。
例如:core.canMoveDirectly(0, 0); // 能否瞬移到地图左上角
destX: 目标点的横坐标
destY: 目标点的纵坐标
返回值:正数表示节约的步数,-1表示不可瞬移", + "!type": "fn(destX: number, destY: number) -> number", }, - "saveMap": { + saveMap: { "!doc": "将当前地图重新变成数字,以便于存档", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "drawBoxAnimate": { + drawBoxAnimate: { "!doc": "绘制UI层的box动画", - "!type": "fn()" + "!type": "fn()", }, - "setBgFgBlock": { - "!doc": "转变图层块
例如:core.setBgFgBlock('bg', 167, 6, 6); // 把当前地图背景层的中心块改为滑冰
name: 背景还是前景
number: 新图层块的数字(也支持纯数字字符串如'1')或id
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", - "!type": "fn(name: string, number: number|string, x: number, y: number, floorId?: string)" + setBgFgBlock: { + "!doc": + "转变图层块
例如:core.setBgFgBlock('bg', 167, 6, 6); // 把当前地图背景层的中心块改为滑冰
name: 背景还是前景
number: 新图层块的数字(也支持纯数字字符串如'1')或id
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", + "!type": + "fn(name: string, number: number|string, x: number, y: number, floorId?: string)", }, - "drawFg": { - "!doc": "绘制前景层(含贴图,其与前景层矩阵的绘制顺序可通过复写此函数来改变)
例如:core.drawFg(); // 绘制当前地图的前景层
floorId: 地图id,不填视为当前地图
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", - "!type": "fn(floorId?: string, ctx?: CanvasRenderingContext2D)" + drawFg: { + "!doc": + "绘制前景层(含贴图,其与前景层矩阵的绘制顺序可通过复写此函数来改变)
例如:core.drawFg(); // 绘制当前地图的前景层
floorId: 地图id,不填视为当前地图
ctx: 某画布的ctx,用于绘制缩略图,一般不需要", + "!type": "fn(floorId?: string, ctx?: CanvasRenderingContext2D)", }, - "getBlock": { + getBlock: { "!doc": "获得某个点的block", - "!type": "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> block" + "!type": + "fn(x: number, y: number, floorId?: string, showDisable?: bool) -> block", }, - "initBlock": { + initBlock: { "!doc": "初始化一个图块", - "!type": "fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?) -> block" + "!type": + "fn(x: number, y: number, id: string|number, addInfo?: bool, eventFloor?: ?) -> block", }, - "addGlobalAnimate": { + addGlobalAnimate: { "!doc": "添加一个全局动画", - "!type": "fn(block?: block)" + "!type": "fn(block?: block)", }, - "animateBlock": { + animateBlock: { "!doc": "显示/隐藏某个块时的动画效果", - "!type": "fn(loc?: [number]|[[number]], type?: string|number, time?: number, callback?: fn())" + "!type": + "fn(loc?: [number]|[[number]], type?: string|number, time?: number, callback?: fn())", }, - "loadMap": { + loadMap: { "!doc": "将存档中的地图信息重新读取出来", - "!type": "fn(data?: ?, floorId?: string, flags?: ?)" + "!type": "fn(data?: ?, floorId?: string, flags?: ?)", }, - "setBlock": { - "!doc": "转变图块
例如:core.setBlock(1, 0, 0); // 把地图左上角变成黄墙
number: 新图块的数字(也支持纯数字字符串如'1')或id
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", - "!type": "fn(number: number|string, x: number, y: number, floorId?: string)" + setBlock: { + "!doc": + "转变图块
例如:core.setBlock(1, 0, 0); // 把地图左上角变成黄墙
number: 新图块的数字(也支持纯数字字符串如'1')或id
x: 横坐标
y: 纵坐标
floorId: 地图id,不填视为当前地图", + "!type": + "fn(number: number|string, x: number, y: number, floorId?: string)", }, - "getFgMapArray": { - "!doc": "生成前景层矩阵
例如:core.getFgMapArray('MT0'); // 生成主塔0层的前景层矩阵,使用缓存
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存
返回值:前景层矩阵,注意对其阵元的访问是[y][x]", - "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]" + getFgMapArray: { + "!doc": + "生成前景层矩阵
例如:core.getFgMapArray('MT0'); // 生成主塔0层的前景层矩阵,使用缓存
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存
返回值:前景层矩阵,注意对其阵元的访问是[y][x]", + "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]", }, - "getBgMapArray": { - "!doc": "生成背景层矩阵
例如:core.getBgMapArray('MT0'); // 生成主塔0层的背景层矩阵,使用缓存
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存
返回值:背景层矩阵,注意对其阵元的访问是[y][x]", - "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]" + getBgMapArray: { + "!doc": + "生成背景层矩阵
例如:core.getBgMapArray('MT0'); // 生成主塔0层的背景层矩阵,使用缓存
floorId: 地图id,不填视为当前地图
noCache: 可选,true表示不使用缓存
返回值:背景层矩阵,注意对其阵元的访问是[y][x]", + "!type": "fn(floorId?: string, noCache?: bool) -> [[number]]", }, - "canMoveHero": { - "!doc": "单点单朝向的可通行性判定;受各图层cannotInOut、起点cannotMove和canGoDeadZone影响,不受canPass和noPass影响
x: 起点横坐标,不填视为主角当前的
y: 起点纵坐标,不填视为主角当前的
direction: 移动的方向,不填视为主角面对的方向
floorId: 地图id,不填视为当前地图", - "!type": "fn(x?: number, y?: number, direction?: string, floorId?: string) -> bool" + canMoveHero: { + "!doc": + "单点单朝向的可通行性判定;受各图层cannotInOut、起点cannotMove和canGoDeadZone影响,不受canPass和noPass影响
x: 起点横坐标,不填视为主角当前的
y: 起点纵坐标,不填视为主角当前的
direction: 移动的方向,不填视为主角面对的方向
floorId: 地图id,不填视为当前地图", + "!type": + "fn(x?: number, y?: number, direction?: string, floorId?: string) -> bool", }, - "drawThumbnail": { - "!doc": "绘制缩略图
例如:core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
options: 绘制信息,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档,同时包含要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心", - "!type": "fn(floorId?: string, blocks?: [block], options?: ?)" + drawThumbnail: { + "!doc": + "绘制缩略图
例如:core.drawThumbnail(); // 绘制当前地图的缩略图
floorId: 地图id,不填视为当前地图
blocks: 一般不需要
options: 绘制信息,可选。可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档,同时包含要绘制到的画布名或画布的ctx或还有其他信息,如起绘坐标、绘制大小、是否绘制全图、截取中心", + "!type": "fn(floorId?: string, blocks?: [block], options?: ?)", }, - "hideBlockByIndex": { + hideBlockByIndex: { "!doc": "根据图块的索引来隐藏图块", - "!type": "fn(index?: number, floorId?: string)" + "!type": "fn(index?: number, floorId?: string)", }, - "getNumberById": { - "!doc": "根据图块id得到数字(地图矩阵中的值)
例如:core.getNumberById('yellowWall'); // 1
id: 图块id
返回值:图块的数字,定义在project\\maps.js(请注意和project\\icons.js中的“图块索引”相区分!)", - "!type": "fn(id: string) -> number" + getNumberById: { + "!doc": + "根据图块id得到数字(地图矩阵中的值)
例如:core.getNumberById('yellowWall'); // 1
id: 图块id
返回值:图块的数字,定义在project\\maps.js(请注意和project\\icons.js中的“图块索引”相区分!)", + "!type": "fn(id: string) -> number", }, - "removeBlockByIndexes": { + removeBlockByIndexes: { "!doc": "一次性删除多个block", - "!type": "fn(indexes?: [number], floorId?: string)" + "!type": "fn(indexes?: [number], floorId?: string)", }, - "hideBlockByIndexes": { + hideBlockByIndexes: { "!doc": "一次性隐藏多个block", - "!type": "fn(indexes?: [number], floorId?: string)" + "!type": "fn(indexes?: [number], floorId?: string)", }, - "generateGroundPattern": { + generateGroundPattern: { "!doc": "生成groundPattern", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "showBgFgMap": { + showBgFgMap: { "!doc": "显示前景/背景地图", - "!type": "fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())" + "!type": + "fn(name?: string, loc?: [number]|[[number]], floorId?: string, callback?: fn())", }, - "showFloorImage": { + showFloorImage: { "!doc": "显示一个楼层贴图", - "!type": "fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())" - } + "!type": + "fn(loc?: [number]|[[number]], floorId?: string, callback?: fn())", + }, }, - "ui": { - "!doc": "负责一切UI界面的绘制。主要包括三个部分:
- 设置某个画布的属性与在某个画布上绘制的相关API
- 具体的某个UI界面的绘制
- 动态创建画布相关的API", - "resizeCanvas": { + ui: { + "!doc": + "负责一切UI界面的绘制。主要包括三个部分:
- 设置某个画布的属性与在某个画布上绘制的相关API
- 具体的某个UI界面的绘制
- 动态创建画布相关的API", + resizeCanvas: { "!doc": "重新设置一个自定义画布的大小", - "!type": "fn(name: string, x?: number, y?: number, styleOnly?: bool, isTempCanvas?: bool)" + "!type": + "fn(name: string, x?: number, y?: number, styleOnly?: bool, isTempCanvas?: bool)", }, - "deleteCanvas": { - "!doc": "删除一个自定义画布
name: 画布名,也可以传入一个函数对所有画布进行筛选", - "!type": "fn(name: string|fn(name: string) -> bool)" + deleteCanvas: { + "!doc": + "删除一个自定义画布
name: 画布名,也可以传入一个函数对所有画布进行筛选", + "!type": "fn(name: string|fn(name: string) -> bool)", }, - "deleteAllCanvas": { + deleteAllCanvas: { "!doc": "清空所有的自定义画布", - "!type": "fn()" + "!type": "fn()", }, - "drawIcon": { + drawIcon: { "!doc": "在某个canvas上绘制一个图标", - "!type": "fn(name: string|CanvasRenderingContext2D, id: string, x: number, y: number, w?: number, h?: number, frame?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, id: string, x: number, y: number, w?: number, h?: number, frame?: number)", }, - "drawFly": { + drawFly: { "!doc": "绘制楼层传送器", - "!type": "fn(page?: ?)" + "!type": "fn(page?: ?)", }, - "setOpacity": { - "!doc": "设置某个canvas整体的透明度;此函数直接改变画布本身,对已经绘制的内容也生效
如果仅想对接下来的绘制生效请使用setAlpha", - "!type": "fn(name: string|CanvasRenderingContext2D, opacity: number)" + setOpacity: { + "!doc": + "设置某个canvas整体的透明度;此函数直接改变画布本身,对已经绘制的内容也生效
如果仅想对接下来的绘制生效请使用setAlpha", + "!type": "fn(name: string|CanvasRenderingContext2D, opacity: number)", }, - "getTextContentHeight": { + getTextContentHeight: { "!doc": "获得某段文字的预计绘制高度;参数说明详见 drawTextContent", - "!type": "fn(content: string, config?: ?)" + "!type": "fn(content: string, config?: ?)", }, - "drawArrow": { + drawArrow: { "!doc": "在某个canvas上绘制一个箭头", - "!type": "fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)", }, - "strokeEllipse": { + strokeEllipse: { "!doc": "在某个canvas上绘制一个椭圆的边框", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string, lineWidth?: number)", }, - "fillCircle": { + fillCircle: { "!doc": "在某个canvas上绘制一个圆", "!url": "https://www.w3school.com.cn/tags/canvas_arc.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, style?: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, style?: string)", }, - "strokeRoundRect": { + strokeRoundRect: { "!doc": "在某个canvas上绘制一个圆角矩形的边框", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, lineWidth?: number, angle?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, lineWidth?: number, angle?: number)", }, - "getContextByName": { - "!doc": "根据画布名找到一个画布的context;支持系统画布和自定义画布。如果不存在画布返回null。
也可以传画布的context自身,则返回自己。", - "!type": "fn(canvas: string|CanvasRenderingContext2D) -> CanvasRenderingContext2D" + getContextByName: { + "!doc": + "根据画布名找到一个画布的context;支持系统画布和自定义画布。如果不存在画布返回null。
也可以传画布的context自身,则返回自己。", + "!type": + "fn(canvas: string|CanvasRenderingContext2D) -> CanvasRenderingContext2D", }, - "drawImage": { - "!doc": "在一个画布上绘制图片
后面的8个坐标参数与canvas的drawImage的八个参数完全相同。
name: 可以是系统画布之一,也可以是任意自定义动态创建的画布名 画布名称或者画布的context
image: 要绘制的图片,可以是一个全塔属性中定义的图片名(会从images中去获取;支持加':x',':y',':o'翻转),图片本身,或者一个画布。
angle:旋转角度", + drawImage: { + "!doc": + "在一个画布上绘制图片
后面的8个坐标参数与canvas的drawImage的八个参数完全相同。
name: 可以是系统画布之一,也可以是任意自定义动态创建的画布名 画布名称或者画布的context
image: 要绘制的图片,可以是一个全塔属性中定义的图片名(会从images中去获取;支持加':x',':y',':o'翻转),图片本身,或者一个画布。
angle:旋转角度", "!url": "http://www.w3school.com.cn/html5/canvas_drawimage.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, image: string|image, x: number, y: number, w?: number, h?: number, x1?: number, y1?: number, w1?: number, h1?: number, angle?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, image: string|image, x: number, y: number, w?: number, h?: number, x1?: number, y1?: number, w1?: number, h1?: number, angle?: number)", }, - "drawTip": { - "!doc": "左上角绘制一段提示
text: 要提示的字符串,支持${}语法
id: 要绘制的图标ID
frame: 要绘制该图标的第几帧", - "!type": "fn(text: string, id?: string, frame?: number)" + drawTip: { + "!doc": + "左上角绘制一段提示
text: 要提示的字符串,支持${}语法
id: 要绘制的图标ID
frame: 要绘制该图标的第几帧", + "!type": "fn(text: string, id?: string, frame?: number)", }, - "drawBackground": { + drawBackground: { "!doc": "绘制一个背景图,可绘制winskin或纯色背景;支持小箭头绘制", - "!type": "fn(left: string, top: string, right: string, bottom: string, posInfo?: {px: number, py: number, direction: string})" + "!type": + "fn(left: string, top: string, right: string, bottom: string, posInfo?: {px: number, py: number, direction: string})", }, - "fillEllipse": { + fillEllipse: { "!doc": "在某个canvas上绘制一个椭圆", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, a: number, b: number, angle?: number, style?: string)", }, - "setFillStyle": { + setFillStyle: { "!doc": "设置某个canvas的绘制属性(如颜色等)", "!url": "https://www.w3school.com.cn/tags/canvas_fillstyle.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, style: string)" + "!type": "fn(name: string|CanvasRenderingContext2D, style: string)", }, - "drawText": { + drawText: { "!doc": "地图中间绘制一段文字", - "!type": "fn(contents: string, callback?: fn())" + "!type": "fn(contents: string, callback?: fn())", }, - "drawConfirmBox": { - "!doc": "绘制一个确认框
此项会打断事件流,如需不打断版本的请使用core.myconfirm()
text: 要绘制的内容,支持 ${} 语法
yesCallback: 点击确认后的回调
noCallback: 点击取消后的回调", - "!type": "fn(text: string, yesCallback?: fn(), noCallback?: fn())" + drawConfirmBox: { + "!doc": + "绘制一个确认框
此项会打断事件流,如需不打断版本的请使用core.myconfirm()
text: 要绘制的内容,支持 ${} 语法
yesCallback: 点击确认后的回调
noCallback: 点击取消后的回调", + "!type": "fn(text: string, yesCallback?: fn(), noCallback?: fn())", }, - "drawUIEventSelector": { - "!doc": "自绘一个闪烁的选择光标
code: 选择光标的编号,必填
background: 要绘制的光标背景,必须是一个合法的WindowSkin
x, y, w, h: 绘制的坐标和长宽
z: 可选,光标的的z值", - "!type": "fn(code: number, background: string, x: number, y: number, w: number, h: number, z?: number)" + drawUIEventSelector: { + "!doc": + "自绘一个闪烁的选择光标
code: 选择光标的编号,必填
background: 要绘制的光标背景,必须是一个合法的WindowSkin
x, y, w, h: 绘制的坐标和长宽
z: 可选,光标的的z值", + "!type": + "fn(code: number, background: string, x: number, y: number, w: number, h: number, z?: number)", }, - "clearUIEventSelector": { - "!doc": "清除若干个自绘的选择光标
codes: 清除的光标编号;可以是单个编号或编号数组;不填则清除所有光标", - "!type": "fn(codes?: number|[number])" + clearUIEventSelector: { + "!doc": + "清除若干个自绘的选择光标
codes: 清除的光标编号;可以是单个编号或编号数组;不填则清除所有光标", + "!type": "fn(codes?: number|[number])", }, - "fillPolygon": { + fillPolygon: { "!doc": "在某个canvas上绘制一个多边形", - "!type": "fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string)", }, - "fillText": { - "!doc": "在某个画布上绘制一段文字
text: 要绘制的文本
style: 绘制的样式
font: 绘制的字体
最大宽度,超过此宽度会自动放缩", + fillText: { + "!doc": + "在某个画布上绘制一段文字
text: 要绘制的文本
style: 绘制的样式
font: 绘制的字体
最大宽度,超过此宽度会自动放缩", "!url": "https://www.w3school.com.cn/tags/canvas_filltext.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, font?: string, maxWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, font?: string, maxWidth?: number)", }, - "setTextBaseline": { - "!doc": "设置某个canvas的基准线
baseline: 可为alphabetic, top, hanging, middle, ideographic, bottom", + setTextBaseline: { + "!doc": + "设置某个canvas的基准线
baseline: 可为alphabetic, top, hanging, middle, ideographic, bottom", "!url": "https://www.w3school.com.cn/tags/canvas_textbaseline.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, baseline: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, baseline: string)", }, - "loadCanvas": { + loadCanvas: { "!doc": "加载某个canvas状态", - "!type": "fn(name: string|CanvasRenderingContext2D)" + "!type": "fn(name: string|CanvasRenderingContext2D)", }, - "splitLines": { + splitLines: { "!doc": "字符串自动换行的分割", - "!type": "fn(name: string|CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, text: string, maxWidth?: number, font?: string)", }, - "setAlpha": { - "!doc": "设置某个canvas接下来绘制的不透明度;不会影响已经绘制的内容
返回设置之前画布的不透明度
如果需要修改画布本身的不透明度请使用setOpacity", + setAlpha: { + "!doc": + "设置某个canvas接下来绘制的不透明度;不会影响已经绘制的内容
返回设置之前画布的不透明度
如果需要修改画布本身的不透明度请使用setOpacity", "!url": "https://www.w3school.com.cn/tags/canvas_globalalpha.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, alpha: number) -> number" + "!type": + "fn(name: string|CanvasRenderingContext2D, alpha: number) -> number", }, - "setFilter": { + setFilter: { "!doc": "设置某个canvas接下来绘制的filter", - "!type": "fn(name: string|CanvasRenderingContext2D, style: string)" + "!type": "fn(name: string|CanvasRenderingContext2D, style: string)", }, - "setLineWidth": { + setLineWidth: { "!doc": "设置某个canvas的线宽度", "!url": "https://www.w3school.com.cn/tags/canvas_linewidth.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, lineWidth: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, lineWidth: number)", }, - "drawTextBox": { + drawTextBox: { "!doc": "绘制一个对话框", - "!type": "fn(content: string, showAll?: bool)" + "!type": "fn(content: string, showAll?: bool)", }, - "relocateCanvas": { + relocateCanvas: { "!doc": "重新定位一个自定义画布", - "!type": "fn(name: string, x: number, y: number, useDelta: bool)" + "!type": "fn(name: string, x: number, y: number, useDelta: bool)", }, - "rotateCanvas": { - "!doc": "设置一个自定义画布的旋转角度
centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。", - "!type": "fn(name: string, angle: number, centerX?: number, centerY?: number)" + rotateCanvas: { + "!doc": + "设置一个自定义画布的旋转角度
centerX, centerY: 旋转中心(以屏幕像素为基准);不填视为图片正中心。", + "!type": + "fn(name: string, angle: number, centerX?: number, centerY?: number)", }, - "closePanel": { + closePanel: { "!doc": "结束一切事件和绘制,关闭UI窗口,返回游戏进程", - "!type": "fn()" + "!type": "fn()", }, - "textImage": { + textImage: { "!doc": "文本图片化", - "!type": "fn(content: string, lineHeight?: number) -> image" + "!type": "fn(content: string, lineHeight?: number) -> image", }, - "drawStatusBar": { + drawStatusBar: { "!doc": "绘制状态栏", - "!type": "fn()" + "!type": "fn()", }, - "setStrokeStyle": { + setStrokeStyle: { "!doc": "设置某个canvas边框属性", "!url": "https://www.w3school.com.cn/tags/canvas_strokestyle.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, style: string)" + "!type": "fn(name: string|CanvasRenderingContext2D, style: string)", }, - "clearUI": { + clearUI: { "!doc": "清空UI层内容", - "!type": "fn()" + "!type": "fn()", }, - "drawWindowSkin": { + drawWindowSkin: { "!doc": "绘制WindowSkin", - "!type": "fn(background: string, ctx: string|CanvasRenderingContext2D, x: number, y: number, w: string, h: string, direction?: string, px?: number, py?: number)" + "!type": + "fn(background: string, ctx: string|CanvasRenderingContext2D, x: number, y: number, w: string, h: string, direction?: string, px?: number, py?: number)", }, - "fillRect": { - "!doc": "绘制一个矩形。
x,y: 绘制的坐标
width,height: 绘制的长宽
style: 绘制的样式
angle: 旋转的角度,弧度制,如Math.PI/2代表90度", + fillRect: { + "!doc": + "绘制一个矩形。
x,y: 绘制的坐标
width,height: 绘制的长宽
style: 绘制的样式
angle: 旋转的角度,弧度制,如Math.PI/2代表90度", "!url": "https://www.w3school.com.cn/tags/canvas_fillrect.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, style?: string, angle?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, style?: string, angle?: number)", }, - "drawScrollText": { + drawScrollText: { "!doc": "绘制滚动字幕", - "!type": "fn(content: string, time: number, lineHeight?: number, callback?: fn())" + "!type": + "fn(content: string, time: number, lineHeight?: number, callback?: fn())", }, - "strokePolygon": { + strokePolygon: { "!doc": "在某个canvas上绘制一个多边形的边框", - "!type": "fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, nodes?: [[number]], style?: string, lineWidth?: number)", }, - "strokeCircle": { + strokeCircle: { "!doc": "在某个canvas上绘制一个圆的边框", "!url": "https://www.w3school.com.cn/tags/canvas_arc.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: ?, style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: ?, style?: string, lineWidth?: number)", }, - "drawWaiting": { + drawWaiting: { "!doc": "绘制等待界面", - "!type": "fn(text: string)" + "!type": "fn(text: string)", }, - "setFont": { + setFont: { "!doc": "设置某个canvas的文字字体", "!url": "https://www.w3school.com.cn/tags/canvas_font.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, font: string)" + "!type": "fn(name: string|CanvasRenderingContext2D, font: string)", }, - "drawChoices": { + drawChoices: { "!doc": "绘制一个选项界面", - "!type": "fn(content?: string, choices?: [?], width?: number, ctx?: string|CanvasRenderingContext2D)" + "!type": + "fn(content?: string, choices?: [?], width?: number, ctx?: string|CanvasRenderingContext2D)", }, - "setFontForMaxWidth": { + setFontForMaxWidth: { "!doc": "根据最大宽度自动缩小字体", - "!type": "fn(name: string|CanvasRenderingContext2D, text: string, maxWidth: number, font?: ?) -> string" + "!type": + "fn(name: string|CanvasRenderingContext2D, text: string, maxWidth: number, font?: ?) -> string", }, - "clearMap": { - "!doc": "清空某个画布图层
name为画布名,可以是系统画布之一,也可以是任意自定义动态创建的画布名;还可以直接传画布的context本身。
如果name也可以是'all',若为all则为清空所有系统画布。", + clearMap: { + "!doc": + "清空某个画布图层
name为画布名,可以是系统画布之一,也可以是任意自定义动态创建的画布名;还可以直接传画布的context本身。
如果name也可以是'all',若为all则为清空所有系统画布。", "!url": "https://www.w3school.com.cn/tags/canvas_clearrect.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x?: number, y?: number, width?: number, height?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x?: number, y?: number, width?: number, height?: number)", }, - "drawTextContent": { - "!doc": "绘制一段文字到某个画布上面
ctx: 要绘制到的画布
content: 要绘制的内容;转义字符不允许保留 \\t, \\b 和 \\f
config: 绘制配置项,目前暂时包含如下内容(均为可选)
left, top:起始点位置;maxWidth:单行最大宽度;color:默认颜色;align:左中右
fontSize:字体大小;lineHeight:行高;time:打字机间隔;font:字体名
返回值:绘制信息", - "!type": "fn(ctx: string|CanvasRenderingContext2D, content: string, config: ?)" + drawTextContent: { + "!doc": + "绘制一段文字到某个画布上面
ctx: 要绘制到的画布
content: 要绘制的内容;转义字符不允许保留 \\t, \\b 和 \\f
config: 绘制配置项,目前暂时包含如下内容(均为可选)
left, top:起始点位置;maxWidth:单行最大宽度;color:默认颜色;align:左中右
fontSize:字体大小;lineHeight:行高;time:打字机间隔;font:字体名
返回值:绘制信息", + "!type": + "fn(ctx: string|CanvasRenderingContext2D, content: string, config: ?)", }, - "calWidth": { + calWidth: { "!doc": "计算某段文字的宽度", "!url": "https://www.w3school.com.cn/tags/canvas_measuretext.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, text: string, font?: string) -> number" + "!type": + "fn(name: string|CanvasRenderingContext2D, text: string, font?: string) -> number", }, - "fillArc": { + fillArc: { "!doc": "在某个canvas上绘制一个扇形", "!url": "https://www.w3school.com.cn/tags/canvas_arc.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string)", }, - "strokeArc": { + strokeArc: { "!doc": "在某个canvas上绘制一段弧", "!url": "https://www.w3school.com.cn/tags/canvas_arc.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, r: number, start: number, end: number, style?: string, lineWidth?: number)", }, - "drawLine": { + drawLine: { "!doc": "在某个canvas上绘制一条线", "!url": "https://www.w3school.com.cn/tags/canvas_lineto.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x1: number, y1: number, x2: number, y2: number, style?: string, lineWidth?: number)", }, - "drawPagination": { + drawPagination: { "!doc": "绘制分页", - "!type": "fn(page?: ?, totalPage?: ?, y?: number)" + "!type": "fn(page?: ?, totalPage?: ?, y?: number)", }, - "getToolboxItems": { + getToolboxItems: { "!doc": "获得所有应该在道具栏显示的某个类型道具", - "!type": "fn(cls: string) -> [string]" + "!type": "fn(cls: string) -> [string]", }, - "strokeRect": { - "!doc": "绘制一个矩形的边框
style: 绘制的样式
lineWidth: 线宽
angle: 旋转角度,弧度制,如Math.PI/2为90度", + strokeRect: { + "!doc": + "绘制一个矩形的边框
style: 绘制的样式
lineWidth: 线宽
angle: 旋转角度,弧度制,如Math.PI/2为90度", "!url": "https://www.w3school.com.cn/tags/canvas_strokerect.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, style?: string, lineWidth?: number, angle?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, style?: string, lineWidth?: number, angle?: number)", }, - "drawBook": { + drawBook: { "!doc": "绘制怪物手册", - "!type": "fn(index?: ?)" + "!type": "fn(index?: ?)", }, - "fillRoundRect": { + fillRoundRect: { "!doc": "在某个canvas上绘制一个圆角矩形", - "!type": "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, angle?: number)" + "!type": + "fn(name: string|CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number, style?: string, angle?: number)", }, - "fillBoldText": { - "!doc": "在某个画布上绘制一个描边文字
text: 要绘制的文本
style: 绘制的样式
strokeStyle: 要绘制的描边颜色
font: 绘制的字体
maxWidth: 最大宽度,超过此宽度会自动放缩", - "!type": "fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, strokeStyle?: string, font?: string, maxWidth?: number)" + fillBoldText: { + "!doc": + "在某个画布上绘制一个描边文字
text: 要绘制的文本
style: 绘制的样式
strokeStyle: 要绘制的描边颜色
font: 绘制的字体
maxWidth: 最大宽度,超过此宽度会自动放缩", + "!type": + "fn(name: string|CanvasRenderingContext2D, text: string, x: number, y: number, style?: string, strokeStyle?: string, font?: string, maxWidth?: number)", }, - "saveCanvas": { + saveCanvas: { "!doc": "保存某个canvas状态", - "!type": "fn(name: string|CanvasRenderingContext2D)" + "!type": "fn(name: string|CanvasRenderingContext2D)", }, - "createCanvas": { - "!doc": "动态创建一个画布。
name: 要创建的画布名,如果已存在则会直接取用当前存在的。
x,y: 创建的画布相对窗口左上角的像素坐标
width,height: 创建的长宽。
zIndex: 创建的纵向高度(关系到画布之间的覆盖),z值高的将覆盖z值低的;系统画布的z值可在个性化中查看。
返回创建的画布的context,也可以通过core.dymCanvas[name]调用。", - "!type": "fn(name: string, x: number, y: number, width: number, height: number, zIndex: number) -> CanvasRenderingContext2D" + createCanvas: { + "!doc": + "动态创建一个画布。
name: 要创建的画布名,如果已存在则会直接取用当前存在的。
x,y: 创建的画布相对窗口左上角的像素坐标
width,height: 创建的长宽。
zIndex: 创建的纵向高度(关系到画布之间的覆盖),z值高的将覆盖z值低的;系统画布的z值可在个性化中查看。
返回创建的画布的context,也可以通过core.dymCanvas[name]调用。", + "!type": + "fn(name: string, x: number, y: number, width: number, height: number, zIndex: number) -> CanvasRenderingContext2D", }, - "setTextAlign": { + setTextAlign: { "!doc": "设置某个canvas的对齐", "!url": "https://www.w3school.com.cn/tags/canvas_textalign.asp", - "!type": "fn(name: string|CanvasRenderingContext2D, align: string)" + "!type": "fn(name: string|CanvasRenderingContext2D, align: string)", }, }, - "enemys": { + enemys: { "!doc": "定义了一系列和怪物相关的API函数。", - "getEnemys": { - "!doc": "获得所有怪物原始数据的一个副本。
请使用core.material.enemys获得当前各项怪物属性。", - "!type": "fn()" + getEnemys: { + "!doc": + "获得所有怪物原始数据的一个副本。
请使用core.material.enemys获得当前各项怪物属性。", + "!type": "fn()", }, - "getEnemyValue": { + getEnemyValue: { "!doc": "获得某个点上怪物的某个属性值", - "!type": "fn(enemy?: string|enemy, name: string, x?: number, y?: number, floorId?: string)" + "!type": + "fn(enemy?: string|enemy, name: string, x?: number, y?: number, floorId?: string)", }, - "getSpecials": { + getSpecials: { "!doc": "获得所有特殊属性的定义", - "!type": "fn() -> [[?]]" + "!type": "fn() -> [[?]]", }, - "getSpecialColor": { + getSpecialColor: { "!doc": "获得某个怪物所有特殊属性的颜色", - "!type": "fn(enemy: string|enemy) -> [string]" + "!type": "fn(enemy: string|enemy) -> [string]", }, - "getSpecialFlag": { - "!doc": "获得某个怪物所有特殊属性的额外标记。

例如,1为全图性技能,需要进行遍历全图(光环/支援等)", - "!type": "fn(enemy: string|enemy) -> number" + getSpecialFlag: { + "!doc": + "获得某个怪物所有特殊属性的额外标记。

例如,1为全图性技能,需要进行遍历全图(光环/支援等)", + "!type": "fn(enemy: string|enemy) -> number", }, - "getSpecialHint": { - "!doc": "获得某种敌人的某种特殊属性的介绍
例如:core.getSpecialHint('bat', 1) // '先攻:怪物首先攻击'
enemy: 敌人id或敌人对象,用于确定属性的具体数值,否则可选
special: 属性编号,可以是该敌人没有的属性
返回值:属性的介绍,以属性名加中文冒号开头", - "!type": "fn(enemy: string|enemy, special: number) -> string" + getSpecialHint: { + "!doc": + "获得某种敌人的某种特殊属性的介绍
例如:core.getSpecialHint('bat', 1) // '先攻:怪物首先攻击'
enemy: 敌人id或敌人对象,用于确定属性的具体数值,否则可选
special: 属性编号,可以是该敌人没有的属性
返回值:属性的介绍,以属性名加中文冒号开头", + "!type": "fn(enemy: string|enemy, special: number) -> string", }, - "getSpecialText": { - "!doc": "获得某种敌人的全部特殊属性名称
例如:core.getSpecialText('greenSlime') // ['先攻', '3连击', '破甲', '反击']
enemy: 敌人id或敌人对象,如core.material.enemys.greenSlime
返回值:字符串数组", - "!type": "fn(enemy: string|enemy) -> [string]" + getSpecialText: { + "!doc": + "获得某种敌人的全部特殊属性名称
例如:core.getSpecialText('greenSlime') // ['先攻', '3连击', '破甲', '反击']
enemy: 敌人id或敌人对象,如core.material.enemys.greenSlime
返回值:字符串数组", + "!type": "fn(enemy: string|enemy) -> [string]", }, - "hasSpecial": { - "!doc": "判定某种特殊属性的有无
例如:core.hasSpecial('greenSlime', 1) // 判定绿头怪有无先攻属性
special: 敌人id或敌人对象或正整数数组或自然数
test: 待检查的属性编号
", - "!type": "fn(special: number|[number]|string|number, test: number) -> bool" + hasSpecial: { + "!doc": + "判定某种特殊属性的有无
例如:core.hasSpecial('greenSlime', 1) // 判定绿头怪有无先攻属性
special: 敌人id或敌人对象或正整数数组或自然数
test: 待检查的属性编号
", + "!type": + "fn(special: number|[number]|string|number, test: number) -> bool", }, - "nextCriticals": { - "!doc": "获得某只敌人接下来的若干个临界及其减伤,算法基于useLoop开关选择回合法或二分法
例如:core.nextCriticals('greenSlime', 9, 0, 0, 'MT0') // 绿头怪接下来的9个临界
enemy: 敌人id或敌人对象
number: 要计算的临界数量,可选,默认为1
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回:两列的二维数组,每行表示一个临界及其减伤", - "!type": "fn(enemy: string|enemy, number?: number, x?: number, y?: number, floorId?: string) -> [[number]]" + nextCriticals: { + "!doc": + "获得某只敌人接下来的若干个临界及其减伤,算法基于useLoop开关选择回合法或二分法
例如:core.nextCriticals('greenSlime', 9, 0, 0, 'MT0') // 绿头怪接下来的9个临界
enemy: 敌人id或敌人对象
number: 要计算的临界数量,可选,默认为1
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回:两列的二维数组,每行表示一个临界及其减伤", + "!type": + "fn(enemy: string|enemy, number?: number, x?: number, y?: number, floorId?: string) -> [[number]]", }, - "getDefDamage": { - "!doc": "计算再加若干点防御能使某只敌人对主角的总伤害降低多少
例如:core.getDefDamage('greenSlime', 10, 0, 0, 'MT0') // 再加10点防御能使绿头怪的伤害降低多少
enemy: 敌人id或敌人对象
k: 假设主角增加的防御力,可选,默认为1
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选", - "!type": "fn(enemy: string|enemy, k?: number, x?: number, y?: number, floorId?: string) -> number" + getDefDamage: { + "!doc": + "计算再加若干点防御能使某只敌人对主角的总伤害降低多少
例如:core.getDefDamage('greenSlime', 10, 0, 0, 'MT0') // 再加10点防御能使绿头怪的伤害降低多少
enemy: 敌人id或敌人对象
k: 假设主角增加的防御力,可选,默认为1
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选", + "!type": + "fn(enemy: string|enemy, k?: number, x?: number, y?: number, floorId?: string) -> number", }, - "canBattle": { - "!doc": "判定主角当前能否打败某只敌人
例如:core.canBattle('greenSlime',0,0,'MT0') // 能否打败主塔0层左上角的绿头怪(假设有)
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:true表示可以打败,false表示无法打败", - "!type": "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> bool" + canBattle: { + "!doc": + "判定主角当前能否打败某只敌人
例如:core.canBattle('greenSlime',0,0,'MT0') // 能否打败主塔0层左上角的绿头怪(假设有)
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:true表示可以打败,false表示无法打败", + "!type": + "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> bool", }, - "getEnemyInfo": { - "!doc": "获得怪物真实属性
hero: 可选,此时的勇士属性
此函数将会计算包括坚固、模仿、光环等若干效果,将同时被怪物手册和伤害计算调用", - "!type": "fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {hp: number, atk: number, def: number, money: number, exp: number, special: [number], point: number, guards: [?]}" + getEnemyInfo: { + "!doc": + "获得怪物真实属性
hero: 可选,此时的勇士属性
此函数将会计算包括坚固、模仿、光环等若干效果,将同时被怪物手册和伤害计算调用", + "!type": + "fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {hp: number, atk: number, def: number, money: number, exp: number, special: [number], point: number, guards: [?]}", }, - "getDamageInfo": { - "!doc": "获得战斗伤害信息
例如:core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
hero: 可选,此时的勇士属性
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:伤害计算信息,如果因为没有破防或无敌怪等其他原因无法战斗,则返回null", - "!type": "fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {damage: number, per_damage: number, hero_per_damage: number, init_damage: number, mon_hp: number, mon_atk: number, mon_def: number, turn: number}" + getDamageInfo: { + "!doc": + "获得战斗伤害信息
例如:core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
hero: 可选,此时的勇士属性
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:伤害计算信息,如果因为没有破防或无敌怪等其他原因无法战斗,则返回null", + "!type": + "fn(enemy: string|enemy, hero?: ?, x?: number, y?: number, floorId?: string) -> {damage: number, per_damage: number, hero_per_damage: number, init_damage: number, mon_hp: number, mon_atk: number, mon_def: number, turn: number}", }, - "getDamage": { - "!doc": "获得某只敌人对主角的总伤害
例如:core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:总伤害,如果因为没有破防或无敌怪等其他原因无法战斗,则返回null", - "!type": "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> number" + getDamage: { + "!doc": + "获得某只敌人对主角的总伤害
例如:core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:总伤害,如果因为没有破防或无敌怪等其他原因无法战斗,则返回null", + "!type": + "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> number", }, - "getDamageString": { - "!doc": "获得某只敌人的地图显伤,包括颜色
例如:core.getDamageString('greenSlime', 0, 0, 'MT0') // 绿头怪的地图显伤
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:damage: 表示伤害值或为'???',color: 形如'#RrGgBb'", - "!type": "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> {color: string, damage: string}" + getDamageString: { + "!doc": + "获得某只敌人的地图显伤,包括颜色
例如:core.getDamageString('greenSlime', 0, 0, 'MT0') // 绿头怪的地图显伤
enemy: 敌人id或敌人对象
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
floorId: 敌人所在的地图,可选
返回值:damage: 表示伤害值或为'???',color: 形如'#RrGgBb'", + "!type": + "fn(enemy: string|enemy, x?: number, y?: number, floorId?: string) -> {color: string, damage: string}", }, - "getCurrentEnemys": { - "!doc": "获得某张地图的敌人集合,用于手册绘制
例如:core.getCurrentEnemys('MT0') // 主塔0层的敌人集合
floorId: 地图id,可选
返回值:敌人集合,按伤害升序排列,支持多朝向怪合并", - "!type": "fn(floorId?: string) -> [enemy]" + getCurrentEnemys: { + "!doc": + "获得某张地图的敌人集合,用于手册绘制
例如:core.getCurrentEnemys('MT0') // 主塔0层的敌人集合
floorId: 地图id,可选
返回值:敌人集合,按伤害升序排列,支持多朝向怪合并", + "!type": "fn(floorId?: string) -> [enemy]", + }, + hasEnemyLeft: { + "!doc": + "检查某些楼层是否还有漏打的(某种)敌人
例如:core.hasEnemyLeft('greenSlime', ['sample0', 'sample1']) // 样板0层和1层是否有漏打的绿头怪
enemyId: 敌人id,可选,null表示任意敌人
floorId: 地图id或其数组,可选,不填为当前地图
返回值:地图中是否还存在该种敌人", + "!type": "fn(enemyId?: string, floorId?: string|[string]) -> bool", }, - "hasEnemyLeft": { - "!doc": "检查某些楼层是否还有漏打的(某种)敌人
例如:core.hasEnemyLeft('greenSlime', ['sample0', 'sample1']) // 样板0层和1层是否有漏打的绿头怪
enemyId: 敌人id,可选,null表示任意敌人
floorId: 地图id或其数组,可选,不填为当前地图
返回值:地图中是否还存在该种敌人", - "!type": "fn(enemyId?: string, floorId?: string|[string]) -> bool" - } }, - "events": { - "!doc": "events.js将处理所有和事件相关的操作,主要分为五个部分:
- 游戏的开始和结束
- 系统事件的处理
- 自定义事件的处理
- 点击状态栏图标所进行的操作
- 一些具体事件的执行内容", - "afterChangeFloor": { + events: { + "!doc": + "events.js将处理所有和事件相关的操作,主要分为五个部分:
- 游戏的开始和结束
- 系统事件的处理
- 自定义事件的处理
- 点击状态栏图标所进行的操作
- 一些具体事件的执行内容", + afterChangeFloor: { "!doc": "转换楼层结束的事件", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "popEventLoc": { + popEventLoc: { "!doc": "将当前点坐标入栈", - "!type": "fn()" + "!type": "fn()", }, - "afterOpenDoor": { + afterOpenDoor: { "!doc": "开一个门后触发的事件", - "!type": "fn(doorId?: string, x?: number, y?: number)" + "!type": "fn(doorId?: string, x?: number, y?: number)", }, - "checkLvUp": { + checkLvUp: { "!doc": "检查升级事件", - "!type": "fn()" + "!type": "fn()", }, - "insertAction": { - "!doc": "插入一段事件;此项不可插入公共事件,请用 core.insertCommonEvent
例如:core.insertAction('一段文字'); // 插入一个显示文章
action: 单个事件指令,或事件指令数组
x: 新的当前点横坐标,可选
y: 新的当前点纵坐标,可选
callback: 新的回调函数,可选
addToLast: 插入的位置,true表示插入到末尾,否则插入到开头", - "!type": "fn(action: string|?|[?], x?: number, y?: number, callback?: fn(), addToLast?: bool)" + insertAction: { + "!doc": + "插入一段事件;此项不可插入公共事件,请用 core.insertCommonEvent
例如:core.insertAction('一段文字'); // 插入一个显示文章
action: 单个事件指令,或事件指令数组
x: 新的当前点横坐标,可选
y: 新的当前点纵坐标,可选
callback: 新的回调函数,可选
addToLast: 插入的位置,true表示插入到末尾,否则插入到开头", + "!type": + "fn(action: string|?|[?], x?: number, y?: number, callback?: fn(), addToLast?: bool)", }, - "unfollow": { + unfollow: { "!doc": "取消跟随
name: 取消跟随的行走图,不填则取消全部跟随者", - "!type": "fn(name?: string)" + "!type": "fn(name?: string)", }, - "hasVisitedFloor": { + hasVisitedFloor: { "!doc": "是否到达过某个楼层", - "!type": "fn(floorId?: string) -> bool" + "!type": "fn(floorId?: string) -> bool", }, - "startEvents": { + startEvents: { "!doc": "开始执行一系列自定义事件", - "!type": "fn(list?: [?], x?: number, y?: number, callback?: fn())" + "!type": "fn(list?: [?], x?: number, y?: number, callback?: fn())", }, - "setHeroIcon": { - "!doc": "更改主角行走图
例如:core.setHeroIcon('npc48.png', true); // 把主角从阳光变成样板0层左下角的小姐姐,但不立即刷新
name: 新的行走图文件名,可以是全塔属性中映射前的中文名。映射后会被存入core.status.hero.image
noDraw: true表示不立即刷新(刷新会导致大地图下视野重置到以主角为中心)", - "!type": "fn(name: string, noDraw?: bool)" + setHeroIcon: { + "!doc": + "更改主角行走图
例如:core.setHeroIcon('npc48.png', true); // 把主角从阳光变成样板0层左下角的小姐姐,但不立即刷新
name: 新的行走图文件名,可以是全塔属性中映射前的中文名。映射后会被存入core.status.hero.image
noDraw: true表示不立即刷新(刷新会导致大地图下视野重置到以主角为中心)", + "!type": "fn(name: string, noDraw?: bool)", }, - "changingFloor": { + changingFloor: { "!doc": "楼层转换中", - "!type": "fn(floorId?: string, heroLoc?: {x: number, y: number, direction: string})" + "!type": + "fn(floorId?: string, heroLoc?: {x: number, y: number, direction: string})", }, - "setEvents": { + setEvents: { "!doc": "直接设置事件列表", - "!type": "fn(list?: [?], x?: number, y?: number, callback?: fn())" + "!type": "fn(list?: [?], x?: number, y?: number, callback?: fn())", }, - "setValue": { + setValue: { "!doc": "数值操作", - "!type": "fn(name: string, operator: string, value: ?, prefix?: string)" + "!type": + "fn(name: string, operator: string, value: ?, prefix?: string)", }, - "precompile": { + precompile: { "!doc": "预编辑事件", - "!type": "fn(data?: ?)" + "!type": "fn(data?: ?)", }, - "vibrate": { - "!doc": "视野抖动
例如:core.vibrate(); // 视野抖动1秒
direction: 抖动方向;可填 horizontal(左右),vertical(上下),diagonal1(左上右下),diagonal2(左下右上)
time: 抖动时长
speed: 抖动速度
power: 抖动幅度
callback: 抖动平息后的回调函数,可选", - "!type": "fn(direction?: string, time?: number, speed?: number, power?: number, callback?: fn())" + vibrate: { + "!doc": + "视野抖动
例如:core.vibrate(); // 视野抖动1秒
direction: 抖动方向;可填 horizontal(左右),vertical(上下),diagonal1(左上右下),diagonal2(左下右上)
time: 抖动时长
speed: 抖动速度
power: 抖动幅度
callback: 抖动平息后的回调函数,可选", + "!type": + "fn(direction?: string, time?: number, speed?: number, power?: number, callback?: fn())", }, - "confirmRestart": { + confirmRestart: { "!doc": "询问是否需要重新开始", - "!type": "fn()" + "!type": "fn()", }, - "battle": { - "!doc": "战斗,如果填写了坐标就会删除该点的敌人并触发战后事件
例如:core.battle('greenSlime'); // 和从天而降的绿头怪战斗(如果打得过)
id: 敌人id,必填
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
force: true表示强制战斗,可选
callback: 回调函数,可选", - "!type": "fn(id: string, x?: number, y?: number, force?: bool, callback?: fn())" + battle: { + "!doc": + "战斗,如果填写了坐标就会删除该点的敌人并触发战后事件
例如:core.battle('greenSlime'); // 和从天而降的绿头怪战斗(如果打得过)
id: 敌人id,必填
x: 敌人的横坐标,可选
y: 敌人的纵坐标,可选
force: true表示强制战斗,可选
callback: 回调函数,可选", + "!type": + "fn(id: string, x?: number, y?: number, force?: bool, callback?: fn())", }, - "follow": { - "!doc": "跟随
name: 要跟随的一个合法的4x4的行走图名称,需要在全塔属性注册", - "!type": "fn(name: string)" + follow: { + "!doc": + "跟随
name: 要跟随的一个合法的4x4的行走图名称,需要在全塔属性注册", + "!type": "fn(name: string)", }, - "beforeBattle": { + beforeBattle: { "!doc": "战斗前触发的事件;返回false代表不进行战斗", - "!type": "fn(enemyId?: string, x?: number, y?: number) -> bool" + "!type": "fn(enemyId?: string, x?: number, y?: number) -> bool", }, - "registerEvent": { - "!doc": "注册一个自定义事件
type: 事件类型
func: 事件的处理函数,可接受(data, x, y, prefix)参数
data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀", - "!type": "fn(type: string, func: fn(data: ?, x?: number, y?: number, prefix?: string))" + registerEvent: { + "!doc": + "注册一个自定义事件
type: 事件类型
func: 事件的处理函数,可接受(data, x, y, prefix)参数
data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀", + "!type": + "fn(type: string, func: fn(data: ?, x?: number, y?: number, prefix?: string))", }, - "flyTo": { + flyTo: { "!doc": "飞往某一层", - "!type": "fn(toId?: string, callback?: fn()) -> bool" + "!type": "fn(toId?: string, callback?: fn()) -> bool", }, - "afterGetItem": { + afterGetItem: { "!doc": "获得一个道具后的事件", - "!type": "fn(id?: string, x?: number, y?: number, isGentleClick?: bool)" + "!type": + "fn(id?: string, x?: number, y?: number, isGentleClick?: bool)", }, - "doAction": { - "!doc": "执行下一个事件指令,常作为回调
例如:core.setCurtain([0,0,0,1], null, null, core.doAction); // 事件中的原生脚本,配合勾选“不自动执行下一个事件”来达到此改变色调只持续到下次场景切换的效果", - "!type": "fn()" + doAction: { + "!doc": + "执行下一个事件指令,常作为回调
例如:core.setCurtain([0,0,0,1], null, null, core.doAction); // 事件中的原生脚本,配合勾选“不自动执行下一个事件”来达到此改变色调只持续到下次场景切换的效果", + "!type": "fn()", }, - "openBook": { + openBook: { "!doc": "点击怪物手册时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "save": { + save: { "!doc": "点击存档按钮时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "load": { + load: { "!doc": "点击读档按钮时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "getNextItem": { - "!doc": "轻按获得面前的物品或周围唯一物品
noRoute: 若为true则不计入录像", - "!type": "fn(noRoute?: bool)" + getNextItem: { + "!doc": + "轻按获得面前的物品或周围唯一物品
noRoute: 若为true则不计入录像", + "!type": "fn(noRoute?: bool)", }, - "hasAsync": { + hasAsync: { "!doc": "当前是否有未处理完毕的异步事件(不包含动画和音效)", - "!type": "fn() -> bool" + "!type": "fn() -> bool", }, - "stopAsync": { + stopAsync: { "!doc": "立刻停止所有正在进行的异步事件", - "!type": "fn()" + "!type": "fn()", }, - "openEquipbox": { + openEquipbox: { "!doc": "点击装备栏时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "recoverEvents": { + recoverEvents: { "!doc": "恢复一个事件", - "!type": "fn(data?: ?)" + "!type": "fn(data?: ?)", }, - "setGlobalFlag": { - "!doc": "设置一个系统开关
例如:core.setGlobalFlag('steelDoorWithoutKey', true); // 使全塔的所有铁门都不再需要钥匙就能打开
name: 系统开关的英文名
value: 开关的新值,您可以用!core.flags[name]简单地表示将此开关反转", - "!type": "fn(name: string, value: bool)" + setGlobalFlag: { + "!doc": + "设置一个系统开关
例如:core.setGlobalFlag('steelDoorWithoutKey', true); // 使全塔的所有铁门都不再需要钥匙就能打开
name: 系统开关的英文名
value: 开关的新值,您可以用!core.flags[name]简单地表示将此开关反转", + "!type": "fn(name: string, value: bool)", }, - "moveImage": { - "!doc": "移动一张图片并/或改变其透明度
例如:core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明
code: 图片编号
to: 新的左上角坐标,省略表示原地改变透明度
opacityVal: 新的透明度,省略表示不变
time: 移动用时,单位为毫秒。不填视为1秒
callback: 图片移动完毕后的回调函数,可选", - "!type": "fn(code: number, to?: [number], opacityVal?: number, moveMode?: string, time?: number, callback?: fn())" + moveImage: { + "!doc": + "移动一张图片并/或改变其透明度
例如:core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明
code: 图片编号
to: 新的左上角坐标,省略表示原地改变透明度
opacityVal: 新的透明度,省略表示不变
time: 移动用时,单位为毫秒。不填视为1秒
callback: 图片移动完毕后的回调函数,可选", + "!type": + "fn(code: number, to?: [number], opacityVal?: number, moveMode?: string, time?: number, callback?: fn())", }, - "rotateImage": { - "!doc": "旋转一张图片
code: 图片编号
center: 旋转中心像素坐标(以屏幕为基准);不填视为图片本身中心
angle: 旋转角度;正数为顺时针,负数为逆时针
moveMode: 旋转模式
time: 旋转用时,单位为毫秒。不填视为1秒
callback: 图片旋转完毕后的回调函数,可选", - "!type": "fn(code: number, center?: [number], angle?: number, moveMode?: string, time?: number, callback?: fn())" + rotateImage: { + "!doc": + "旋转一张图片
code: 图片编号
center: 旋转中心像素坐标(以屏幕为基准);不填视为图片本身中心
angle: 旋转角度;正数为顺时针,负数为逆时针
moveMode: 旋转模式
time: 旋转用时,单位为毫秒。不填视为1秒
callback: 图片旋转完毕后的回调函数,可选", + "!type": + "fn(code: number, center?: [number], angle?: number, moveMode?: string, time?: number, callback?: fn())", }, - "scaleImage": { + scaleImage: { "!doc": "放缩一张图片", - "!type": "fn(code: number, center?: [number], scale?: number, moveMode?: string, time?: number, callback?: fn())" + "!type": + "fn(code: number, center?: [number], scale?: number, moveMode?: string, time?: number, callback?: fn())", }, - "moveTextBox": { + moveTextBox: { "!doc": "移动对话框", - "!type": "fn(code: number, loc: [number], relative?: bool, moveMode?: string, time?: number, callback?: fn())" + "!type": + "fn(code: number, loc: [number], relative?: bool, moveMode?: string, time?: number, callback?: fn())", }, - "clearTextBox": { + clearTextBox: { "!doc": "清除对话框", - "!type": "fn(code: number)" + "!type": "fn(code: number)", }, - "openSettings": { + openSettings: { "!doc": "点击设置按钮时的操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "afterPushBox": { + afterPushBox: { "!doc": "推箱子后的事件", - "!type": "fn()" + "!type": "fn()", }, - "unregisterSystemEvent": { + unregisterSystemEvent: { "!doc": "注销一个系统事件", - "!type": "fn(type: string)" + "!type": "fn(type: string)", }, - "trigger": { - "!doc": "触发(x,y)点的系统事件;会执行该点图块的script属性,同时支持战斗(会触发战后)、道具(会触发道具后)、楼层切换等等
callback: 执行完毕的回调函数
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(x?: number, y?: number, callback?: fn())" + trigger: { + "!doc": + "触发(x,y)点的系统事件;会执行该点图块的script属性,同时支持战斗(会触发战后)、道具(会触发道具后)、楼层切换等等
callback: 执行完毕的回调函数
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(x?: number, y?: number, callback?: fn())", }, - "restart": { + restart: { "!doc": "重新开始游戏;此函数将回到标题页面", - "!type": "fn()" + "!type": "fn()", }, - "doEvent": { + doEvent: { "!doc": "执行一个自定义事件", - "!type": "fn(data?: ?, x?: number, y?: number, prefix?: string)" + "!type": "fn(data?: ?, x?: number, y?: number, prefix?: string)", }, - "win": { + win: { "!doc": "游戏获胜事件", - "!type": "fn(reason?: string, norank?: bool, noexit?: bool)" + "!type": "fn(reason?: string, norank?: bool, noexit?: bool)", }, - "setGlobalAttribute": { + setGlobalAttribute: { "!doc": "设置全塔属性", - "!type": "fn(name: string, value: string)" + "!type": "fn(name: string, value: string)", }, - "setNameMap": { + setNameMap: { "!doc": "设置文件别名", - "!type": "fn(name: string, value?: string)" + "!type": "fn(name: string, value?: string)", }, - "setTextAttribute": { + setTextAttribute: { "!doc": "设置剧情文本的属性", - "!type": "fn(data: ?)" + "!type": "fn(data: ?)", }, - "openToolbox": { + openToolbox: { "!doc": "点击工具栏时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "setVolume": { - "!doc": "调节bgm的音量
例如:core.setVolume(0, 100, core.jumpHero); // 0.1秒内淡出bgm,然后主角原地跳跃半秒
value: 新的音量,为0或不大于1的正数。注意系统设置中是这个值的平方根的十倍
time: 渐变用时,单位为毫秒。不填或小于100毫秒都视为0
callback: 渐变完成后的回调函数,可选", - "!type": "fn(value: number, time?: number, callback?: fn())" + setVolume: { + "!doc": + "调节bgm的音量
例如:core.setVolume(0, 100, core.jumpHero); // 0.1秒内淡出bgm,然后主角原地跳跃半秒
value: 新的音量,为0或不大于1的正数。注意系统设置中是这个值的平方根的十倍
time: 渐变用时,单位为毫秒。不填或小于100毫秒都视为0
callback: 渐变完成后的回调函数,可选", + "!type": "fn(value: number, time?: number, callback?: fn())", }, - "pushEventLoc": { + pushEventLoc: { "!doc": "将当前点坐标入栈", - "!type": "fn(x?: number, y?: number, floorId?: string) -> bool" + "!type": "fn(x?: number, y?: number, floorId?: string) -> bool", }, - "openKeyBoard": { + openKeyBoard: { "!doc": "点击虚拟键盘时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "insertCommonEvent": { - "!doc": "插入一个公共事件
例如:core.insertCommonEvent('加点事件', [3]);
name: 公共事件名;如果公共事件不存在则直接忽略
args: 参数列表,为一个数组,将依次赋值给 flag:arg1, flag:arg2, ...
x: 新的当前点横坐标,可选
y: 新的当前点纵坐标,可选
callback: 新的回调函数,可选
addToLast: 插入的位置,true表示插入到末尾,否则插入到开头", - "!type": "fn(name?: string, args?: [?], x?: number, y?: number, callback?: fn(), addToLast?: bool)" + insertCommonEvent: { + "!doc": + "插入一个公共事件
例如:core.insertCommonEvent('加点事件', [3]);
name: 公共事件名;如果公共事件不存在则直接忽略
args: 参数列表,为一个数组,将依次赋值给 flag:arg1, flag:arg2, ...
x: 新的当前点横坐标,可选
y: 新的当前点纵坐标,可选
callback: 新的回调函数,可选
addToLast: 插入的位置,true表示插入到末尾,否则插入到开头", + "!type": + "fn(name?: string, args?: [?], x?: number, y?: number, callback?: fn(), addToLast?: bool)", }, - "hideImage": { - "!doc": "隐藏一张图片
例如:core.hideImage(1, 1000, core.jumpHero); // 1秒内淡出1号图片,然后主角原地跳跃半秒
code: 图片编号
time: 淡出时间,单位为毫秒
callback: 图片完全消失后的回调函数,可选", - "!type": "fn(code: number, time?: number, callback?: fn())" + hideImage: { + "!doc": + "隐藏一张图片
例如:core.hideImage(1, 1000, core.jumpHero); // 1秒内淡出1号图片,然后主角原地跳跃半秒
code: 图片编号
time: 淡出时间,单位为毫秒
callback: 图片完全消失后的回调函数,可选", + "!type": "fn(code: number, time?: number, callback?: fn())", }, - "visitFloor": { + visitFloor: { "!doc": "到达某楼层", - "!type": "fn(floorId?: string)" + "!type": "fn(floorId?: string)", }, - "openQuickShop": { + openQuickShop: { "!doc": "点击快捷商店按钮时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", }, - "afterBattle": { + afterBattle: { "!doc": "战斗结束后触发的事件", - "!type": "fn(enemyId?: string, x?: number, y?: number)" + "!type": "fn(enemyId?: string, x?: number, y?: number)", }, - "pushBox": { + pushBox: { "!doc": "推箱子", - "!type": "fn(data?: ?)" + "!type": "fn(data?: ?)", }, - "autoEventExecuted": { + autoEventExecuted: { "!doc": "当前是否执行过某个自动事件", - "!type": "fn(symbol?: string, value?: ?) -> bool" + "!type": "fn(symbol?: string, value?: ?) -> bool", }, - "onSki": { + onSki: { "!doc": "当前是否在冰上", - "!type": "fn(number?: number) -> bool" + "!type": "fn(number?: number) -> bool", }, - "showImage": { - "!doc": "显示一张图片
例如:core.showImage(1, core.material.images.images['winskin.png'], [0,0,128,128], [0,0,416,416], 0.5, 1000); // 裁剪winskin.png的最左边128×128px,放大到铺满整个视野,1秒内淡入到50%透明,编号为1
code: 图片编号,为不大于50的正整数,加上100后就是对应画布层的z值,较大的会遮罩较小的,注意色调层的z值为125,UI层为140
image: 图片文件名(可以是全塔属性中映射前的中文名)或图片对象(见上面的例子)
sloc: 一行且至多四列的数组,表示从原图裁剪的左上角坐标和宽高,可选
loc: 一行且至多四列的数组,表示图片在视野中的左上角坐标和宽高,可选
opacityVal: 不透明度,为小于1的正数。不填视为1
time: 淡入时间,单位为毫秒。不填视为0
callback: 图片完全显示出来后的回调函数,可选", - "!type": "fn(code: number, image: string|image, sloc?: [number], loc?: [number], opacityVal?: number, time?: number, callback?: fn())" + showImage: { + "!doc": + "显示一张图片
例如:core.showImage(1, core.material.images.images['winskin.png'], [0,0,128,128], [0,0,416,416], 0.5, 1000); // 裁剪winskin.png的最左边128×128px,放大到铺满整个视野,1秒内淡入到50%透明,编号为1
code: 图片编号,为不大于50的正整数,加上100后就是对应画布层的z值,较大的会遮罩较小的,注意色调层的z值为125,UI层为140
image: 图片文件名(可以是全塔属性中映射前的中文名)或图片对象(见上面的例子)
sloc: 一行且至多四列的数组,表示从原图裁剪的左上角坐标和宽高,可选
loc: 一行且至多四列的数组,表示图片在视野中的左上角坐标和宽高,可选
opacityVal: 不透明度,为小于1的正数。不填视为1
time: 淡入时间,单位为毫秒。不填视为0
callback: 图片完全显示出来后的回调函数,可选", + "!type": + "fn(code: number, image: string|image, sloc?: [number], loc?: [number], opacityVal?: number, time?: number, callback?: fn())", }, - "getItem": { - "!doc": "获得道具并提示,如果填写了坐标就会删除该点的该道具
例如:core.getItem('book'); // 获得敌人手册并提示
id: 道具id,必填
num: 获得的数量,不填视为1,填了就别填坐标了
x: 道具的横坐标,可选
y: 道具的纵坐标,可选
callback: 回调函数,可选", - "!type": "fn(id: string, num?: number, x?: number, y?: number, callback?: fn())" + getItem: { + "!doc": + "获得道具并提示,如果填写了坐标就会删除该点的该道具
例如:core.getItem('book'); // 获得敌人手册并提示
id: 道具id,必填
num: 获得的数量,不填视为1,填了就别填坐标了
x: 道具的横坐标,可选
y: 道具的纵坐标,可选
callback: 回调函数,可选", + "!type": + "fn(id: string, num?: number, x?: number, y?: number, callback?: fn())", }, - "registerSystemEvent": { - "!doc": "注册一个系统事件
type: 事件名
func: 为事件的处理函数,可接受(data,callback)参数", - "!type": "fn(type: string, func: fn(data?: ?, callback?: fn()))" + registerSystemEvent: { + "!doc": + "注册一个系统事件
type: 事件名
func: 为事件的处理函数,可接受(data,callback)参数", + "!type": "fn(type: string, func: fn(data?: ?, callback?: fn()))", }, - "startGame": { - "!doc": "开始新游戏
例如:core.startGame('咸鱼乱撞', 0, ''); // 开始一局咸鱼乱撞难度的新游戏,随机种子为0
hard: 难度名,会显示在左下角(横屏)或右下角(竖屏)
seed: 随机种子,相同的种子保证了录像的可重复性
route: 经由base64压缩后的录像,用于从头开始的录像回放
callback: 回调函数,可选", - "!type": "fn(hard: string, seed: number, route: string, callback?: fn())" + startGame: { + "!doc": + "开始新游戏
例如:core.startGame('咸鱼乱撞', 0, ''); // 开始一局咸鱼乱撞难度的新游戏,随机种子为0
hard: 难度名,会显示在左下角(横屏)或右下角(竖屏)
seed: 随机种子,相同的种子保证了录像的可重复性
route: 经由base64压缩后的录像,用于从头开始的录像回放
callback: 回调函数,可选", + "!type": + "fn(hard: string, seed: number, route: string, callback?: fn())", }, - "doSystemEvent": { + doSystemEvent: { "!doc": "执行一个系统事件", - "!type": "fn(type: string, data?: ?, callback?: fn())" + "!type": "fn(type: string, data?: ?, callback?: fn())", }, - "resetGame": { + resetGame: { "!doc": "初始化游戏", - "!type": "fn(hero?: ?, hard?: ?, floorId?: string, maps?: ?, values?: ?)" + "!type": + "fn(hero?: ?, hard?: ?, floorId?: string, maps?: ?, values?: ?)", }, - "setFloorInfo": { - "!doc": "设置一项楼层属性并刷新状态栏
例如:core.setFloorInfo('ratio', 2, 'MT0'); // 把主塔0层的血瓶和宝石变为双倍效果
name: 要修改的属性名
values: 属性的新值。
floorId: 楼层id,不填视为当前层
prefix: 独立开关前缀,一般不需要", - "!type": "fn(name: string, values: ?, floorId?: string, prefix?: string)" + setFloorInfo: { + "!doc": + "设置一项楼层属性并刷新状态栏
例如:core.setFloorInfo('ratio', 2, 'MT0'); // 把主塔0层的血瓶和宝石变为双倍效果
name: 要修改的属性名
values: 属性的新值。
floorId: 楼层id,不填视为当前层
prefix: 独立开关前缀,一般不需要", + "!type": + "fn(name: string, values: ?, floorId?: string, prefix?: string)", }, - "openDoor": { - "!doc": "开门(包括三种基础墙)
例如:core.openDoor(0, 0, true, core.jumpHero); // 打开左上角的门,需要钥匙,然后主角原地跳跃半秒
x: 门的横坐标
y: 门的纵坐标
needKey: true表示需要钥匙,会导致机关门打不开
callback: 门完全打开后或打不开时的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(x: number, y: number, needKey?: bool, callback?: fn())" + openDoor: { + "!doc": + "开门(包括三种基础墙)
例如:core.openDoor(0, 0, true, core.jumpHero); // 打开左上角的门,需要钥匙,然后主角原地跳跃半秒
x: 门的横坐标
y: 门的纵坐标
needKey: true表示需要钥匙,会导致机关门打不开
callback: 门完全打开后或打不开时的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(x: number, y: number, needKey?: bool, callback?: fn())", }, - "setEnemy": { - "!doc": "设置一项敌人属性并计入存档
例如:core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0
id: 敌人id
name: 属性的英文缩写
value: 属性的新值,可选
operator: 运算操作符如+=,可选
prefix: 独立开关前缀,一般不需要,下同", - "!type": "fn(id: string, name: string, value: ?, operator?: string, prefix?: string)" + setEnemy: { + "!doc": + "设置一项敌人属性并计入存档
例如:core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0
id: 敌人id
name: 属性的英文缩写
value: 属性的新值,可选
operator: 运算操作符如+=,可选
prefix: 独立开关前缀,一般不需要,下同", + "!type": + "fn(id: string, name: string, value: ?, operator?: string, prefix?: string)", }, - "setEnemyOnPoint": { - "!doc": "设置某个点的敌人属性。如果该点不是怪物,则忽略此函数。
例如:core.setEnemyOnPoint(3, 5, null, 'atk', 100, '+='); // 仅将(3,5)点怪物的攻击力加100。", - "!type": "fn(x: number, y: number, floorId?: string, name: string, value: ?, operator?: string, prefix?: string)" + setEnemyOnPoint: { + "!doc": + "设置某个点的敌人属性。如果该点不是怪物,则忽略此函数。
例如:core.setEnemyOnPoint(3, 5, null, 'atk', 100, '+='); // 仅将(3,5)点怪物的攻击力加100。", + "!type": + "fn(x: number, y: number, floorId?: string, name: string, value: ?, operator?: string, prefix?: string)", }, - "resetEnemyOnPoint": { + resetEnemyOnPoint: { "!doc": "重置某个点的怪物属性", - "!type": "fn(x: number, y: number, floorId?: string)" + "!type": "fn(x: number, y: number, floorId?: string)", }, - "moveEnemyOnPoint": { + moveEnemyOnPoint: { "!doc": "将某个点已经设置的敌人属性移动到其他点", - "!type": "fn(fromX: number, fromY: number, toX: number, toY: number, floorId?: string)" + "!type": + "fn(fromX: number, fromY: number, toX: number, toY: number, floorId?: string)", }, - "autoEventExecuting": { + autoEventExecuting: { "!doc": "当前是否在执行某个自动事件", - "!type": "fn(symbol?: string, value?: ?) -> bool" + "!type": "fn(symbol?: string, value?: ?) -> bool", }, - "checkAutoEvents": { + checkAutoEvents: { "!doc": "检测自动事件", - "!type": "fn()" + "!type": "fn()", }, - "showGif": { - "!doc": "绘制一张动图或擦除所有动图
例如:core.showGif(); // 擦除所有动图
name: 动图文件名,可以是全塔属性中映射前的中文名
x: 动图在视野中的左上角横坐标
y: 动图在视野中的左上角纵坐标", - "!type": "fn(name?: string, x?: number, y?: number)" + showGif: { + "!doc": + "绘制一张动图或擦除所有动图
例如:core.showGif(); // 擦除所有动图
name: 动图文件名,可以是全塔属性中映射前的中文名
x: 动图在视野中的左上角横坐标
y: 动图在视野中的左上角纵坐标", + "!type": "fn(name?: string, x?: number, y?: number)", }, - "unregisterEvent": { + unregisterEvent: { "!doc": "注销一个自定义事件", - "!type": "fn(type: string)" + "!type": "fn(type: string)", }, - "jumpHero": { - "!doc": "主角跳跃,跳跃勇士。ex和ey为目标点的坐标,可以为null表示原地跳跃。time为总跳跃时间。
例如:core.jumpHero(); // 主角原地跳跃半秒
ex: 跳跃后的横坐标
ey: 跳跃后的纵坐标
time: 跳跃时长,单位为毫秒。不填视为半秒
callback: 跳跃完毕后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(ex?: number, ey?: number, time?: number, callback?: fn())" + jumpHero: { + "!doc": + "主角跳跃,跳跃勇士。ex和ey为目标点的坐标,可以为null表示原地跳跃。time为总跳跃时间。
例如:core.jumpHero(); // 主角原地跳跃半秒
ex: 跳跃后的横坐标
ey: 跳跃后的纵坐标
time: 跳跃时长,单位为毫秒。不填视为半秒
callback: 跳跃完毕后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": + "fn(ex?: number, ey?: number, time?: number, callback?: fn())", }, - "closeDoor": { - "!doc": "关门,目标点必须为空地
例如:core.closeDoor(0, 0, 'yellowWall', core.jumpHero); // 在左上角关掉一堵黄墙,然后主角原地跳跃半秒
x: 横坐标
y: 纵坐标
id: 门的id,也可以用三种基础墙
callback: 门完全关上后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(x: number, y: number, id: string, callback?: fn())" + closeDoor: { + "!doc": + "关门,目标点必须为空地
例如:core.closeDoor(0, 0, 'yellowWall', core.jumpHero); // 在左上角关掉一堵黄墙,然后主角原地跳跃半秒
x: 横坐标
y: 纵坐标
id: 门的id,也可以用三种基础墙
callback: 门完全关上后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(x: number, y: number, id: string, callback?: fn())", }, - "eventMoveHero": { - "!doc": "强制移动主角(包括后退),这个函数的作者已经看不懂这个函数了
例如:core.eventMoveHero(['forward'], 125, core.jumpHero); // 主角强制前进一步,用时1/8秒,然后主角原地跳跃半秒
steps: 步伐数组,注意后退时跟随者的行为会很难看
time: 每步的用时,单位为毫秒。0或不填则取主角的移速,如果后者也不存在就取0.1秒
callback: 移动完毕后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(steps: [step], time?: number, callback?: fn())" + eventMoveHero: { + "!doc": + "强制移动主角(包括后退),这个函数的作者已经看不懂这个函数了
例如:core.eventMoveHero(['forward'], 125, core.jumpHero); // 主角强制前进一步,用时1/8秒,然后主角原地跳跃半秒
steps: 步伐数组,注意后退时跟随者的行为会很难看
time: 每步的用时,单位为毫秒。0或不填则取主角的移速,如果后者也不存在就取0.1秒
callback: 移动完毕后的回调函数,可选
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": "fn(steps: [step], time?: number, callback?: fn())", }, - "changeFloor": { - "!doc": "场景切换
例如:core.changeFloor('MT0'); // 传送到主塔0层,主角坐标和朝向不变,黑屏时间取用户定义的值
floorId: 传送的目标地图id,可以填':before'和':next'分别表示楼下或楼上
stair: 传送的位置
heroLoc: 传送的坐标;会覆盖stair
time: 传送的黑屏时间,单位为毫秒;不填为用户设置值
callback: 传送的回调函数
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", - "!type": "fn(floorId: string, stair?: string, heroLoc?: {x?: number, y?: number, direction?: string}, time?: number, callback?: fn())" + changeFloor: { + "!doc": + "场景切换
例如:core.changeFloor('MT0'); // 传送到主塔0层,主角坐标和朝向不变,黑屏时间取用户定义的值
floorId: 传送的目标地图id,可以填':before'和':next'分别表示楼下或楼上
stair: 传送的位置
heroLoc: 传送的坐标;会覆盖stair
time: 传送的黑屏时间,单位为毫秒;不填为用户设置值
callback: 传送的回调函数
【异步脚本,请勿在脚本中直接调用(而是使用对应的事件),否则可能导致录像出错】", + "!type": + "fn(floorId: string, stair?: string, heroLoc?: {x?: number, y?: number, direction?: string}, time?: number, callback?: fn())", }, - "getCommonEvent": { + getCommonEvent: { "!doc": "获得一个公共事件", - "!type": "fn(name: string) -> [?]" + "!type": "fn(name: string) -> [?]", }, - "lose": { + lose: { "!doc": "游戏失败事件", - "!type": "fn(reason?: string)" + "!type": "fn(reason?: string)", }, - "gameOver": { - "!doc": "游戏结束
例如:core.gameOver(); // 游戏失败
ending: 结局名,省略表示失败
fromReplay: true表示在播放录像,可选
norank: true表示不计入榜单,可选", - "!type": "fn(ending?: string, fromReplay?: bool, norank?: bool)" + gameOver: { + "!doc": + "游戏结束
例如:core.gameOver(); // 游戏失败
ending: 结局名,省略表示失败
fromReplay: true表示在播放录像,可选
norank: true表示不计入榜单,可选", + "!type": "fn(ending?: string, fromReplay?: bool, norank?: bool)", }, - "useFly": { + useFly: { "!doc": "点击楼层传送器时的打开操作", - "!type": "fn(fromUserAction?: bool)" + "!type": "fn(fromUserAction?: bool)", + }, + tryUseItem: { + "!doc": + "尝试使用一个道具
例如:core.tryUseItem('pickaxe'); // 尝试使用破墙镐
itemId: 道具id,其中敌人手册、传送器和飞行器会被特殊处理", + "!type": "fn(itemId: string)", }, - "tryUseItem": { - "!doc": "尝试使用一个道具
例如:core.tryUseItem('pickaxe'); // 尝试使用破墙镐
itemId: 道具id,其中敌人手册、传送器和飞行器会被特殊处理", - "!type": "fn(itemId: string)" - } }, - "plugin": { + plugin: { "!doc": "插件编写中内置了一些常用的插件。", - "drawLight": { - "!doc": "绘制一段灯光效果
name:必填,要绘制到的画布名;可以是一个系统画布,或者是个自定义画布;如果不存在则创建
color:可选,只能是一个0~1之间的数,为不透明度的值。不填则默认为0.9。
lights:可选,一个数组,定义了每个独立的灯光。其中每一项是三元组 [x,y,r] x和y分别为该灯光的横纵坐标,r为该灯光的半径。
lightDec:可选,0到1之间,光从多少百分比才开始衰减(在此范围内保持全亮),不设置默认为0。比如lightDec为0.5代表,每个灯光部分内圈50%的范围全亮,50%以后才开始快速衰减。
例如:core.plugin.drawLight('test', 0.2, [[25,11,46,0.1]]); // 创建一个test图层,不透明度0.2,其中在(25,11)点存在一个半径为46的灯光效果,灯光中心不透明度0.1。
core.plugin.drawLight('test2', 0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 创建test2图层,且存在三个灯光效果,分别是中心(25,11)半径46,中心(105,121)半径88,中心(301,221)半径106。", - "!type": "fn(name: string|CanvasRenderingContext2D, color?: number, lights?: [[number]], lightDec?: number)" + drawLight: { + "!doc": + "绘制一段灯光效果
name:必填,要绘制到的画布名;可以是一个系统画布,或者是个自定义画布;如果不存在则创建
color:可选,只能是一个0~1之间的数,为不透明度的值。不填则默认为0.9。
lights:可选,一个数组,定义了每个独立的灯光。其中每一项是三元组 [x,y,r] x和y分别为该灯光的横纵坐标,r为该灯光的半径。
lightDec:可选,0到1之间,光从多少百分比才开始衰减(在此范围内保持全亮),不设置默认为0。比如lightDec为0.5代表,每个灯光部分内圈50%的范围全亮,50%以后才开始快速衰减。
例如:core.plugin.drawLight('test', 0.2, [[25,11,46,0.1]]); // 创建一个test图层,不透明度0.2,其中在(25,11)点存在一个半径为46的灯光效果,灯光中心不透明度0.1。
core.plugin.drawLight('test2', 0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 创建test2图层,且存在三个灯光效果,分别是中心(25,11)半径46,中心(105,121)半径88,中心(301,221)半径106。", + "!type": + "fn(name: string|CanvasRenderingContext2D, color?: number, lights?: [[number]], lightDec?: number)", }, - "openShop": { - "!doc": "打开一个全局商店
shopId: 要开启的商店ID
noRoute: 打开行为是否不计入录像", - "!type": "fn(shopId: string, noRoute?: bool)" + openShop: { + "!doc": + "打开一个全局商店
shopId: 要开启的商店ID
noRoute: 打开行为是否不计入录像", + "!type": "fn(shopId: string, noRoute?: bool)", }, - "isShopVisited": { + isShopVisited: { "!doc": "某个全局商店是否被访问过", - "!type": "fn(id: string) -> bool" + "!type": "fn(id: string) -> bool", }, - "listShopIds": { + listShopIds: { "!doc": "列出所有应当显示的快捷商店列表", - "!type": "fn() -> [string]" + "!type": "fn() -> [string]", }, - "canOpenShop": { + canOpenShop: { "!doc": "当前能否打开某个商店", - "!type": "fn(id: string) -> bool" + "!type": "fn(id: string) -> bool", }, - "setShopVisited": { + setShopVisited: { "!doc": "设置某个商店的访问状态", - "!type": "fn(id: string, visited?: bool)" + "!type": "fn(id: string, visited?: bool)", }, - "canUseQuickShop": { - "!doc": "当前能否使用某个快捷商店
如果返回一个字符串,则代表不能,返回的字符串作为不能的提示;返回null表示可以使用", - "!type": "fn(id: string) -> string" + canUseQuickShop: { + "!doc": + "当前能否使用某个快捷商店
如果返回一个字符串,则代表不能,返回的字符串作为不能的提示;返回null表示可以使用", + "!type": "fn(id: string) -> string", }, - "removeMaps": { - "!doc": "删除某一些楼层;删除后不会存入存档,不可浏览地图也不可飞到。
fromId: 开始删除的楼层ID
toId: 删除到的楼层编号;可选,不填则视为fromId
例如:core.removeMaps(\"MT1\", \"MT300\") 删除MT1~MT300之间的全部层
core.removeMaps(\"MT10\") 只删除MT10层", - "!type": "fn(fromId: string, toId?: string)" + removeMaps: { + "!doc": + '删除某一些楼层;删除后不会存入存档,不可浏览地图也不可飞到。
fromId: 开始删除的楼层ID
toId: 删除到的楼层编号;可选,不填则视为fromId
例如:core.removeMaps("MT1", "MT300") 删除MT1~MT300之间的全部层
core.removeMaps("MT10") 只删除MT10层', + "!type": "fn(fromId: string, toId?: string)", }, - "resumeMaps": { - "!doc": "恢复某一些被删除楼层。
fromId: 开始恢复的楼层ID
toId: 恢复到的楼层编号;可选,不填则视为fromId
例如:core.resumeMaps(\"MT1\", \"MT300\") 恢复MT1~MT300之间的全部层
core.resumeMaps(\"MT10\") 只删恢复MT10层", - "!type": "fn(fromId: string, toId?: string)" + resumeMaps: { + "!doc": + '恢复某一些被删除楼层。
fromId: 开始恢复的楼层ID
toId: 恢复到的楼层编号;可选,不填则视为fromId
例如:core.resumeMaps("MT1", "MT300") 恢复MT1~MT300之间的全部层
core.resumeMaps("MT10") 只删恢复MT10层', + "!type": "fn(fromId: string, toId?: string)", }, - "autoRemoveMaps": { + autoRemoveMaps: { "!doc": "根据楼层分区信息自动砍层与恢复", - "!type": "fn(floorId: string)" + "!type": "fn(floorId: string)", }, - "openItemShop": { + openItemShop: { "!doc": "打开一个道具商店", - "!type": "fn(itemShopId: string)" - } - } + "!type": "fn(itemShopId: string)", + }, + }, }, - "lzw_encode": { + lzw_encode: { "!doc": "LZW压缩算法", "!url": "https://gist.github.com/revolunet/843889", - "!type": "fn(s: string) -> string" + "!type": "fn(s: string) -> string", }, - "lzw_decode": { + lzw_decode: { "!doc": "LZW解压缩算法", "!url": "https://gist.github.com/revolunet/843889", - "!type": "fn(s: string) -> string" + "!type": "fn(s: string) -> string", }, - "hero": { + hero: { "!type": "heroStatus", "!doc": "勇士信息,为 core.status.hero 的简写", }, - "flags": { + flags: { "!type": "flag", "!doc": "游戏中用到的变量,为 core.status.hero.flags 的简写", - } - } -]; \ No newline at end of file + }, + }, +]; diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 63c674d..7cfcd64 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -567,7 +567,7 @@ doorInfo_m /* doorInfo_m tooltip : 开门信息 -default : [160, 'door.mp3', 'door.mp3'] +default : [160, 'door.opus', 'door.opus'] helpUrl : /_docs/#/instruction EvalString_0 = EvalString_0 && (', "openSound": "' + EvalString_0 + '"'); EvalString_1 = EvalString_1 && (', "closeSound": "' + EvalString_1 + '"'); @@ -854,6 +854,8 @@ action | waitAsync_s | stopAsync_s | op_s + | setmusics_s + | introAndLoop_s | battle_s | battle_1_s | openDoor_s @@ -958,11 +960,12 @@ action | removeMouse_s | drawWarning_s | addPop_s + | setq_s + | setcgs_s | animationDrawable_s | over_s | overlist_s - | playStereo_s - | moveStereo_s + | cgtextList_s | pass_s ; @@ -1121,22 +1124,33 @@ overtextEmpty var code = []; return code; */; +cgtextList_s + : '切换剧情文本库' EvalString Newline + + +/* cgtextList_s +tooltip : cgtextList:设置cg剧情文本库 +helpUrl : /_docs/#/instruction +default : ["chapter0"] +var code = '{"type": "cgtextList", "textList":"'+EvalString_0+'"},\n'; +return code; +*/; cgtext_s - : '背景' EvalString? '回忆滤镜' Bool? '移除对话框' Bool? '头像' EvalString?'名字' EvalString?'坐标PX' Number'打字间隔' Int? BGNL? Newline - '自动等待时长' Int '音频文件(需在全塔属性——使用音效注册)'EvalString? BGNL? Newline - EvalString? BGNL? Newline textcgDrawingList+? Newline + : '背景' EvalString? '不使用背景' Bool? '回忆滤镜' Bool? '移除对话框' Bool? '剧情库序列' Int '头像' EvalString?'坐标PX' Number'打字间隔' Int? BGNL? Newline + '自动等待时长' Int BGNL? Newline + textcgDrawingList+? Newline /* cgtext_s tooltip : cgtext:显示一段包含cg的文字(剧情) helpUrl : /_docs/#/instruction allImages : ['EvalString_0','EvalString_1'] -allSounds : ['EvalString_3'] -default : ["bg_5043.webp",false,"face_050445.webp",false,"菲奥奈",-300,0,2000,"","这句话显示在对话框内",[{ "name":"tati_050145a.webp" , "px": 100,"filter":false }]] +default : ["bg_5043.webp",false,false,false,0,"face_050445.webp",-300,0,2000,"","这句话显示在对话框内",[{ "name":"tati_050145a.webp" , "px": 100,"filter":false }]] var head ='{ "name": "'+EvalString_1+'", "px": '+Number_0+' }' var list=',"bodyList": [\n'+textcgDrawingList_0.slice(0,-1)+'\n]' -var code = '{"type": "cgtext", "bg":"'+EvalString_0+'","memory":'+Bool_0+',"WindowSkin":'+Bool_1+',"head":'+head+' ,"name":"'+EvalString_2+'","time":'+Int_0+',"wait":'+Int_1+',"sound":"'+EvalString_3+'","text": "'+EvalString_4+'"'+list+' },\n'; +Bool_0=Bool_0?',"nobg":'+Bool_0:'' +var code = '{"type": "cgtext", "bg":"'+EvalString_0+'"'+Bool_0+',"memory":'+Bool_1+',"WindowSkin":'+Bool_2+',"head":'+head+' ,"index":"'+Int_0+'","time":'+Int_1+',"wait":'+Int_2+list+' },\n'; return code; */; textcgDrawingList @@ -1144,16 +1158,19 @@ textcgDrawingList | textcgDrawingEmpty; textcgDrawing - : '立绘' EvalString? '绘制坐标' 'x' Number '变暗'Bool? Newline + : '立绘' EvalString? '绘制坐标' 'x' Number '变暗'Bool? '绘制大小w' IntString? 'h' IntString? '绘制比例(填写后w、h失效,此项默认1.7)' EvalString? Newline /* textcgDrawing tooltip : 立绘 helpUrl : /_docs/#/instruction -default : ["tati_050145a.webp",100,false] +default : ["tati_050145a.webp",100,false,"","",""] colour : this.subColor allImages : ['EvalString_0'] - -return '{ "name": "'+EvalString_0+'", "px": '+Number_0+',"filter":'+Bool_0+' },' +if(EvalString_1&&!/^(0|([1-9][0-9]*))(\.[\d]+)?$/.test(EvalString_1))throw new Error("此项仅能填写小数、整数或不填"); +IntString_0=IntString_0?(',"w":'+IntString_0+''):'' +IntString_1=IntString_1?(',"h":'+IntString_1+''):'' +EvalString_1=EvalString_1?(',"scale":'+EvalString_1+''):'' +return '{ "name": "'+EvalString_0+'", "px": '+Number_0+',"filter":'+Bool_0+IntString_0+IntString_1+EvalString_1+' },' */; textcgDrawingEmpty @@ -1951,16 +1968,17 @@ return code; */; drawWarning_s - : '警告坐标x' PosString 'y' PosString '文字大小'Int '警告内容' EvalString? '副标题' EvalString? '不播放音效' Bool? Newline + : '警告坐标x' PosString 'y' PosString '缩放倍率'EvalString '文字大小'Int '警告内容' EvalString? '副标题' EvalString? '不播放音效' Bool? Newline /* drawWarning_s tooltip : drawWarning: 绘制warning警告并拉进镜头,本事件为异步事件,下一事件将在3100ms后执行 helpUrl : /_docs/#/instruction -default : [0, 0,24,"这里是提示内容","绿色史莱姆",false] +default : [0, 0,'2',24,"这里是提示内容","绿色史莱姆",false] colour : this.soundColor selectPoint : ["PosString_0", "PosString_1"] -var code = '{"type": "drawWarning", "x": '+PosString_0+', "y": '+PosString_1+',"size":'+Int_0+',"text": "'+EvalString_0+'", "text2": "'+EvalString_1+'", "warning": '+Bool_0+'},\n'; +if(!EvalString_1||!/^(0|([1-9][0-9]*))(\.[\d]+)?$/.test(EvalString_1))throw new Error("此项仅能填写小数或整数"); +var code = '{"type": "drawWarning", "x": '+PosString_0+', "y": '+PosString_1+',"large":'+EvalString_0+',"size":'+Int_0+',"text": "'+EvalString_1+'", "text2": "'+EvalString_2+'", "warning": '+Bool_0+'},\n'; return code; */; @@ -2229,7 +2247,7 @@ setanimate_s : '新建 帧动画/特效' '名称' EvalString '参照点偏移像素x' IntString? 'y' IntString? '动画大小 宽' IntString '高' IntString '总帧数' IntString BGNL?Newline '图片序列(同一帧后面覆盖先前的,默认起始帧为0,结束帧为最后一帧)'BGNL?Newline '(剪裁区域不填写为全图,绘制区域不填写为全画面)'BGNL?Newline - '(透明度100为不透明,默认为不透明,结束透明度默认与开始透明度相同)'BGNL?Newline + '(不透明度100为不透明,默认为不透明,结束透明度默认与开始不透明度相同)'BGNL?Newline animateDrawableimage+? Newline '音频序列(到达对应帧进行播放)'BGNL?Newline animateDrawablesound+? Newline @@ -2238,12 +2256,12 @@ setanimate_s tooltip : setanimate:设置帧动画/特效(此项仅储存,不播放) helpUrl : /_docs/#/instruction default : ["sword","","",192,192,60] -colour : this.soundColor +colour : this.imageColor IntString_0 = IntString_0 ? (', "px": '+IntString_0+'') : ''; IntString_1 = IntString_1 ? (', "py": '+IntString_1+'') : ''; var imageList=animateDrawableimage_0?',"imageList": [\n'+animateDrawableimage_0.slice(0,-1)+'\n]':'' var soundList=animateDrawablesound_0?',"soundList": [\n'+animateDrawablesound_0.slice(0,-1)+'\n]':'' -var code = '{"type": "setanimate", "name": "'+EvalString_0+'",'+IntString_0+IntString_1+' "width": '+IntString_2+', "height": '+IntString_3+', "allFarme": '+IntString_4+imageList+soundList+'},\n'; +var code = '{"type": "setanimate", "name": "'+EvalString_0+'"'+IntString_0+IntString_1+' ,"width": '+IntString_2+', "height": '+IntString_3+', "allFarme": '+IntString_4+imageList+soundList+'},\n'; return code; */; @@ -2253,17 +2271,17 @@ animateDrawableList | animateDrawabletextEmpty; animateDrawableimage - : '图片' EvalString? '起始帧' IntString? '起始透明度' IntString? BGNL? Newline + : '图片' EvalString? '起始帧' IntString? '起始不透明度' IntString? BGNL? Newline '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString?'旋转角度'IntString? BGNL? Newline - '结束帧' IntString? '结束透明度' IntString? '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString?'旋转角度'IntString? Newline + '结束帧' IntString? '结束不透明度' IntString? '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString?'旋转角度'IntString? Newline /* animateDrawableimage tooltip : 帧动画图片列表 helpUrl : /_docs/#/instruction default : ["","","","","","","","","","","","","","","","","","","","","","",""] colour : this.subColor allImages : ['EvalString_0'] -if (IntString_1&&(IntString_1 < 0||IntString_1>100)) throw new Error('透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') -if (IntString_12&&(IntString_12 < 0||IntString_12>100)) throw new Error('透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') +if (IntString_1&&(IntString_1 < 0||IntString_1>100)) throw new Error('不透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') +if (IntString_12&&(IntString_12 < 0||IntString_12>100)) throw new Error('不透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') IntString_0 = IntString_0 ? (', "beforefarme": '+IntString_0+'') : ''; IntString_1 = IntString_1 ? (', "globalAlpha": '+IntString_1+'') : ''; IntString_2 = IntString_2 ? (', "cx": '+IntString_2+'') : ''; @@ -2317,28 +2335,30 @@ deleteanimate_s /* deleteanimate_s tooltip : deleteanimate:删除储存的帧动画 helpUrl : /_docs/#/instruction -default : [""] +default : ["zone"] -colour : this.soundColor +colour : this.imageColor var code = '{"type": "deleteanimate", "name": "'+EvalString_0+'"},\n'; return code; */; playanimate_s - : '播放 帧动画/特效' '名称' EvalString '像素x' IntString? 'y' IntString? '跟随勇士' Bool 'x方向缩放' IntString? 'y方向缩放'IntString? Newline + : '播放 帧动画/特效' '名称' EvalString '像素x' IntString? 'y' IntString? '跟随勇士' Bool 'x方向缩放' EvalString? 'y方向缩放'EvalString? Newline /* playanimate_s tooltip : playanimate:播放帧动画,选择跟随勇士后x、y将失效改为勇士中心坐标 helpUrl : /_docs/#/instruction default : ["zone","","",false,"",""] -colour : this.soundColor +colour : this.imageColor IntString_0 = IntString_0 ? (', "x": '+IntString_0+'') : ''; IntString_1 = IntString_1 ? (', "y": '+IntString_1+'') : ''; -IntString_2 = IntString_2 ? (', "scalex": '+IntString_2+'') : ''; -IntString_3 = IntString_3 ? (', "scaley": '+IntString_3+'') : ''; -var code = '{"type": "playanimate", "name": "'+EvalString_0+'"'+IntString_0+IntString_1+',"hero":'+Bool_0+IntString_2+IntString_3+'},\n'; +if(EvalString_1&&!/^(0|([1-9][0-9]*))(\.[\d]+)?$/.test(EvalString_1))throw new Error("此项仅能填写小数、整数或不填"); +if(EvalString_2&&!/^(0|([1-9][0-9]*))(\.[\d]+)?$/.test(EvalString_2))throw new Error("此项仅能填写小数、整数或不填"); +EvalString_1 = EvalString_1 ? (', "scalex": '+EvalString_1+'') : ''; +EvalString_2 = EvalString_2 ? (', "scaley": '+EvalString_2+'') : ''; +var code = '{"type": "playanimate", "name": "'+EvalString_0+'"'+IntString_0+IntString_1+',"hero":'+Bool_0+EvalString_1+EvalString_2+'},\n'; return code; */; @@ -2349,7 +2369,7 @@ clearanimate_s tooltip : clearanimate:清空正在播放的帧动画 helpUrl : /_docs/#/instruction -colour : this.soundColor +colour : this.imageColor var code = '{"type": "clearanimate"},\n'; return code; @@ -2591,6 +2611,66 @@ var code = '{"type": "rotateImage", "code": '+NInt_0+loc+', "angle": '+NInt_1+Mo return code; */; +setq_s + : '设置任务目标楼层'IdString?'不填为清空当前任务指引' Newline + +/* setq_s +tooltip : setq:设置任务目标楼层(显示在小地图) +helpUrl : /_docs/#/instruction +default : [""] +allFloorIds : ['IdString_0'] +colour : this.soundColor +IdString_0 = IdString_0 ? (', "id": "'+IdString_0+'"') : ''; +var code = '{"type": "setq"'+IdString_0+'},\n'; +return code; +*/; + +introAndLoop_s + : '前奏音乐文件'EvalString? '前奏音乐文件播放时长(可填小数,单位为秒)'EvalString'循环音乐文件'EvalString? Newline + +/* introAndLoop_s +tooltip : introAndLoop:设置任务目标楼层(显示在小地图) +helpUrl : /_docs/#/instruction +default : ["",1,""] +allBgms : ['EvalString_0','EvalString_2'] +colour :this.imageColor +if(EvalString_1&&!/^(0|([1-9][0-9]*))(\.[\d]+)?$/.test(EvalString_1))throw new Error("此项仅能填写小数或整数,单位为秒"); +EvalString_0 = EvalString_0 ? (', "intro": "'+EvalString_0+'"') : ''; +EvalString_1= EvalString_1 ? (', "time": '+EvalString_1+'') : ''; +EvalString_2 = EvalString_2 ? (', "loop": "'+EvalString_2+'"') : ''; +var code = '{"type": "introAndLoop"'+EvalString_0+EvalString_1+EvalString_2+'},\n'; +return code; +*/; + + +setcgs_s + : 'cg回廊获取cg 文件名'EvalString?'不填为清空cg获取记录' Newline + +/* setcgs_s +tooltip : setcgs:cg回廊中的cg获取 +helpUrl : /_docs/#/instruction +default : [""] +allImages : ['EvalString_0'] +colour : this.soundColor +EvalString_0 = EvalString_0 ? (', "img": "'+EvalString_0+'"') : ''; +var code = '{"type": "setcgs"'+EvalString_0+'},\n'; +return code; +*/; + +setmusics_s + : '音乐鉴赏music 文件名'EvalString?'不填为清空music获取记录' Newline + +/* setmusics_s +tooltip : setmusics:音乐鉴赏中的隐藏music获取 +helpUrl : /_docs/#/instruction +default : [""] +allBgms : ['EvalString_0'] +colour : this.soundColor +EvalString_0 = EvalString_0 ? (', "bgm": "'+EvalString_0+'"') : ''; +var code = '{"type": "setmusics"'+EvalString_0+'},\n'; +return code; +*/; + scaleImage_s : '图片放缩' '图片编号' NInt '中心点像素' 'x' PosString? 'y' PosString? '移动方式' MoveMode_List BGNL? '放缩比例' Number '动画时间' Int '不等待执行完毕' Bool Newline @@ -2610,11 +2690,12 @@ var code = '{"type": "scaleImage", "code": '+NInt_0+loc+', "scale": '+Number_0+M return code; */; + animationDrawable_s - : '帧动画' '总显示帧数' IntString '底色' ColorString? Colour '底色透明度' IntString? BGNL?Newline + : '帧动画' '总显示帧数' IntString '底色' ColorString? Colour '底色不透明度' IntString? BGNL?Newline '图片序列(同一帧后面覆盖先前的,默认起始帧为0,结束帧为最后一帧)'BGNL?Newline '(剪裁区域不填写为全图,绘制区域不填写为全画面)'BGNL?Newline - '(透明度100为不透明,默认为不透明,结束透明度默认与开始透明度相同)'BGNL?Newline + '(不透明度100为不透明,默认为不透明,结束不透明度默认与开始透明度相同)'BGNL?Newline animationDrawableimage+? Newline '音频序列(到达对应帧进行播放)'BGNL?Newline animationDrawablesound+? Newline @@ -2642,17 +2723,17 @@ animationDrawableList | animationDrawabletextEmpty; animationDrawableimage - : '图片' EvalString? '起始帧' IntString? '起始透明度' IntString? BGNL? Newline + : '图片' EvalString? '起始帧' IntString? '起始不透明度' IntString? BGNL? Newline '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString? BGNL? Newline - '结束帧' IntString? '结束透明度' IntString? '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString? Newline + '结束帧' IntString? '结束不透明度' IntString? '剪裁坐标cx' IntString? 'cy' IntString? '宽' IntString? '高' IntString? '绘制坐标x'IntString? 'y' IntString? '宽' IntString? '高' IntString? Newline /* animationDrawableimage tooltip : 帧动画图片列表 helpUrl : /_docs/#/instruction default : ["","","","","","","","","","","","","","","","","","","","",""] colour : this.subColor allImages : ['EvalString_0'] -if (IntString_1&&(IntString_1 < 0||IntString_1>100)) throw new Error('透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') -if (IntString_11&&(IntString_11 < 0||IntString_11>100)) throw new Error('透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') +if (IntString_1&&(IntString_1 < 0||IntString_1>100)) throw new Error('不透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') +if (IntString_11&&(IntString_11 < 0||IntString_11>100)) throw new Error('不透明度范围为0-100,0为透明,100为不透明,不填默认为不透明') IntString_0 = IntString_0 ? (', "beforefarme": '+IntString_0+'') : ''; IntString_1 = IntString_1 ? (', "globalAlpha": '+IntString_1+'') : ''; IntString_2 = IntString_2 ? (', "cx": '+IntString_2+'') : ''; @@ -3008,38 +3089,7 @@ var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+IntString_0 return code; */; -playStereo_s - : '播放音效(立体音)' EvalString '左声道音量' Int '右声道音量' Int '启用立体音' Bool? Newline - -/* playStereo_s -tooltip : playSound: 播放音效(立体音) -helpUrl : /_docs/#/instruction -default : ["item.mp3",1,1,true] -colour : this.imageColor -allSounds : ['EvalString_0'] -material : ["./project/sounds/", "EvalString_0"] - -var code = '{"type": "playStereo", "name": "'+EvalString_0+'", "left": '+Int_0+', "right": '+Int_1+', "split": '+Bool_0+'},\n'; -return code; -*/; - -moveStereo_s - : '播放渐变音效(立体音)' EvalString '左声道音量' Int '右声道音量' Int '启用立体音' Bool? BGNL? Newline - '左声道目标音量' Int '右声道目标音量' Int '渐变时长'Int Newline - - -/* moveStereo_s -tooltip : playSound: 播放渐变音效(立体音) -helpUrl : /_docs/#/instruction -default : ["item.mp3",1,1,true,10,10,1000] -colour : this.imageColor -allSounds : ['EvalString_0'] -material : ["./project/sounds/", "EvalString_0"] - -var code = '{"type": "moveStereo", "name": "'+EvalString_0+'", "left": '+Int_0+', "right": '+Int_1+', "split": '+Bool_0+', "leftTo": '+Int_2+', "rightTo": '+Int_3+', "time": '+Int_4+'},\n'; -return code; -*/; playSound_1_s : '播放系统音效' NameMap_List '停止之前音效' Bool? '音调' IntString? '等待播放完毕' Bool? Newline @@ -4575,8 +4625,8 @@ IdString ; FixedId_List - : '生命'|'生命上限'|'攻击'|'防御'|'护盾'|'黄钥匙'|'蓝钥匙'|'红钥匙'|'金币'|'经验'|'魔力'|'魔力上限'|'当前横坐标'|'当前纵坐标'|'当前朝向'|'攻击增益'|'防御增益'|'护盾增益' - /*FixedId_List ['status:hp','status:hpmax','status:atk','status:def','status:mdef','item:yellowKey','item:blueKey','item:redKey','status:money','status:exp','status:mana','status:manamax','status:x','status:y','status:direction','buff:atk','buff:def','buff:mdef']*/; + : '生命'|'生命上限'|'攻击'|'防御'|'法强'|'魔攻比例'|'护盾比例'|'法抗比例'|'黄钥匙'|'蓝钥匙'|'红钥匙'|'金币'|'经验'|'魔力'|'魔力上限'|'当前横坐标'|'当前纵坐标'|'当前朝向'|'攻击增益'|'防御增益'|'法强增益'|'魔攻增益'|'法抗增益'|'护盾增益' + /*FixedId_List ['status:hp','status:hpmax','status:atk','status:def','status:spell','status:matk','status:mhp','status:mdef','item:yellowKey','item:blueKey','item:redKey','status:money','status:exp','status:mana','status:manamax','status:x','status:y','status:direction','buff:atk','buff:def','buff:spell','buff:matk','buff:mdef','buff:mhp']*/; Id_List : '变量' | '状态' | '物品' | '增益' | '独立开关' | '临时变量' |'全局存储' @@ -4591,8 +4641,8 @@ EnemyPoint_List /*EnemyPoint_List ['hp','atk','def','money','exp','point','name']*/; Equip_List - : '生命'|'生命上限'|'攻击'|'防御'|'护盾'|'魔力'|'魔力上限' - /*Equip_List ['hp','hpmax','atk','def','mdef','mana','manamax']*/; + : '生命'|'生命上限'|'攻击'|'防御'|'法强'|'魔攻比例'|'护盾比例'|'法抗百分比'|'魔力'|'魔力上限'|'速度' + /*Equip_List ['hp','hpmax','atk','def','spell','matk','mhp','mdef','mana','manamax','speed']*/; Key_List : '黄钥匙'|'蓝钥匙'|'红钥匙'|'绿钥匙'|'铁门钥匙' diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js index a6cd595..c4ce5b7 100644 --- a/_server/MotaActionParser.js +++ b/_server/MotaActionParser.js @@ -542,6 +542,12 @@ MotaActionParser = function () { ); } break; + case "cgtextList": + this.next = MotaActionBlocks["cgtextList_s"].xmlText([ + data.textList, + this.next, + ]); + break; case "cgtext": // cg对话框 var buildcgDrawing = function (obj) { obj = MotaActionFunctions.processcgDrawing(obj || []); @@ -551,6 +557,9 @@ MotaActionParser = function () { one[0], one[1], one[2], + one[3], + one[4], + one[5], res, ]); } @@ -558,15 +567,14 @@ MotaActionParser = function () { }; this.next = MotaActionBlocks["cgtext_s"].xmlText([ data.bg, + data.nobg??false, data.memory, data.WindowSkin, + data.index, data.head.name, - data.name || "", data.head.px || -300, data.time, data.wait, - data.sound, - data.text, buildcgDrawing(data.bodyList), this.next, ]); @@ -611,6 +619,26 @@ MotaActionParser = function () { this.next, ]); break; + case "setq": + this.next = MotaActionBlocks["setq_s"].xmlText([data.id, this.next]); + break; + case "setcgs": + this.next = MotaActionBlocks["setcgs_s"].xmlText([data.img, this.next]); + break; + case "setmusics": + this.next = MotaActionBlocks["setmusics_s"].xmlText([ + data.bgm, + this.next, + ]); + break; + case "introAndLoop": + this.next = MotaActionBlocks["introAndLoop_s"].xmlText([ + data.intro, + data.time, + data.loop, + this.next, + ]); + break; case "comment": // 注释 this.next = MotaActionBlocks["comment_s"].xmlText([ this.EvalString_Multi(data.text), @@ -642,6 +670,7 @@ MotaActionParser = function () { this.next, ]); break; + case "addPop": this.next = MotaActionBlocks["addPop_s"].xmlText([ data.value, @@ -767,18 +796,18 @@ MotaActionParser = function () { break; case "deleteanimate": this.next = MotaActionBlocks["deleteanimate_s"].xmlText([ - this.name, + data.name, this.next, ]); break; case "playanimate": this.next = MotaActionBlocks["playanimate_s"].xmlText([ - this.name, - this.x, - this.y, - this.hero, - this.scalex, - this.scaley, + data.name, + data.x, + data.y, + data.hero, + data.scalex, + data.scaley, this.next, ]); break; @@ -837,6 +866,7 @@ MotaActionParser = function () { this.next, ]); break; + case "tip": this.next = MotaActionBlocks["tip_s"].xmlText([ data.text, @@ -1495,27 +1525,6 @@ MotaActionParser = function () { ]); } break; - case "playStereo": - this.next = MotaActionBlocks["playStereo_s"].xmlText([ - data.name, - data.left, - data.right, - data.split || true, - this.next, - ]); - break; - case "moveStereo": - this.next = MotaActionBlocks["moveStereo_s"].xmlText([ - data.name, - data.left, - data.right, - data.split || true, - data.leftTo, - data.rightTo, - data.time, - this.next, - ]); - break; case "playSound": var knownItems = MotaActionBlocks["NameMap_List"].options.map(function ( one @@ -2096,6 +2105,7 @@ MotaActionParser = function () { this.next = MotaActionBlocks["drawWarning_s"].xmlText([ data.x, data.y, + data.large, data.size, data?.text, data?.text2, @@ -2901,7 +2911,7 @@ MotaActionParser = function () { MotaActionFunctions.processcgDrawing = function (bodyList) { var list = []; bodyList.forEach(function (one) { - list.push([one.name, one.px, one.filter]); + list.push([one.name, one.px, one.filter, one.w, one.h, one.scale]); }); return list; }; diff --git a/_server/config.json b/_server/config.json deleted file mode 100644 index d292a15..0000000 --- a/_server/config.json +++ /dev/null @@ -1 +0,0 @@ -{"viewportLoc":[0,0],"editorLastFloorId":"xiaoxiang3","lastUsed":[{"idnum":201037,"id":"X201037","images":"C5.webp","x":5,"y":129,"isTile":true,"recent":1736851459688,"frequent":19},{"idnum":130167,"id":"X130167","images":"C2.webp","x":7,"y":20,"isTile":true,"recent":1736851331961,"frequent":2},{"idnum":110222,"id":"X110222","images":"C4.webp","x":6,"y":27,"isTile":true,"recent":1736851316544,"frequent":1},{"idnum":110189,"id":"X110189","images":"C4.webp","x":5,"y":23,"isTile":true,"recent":1736851247648,"frequent":23},{"idnum":110191,"id":"X110191","images":"C4.webp","x":7,"y":23,"isTile":true,"recent":1736851245817,"frequent":23},{"idnum":90649,"id":"X90649","images":"12.webp","x":1,"y":81,"isTile":true,"recent":1736851236632,"frequent":3},{"idnum":110146,"id":"X110146","images":"C4.webp","x":2,"y":18,"isTile":true,"recent":1736850986169,"frequent":20},{"idnum":110114,"id":"X110114","images":"C4.png","x":2,"y":14,"isTile":true,"recent":1736850978473,"frequent":56},{"idnum":110122,"id":"X110122","images":"C4.png","x":2,"y":15,"isTile":true,"recent":1736850974401,"frequent":22},{"idnum":110138,"id":"X110138","images":"C4.webp","x":2,"y":17,"isTile":true,"recent":1736850957209,"frequent":10},{"idnum":110224,"id":"X110224","images":"C4.webp","x":0,"y":28,"isTile":true,"recent":1736850940097,"frequent":6},{"idnum":110233,"id":"X110233","images":"C4.webp","x":1,"y":29,"isTile":true,"recent":1736850910193,"frequent":12},{"idnum":71843,"id":"X71843","images":"11.webp","x":3,"y":230,"isTile":true,"recent":1736850787193,"frequent":1},{"idnum":110199,"id":"X110199","images":"C4.webp","x":7,"y":24,"isTile":true,"recent":1736850714986,"frequent":42},{"idnum":110197,"id":"X110197","images":"C4.webp","x":5,"y":24,"isTile":true,"recent":1736850691026,"frequent":33},{"idnum":140,"id":"autotile4","images":"autotile","y":0,"recent":1736850685881,"frequent":188},{"idnum":110131,"id":"X110131","images":"C4.webp","x":3,"y":16,"isTile":true,"recent":1736850632809,"frequent":16},{"idnum":110207,"id":"X110207","images":"C4.webp","x":7,"y":25,"isTile":true,"recent":1736850622297,"frequent":16},{"idnum":110168,"id":"X110168","images":"C4.webp","x":0,"y":21,"isTile":true,"recent":1736850565609,"frequent":2},{"idnum":110204,"id":"X110204","images":"C4.webp","x":4,"y":25,"isTile":true,"recent":1736850548026,"frequent":22},{"idnum":110225,"id":"X110225","images":"C4.webp","x":1,"y":28,"isTile":true,"recent":1736850485706,"frequent":8},{"idnum":110143,"id":"X110143","images":"C4.webp","x":7,"y":17,"isTile":true,"recent":1736850348898,"frequent":4},{"idnum":110226,"id":"X110226","images":"C4.webp","x":2,"y":28,"isTile":true,"recent":1736849357212,"frequent":15},{"idnum":110234,"id":"X110234","images":"C4.webp","x":2,"y":29,"isTile":true,"recent":1736849355211,"frequent":8},{"idnum":110232,"id":"X110232","images":"C4.webp","x":0,"y":29,"isTile":true,"recent":1736849329404,"frequent":5},{"idnum":110206,"id":"X110206","images":"C4.webp","x":6,"y":25,"isTile":true,"recent":1736849321979,"frequent":23},{"idnum":110205,"id":"X110205","images":"C4.webp","x":5,"y":25,"isTile":true,"recent":1736849316019,"frequent":10},{"idnum":110123,"id":"X110123","images":"C4.webp","x":3,"y":15,"isTile":true,"recent":1736849246971,"frequent":3},{"idnum":200990,"id":"X200990","images":"C5.webp","x":6,"y":123,"isTile":true,"recent":1736849222003,"frequent":5},{"idnum":200991,"id":"X200991","images":"C5.webp","x":7,"y":123,"isTile":true,"recent":1736849220163,"frequent":3},{"idnum":200999,"id":"X200999","images":"C5.webp","x":7,"y":124,"isTile":true,"recent":1736849216843,"frequent":3},{"idnum":200998,"id":"X200998","images":"C5.webp","x":6,"y":124,"isTile":true,"recent":1736849214307,"frequent":3},{"idnum":120019,"id":"X120019","images":"C3.webp","x":3,"y":2,"isTile":true,"recent":1736849111748,"frequent":9},{"idnum":120020,"id":"X120020","images":"C3.webp","x":4,"y":2,"isTile":true,"recent":1736849100028,"frequent":3},{"idnum":110116,"id":"X110116","images":"C4.webp","x":4,"y":14,"isTile":true,"recent":1736849040692,"frequent":14},{"idnum":110129,"id":"X110129","images":"C4.webp","x":1,"y":16,"isTile":true,"recent":1736849036387,"frequent":14},{"idnum":110150,"id":"X110150","images":"C4.webp","x":6,"y":18,"isTile":true,"recent":1736849032996,"frequent":3},{"idnum":110117,"id":"X110117","images":"C4.webp","x":5,"y":14,"isTile":true,"recent":1736849008732,"frequent":7},{"idnum":201021,"id":"X201021","images":"C5.webp","x":5,"y":127,"isTile":true,"recent":1736848143509,"frequent":26},{"idnum":201029,"id":"X201029","images":"C5.webp","x":5,"y":128,"isTile":true,"recent":1736848140573,"frequent":11},{"idnum":120035,"id":"X120035","images":"C3.webp","x":3,"y":4,"isTile":true,"recent":1736848099941,"frequent":1},{"idnum":120027,"id":"X120027","images":"C3.webp","x":3,"y":3,"isTile":true,"recent":1736848095845,"frequent":1},{"idnum":110203,"id":"X110203","images":"C4.webp","x":3,"y":25,"isTile":true,"recent":1736847662782,"frequent":12},{"idnum":110160,"id":"X110160","images":"C4.webp","x":0,"y":20,"isTile":true,"recent":1736847176335,"frequent":3},{"idnum":110132,"id":"X110132","images":"C4.webp","x":4,"y":16,"isTile":true,"recent":1736847155807,"frequent":6},{"idnum":110152,"id":"X110152","images":"C4.webp","x":0,"y":19,"isTile":true,"recent":1736847142200,"frequent":5},{"idnum":201007,"id":"X201007","images":"C5.webp","x":7,"y":125,"isTile":true,"recent":1736847024455,"frequent":5},{"idnum":201015,"id":"X201015","images":"C5.webp","x":7,"y":126,"isTile":true,"recent":1736846998486,"frequent":4},{"idnum":110062,"id":"X110062","images":"C4.webp","x":6,"y":7,"isTile":true,"recent":1736846960495,"frequent":1},{"idnum":120103,"id":"X120103","images":"C3.webp","x":7,"y":12,"isTile":true,"recent":1736846940535,"frequent":3},{"idnum":120095,"id":"X120095","images":"C3.webp","x":7,"y":11,"isTile":true,"recent":1736846938263,"frequent":4},{"idnum":110125,"id":"X110125","images":"C4.webp","x":5,"y":15,"isTile":true,"recent":1736846875800,"frequent":6},{"idnum":110142,"id":"X110142","images":"C4.webp","x":6,"y":17,"isTile":true,"recent":1736846204776,"frequent":1},{"idnum":110127,"id":"X110127","images":"C4.webp","x":7,"y":15,"isTile":true,"recent":1736846198703,"frequent":2},{"idnum":110139,"id":"X110139","images":"C4.webp","x":3,"y":17,"isTile":true,"recent":1736846123424,"frequent":2},{"idnum":110137,"id":"X110137","images":"C4.webp","x":1,"y":17,"isTile":true,"recent":1736846119448,"frequent":2},{"idnum":110153,"id":"X110153","images":"C4.webp","x":1,"y":19,"isTile":true,"recent":1736846111320,"frequent":5},{"idnum":110133,"id":"X110133","images":"C4.webp","x":5,"y":16,"isTile":true,"recent":1736846027456,"frequent":8},{"idnum":110115,"id":"X110115","images":"C4.webp","x":3,"y":14,"isTile":true,"recent":1736846004433,"frequent":1},{"idnum":80089,"id":"X80089","images":"6.webp","x":1,"y":11,"isTile":true,"recent":1736845859072,"frequent":1},{"idnum":201023,"id":"X201023","images":"C5.webp","x":7,"y":127,"isTile":true,"recent":1736845782753,"frequent":4},{"idnum":201031,"id":"X201031","images":"C5.webp","x":7,"y":128,"isTile":true,"recent":1736845778577,"frequent":4},{"idnum":120039,"id":"X120039","images":"C3.webp","x":7,"y":4,"isTile":true,"recent":1736845724073,"frequent":4},{"idnum":120011,"id":"X120011","images":"C3.webp","x":3,"y":1,"isTile":true,"recent":1736845711809,"frequent":1},{"idnum":120038,"id":"X120038","images":"C3.webp","x":6,"y":4,"isTile":true,"recent":1736845698409,"frequent":2},{"idnum":120046,"id":"X120046","images":"C3.webp","x":6,"y":5,"isTile":true,"recent":1736845695489,"frequent":2},{"idnum":120047,"id":"X120047","images":"C3.webp","x":7,"y":5,"isTile":true,"recent":1736845671929,"frequent":1},{"idnum":110124,"id":"X110124","images":"C4.webp","x":4,"y":15,"isTile":true,"recent":1736845531880,"frequent":8},{"idnum":110126,"id":"X110126","images":"C4.webp","x":6,"y":15,"isTile":true,"recent":1736845503009,"frequent":3},{"idnum":110119,"id":"X110119","images":"C4.png","x":7,"y":14,"isTile":true,"recent":1736845490450,"frequent":4},{"idnum":110121,"id":"X110121","images":"C4.webp","x":1,"y":15,"isTile":true,"recent":1736845383593,"frequent":1},{"idnum":201039,"id":"X201039","images":"C5.webp","x":7,"y":129,"isTile":true,"recent":1736845104649,"frequent":2},{"idnum":120049,"id":"X120049","images":"C3.webp","x":1,"y":6,"isTile":true,"recent":1736845070842,"frequent":6},{"idnum":120057,"id":"X120057","images":"C3.webp","x":1,"y":7,"isTile":true,"recent":1736845067370,"frequent":6},{"idnum":110016,"id":"X110016","images":"C4.webp","x":0,"y":2,"isTile":true,"recent":1736845042923,"frequent":1},{"idnum":110024,"id":"X110024","images":"C4.webp","x":0,"y":3,"isTile":true,"recent":1736845040074,"frequent":1},{"idnum":120080,"id":"X120080","images":"C3.webp","x":0,"y":10,"isTile":true,"recent":1736845019114,"frequent":2},{"idnum":120067,"id":"X120067","images":"C3.webp","x":3,"y":8,"isTile":true,"recent":1736844973058,"frequent":3},{"idnum":120075,"id":"X120075","images":"C3.webp","x":3,"y":9,"isTile":true,"recent":1736844958906,"frequent":2},{"idnum":120083,"id":"X120083","images":"C3.webp","x":3,"y":10,"isTile":true,"recent":1736844957355,"frequent":2},{"idnum":120065,"id":"X120065","images":"C3.webp","x":1,"y":8,"isTile":true,"recent":1736844939746,"frequent":1},{"idnum":120073,"id":"X120073","images":"C3.webp","x":1,"y":9,"isTile":true,"recent":1736844937513,"frequent":1},{"idnum":120041,"id":"X120041","images":"C3.png","x":1,"y":5,"isTile":true,"recent":1736844850098,"frequent":3},{"idnum":120048,"id":"X120048","images":"C3.webp","x":0,"y":6,"isTile":true,"recent":1736844845474,"frequent":1},{"idnum":90650,"id":"X90650","images":"12.webp","x":2,"y":81,"isTile":true,"recent":1736844807043,"frequent":4},{"idnum":90651,"id":"X90651","images":"12.webp","x":3,"y":81,"isTile":true,"recent":1736844805036,"frequent":7},{"idnum":90667,"id":"X90667","images":"12.webp","x":3,"y":83,"isTile":true,"recent":1736844774770,"frequent":4},{"idnum":90675,"id":"X90675","images":"12.webp","x":3,"y":84,"isTile":true,"recent":1736844771602,"frequent":1},{"idnum":90648,"id":"X90648","images":"12.webp","x":0,"y":81,"isTile":true,"recent":1736844743706,"frequent":8},{"idnum":140109,"id":"X140109","images":"C1.webp","x":5,"y":13,"isTile":true,"recent":1736844703370,"frequent":2},{"idnum":140108,"id":"X140108","images":"C1.webp","x":4,"y":13,"isTile":true,"recent":1736844701690,"frequent":4},{"idnum":140107,"id":"X140107","images":"C1.webp","x":3,"y":13,"isTile":true,"recent":1736844696874,"frequent":2},{"idnum":140091,"id":"X140091","images":"C1.webp","x":3,"y":11,"isTile":true,"recent":1736844639114,"frequent":2},{"idnum":140093,"id":"X140093","images":"C1.webp","x":5,"y":11,"isTile":true,"recent":1736844631826,"frequent":1},{"idnum":140092,"id":"X140092","images":"C1.webp","x":4,"y":11,"isTile":true,"recent":1736844629818,"frequent":1},{"idnum":140101,"id":"X140101","images":"C1.webp","x":5,"y":12,"isTile":true,"recent":1736844624498,"frequent":1},{"idnum":140100,"id":"X140100","images":"C1.webp","x":4,"y":12,"isTile":true,"recent":1736844622018,"frequent":2},{"idnum":140099,"id":"X140099","images":"C1.webp","x":3,"y":12,"isTile":true,"recent":1736844618226,"frequent":1},{"idnum":140022,"id":"X140022","images":"C1.webp","x":6,"y":2,"isTile":true,"recent":1736844577634,"frequent":1},{"idnum":90078,"id":"X90078","images":"12.webp","x":6,"y":9,"isTile":true,"recent":1736844533787,"frequent":7},{"idnum":180031,"id":"X180031","images":"7.webp","x":7,"y":3,"isTile":true,"recent":1736844496362,"frequent":2},{"idnum":180039,"id":"X180039","images":"7.webp","x":7,"y":4,"isTile":true,"recent":1736844492466,"frequent":1},{"idnum":180068,"id":"X180068","images":"7.webp","x":4,"y":8,"isTile":true,"recent":1736844471323,"frequent":6},{"idnum":180046,"id":"X180046","images":"7.webp","x":6,"y":5,"isTile":true,"recent":1736844452658,"frequent":1},{"idnum":180030,"id":"X180030","images":"7.webp","x":6,"y":3,"isTile":true,"recent":1736844434698,"frequent":3},{"idnum":180029,"id":"X180029","images":"7.webp","x":5,"y":3,"isTile":true,"recent":1736844426314,"frequent":4},{"idnum":180037,"id":"X180037","images":"7.webp","x":5,"y":4,"isTile":true,"recent":1736844424386,"frequent":6},{"idnum":140122,"id":"X140122","images":"C1.webp","x":2,"y":15,"isTile":true,"recent":1736844284947,"frequent":1},{"idnum":140138,"id":"X140138","images":"C1.webp","x":2,"y":17,"isTile":true,"recent":1736844278403,"frequent":2},{"idnum":130194,"id":"X130194","images":"C2.webp","x":2,"y":24,"isTile":true,"recent":1736844144043,"frequent":6},{"idnum":143,"id":"autotile10","images":"autotile","y":0,"recent":1736844137635,"frequent":14},{"idnum":130202,"id":"X130202","images":"C2.webp","x":2,"y":25,"isTile":true,"recent":1736844088539,"frequent":3},{"idnum":90851,"id":"X90851","images":"12.webp","x":3,"y":106,"isTile":true,"recent":1736843731172,"frequent":2},{"idnum":90852,"id":"X90852","images":"12.webp","x":4,"y":106,"isTile":true,"recent":1736843729019,"frequent":1},{"idnum":90850,"id":"X90850","images":"12.webp","x":2,"y":106,"isTile":true,"recent":1736843724573,"frequent":1},{"idnum":90619,"id":"X90619","images":"12.webp","x":3,"y":77,"isTile":true,"recent":1736843709803,"frequent":1},{"idnum":90625,"id":"X90625","images":"12.webp","x":1,"y":78,"isTile":true,"recent":1736843703883,"frequent":1},{"idnum":90617,"id":"X90617","images":"12.webp","x":1,"y":77,"isTile":true,"recent":1736843700155,"frequent":1},{"idnum":90624,"id":"X90624","images":"12.webp","x":0,"y":78,"isTile":true,"recent":1736843697357,"frequent":1},{"idnum":90642,"id":"X90642","images":"12.webp","x":2,"y":80,"isTile":true,"recent":1736843692492,"frequent":1},{"idnum":90633,"id":"X90633","images":"12.webp","x":1,"y":79,"isTile":true,"recent":1736843680621,"frequent":1},{"idnum":90641,"id":"X90641","images":"12.webp","x":1,"y":80,"isTile":true,"recent":1736843671076,"frequent":1},{"idnum":90632,"id":"X90632","images":"12.webp","x":0,"y":79,"isTile":true,"recent":1736843667819,"frequent":1},{"idnum":90674,"id":"X90674","images":"12.webp","x":2,"y":84,"isTile":true,"recent":1736843654780,"frequent":1},{"idnum":90666,"id":"X90666","images":"12.webp","x":2,"y":83,"isTile":true,"recent":1736843652739,"frequent":1},{"idnum":90672,"id":"X90672","images":"12.webp","x":0,"y":84,"isTile":true,"recent":1736843649708,"frequent":1},{"idnum":90673,"id":"X90673","images":"12.webp","x":1,"y":84,"isTile":true,"recent":1736843647476,"frequent":1},{"idnum":90664,"id":"X90664","images":"12.webp","x":0,"y":83,"isTile":true,"recent":1736843641796,"frequent":1},{"idnum":90659,"id":"X90659","images":"12.webp","x":3,"y":82,"isTile":true,"recent":1736843568843,"frequent":2},{"idnum":110210,"id":"X110210","images":"C4.webp","x":2,"y":26,"isTile":true,"recent":1736843451748,"frequent":3},{"idnum":120007,"id":"X120007","images":"C3.webp","x":7,"y":0,"isTile":true,"recent":1736843417461,"frequent":4},{"idnum":120015,"id":"X120015","images":"C3.webp","x":7,"y":1,"isTile":true,"recent":1736843413012,"frequent":3},{"idnum":110218,"id":"X110218","images":"C4.webp","x":2,"y":27,"isTile":true,"recent":1736843385741,"frequent":3},{"idnum":90424,"id":"X90424","images":"12.webp","x":0,"y":53,"isTile":true,"recent":1736843336621,"frequent":1},{"idnum":140116,"id":"X140116","images":"C1.webp","x":4,"y":14,"isTile":true,"recent":1736843303164,"frequent":3},{"idnum":120010,"id":"X120010","images":"C3.webp","x":2,"y":1,"isTile":true,"recent":1736843287124,"frequent":2},{"idnum":120013,"id":"X120013","images":"C3.webp","x":5,"y":1,"isTile":true,"recent":1736843263501,"frequent":1},{"idnum":120034,"id":"X120034","images":"C3.webp","x":2,"y":4,"isTile":true,"recent":1736843239684,"frequent":1},{"idnum":120026,"id":"X120026","images":"C3.webp","x":2,"y":3,"isTile":true,"recent":1736843236972,"frequent":1},{"idnum":140118,"id":"X140118","images":"C1.webp","x":6,"y":14,"isTile":true,"recent":1736843209517,"frequent":2},{"idnum":130166,"id":"X130166","images":"C2.webp","x":6,"y":20,"isTile":true,"recent":1736843200932,"frequent":2},{"idnum":130156,"id":"X130156","images":"C2.webp","x":4,"y":19,"isTile":true,"recent":1736843197188,"frequent":2},{"idnum":140117,"id":"X140117","images":"C1.webp","x":5,"y":14,"isTile":true,"recent":1736843175780,"frequent":2},{"idnum":90780,"id":"X90780","images":"12.webp","x":4,"y":97,"isTile":true,"recent":1736843134029,"frequent":1},{"idnum":90782,"id":"X90782","images":"12.webp","x":6,"y":97,"isTile":true,"recent":1736843119501,"frequent":1},{"idnum":90783,"id":"X90783","images":"12.webp","x":7,"y":97,"isTile":true,"recent":1736843114116,"frequent":1},{"idnum":90779,"id":"X90779","images":"12.webp","x":3,"y":97,"isTile":true,"recent":1736843106372,"frequent":1},{"idnum":90787,"id":"X90787","images":"12.webp","x":3,"y":98,"isTile":true,"recent":1736843103652,"frequent":1},{"idnum":90563,"id":"X90563","images":"12.webp","x":3,"y":70,"isTile":true,"recent":1736843094141,"frequent":1},{"idnum":90452,"id":"X90452","images":"12.webp","x":4,"y":56,"isTile":true,"recent":1736843085541,"frequent":1},{"idnum":90343,"id":"X90343","images":"12.webp","x":7,"y":42,"isTile":true,"recent":1736843075756,"frequent":1},{"idnum":90342,"id":"X90342","images":"12.webp","x":6,"y":42,"isTile":true,"recent":1736843066764,"frequent":1},{"idnum":90207,"id":"X90207","images":"12.webp","x":7,"y":25,"isTile":true,"recent":1736843026885,"frequent":1},{"idnum":130060,"id":"X130060","images":"C2.webp","x":4,"y":7,"isTile":true,"recent":1736843007396,"frequent":1},{"idnum":130157,"id":"X130157","images":"C2.webp","x":5,"y":19,"isTile":true,"recent":1736842984684,"frequent":1},{"idnum":130150,"id":"X130150","images":"C2.webp","x":6,"y":18,"isTile":true,"recent":1736842972524,"frequent":1},{"idnum":120028,"id":"X120028","images":"C3.webp","x":4,"y":3,"isTile":true,"recent":1736842902516,"frequent":1},{"idnum":201014,"id":"X201014","images":"C5.webp","x":6,"y":126,"isTile":true,"recent":1736842836886,"frequent":2},{"idnum":201006,"id":"X201006","images":"C5.webp","x":6,"y":125,"isTile":true,"recent":1736842827397,"frequent":1},{"idnum":120056,"id":"X120056","images":"C3.webp","x":0,"y":7,"isTile":true,"recent":1736842747373,"frequent":1},{"idnum":120064,"id":"X120064","images":"C3.webp","x":0,"y":8,"isTile":true,"recent":1736842743861,"frequent":1},{"idnum":110113,"id":"X110113","images":"C4.webp","x":1,"y":14,"isTile":true,"recent":1736842591446,"frequent":1},{"idnum":90425,"id":"X90425","images":"12.webp","x":1,"y":53,"isTile":true,"recent":1736842466654,"frequent":2},{"idnum":50133,"id":"X50133","images":"2.webp","x":5,"y":16,"isTile":true,"recent":1736842438765,"frequent":1},{"idnum":140010,"id":"X140010","images":"C1.webp","x":2,"y":1,"isTile":true,"recent":1736842372798,"frequent":2},{"idnum":90762,"id":"X90762","images":"12.webp","x":2,"y":95,"isTile":true,"recent":1736842308942,"frequent":1},{"idnum":90763,"id":"X90763","images":"12.webp","x":3,"y":95,"isTile":true,"recent":1736842306261,"frequent":1},{"idnum":90682,"id":"X90682","images":"12.webp","x":2,"y":85,"isTile":true,"recent":1736842299469,"frequent":1},{"idnum":90242,"id":"X90242","images":"12.webp","x":2,"y":30,"isTile":true,"recent":1736842284126,"frequent":2},{"idnum":100308,"id":"X100308","images":"Outside_B.webp","x":20,"y":12,"isTile":true,"recent":1736842262134,"frequent":1},{"idnum":100307,"id":"X100307","images":"Outside_B.webp","x":19,"y":12,"isTile":true,"recent":1736842258973,"frequent":2},{"idnum":100309,"id":"X100309","images":"Outside_B.webp","x":21,"y":12,"isTile":true,"recent":1736842254526,"frequent":2},{"idnum":100333,"id":"X100333","images":"Outside_B.webp","x":21,"y":13,"isTile":true,"recent":1736842251102,"frequent":1},{"idnum":100356,"id":"X100356","images":"Outside_B.webp","x":20,"y":14,"isTile":true,"recent":1736842246279,"frequent":1},{"idnum":100358,"id":"X100358","images":"Outside_B.webp","x":22,"y":14,"isTile":true,"recent":1736842241462,"frequent":1},{"idnum":90684,"id":"X90684","images":"12.webp","x":4,"y":85,"isTile":true,"recent":1736842218269,"frequent":2},{"idnum":130058,"id":"X130058","images":"C2.webp","x":2,"y":7,"isTile":true,"recent":1736842189270,"frequent":1},{"idnum":180013,"id":"X180013","images":"7.webp","x":5,"y":1,"isTile":true,"recent":1736842173494,"frequent":1},{"idnum":110190,"id":"X110190","images":"C4.webp","x":6,"y":23,"isTile":true,"recent":1736842137031,"frequent":1},{"idnum":140124,"id":"X140124","images":"C1.webp","x":4,"y":15,"isTile":true,"recent":1736841988958,"frequent":1},{"idnum":140149,"id":"X140149","images":"C1.webp","x":5,"y":18,"isTile":true,"recent":1736841969583,"frequent":1},{"idnum":140151,"id":"X140151","images":"C1.webp","x":7,"y":18,"isTile":true,"recent":1736841947789,"frequent":1},{"idnum":140119,"id":"X140119","images":"C1.webp","x":7,"y":14,"isTile":true,"recent":1736841945118,"frequent":1},{"idnum":140126,"id":"X140126","images":"C1.webp","x":6,"y":15,"isTile":true,"recent":1736841938646,"frequent":1},{"idnum":140134,"id":"X140134","images":"C1.webp","x":6,"y":16,"isTile":true,"recent":1736841934918,"frequent":1},{"idnum":140142,"id":"X140142","images":"C1.webp","x":6,"y":17,"isTile":true,"recent":1736841932838,"frequent":1},{"idnum":140150,"id":"X140150","images":"C1.webp","x":6,"y":18,"isTile":true,"recent":1736841930462,"frequent":1},{"idnum":130210,"id":"X130210","images":"C2.webp","x":2,"y":26,"isTile":true,"recent":1736841883934,"frequent":1},{"idnum":110231,"id":"X110231","images":"C4.webp","x":7,"y":28,"isTile":true,"recent":1736841833622,"frequent":1},{"idnum":110238,"id":"X110238","images":"C4.webp","x":6,"y":29,"isTile":true,"recent":1736841829030,"frequent":1},{"idnum":110235,"id":"X110235","images":"C4.webp","x":3,"y":29,"isTile":true,"recent":1736841675103,"frequent":1},{"idnum":110209,"id":"X110209","images":"C4.webp","x":1,"y":26,"isTile":true,"recent":1736841567951,"frequent":5},{"idnum":110208,"id":"X110208","images":"C4.webp","x":0,"y":26,"isTile":true,"recent":1736841565071,"frequent":2},{"idnum":110217,"id":"X110217","images":"C4.webp","x":1,"y":27,"isTile":true,"recent":1736841557854,"frequent":1},{"idnum":110216,"id":"X110216","images":"C4.webp","x":0,"y":27,"isTile":true,"recent":1736841555614,"frequent":3},{"idnum":130193,"id":"X130193","images":"C2.webp","x":1,"y":24,"isTile":true,"recent":1736841377878,"frequent":13},{"idnum":130200,"id":"X130200","images":"C2.webp","x":0,"y":25,"isTile":true,"recent":1736841375967,"frequent":4},{"idnum":130192,"id":"X130192","images":"C2.webp","x":0,"y":24,"isTile":true,"recent":1736841373854,"frequent":4},{"idnum":130007,"id":"X130007","images":"C2.webp","x":7,"y":0,"isTile":true,"recent":1736841273201,"frequent":1},{"idnum":90805,"id":"X90805","images":"12.webp","x":5,"y":100,"isTile":true,"recent":1736841191383,"frequent":2},{"idnum":130091,"id":"X130091","images":"C2.webp","x":3,"y":11,"isTile":true,"recent":1736841167000,"frequent":1},{"idnum":110319,"id":"X110319","images":"C4.webp","x":7,"y":39,"isTile":true,"recent":1736745378478,"frequent":2},{"idnum":140206,"id":"X140206","images":"C1.webp","x":6,"y":25,"isTile":true,"recent":1736745321017,"frequent":2},{"idnum":170253,"id":"X170253","images":"8.webp","x":5,"y":31,"isTile":true,"recent":1736745315448,"frequent":2},{"idnum":72098,"id":"X72098","images":"11.webp","x":2,"y":262,"isTile":true,"recent":1736347614521,"frequent":6},{"idnum":110088,"id":"X110088","images":"C4.webp","x":0,"y":11,"isTile":true,"recent":1736347591933,"frequent":1},{"idnum":110072,"id":"X110072","images":"C4.webp","x":0,"y":9,"isTile":true,"recent":1736347590055,"frequent":2},{"idnum":110080,"id":"X110080","images":"C4.webp","x":0,"y":10,"isTile":true,"recent":1736347588471,"frequent":1},{"idnum":90804,"id":"X90804","images":"12.webp","x":4,"y":100,"isTile":true,"recent":1736347567687,"frequent":1},{"idnum":90796,"id":"X90796","images":"12.webp","x":4,"y":99,"isTile":true,"recent":1736347564015,"frequent":1},{"idnum":90797,"id":"X90797","images":"12.webp","x":5,"y":99,"isTile":true,"recent":1736347557898,"frequent":3},{"idnum":90799,"id":"X90799","images":"12.webp","x":7,"y":99,"isTile":true,"recent":1736347534584,"frequent":1},{"idnum":190030,"id":"X190030","images":"10.webp","x":6,"y":3,"isTile":true,"recent":1736347505134,"frequent":1},{"idnum":190023,"id":"X190023","images":"10.webp","x":7,"y":2,"isTile":true,"recent":1736347501966,"frequent":1},{"idnum":200063,"id":"X200063","images":"C5.webp","x":7,"y":7,"isTile":true,"recent":1736347489759,"frequent":2},{"idnum":190148,"id":"X190148","images":"10.webp","x":4,"y":18,"isTile":true,"recent":1736347475567,"frequent":2},{"idnum":190149,"id":"X190149","images":"10.webp","x":5,"y":18,"isTile":true,"recent":1736347473767,"frequent":1},{"idnum":190142,"id":"X190142","images":"10.webp","x":6,"y":17,"isTile":true,"recent":1736347468543,"frequent":1},{"idnum":200175,"id":"X200175","images":"C5.webp","x":7,"y":21,"isTile":true,"recent":1736347456646,"frequent":2},{"idnum":200183,"id":"X200183","images":"C5.webp","x":7,"y":22,"isTile":true,"recent":1736347453983,"frequent":1},{"idnum":200191,"id":"X200191","images":"C5.webp","x":7,"y":23,"isTile":true,"recent":1736347449878,"frequent":2},{"idnum":200638,"id":"X200638","images":"C5.webp","x":6,"y":79,"isTile":true,"recent":1736347409930,"frequent":1},{"idnum":72112,"id":"X72112","images":"11.webp","x":0,"y":264,"isTile":true,"recent":1736347378663,"frequent":2},{"idnum":130201,"id":"X130201","images":"C2.webp","x":1,"y":25,"isTile":true,"recent":1736347347625,"frequent":5},{"idnum":120082,"id":"X120082","images":"C3.webp","x":2,"y":10,"isTile":true,"recent":1736347337504,"frequent":1},{"idnum":120066,"id":"X120066","images":"C3.webp","x":2,"y":8,"isTile":true,"recent":1736347333791,"frequent":1},{"idnum":90658,"id":"X90658","images":"12.webp","x":2,"y":82,"isTile":true,"recent":1736347321655,"frequent":3},{"idnum":110134,"id":"X110134","images":"C4.webp","x":6,"y":16,"isTile":true,"recent":1736347275138,"frequent":2},{"idnum":60038,"id":"X60038","images":"1.webp","x":6,"y":4,"isTile":true,"recent":1736347241000,"frequent":3},{"idnum":60046,"id":"X60046","images":"1.webp","x":6,"y":5,"isTile":true,"recent":1736347238727,"frequent":1},{"idnum":110149,"id":"X110149","images":"C4.webp","x":5,"y":18,"isTile":true,"recent":1736347217819,"frequent":1},{"idnum":110215,"id":"X110215","images":"C4.webp","x":7,"y":26,"isTile":true,"recent":1736347209926,"frequent":2},{"idnum":110223,"id":"X110223","images":"C4.webp","x":7,"y":27,"isTile":true,"recent":1736347205624,"frequent":1},{"idnum":110212,"id":"X110212","images":"C4.webp","x":4,"y":26,"isTile":true,"recent":1736347197794,"frequent":1},{"idnum":110327,"id":"X110327","images":"C4.webp","x":7,"y":40,"isTile":true,"recent":1736343627722,"frequent":1},{"idnum":71845,"id":"X71845","images":"11.webp","x":5,"y":230,"isTile":true,"recent":1736343541803,"frequent":1},{"idnum":71835,"id":"X71835","images":"11.webp","x":3,"y":229,"isTile":true,"recent":1736343535218,"frequent":2},{"idnum":110161,"id":"X110161","images":"C4.webp","x":1,"y":20,"isTile":true,"recent":1736343505756,"frequent":1},{"idnum":110140,"id":"X110140","images":"C4.webp","x":4,"y":17,"isTile":true,"recent":1736343487458,"frequent":1},{"idnum":170263,"id":"X170263","images":"8.webp","x":7,"y":32,"isTile":true,"recent":1736343443354,"frequent":1},{"idnum":130177,"id":"X130177","images":"C2.webp","x":1,"y":22,"isTile":true,"recent":1736343093302,"frequent":2},{"idnum":130184,"id":"X130184","images":"C2.webp","x":0,"y":23,"isTile":true,"recent":1736342157418,"frequent":3},{"idnum":130176,"id":"X130176","images":"C2.webp","x":0,"y":22,"isTile":true,"recent":1736342153800,"frequent":8},{"idnum":130232,"id":"X130232","images":"C2.webp","x":0,"y":29,"isTile":true,"recent":1736342149093,"frequent":1},{"idnum":130185,"id":"X130185","images":"C2.webp","x":1,"y":23,"isTile":true,"recent":1736342140017,"frequent":4},{"idnum":130170,"id":"X130170","images":"C2.webp","x":2,"y":21,"isTile":true,"recent":1736342092104,"frequent":3},{"idnum":130186,"id":"X130186","images":"C2.webp","x":2,"y":23,"isTile":true,"recent":1736342082587,"frequent":3},{"idnum":130178,"id":"X130178","images":"C2.webp","x":2,"y":22,"isTile":true,"recent":1736341851160,"frequent":4},{"idnum":330,"id":"bearUp","images":"enemy48","y":7,"recent":1736341728703,"frequent":1},{"idnum":110118,"id":"X110118","images":"C4.webp","x":6,"y":14,"isTile":true,"recent":1736341655602,"frequent":1},{"idnum":170255,"id":"X170255","images":"8.webp","x":7,"y":31,"isTile":true,"recent":1736341410449,"frequent":4},{"idnum":170252,"id":"X170252","images":"8.webp","x":4,"y":31,"isTile":true,"recent":1736341407808,"frequent":2},{"idnum":170254,"id":"X170254","images":"8.webp","x":6,"y":31,"isTile":true,"recent":1736341405049,"frequent":1},{"idnum":170260,"id":"X170260","images":"8.webp","x":4,"y":32,"isTile":true,"recent":1736341307343,"frequent":1},{"idnum":170268,"id":"X170268","images":"8.webp","x":4,"y":33,"isTile":true,"recent":1736341304608,"frequent":1},{"idnum":170270,"id":"X170270","images":"8.webp","x":6,"y":33,"isTile":true,"recent":1736341301039,"frequent":1},{"idnum":210,"id":"skeletonWarrior","images":"enemys","y":9,"recent":1735825145197,"frequent":4},{"idnum":21,"id":"yellowKey","images":"items","y":0,"recent":1735824906066,"frequent":14},{"idnum":81,"id":"yellowDoor","images":"animates","y":4,"recent":1735824901122,"frequent":26},{"idnum":214,"id":"zombieKnight","images":"enemys","y":13,"recent":1735824888165,"frequent":2},{"idnum":82,"id":"blueDoor","images":"animates","y":5,"recent":1735824878838,"frequent":4},{"idnum":32,"id":"bluePotion","images":"items","y":21,"recent":1735824871469,"frequent":2},{"idnum":28,"id":"blueGem","images":"items","y":17,"recent":1735824867878,"frequent":6},{"idnum":27,"id":"redGem","images":"items","y":16,"recent":1735824864181,"frequent":5},{"idnum":22,"id":"blueKey","images":"items","y":1,"recent":1735824852246,"frequent":4},{"idnum":209,"id":"skeleton","images":"enemys","y":8,"recent":1735824813505,"frequent":2},{"idnum":94,"id":"rightPortal","images":"animates","y":25,"recent":1735824733893,"frequent":6},{"idnum":92,"id":"leftPortal","images":"animates","y":24,"recent":1735824084823,"frequent":2},{"idnum":91,"id":"upPortal","images":"animates","y":26,"recent":1735821889246,"frequent":2},{"idnum":85,"id":"specialDoor","images":"animates","y":8,"recent":1735820976103,"frequent":3},{"idnum":93,"id":"downPortal","images":"animates","y":23,"recent":1735820969951,"frequent":2},{"idnum":89,"id":"portal","images":"animates","y":17,"recent":1735820958612,"frequent":1},{"idnum":26,"id":"bigKey","images":"items","y":6,"recent":1735820920269,"frequent":1},{"idnum":34,"id":"yellowPotion","images":"items","y":23,"recent":1735820909149,"frequent":1},{"idnum":33,"id":"greenPotion","images":"items","y":22,"recent":1735820906301,"frequent":1},{"idnum":83,"id":"redDoor","images":"animates","y":6,"recent":1735820844323,"frequent":2},{"idnum":247,"id":"magicMaster","images":"enemys","y":46,"recent":1735820830425,"frequent":1},{"idnum":20160,"id":"X20160","images":"5.png","x":0,"y":20,"isTile":true,"recent":1735398503013,"frequent":2},{"idnum":20168,"id":"X20168","images":"5.png","x":0,"y":21,"isTile":true,"recent":1735398496973,"frequent":3},{"idnum":20176,"id":"X20176","images":"5.png","x":0,"y":22,"isTile":true,"recent":1735398485125,"frequent":1},{"idnum":71742,"id":"X71742","images":"11.png","x":6,"y":217,"isTile":true,"recent":1735398452693,"frequent":1},{"idnum":71750,"id":"X71750","images":"11.png","x":6,"y":218,"isTile":true,"recent":1735398448325,"frequent":1},{"idnum":71751,"id":"X71751","images":"11.png","x":7,"y":218,"isTile":true,"recent":1735398443645,"frequent":1},{"idnum":71783,"id":"X71783","images":"11.png","x":7,"y":222,"isTile":true,"recent":1735398426909,"frequent":7},{"idnum":71799,"id":"X71799","images":"11.png","x":7,"y":224,"isTile":true,"recent":1735398421365,"frequent":5},{"idnum":71826,"id":"X71826","images":"11.png","x":2,"y":228,"isTile":true,"recent":1735398415661,"frequent":2},{"idnum":71818,"id":"X71818","images":"11.png","x":2,"y":227,"isTile":true,"recent":1735398413269,"frequent":3},{"idnum":224,"id":"swordsman","images":"enemys","y":23,"recent":1735398341974,"frequent":6},{"idnum":71842,"id":"X71842","images":"11.png","x":2,"y":230,"isTile":true,"recent":1735398315069,"frequent":1},{"idnum":71834,"id":"X71834","images":"11.png","x":2,"y":229,"isTile":true,"recent":1735398312437,"frequent":1},{"idnum":110028,"id":"X110028","images":"C4.png","x":4,"y":3,"isTile":true,"recent":1735398198709,"frequent":2},{"idnum":110020,"id":"X110020","images":"C4.png","x":4,"y":2,"isTile":true,"recent":1735398191398,"frequent":2},{"idnum":71791,"id":"X71791","images":"11.png","x":7,"y":223,"isTile":true,"recent":1735398163774,"frequent":3},{"idnum":71785,"id":"X71785","images":"11.png","x":1,"y":223,"isTile":true,"recent":1735398120734,"frequent":2},{"idnum":71784,"id":"X71784","images":"11.png","x":0,"y":223,"isTile":true,"recent":1735398118318,"frequent":3},{"idnum":71793,"id":"X71793","images":"11.png","x":1,"y":224,"isTile":true,"recent":1735398115446,"frequent":2},{"idnum":71792,"id":"X71792","images":"11.png","x":0,"y":224,"isTile":true,"recent":1735398113142,"frequent":2},{"idnum":71787,"id":"X71787","images":"11.png","x":3,"y":223,"isTile":true,"recent":1735398102326,"frequent":1},{"idnum":71786,"id":"X71786","images":"11.png","x":2,"y":223,"isTile":true,"recent":1735398099430,"frequent":1},{"idnum":71795,"id":"X71795","images":"11.png","x":3,"y":224,"isTile":true,"recent":1735398097359,"frequent":1},{"idnum":71794,"id":"X71794","images":"11.png","x":2,"y":224,"isTile":true,"recent":1735398094982,"frequent":1},{"idnum":130006,"id":"X130006","images":"C2.png","x":6,"y":0,"isTile":true,"recent":1735398082894,"frequent":3},{"idnum":130011,"id":"X130011","images":"C2.png","x":3,"y":1,"isTile":true,"recent":1735398078792,"frequent":2},{"idnum":71817,"id":"X71817","images":"11.png","x":1,"y":227,"isTile":true,"recent":1735398027294,"frequent":3},{"idnum":71837,"id":"X71837","images":"11.png","x":5,"y":229,"isTile":true,"recent":1735398013126,"frequent":1},{"idnum":71829,"id":"X71829","images":"11.png","x":5,"y":228,"isTile":true,"recent":1735398008166,"frequent":1},{"idnum":71821,"id":"X71821","images":"11.png","x":5,"y":227,"isTile":true,"recent":1735398005430,"frequent":1},{"idnum":71836,"id":"X71836","images":"11.png","x":4,"y":229,"isTile":true,"recent":1735397997622,"frequent":1},{"idnum":71828,"id":"X71828","images":"11.png","x":4,"y":228,"isTile":true,"recent":1735397993455,"frequent":1},{"idnum":71820,"id":"X71820","images":"11.png","x":4,"y":227,"isTile":true,"recent":1735397989903,"frequent":1},{"idnum":30217,"id":"X30217","images":"4.png","x":1,"y":27,"isTile":true,"recent":1735397944838,"frequent":3},{"idnum":110012,"id":"X110012","images":"C4.png","x":4,"y":1,"isTile":true,"recent":1735397929366,"frequent":2},{"idnum":100485,"id":"X100485","images":"Outside_B.png","x":5,"y":20,"isTile":true,"recent":1735397919927,"frequent":2},{"idnum":100436,"id":"X100436","images":"Outside_B.png","x":4,"y":18,"isTile":true,"recent":1735397880486,"frequent":1},{"idnum":100437,"id":"X100437","images":"Outside_B.png","x":5,"y":18,"isTile":true,"recent":1735397877086,"frequent":1},{"idnum":100461,"id":"X100461","images":"Outside_B.png","x":5,"y":19,"isTile":true,"recent":1735397868606,"frequent":1},{"idnum":100460,"id":"X100460","images":"Outside_B.png","x":4,"y":19,"isTile":true,"recent":1735397843448,"frequent":2},{"idnum":100484,"id":"X100484","images":"Outside_B.png","x":4,"y":20,"isTile":true,"recent":1735397840545,"frequent":2},{"idnum":40136,"id":"X40136","images":"3.png","x":0,"y":17,"isTile":true,"recent":1735397799150,"frequent":1},{"idnum":40144,"id":"X40144","images":"3.png","x":0,"y":18,"isTile":true,"recent":1735397796038,"frequent":2},{"idnum":30227,"id":"X30227","images":"4.png","x":3,"y":28,"isTile":true,"recent":1735397775591,"frequent":2},{"idnum":30214,"id":"X30214","images":"4.png","x":6,"y":26,"isTile":true,"recent":1735397768303,"frequent":1},{"idnum":30218,"id":"X30218","images":"4.png","x":2,"y":27,"isTile":true,"recent":1735397761062,"frequent":1},{"idnum":120042,"id":"X120042","images":"C3.png","x":2,"y":5,"isTile":true,"recent":1735397702167,"frequent":2},{"idnum":120006,"id":"X120006","images":"C3.png","x":6,"y":0,"isTile":true,"recent":1735397659951,"frequent":5},{"idnum":120014,"id":"X120014","images":"C3.png","x":6,"y":1,"isTile":true,"recent":1735397644591,"frequent":4},{"idnum":120090,"id":"X120090","images":"C3.png","x":2,"y":11,"isTile":true,"recent":1735397629759,"frequent":3},{"idnum":120150,"id":"X120150","images":"C3.png","x":6,"y":18,"isTile":true,"recent":1735397613207,"frequent":3},{"idnum":120166,"id":"X120166","images":"C3.png","x":6,"y":20,"isTile":true,"recent":1735397574639,"frequent":1},{"idnum":140170,"id":"X140170","images":"C1.png","x":2,"y":21,"isTile":true,"recent":1735397516295,"frequent":1},{"idnum":80083,"id":"X80083","images":"6.png","x":3,"y":10,"isTile":true,"recent":1735397403120,"frequent":6},{"idnum":80082,"id":"X80082","images":"6.png","x":2,"y":10,"isTile":true,"recent":1735397393215,"frequent":2},{"idnum":71824,"id":"X71824","images":"11.png","x":0,"y":228,"isTile":true,"recent":1735397302354,"frequent":1},{"idnum":71816,"id":"X71816","images":"11.png","x":0,"y":227,"isTile":true,"recent":1735397300089,"frequent":1},{"idnum":71825,"id":"X71825","images":"11.png","x":1,"y":228,"isTile":true,"recent":1735397296728,"frequent":1},{"idnum":71841,"id":"X71841","images":"11.png","x":1,"y":230,"isTile":true,"recent":1735397274905,"frequent":1},{"idnum":71840,"id":"X71840","images":"11.png","x":0,"y":230,"isTile":true,"recent":1735397272160,"frequent":1},{"idnum":71833,"id":"X71833","images":"11.png","x":1,"y":229,"isTile":true,"recent":1735397269433,"frequent":1},{"idnum":71832,"id":"X71832","images":"11.png","x":0,"y":229,"isTile":true,"recent":1735397266704,"frequent":1},{"idnum":71815,"id":"X71815","images":"11.png","x":7,"y":226,"isTile":true,"recent":1735397232288,"frequent":1},{"idnum":71807,"id":"X71807","images":"11.png","x":7,"y":225,"isTile":true,"recent":1735397229624,"frequent":1},{"idnum":71827,"id":"X71827","images":"11.png","x":3,"y":228,"isTile":true,"recent":1735397220728,"frequent":1},{"idnum":71819,"id":"X71819","images":"11.png","x":3,"y":227,"isTile":true,"recent":1735397218496,"frequent":1},{"idnum":120173,"id":"X120173","images":"C3.png","x":5,"y":21,"isTile":true,"recent":1735397183385,"frequent":3},{"idnum":120174,"id":"X120174","images":"C3.png","x":6,"y":21,"isTile":true,"recent":1735397125953,"frequent":6},{"idnum":120134,"id":"X120134","images":"C3.png","x":6,"y":16,"isTile":true,"recent":1735396971049,"frequent":1},{"idnum":130173,"id":"X130173","images":"C2.png","x":5,"y":21,"isTile":true,"recent":1735396958897,"frequent":1},{"idnum":120109,"id":"X120109","images":"C3.png","x":5,"y":13,"isTile":true,"recent":1735396928298,"frequent":2},{"idnum":120117,"id":"X120117","images":"C3.png","x":5,"y":14,"isTile":true,"recent":1735396877690,"frequent":1},{"idnum":120125,"id":"X120125","images":"C3.png","x":5,"y":15,"isTile":true,"recent":1735396864194,"frequent":6},{"idnum":70169,"id":"X70169","images":"11.png","x":1,"y":21,"isTile":true,"recent":1735396825666,"frequent":3},{"idnum":70161,"id":"X70161","images":"11.png","x":1,"y":20,"isTile":true,"recent":1735396814418,"frequent":3},{"idnum":70145,"id":"X70145","images":"11.png","x":1,"y":18,"isTile":true,"recent":1735396802466,"frequent":14},{"idnum":70146,"id":"X70146","images":"11.png","x":2,"y":18,"isTile":true,"recent":1735396788810,"frequent":1},{"idnum":70144,"id":"X70144","images":"11.png","x":0,"y":18,"isTile":true,"recent":1735396782475,"frequent":4},{"idnum":100386,"id":"X100386","images":"Outside_B.png","x":2,"y":16,"isTile":true,"recent":1735396757386,"frequent":1},{"idnum":100362,"id":"X100362","images":"Outside_B.png","x":2,"y":15,"isTile":true,"recent":1735396754546,"frequent":1},{"idnum":100385,"id":"X100385","images":"Outside_B.png","x":1,"y":16,"isTile":true,"recent":1735396751066,"frequent":1},{"idnum":100384,"id":"X100384","images":"Outside_B.png","x":0,"y":16,"isTile":true,"recent":1735396747826,"frequent":1},{"idnum":100361,"id":"X100361","images":"Outside_B.png","x":1,"y":15,"isTile":true,"recent":1735396745106,"frequent":2},{"idnum":100360,"id":"X100360","images":"Outside_B.png","x":0,"y":15,"isTile":true,"recent":1735396742682,"frequent":3},{"idnum":90196,"id":"X90196","images":"12.png","x":4,"y":24,"isTile":true,"recent":1735396698234,"frequent":1},{"idnum":90195,"id":"X90195","images":"12.png","x":3,"y":24,"isTile":true,"recent":1735396695530,"frequent":1},{"idnum":90194,"id":"X90194","images":"12.png","x":2,"y":24,"isTile":true,"recent":1735396691098,"frequent":1},{"idnum":90187,"id":"X90187","images":"12.png","x":3,"y":23,"isTile":true,"recent":1735396687866,"frequent":3},{"idnum":90186,"id":"X90186","images":"12.png","x":2,"y":23,"isTile":true,"recent":1735396672410,"frequent":1},{"idnum":31,"id":"redPotion","images":"items","y":20,"recent":1735396611866,"frequent":7},{"idnum":221,"id":"yellowGateKeeper","images":"enemys","y":20,"recent":1735396537794,"frequent":4},{"idnum":222,"id":"blueGateKeeper","images":"enemys","y":21,"recent":1735396534626,"frequent":3},{"idnum":226,"id":"yellowKnight","images":"enemys","y":25,"recent":1735396460524,"frequent":1},{"idnum":225,"id":"soldier","images":"enemys","y":24,"recent":1735396456036,"frequent":1},{"idnum":326,"id":"tulipFairy","images":"enemys","y":72,"recent":1735396229196,"frequent":1},{"idnum":141,"id":"autotile8","images":"autotile","y":0,"recent":1735391328901,"frequent":2},{"idnum":30,"id":"yellowGem","images":"items","y":19,"recent":1735391294213,"frequent":1},{"idnum":44,"id":"shield5","images":"items","y":59,"recent":1735391193096,"frequent":1},{"idnum":138,"id":"blueTrader","images":"npcs","y":13,"recent":1735391190680,"frequent":1},{"idnum":43,"id":"sword5","images":"items","y":54,"recent":1735391188576,"frequent":1}]} \ No newline at end of file diff --git a/_server/editor_blocklyconfig.js b/_server/editor_blocklyconfig.js index be72015..b0f038c 100644 --- a/_server/editor_blocklyconfig.js +++ b/_server/editor_blocklyconfig.js @@ -1,705 +1,908 @@ -editor_blocklyconfig=(function(){ -// start mark sfergsvae +editor_blocklyconfig = function () { + // start mark sfergsvae + (function () { + var getCategory = function (name, custom) { + for (var node of document.getElementById("toolbox").children) { + if (node.getAttribute("name") == name) return node; + } + var node = document.createElement("category"); + node.setAttribute("name", name); + if (custom) node.setAttribute("custom", custom); + document.getElementById("toolbox").appendChild(node); + return node; + }; - -(function(){ - var getCategory = function(name,custom){ - for(var node of document.getElementById('toolbox').children) { - if(node.getAttribute('name')==name) return node; - } - var node = document.createElement('category'); - node.setAttribute('name',name); - if(custom)node.setAttribute('custom',custom); - document.getElementById('toolbox').appendChild(node); - return node; - } - - var toolboxObj = { - '入口方块':[ - '', - MotaActionFunctions.actionParser.parse([ - "欢迎使用事件编辑器", - "本事件触发一次后会消失", - {"type": "hide", "time": 500}, - ],'event'), - MotaActionFunctions.actionParser.parse({ - "condition": "flag:__door__===2", - "currentFloor": true, - "priority": 0, - "delayExecute": false, - "multiExecute": false, - "data": [ - {"type": "openDoor", "loc": [10,5]} - ], - },'autoEvent'), - MotaActionBlocks['changeFloor_m'].xmlText(), - MotaActionFunctions.actionParser.parse([{ - "id": "shop1", - "text": "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", - "textInList": "1F金币商店", - "choices": [ - {"text": "生命+800", "need": "status:money>=20+2*flag:shop1", "action": [ - {"type": "comment", "text": "新版商店中需要手动扣减金币和增加访问次数"}, - {"type": "setValue", "name": "status:money", "operator": "-=", "value": "20+2*flag:shop1"}, - {"type": "setValue", "name": "flag:shop1", "operator": "+=", "value": "1"}, - {"type": "setValue", "name": "status:hp", "operator": "+=", "value": "800"} - ]} - ] - },{ - "id": "itemShop", - "item": true, - "textInList": "道具商店", - "choices": [ - {"id": "yellowKey", "number": 10, "money": 10} - ] - },{ - "id": "keyShop1", - "textInList": "回收钥匙商店", - "commonEvent": "回收钥匙商店", - "args": "" - }],'shop'), - MotaActionBlocks['common_m'].xmlText(), - MotaActionBlocks['beforeBattle_m'].xmlText(), - MotaActionBlocks['afterBattle_m'].xmlText(), - MotaActionBlocks['afterGetItem_m'].xmlText(), - MotaActionBlocks['afterOpenDoor_m'].xmlText(), - MotaActionBlocks['firstArrive_m'].xmlText(), - MotaActionBlocks['eachArrive_m'].xmlText(), - MotaActionBlocks['level_m'].xmlText(), - MotaActionFunctions.actionParser.parse([ - ['MTx', ''] - ], 'floorPartition'), - MotaActionBlocks['commonEvent_m'].xmlText(), - MotaActionBlocks['item_m'].xmlText(), - MotaActionFunctions.actionParser.parse([ - {"title":"简单", "name": "Easy", "hard": 1, "action": [ - {"type": "comment", "text": "在这里写该难度需执行的事件"} - ]} - ], 'levelChoose'), - MotaActionFunctions.actionParser.parse({ - "type": 0, "value": {"atk": 10}, "percentage": {"speed": 10}, - }, 'equip'), - MotaActionFunctions.actionParser.parse([{ - "name": "bg.jpg", "x": 0, "y": 0, "canvas": "bg" - }], 'floorImage'), - MotaActionFunctions.actionParser.parse({ - "time": 160, "openSound": "door.mp3", "closeSound": "door.mp3", "keys": {"yellowKey": 1, "orangeKey": 1} - }, 'doorInfo'), - MotaActionBlocks['faceIds_m'].xmlText(), - MotaActionBlocks['mainStyle_m'].xmlText(), - MotaActionFunctions.actionParser.parse({ - "背景音乐": "bgm.mp3", "确定": "confirm.mp3", "攻击": "attack.mp3", "背景图": "bg.jpg", "领域": "zone", "文件名": "file.jpg" - }, 'nameMap'), - MotaActionFunctions.actionParser.parse([ - {"name": "hero.png", "width": 32, "height": 32, "prefix": "hero_"}, - ], 'splitImages'), - ], - '显示文字':[ - MotaActionBlocks['text_0_s'].xmlText(), - MotaActionBlocks['text_1_s'].xmlText(), - MotaActionFunctions.actionParser.parseList("\t[小妖精,fairy]\f[fairy.png,0,0]欢迎使用事件编辑器(双击方块可直接预览)"), - MotaActionBlocks['moveTextBox_s'].xmlText(), - MotaActionBlocks['clearTextBox_s'].xmlText(), - MotaActionBlocks['comment_s'].xmlText(), - MotaActionBlocks['autoText_s'].xmlText(), - MotaActionBlocks['scrollText_s'].xmlText(), - MotaActionBlocks['setText_s'].xmlText(), - MotaActionBlocks['tip_s'].xmlText(), - MotaActionBlocks['confirm_s'].xmlText(), - MotaActionBlocks['choices_s'].xmlText([ - '选择剑或者盾','流浪者','man',0,'',MotaActionBlocks['choicesContext'].xmlText([ - '剑','','',null,'','',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), - ]) - ]), - MotaActionBlocks['win_s'].xmlText(), - MotaActionBlocks['lose_s'].xmlText(), - MotaActionBlocks['restart_s'].xmlText(), - ], - '数据相关':[ - MotaActionBlocks['setValue_s'].xmlText([ - MotaActionBlocks['idIdList_e'].xmlText(['status','生命']), '=', '', false - ]), - MotaActionBlocks['setEnemy_s'].xmlText(), - MotaActionBlocks['setEnemyOnPoint_s'].xmlText(), - MotaActionBlocks['resetEnemyOnPoint_s'].xmlText(), - MotaActionBlocks['moveEnemyOnPoint_s'].xmlText(), - MotaActionBlocks['moveEnemyOnPoint_1_s'].xmlText(), - MotaActionBlocks['setEquip_s'].xmlText(), - MotaActionBlocks['setFloor_s'].xmlText(), - MotaActionBlocks['setGlobalAttribute_s'].xmlText(), - MotaActionBlocks['setGlobalValue_s'].xmlText(), - MotaActionBlocks['setGlobalFlag_s'].xmlText(), - MotaActionBlocks['setNameMap_s'].xmlText(), - MotaActionBlocks['input_s'].xmlText(), - MotaActionBlocks['input2_s'].xmlText(), - MotaActionBlocks['update_s'].xmlText(), - MotaActionBlocks['moveAction_s'].xmlText(), - MotaActionBlocks['changeFloor_s'].xmlText(), - MotaActionBlocks['changePos_s'].xmlText(), - MotaActionBlocks['battle_s'].xmlText(), - MotaActionBlocks['useItem_s'].xmlText(), - MotaActionBlocks['loadEquip_s'].xmlText(), - MotaActionBlocks['unloadEquip_s'].xmlText(), - MotaActionBlocks['openShop_s'].xmlText(), - MotaActionBlocks['disableShop_s'].xmlText(), - MotaActionBlocks['setHeroIcon_s'].xmlText(), - MotaActionBlocks['follow_s'].xmlText(), - MotaActionBlocks['unfollow_s'].xmlText(), - ], - '地图处理':[ - MotaActionBlocks['battle_1_s'].xmlText(), - MotaActionBlocks['openDoor_s'].xmlText(), - MotaActionBlocks['closeDoor_s'].xmlText(), - MotaActionBlocks['show_s'].xmlText(), - MotaActionBlocks['hide_s'].xmlText(), - MotaActionBlocks['setBlock_s'].xmlText(), - MotaActionBlocks['setBlockOpacity_s'].xmlText(), - MotaActionBlocks['setBlockFilter_s'].xmlText(), - MotaActionBlocks['turnBlock_s'].xmlText(), - MotaActionBlocks['moveHero_s'].xmlText(), - MotaActionBlocks['move_s'].xmlText(), - MotaActionBlocks['jumpHero_s'].xmlText(), - MotaActionBlocks['jumpHero_1_s'].xmlText(), - MotaActionBlocks['jump_s'].xmlText(), - MotaActionBlocks['jump_1_s'].xmlText(), - MotaActionBlocks['showBgFgMap_s'].xmlText(), - MotaActionBlocks['hideBgFgMap_s'].xmlText(), - MotaActionBlocks['setBgFgBlock_s'].xmlText(), - MotaActionBlocks['showFloorImg_s'].xmlText(), - MotaActionBlocks['hideFloorImg_s'].xmlText(), - ], - '事件控制':[ - MotaActionBlocks['if_1_s'].xmlText(), - MotaActionBlocks['if_s'].xmlText(), - MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [ - {"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]}, - {"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]}, - ]}), - MotaActionFunctions.actionParser.parseList({"type": "for", "name": "temp:A", "from": "0", "to": "12", "step": "1", "data": []}), - MotaActionFunctions.actionParser.parseList({"type": "forEach", "name": "temp:A", "list": ["status:atk","status:def"], "data": []}), - MotaActionBlocks['while_s'].xmlText(), - MotaActionBlocks['dowhile_s'].xmlText(), - MotaActionBlocks['break_s'].xmlText(), - MotaActionBlocks['continue_s'].xmlText(), - MotaActionBlocks['exit_s'].xmlText(), - MotaActionBlocks['trigger_s'].xmlText(), - MotaActionBlocks['insert_1_s'].xmlText(), - MotaActionBlocks['insert_2_s'].xmlText(), - ], - '特效表现':[ - MotaActionBlocks['sleep_s'].xmlText(), - MotaActionFunctions.actionParser.parseList({"type": "wait", "timeout": 0, "data": [ - {"case": "keyboard", "keycode": "13,32", "action": [{"type": "comment", "text": "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout"}]}, - {"case": "mouse", "px": [0,32], "py": [0,32], "action": [{"type": "comment", "text": "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout"}]}, - {"case": "condition", "condition": "flag:type==0\n&&flag:keycode==13", "action": [{"type": "comment", "text": "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout"}]}, - {"case": "timeout", "action": [{"type": "comment", "text": "当超时未操作时执行此事件"}]}, - ]}), - MotaActionBlocks['waitAsync_s'].xmlText(), - MotaActionBlocks['stopAsync_s'].xmlText(), - MotaActionBlocks['vibrate_s'].xmlText(), - MotaActionBlocks['animate_s'].xmlText(), - MotaActionBlocks['animate_1_s'].xmlText(), - MotaActionBlocks['stopAnimate_s'].xmlText(), - MotaActionBlocks['setViewport_s'].xmlText(), - MotaActionBlocks['setViewport_1_s'].xmlText(), - MotaActionBlocks['lockViewport_s'].xmlText(), - MotaActionBlocks['showStatusBar_s'].xmlText(), - MotaActionBlocks['hideStatusBar_s'].xmlText(), - MotaActionBlocks['setHeroOpacity_s'].xmlText(), - MotaActionBlocks['setCurtain_0_s'].xmlText(), - MotaActionBlocks['setCurtain_1_s'].xmlText(), - MotaActionBlocks['screenFlash_s'].xmlText(), - MotaActionBlocks['setWeather_s'].xmlText(), - MotaActionBlocks['callBook_s'].xmlText(), - MotaActionBlocks['callSave_s'].xmlText(), - MotaActionBlocks['autoSave_s'].xmlText(), - MotaActionBlocks['forbidSave_s'].xmlText(), - MotaActionBlocks['callLoad_s'].xmlText(), - ], - '音像处理':[ - MotaActionBlocks['showImage_s'].xmlText(), - MotaActionBlocks['showImage_1_s'].xmlText(), - MotaActionBlocks['hideImage_s'].xmlText(), - MotaActionBlocks['showTextImage_s'].xmlText(), - MotaActionBlocks['moveImage_s'].xmlText(), - MotaActionBlocks['rotateImage_s'].xmlText(), - MotaActionBlocks['scaleImage_s'].xmlText(), - MotaActionBlocks['showGif_s'].xmlText(), - MotaActionBlocks['playBgm_s'].xmlText(), - MotaActionBlocks['pauseBgm_s'].xmlText(), - MotaActionBlocks['resumeBgm_s'].xmlText(), - MotaActionBlocks['loadBgm_s'].xmlText(), - MotaActionBlocks['freeBgm_s'].xmlText(), - MotaActionBlocks['playSound_s'].xmlText(), - MotaActionBlocks['playSound_1_s'].xmlText(), - MotaActionBlocks['stopSound_s'].xmlText(), - MotaActionBlocks['setVolume_s'].xmlText(), - MotaActionBlocks['setBgmSpeed_s'].xmlText(), - ], - 'UI绘制':[ - MotaActionBlocks['previewUI_s'].xmlText(), - MotaActionBlocks['clearMap_s'].xmlText(), - MotaActionBlocks['setAttribute_s'].xmlText(), - MotaActionBlocks['setFilter_s'].xmlText(), - MotaActionBlocks['fillText_s'].xmlText(), - MotaActionBlocks['fillBoldText_s'].xmlText(), - MotaActionBlocks['drawTextContent_s'].xmlText(), - MotaActionBlocks['fillRect_s'].xmlText(), - MotaActionBlocks['strokeRect_s'].xmlText(), - MotaActionBlocks['drawLine_s'].xmlText(), - MotaActionBlocks['drawArrow_s'].xmlText(), - MotaActionBlocks['fillPolygon_s'].xmlText(), - MotaActionBlocks['strokePolygon_s'].xmlText(), - MotaActionBlocks['fillEllipse_s'].xmlText(), - MotaActionBlocks['strokeEllipse_s'].xmlText(), - MotaActionBlocks['fillArc_s'].xmlText(), - MotaActionBlocks['strokeArc_s'].xmlText(), - MotaActionBlocks['drawImage_s'].xmlText(), - MotaActionBlocks['drawImage_1_s'].xmlText(), - MotaActionBlocks['drawIcon_s'].xmlText(), - MotaActionBlocks['drawBackground_s'].xmlText(), - MotaActionBlocks['drawSelector_s'].xmlText(), - MotaActionBlocks['drawSelector_1_s'].xmlText(), - ], - '原生脚本':[ - MotaActionBlocks['function_s'].xmlText(), - MotaActionBlocks['unknown_s'].xmlText(), - ], - '值块':[ - MotaActionBlocks['setValue_s'].xmlText([ - MotaActionBlocks['idIdList_e'].xmlText(['status','生命']), '=', '', false - ]), - MotaActionBlocks['expression_arithmetic_0'].xmlText(), - MotaActionBlocks['idFlag_e'].xmlText(), - MotaActionBlocks['idTemp_e'].xmlText(), - MotaActionBlocks['negate_e'].xmlText(), - MotaActionBlocks['unaryOperation_e'].xmlText(), - MotaActionBlocks['bool_e'].xmlText(), - MotaActionBlocks['idString_e'].xmlText(), - MotaActionBlocks['idIdList_e'].xmlText(), - MotaActionBlocks['idFixedList_e'].xmlText(), - MotaActionBlocks['enemyattr_e'].xmlText(), - MotaActionBlocks['blockId_e'].xmlText(), - MotaActionBlocks['blockNumber_e'].xmlText(), - MotaActionBlocks['blockCls_e'].xmlText(), - MotaActionBlocks['hasEquip_e'].xmlText(), - MotaActionBlocks['equip_e'].xmlText(), - MotaActionBlocks['nextXY_e'].xmlText(), - MotaActionBlocks['isReplaying_e'].xmlText(), - MotaActionBlocks['hasVisitedFloor_e'].xmlText(), - MotaActionBlocks['isShopVisited_e'].xmlText(), - MotaActionBlocks['canBattle_e'].xmlText(), - MotaActionBlocks['damage_e'].xmlText(), - MotaActionBlocks['damage_1_e'].xmlText(), - MotaActionBlocks['rand_e'].xmlText(), - MotaActionBlocks['evalString_e'].xmlText(), - ], - '常见事件模板':[ - '', - MotaActionFunctions.actionParser.parseList({"type": "if", "condition": "!core.musicStatus.bgmStatus", - "true": [ - "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳" - ], - "false": [] - }), - '', - MotaActionFunctions.actionParser.parse([ - { - "type": "if", - "condition": "switch:A", - "true": [ - "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", - { - "type": "comment", - "text": "下一条指令可视情况使用或不使用" - }, - { - "type": "hide", - "remove": true, - "time": 250 - } + var toolboxObj = { + 入口方块: [ + '', + MotaActionFunctions.actionParser.parse( + [ + "欢迎使用事件编辑器", + "本事件触发一次后会消失", + { type: "hide", time: 500 }, ], - "false": [ + "event" + ), + MotaActionFunctions.actionParser.parse( + { + condition: "flag:__door__===2", + currentFloor: true, + priority: 0, + delayExecute: false, + multiExecute: false, + data: [{ type: "openDoor", loc: [10, 5] }], + }, + "autoEvent" + ), + MotaActionBlocks["changeFloor_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [ { - "type": "confirm", - "text": "我有3把黄钥匙,\n你出50金币就卖给你。", - "yes": [ + id: "shop1", + text: "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", + textInList: "1F金币商店", + choices: [ { - "type": "if", - "condition": "status:money>=50", - "true": [ + text: "生命+800", + need: "status:money>=20+2*flag:shop1", + action: [ { - "type": "setValue", - "name": "status:money", - "operator": "-=", - "value": "50" + type: "comment", + text: "新版商店中需要手动扣减金币和增加访问次数", }, { - "type": "setValue", - "name": "item:yellowKey", - "operator": "+=", - "value": "3" + type: "setValue", + name: "status:money", + operator: "-=", + value: "20+2*flag:shop1", }, { - "type": "playSound", - "name": "确定", - "stop": true + type: "setValue", + name: "flag:shop1", + operator: "+=", + value: "1", }, { - "type": "setValue", - "name": "switch:A", - "value": "true" - } + type: "setValue", + name: "status:hp", + operator: "+=", + value: "800", + }, ], - "false": [ - { - "type": "playSound", - "name": "操作失败" - }, - "\t[行商,trader]\b[this]你的金币不足!" - ] - } + }, ], - "no": [] - } - ] - } - ], 'event'), - '', - MotaActionFunctions.actionParser.parse([ - { - "type": "comment", - "text": "全地图选中一个点,需要用鼠标或触屏操作" - }, - { - "type": "setValue", - "name": "temp:X", - "value": "status:x" - }, - { - "type": "setValue", - "name": "temp:Y", - "value": "status:y" - }, - { - "type": "tip", - "text": "再次点击闪烁位置确认" - }, - { - "type": "while", - "condition": "true", - "data": [ - { - "type": "drawSelector", - "image": "winskin.png", - "code": 1, - "x": "32*temp:X", - "y": "32*temp:Y", - "width": 32, - "height": 32 }, { - "type": "wait" + id: "itemShop", + item: true, + textInList: "道具商店", + choices: [{ id: "yellowKey", number: 10, money: 10 }], }, { - "type": "if", - "condition": "(flag:type === 1)", - "true": [ + id: "keyShop1", + textInList: "回收钥匙商店", + commonEvent: "回收钥匙商店", + args: "", + }, + ], + "shop" + ), + MotaActionBlocks["common_m"].xmlText(), + MotaActionBlocks["beforeBattle_m"].xmlText(), + MotaActionBlocks["afterBattle_m"].xmlText(), + MotaActionBlocks["afterGetItem_m"].xmlText(), + MotaActionBlocks["afterOpenDoor_m"].xmlText(), + MotaActionBlocks["firstArrive_m"].xmlText(), + MotaActionBlocks["eachArrive_m"].xmlText(), + MotaActionBlocks["level_m"].xmlText(), + MotaActionFunctions.actionParser.parse([["MTx", ""]], "floorPartition"), + MotaActionBlocks["commonEvent_m"].xmlText(), + MotaActionBlocks["item_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [ + { + title: "简单", + name: "Easy", + hard: 1, + action: [{ type: "comment", text: "在这里写该难度需执行的事件" }], + }, + ], + "levelChoose" + ), + MotaActionFunctions.actionParser.parse( + { + type: 0, + value: { atk: 10 }, + percentage: { speed: 10 }, + }, + "equip" + ), + MotaActionFunctions.actionParser.parse( + [ + { + name: "bg.jpg", + x: 0, + y: 0, + canvas: "bg", + }, + ], + "floorImage" + ), + MotaActionFunctions.actionParser.parse( + { + time: 160, + openSound: "door.opus", + closeSound: "door.opus", + keys: { yellowKey: 1, orangeKey: 1 }, + }, + "doorInfo" + ), + MotaActionBlocks["faceIds_m"].xmlText(), + MotaActionBlocks["mainStyle_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + { + 背景音乐: "bgm.opus", + 确定: "confirm.opus", + 攻击: "attack.opus", + 背景图: "bg.jpg", + 领域: "zone", + 文件名: "file.jpg", + }, + "nameMap" + ), + MotaActionFunctions.actionParser.parse( + [{ name: "hero.png", width: 32, height: 32, prefix: "hero_" }], + "splitImages" + ), + ], + 显示文字: [ + MotaActionBlocks["text_0_s"].xmlText(), + MotaActionBlocks["text_1_s"].xmlText(), + MotaActionFunctions.actionParser.parseList( + "\t[小妖精,fairy]\f[fairy.png,0,0]欢迎使用事件编辑器(双击方块可直接预览)" + ), + MotaActionBlocks["moveTextBox_s"].xmlText(), + MotaActionBlocks["clearTextBox_s"].xmlText(), + MotaActionBlocks["comment_s"].xmlText(), + MotaActionBlocks["autoText_s"].xmlText(), + MotaActionBlocks["scrollText_s"].xmlText(), + MotaActionBlocks["setText_s"].xmlText(), + MotaActionBlocks["tip_s"].xmlText(), + MotaActionBlocks["confirm_s"].xmlText(), + MotaActionBlocks["choices_s"].xmlText([ + "选择剑或者盾", + "流浪者", + "man", + 0, + "", + MotaActionBlocks["choicesContext"].xmlText([ + "剑", + "", + "", + null, + "", + "", + MotaActionFunctions.actionParser.parseList([ + { type: "openDoor", loc: [3, 3] }, + ]), + ]), + ]), + MotaActionBlocks["win_s"].xmlText(), + MotaActionBlocks["lose_s"].xmlText(), + MotaActionBlocks["restart_s"].xmlText(), + ], + 数据相关: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["setEnemy_s"].xmlText(), + MotaActionBlocks["setEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["resetEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_1_s"].xmlText(), + MotaActionBlocks["setEquip_s"].xmlText(), + MotaActionBlocks["setFloor_s"].xmlText(), + MotaActionBlocks["setGlobalAttribute_s"].xmlText(), + MotaActionBlocks["setGlobalValue_s"].xmlText(), + MotaActionBlocks["setGlobalFlag_s"].xmlText(), + MotaActionBlocks["setNameMap_s"].xmlText(), + MotaActionBlocks["input_s"].xmlText(), + MotaActionBlocks["input2_s"].xmlText(), + MotaActionBlocks["update_s"].xmlText(), + MotaActionBlocks["moveAction_s"].xmlText(), + MotaActionBlocks["changeFloor_s"].xmlText(), + MotaActionBlocks["changePos_s"].xmlText(), + MotaActionBlocks["battle_s"].xmlText(), + MotaActionBlocks["useItem_s"].xmlText(), + MotaActionBlocks["loadEquip_s"].xmlText(), + MotaActionBlocks["unloadEquip_s"].xmlText(), + MotaActionBlocks["openShop_s"].xmlText(), + MotaActionBlocks["disableShop_s"].xmlText(), + MotaActionBlocks["setHeroIcon_s"].xmlText(), + MotaActionBlocks["follow_s"].xmlText(), + MotaActionBlocks["unfollow_s"].xmlText(), + ], + 地图处理: [ + MotaActionBlocks["battle_1_s"].xmlText(), + MotaActionBlocks["openDoor_s"].xmlText(), + MotaActionBlocks["closeDoor_s"].xmlText(), + MotaActionBlocks["show_s"].xmlText(), + MotaActionBlocks["hide_s"].xmlText(), + MotaActionBlocks["setBlock_s"].xmlText(), + MotaActionBlocks["setBlockOpacity_s"].xmlText(), + MotaActionBlocks["setBlockFilter_s"].xmlText(), + MotaActionBlocks["turnBlock_s"].xmlText(), + MotaActionBlocks["moveHero_s"].xmlText(), + MotaActionBlocks["move_s"].xmlText(), + MotaActionBlocks["jumpHero_s"].xmlText(), + MotaActionBlocks["jumpHero_1_s"].xmlText(), + MotaActionBlocks["jump_s"].xmlText(), + MotaActionBlocks["jump_1_s"].xmlText(), + MotaActionBlocks["showBgFgMap_s"].xmlText(), + MotaActionBlocks["hideBgFgMap_s"].xmlText(), + MotaActionBlocks["setBgFgBlock_s"].xmlText(), + MotaActionBlocks["showFloorImg_s"].xmlText(), + MotaActionBlocks["hideFloorImg_s"].xmlText(), + ], + 事件控制: [ + MotaActionBlocks["if_1_s"].xmlText(), + MotaActionBlocks["if_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "switch", + condition: "判别值", + caseList: [ + { + action: [ + { type: "comment", text: "当判别值是值的场合执行此事件" }, + ], + }, + { + case: "default", + action: [ { - "type": "if", - "condition": "((temp:X===flag:x)&&(temp:Y===flag:y))", - "true": [ + type: "comment", + text: "当没有符合的值的场合执行default事件", + }, + ], + }, + ], + }), + MotaActionFunctions.actionParser.parseList({ + type: "for", + name: "temp:A", + from: "0", + to: "12", + step: "1", + data: [], + }), + MotaActionFunctions.actionParser.parseList({ + type: "forEach", + name: "temp:A", + list: ["status:atk", "status:def"], + data: [], + }), + MotaActionBlocks["while_s"].xmlText(), + MotaActionBlocks["dowhile_s"].xmlText(), + MotaActionBlocks["break_s"].xmlText(), + MotaActionBlocks["continue_s"].xmlText(), + MotaActionBlocks["exit_s"].xmlText(), + MotaActionBlocks["trigger_s"].xmlText(), + MotaActionBlocks["insert_1_s"].xmlText(), + MotaActionBlocks["insert_2_s"].xmlText(), + ], + 特效表现: [ + MotaActionBlocks["sleep_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "wait", + timeout: 0, + data: [ + { + case: "keyboard", + keycode: "13,32", + action: [ + { + type: "comment", + text: "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "mouse", + px: [0, 32], + py: [0, 32], + action: [ + { + type: "comment", + text: "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "condition", + condition: "flag:type==0\n&&flag:keycode==13", + action: [ + { + type: "comment", + text: "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "timeout", + action: [{ type: "comment", text: "当超时未操作时执行此事件" }], + }, + ], + }), + MotaActionBlocks["waitAsync_s"].xmlText(), + MotaActionBlocks["stopAsync_s"].xmlText(), + MotaActionBlocks["vibrate_s"].xmlText(), + MotaActionBlocks["animate_s"].xmlText(), + MotaActionBlocks["animate_1_s"].xmlText(), + MotaActionBlocks["stopAnimate_s"].xmlText(), + MotaActionBlocks["setViewport_s"].xmlText(), + MotaActionBlocks["setViewport_1_s"].xmlText(), + MotaActionBlocks["lockViewport_s"].xmlText(), + MotaActionBlocks["showStatusBar_s"].xmlText(), + MotaActionBlocks["hideStatusBar_s"].xmlText(), + MotaActionBlocks["setHeroOpacity_s"].xmlText(), + MotaActionBlocks["setCurtain_0_s"].xmlText(), + MotaActionBlocks["setCurtain_1_s"].xmlText(), + MotaActionBlocks["screenFlash_s"].xmlText(), + MotaActionBlocks["setWeather_s"].xmlText(), + MotaActionBlocks["callBook_s"].xmlText(), + MotaActionBlocks["callSave_s"].xmlText(), + MotaActionBlocks["autoSave_s"].xmlText(), + MotaActionBlocks["forbidSave_s"].xmlText(), + MotaActionBlocks["callLoad_s"].xmlText(), + ], + 音像处理: [ + MotaActionBlocks["showImage_s"].xmlText(), + MotaActionBlocks["showImage_1_s"].xmlText(), + MotaActionBlocks["hideImage_s"].xmlText(), + MotaActionBlocks["showTextImage_s"].xmlText(), + MotaActionBlocks["moveImage_s"].xmlText(), + MotaActionBlocks["rotateImage_s"].xmlText(), + MotaActionBlocks["scaleImage_s"].xmlText(), + MotaActionBlocks["showGif_s"].xmlText(), + MotaActionBlocks["playBgm_s"].xmlText(), + MotaActionBlocks["pauseBgm_s"].xmlText(), + MotaActionBlocks["resumeBgm_s"].xmlText(), + MotaActionBlocks["loadBgm_s"].xmlText(), + MotaActionBlocks["freeBgm_s"].xmlText(), + MotaActionBlocks["playSound_s"].xmlText(), + MotaActionBlocks["playSound_1_s"].xmlText(), + MotaActionBlocks["stopSound_s"].xmlText(), + MotaActionBlocks["setVolume_s"].xmlText(), + MotaActionBlocks["setBgmSpeed_s"].xmlText(), + ], + UI绘制: [ + MotaActionBlocks["previewUI_s"].xmlText(), + MotaActionBlocks["clearMap_s"].xmlText(), + MotaActionBlocks["setAttribute_s"].xmlText(), + MotaActionBlocks["setFilter_s"].xmlText(), + MotaActionBlocks["fillText_s"].xmlText(), + MotaActionBlocks["fillBoldText_s"].xmlText(), + MotaActionBlocks["drawTextContent_s"].xmlText(), + MotaActionBlocks["fillRect_s"].xmlText(), + MotaActionBlocks["strokeRect_s"].xmlText(), + MotaActionBlocks["drawLine_s"].xmlText(), + MotaActionBlocks["drawArrow_s"].xmlText(), + MotaActionBlocks["fillPolygon_s"].xmlText(), + MotaActionBlocks["strokePolygon_s"].xmlText(), + MotaActionBlocks["fillEllipse_s"].xmlText(), + MotaActionBlocks["strokeEllipse_s"].xmlText(), + MotaActionBlocks["fillArc_s"].xmlText(), + MotaActionBlocks["strokeArc_s"].xmlText(), + MotaActionBlocks["drawImage_s"].xmlText(), + MotaActionBlocks["drawImage_1_s"].xmlText(), + MotaActionBlocks["drawIcon_s"].xmlText(), + MotaActionBlocks["drawBackground_s"].xmlText(), + MotaActionBlocks["drawSelector_s"].xmlText(), + MotaActionBlocks["drawSelector_1_s"].xmlText(), + ], + 原生脚本: [ + MotaActionBlocks["function_s"].xmlText(), + MotaActionBlocks["unknown_s"].xmlText(), + ], + 值块: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["expression_arithmetic_0"].xmlText(), + MotaActionBlocks["idFlag_e"].xmlText(), + MotaActionBlocks["idTemp_e"].xmlText(), + MotaActionBlocks["negate_e"].xmlText(), + MotaActionBlocks["unaryOperation_e"].xmlText(), + MotaActionBlocks["bool_e"].xmlText(), + MotaActionBlocks["idString_e"].xmlText(), + MotaActionBlocks["idIdList_e"].xmlText(), + MotaActionBlocks["idFixedList_e"].xmlText(), + MotaActionBlocks["enemyattr_e"].xmlText(), + MotaActionBlocks["blockId_e"].xmlText(), + MotaActionBlocks["blockNumber_e"].xmlText(), + MotaActionBlocks["blockCls_e"].xmlText(), + MotaActionBlocks["hasEquip_e"].xmlText(), + MotaActionBlocks["equip_e"].xmlText(), + MotaActionBlocks["nextXY_e"].xmlText(), + MotaActionBlocks["isReplaying_e"].xmlText(), + MotaActionBlocks["hasVisitedFloor_e"].xmlText(), + MotaActionBlocks["isShopVisited_e"].xmlText(), + MotaActionBlocks["canBattle_e"].xmlText(), + MotaActionBlocks["damage_e"].xmlText(), + MotaActionBlocks["damage_1_e"].xmlText(), + MotaActionBlocks["rand_e"].xmlText(), + MotaActionBlocks["evalString_e"].xmlText(), + ], + 常见事件模板: [ + '', + MotaActionFunctions.actionParser.parseList({ + type: "if", + condition: "!core.musicStatus.bgmStatus", + true: ["\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳"], + false: [], + }), + '', + MotaActionFunctions.actionParser.parse( + [ + { + type: "if", + condition: "switch:A", + true: [ + "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", + { + type: "comment", + text: "下一条指令可视情况使用或不使用", + }, + { + type: "hide", + remove: true, + time: 250, + }, + ], + false: [ + { + type: "confirm", + text: "我有3把黄钥匙,\n你出50金币就卖给你。", + yes: [ { - "type": "break", - "n": 1 - } - ] + type: "if", + condition: "status:money>=50", + true: [ + { + type: "setValue", + name: "status:money", + operator: "-=", + value: "50", + }, + { + type: "setValue", + name: "item:yellowKey", + operator: "+=", + value: "3", + }, + { + type: "playSound", + name: "确定", + stop: true, + }, + { + type: "setValue", + name: "switch:A", + value: "true", + }, + ], + false: [ + { + type: "playSound", + name: "操作失败", + }, + "\t[行商,trader]\b[this]你的金币不足!", + ], + }, + ], + no: [], }, - { - "type": "setValue", - "name": "temp:X", - "value": "flag:x" - }, - { - "type": "setValue", - "name": "temp:Y", - "value": "flag:y" - } - ] - } - ] - }, - { - "type": "drawSelector", - "code": 1 - }, - { - "type": "comment", - "text": "流程进行到这里可以对[X,Y]点进行处理,比如" - }, - { - "type": "closeDoor", - "id": "yellowDoor", - "loc": [ - "temp:X", - "temp:Y" - ] - } - ],'event'), - '', - MotaActionFunctions.actionParser.parse([ - { - "type": "comment", - "text": "多阶段boss,请直接作为战后事件使用" - }, - { - "type": "setValue", - "name": "switch:A", - "operator": "+=", - "value": "1" - }, - { - "type": "switch", - "condition": "switch:A", - "caseList": [ + ], + }, + ], + "event" + ), + '', + MotaActionFunctions.actionParser.parse( + [ { - "case": "1", - "action": [ - { - "type": "setBlock", - "number": "redSlime" - }, - "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?" - ] + type: "comment", + text: "全地图选中一个点,需要用鼠标或触屏操作", }, { - "case": "2", - "action": [ - { - "type": "setBlock", - "number": "blackSlime" - }, - "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!" - ] + type: "setValue", + name: "temp:X", + value: "status:x", }, { - "case": "3", - "action": [ - { - "type": "setBlock", - "number": "slimelord" - }, - "\t[4阶段boss,slimelord]\b[this]我还能打!" - ] + type: "setValue", + name: "temp:Y", + value: "status:y", }, { - "case": "4", - "action": [ - "\t[4阶段boss,slimelord]我一定会回来的!" - ] - } - ] - } - ],'afterBattle'), - ], - '最近使用事件':[ - '', - ] - } - var toolboxgap = '' - //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') - //MotaActionBlocks['idString_e'].xmlText() + type: "tip", + text: "再次点击闪烁位置确认", + }, + { + type: "while", + condition: "true", + data: [ + { + type: "drawSelector", + image: "winskin.png", + code: 1, + x: "32*temp:X", + y: "32*temp:Y", + width: 32, + height: 32, + }, + { + type: "wait", + }, + { + type: "if", + condition: "(flag:type === 1)", + true: [ + { + type: "if", + condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", + true: [ + { + type: "break", + n: 1, + }, + ], + }, + { + type: "setValue", + name: "temp:X", + value: "flag:x", + }, + { + type: "setValue", + name: "temp:Y", + value: "flag:y", + }, + ], + }, + ], + }, + { + type: "drawSelector", + code: 1, + }, + { + type: "comment", + text: "流程进行到这里可以对[X,Y]点进行处理,比如", + }, + { + type: "closeDoor", + id: "yellowDoor", + loc: ["temp:X", "temp:Y"], + }, + ], + "event" + ), + '', + MotaActionFunctions.actionParser.parse( + [ + { + type: "comment", + text: "多阶段boss,请直接作为战后事件使用", + }, + { + type: "setValue", + name: "switch:A", + operator: "+=", + value: "1", + }, + { + type: "switch", + condition: "switch:A", + caseList: [ + { + case: "1", + action: [ + { + type: "setBlock", + number: "redSlime", + }, + "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", + ], + }, + { + case: "2", + action: [ + { + type: "setBlock", + number: "blackSlime", + }, + "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", + ], + }, + { + case: "3", + action: [ + { + type: "setBlock", + number: "slimelord", + }, + "\t[4阶段boss,slimelord]\b[this]我还能打!", + ], + }, + { + case: "4", + action: ["\t[4阶段boss,slimelord]我一定会回来的!"], + }, + ], + }, + ], + "afterBattle" + ), + ], + 最近使用事件: [ + '', + ], + }; + var toolboxgap = ''; + //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') + //MotaActionBlocks['idString_e'].xmlText() - for (var name in toolboxObj){ - var custom = null; - if(name=='最近使用事件')custom='searchBlockCategory'; - if(name=='入口方块')custom='entranceCategory'; - getCategory(name,custom).innerHTML = toolboxObj[name].join(toolboxgap); - } - -var blocklyArea = document.getElementById('blocklyArea'); -var blocklyDiv = document.getElementById('blocklyDiv'); -var workspace = Blockly.inject(blocklyDiv,{ - media: '_server/blockly/media/', - toolbox: document.getElementById('toolbox'), - zoom:{ - controls: true, - wheel: false,//滚轮改为上下(shift:左右)翻滚 - startScale: 1.0, - maxScale: 3, - minScale: 0.3, - scaleSpeed: 1.08 - }, - trashcan: false, -}); - -editor_blockly.isCommonEntry = function () { - var commonEntries = ['beforeBattle', 'afterBattle', 'afterOpenDoor', 'firstArrive', 'eachArrive', 'commonEvent', 'item']; - return commonEntries.indexOf(editor_blockly.entryType) >= 0; -} - -editor_blockly.entranceCategoryCallback = function(workspace) { - var list=toolboxObj['入口方块'] - var xmlList = []; - var eventType = (editor_blockly.isCommonEntry() ? 'common' : editor_blockly.entryType)+'_m'; - for(var ii=0,blockText;blockText=list[ii];ii++){ - if(new RegExp('').exec(blockText)){ - var block = Blockly.Xml.textToDom(''+blockText+'').firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); + for (var name in toolboxObj) { + var custom = null; + if (name == "最近使用事件") custom = "searchBlockCategory"; + if (name == "入口方块") custom = "entranceCategory"; + getCategory(name, custom).innerHTML = toolboxObj[name].join(toolboxgap); } - } - return xmlList; -} -workspace.registerToolboxCategoryCallback( - 'entranceCategory', editor_blockly.entranceCategoryCallback); + var blocklyArea = document.getElementById("blocklyArea"); + var blocklyDiv = document.getElementById("blocklyDiv"); + var workspace = Blockly.inject(blocklyDiv, { + media: "_server/blockly/media/", + toolbox: document.getElementById("toolbox"), + zoom: { + controls: true, + wheel: false, //滚轮改为上下(shift:左右)翻滚 + startScale: 1.0, + maxScale: 3, + minScale: 0.3, + scaleSpeed: 1.08, + }, + trashcan: false, + }); -editor_blockly.searchBlockCategoryCallback = function(workspace) { - var xmlList = []; - var labels = editor_blockly.searchBlock(); - for (var i = 0; i < labels.length; i++) { - var blockText = '' + - MotaActionBlocks[labels[i]].xmlText() + - ''; - var block = Blockly.Xml.textToDom(blockText).firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); - } - return xmlList; -}; + editor_blockly.isCommonEntry = function () { + var commonEntries = [ + "beforeBattle", + "afterBattle", + "afterOpenDoor", + "firstArrive", + "eachArrive", + "commonEvent", + "item", + ]; + return commonEntries.indexOf(editor_blockly.entryType) >= 0; + }; -workspace.registerToolboxCategoryCallback( - 'searchBlockCategory', editor_blockly.searchBlockCategoryCallback); - -var onresize = function(e) { - blocklyDiv.style.width = blocklyArea.offsetWidth + 'px'; - blocklyDiv.style.height = blocklyArea.offsetHeight + 'px'; - Blockly.svgResize(workspace); -}; -if(typeof editor !== "undefined" && !editor.isMobile)window.addEventListener('resize', onresize, false); -onresize(); -//Blockly.svgResize(workspace); - -//Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); -document.getElementById('blocklyDiv').onmousewheel = function(e){ - //console.log(e); - e.preventDefault(); - var hvScroll = e.shiftKey?'hScroll':'vScroll'; - var mousewheelOffsetValue=20/380*workspace.scrollbar[hvScroll].handleLength_*3; - workspace.scrollbar[hvScroll].handlePosition_+=( ((e.deltaY||0)+(e.detail||0)) >0?mousewheelOffsetValue:-mousewheelOffsetValue); - workspace.scrollbar[hvScroll].onScroll_(); - // workspace.setScale(workspace.scale); -} - -var doubleClickCheck=[[0,'abc']]; -function omitedcheckUpdateFunction(event) { - if(event.type==='create'){ - editor_blockly.addIntoLastUsedType(event.blockId); - } - if(event.type==='ui' && event.element == 'click'){ - var newClick = [new Date().getTime(),event.blockId]; - var lastClick = doubleClickCheck.shift(); - doubleClickCheck.push(newClick); - if(newClick[0]-lastClick[0]<500){ - if(newClick[1]===lastClick[1]){ - editor_blockly.doubleClickBlock(newClick[1]); - } - } - } - // Only handle these events - if (["create", "move", "change", "delete"].indexOf(event.type) < 0) return; - if(editor_blockly.workspace.topBlocks_.length>=2){ - editor_blockly.setValue('入口方块只能有一个'); - return; - } - var eventType = editor_blockly.entryType; - if(editor_blockly.workspace.topBlocks_.length==1){ - var blockType = editor_blockly.workspace.topBlocks_[0].type; - if(blockType!==eventType+'_m' && !(editor_blockly.isCommonEntry() && blockType == 'common_m')){ - editor_blockly.setValue('入口方块类型错误'); - return; - } - } - try { - var code = Blockly.JavaScript.workspaceToCode(workspace).replace(/\\(i|c|d|e|g|z)/g, '\\\\$1'); - editor_blockly.setValue(code); - } catch (error) { - editor_blockly.setValue(String(error)); - if (error instanceof OmitedError){ - var blockName = error.blockName; - var varName = error.varName; - var block = error.block; - } - // console.log(error); - } - } - - workspace.addChangeListener(omitedcheckUpdateFunction); - - workspace.addChangeListener(Blockly.Events.disableOrphans); - - editor_blockly.workspace = workspace; - - MotaActionFunctions.workspace = function(){ - return editor_blockly.workspace; - } - - // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 - MotaActionFunctions.xmlText = function (ruleName,inputs,isShadow,comment,collapsed,disabled) { - var rule = MotaActionBlocks[ruleName]; - var blocktext = isShadow?'shadow':'block'; - var xmlText = []; - xmlText.push('<'+blocktext+' type="'+ruleName+'"'+(collapsed ? ' collapsed="true"' : '')+(disabled ? ' disabled="true"' : '')+'>'); - if(!inputs)inputs=[]; - for (var ii=0,inputType;inputType=rule.argsType[ii];ii++) { - var input = inputs[ii]; - var _input = ''; - var noinput = (input===null || input===undefined); - if(noinput && inputType==='field' && MotaActionBlocks[rule.argsGrammarName[ii]].type!=='field_dropdown') continue; - if(noinput && inputType==='field') { - noinput = false; - input = rule.fieldDefault(rule.args[ii]) - } - if(noinput) input = ''; - if(inputType==='field' && MotaActionBlocks[rule.argsGrammarName[ii]].type==='field_checkbox')input=input?'TRUE':'FALSE'; - if(inputType!=='field') { - var subList = false; - var subrulename = rule.argsGrammarName[ii]; - var subrule = MotaActionBlocks[subrulename]; - if (subrule instanceof Array) { - subrulename=subrule[subrule.length-1]; - subrule = MotaActionBlocks[subrulename]; - subList = true; - } - _input = subrule.xmlText([],true); - if(noinput && !subList && !isShadow) { - //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 - input = subrule.xmlText(); + editor_blockly.entranceCategoryCallback = function (workspace) { + var list = toolboxObj["入口方块"]; + var xmlList = []; + var eventType = + (editor_blockly.isCommonEntry() ? "common" : editor_blockly.entryType) + + "_m"; + for (var ii = 0, blockText; (blockText = list[ii]); ii++) { + if (new RegExp('').exec(blockText)) { + var block = Blockly.Xml.textToDom( + "" + blockText + "" + ).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); } } - xmlText.push('<'+inputType+' name="'+rule.args[ii]+'">'); - xmlText.push(_input+input); - xmlText.push(''); - } - if(comment){ - xmlText.push(''); - xmlText.push(comment); - xmlText.push(''); - } - var next = inputs[rule.args.length]; - if (next) {//next - xmlText.push(''); - xmlText.push(next); - xmlText.push(''); - } - xmlText.push(''); - return xmlText.join(''); - } -})(); + return xmlList; + }; + workspace.registerToolboxCategoryCallback( + "entranceCategory", + editor_blockly.entranceCategoryCallback + ); + editor_blockly.searchBlockCategoryCallback = function (workspace) { + var xmlList = []; + var labels = editor_blockly.searchBlock(); + for (var i = 0; i < labels.length; i++) { + var blockText = + "" + MotaActionBlocks[labels[i]].xmlText() + ""; + var block = Blockly.Xml.textToDom(blockText).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + return xmlList; + }; -// end mark sfergsvae -}).toString().split('// start mark sfergsvae')[1].split('// end mark sfergsvae')[0] + workspace.registerToolboxCategoryCallback( + "searchBlockCategory", + editor_blockly.searchBlockCategoryCallback + ); + + var onresize = function (e) { + blocklyDiv.style.width = blocklyArea.offsetWidth + "px"; + blocklyDiv.style.height = blocklyArea.offsetHeight + "px"; + Blockly.svgResize(workspace); + }; + if (typeof editor !== "undefined" && !editor.isMobile) + window.addEventListener("resize", onresize, false); + onresize(); + //Blockly.svgResize(workspace); + + //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); + document.getElementById("blocklyDiv").onmousewheel = function (e) { + //console.log(e); + e.preventDefault(); + var hvScroll = e.shiftKey ? "hScroll" : "vScroll"; + var mousewheelOffsetValue = + (20 / 380) * workspace.scrollbar[hvScroll].handleLength_ * 3; + workspace.scrollbar[hvScroll].handlePosition_ += + (e.deltaY || 0) + (e.detail || 0) > 0 + ? mousewheelOffsetValue + : -mousewheelOffsetValue; + workspace.scrollbar[hvScroll].onScroll_(); + // workspace.setScale(workspace.scale); + }; + + var doubleClickCheck = [[0, "abc"]]; + function omitedcheckUpdateFunction(event) { + if (event.type === "create") { + editor_blockly.addIntoLastUsedType(event.blockId); + } + if (event.type === "ui" && event.element == "click") { + var newClick = [new Date().getTime(), event.blockId]; + var lastClick = doubleClickCheck.shift(); + doubleClickCheck.push(newClick); + if (newClick[0] - lastClick[0] < 500) { + if (newClick[1] === lastClick[1]) { + editor_blockly.doubleClickBlock(newClick[1]); + } + } + } + // Only handle these events + if (["create", "move", "change", "delete"].indexOf(event.type) < 0) + return; + if (editor_blockly.workspace.topBlocks_.length >= 2) { + editor_blockly.setValue("入口方块只能有一个"); + return; + } + var eventType = editor_blockly.entryType; + if (editor_blockly.workspace.topBlocks_.length == 1) { + var blockType = editor_blockly.workspace.topBlocks_[0].type; + if ( + blockType !== eventType + "_m" && + !(editor_blockly.isCommonEntry() && blockType == "common_m") + ) { + editor_blockly.setValue("入口方块类型错误"); + return; + } + } + try { + var code = Blockly.JavaScript.workspaceToCode(workspace).replace( + /\\(i|c|d|e|g|z)/g, + "\\\\$1" + ); + editor_blockly.setValue(code); + } catch (error) { + editor_blockly.setValue(String(error)); + if (error instanceof OmitedError) { + var blockName = error.blockName; + var varName = error.varName; + var block = error.block; + } + // console.log(error); + } + } + + workspace.addChangeListener(omitedcheckUpdateFunction); + + workspace.addChangeListener(Blockly.Events.disableOrphans); + + editor_blockly.workspace = workspace; + + MotaActionFunctions.workspace = function () { + return editor_blockly.workspace; + }; + + // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 + MotaActionFunctions.xmlText = function ( + ruleName, + inputs, + isShadow, + comment, + collapsed, + disabled + ) { + var rule = MotaActionBlocks[ruleName]; + var blocktext = isShadow ? "shadow" : "block"; + var xmlText = []; + xmlText.push( + "<" + + blocktext + + ' type="' + + ruleName + + '"' + + (collapsed ? ' collapsed="true"' : "") + + (disabled ? ' disabled="true"' : "") + + ">" + ); + if (!inputs) inputs = []; + for (var ii = 0, inputType; (inputType = rule.argsType[ii]); ii++) { + var input = inputs[ii]; + var _input = ""; + var noinput = input === null || input === undefined; + if ( + noinput && + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type !== "field_dropdown" + ) + continue; + if (noinput && inputType === "field") { + noinput = false; + input = rule.fieldDefault(rule.args[ii]); + } + if (noinput) input = ""; + if ( + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type === "field_checkbox" + ) + input = input ? "TRUE" : "FALSE"; + if (inputType !== "field") { + var subList = false; + var subrulename = rule.argsGrammarName[ii]; + var subrule = MotaActionBlocks[subrulename]; + if (subrule instanceof Array) { + subrulename = subrule[subrule.length - 1]; + subrule = MotaActionBlocks[subrulename]; + subList = true; + } + _input = subrule.xmlText([], true); + if (noinput && !subList && !isShadow) { + //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 + input = subrule.xmlText(); + } + } + xmlText.push("<" + inputType + ' name="' + rule.args[ii] + '">'); + xmlText.push(_input + input); + xmlText.push(""); + } + if (comment) { + xmlText.push(""); + xmlText.push(comment); + xmlText.push(""); + } + var next = inputs[rule.args.length]; + if (next) { + //next + xmlText.push(""); + xmlText.push(next); + xmlText.push(""); + } + xmlText.push(""); + return xmlText.join(""); + }; + })(); + + // end mark sfergsvae +} + .toString() + .split("// start mark sfergsvae")[1] + .split("// end mark sfergsvae")[0]; diff --git a/_server/table/comment.js b/_server/table/comment.js index b417a50..b8ae4ff 100644 --- a/_server/table/comment.js +++ b/_server/table/comment.js @@ -116,6 +116,14 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_lint": true, "_docs": "能否使用或装备", "_data": "当前能否使用或装备该道具,仅对cls不为items有效。null表示始终不可使用但可装备" + }, + "canBatchUse": { + "_leaf": true, + "_type": "textarea", + "_string": true, + "_lint": true, + "_docs": "能否批量使用", + "_data": "该道具是否允许批量使用,仅对cls为tools或constants有效,true表示可批量使用。建议同时勾选【回放不绘制道具栏】" } } }, @@ -187,24 +195,25 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "def": { "_leaf": true, "_type": "textarea", - "_data": "物理防御力" + "_data": "防御力" }, "mdef": { "_leaf": true, "_type": "textarea", - "_data": "魔法防御力" + "_docs": "法抗", + "_data": "百分数,如10为10%法抗,怪物受到勇士的法术伤害减免比例" + + }, + "spell": { + "_leaf": true, + "_type": "textarea", + "_data": "法强" }, "speed": { "_leaf": true, "_type": "textarea", "_data": "速度" }, - "magic": { - "_leaf": true, - "_type": "checkbox", - "_docs": "是否为魔法攻击", - "_data": "勾选以魔法攻击计算,不勾选以物理攻击计算" - }, "money": { "_leaf": true, "_type": "textarea", @@ -372,7 +381,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_docs": "退化扣防", "_data": "退化时勇士下降的防御力点数" }, - "damage": { + "damage2": { "_leaf": true, "_type": "textarea", "_range": "thiseval==~~thiseval||thiseval==null", @@ -395,7 +404,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { } } }, - "enemys_template": { 'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'exp': 0, 'point': 0, 'special': [] }, + "enemys_template": { 'name': '新敌人', 'hp': 0, 'atk': 0, 'def': 0, 'mdef': 0, 'speed': 1, 'money': 0, 'exp': 0, 'point': 0, 'special': [] }, // --------------------------- 【图块属性】相关的表格配置 --------------------------- // diff --git a/_server/table/data.comment.js b/_server/table/data.comment.js index de82674..358881b 100644 --- a/_server/table/data.comment.js +++ b/_server/table/data.comment.js @@ -89,7 +89,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_range": "editor.mode.checkUnique(thiseval)", "_directory": "./project/bgms/", "_transform": (function (one) { - if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac')) + if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac') || one.endsWith('.opus')) return one; return null; }).toString(), @@ -102,7 +102,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_range": "editor.mode.checkUnique(thiseval)", "_directory": "./project/sounds/", "_transform": (function (one) { - if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac')) + if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac') || one.endsWith('.opus')) return one; return null; }).toString(), @@ -147,7 +147,7 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_type": "material", "_directory": "./project/bgms/", "_transform": (function (one) { - if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac')) + if (one.endsWith('.mp3') || one.endsWith('.ogg') || one.endsWith('.wav') || one.endsWith('.m4a') || one.endsWith('.flac') || one.endsWith('.opus')) return one; return null; }).toString(), @@ -262,44 +262,36 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "def": { "_leaf": true, "_type": "textarea", - "_data": "物理防御" + "_data": "防御" + }, + "spell": { + "_leaf": true, + "_type": "textarea", + "_data": "法强", }, "mdef": { "_leaf": true, "_type": "textarea", - "_data": "魔法防御" + "_data": "法抗百分比", + }, + "matk": { + "_leaf": true, + "_type": "textarea", + "_data": "100为法强转化为等值魔攻", + "_docs": "魔攻比例" + }, + "mhp": { + "_leaf": true, + "_type": "textarea", + "_data": "100为法强转化为等值护盾", + "_docs": "护盾比例" }, "speed": { "_leaf": true, "_type": "textarea", - "_data": "攻击速度" - }, - "str": { - "_leaf": true, - "_type": "textarea", - "_data": "力量" - }, - "agi": { - "_leaf": true, - "_type": "textarea", - "_data": "敏捷" - }, - "int": { - "_leaf": true, - "_type": "textarea", - "_data": "智力" - }, - "con": { - "_leaf": true, - "_type": "textarea", - "_data": "体质" - }, - "magic": { - "_leaf": true, - "_type": "checkbox", - "_docs": "攻击类型", - "_data": "攻击类型是否是魔法" + "_data": "速度" }, + "money": { "_leaf": true, "_type": "textarea", diff --git a/_server/table/plugins.comment.js b/_server/table/plugins.comment.js index a02e298..0ea6e33 100644 --- a/_server/table/plugins.comment.js +++ b/_server/table/plugins.comment.js @@ -122,6 +122,12 @@ var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_type": "textarea", "_range": "typeof(thiseval)=='string' || thiseval==null", "_data": "音乐鉴赏" + }, + "intro&loop": { + "_leaf": true, + "_type": "textarea", + "_range": "typeof(thiseval)=='string' || thiseval==null", + "_data": "背景音乐拼接" } } if (obj[key]) return obj[key]; diff --git a/index.html b/index.html index dceab9b..a316bc3 100644 --- a/index.html +++ b/index.html @@ -47,6 +47,20 @@ startImageDiv.classList.add("startImageDivAnimation"); // 注释下面这句话以禁止单击立刻跳过开场动画 startImageBackgroundDiv.onclick = onAnimationEnd; + // 新增加载图片轮播逻辑 + const slides = document.querySelectorAll('.loading-slide'); + let currentSlide = 0; + + const slideInterval = setInterval(() => { + slides[currentSlide].classList.remove('active'); + currentSlide = (currentSlide + 1) % slides.length; + slides[currentSlide].classList.add('active'); + }, 3000); + + // 在加载完成时清除定时器 + window.addEventListener('load', () => { + clearInterval(slideInterval); + }); }; startImageLogo.onerror = function () {}; startImageLogo.src = "logo.png"; @@ -58,6 +72,14 @@
+ +
+ + + + + +
@@ -213,6 +235,9 @@
+ + + diff --git a/libs/control.js b/libs/control.js index c6e4f30..93b4a0a 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1,4 +1,3 @@ - /* control.js:游戏主要逻辑控制 主要负责status相关内容,以及各种变量获取/存储 @@ -7,57 +6,93 @@ control.js:游戏主要逻辑控制 "use strict"; -function control () { - this._init(); +function control() { + this._init(); } control.prototype._init = function () { - this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control; - this.renderFrameFuncs = []; - this.replayActions = []; - this.weathers = {}; - this.resizes = []; - this.noAutoEvents = true; - this.updateNextFrame = false; - // --- 注册系统的animationFrame - this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); - this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); - this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate); - this.registerAnimationFrame("animate", true, this._animationFrame_animate); - this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving); - this.registerAnimationFrame("weather", true, this._animationFrame_weather); - this.registerAnimationFrame("tip", true, this._animateFrame_tip); - this.registerAnimationFrame("parallelDo", false, this._animationFrame_parallelDo); - // --- 注册系统的天气 - this.registerWeather("rain", this._weather_rain, this._animationFrame_weather_rain); - this.registerWeather("snow", this._weather_snow, this._animationFrame_weather_snow); - this.registerWeather("fog", this._weather_fog, this.__animateFrame_weather_image); - this.registerWeather("cloud", this._weather_cloud, this.__animateFrame_weather_image); - this.registerWeather("sun", this._weather_sun, this._animationFrame_weather_sun); - // --- 注册系统的replay - this.registerReplayAction("move", this._replayAction_move); - this.registerReplayAction("item", this._replayAction_item); - this.registerReplayAction("equip", this._replayAction_equip); - this.registerReplayAction("unEquip", this._replayAction_unEquip); - this.registerReplayAction("saveEquip", this._replayAction_saveEquip); - this.registerReplayAction("loadEquip", this._replayAction_loadEquip); - this.registerReplayAction("fly", this._replayAction_fly); - this.registerReplayAction("shop", this._replayAction_shop); - this.registerReplayAction("turn", this._replayAction_turn); - this.registerReplayAction("getNext", this._replayAction_getNext); - this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); - this.registerReplayAction("key", this._replayAction_key); - this.registerReplayAction("click", this._replayAction_click); - this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput); - this.registerReplayAction("no", this._replayAction_no); - // --- 注册系统的resize - this.registerResize("gameGroup", this._resize_gameGroup); - this.registerResize("canvas", this._resize_canvas); - this.registerResize("statusBar", this._resize_statusBar); - this.registerResize("status", this._resize_status); - this.registerResize("toolBar", this._resize_toolBar); - this.registerResize("tools", this._resize_tools); -} + this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control; + this.renderFrameFuncs = []; + this.replayActions = []; + this.weathers = {}; + this.resizes = []; + this.noAutoEvents = true; + this.updateNextFrame = false; + // --- 注册系统的animationFrame + this.registerAnimationFrame( + "totalTime", + false, + this._animationFrame_totalTime + ); + this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); + this.registerAnimationFrame( + "globalAnimate", + true, + this._animationFrame_globalAnimate + ); + this.registerAnimationFrame("animate", true, this._animationFrame_animate); + this.registerAnimationFrame( + "heroMoving", + true, + this._animationFrame_heroMoving + ); + this.registerAnimationFrame("weather", true, this._animationFrame_weather); + this.registerAnimationFrame("tip", true, this._animateFrame_tip); + this.registerAnimationFrame( + "parallelDo", + false, + this._animationFrame_parallelDo + ); + // --- 注册系统的天气 + this.registerWeather( + "rain", + this._weather_rain, + this._animationFrame_weather_rain + ); + this.registerWeather( + "snow", + this._weather_snow, + this._animationFrame_weather_snow + ); + this.registerWeather( + "fog", + this._weather_fog, + this.__animateFrame_weather_image + ); + this.registerWeather( + "cloud", + this._weather_cloud, + this.__animateFrame_weather_image + ); + this.registerWeather( + "sun", + this._weather_sun, + this._animationFrame_weather_sun + ); + // --- 注册系统的replay + this.registerReplayAction("move", this._replayAction_move); + this.registerReplayAction("item", this._replayAction_item); + this.registerReplayAction("equip", this._replayAction_equip); + this.registerReplayAction("unEquip", this._replayAction_unEquip); + this.registerReplayAction("saveEquip", this._replayAction_saveEquip); + this.registerReplayAction("loadEquip", this._replayAction_loadEquip); + this.registerReplayAction("fly", this._replayAction_fly); + this.registerReplayAction("shop", this._replayAction_shop); + this.registerReplayAction("turn", this._replayAction_turn); + this.registerReplayAction("getNext", this._replayAction_getNext); + this.registerReplayAction("moveDirectly", this._replayAction_moveDirectly); + this.registerReplayAction("key", this._replayAction_key); + this.registerReplayAction("click", this._replayAction_click); + this.registerReplayAction("ignoreInput", this._replayAction_ignoreInput); + this.registerReplayAction("no", this._replayAction_no); + // --- 注册系统的resize + this.registerResize("gameGroup", this._resize_gameGroup); + this.registerResize("canvas", this._resize_canvas); + this.registerResize("statusBar", this._resize_statusBar); + this.registerResize("status", this._resize_status); + this.registerResize("toolBar", this._resize_toolBar); + this.registerResize("tools", this._resize_tools); +}; // ------ requestAnimationFrame 相关 ------ // @@ -65,1542 +100,1938 @@ control.prototype._init = function () { // name:名称,可用来作为注销使用;needPlaying:是否只在游戏运行时才执行(在标题界面不执行) // func:要执行的函数,或插件中的函数名;可接受timestamp(从页面加载完毕到当前所经过的时间)作为参数 control.prototype.registerAnimationFrame = function (name, needPlaying, func) { - this.unregisterAnimationFrame(name); - this.renderFrameFuncs.push({ name: name, needPlaying: needPlaying, func: func }); -} + this.unregisterAnimationFrame(name); + this.renderFrameFuncs.push({ + name: name, + needPlaying: needPlaying, + func: func, + }); +}; ////// 注销一个 animationFrame ////// control.prototype.unregisterAnimationFrame = function (name) { - this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { return x.name != name; }); -} + this.renderFrameFuncs = this.renderFrameFuncs.filter(function (x) { + return x.name != name; + }); +}; ////// 设置requestAnimationFrame ////// control.prototype._setRequestAnimationFrame = function () { - this._checkRequestAnimationFrame(); - core.animateFrame.totalTime = Math.max(core.animateFrame.totalTime, core.getLocalStorage('totalTime', 0)); - var loop = function (timestamp) { - core.control.renderFrameFuncs.forEach(function (b) { - if (b.func) { - try { - if (core.isPlaying() || !b.needPlaying) - core.doFunc(b.func, core.control, timestamp); - } - catch (e) { - console.error(e); - console.error("ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。"); - core.unregisterAnimationFrame(b.name); - } - } - }) - window.requestAnimationFrame(loop); - } + this._checkRequestAnimationFrame(); + core.animateFrame.totalTime = Math.max( + core.animateFrame.totalTime, + core.getLocalStorage("totalTime", 0) + ); + var loop = function (timestamp) { + core.control.renderFrameFuncs.forEach(function (b) { + if (b.func) { + try { + if (core.isPlaying() || !b.needPlaying) + core.doFunc(b.func, core.control, timestamp); + } catch (e) { + console.error(e); + console.error( + "ERROR in requestAnimationFrame[" + b.name + "]:已自动注销该项。" + ); + core.unregisterAnimationFrame(b.name); + } + } + }); window.requestAnimationFrame(loop); -} + }; + window.requestAnimationFrame(loop); +}; control.prototype._checkRequestAnimationFrame = function () { - (function () { - var lastTime = 0; - var vendors = ['webkit', 'moz']; - for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了 - window[vendors[x] + 'CancelRequestAnimationFrame']; - } + (function () { + var lastTime = 0; + var vendors = ["webkit", "moz"]; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = + window[vendors[x] + "RequestAnimationFrame"]; + window.cancelAnimationFrame = + window[vendors[x] + "CancelAnimationFrame"] || // Webkit中此取消方法的名字变了 + window[vendors[x] + "CancelRequestAnimationFrame"]; + } - if (!window.requestAnimationFrame) { - window.requestAnimationFrame = function (callback, element) { - var currTime = new Date().getTime(); - var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); - var id = window.setTimeout(function () { - callback(currTime + timeToCall); - }, timeToCall); - lastTime = currTime + timeToCall; - return id; - }; - } - if (!window.cancelAnimationFrame) { - window.cancelAnimationFrame = function (id) { - clearTimeout(id); - }; - } - }()); -} + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function (callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function () { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function (id) { + clearTimeout(id); + }; + } + })(); +}; control.prototype._animationFrame_totalTime = function (timestamp) { - core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart; - core.animateFrame.totalTimeStart = timestamp; - if (core.isPlaying()) { - core.status.hero.statistics.totalTime = core.animateFrame.totalTime; - core.status.hero.statistics.currTime += timestamp - (core.status.hero.statistics.start || timestamp); - core.status.hero.statistics.start = timestamp; - } -} + core.animateFrame.totalTime += timestamp - core.animateFrame.totalTimeStart; + core.animateFrame.totalTimeStart = timestamp; + if (core.isPlaying()) { + core.status.hero.statistics.totalTime = core.animateFrame.totalTime; + core.status.hero.statistics.currTime += + timestamp - (core.status.hero.statistics.start || timestamp); + core.status.hero.statistics.start = timestamp; + } +}; control.prototype._animationFrame_autoSave = function (timestamp) { - if (timestamp - core.saves.autosave.time <= 5000) return; - core.control.checkAutosave(); - core.saves.autosave.time = timestamp; -} + if (timestamp - core.saves.autosave.time <= 5000) return; + core.control.checkAutosave(); + core.saves.autosave.time = timestamp; +}; control.prototype._animationFrame_globalAnimate = function (timestamp) { - if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) return; - core.status.globalAnimateStatus++; - if (core.status.floorId) { - // Global Animate - core.status.globalAnimateObjs.forEach(function (block) { - core.drawBlock(block, core.status.globalAnimateStatus); - }); + if (timestamp - core.animateFrame.globalTime <= core.values.animateSpeed) + return; + core.status.globalAnimateStatus++; + if (core.status.floorId) { + // Global Animate + core.status.globalAnimateObjs.forEach(function (block) { + core.drawBlock(block, core.status.globalAnimateStatus); + }); - // Global floor images - core.maps._drawFloorImages(core.status.floorId, core.canvas.bg, 'bg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus); - core.maps._drawFloorImages(core.status.floorId, core.canvas.fg, 'fg', core.status.floorAnimateObjs || [], core.status.globalAnimateStatus); + // Global floor images + core.maps._drawFloorImages( + core.status.floorId, + core.canvas.bg, + "bg", + core.status.floorAnimateObjs || [], + core.status.globalAnimateStatus + ); + core.maps._drawFloorImages( + core.status.floorId, + core.canvas.fg, + "fg", + core.status.floorAnimateObjs || [], + core.status.globalAnimateStatus + ); - // Global Autotile Animate - core.status.autotileAnimateObjs.forEach(function (block) { - core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus); - }); + // Global Autotile Animate + core.status.autotileAnimateObjs.forEach(function (block) { + core.maps._drawAutotileAnimate(block, core.status.globalAnimateStatus); + }); - // Global hero animate - if ((core.status.hero || {}).animate && core.status.heroMoving == 0 && main.mode == 'play' && !core.status.preview.enabled) { - core.drawHero('stop', null, core.status.globalAnimateStatus); - } + // Global hero animate + if ( + (core.status.hero || {}).animate && + core.status.heroMoving == 0 && + main.mode == "play" && + !core.status.preview.enabled + ) { + core.drawHero("stop", null, core.status.globalAnimateStatus); } - // Box animate - core.drawBoxAnimate(); - core.animateFrame.globalTime = timestamp; -} + } + // Box animate + core.drawBoxAnimate(); + core.animateFrame.globalTime = timestamp; +}; control.prototype._animationFrame_animate = function (timestamp) { - if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return; - core.clearMap('animate'); - // 更新帧 - for (var i = 0; i < core.status.animateObjs.length; i++) { - var obj = core.status.animateObjs[i]; - if (obj.index == obj.animate.frames.length) { - (function (callback) { - setTimeout(function () { - if (callback) callback(); - }); - })(obj.callback); - } + if ( + timestamp - core.animateFrame.animateTime < 50 || + !core.status.animateObjs || + core.status.animateObjs.length == 0 + ) + return; + core.clearMap("animate"); + // 更新帧 + for (var i = 0; i < core.status.animateObjs.length; i++) { + var obj = core.status.animateObjs[i]; + if (obj.index == obj.animate.frames.length) { + (function (callback) { + setTimeout(function () { + if (callback) callback(); + }); + })(obj.callback); } - core.status.animateObjs = core.status.animateObjs.filter(function (obj) { - return obj.index < obj.animate.frames.length; - }); - core.status.animateObjs.forEach(function (obj) { - if (obj.hero) { - core.maps._drawAnimateFrame('animate', obj.animate, core.status.heroCenter.px, core.status.heroCenter.py, obj.index++); - } else { - core.maps._drawAnimateFrame('animate', obj.animate, obj.centerX, obj.centerY, obj.index++); - } - }); - core.animateFrame.animateTime = timestamp; -} + } + core.status.animateObjs = core.status.animateObjs.filter(function (obj) { + return obj.index < obj.animate.frames.length; + }); + core.status.animateObjs.forEach(function (obj) { + if (obj.hero) { + core.maps._drawAnimateFrame( + "animate", + obj.animate, + core.status.heroCenter.px, + core.status.heroCenter.py, + obj.index++ + ); + } else { + core.maps._drawAnimateFrame( + "animate", + obj.animate, + obj.centerX, + obj.centerY, + obj.index++ + ); + } + }); + core.animateFrame.animateTime = timestamp; +}; control.prototype._animationFrame_heroMoving = function (timestamp) { - if (core.status.heroMoving <= 0) return; - // 换腿 - if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) { - core.animateFrame.leftLeg = !core.animateFrame.leftLeg; - core.animateFrame.moveTime = timestamp; - } - core.drawHero(core.animateFrame.leftLeg ? 'leftFoot' : 'rightFoot', 4 * core.status.heroMoving); -} + if (core.status.heroMoving <= 0) return; + // 换腿 + if (timestamp - core.animateFrame.moveTime > core.values.moveSpeed) { + core.animateFrame.leftLeg = !core.animateFrame.leftLeg; + core.animateFrame.moveTime = timestamp; + } + core.drawHero( + core.animateFrame.leftLeg ? "leftFoot" : "rightFoot", + 4 * core.status.heroMoving + ); +}; control.prototype._animationFrame_weather = function (timestamp) { - var weather = core.animateFrame.weather, type = weather.type; - if (!core.dymCanvas.weather || !core.control.weathers[type] || !core.control.weathers[type].frameFunc) return; - try { - core.doFunc(core.control.weathers[type].frameFunc, core.control, timestamp, core.animateFrame.weather.level); - } catch (e) { - console.error(e); - console.error("ERROR in weather[" + type + "]:已自动注销该项。"); - core.unregisterWeather(type); - } -} + var weather = core.animateFrame.weather, + type = weather.type; + if ( + !core.dymCanvas.weather || + !core.control.weathers[type] || + !core.control.weathers[type].frameFunc + ) + return; + try { + core.doFunc( + core.control.weathers[type].frameFunc, + core.control, + timestamp, + core.animateFrame.weather.level + ); + } catch (e) { + console.error(e); + console.error("ERROR in weather[" + type + "]:已自动注销该项。"); + core.unregisterWeather(type); + } +}; control.prototype._animationFrame_weather_rain = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; - core.clearMap('weather'); - ctx.strokeStyle = 'rgba(174,194,224,0.8)'; - ctx.lineWidth = 1; - ctx.lineCap = 'round'; + if (timestamp - core.animateFrame.weather.time < 30) return; + var ctx = core.dymCanvas.weather, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weather"); + ctx.strokeStyle = "rgba(174,194,224,0.8)"; + ctx.lineWidth = 1; + ctx.lineCap = "round"; - core.animateFrame.weather.nodes.forEach(function (p) { - ctx.beginPath(); - ctx.moveTo(p.x - ox, p.y - oy); - ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy); - ctx.stroke(); + core.animateFrame.weather.nodes.forEach(function (p) { + ctx.beginPath(); + ctx.moveTo(p.x - ox, p.y - oy); + ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy); + ctx.stroke(); - p.x += p.xs; - p.y += p.ys; - if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) { - p.x = Math.random() * core.bigmap.width * 32; - p.y = -10; - } + p.x += p.xs; + p.y += p.ys; + if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } + }); - }); - - ctx.fill(); - core.animateFrame.weather.time = timestamp; -} + ctx.fill(); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animationFrame_weather_snow = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; - core.clearMap('weather'); - ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; - ctx.beginPath(); - core.animateFrame.weather.data = core.animateFrame.weather.data || 0; - core.animateFrame.weather.data += 0.01; + if (timestamp - core.animateFrame.weather.time < 30) return; + var ctx = core.dymCanvas.weather, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weather"); + ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; + ctx.beginPath(); + core.animateFrame.weather.data = core.animateFrame.weather.data || 0; + core.animateFrame.weather.data += 0.01; - var angle = core.animateFrame.weather.data; - core.animateFrame.weather.nodes.forEach(function (p) { - ctx.moveTo(p.x - ox, p.y - oy); - ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true); - // update - p.x += Math.sin(angle) * core.animateFrame.weather.level; - p.y += Math.cos(angle + p.d) + 1 + p.r / 2; - if (p.x > core.bigmap.width * 32 + 5 || p.x < -5 || p.y > core.bigmap.height * 32) { - if (Math.random() > 1 / 3) { - p.x = Math.random() * core.bigmap.width * 32; - p.y = -10; - } - else { - if (Math.sin(angle) > 0) - p.x = -5; - else - p.x = core.bigmap.width * 32 + 5; - p.y = Math.random() * core.bigmap.height * 32; - } - } - }); - ctx.fill(); - core.animateFrame.weather.time = timestamp; -} + var angle = core.animateFrame.weather.data; + core.animateFrame.weather.nodes.forEach(function (p) { + ctx.moveTo(p.x - ox, p.y - oy); + ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true); + // update + p.x += Math.sin(angle) * core.animateFrame.weather.level; + p.y += Math.cos(angle + p.d) + 1 + p.r / 2; + if ( + p.x > core.bigmap.width * 32 + 5 || + p.x < -5 || + p.y > core.bigmap.height * 32 + ) { + if (Math.random() > 1 / 3) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } else { + if (Math.sin(angle) > 0) p.x = -5; + else p.x = core.bigmap.width * 32 + 5; + p.y = Math.random() * core.bigmap.height * 32; + } + } + }); + ctx.fill(); + core.animateFrame.weather.time = timestamp; +}; control.prototype.__animateFrame_weather_image = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var node = core.animateFrame.weather.nodes[0]; - var image = node.image; - if (!image) return; - core.clearMap('weather'); - core.setAlpha('weather', node.level / 500); - var wind = 1.5; - var width = image.width, height = image.height; - node.x += node.dx * wind; - node.y += (2 * node.dy - 1) * wind; - if (node.x + 3 * width <= core._PX_) { - node.x += 4 * width; - while (node.x > 0) node.x -= width; + if (timestamp - core.animateFrame.weather.time < 30) return; + var node = core.animateFrame.weather.nodes[0]; + var image = node.image; + if (!image) return; + core.clearMap("weather"); + core.setAlpha("weather", node.level / 500); + var wind = 1.5; + var width = image.width, + height = image.height; + node.x += node.dx * wind; + node.y += (2 * node.dy - 1) * wind; + if (node.x + 3 * width <= core._PX_) { + node.x += 4 * width; + while (node.x > 0) node.x -= width; + } + node.dy += node.delta; + if (node.dy >= 1) { + node.delta = -0.001; + } else if (node.dy <= 0) { + node.delta = 0.001; + } + if (node.y + 3 * height <= core._PY_) { + node.y += 4 * height; + while (node.y > 0) node.y -= height; + } else if (node.y >= 0) { + node.y -= height; + } + for (var i = 0; i < 3; ++i) { + for (var j = 0; j < 3; ++j) { + if ( + node.x + (i + 1) * width <= 0 || + node.x + i * width >= core._PX_ || + node.y + (j + 1) * height <= 0 || + node.y + j * height >= core._PY_ + ) + continue; + core.drawImage("weather", image, node.x + i * width, node.y + j * height); } - node.dy += node.delta; - if (node.dy >= 1) { - node.delta = -0.001; - } else if (node.dy <= 0) { - node.delta = 0.001; - } - if (node.y + 3 * height <= core._PY_) { - node.y += 4 * height; - while (node.y > 0) node.y -= height; - } - else if (node.y >= 0) { - node.y -= height; - } - for (var i = 0; i < 3; ++i) { - for (var j = 0; j < 3; ++j) { - if (node.x + (i + 1) * width <= 0 || node.x + i * width >= core._PX_ - || node.y + (j + 1) * height <= 0 || node.y + j * height >= core._PY_) - continue; - core.drawImage('weather', image, node.x + i * width, node.y + j * height); - } - } - core.setAlpha('weather', 1); - core.animateFrame.weather.time = timestamp; -} + } + core.setAlpha("weather", 1); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animationFrame_weather_sun = function (timestamp, level) { - if (timestamp - core.animateFrame.weather.time < 30) return; - var node = core.animateFrame.weather.nodes[0]; - var opacity = node.opacity + node.delta; - if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3) - node.delta = -node.delta; - node.opacity = opacity; - core.setOpacity('weather', core.clamp(opacity, 0, 1)); - core.animateFrame.weather.time = timestamp; -} + if (timestamp - core.animateFrame.weather.time < 30) return; + var node = core.animateFrame.weather.nodes[0]; + var opacity = node.opacity + node.delta; + if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3) + node.delta = -node.delta; + node.opacity = opacity; + core.setOpacity("weather", core.clamp(opacity, 0, 1)); + core.animateFrame.weather.time = timestamp; +}; control.prototype._animateFrame_tip = function (timestamp) { - if (core.animateFrame.tip == null) return; - var tip = core.animateFrame.tip; - if (timestamp - tip.time <= 30) return; - var delta = timestamp - tip.time; - tip.time = timestamp; + if (core.animateFrame.tip == null) return; + var tip = core.animateFrame.tip; + if (timestamp - tip.time <= 30) return; + var delta = timestamp - tip.time; + tip.time = timestamp; - core.setFont('data', "16px Arial"); - core.setTextAlign('data', 'left'); - core.clearMap('data', 0, 0, core._PX_, 50); - core.ui._drawTip_drawOne(tip); - if (tip.stage == 1) { - tip.opacity += 0.05; - if (tip.opacity >= 0.6) { - tip.stage = 2; - tip.displayTime = 0; - } - } else if (tip.stage == 2) { - tip.displayTime += delta; - if (tip.displayTime >= 1000) tip.stage = 3; - } else tip.opacity -= 0.05; - - if (tip.opacity <= 0) { - core.animateFrame.tip = null; + core.setFont("data", "16px Arial"); + core.setTextAlign("data", "left"); + core.clearMap("data", 0, 0, core._PX_, 50); + core.ui._drawTip_drawOne(tip); + if (tip.stage == 1) { + tip.opacity += 0.05; + if (tip.opacity >= 0.6) { + tip.stage = 2; + tip.displayTime = 0; } -} + } else if (tip.stage == 2) { + tip.displayTime += delta; + if (tip.displayTime >= 1000) tip.stage = 3; + } else tip.opacity -= 0.05; + + if (tip.opacity <= 0) { + core.animateFrame.tip = null; + } +}; control.prototype._animationFrame_parallelDo = function (timestamp) { - core.control.controldata.parallelDo(timestamp); -} + core.control.controldata.parallelDo(timestamp); +}; // ------ 标题界面的处理 ------ // ////// 显示游戏开始界面 ////// control.prototype.showStartAnimate = function (noAnimate, callback) { - this._showStartAnimate_resetDom(); - if (core.flags.startUsingCanvas || noAnimate) - return this._showStartAnimate_finished(core.flags.startUsingCanvas, callback); - core.hideWithAnimate(core.dom.startTop, 20, function () { - core.control._showStartAnimate_finished(false, callback); - }); -} + this._showStartAnimate_resetDom(); + if (core.flags.startUsingCanvas || noAnimate) + return this._showStartAnimate_finished( + core.flags.startUsingCanvas, + callback + ); + core.hideWithAnimate(core.dom.startTop, 20, function () { + core.control._showStartAnimate_finished(false, callback); + }); +}; control.prototype._showStartAnimate_resetDom = function () { - core.dom.startPanel.style.opacity = 1; - core.dom.startPanel.style.display = "block"; - core.dom.startTop.style.opacity = 1; - core.dom.startTop.style.display = "block"; - core.dom.startButtonGroup.style.display = 'none'; - core.dom.startButtons.style.display = 'block'; - core.dom.levelChooseButtons.style.display = 'none'; - core.status.played = false; - core.clearStatus(); - core.clearMap('all'); - core.dom.musicBtn.style.display = 'block'; - core.setMusicBtn(); - // 重置音量 - core.events.setVolume(1, 0); - core.updateStatusBar(); -} + core.dom.startPanel.style.opacity = 1; + core.dom.startPanel.style.display = "block"; + core.dom.startTop.style.opacity = 1; + core.dom.startTop.style.display = "block"; + core.dom.startButtonGroup.style.display = "none"; + core.dom.startButtons.style.display = "block"; + core.dom.levelChooseButtons.style.display = "none"; + core.status.played = false; + core.clearStatus(); + core.clearMap("all"); + core.dom.musicBtn.style.display = "block"; + core.setMusicBtn(); + // 重置音量 + core.events.setVolume(1, 0); + core.updateStatusBar(); +}; control.prototype._showStartAnimate_finished = function (start, callback) { - core.dom.startTop.style.display = 'none'; - core.dom.startButtonGroup.style.display = 'block'; - main.selectedButton = null; - main.selectButton(0); - if (start) core.startGame(); - if (callback) callback(); -} + core.dom.startTop.style.display = "none"; + core.dom.startButtonGroup.style.display = "block"; + main.selectedButton = null; + main.selectButton(0); + if (start) core.startGame(); + if (callback) callback(); +}; ////// 隐藏游戏开始界面 ////// control.prototype.hideStartAnimate = function (callback) { - core.hideWithAnimate(core.dom.startPanel, 20, callback); -} + core.hideWithAnimate(core.dom.startPanel, 20, callback); +}; ////// 游戏是否已经开始 ////// control.prototype.isPlaying = function () { - return core.status.played; -} + return core.status.played; +}; ////// 清除游戏状态和数据 ////// control.prototype.clearStatus = function () { - // 停止各个Timeout和Interval - for (var i in core.timeout) { - clearTimeout(core.timeout[i]); - core.timeout[i] = null; - } - for (var i in core.interval) { - clearInterval(core.interval[i]); - core.interval[i] = null; - } - core.status = {}; - core.clearStatusBar(); - core.deleteAllCanvas(); - core.status.played = false; -} + // 停止各个Timeout和Interval + for (var i in core.timeout) { + clearTimeout(core.timeout[i]); + core.timeout[i] = null; + } + for (var i in core.interval) { + clearInterval(core.interval[i]); + core.interval[i] = null; + } + core.status = {}; + core.clearStatusBar(); + core.deleteAllCanvas(); + core.status.played = false; +}; control.prototype._initStatistics = function (totalTime) { - if (!core.isset(core.status.hero.statistics)) - core.status.hero.statistics = { - 'totalTime': totalTime, - 'currTime': 0, - 'hp': 0, - "battle": 0, - 'money': 0, - 'exp': 0, - 'battleDamage': 0, - 'poisonDamage': 0, - 'extraDamage': 0, - 'moveDirectly': 0, - 'ignoreSteps': 0, - } -} + if (!core.isset(core.status.hero.statistics)) + core.status.hero.statistics = { + totalTime: totalTime, + currTime: 0, + hp: 0, + battle: 0, + money: 0, + exp: 0, + battleDamage: 0, + poisonDamage: 0, + extraDamage: 0, + moveDirectly: 0, + ignoreSteps: 0, + }; +}; // ------ 自动寻路,人物行走 ------ // ////// 清除自动寻路路线 ////// control.prototype.clearAutomaticRouteNode = function (x, y) { - core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27); -} + core.clearMap( + "route", + x * 32 + 5 - core.status.automaticRoute.offsetX, + y * 32 + 5 - core.status.automaticRoute.offsetY, + 27, + 27 + ); +}; ////// 停止自动寻路操作 ////// control.prototype.stopAutomaticRoute = function () { - if (!core.status.played) return; - core.status.automaticRoute.autoHeroMove = false; - core.status.automaticRoute.autoStep = 0; - core.status.automaticRoute.destStep = 0; - core.status.automaticRoute.movedStep = 0; - core.status.automaticRoute.autoStepRoutes = []; - core.status.automaticRoute.destX = null; - core.status.automaticRoute.destY = null; - core.status.automaticRoute.lastDirection = null; - core.status.heroStop = true; - if (core.status.automaticRoute.moveStepBeforeStop.length == 0) - core.deleteCanvas('route'); -} + if (!core.status.played) return; + core.status.automaticRoute.autoHeroMove = false; + core.status.automaticRoute.autoStep = 0; + core.status.automaticRoute.destStep = 0; + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.autoStepRoutes = []; + core.status.automaticRoute.destX = null; + core.status.automaticRoute.destY = null; + core.status.automaticRoute.lastDirection = null; + core.status.heroStop = true; + if (core.status.automaticRoute.moveStepBeforeStop.length == 0) + core.deleteCanvas("route"); +}; ////// 保存剩下的寻路,并停止 ////// control.prototype.saveAndStopAutomaticRoute = function () { - var automaticRoute = core.status.automaticRoute; - if (automaticRoute.moveStepBeforeStop.length == 0) { - automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice(automaticRoute.autoStep - 1); - if (automaticRoute.moveStepBeforeStop.length >= 1) - automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep; - } - this.stopAutomaticRoute(); -} + var automaticRoute = core.status.automaticRoute; + if (automaticRoute.moveStepBeforeStop.length == 0) { + automaticRoute.moveStepBeforeStop = automaticRoute.autoStepRoutes.slice( + automaticRoute.autoStep - 1 + ); + if (automaticRoute.moveStepBeforeStop.length >= 1) + automaticRoute.moveStepBeforeStop[0].step -= automaticRoute.movedStep; + } + this.stopAutomaticRoute(); +}; ////// 继续剩下的自动寻路操作 ////// control.prototype.continueAutomaticRoute = function () { - // 此函数只应由events.afterOpenDoor和events.afterBattle调用 - var moveStep = core.status.automaticRoute.moveStepBeforeStop; - //core.status.automaticRoute.moveStepBeforeStop = []; - if (moveStep.length === 0 || (moveStep.length === 1 && moveStep[0].step === 1)) { - core.status.automaticRoute.moveStepBeforeStop = []; - } - else { - core.setAutoHeroMove(moveStep); - } -} + // 此函数只应由events.afterOpenDoor和events.afterBattle调用 + var moveStep = core.status.automaticRoute.moveStepBeforeStop; + //core.status.automaticRoute.moveStepBeforeStop = []; + if ( + moveStep.length === 0 || + (moveStep.length === 1 && moveStep[0].step === 1) + ) { + core.status.automaticRoute.moveStepBeforeStop = []; + } else { + core.setAutoHeroMove(moveStep); + } +}; ////// 清空剩下的自动寻路列表 ////// control.prototype.clearContinueAutomaticRoute = function (callback) { - core.deleteCanvas('route'); - core.status.automaticRoute.moveStepBeforeStop = []; - if (callback) callback(); -} + core.deleteCanvas("route"); + core.status.automaticRoute.moveStepBeforeStop = []; + if (callback) callback(); +}; ////// 设置自动寻路路线 ////// control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { - if (!core.status.played || core.status.lockControl) return; - if (this._setAutomaticRoute_isMoving(destX, destY)) return; - if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return; - if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return; - // 找寻自动寻路路线 - var moveStep = core.automaticRoute(destX, destY); - if (moveStep.length == 0 && (destX != core.status.hero.loc.x || destY != core.status.hero.loc.y || stepPostfix.length == 0)) - return; - moveStep = moveStep.concat(stepPostfix); - core.status.automaticRoute.destX = destX; - core.status.automaticRoute.destY = destY; - this._setAutomaticRoute_drawRoute(moveStep); - this._setAutomaticRoute_setAutoSteps(moveStep); - // 立刻移动 - core.setAutoHeroMove(); -} + if (!core.status.played || core.status.lockControl) return; + if (this._setAutomaticRoute_isMoving(destX, destY)) return; + if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return; + if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) + return; + // 找寻自动寻路路线 + var moveStep = core.automaticRoute(destX, destY); + if ( + moveStep.length == 0 && + (destX != core.status.hero.loc.x || + destY != core.status.hero.loc.y || + stepPostfix.length == 0) + ) + return; + moveStep = moveStep.concat(stepPostfix); + core.status.automaticRoute.destX = destX; + core.status.automaticRoute.destY = destY; + this._setAutomaticRoute_drawRoute(moveStep); + this._setAutomaticRoute_setAutoSteps(moveStep); + // 立刻移动 + core.setAutoHeroMove(); +}; control.prototype._setAutomaticRoute_isMoving = function (destX, destY) { - if (core.status.automaticRoute.autoHeroMove) { - var lastX = core.status.automaticRoute.destX, lastY = core.status.automaticRoute.destY; - core.stopAutomaticRoute(); - // 双击瞬移 - if (lastX == destX && lastY == destY) { - core.status.automaticRoute.moveDirectly = true; - setTimeout(function () { - if (core.status.automaticRoute.moveDirectly && core.status.heroMoving == 0) { - core.control.tryMoveDirectly(destX, destY); - } - core.status.automaticRoute.moveDirectly = false; - }, core.values.moveSpeed); + if (core.status.automaticRoute.autoHeroMove) { + var lastX = core.status.automaticRoute.destX, + lastY = core.status.automaticRoute.destY; + core.stopAutomaticRoute(); + // 双击瞬移 + if (lastX == destX && lastY == destY) { + core.status.automaticRoute.moveDirectly = true; + setTimeout(function () { + if ( + core.status.automaticRoute.moveDirectly && + core.status.heroMoving == 0 + ) { + core.control.tryMoveDirectly(destX, destY); } - return true; + core.status.automaticRoute.moveDirectly = false; + }, core.values.moveSpeed); } - return false; -} + return true; + } + return false; +}; -control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) { - if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length == 0) { - if (core.timeout.turnHeroTimeout == null) { - var routeLength = core.status.route.length; - core.timeout.turnHeroTimeout = setTimeout(function () { - if (core.status.route.length == routeLength) core.turnHero(); - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - }, 250); - } - else { - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - core.getNextItem(); - } - return true; +control.prototype._setAutomaticRoute_isTurning = function ( + destX, + destY, + stepPostfix +) { + if ( + destX == core.status.hero.loc.x && + destY == core.status.hero.loc.y && + stepPostfix.length == 0 + ) { + if (core.timeout.turnHeroTimeout == null) { + var routeLength = core.status.route.length; + core.timeout.turnHeroTimeout = setTimeout(function () { + if (core.status.route.length == routeLength) core.turnHero(); + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + }, 250); + } else { + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + core.getNextItem(); } - if (core.timeout.turnHeroTimeout != null) return true; - return false; -} + return true; + } + if (core.timeout.turnHeroTimeout != null) return true; + return false; +}; -control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) { - // 单击瞬间移动 - if (core.status.heroStop && core.status.heroMoving == 0) { - if (stepPostfix.length <= 1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY)) - return true; - } - return false; -} +control.prototype._setAutomaticRoute_clickMoveDirectly = function ( + destX, + destY, + stepPostfix +) { + // 单击瞬间移动 + if (core.status.heroStop && core.status.heroMoving == 0) { + if ( + stepPostfix.length <= 1 && + !core.hasFlag("__noClickMove__") && + core.control.tryMoveDirectly(destX, destY) + ) + return true; + } + return false; +}; control.prototype._setAutomaticRoute_drawRoute = function (moveStep) { - // 计算绘制区域的宽高,并尽可能小的创建route层 - var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0; - moveStep.forEach(function (t) { - sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32); - sy = Math.min(sy, t.y * 32); dy = Math.max(dy, t.y * 32); - }); - core.status.automaticRoute.offsetX = sx; - core.status.automaticRoute.offsetY = sy; - var ctx = core.createCanvas('route', sx - core.bigmap.offsetX, sy - core.bigmap.offsetY, dx - sx + 32, dy - sy + 32, 95); - ctx.fillStyle = '#bfbfbf'; - ctx.strokeStyle = '#bfbfbf'; - ctx.lineWidth = 8; - for (var m = 0; m < moveStep.length; m++) { - if (m == moveStep.length - 1) { - ctx.fillRect(moveStep[m].x * 32 + 10 - sx, moveStep[m].y * 32 + 10 - sy, 12, 12); - } - else { - ctx.beginPath(); - var cx = moveStep[m].x * 32 + 16 - sx, cy = moveStep[m].y * 32 + 16 - sy; - var currDir = moveStep[m].direction, nextDir = moveStep[m + 1].direction; - ctx.moveTo(cx - core.utils.scan[currDir].x * 11, cy - core.utils.scan[currDir].y * 11); - ctx.lineTo(cx, cy); - ctx.lineTo(cx + core.utils.scan[nextDir].x * 11, cy + core.utils.scan[nextDir].y * 11); - ctx.stroke(); - } + // 计算绘制区域的宽高,并尽可能小的创建route层 + var sx = core.bigmap.width * 32, + sy = core.bigmap.height * 32, + dx = 0, + dy = 0; + moveStep.forEach(function (t) { + sx = Math.min(sx, t.x * 32); + dx = Math.max(dx, t.x * 32); + sy = Math.min(sy, t.y * 32); + dy = Math.max(dy, t.y * 32); + }); + core.status.automaticRoute.offsetX = sx; + core.status.automaticRoute.offsetY = sy; + var ctx = core.createCanvas( + "route", + sx - core.bigmap.offsetX, + sy - core.bigmap.offsetY, + dx - sx + 32, + dy - sy + 32, + 95 + ); + ctx.fillStyle = "#bfbfbf"; + ctx.strokeStyle = "#bfbfbf"; + ctx.lineWidth = 8; + for (var m = 0; m < moveStep.length; m++) { + if (m == moveStep.length - 1) { + ctx.fillRect( + moveStep[m].x * 32 + 10 - sx, + moveStep[m].y * 32 + 10 - sy, + 12, + 12 + ); + } else { + ctx.beginPath(); + var cx = moveStep[m].x * 32 + 16 - sx, + cy = moveStep[m].y * 32 + 16 - sy; + var currDir = moveStep[m].direction, + nextDir = moveStep[m + 1].direction; + ctx.moveTo( + cx - core.utils.scan[currDir].x * 11, + cy - core.utils.scan[currDir].y * 11 + ); + ctx.lineTo(cx, cy); + ctx.lineTo( + cx + core.utils.scan[nextDir].x * 11, + cy + core.utils.scan[nextDir].y * 11 + ); + ctx.stroke(); } -} + } +}; control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) { - // 路线转autoStepRoutes - var step = 0, currStep = null; - moveStep.forEach(function (t) { - var dir = t.direction; - if (currStep == null || currStep == dir) - step++; - else { - core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step }); - step = 1; - } - currStep = dir; - }); - core.status.automaticRoute.autoStepRoutes.push({ 'direction': currStep, 'step': step }); -} + // 路线转autoStepRoutes + var step = 0, + currStep = null; + moveStep.forEach(function (t) { + var dir = t.direction; + if (currStep == null || currStep == dir) step++; + else { + core.status.automaticRoute.autoStepRoutes.push({ + direction: currStep, + step: step, + }); + step = 1; + } + currStep = dir; + }); + core.status.automaticRoute.autoStepRoutes.push({ + direction: currStep, + step: step, + }); +}; ////// 设置勇士的自动行走路线 ////// control.prototype.setAutoHeroMove = function (steps) { - steps = steps || core.status.automaticRoute.autoStepRoutes; - if (steps.length == 0) return; - core.status.automaticRoute.autoStepRoutes = steps; - core.status.automaticRoute.autoHeroMove = true; - core.status.automaticRoute.autoStep = 1; - core.status.automaticRoute.destStep = steps[0].step; - core.moveHero(steps[0].direction); -} + steps = steps || core.status.automaticRoute.autoStepRoutes; + if (steps.length == 0) return; + core.status.automaticRoute.autoStepRoutes = steps; + core.status.automaticRoute.autoHeroMove = true; + core.status.automaticRoute.autoStep = 1; + core.status.automaticRoute.destStep = steps[0].step; + core.moveHero(steps[0].direction); +}; ////// 设置行走的效果动画 ////// control.prototype.setHeroMoveInterval = function (callback) { - if (core.status.heroMoving > 0) return; - if (core.status.replay.speed == 24) { - if (callback) callback(); - return; + if (core.status.heroMoving > 0) return; + if (core.status.replay.speed == 24) { + if (callback) callback(); + return; + } + + core.status.heroMoving = 1; + + var toAdd = 1; + if (core.status.replay.speed > 3) toAdd = 2; + if (core.status.replay.speed > 6) toAdd = 4; + if (core.status.replay.speed > 12) toAdd = 8; + + core.interval.heroMoveInterval = window.setInterval(function () { + core.status.heroMoving += toAdd; + if (core.status.heroMoving >= 8) { + clearInterval(core.interval.heroMoveInterval); + core.status.heroMoving = 0; + if (callback) callback(); } - - core.status.heroMoving = 1; - - var toAdd = 1; - if (core.status.replay.speed > 3) toAdd = 2; - if (core.status.replay.speed > 6) toAdd = 4; - if (core.status.replay.speed > 12) toAdd = 8; - - core.interval.heroMoveInterval = window.setInterval(function () { - core.status.heroMoving += toAdd; - if (core.status.heroMoving >= 8) { - clearInterval(core.interval.heroMoveInterval); - core.status.heroMoving = 0; - if (callback) callback(); - } - }, core.values.moveSpeed / 8 * toAdd / core.status.replay.speed); -} + }, ((core.values.moveSpeed / 8) * toAdd) / core.status.replay.speed); +}; ////// 每移动一格后执行的事件 ////// control.prototype.moveOneStep = function (callback) { - return this.controldata.moveOneStep(callback); -} + return this.controldata.moveOneStep(callback); +}; ////// 实际每一步的行走过程 ////// control.prototype.moveAction = function (callback) { - if (core.status.heroMoving > 0) return; - var noPass = core.noPass(core.nextX(), core.nextY()), canMove = core.canMoveHero(); - // 下一个点如果不能走 - if (noPass || !canMove) return this._moveAction_noPass(canMove, callback); - this._moveAction_moving(callback); -} + if (core.status.heroMoving > 0) return; + var noPass = core.noPass(core.nextX(), core.nextY()), + canMove = core.canMoveHero(); + // 下一个点如果不能走 + if (noPass || !canMove) return this._moveAction_noPass(canMove, callback); + this._moveAction_moving(callback); +}; control.prototype._moveAction_noPass = function (canMove, callback) { - core.status.route.push(core.getHeroLoc('direction')); - core.status.automaticRoute.moveStepBeforeStop = []; - core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); - if (canMove) core.trigger(core.nextX(), core.nextY()); - core.drawHero(); + core.status.route.push(core.getHeroLoc("direction")); + core.status.automaticRoute.moveStepBeforeStop = []; + core.status.automaticRoute.lastDirection = core.getHeroLoc("direction"); + if (canMove) core.trigger(core.nextX(), core.nextY()); + core.drawHero(); - if (core.status.automaticRoute.moveStepBeforeStop.length == 0) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - if (callback) callback(); -} + if (core.status.automaticRoute.moveStepBeforeStop.length == 0) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + if (callback) callback(); +}; control.prototype._moveAction_moving = function (callback) { - core.setHeroMoveInterval(function () { - core.setHeroLoc('x', core.nextX(), true); - core.setHeroLoc('y', core.nextY(), true); + core.setHeroMoveInterval(function () { + core.setHeroLoc("x", core.nextX(), true); + core.setHeroLoc("y", core.nextY(), true); - var direction = core.getHeroLoc('direction'); - core.control._moveAction_popAutomaticRoute(); - core.status.route.push(direction); + var direction = core.getHeroLoc("direction"); + core.control._moveAction_popAutomaticRoute(); + core.status.route.push(direction); - core.moveOneStep(); - core.checkRouteFolding(); - if (callback) callback(); - }); -} + core.moveOneStep(); + core.checkRouteFolding(); + if (callback) callback(); + }); +}; control.prototype._moveAction_popAutomaticRoute = function () { - var automaticRoute = core.status.automaticRoute; - // 检查自动寻路是否被弹出 - if (automaticRoute.autoHeroMove) { - automaticRoute.movedStep++; - automaticRoute.lastDirection = core.getHeroLoc('direction'); - if (automaticRoute.destStep == automaticRoute.movedStep) { - if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - else { - automaticRoute.movedStep = 0; - automaticRoute.destStep = automaticRoute.autoStepRoutes[automaticRoute.autoStep].step; - core.setHeroLoc('direction', automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction); - core.status.automaticRoute.autoStep++; - } - } + var automaticRoute = core.status.automaticRoute; + // 检查自动寻路是否被弹出 + if (automaticRoute.autoHeroMove) { + automaticRoute.movedStep++; + automaticRoute.lastDirection = core.getHeroLoc("direction"); + if (automaticRoute.destStep == automaticRoute.movedStep) { + if (automaticRoute.autoStep == automaticRoute.autoStepRoutes.length) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } else { + automaticRoute.movedStep = 0; + automaticRoute.destStep = + automaticRoute.autoStepRoutes[automaticRoute.autoStep].step; + core.setHeroLoc( + "direction", + automaticRoute.autoStepRoutes[automaticRoute.autoStep].direction + ); + core.status.automaticRoute.autoStep++; + } } -} + } +}; ////// 让勇士开始移动 ////// control.prototype.moveHero = function (direction, callback) { - // 如果正在移动,直接return - if (core.status.heroMoving != 0) return; - if (core.isset(direction)) - core.setHeroLoc('direction', direction); + // 如果正在移动,直接return + if (core.status.heroMoving != 0) return; + if (core.isset(direction)) core.setHeroLoc("direction", direction); - if (callback) return this.moveAction(callback); - this._moveHero_moving(); -} + if (callback) return this.moveAction(callback); + this._moveHero_moving(); +}; control.prototype._moveHero_moving = function () { - // ------ 我已经看不懂这个函数了,反正好用就行23333333 - core.status.heroStop = false; - core.status.automaticRoute.moveDirectly = false; - var move = function () { - if (!core.status.heroStop) { - if (core.hasFlag('debug') && core.status.ctrlDown) { - if (core.status.heroMoving != 0) return; - // 检测是否穿出去 - var nx = core.nextX(), ny = core.nextY(); - if (nx < 0 || nx >= core.bigmap.width || ny < 0 || ny >= core.bigmap.height) return; - core.eventMoveHero([core.getHeroLoc('direction')], core.values.moveSpeed, move); - } - else { - core.moveAction(); - setTimeout(move, 50); - } - } + // ------ 我已经看不懂这个函数了,反正好用就行23333333 + core.status.heroStop = false; + core.status.automaticRoute.moveDirectly = false; + var move = function () { + if (!core.status.heroStop) { + if (core.hasFlag("debug") && core.status.ctrlDown) { + if (core.status.heroMoving != 0) return; + // 检测是否穿出去 + var nx = core.nextX(), + ny = core.nextY(); + if ( + nx < 0 || + nx >= core.bigmap.width || + ny < 0 || + ny >= core.bigmap.height + ) + return; + core.eventMoveHero( + [core.getHeroLoc("direction")], + core.values.moveSpeed, + move + ); + } else { + core.moveAction(); + setTimeout(move, 50); + } } - move(); -} + }; + move(); +}; ////// 当前是否正在移动 ////// control.prototype.isMoving = function () { - return !core.status.heroStop || core.status.heroMoving > 0; -} + return !core.status.heroStop || core.status.heroMoving > 0; +}; ////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback ////// control.prototype.waitHeroToStop = function (callback) { - var lastDirection = core.status.automaticRoute.lastDirection; - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - if (callback) { - core.status.replay.animate = true; - core.lockControl(); - core.status.automaticRoute.moveDirectly = false; - setTimeout(function () { - core.status.replay.animate = false; - if (core.isset(lastDirection)) - core.setHeroLoc('direction', lastDirection); - core.drawHero(); - callback(); - }, core.status.replay.speed == 24 ? 1 : 30); - } -} + var lastDirection = core.status.automaticRoute.lastDirection; + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + if (callback) { + core.status.replay.animate = true; + core.lockControl(); + core.status.automaticRoute.moveDirectly = false; + setTimeout( + function () { + core.status.replay.animate = false; + if (core.isset(lastDirection)) + core.setHeroLoc("direction", lastDirection); + core.drawHero(); + callback(); + }, + core.status.replay.speed == 24 ? 1 : 30 + ); + } +}; ////// 转向 ////// control.prototype.turnHero = function (direction) { - if (direction) { - core.setHeroLoc('direction', direction); - core.drawHero(); - core.status.route.push("turn:" + direction); - return; - } - core.setHeroLoc('direction', core.turnDirection(':right')); + if (direction) { + core.setHeroLoc("direction", direction); core.drawHero(); - core.status.route.push("turn"); - core.checkRouteFolding(); -} + core.status.route.push("turn:" + direction); + return; + } + core.setHeroLoc("direction", core.turnDirection(":right")); + core.drawHero(); + core.status.route.push("turn"); + core.checkRouteFolding(); +}; ////// 瞬间移动 ////// control.prototype.moveDirectly = function (destX, destY, ignoreSteps) { - return this.controldata.moveDirectly(destX, destY, ignoreSteps); -} + return this.controldata.moveDirectly(destX, destY, ignoreSteps); +}; ////// 尝试瞬间移动 ////// control.prototype.tryMoveDirectly = function (destX, destY) { - if (this.nearHero(destX, destY)) return false; - var canMoveArray = core.maps.generateMovableArray(); - var dirs = [[destX, destY], [destX - 1, destY, "right"], [destX, destY - 1, "down"], [destX, destY + 1, "up"], [destX + 1, destY, "left"]]; - var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray); + if (this.nearHero(destX, destY)) return false; + var canMoveArray = core.maps.generateMovableArray(); + var dirs = [ + [destX, destY], + [destX - 1, destY, "right"], + [destX, destY - 1, "down"], + [destX, destY + 1, "up"], + [destX + 1, destY, "left"], + ]; + var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray); - for (var i = 0; i < dirs.length; ++i) { - var d = dirs[i], dx = d[0], dy = d[1], dir = d[2]; - if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) continue; - if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue; - if (canMoveDirectlyArray[i] < 0) continue; - if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) { - if (dir) core.moveHero(dir, function () { }); - return true; - } + for (var i = 0; i < dirs.length; ++i) { + var d = dirs[i], + dx = d[0], + dy = d[1], + dir = d[2]; + if (dx < 0 || dx >= core.bigmap.width || dy < 0 || dy >= core.bigmap.height) + continue; + if (dir && !core.inArray(canMoveArray[dx][dy], dir)) continue; + if (canMoveDirectlyArray[i] < 0) continue; + if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) { + if (dir) core.moveHero(dir, function () {}); + return true; } - return false; -} + } + return false; +}; ////// 绘制勇士 ////// control.prototype.drawHero = function (status, offset, frame) { - if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); - status = status || 'stop'; - if (!offset) offset = 0; + if (!core.isPlaying() || !core.status.floorId || core.status.gameOver) return; + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + direction = core.getHeroLoc("direction"); + status = status || "stop"; + if (!offset) offset = 0; - var way = core.utils.scan2[direction]; - var dx = way.x, dy = way.y; - var offsetX = typeof offset == 'number' ? dx * offset : (offset.x || 0); - var offsetY = typeof offset == 'number' ? dy * offset : (offset.y || 0); - offset = { x: offsetX, y: offsetY, offset: offset }; + var way = core.utils.scan2[direction]; + var dx = way.x, + dy = way.y; + var offsetX = typeof offset == "number" ? dx * offset : offset.x || 0; + var offsetY = typeof offset == "number" ? dy * offset : offset.y || 0; + offset = { x: offsetX, y: offsetY, offset: offset }; - core.clearAutomaticRouteNode(x + dx, y + dy); - core.clearMap('hero'); - core.status.heroCenter.px = 32 * x + offsetX + 16; - core.status.heroCenter.py = 32 * y + offsetY + 32 - core.material.icons.hero.height / 2; + core.clearAutomaticRouteNode(x + dx, y + dy); + core.clearMap("hero"); + core.status.heroCenter.px = 32 * x + offsetX + 16; + core.status.heroCenter.py = + 32 * y + offsetY + 32 - core.material.icons.hero.height / 2; - // 重置hero层画布 - core.setGameCanvasTranslate('hero', 0, 0); - delete core.canvas.hero._px; - delete core.canvas.hero._py; - core.status.preview.enabled = false; - if (!core.hasFlag('__lockViewport__')) { - this._drawHero_updateViewport(x, y, offset); - } + // 重置hero层画布 + core.setGameCanvasTranslate("hero", 0, 0); + delete core.canvas.hero._px; + delete core.canvas.hero._py; + core.status.preview.enabled = false; + if (!core.hasFlag("__lockViewport__")) { + this._drawHero_updateViewport(x, y, offset); + } - this._drawHero_draw(direction, x, y, status, offset, frame); -} + this._drawHero_draw(direction, x, y, status, offset, frame); +}; control.prototype._drawHero_updateViewport = function (x, y, offset) { - core.bigmap.offsetX = core.clamp((x - core._HALF_WIDTH_) * 32 + offset.x, 0, Math.max(32 * core.bigmap.width - core._PX_, 0)); - core.bigmap.offsetY = core.clamp((y - core._HALF_HEIGHT_) * 32 + offset.y, 0, Math.max(32 * core.bigmap.height - core._PY_, 0)); - core.control.updateViewport(); -} + core.bigmap.offsetX = core.clamp( + (x - core._HALF_WIDTH_) * 32 + offset.x, + 0, + Math.max(32 * core.bigmap.width - core._PX_, 0) + ); + core.bigmap.offsetY = core.clamp( + (y - core._HALF_HEIGHT_) * 32 + offset.y, + 0, + Math.max(32 * core.bigmap.height - core._PY_, 0) + ); + core.control.updateViewport(); +}; -control.prototype._drawHero_draw = function (direction, x, y, status, offset, frame) { - offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 }; - var opacity = core.setAlpha('hero', core.getFlag('__heroOpacity__', 1)) - this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function (block) { - core.drawImage('hero', block.img, (block.heroIcon[block.status] + (frame || 0)) % 4 * block.width, - block.heroIcon.loc * block.height, block.width, block.height, - block.posx + (32 - block.width) / 2, block.posy + 32 - block.height, block.width, block.height); - }); - core.setAlpha('hero', opacity); -} +control.prototype._drawHero_draw = function ( + direction, + x, + y, + status, + offset, + frame +) { + offset = offset || { x: 0, y: 0, offset: 0, px: 0, py: 0 }; + var opacity = core.setAlpha("hero", core.getFlag("__heroOpacity__", 1)); + this._drawHero_getDrawObjs(direction, x, y, status, offset).forEach(function ( + block + ) { + core.drawImage( + "hero", + block.img, + ((block.heroIcon[block.status] + (frame || 0)) % 4) * block.width, + block.heroIcon.loc * block.height, + block.width, + block.height, + block.posx + (32 - block.width) / 2, + block.posy + 32 - block.height, + block.width, + block.height + ); + }); + core.setAlpha("hero", opacity); +}; -control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) { - var heroIconArr = core.material.icons.hero, drawObjs = [], index = 0; - drawObjs.push({ - "img": core.material.images.hero, - "width": core.material.icons.hero.width || 32, - "height": core.material.icons.hero.height, - "heroIcon": heroIconArr[direction], - "posx": x * 32 - core.bigmap.offsetX + offset.x, - "posy": y * 32 - core.bigmap.offsetY + offset.y, - "status": status, - "index": index++, +control.prototype._drawHero_getDrawObjs = function ( + direction, + x, + y, + status, + offset +) { + var heroIconArr = core.material.icons.hero, + drawObjs = [], + index = 0; + drawObjs.push({ + img: core.material.images.hero, + width: core.material.icons.hero.width || 32, + height: core.material.icons.hero.height, + heroIcon: heroIconArr[direction], + posx: x * 32 - core.bigmap.offsetX + offset.x, + posy: y * 32 - core.bigmap.offsetY + offset.y, + status: status, + index: index++, + }); + if (typeof offset.offset == "number") { + core.status.hero.followers.forEach(function (t) { + drawObjs.push({ + img: core.material.images.images[t.name], + width: core.material.images.images[t.name].width / 4, + height: core.material.images.images[t.name].height / 4, + heroIcon: heroIconArr[t.direction], + posx: + 32 * t.x - + core.bigmap.offsetX + + (t.stop + ? 0 + : core.utils.scan2[t.direction].x * Math.abs(offset.offset)), + posy: + 32 * t.y - + core.bigmap.offsetY + + (t.stop + ? 0 + : core.utils.scan2[t.direction].y * Math.abs(offset.offset)), + status: t.stop ? "stop" : status, + index: index++, + }); }); - if (typeof offset.offset == 'number') { - core.status.hero.followers.forEach(function (t) { - drawObjs.push({ - "img": core.material.images.images[t.name], - "width": core.material.images.images[t.name].width / 4, - "height": core.material.images.images[t.name].height / 4, - "heroIcon": heroIconArr[t.direction], - "posx": 32 * t.x - core.bigmap.offsetX + (t.stop ? 0 : core.utils.scan2[t.direction].x * Math.abs(offset.offset)), - "posy": 32 * t.y - core.bigmap.offsetY + (t.stop ? 0 : core.utils.scan2[t.direction].y * Math.abs(offset.offset)), - "status": t.stop ? "stop" : status, - "index": index++ - }); - }); + } + return drawObjs.sort(function (a, b) { + return a.posy == b.posy ? b.index - a.index : a.posy - b.posy; + }); +}; + +control.prototype.setHeroOpacity = function ( + opacity, + moveMode, + time, + callback +) { + time = time || 0; + if (time == 0) { + core.setFlag("__heroOpacity__", opacity); + core.drawHero(); + if (callback) callback(); + return; + } + time /= Math.max(core.status.replay.speed, 1); + + var fromOpacity = core.getFlag("__heroOpacity__", 1); + var step = 0, + steps = parseInt(time / 10); + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(moveMode); + + var animate = setInterval(function () { + step++; + core.setFlag( + "__heroOpacity__", + fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps) + ); + core.drawHero(); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } - return drawObjs.sort(function (a, b) { - return a.posy == b.posy ? b.index - a.index : a.posy - b.posy; - }); -} + }, 10); -control.prototype.setHeroOpacity = function (opacity, moveMode, time, callback) { - time = time || 0; - if (time == 0) { - core.setFlag('__heroOpacity__', opacity); - core.drawHero(); - if (callback) callback(); - return; - } - time /= Math.max(core.status.replay.speed, 1) - - var fromOpacity = core.getFlag('__heroOpacity__', 1); - var step = 0, steps = parseInt(time / 10); - if (steps <= 0) steps = 1; - var moveFunc = core.applyEasing(moveMode); - - var animate = setInterval(function () { - step++; - core.setFlag('__heroOpacity__', fromOpacity + (opacity - fromOpacity) * moveFunc(step / steps)); - core.drawHero(); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 10); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; // ------ 画布、位置、阻激夹域,显伤 ------ // ////// 设置画布偏移 control.prototype.setGameCanvasTranslate = function (canvas, x, y) { - 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)'; - c.style.webkitTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - c.style.OTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - c.style.MozTransform = 'translate(' + (x / core._PX_ * 96) + 'vw,' + (y / core._PY_ * 96) + 'vw)'; - } + 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)"; + c.style.webkitTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + c.style.OTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + c.style.MozTransform = + "translate(" + + (x / core._PX_) * 96 + + "vw," + + (y / core._PY_) * 96 + + "vw)"; + } }; ////// 加减画布偏移 control.prototype.addGameCanvasTranslate = function (x, y) { - for (var ii = 0, canvas; canvas = core.dom.gameCanvas[ii]; ii++) { - var id = canvas.getAttribute('id'); - if (id == 'ui' || id == 'data') continue; // UI层和data层不移动 - var offsetX = x, offsetY = y; - if (core.bigmap.canvas.indexOf(id) >= 0) { - if (core.bigmap.v2) { - offsetX -= (core.bigmap.offsetX - 32 * core.bigmap.posX) + 32; - offsetY -= (core.bigmap.offsetY - 32 * core.bigmap.posY) + 32; - } else { - offsetX -= core.bigmap.offsetX; - offsetY -= core.bigmap.offsetY; - } - } - core.control.setGameCanvasTranslate(id, offsetX, offsetY); + for (var ii = 0, canvas; (canvas = core.dom.gameCanvas[ii]); ii++) { + var id = canvas.getAttribute("id"); + if (id == "ui" || id == "data") continue; // UI层和data层不移动 + var offsetX = x, + offsetY = y; + if (core.bigmap.canvas.indexOf(id) >= 0) { + if (core.bigmap.v2) { + offsetX -= core.bigmap.offsetX - 32 * core.bigmap.posX + 32; + offsetY -= core.bigmap.offsetY - 32 * core.bigmap.posY + 32; + } else { + offsetX -= core.bigmap.offsetX; + offsetY -= core.bigmap.offsetY; + } } -} + core.control.setGameCanvasTranslate(id, offsetX, offsetY); + } +}; ////// 更新视野范围 ////// control.prototype.updateViewport = function () { - // 当前是否应该重绘? - if (core.bigmap.v2) { - if (core.bigmap.offsetX >= core.bigmap.posX * 32 + 32 - || core.bigmap.offsetX <= core.bigmap.posX * 32 - 32 - || core.bigmap.offsetY >= core.bigmap.posY * 32 + 32 - || core.bigmap.offsetY <= core.bigmap.posY * 32 - 32) { - core.bigmap.posX = parseInt(core.bigmap.offsetX / 32); - core.bigmap.posY = parseInt(core.bigmap.offsetY / 32); - core.redrawMap(); - } - } else { - core.bigmap.posX = core.bigmap.posY = 0; + // 当前是否应该重绘? + if (core.bigmap.v2) { + if ( + core.bigmap.offsetX >= core.bigmap.posX * 32 + 32 || + core.bigmap.offsetX <= core.bigmap.posX * 32 - 32 || + core.bigmap.offsetY >= core.bigmap.posY * 32 + 32 || + core.bigmap.offsetY <= core.bigmap.posY * 32 - 32 + ) { + core.bigmap.posX = parseInt(core.bigmap.offsetX / 32); + core.bigmap.posY = parseInt(core.bigmap.offsetY / 32); + core.redrawMap(); } - var offsetX = core.bigmap.v2 ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 : -core.bigmap.offsetX; - var offsetY = core.bigmap.v2 ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 : -core.bigmap.offsetY; + } else { + core.bigmap.posX = core.bigmap.posY = 0; + } + var offsetX = core.bigmap.v2 + ? -(core.bigmap.offsetX - 32 * core.bigmap.posX) - 32 + : -core.bigmap.offsetX; + var offsetY = core.bigmap.v2 + ? -(core.bigmap.offsetY - 32 * core.bigmap.posY) - 32 + : -core.bigmap.offsetY; - core.bigmap.canvas.forEach(function (cn) { - core.control.setGameCanvasTranslate(cn, offsetX, offsetY); - }); - // ------ 路线 - core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY); - // ------ 所有的大怪物也都需要重定位 - for (var one in core.dymCanvas) { - if (one.startsWith('_bigImage_')) { - var ox = core.dymCanvas[one].canvas.getAttribute('_ox'); - var oy = core.dymCanvas[one].canvas.getAttribute('_oy'); - if (ox != null && oy != null) { - core.relocateCanvas(one, parseInt(ox) - core.bigmap.offsetX, parseInt(oy) - core.bigmap.offsetY); - } - } + core.bigmap.canvas.forEach(function (cn) { + core.control.setGameCanvasTranslate(cn, offsetX, offsetY); + }); + // ------ 路线 + core.relocateCanvas( + "route", + core.status.automaticRoute.offsetX - core.bigmap.offsetX, + core.status.automaticRoute.offsetY - core.bigmap.offsetY + ); + // ------ 所有的大怪物也都需要重定位 + for (var one in core.dymCanvas) { + if (one.startsWith("_bigImage_")) { + var ox = core.dymCanvas[one].canvas.getAttribute("_ox"); + var oy = core.dymCanvas[one].canvas.getAttribute("_oy"); + if (ox != null && oy != null) { + core.relocateCanvas( + one, + parseInt(ox) - core.bigmap.offsetX, + parseInt(oy) - core.bigmap.offsetY + ); + } } - -} + } +}; ////// 设置视野范围 ////// control.prototype.setViewport = function (px, py) { - var originOffsetX = core.bigmap.offsetX, originOffsetY = core.bigmap.offsetY; - core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core._PX_); - core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core._PY_); - this.updateViewport(); - // ------ hero层也需要! - var px = parseFloat(core.canvas.hero._px) || 0; - var py = parseFloat(core.canvas.hero._py) || 0; - px += originOffsetX - core.bigmap.offsetX; - py += originOffsetY - core.bigmap.offsetY; - core.control.setGameCanvasTranslate('hero', px, py); - core.canvas.hero._px = px; - core.canvas.hero._py = py; -} + var originOffsetX = core.bigmap.offsetX, + originOffsetY = core.bigmap.offsetY; + core.bigmap.offsetX = core.clamp(px, 0, 32 * core.bigmap.width - core._PX_); + core.bigmap.offsetY = core.clamp(py, 0, 32 * core.bigmap.height - core._PY_); + this.updateViewport(); + // ------ hero层也需要! + var px = parseFloat(core.canvas.hero._px) || 0; + var py = parseFloat(core.canvas.hero._py) || 0; + px += originOffsetX - core.bigmap.offsetX; + py += originOffsetY - core.bigmap.offsetY; + core.control.setGameCanvasTranslate("hero", px, py); + core.canvas.hero._px = px; + core.canvas.hero._py = py; +}; ////// 移动视野范围 ////// control.prototype.moveViewport = function (x, y, moveMode, time, callback) { - time = time || 0; - time /= Math.max(core.status.replay.speed, 1) - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) { - this.setViewport(32 * x, 32 * y); - if (callback) callback(); - return; + time = time || 0; + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) { + this.setViewport(32 * x, 32 * y); + if (callback) callback(); + return; + } + var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core._PX_); + var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core._PY_); + var cx = core.bigmap.offsetX; + var cy = core.bigmap.offsetY; + var moveFunc = core.applyEasing(moveMode); + + var animate = window.setInterval(function () { + step++; + core.setViewport( + cx + moveFunc(step / steps) * (px - cx), + cy + moveFunc(step / steps) * (py - cy) + ); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + core.setViewport(px, py); + if (callback) callback(); } - var px = core.clamp(32 * x, 0, 32 * core.bigmap.width - core._PX_); - var py = core.clamp(32 * y, 0, 32 * core.bigmap.height - core._PY_); - var cx = core.bigmap.offsetX; - var cy = core.bigmap.offsetY; - var moveFunc = core.applyEasing(moveMode); + }, per_time); - var animate = window.setInterval(function () { - step++; - core.setViewport(cx + moveFunc(step / steps) * (px - cx), cy + moveFunc(step / steps) * (py - cy)); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - core.setViewport(px, py); - if (callback) callback(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 获得勇士面对位置的x坐标 ////// control.prototype.nextX = function (n) { - if (n == null) n = 1; - return core.getHeroLoc('x') + core.utils.scan[core.getHeroLoc('direction')].x * n; -} + if (n == null) n = 1; + return ( + core.getHeroLoc("x") + core.utils.scan[core.getHeroLoc("direction")].x * n + ); +}; ////// 获得勇士面对位置的y坐标 ////// control.prototype.nextY = function (n) { - if (n == null) n = 1; - return core.getHeroLoc('y') + core.utils.scan[core.getHeroLoc('direction')].y * n; -} + if (n == null) n = 1; + return ( + core.getHeroLoc("y") + core.utils.scan[core.getHeroLoc("direction")].y * n + ); +}; ////// 某个点是否在勇士旁边 ////// control.prototype.nearHero = function (x, y, n) { - if (n == null) n = 1; - return Math.abs(x - core.getHeroLoc('x')) + Math.abs(y - core.getHeroLoc('y')) <= n; -} + if (n == null) n = 1; + return ( + Math.abs(x - core.getHeroLoc("x")) + Math.abs(y - core.getHeroLoc("y")) <= n + ); +}; ////// 聚集跟随者 ////// control.prototype.gatherFollowers = function () { - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), dir = core.getHeroLoc('direction'); - core.status.hero.followers.forEach(function (t) { - t.x = x; - t.y = y; - t.stop = true; - t.direction = dir; - }); -} + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + dir = core.getHeroLoc("direction"); + core.status.hero.followers.forEach(function (t) { + t.x = x; + t.y = y; + t.stop = true; + t.direction = dir; + }); +}; ////// 更新跟随者坐标 ////// control.prototype.updateFollowers = function () { - core.status.hero.followers.forEach(function (t) { - if (!t.stop) { - t.x += core.utils.scan2[t.direction].x; - t.y += core.utils.scan2[t.direction].y; - } - }) + core.status.hero.followers.forEach(function (t) { + if (!t.stop) { + t.x += core.utils.scan2[t.direction].x; + t.y += core.utils.scan2[t.direction].y; + } + }); - var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y'); - core.status.hero.followers.forEach(function (t) { - t.stop = true; - var dx = nowx - t.x, dy = nowy - t.y; - for (var dir in core.utils.scan2) { - if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { - t.stop = false; - t.direction = dir; - } - } - nowx = t.x; nowy = t.y; - }) -} + var nowx = core.getHeroLoc("x"), + nowy = core.getHeroLoc("y"); + core.status.hero.followers.forEach(function (t) { + t.stop = true; + var dx = nowx - t.x, + dy = nowy - t.y; + for (var dir in core.utils.scan2) { + if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { + t.stop = false; + t.direction = dir; + } + } + nowx = t.x; + nowy = t.y; + }); +}; ////// 瞬移更新跟随者坐标 ////// control.prototype._moveDirectyFollowers = function (x, y) { - var route = core.automaticRoute(x, y); - if (route.length == 0) route = [{ x: x, y: y, direction: core.getHeroLoc('direction') }]; + var route = core.automaticRoute(x, y); + if (route.length == 0) + route = [{ x: x, y: y, direction: core.getHeroLoc("direction") }]; - var nowx = x, nowy = y; - for (var i = 0; i < core.status.hero.followers.length; ++i) { - var t = core.status.hero.followers[i]; - var index = route.length - i - 2; - if (index < 0) index = 0; - t.stop = true; - t.x = route[index].x; - t.y = route[index].y; - t.direction = route[index].direction; - var dx = nowx - t.x, dy = nowy - t.y; - for (var dir in core.utils.scan2) { - if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { - t.stop = false; - t.direction = dir; - } - } - nowx = t.x; nowy = t.y; + var nowx = x, + nowy = y; + for (var i = 0; i < core.status.hero.followers.length; ++i) { + var t = core.status.hero.followers[i]; + var index = route.length - i - 2; + if (index < 0) index = 0; + t.stop = true; + t.x = route[index].x; + t.y = route[index].y; + t.direction = route[index].direction; + var dx = nowx - t.x, + dy = nowy - t.y; + for (var dir in core.utils.scan2) { + if (core.utils.scan2[dir].x == dx && core.utils.scan2[dir].y == dy) { + t.stop = false; + t.direction = dir; + } } -} + nowx = t.x; + nowy = t.y; + } +}; ////// 更新领域、夹击、阻击的伤害地图 ////// control.prototype.updateCheckBlock = function (floorId) { - return this.controldata.updateCheckBlock(floorId); -} + return this.controldata.updateCheckBlock(floorId); +}; ////// 检查并执行领域、夹击、阻击事件 ////// control.prototype.checkBlock = function () { - var x = core.getHeroLoc('x'), y = core.getHeroLoc('y'), loc = x + "," + y; - var damage = core.status.checkBlock.damage[loc]; - if (damage) { - core.status.hero.hp -= damage; - var text = (Object.keys(core.status.checkBlock.type[loc] || {}).join(",")) || "伤害"; - core.drawTip("受到" + text + damage + "点"); - core.drawHeroAnimate("zone"); - this._checkBlock_disableQuickShop(); - core.status.hero.statistics.extraDamage += damage; - if (core.status.hero.hp <= 0) { - core.status.hero.hp = 0; - core.updateStatusBar(false, true); - core.events.lose(); - return; - } else { - core.updateStatusBar(false, true); - } + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"), + loc = x + "," + y; + var damage = core.status.checkBlock.damage[loc]; + if (damage) { + core.status.hero.hp -= damage; + var text = + Object.keys(core.status.checkBlock.type[loc] || {}).join(",") || "伤害"; + core.drawTip("受到" + text + damage + "点"); + core.drawHeroAnimate("zone"); + this._checkBlock_disableQuickShop(); + core.status.hero.statistics.extraDamage += damage; + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(false, true); + core.events.lose(); + return; + } else { + core.updateStatusBar(false, true); } - this._checkBlock_ambush(core.status.checkBlock.ambush[loc]); - this._checkBlock_repulse(core.status.checkBlock.repulse[loc]); -} + } + this._checkBlock_ambush(core.status.checkBlock.ambush[loc]); + this._checkBlock_repulse(core.status.checkBlock.repulse[loc]); +}; control.prototype._checkBlock_disableQuickShop = function () { - // 禁用快捷商店 - if (core.flags.disableShopOnDamage) { - Object.keys(core.status.shops).forEach(function (shopId) { - core.setShopVisited(shopId, false); - }); - } -} + // 禁用快捷商店 + if (core.flags.disableShopOnDamage) { + Object.keys(core.status.shops).forEach(function (shopId) { + core.setShopVisited(shopId, false); + }); + } +}; ////// 阻击 ////// control.prototype._checkBlock_repulse = function (repulse) { - if (!repulse || repulse.length == 0) return; - var actions = []; - repulse.forEach(function (t) { - actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 250, "keep": true, "async": true }); + if (!repulse || repulse.length == 0) return; + var actions = []; + repulse.forEach(function (t) { + actions.push({ + type: "move", + loc: [t[0], t[1]], + steps: [t[3]], + time: 250, + keep: true, + async: true, }); - actions.push({ "type": "waitAsync" }); - core.insertAction(actions); -} + }); + actions.push({ type: "waitAsync" }); + core.insertAction(actions); +}; ////// 捕捉 ////// control.prototype._checkBlock_ambush = function (ambush) { - if (!ambush || ambush.length == 0) return; - // 捕捉效果 - var actions = []; - ambush.forEach(function (t) { - actions.push({ "type": "move", "loc": [t[0], t[1]], "steps": [t[3]], "time": 250, "keep": false, "async": true }); + if (!ambush || ambush.length == 0) return; + // 捕捉效果 + var actions = []; + ambush.forEach(function (t) { + actions.push({ + type: "move", + loc: [t[0], t[1]], + steps: [t[3]], + time: 250, + keep: false, + async: true, }); - actions.push({ "type": "waitAsync" }); - // 强制战斗 - ambush.forEach(function (t) { - actions.push({ - "type": "function", "function": "function() { " + - "core.battle('" + t[2] + "', " + t[0] + "," + t[1] + ", true, core.doAction); " + - "}", "async": true - }); + }); + actions.push({ type: "waitAsync" }); + // 强制战斗 + ambush.forEach(function (t) { + actions.push({ + type: "function", + function: + "function() { " + + "core.battle('" + + t[2] + + "', " + + t[0] + + "," + + t[1] + + ", true, core.doAction); " + + "}", + async: true, }); - core.insertAction(actions); -} + }); + core.insertAction(actions); +}; ////// 更新全地图显伤 ////// control.prototype.updateDamage = function (floorId, ctx) { - floorId = floorId || core.status.floorId; - if (!floorId || core.status.gameOver || main.mode != 'play') return; - var onMap = ctx == null; + floorId = floorId || core.status.floorId; + if (!floorId || core.status.gameOver || main.mode != "play") return; + var onMap = ctx == null; - // 没有怪物手册 - if (!core.hasItem('book')) return; - core.status.damage.posX = core.bigmap.posX; - core.status.damage.posY = core.bigmap.posY; - if (!onMap) { - var width = core.floors[floorId].width, height = core.floors[floorId].height; - // 地图过大的缩略图不绘制显伤 - if (width * height > core.bigmap.threshold) return; - } - this._updateDamage_damage(floorId, onMap); - this._updateDamage_extraDamage(floorId, onMap); - this.drawDamage(ctx); -} + // 没有怪物手册 + if (!core.hasItem("book")) return; + core.status.damage.posX = core.bigmap.posX; + core.status.damage.posY = core.bigmap.posY; + if (!onMap) { + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + // 地图过大的缩略图不绘制显伤 + if (width * height > core.bigmap.threshold) return; + } + this._updateDamage_damage(floorId, onMap); + this._updateDamage_extraDamage(floorId, onMap); + this.drawDamage(ctx); +}; control.prototype._updateDamage_damage = function (floorId, onMap) { - core.status.damage.data = []; - if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return; + core.status.damage.data = []; + if (!core.flags.displayEnemyDamage && !core.flags.displayExtraDamage) return; - core.extractBlocks(floorId); - core.status.maps[floorId].blocks.forEach(function (block) { - var x = block.x, y = block.y; + core.extractBlocks(floorId); + core.status.maps[floorId].blocks.forEach(function (block) { + var x = block.x, + y = block.y; - // v2优化,只绘制范围内的部分 - if (onMap && core.bigmap.v2) { - if (x < core.bigmap.posX - core.bigmap.extend || x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend - || y < core.bigmap.posY - core.bigmap.extend || y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend) { - return; - } - } + // v2优化,只绘制范围内的部分 + if (onMap && core.bigmap.v2) { + if ( + x < core.bigmap.posX - core.bigmap.extend || + x > core.bigmap.posX + core._WIDTH_ + core.bigmap.extend || + y < core.bigmap.posY - core.bigmap.extend || + y > core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + ) { + return; + } + } - if (!block.disable && block.event.cls.indexOf('enemy') == 0 && block.event.displayDamage !== false) { - if (core.flags.displayEnemyDamage) { - var damageString = core.enemys.getDamageString(block.event.id, x, y, floorId); - core.status.damage.data.push({ text: damageString.damage, px: 32 * x + 1, py: 32 * (y + 1) - 1, color: damageString.color }); - } - if (core.flags.displayCritical) { - var critical = core.enemys.nextCriticals(block.event.id, 1, x, y, floorId); - critical = core.formatBigNumber((critical[0] || [])[0], true); - if (critical == '???') critical = '?'; - core.status.damage.data.push({ text: critical, px: 32 * x + 1, py: 32 * (y + 1) - 11, color: '#FFFFFF' }); - } - } - }); -} + if ( + !block.disable && + block.event.cls.indexOf("enemy") == 0 && + block.event.displayDamage !== false + ) { + if (core.flags.displayEnemyDamage) { + var damageString = core.enemys.getDamageString( + block.event.id, + x, + y, + floorId + ); + core.status.damage.data.push({ + text: damageString.damage, + px: 32 * x + 1, + py: 32 * (y + 1) - 1, + color: damageString.color, + }); + } + if (core.flags.displayCritical) { + var critical = core.enemys.nextCriticals( + block.event.id, + 1, + x, + y, + floorId + ); + critical = core.formatBigNumber((critical[0] || [])[0], true); + if (critical == "???") critical = "?"; + core.status.damage.data.push({ + text: critical, + px: 32 * x + 1, + py: 32 * (y + 1) - 11, + color: "#FFFFFF", + }); + } + } + }); +}; control.prototype._updateDamage_extraDamage = function (floorId, onMap) { - core.status.damage.extraData = []; - if (!core.flags.displayExtraDamage) return; + core.status.damage.extraData = []; + if (!core.flags.displayExtraDamage) return; - var width = core.floors[floorId].width, height = core.floors[floorId].height; - var startX = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posX - core.bigmap.extend) : 0; - var endX = onMap && core.bigmap.v2 ? Math.min(width, core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1) : width; - var startY = onMap && core.bigmap.v2 ? Math.max(0, core.bigmap.posY - core.bigmap.extend) : 0; - var endY = onMap && core.bigmap.v2 ? Math.min(height, core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1) : height; + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + var startX = + onMap && core.bigmap.v2 + ? Math.max(0, core.bigmap.posX - core.bigmap.extend) + : 0; + var endX = + onMap && core.bigmap.v2 + ? Math.min( + width, + core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1 + ) + : width; + var startY = + onMap && core.bigmap.v2 + ? Math.max(0, core.bigmap.posY - core.bigmap.extend) + : 0; + var endY = + onMap && core.bigmap.v2 + ? Math.min( + height, + core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1 + ) + : height; - for (var x = startX; x < endX; x++) { - for (var y = startY; y < endY; y++) { - var alpha = 1; - if (core.noPass(x, y, floorId)) { - if (core.flags.extraDamageType == 2) alpha = 0; - else if (core.flags.extraDamageType == 1) alpha = 0.6; - } - var damage = core.status.checkBlock.damage[x + "," + y] || 0; - if (damage > 0) { // 该点伤害 - damage = core.formatBigNumber(damage, true); - core.status.damage.extraData.push({ text: damage, px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha }); - } - else { // 检查捕捉 - if (core.status.checkBlock.ambush[x + "," + y]) { - core.status.damage.extraData.push({ text: '!', px: 32 * x + 16, py: 32 * (y + 1) - 14, color: '#ffaa33', alpha: alpha }); - } - } + for (var x = startX; x < endX; x++) { + for (var y = startY; y < endY; y++) { + var alpha = 1; + if (core.noPass(x, y, floorId)) { + if (core.flags.extraDamageType == 2) alpha = 0; + else if (core.flags.extraDamageType == 1) alpha = 0.6; + } + var damage = core.status.checkBlock.damage[x + "," + y] || 0; + if (damage > 0) { + // 该点伤害 + damage = core.formatBigNumber(damage, true); + core.status.damage.extraData.push({ + text: damage, + px: 32 * x + 16, + py: 32 * (y + 1) - 14, + color: "#ffaa33", + alpha: alpha, + }); + } else { + // 检查捕捉 + if (core.status.checkBlock.ambush[x + "," + y]) { + core.status.damage.extraData.push({ + text: "!", + px: 32 * x + 16, + py: 32 * (y + 1) - 14, + color: "#ffaa33", + alpha: alpha, + }); } + } } -} + } +}; ////// 重绘地图显伤 ////// control.prototype.drawDamage = function (ctx) { - if (core.status.gameOver || !core.status.damage || main.mode != 'play') return; - var onMap = false; - if (ctx == null) { - ctx = core.canvas.damage; - core.clearMap('damage'); - onMap = true; - } + if (core.status.gameOver || !core.status.damage || main.mode != "play") + return; + var onMap = false; + if (ctx == null) { + ctx = core.canvas.damage; + core.clearMap("damage"); + onMap = true; + } - if (onMap && core.bigmap.v2) { - // 检查是否需要重算... - if (Math.abs(core.bigmap.posX - core.status.damage.posX) >= core.bigmap.extend - 1 - || Math.abs(core.bigmap.posY - core.status.damage.posY) >= core.bigmap.extend - 1) { - return this.updateDamage(); - } + if (onMap && core.bigmap.v2) { + // 检查是否需要重算... + if ( + Math.abs(core.bigmap.posX - core.status.damage.posX) >= + core.bigmap.extend - 1 || + Math.abs(core.bigmap.posY - core.status.damage.posY) >= + core.bigmap.extend - 1 + ) { + return this.updateDamage(); } - return this._drawDamage_draw(ctx, onMap); -} + } + return this._drawDamage_draw(ctx, onMap); +}; control.prototype._drawDamage_draw = function (ctx, onMap) { - if (!core.hasItem('book')) return; + if (!core.hasItem("book")) return; - core.setFont(ctx, "bold 11px Arial"); - core.setTextAlign(ctx, 'left'); - core.status.damage.data.forEach(function (one) { - var px = one.px, py = one.py; - if (onMap && core.bigmap.v2) { - px -= core.bigmap.posX * 32; - py -= core.bigmap.posY * 32; - if (px < -32 * 2 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) - return; - } - core.fillBoldText(ctx, one.text, px, py, one.color); - }); + core.setFont(ctx, "bold 11px Arial"); + core.setTextAlign(ctx, "left"); + core.status.damage.data.forEach(function (one) { + var px = one.px, + py = one.py; + if (onMap && core.bigmap.v2) { + px -= core.bigmap.posX * 32; + py -= core.bigmap.posY * 32; + if ( + px < -32 * 2 || + px > core._PX_ + 32 || + py < -32 || + py > core._PY_ + 32 + ) + return; + } + core.fillBoldText(ctx, one.text, px, py, one.color); + }); - core.setTextAlign(ctx, 'center'); - core.status.damage.extraData.forEach(function (one) { - var px = one.px, py = one.py; - if (onMap && core.bigmap.v2) { - px -= core.bigmap.posX * 32; - py -= core.bigmap.posY * 32; - if (px < -32 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) - return; - } - var alpha = core.setAlpha(ctx, one.alpha); - core.fillBoldText(ctx, one.text, px, py, one.color); - core.setAlpha(ctx, alpha); - }); -} + core.setTextAlign(ctx, "center"); + core.status.damage.extraData.forEach(function (one) { + var px = one.px, + py = one.py; + if (onMap && core.bigmap.v2) { + px -= core.bigmap.posX * 32; + py -= core.bigmap.posY * 32; + if (px < -32 || px > core._PX_ + 32 || py < -32 || py > core._PY_ + 32) + return; + } + var alpha = core.setAlpha(ctx, one.alpha); + core.fillBoldText(ctx, one.text, px, py, one.color); + core.setAlpha(ctx, alpha); + }); +}; // ------ 录像相关 ------ // ////// 选择录像文件 ////// control.prototype.chooseReplayFile = function () { - core.readFile(function (obj) { - if (obj.name != core.firstData.name) return alert("存档和游戏不一致!"); - if (!obj.route) return alert("无效的录像!"); - var _replay = function () { - core.startGame(core.flags.startUsingCanvas ? '' : obj.hard || '', obj.seed, core.decodeRoute(obj.route)); - } - if (obj.version && obj.version != core.firstData.version) { - core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay); - return; - } - _replay(); - }, null, ".h5route"); -} + core.readFile( + function (obj) { + if (obj.name != core.firstData.name) return alert("存档和游戏不一致!"); + if (!obj.route) return alert("无效的录像!"); + var _replay = function () { + core.startGame( + core.flags.startUsingCanvas ? "" : obj.hard || "", + obj.seed, + core.decodeRoute(obj.route) + ); + }; + if (obj.version && obj.version != core.firstData.version) { + core.myconfirm("游戏版本不一致!\n你仍然想播放录像吗?", _replay); + return; + } + _replay(); + }, + null, + ".h5route" + ); +}; ////// 开始播放 ////// control.prototype.startReplay = function (list) { - if (!core.isPlaying()) return; - core.status.replay.replaying = true; - core.status.replay.pausing = true; - core.status.replay.failed = false; - core.status.replay.speed = 1.0; - core.status.replay.toReplay = core.cloneArray(list); - core.status.replay.totalList = core.status.route.concat(list); - core.status.replay.steps = 0; - core.status.replay.save = []; - core.createCanvas('replay', 0, core._PY_ - 40, core._PX_, 40, 199); - core.setOpacity('replay', 0.6); - this._replay_drawProgress(); - core.updateStatusBar(false, true); - core.drawTip("开始播放"); - this.replay(); -} + if (!core.isPlaying()) return; + core.status.replay.replaying = true; + core.status.replay.pausing = true; + core.status.replay.failed = false; + core.status.replay.speed = 1.0; + core.status.replay.toReplay = core.cloneArray(list); + core.status.replay.totalList = core.status.route.concat(list); + core.status.replay.steps = 0; + core.status.replay.save = []; + core.createCanvas("replay", 0, core._PY_ - 40, core._PX_, 40, 199); + core.setOpacity("replay", 0.6); + this._replay_drawProgress(); + core.updateStatusBar(false, true); + core.drawTip("开始播放"); + this.replay(); +}; ////// 更改播放状态 ////// control.prototype.triggerReplay = function () { - if (core.status.replay.pausing) this.resumeReplay(); - else this.pauseReplay(); -} + if (core.status.replay.pausing) this.resumeReplay(); + else this.pauseReplay(); +}; ////// 暂停播放 ////// control.prototype.pauseReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - core.status.replay.pausing = true; - core.updateStatusBar(false, true); - core.drawTip("暂停播放"); -} + if (!core.isPlaying() || !core.isReplaying()) return; + core.status.replay.pausing = true; + core.updateStatusBar(false, true); + core.drawTip("暂停播放"); +}; ////// 恢复播放 ////// control.prototype.resumeReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - core.status.replay.pausing = false; - core.updateStatusBar(false, true); - core.drawTip("恢复播放"); - core.replay(); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + core.status.replay.pausing = false; + core.updateStatusBar(false, true); + core.drawTip("恢复播放"); + core.replay(); +}; ////// 单步播放 ////// control.prototype.stepReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - core.replay(true); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + core.replay(true); +}; ////// 加速播放 ////// control.prototype.speedUpReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; - for (var i = speeds.length - 2; i >= 0; i--) { - if (speeds[i] <= core.status.replay.speed) { - core.status.replay.speed = speeds[i + 1]; - break; - } + if (!core.isPlaying() || !core.isReplaying()) return; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = speeds.length - 2; i >= 0; i--) { + if (speeds[i] <= core.status.replay.speed) { + core.status.replay.speed = speeds[i + 1]; + break; } - core.drawTip("x" + core.status.replay.speed + "倍"); -} + } + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 减速播放 ////// control.prototype.speedDownReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; - for (var i = 1; i <= speeds.length; i++) { - if (speeds[i] >= core.status.replay.speed) { - core.status.replay.speed = speeds[i - 1]; - break; - } + if (!core.isPlaying() || !core.isReplaying()) return; + var speeds = [0.2, 0.5, 1, 2, 3, 6, 12, 24]; + for (var i = 1; i <= speeds.length; i++) { + if (speeds[i] >= core.status.replay.speed) { + core.status.replay.speed = speeds[i - 1]; + break; } - core.drawTip("x" + core.status.replay.speed + "倍"); -} + } + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 设置播放速度 ////// control.prototype.setReplaySpeed = function (speed) { - if (!core.isPlaying() || !core.isReplaying()) return; - core.status.replay.speed = speed; - core.drawTip("x" + core.status.replay.speed + "倍"); -} + if (!core.isPlaying() || !core.isReplaying()) return; + core.status.replay.speed = speed; + core.drawTip("x" + core.status.replay.speed + "倍"); +}; ////// 停止播放 ////// control.prototype.stopReplay = function (force) { - if (!core.isPlaying()) return; - if (!core.isReplaying() && !force) return; - core.status.replay.toReplay = []; - core.status.replay.totalList = []; - core.status.replay.replaying = false; - core.status.replay.pausing = false; - core.status.replay.failed = false; - core.status.replay.speed = 1.0; - core.status.replay.steps = 0; - core.status.replay.save = []; - core.deleteCanvas('replay'); - core.updateStatusBar(false, true); - core.drawTip("停止播放并恢复游戏"); -} + if (!core.isPlaying()) return; + if (!core.isReplaying() && !force) return; + core.status.replay.toReplay = []; + core.status.replay.totalList = []; + core.status.replay.replaying = false; + core.status.replay.pausing = false; + core.status.replay.failed = false; + core.status.replay.speed = 1.0; + core.status.replay.steps = 0; + core.status.replay.save = []; + core.deleteCanvas("replay"); + core.updateStatusBar(false, true); + core.drawTip("停止播放并恢复游戏"); +}; ////// 回退 ////// control.prototype.rewindReplay = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (core.status.replay.save.length == 0) { - core.playSound('操作失败'); - return core.drawTip("无法再回到上一个节点"); - } - var save = core.status.replay.save, data = save.pop(); - core.loadData(data.data, function () { - core.removeFlag('__fromLoad__'); - core.status.replay = { - "replaying": true, - "pausing": true, - "animate": false, - "toReplay": data.replay.toReplay, - "totalList": data.replay.totalList, - "speed": core.status.replay.speed, - "steps": data.replay.steps, - "save": save - } - core.createCanvas('replay', 0, core._PY_ - 40, core._PX_, 40, 199); - core.setOpacity('replay', 0.6); - core.control._replay_drawProgress(); - core.updateStatusBar(false, true); - core.drawTip("成功回退到上一个节点"); - }); -} + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (core.status.replay.save.length == 0) { + core.playSound("操作失败"); + return core.drawTip("无法再回到上一个节点"); + } + var save = core.status.replay.save, + data = save.pop(); + core.loadData(data.data, function () { + core.removeFlag("__fromLoad__"); + core.status.replay = { + replaying: true, + pausing: true, + animate: false, + toReplay: data.replay.toReplay, + totalList: data.replay.totalList, + speed: core.status.replay.speed, + steps: data.replay.steps, + save: save, + }; + core.createCanvas("replay", 0, core._PY_ - 40, core._PX_, 40, 199); + core.setOpacity("replay", 0.6); + core.control._replay_drawProgress(); + core.updateStatusBar(false, true); + core.drawTip("成功回退到上一个节点"); + }); +}; ////// 回放时存档 ////// control.prototype._replay_SL = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (core.hasFlag('__forbidSave__')) { - core.playSound('操作失败'); - return core.drawTip('当前禁止存档'); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (core.hasFlag("__forbidSave__")) { + core.playSound("操作失败"); + return core.drawTip("当前禁止存档"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'save'; - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; + core.lockControl(); + core.status.event.id = "save"; + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; - core.ui._drawSLPanel(10 * page + offset); -} + core.ui._drawSLPanel(10 * page + offset); +}; ////// 回放时查看怪物手册 ////// control.prototype._replay_book = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || (core.status.event.id && core.status.event.id != 'viewMaps')) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - if (!core.hasItem('book')) { - core.playSound('操作失败'); - return core.drawTip('你没有' + core.material.items['book'].name, 'book'); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if ( + core.isMoving() || + core.status.replay.animate || + (core.status.event.id && core.status.event.id != "viewMaps") + ) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + if (!core.hasItem("book")) { + core.playSound("操作失败"); + return core.drawTip("你没有" + core.material.items["book"].name, "book"); + } + this._replay_hideProgress(); - // 从“浏览地图”页面打开 - if (core.status.event.id == 'viewMaps') - core.status.event.ui = core.status.event.data; + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps") + core.status.event.ui = core.status.event.data; - core.lockControl(); - core.status.event.id = 'book'; - core.useItem('book', true); -} + core.lockControl(); + core.status.event.id = "book"; + core.useItem("book", true); +}; ////// 回放录像时浏览地图 ////// control.prototype._replay_viewMap = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'viewMaps'; - core.ui._drawViewMaps(); -} + core.lockControl(); + core.status.event.id = "viewMaps"; + core.ui._drawViewMaps(); +}; control.prototype._replay_toolbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'toolbox'; - core.ui._drawToolbox(); -} + core.lockControl(); + core.status.event.id = "toolbox"; + core.ui._drawToolbox(); +}; control.prototype._replay_equipbox = function () { - if (!core.isPlaying() || !core.isReplaying()) return; - if (!core.status.replay.pausing) { - core.playSound('操作失败'); - return core.drawTip("请先暂停录像"); - } - if (core.isMoving() || core.status.replay.animate || core.status.event.id) { - core.playSound('操作失败'); - return core.drawTip("请等待当前事件的处理结束"); - } - this._replay_hideProgress(); + if (!core.isPlaying() || !core.isReplaying()) return; + if (!core.status.replay.pausing) { + core.playSound("操作失败"); + return core.drawTip("请先暂停录像"); + } + if (core.isMoving() || core.status.replay.animate || core.status.event.id) { + core.playSound("操作失败"); + return core.drawTip("请等待当前事件的处理结束"); + } + this._replay_hideProgress(); - core.lockControl(); - core.status.event.id = 'equipbox'; - core.ui._drawEquipbox(); -} + core.lockControl(); + core.status.event.id = "equipbox"; + core.ui._drawEquipbox(); +}; ////// 是否正在播放录像 ////// control.prototype.isReplaying = function () { - return (core.status.replay || {}).replaying; -} + return (core.status.replay || {}).replaying; +}; ////// 回放 ////// control.prototype.replay = function (force) { - if (!core.isPlaying() || !core.isReplaying() - || core.status.replay.animate || core.status.event.id || core.status.replay.failed) return; - if (core.status.replay.pausing && !force) return; - this._replay_drawProgress(); - if (core.status.replay.toReplay.length == 0) - return this._replay_finished(); - this._replay_save(); - var action = core.status.replay.toReplay.shift(); - if (this._doReplayAction(action)) return; - this._replay_error(action); -} + if ( + !core.isPlaying() || + !core.isReplaying() || + core.status.replay.animate || + core.status.event.id || + core.status.replay.failed + ) + return; + if (core.status.replay.pausing && !force) return; + this._replay_drawProgress(); + if (core.status.replay.toReplay.length == 0) return this._replay_finished(); + this._replay_save(); + var action = core.status.replay.toReplay.shift(); + if (this._doReplayAction(action)) return; + this._replay_error(action); +}; ////// 注册一个录像行为 ////// // name:自定义名称,可用于注销使用 @@ -1608,1958 +2039,2394 @@ control.prototype.replay = function (force) { // 需要接受一个action参数,代表录像回放时的下一个操作 // func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。 control.prototype.registerReplayAction = function (name, func) { - this.unregisterReplayAction(name); - this.replayActions.push({ name: name, func: func }); -} + this.unregisterReplayAction(name); + this.replayActions.push({ name: name, func: func }); +}; ////// 注销一个录像行为 ////// control.prototype.unregisterReplayAction = function (name) { - this.replayActions = this.replayActions.filter(function (b) { return b.name != name; }); -} + this.replayActions = this.replayActions.filter(function (b) { + return b.name != name; + }); +}; ////// 执行录像行为,会在注册的函数中依次执行直到得到true为止 ////// control.prototype._doReplayAction = function (action) { - for (var i in this.replayActions) { - try { - if (core.doFunc(this.replayActions[i].func, this, action)) return true; - } catch (e) { - console.error(e); - console.error("ERROR in replayActions[" + this.replayActions[i].name + "]:已自动注销该项。"); - core.unregisterReplayAction(this.replayActions[i].name); - } + for (var i in this.replayActions) { + try { + if (core.doFunc(this.replayActions[i].func, this, action)) return true; + } catch (e) { + console.error(e); + console.error( + "ERROR in replayActions[" + + this.replayActions[i].name + + "]:已自动注销该项。" + ); + core.unregisterReplayAction(this.replayActions[i].name); } - return false; -} + } + return false; +}; control.prototype._replay_finished = function () { - core.status.replay.replaying = false; - core.status.replay.failed = false; - core.status.event.selection = 0; - var str = "录像播放完毕,你想退出播放吗?"; - if (core.status.route.length != core.status.replay.totalList.length - || core.subarray(core.status.route, core.status.replay.totalList) == null) { - str = "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?"; + core.status.replay.replaying = false; + core.status.replay.failed = false; + core.status.event.selection = 0; + var str = "录像播放完毕,你想退出播放吗?"; + if ( + core.status.route.length != core.status.replay.totalList.length || + core.subarray(core.status.route, core.status.replay.totalList) == null + ) { + str = + "录像播放完毕,但记录不一致。\n请检查录像播放时的二次记录问题。\n你想退出播放吗?"; + } + core.ui.drawConfirmBox( + str, + function () { + core.ui.closePanel(); + core.stopReplay(true); + }, + function () { + core.status.replay.replaying = true; + core.ui.closePanel(); + core.pauseReplay(); } - core.ui.drawConfirmBox(str, function () { - core.ui.closePanel(); - core.stopReplay(true); - }, function () { - core.status.replay.replaying = true; - core.ui.closePanel(); - core.pauseReplay(); - }); -} + ); +}; control.prototype._replay_save = function () { - core.status.replay.steps++; - if (core.status.replay.steps % 40 == 1) { - if (core.status.replay.save.length == 30) - core.status.replay.save.shift(); - core.status.replay.save.push({ - "data": core.saveData(), "replay": { - "totalList": core.cloneArray(core.status.replay.totalList), - "toReplay": core.cloneArray(core.status.replay.toReplay), - "steps": core.status.replay.steps - } - }); - } -} + core.status.replay.steps++; + if (core.status.replay.steps % 40 == 1) { + if (core.status.replay.save.length == 30) core.status.replay.save.shift(); + core.status.replay.save.push({ + data: core.saveData(), + replay: { + totalList: core.cloneArray(core.status.replay.totalList), + toReplay: core.cloneArray(core.status.replay.toReplay), + steps: core.status.replay.steps, + }, + }); + } +}; control.prototype._replay_error = function (action, callback) { - core.ui.closePanel(); - core.status.replay.replaying = false; - core.status.replay.failed = true; - var len = core.status.replay.toReplay.length; - var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); - var nextList = core.status.replay.toReplay.slice(0, 10); - console.log("录像文件出错,当前操作:" + action); - console.log("之前的10个操作是:\n" + prevList.toString()); - console.log("接下来10个操作是:\n" + nextList.toString()); - core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { - core.status.replay.failed = false; - core.ui.closePanel(); - if (core.status.replay.save.length > 0) { - core.status.replay.replaying = true; - core.status.replay.pausing = true; - core.rewindReplay(); - } - else { - core.playSound('操作失败'); - core.stopReplay(true); - core.drawTip("无法回到上一个节点"); - if (callback) callback(); - } - }, function () { - core.status.replay.failed = false; - core.ui.closePanel(); + core.ui.closePanel(); + core.status.replay.replaying = false; + core.status.replay.failed = true; + var len = core.status.replay.toReplay.length; + var prevList = core.status.replay.totalList.slice(-len - 11, -len - 1); + var nextList = core.status.replay.toReplay.slice(0, 10); + console.log("录像文件出错,当前操作:" + action); + console.log("之前的10个操作是:\n" + prevList.toString()); + console.log("接下来10个操作是:\n" + nextList.toString()); + core.ui.drawConfirmBox( + "录像文件出错,你想回到上个节点吗?", + function () { + core.status.replay.failed = false; + core.ui.closePanel(); + if (core.status.replay.save.length > 0) { + core.status.replay.replaying = true; + core.status.replay.pausing = true; + core.rewindReplay(); + } else { + core.playSound("操作失败"); core.stopReplay(true); + core.drawTip("无法回到上一个节点"); if (callback) callback(); - }); -} + } + }, + function () { + core.status.replay.failed = false; + core.ui.closePanel(); + core.stopReplay(true); + if (callback) callback(); + } + ); +}; control.prototype._replay_hideProgress = function () { - if (core.dymCanvas.replay) core.dymCanvas.replay.canvas.style.display = 'none'; -} + if (core.dymCanvas.replay) + core.dymCanvas.replay.canvas.style.display = "none"; +}; control.prototype._replay_drawProgress = function () { - if (!core.dymCanvas.replay) return; - if (core.dymCanvas.replay.canvas.style.display == 'none') core.dymCanvas.replay.canvas.style.display = 'block'; - var total = core.status.replay.totalList.length, left = total - core.status.replay.toReplay.length; - var content = '播放进度:' + left + ' / ' + total + '(' + (left / total * 100).toFixed(2) + '%)'; - var width = 26 + core.calWidth('replay', content, "16px Arial"); - core.clearMap('replay'); - core.fillRect('replay', 0, 0, width, 40, '#000000'); - core.fillText('replay', content, 16, 27, '#FFFFFF'); -} + if (!core.dymCanvas.replay) return; + if (core.dymCanvas.replay.canvas.style.display == "none") + core.dymCanvas.replay.canvas.style.display = "block"; + var total = core.status.replay.totalList.length, + left = total - core.status.replay.toReplay.length; + var content = + "播放进度:" + + left + + " / " + + total + + "(" + + ((left / total) * 100).toFixed(2) + + "%)"; + var width = 26 + core.calWidth("replay", content, "16px Arial"); + core.clearMap("replay"); + core.fillRect("replay", 0, 0, width, 40, "#000000"); + core.fillText("replay", content, 16, 27, "#FFFFFF"); +}; control.prototype.__replay_getTimeout = function () { - if (core.status.replay.speed == 24) return 0; - return 750 / Math.max(1, core.status.replay.speed); -} + if (core.status.replay.speed == 24) return 0; + return 750 / Math.max(1, core.status.replay.speed); +}; control.prototype._replayAction_move = function (action) { - if (["up", "down", "left", "right"].indexOf(action) < 0) return false; - core.moveHero(action, core.replay); - return true; -} + if (["up", "down", "left", "right"].indexOf(action) < 0) return false; + core.moveHero(action, core.replay); + return true; +}; control.prototype._replayAction_item = function (action) { - if (action.indexOf("item:") != 0) return false; - var itemId = action.substring(5); - if (!core.canUseItem(itemId)) return false; - if (core.material.items[itemId].hideInReplay || core.status.replay.speed == 24) { - core.useItem(itemId, false, core.replay); - return true; - } - var tools = core.getToolboxItems('tools'), - constants = core.getToolboxItems('constants'); - var index, per = core._WIDTH_ - 1; - if ((index = tools.indexOf(itemId)) >= 0) { - core.status.event.data = { "toolsPage": Math.floor(index / per) + 1, "constantsPage": 1 }; - index = index % per; - } - else if ((index = constants.indexOf(itemId)) >= 0) { - core.status.event.data = { "toolsPage": 1, "constantsPage": Math.floor(index / per) + 1 }; - index = index % per + per; - } - if (index < 0) return false; - core.ui._drawToolbox(index); - setTimeout(function () { - core.ui.closePanel(); - core.useItem(itemId, false, core.replay); - }, core.control.__replay_getTimeout()); + if (action.indexOf("item:") != 0) return false; + var itemId = action.substring(5); + if (!core.canUseItem(itemId)) return false; + if ( + core.material.items[itemId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.useItem(itemId, false, core.replay); return true; -} + } + var tools = core.getToolboxItems("tools"), + constants = core.getToolboxItems("constants"); + var index, + per = core._WIDTH_ - 1; + if ((index = tools.indexOf(itemId)) >= 0) { + core.status.event.data = { + toolsPage: Math.floor(index / per) + 1, + constantsPage: 1, + }; + index = index % per; + } else if ((index = constants.indexOf(itemId)) >= 0) { + core.status.event.data = { + toolsPage: 1, + constantsPage: Math.floor(index / per) + 1, + }; + index = (index % per) + per; + } + if (index < 0) return false; + core.ui._drawToolbox(index); + setTimeout(function () { + core.ui.closePanel(); + core.useItem(itemId, false, core.replay); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_equip = function (action) { - if (action.indexOf("equip:") != 0) return false; - var equipId = action.substring(6); - var ownEquipment = core.getToolboxItems('equips'); - var index = ownEquipment.indexOf(equipId), per = core._WIDTH_ - 1; - if (index < 0) { - core.removeFlag('__doNotCheckAutoEvents__'); - return false; - } + if (action.indexOf("equip:") != 0) return false; + var equipId = action.substring(6); + var ownEquipment = core.getToolboxItems("equips"); + var index = ownEquipment.indexOf(equipId), + per = core._WIDTH_ - 1; + if (index < 0) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) { - core.removeFlag('__doNotCheckAutoEvents__'); - core.checkAutoEvents(); - } - core.replay(); + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); } - core.setFlag('__doNotCheckAutoEvents__', true); + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); - core.status.route.push(action); - if (core.material.items[equipId].hideInReplay || core.status.replay.speed == 24) { - core.loadEquip(equipId, cb); - return true; - } - core.status.event.data = { "page": Math.floor(index / per) + 1, "selectId": null }; - index = index % per + per; - core.ui._drawEquipbox(index); - setTimeout(function () { - core.ui.closePanel(); - core.loadEquip(equipId, cb); - }, core.control.__replay_getTimeout()); + core.status.route.push(action); + if ( + core.material.items[equipId].hideInReplay || + core.status.replay.speed == 24 + ) { + core.loadEquip(equipId, cb); return true; -} + } + core.status.event.data = { + page: Math.floor(index / per) + 1, + selectId: null, + }; + index = (index % per) + per; + core.ui._drawEquipbox(index); + setTimeout(function () { + core.ui.closePanel(); + core.loadEquip(equipId, cb); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_unEquip = function (action) { - if (action.indexOf("unEquip:") != 0) return false; - var equipType = parseInt(action.substring(8)); - if (!core.isset(equipType)) { - core.removeFlag('__doNotCheckAutoEvents__'); - return false; - } + if (action.indexOf("unEquip:") != 0) return false; + var equipType = parseInt(action.substring(8)); + if (!core.isset(equipType)) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } - var cb = function () { - var next = core.status.replay.toReplay[0] || ""; - if (!next.startsWith('equip:') && !next.startsWith('unEquip:')) { - core.removeFlag('__doNotCheckAutoEvents__'); - core.checkAutoEvents(); - } - core.replay(); + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); } - core.setFlag('__doNotCheckAutoEvents__', true); + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); - core.ui._drawEquipbox(equipType); - core.status.route.push(action); - if (core.status.replay.speed == 24) { - core.unloadEquip(equipType, cb); - return true; - } - setTimeout(function () { - core.ui.closePanel(); - core.unloadEquip(equipType, cb); - }, core.control.__replay_getTimeout()); + core.ui._drawEquipbox(equipType); + core.status.route.push(action); + if (core.status.replay.speed == 24) { + core.unloadEquip(equipType, cb); return true; -} + } + setTimeout(function () { + core.ui.closePanel(); + core.unloadEquip(equipType, cb); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_saveEquip = function (action) { - if (action.indexOf('saveEquip:') != 0) return false; - core.quickSaveEquip(parseInt(action.substring(10))); - core.replay(); - return true; -} + if (action.indexOf("saveEquip:") != 0) return false; + core.quickSaveEquip(parseInt(action.substring(10))); + core.replay(); + return true; +}; control.prototype._replayAction_loadEquip = function (action) { - if (action.indexOf('loadEquip:') != 0) return false; - core.quickLoadEquip(parseInt(action.substring(10))); - core.replay(); - return true; -} + if (action.indexOf("loadEquip:") != 0) return false; + core.quickLoadEquip(parseInt(action.substring(10))); + core.replay(); + return true; +}; control.prototype._replayAction_fly = function (action) { - if (action.indexOf("fly:") != 0) return false; - var floorId = action.substring(4); - var toIndex = core.floorIds.indexOf(floorId); - if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) return false; - core.ui.drawFly(toIndex); - if (core.status.replay.speed == 24) { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - return true; - } - setTimeout(function () { - if (!core.flyTo(floorId, core.replay)) - core.control._replay_error(action); - }, core.control.__replay_getTimeout()); + if (action.indexOf("fly:") != 0) return false; + var floorId = action.substring(4); + var toIndex = core.floorIds.indexOf(floorId); + if ( + !core.canUseItem("fly") || + (core.flags.flyNearStair && !core.nearStair() && !flags.canMoveFloor) + ) + return false; + core.ui.drawFly(toIndex); + if (core.status.replay.speed == 24) { + if (!core.flyTo(floorId, core.replay)) core.control._replay_error(action); return true; -} + } + setTimeout(function () { + if (!core.flyTo(floorId, core.replay)) core.control._replay_error(action); + }, core.control.__replay_getTimeout()); + return true; +}; control.prototype._replayAction_shop = function (action) { - if (action.indexOf("shop:") != 0) return false; - var shopId = action.substring(5); - if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) { - this._replay_error(shopId); - return true; - } - core.openShop(shopId, false); - core.replay(); + if (action.indexOf("shop:") != 0) return false; + var shopId = action.substring(5); + if (core.canUseQuickShop(shopId) != null || !core.canOpenShop(shopId)) { + this._replay_error(shopId); return true; -} + } + core.openShop(shopId, false); + core.replay(); + return true; +}; control.prototype._replayAction_turn = function (action) { - if (action != 'turn' && action.indexOf('turn:') != 0) return false; - if (action == 'turn') core.turnHero(); - else core.turnHero(action.substring(5)); - core.replay(); - return true; -} + if (action != "turn" && action.indexOf("turn:") != 0) return false; + if (action == "turn") core.turnHero(); + else core.turnHero(action.substring(5)); + core.replay(); + return true; +}; control.prototype._replayAction_getNext = function (action) { - if (action != "getNext") return false; - core.getNextItem(); - core.replay(); - return true; -} + if (action != "getNext") return false; + core.getNextItem(); + core.replay(); + return true; +}; control.prototype._replayAction_moveDirectly = function (action) { - if (action.indexOf("move:") != 0) return false; - // 忽略连续的瞬移事件;如果大地图某一边超过计算范围则不合并 - if (!core.hasFlag('poison') && core.status.thisMap.width < 2 * core.bigmap.extend + core._WIDTH_ - && core.status.thisMap.height < 2 * core.bigmap.extend + core._HEIGHT_) { - while (core.status.replay.toReplay.length > 0 && - core.status.replay.toReplay[0].indexOf('move:') == 0) { - core.status.route.push(action); - action = core.status.replay.toReplay.shift(); - } + if (action.indexOf("move:") != 0) return false; + // 忽略连续的瞬移事件;如果大地图某一边超过计算范围则不合并 + if ( + !core.hasFlag("poison") && + core.status.thisMap.width < 2 * core.bigmap.extend + core._WIDTH_ && + core.status.thisMap.height < 2 * core.bigmap.extend + core._HEIGHT_ + ) { + while ( + core.status.replay.toReplay.length > 0 && + core.status.replay.toReplay[0].indexOf("move:") == 0 + ) { + core.status.route.push(action); + action = core.status.replay.toReplay.shift(); } + } - var pos = action.substring(5).split(":"); - var x = parseInt(pos[0]), y = parseInt(pos[1]); - var nowx = core.getHeroLoc('x'), nowy = core.getHeroLoc('y'); - var ignoreSteps = core.canMoveDirectly(x, y); - if (!core.moveDirectly(x, y, ignoreSteps)) return false; - if (core.status.replay.speed == 24) { - core.replay(); - return true; - } - - core.ui.drawArrow('ui', 32 * nowx + 16 - core.bigmap.offsetX, 32 * nowy + 16 - core.bigmap.offsetY, - 32 * x + 16 - core.bigmap.offsetX, 32 * y + 16 - core.bigmap.offsetY, '#FF0000', 3); - var timeout = this.__replay_getTimeout(); - if (ignoreSteps < 10) timeout = timeout * ignoreSteps / 10; - setTimeout(function () { - core.clearMap('ui'); - core.replay(); - }, timeout); + var pos = action.substring(5).split(":"); + var x = parseInt(pos[0]), + y = parseInt(pos[1]); + var nowx = core.getHeroLoc("x"), + nowy = core.getHeroLoc("y"); + var ignoreSteps = core.canMoveDirectly(x, y); + if (!core.moveDirectly(x, y, ignoreSteps)) return false; + if (core.status.replay.speed == 24) { + core.replay(); return true; -} + } + + core.ui.drawArrow( + "ui", + 32 * nowx + 16 - core.bigmap.offsetX, + 32 * nowy + 16 - core.bigmap.offsetY, + 32 * x + 16 - core.bigmap.offsetX, + 32 * y + 16 - core.bigmap.offsetY, + "#FF0000", + 3 + ); + var timeout = this.__replay_getTimeout(); + if (ignoreSteps < 10) timeout = (timeout * ignoreSteps) / 10; + setTimeout(function () { + core.clearMap("ui"); + core.replay(); + }, timeout); + return true; +}; control.prototype._replayAction_key = function (action) { - if (action.indexOf("key:") != 0) return false; - core.actions.keyUp(parseInt(action.substring(4)), false, true); - core.replay(); - return true; -} + if (action.indexOf("key:") != 0) return false; + core.actions.keyUp(parseInt(action.substring(4)), false, true); + core.replay(); + return true; +}; control.prototype._replayAction_click = function (action) { - if (action.indexOf("click:") != 0) return false; - var p = action.split(":"); - if (p.length != 4) return false; - core.actions.doRegisteredAction("onStatusBarClick", parseInt(p[2]), parseInt(p[3]), parseInt(p[1])); - core.replay(); - return true; -} + if (action.indexOf("click:") != 0) return false; + var p = action.split(":"); + if (p.length != 4) return false; + core.actions.doRegisteredAction( + "onStatusBarClick", + parseInt(p[2]), + parseInt(p[3]), + parseInt(p[1]) + ); + core.replay(); + return true; +}; control.prototype._replayAction_ignoreInput = function (action) { - if (action.indexOf('input:') == 0 || action.indexOf('input2:') == 0 || action.indexOf('choices:') == 0 || action.indexOf('random:') == 0) { - console.warn('警告!录像播放中出现了未知的 ' + action + '!'); - core.replay(); - return true; - } - return false; -} - -control.prototype._replayAction_no = function (action) { - if (action != 'no') return false; - core.status.route.push(action); + if ( + action.indexOf("input:") == 0 || + action.indexOf("input2:") == 0 || + action.indexOf("choices:") == 0 || + action.indexOf("random:") == 0 + ) { + console.warn("警告!录像播放中出现了未知的 " + action + "!"); core.replay(); return true; -} + } + return false; +}; + +control.prototype._replayAction_no = function (action) { + if (action != "no") return false; + core.status.route.push(action); + core.replay(); + return true; +}; // ------ 存读档相关 ------ // ////// 自动存档 ////// control.prototype.autosave = function (removeLast) { - if (core.hasFlag('__forbidSave__')) return; - var x = null; - if (removeLast) { - x = core.status.route.pop(); - core.status.route.push("turn:" + core.getHeroLoc('direction')); + if (core.hasFlag("__forbidSave__")) return; + var x = null; + if (removeLast) { + x = core.status.route.pop(); + core.status.route.push("turn:" + core.getHeroLoc("direction")); + } + if (core.status.event.id == "action" && !removeLast) + // 事件中自动存档,读档后是否回到事件触发前 + core.setFlag("__events__", core.clone(core.status.event.data)); + if (core.saves.autosave.data == null) { + core.saves.autosave.data = []; + } + core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData()); + core.saves.autosave.now += 1; + if (core.saves.autosave.data.length > core.saves.autosave.max) { + if (core.saves.autosave.now < core.saves.autosave.max / 2) + core.saves.autosave.data.pop(); + else { + core.saves.autosave.data.shift(); + core.saves.autosave.now = core.saves.autosave.now - 1; } - if (core.status.event.id == 'action' && !removeLast) // 事件中自动存档,读档后是否回到事件触发前 - core.setFlag("__events__", core.clone(core.status.event.data)); - if (core.saves.autosave.data == null) { - core.saves.autosave.data = []; - } - core.saves.autosave.data.splice(core.saves.autosave.now, 0, core.saveData()); - core.saves.autosave.now += 1; - if (core.saves.autosave.data.length > core.saves.autosave.max) { - if (core.saves.autosave.now < core.saves.autosave.max / 2) - core.saves.autosave.data.pop(); - else { - core.saves.autosave.data.shift(); - core.saves.autosave.now = core.saves.autosave.now - 1; - } - } - core.saves.autosave.updated = true; - core.saves.ids[0] = true; - core.removeFlag("__events__"); - if (removeLast) { - core.status.route.pop(); - if (x) core.status.route.push(x); - } -} + } + core.saves.autosave.updated = true; + core.saves.ids[0] = true; + core.removeFlag("__events__"); + if (removeLast) { + core.status.route.pop(); + if (x) core.status.route.push(x); + } +}; /////// 实际进行自动存档 ////// control.prototype.checkAutosave = function () { - if (!core.animateFrame || !core.saves || !core.saves.autosave) return; - core.setLocalStorage('totalTime', core.animateFrame.totalTime); - var autosave = core.saves.autosave; - if (autosave.data == null || !autosave.updated || !autosave.storage) return; - autosave.updated = false; - if (autosave.data.length >= 1) { - core.setLocalForage("autoSave", autosave.data[autosave.now - 1]); - } -} + if (!core.animateFrame || !core.saves || !core.saves.autosave) return; + core.setLocalStorage("totalTime", core.animateFrame.totalTime); + var autosave = core.saves.autosave; + if (autosave.data == null || !autosave.updated || !autosave.storage) return; + autosave.updated = false; + if (autosave.data.length >= 1) { + core.setLocalForage("autoSave", autosave.data[autosave.now - 1]); + } +}; ////// 实际进行存读档事件 ////// control.prototype.doSL = function (id, type) { - switch (type) { - case 'save': this._doSL_save(id); break; - case 'load': this._doSL_load(id, this._doSL_load_afterGet); break; - case 'reload': this._doSL_reload(id, this._doSL_load_afterGet); break; - case 'replayLoad': this._doSL_load(id, this._doSL_replayLoad_afterGet); break; - case 'replayRemain': this._doSL_load(id, this._doSL_replayRemain_afterGet); break; - case 'replaySince': this._doSL_load(id, this._doSL_replaySince_afterGet); break; - } -} + switch (type) { + case "save": + this._doSL_save(id); + break; + case "load": + this._doSL_load(id, this._doSL_load_afterGet); + break; + case "reload": + this._doSL_reload(id, this._doSL_load_afterGet); + break; + case "replayLoad": + this._doSL_load(id, this._doSL_replayLoad_afterGet); + break; + case "replayRemain": + this._doSL_load(id, this._doSL_replayRemain_afterGet); + break; + case "replaySince": + this._doSL_load(id, this._doSL_replaySince_afterGet); + break; + } +}; control.prototype._doSL_save = function (id) { - if (id == 'autoSave') { - core.playSound('操作失败'); - return core.drawTip('不能覆盖自动存档!'); + if (id == "autoSave") { + core.playSound("操作失败"); + return core.drawTip("不能覆盖自动存档!"); + } + // 在事件中的存档 + if (core.status.event.interval != null) + core.setFlag("__events__", core.status.event.interval); + var data = core.saveData(); + if (core.isReplaying() && core.status.replay.toReplay.length > 0) { + data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay); + } + core.setLocalForage( + "save" + id, + data, + function () { + core.saves.saveIndex = id; + core.setLocalStorage("saveIndex", core.saves.saveIndex); + // 恢复事件 + if (!core.events.recoverEvents(core.status.event.interval)) + core.ui.closePanel(); + core.playSound("存档"); + core.drawTip("存档成功!"); + }, + function (err) { + console.error(err); + alert("存档失败,错误信息:\n" + err); } - // 在事件中的存档 - if (core.status.event.interval != null) - core.setFlag("__events__", core.status.event.interval); - var data = core.saveData(); - if (core.isReplaying() && core.status.replay.toReplay.length > 0) { - data.__toReplay__ = core.encodeRoute(core.status.replay.toReplay); - } - core.setLocalForage("save" + id, data, function () { - core.saves.saveIndex = id; - core.setLocalStorage('saveIndex', core.saves.saveIndex); - // 恢复事件 - if (!core.events.recoverEvents(core.status.event.interval)) - core.ui.closePanel(); - core.playSound('存档'); - core.drawTip('存档成功!'); - }, function (err) { - console.error(err); - alert("存档失败,错误信息:\n" + err); - }); - core.removeFlag("__events__"); - return; -} + ); + core.removeFlag("__events__"); + return; +}; control.prototype._doSL_load = function (id, callback) { - if (id == 'autoSave' && core.saves.autosave.data != null) { - core.saves.autosave.now -= 1; - var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; - if (core.isPlaying() && !core.status.gameOver) { - core.control.autosave(0); - core.saves.autosave.now -= 1; - } - if (core.saves.autosave.now == 0) { - core.saves.autosave.data.unshift(core.clone(data)); - core.saves.autosave.now += 1; + if (id == "autoSave" && core.saves.autosave.data != null) { + core.saves.autosave.now -= 1; + var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; + if (core.isPlaying() && !core.status.gameOver) { + core.control.autosave(0); + core.saves.autosave.now -= 1; + } + if (core.saves.autosave.now == 0) { + core.saves.autosave.data.unshift(core.clone(data)); + core.saves.autosave.now += 1; + } + callback(id, data); + } else { + core.getLocalForage( + id == "autoSave" ? id : "save" + id, + null, + function (data) { + if (id == "autoSave" && data != null) { + core.saves.autosave.data = data; + if (!(core.saves.autosave.data instanceof Array)) { + core.saves.autosave.data = [core.saves.autosave.data]; + } + core.saves.autosave.now = core.saves.autosave.data.length; + return core.control._doSL_load(id, callback); } callback(id, data); - } - else { - core.getLocalForage(id == 'autoSave' ? id : "save" + id, null, function (data) { - if (id == 'autoSave' && data != null) { - core.saves.autosave.data = data; - if (!(core.saves.autosave.data instanceof Array)) { - core.saves.autosave.data = [core.saves.autosave.data]; - } - core.saves.autosave.now = core.saves.autosave.data.length; - return core.control._doSL_load(id, callback); - } - callback(id, data); - }, function (err) { - console.error(err); - alert("无效的存档"); - }) - } - return; -} + }, + function (err) { + console.error(err); + alert("无效的存档"); + } + ); + } + return; +}; control.prototype._doSL_reload = function (id, callback) { - if (core.saves.autosave.data != null && core.saves.autosave.now < core.saves.autosave.data.length) { - var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; - core.control.autosave(false); - callback(id, data); - } - return; -} + if ( + core.saves.autosave.data != null && + core.saves.autosave.now < core.saves.autosave.data.length + ) { + var data = core.saves.autosave.data.splice(core.saves.autosave.now, 1)[0]; + core.control.autosave(false); + callback(id, data); + } + return; +}; control.prototype._doSL_load_afterGet = function (id, data) { - if (!data) return alert("无效的存档"); - var _replay = function () { - core.startGame(data.hard, data.hero.flags.__seed__, core.decodeRoute(data.route)); - }; - if (data.version != core.firstData.version) { - core.myconfirm("存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", _replay); - return; + if (!data) return alert("无效的存档"); + var _replay = function () { + core.startGame( + data.hard, + data.hero.flags.__seed__, + core.decodeRoute(data.route) + ); + }; + if (data.version != core.firstData.version) { + core.myconfirm( + "存档版本不匹配!\n你想回放此存档的录像吗?\n可以随时停止录像播放以继续游戏。", + _replay + ); + return; + } + if (data.hero.flags.__events__ && data.guid != core.getGuid()) { + core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay); + return; + } + core.ui.closePanel(); + core.loadData(data, function () { + core.removeFlag("__fromLoad__"); + core.drawTip("读档成功"); + if (id != "autoSave") { + core.saves.saveIndex = id; + core.setLocalStorage("saveIndex", core.saves.saveIndex); } - if (data.hero.flags.__events__ && data.guid != core.getGuid()) { - core.myconfirm("此存档可能存在风险,你想要播放录像么?", _replay); - return; - } - core.ui.closePanel(); - core.loadData(data, function () { - core.removeFlag('__fromLoad__'); - core.drawTip("读档成功"); - if (id != "autoSave") { - core.saves.saveIndex = id; - core.setLocalStorage('saveIndex', core.saves.saveIndex); - } - }); -} + }); +}; control.prototype._doSL_replayLoad_afterGet = function (id, data) { - if (!data) { - core.playSound('操作失败'); - return core.drawTip("无效的存档"); - } - if (data.version != core.firstData.version) { - core.playSound('操作失败'); - return core.drawTip("存档版本不匹配"); - } - if (data.hero.flags.__events__ && data.guid != core.getGuid()) { - core.playSound('操作失败'); - return core.drawTip("此存档可能存在风险,无法读档"); - } - var route = core.subarray(core.status.route, core.decodeRoute(data.route)); - if (route == null) { - core.playSound('操作失败'); - return core.drawTip("无法从此存档回放录像"); - } - core.loadData(data, function () { - core.removeFlag('__fromLoad__'); - core.startReplay(route); - core.drawTip("回退到存档节点"); - }); -} + if (!data) { + core.playSound("操作失败"); + return core.drawTip("无效的存档"); + } + if (data.version != core.firstData.version) { + core.playSound("操作失败"); + return core.drawTip("存档版本不匹配"); + } + if (data.hero.flags.__events__ && data.guid != core.getGuid()) { + core.playSound("操作失败"); + return core.drawTip("此存档可能存在风险,无法读档"); + } + var route = core.subarray(core.status.route, core.decodeRoute(data.route)); + if (route == null) { + core.playSound("操作失败"); + return core.drawTip("无法从此存档回放录像"); + } + core.loadData(data, function () { + core.removeFlag("__fromLoad__"); + core.startReplay(route); + core.drawTip("回退到存档节点"); + }); +}; control.prototype._doSL_replayRemain_afterGet = function (id, data) { - if (!data) { - core.playSound('操作失败'); - return core.drawTip("无效的存档"); - } - var route = core.decodeRoute(data.route); - if (core.status.tempRoute) { - var remainRoute = core.subarray(route, core.status.tempRoute); - if (remainRoute == null) - return alert("无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。"); - delete core.status.tempRoute; - core.ui.closePanel(); - core.startReplay(remainRoute); - core.drawTip("接续播放录像"); - return; - } - else if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y')) - return alert("楼层或坐标不一致!"); - - core.status.tempRoute = route; + if (!data) { + core.playSound("操作失败"); + return core.drawTip("无效的存档"); + } + var route = core.decodeRoute(data.route); + if (core.status.tempRoute) { + var remainRoute = core.subarray(route, core.status.tempRoute); + if (remainRoute == null) + return alert( + "无法接续播放录像!\n该存档必须是前一个选择的存档的后续内容。" + ); + delete core.status.tempRoute; core.ui.closePanel(); - core.drawText("\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", function () { - core.status.event.id = 'replayRemain'; - core.lockControl(); - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; - core.ui._drawSLPanel(10 * page + offset); - }); -} + core.startReplay(remainRoute); + core.drawTip("接续播放录像"); + return; + } else if ( + data.floorId != core.status.floorId || + data.hero.loc.x != core.getHeroLoc("x") || + data.hero.loc.y != core.getHeroLoc("y") + ) + return alert("楼层或坐标不一致!"); + + core.status.tempRoute = route; + core.ui.closePanel(); + core.drawText( + "\t[步骤2]请选择第二个存档。\n\r[yellow]该存档必须是前一个存档的后续。\r\n将尝试播放到此存档。", + function () { + core.status.event.id = "replayRemain"; + core.lockControl(); + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; + core.ui._drawSLPanel(10 * page + offset); + } + ); +}; control.prototype._doSL_replaySince_afterGet = function (id, data) { - if (data.floorId != core.status.floorId || data.hero.loc.x != core.getHeroLoc('x') || data.hero.loc.y != core.getHeroLoc('y')) - return alert("楼层或坐标不一致!"); - if (!data.__toReplay__) return alert('该存档没有剩余录像!'); - core.ui.closePanel(); - core.startReplay(core.decodeRoute(data.__toReplay__)); - core.drawTip("播放存档剩余录像"); - return; -} + if ( + data.floorId != core.status.floorId || + data.hero.loc.x != core.getHeroLoc("x") || + data.hero.loc.y != core.getHeroLoc("y") + ) + return alert("楼层或坐标不一致!"); + if (!data.__toReplay__) return alert("该存档没有剩余录像!"); + core.ui.closePanel(); + core.startReplay(core.decodeRoute(data.__toReplay__)); + core.drawTip("播放存档剩余录像"); + return; +}; ////// 同步存档到服务器 ////// control.prototype.syncSave = function (type) { - core.ui.drawWaiting("正在同步,请稍候..."); - var callback = function (saves) { - core.control._syncSave_http(type, saves); - } - if (type == 'all') core.getAllSaves(callback); - else core.getSave(core.saves.saveIndex, callback); -} + core.ui.drawWaiting("正在同步,请稍候..."); + var callback = function (saves) { + core.control._syncSave_http(type, saves); + }; + if (type == "all") core.getAllSaves(callback); + else core.getSave(core.saves.saveIndex, callback); +}; control.prototype._syncSave_http = function (type, saves) { - if (!saves) return core.drawText("没有要同步的存档"); - var formData = new FormData(); - formData.append('type', 'save'); - formData.append('name', core.firstData.name); - formData.append('data', LZString.compressToBase64(JSON.stringify(saves))); - formData.append('shorten', '1'); + if (!saves) return core.drawText("没有要同步的存档"); + var formData = new FormData(); + formData.append("type", "save"); + formData.append("name", core.firstData.name); + formData.append("data", LZString.compressToBase64(JSON.stringify(saves))); + formData.append("shorten", "1"); - core.http("POST", "/games/sync.php", formData, function (data) { - var response = JSON.parse(data); - if (response.code < 0) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg); - } - else { - core.drawText((type == 'all' ? "所有存档" : "存档" + core.saves.saveIndex) + "同步成功!\n\n您的存档编号+密码: \r[yellow]" - + response.code + response.msg - + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r") - } - }, function (e) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e); - }) -} + core.http( + "POST", + "/games/sync.php", + formData, + function (data) { + var response = JSON.parse(data); + if (response.code < 0) { + core.drawText( + "出错啦!\n无法同步存档到服务器。\n错误原因:" + response.msg + ); + } else { + core.drawText( + (type == "all" ? "所有存档" : "存档" + core.saves.saveIndex) + + "同步成功!\n\n您的存档编号+密码: \r[yellow]" + + response.code + + response.msg + + "\r\n\n请牢记以上信息(如截图等),在从服务器\n同步存档时使用。\n\r[yellow]另外请注意,存档同步只会保存一个月的时间。\r" + ); + } + }, + function (e) { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:" + e); + } + ); +}; ////// 从服务器加载存档 ////// control.prototype.syncLoad = function () { - core.myprompt("请输入存档编号+密码", null, function (idpassword) { - if (!idpassword) return core.ui._drawSyncSave(); - if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) { - core.drawText("不合法的存档编号+密码!"); - return; - } - core.ui.drawWaiting("正在同步,请稍候..."); - if (idpassword.length == 7) { - core.control._syncLoad_http(idpassword.substring(0, 4), idpassword.substring(4)); - } else { - core.control._syncLoad_http(idpassword.substring(0, 6), idpassword.substring(6)); - } - }); -} + core.myprompt("请输入存档编号+密码", null, function (idpassword) { + if (!idpassword) return core.ui._drawSyncSave(); + if (!/^\d{6}\w{4}$/.test(idpassword) && !/^\d{4}\w{3}$/.test(idpassword)) { + core.drawText("不合法的存档编号+密码!"); + return; + } + core.ui.drawWaiting("正在同步,请稍候..."); + if (idpassword.length == 7) { + core.control._syncLoad_http( + idpassword.substring(0, 4), + idpassword.substring(4) + ); + } else { + core.control._syncLoad_http( + idpassword.substring(0, 6), + idpassword.substring(6) + ); + } + }); +}; control.prototype._syncLoad_http = function (id, password) { - var formData = new FormData(); - formData.append('type', 'load'); - formData.append('name', core.firstData.name); - formData.append('id', id); - formData.append('password', password); + var formData = new FormData(); + formData.append("type", "load"); + formData.append("name", core.firstData.name); + formData.append("id", id); + formData.append("password", password); - core.http("POST", "/games/sync.php", formData, function (data) { - var response = JSON.parse(data); - if (response.code == 0) { - var msg = null; - try { - msg = JSON.parse(LZString.decompressFromBase64(response.msg)); - } catch (e) { } - if (!msg) { - try { - msg = JSON.parse(response.msg); - } catch (e) { } - } - if (msg) { - core.control._syncLoad_write(msg); - } else { - core.drawText("出错啦!\n存档解析失败!"); - } + core.http( + "POST", + "/games/sync.php", + formData, + function (data) { + var response = JSON.parse(data); + if (response.code == 0) { + var msg = null; + try { + msg = JSON.parse(LZString.decompressFromBase64(response.msg)); + } catch (e) {} + if (!msg) { + try { + msg = JSON.parse(response.msg); + } catch (e) {} } - else { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg); + if (msg) { + core.control._syncLoad_write(msg); + } else { + core.drawText("出错啦!\n存档解析失败!"); } - }, function (e) { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e); - }); -} + } else { + core.drawText( + "出错啦!\n无法从服务器同步存档。\n错误原因:" + response.msg + ); + } + }, + function (e) { + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:" + e); + } + ); +}; control.prototype._syncLoad_write = function (data) { - if (data instanceof Array) { - core.status.event.selection = 1; - core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { - for (var i = 1; i <= 5 * (main.savePages || 30); i++) { - if (i <= data.length) - core.setLocalForage("save" + i, data[i - 1]); - else if (core.saves.ids[i]) - core.removeLocalForage("save" + i); - } - core.ui.closePanel(); - core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); - }, function () { - core.status.event.selection = 0; - core.ui._drawSyncSave(); - }); - } - else { - // 只覆盖单存档 - core.setLocalForage("save" + core.saves.saveIndex, data, function () { - core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex); - }); - } -} + if (data instanceof Array) { + core.status.event.selection = 1; + core.ui.drawConfirmBox( + "所有本地存档都将被覆盖,确认?", + function () { + for (var i = 1; i <= 5 * (main.savePages || 30); i++) { + if (i <= data.length) core.setLocalForage("save" + i, data[i - 1]); + else if (core.saves.ids[i]) core.removeLocalForage("save" + i); + } + core.ui.closePanel(); + core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); + }, + function () { + core.status.event.selection = 0; + core.ui._drawSyncSave(); + } + ); + } else { + // 只覆盖单存档 + core.setLocalForage("save" + core.saves.saveIndex, data, function () { + core.drawText("同步成功!\n单存档已覆盖至存档" + core.saves.saveIndex); + }); + } +}; ////// 存档到本地 ////// control.prototype.saveData = function () { - return this.controldata.saveData(); -} + return this.controldata.saveData(); +}; ////// 从本地读档 ////// control.prototype.loadData = function (data, callback) { - return this.controldata.loadData(data, callback); -} + return this.controldata.loadData(data, callback); +}; control.prototype.getSave = function (index, callback) { - if (index == 0) { - // --- 自动存档先从缓存中获取 - if (core.saves.autosave.data != null) - callback(core.saves.autosave.data); - else { - core.getLocalForage("autoSave", null, function (data) { - if (data != null) { - core.saves.autosave.data = data; - if (!(core.saves.autosave.data instanceof Array)) { - core.saves.autosave.data = [core.saves.autosave.data]; - } - core.saves.autosave.now = core.saves.autosave.data.length; - } - callback(core.saves.autosave.data); - }, function (err) { - console.error(err); - callback(null); - }); + if (index == 0) { + // --- 自动存档先从缓存中获取 + if (core.saves.autosave.data != null) callback(core.saves.autosave.data); + else { + core.getLocalForage( + "autoSave", + null, + function (data) { + if (data != null) { + core.saves.autosave.data = data; + if (!(core.saves.autosave.data instanceof Array)) { + core.saves.autosave.data = [core.saves.autosave.data]; + } + core.saves.autosave.now = core.saves.autosave.data.length; + } + callback(core.saves.autosave.data); + }, + function (err) { + console.error(err); + callback(null); } - return; + ); } - core.getLocalForage("save" + index, null, function (data) { - if (callback) callback(data); - }, function (err) { - console.error(err); - if (callback) callback(null); - }); -} + return; + } + core.getLocalForage( + "save" + index, + null, + function (data) { + if (callback) callback(data); + }, + function (err) { + console.error(err); + if (callback) callback(null); + } + ); +}; control.prototype.getSaves = function (ids, callback) { - if (!(ids instanceof Array)) return this.getSave(ids, callback); - var count = ids.length, data = {}; - for (var i = 0; i < ids.length; ++i) { - (function (i) { - core.getSave(ids[i], function (result) { - data[i] = result; - if (Object.keys(data).length == count) - callback(data); - }) - })(i); - } -} + if (!(ids instanceof Array)) return this.getSave(ids, callback); + var count = ids.length, + data = {}; + for (var i = 0; i < ids.length; ++i) { + (function (i) { + core.getSave(ids[i], function (result) { + data[i] = result; + if (Object.keys(data).length == count) callback(data); + }); + })(i); + } +}; control.prototype.getAllSaves = function (callback) { - var ids = Object.keys(core.saves.ids).filter(function (x) { return x != 0; }) - .sort(function (a, b) { return a - b; }), saves = []; - this.getSaves(ids, function (data) { - for (var i = 0; i < ids.length; ++i) { - if (data[i] != null) - saves.push(data[i]); - } - callback(saves); - }); -} + var ids = Object.keys(core.saves.ids) + .filter(function (x) { + return x != 0; + }) + .sort(function (a, b) { + return a - b; + }), + saves = []; + this.getSaves(ids, function (data) { + for (var i = 0; i < ids.length; ++i) { + if (data[i] != null) saves.push(data[i]); + } + callback(saves); + }); +}; ////// 获得所有存在存档的存档位 ////// control.prototype.getSaveIndexes = function (callback) { - var indexes = {}; - core.keysLocalForage(function (err, keys) { - if (err) { - console.error(err); - return callback(indexes); - } - keys.forEach(function (key) { - core.control._getSaveIndexes_getIndex(indexes, key); - }); - callback(indexes); + var indexes = {}; + core.keysLocalForage(function (err, keys) { + if (err) { + console.error(err); + return callback(indexes); + } + keys.forEach(function (key) { + core.control._getSaveIndexes_getIndex(indexes, key); }); -} + callback(indexes); + }); +}; control.prototype._getSaveIndexes_getIndex = function (indexes, name) { - var e = new RegExp('^' + core.firstData.name + "_(save\\d+|autoSave)$").exec(name); - if (e) { - if (e[1] == 'autoSave') indexes[0] = true; - else indexes[parseInt(e[1].substring(4))] = true; - } -} + var e = new RegExp("^" + core.firstData.name + "_(save\\d+|autoSave)$").exec( + name + ); + if (e) { + if (e[1] == "autoSave") indexes[0] = true; + else indexes[parseInt(e[1].substring(4))] = true; + } +}; ////// 判断某个存档位是否存在存档 ////// control.prototype.hasSave = function (index) { - return core.saves.ids[index] || false; -} + return core.saves.ids[index] || false; +}; ////// 删除某个存档 control.prototype.removeSave = function (index, callback) { - if (index == 0 || index == "autoSave") { - index = "autoSave"; - core.removeLocalForage(index, function () { - core.saves.autosave.data = null; - core.saves.autosave.updated = false; - if (callback) callback(); - }); - return; - } - core.removeLocalForage("save" + index, function () { - core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); - delete core.saves.favoriteName[index]; - core.control._updateFavoriteSaves(); - if (callback) callback(); - }, function () { - core.playSound('操作失败'); - core.drawTip("无法删除存档!"); - if (callback) callback(); + if (index == 0 || index == "autoSave") { + index = "autoSave"; + core.removeLocalForage(index, function () { + core.saves.autosave.data = null; + core.saves.autosave.updated = false; + if (callback) callback(); }); -} + return; + } + core.removeLocalForage( + "save" + index, + function () { + core.saves.favorite = core.saves.favorite.filter(function (i) { + return core.hasSave(i); + }); + delete core.saves.favoriteName[index]; + core.control._updateFavoriteSaves(); + if (callback) callback(); + }, + function () { + core.playSound("操作失败"); + core.drawTip("无法删除存档!"); + if (callback) callback(); + } + ); +}; ////// 读取收藏信息 control.prototype._loadFavoriteSaves = function () { - core.saves.favorite = core.getLocalStorage("favorite", []); - // --- 移除不存在的收藏 - core.saves.favorite = core.saves.favorite.filter(function (i) { return core.hasSave(i); }); - core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); -} + core.saves.favorite = core.getLocalStorage("favorite", []); + // --- 移除不存在的收藏 + core.saves.favorite = core.saves.favorite.filter(function (i) { + return core.hasSave(i); + }); + core.saves.favoriteName = core.getLocalStorage("favoriteName", {}); +}; control.prototype._updateFavoriteSaves = function () { - core.setLocalStorage("favorite", core.saves.favorite); - core.setLocalStorage("favoriteName", core.saves.favoriteName); -} + core.setLocalStorage("favorite", core.saves.favorite); + core.setLocalStorage("favoriteName", core.saves.favoriteName); +}; // ------ 属性,状态,位置,buff,变量,锁定控制等 ------ // ////// 设置勇士属性 ////// control.prototype.setStatus = function (name, value) { - if (!core.status.hero) return; - if (name == 'x' || name == 'y' || name == 'direction') - this.setHeroLoc(name, value); - else - core.status.hero[name] = value; -} + if (!core.status.hero) return; + if (name == "x" || name == "y" || name == "direction") + this.setHeroLoc(name, value); + else core.status.hero[name] = value; +}; ////// 增减勇士属性 ////// control.prototype.addStatus = function (name, value) { - this.setStatus(name, this.getStatus(name) + value); -} + this.setStatus(name, this.getStatus(name) + value); +}; ////// 获得勇士属性 ////// control.prototype.getStatus = function (name) { - if (!core.status.hero) return null; - if (name == 'x' || name == 'y' || name == 'direction') - return this.getHeroLoc(name); - if (main.mode == 'editor' && !core.hasFlag('__statistics__')) { - return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; - } - return core.status.hero[name]; -} + if (!core.status.hero) return null; + if (name == "x" || name == "y" || name == "direction") + return this.getHeroLoc(name); + if (main.mode == "editor" && !core.hasFlag("__statistics__")) { + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; + } + return core.status.hero[name]; +}; ////// 从status中获得属性,如果不存在则从勇士属性中获取 ////// control.prototype.getStatusOrDefault = function (status, name) { - if (status && name in status) - return Math.floor(status[name]); - return Math.floor(this.getStatus(name)); -} + if (status && name in status) return Math.floor(status[name]); + return Math.floor(this.getStatus(name)); +}; ////// 获得勇士实际属性(增幅后的) ////// control.prototype.getRealStatus = function (name) { - return this.getRealStatusOrDefault(null, name); -} + return this.getRealStatusOrDefault(null, name); +}; ////// 从status中获得实际属性(增幅后的),如果不存在则从勇士属性中获取 ////// control.prototype.getRealStatusOrDefault = function (status, name) { - return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name)); -} + return Math.floor(this.getStatusOrDefault(status, name) * this.getBuff(name)); +}; ////// 获得勇士原始属性(无装备和衰弱影响) ////// control.prototype.getNakedStatus = function (name) { - var value = this.getStatus(name); - if (value == null) return value; - // 装备增幅 - core.status.hero.equipment.forEach(function (v) { - if (!v || !(core.material.items[v] || {}).equip) return; - value -= core.material.items[v].equip.value[name] || 0; - }); - // 衰弱扣除 - if (core.hasFlag('weak') && core.values.weakValue >= 1 && (name == 'atk' || name == 'def')) { - value += core.values.weakValue; - } - return value; -} + var value = this.getStatus(name); + if (value == null) return value; + // 装备增幅 + core.status.hero.equipment.forEach(function (v) { + if (!v || !(core.material.items[v] || {}).equip) return; + value -= core.material.items[v].equip.value[name] || 0; + }); + // 衰弱扣除 + if ( + core.hasFlag("weak") && + core.values.weakValue >= 1 && + (name == "atk" || name == "def") + ) { + value += core.values.weakValue; + } + return value; +}; ////// 获得某个属性的名字 ////// control.prototype.getStatusLabel = function (name) { - if (this.controldata.getStatusLabel) { - return this.controldata.getStatusLabel(name) || name; - } - return { - name: "名称", lv: "等级", hpmax: "生命上限", hp: "生命", manamax: "魔力上限", mana: "魔力", - atk: "攻击", def: "防御", mdef: "护盾", money: "金币", exp: "经验", point: "加点", steps: "步数" - }[name] || name; -} + if (this.controldata.getStatusLabel) { + return this.controldata.getStatusLabel(name) || name; + } + return ( + { + name: "名称", + lv: "等级", + hpmax: "生命上限", + hp: "生命", + manamax: "魔力上限", + mana: "魔力", + atk: "攻击", + def: "防御", + mdef: "护盾", + money: "金币", + exp: "经验", + point: "加点", + steps: "步数", + }[name] || name + ); +}; ////// 设置某个属性的增幅值 ////// control.prototype.setBuff = function (name, value) { - // 仅保留三位有效buff值 - value = parseFloat(value.toFixed(3)); - this.setFlag('__' + name + '_buff__', value); -} + // 仅保留三位有效buff值 + value = parseFloat(value.toFixed(3)); + this.setFlag("__" + name + "_buff__", value); +}; ////// 加减某个属性的增幅值 ////// control.prototype.addBuff = function (name, value) { - var buff = this.getBuff(name) + value; - // 仅保留三位有效buff值 - buff = parseFloat(buff.toFixed(3)); - this.setFlag('__' + name + '_buff__', buff); -} + var buff = this.getBuff(name) + value; + // 仅保留三位有效buff值 + buff = parseFloat(buff.toFixed(3)); + this.setFlag("__" + name + "_buff__", buff); +}; ////// 获得某个属性的增幅值 ////// control.prototype.getBuff = function (name) { - return core.getFlag('__' + name + '_buff__', 1); -} + return core.getFlag("__" + name + "_buff__", 1); +}; ////// 获得或移除毒衰咒效果 ////// control.prototype.triggerDebuff = function (action, type) { - return this.controldata.triggerDebuff(action, type); -} + return this.controldata.triggerDebuff(action, type); +}; ////// 设置勇士的位置 ////// control.prototype.setHeroLoc = function (name, value, noGather) { - if (!core.status.hero) return; - core.status.hero.loc[name] = value; - if ((name == 'x' || name == 'y') && !noGather) { - this.gatherFollowers(); - } - core.ui.drawStatusBar(); -} + if (!core.status.hero) return; + core.status.hero.loc[name] = value; + if ((name == "x" || name == "y") && !noGather) { + this.gatherFollowers(); + } + core.ui.drawStatusBar(); +}; ////// 获得勇士的位置 ////// control.prototype.getHeroLoc = function (name) { - if (!core.status.hero) return; - if (main.mode == 'editor') { - if (name == null) return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc; - return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name]; - } - if (name == null) return core.status.hero.loc; - return core.status.hero.loc[name]; -} + if (!core.status.hero) return; + if (main.mode == "editor") { + if (name == null) + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc; + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero.loc[name]; + } + if (name == null) return core.status.hero.loc; + return core.status.hero.loc[name]; +}; ////// 获得某个等级的名称 ////// control.prototype.getLvName = function (lv) { - if (!core.status.hero) return null; - if (lv == null) lv = core.status.hero.lv; - return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv; -} + if (!core.status.hero) return null; + if (lv == null) lv = core.status.hero.lv; + return ((core.firstData.levelUp || [])[lv - 1] || {}).title || lv; +}; ////// 获得下个等级所需经验;如果不存在下个等级,返回null。 ////// control.prototype.getNextLvUpNeed = function () { - if (!core.status.hero) return null; - if (core.status.hero.lv >= core.firstData.levelUp.length) return null; - var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need); - if (core.flags.statusBarItems.indexOf('levelUpLeftMode') >= 0) - return Math.max(need - core.getStatus('exp'), 0); - else return need; -} + if (!core.status.hero) return null; + if (core.status.hero.lv >= core.firstData.levelUp.length) return null; + var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need); + if (core.flags.statusBarItems.indexOf("levelUpLeftMode") >= 0) + return Math.max(need - core.getStatus("exp"), 0); + else return need; +}; ////// 设置某个自定义变量或flag ////// control.prototype.setFlag = function (name, value) { - if (value == null) return this.removeFlag(name); - if (!core.status.hero) return; - core.status.hero.flags[name] = value; -} + if (value == null) return this.removeFlag(name); + if (!core.status.hero) return; + core.status.hero.flags[name] = value; +}; ////// 增加某个flag数值 ////// control.prototype.addFlag = function (name, value) { - if (!core.status.hero) return; - core.setFlag(name, core.getFlag(name, 0) + value); -} + if (!core.status.hero) return; + core.setFlag(name, core.getFlag(name, 0) + value); +}; ////// 获得某个自定义变量或flag ////// control.prototype.getFlag = function (name, defaultValue) { - if (!core.status.hero) return defaultValue; - var value = core.status.hero.flags[name]; - return value != null ? value : defaultValue; -} + if (!core.status.hero) return defaultValue; + var value = core.status.hero.flags[name]; + return value != null ? value : defaultValue; +}; ////// 是否存在某个自定义变量或flag,且值为true ////// control.prototype.hasFlag = function (name) { - return !!core.getFlag(name); -} + return !!core.getFlag(name); +}; ////// 删除某个自定义变量或flag ////// control.prototype.removeFlag = function (name) { - if (!core.status.hero) return; - delete core.status.hero.flags[name]; -} + if (!core.status.hero) return; + delete core.status.hero.flags[name]; +}; ////// 获得某个点的独立开关 ////// control.prototype.getSwitch = function (x, y, floorId, name, defaultValue) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.getFlag(prefix + "@" + name, defaultValue); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.getFlag(prefix + "@" + name, defaultValue); +}; ////// 设置某个点的独立开关 ////// control.prototype.setSwitch = function (x, y, floorId, name, value) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.setFlag(prefix + "@" + name, value); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.setFlag(prefix + "@" + name, value); +}; ////// 增加某个点的独立开关 ////// control.prototype.addSwitch = function (x, y, floorId, name, value) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.addFlag(prefix + "@" + name, value); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.addFlag(prefix + "@" + name, value); +}; ////// 判定某个点的独立开关 ////// control.prototype.hasSwitch = function (x, y, floorId, name) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.hasFlag(prefix + "@" + name); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.hasFlag(prefix + "@" + name); +}; ////// 删除某个点的独立开关 ////// control.prototype.removeSwitch = function (x, y, floorId, name) { - var prefix = [floorId || core.status.floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - return this.removeFlag(prefix + "@" + name); -} + var prefix = [ + floorId || core.status.floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + return this.removeFlag(prefix + "@" + name); +}; ////// 锁定状态栏,常常用于事件处理 ////// control.prototype.lockControl = function () { - core.status.lockControl = true; -} + core.status.lockControl = true; +}; ////// 解锁状态栏 ////// control.prototype.unlockControl = function () { - core.status.lockControl = false; -} + core.status.lockControl = false; +}; ////// 开启debug模式 ////// control.prototype.debug = function () { - core.setFlag('debug', true); - core.drawText("\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。"); -} + core.setFlag("debug", true); + core.drawText( + "\t[调试模式开启]此模式下按住Ctrl键(或Ctrl+Shift键)可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。" + ); +}; control.prototype._bindRoutePush = function () { - core.status.route.push = function (element) { - // 忽视移动、转向、瞬移 - if (["up", "down", "left", "right", "turn"].indexOf(element) < 0 && !element.startsWith("move:")) { - core.clearRouteFolding(); - } - Array.prototype.push.call(core.status.route, element); + core.status.route.push = function (element) { + // 忽视移动、转向、瞬移 + if ( + ["up", "down", "left", "right", "turn"].indexOf(element) < 0 && + !element.startsWith("move:") + ) { + core.clearRouteFolding(); } -} + Array.prototype.push.call(core.status.route, element); + }; +}; ////// 清除录像折叠信息 ////// control.prototype.clearRouteFolding = function () { - core.status.routeFolding = {}; -} + core.status.routeFolding = {}; +}; ////// 检查录像折叠 ////// control.prototype.checkRouteFolding = function () { - // 未开启、未开始游戏、录像播放中、正在事件中:不执行 - if (!core.flags.enableRouteFolding || !core.isPlaying() || core.isReplaying() || core.status.event.id) { - return this.clearRouteFolding(); + // 未开启、未开始游戏、录像播放中、正在事件中:不执行 + if ( + !core.flags.enableRouteFolding || + !core.isPlaying() || + core.isReplaying() || + core.status.event.id + ) { + return this.clearRouteFolding(); + } + var hero = core.clone(core.status.hero, function (name, value) { + return name != "steps" && typeof value == "number"; + }); + var index = [ + core.getHeroLoc("x"), + core.getHeroLoc("y"), + core.getHeroLoc("direction").charAt(0), + ].join(","); + core.status.routeFolding = core.status.routeFolding || {}; + if (core.status.routeFolding[index]) { + var one = core.status.routeFolding[index]; + if (core.same(one.hero, hero) && one.length < core.status.route.length) { + Object.keys(core.status.routeFolding).forEach(function (v) { + if (core.status.routeFolding[v].length >= one.length) + delete core.status.routeFolding[v]; + }); + core.status.route = core.status.route.slice(0, one.length); + this._bindRoutePush(); } - var hero = core.clone(core.status.hero, function (name, value) { - return name != 'steps' && typeof value == 'number'; - }); - var index = [core.getHeroLoc('x'), core.getHeroLoc('y'), core.getHeroLoc('direction').charAt(0)].join(','); - core.status.routeFolding = core.status.routeFolding || {}; - if (core.status.routeFolding[index]) { - var one = core.status.routeFolding[index]; - if (core.same(one.hero, hero) && one.length < core.status.route.length) { - Object.keys(core.status.routeFolding).forEach(function (v) { - if (core.status.routeFolding[v].length >= one.length) delete core.status.routeFolding[v]; - }); - core.status.route = core.status.route.slice(0, one.length); - this._bindRoutePush(); - } - } - core.status.routeFolding[index] = { hero: hero, length: core.status.route.length }; -} + } + core.status.routeFolding[index] = { + hero: hero, + length: core.status.route.length, + }; +}; // ------ 天气,色调,BGM ------ // control.prototype.getMappedName = function (name) { - return core.getFlag('__nameMap__', {})[name] || (main.nameMap || {})[name] || name; -} + return ( + core.getFlag("__nameMap__", {})[name] || (main.nameMap || {})[name] || name + ); +}; ////// 更改天气效果 ////// control.prototype.setWeather = function (type, level) { - // 非雨雪 - if (type == null || !this.weathers[type]) { - core.deleteCanvas('weather') - core.animateFrame.weather.type = null; - core.animateFrame.weather.nodes = []; - return; - } - if (level == null) level = core.animateFrame.weather.level; - level = core.clamp(parseInt(level) || 5, 1, 10); - // 当前天气:则忽略 - if (type == core.animateFrame.weather.type && level == core.animateFrame.weather.level) return; - - // 计算当前的宽高 - core.createCanvas('weather', 0, 0, core._PX_, core._PY_, 80); - core.setOpacity('weather', 1.0); - core.animateFrame.weather.type = type; - core.animateFrame.weather.level = level; + // 非雨雪 + if (type == null || !this.weathers[type]) { + core.deleteCanvas("weather"); + core.animateFrame.weather.type = null; core.animateFrame.weather.nodes = []; - try { - core.doFunc(this.weathers[type].initFunc, this, level); - } catch (e) { - console.error(e); - console.error("ERROR in weather[" + type + "]:已自动注销该项。"); - core.unregisterWeather(type); - } -} + return; + } + if (level == null) level = core.animateFrame.weather.level; + level = core.clamp(parseInt(level) || 5, 1, 10); + // 当前天气:则忽略 + if ( + type == core.animateFrame.weather.type && + level == core.animateFrame.weather.level + ) + return; + + // 计算当前的宽高 + core.createCanvas("weather", 0, 0, core._PX_, core._PY_, 80); + core.setOpacity("weather", 1.0); + core.animateFrame.weather.type = type; + core.animateFrame.weather.level = level; + core.animateFrame.weather.nodes = []; + try { + core.doFunc(this.weathers[type].initFunc, this, level); + } catch (e) { + console.error(e); + console.error("ERROR in weather[" + type + "]:已自动注销该项。"); + core.unregisterWeather(type); + } +}; ////// 注册一个天气 ////// // name为天气类型,如 sun, rain, snow 等 // initFunc 为设置为此天气时的初始化,接受level参数 // frameFunc 为该天气下每帧的效果,接受和timestamp参数(从页面加载完毕到当前经过的时间) control.prototype.registerWeather = function (name, initFunc, frameFunc) { - this.unregisterWeather(name); - this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc }; -} + this.unregisterWeather(name); + this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc }; +}; ////// 取消注册一个天气 ////// control.prototype.unregisterWeather = function (name) { - delete this.weathers[name]; - if (core.animateFrame.weather.type == name) { - this.setWeather(null); - } -} + delete this.weathers[name]; + if (core.animateFrame.weather.type == name) { + this.setWeather(null); + } +}; control.prototype._weather_rain = function (level) { - var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core._WIDTH_ * core._HEIGHT_)); - for (var a = 0; a < number; a++) { - core.animateFrame.weather.nodes.push({ - 'x': Math.random() * core.bigmap.width * 32, - 'y': Math.random() * core.bigmap.height * 32, - 'l': Math.random() * 2.5, - 'xs': -4 + Math.random() * 4 + 2, - 'ys': Math.random() * 10 + 10 - }) - } -} + var number = + level * + parseInt( + (20 * core.bigmap.width * core.bigmap.height) / + (core._WIDTH_ * core._HEIGHT_) + ); + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + l: Math.random() * 2.5, + xs: -4 + Math.random() * 4 + 2, + ys: Math.random() * 10 + 10, + }); + } +}; control.prototype._weather_snow = function (level) { - var number = level * parseInt(20 * core.bigmap.width * core.bigmap.height / (core._WIDTH_ * core._HEIGHT_)); - for (var a = 0; a < number; a++) { - core.animateFrame.weather.nodes.push({ - 'x': Math.random() * core.bigmap.width * 32, - 'y': Math.random() * core.bigmap.height * 32, - 'r': Math.random() * 5 + 1, - 'd': Math.random() * Math.min(level, 200), - }) - } -} + var number = + level * + parseInt( + (20 * core.bigmap.width * core.bigmap.height) / + (core._WIDTH_ * core._HEIGHT_) + ); + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + r: Math.random() * 5 + 1, + d: Math.random() * Math.min(level, 200), + }); + } +}; control.prototype._weather_fog = function (level) { - if (!core.animateFrame.weather.fog) return; - core.animateFrame.weather.nodes = [{ - 'image': core.animateFrame.weather.fog, - 'level': 40 * level, - 'x': 0, - 'y': -core._PY_ / 2, - 'dx': -Math.random() * 1.5, - 'dy': Math.random(), - 'delta': 0.001, - }]; -} + if (!core.animateFrame.weather.fog) return; + core.animateFrame.weather.nodes = [ + { + image: core.animateFrame.weather.fog, + level: 40 * level, + x: 0, + y: -core._PY_ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; +}; control.prototype._weather_cloud = function (level) { - if (!core.animateFrame.weather.cloud) return; - core.animateFrame.weather.nodes = [{ - 'image': core.animateFrame.weather.cloud, - 'level': 40 * level, - 'x': 0, - 'y': -core._PY_ / 2, - 'dx': -Math.random() * 1.5, - 'dy': Math.random(), - 'delta': 0.001, - }]; -} + if (!core.animateFrame.weather.cloud) return; + core.animateFrame.weather.nodes = [ + { + image: core.animateFrame.weather.cloud, + level: 40 * level, + x: 0, + y: -core._PY_ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; +}; control.prototype._weather_sun = function (level) { - if (!core.animateFrame.weather.sun) return; - // 直接绘制 - core.clearMap('weather'); - core.drawImage( - 'weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core._PX_, core._PY_ - ); - core.setOpacity('weather', level / 10); - core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }]; -} + if (!core.animateFrame.weather.sun) return; + // 直接绘制 + core.clearMap("weather"); + core.drawImage( + "weather", + core.animateFrame.weather.sun, + 0, + 0, + core.animateFrame.weather.sun.width, + core.animateFrame.weather.sun.height, + 0, + 0, + core._PX_, + core._PY_ + ); + core.setOpacity("weather", level / 10); + core.animateFrame.weather.nodes = [{ opacity: level / 10, delta: 0.01 }]; +}; ////// 更改画面色调 ////// control.prototype.setCurtain = function (color, time, moveMode, callback) { - if (time == null) time = 750; - if (time <= 0) time = 0; - if (!core.status.curtainColor) - core.status.curtainColor = [0, 0, 0, 0]; - if (!color) color = [0, 0, 0, 0]; - if (color[3] == null) color[3] = 1; - color[3] = core.clamp(color[3], 0, 1); + if (time == null) time = 750; + if (time <= 0) time = 0; + if (!core.status.curtainColor) core.status.curtainColor = [0, 0, 0, 0]; + if (!color) color = [0, 0, 0, 0]; + if (color[3] == null) color[3] = 1; + color[3] = core.clamp(color[3], 0, 1); - if (time == 0) { - // 直接变色 - core.clearMap('curtain'); - core.fillRect('curtain', 0, 0, core._PX_, core._PY_, core.arrayToRGBA(color)); - core.status.curtainColor = color; - if (callback) callback(); - return; + if (time == 0) { + // 直接变色 + core.clearMap("curtain"); + core.fillRect( + "curtain", + 0, + 0, + core._PX_, + core._PY_, + core.arrayToRGBA(color) + ); + core.status.curtainColor = color; + if (callback) callback(); + return; + } + + this._setCurtain_animate( + core.status.curtainColor, + color, + time, + moveMode, + callback + ); +}; + +control.prototype._setCurtain_animate = function ( + nowColor, + color, + time, + moveMode, + callback +) { + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) steps = 1; + var curr = nowColor; + var moveFunc = core.applyEasing(moveMode); + + var cb = function () { + core.status.curtainColor = curr; + if (callback) callback(); + }; + var animate = setInterval(function () { + step++; + curr = [ + nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps), + nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps), + nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps), + nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps), + ]; + core.clearMap("curtain"); + core.fillRect( + "curtain", + 0, + 0, + core._PX_, + core._PY_, + core.arrayToRGBA(curr) + ); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); } + }, per_time); - this._setCurtain_animate(core.status.curtainColor, color, time, moveMode, callback); -} - -control.prototype._setCurtain_animate = function (nowColor, color, time, moveMode, callback) { - time /= Math.max(core.status.replay.speed, 1) - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) steps = 1; - var curr = nowColor; - var moveFunc = core.applyEasing(moveMode); - - var cb = function () { - core.status.curtainColor = curr; - if (callback) callback(); - } - var animate = setInterval(function () { - step++; - curr = [ - nowColor[0] + (color[0] - nowColor[0]) * moveFunc(step / steps), - nowColor[1] + (color[1] - nowColor[1]) * moveFunc(step / steps), - nowColor[2] + (color[2] - nowColor[2]) * moveFunc(step / steps), - nowColor[3] + (color[3] - nowColor[3]) * moveFunc(step / steps), - ] - core.clearMap('curtain'); - core.fillRect('curtain', 0, 0, core._PX_, core._PY_, core.arrayToRGBA(curr)); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 画面闪烁 ////// -control.prototype.screenFlash = function (color, time, times, moveMode, callback) { - times = times || 1; - time = time / 3; - var nowColor = core.clone(core.status.curtainColor); - core.setCurtain(color, time, moveMode, function () { - core.setCurtain(nowColor, time * 2, moveMode, function () { - if (times > 1) - core.screenFlash(color, time * 3, times - 1, moveMode, callback); - else { - if (callback) callback(); - } - }); +control.prototype.screenFlash = function ( + color, + time, + times, + moveMode, + callback +) { + times = times || 1; + time = time / 3; + var nowColor = core.clone(core.status.curtainColor); + core.setCurtain(color, time, moveMode, function () { + core.setCurtain(nowColor, time * 2, moveMode, function () { + if (times > 1) + core.screenFlash(color, time * 3, times - 1, moveMode, callback); + else { + if (callback) callback(); + } }); -} + }); +}; ////// 播放背景音乐 ////// control.prototype.playBgm = function (bgm, startTime) { - bgm = core.getMappedName(bgm); - if (main.mode != 'play' || !core.material.bgms[bgm]) return; - // 如果不允许播放 - if (!core.musicStatus.bgmStatus) { - try { - core.musicStatus.playingBgm = bgm; - core.musicStatus.lastBgm = bgm; - core.material.bgms[bgm].pause(); - } - catch (e) { - console.error(e); - } - return; - } - this.setMusicBtn(); - + bgm = core.getMappedName(bgm); + if (main.mode != "play" || !core.material.bgms[bgm]) return; + // 如果不允许播放 + if (!core.musicStatus.bgmStatus) { try { - this._playBgm_play(bgm, startTime); + core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; + core.material.bgms[bgm].pause(); + } catch (e) { + console.error(e); } - catch (e) { - console.log("无法播放BGM " + bgm); - console.error(e); - core.musicStatus.playingBgm = null; - } -} + return; + } + this.setMusicBtn(); + + try { + this._playBgm_play(bgm, startTime); + } catch (e) { + console.log("无法播放BGM " + bgm); + console.error(e); + core.musicStatus.playingBgm = null; + } +}; control.prototype._playBgm_play = function (bgm, startTime) { - // 如果当前正在播放,且和本BGM相同,直接忽略 - if (core.musicStatus.playingBgm == bgm && !core.material.bgms[core.musicStatus.playingBgm].paused) { - return; - } - // 如果正在播放中,暂停 - if (core.musicStatus.playingBgm) { - core.material.bgms[core.musicStatus.playingBgm].pause(); - } - // 缓存BGM - core.loader.loadBgm(bgm); - // 播放当前BGM - core.material.bgms[bgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume; - core.material.bgms[bgm].currentTime = startTime || 0; - core.material.bgms[bgm].play(); - core.musicStatus.playingBgm = bgm; - core.musicStatus.lastBgm = bgm; - core.setBgmSpeed(100); -} + // 如果当前正在播放,且和本BGM相同,直接忽略 + if ( + core.musicStatus.playingBgm == bgm && + !core.material.bgms[core.musicStatus.playingBgm].paused + ) { + return; + } + // 如果正在播放中,暂停 + if (core.musicStatus.playingBgm) { + core.material.bgms[core.musicStatus.playingBgm].pause(); + } + // 缓存BGM + core.loader.loadBgm(bgm); + // 播放当前BGM + core.material.bgms[bgm].volume = + core.musicStatus.userVolume * core.musicStatus.designVolume; + core.material.bgms[bgm].currentTime = startTime || 0; + core.material.bgms[bgm].play(); + core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; + core.setBgmSpeed(100); +}; ///// 设置当前背景音乐的播放速度 ////// control.prototype.setBgmSpeed = function (speed, usePitch) { - var bgm = core.musicStatus.playingBgm; - if (main.mode != 'play' || !core.material.bgms[bgm]) return; - bgm = core.material.bgms[bgm]; - if (speed < 30 || speed > 300) return; - bgm.playbackRate = speed / 100; - core.musicStatus.bgmSpeed = speed; + var bgm = core.musicStatus.playingBgm; + if (main.mode != "play" || !core.material.bgms[bgm]) return; + bgm = core.material.bgms[bgm]; + if (speed < 30 || speed > 300) return; + bgm.playbackRate = speed / 100; + core.musicStatus.bgmSpeed = speed; - if (bgm.preservesPitch != null) { - if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch; - if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch; - else if (usePitch) bgm.preservesPitch = false; - else bgm.preservesPitch = true; - core.musicStatus.bgmUsePitch = usePitch; - } -} + if (bgm.preservesPitch != null) { + if (bgm.__preservesPitch == null) bgm.__preservesPitch = bgm.preservesPitch; + if (usePitch == null) bgm.preservesPitch = bgm.__preservesPitch; + else if (usePitch) bgm.preservesPitch = false; + else bgm.preservesPitch = true; + core.musicStatus.bgmUsePitch = usePitch; + } +}; ////// 暂停背景音乐的播放 ////// control.prototype.pauseBgm = function () { - if (main.mode != 'play') return; - try { - if (core.musicStatus.playingBgm) { - core.musicStatus.pauseTime = core.material.bgms[core.musicStatus.playingBgm].currentTime; - core.material.bgms[core.musicStatus.playingBgm].pause(); - core.musicStatus.playingBgm = null; - } + if (main.mode != "play") return; + try { + if (core.musicStatus.playingBgm) { + core.musicStatus.pauseTime = + core.material.bgms[core.musicStatus.playingBgm].currentTime; + core.material.bgms[core.musicStatus.playingBgm].pause(); + core.musicStatus.playingBgm = null; } - catch (e) { - console.log("无法暂停BGM"); - console.error(e); - } - this.setMusicBtn(); -} + } catch (e) { + console.log("无法暂停BGM"); + console.error(e); + } + this.setMusicBtn(); +}; ////// 恢复背景音乐的播放 ////// control.prototype.resumeBgm = function (resumeTime) { - if (main.mode != 'play') return; - try { - var speed = core.musicStatus.bgmSpeed; - var usePitch = core.musicStatus.bgmUsePitch; - core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm, - resumeTime ? core.musicStatus.pauseTime : 0); - if (resumeTime) { - core.setBgmSpeed(speed, usePitch); - } + if (main.mode != "play") return; + try { + var speed = core.musicStatus.bgmSpeed; + var usePitch = core.musicStatus.bgmUsePitch; + core.playBgm( + core.musicStatus.playingBgm || core.musicStatus.lastBgm || main.startBgm, + resumeTime ? core.musicStatus.pauseTime : 0 + ); + if (resumeTime) { + core.setBgmSpeed(speed, usePitch); } - catch (e) { - console.log("无法恢复BGM"); - console.error(e); - } - this.setMusicBtn(); -} + } catch (e) { + console.log("无法恢复BGM"); + console.error(e); + } + this.setMusicBtn(); +}; control.prototype.setMusicBtn = function () { - if (core.musicStatus.bgmStatus) - core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII="; - else - core.dom.musicBtn.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg=="; -} + if (core.musicStatus.bgmStatus) + core.dom.musicBtn.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABWVBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL///8AAAC5ubn+/v6xsbEtLS0MDAxmZmZoaGhvb2/c3Nzd3d38/Pz9/f0oKCgpKSl0dHR1dXW6urrb29v7+/v09PTv7+/39/cgICACAgImJibh4eGFhYWGhoaHh4eOjo5paWm7u7vDw8PMzMwyMjI7OztAQEDe3t5FRUVMTEzj4+Pl5eXm5ubp6enr6+tcXFzi4uL19fVeXl74+PgjIyNkZGQGBgaSkpKYmJiampqenp4DAwMwMDBnZ2cICAivr68eHh63t7cLCwsSEhLw8PBhYWEUFBQVFRXNzc3Pz8/Z2dna2toaGhqkpKSlpaWpqamrq6tFOUNAAAAAc3RSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyA0IuUgAAAVdJREFUeF5NkVVbw0AQRTcQrLR4IIEGcidJoaUuQHF3d3d3+P/CkuxCzss8nG++mbnDBJXhNt2CpbeFK1kQpSEKidlc8S9qdATRa6UIdQMoxEpDA0Ov3wUAPfW+qLWACydNv9zMrzkJwPK6FB3oHyOfXfuNxvoBQ+GmBYinhHB77TmiVBxoYUw1AYcEq332AS8OYKosAuTT0nza9uU2USYPRJgGxEiSOFywJ3mNARozgBJJzkfLvfu8JgGDWcC9FEsjWzR+y80gYDEAA8QZ3N6kmP1Fs3fEASB7pob7Hh+Wz5L0ci17Or05J7bH6B6dZv05XWK3rG+myV05Ert592Qo55sPuoIr7hEZHHtieIPWy0RU9DLwc3Mnck/vi8/E8XNrDWQtEVnL/ySKMrv0jPwPp870fprcyYifmiEmqGpHkI5q9ofSFIUk2qiwIGpEMyxYhhZRRcMPz89RJ2s9W8wAAAAASUVORK5CYII="; + else + core.dom.musicBtn.src = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAABYlBMVEX///9iYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmL////8/PwAAABmZmZoaGihoaGioqKxsbG5ubnb29vc3Nzd3d3h4eHi4uL9/f3+/v4tLS1nZ2d0dHSUlJSenp66uroMDAz7+/spKSkoKCgUFBRpaWkVFRVvb291dXU7OzuVlZWYmJhkZGQgICAjIyOkpKQCAgK3t7cGBgbv7++pqamrq6seHh4mJiZhYWGamprp6enr6+saGhpeXl7j4+Pl5eXm5uZKSkrw8PD09PT19fW7u7vDw8PMzMwICAgwMDAyMjILCwtAQECGhoaHh4eBgYGFhYUSEhJXV1dZWVlcXFyOjo6SkpLNzc339/fPz8/Z2dna2tqTk5OlpaWxOPeTAAAAdnRSTlMAAwQFBhUWGxwkJSYyO0dISVBRUmpvj5CSk5SVoaOlpqiysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKyNuo+uwAAAWJJREFUeF5NkmV34zAQReUm7WbTuJBNunY3bvXGDjNTkZkZlpn5/9eR5FPfbzr3jGb0RkwRiMQMDm7EIgHmRxtLwMOaHHoQjwz4MUKeCM8AWMrmd7u7f/aXAMyOShHiQD1n04DtN5e5FMBFlSauIsm585dKi4CpuSYKJIv1tBDVmvOSqJgEoowFLSBHaQh10XHWiCgHWEGmAw2blPrvOK/KRJUGoLM4kCVSKrWz7HwgoiwQZyaQJ0+9PvxV23BNATAZB25IqX9b3+jTW9fcApwB6NLgUD5NY3mPXnwmFwBezff1ztzRFzTp94FXMy36HDuCa2RafdnnmZqtL818Gl9/qNnEeyrUk2aTPiKj3qMyWBVi/YSuWq5qiwxkbtX3vYWzdz/l8M0k8ERlvViiB1Ygslb7SbVtJezncj+Cx5bYaeGuonZqhZlieAp+no74/s5EAh6JcY35Cepxk4ObcT3IJPe/1lKsDpFCFQAAAABJRU5ErkJggg=="; +}; ////// 更改背景音乐的播放 ////// control.prototype.triggerBgm = function () { - if (main.mode != 'play') return; + if (main.mode != "play") return; - core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; - if (core.musicStatus.bgmStatus) - this.resumeBgm(); - else - this.pauseBgm(); - core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus); -} + core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; + if (core.musicStatus.bgmStatus) this.resumeBgm(); + else this.pauseBgm(); + core.setLocalStorage("bgmStatus", core.musicStatus.bgmStatus); +}; ////// 播放音频 ////// control.prototype.playSound = function (sound, pitch, callback) { - sound = core.getMappedName(sound); - if (main.mode != 'play' || !core.musicStatus.soundStatus || !core.material.sounds[sound]) return; - try { - if (core.musicStatus.audioContext != null) { - var source = core.musicStatus.audioContext.createBufferSource(); - source.__name = sound; - source.buffer = core.material.sounds[sound]; - source.connect(core.musicStatus.gainNode); - var id = setTimeout(null); - if (pitch && pitch >= 30 && pitch <= 300) { - source.playbackRate.setValueAtTime(pitch / 100, 0); - } - source.onended = function () { - delete core.musicStatus.playingSounds[id]; - if (callback) callback(); - } - core.musicStatus.playingSounds[id] = source; - if (source.start) source.start(0); - else if (source.noteOn) source.noteOn(0); - return id; - } - else { - core.material.sounds[sound].volume = core.musicStatus.userVolume; - core.material.sounds[sound].play(); - if (callback) callback(); - } + sound = core.getMappedName(sound); + if ( + main.mode != "play" || + !core.musicStatus.soundStatus || + !core.material.sounds[sound] + ) + return; + try { + if (core.musicStatus.audioContext != null) { + var source = core.musicStatus.audioContext.createBufferSource(); + source.__name = sound; + source.buffer = core.material.sounds[sound]; + source.connect(core.musicStatus.gainNode); + var id = setTimeout(null); + if (pitch && pitch >= 30 && pitch <= 300) { + source.playbackRate.setValueAtTime(pitch / 100, 0); + } + source.onended = function () { + delete core.musicStatus.playingSounds[id]; + if (callback) callback(); + }; + core.musicStatus.playingSounds[id] = source; + if (source.start) source.start(0); + else if (source.noteOn) source.noteOn(0); + return id; + } else { + core.material.sounds[sound].volume = core.musicStatus.userVolume; + core.material.sounds[sound].play(); + if (callback) callback(); } - catch (e) { - console.log("无法播放SE " + sound); - console.error(e); - } -} + } catch (e) { + console.log("无法播放SE " + sound); + console.error(e); + } +}; ////// 停止所有音频 ////// control.prototype.stopSound = function (id) { - if (id == null) { - Object.keys(core.musicStatus.playingSounds).forEach(function (id) { - core.control.stopSound(id); - }); - return; - } - var source = core.musicStatus.playingSounds[id]; - if (!source) return; - try { - if (source.stop) source.stop(); - else if (source.noteOff) source.noteOff(); - } - catch (e) { - console.error(e); - } - delete core.musicStatus.playingSounds[id]; -} + if (id == null) { + Object.keys(core.musicStatus.playingSounds).forEach(function (id) { + core.control.stopSound(id); + }); + return; + } + var source = core.musicStatus.playingSounds[id]; + if (!source) return; + try { + if (source.stop) source.stop(); + else if (source.noteOff) source.noteOff(); + } catch (e) { + console.error(e); + } + delete core.musicStatus.playingSounds[id]; +}; ////// 获得当前正在播放的所有(指定)音效的id列表 ////// control.prototype.getPlayingSounds = function (name) { - name = core.getMappedName(name); - return Object.keys(core.musicStatus.playingSounds).filter(function (one) { - return name == null || core.musicStatus.playingSounds[one].__name == name - }); -} + name = core.getMappedName(name); + return Object.keys(core.musicStatus.playingSounds).filter(function (one) { + return name == null || core.musicStatus.playingSounds[one].__name == name; + }); +}; ////// 检查bgm状态 ////// control.prototype.checkBgm = function () { - core.playBgm(core.musicStatus.playingBgm || main.startBgm); -} + core.playBgm(core.musicStatus.playingBgm || main.startBgm); +}; ///// 设置屏幕放缩 ////// control.prototype.setDisplayScale = function (delta) { - var index = core.domStyle.availableScale.indexOf(core.domStyle.scale); - if (index < 0) return; - index = (index + delta + core.domStyle.availableScale.length) % core.domStyle.availableScale.length; - core.domStyle.scale = core.domStyle.availableScale[index]; - core.setLocalStorage('scale', core.domStyle.scale); - core.resize(); -} + var index = core.domStyle.availableScale.indexOf(core.domStyle.scale); + if (index < 0) return; + index = + (index + delta + core.domStyle.availableScale.length) % + core.domStyle.availableScale.length; + core.domStyle.scale = core.domStyle.availableScale[index]; + core.setLocalStorage("scale", core.domStyle.scale); + core.resize(); +}; // ------ 状态栏,工具栏等相关 ------ // ////// 清空状态栏 ////// control.prototype.clearStatusBar = function () { - Object.keys(core.statusBar).forEach(function (e) { - if (core.statusBar[e].innerHTML != null) { - core.statusBar[e].innerHTML = " "; - core.statusBar[e].removeAttribute('_style'); - core.statusBar[e].removeAttribute('_value'); - } - }) - core.statusBar.image.book.style.opacity = 0.3; - if (!core.flags.equipboxButton) - core.statusBar.image.fly.style.opacity = 0.3; -} + Object.keys(core.statusBar).forEach(function (e) { + if (core.statusBar[e].innerHTML != null) { + core.statusBar[e].innerHTML = " "; + core.statusBar[e].removeAttribute("_style"); + core.statusBar[e].removeAttribute("_value"); + } + }); + core.statusBar.image.book.style.opacity = 0.3; + if (!core.flags.equipboxButton) core.statusBar.image.fly.style.opacity = 0.3; +}; ////// 更新状态栏 ////// control.prototype.updateStatusBar = function (doNotCheckAutoEvents, immediate) { - if (!core.isPlaying()) return; - if (immediate) { - return this.updateStatusBar_update(); - } - if (!doNotCheckAutoEvents) this.noAutoEvents = false; - if (core.isReplaying()) return this.updateStatusBar_update(); - if (!core.control.updateNextFrame) { - core.control.updateNextFrame = true; - requestAnimationFrame(this.updateStatusBar_update); - } + if (!core.isPlaying()) return; + if (immediate) { + return this.updateStatusBar_update(); + } + if (!doNotCheckAutoEvents) this.noAutoEvents = false; + if (core.isReplaying()) return this.updateStatusBar_update(); + if (!core.control.updateNextFrame) { + core.control.updateNextFrame = true; + requestAnimationFrame(this.updateStatusBar_update); + } }; control.prototype.updateStatusBar_update = function () { - core.control.updateNextFrame = false; - if (!core.isPlaying() || core.hasFlag('__statistics__')) return; - core.control.controldata.updateStatusBar(); - if (!core.control.noAutoEvents) core.checkAutoEvents(); - core.control._updateStatusBar_setToolboxIcon(); - core.clearRouteFolding(); - core.control.noAutoEvents = true; + core.control.updateNextFrame = false; + if (!core.isPlaying() || core.hasFlag("__statistics__")) return; + core.control.controldata.updateStatusBar(); + if (!core.control.noAutoEvents) core.checkAutoEvents(); + core.control._updateStatusBar_setToolboxIcon(); + core.clearRouteFolding(); + core.control.noAutoEvents = true; }; control.prototype._updateStatusBar_setToolboxIcon = function () { - if (core.isReplaying()) { - core.statusBar.image.book.src = core.status.replay.pausing ? core.statusBar.icons.play.src : core.statusBar.icons.pause.src; - core.statusBar.image.book.style.opacity = 1; - core.statusBar.image.fly.src = core.statusBar.icons.stop.src; - core.statusBar.image.fly.style.opacity = 1; - core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; - core.statusBar.image.keyboard.src = core.statusBar.icons.book.src; - core.statusBar.image.shop.src = core.statusBar.icons.floor.src; - core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; - core.statusBar.image.save.style.opacity = 1; - core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; - core.statusBar.image.settings.src = core.statusBar.icons.save.src; + if (core.isReplaying()) { + core.statusBar.image.book.src = core.status.replay.pausing + ? core.statusBar.icons.play.src + : core.statusBar.icons.pause.src; + core.statusBar.image.book.style.opacity = 1; + core.statusBar.image.fly.src = core.statusBar.icons.stop.src; + core.statusBar.image.fly.style.opacity = 1; + core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; + core.statusBar.image.keyboard.src = core.statusBar.icons.book.src; + core.statusBar.image.shop.src = core.statusBar.icons.floor.src; + core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; + core.statusBar.image.save.style.opacity = 1; + core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; + core.statusBar.image.settings.src = core.statusBar.icons.save.src; + } else { + core.statusBar.image.book.src = core.statusBar.icons.book.src; + core.statusBar.image.book.style.opacity = core.hasItem("book") ? 1 : 0.3; + if (!core.flags.equipboxButton) { + core.statusBar.image.fly.src = core.statusBar.icons.fly.src; + core.statusBar.image.fly.style.opacity = core.hasItem("fly") ? 1 : 0.3; + } else { + core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src; + core.statusBar.image.fly.style.opacity = 1; } - else { - core.statusBar.image.book.src = core.statusBar.icons.book.src; - core.statusBar.image.book.style.opacity = core.hasItem('book') ? 1 : 0.3; - if (!core.flags.equipboxButton) { - core.statusBar.image.fly.src = core.statusBar.icons.fly.src; - core.statusBar.image.fly.style.opacity = core.hasItem('fly') ? 1 : 0.3; - } - else { - core.statusBar.image.fly.src = core.statusBar.icons.equipbox.src; - core.statusBar.image.fly.style.opacity = 1; - } - core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; - core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src; - core.statusBar.image.shop.src = core.statusBar.icons.shop.src; - core.statusBar.image.save.src = core.statusBar.icons.save.src; - core.statusBar.image.save.style.opacity = core.hasFlag('__forbidSave__') ? 0.3 : 1; - core.statusBar.image.load.src = core.statusBar.icons.load.src; - core.statusBar.image.settings.src = core.statusBar.icons.settings.src; - } -} + core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; + core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src; + core.statusBar.image.shop.src = core.statusBar.icons.shop.src; + core.statusBar.image.save.src = core.statusBar.icons.save.src; + core.statusBar.image.save.style.opacity = core.hasFlag("__forbidSave__") + ? 0.3 + : 1; + core.statusBar.image.load.src = core.statusBar.icons.load.src; + core.statusBar.image.settings.src = core.statusBar.icons.settings.src; + } +}; control.prototype.showStatusBar = function () { - if (main.mode == 'editor') return; - if (core.domStyle.showStatusBar) return; - var statusItems = core.dom.status; - core.domStyle.showStatusBar = true; - core.removeFlag('hideStatusBar'); - // 显示 - for (var i = 0; i < statusItems.length; ++i) - statusItems[i].style.opacity = 1; - this.setToolbarButton(false); - core.dom.tools.hard.style.display = 'block'; - core.dom.toolBar.style.display = 'block'; -} + if (main.mode == "editor") return; + if (core.domStyle.showStatusBar) return; + var statusItems = core.dom.status; + core.domStyle.showStatusBar = true; + core.removeFlag("hideStatusBar"); + // 显示 + for (var i = 0; i < statusItems.length; ++i) statusItems[i].style.opacity = 1; + this.setToolbarButton(false); + core.dom.tools.hard.style.display = "block"; + core.dom.toolBar.style.display = "block"; +}; control.prototype.hideStatusBar = function (showToolbox) { - if (main.mode == 'editor') return; + if (main.mode == "editor") return; - // 如果原本就是隐藏的,则先显示 - if (!core.domStyle.showStatusBar) - this.showStatusBar(); - if (core.isReplaying()) showToolbox = true; + // 如果原本就是隐藏的,则先显示 + if (!core.domStyle.showStatusBar) this.showStatusBar(); + if (core.isReplaying()) showToolbox = true; - var statusItems = core.dom.status, toolItems = core.dom.tools; - core.domStyle.showStatusBar = false; - core.setFlag('hideStatusBar', true); - core.setFlag('showToolbox', showToolbox || null); - // 隐藏 - for (var i = 0; i < statusItems.length; ++i) - statusItems[i].style.opacity = 0; - if ((!core.domStyle.isVertical && !core.flags.extendToolbar) || !showToolbox) { - for (var i = 0; i < toolItems.length; ++i) - toolItems[i].style.display = 'none'; - } - if (!core.domStyle.isVertical && !core.flags.extendToolbar) { - core.dom.toolBar.style.display = 'none'; - } -} + var statusItems = core.dom.status, + toolItems = core.dom.tools; + core.domStyle.showStatusBar = false; + core.setFlag("hideStatusBar", true); + core.setFlag("showToolbox", showToolbox || null); + // 隐藏 + for (var i = 0; i < statusItems.length; ++i) statusItems[i].style.opacity = 0; + if ( + (!core.domStyle.isVertical && !core.flags.extendToolbar) || + !showToolbox + ) { + for (var i = 0; i < toolItems.length; ++i) + toolItems[i].style.display = "none"; + } + if (!core.domStyle.isVertical && !core.flags.extendToolbar) { + core.dom.toolBar.style.display = "none"; + } +}; ////// 更新状态栏的勇士图标 ////// control.prototype.updateHeroIcon = function (name) { - name = name || "hero.png"; - if (core.statusBar.icons.name == name) return; - core.statusBar.icons.name = name; + name = name || "hero.png"; + if (core.statusBar.icons.name == name) return; + core.statusBar.icons.name = name; - var image = core.material.images.hero; - // 全身图 - var w = core.material.icons.hero.width || 32; - var h = core.material.icons.hero.height || 48; - var ratio = Math.min(w / h, 1), width = 32 * ratio, left = 16 - width / 2; + var image = core.material.images.hero; + // 全身图 + var w = core.material.icons.hero.width || 32; + var h = core.material.icons.hero.height || 48; + var ratio = Math.min(w / h, 1), + width = 32 * ratio, + left = 16 - width / 2; - var canvas = document.createElement("canvas"); - var ctx = canvas.getContext("2d"); - canvas.width = 32; - canvas.height = 32; - core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32); + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + canvas.width = 32; + canvas.height = 32; + core.drawImage(ctx, image, 0, 0, w, h, left, 0, width, 32); - core.statusBar.image.name.src = canvas.toDataURL("image/png"); -} + core.statusBar.image.name.src = canvas.toDataURL("image/png"); +}; ////// 改变工具栏为按钮1-8 ////// control.prototype.setToolbarButton = function (useButton) { - if (!core.domStyle.showStatusBar) { - // 隐藏状态栏时检查竖屏 - if (!core.domStyle.isVertical && !core.flags.extendToolbar) { - for (var i = 0; i < core.dom.tools.length; ++i) - core.dom.tools[i].style.display = 'none'; - return; - } - if (!core.hasFlag('showToolbox')) return; - else core.dom.tools.hard.style.display = 'block'; + if (!core.domStyle.showStatusBar) { + // 隐藏状态栏时检查竖屏 + if (!core.domStyle.isVertical && !core.flags.extendToolbar) { + for (var i = 0; i < core.dom.tools.length; ++i) + core.dom.tools[i].style.display = "none"; + return; } + if (!core.hasFlag("showToolbox")) return; + else core.dom.tools.hard.style.display = "block"; + } - if (useButton == null) useButton = core.domStyle.toolbarBtn; - if ((!core.domStyle.isVertical && !core.flags.extendToolbar)) useButton = false; - core.domStyle.toolbarBtn = useButton; + if (useButton == null) useButton = core.domStyle.toolbarBtn; + if (!core.domStyle.isVertical && !core.flags.extendToolbar) useButton = false; + core.domStyle.toolbarBtn = useButton; - if (useButton) { - ["book", "fly", "toolbox", "keyboard", "shop", "save", "load", "settings"].forEach(function (t) { - core.statusBar.image[t].style.display = 'none'; - }); - ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) { - core.statusBar.image[t].style.display = 'block'; - }) - main.statusBar.image.btn8.style.filter = core.getLocalStorage('altKey') ? 'sepia(1) contrast(1.5)' : ''; - } - else { - ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach(function (t) { - core.statusBar.image[t].style.display = 'none'; - }); - ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function (t) { - core.statusBar.image[t].style.display = 'block'; - }); - core.statusBar.image.keyboard.style.display - = core.statusBar.image.shop.style.display - = core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none"; - } -} + if (useButton) { + [ + "book", + "fly", + "toolbox", + "keyboard", + "shop", + "save", + "load", + "settings", + ].forEach(function (t) { + core.statusBar.image[t].style.display = "none"; + }); + ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach( + function (t) { + core.statusBar.image[t].style.display = "block"; + } + ); + main.statusBar.image.btn8.style.filter = core.getLocalStorage("altKey") + ? "sepia(1) contrast(1.5)" + : ""; + } else { + ["btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7", "btn8"].forEach( + function (t) { + core.statusBar.image[t].style.display = "none"; + } + ); + ["book", "fly", "toolbox", "save", "load", "settings"].forEach(function ( + t + ) { + core.statusBar.image[t].style.display = "block"; + }); + core.statusBar.image.keyboard.style.display = + core.statusBar.image.shop.style.display = + core.domStyle.isVertical || core.flags.extendToolbar ? "block" : "none"; + } +}; ////// ------ resize处理 ------ // control.prototype._shouldDisplayStatus = function (id) { - if (id == null) { - var toDraw = [], status = core.dom.status; - for (var i = 0; i < status.length; ++i) { - var dom = core.dom.status[i], idCol = dom.id; - if (idCol.indexOf("Col") != idCol.length - 3) continue; - var id = idCol.substring(0, idCol.length - 3); - if (!this._shouldDisplayStatus(id)) continue; - toDraw.push(id); - } - return toDraw; + if (id == null) { + var toDraw = [], + status = core.dom.status; + for (var i = 0; i < status.length; ++i) { + var dom = core.dom.status[i], + idCol = dom.id; + if (idCol.indexOf("Col") != idCol.length - 3) continue; + var id = idCol.substring(0, idCol.length - 3); + if (!this._shouldDisplayStatus(id)) continue; + toDraw.push(id); } - var obj = {}; - core.flags.statusBarItems.forEach(function (v) { obj[v] = true; }) - switch (id) { - case 'floor': return obj.enableFloor; - case 'name': return obj.enableName; - case 'lv': return obj.enableLv; - case 'hp': return obj.enableHP; - case 'hpmax': return obj.enableHPMax; - case 'mana': return obj.enableMana; - case 'atk': return obj.enableAtk; - case 'def': return obj.enableDef; - case 'mdef': return obj.enableMDef; - case 'money': return obj.enableMoney; - case 'exp': return obj.enableExp && !obj.levelUpLeftMode; - case 'up': return obj.enableLevelUp; - case 'skill': return obj.enableSkill; - case 'key': return obj.enableKeys; - case 'pzf': return obj.enablePZF; - case 'debuff': return obj.enableDebuff; - default: return true; - } -} + return toDraw; + } + var obj = {}; + core.flags.statusBarItems.forEach(function (v) { + obj[v] = true; + }); + switch (id) { + case "floor": + return obj.enableFloor; + case "name": + return obj.enableName; + case "lv": + return obj.enableLv; + case "hp": + return obj.enableHP; + case "hpmax": + return obj.enableHPMax; + case "mana": + return obj.enableMana; + case "atk": + return obj.enableAtk; + case "def": + return obj.enableDef; + case "mdef": + return obj.enableMDef; + case "money": + return obj.enableMoney; + case "exp": + return obj.enableExp && !obj.levelUpLeftMode; + case "up": + return obj.enableLevelUp; + case "skill": + return obj.enableSkill; + case "key": + return obj.enableKeys; + case "pzf": + return obj.enablePZF; + case "debuff": + return obj.enableDebuff; + default: + return true; + } +}; ////// 注册一个resize函数 ////// // name为名称,可供注销使用 // func可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。 control.prototype.registerResize = function (name, func) { - this.unregisterResize(name); - this.resizes.push({ name: name, func: func }); -} + this.unregisterResize(name); + this.resizes.push({ name: name, func: func }); +}; ////// 注销一个resize函数 ////// control.prototype.unregisterResize = function (name) { - this.resizes = this.resizes.filter(function (b) { return b.name != name; }); -} + this.resizes = this.resizes.filter(function (b) { + return b.name != name; + }); +}; control.prototype._doResize = function (obj) { - for (var i in this.resizes) { - try { - if (core.doFunc(this.resizes[i].func, this, obj)) return true; - } catch (e) { - console.error(e); - console.error("ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。"); - this.unregisterResize(this.resizes[i].name); - } + for (var i in this.resizes) { + try { + if (core.doFunc(this.resizes[i].func, this, obj)) return true; + } catch (e) { + console.error(e); + console.error( + "ERROR in resizes[" + this.resizes[i].name + "]:已自动注销该项。" + ); + this.unregisterResize(this.resizes[i].name); } - return false; -} + } + return false; +}; ////// 屏幕分辨率改变后重新自适应 ////// control.prototype.resize = function () { - if (main.mode == 'editor') return; - var clientWidth = main.dom.body.clientWidth, clientHeight = main.dom.body.clientHeight; - var BORDER = 3; - var extendToolbar = core.flags.extendToolbar; - let hideLeftStatusBar = core.flags.hideLeftStatusBar; - var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31); + if (main.mode == "editor") return; + var clientWidth = main.dom.body.clientWidth, + clientHeight = main.dom.body.clientHeight; + var BORDER = 3; + var extendToolbar = core.flags.extendToolbar; + let hideLeftStatusBar = core.flags.hideLeftStatusBar; + var BAR_WIDTH = hideLeftStatusBar ? 0 : Math.round(core._PY_ * 0.31); - var horizontalMaxRatio = (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / (core._PY_ + (hideLeftStatusBar ? 38 : 0)); + var horizontalMaxRatio = + (clientHeight - 2 * BORDER - (hideLeftStatusBar ? BORDER : 0)) / + (core._PY_ + (hideLeftStatusBar ? 38 : 0)); - if (clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || (clientWidth > clientHeight && horizontalMaxRatio < 1)) { - // 横屏 - core.domStyle.isVertical = false; + if ( + clientWidth - 3 * BORDER >= core._PX_ + BAR_WIDTH || + (clientWidth > clientHeight && horizontalMaxRatio < 1) + ) { + // 横屏 + core.domStyle.isVertical = false; - core.domStyle.availableScale = []; - [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) { - if (clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) && horizontalMaxRatio >= v) { - core.domStyle.availableScale.push(v); - } - }); - if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { - core.domStyle.scale = Math.min(1, horizontalMaxRatio); - } - } - else { - // 竖屏 - core.domStyle.isVertical = true; - core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); - core.domStyle.availableScale = []; - extendToolbar = false; - hideLeftStatusBar = false; - BAR_WIDTH = Math.round(core._PX_ * 0.3); + core.domStyle.availableScale = []; + [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5].forEach(function (v) { + if ( + clientWidth - 3 * BORDER >= v * (core._PX_ + BAR_WIDTH) && + horizontalMaxRatio >= v + ) { + core.domStyle.availableScale.push(v); + } + }); + if (core.domStyle.availableScale.indexOf(core.domStyle.scale) < 0) { + core.domStyle.scale = Math.min(1, horizontalMaxRatio); } + } else { + // 竖屏 + core.domStyle.isVertical = true; + core.domStyle.scale = Math.min((clientWidth - 2 * BORDER) / core._PX_); + core.domStyle.availableScale = []; + extendToolbar = false; + hideLeftStatusBar = false; + BAR_WIDTH = Math.round(core._PX_ * 0.3); + } - var statusDisplayArr = this._shouldDisplayStatus(), count = statusDisplayArr.length; - var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; - var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3); - if (col > 5) { - if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!"); - else alert("当前状态栏数目(" + count + ")大于15,请调整到不超过15以避免手机端出现显示问题。"); - } - var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; + var statusDisplayArr = this._shouldDisplayStatus(), + count = statusDisplayArr.length; + var statusCanvas = core.flags.statusCanvas, + statusCanvasRows = core.values.statusCanvasRowsOnMobile || 3; + var col = statusCanvas ? statusCanvasRows : Math.ceil(count / 3); + if (col > 5) { + if (statusCanvas) alert("自绘状态栏的在竖屏下的行数应不超过5!"); + else + alert( + "当前状态栏数目(" + + count + + ")大于15,请调整到不超过15以避免手机端出现显示问题。" + ); + } + var globalAttribute = + core.status.globalAttribute || core.initStatus.globalAttribute; - var obj = { - clientWidth: clientWidth, - clientHeight: clientHeight, - BORDER: BORDER, - BAR_WIDTH: BAR_WIDTH, - TOOLBAR_HEIGHT: 38, - outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER, - outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER, - globalAttribute: globalAttribute, - border: '3px ' + core.arrayToRGBA(globalAttribute.borderColor) + ' solid', - statusDisplayArr: statusDisplayArr, - count: count, - col: col, - statusBarHeightInVertical: core.domStyle.isVertical ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER : 0, - toolbarHeightInVertical: core.domStyle.isVertical ? 38 * core.domStyle.scale + 2 * BORDER : 0, - extendToolbar: extendToolbar, - is15x15: false, - hideLeftStatusBar - }; + var obj = { + clientWidth: clientWidth, + clientHeight: clientHeight, + BORDER: BORDER, + BAR_WIDTH: BAR_WIDTH, + TOOLBAR_HEIGHT: 38, + outerWidth: core._PX_ * core.domStyle.scale + 2 * BORDER, + outerHeight: core._PY_ * core.domStyle.scale + 2 * BORDER, + globalAttribute: globalAttribute, + border: "3px " + core.arrayToRGBA(globalAttribute.borderColor) + " solid", + statusDisplayArr: statusDisplayArr, + count: count, + col: col, + statusBarHeightInVertical: core.domStyle.isVertical + ? (32 * col + 6) * core.domStyle.scale + 2 * BORDER + : 0, + toolbarHeightInVertical: core.domStyle.isVertical + ? 38 * core.domStyle.scale + 2 * BORDER + : 0, + extendToolbar: extendToolbar, + is15x15: false, + hideLeftStatusBar, + }; - this._doResize(obj); - this.setToolbarButton(); - core.updateStatusBar(); -} + this._doResize(obj); + this.setToolbarButton(); + core.updateStatusBar(); +}; control.prototype._resize_gameGroup = function (obj) { - var startBackground = core.domStyle.isVertical ? (main.styles.startVerticalBackground || main.styles.startBackground) : main.styles.startBackground; - if (main.dom.startBackground.getAttribute('__src__') != startBackground) { - main.dom.startBackground.setAttribute('__src__', startBackground); - main.dom.startBackground.src = startBackground; - } + var startBackground = core.domStyle.isVertical + ? main.styles.startVerticalBackground || main.styles.startBackground + : main.styles.startBackground; + if (main.dom.startBackground.getAttribute("__src__") != startBackground) { + main.dom.startBackground.setAttribute("__src__", startBackground); + main.dom.startBackground.src = startBackground; + } - var gameGroup = core.dom.gameGroup; - var totalWidth, totalHeight; - if (core.domStyle.isVertical) { - totalWidth = obj.outerWidth; - totalHeight = obj.outerHeight + obj.statusBarHeightInVertical + obj.toolbarHeightInVertical - } - else { - totalWidth = obj.outerWidth + obj.BAR_WIDTH * core.domStyle.scale + (obj.hideLeftStatusBar ? 0 : obj.BORDER); - totalHeight = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0); - } - gameGroup.style.width = totalWidth + "px"; - gameGroup.style.height = totalHeight + "px"; - gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px"; - gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px"; - // floorMsgGroup - var floorMsgGroup = core.dom.floorMsgGroup; - floorMsgGroup.style = obj.globalAttribute.floorChangingStyle; - floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + "px"; - floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px"; - floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; - // startPanel - core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px"; - // musicBtn - if (core.domStyle.isVertical || core.domStyle.scale < 1) { - core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px"; - } - else { - core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px"; - core.dom.musicBtn.style.bottom = (obj.clientHeight - totalHeight) / 2 - 27 + "px"; - } -} + var gameGroup = core.dom.gameGroup; + var totalWidth, totalHeight; + if (core.domStyle.isVertical) { + totalWidth = obj.outerWidth; + totalHeight = + obj.outerHeight + + obj.statusBarHeightInVertical + + obj.toolbarHeightInVertical; + } else { + totalWidth = + obj.outerWidth + + obj.BAR_WIDTH * core.domStyle.scale + + (obj.hideLeftStatusBar ? 0 : obj.BORDER); + totalHeight = + obj.outerHeight + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0); + } + gameGroup.style.width = totalWidth + "px"; + gameGroup.style.height = totalHeight + "px"; + gameGroup.style.left = (obj.clientWidth - totalWidth) / 2 + "px"; + gameGroup.style.top = (obj.clientHeight - totalHeight) / 2 + "px"; + // floorMsgGroup + var floorMsgGroup = core.dom.floorMsgGroup; + floorMsgGroup.style = obj.globalAttribute.floorChangingStyle; + floorMsgGroup.style.width = obj.outerWidth - 2 * obj.BORDER + "px"; + floorMsgGroup.style.height = totalHeight - 2 * obj.BORDER + "px"; + floorMsgGroup.style.fontSize = 16 * core.domStyle.scale + "px"; + // startPanel + core.dom.startPanel.style.fontSize = 16 * core.domStyle.scale + "px"; + // musicBtn + if (core.domStyle.isVertical || core.domStyle.scale < 1) { + core.dom.musicBtn.style.right = core.dom.musicBtn.style.bottom = "3px"; + } else { + core.dom.musicBtn.style.right = (obj.clientWidth - totalWidth) / 2 + "px"; + core.dom.musicBtn.style.bottom = + (obj.clientHeight - totalHeight) / 2 - 27 + "px"; + } +}; control.prototype._resize_canvas = function (obj) { - var innerWidth = (core._PX_ * core.domStyle.scale) + "px", innerHeight = (core._PY_ * core.domStyle.scale) + "px"; - if (!core.isPlaying()) { - for (var i = 0; i < core.dom.gameCanvas.length; ++i) { - var ctx = core.dom.gameCanvas[i].getContext('2d'); - core.resizeCanvas(ctx, core._PX_, core._PY_); - core.dom.gameCanvas[i].style.width = innerWidth; - core.dom.gameCanvas[i].style.height = innerHeight; - } - } else { - requestAnimationFrame(function () { - for (var i = 0; i < core.dom.gameCanvas.length; ++i) { - core.dom.gameCanvas[i].style.width = innerWidth; - core.dom.gameCanvas[i].style.height = innerHeight; - } - }); + var innerWidth = core._PX_ * core.domStyle.scale + "px", + innerHeight = core._PY_ * core.domStyle.scale + "px"; + if (!core.isPlaying()) { + for (var i = 0; i < core.dom.gameCanvas.length; ++i) { + var ctx = core.dom.gameCanvas[i].getContext("2d"); + core.resizeCanvas(ctx, core._PX_, core._PY_); + core.dom.gameCanvas[i].style.width = innerWidth; + core.dom.gameCanvas[i].style.height = innerHeight; } - core.dom.gif.style.width = innerWidth; - core.dom.gif.style.height = innerHeight; - core.dom.gif2.style.width = innerWidth; - core.dom.gif2.style.height = innerHeight; - core.dom.gameDraw.style.width = innerWidth; - core.dom.gameDraw.style.height = innerHeight; - core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px"; - core.dom.gameDraw.style.right = 0; - core.dom.gameDraw.style.border = obj.border; - // resize bigmap - core.bigmap.canvas.forEach(function (cn) { - var ratio = core.canvas[cn].canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1; - core.canvas[cn].canvas.style.width = core.canvas[cn].canvas.width / ratio * core.domStyle.scale + "px"; - core.canvas[cn].canvas.style.height = core.canvas[cn].canvas.height / ratio * core.domStyle.scale + "px"; + } else { + requestAnimationFrame(function () { + for (var i = 0; i < core.dom.gameCanvas.length; ++i) { + core.dom.gameCanvas[i].style.width = innerWidth; + core.dom.gameCanvas[i].style.height = innerHeight; + } }); - // resize dynamic canvas - if (!core.isPlaying()) { - for (var name in core.dymCanvas) { - var ctx = core.dymCanvas[name], canvas = ctx.canvas; - // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height'))); - canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; - canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; - var scale = canvas.getAttribute('_scale') || 1; - core.resizeCanvas(canvas, canvas.width * scale / core.domStyle.scale, canvas.height * scale / core.domStyle.scale); - } - } else { - for (var name in core.dymCanvas) { - var ctx = core.dymCanvas[name], canvas = ctx.canvas; - core.resizeCanvas(ctx, parseFloat(canvas.getAttribute("_width")), parseFloat(canvas.getAttribute("_height"))) - canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; - canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; - } + } + core.dom.gif.style.width = innerWidth; + core.dom.gif.style.height = innerHeight; + core.dom.gif2.style.width = innerWidth; + core.dom.gif2.style.height = innerHeight; + core.dom.gameDraw.style.width = innerWidth; + core.dom.gameDraw.style.height = innerHeight; + core.dom.gameDraw.style.top = obj.statusBarHeightInVertical + "px"; + core.dom.gameDraw.style.right = 0; + core.dom.gameDraw.style.border = obj.border; + // resize bigmap + core.bigmap.canvas.forEach(function (cn) { + var ratio = core.canvas[cn].canvas.hasAttribute("isHD") + ? core.domStyle.ratio + : 1; + core.canvas[cn].canvas.style.width = + (core.canvas[cn].canvas.width / ratio) * core.domStyle.scale + "px"; + core.canvas[cn].canvas.style.height = + (core.canvas[cn].canvas.height / ratio) * core.domStyle.scale + "px"; + }); + // resize dynamic canvas + if (!core.isPlaying()) { + for (var name in core.dymCanvas) { + var ctx = core.dymCanvas[name], + canvas = ctx.canvas; + // core.maps._setHDCanvasSize(ctx, parseFloat(canvas.getAttribute('_width')), parseFloat(canvas.getAttribute('_height'))); + canvas.style.left = + parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; + canvas.style.top = + parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; + var scale = canvas.getAttribute("_scale") || 1; + core.resizeCanvas( + canvas, + (canvas.width * scale) / core.domStyle.scale, + (canvas.height * scale) / core.domStyle.scale + ); } - // resize next - main.dom.next.style.width = main.dom.next.style.height = 5 * core.domStyle.scale + "px"; - main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px"; -} + } else { + for (var name in core.dymCanvas) { + var ctx = core.dymCanvas[name], + canvas = ctx.canvas; + core.resizeCanvas( + ctx, + parseFloat(canvas.getAttribute("_width")), + parseFloat(canvas.getAttribute("_height")) + ); + canvas.style.left = + parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; + canvas.style.top = + parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; + } + } + // resize next + main.dom.next.style.width = main.dom.next.style.height = + 5 * core.domStyle.scale + "px"; + main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = + 4 * core.domStyle.scale + "px"; +}; control.prototype._resize_statusBar = function (obj) { - // statusBar - var statusBar = core.dom.statusBar; - if (core.domStyle.isVertical) { - statusBar.style.width = obj.outerWidth + "px"; - statusBar.style.height = obj.statusBarHeightInVertical + "px"; - statusBar.style.background = obj.globalAttribute.statusTopBackground; - statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + // statusBar + var statusBar = core.dom.statusBar; + if (core.domStyle.isVertical) { + statusBar.style.width = obj.outerWidth + "px"; + statusBar.style.height = obj.statusBarHeightInVertical + "px"; + statusBar.style.background = obj.globalAttribute.statusTopBackground; + statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + } else { + statusBar.style.width = + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; + statusBar.style.height = + obj.outerHeight + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0) + + "px"; + statusBar.style.background = obj.globalAttribute.statusLeftBackground; + // --- 计算文字大小 + if (obj.hideLeftStatusBar) { + statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; + } else { + statusBar.style.fontSize = + 16 * + Math.min(1, (core._HEIGHT_ - 4) / obj.count) * + core.domStyle.scale + + "px"; } - else { - statusBar.style.width = (obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER) + "px"; - statusBar.style.height = obj.outerHeight + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; - statusBar.style.background = obj.globalAttribute.statusLeftBackground; - // --- 计算文字大小 - if (obj.hideLeftStatusBar) { - statusBar.style.fontSize = 16 * core.domStyle.scale + "px"; - } else { - statusBar.style.fontSize = 16 * Math.min(1, (core._HEIGHT_ - 4) / obj.count) * core.domStyle.scale + "px"; - } - } - statusBar.style.display = obj.hideLeftStatusBar ? 'none' : 'block'; - statusBar.style.borderTop = statusBar.style.borderLeft = obj.border; - statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : ''; - statusBar.style.borderBottom = core.domStyle.isVertical ? '' : obj.border; - // 自绘状态栏 - if (core.domStyle.isVertical) { - core.dom.statusCanvas.style.width = core._PX_ * core.domStyle.scale + "px"; - core.dom.statusCanvas.style.height = obj.statusBarHeightInVertical - 3 + "px"; - core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, core._PX_, obj.col * 32 + 9); - } - else { - core.dom.statusCanvas.style.width = obj.BAR_WIDTH * core.domStyle.scale + "px"; - core.dom.statusCanvas.style.height = obj.outerHeight - 2 * obj.BORDER + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER : 0) + "px"; - core.maps._setHDCanvasSize(core.dom.statusCanvasCtx, obj.BAR_WIDTH, core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0)); - } - core.dom.statusCanvas.style.display = core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none"; -} + } + statusBar.style.display = obj.hideLeftStatusBar ? "none" : "block"; + statusBar.style.borderTop = statusBar.style.borderLeft = obj.border; + statusBar.style.borderRight = core.domStyle.isVertical ? obj.border : ""; + statusBar.style.borderBottom = core.domStyle.isVertical ? "" : obj.border; + // 自绘状态栏 + if (core.domStyle.isVertical) { + core.dom.statusCanvas.style.width = core._PX_ * core.domStyle.scale + "px"; + core.dom.statusCanvas.style.height = + obj.statusBarHeightInVertical - 3 + "px"; + core.maps._setHDCanvasSize( + core.dom.statusCanvasCtx, + core._PX_, + obj.col * 32 + 9 + ); + } else { + core.dom.statusCanvas.style.width = + obj.BAR_WIDTH * core.domStyle.scale + "px"; + core.dom.statusCanvas.style.height = + obj.outerHeight - + 2 * obj.BORDER + + (obj.extendToolbar + ? obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + : 0) + + "px"; + core.maps._setHDCanvasSize( + core.dom.statusCanvasCtx, + obj.BAR_WIDTH, + core._PY_ + (obj.extendToolbar ? obj.TOOLBAR_HEIGHT + obj.BORDER : 0) + ); + } + core.dom.statusCanvas.style.display = + core.flags.statusCanvas && !obj.hideLeftStatusBar ? "block" : "none"; +}; control.prototype._resize_status = function (obj) { - var statusHeight; - if (core.domStyle.isVertical) { - statusHeight = 32 * core.domStyle.scale * 0.8; - } else { - statusHeight = (obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / obj.count * 32 * core.domStyle.scale * 0.8; - } - // status - for (var i = 0; i < core.dom.status.length; ++i) { - var id = core.dom.status[i].id, style = core.dom.status[i].style; - if (id.endsWith("Col")) id = id.substring(0, id.length - 3); - style.display = core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 ? 'none' : 'block'; - style.margin = 3 * core.domStyle.scale + "px"; - style.height = statusHeight + "px"; - style.maxWidth = obj.BAR_WIDTH * core.domStyle.scale * (core.domStyle.isVertical ? 0.95 : 1) + obj.BORDER + "px"; - if (obj.is15x15 && !core.domStyle.isVertical) - style.marginLeft = 11 * core.domStyle.scale + "px"; - } - // statusLabels, statusTexts - for (var i = 0; i < core.dom.statusLabels.length; ++i) { - core.dom.statusLabels[i].style.lineHeight = statusHeight + "px"; - core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px"; - } - for (var i = 0; i < core.dom.statusTexts.length; ++i) { - core.dom.statusTexts[i].style.color = core.arrayToRGBA(obj.globalAttribute.statusBarColor); - } - // keys - if (core.flags.statusBarItems.indexOf('enableGreenKey') >= 0) { - core.dom.keyCol.style.fontSize = '0.75em'; - core.statusBar.greenKey.style.display = ''; - } else { - core.dom.keyCol.style.fontSize = ''; - core.statusBar.greenKey.style.display = 'none'; - } -} + var statusHeight; + if (core.domStyle.isVertical) { + statusHeight = 32 * core.domStyle.scale * 0.8; + } else { + statusHeight = + ((obj.hideLeftStatusBar ? core._HEIGHT_ : core._HEIGHT_ - 4) / + obj.count) * + 32 * + core.domStyle.scale * + 0.8; + } + // status + for (var i = 0; i < core.dom.status.length; ++i) { + var id = core.dom.status[i].id, + style = core.dom.status[i].style; + if (id.endsWith("Col")) id = id.substring(0, id.length - 3); + style.display = + core.flags.statusCanvas || obj.statusDisplayArr.indexOf(id) < 0 + ? "none" + : "block"; + style.margin = 3 * core.domStyle.scale + "px"; + style.height = statusHeight + "px"; + style.maxWidth = + obj.BAR_WIDTH * + core.domStyle.scale * + (core.domStyle.isVertical ? 0.95 : 1) + + obj.BORDER + + "px"; + if (obj.is15x15 && !core.domStyle.isVertical) + style.marginLeft = 11 * core.domStyle.scale + "px"; + } + // statusLabels, statusTexts + for (var i = 0; i < core.dom.statusLabels.length; ++i) { + core.dom.statusLabels[i].style.lineHeight = statusHeight + "px"; + core.dom.statusLabels[i].style.marginLeft = 6 * core.domStyle.scale + "px"; + } + for (var i = 0; i < core.dom.statusTexts.length; ++i) { + core.dom.statusTexts[i].style.color = core.arrayToRGBA( + obj.globalAttribute.statusBarColor + ); + } + // keys + if (core.flags.statusBarItems.indexOf("enableGreenKey") >= 0) { + core.dom.keyCol.style.fontSize = "0.75em"; + core.statusBar.greenKey.style.display = ""; + } else { + core.dom.keyCol.style.fontSize = ""; + core.statusBar.greenKey.style.display = "none"; + } +}; control.prototype._resize_toolBar = function (obj) { - // toolBar - var toolBar = core.dom.toolBar; - if (core.domStyle.isVertical) { - toolBar.style.left = 0; - toolBar.style.right = ""; - toolBar.style.width = obj.outerWidth + "px"; - toolBar.style.top = obj.statusBarHeightInVertical + obj.outerHeight + "px"; - toolBar.style.height = obj.toolbarHeightInVertical + "px"; - toolBar.style.background = obj.globalAttribute.toolsBackground; - } - else { - if (obj.extendToolbar || obj.hideLeftStatusBar) { - toolBar.style.left = ""; - toolBar.style.right = 0; - toolBar.style.width = obj.outerWidth + "px"; - toolBar.style.top = obj.outerHeight + "px"; - toolBar.style.height = obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px"; - toolBar.style.background = obj.globalAttribute.toolsBackground; - } else { - toolBar.style.left = 0; - toolBar.style.right = ""; - toolBar.style.width = obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; - toolBar.style.top = 0.75 * obj.outerHeight + "px"; - toolBar.style.height = 0.25 * obj.outerHeight + "px"; - toolBar.style.background = 'transparent'; - } - } - toolBar.style.borderLeft = obj.border; - toolBar.style.borderRight = toolBar.style.borderBottom = core.domStyle.isVertical || obj.extendToolbar ? obj.border : ''; - toolBar.style.fontSize = 16 * core.domStyle.scale + "px"; - - if (!core.domStyle.showStatusBar && !core.domStyle.isVertical && !obj.extendToolbar) { - toolBar.style.display = 'none'; + // toolBar + var toolBar = core.dom.toolBar; + if (core.domStyle.isVertical) { + toolBar.style.left = 0; + toolBar.style.right = ""; + toolBar.style.width = obj.outerWidth + "px"; + toolBar.style.top = obj.statusBarHeightInVertical + obj.outerHeight + "px"; + toolBar.style.height = obj.toolbarHeightInVertical + "px"; + toolBar.style.background = obj.globalAttribute.toolsBackground; + } else { + if (obj.extendToolbar || obj.hideLeftStatusBar) { + toolBar.style.left = ""; + toolBar.style.right = 0; + toolBar.style.width = obj.outerWidth + "px"; + toolBar.style.top = obj.outerHeight + "px"; + toolBar.style.height = + obj.TOOLBAR_HEIGHT * core.domStyle.scale + obj.BORDER + "px"; + toolBar.style.background = obj.globalAttribute.toolsBackground; } else { - toolBar.style.display = 'block'; + toolBar.style.left = 0; + toolBar.style.right = ""; + toolBar.style.width = + obj.BAR_WIDTH * core.domStyle.scale + obj.BORDER + "px"; + toolBar.style.top = 0.75 * obj.outerHeight + "px"; + toolBar.style.height = 0.25 * obj.outerHeight + "px"; + toolBar.style.background = "transparent"; } -} + } + toolBar.style.borderLeft = obj.border; + toolBar.style.borderRight = toolBar.style.borderBottom = + core.domStyle.isVertical || obj.extendToolbar ? obj.border : ""; + toolBar.style.fontSize = 16 * core.domStyle.scale + "px"; + + if ( + !core.domStyle.showStatusBar && + !core.domStyle.isVertical && + !obj.extendToolbar + ) { + toolBar.style.display = "none"; + } else { + toolBar.style.display = "block"; + } +}; control.prototype._resize_tools = function (obj) { - var toolsHeight = 32 * core.domStyle.scale * ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 ? 0.95 : 1); - var toolsMarginLeft; - if (core.domStyle.isVertical || obj.extendToolbar) - toolsMarginLeft = (core._HALF_WIDTH_ - 3) * 3 * core.domStyle.scale; - else - toolsMarginLeft = (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4; - for (var i = 0; i < core.dom.tools.length; ++i) { - var style = core.dom.tools[i].style; - style.height = toolsHeight + "px"; - style.marginLeft = toolsMarginLeft + "px"; - style.marginTop = 3 * core.domStyle.scale + "px" - } - core.dom.hard.style.lineHeight = toolsHeight + "px"; - if (core.domStyle.isVertical || obj.extendToolbar) { - core.dom.hard.style.width = obj.outerWidth - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px"; - } - else { - core.dom.hard.style.width = obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px"; - if (!obj.is15x15) core.dom.hard.style.marginTop = 0; - } -} + var toolsHeight = + 32 * + core.domStyle.scale * + ((core.domStyle.isVertical || obj.extendToolbar) && !obj.is15x15 + ? 0.95 + : 1); + var toolsMarginLeft; + if (core.domStyle.isVertical || obj.extendToolbar) + toolsMarginLeft = (core._HALF_WIDTH_ - 3) * 3 * core.domStyle.scale; + else + toolsMarginLeft = + (obj.BAR_WIDTH * core.domStyle.scale - 9 - toolsHeight * 3) / 4; + for (var i = 0; i < core.dom.tools.length; ++i) { + var style = core.dom.tools[i].style; + style.height = toolsHeight + "px"; + style.marginLeft = toolsMarginLeft + "px"; + style.marginTop = 3 * core.domStyle.scale + "px"; + } + core.dom.hard.style.lineHeight = toolsHeight + "px"; + if (core.domStyle.isVertical || obj.extendToolbar) { + core.dom.hard.style.width = + obj.outerWidth - 9 * toolsMarginLeft - 8.5 * toolsHeight - 12 + "px"; + } else { + core.dom.hard.style.width = + obj.BAR_WIDTH * core.domStyle.scale - 9 - 2 * toolsMarginLeft + "px"; + if (!obj.is15x15) core.dom.hard.style.marginTop = 0; + } +}; diff --git a/libs/events.js b/libs/events.js index 66d9954..41c383d 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1,429 +1,485 @@ - "use strict"; -function events () { - this._init(); +function events() { + this._init(); } ////// 初始化 ////// events.prototype._init = function () { - this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events; - this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent; - this.systemEvents = {}; - this.actions = {}; -} + this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events; + this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent; + this.systemEvents = {}; + this.actions = {}; +}; // ------ 初始化,开始和结束 ------ // /// 初始化游戏 events.prototype.resetGame = function (hero, hard, floorId, maps, values) { - this.eventdata.resetGame(hero, hard, floorId, maps, values); -} + this.eventdata.resetGame(hero, hard, floorId, maps, values); +}; ////// 游戏开始事件 ////// events.prototype.startGame = function (hard, seed, route, callback) { - main.dom.levelChooseButtons.style.display = 'none'; - main.dom.startButtonGroup.style.display = 'none'; - hard = hard || ""; + main.dom.levelChooseButtons.style.display = "none"; + main.dom.startButtonGroup.style.display = "none"; + hard = hard || ""; - if (main.mode != 'play') return; + if (main.mode != "play") return; - // 无动画的开始游戏 - if (core.flags.startUsingCanvas || route != null) { - core.dom.startPanel.style.display = 'none'; - this._startGame_start(hard, seed, route, callback); - } - else { - core.hideStartAnimate(function () { - core.events._startGame_start(hard, seed, route, callback); - }); - } -} + // 无动画的开始游戏 + if (core.flags.startUsingCanvas || route != null) { + core.dom.startPanel.style.display = "none"; + this._startGame_start(hard, seed, route, callback); + } else { + core.hideStartAnimate(function () { + core.events._startGame_start(hard, seed, route, callback); + }); + } +}; events.prototype._startGame_start = function (hard, seed, route, callback) { - core.resetGame(core.firstData.hero, hard, null, core.cloneArray(core.initStatus.maps)); - core.setHeroLoc('x', -1); - core.setHeroLoc('y', -1); + core.resetGame( + core.firstData.hero, + hard, + null, + core.cloneArray(core.initStatus.maps) + ); + core.setHeroLoc("x", -1); + core.setHeroLoc("y", -1); - if (seed != null && seed > 0) { - core.setFlag('__seed__', seed); - core.setFlag('__rand__', seed); - } - else core.utils.__init_seed(); - core.clearStatusBar(); + if (seed != null && seed > 0) { + core.setFlag("__seed__", seed); + core.setFlag("__rand__", seed); + } else core.utils.__init_seed(); + core.clearStatusBar(); - var todo = []; - if (core.flags.startUsingCanvas) { - core.hideStatusBar(); - core.dom.musicBtn.style.display = 'block'; - core.push(todo, core.firstData.startCanvas); - } - core.push(todo, { "type": "function", "function": "function() { core.events._startGame_setHard(); }" }) - core.push(todo, core.firstData.startText); - this.insertAction(todo, null, null, function () { - core.events._startGame_afterStart(callback); - }); + var todo = []; + if (core.flags.startUsingCanvas) { + core.hideStatusBar(); + core.dom.musicBtn.style.display = "block"; + core.push(todo, core.firstData.startCanvas); + } + core.push(todo, { + type: "function", + function: "function() { core.events._startGame_setHard(); }", + }); + core.push(todo, core.firstData.startText); + this.insertAction(todo, null, null, function () { + core.events._startGame_afterStart(callback); + }); - if (route != null) core.startReplay(route); -} + if (route != null) core.startReplay(route); +}; events.prototype._startGame_setHard = function () { - // 根据难度设置flag:hard - // 这一段应当在startCanvas之后,startText之前做 - var hardValue = 0; - var hardColor = 'red'; - main.levelChoose.forEach(function (one) { - if (one.name == core.status.hard) { - hardValue = one.hard; - hardColor = core.arrayToRGBA(one.color || [255, 0, 0, 1]); - core.insertAction(one.action); - } - }); - core.setFlag('hard', hardValue || 0); - core.setFlag('__hardColor__', hardColor); -} + // 根据难度设置flag:hard + // 这一段应当在startCanvas之后,startText之前做 + var hardValue = 0; + var hardColor = "red"; + main.levelChoose.forEach(function (one) { + if (one.name == core.status.hard) { + hardValue = one.hard; + hardColor = core.arrayToRGBA(one.color || [255, 0, 0, 1]); + core.insertAction(one.action); + } + }); + core.setFlag("hard", hardValue || 0); + core.setFlag("__hardColor__", hardColor); +}; events.prototype._startGame_afterStart = function (callback) { - core.ui.closePanel(); - core.changeFloor(core.firstData.floorId, null, core.firstData.hero.loc, null, function () { - // 插入一个空事件避免直接回放录像出错 - core.insertAction([]); - if (callback) callback(); - }); - this._startGame_upload(); -} + core.ui.closePanel(); + core.changeFloor( + core.firstData.floorId, + null, + core.firstData.hero.loc, + null, + function () { + // 插入一个空事件避免直接回放录像出错 + core.insertAction([]); + if (callback) callback(); + } + ); + this._startGame_upload(); +}; events.prototype._startGame_upload = function () { - // Upload - var formData = new FormData(); - formData.append('type', 'people'); - formData.append('name', core.firstData.name); - formData.append('version', core.firstData.version); - formData.append('platform', core.platform.string); - formData.append('hard', core.encodeBase64(core.status.hard)); - formData.append('hardCode', core.getFlag('hard', 0)); - formData.append('base64', 1); + // Upload + var formData = new FormData(); + formData.append("type", "people"); + formData.append("name", core.firstData.name); + formData.append("version", core.firstData.version); + formData.append("platform", core.platform.string); + formData.append("hard", core.encodeBase64(core.status.hard)); + formData.append("hardCode", core.getFlag("hard", 0)); + formData.append("base64", 1); - core.utils.http("POST", "/games/upload.php", formData); -} + core.utils.http("POST", "/games/upload.php", formData); +}; ////// 游戏获胜事件 ////// events.prototype.win = function (reason, norank, noexit) { - if (!noexit) core.status.gameOver = true; - return this.eventdata.win(reason, norank, noexit); -} + if (!noexit) core.status.gameOver = true; + return this.eventdata.win(reason, norank, noexit); +}; ////// 游戏失败事件 ////// events.prototype.lose = function (reason) { - if (core.isReplaying()) return core.control._replay_error(reason, function () { core.lose(reason); }); - core.status.gameOver = true; - return this.eventdata.lose(reason); -} + if (core.isReplaying()) + return core.control._replay_error(reason, function () { + core.lose(reason); + }); + core.status.gameOver = true; + return this.eventdata.lose(reason); +}; ////// 游戏结束 ////// events.prototype.gameOver = function (ending, fromReplay, norank) { - if (!core.status.extraEvent) { - core.clearMap('all'); - core.deleteAllCanvas(); - core.dom.gif2.innerHTML = ""; - core.setWeather(); - } - core.ui.closePanel(); + if (!core.status.extraEvent) { + core.clearMap("all"); + core.deleteAllCanvas(); + core.dom.gif2.innerHTML = ""; + core.setWeather(); + } + core.ui.closePanel(); - if (main.isCompetition && ending != null) { - if (ending == "") ending = "恭喜通关"; - ending += "[比赛]"; - } + if (main.isCompetition && ending != null) { + if (ending == "") ending = "恭喜通关"; + ending += "[比赛]"; + } - var reason = null; - if (fromReplay) reason = "录像回放完毕!"; - else if (core.hasFlag("debug")) reason = "\t[系统提示]调试模式下无法上传成绩"; + var reason = null; + if (fromReplay) reason = "录像回放完毕!"; + else if (core.hasFlag("debug")) reason = "\t[系统提示]调试模式下无法上传成绩"; - if (reason != null) - core.drawText(reason, core.restart); - else - this._gameOver_confirmUpload(ending, norank); -} + if (reason != null) core.drawText(reason, core.restart); + else this._gameOver_confirmUpload(ending, norank); +}; events.prototype._gameOver_confirmUpload = function (ending, norank) { - core.ui.closePanel(); + core.ui.closePanel(); - if (ending == null) { - this._gameOver_confirmDownload(ending); - return; + if (ending == null) { + this._gameOver_confirmDownload(ending); + return; + } + core.ui.drawConfirmBox( + "你想记录你的ID和成绩吗?", + function () { + if (main.isCompetition) { + core.events._gameOver_doUpload("", ending, norank); + } else { + var id = core.getCookie("id") || ""; + var hint = + "请输入你的ID:\n(登录状态下输入数字用户编号可成为蓝名成绩并计入用户通关数)"; + if (id) + hint = + "请输入你的ID:\n(输入数字用户编号" + + id + + "可成为蓝名成绩并计入用户通关数)"; + core.myprompt(hint, id, function (username) { + core.events._gameOver_doUpload(username, ending, norank); + }); + } + }, + function () { + if (main.isCompetition) core.events._gameOver_confirmDownload(ending); + else core.events._gameOver_doUpload(null, ending, norank); } - core.ui.drawConfirmBox("你想记录你的ID和成绩吗?", function () { - if (main.isCompetition) { - core.events._gameOver_doUpload("", ending, norank); - } - else { - var id = core.getCookie('id') || ""; - var hint = "请输入你的ID:\n(登录状态下输入数字用户编号可成为蓝名成绩并计入用户通关数)"; - if (id) hint = "请输入你的ID:\n(输入数字用户编号" + id + "可成为蓝名成绩并计入用户通关数)"; - core.myprompt(hint, id, function (username) { - core.events._gameOver_doUpload(username, ending, norank); - }); - } - }, function () { - if (main.isCompetition) - core.events._gameOver_confirmDownload(ending); - else - core.events._gameOver_doUpload(null, ending, norank); - }) -} + ); +}; events.prototype._gameOver_doUpload = function (username, ending, norank) { - var hp = core.status.hero.hp; - if (username == null) hp = 1; - core.ui.closePanel(); - // upload - var formData = new FormData(); - formData.append('type', 'score'); - formData.append('name', core.firstData.name); - formData.append('version', core.firstData.version); - formData.append('platform', core.platform.string); - formData.append('hard', core.encodeBase64(core.status.hard)); - formData.append('username', core.encodeBase64(username || "")); - formData.append('ending', core.encodeBase64(ending)); - formData.append('lv', core.status.hero.lv); - formData.append('hp', Math.min(hp, Math.pow(2, 63))); - formData.append('atk', core.status.hero.atk); - formData.append('def', core.status.hero.def); - formData.append('mdef', core.status.hero.mdef); - formData.append('money', core.status.hero.money); - formData.append('experience', core.status.hero.exp); - formData.append('steps', core.status.hero.steps); - formData.append('norank', norank ? 1 : 0); - formData.append('seed', core.getFlag('__seed__')); - formData.append('totalTime', Math.floor(core.status.hero.statistics.totalTime / 1000)); - formData.append('route', core.encodeRoute(core.status.route)); - formData.append('base64', 1); + var hp = core.status.hero.hp; + if (username == null) hp = 1; + core.ui.closePanel(); + // upload + var formData = new FormData(); + formData.append("type", "score"); + formData.append("name", core.firstData.name); + formData.append("version", core.firstData.version); + formData.append("platform", core.platform.string); + formData.append("hard", core.encodeBase64(core.status.hard)); + formData.append("username", core.encodeBase64(username || "")); + formData.append("ending", core.encodeBase64(ending)); + formData.append("lv", core.status.hero.lv); + formData.append("hp", Math.min(hp, Math.pow(2, 63))); + formData.append("atk", core.status.hero.atk); + formData.append("def", core.status.hero.def); + formData.append("mdef", core.status.hero.mdef); + formData.append("money", core.status.hero.money); + formData.append("experience", core.status.hero.exp); + formData.append("steps", core.status.hero.steps); + formData.append("norank", norank ? 1 : 0); + formData.append("seed", core.getFlag("__seed__")); + formData.append( + "totalTime", + Math.floor(core.status.hero.statistics.totalTime / 1000) + ); + formData.append("route", core.encodeRoute(core.status.route)); + formData.append("base64", 1); - if (main.isCompetition) - core.http("POST", "/games/competition/upload.php", formData); - else - core.http("POST", "/games/upload.php", formData); + if (main.isCompetition) + core.http("POST", "/games/competition/upload.php", formData); + else core.http("POST", "/games/upload.php", formData); - core.events._gameOver_confirmDownload(ending); -} + core.events._gameOver_confirmDownload(ending); +}; events.prototype._gameOver_confirmDownload = function (ending) { - core.ui.closePanel(); - core.ui.drawConfirmBox("你想下载录像吗?", function () { - var obj = { - 'name': core.firstData.name, - 'version': core.firstData.version, - 'hard': core.status.hard, - 'seed': core.getFlag('__seed__'), - 'route': core.encodeRoute(core.status.route) - } - core.download(core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5route", - LZString.compressToBase64(JSON.stringify(obj))); - core.events._gameOver_askRate(ending); - }, function () { - core.events._gameOver_askRate(ending); - }); -} + core.ui.closePanel(); + core.ui.drawConfirmBox( + "你想下载录像吗?", + function () { + var obj = { + name: core.firstData.name, + version: core.firstData.version, + hard: core.status.hard, + seed: core.getFlag("__seed__"), + route: core.encodeRoute(core.status.route), + }; + core.download( + core.firstData.name + "_" + core.formatDate2(new Date()) + ".h5route", + LZString.compressToBase64(JSON.stringify(obj)) + ); + core.events._gameOver_askRate(ending); + }, + function () { + core.events._gameOver_askRate(ending); + } + ); +}; events.prototype._gameOver_askRate = function (ending) { - core.ui.closePanel(); + core.ui.closePanel(); - // 继续接下来的事件 - if (core.status.extraEvent) { - core.status.event = core.status.extraEvent; - delete core.status.extraEvent; - core.lockControl(); - core.doAction(); - return; + // 继续接下来的事件 + if (core.status.extraEvent) { + core.status.event = core.status.extraEvent; + delete core.status.extraEvent; + core.lockControl(); + core.doAction(); + return; + } + + if (ending == null) { + if (!core.hasSave(0)) { + core.ui.closePanel(); + core.restart(); + return; } - if (ending == null) { - if (!core.hasSave(0)) { - core.ui.closePanel(); - core.restart(); - return; - } - - core.status.event.selection = 0; - core.ui.drawConfirmBox("你想读取自动存档么?", function () { - core.ui.closePanel(); - core.doSL("autoSave", "load"); - }, function () { - core.ui.closePanel(); - core.restart(); - }); - return; - } - - core.ui.drawConfirmBox("恭喜通关!你想查看榜单、评论,\n以及评分和标色投票吗?", function () { - if (core.platform.isPC) { - window.open("/tower/?name=" + core.firstData.name, "_blank"); - core.restart(); - } - else { - window.location.href = "/tower/?name=" + core.firstData.name; - } - }, function () { + core.status.event.selection = 0; + core.ui.drawConfirmBox( + "你想读取自动存档么?", + function () { + core.ui.closePanel(); + core.doSL("autoSave", "load"); + }, + function () { + core.ui.closePanel(); core.restart(); - }); -} + } + ); + return; + } + + core.ui.drawConfirmBox( + "恭喜通关!你想查看榜单、评论,\n以及评分和标色投票吗?", + function () { + if (core.platform.isPC) { + window.open("/tower/?name=" + core.firstData.name, "_blank"); + core.restart(); + } else { + window.location.href = "/tower/?name=" + core.firstData.name; + } + }, + function () { + core.restart(); + } + ); +}; ////// 重新开始游戏;此函数将回到标题页面 ////// events.prototype.restart = function () { - core.showStartAnimate(); - core.playBgm(main.startBgm); -} + core.showStartAnimate(); + core.playBgm(main.startBgm); +}; ////// 询问是否需要重新开始 ////// events.prototype.confirmRestart = function () { - core.playSound('打开界面'); - core.status.event.selection = 1; - core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () { - core.playSound('确定'); - core.ui.closePanel(); - core.restart(); - }, function () { - core.playSound('取消'); - core.ui.closePanel(); - }); -} + core.playSound("打开界面"); + core.status.event.selection = 1; + core.ui.drawConfirmBox( + "你确定要返回标题页面吗?", + function () { + core.playSound("确定"); + core.ui.closePanel(); + core.restart(); + }, + function () { + core.playSound("取消"); + core.ui.closePanel(); + } + ); +}; // ------ 系统事件的处理 ------ // ////// 注册一个系统事件 ////// // type为事件名,func为事件的处理函数,可接受(data, callback)参数 events.prototype.registerSystemEvent = function (type, func) { - this.systemEvents[type] = func; -} + this.systemEvents[type] = func; +}; ////// 注销一个系统事件 ////// events.prototype.unregisterSystemEvent = function (type) { - delete this.systemEvents[type]; -} + delete this.systemEvents[type]; +}; ////// 执行一个系统事件 ////// events.prototype.doSystemEvent = function (type, data, callback) { - core.clearRouteFolding(); - if (this.systemEvents[type]) { - try { - return core.doFunc(this.systemEvents[type], this, data, callback); - } - catch (e) { - console.error(e); - console.error("ERROR in systemEvents[" + type + "]"); - } + core.clearRouteFolding(); + if (this.systemEvents[type]) { + try { + return core.doFunc(this.systemEvents[type], this, data, callback); + } catch (e) { + console.error(e); + console.error("ERROR in systemEvents[" + type + "]"); } - if (this["_sys_" + type]) return this["_sys_" + type](data, callback); - console.error("未知的系统事件: " + type + "!"); - if (callback) callback(); -} + } + if (this["_sys_" + type]) return this["_sys_" + type](data, callback); + console.error("未知的系统事件: " + type + "!"); + if (callback) callback(); +}; ////// 触发(x,y)点的事件 ////// events.prototype.trigger = function (x, y, callback) { - var _executeCallback = function () { - // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测) - // 所以这里强制callback被异步触发 - if (callback) { - setTimeout(callback, 1); // +1是为了录像检测系统 - } - return; - } - if (core.status.gameOver) return _executeCallback(); - if (core.status.event.id == 'action') { - core.insertAction({ "type": "function", "function": "function () { core.events._trigger_inAction(" + x + "," + y + "); }", "async": true }, - null, null, null, true); - return _executeCallback(); - } - if (core.status.event.id) return _executeCallback(); - - var block = core.getBlock(x, y); - if (block == null) return _executeCallback(); - - // 执行该点的脚本 - if (block.event.script) { - core.clearRouteFolding(); - try { - eval(block.event.script); - } catch (ee) { console.error(ee) } - } - - // 碰触事件 - if (block.event.event) { - core.clearRouteFolding(); - core.insertAction(block.event.event, block.x, block.y); - // 不再执行该点的系统事件 - return _executeCallback(); - } - - if (block.event.trigger && block.event.trigger != 'null') { - var noPass = block.event.noPass, trigger = block.event.trigger; - if (noPass) core.clearAutomaticRouteNode(x, y); - - // 转换楼层能否穿透 - if (trigger == 'changeFloor' && !noPass && this._trigger_ignoreChangeFloor(block)) - return _executeCallback(); - core.status.automaticRoute.moveDirectly = false; - this.doSystemEvent(trigger, block); + var _executeCallback = function () { + // 因为trigger之后还有可能触发其他同步脚本(比如阻激夹域检测) + // 所以这里强制callback被异步触发 + if (callback) { + setTimeout(callback, 1); // +1是为了录像检测系统 } + return; + }; + if (core.status.gameOver) return _executeCallback(); + if (core.status.event.id == "action") { + core.insertAction( + { + type: "function", + function: + "function () { core.events._trigger_inAction(" + x + "," + y + "); }", + async: true, + }, + null, + null, + null, + true + ); return _executeCallback(); -} + } + if (core.status.event.id) return _executeCallback(); + + var block = core.getBlock(x, y); + if (block == null) return _executeCallback(); + + // 执行该点的脚本 + if (block.event.script) { + core.clearRouteFolding(); + try { + eval(block.event.script); + } catch (ee) { + console.error(ee); + } + } + + // 碰触事件 + if (block.event.event) { + core.clearRouteFolding(); + core.insertAction(block.event.event, block.x, block.y); + // 不再执行该点的系统事件 + return _executeCallback(); + } + + if (block.event.trigger && block.event.trigger != "null") { + var noPass = block.event.noPass, + trigger = block.event.trigger; + if (noPass) core.clearAutomaticRouteNode(x, y); + + // 转换楼层能否穿透 + if ( + trigger == "changeFloor" && + !noPass && + this._trigger_ignoreChangeFloor(block) + ) + return _executeCallback(); + core.status.automaticRoute.moveDirectly = false; + this.doSystemEvent(trigger, block); + } + return _executeCallback(); +}; events.prototype._trigger_inAction = function (x, y) { - if (core.status.gameOver || core.status.event.id != 'action') return; + if (core.status.gameOver || core.status.event.id != "action") return; - var block = core.getBlock(x, y); - if (block == null) return core.doAction(); + var block = core.getBlock(x, y); + if (block == null) return core.doAction(); - // 执行该点的脚本 - try { - eval(block.event.script); - } catch (ee) { console.error(ee) } + // 执行该点的脚本 + try { + eval(block.event.script); + } catch (ee) { + console.error(ee); + } - // 碰触事件 - if (block.event.event) { - core.clearRouteFolding(); - core.insertAction(block.event.event, block.x, block.y); - // 不再执行该点的系统事件 - return core.doAction(); - } - - if (block.event.trigger && block.event.trigger != 'null') { - this.setEvents(null, x, y); - if (block.event.trigger == 'action') { - this.insertAction(block.event.data); - } - else { - this.doSystemEvent(block.event.trigger, block, core.doAction); - return; - } - } + // 碰触事件 + if (block.event.event) { + core.clearRouteFolding(); + core.insertAction(block.event.event, block.x, block.y); + // 不再执行该点的系统事件 return core.doAction(); -} + } + + if (block.event.trigger && block.event.trigger != "null") { + this.setEvents(null, x, y); + if (block.event.trigger == "action") { + this.insertAction(block.event.data); + } else { + this.doSystemEvent(block.event.trigger, block, core.doAction); + return; + } + } + return core.doAction(); +}; events.prototype._trigger_ignoreChangeFloor = function (block) { - var able = core.flags.ignoreChangeFloor; - if (block.event.data && block.event.data.ignoreChangeFloor != null) - able = block.event.data.ignoreChangeFloor; - if (able) { - if (core.isReplaying()) { - if (core.status.replay.toReplay[0] == 'no') { - core.status.replay.toReplay.shift(); - core.status.route.push("no"); - return true; - } - } - else if (core.status.automaticRoute.autoHeroMove - || core.status.automaticRoute.autoStep < core.status.automaticRoute.autoStepRoutes.length) { - core.status.route.push("no"); - return true; - } + var able = core.flags.ignoreChangeFloor; + if (block.event.data && block.event.data.ignoreChangeFloor != null) + able = block.event.data.ignoreChangeFloor; + if (able) { + if (core.isReplaying()) { + if (core.status.replay.toReplay[0] == "no") { + core.status.replay.toReplay.shift(); + core.status.route.push("no"); + return true; + } + } else if ( + core.status.automaticRoute.autoHeroMove || + core.status.automaticRoute.autoStep < + core.status.automaticRoute.autoStepRoutes.length + ) { + core.status.route.push("no"); + return true; } - return false; -} + } + return false; +}; events.prototype._sys_battle = function (data, callback) { - // 检查是否需要改变朝向 - /* if (data.x == core.nextX() && data.y == core.nextY()) { + // 检查是否需要改变朝向 + /* if (data.x == core.nextX() && data.y == core.nextY()) { var dir = core.turnDirection(":back"); var id = data.event.id, toId = (data.event.faceIds || {})[dir]; if (toId && id != toId) { @@ -433,499 +489,554 @@ events.prototype._sys_battle = function (data, callback) { } } */ - // 检查战前事件 - var beforeBattle = []; - core.push(beforeBattle, core.floors[core.status.floorId].beforeBattle[data.x + "," + data.y]); - core.push(beforeBattle, (core.material.enemys[data.event.id] || {}).beforeBattle); - if (beforeBattle.length > 0) { - core.push(beforeBattle, [{ "type": "battle", "x": data.x, "y": data.y }]); - core.clearContinueAutomaticRoute(); + // 检查战前事件 + var beforeBattle = []; + core.push( + beforeBattle, + core.floors[core.status.floorId].beforeBattle[data.x + "," + data.y] + ); + core.push( + beforeBattle, + (core.material.enemys[data.event.id] || {}).beforeBattle + ); + if (beforeBattle.length > 0) { + core.push(beforeBattle, [{ type: "battle", x: data.x, y: data.y }]); + core.clearContinueAutomaticRoute(); - // 自动存档 - var inAction = core.status.event.id == 'action'; - if (inAction) { - core.insertAction(beforeBattle, data.x, data.y); - core.doAction(); - } else { - core.autosave(true); - core.insertAction(beforeBattle, data.x, data.y, callback); - } + // 自动存档 + var inAction = core.status.event.id == "action"; + if (inAction) { + core.insertAction(beforeBattle, data.x, data.y); + core.doAction(); } else { - this.battle(data.event.id, data.x, data.y, false, callback); + core.autosave(true); + core.insertAction(beforeBattle, data.x, data.y, callback); } -} + } else { + this.battle(data.event.id, data.x, data.y, false, callback); + } +}; ////// 战斗 ////// events.prototype.battle = function (id, x, y, force, callback) { - core.saveAndStopAutomaticRoute(); - id = id || core.getBlockId(x, y); - if (!id) return core.clearContinueAutomaticRoute(callback); - // 非强制战斗 - if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { - core.stopSound(); - core.playSound('操作失败'); - core.drawTip("你打不过此怪物!", id); - return core.clearContinueAutomaticRoute(callback); - } - // 自动存档 - if (!core.status.event.id) core.autosave(true); - // 战前事件 - if (!this.beforeBattle(id, x, y)) - return core.clearContinueAutomaticRoute(callback); - // 战后事件 - this.afterBattle(id, x, y); - if (callback) callback(); -} + core.saveAndStopAutomaticRoute(); + id = id || core.getBlockId(x, y); + if (!id) return core.clearContinueAutomaticRoute(callback); + // 非强制战斗 + if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip("你打不过此怪物!", id); + return core.clearContinueAutomaticRoute(callback); + } + // 自动存档 + if (!core.status.event.id) core.autosave(true); + // 战前事件 + if (!this.beforeBattle(id, x, y)) + return core.clearContinueAutomaticRoute(callback); + // 战后事件 + this.afterBattle(id, x, y); + if (callback) callback(); +}; ////// 战斗前触发的事件 ////// events.prototype.beforeBattle = function (enemyId, x, y) { - return this.eventdata.beforeBattle(enemyId, x, y) -} + return this.eventdata.beforeBattle(enemyId, x, y); +}; ////// 战斗结束后触发的事件 ////// events.prototype.afterBattle = function (enemyId, x, y) { - return this.eventdata.afterBattle(enemyId, x, y); -} + return this.eventdata.afterBattle(enemyId, x, y); +}; events.prototype._sys_openDoor = function (data, callback) { - this.openDoor(data.x, data.y, true, function () { - core.replay(); - if (callback) callback(); - }); -} + this.openDoor(data.x, data.y, true, function () { + core.replay(); + if (callback) callback(); + }); +}; ////// 开门 ////// events.prototype.openDoor = function (x, y, needKey, callback) { - var block = core.getBlock(x, y); - core.saveAndStopAutomaticRoute(); - if (!this._openDoor_check(block, x, y, needKey)) { - var locked = core.status.lockControl; - core.waitHeroToStop(function () { - if (!locked) core.unlockControl(); - if (callback) callback(); - }); - return; - } - if (core.status.replay.speed == 24) { - core.status.replay.animate = true; - core.removeBlock(x, y); - setTimeout(function () { - core.status.replay.animate = false; - core.events.afterOpenDoor(block.event.id, x, y); - if (callback) callback(); - }, 1); // +1是为了录像检测系统 - } else { - this._openDoor_animate(block, x, y, callback); - } -} - -events.prototype._openDoor_check = function (block, x, y, needKey) { - var clearAndReturn = function () { - core.clearContinueAutomaticRoute(); - return false; - } - - if (block == null || block.event == null) return clearAndReturn(); - var id = block.event.id; - - // 是否存在门或暗墙 - if (core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null) { - return clearAndReturn(); - } - - if (id == 'steelDoor' && core.flags.steelDoorWithoutKey) - needKey = false; - var doorInfo = block.event.doorInfo; - if (doorInfo == null) return clearAndReturn(); - // Check all keys - var keyInfo = doorInfo.keys || {}; - if (needKey) { - for (var keyName in keyInfo) { - var keyValue = keyInfo[keyName]; - if (keyName.endsWith(':o')) keyName = keyName.substring(0, keyName.length - 2); - - // --- 如果是一个不存在的道具,则直接认为无法开启 - if (!core.material.items[keyName]) { - core.stopSound(); - core.playSound('操作失败'); - core.drawTip("无法开启此门"); - return clearAndReturn(); - } - if (core.itemCount(keyName) < keyValue) { - core.stopSound(); - core.playSound('操作失败'); - core.drawTip("你的" + ((core.material.items[keyName] || {}).name || "钥匙") + "不足!", null, true); - return false; - } - } - if (!core.status.event.id) core.autosave(true); - for (var keyName in keyInfo) { - if (!keyName.endsWith(':o')) core.removeItem(keyName, keyInfo[keyName]); - } - } - core.playSound(doorInfo.openSound); - return true; -} - -events.prototype._openDoor_animate = function (block, x, y, callback) { - var blockInfo = core.getBlockInfo(block); - blockInfo.opacity = block.opacity; - blockInfo.filter = block.filter; - - var speed = (block.event.doorInfo.time || 160) / 4; - + var block = core.getBlock(x, y); + core.saveAndStopAutomaticRoute(); + if (!this._openDoor_check(block, x, y, needKey)) { var locked = core.status.lockControl; - core.lockControl(); + core.waitHeroToStop(function () { + if (!locked) core.unlockControl(); + if (callback) callback(); + }); + return; + } + if (core.status.replay.speed == 24) { core.status.replay.animate = true; core.removeBlock(x, y); + setTimeout(function () { + core.status.replay.animate = false; + core.events.afterOpenDoor(block.event.id, x, y); + if (callback) callback(); + }, 1); // +1是为了录像检测系统 + } else { + this._openDoor_animate(block, x, y, callback); + } +}; - blockInfo.posX = 0; - core.maps._drawBlockInfo(blockInfo, x, y); +events.prototype._openDoor_check = function (block, x, y, needKey) { + var clearAndReturn = function () { + core.clearContinueAutomaticRoute(); + return false; + }; - var cb = function () { - core.maps._removeBlockFromMap(core.status.floorId, block); - if (!locked) core.unlockControl(); - core.status.replay.animate = false; - core.events.afterOpenDoor(block.event.id, x, y); - if (callback) callback(); + if (block == null || block.event == null) return clearAndReturn(); + var id = block.event.id; + + // 是否存在门或暗墙 + if ( + core.material.icons.animates[id] == null && + core.material.icons.npc48[id] == null + ) { + return clearAndReturn(); + } + + if (id == "steelDoor" && core.flags.steelDoorWithoutKey) needKey = false; + var doorInfo = block.event.doorInfo; + if (doorInfo == null) return clearAndReturn(); + // Check all keys + var keyInfo = doorInfo.keys || {}; + if (needKey) { + for (var keyName in keyInfo) { + var keyValue = keyInfo[keyName]; + if (keyName.endsWith(":o")) + keyName = keyName.substring(0, keyName.length - 2); + + // --- 如果是一个不存在的道具,则直接认为无法开启 + if (!core.material.items[keyName]) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip("无法开启此门"); + return clearAndReturn(); + } + if (core.itemCount(keyName) < keyValue) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip( + "你的" + + ((core.material.items[keyName] || {}).name || "钥匙") + + "不足!", + null, + true + ); + return false; + } } + if (!core.status.event.id) core.autosave(true); + for (var keyName in keyInfo) { + if (!keyName.endsWith(":o")) core.removeItem(keyName, keyInfo[keyName]); + } + } + core.playSound(doorInfo.openSound); + return true; +}; - var animate = window.setInterval(function () { - blockInfo.posX++; - if (blockInfo.posX == 4) { - clearInterval(animate); - delete core.animateFrame.asyncId[animate]; - cb(); - return; - } - core.maps._drawBlockInfo(blockInfo, x, y); - }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); +events.prototype._openDoor_animate = function (block, x, y, callback) { + var blockInfo = core.getBlockInfo(block); + blockInfo.opacity = block.opacity; + blockInfo.filter = block.filter; - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + var speed = (block.event.doorInfo.time || 160) / 4; + + var locked = core.status.lockControl; + core.lockControl(); + core.status.replay.animate = true; + core.removeBlock(x, y); + + blockInfo.posX = 0; + core.maps._drawBlockInfo(blockInfo, x, y); + + var cb = function () { + core.maps._removeBlockFromMap(core.status.floorId, block); + if (!locked) core.unlockControl(); + core.status.replay.animate = false; + core.events.afterOpenDoor(block.event.id, x, y); + if (callback) callback(); + }; + + var animate = window.setInterval( + function () { + blockInfo.posX++; + if (blockInfo.posX == 4) { + clearInterval(animate); + delete core.animateFrame.asyncId[animate]; + cb(); + return; + } + core.maps._drawBlockInfo(blockInfo, x, y); + }, + core.status.replay.speed == 24 + ? 1 + : speed / Math.max(core.status.replay.speed, 1) + ); + + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 开一个门后触发的事件 ////// events.prototype.afterOpenDoor = function (doorId, x, y) { - return this.eventdata.afterOpenDoor(doorId, x, y); -} + return this.eventdata.afterOpenDoor(doorId, x, y); +}; events.prototype._sys_getItem = function (data, callback) { - this.getItem(data.event.id, 1, data.x, data.y, false, callback); -} + this.getItem(data.event.id, 1, data.x, data.y, false, callback); +}; ////// 获得某个物品 ////// events.prototype.getItem = function (id, num, x, y, isGentleClick, callback) { - if (num == null) num = 1; - var itemCls = core.material.items[id].cls; - core.removeBlock(x, y); - core.items.getItemEffect(id, num); - var text = '获得 ' + core.material.items[id].name; - if (num > 1) text += "x" + num; - if (itemCls === 'items' && num == 1) text += core.items.getItemEffectTip(id); - core.drawTip(text, id); + if (num == null) num = 1; + var itemCls = core.material.items[id].cls; + core.removeBlock(x, y); + core.items.getItemEffect(id, num); + var text = "获得 " + core.material.items[id].name; + if (num > 1) text += "x" + num; + if (itemCls === "items" && num == 1) text += core.items.getItemEffectTip(id); + core.drawTip(text, id); - // --- 首次获得道具的提示 - if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []); - var itemHint = core.getFlag("__itemHint__"); - if (core.flags.itemFirstText && itemHint.indexOf(id) < 0 && itemCls != 'items') { - var hint = core.material.items[id].text || "该道具暂无描述"; - try { - hint = core.replaceText(hint); - } catch (e) { } - if (!core.status.event.id || core.status.event.id == 'action') { - core.insertAction("\t[" + core.material.items[id].name + "," + id + "]" + hint + "\n" - + (id.endsWith('Key') ? "(钥匙类道具,遇到对应的门时自动打开)" - : itemCls == 'tools' ? "(消耗类道具,请按T在道具栏使用)" - : itemCls == 'constants' ? "(永久类道具,请按T在道具栏使用)" - : itemCls == 'equips' ? "(装备类道具,请按Q在装备栏进行装备)" : "")); - } - itemHint.push(id); + // --- 首次获得道具的提示 + if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []); + var itemHint = core.getFlag("__itemHint__"); + if ( + core.flags.itemFirstText && + itemHint.indexOf(id) < 0 && + itemCls != "items" + ) { + var hint = core.material.items[id].text || "该道具暂无描述"; + try { + hint = core.replaceText(hint); + } catch (e) {} + if (!core.status.event.id || core.status.event.id == "action") { + core.insertAction( + "\t[" + + core.material.items[id].name + + "," + + id + + "]" + + hint + + "\n" + + (id.endsWith("Key") + ? "(钥匙类道具,遇到对应的门时自动打开)" + : itemCls == "tools" + ? "(消耗类道具,请按T在道具栏使用)" + : itemCls == "constants" + ? "(永久类道具,请按T在道具栏使用)" + : itemCls == "equips" + ? "(装备类道具,请按Q在装备栏进行装备)" + : "") + ); } + itemHint.push(id); + } - this.afterGetItem(id, x, y, isGentleClick); - if (callback) callback(); -} + this.afterGetItem(id, x, y, isGentleClick); + if (callback) callback(); +}; events.prototype.afterGetItem = function (id, x, y, isGentleClick) { - this.eventdata.afterGetItem(id, x, y, isGentleClick); -} + this.eventdata.afterGetItem(id, x, y, isGentleClick); +}; ////// 获得面前的物品(轻按) ////// events.prototype.getNextItem = function (noRoute) { - if (core.isMoving() || !core.flags.enableGentleClick) return false; - if (this._canGetNextItem()) return this._getNextItem(null, noRoute); + if (core.isMoving() || !core.flags.enableGentleClick) return false; + if (this._canGetNextItem()) return this._getNextItem(null, noRoute); - var directions = ["up", "down", "left", "right"].filter(function (dir) { - return core.events._canGetNextItem(dir); - }); - return directions.length > 0 ? this._getNextItem(directions[0], noRoute) : false; -} + var directions = ["up", "down", "left", "right"].filter(function (dir) { + return core.events._canGetNextItem(dir); + }); + return directions.length > 0 + ? this._getNextItem(directions[0], noRoute) + : false; +}; events.prototype._canGetNextItem = function (direction) { - direction = direction || core.getHeroLoc('direction'); - if (!core.canMoveHero(null, null, direction)) return; - var nx = core.getHeroLoc('x') + core.utils.scan[direction].x; - var ny = core.getHeroLoc('y') + core.utils.scan[direction].y; - var block = core.getBlock(nx, ny); - return block != null && !block.event.script && !block.event.event && block.event.trigger == 'getItem'; -} + direction = direction || core.getHeroLoc("direction"); + if (!core.canMoveHero(null, null, direction)) return; + var nx = core.getHeroLoc("x") + core.utils.scan[direction].x; + var ny = core.getHeroLoc("y") + core.utils.scan[direction].y; + var block = core.getBlock(nx, ny); + return ( + block != null && + !block.event.script && + !block.event.event && + block.event.trigger == "getItem" + ); +}; events.prototype._getNextItem = function (direction, noRoute) { - direction = direction || core.getHeroLoc('direction'); - var nx = core.getHeroLoc('x') + core.utils.scan[direction].x; - var ny = core.getHeroLoc('y') + core.utils.scan[direction].y; - if (!noRoute) core.status.route.push("getNext"); - this.getItem(core.getBlockId(nx, ny), 1, nx, ny, true); - return true; -} + direction = direction || core.getHeroLoc("direction"); + var nx = core.getHeroLoc("x") + core.utils.scan[direction].x; + var ny = core.getHeroLoc("y") + core.utils.scan[direction].y; + if (!noRoute) core.status.route.push("getNext"); + this.getItem(core.getBlockId(nx, ny), 1, nx, ny, true); + return true; +}; events.prototype._sys_changeFloor = function (data, callback) { - data = data.event.data; - var heroLoc = {}; - if (data.loc) heroLoc = { 'x': data.loc[0], 'y': data.loc[1] }; - if (data.direction) heroLoc.direction = data.direction; - if (core.status.event.id != 'action') core.status.event.id = null; - core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () { - core.replay(); - if (callback) callback(); - }); -} + data = data.event.data; + var heroLoc = {}; + if (data.loc) heroLoc = { x: data.loc[0], y: data.loc[1] }; + if (data.direction) heroLoc.direction = data.direction; + if (core.status.event.id != "action") core.status.event.id = null; + core.changeFloor(data.floorId, data.stair, heroLoc, data.time, function () { + core.replay(); + if (callback) callback(); + }); +}; ////// 楼层切换 ////// -events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) { - var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); - if (info == null) { - if (callback) callback(); - return; - } - floorId = info.floorId; - info.locked = core.status.lockControl; +events.prototype.changeFloor = function ( + floorId, + stair, + heroLoc, + time, + callback +) { + var info = this._changeFloor_getInfo(floorId, stair, heroLoc, time); + if (info == null) { + if (callback) callback(); + return; + } + floorId = info.floorId; + info.locked = core.status.lockControl; - core.dom.floorNameLabel.innerText = core.status.maps[floorId].title; - core.lockControl(); - core.stopAutomaticRoute(); - core.clearContinueAutomaticRoute(); - core.status.replay.animate = true; - clearInterval(core.interval.onDownInterval); - core.interval.onDownInterval = 'tmp'; + core.dom.floorNameLabel.innerText = core.status.maps[floorId].title; + core.lockControl(); + core.stopAutomaticRoute(); + core.clearContinueAutomaticRoute(); + core.status.replay.animate = true; + clearInterval(core.interval.onDownInterval); + core.interval.onDownInterval = "tmp"; - this._changeFloor_beforeChange(info, callback); -} + this._changeFloor_beforeChange(info, callback); +}; -events.prototype._changeFloor_getInfo = function (floorId, stair, heroLoc, time) { - floorId = floorId || core.status.floorId; - if (floorId == ':before') { - var index = core.floorIds.indexOf(core.status.floorId); - if (index > 0) floorId = core.floorIds[index - 1]; - else floorId = core.status.floorId; - } - else if (floorId == ':next') { - var index = core.floorIds.indexOf(core.status.floorId); - if (index < core.floorIds.length - 1) floorId = core.floorIds[index + 1]; - else floorId = core.status.floorId; - } else if (floorId == ':now') { - floorId = core.status.floorId; - } - if (!core.status.maps[floorId]) { - console.error("不存在的楼层:" + floorId); - return null; - } +events.prototype._changeFloor_getInfo = function ( + floorId, + stair, + heroLoc, + time +) { + floorId = floorId || core.status.floorId; + if (floorId == ":before") { + var index = core.floorIds.indexOf(core.status.floorId); + if (index > 0) floorId = core.floorIds[index - 1]; + else floorId = core.status.floorId; + } else if (floorId == ":next") { + var index = core.floorIds.indexOf(core.status.floorId); + if (index < core.floorIds.length - 1) floorId = core.floorIds[index + 1]; + else floorId = core.status.floorId; + } else if (floorId == ":now") { + floorId = core.status.floorId; + } + if (!core.status.maps[floorId]) { + console.error("不存在的楼层:" + floorId); + return null; + } - if (main.mode != 'play' || core.isReplaying()) time = 0; - if (time == null) time = core.values.floorChangeTime; - time /= 20; + if (main.mode != "play" || core.isReplaying()) time = 0; + if (time == null) time = core.values.floorChangeTime; + time /= 20; - return { - floorId: floorId, - time: time, - heroLoc: core.clone(this._changeFloor_getHeroLoc(floorId, stair, heroLoc)) - }; -} + return { + floorId: floorId, + time: time, + heroLoc: core.clone(this._changeFloor_getHeroLoc(floorId, stair, heroLoc)), + }; +}; events.prototype._changeFloor_getHeroLoc = function (floorId, stair, heroLoc) { - if (!heroLoc) - heroLoc = core.clone(core.status.hero.loc); - if (stair) { - // --- 对称 - if (stair == ':now') - heroLoc = core.clone(core.status.hero.loc); - else if (stair == ':symmetry') { - heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x'); - heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y'); - } - else if (stair == ':symmetry_x') - heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc('x'); - else if (stair == ':symmetry_y') - heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc('y'); - // 检查该层地图的 upFloor & downFloor & flyPoint - else if (core.status.maps[floorId][stair]) { - heroLoc.x = core.status.maps[floorId][stair][0]; - heroLoc.y = core.status.maps[floorId][stair][1]; - } - else { - core.extractBlocks(floorId); - var blocks = core.status.maps[floorId].blocks; - for (var i in blocks) { - if (!blocks[i].disable && blocks[i].event.id === stair) { - heroLoc.x = blocks[i].x; - heroLoc.y = blocks[i].y; - break; - } - } + if (!heroLoc) heroLoc = core.clone(core.status.hero.loc); + if (stair) { + // --- 对称 + if (stair == ":now") heroLoc = core.clone(core.status.hero.loc); + else if (stair == ":symmetry") { + heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc("x"); + heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc("y"); + } else if (stair == ":symmetry_x") + heroLoc.x = core.bigmap.width - 1 - core.getHeroLoc("x"); + else if (stair == ":symmetry_y") + heroLoc.y = core.bigmap.height - 1 - core.getHeroLoc("y"); + // 检查该层地图的 upFloor & downFloor & flyPoint + else if (core.status.maps[floorId][stair]) { + heroLoc.x = core.status.maps[floorId][stair][0]; + heroLoc.y = core.status.maps[floorId][stair][1]; + } else { + core.extractBlocks(floorId); + var blocks = core.status.maps[floorId].blocks; + for (var i in blocks) { + if (!blocks[i].disable && blocks[i].event.id === stair) { + heroLoc.x = blocks[i].x; + heroLoc.y = blocks[i].y; + break; } + } } - ['x', 'y', 'direction'].forEach(function (name) { - if (heroLoc[name] == null) - heroLoc[name] = core.getHeroLoc(name); - }); - return heroLoc; -} + } + ["x", "y", "direction"].forEach(function (name) { + if (heroLoc[name] == null) heroLoc[name] = core.getHeroLoc(name); + }); + return heroLoc; +}; events.prototype._changeFloor_beforeChange = function (info, callback) { - this._changeFloor_playSound(); - // 需要 setTimeout 执行,不然会出错 - window.setTimeout(function () { - if (info.time == 0) - core.events._changeFloor_changing(info, callback); - else - core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () { - core.events._changeFloor_changing(info, callback); - }); - }, 25) -} + this._changeFloor_playSound(); + // 需要 setTimeout 执行,不然会出错 + window.setTimeout(function () { + if (info.time == 0) core.events._changeFloor_changing(info, callback); + else + core.showWithAnimate(core.dom.floorMsgGroup, info.time / 2, function () { + core.events._changeFloor_changing(info, callback); + }); + }, 25); +}; events.prototype._changeFloor_playSound = function () { - // 播放换层音效 - if (core.hasFlag('__fromLoad__')) // 是否是读档造成的切换 - core.playSound('读档'); - else if (core.hasFlag('__isFlying__')) // 是否是楼传造成的切换 - core.playSound('飞行器'); - else - core.playSound('上下楼'); -} + // 播放换层音效 + if (core.hasFlag("__fromLoad__")) + // 是否是读档造成的切换 + core.playSound("读档"); + else if (core.hasFlag("__isFlying__")) + // 是否是楼传造成的切换 + core.playSound("飞行器"); + else core.playSound("上下楼"); +}; events.prototype._changeFloor_changing = function (info, callback) { - this.changingFloor(info.floorId, info.heroLoc); - // 回归视角 - var __lockViewport__ = flags.__lockViewport__; - core.setFlag('__lockViewport__', null); - core.drawHero(); - core.setFlag('__lockViewport__', __lockViewport__); + this.changingFloor(info.floorId, info.heroLoc); + // 回归视角 + var __lockViewport__ = flags.__lockViewport__; + core.setFlag("__lockViewport__", null); + core.drawHero(); + core.setFlag("__lockViewport__", __lockViewport__); - if (info.time == 0) - this._changeFloor_afterChange(info, callback); - else - core.hideWithAnimate(core.dom.floorMsgGroup, info.time / 4, function () { - core.events._changeFloor_afterChange(info, callback); - }); -} + if (info.time == 0) this._changeFloor_afterChange(info, callback); + else + core.hideWithAnimate(core.dom.floorMsgGroup, info.time / 4, function () { + core.events._changeFloor_afterChange(info, callback); + }); +}; events.prototype._changeFloor_afterChange = function (info, callback) { - if (!info.locked) core.unlockControl(); - core.status.replay.animate = false; - core.events.afterChangeFloor(info.floorId); + if (!info.locked) core.unlockControl(); + core.status.replay.animate = false; + core.events.afterChangeFloor(info.floorId); - if (callback) callback(); -} + if (callback) callback(); +}; events.prototype.changingFloor = function (floorId, heroLoc) { - this.eventdata.changingFloor(floorId, heroLoc); -} + this.eventdata.changingFloor(floorId, heroLoc); +}; ////// 转换楼层结束的事件 ////// events.prototype.afterChangeFloor = function (floorId) { - if (main.mode != 'play') return; - return this.eventdata.afterChangeFloor(floorId); -} + if (main.mode != "play") return; + return this.eventdata.afterChangeFloor(floorId); +}; ////// 是否到达过某个楼层 ////// events.prototype.hasVisitedFloor = function (floorId) { - if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); - return core.getFlag("__visited__")[floorId] || false; -} + if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); + return core.getFlag("__visited__")[floorId] || false; +}; ////// 到达某楼层 ////// events.prototype.visitFloor = function (floorId) { - if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); - core.getFlag("__visited__")[floorId] = true; -} + if (!core.hasFlag("__visited__")) core.setFlag("__visited__", {}); + core.getFlag("__visited__")[floorId] = true; +}; events.prototype._sys_pushBox = function (data, callback) { - this.pushBox(data); - if (callback) callback(); -} + this.pushBox(data); + if (callback) callback(); +}; ////// 推箱子 ////// events.prototype.pushBox = function (data) { - if (data.event.id != 'box' && data.event.id != 'boxed') return; + if (data.event.id != "box" && data.event.id != "boxed") return; - // 判断还能否前进,看看是否存在事件 - var direction = core.getHeroLoc('direction'), - nx = data.x + core.utils.scan[direction].x, ny = data.y + core.utils.scan[direction].y; + // 判断还能否前进,看看是否存在事件 + var direction = core.getHeroLoc("direction"), + nx = data.x + core.utils.scan[direction].x, + ny = data.y + core.utils.scan[direction].y; - // 检测能否推上去 - if (!core.canMoveHero()) return; - var canGoDeadZone = core.flags.canGoDeadZone; - core.flags.canGoDeadZone = true; - if (!core.canMoveHero(data.x, data.y, direction)) { - core.flags.canGoDeadZone = canGoDeadZone; - return; - } + // 检测能否推上去 + if (!core.canMoveHero()) return; + var canGoDeadZone = core.flags.canGoDeadZone; + core.flags.canGoDeadZone = true; + if (!core.canMoveHero(data.x, data.y, direction)) { core.flags.canGoDeadZone = canGoDeadZone; + return; + } + core.flags.canGoDeadZone = canGoDeadZone; - var nextId = core.getBlockId(nx, ny); - if (nextId != null && nextId != 'flower') return; + var nextId = core.getBlockId(nx, ny); + if (nextId != null && nextId != "flower") return; - core.setBlock(nextId == null ? 'box' : 'boxed', nx, ny); + core.setBlock(nextId == null ? "box" : "boxed", nx, ny); - if (data.event.id == 'box') - core.removeBlock(data.x, data.y); - else - core.setBlock('flower', data.x, data.y); - // 勇士前进一格,然后触发推箱子后事件 - core.insertAction([ - { "type": "moveAction" }, - { "type": "function", "function": "function() { core.afterPushBox(); }" } - ]); -} + if (data.event.id == "box") core.removeBlock(data.x, data.y); + else core.setBlock("flower", data.x, data.y); + // 勇士前进一格,然后触发推箱子后事件 + core.insertAction([ + { type: "moveAction" }, + { type: "function", function: "function() { core.afterPushBox(); }" }, + ]); +}; ////// 推箱子后的事件 ////// events.prototype.afterPushBox = function () { - return this.eventdata.afterPushBox(); -} + return this.eventdata.afterPushBox(); +}; events.prototype._sys_ski = function (data, callback) { - core.insertAction(["V2.6后,请将滑冰放在背景层!"], data.x, data.y); - if (callback) callback(); -} + core.insertAction(["V2.6后,请将滑冰放在背景层!"], data.x, data.y); + if (callback) callback(); +}; /// 当前是否在冰上 events.prototype.onSki = function (number) { - if (number == null) number = core.getBgNumber(); - var block = core.getBlockByNumber(number); - return block && block.event && block.event.trigger == 'ski'; -} + if (number == null) number = core.getBgNumber(); + var block = core.getBlockByNumber(number); + return block && block.event && block.event.trigger == "ski"; +}; events.prototype._sys_action = function (data, callback) { - var ev = core.clone(data.event.data), ex = data.x, ey = data.y; - // 检查是否需要改变朝向 - if (ex == core.nextX() && ey == core.nextY()) { - var dir = core.turnDirection(":back"); - var id = data.event.id, toId = (data.event.faceIds || {})[dir]; - if (toId && id != toId) { - var number = core.getNumberById(toId); - if (number > 0) - core.setBlock(number, ex, ey); - } + var ev = core.clone(data.event.data), + ex = data.x, + ey = data.y; + // 检查是否需要改变朝向 + if (ex == core.nextX() && ey == core.nextY()) { + var dir = core.turnDirection(":back"); + var id = data.event.id, + toId = (data.event.faceIds || {})[dir]; + if (toId && id != toId) { + var number = core.getNumberById(toId); + if (number > 0) core.setBlock(number, ex, ey); } - this.insertAction(ev, ex, ey, callback); -} + } + this.insertAction(ev, ex, ey, callback); +}; events.prototype._sys_custom = function (data, callback) { - core.insertAction(["请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!"], - data.x, data.y, callback); -} + core.insertAction( + [ + "请使用\r[yellow]core.registerSystemEvent('custom', func)\r来处理自己添加的系统触发器!", + ], + data.x, + data.y, + callback + ); +}; // ------ 自定义事件的处理 ------ // @@ -933,2856 +1044,3552 @@ events.prototype._sys_custom = function (data, callback) { // type为事件名,func为事件的处理函数,可接受(data, x, y, prefix)参数 // data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀 events.prototype.registerEvent = function (type, func) { - this.actions[type] = func; -} + this.actions[type] = func; +}; ////// 注销一个自定义事件 events.prototype.unregisterEvent = function (type) { - delete this.actions[type]; -} + delete this.actions[type]; +}; ////// 执行一个自定义事件 events.prototype.doEvent = function (data, x, y, prefix) { - var type = data.type; - if (this.actions[type]) { - try { - return core.doFunc(this.actions[type], this, data, x, y, prefix); - } - catch (e) { - console.error(e); - console.error("ERROR in actions[" + type + "]"); - } + var type = data.type; + if (this.actions[type]) { + try { + return core.doFunc(this.actions[type], this, data, x, y, prefix); + } catch (e) { + console.error(e); + console.error("ERROR in actions[" + type + "]"); } - if (this["_action_" + type]) return this["_action_" + type](data, x, y, prefix); - core.insertAction("未知的自定义事件: " + type + "!"); - core.doAction(); -} + } + if (this["_action_" + type]) + return this["_action_" + type](data, x, y, prefix); + core.insertAction("未知的自定义事件: " + type + "!"); + core.doAction(); +}; events.prototype.setEvents = function (list, x, y, callback) { - var data = core.status.event.data || {}; - if (list) { - var l = core.clone(list); - if (!(l instanceof Array)) l = [l]; - l.push({ "type": "_label" }); - data.list = [{ todo: l, total: core.clone(l), condition: "false" }]; - // 结束所有正在执行的自动事件 - if (list.length == 0) { - core.status.autoEvents.forEach(function (autoEvent) { - core.autoEventExecuting(autoEvent.symbol, false); - }); - } + var data = core.status.event.data || {}; + if (list) { + var l = core.clone(list); + if (!(l instanceof Array)) l = [l]; + l.push({ type: "_label" }); + data.list = [{ todo: l, total: core.clone(l), condition: "false" }]; + // 结束所有正在执行的自动事件 + if (list.length == 0) { + core.status.autoEvents.forEach(function (autoEvent) { + core.autoEventExecuting(autoEvent.symbol, false); + }); } - if (x != null) data.x = x; - if (y != null) data.y = y; - if (callback) data.callback = callback; - if (!data.appendingEvents) data.appendingEvents = []; - if (!data.locStack) data.locStack = []; - core.status.event.id = 'action'; - core.status.event.data = data; -} + } + if (x != null) data.x = x; + if (y != null) data.y = y; + if (callback) data.callback = callback; + if (!data.appendingEvents) data.appendingEvents = []; + if (!data.locStack) data.locStack = []; + core.status.event.id = "action"; + core.status.event.data = data; +}; ////// 开始执行一系列自定义事件 ////// events.prototype.startEvents = function (list, x, y, callback) { - if (!list) return; - if (!(list instanceof Array)) { - list = [list]; - } - this.setEvents(list, x, y, callback); - // 停止勇士 - core.waitHeroToStop(function () { - core.lockControl(); - core.doAction(); - }); -} + if (!list) return; + if (!(list instanceof Array)) { + list = [list]; + } + this.setEvents(list, x, y, callback); + // 停止勇士 + core.waitHeroToStop(function () { + core.lockControl(); + core.doAction(); + }); +}; ////// 执行当前自定义事件列表中的下一个事件 ////// events.prototype.doAction = function () { - // 清空boxAnimate和UI层 - clearInterval(core.status.event.interval); - clearTimeout(core.status.event.interval); - clearInterval(core.status.event.animateUI); - core.status.event.interval = null; - delete core.status.event.aniamteUI; - if (core.status.gameOver || core.status.replay.failed) return; - // 判定是否执行完毕 - if (this._doAction_finishEvents()) return; - core.clearUI(); - var floorId = core.status.event.data.floorId || core.status.floorId; - // 当前点坐标和前缀 - var x = core.status.event.data.x, y = core.status.event.data.y; - var prefix = [floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join("@"); - var current = core.status.event.data.list[0]; - if (this._popEvents(current, prefix)) return; - // 当前要执行的事件 - var data = current.todo.shift(); - core.status.event.data.current = data; - if (typeof data == "string") - data = { "type": "text", "text": data }; - // 该事件块已经被禁用 - if (data._disabled) return core.doAction(); - data.floorId = data.floorId || floorId; - core.status.event.data.type = data.type; - this.doEvent(data, x, y, prefix); - return; -} + // 清空boxAnimate和UI层 + clearInterval(core.status.event.interval); + clearTimeout(core.status.event.interval); + clearInterval(core.status.event.animateUI); + core.status.event.interval = null; + delete core.status.event.aniamteUI; + if (core.status.gameOver || core.status.replay.failed) return; + // 判定是否执行完毕 + if (this._doAction_finishEvents()) return; + core.clearUI(); + var floorId = core.status.event.data.floorId || core.status.floorId; + // 当前点坐标和前缀 + var x = core.status.event.data.x, + y = core.status.event.data.y; + var prefix = [floorId || ":f", x != null ? x : "x", y != null ? y : "y"].join( + "@" + ); + var current = core.status.event.data.list[0]; + if (this._popEvents(current, prefix)) return; + // 当前要执行的事件 + var data = current.todo.shift(); + core.status.event.data.current = data; + if (typeof data == "string") data = { type: "text", text: data }; + // 该事件块已经被禁用 + if (data._disabled) return core.doAction(); + data.floorId = data.floorId || floorId; + core.status.event.data.type = data.type; + this.doEvent(data, x, y, prefix); + return; +}; events.prototype._doAction_finishEvents = function () { - if (core.status.event.id != 'action') return true; - // 事件处理完毕 - if (core.status.event.data.list.length == 0) { - // 检测并执行延迟自动事件 - if (core.status.event.data.appendingEvents.length > 0) { - this.setEvents(core.status.event.data.appendingEvents.shift()); - return false; - } - var callback = core.status.event.data.callback; - core.ui.closePanel(); - if (callback) callback(); - core.replay(); - return true; + if (core.status.event.id != "action") return true; + // 事件处理完毕 + if (core.status.event.data.list.length == 0) { + // 检测并执行延迟自动事件 + if (core.status.event.data.appendingEvents.length > 0) { + this.setEvents(core.status.event.data.appendingEvents.shift()); + return false; } - return false; -} + var callback = core.status.event.data.callback; + core.ui.closePanel(); + if (callback) callback(); + core.replay(); + return true; + } + return false; +}; events.prototype._popEvents = function (current, prefix) { - if (current.todo.length == 0) { // current list is empty - if (core.calValue(current.condition, prefix)) { // check condition - current.todo = core.clone(current.total); - } - else { - core.status.event.data.list.shift(); // remove stack - } - core.doAction(); - return true; + if (current.todo.length == 0) { + // current list is empty + if (core.calValue(current.condition, prefix)) { + // check condition + current.todo = core.clone(current.total); + } else { + core.status.event.data.list.shift(); // remove stack } - return false; -} + core.doAction(); + return true; + } + return false; +}; ////// 往当前事件列表之前或之后添加一个或多个事件 ////// events.prototype.insertAction = function (action, x, y, callback, addToLast) { - if (core.hasFlag("__statistics__")) return; - if (core.status.gameOver) return; - if (!action) return; - core.clearRouteFolding(); + if (core.hasFlag("__statistics__")) return; + if (core.status.gameOver) return; + if (!action) return; + core.clearRouteFolding(); - action = this.precompile(action); + action = this.precompile(action); - if (core.status.event.id != 'action') { - this.startEvents(action, x, y, callback); - } - else { - if (addToLast) { - var list = core.status.event.data.list[0].todo; - var index = 0; - for (var index = 0; index < list.length; index++) { - if (list[index].type == '_label') { - list.splice(index, 0, action); - break; - } - } + if (core.status.event.id != "action") { + this.startEvents(action, x, y, callback); + } else { + if (addToLast) { + var list = core.status.event.data.list[0].todo; + var index = 0; + for (var index = 0; index < list.length; index++) { + if (list[index].type == "_label") { + list.splice(index, 0, action); + break; } - else core.unshift(core.status.event.data.list[0].todo, action); - this.setEvents(null, x, y, callback); - } -} + } + } else core.unshift(core.status.event.data.list[0].todo, action); + this.setEvents(null, x, y, callback); + } +}; ////// 往当前事件列表之前或之后添加一个公共事件 ////// -events.prototype.insertCommonEvent = function (name, args, x, y, callback, addToLast) { - var commonEvent = this.getCommonEvent(name); - if (!commonEvent) { - if (callback) callback(); - return; - } +events.prototype.insertCommonEvent = function ( + name, + args, + x, + y, + callback, + addToLast +) { + var commonEvent = this.getCommonEvent(name); + if (!commonEvent) { + if (callback) callback(); + return; + } - // 设置参数 - core.setFlag('arg0', name); - if (args instanceof Array) { - for (var i = 0; i < args.length; ++i) { - try { - if (args[i] != null) - core.setFlag('arg' + (i + 1), args[i]); - } catch (ee) { console.error(ee) } - } + // 设置参数 + core.setFlag("arg0", name); + if (args instanceof Array) { + for (var i = 0; i < args.length; ++i) { + try { + if (args[i] != null) core.setFlag("arg" + (i + 1), args[i]); + } catch (ee) { + console.error(ee); + } } + } - this.insertAction({ "type": "dowhile", "condition": "false", "data": commonEvent }, x, y, callback, addToLast); -} + this.insertAction( + { type: "dowhile", condition: "false", data: commonEvent }, + x, + y, + callback, + addToLast + ); +}; ////// 获得一个公共事件 ////// events.prototype.getCommonEvent = function (name) { - if (!name || typeof name !== 'string') return null; - return this.commonEvent[name] || null; -} + if (!name || typeof name !== "string") return null; + return this.commonEvent[name] || null; +}; ////// 恢复一个事件 ////// events.prototype.recoverEvents = function (data) { - if (data) { - core.ui.closePanel(); - core.lockControl(); - core.status.event.id = 'action'; - core.status.event.data = data; - setTimeout(function () { - core.doAction(); - }, 30); - return true; - } - return false; -} + if (data) { + core.ui.closePanel(); + core.lockControl(); + core.status.event.id = "action"; + core.status.event.data = data; + setTimeout(function () { + core.doAction(); + }, 30); + return true; + } + return false; +}; ////// 检测自动事件 ////// events.prototype.checkAutoEvents = function () { - // 只有在无操作或事件流中才能执行自动事件! - if (!core.isPlaying() || (core.status.lockControl && core.status.event.id != 'action')) return; - if (core.hasFlag('__doNotCheckAutoEvents__')) return; - var todo = [], delay = []; - core.status.autoEvents.forEach(function (autoEvent) { - var symbol = autoEvent.symbol, x = autoEvent.x, y = autoEvent.y, floorId = autoEvent.floorId; - // 不在当前楼层 or 已经执行过 or 已被分区 or 正在执行中 - if (autoEvent.currentFloor && floorId != core.status.floorId) return; - if (!autoEvent.multiExecute && core.autoEventExecuted(symbol)) return; - if ((flags.__removed__ || []).indexOf(floorId) >= 0) return; - if (core.autoEventExecuting(symbol)) return; - var prefix = floorId + "@" + x + "@" + y; - try { - if (!core.calValue(autoEvent.condition, prefix)) return; - } catch (e) { - return; - } - - core.autoEventExecuting(symbol, true); - core.autoEventExecuted(symbol, true); - - var event; - if (x == null && y == null) { - event = [ - // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, - { - "type": "function", "function": - "function() { core.autoEventExecuting('" + symbol + "', false); }" - } - ]; - } else { - event = [ - { - "type": "function", "function": - "function() { core.pushEventLoc(" + x + ", " + y + ", '" + floorId + "' ); }" - }, - // 用do-while(0)包一层防止break影响事件流 - { "type": "dowhile", "condition": "false", "data": autoEvent.data }, - { - "type": "function", "function": - "function() { core.popEventLoc(); core.autoEventExecuting('" + symbol + "', false); }" - } - ]; - } - - if (autoEvent.delayExecute) - delay.push(event); - else - core.push(todo, event); - }); - - if (todo.length == 0 && delay.length == 0) return; - - if (core.status.event.id == 'action' || todo.length > 0) { - core.insertAction(todo); - core.push(core.status.event.data.appendingEvents, delay); - } else { - core.insertAction(delay[0]); - if (delay.length > 0) { - core.insertAction(delay.slice(1)); - } + // 只有在无操作或事件流中才能执行自动事件! + if ( + !core.isPlaying() || + (core.status.lockControl && core.status.event.id != "action") + ) + return; + if (core.hasFlag("__doNotCheckAutoEvents__")) return; + var todo = [], + delay = []; + core.status.autoEvents.forEach(function (autoEvent) { + var symbol = autoEvent.symbol, + x = autoEvent.x, + y = autoEvent.y, + floorId = autoEvent.floorId; + // 不在当前楼层 or 已经执行过 or 已被分区 or 正在执行中 + if (autoEvent.currentFloor && floorId != core.status.floorId) return; + if (!autoEvent.multiExecute && core.autoEventExecuted(symbol)) return; + if ((flags.__removed__ || []).indexOf(floorId) >= 0) return; + if (core.autoEventExecuting(symbol)) return; + var prefix = floorId + "@" + x + "@" + y; + try { + if (!core.calValue(autoEvent.condition, prefix)) return; + } catch (e) { + return; } -} + core.autoEventExecuting(symbol, true); + core.autoEventExecuted(symbol, true); + + var event; + if (x == null && y == null) { + event = [ + // 用do-while(0)包一层防止break影响事件流 + { type: "dowhile", condition: "false", data: autoEvent.data }, + { + type: "function", + function: + "function() { core.autoEventExecuting('" + symbol + "', false); }", + }, + ]; + } else { + event = [ + { + type: "function", + function: + "function() { core.pushEventLoc(" + + x + + ", " + + y + + ", '" + + floorId + + "' ); }", + }, + // 用do-while(0)包一层防止break影响事件流 + { type: "dowhile", condition: "false", data: autoEvent.data }, + { + type: "function", + function: + "function() { core.popEventLoc(); core.autoEventExecuting('" + + symbol + + "', false); }", + }, + ]; + } + + if (autoEvent.delayExecute) delay.push(event); + else core.push(todo, event); + }); + + if (todo.length == 0 && delay.length == 0) return; + + if (core.status.event.id == "action" || todo.length > 0) { + core.insertAction(todo); + core.push(core.status.event.data.appendingEvents, delay); + } else { + core.insertAction(delay[0]); + if (delay.length > 0) { + core.insertAction(delay.slice(1)); + } + } +}; events.prototype.autoEventExecuting = function (symbol, value) { - var aei = core.getFlag('__aei__', []); - if (value == null) return aei.indexOf(symbol) >= 0; - else { - aei = aei.filter(function (one) { return one != symbol; }); - if (value) aei.push(symbol); - core.setFlag('__aei__', aei); - } -} + var aei = core.getFlag("__aei__", []); + if (value == null) return aei.indexOf(symbol) >= 0; + else { + aei = aei.filter(function (one) { + return one != symbol; + }); + if (value) aei.push(symbol); + core.setFlag("__aei__", aei); + } +}; events.prototype.autoEventExecuted = function (symbol, value) { - var aed = core.getFlag('__aed__', []); - if (value == null) return aed.indexOf(symbol) >= 0; - else { - aed = aed.filter(function (one) { return one != symbol; }); - if (value) aed.push(symbol); - core.setFlag('__aed__', aed); - } -} + var aed = core.getFlag("__aed__", []); + if (value == null) return aed.indexOf(symbol) >= 0; + else { + aed = aed.filter(function (one) { + return one != symbol; + }); + if (value) aed.push(symbol); + core.setFlag("__aed__", aed); + } +}; events.prototype.pushEventLoc = function (x, y, floorId) { - if (core.status.event.id != 'action') return; - core.status.event.data.locStack.push({ - x: core.status.event.data.x, - y: core.status.event.data.y, - floorId: core.status.event.data.floorId - }); - core.status.event.data.x = x; - core.status.event.data.y = y; - core.status.event.data.floorId = floorId; -} + if (core.status.event.id != "action") return; + core.status.event.data.locStack.push({ + x: core.status.event.data.x, + y: core.status.event.data.y, + floorId: core.status.event.data.floorId, + }); + core.status.event.data.x = x; + core.status.event.data.y = y; + core.status.event.data.floorId = floorId; +}; events.prototype.popEventLoc = function () { - if (core.status.event.id != 'action') return; - var loc = core.status.event.data.locStack.shift(); - if (loc) { - core.status.event.data.x = loc.x; - core.status.event.data.y = loc.y; - core.status.event.data.floorId = loc.floorId; - } -} + if (core.status.event.id != "action") return; + var loc = core.status.event.data.locStack.shift(); + if (loc) { + core.status.event.data.x = loc.x; + core.status.event.data.y = loc.y; + core.status.event.data.floorId = loc.floorId; + } +}; events.prototype.precompile = function (data) { - var array = this.__precompile_getArray(); - if (typeof data == 'string') { - return this.__precompile_text(data); - } - if (data instanceof Array) { - for (var i = 0; i < data.length; ++i) { - data[i] = this.precompile(data[i]); - } - return data; - } - if (data && data.type) { - if (this["_precompile_" + data.type]) { - data = this["_precompile_" + data.type](data); - } - if (array.texts.indexOf(data.type) >= 0) { - data.text = this.__precompile_text(data.text); - } - if (array.locs.indexOf(data.type) >= 0) { - data.loc = this.__precompile_array(data.loc); - } - if (array.values.indexOf(data.type) >= 0) { - data.value = core.replaceValue(data.value); - } - if (array.uievents.indexOf(data.type) >= 0) { - data.x = core.replaceValue(data.x); - data.y = core.replaceValue(data.y); - data.width = core.replaceValue(data.width); - data.height = core.replaceValue(data.height); - } - if (data.type in array.others) { - array.others[data.type].forEach(function (field) { - data[field] = core.replaceValue(data[field]); - }) - } + var array = this.__precompile_getArray(); + if (typeof data == "string") { + return this.__precompile_text(data); + } + if (data instanceof Array) { + for (var i = 0; i < data.length; ++i) { + data[i] = this.precompile(data[i]); } return data; -} + } + if (data && data.type) { + if (this["_precompile_" + data.type]) { + data = this["_precompile_" + data.type](data); + } + if (array.texts.indexOf(data.type) >= 0) { + data.text = this.__precompile_text(data.text); + } + if (array.locs.indexOf(data.type) >= 0) { + data.loc = this.__precompile_array(data.loc); + } + if (array.values.indexOf(data.type) >= 0) { + data.value = core.replaceValue(data.value); + } + if (array.uievents.indexOf(data.type) >= 0) { + data.x = core.replaceValue(data.x); + data.y = core.replaceValue(data.y); + data.width = core.replaceValue(data.width); + data.height = core.replaceValue(data.height); + } + if (data.type in array.others) { + array.others[data.type].forEach(function (field) { + data[field] = core.replaceValue(data[field]); + }); + } + } + return data; +}; events.prototype.__precompile_getArray = function () { - var texts = [ - "text", "autoText", "scrollText", "tip", "textImage", "input", "input2", - "choices", "confirm", "fillText", "fillBoldText", "drawTextContent" - ]; - var locs = [ - "show", "hide", "setBlock", "setBlockOpacity", "showFloorImg", "hideFloorImg", "showBgFgMap", - "hideBgFgMap", "setBgFgBlock", "animate", "setViewport", "move", "jumoHero", - "changeFloor", "changePos", "showTextImage", "showGif", "openDoor", - "closeDoor", "battle", "trigger", "insert", "setEnemyOnPoint", "resetEnemyOnPoint" - ]; - var values = [ - "setValue", "setEnemy", "setEnemyOnPoint", "setEquip", "setFloor", "setGlobalValue", - ]; - var uievents = [ - "clearMap", "fillText", "fillBoldText", "fillRect", "strokeRect", "fillEllipse", "strokeEllipse", - "fillArc", "strokeArc", "drawIcon", "drawSelector", "drawBackground", - ]; - var others = { - "fillEllipse": ["a", "b", "angle"], - "strokeEllipse": ["a", "b", "angle"], - "fillRect": ["radius", "angle"], - "strokeRect": ["radius", "angle"], - "fillArc": ["r", "start", "end"], - "strokeArc": ["r", "start", "end"], - "drawLine": ["x1", "y1", "x2", "y2"], - "drawArrow": ["x1", "y1", "x2", "y2"], - "drawImage": ["x", "y", "w", "h", "x1", "y1", "w1", "h1", "angle"], - "drawTextContent": ["left", "top"], - }; - return { - texts: texts, - locs: locs, - values: values, - uievents: uievents, - others: others - }; -} + var texts = [ + "text", + "autoText", + "scrollText", + "tip", + "textImage", + "input", + "input2", + "choices", + "confirm", + "fillText", + "fillBoldText", + "drawTextContent", + ]; + var locs = [ + "show", + "hide", + "setBlock", + "setBlockOpacity", + "showFloorImg", + "hideFloorImg", + "showBgFgMap", + "hideBgFgMap", + "setBgFgBlock", + "animate", + "setViewport", + "move", + "jumoHero", + "changeFloor", + "changePos", + "showTextImage", + "showGif", + "openDoor", + "closeDoor", + "battle", + "trigger", + "insert", + "setEnemyOnPoint", + "resetEnemyOnPoint", + ]; + var values = [ + "setValue", + "setEnemy", + "setEnemyOnPoint", + "setEquip", + "setFloor", + "setGlobalValue", + ]; + var uievents = [ + "clearMap", + "fillText", + "fillBoldText", + "fillRect", + "strokeRect", + "fillEllipse", + "strokeEllipse", + "fillArc", + "strokeArc", + "drawIcon", + "drawSelector", + "drawBackground", + ]; + var others = { + fillEllipse: ["a", "b", "angle"], + strokeEllipse: ["a", "b", "angle"], + fillRect: ["radius", "angle"], + strokeRect: ["radius", "angle"], + fillArc: ["r", "start", "end"], + strokeArc: ["r", "start", "end"], + drawLine: ["x1", "y1", "x2", "y2"], + drawArrow: ["x1", "y1", "x2", "y2"], + drawImage: ["x", "y", "w", "h", "x1", "y1", "w1", "h1", "angle"], + drawTextContent: ["left", "top"], + }; + return { + texts: texts, + locs: locs, + values: values, + uievents: uievents, + others: others, + }; +}; events.prototype.__precompile_text = function (text) { - if (typeof text != 'string') return text; - return text.replace(/\${(.*?)}/g, function (word, value) { - return "${" + core.replaceValue(value) + "}"; - }); -} + if (typeof text != "string") return text; + return text.replace(/\${(.*?)}/g, function (word, value) { + return "${" + core.replaceValue(value) + "}"; + }); +}; events.prototype.__precompile_array = function (value) { - if (typeof value == 'string') { - value = core.replaceValue(value); - return value; - } - if (value instanceof Array) { - for (var i = 0; i < value.length; ++i) { - value[i] = this.__precompile_array(value[i]); - } - } + if (typeof value == "string") { + value = core.replaceValue(value); return value; -} + } + if (value instanceof Array) { + for (var i = 0; i < value.length; ++i) { + value[i] = this.__precompile_array(value[i]); + } + } + return value; +}; // ------ 样板提供的的自定义事件 ------ // events.prototype.__action_checkReplaying = function () { - if (core.isReplaying()) { - core.doAction(); - return true; - } - return false; -} + if (core.isReplaying()) { + core.doAction(); + return true; + } + return false; +}; events.prototype.__action_getLoc = function (loc, x, y, prefix) { - if (loc) { - x = core.calValue(loc[0], prefix); - y = core.calValue(loc[1], prefix); - } - return [x, y]; -} + if (loc) { + x = core.calValue(loc[0], prefix); + y = core.calValue(loc[1], prefix); + } + return [x, y]; +}; events.prototype.__action_getHeroLoc = function (loc, prefix) { - return this.__action_getLoc(loc, core.getHeroLoc('x'), core.getHeroLoc('y'), prefix); -} + return this.__action_getLoc( + loc, + core.getHeroLoc("x"), + core.getHeroLoc("y"), + prefix + ); +}; events.prototype.__action_getLoc2D = function (loc, x, y, prefix) { - if (!(loc && loc[0] instanceof Array)) - loc = [this.__action_getLoc(loc, x, y, prefix)]; - return loc; -} + if (!(loc && loc[0] instanceof Array)) + loc = [this.__action_getLoc(loc, x, y, prefix)]; + return loc; +}; events.prototype.__action_doAsyncFunc = function (isAsync, func) { - var parameters = Array.prototype.slice.call(arguments, 2); - if (isAsync) { - func.apply(this, parameters); - core.doAction(); - } - else { - func.apply(this, parameters.concat(core.doAction)); - } -} + var parameters = Array.prototype.slice.call(arguments, 2); + if (isAsync) { + func.apply(this, parameters); + core.doAction(); + } else { + func.apply(this, parameters.concat(core.doAction)); + } +}; events.prototype._action_text = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - 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(); - }); - } -} + if (this.__action_checkReplaying()) return; + 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(); + }); + } +}; events.prototype._action_moveTextBox = function (data, x, y, prefix) { - 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); -} + 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 + ); +}; events.prototype._action_clearTextBox = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - core.clearTextBox(data.code, core.doAction); -} + 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); -} + if (this.__action_checkReplaying()) return; + data.text = core.replaceText(data.text, prefix); + core.ui.drawTextBox(data.text); + setTimeout(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); -} + 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 + ); +}; events.prototype._action_comment = function (data, x, y, prefix) { - core.doAction(); -} + core.doAction(); +}; events.prototype._action__label = function (data, x, y, prefix) { - core.doAction(); -} + core.doAction(); +}; events.prototype._action_setText = function (data, x, y, prefix) { - this.setTextAttribute(data); - core.doAction(); -} + this.setTextAttribute(data); + core.doAction(); +}; events.prototype._action_tip = function (data, x, y, prefix) { - core.drawTip(core.replaceText(data.text, prefix), data.icon); - core.doAction(); -} + core.drawTip(core.replaceText(data.text, prefix), data.icon); + core.doAction(); +}; 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) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, 'show', data.time); - } - else { - data.loc.forEach(function (t) { - core.showBlock(t[0], t[1], data.floorId); - }); - core.doAction(); - } -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + if (data.time > 0 && data.floorId == core.status.floorId) { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + "show", + data.time + ); + } else { + data.loc.forEach(function (t) { + core.showBlock(t[0], t[1], data.floorId); + }); + core.doAction(); + } +}; events.prototype._action_hide = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, data.remove ? 'remove' : 'hide', data.time); - } - else { - data.loc.forEach(function (t) { - if (data.remove) core.removeBlock(t[0], t[1], data.floorId); - else core.hideBlock(t[0], t[1], data.floorId); - }); - core.doAction(); - } -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + if (data.time > 0 && data.floorId == core.status.floorId) { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + data.remove ? "remove" : "hide", + data.time + ); + } else { + data.loc.forEach(function (t) { + if (data.remove) core.removeBlock(t[0], t[1], data.floorId); + else core.hideBlock(t[0], t[1], data.floorId); + }); + core.doAction(); + } +}; events.prototype._action_setBlock = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - data.time = data.time || 0; - data.floorId = data.floorId || core.status.floorId; - if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateSetBlocks, data.number, data.loc, data.floorId, data.time); - } else { - data.loc.forEach(function (loc) { - core.setBlock(data.number, loc[0], loc[1], data.floorId); - }); - core.doAction(); - } -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.time = data.time || 0; + data.floorId = data.floorId || core.status.floorId; + if (data.time > 0 && data.floorId == core.status.floorId) { + this.__action_doAsyncFunc( + data.async, + core.animateSetBlocks, + data.number, + data.loc, + data.floorId, + data.time + ); + } else { + data.loc.forEach(function (loc) { + core.setBlock(data.number, loc[0], loc[1], data.floorId); + }); + core.doAction(); + } +}; events.prototype._action_setBlockOpacity = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - if (data.time > 0 && data.floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.animateBlock, data.loc, data.opacity, data.time); - } - else { - data.loc.forEach(function (t) { - core.setBlockOpacity(data.opacity, t[0], t[1], data.floorId); - }); - core.doAction(); - } -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + if (data.time > 0 && data.floorId == core.status.floorId) { + this.__action_doAsyncFunc( + data.async, + core.animateBlock, + data.loc, + data.opacity, + data.time + ); + } else { + data.loc.forEach(function (t) { + core.setBlockOpacity(data.opacity, t[0], t[1], data.floorId); + }); + core.doAction(); + } +}; events.prototype._action_setBlockFilter = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - data.loc.forEach(function (t) { - core.setBlockFilter(data, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + core.setBlockFilter(data, t[0], t[1], data.floorId); + }); + core.doAction(); +}; events.prototype._action_turnBlock = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - data.loc.forEach(function (t) { - core.turnBlock(data.direction, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + core.turnBlock(data.direction, t[0], t[1], data.floorId); + }); + core.doAction(); +}; events.prototype._action_showFloorImg = function (data, x, y, prefix) { - core.maps.showFloorImage(this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.showFloorImage( + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_hideFloorImg = function (data, x, y, prefix) { - core.maps.hideFloorImage(this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.hideFloorImage( + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_showBgFgMap = function (data, x, y, prefix) { - core.maps.showBgFgMap(data.name, this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction) -} + core.maps.showBgFgMap( + data.name, + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_hideBgFgMap = function (data, x, y, prefix) { - core.maps.hideBgFgMap(data.name, this.__action_getLoc2D(data.loc, x, y, prefix), data.floorId, core.doAction); -} + core.maps.hideBgFgMap( + data.name, + this.__action_getLoc2D(data.loc, x, y, prefix), + data.floorId, + core.doAction + ); +}; events.prototype._action_setBgFgBlock = function (data, x, y, prefix) { - data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); - data.loc.forEach(function (t) { - core.setBgFgBlock(data.name, data.number, t[0], t[1], data.floorId); - }); - core.doAction(); -} + data.loc = this.__action_getLoc2D(data.loc, x, y, prefix); + data.loc.forEach(function (t) { + core.setBgFgBlock(data.name, data.number, t[0], t[1], data.floorId); + }); + core.doAction(); +}; events.prototype._action_follow = function (data, x, y, prefix) { - this.follow(data.name); - core.doAction(); -} + this.follow(data.name); + core.doAction(); +}; events.prototype._action_unfollow = function (data, x, y, prefix) { - this.unfollow(data.name); - core.doAction(); -} + this.unfollow(data.name); + core.doAction(); +}; events.prototype._action_animate = function (data, x, y, prefix) { - if (data.loc == 'hero') { - this.__action_doAsyncFunc(data.async, core.drawHeroAnimate, data.name); - } else { - data.loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.drawAnimate, data.name, data.loc[0], data.loc[1], data.alignWindow); - } -} + if (data.loc == "hero") { + this.__action_doAsyncFunc(data.async, core.drawHeroAnimate, data.name); + } else { + data.loc = this.__action_getLoc(data.loc, x, y, prefix); + this.__action_doAsyncFunc( + data.async, + core.drawAnimate, + data.name, + data.loc[0], + data.loc[1], + data.alignWindow + ); + } +}; events.prototype._action_stopAnimate = function (data, x, y, prefix) { - core.stopAnimate(null, data.doCallback); - core.doAction(); -} + core.stopAnimate(null, data.doCallback); + core.doAction(); +}; events.prototype._action_setViewport = function (data, x, y, prefix) { - if (data.dxy != null) { - data.loc = [core.bigmap.offsetX / 32 + (core.calValue(data.dxy[0], prefix) || 0), core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0)]; - } else if (data.loc == null) { - data.loc = [core.getHeroLoc('x') - core._HALF_WIDTH_, core.getHeroLoc('y') - core._HALF_HEIGHT_]; - } else { - data.loc = this.__action_getLoc(data.loc, x, y, prefix); - } - this.__action_doAsyncFunc(data.async, core.moveViewport, data.loc[0], data.loc[1], data.moveMode, data.time); -} + if (data.dxy != null) { + data.loc = [ + core.bigmap.offsetX / 32 + (core.calValue(data.dxy[0], prefix) || 0), + core.bigmap.offsetY / 32 + (core.calValue(data.dxy[1], prefix) || 0), + ]; + } else if (data.loc == null) { + data.loc = [ + core.getHeroLoc("x") - core._HALF_WIDTH_, + core.getHeroLoc("y") - core._HALF_HEIGHT_, + ]; + } else { + data.loc = this.__action_getLoc(data.loc, x, y, prefix); + } + this.__action_doAsyncFunc( + data.async, + core.moveViewport, + data.loc[0], + data.loc[1], + data.moveMode, + data.time + ); +}; events.prototype._action_lockViewport = function (data, x, y, prefix) { - core.setFlag('__lockViewport__', data.lock || null); - core.doAction(); -} + core.setFlag("__lockViewport__", data.lock || null); + core.doAction(); +}; events.prototype._action_move = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.moveBlock, loc[0], loc[1], data.steps, data.time, data.keep); -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this.__action_doAsyncFunc( + data.async, + core.moveBlock, + loc[0], + loc[1], + data.steps, + data.time, + data.keep + ); +}; events.prototype._action_moveAction = function (data, x, y, prefix) { - // 检查下一个点是否可通行 - if (core.canMoveHero()) { - var nx = core.nextX(), ny = core.nextY(); - // 检查noPass决定是撞击还是移动 - if (core.noPass(nx, ny)) { - core.insertAction([ - { "type": "trigger", "loc": [nx, ny] } - ]); - } else { - // 先移动一格,然后尝试触发事件 - core.insertAction([ - { "type": "moveHero", "steps": ["forward"] }, - { "type": "function", "function": "function() { core.moveOneStep(core.doAction); }", "async": true }, - { "type": "_label" }, - ]); - } + // 检查下一个点是否可通行 + if (core.canMoveHero()) { + var nx = core.nextX(), + ny = core.nextY(); + // 检查noPass决定是撞击还是移动 + if (core.noPass(nx, ny)) { + core.insertAction([{ type: "trigger", loc: [nx, ny] }]); + } else { + // 先移动一格,然后尝试触发事件 + core.insertAction([ + { type: "moveHero", steps: ["forward"] }, + { + type: "function", + function: "function() { core.moveOneStep(core.doAction); }", + async: true, + }, + { type: "_label" }, + ]); } - core.doAction(); -} + } + core.doAction(); +}; events.prototype._action_moveHero = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.eventMoveHero, data.steps, data.time); -} + this.__action_doAsyncFunc( + data.async, + core.eventMoveHero, + data.steps, + data.time + ); +}; events.prototype._action_jump = function (data, x, y, prefix) { - var from = this.__action_getLoc(data.from, x, y, prefix), to; - if (data.dxy) { - to = [from[0] + (core.calValue(data.dxy[0], prefix) || 0), from[1] + (core.calValue(data.dxy[1], prefix) || 0)]; - } else { - to = this.__action_getLoc(data.to, x, y, prefix); - } - this.__action_doAsyncFunc(data.async, core.jumpBlock, from[0], from[1], to[0], to[1], data.time, data.keep); -} + var from = this.__action_getLoc(data.from, x, y, prefix), + to; + if (data.dxy) { + to = [ + from[0] + (core.calValue(data.dxy[0], prefix) || 0), + from[1] + (core.calValue(data.dxy[1], prefix) || 0), + ]; + } else { + to = this.__action_getLoc(data.to, x, y, prefix); + } + this.__action_doAsyncFunc( + data.async, + core.jumpBlock, + from[0], + from[1], + to[0], + to[1], + data.time, + data.keep + ); +}; events.prototype._precompile_jump = function (data) { - data.from = this.__precompile_array(data.from); - data.to = this.__precompile_array(data.to); - data.dxy = this.__precompile_array(data.dxy); - return data; -} + data.from = this.__precompile_array(data.from); + data.to = this.__precompile_array(data.to); + data.dxy = this.__precompile_array(data.dxy); + return data; +}; events.prototype._action_jumpHero = function (data, x, y, prefix) { - var loc; - if (data.dxy) { - loc = [core.getHeroLoc('x') + (core.calValue(data.dxy[0], prefix) || 0), core.getHeroLoc('y') + (core.calValue(data.dxy[1], prefix) || 0)]; - } else { - loc = this.__action_getHeroLoc(data.loc, prefix); - } - this.__action_doAsyncFunc(data.async, core.jumpHero, loc[0], loc[1], data.time); -} + var loc; + if (data.dxy) { + loc = [ + core.getHeroLoc("x") + (core.calValue(data.dxy[0], prefix) || 0), + core.getHeroLoc("y") + (core.calValue(data.dxy[1], prefix) || 0), + ]; + } else { + loc = this.__action_getHeroLoc(data.loc, prefix); + } + this.__action_doAsyncFunc( + data.async, + core.jumpHero, + loc[0], + loc[1], + data.time + ); +}; events.prototype._action_changeFloor = function (data, x, y, prefix) { - var loc = this.__action_getHeroLoc(data.loc, prefix); - var heroLoc = { x: loc[0], y: loc[1], direction: data.direction }; - core.changeFloor(data.floorId, data.stair, heroLoc, data.time, core.doAction); -} + var loc = this.__action_getHeroLoc(data.loc, prefix); + var heroLoc = { x: loc[0], y: loc[1], direction: data.direction }; + core.changeFloor(data.floorId, data.stair, heroLoc, data.time, core.doAction); +}; events.prototype._action_changePos = function (data, x, y, prefix) { - core.clearMap('hero'); - if (!data.loc && data.direction) { - core.setHeroLoc('direction', core.turnDirection(data.direction), true); - core.drawHero(); - return core.doAction(); - } - - var loc = this.__action_getHeroLoc(data.loc, prefix); - core.setHeroLoc('x', loc[0]); - core.setHeroLoc('y', loc[1]); - if (data.direction) core.setHeroLoc('direction', core.turnDirection(data.direction)); + core.clearMap("hero"); + if (!data.loc && data.direction) { + core.setHeroLoc("direction", core.turnDirection(data.direction), true); core.drawHero(); - core.doAction(); -} + return core.doAction(); + } + + var loc = this.__action_getHeroLoc(data.loc, prefix); + core.setHeroLoc("x", loc[0]); + core.setHeroLoc("y", loc[1]); + if (data.direction) + core.setHeroLoc("direction", core.turnDirection(data.direction)); + core.drawHero(); + core.doAction(); +}; events.prototype._action_showImage = function (data, x, y, prefix) { - if (core.isReplaying()) data.time = 0; - this.__action_doAsyncFunc(data.async || data.time == 0, core.showImage, - data.code, data.image + (data.reverse || ''), data.sloc, data.loc, data.opacity, data.time); -} + if (core.isReplaying()) data.time = 0; + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.showImage, + data.code, + data.image + (data.reverse || ""), + data.sloc, + data.loc, + data.opacity, + data.time + ); +}; events.prototype._precompile_showImage = function (data) { - data.sloc = this.__precompile_array(data.sloc); - data.loc = this.__precompile_array(data.loc); - return data; -} + data.sloc = this.__precompile_array(data.sloc); + data.loc = this.__precompile_array(data.loc); + return data; +}; events.prototype._action_showTextImage = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, 0, 0, prefix); - if (core.isReplaying()) data.time = 0; - data.text = core.replaceText(data.text, prefix); - var __tmpName = (Math.random() + "_" + Math.random()).replace(/\./g, "") + ".png"; - core.material.images.images[__tmpName] = core.ui.textImage(data.text); - this.__action_doAsyncFunc(data.async || data.time == 0, core.showImage, - data.code, __tmpName + (data.reverse || ""), null, loc, data.opacity, data.time); - delete core.material.images.images[__tmpName]; -} + var loc = this.__action_getLoc(data.loc, 0, 0, prefix); + if (core.isReplaying()) data.time = 0; + data.text = core.replaceText(data.text, prefix); + var __tmpName = + (Math.random() + "_" + Math.random()).replace(/\./g, "") + ".png"; + core.material.images.images[__tmpName] = core.ui.textImage(data.text); + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.showImage, + data.code, + __tmpName + (data.reverse || ""), + null, + loc, + data.opacity, + data.time + ); + delete core.material.images.images[__tmpName]; +}; events.prototype._action_hideImage = function (data, x, y, prefix) { - if (core.isReplaying()) data.time = 0; - this.__action_doAsyncFunc(data.async || data.time == 0, core.hideImage, data.code, data.time); -} + if (core.isReplaying()) data.time = 0; + this.__action_doAsyncFunc( + data.async || data.time == 0, + core.hideImage, + data.code, + data.time + ); +}; events.prototype._action_showGif = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, 0, 0, prefix); - this.showGif(data.name, loc[0], loc[1]); - core.doAction(); -} + var loc = this.__action_getLoc(data.loc, 0, 0, prefix); + this.showGif(data.name, loc[0], loc[1]); + core.doAction(); +}; events.prototype._action_moveImage = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.moveImage, data.code, data.to, data.opacity, data.moveMode, data.time); -} + if (this.__action_checkReplaying()) return; + this.__action_doAsyncFunc( + data.async, + core.moveImage, + data.code, + data.to, + data.opacity, + data.moveMode, + data.time + ); +}; events.prototype._precompile_moveImage = function (data) { - data.to = this.__precompile_array(data.to); - return data; -} + data.to = this.__precompile_array(data.to); + return data; +}; events.prototype._action_rotateImage = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.rotateImage, data.code, data.center, data.angle, data.moveMode, data.time); -} + if (this.__action_checkReplaying()) return; + this.__action_doAsyncFunc( + data.async, + core.rotateImage, + data.code, + data.center, + data.angle, + data.moveMode, + data.time + ); +}; events.prototype._precompile_rotateImage = function (data) { - data.center = this.__precompile_array(data.center); - return data; -} + data.center = this.__precompile_array(data.center); + return data; +}; events.prototype._action_scaleImage = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; - this.__action_doAsyncFunc(data.async, core.scaleImage, data.code, data.center, data.scale, data.moveMode, data.time); -} + if (this.__action_checkReplaying()) return; + this.__action_doAsyncFunc( + data.async, + core.scaleImage, + data.code, + data.center, + data.scale, + data.moveMode, + data.time + ); +}; events.prototype._precompile_scaleImage = function (data) { - data.center = this.__precompile_array(data.center); - return data; -} + data.center = this.__precompile_array(data.center); + return data; +}; events.prototype._action_setCurtain = function (data, x, y, prefix) { - if (data.async) { - core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode); - if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); + if (data.async) { + core.setCurtain( + data.color || core.status.thisMap.color, + data.time, + data.moveMode + ); + if (data.color == null || data.keep) + core.setFlag("__color__", data.color || null); + core.doAction(); + } else { + core.setCurtain( + data.color || core.status.thisMap.color, + data.time, + data.moveMode, + function () { + if (data.color == null || data.keep) + core.setFlag("__color__", data.color || null); core.doAction(); - } - else { - core.setCurtain(data.color || core.status.thisMap.color, data.time, data.moveMode, function () { - if (data.color == null || data.keep) core.setFlag('__color__', data.color || null); - core.doAction(); - }); - } -} + } + ); + } +}; events.prototype._action_screenFlash = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.screenFlash, data.color, data.time, data.times, data.moveMode); -} + this.__action_doAsyncFunc( + data.async, + core.screenFlash, + data.color, + data.time, + data.times, + data.moveMode + ); +}; events.prototype._action_setWeather = function (data, x, y, prefix) { - core.setWeather(data.name, data.level); - if (data.keep && ['rain', 'snow', 'sun', 'fog', 'cloud'].indexOf(data.name) >= 0) - core.setFlag('__weather__', [data.name, data.level]); - else core.removeFlag('__weather__'); - core.doAction(); -} + core.setWeather(data.name, data.level); + if ( + data.keep && + ["rain", "snow", "sun", "fog", "cloud"].indexOf(data.name) >= 0 + ) + core.setFlag("__weather__", [data.name, data.level]); + else core.removeFlag("__weather__"); + core.doAction(); +}; events.prototype._action_openDoor = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, x, y, prefix); - var floorId = data.floorId; - if (floorId == core.status.floorId) { - this.__action_doAsyncFunc(data.async, core.openDoor, loc[0], loc[1], data.needKey); - } - else { - core.removeBlock(loc[0], loc[1], floorId); - core.doAction(); - } -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + var floorId = data.floorId; + if (floorId == core.status.floorId) { + this.__action_doAsyncFunc( + data.async, + core.openDoor, + loc[0], + loc[1], + data.needKey + ); + } else { + core.removeBlock(loc[0], loc[1], floorId); + core.doAction(); + } +}; events.prototype._action_closeDoor = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, x, y, prefix); - this.__action_doAsyncFunc(data.async, core.closeDoor, loc[0], loc[1], data.id); -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this.__action_doAsyncFunc( + data.async, + core.closeDoor, + loc[0], + loc[1], + data.id + ); +}; events.prototype._action_useItem = function (data, x, y, prefix) { - // 考虑到可能覆盖楼传事件的问题,这里不对fly进行检查。 - if (data.id != 'book' && core.canUseItem(data.id)) { - core.useItem(data.id, true, core.doAction); - } - else { - core.playSound('操作失败'); - core.drawTip("当前无法使用" + ((core.material.items[data.id] || {}).name || "未知道具")); - core.doAction(); - } -} - -events.prototype._action_loadEquip = function (data, x, y, prefix) { - core.loadEquip(data.id); - core.doAction(); -} - -events.prototype._action_unloadEquip = function (data, x, y, prefix) { - core.unloadEquip(data.pos); - core.doAction(); -} - -events.prototype._action_openShop = function (data, x, y, prefix) { - core.setShopVisited(data.id, true); - if (data.open) core.openShop(data.id, true); - core.doAction(); -} - -events.prototype._action_disableShop = function (data, x, y, prefix) { - core.setShopVisited(data.id, false); - core.doAction(); -} - -events.prototype._action_battle = function (data, x, y, prefix) { - if (data.id) { - this.battle(data.id, null, null, true, core.doAction); - } - else { - if (data.floorId != core.status.floorId) { - core.doAction(); - return; - } - var loc = this.__action_getLoc(data.loc, x, y, prefix); - this.battle(null, loc[0], loc[1], true, core.doAction); - } -} - -events.prototype._action_trigger = function (data, x, y, prefix) { - var loc = this.__action_getLoc(data.loc, x, y, prefix); - this._trigger_inAction(loc[0], loc[1]); -} - -events.prototype._action_insert = function (data, x, y, prefix) { - if (data.name) { // 公共事件 - core.insertCommonEvent(data.name, data.args); - } - else { - // 设置参数 - if (data.args instanceof Array) { - for (var i = 0; i < data.args.length; ++i) { - try { - if (data.args[i] != null) - core.setFlag('arg' + (i + 1), data.args[i]); - } catch (ee) { console.error(ee) } - } - } - var loc = this.__action_getLoc(data.loc, x, y, prefix); - core.setFlag('arg0', loc); - var floorId = data.floorId; - var which = data.which || "events"; - var event = (core.floors[floorId][which] || [])[loc[0] + "," + loc[1]]; - if (event) this.insertAction(event.data || event); - } - core.doAction(); -} - -events.prototype._action_playBgm = function (data, x, y, prefix) { - core.playBgm(data.name, data.startTime || 0); - core.setFlag("__bgm__", data.keep ? data.name : null); - core.doAction(); -} - -events.prototype._action_pauseBgm = function (data, x, y, prefix) { - core.pauseBgm(); - core.doAction(); -} - -events.prototype._action_resumeBgm = function (data, x, y, prefix) { - core.resumeBgm(data.resume); - core.doAction(); -} - -events.prototype._action_loadBgm = function (data, x, y, prefix) { - core.loadBgm(data.name); - core.doAction(); -} - -events.prototype._action_freeBgm = function (data, x, y, prefix) { - core.freeBgm(data.name); - core.doAction(); -} - -events.prototype._action_playSound = function (data, x, y, prefix) { - if (data.stop) core.stopSound(); - if (data.sync) { - core.playSound(data.name, data.pitch, core.doAction); - } else { - core.playSound(data.name, data.pitch); - core.doAction(); - } -} - -events.prototype._action_stopSound = function (data, x, y, prefix) { - core.stopSound(); - core.doAction(); -} - -events.prototype._action_setVolume = function (data, x, y, prefix) { - data.value = core.clamp(parseInt(data.value) / 100, 0, 1); - core.setFlag("__volume__", data.value); - this.__action_doAsyncFunc(data.async, core.setVolume, data.value, data.time || 0); -} - -events.prototype._action_setBgmSpeed = function (data, x, y, prefix) { - core.setBgmSpeed(data.value, data.pitch || false); - core.doAction(); -} - -events.prototype._action_setValue = function (data, x, y, prefix) { - this.setValue(data.name, data.operator, data.value, prefix); - if (!data.norefresh) { - if (core.status.hero.hp <= 0) { - core.status.hero.hp = 0; - core.updateStatusBar(); - core.events.lose(); - } else { - core.updateStatusBar(); - } - } - core.doAction(); -} - -events.prototype._action_addValue = function (data, x, y, prefix) { - data.operator = '+='; - this._action_setValue(data, x, y, prefix); -} - -events.prototype._action_setEnemy = function (data, x, y, prefix) { - this.setEnemy(data.id, data.name, data.value, data.operator, prefix, data.norefresh); - core.doAction(); -} - -events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) { - var loc = this.__action_getLoc2D(data.loc, x, y, prefix); - loc.forEach(function (one) { - core.setEnemyOnPoint(one[0], one[1], data.floorId, data.name, data.value, data.operator, prefix, data.norefresh); - }); - core.doAction(); -} - -events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { - var loc = this.__action_getLoc2D(data.loc, x, y, prefix); - loc.forEach(function (one) { - core.resetEnemyOnPoint(one[0], one[1], data.floorId, data.norefresh); - }); - core.doAction(); -} - -events.prototype._precompile_moveEnemyOnPoint = function (data) { - data.from = this.__precompile_array(data.from); - data.to = this.__precompile_array(data.to); - data.dxy = this.__precompile_array(data.dxy); - return data; -} - -events.prototype._action_moveEnemyOnPoint = function (data, x, y, prefix) { - var from = this.__action_getLoc(data.from, x, y, prefix), to; - if (data.dxy) { - to = [from[0] + (core.calValue(data.dxy[0], prefix) || 0), from[1] + (core.calValue(data.dxy[1], prefix) || 0)]; - } else { - to = this.__action_getLoc(data.to, x, y, prefix); - } - this.moveEnemyOnPoint(from[0], from[1], to[0], to[1], data.floorId, data.norefresh); - core.doAction(); -} - -events.prototype._action_setEquip = function (data, x, y, prefix) { - core.setEquip(data.id, data.valueType, data.name, data.value, data.operator, prefix); - core.doAction(); -} - -events.prototype._action_setFloor = function (data, x, y, prefix) { - this.setFloorInfo(data.name, data.value, data.floorId, prefix); - core.doAction(); -} - -events.prototype._action_setGlobalAttribute = function (data, x, y, prefix) { - this.setGlobalAttribute(data.name, data.value); - core.doAction(); -} - -events.prototype._action_setGlobalValue = function (data, x, y, prefix) { - core.values[data.name] = data.value; - core.doAction(); -} - -events.prototype._action_setGlobalFlag = function (data, x, y, prefix) { - this.setGlobalFlag(data.name, data.value); - core.doAction(); -} - -events.prototype._action_setNameMap = function (data, x, y, floorId) { - this.setNameMap(data.name, data.value); - core.doAction(); -} - -events.prototype._action_setHeroIcon = function (data, x, y, prefix) { - this.setHeroIcon(data.name, data.noDraw); - core.doAction(); -} - -events.prototype._action_input = function (data, x, y, prefix) { - this.__action_getInput(core.replaceText(data.text, prefix), false, function (value) { - value = parseInt(value) || 0; // 允许负整数 - core.status.route.push("input:" + value); - core.setFlag("input", value); - core.doAction(); - }); -} - -events.prototype._action_input2 = function (data, x, y, prefix) { - this.__action_getInput(core.replaceText(data.text, prefix), true, function (value) { - value = value || ""; - core.status.route.push("input2:" + core.encodeBase64(value)); - core.setFlag("input", value); - core.doAction(); - }); -} - -events.prototype.__action_getInput = function (hint, isText, callback) { - var value, prefix = isText ? "input2:" : "input:"; - if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(); - try { - if (action.indexOf(prefix) != 0) { - console.warn("警告!当前需要一个 " + prefix + " 项,实际为 " + action); - core.status.replay.toReplay.unshift(action); - return callback(isText ? '' : 0); - } - if (isText) value = core.decodeBase64(action.substring(7)); - else value = parseInt(action.substring(6)); - callback(value); - } - catch (e) { - core.control._replay_error(action); - return; - } - } - else { - core.myprompt(core.replaceText(hint), null, callback); - } -} - -events.prototype._action_if = function (data, x, y, prefix) { - if (core.calValue(data.condition, prefix)) - core.events.insertAction(data["true"]) - else - core.events.insertAction(data["false"]) - core.doAction(); -} - -events.prototype._precompile_if = function (data) { - data.condition = core.replaceValue(data.condition); - data["true"] = this.precompile(data["true"]); - data["false"] = this.precompile(data["false"]); - return data; -} - -events.prototype._action_switch = function (data, x, y, prefix) { - var key = core.calValue(data.condition, prefix) - var list = []; - for (var i = 0; i < data.caseList.length; i++) { - if (data.caseList[i]._disabled) continue; - var condition = data.caseList[i]["case"]; - if (condition == "default" || core.calValue(condition, prefix) === key) { - core.push(list, data.caseList[i].action); - if (!data.caseList[i].nobreak) - break; - } - } - core.insertAction(list); - core.doAction(); -} - -events.prototype._precompile_switch = function (data) { - data.condition = core.replaceValue(data.condition); - for (var i = 0; i < data.caseList.length; i++) { - data.caseList[i]["case"] = core.replaceValue(data.caseList[i]["case"]); - data.caseList[i].action = this.precompile(data.caseList[i].action); - } - return data; -} - -events.prototype._action_choices = function (data, x, y, prefix) { - data.choices = data.choices.filter(function (x) { - if (x._disabled) return false; - if (x.condition == null || x.condition == '') return true; - try { return core.calValue(x.condition, prefix); } catch (e) { return true; } - }) - if (data.choices.length == 0) return this.doAction(); - if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(); - if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) { - var index = action.substring(8); - if (!this.__action_choices_replaying(data, index)) { - core.control._replay_error(action); - return; - } - } else { - // 容错录像 - if (main.replayChecking) { - // 录像验证系统中选最后一项 - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 - core.events.__action_choices_replaying(data, -1); - } else { - // 正常游戏中弹窗选择 - core.myprompt('录像回放出错!当前需要执行选择项但录像中未记录。\n如需修复请输入您要选的项(从0起),点击取消将不会修复。', 0, function (value) { - if (value == null) { - core.control._replay_error(action); - return; - } - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 - core.events.__action_choices_replaying(data, ((parseInt(value) || 0) + data.choices.length) % data.choices.length); - }); - } - } - } else { - if (data.timeout) { - core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); - core.setFlag('timeout', 0); - core.doAction(); - }, data.timeout); - } - core.status.event.timeout = new Date().getTime() + (data.timeout || 0); - } - for (var i = 0; i < data.choices.length; i++) { - if (typeof data.choices[i] === 'string') - data.choices[i] = { "text": data.choices[i] }; - data.choices[i].text = core.replaceText(data.choices[i].text, 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') { - selection = parseInt(index); - if (isNaN(selection)) return false; - if (selection < 0) selection += data.choices.length; - if (selection < 0) return false; - if (selection % 100 > 50) selection += data.choices.length; - if (selection % 100 > data.choices.length) return false; - var timeout = Math.floor(selection / 100) || 0; - core.setFlag('timeout', timeout); - selection %= 100; - } else core.setFlag('timeout', 0); - core.status.event.selection = selection; - setTimeout(function () { - core.status.route.push("choices:" + index); - if (selection != 'none') { - // 检查 - var choice = data.choices[selection]; - if (choice.need != null && choice.need != '' && !core.calValue(choice.need)) { - // 无法选择此项 - core.control._replay_error("无法选择项:" + index); - return; - } else { - core.insertAction(choice.action); - } - } - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); - return true; -} - -events.prototype._precompile_choices = function (data) { - if (!(data.choices instanceof Array)) return data; - for (var i = 0; i < data.choices.length; ++i) { - data.choices[i].condition = core.replaceValue(data.choices[i].condition); - data.choices[i].text = this.__precompile_text(data.choices[i].text); - data.choices[i].action = this.precompile(data.choices[i].action); - } - return data; -} - -events.prototype._action_confirm = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - core.status.event.ui = { "text": data.text, "yes": data.yes, "no": data.no }; - if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(); - if (action.indexOf('choices:') == 0 && !(action == 'choices:none' && !data.timeout)) { - var index = action.substring(8); - if (index == 'none' || ((index = parseInt(index)) >= 0) && index % 100 < 2) { - this.__action_confirm_replaying(data, index); - } else { - core.control._replay_error(action); - return; - } - } else { - // 录像中未记录选了哪个,则选默认值,而不是直接报错 - if (action != 'choices:none') core.status.replay.toReplay.unshift(action); - this.__action_confirm_replaying(data, data["default"] ? 0 : 1); - } - } - else { - core.status.event.selection = data["default"] ? 0 : 1; - if (data.timeout) { - core.status.event.interval = setTimeout(function () { - core.status.route.push("choices:none"); - core.setFlag('timeout', 0); - core.doAction(); - }, data.timeout); - } - core.status.event.timeout = new Date().getTime() + (data.timeout || 0); - } - core.ui.drawConfirmBox(data.text); -} - -events.prototype.__action_confirm_replaying = function (data, index) { - if (index != 'none') { - var timeout = Math.floor(index / 100) || 0; - core.setFlag('timeout', timeout); - index %= 100; - } else core.setFlag('timeout', 0); - core.status.event.selection = index; - setTimeout(function () { - core.status.route.push("choices:" + index); - if (index != 'none') { - if (index == 0) core.insertAction(data.yes); - else core.insertAction(data.no); - } - core.doAction(); - }, core.status.replay.speed == 24 ? 1 : 750 / Math.max(1, core.status.replay.speed)); -} - -events.prototype._precompile_confirm = function (data) { - data.yes = this.precompile(data.yes); - data.no = this.precompile(data.no); - return data; -} - -events.prototype._action_for = function (data, x, y, prefix) { - // Only support temp:A - if (!/^temp:[A-Z]$/.test(data.name)) { - core.insertAction('循环遍历事件只支持临时变量!'); - return core.doAction(); - } - var from = core.calValue(data.from); - var to = core.calValue(data.to); - var step = core.calValue(data.step); - if (typeof from != 'number' || typeof to != 'number' || typeof step != 'number') { - core.insertAction('循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!'); - return core.doAction(); - } - // 首次判定 - if ((step > 0 && from > to) || (step < 0 && from < to)) { - core.doAction(); - return; - } - - var letter = data.name.substring(5); - core.setFlag('@temp@' + letter, from); - var toName = '@temp@for-to@' + letter; - var stepName = '@temp@for-step@' + letter; - core.setFlag(toName, data.to); - core.setFlag(stepName, data.step); - var condition = "(function () {" + - "var to = core.calValue(core.getFlag('" + toName + "'));" + - "var step = core.calValue(core.getFlag('" + stepName + "'));" + - "if (typeof step != 'number' || typeof to != 'number') return false;" + - "if (step == 0) return true;" + - "var currentValue = core.getFlag('@temp@" + letter + "');" + - "currentValue += step;" + - "core.setFlag('@temp@" + letter + "', currentValue);" + - "if (step > 0) { return currentValue <= to; }" + - "else { return currentValue >= to; }" + - "})()"; - return this._action_dowhile({ "condition": condition, "data": data.data }, x, y, prefix); -} - -events.prototype._precompile_for = function (data) { - data.from = core.replaceValue(data.from); - data.to = core.replaceValue(data.to); - data.step = core.replaceValue(data.step); - data.data = this.precompile(data.data); - return data; -} - -events.prototype._action_forEach = function (data, x, y, prefix) { - // Only support temp:A - if (!/^temp:[A-Z]$/.test(data.name)) { - core.insertAction(['循环遍历事件只支持临时变量!']); - return core.doAction(); - } - var listName = '@temp@forEach@' + data.name.substring(5); - core.setFlag(listName, core.clone(data.list)); - var condition = "(function () {" + - "var list = core.getFlag('" + listName + "', []);" + - "if (list.length == 0) return false;" + - "core.setFlag('@temp@'+'" + data.name.substring(5) + "', list.shift());" + - "return true;" + - "})()"; - return this._action_while({ "condition": condition, "data": data.data }, x, y, prefix); -} - -events.prototype._precompile_forEach = function (data) { - data.data = this.precompile(data.data); - return data; -} - -events.prototype._action_while = function (data, x, y, prefix) { - if (core.calValue(data.condition, prefix)) { - var list = core.clone(data.data); - if (!(list instanceof Array)) list = [list]; - list.push({ "type": "_label" }); - core.unshift(core.status.event.data.list, - { "todo": list, "total": core.clone(list), "condition": data.condition } - ); - } - core.doAction(); -} - -events.prototype._precompile_while = function (data) { - data.condition = core.replaceValue(data.condition); - data.data = this.precompile(data.data); - return data; -} - -events.prototype._action_dowhile = function (data, x, y, prefix) { - var list = core.clone(data.data); - if (!(list instanceof Array)) list = [list]; - list.push({ "type": "_label" }); - core.unshift(core.status.event.data.list, - { "todo": list, "total": core.clone(list), "condition": data.condition } + // 考虑到可能覆盖楼传事件的问题,这里不对fly进行检查。 + if (data.id != "book" && core.canUseItem(data.id)) { + core.useItem(data.id, true, core.doAction); + } else { + core.playSound("操作失败"); + core.drawTip( + "当前无法使用" + ((core.material.items[data.id] || {}).name || "未知道具") ); core.doAction(); -} + } +}; -events.prototype._precompile_dowhile = function (data) { - data.condition = core.replaceValue(data.condition); - data.data = this.precompile(data.data); - return data; -} +events.prototype._action_loadEquip = function (data, x, y, prefix) { + core.loadEquip(data.id); + core.doAction(); +}; -events.prototype._action_break = function (data, x, y, prefix) { - var n = data.n || 1; - while (n--) { - if (core.status.event.data.list.length > 1) - core.status.event.data.list.shift(); +events.prototype._action_unloadEquip = function (data, x, y, prefix) { + core.unloadEquip(data.pos); + core.doAction(); +}; + +events.prototype._action_openShop = function (data, x, y, prefix) { + core.setShopVisited(data.id, true); + if (data.open) core.openShop(data.id, true); + core.doAction(); +}; + +events.prototype._action_disableShop = function (data, x, y, prefix) { + core.setShopVisited(data.id, false); + core.doAction(); +}; + +events.prototype._action_battle = function (data, x, y, prefix) { + if (data.id) { + this.battle(data.id, null, null, true, core.doAction); + } else { + if (data.floorId != core.status.floorId) { + core.doAction(); + return; } - core.doAction(); -} + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this.battle(null, loc[0], loc[1], true, core.doAction); + } +}; -events.prototype._action_continue = function (data, x, y, prefix) { - var n = data.n || 1; - while (n-- > 1) { - if (core.status.event.data.list.length > 1) - core.status.event.data.list.shift(); - } - if (core.status.event.data.list.length > 1) { - if (core.calValue(core.status.event.data.list[0].condition, prefix)) { - core.status.event.data.list[0].todo = core.clone(core.status.event.data.list[0].total); - } - else { - core.status.event.data.list.shift(); +events.prototype._action_trigger = function (data, x, y, prefix) { + var loc = this.__action_getLoc(data.loc, x, y, prefix); + this._trigger_inAction(loc[0], loc[1]); +}; + +events.prototype._action_insert = function (data, x, y, prefix) { + if (data.name) { + // 公共事件 + core.insertCommonEvent(data.name, data.args); + } else { + // 设置参数 + if (data.args instanceof Array) { + for (var i = 0; i < data.args.length; ++i) { + try { + if (data.args[i] != null) core.setFlag("arg" + (i + 1), data.args[i]); + } catch (ee) { + console.error(ee); } + } } + var loc = this.__action_getLoc(data.loc, x, y, prefix); + core.setFlag("arg0", loc); + var floorId = data.floorId; + var which = data.which || "events"; + var event = (core.floors[floorId][which] || [])[loc[0] + "," + loc[1]]; + if (event) this.insertAction(event.data || event); + } + core.doAction(); +}; + +events.prototype._action_playBgm = function (data, x, y, prefix) { + core.playBgm(data.name, data.startTime || 0); + core.setFlag("__bgm__", data.keep ? data.name : null); + core.doAction(); +}; + +events.prototype._action_pauseBgm = function (data, x, y, prefix) { + core.pauseBgm(); + core.doAction(); +}; + +events.prototype._action_resumeBgm = function (data, x, y, prefix) { + core.resumeBgm(data.resume); + core.doAction(); +}; + +events.prototype._action_loadBgm = function (data, x, y, prefix) { + core.loadBgm(data.name); + core.doAction(); +}; + +events.prototype._action_freeBgm = function (data, x, y, prefix) { + core.freeBgm(data.name); + core.doAction(); +}; + +events.prototype._action_playSound = function (data, x, y, prefix) { + if (data.stop) core.stopSound(); + if (data.sync) { + core.playSound(data.name, data.pitch, core.doAction); + } else { + core.playSound(data.name, data.pitch); core.doAction(); -} + } +}; -events.prototype._action_win = function (data, x, y, prefix) { - this.win(core.replaceText(data.reason, prefix), data.norank, data.noexit); -} +events.prototype._action_stopSound = function (data, x, y, prefix) { + core.stopSound(); + core.doAction(); +}; -events.prototype._action_lose = function (data, x, y, prefix) { - this.lose(core.replaceText(data.reason, prefix)); -} +events.prototype._action_setVolume = function (data, x, y, prefix) { + data.value = core.clamp(parseInt(data.value) / 100, 0, 1); + core.setFlag("__volume__", data.value); + this.__action_doAsyncFunc( + data.async, + core.setVolume, + data.value, + data.time || 0 + ); +}; -events.prototype._action_restart = function (data, x, y, prefix) { - core.restart(); -} +events.prototype._action_setBgmSpeed = function (data, x, y, prefix) { + core.setBgmSpeed(data.value, data.pitch || false); + core.doAction(); +}; -events.prototype._action_function = function (data, x, y, prefix) { - var func = data["function"]; - try { - if (typeof func == "string" && func.indexOf("function") == 0) { - eval('(' + func + ')()'); - } - } catch (e) { - console.error(e); - } - if (!data.async) - core.doAction(); -} - -events.prototype._action_update = function (data, x, y, prefix) { - core.updateStatusBar(data.doNotCheckAutoEvents, true); - core.doAction(); -} - -events.prototype._action_showStatusBar = function (data, x, y, prefix) { - core.showStatusBar(); - core.doAction(); -} - -events.prototype._action_hideStatusBar = function (data, x, y, prefix) { - core.hideStatusBar(data.toolbox); - core.doAction(); -} - -events.prototype._action_showHero = function (data, x, y, prefix) { - data.opacity = 1; - return this._action_setHeroOpacity(data, x, y, prefix); -} - -events.prototype._action_hideHero = function (data, x, y, prefix) { - data.opacity = 0; - return this._action_setHeroOpacity(data, x, y, prefix); -} - -events.prototype._action_setHeroOpacity = function (data, x, y, prefix) { - data.time = data.time || 0; - if (data.opacity == null) data.opacity = 1; - if (data.time > 0) { - this.__action_doAsyncFunc(data.async, core.setHeroOpacity, data.opacity, data.moveMode, data.time); +events.prototype._action_setValue = function (data, x, y, prefix) { + this.setValue(data.name, data.operator, data.value, prefix); + if (!data.norefresh) { + if (core.status.hero.hp <= 0) { + core.status.hero.hp = 0; + core.updateStatusBar(); + core.events.lose(); } else { - core.setFlag('__heroOpacity__', data.opacity); - core.drawHero(); - core.doAction(); + core.updateStatusBar(); } -} + } + core.doAction(); +}; -events.prototype._action_vibrate = function (data, x, y, prefix) { - this.__action_doAsyncFunc(data.async, core.vibrate, data.direction, data.time, data.speed, data.power); -} +events.prototype._action_addValue = function (data, x, y, prefix) { + data.operator = "+="; + this._action_setValue(data, x, y, prefix); +}; -events.prototype._action_sleep = function (data, x, y, prefix) { - core.timeout.sleepTimeout = setTimeout(function () { - core.timeout.sleepTimeout = null; - core.doAction(); - }, core.isReplaying() ? Math.min(data.time, 20) : data.time); -} +events.prototype._action_setEnemy = function (data, x, y, prefix) { + this.setEnemy( + data.id, + data.name, + data.value, + data.operator, + prefix, + data.norefresh + ); + core.doAction(); +}; -events.prototype._action_wait = function (data, x, y, prefix) { - if (core.isReplaying()) { - var code = core.status.replay.toReplay.shift(); - if (code.indexOf("input:") == 0 && !(code == "input:none" && !data.timeout)) { - if (code == "input:none") { - core.status.route.push("input:none"); - core.setFlag("type", -1); - core.setFlag("timeout", 0); - this.__action_wait_afterGet(data); - return core.doAction(); - } else { - var value = parseInt(code.substring(6)); - core.status.route.push("input:" + value); - this.__action_wait_getValue(value); - if (this.__action_wait_afterGet(data) || !data.forceChild) return core.doAction(); - } - } - core.control._replay_error(code); +events.prototype._action_setEnemyOnPoint = function (data, x, y, prefix) { + var loc = this.__action_getLoc2D(data.loc, x, y, prefix); + loc.forEach(function (one) { + core.setEnemyOnPoint( + one[0], + one[1], + data.floorId, + data.name, + data.value, + data.operator, + prefix, + data.norefresh + ); + }); + core.doAction(); +}; + +events.prototype._action_resetEnemyOnPoint = function (data, x, y, prefix) { + var loc = this.__action_getLoc2D(data.loc, x, y, prefix); + loc.forEach(function (one) { + core.resetEnemyOnPoint(one[0], one[1], data.floorId, data.norefresh); + }); + core.doAction(); +}; + +events.prototype._precompile_moveEnemyOnPoint = function (data) { + data.from = this.__precompile_array(data.from); + data.to = this.__precompile_array(data.to); + data.dxy = this.__precompile_array(data.dxy); + return data; +}; + +events.prototype._action_moveEnemyOnPoint = function (data, x, y, prefix) { + var from = this.__action_getLoc(data.from, x, y, prefix), + to; + if (data.dxy) { + to = [ + from[0] + (core.calValue(data.dxy[0], prefix) || 0), + from[1] + (core.calValue(data.dxy[1], prefix) || 0), + ]; + } else { + to = this.__action_getLoc(data.to, x, y, prefix); + } + this.moveEnemyOnPoint( + from[0], + from[1], + to[0], + to[1], + data.floorId, + data.norefresh + ); + core.doAction(); +}; + +events.prototype._action_setEquip = function (data, x, y, prefix) { + core.setEquip( + data.id, + data.valueType, + data.name, + data.value, + data.operator, + prefix + ); + core.doAction(); +}; + +events.prototype._action_setFloor = function (data, x, y, prefix) { + this.setFloorInfo(data.name, data.value, data.floorId, prefix); + core.doAction(); +}; + +events.prototype._action_setGlobalAttribute = function (data, x, y, prefix) { + this.setGlobalAttribute(data.name, data.value); + core.doAction(); +}; + +events.prototype._action_setGlobalValue = function (data, x, y, prefix) { + core.values[data.name] = data.value; + core.doAction(); +}; + +events.prototype._action_setGlobalFlag = function (data, x, y, prefix) { + this.setGlobalFlag(data.name, data.value); + core.doAction(); +}; + +events.prototype._action_setNameMap = function (data, x, y, floorId) { + this.setNameMap(data.name, data.value); + core.doAction(); +}; + +events.prototype._action_setHeroIcon = function (data, x, y, prefix) { + this.setHeroIcon(data.name, data.noDraw); + core.doAction(); +}; + +events.prototype._action_input = function (data, x, y, prefix) { + this.__action_getInput( + core.replaceText(data.text, prefix), + false, + function (value) { + value = parseInt(value) || 0; // 允许负整数 + core.status.route.push("input:" + value); + core.setFlag("input", value); + core.doAction(); + } + ); +}; + +events.prototype._action_input2 = function (data, x, y, prefix) { + this.__action_getInput( + core.replaceText(data.text, prefix), + true, + function (value) { + value = value || ""; + core.status.route.push("input2:" + core.encodeBase64(value)); + core.setFlag("input", value); + core.doAction(); + } + ); +}; + +events.prototype.__action_getInput = function (hint, isText, callback) { + var value, + prefix = isText ? "input2:" : "input:"; + if (core.isReplaying()) { + var action = core.status.replay.toReplay.shift(); + try { + if (action.indexOf(prefix) != 0) { + console.warn("警告!当前需要一个 " + prefix + " 项,实际为 " + action); + core.status.replay.toReplay.unshift(action); + return callback(isText ? "" : 0); + } + if (isText) value = core.decodeBase64(action.substring(7)); + else value = parseInt(action.substring(6)); + callback(value); + } catch (e) { + core.control._replay_error(action); + return; + } + } else { + core.myprompt(core.replaceText(hint), null, callback); + } +}; + +events.prototype._action_if = function (data, x, y, prefix) { + if (core.calValue(data.condition, prefix)) + core.events.insertAction(data["true"]); + else core.events.insertAction(data["false"]); + core.doAction(); +}; + +events.prototype._precompile_if = function (data) { + data.condition = core.replaceValue(data.condition); + data["true"] = this.precompile(data["true"]); + data["false"] = this.precompile(data["false"]); + return data; +}; + +events.prototype._action_switch = function (data, x, y, prefix) { + var key = core.calValue(data.condition, prefix); + var list = []; + for (var i = 0; i < data.caseList.length; i++) { + if (data.caseList[i]._disabled) continue; + var condition = data.caseList[i]["case"]; + if (condition == "default" || core.calValue(condition, prefix) === key) { + core.push(list, data.caseList[i].action); + if (!data.caseList[i].nobreak) break; + } + } + core.insertAction(list); + core.doAction(); +}; + +events.prototype._precompile_switch = function (data) { + data.condition = core.replaceValue(data.condition); + for (var i = 0; i < data.caseList.length; i++) { + data.caseList[i]["case"] = core.replaceValue(data.caseList[i]["case"]); + data.caseList[i].action = this.precompile(data.caseList[i].action); + } + return data; +}; + +events.prototype._action_choices = function (data, x, y, prefix) { + data.choices = data.choices.filter(function (x) { + if (x._disabled) return false; + if (x.condition == null || x.condition == "") return true; + try { + return core.calValue(x.condition, prefix); + } catch (e) { + return true; + } + }); + if (data.choices.length == 0) return this.doAction(); + if (core.isReplaying()) { + var action = core.status.replay.toReplay.shift(); + if ( + action.indexOf("choices:") == 0 && + !(action == "choices:none" && !data.timeout) + ) { + var index = action.substring(8); + if (!this.__action_choices_replaying(data, index)) { + core.control._replay_error(action); return; - } else if (data.timeout) { - core.status.event.interval = setTimeout(function () { - core.status.route.push("input:none"); - core.setFlag("type", -1); - core.setFlag("timeout", 0); - core.events.__action_wait_afterGet(data); - core.doAction(); - }, data.timeout); + } + } else { + // 容错录像 + if (main.replayChecking) { + // 录像验证系统中选最后一项 + if (action != "choices:none") + core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 + core.events.__action_choices_replaying(data, -1); + } else { + // 正常游戏中弹窗选择 + core.myprompt( + "录像回放出错!当前需要执行选择项但录像中未记录。\n如需修复请输入您要选的项(从0起),点击取消将不会修复。", + 0, + function (value) { + if (value == null) { + core.control._replay_error(action); + return; + } + if (action != "choices:none") + core.status.replay.toReplay.unshift(action); // 首先归还刚才读出的下一步操作 + core.events.__action_choices_replaying( + data, + ((parseInt(value) || 0) + data.choices.length) % + data.choices.length + ); + } + ); + } + } + } else { + if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("choices:none"); + core.setFlag("timeout", 0); + core.doAction(); + }, data.timeout); } core.status.event.timeout = new Date().getTime() + (data.timeout || 0); -} + } + for (var i = 0; i < data.choices.length; i++) { + if (typeof data.choices[i] === "string") + data.choices[i] = { text: data.choices[i] }; + data.choices[i].text = core.replaceText(data.choices[i].text, 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") { + selection = parseInt(index); + if (isNaN(selection)) return false; + if (selection < 0) selection += data.choices.length; + if (selection < 0) return false; + if (selection % 100 > 50) selection += data.choices.length; + if (selection % 100 > data.choices.length) return false; + var timeout = Math.floor(selection / 100) || 0; + core.setFlag("timeout", timeout); + selection %= 100; + } else core.setFlag("timeout", 0); + core.status.event.selection = selection; + setTimeout( + function () { + core.status.route.push("choices:" + index); + if (selection != "none") { + // 检查 + var choice = data.choices[selection]; + if ( + choice.need != null && + choice.need != "" && + !core.calValue(choice.need) + ) { + // 无法选择此项 + core.control._replay_error("无法选择项:" + index); + return; + } else { + core.insertAction(choice.action); + } + } + core.doAction(); + }, + core.status.replay.speed == 24 + ? 1 + : 750 / Math.max(1, core.status.replay.speed) + ); + return true; +}; + +events.prototype._precompile_choices = function (data) { + if (!(data.choices instanceof Array)) return data; + for (var i = 0; i < data.choices.length; ++i) { + data.choices[i].condition = core.replaceValue(data.choices[i].condition); + data.choices[i].text = this.__precompile_text(data.choices[i].text); + data.choices[i].action = this.precompile(data.choices[i].action); + } + return data; +}; + +events.prototype._action_confirm = function (data, x, y, prefix) { + data.text = core.replaceText(data.text, prefix); + core.status.event.ui = { text: data.text, yes: data.yes, no: data.no }; + if (core.isReplaying()) { + var action = core.status.replay.toReplay.shift(); + if ( + action.indexOf("choices:") == 0 && + !(action == "choices:none" && !data.timeout) + ) { + var index = action.substring(8); + if ( + index == "none" || + ((index = parseInt(index)) >= 0 && index % 100 < 2) + ) { + this.__action_confirm_replaying(data, index); + } else { + core.control._replay_error(action); + return; + } + } else { + // 录像中未记录选了哪个,则选默认值,而不是直接报错 + if (action != "choices:none") core.status.replay.toReplay.unshift(action); + this.__action_confirm_replaying(data, data["default"] ? 0 : 1); + } + } else { + core.status.event.selection = data["default"] ? 0 : 1; + if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("choices:none"); + core.setFlag("timeout", 0); + core.doAction(); + }, data.timeout); + } + core.status.event.timeout = new Date().getTime() + (data.timeout || 0); + } + core.ui.drawConfirmBox(data.text); +}; + +events.prototype.__action_confirm_replaying = function (data, index) { + if (index != "none") { + var timeout = Math.floor(index / 100) || 0; + core.setFlag("timeout", timeout); + index %= 100; + } else core.setFlag("timeout", 0); + core.status.event.selection = index; + setTimeout( + function () { + core.status.route.push("choices:" + index); + if (index != "none") { + if (index == 0) core.insertAction(data.yes); + else core.insertAction(data.no); + } + core.doAction(); + }, + core.status.replay.speed == 24 + ? 1 + : 750 / Math.max(1, core.status.replay.speed) + ); +}; + +events.prototype._precompile_confirm = function (data) { + data.yes = this.precompile(data.yes); + data.no = this.precompile(data.no); + return data; +}; + +events.prototype._action_for = function (data, x, y, prefix) { + // Only support temp:A + if (!/^temp:[A-Z]$/.test(data.name)) { + core.insertAction("循环遍历事件只支持临时变量!"); + return core.doAction(); + } + var from = core.calValue(data.from); + var to = core.calValue(data.to); + var step = core.calValue(data.step); + if ( + typeof from != "number" || + typeof to != "number" || + typeof step != "number" + ) { + core.insertAction( + "循环遍历事件要求【起始点】【终止点】【每步】仅能是数字!" + ); + return core.doAction(); + } + // 首次判定 + if ((step > 0 && from > to) || (step < 0 && from < to)) { + core.doAction(); + return; + } + + var letter = data.name.substring(5); + core.setFlag("@temp@" + letter, from); + var toName = "@temp@for-to@" + letter; + var stepName = "@temp@for-step@" + letter; + core.setFlag(toName, data.to); + core.setFlag(stepName, data.step); + var condition = + "(function () {" + + "var to = core.calValue(core.getFlag('" + + toName + + "'));" + + "var step = core.calValue(core.getFlag('" + + stepName + + "'));" + + "if (typeof step != 'number' || typeof to != 'number') return false;" + + "if (step == 0) return true;" + + "var currentValue = core.getFlag('@temp@" + + letter + + "');" + + "currentValue += step;" + + "core.setFlag('@temp@" + + letter + + "', currentValue);" + + "if (step > 0) { return currentValue <= to; }" + + "else { return currentValue >= to; }" + + "})()"; + return this._action_dowhile( + { condition: condition, data: data.data }, + x, + y, + prefix + ); +}; + +events.prototype._precompile_for = function (data) { + data.from = core.replaceValue(data.from); + data.to = core.replaceValue(data.to); + data.step = core.replaceValue(data.step); + data.data = this.precompile(data.data); + return data; +}; + +events.prototype._action_forEach = function (data, x, y, prefix) { + // Only support temp:A + if (!/^temp:[A-Z]$/.test(data.name)) { + core.insertAction(["循环遍历事件只支持临时变量!"]); + return core.doAction(); + } + var listName = "@temp@forEach@" + data.name.substring(5); + core.setFlag(listName, core.clone(data.list)); + var condition = + "(function () {" + + "var list = core.getFlag('" + + listName + + "', []);" + + "if (list.length == 0) return false;" + + "core.setFlag('@temp@'+'" + + data.name.substring(5) + + "', list.shift());" + + "return true;" + + "})()"; + return this._action_while( + { condition: condition, data: data.data }, + x, + y, + prefix + ); +}; + +events.prototype._precompile_forEach = function (data) { + data.data = this.precompile(data.data); + return data; +}; + +events.prototype._action_while = function (data, x, y, prefix) { + if (core.calValue(data.condition, prefix)) { + var list = core.clone(data.data); + if (!(list instanceof Array)) list = [list]; + list.push({ type: "_label" }); + core.unshift(core.status.event.data.list, { + todo: list, + total: core.clone(list), + condition: data.condition, + }); + } + core.doAction(); +}; + +events.prototype._precompile_while = function (data) { + data.condition = core.replaceValue(data.condition); + data.data = this.precompile(data.data); + return data; +}; + +events.prototype._action_dowhile = function (data, x, y, prefix) { + var list = core.clone(data.data); + if (!(list instanceof Array)) list = [list]; + list.push({ type: "_label" }); + core.unshift(core.status.event.data.list, { + todo: list, + total: core.clone(list), + condition: data.condition, + }); + core.doAction(); +}; + +events.prototype._precompile_dowhile = function (data) { + data.condition = core.replaceValue(data.condition); + data.data = this.precompile(data.data); + return data; +}; + +events.prototype._action_break = function (data, x, y, prefix) { + var n = data.n || 1; + while (n--) { + if (core.status.event.data.list.length > 1) + core.status.event.data.list.shift(); + } + core.doAction(); +}; + +events.prototype._action_continue = function (data, x, y, prefix) { + var n = data.n || 1; + while (n-- > 1) { + if (core.status.event.data.list.length > 1) + core.status.event.data.list.shift(); + } + if (core.status.event.data.list.length > 1) { + if (core.calValue(core.status.event.data.list[0].condition, prefix)) { + core.status.event.data.list[0].todo = core.clone( + core.status.event.data.list[0].total + ); + } else { + core.status.event.data.list.shift(); + } + } + core.doAction(); +}; + +events.prototype._action_win = function (data, x, y, prefix) { + this.win(core.replaceText(data.reason, prefix), data.norank, data.noexit); +}; + +events.prototype._action_lose = function (data, x, y, prefix) { + this.lose(core.replaceText(data.reason, prefix)); +}; + +events.prototype._action_restart = function (data, x, y, prefix) { + core.restart(); +}; + +events.prototype._action_function = function (data, x, y, prefix) { + var func = data["function"]; + try { + if (typeof func == "string" && func.indexOf("function") == 0) { + eval("(" + func + ")()"); + } + } catch (e) { + console.error(e); + } + if (!data.async) core.doAction(); +}; + +events.prototype._action_update = function (data, x, y, prefix) { + core.updateStatusBar(data.doNotCheckAutoEvents, true); + core.doAction(); +}; + +events.prototype._action_showStatusBar = function (data, x, y, prefix) { + core.showStatusBar(); + core.doAction(); +}; + +events.prototype._action_hideStatusBar = function (data, x, y, prefix) { + core.hideStatusBar(data.toolbox); + core.doAction(); +}; + +events.prototype._action_showHero = function (data, x, y, prefix) { + data.opacity = 1; + return this._action_setHeroOpacity(data, x, y, prefix); +}; + +events.prototype._action_hideHero = function (data, x, y, prefix) { + data.opacity = 0; + return this._action_setHeroOpacity(data, x, y, prefix); +}; + +events.prototype._action_setHeroOpacity = function (data, x, y, prefix) { + data.time = data.time || 0; + if (data.opacity == null) data.opacity = 1; + if (data.time > 0) { + this.__action_doAsyncFunc( + data.async, + core.setHeroOpacity, + data.opacity, + data.moveMode, + data.time + ); + } else { + core.setFlag("__heroOpacity__", data.opacity); + core.drawHero(); + core.doAction(); + } +}; + +events.prototype._action_vibrate = function (data, x, y, prefix) { + this.__action_doAsyncFunc( + data.async, + core.vibrate, + data.direction, + data.time, + data.speed, + data.power + ); +}; + +events.prototype._action_sleep = function (data, x, y, prefix) { + core.timeout.sleepTimeout = setTimeout( + function () { + core.timeout.sleepTimeout = null; + core.doAction(); + }, + core.isReplaying() ? Math.min(data.time, 20) : data.time + ); +}; + +events.prototype._action_wait = function (data, x, y, prefix) { + if (core.isReplaying()) { + var code = core.status.replay.toReplay.shift(); + if ( + code.indexOf("input:") == 0 && + !(code == "input:none" && !data.timeout) + ) { + if (code == "input:none") { + core.status.route.push("input:none"); + core.setFlag("type", -1); + core.setFlag("timeout", 0); + this.__action_wait_afterGet(data); + return core.doAction(); + } else { + var value = parseInt(code.substring(6)); + core.status.route.push("input:" + value); + this.__action_wait_getValue(value); + if (this.__action_wait_afterGet(data) || !data.forceChild) + return core.doAction(); + } + } + core.control._replay_error(code); + return; + } else if (data.timeout) { + core.status.event.interval = setTimeout(function () { + core.status.route.push("input:none"); + core.setFlag("type", -1); + core.setFlag("timeout", 0); + core.events.__action_wait_afterGet(data); + core.doAction(); + }, data.timeout); + } + core.status.event.timeout = new Date().getTime() + (data.timeout || 0); +}; events.prototype.__action_wait_getValue = function (value) { - core.setFlag("timeout", Math.floor(value / 1e8) || 0); - value %= 1e8; - if (value >= 1000000) { - core.setFlag('type', 1); - var px = parseInt((value - 1000000) / 1000), py = value % 1000; - core.setFlag('px', px); - core.setFlag('py', py); - core.setFlag('x', parseInt(px / 32)); - core.setFlag('y', parseInt(py / 32)); - } - else if (value >= 10000) { - core.setFlag('type', 1); - var x = parseInt((value - 10000) / 100), y = value % 100; - core.setFlag('px', 32 * x + 16); - core.setFlag('py', 32 * y + 16); - core.setFlag('x', x); - core.setFlag('y', y); - } - else if (value > 0) { - core.setFlag('type', 0); - core.setFlag('keycode', value); - } -} + core.setFlag("timeout", Math.floor(value / 1e8) || 0); + value %= 1e8; + if (value >= 1000000) { + core.setFlag("type", 1); + var px = parseInt((value - 1000000) / 1000), + py = value % 1000; + core.setFlag("px", px); + core.setFlag("py", py); + core.setFlag("x", parseInt(px / 32)); + core.setFlag("y", parseInt(py / 32)); + } else if (value >= 10000) { + core.setFlag("type", 1); + var x = parseInt((value - 10000) / 100), + y = value % 100; + core.setFlag("px", 32 * x + 16); + core.setFlag("py", 32 * y + 16); + core.setFlag("x", x); + core.setFlag("y", y); + } else if (value > 0) { + core.setFlag("type", 0); + core.setFlag("keycode", value); + } +}; events.prototype.__action_wait_afterGet = function (data) { - if (!data.data) return false; - var todo = []; - var stop = false; - var found = false; - data.data.forEach(function (one) { - if (one._disabled || stop) return; - if (one["case"] == "keyboard" && core.getFlag("type") == 0) { - (one.keycode + "").split(",").forEach(function (keycode) { - if (core.getFlag("keycode", 0) == keycode) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - }); + if (!data.data) return false; + var todo = []; + var stop = false; + var found = false; + data.data.forEach(function (one) { + if (one._disabled || stop) return; + if (one["case"] == "keyboard" && core.getFlag("type") == 0) { + (one.keycode + "").split(",").forEach(function (keycode) { + if (core.getFlag("keycode", 0) == keycode) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; } - if (one["case"] == "mouse" && one.px instanceof Array - && one.py instanceof Array && core.getFlag("type") == 1) { - var pxmin = core.calValue(one.px[0]); - var pxmax = core.calValue(one.px[1]); - var pymin = core.calValue(one.py[0]); - var pymax = core.calValue(one.py[1]); - var px = core.getFlag("px", 0), py = core.getFlag("py", 0); - if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - } - if (one["case"] == "condition") { - var condition = false; - try { condition = core.calValue(one.condition); } catch (e) { } - if (condition) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - } - if (one["case"] == "timeout" && core.getFlag("type") == -1) { - found = true; - core.push(todo, one.action); - if (one["break"]) stop = true; - } - }) - if (found) { - core.insertAction(todo); - return true; + }); } - return false; -} + if ( + one["case"] == "mouse" && + one.px instanceof Array && + one.py instanceof Array && + core.getFlag("type") == 1 + ) { + var pxmin = core.calValue(one.px[0]); + var pxmax = core.calValue(one.px[1]); + var pymin = core.calValue(one.py[0]); + var pymax = core.calValue(one.py[1]); + var px = core.getFlag("px", 0), + py = core.getFlag("py", 0); + if (px >= pxmin && px <= pxmax && py >= pymin && py <= pymax) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; + } + } + if (one["case"] == "condition") { + var condition = false; + try { + condition = core.calValue(one.condition); + } catch (e) {} + if (condition) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; + } + } + if (one["case"] == "timeout" && core.getFlag("type") == -1) { + found = true; + core.push(todo, one.action); + if (one["break"]) stop = true; + } + }); + if (found) { + core.insertAction(todo); + return true; + } + return false; +}; events.prototype._precompile_wait = function (data) { - if (data.data) { - data.data.forEach(function (v) { - if (v.px != null) v.px = this.__precompile_array(v.px); - if (v.py != null) v.py = this.__precompile_array(v.py); - if (v.condition != null) v.condition = this.__precompile_array(v.condition); - v.action = this.precompile(v.action); - }, this); - } - return data; -} + if (data.data) { + data.data.forEach(function (v) { + if (v.px != null) v.px = this.__precompile_array(v.px); + if (v.py != null) v.py = this.__precompile_array(v.py); + if (v.condition != null) + v.condition = this.__precompile_array(v.condition); + v.action = this.precompile(v.action); + }, this); + } + return data; +}; events.prototype._action_waitAsync = function (data, x, y, prefix) { - var test = window.setInterval(function () { - if (!core.hasAsync() - && (data.excludeAnimates || core.isReplaying() || core.getPlayingAnimates().length == 0) - && (!data.includeSounds || core.isReplaying() || core.getPlayingSounds().length == 0)) { - clearInterval(test); - core.doAction(); - } - }, 50 / core.status.replay.speed); -} + var test = window.setInterval(function () { + if ( + !core.hasAsync() && + (data.excludeAnimates || + core.isReplaying() || + core.getPlayingAnimates().length == 0) && + (!data.includeSounds || + core.isReplaying() || + core.getPlayingSounds().length == 0) + ) { + clearInterval(test); + core.doAction(); + } + }, 50 / core.status.replay.speed); +}; events.prototype._action_stopAsync = function (data, x, y, prefix) { - core.stopAsync(); - core.doAction(); -} + core.stopAsync(); + core.doAction(); +}; events.prototype._action_callBook = function (data, x, y, prefix) { - if (core.isReplaying() || !core.hasItem('book')) { - core.doAction(); - } - else { - var e = core.clone(core.status.event.data); - core.ui.closePanel(); - core.openBook(); - core.status.event.interval = e; - } -} - -events.prototype._action_callSave = function (data, x, y, prefix) { - if (core.isReplaying() || core.hasFlag("__events__")) { - core.removeFlag("__events__"); - core.doAction(); - } - else { - var e = core.clone(core.status.event.data); - core.ui.closePanel(); - var forbidSave = core.hasFlag('__forbidSave__'); - core.removeFlag('__forbidSave__'); - core.save(); - if (forbidSave) core.setFlag('__forbidSave__', true); - core.status.event.interval = e; - } -} - -events.prototype._action_autoSave = function (data, x, y, prefix) { - var forbidSave = core.hasFlag('__forbidSave__'); - core.removeFlag('__forbidSave__'); - core.autosave(data.removeLast); - if (forbidSave) core.setFlag('__forbidSave__', true); + if (core.isReplaying() || !core.hasItem("book")) { core.doAction(); -} - -events.prototype._action_forbidSave = function (data, x, y, prefix) { - core.setFlag('__forbidSave__', data.forbid || null); - core.doAction(); -} - -events.prototype._action_callLoad = function (data, x, y, prefix) { - if (this.__action_checkReplaying()) return; + } else { var e = core.clone(core.status.event.data); core.ui.closePanel(); - core.load(); + core.openBook(); core.status.event.interval = e; -} + } +}; + +events.prototype._action_callSave = function (data, x, y, prefix) { + if (core.isReplaying() || core.hasFlag("__events__")) { + core.removeFlag("__events__"); + core.doAction(); + } else { + var e = core.clone(core.status.event.data); + core.ui.closePanel(); + var forbidSave = core.hasFlag("__forbidSave__"); + core.removeFlag("__forbidSave__"); + core.save(); + if (forbidSave) core.setFlag("__forbidSave__", true); + core.status.event.interval = e; + } +}; + +events.prototype._action_autoSave = function (data, x, y, prefix) { + var forbidSave = core.hasFlag("__forbidSave__"); + core.removeFlag("__forbidSave__"); + core.autosave(data.removeLast); + if (forbidSave) core.setFlag("__forbidSave__", true); + core.doAction(); +}; + +events.prototype._action_forbidSave = function (data, x, y, prefix) { + core.setFlag("__forbidSave__", data.forbid || null); + core.doAction(); +}; + +events.prototype._action_callLoad = function (data, x, y, prefix) { + if (this.__action_checkReplaying()) return; + var e = core.clone(core.status.event.data); + core.ui.closePanel(); + core.load(); + core.status.event.interval = e; +}; events.prototype._action_exit = function (data, x, y, prefix) { - this.setEvents([]); - core.doAction(); -} + this.setEvents([]); + core.doAction(); +}; events.prototype._action_previewUI = function (data, x, y, prefix) { - this.insertAction(data.action); - core.doAction(); -} + this.insertAction(data.action); + core.doAction(); +}; events.prototype._precompile_previewUI = function (data) { - data.action = this.precompile(data.action); - return data; -} + data.action = this.precompile(data.action); + return data; +}; events.prototype.__action_doUIEvent = function (data) { - this.__action_doUIEvent_doOne(data); - var current = core.status.event.data.list[0]; - while (current.todo.length > 0) { - data = current.todo[0]; - if (this.__action_doUIEvent_doOne(current.todo[0])) - current.todo.shift(); - else break; - } - core.doAction(); -} + this.__action_doUIEvent_doOne(data); + var current = core.status.event.data.list[0]; + while (current.todo.length > 0) { + data = current.todo[0]; + if (this.__action_doUIEvent_doOne(current.todo[0])) current.todo.shift(); + else break; + } + core.doAction(); +}; events.prototype.__action_doUIEvent_doOne = function (data) { - if (core.ui['_uievent_' + data.type]) { - core.ui['_uievent_' + data.type](data); - return true; - } - return false; -} + if (core.ui["_uievent_" + data.type]) { + core.ui["_uievent_" + data.type](data); + return true; + } + return false; +}; events.prototype._action_clearMap = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillText = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - this.__action_doUIEvent(data); -} + data.text = core.replaceText(data.text, prefix); + this.__action_doUIEvent(data); +}; events.prototype._action_fillBoldText = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - this.__action_doUIEvent(data); -} + data.text = core.replaceText(data.text, prefix); + this.__action_doUIEvent(data); +}; events.prototype._action_fillRect = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillPolygon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._precompile_fillPolygon = function (data) { - data.nodes = this.__precompile_array(data.nodes); - return data; -} + data.nodes = this.__precompile_array(data.nodes); + return data; +}; events.prototype._action_strokeRect = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokePolygon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._precompile_strokePolygon = function (data) { - data.nodes = this.__precompile_array(data.nodes); - return data; -} + data.nodes = this.__precompile_array(data.nodes); + return data; +}; events.prototype._action_fillEllipse = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokeEllipse = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_fillArc = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_strokeArc = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawLine = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawArrow = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_setAttribute = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_setFilter = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawImage = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawIcon = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawSelector = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawBackground = function (data, x, y, prefix) { - this.__action_doUIEvent(data); -} + this.__action_doUIEvent(data); +}; events.prototype._action_drawTextContent = function (data, x, y, prefix) { - data.text = core.replaceText(data.text, prefix); - this.__action_doUIEvent(data); -} + data.text = core.replaceText(data.text, prefix); + this.__action_doUIEvent(data); +}; // ------ 点击状态栏图标所进行的一些操作 ------ // ////// 判断当前能否进入某个事件 ////// events.prototype._checkStatus = function (name, fromUserAction, checkItem) { - if (fromUserAction && core.status.event.id == name) { - core.ui.closePanel(); - return false; - } - if (fromUserAction && core.status.lockControl) return false; - if (checkItem && !core.hasItem(name)) { - core.playSound('操作失败'); - core.drawTip("你没有" + core.material.items[name].name, name); - return false; - } - if (core.isMoving()) { - core.playSound('操作失败'); - core.drawTip("请先停止勇士行动"); - return false; - } - core.lockControl(); - core.status.event.id = name; - return true; -} + if (fromUserAction && core.status.event.id == name) { + core.ui.closePanel(); + return false; + } + if (fromUserAction && core.status.lockControl) return false; + if (checkItem && !core.hasItem(name)) { + core.playSound("操作失败"); + core.drawTip("你没有" + core.material.items[name].name, name); + return false; + } + if (core.isMoving()) { + core.playSound("操作失败"); + core.drawTip("请先停止勇士行动"); + return false; + } + core.lockControl(); + core.status.event.id = name; + return true; +}; ////// 点击怪物手册时的打开操作 ////// events.prototype.openBook = function (fromUserAction) { - if (core.isReplaying()) return; - // 如果能恢复事件(从callBook事件触发) - if (core.status.event.id == 'book' && core.events.recoverEvents(core.status.event.interval)) - return; - // 当前是book,且从“浏览地图”打开 - if (core.status.event.id == 'book' && core.status.event.ui) { - core.status.boxAnimateObjs = []; - core.ui._drawViewMaps(core.status.event.ui); - return; - } - // 从“浏览地图”页面打开 - if (core.status.event.id == 'viewMaps') { - fromUserAction = false; - core.status.event.ui = core.status.event.data; - } - if (!this._checkStatus('book', fromUserAction, true)) return; - core.playSound('打开界面'); - core.useItem('book', true); -} + if (core.isReplaying()) return; + // 如果能恢复事件(从callBook事件触发) + if ( + core.status.event.id == "book" && + core.events.recoverEvents(core.status.event.interval) + ) + return; + // 当前是book,且从“浏览地图”打开 + if (core.status.event.id == "book" && core.status.event.ui) { + core.status.boxAnimateObjs = []; + core.ui._drawViewMaps(core.status.event.ui); + return; + } + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps") { + fromUserAction = false; + core.status.event.ui = core.status.event.data; + } + if (!this._checkStatus("book", fromUserAction, true)) return; + core.playSound("打开界面"); + core.useItem("book", true); +}; ////// 点击楼层传送器时的打开操作 ////// events.prototype.useFly = function (fromUserAction) { - if (core.isReplaying()) return; - // 从“浏览地图”页面:尝试直接传送到该层 - if (core.status.event.id == 'viewMaps') { - if (!core.hasItem('fly')) { - core.playSound('操作失败'); - core.drawTip('你没有' + core.material.items['fly'].name, 'fly'); - } else if (!core.canUseItem('fly') || (core.flags.flyNearStair && !core.nearStair())) { - core.playSound('操作失败'); - core.drawTip('无法传送到当前层', 'fly'); - } else { - core.flyTo(core.status.event.data.floorId); - } - return; + if (core.isReplaying()) return; + // 从“浏览地图”页面:尝试直接传送到该层 + if (core.status.event.id == "viewMaps") { + if (!core.hasItem("fly")) { + core.playSound("操作失败"); + core.drawTip("你没有" + core.material.items["fly"].name, "fly"); + } else if ( + !core.canUseItem("fly") || + (core.flags.flyNearStair && !core.nearStair()) + ) { + core.playSound("操作失败"); + core.drawTip("无法传送到当前层", "fly"); + } else { + core.flyTo(core.status.event.data.floorId); } - - if (!this._checkStatus('fly', fromUserAction, true)) return; - if (core.flags.flyNearStair && !core.nearStair()) { - core.playSound('操作失败'); - core.drawTip("只有在楼梯边才能使用" + core.material.items['fly'].name, 'fly'); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - if (!core.canUseItem('fly')) { - core.playSound('操作失败'); - core.drawTip(core.material.items['fly'].name + "好像失效了", 'fly'); - core.unlockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - core.playSound('打开界面'); - core.useItem('fly', true); return; -} + } + + if (!this._checkStatus("fly", fromUserAction, true)) return; + if (core.flags.flyNearStair && !core.nearStair()) { + core.playSound("操作失败"); + core.drawTip( + "只有在楼梯边才能使用" + core.material.items["fly"].name, + "fly" + ); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + if (!core.canUseItem("fly")) { + core.playSound("操作失败"); + core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); + core.unlockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + core.playSound("打开界面"); + core.useItem("fly", true); + return; +}; events.prototype.flyTo = function (toId, callback) { - return this.eventdata.flyTo(toId, callback); -} + return this.eventdata.flyTo(toId, callback); +}; ////// 点击装备栏时的打开操作 ////// events.prototype.openEquipbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('equipbox', fromUserAction)) return; - core.playSound('打开界面'); - core.ui._drawEquipbox(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("equipbox", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawEquipbox(); +}; ////// 点击工具栏时的打开操作 ////// events.prototype.openToolbox = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('toolbox', fromUserAction)) return; - core.playSound('打开界面'); - core.ui._drawToolbox(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("toolbox", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawToolbox(); +}; ////// 点击快捷商店按钮时的打开操作 ////// events.prototype.openQuickShop = function (fromUserAction) { - if (core.isReplaying()) return; + if (core.isReplaying()) return; - if (Object.keys(core.status.shops).length == 0) { - core.playSound('操作失败'); - core.drawTip("本游戏没有快捷商店!"); - return; + if (Object.keys(core.status.shops).length == 0) { + core.playSound("操作失败"); + core.drawTip("本游戏没有快捷商店!"); + return; + } + + // --- 如果只有一个商店,则直接打开之 + if (Object.keys(core.status.shops).length == 1) { + var shopId = Object.keys(core.status.shops)[0]; + if (core.status.event.id != null) return; + if (!core.canOpenShop(shopId)) { + core.playSound("操作失败"); + core.drawTip("当前无法打开快捷商店!"); + return; } - - // --- 如果只有一个商店,则直接打开之 - if (Object.keys(core.status.shops).length == 1) { - var shopId = Object.keys(core.status.shops)[0]; - if (core.status.event.id != null) return; - if (!core.canOpenShop(shopId)) { - core.playSound('操作失败'); - core.drawTip("当前无法打开快捷商店!"); - return; - } - var message = core.canUseQuickShop(shopId); - if (message != null) { - core.playSound('操作失败'); - core.drawTip(message); - return; - } - core.openShop(shopId, false); - return; + var message = core.canUseQuickShop(shopId); + if (message != null) { + core.playSound("操作失败"); + core.drawTip(message); + return; } + core.openShop(shopId, false); + return; + } - if (!this._checkStatus('selectShop', fromUserAction)) return; - core.ui._drawQuickShop(); -} + if (!this._checkStatus("selectShop", fromUserAction)) return; + core.ui._drawQuickShop(); +}; events.prototype.openKeyBoard = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('keyBoard', fromUserAction)) return; - core.ui._drawKeyBoard(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("keyBoard", fromUserAction)) return; + core.ui._drawKeyBoard(); +}; ////// 点击保存按钮时的打开操作 ////// events.prototype.save = function (fromUserAction) { - if (core.isReplaying()) return; - if (core.hasFlag('__forbidSave__')) { - core.playSound('操作失败'); - core.drawTip('当前禁止存档'); - return; - } - if (core.status.event.id == 'save' && core.events.recoverEvents(core.status.event.interval)) - return; - if (!this._checkStatus('save', fromUserAction)) return; - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; - core.playSound('打开界面'); - core.ui._drawSLPanel(10 * page + offset); -} + if (core.isReplaying()) return; + if (core.hasFlag("__forbidSave__")) { + core.playSound("操作失败"); + core.drawTip("当前禁止存档"); + return; + } + if ( + core.status.event.id == "save" && + core.events.recoverEvents(core.status.event.interval) + ) + return; + if (!this._checkStatus("save", fromUserAction)) return; + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; + core.playSound("打开界面"); + core.ui._drawSLPanel(10 * page + offset); +}; ////// 点击读取按钮时的打开操作 ////// events.prototype.load = function (fromUserAction) { - if (core.isReplaying()) return; - var saveIndex = core.saves.saveIndex; - var page = parseInt((saveIndex - 1) / 5), offset = saveIndex - 5 * page; - // 游戏开始前读档 - if (!core.isPlaying()) { - core.dom.startPanel.style.display = 'none'; - core.clearStatus(); - core.clearMap('all'); - core.status.event = { 'id': 'load', 'data': null }; - core.status.lockControl = true; - core.playSound('打开界面'); - core.ui._drawSLPanel(10 * page + offset); - return; - } - if (core.status.event.id == 'load' && core.events.recoverEvents(core.status.event.interval)) - return; - if (!this._checkStatus('load', fromUserAction)) return; - core.playSound('打开界面'); + if (core.isReplaying()) return; + var saveIndex = core.saves.saveIndex; + var page = parseInt((saveIndex - 1) / 5), + offset = saveIndex - 5 * page; + // 游戏开始前读档 + if (!core.isPlaying()) { + core.dom.startPanel.style.display = "none"; + core.clearStatus(); + core.clearMap("all"); + core.status.event = { id: "load", data: null }; + core.status.lockControl = true; + core.playSound("打开界面"); core.ui._drawSLPanel(10 * page + offset); -} + return; + } + if ( + core.status.event.id == "load" && + core.events.recoverEvents(core.status.event.interval) + ) + return; + if (!this._checkStatus("load", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawSLPanel(10 * page + offset); +}; ////// 点击设置按钮时的操作 ////// events.prototype.openSettings = function (fromUserAction) { - if (core.isReplaying()) return; - if (!this._checkStatus('settings', fromUserAction)) - return; - core.playSound('打开界面'); - core.ui._drawSettings(); -} + if (core.isReplaying()) return; + if (!this._checkStatus("settings", fromUserAction)) return; + core.playSound("打开界面"); + core.ui._drawSettings(); +}; // ------ 一些事件的具体执行过程 ------ // events.prototype.hasAsync = function () { - return Object.keys(core.animateFrame.asyncId).length > 0; -} + return Object.keys(core.animateFrame.asyncId).length > 0; +}; ////// 立刻停止所有异步事件 ////// events.prototype.stopAsync = function () { - var callbacks = []; - for (var id in core.animateFrame.asyncId) { - clearInterval(id); - callbacks.push(core.animateFrame.asyncId[id]); - } - core.animateFrame.asyncId = {}; - callbacks.forEach(function (cb) { - if (cb && cb instanceof Function) cb(); - }); -} + var callbacks = []; + for (var id in core.animateFrame.asyncId) { + clearInterval(id); + callbacks.push(core.animateFrame.asyncId[id]); + } + core.animateFrame.asyncId = {}; + callbacks.forEach(function (cb) { + if (cb && cb instanceof Function) cb(); + }); +}; events.prototype.hasAsyncAnimate = function () { - return (core.status.animateObjs || []).length > 0; -} + return (core.status.animateObjs || []).length > 0; +}; ////// 跟随 ////// events.prototype.follow = function (name) { - name = core.getMappedName(name); - if (core.material.images.images[name]) { - core.status.hero.followers.push({ "name": name }); - core.gatherFollowers(); - core.clearMap('hero'); - core.drawHero(); - } - core.clearRouteFolding(); -} + name = core.getMappedName(name); + if (core.material.images.images[name]) { + core.status.hero.followers.push({ name: name }); + core.gatherFollowers(); + core.clearMap("hero"); + core.drawHero(); + } + core.clearRouteFolding(); +}; ////// 取消跟随 ////// events.prototype.unfollow = function (name) { - if (!name) { - core.status.hero.followers = []; + if (!name) { + core.status.hero.followers = []; + } else { + name = core.getMappedName(name); + for (var i = 0; i < core.status.hero.followers.length; i++) { + if (core.status.hero.followers[i].name == name) { + core.status.hero.followers.splice(i, 1); + break; + } } - else { - name = core.getMappedName(name); - for (var i = 0; i < core.status.hero.followers.length; i++) { - if (core.status.hero.followers[i].name == name) { - core.status.hero.followers.splice(i, 1); - break; - } - } - } - core.gatherFollowers(); - core.clearMap('hero'); - core.drawHero(); - core.clearRouteFolding(); -} + } + core.gatherFollowers(); + core.clearMap("hero"); + core.drawHero(); + core.clearRouteFolding(); +}; -events.prototype._updateValueByOperator = function (value, originValue, operator) { - switch (operator) { - case '+=': value = originValue + value; break; - case '-=': value = originValue - value; break; - case '*=': value = originValue * value; break; - case '/=': value = originValue / value; break; - case '**=': value = Math.pow(originValue, value); break; - case '//=': value = Math.trunc(originValue / value); break; - case '%=': value = originValue % value; break; - case 'min=': value = Math.min(originValue, value); break; - case 'max=': value = Math.max(originValue, value); break; - default: break; - } - return value; -} +events.prototype._updateValueByOperator = function ( + value, + originValue, + operator +) { + switch (operator) { + case "+=": + value = originValue + value; + break; + case "-=": + value = originValue - value; + break; + case "*=": + value = originValue * value; + break; + case "/=": + value = originValue / value; + break; + case "**=": + value = Math.pow(originValue, value); + break; + case "//=": + value = Math.trunc(originValue / value); + break; + case "%=": + value = originValue % value; + break; + case "min=": + value = Math.min(originValue, value); + break; + case "max=": + value = Math.max(originValue, value); + break; + default: + break; + } + return value; +}; ////// 数值操作 ////// events.prototype.setValue = function (name, operator, value, prefix) { - value = this._updateValueByOperator(core.calValue(value, prefix), core.calValue(name, prefix), operator); - this._setValue_setStatus(name, value); - this._setValue_setBuff(name, value); - this._setValue_setItem(name, value); - this._setValue_setFlag(name, value); - this._setValue_setSwitch(name, value, prefix); - this._setValue_setTemp(name, value, prefix); - this._setValue_setGlobal(name, value); -} + value = this._updateValueByOperator( + core.calValue(value, prefix), + core.calValue(name, prefix), + operator + ); + this._setValue_setStatus(name, value); + this._setValue_setBuff(name, value); + this._setValue_setItem(name, value); + this._setValue_setFlag(name, value); + this._setValue_setSwitch(name, value, prefix); + this._setValue_setTemp(name, value, prefix); + this._setValue_setGlobal(name, value); +}; events.prototype._setValue_setStatus = function (name, value) { - if (name.indexOf("status:") !== 0) return; - core.setStatus(name.substring(7), value); -} + if (name.indexOf("status:") !== 0) return; + core.setStatus(name.substring(7), value); +}; events.prototype._setValue_setBuff = function (name, value) { - if (name.indexOf('buff:') !== 0) return; - core.setBuff(name.substring(5), value); -} + if (name.indexOf("buff:") !== 0) return; + core.setBuff(name.substring(5), value); +}; events.prototype._setValue_setItem = function (name, value) { - if (name.indexOf("item:") !== 0) return; - var itemId = name.substring(5), count = core.itemCount(itemId); - if (value > count) core.getItem(itemId, value - count); - else core.setItem(itemId, value); -} + if (name.indexOf("item:") !== 0) return; + var itemId = name.substring(5), + count = core.itemCount(itemId); + if (value > count) core.getItem(itemId, value - count); + else core.setItem(itemId, value); +}; events.prototype._setValue_setFlag = function (name, value) { - if (name.indexOf("flag:") !== 0) return; - core.setFlag(name.substring(5), value); -} + if (name.indexOf("flag:") !== 0) return; + core.setFlag(name.substring(5), value); +}; events.prototype._setValue_setSwitch = function (name, value, prefix) { - if (name.indexOf("switch:") !== 0) return; - core.setFlag((prefix || ":f@x@y") + "@" + name.substring(7), value); -} + if (name.indexOf("switch:") !== 0) return; + core.setFlag((prefix || ":f@x@y") + "@" + name.substring(7), value); +}; events.prototype._setValue_setTemp = function (name, value) { - if (name.indexOf("temp:") !== 0) return; - core.setFlag("@temp@" + name.substring(5), value); -} + if (name.indexOf("temp:") !== 0) return; + core.setFlag("@temp@" + name.substring(5), value); +}; events.prototype._setValue_setGlobal = function (name, value) { - if (name.indexOf("global:") !== 0) return; - core.setGlobal(name.substring(7), value); -} + if (name.indexOf("global:") !== 0) return; + core.setGlobal(name.substring(7), value); +}; ////// 设置一个怪物属性 ////// -events.prototype.setEnemy = function (id, name, value, operator, prefix, norefresh) { - if (!core.hasFlag('enemyInfo')) { - core.setFlag('enemyInfo', {}); - } - var enemyInfo = core.getFlag('enemyInfo'); - if (!enemyInfo[id]) enemyInfo[id] = {}; - if (typeof value === 'string' && name == 'name') value = value.replace(/\r/g, '\\r'); - value = this._updateValueByOperator(core.calValue(value, prefix), (core.material.enemys[id] || {})[name], operator); - enemyInfo[id][name] = value; - (core.material.enemys[id] || {})[name] = core.clone(value); - if (!norefresh) core.updateStatusBar(); -} +events.prototype.setEnemy = function ( + id, + name, + value, + operator, + prefix, + norefresh +) { + if (!core.hasFlag("enemyInfo")) { + core.setFlag("enemyInfo", {}); + } + var enemyInfo = core.getFlag("enemyInfo"); + if (!enemyInfo[id]) enemyInfo[id] = {}; + if (typeof value === "string" && name == "name") + value = value.replace(/\r/g, "\\r"); + value = this._updateValueByOperator( + core.calValue(value, prefix), + (core.material.enemys[id] || {})[name], + operator + ); + enemyInfo[id][name] = value; + (core.material.enemys[id] || {})[name] = core.clone(value); + if (!norefresh) core.updateStatusBar(); +}; ////// 设置某个点上的怪物属性 ////// -events.prototype.setEnemyOnPoint = function (x, y, floorId, name, value, operator, prefix, norefresh) { - floorId = floorId || core.status.floorId; - var block = core.getBlock(x, y, floorId); - if (block == null) return; - if (block.event.cls.indexOf('enemy') != 0) return; - var enemy = core.material.enemys[block.event.id]; - if (enemy == null) return; - if (typeof value === 'string' && name == 'name') value = value.replaceAll(/\r/g, '\\r'); - value = this._updateValueByOperator(core.calValue(value, prefix), core.getEnemyValue(enemy, name, x, y, floorId), operator); - flags.enemyOnPoint = flags.enemyOnPoint || {}; - flags.enemyOnPoint[floorId] = flags.enemyOnPoint[floorId] || {}; - flags.enemyOnPoint[floorId][x + "," + y] = flags.enemyOnPoint[floorId][x + "," + y] || {}; - flags.enemyOnPoint[floorId][x + "," + y][name] = value; - if (!norefresh) core.updateStatusBar(); -} +events.prototype.setEnemyOnPoint = function ( + x, + y, + floorId, + name, + value, + operator, + prefix, + norefresh +) { + floorId = floorId || core.status.floorId; + var block = core.getBlock(x, y, floorId); + if (block == null) return; + if (block.event.cls.indexOf("enemy") != 0) return; + var enemy = core.material.enemys[block.event.id]; + if (enemy == null) return; + if (typeof value === "string" && name == "name") + value = value.replaceAll(/\r/g, "\\r"); + value = this._updateValueByOperator( + core.calValue(value, prefix), + core.getEnemyValue(enemy, name, x, y, floorId), + operator + ); + flags.enemyOnPoint = flags.enemyOnPoint || {}; + flags.enemyOnPoint[floorId] = flags.enemyOnPoint[floorId] || {}; + flags.enemyOnPoint[floorId][x + "," + y] = + flags.enemyOnPoint[floorId][x + "," + y] || {}; + flags.enemyOnPoint[floorId][x + "," + y][name] = value; + if (!norefresh) core.updateStatusBar(); +}; ////// 重置某个点上的怪物属性 ////// events.prototype.resetEnemyOnPoint = function (x, y, floorId, norefresh) { - delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[x + "," + y]; - if (!norefresh) core.updateStatusBar(); -} + delete ((flags.enemyOnPoint || {})[floorId || core.status.floorId] || {})[ + x + "," + y + ]; + if (!norefresh) core.updateStatusBar(); +}; ////// 将某个点上已经设置的怪物属性移动到其他点 ////// -events.prototype.moveEnemyOnPoint = function (fromX, fromY, toX, toY, floorId, norefresh) { - floorId = floorId || core.status.floorId; - if (((flags.enemyOnPoint || {})[floorId] || {})[fromX + "," + fromY]) { - flags.enemyOnPoint[floorId][toX + "," + toY] = flags.enemyOnPoint[floorId][fromX + "," + fromY]; - delete flags.enemyOnPoint[floorId][fromX + "," + fromY]; - if (!norefresh) core.updateStatusBar(); - } -} +events.prototype.moveEnemyOnPoint = function ( + fromX, + fromY, + toX, + toY, + floorId, + norefresh +) { + floorId = floorId || core.status.floorId; + if (((flags.enemyOnPoint || {})[floorId] || {})[fromX + "," + fromY]) { + flags.enemyOnPoint[floorId][toX + "," + toY] = + flags.enemyOnPoint[floorId][fromX + "," + fromY]; + delete flags.enemyOnPoint[floorId][fromX + "," + fromY]; + if (!norefresh) core.updateStatusBar(); + } +}; ////// 设置楼层属性 ////// events.prototype.setFloorInfo = function (name, value, floorId, prefix) { - floorId = floorId || core.status.floorId; - core.status.maps[floorId][name] = value; - core.updateStatusBar(); -} + floorId = floorId || core.status.floorId; + core.status.maps[floorId][name] = value; + core.updateStatusBar(); +}; ////// 设置全塔属性 ////// events.prototype.setGlobalAttribute = function (name, value) { - if (typeof value == 'string') { - if ((value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') - || (value.charAt(0) == "'" && value.charAt(value.length - 1) == "'")) - value = value.substring(1, value.length - 1); - // --- 检查 [] - if (value.charAt(0) == '[' && value.charAt(value.length - 1) == ']') - value = eval(value); - // --- 检查颜色 - if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) { - value = 'rgba(' + value + ')'; - } + if (typeof value == "string") { + if ( + (value.charAt(0) == '"' && value.charAt(value.length - 1) == '"') || + (value.charAt(0) == "'" && value.charAt(value.length - 1) == "'") + ) + value = value.substring(1, value.length - 1); + // --- 检查 [] + if (value.charAt(0) == "[" && value.charAt(value.length - 1) == "]") + value = eval(value); + // --- 检查颜色 + if (/^[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?$/.test(value)) { + value = "rgba(" + value + ")"; } - core.status.globalAttribute[name] = value; - core.setFlag('globalAttribute', core.status.globalAttribute); - core.resize(); -} + } + core.status.globalAttribute[name] = value; + core.setFlag("globalAttribute", core.status.globalAttribute); + core.resize(); +}; ////// 设置全局开关 ////// events.prototype.setGlobalFlag = function (name, value) { - var flags = core.getFlag("globalFlags", {}); - if (name.startsWith('s:')) { - name = name.substring(2); - var statusBarItems = core.flags.statusBarItems.filter(function (v) { return v != name; }); - if (value) statusBarItems.push(name); - core.flags.statusBarItems = statusBarItems; - flags.statusBarItems = core.clone(statusBarItems); - } else { - flags[name] = core.flags[name] = value; - } - core.setFlag("globalFlags", flags); - core.resize(); - if (name == 'blurFg') - core.redrawMap(); -} + var flags = core.getFlag("globalFlags", {}); + if (name.startsWith("s:")) { + name = name.substring(2); + var statusBarItems = core.flags.statusBarItems.filter(function (v) { + return v != name; + }); + if (value) statusBarItems.push(name); + core.flags.statusBarItems = statusBarItems; + flags.statusBarItems = core.clone(statusBarItems); + } else { + flags[name] = core.flags[name] = value; + } + core.setFlag("globalFlags", flags); + core.resize(); + if (name == "blurFg") core.redrawMap(); +}; ////// 设置文件别名 ////// events.prototype.setNameMap = function (name, value) { - if (!core.hasFlag('__nameMap__')) core.setFlag('__nameMap__', {}); - flags.__nameMap__[name] = value; -} + if (!core.hasFlag("__nameMap__")) core.setFlag("__nameMap__", {}); + flags.__nameMap__[name] = value; +}; ////// 设置剧情文本的属性 ////// events.prototype.setTextAttribute = function (data) { - if (!core.isPlaying()) return; - ["position", "offset", "align", "bold", "titlefont", "textfont", "lineHeight", "time", "letterSpacing", "animateTime"].forEach(function (t) { - if (data[t] != null) core.status.textAttribute[t] = data[t]; - }); - ["background", "title", "text"].forEach(function (t) { - if ((data[t] instanceof Array) && data[t].length >= 3) { - if (data[t].length == 3) data[t].push(1); - core.status.textAttribute[t] = data[t]; - } - if (t == 'background') { - var name = core.getMappedName(data[t]); - var img = core.material.images.images[name]; - if (img && img.width == 192 && img.height == 128) { - core.status.textAttribute[t] = name; - } - } - }); - if (main.mode == 'play') core.setFlag('textAttribute', core.status.textAttribute); -} - -events.prototype.moveTextBox = function (code, loc, relative, moveMode, time, callback) { - var ctx = core.getContextByName('__text__' + code); - if (!ctx) { - if (callback) callback(); - return; + if (!core.isPlaying()) return; + [ + "position", + "offset", + "align", + "bold", + "titlefont", + "textfont", + "lineHeight", + "time", + "letterSpacing", + "animateTime", + ].forEach(function (t) { + if (data[t] != null) core.status.textAttribute[t] = data[t]; + }); + ["background", "title", "text"].forEach(function (t) { + if (data[t] instanceof Array && data[t].length >= 3) { + if (data[t].length == 3) data[t].push(1); + core.status.textAttribute[t] = data[t]; } - var sx = parseInt(ctx.canvas.getAttribute('_text_left')) || 0; - var sy = parseInt(ctx.canvas.getAttribute('_text_top')) || 0; - var dx = relative ? loc[0] : (loc[0] - sx); - var dy = relative ? loc[1] : (loc[1] - sy); - var ox = parseInt(ctx.canvas.getAttribute('_left')) || 0; - var oy = parseInt(ctx.canvas.getAttribute('_top')) || 0; - - if (!time) { - core.relocateCanvas(ctx, ox + dx, oy + dy); - ctx.canvas.setAttribute('_text_left', loc[0]); - ctx.canvas.setAttribute('_text_top', loc[1]); - if (callback) callback(); - return; + if (t == "background") { + var name = core.getMappedName(data[t]); + var img = core.material.images.images[name]; + if (img && img.width == 192 && img.height == 128) { + core.status.textAttribute[t] = name; + } } + }); + if (main.mode == "play") + core.setFlag("textAttribute", core.status.textAttribute); +}; - var moveInfo = { - sx: sx, sy: sy, dx: dx, dy: dy, ox: ox, oy: oy, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) - }; - this._moveTextBox_moving(ctx, moveInfo, callback); -} +events.prototype.moveTextBox = function ( + code, + loc, + relative, + moveMode, + time, + callback +) { + var ctx = core.getContextByName("__text__" + code); + if (!ctx) { + if (callback) callback(); + return; + } + var sx = parseInt(ctx.canvas.getAttribute("_text_left")) || 0; + var sy = parseInt(ctx.canvas.getAttribute("_text_top")) || 0; + var dx = relative ? loc[0] : loc[0] - sx; + var dy = relative ? loc[1] : loc[1] - sy; + var ox = parseInt(ctx.canvas.getAttribute("_left")) || 0; + var oy = parseInt(ctx.canvas.getAttribute("_top")) || 0; + + if (!time) { + core.relocateCanvas(ctx, ox + dx, oy + dy); + ctx.canvas.setAttribute("_text_left", loc[0]); + ctx.canvas.setAttribute("_text_top", loc[1]); + if (callback) callback(); + return; + } + + var moveInfo = { + sx: sx, + sy: sy, + dx: dx, + dy: dy, + ox: ox, + oy: oy, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1), + }; + this._moveTextBox_moving(ctx, moveInfo, callback); +}; events.prototype._moveTextBox_moving = function (ctx, moveInfo, callback) { - var step = 0, steps = moveInfo.time / 10; - if (steps <= 0) steps = 1; - var moveFunc = core.applyEasing(moveInfo.moveMode); - var animate = setInterval(function () { - step++; - var dx = moveInfo.dx * moveFunc(step / steps); - var dy = moveInfo.dy * moveFunc(step / steps); - core.relocateCanvas(ctx, parseInt(moveInfo.ox + dx), parseInt(moveInfo.oy + dy)); - ctx.canvas.setAttribute('_text_left', moveInfo.sx + dx); - ctx.canvas.setAttribute('_text_top', moveInfo.sy + dy); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, 10); + var step = 0, + steps = moveInfo.time / 10; + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(moveInfo.moveMode); + var animate = setInterval(function () { + step++; + var dx = moveInfo.dx * moveFunc(step / steps); + var dy = moveInfo.dy * moveFunc(step / steps); + core.relocateCanvas( + ctx, + parseInt(moveInfo.ox + dx), + parseInt(moveInfo.oy + dy) + ); + ctx.canvas.setAttribute("_text_left", moveInfo.sx + dx); + ctx.canvas.setAttribute("_text_top", moveInfo.sy + dy); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, 10); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 清除对话框 ////// events.prototype.clearTextBox = function (code, callback) { - if (code == null) { - code = Object.keys(core.dymCanvas).filter(function (one) { return one.startsWith('__text__') }) - .map(function (one) { return one.substring('__text__'.length); }) - } + if (code == null) { + code = Object.keys(core.dymCanvas) + .filter(function (one) { + return one.startsWith("__text__"); + }) + .map(function (one) { + return one.substring("__text__".length); + }); + } - if (!(code instanceof Array)) code = [code]; - var index = 0; - var _work = function () { - if (index == code.length) { - if (callback) callback(); - return; - } - var ctx = '__text__' + code[index++]; - if (!core.getContextByName(ctx)) return _work(); - core.ui._animateUI('hide', ctx, function () { - core.deleteCanvas(ctx); - _work(); - }); - }; - _work(); -} + if (!(code instanceof Array)) code = [code]; + var index = 0; + var _work = function () { + if (index == code.length) { + if (callback) callback(); + return; + } + var ctx = "__text__" + code[index++]; + if (!core.getContextByName(ctx)) return _work(); + core.ui._animateUI("hide", ctx, function () { + core.deleteCanvas(ctx); + _work(); + }); + }; + _work(); +}; ////// 关门 ////// events.prototype.closeDoor = function (x, y, id, callback) { - id = id || ""; - if ((core.material.icons.animates[id] == null && core.material.icons.npc48[id] == null) - || core.getBlock(x, y) != null) { - if (callback) callback(); + id = id || ""; + if ( + (core.material.icons.animates[id] == null && + core.material.icons.npc48[id] == null) || + core.getBlock(x, y) != null + ) { + if (callback) callback(); + return; + } + var block = core.getBlockById(id); + var doorInfo = (block.event || {}).doorInfo; + if (!doorInfo) { + if (callback) callback(); + return; + } + + core.playSound(doorInfo.closeSound); + var blockInfo = core.getBlockInfo(block); + var speed = (doorInfo.time || 160) / 4; + blockInfo.posX = 3; + core.maps._drawBlockInfo(blockInfo, x, y); + + var cb = function () { + core.setBlock(id, x, y); + core.showBlock(x, y); + if (callback) callback(); + }; + + var animate = window.setInterval( + function () { + blockInfo.posX--; + if (blockInfo.posX < 0) { + clearInterval(animate); + delete core.animateFrame.asyncId[animate]; + cb(); return; - } - var block = core.getBlockById(id); - var doorInfo = (block.event || {}).doorInfo; - if (!doorInfo) { - if (callback) callback(); - return; - } + } + core.maps._drawBlockInfo(blockInfo, x, y); + }, + core.status.replay.speed == 24 + ? 1 + : speed / Math.max(core.status.replay.speed, 1) + ); - core.playSound(doorInfo.closeSound); - var blockInfo = core.getBlockInfo(block); - var speed = (doorInfo.time || 160) / 4; - blockInfo.posX = 3; - core.maps._drawBlockInfo(blockInfo, x, y); - - var cb = function () { - core.setBlock(id, x, y); - core.showBlock(x, y); - if (callback) callback(); - } - - var animate = window.setInterval(function () { - blockInfo.posX--; - if (blockInfo.posX < 0) { - clearInterval(animate); - delete core.animateFrame.asyncId[animate]; - cb(); - return; - } - core.maps._drawBlockInfo(blockInfo, x, y); - }, core.status.replay.speed == 24 ? 1 : speed / Math.max(core.status.replay.speed, 1)); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; ////// 显示图片 ////// -events.prototype.showImage = function (code, image, sloc, loc, opacityVal, time, callback) { - var imageName = null; - if (typeof image == 'string') { - imageName = image; - if (image.endsWith(':x') || image.endsWith(':y') || image.endsWith(':o')) { - image = image.substring(0, image.length - 2); - } - image = core.getMappedName(image); - image = core.material.images.images[image]; +events.prototype.showImage = function ( + code, + image, + sloc, + loc, + opacityVal, + time, + callback +) { + var imageName = null; + if (typeof image == "string") { + imageName = image; + if (image.endsWith(":x") || image.endsWith(":y") || image.endsWith(":o")) { + image = image.substring(0, image.length - 2); } - if (!image) { - if (callback) callback(); - return; - } - sloc = sloc || []; - var sx = core.calValue(sloc[0]) || 0, sy = core.calValue(sloc[1]) || 0; - var sw = core.calValue(sloc[2]), sh = core.calValue(sloc[3]); - if (sw == null) sw = image.width; - if (sh == null) sh = image.height; - loc = loc || []; - var x = core.calValue(loc[0]) || 0, y = core.calValue(loc[1]) || 0; - var w = core.calValue(loc[2]), h = core.calValue(loc[3]); - if (w == null) w = sw; - if (h == null) h = sh; - var zIndex = code + 100; - time = time || 0; - var name = "image" + zIndex; - var ctx = core.createCanvas(name, x, y, w, h, zIndex); - core.drawImage(ctx, imageName == null ? image : imageName, sx, sy, sw, sh, 0, 0, w, h); - if (time == 0) { - core.setOpacity(name, opacityVal); - if (callback) callback(); - return; - } - core.setOpacity(name, 0); - this.moveImage(code, null, opacityVal, null, time, callback); -} + image = core.getMappedName(image); + image = core.material.images.images[image]; + } + if (!image) { + if (callback) callback(); + return; + } + sloc = sloc || []; + var sx = core.calValue(sloc[0]) || 0, + sy = core.calValue(sloc[1]) || 0; + var sw = core.calValue(sloc[2]), + sh = core.calValue(sloc[3]); + if (sw == null) sw = image.width; + if (sh == null) sh = image.height; + loc = loc || []; + var x = core.calValue(loc[0]) || 0, + y = core.calValue(loc[1]) || 0; + var w = core.calValue(loc[2]), + h = core.calValue(loc[3]); + if (w == null) w = sw; + if (h == null) h = sh; + var zIndex = code + 100; + time = time || 0; + var name = "image" + zIndex; + var ctx = core.createCanvas(name, x, y, w, h, zIndex); + core.drawImage( + ctx, + imageName == null ? image : imageName, + sx, + sy, + sw, + sh, + 0, + 0, + w, + h + ); + if (time == 0) { + core.setOpacity(name, opacityVal); + if (callback) callback(); + return; + } + core.setOpacity(name, 0); + this.moveImage(code, null, opacityVal, null, time, callback); +}; ////// 隐藏图片 ////// events.prototype.hideImage = function (code, time, callback) { - time = time || 0; - var name = "image" + (code + 100); - if (time == 0 || !core.dymCanvas[name]) { - core.deleteCanvas(name); - if (callback) callback(); - return; - } - this.moveImage(code, null, 0, null, time, function () { - core.deleteCanvas(name); - if (callback) callback(); - }); -} + time = time || 0; + var name = "image" + (code + 100); + if (time == 0 || !core.dymCanvas[name]) { + core.deleteCanvas(name); + if (callback) callback(); + return; + } + this.moveImage(code, null, 0, null, time, function () { + core.deleteCanvas(name); + if (callback) callback(); + }); +}; ////// 移动图片 ////// -events.prototype.moveImage = function (code, to, opacityVal, moveMode, time, callback) { - to = to || []; - var name = "image" + (code + 100); - if (!core.dymCanvas[name]) { - if (callback) callback(); - return; - } - var getOrDefault = function (a, b) { - a = core.calValue(a); - return a != null ? a : b; - } - var canvas = core.dymCanvas[name].canvas; - var fromX = parseFloat(canvas.getAttribute("_left")), - fromY = parseFloat(canvas.getAttribute("_top")), - toX = getOrDefault(to[0], fromX), toY = getOrDefault(to[1], fromY); +events.prototype.moveImage = function ( + code, + to, + opacityVal, + moveMode, + time, + callback +) { + to = to || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + var getOrDefault = function (a, b) { + a = core.calValue(a); + return a != null ? a : b; + }; + var canvas = core.dymCanvas[name].canvas; + var fromX = parseFloat(canvas.getAttribute("_left")), + fromY = parseFloat(canvas.getAttribute("_top")), + toX = getOrDefault(to[0], fromX), + toY = getOrDefault(to[1], fromY); - var opacity = parseFloat(canvas.style.opacity), toOpacity = getOrDefault(opacityVal, opacity); + var opacity = parseFloat(canvas.style.opacity), + toOpacity = getOrDefault(opacityVal, opacity); - if (!time) { - core.relocateCanvas(name, toX, toY); - core.setOpacity(toOpacity); - if (callback) callback(); - return; - } + if (!time) { + core.relocateCanvas(name, toX, toY); + core.setOpacity(toOpacity); + if (callback) callback(); + return; + } - this._moveImage_moving(name, { - fromX: fromX, fromY: fromY, toX: toX, toY: toY, opacity: opacity, toOpacity: toOpacity, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) - }, callback) -} + this._moveImage_moving( + name, + { + fromX: fromX, + fromY: fromY, + toX: toX, + toY: toY, + opacity: opacity, + toOpacity: toOpacity, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1), + }, + callback + ); +}; events.prototype._moveImage_moving = function (name, moveInfo, callback) { - var per_time = 10, step = 0, steps = parseInt(moveInfo.time / per_time); - if (steps <= 0) steps = 1; - var fromX = moveInfo.fromX, fromY = moveInfo.fromY, toX = moveInfo.toX, toY = moveInfo.toY, - opacity = moveInfo.opacity, toOpacity = moveInfo.toOpacity; - var currX = fromX, currY = fromY, currOpacity = opacity; - var moveFunc = core.applyEasing(moveInfo.moveMode); - var animate = setInterval(function () { - step++; - currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps); - currX = parseInt(fromX + (toX - fromX) * moveFunc(step / steps)); - currY = parseInt(fromY + (toY - fromY) * moveFunc(step / steps)); - core.setOpacity(name, currOpacity); - core.relocateCanvas(name, currX, currY); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); + var per_time = 10, + step = 0, + steps = parseInt(moveInfo.time / per_time); + if (steps <= 0) steps = 1; + var fromX = moveInfo.fromX, + fromY = moveInfo.fromY, + toX = moveInfo.toX, + toY = moveInfo.toY, + opacity = moveInfo.opacity, + toOpacity = moveInfo.toOpacity; + var currX = fromX, + currY = fromY, + currOpacity = opacity; + var moveFunc = core.applyEasing(moveInfo.moveMode); + var animate = setInterval(function () { + step++; + currOpacity = opacity + (toOpacity - opacity) * moveFunc(step / steps); + currX = parseInt(fromX + (toX - fromX) * moveFunc(step / steps)); + currY = parseInt(fromY + (toY - fromY) * moveFunc(step / steps)); + core.setOpacity(name, currOpacity); + core.relocateCanvas(name, currX, currY); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 旋转图片 ////// -events.prototype.rotateImage = function (code, center, angle, moveMode, time, callback) { - center = center || []; - var name = "image" + (code + 100); - if (!core.dymCanvas[name]) { - if (callback) callback(); - return; - } - var canvas = core.dymCanvas[name].canvas; - var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]); +events.prototype.rotateImage = function ( + code, + center, + angle, + moveMode, + time, + callback +) { + center = center || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + var canvas = core.dymCanvas[name].canvas; + var centerX = core.calValue(center[0]), + centerY = core.calValue(center[1]); - var fromAngle = parseFloat(canvas.getAttribute('_angle')) || 0; + var fromAngle = parseFloat(canvas.getAttribute("_angle")) || 0; - if (!time) { - core.rotateCanvas(name, fromAngle + angle, centerX, centerY); - if (callback) callback(); - return; - } + if (!time) { + core.rotateCanvas(name, fromAngle + angle, centerX, centerY); + if (callback) callback(); + return; + } - var rotateInfo = { - fromAngle: fromAngle, angle: angle, centerX: centerX, centerY: centerY, - moveMode: moveMode, time: time / Math.max(core.status.replay.speed, 1) - } - this._rotateImage_rotating(name, rotateInfo, callback); -} + var rotateInfo = { + fromAngle: fromAngle, + angle: angle, + centerX: centerX, + centerY: centerY, + moveMode: moveMode, + time: time / Math.max(core.status.replay.speed, 1), + }; + this._rotateImage_rotating(name, rotateInfo, callback); +}; events.prototype._rotateImage_rotating = function (name, rotateInfo, callback) { - var per_time = 10, step = 0, steps = parseInt(rotateInfo.time / per_time); - if (steps <= 0) steps = 1; - var moveFunc = core.applyEasing(rotateInfo.moveMode); - var animate = setInterval(function () { - step++; - var currAngle = rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps); - core.rotateCanvas(name, currAngle, rotateInfo.centerX, rotateInfo.centerY); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); + var per_time = 10, + step = 0, + steps = parseInt(rotateInfo.time / per_time); + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(rotateInfo.moveMode); + var animate = setInterval(function () { + step++; + var currAngle = + rotateInfo.fromAngle + rotateInfo.angle * moveFunc(step / steps); + core.rotateCanvas(name, currAngle, rotateInfo.centerX, rotateInfo.centerY); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 放缩一张图片 ////// -events.prototype.scaleImage = function (code, center, scale, moveMode, time, callback) { - center = center || []; - var name = "image" + (code + 100); - if (!core.dymCanvas[name]) { - if (callback) callback(); - return; - } - var ctx = core.dymCanvas[name]; - var currScale = 1.0; - if (ctx.canvas.hasAttribute('_scale')) { - currScale = parseFloat(ctx.canvas.getAttribute('_scale')); - } - var ratio = ctx.canvas.hasAttribute('isHD') ? core.domStyle.ratio : 1; - var width = ctx.canvas.width / ratio, height = ctx.canvas.height / ratio; - var currLeft = parseFloat(ctx.canvas.getAttribute("_left")); - var currTop = parseFloat(ctx.canvas.getAttribute("_top")); - var centerX = core.calValue(center[0]), centerY = core.calValue(center[1]); - if (centerX == null || centerY == null) { - centerX = currLeft + width * currScale / 2; - centerY = currTop + height * currScale / 2; - } - var scaleInfo = { - x: (currLeft - centerX) / currScale, y: (currTop - centerY) / currScale, centerX: centerX, centerY: centerY, - width: width, height: height, currScale: currScale, scale: scale, moveMode: moveMode, time: time - } - this._scaleImage_scale(ctx, scaleInfo, callback); -} +events.prototype.scaleImage = function ( + code, + center, + scale, + moveMode, + time, + callback +) { + center = center || []; + var name = "image" + (code + 100); + if (!core.dymCanvas[name]) { + if (callback) callback(); + return; + } + var ctx = core.dymCanvas[name]; + var currScale = 1.0; + if (ctx.canvas.hasAttribute("_scale")) { + currScale = parseFloat(ctx.canvas.getAttribute("_scale")); + } + var ratio = ctx.canvas.hasAttribute("isHD") ? core.domStyle.ratio : 1; + var width = ctx.canvas.width / ratio, + height = ctx.canvas.height / ratio; + var currLeft = parseFloat(ctx.canvas.getAttribute("_left")); + var currTop = parseFloat(ctx.canvas.getAttribute("_top")); + var centerX = core.calValue(center[0]), + centerY = core.calValue(center[1]); + if (centerX == null || centerY == null) { + centerX = currLeft + (width * currScale) / 2; + centerY = currTop + (height * currScale) / 2; + } + var scaleInfo = { + x: (currLeft - centerX) / currScale, + y: (currTop - centerY) / currScale, + centerX: centerX, + centerY: centerY, + width: width, + height: height, + currScale: currScale, + scale: scale, + moveMode: moveMode, + time: time, + }; + this._scaleImage_scale(ctx, scaleInfo, callback); +}; events.prototype._scaleInfo_scale = function (ctx, scaleInfo, scale) { - core.resizeCanvas(ctx, scaleInfo.width * scale, scaleInfo.height * scale, true); - core.relocateCanvas(ctx, scaleInfo.centerX + scaleInfo.x * scale, scaleInfo.centerY + scaleInfo.y * scale); - ctx.canvas.setAttribute('_scale', scale); -} + core.resizeCanvas( + ctx, + scaleInfo.width * scale, + scaleInfo.height * scale, + true + ); + core.relocateCanvas( + ctx, + scaleInfo.centerX + scaleInfo.x * scale, + scaleInfo.centerY + scaleInfo.y * scale + ); + ctx.canvas.setAttribute("_scale", scale); +}; events.prototype._scaleImage_scale = function (ctx, scaleInfo, callback) { - if (!scaleInfo.time) { - this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale); - if (callback) callback(); - return; + if (!scaleInfo.time) { + this._scaleInfo_scale(ctx, scaleInfo, scaleInfo.scale); + if (callback) callback(); + return; + } + + var per_time = 10, + step = 0, + steps = parseInt(scaleInfo.time / per_time); + if (steps <= 0) steps = 1; + var moveFunc = core.applyEasing(scaleInfo.moveMode); + + var animate = setInterval(function () { + step++; + var scale = + scaleInfo.currScale + + (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps); + core.events._scaleInfo_scale(ctx, scaleInfo, scale); + if (step == steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } + }, per_time); - var per_time = 10, step = 0, steps = parseInt(scaleInfo.time / per_time); - if (steps <= 0) steps = 1; - var moveFunc = core.applyEasing(scaleInfo.moveMode); - - var animate = setInterval(function () { - step++; - var scale = scaleInfo.currScale + (scaleInfo.scale - scaleInfo.currScale) * moveFunc(step / steps); - core.events._scaleInfo_scale(ctx, scaleInfo, scale); - if (step == steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 绘制或取消一张gif图片 ////// events.prototype.showGif = function (name, x, y) { - name = core.getMappedName(name); - var image = core.material.images.images[name]; - if (image) { - var gif = new Image(); - gif.src = image.src; - gif.style.position = 'absolute'; - gif.style.left = x * core.domStyle.scale + "px"; - gif.style.top = y * core.domStyle.scale + "px"; - gif.style.width = image.width * core.domStyle.scale + "px"; - gif.style.height = image.height * core.domStyle.scale + "px"; - core.dom.gif2.appendChild(gif); - } - else { - core.dom.gif2.innerHTML = ""; - } -} + name = core.getMappedName(name); + var image = core.material.images.images[name]; + if (image) { + var gif = new Image(); + gif.src = image.src; + gif.style.position = "absolute"; + gif.style.left = x * core.domStyle.scale + "px"; + gif.style.top = y * core.domStyle.scale + "px"; + gif.style.width = image.width * core.domStyle.scale + "px"; + gif.style.height = image.height * core.domStyle.scale + "px"; + core.dom.gif2.appendChild(gif); + } else { + core.dom.gif2.innerHTML = ""; + } +}; ////// 淡入淡出音乐 ////// events.prototype.setVolume = function (value, time, callback) { - var set = function (value) { - core.musicStatus.designVolume = value; - if (core.musicStatus.playingBgm) - core.material.bgms[core.musicStatus.playingBgm].volume = core.musicStatus.userVolume * core.musicStatus.designVolume; + var set = function (value) { + core.musicStatus.designVolume = value; + if (core.musicStatus.playingBgm) + core.material.bgms[core.musicStatus.playingBgm].volume = + core.musicStatus.userVolume * core.musicStatus.designVolume; + }; + if (!time || time < 100) { + set(value); + if (callback) callback(); + return; + } + var currVolume = core.musicStatus.designVolume; + time /= Math.max(core.status.replay.speed, 1); + var per_time = 10, + step = 0, + steps = parseInt(time / per_time); + if (steps <= 0) steps = 1; + var animate = setInterval(function () { + step++; + set(currVolume + ((value - currVolume) * step) / steps); + if (step >= steps) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); } - if (!time || time < 100) { - set(value); - if (callback) callback(); - return; - } - var currVolume = core.musicStatus.designVolume; - time /= Math.max(core.status.replay.speed, 1); - var per_time = 10, step = 0, steps = parseInt(time / per_time); - if (steps <= 0) steps = 1; - var animate = setInterval(function () { - step++; - set(currVolume + (value - currVolume) * step / steps); - if (step >= steps) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - if (callback) callback(); - } - }, per_time); + }, per_time); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = callback; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = callback; +}; ////// 画面震动 ////// events.prototype.vibrate = function (direction, time, speed, power, callback) { - if (core.isReplaying()) { - if (callback) callback(); - return; + if (core.isReplaying()) { + if (callback) callback(); + return; + } + if (!time) time = 1000; + speed = speed || 10; + power = power || 10; + var shakeInfo = { + duration: parseInt(time / 10), + speed: speed, + power: power, + direction: 1, + shake: 0, + }; + if (direction == "random") { + direction = ["horizontal", "vertical", "diagonal1", "diagonal2"][ + Math.floor(Math.random() * 4) + ]; + } + var cb = function () { + core.addGameCanvasTranslate(0, 0); + if (callback) callback(); + }; + var animate = setInterval(function () { + core.events._vibrate_update(shakeInfo); + switch (direction) { + case "vertical": + core.addGameCanvasTranslate(0, shakeInfo.shake); + break; + case "diagonal1": + core.addGameCanvasTranslate(shakeInfo.shake, shakeInfo.shake); + break; + case "diagonal2": + core.addGameCanvasTranslate(-shakeInfo.shake, shakeInfo.shake); + break; + default: + core.addGameCanvasTranslate(shakeInfo.shake, 0); } - if (!time) time = 1000; - speed = speed || 10; - power = power || 10; - var shakeInfo = { duration: parseInt(time / 10), speed: speed, power: power, direction: 1, shake: 0 }; - if (direction == 'random') { - direction = ['horizontal', 'vertical', 'diagonal1', 'diagonal2'][Math.floor(Math.random() * 4)]; + if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); } - var cb = function () { - core.addGameCanvasTranslate(0, 0); - if (callback) callback(); - } - var animate = setInterval(function () { - core.events._vibrate_update(shakeInfo); - switch (direction) { - case 'vertical': core.addGameCanvasTranslate(0, shakeInfo.shake); break; - case 'diagonal1': core.addGameCanvasTranslate(shakeInfo.shake, shakeInfo.shake); break; - case 'diagonal2': core.addGameCanvasTranslate(-shakeInfo.shake, shakeInfo.shake); break; - default: core.addGameCanvasTranslate(shakeInfo.shake, 0); - } - if (shakeInfo.duration === 0 && shakeInfo.shake == 0) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - }, 10); + }, 10); - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; -} + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; events.prototype._vibrate_update = function (shakeInfo) { - if (shakeInfo.duration >= 1 || shakeInfo.shake != 0) { - var delta = shakeInfo.speed * shakeInfo.direction / 6; - if (shakeInfo.duration <= 1 && shakeInfo.shake * (shakeInfo.shake + delta) < 0) { - shakeInfo.shake = 0; - } else { - shakeInfo.shake += delta; - } - if (shakeInfo.shake > shakeInfo.power) { - shakeInfo.direction = -1; - } - if (shakeInfo.shake < -shakeInfo.power) { - shakeInfo.direction = 1; - } - if (shakeInfo.duration >= 1) { - shakeInfo.duration -= 1 - } + if (shakeInfo.duration >= 1 || shakeInfo.shake != 0) { + var delta = (shakeInfo.speed * shakeInfo.direction) / 6; + if ( + shakeInfo.duration <= 1 && + shakeInfo.shake * (shakeInfo.shake + delta) < 0 + ) { + shakeInfo.shake = 0; + } else { + shakeInfo.shake += delta; } -} + if (shakeInfo.shake > shakeInfo.power) { + shakeInfo.direction = -1; + } + if (shakeInfo.shake < -shakeInfo.power) { + shakeInfo.direction = 1; + } + if (shakeInfo.duration >= 1) { + shakeInfo.duration -= 1; + } + } +}; /////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// events.prototype.eventMoveHero = function (steps, time, callback) { - time = time || core.values.moveSpeed; - var step = 0, moveSteps = (steps || []).map(function (t) { - return [t.split(':')[0], parseInt(t.split(':')[1] || "1")]; - }).filter(function (t) { - return ['up', 'down', 'left', 'right', 'forward', 'backward', 'leftup', 'leftdown', 'rightup', 'rightdown', 'speed'].indexOf(t[0]) >= 0 - && !(t[0] == 'speed' && t[1] < 16); - }); - core.status.heroMoving = -1; - var _run = function () { - var cb = function () { - core.status.heroMoving = 0; - core.drawHero(); - if (callback) callback(); - } - - var animate = window.setInterval(function () { - if (moveSteps.length == 0) { - delete core.animateFrame.asyncId[animate]; - clearInterval(animate); - cb(); - } - else { - if (step == 0 && moveSteps[0][0] == 'speed' && moveSteps[0][1] >= 16) { - time = moveSteps[0][1]; - moveSteps.shift(); - clearInterval(animate); - delete core.animateFrame.asyncId[animate]; - _run(); - } - else if (core.events._eventMoveHero_moving(++step, moveSteps)) - step = 0; - } - }, core.status.replay.speed == 24 ? 1 : time / 8 / core.status.replay.speed); - - core.animateFrame.lastAsyncId = animate; - core.animateFrame.asyncId[animate] = cb; - } - _run(); -} - -events.prototype._eventMoveHero_moving = function (step, moveSteps) { - var curr = moveSteps[0]; - var direction = curr[0], x = core.getHeroLoc('x'), y = core.getHeroLoc('y'); - // ------ 前进/后退 - var o = direction == 'backward' ? -1 : 1; - if (direction == 'forward' || direction == 'backward') direction = core.getHeroLoc('direction'); - var faceDirection = direction; - if (direction == 'leftup' || direction == 'leftdown') faceDirection = 'left'; - if (direction == 'rightup' || direction == 'rightdown') faceDirection = 'right'; - core.setHeroLoc('direction', direction); - if (curr[1] <= 0) { - core.setHeroLoc('direction', faceDirection); - moveSteps.shift(); - return true; - } - if (step <= 4) { - core.drawHero('leftFoot', 4 * o * step); - } - else if (step <= 8) { - core.drawHero('rightFoot', 4 * o * step); - } - if (step == 8) { - core.setHeroLoc('x', x + o * core.utils.scan2[direction].x, true); - core.setHeroLoc('y', y + o * core.utils.scan2[direction].y, true); - core.updateFollowers(); - curr[1]--; - if (curr[1] <= 0) moveSteps.shift(); - core.setHeroLoc('direction', faceDirection); - return true; - } - return false; -} - -////// 勇士跳跃事件 ////// -events.prototype.jumpHero = function (ex, ey, time, callback) { - var sx = core.getHeroLoc('x'), sy = core.getHeroLoc('y'); - if (ex == null) ex = sx; - if (ey == null) ey = sy; - var sx = core.status.hero.loc.x, sy = core.status.hero.loc.y; - if (!core.isset(ex)) ex = sx; - if (!core.isset(ey)) ey = sy; - var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); - jumpInfo.icon = core.material.icons.hero[core.getHeroLoc('direction')]; - jumpInfo.width = core.material.icons.hero.width || 32; - jumpInfo.height = core.material.icons.hero.height; - - this._jumpHero_doJump(jumpInfo, callback); -} - -events.prototype._jumpHero_doJump = function (jumpInfo, callback) { + time = time || core.values.moveSpeed; + var step = 0, + moveSteps = (steps || []) + .map(function (t) { + return [t.split(":")[0], parseInt(t.split(":")[1] || "1")]; + }) + .filter(function (t) { + return ( + [ + "up", + "down", + "left", + "right", + "forward", + "backward", + "leftup", + "leftdown", + "rightup", + "rightdown", + "speed", + ].indexOf(t[0]) >= 0 && !(t[0] == "speed" && t[1] < 16) + ); + }); + core.status.heroMoving = -1; + var _run = function () { var cb = function () { - core.setHeroLoc('x', jumpInfo.ex); - core.setHeroLoc('y', jumpInfo.ey); - core.status.heroMoving = 0; - core.drawHero(); - if (callback) callback(); - } + core.status.heroMoving = 0; + core.drawHero(); + if (callback) callback(); + }; - core.status.heroMoving = -1; - var animate = window.setInterval(function () { - if (jumpInfo.jump_count > 0) - core.events._jumpHero_jumping(jumpInfo) - else { - delete core.animateFrame.asyncId[animate]; + var animate = window.setInterval( + function () { + if (moveSteps.length == 0) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); + } else { + if ( + step == 0 && + moveSteps[0][0] == "speed" && + moveSteps[0][1] >= 16 + ) { + time = moveSteps[0][1]; + moveSteps.shift(); clearInterval(animate); - cb(); + delete core.animateFrame.asyncId[animate]; + _run(); + } else if (core.events._eventMoveHero_moving(++step, moveSteps)) + step = 0; } - }, jumpInfo.per_time); + }, + core.status.replay.speed == 24 ? 1 : time / 8 / core.status.replay.speed + ); core.animateFrame.lastAsyncId = animate; core.animateFrame.asyncId[animate] = cb; -} + }; + _run(); +}; + +events.prototype._eventMoveHero_moving = function (step, moveSteps) { + var curr = moveSteps[0]; + var direction = curr[0], + x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"); + // ------ 前进/后退 + var o = direction == "backward" ? -1 : 1; + if (direction == "forward" || direction == "backward") + direction = core.getHeroLoc("direction"); + var faceDirection = direction; + if (direction == "leftup" || direction == "leftdown") faceDirection = "left"; + if (direction == "rightup" || direction == "rightdown") + faceDirection = "right"; + core.setHeroLoc("direction", direction); + if (curr[1] <= 0) { + core.setHeroLoc("direction", faceDirection); + moveSteps.shift(); + return true; + } + if (step <= 4) { + core.drawHero("leftFoot", 4 * o * step); + } else if (step <= 8) { + core.drawHero("rightFoot", 4 * o * step); + } + if (step == 8) { + core.setHeroLoc("x", x + o * core.utils.scan2[direction].x, true); + core.setHeroLoc("y", y + o * core.utils.scan2[direction].y, true); + core.updateFollowers(); + curr[1]--; + if (curr[1] <= 0) moveSteps.shift(); + core.setHeroLoc("direction", faceDirection); + return true; + } + return false; +}; + +////// 勇士跳跃事件 ////// +events.prototype.jumpHero = function (ex, ey, time, callback) { + var sx = core.getHeroLoc("x"), + sy = core.getHeroLoc("y"); + if (ex == null) ex = sx; + if (ey == null) ey = sy; + var sx = core.status.hero.loc.x, + sy = core.status.hero.loc.y; + if (!core.isset(ex)) ex = sx; + if (!core.isset(ey)) ey = sy; + var jumpInfo = core.maps.__generateJumpInfo(sx, sy, ex, ey, time || 500); + jumpInfo.icon = core.material.icons.hero[core.getHeroLoc("direction")]; + jumpInfo.width = core.material.icons.hero.width || 32; + jumpInfo.height = core.material.icons.hero.height; + + this._jumpHero_doJump(jumpInfo, callback); +}; + +events.prototype._jumpHero_doJump = function (jumpInfo, callback) { + var cb = function () { + core.setHeroLoc("x", jumpInfo.ex); + core.setHeroLoc("y", jumpInfo.ey); + core.status.heroMoving = 0; + core.drawHero(); + if (callback) callback(); + }; + + core.status.heroMoving = -1; + var animate = window.setInterval(function () { + if (jumpInfo.jump_count > 0) core.events._jumpHero_jumping(jumpInfo); + else { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + cb(); + } + }, jumpInfo.per_time); + + core.animateFrame.lastAsyncId = animate; + core.animateFrame.asyncId[animate] = cb; +}; events.prototype._jumpHero_jumping = function (jumpInfo) { - core.clearMap('hero'); - core.maps.__updateJumpInfo(jumpInfo); - var x = core.getHeroLoc('x'), - y = core.getHeroLoc('y'); - var nowx = jumpInfo.px, nowy = jumpInfo.py, width = jumpInfo.width || 32, height = jumpInfo.height; - core.drawHero('stop', { x: nowx - 32 * x, y: nowy - 32 * y }); -} + core.clearMap("hero"); + core.maps.__updateJumpInfo(jumpInfo); + var x = core.getHeroLoc("x"), + y = core.getHeroLoc("y"); + var nowx = jumpInfo.px, + nowy = jumpInfo.py, + width = jumpInfo.width || 32, + height = jumpInfo.height; + core.drawHero("stop", { x: nowx - 32 * x, y: nowy - 32 * y }); +}; ////// 设置角色行走图 ////// events.prototype.setHeroIcon = function (name, noDraw) { - name = core.getMappedName(name); - var img = core.material.images.images[name]; - if (!img) { - console.error("找不到图片: " + img); - return; - } - if (core.material.images.hero == img) return; - core.status.hero.image = name; - core.material.images.hero = img; - core.material.icons.hero.width = img.width / 4; - core.material.icons.hero.height = img.height / 4; - core.control.updateHeroIcon(name); - if (!noDraw) core.drawHero(); -} + name = core.getMappedName(name); + var img = core.material.images.images[name]; + if (!img) { + console.error("找不到图片: " + img); + return; + } + if (core.material.images.hero == img) return; + core.status.hero.image = name; + core.material.images.hero = img; + core.material.icons.hero.width = img.width / 4; + core.material.icons.hero.height = img.height / 4; + core.control.updateHeroIcon(name); + if (!noDraw) core.drawHero(); +}; ////// 检查升级事件 ////// events.prototype.checkLvUp = function () { - var actions = []; - while (true) { - var next = this._checkLvUp_check(); - if (next == null) break; - actions = actions.concat(next); - } - if (actions.length > 0) core.insertAction(actions); -} + var actions = []; + while (true) { + var next = this._checkLvUp_check(); + if (next == null) break; + actions = actions.concat(next); + } + if (actions.length > 0) core.insertAction(actions); +}; events.prototype._checkLvUp_check = function () { - if (core.flags.statusBarItems.indexOf('enableLevelUp') < 0 || !core.firstData.levelUp - || core.status.hero.lv >= core.firstData.levelUp.length) return null; - // 计算下一个所需要的数值 - var next = (core.firstData.levelUp[core.status.hero.lv] || {}); - var need = core.calValue(next.need); - if (need == null) return null; - if (core.status.hero.exp >= need) { - // 升级 - core.status.hero.lv++; - if (next.clear) core.status.hero.exp -= need; - return next.action || []; - } + if ( + core.flags.statusBarItems.indexOf("enableLevelUp") < 0 || + !core.firstData.levelUp || + core.status.hero.lv >= core.firstData.levelUp.length + ) return null; -} + // 计算下一个所需要的数值 + var next = core.firstData.levelUp[core.status.hero.lv] || {}; + var need = core.calValue(next.need); + if (need == null) return null; + if (core.status.hero.exp >= need) { + // 升级 + core.status.hero.lv++; + if (next.clear) core.status.hero.exp -= need; + return next.action || []; + } + return null; +}; ////// 尝试使用道具 ////// events.prototype.tryUseItem = function (itemId) { - if (itemId == 'book') { - core.ui.closePanel(); - return core.openBook(false); - } - if (itemId == 'fly') { - core.ui.closePanel(); - return core.useFly(false); - } - if (itemId == 'centerFly') { - core.ui.closePanel(); - return core.ui._drawCenterFly(); - } - if (core.canUseItem(itemId)) { - core.ui.closePanel(); - core.useItem(itemId); - } else { - core.playSound('操作失败'); - core.drawTip("当前无法使用" + core.material.items[itemId].name, itemId); - } -} + if (itemId == "book") { + core.ui.closePanel(); + return core.openBook(false); + } + if (itemId == "fly") { + core.ui.closePanel(); + return core.useFly(false); + } + if (itemId == "centerFly") { + core.ui.closePanel(); + return core.ui._drawCenterFly(); + } + if (core.canUseItem(itemId)) { + core.ui.closePanel(); + core.useItem(itemId); + } else { + core.playSound("操作失败"); + core.drawTip("当前无法使用" + core.material.items[itemId].name, itemId); + } +}; diff --git a/libs/loader.js b/libs/loader.js index e00620d..b81aba2 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -1,606 +1,818 @@ - /* loader.js:负责对资源的加载 */ "use strict"; -function loader () { - this._init(); +function loader() { + this._init(); } -loader.prototype._init = function () { - -} +loader.prototype._init = function () {}; ////// 设置加载进度条进度 ////// loader.prototype._setStartProgressVal = function (val) { - core.dom.startTopProgress.style.width = val + '%'; -} + core.dom.startTopProgress.style.width = val + "%"; +}; ////// 设置加载进度条提示文字 ////// loader.prototype._setStartLoadTipText = function (text) { - core.dom.startTopLoadTips.innerText = text; -} + core.dom.startTopLoadTips.innerText = text; +}; loader.prototype._load = function (callback) { - this._loadMusics(); - if (main.useCompress) { - this._load_async(callback); - } else { - this._load_sync(callback); - } -} + this._loadMusics(); + if (main.useCompress) { + this._load_async(callback); + } else { + this._load_sync(callback); + } +}; loader.prototype._load_sync = function (callback) { - this._loadAnimates_sync(); - this._loadSounds_sync(); - core.loader._loadMaterials_sync(function () { - core.loader._loadExtraImages_sync(function () { - core.loader._loadAutotiles_sync(function () { - core.loader._loadTilesets_sync(callback); - }) - }) + this._loadAnimates_sync(); + this._loadSounds_sync(); + core.loader._loadMaterials_sync(function () { + core.loader._loadExtraImages_sync(function () { + core.loader._loadAutotiles_sync(function () { + core.loader._loadTilesets_sync(callback); + }); }); -} + }); +}; loader.prototype._load_async = function (callback) { - core.loader._setStartLoadTipText('正在加载资源文件...'); - const all = {}; + core.loader._setStartLoadTipText("正在加载资源文件..."); + const all = {}; - const _makeOnProgress = function (name) { - if (!all[name]) all[name] = { loaded: 0, total: 0, finished: false }; - return (loaded, total) => { - all[name].loaded = loaded; - all[name].total = total; - let allLoaded = 0, allTotal = 0; - for (const one of Object.values(all)) { - allLoaded += one.loaded; - allTotal += one.total; - } - console.log(allLoaded. allTotal); - if (allTotal > 0) { - if (allLoaded == allTotal) { - core.loader._setStartLoadTipText("正在处理资源文件... 请稍候..."); - } else { - core.loader._setStartLoadTipText('正在加载资源文件... ' + - core.formatSize(allLoaded) + " / " + core.formatSize(allTotal) + - " (" + (allLoaded / allTotal * 100).toFixed(2) + "%)"); - } - core.loader._setStartProgressVal(allLoaded / allTotal * 100); - } - }; - } - const _makeOnFinished = function (name) { - return () => { - setTimeout(() => { - all[name].finished = true; - for (var one in all) { - if (!all[one].finished) return; - } - callback(); - }); + const _makeOnProgress = function (name) { + if (!all[name]) all[name] = { loaded: 0, total: 0, finished: false }; + return (loaded, total) => { + all[name].loaded = loaded; + all[name].total = total; + let allLoaded = 0, + allTotal = 0; + for (const one of Object.values(all)) { + allLoaded += one.loaded; + allTotal += one.total; + } + console.log(allLoaded.allTotal); + if (allTotal > 0) { + if (allLoaded == allTotal) { + core.loader._setStartLoadTipText("正在处理资源文件... 请稍候..."); + } else { + core.loader._setStartLoadTipText( + "正在加载资源文件... " + + core.formatSize(allLoaded) + + " / " + + core.formatSize(allTotal) + + " (" + + ((allLoaded / allTotal) * 100).toFixed(2) + + "%)" + ); } - } + core.loader._setStartProgressVal((allLoaded / allTotal) * 100); + } + }; + }; + const _makeOnFinished = function (name) { + return () => { + setTimeout(() => { + all[name].finished = true; + for (var one in all) { + if (!all[one].finished) return; + } + callback(); + }); + }; + }; - if (main.splitChunkMap) { - this._loadAnimates_chunked(main.splitChunkMap.animates, _makeOnProgress, _makeOnFinished); - this._loadSounds_chunked(main.splitChunkMap.sounds, _makeOnProgress, _makeOnFinished); - this._loadMaterials_chunked(main.splitChunkMap.materials, _makeOnProgress, _makeOnFinished); - this._loadExtraImages_chunked(main.splitChunkMap.images, _makeOnProgress, _makeOnFinished); - this._loadAutotiles_chunked(main.splitChunkMap.autotiles, _makeOnProgress, _makeOnFinished); - this._loadTilesets_chunked(main.splitChunkMap.tilesets, _makeOnProgress, _makeOnFinished); - } else { - this._loadAnimates_async(_makeOnProgress('animates'), _makeOnFinished('animates')); - this._loadSounds_async(_makeOnProgress('sounds'), _makeOnFinished('sounds')); - this._loadMaterials_async(_makeOnProgress('materials'), _makeOnFinished('materials')); - this._loadExtraImages_async(_makeOnProgress('images'), _makeOnFinished('images')); - this._loadAutotiles_async(_makeOnProgress('autotiles'), _makeOnFinished('autotiles')); - this._loadTilesets_async(_makeOnProgress('tilesets'), _makeOnFinished('tilesets')); - } -} + if (main.splitChunkMap) { + this._loadAnimates_chunked( + main.splitChunkMap.animates, + _makeOnProgress, + _makeOnFinished + ); + this._loadSounds_chunked( + main.splitChunkMap.sounds, + _makeOnProgress, + _makeOnFinished + ); + this._loadMaterials_chunked( + main.splitChunkMap.materials, + _makeOnProgress, + _makeOnFinished + ); + this._loadExtraImages_chunked( + main.splitChunkMap.images, + _makeOnProgress, + _makeOnFinished + ); + this._loadAutotiles_chunked( + main.splitChunkMap.autotiles, + _makeOnProgress, + _makeOnFinished + ); + this._loadTilesets_chunked( + main.splitChunkMap.tilesets, + _makeOnProgress, + _makeOnFinished + ); + } else { + this._loadAnimates_async( + _makeOnProgress("animates"), + _makeOnFinished("animates") + ); + this._loadSounds_async( + _makeOnProgress("sounds"), + _makeOnFinished("sounds") + ); + this._loadMaterials_async( + _makeOnProgress("materials"), + _makeOnFinished("materials") + ); + this._loadExtraImages_async( + _makeOnProgress("images"), + _makeOnFinished("images") + ); + this._loadAutotiles_async( + _makeOnProgress("autotiles"), + _makeOnFinished("autotiles") + ); + this._loadTilesets_async( + _makeOnProgress("tilesets"), + _makeOnFinished("tilesets") + ); + } +}; // ----- 加载资源文件 ------ // loader.prototype._loadMaterials_sync = function (callback) { - this._setStartLoadTipText("正在加载资源文件..."); - this.loadImages("materials", core.materials, core.material.images, function () { - core.loader._loadMaterials_afterLoad(); - callback(); - }); -} + this._setStartLoadTipText("正在加载资源文件..."); + this.loadImages( + "materials", + core.materials, + core.material.images, + function () { + core.loader._loadMaterials_afterLoad(); + callback(); + } + ); +}; loader.prototype._loadMaterials_async = function (onprogress, onfinished) { - this.loadImagesFromZip('project/materials/materials.h5data', core.materials, core.material.images, onprogress, function () { - core.loader._loadMaterials_afterLoad(); - onfinished(); - }); -} + this.loadImagesFromZip( + "project/materials/materials.h5data", + core.materials, + core.material.images, + onprogress, + function () { + core.loader._loadMaterials_afterLoad(); + onfinished(); + } + ); +}; -loader.prototype._loadMaterials_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - await this._loadImagesFromChunks(chunks, core.materials, core.material.images, makeOnProgress, makeOnFinished); - core.loader._loadMaterials_afterLoad(); -} +loader.prototype._loadMaterials_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + await this._loadImagesFromChunks( + chunks, + core.materials, + core.material.images, + makeOnProgress, + makeOnFinished + ); + core.loader._loadMaterials_afterLoad(); +}; loader.prototype._loadMaterials_afterLoad = function () { - const images = core.splitImage(core.material.images['icons']); - for (let key in core.statusBar.icons) { - if (typeof core.statusBar.icons[key] == 'number') { - core.statusBar.icons[key] = images[core.statusBar.icons[key]]; - if (core.statusBar.image[key] != null) - core.statusBar.image[key].src = core.statusBar.icons[key].src; - } + const images = core.splitImage(core.material.images["icons"]); + for (let key in core.statusBar.icons) { + if (typeof core.statusBar.icons[key] == "number") { + core.statusBar.icons[key] = images[core.statusBar.icons[key]]; + if (core.statusBar.image[key] != null) + core.statusBar.image[key].src = core.statusBar.icons[key].src; } -} + } +}; // ------ 加载使用的图片 ------ // loader.prototype._loadExtraImages_sync = function (callback) { - core.material.images.images = {}; - this._setStartLoadTipText("正在加载图片文件..."); - core.loadImages("images", core.images, core.material.images.images, callback); -} + core.material.images.images = {}; + this._setStartLoadTipText("正在加载图片文件..."); + core.loadImages("images", core.images, core.material.images.images, callback); +}; loader.prototype._loadExtraImages_async = function (onprogress, onfinished) { - core.material.images.images = {}; - - // Check .gif - const gifs = images.filter(function (name) { - return name.toLowerCase().endsWith('.gif'); - }); - // gif没有被压缩在zip中,延迟加载... - this._loadExtraImages_loadLazy(gifs); + core.material.images.images = {}; - images = images.filter((name) => !name.toLowerCase().endsWith('.gif')); + // Check .gif + const gifs = images.filter(function (name) { + return name.toLowerCase().endsWith(".gif"); + }); + // gif没有被压缩在zip中,延迟加载... + this._loadExtraImages_loadLazy(gifs); - this.loadImagesFromZip('project/images/images.h5data', images, core.material.images.images, onprogress, onfinished); -} + images = images.filter((name) => !name.toLowerCase().endsWith(".gif")); -loader.prototype._loadExtraImages_chunked = function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.images = {}; - let images = core.images; + this.loadImagesFromZip( + "project/images/images.h5data", + images, + core.material.images.images, + onprogress, + onfinished + ); +}; - // Check .gif - const gifs = images.filter(function (name) { - return name.toLowerCase().endsWith('.gif'); - }); - // gif没有被压缩在zip中,延迟加载... - this._loadExtraImages_loadLazy(gifs); +loader.prototype._loadExtraImages_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.images = {}; + let images = core.images; - images = images.filter((name) => !name.toLowerCase().endsWith('.gif')); + // Check .gif + const gifs = images.filter(function (name) { + return name.toLowerCase().endsWith(".gif"); + }); + // gif没有被压缩在zip中,延迟加载... + this._loadExtraImages_loadLazy(gifs); - this._loadImagesFromChunks(chunks, images, core.material.images.images, makeOnProgress, makeOnFinished); -} + images = images.filter((name) => !name.toLowerCase().endsWith(".gif")); + + this._loadImagesFromChunks( + chunks, + images, + core.material.images.images, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._loadExtraImages_loadLazy = function (list) { - list.forEach(function (gif) { - this.loadImage("images", gif, (id, image) => { - if (image != null) { - core.material.images.images[gif] = image; - } - }); - }, this); -} + list.forEach(function (gif) { + this.loadImage("images", gif, (id, image) => { + if (image != null) { + core.material.images.images[gif] = image; + } + }); + }, this); +}; // ------ 加载自动元件 ------ // loader.prototype._loadAutotiles_sync = function (callback) { - core.material.images.autotile = {}; - var keys = Object.keys(core.material.icons.autotile); - var autotiles = {}; + core.material.images.autotile = {}; + var keys = Object.keys(core.material.icons.autotile); + var autotiles = {}; - this._setStartLoadTipText("正在加载自动元件..."); - this.loadImages("autotiles", keys, autotiles, function () { - core.loader._loadAutotiles_afterLoad(keys, autotiles); - callback(); - }); -} + this._setStartLoadTipText("正在加载自动元件..."); + this.loadImages("autotiles", keys, autotiles, function () { + core.loader._loadAutotiles_afterLoad(keys, autotiles); + callback(); + }); +}; loader.prototype._loadAutotiles_async = function (onprogress, onfinished) { - core.material.images.autotile = {}; - var keys = Object.keys(core.material.icons.autotile); - var autotiles = {}; + core.material.images.autotile = {}; + var keys = Object.keys(core.material.icons.autotile); + var autotiles = {}; - this.loadImagesFromZip('project/autotiles/autotiles.h5data', keys, autotiles, onprogress, function () { - core.loader._loadAutotiles_afterLoad(keys, autotiles); - onfinished(); - }); -} + this.loadImagesFromZip( + "project/autotiles/autotiles.h5data", + keys, + autotiles, + onprogress, + function () { + core.loader._loadAutotiles_afterLoad(keys, autotiles); + onfinished(); + } + ); +}; -loader.prototype._loadAutotiles_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.autotile = {}; - const keys = Object.keys(core.material.icons.autotile); - const autotiles = {}; +loader.prototype._loadAutotiles_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.autotile = {}; + const keys = Object.keys(core.material.icons.autotile); + const autotiles = {}; - await this._loadImagesFromChunks(chunks, keys, autotiles, makeOnProgress, makeOnFinished); - core.loader._loadAutotiles_afterLoad(keys, autotiles); -} + await this._loadImagesFromChunks( + chunks, + keys, + autotiles, + makeOnProgress, + makeOnFinished + ); + core.loader._loadAutotiles_afterLoad(keys, autotiles); +}; loader.prototype._loadAutotiles_afterLoad = function (keys, autotiles) { - // autotile需要保证顺序 - keys.forEach(function (v) { - core.material.images.autotile[v] = autotiles[v]; - }); + // autotile需要保证顺序 + keys.forEach(function (v) { + core.material.images.autotile[v] = autotiles[v]; + }); - setTimeout(function () { - core.maps._makeAutotileEdges(); - }); - -} + setTimeout(function () { + core.maps._makeAutotileEdges(); + }); +}; // ------ 加载额外素材 ------ // loader.prototype._loadTilesets_sync = function (callback) { - core.material.images.tilesets = {}; - this._setStartLoadTipText("正在加载额外素材..."); - this.loadImages("tilesets", core.tilesets, core.material.images.tilesets, function () { - core.loader._loadTilesets_afterLoad(); - callback(); - }); -} + core.material.images.tilesets = {}; + this._setStartLoadTipText("正在加载额外素材..."); + this.loadImages( + "tilesets", + core.tilesets, + core.material.images.tilesets, + function () { + core.loader._loadTilesets_afterLoad(); + callback(); + } + ); +}; loader.prototype._loadTilesets_async = function (onprogress, onfinished) { - core.material.images.tilesets = {}; - this.loadImagesFromZip('project/tilesets/tilesets.h5data', core.tilesets, core.material.images.tilesets, onprogress, function () { - core.loader._loadTilesets_afterLoad(); - onfinished(); - }); -} + core.material.images.tilesets = {}; + this.loadImagesFromZip( + "project/tilesets/tilesets.h5data", + core.tilesets, + core.material.images.tilesets, + onprogress, + function () { + core.loader._loadTilesets_afterLoad(); + onfinished(); + } + ); +}; -loader.prototype._loadTilesets_chunked = async function (chunks, makeOnProgress, makeOnFinished) { - core.material.images.tilesets = {}; - await this._loadImagesFromChunks(chunks, core.tilesets, core.material.images.tilesets, makeOnProgress, makeOnFinished); - core.loader._loadTilesets_afterLoad(); -} +loader.prototype._loadTilesets_chunked = async function ( + chunks, + makeOnProgress, + makeOnFinished +) { + core.material.images.tilesets = {}; + await this._loadImagesFromChunks( + chunks, + core.tilesets, + core.material.images.tilesets, + makeOnProgress, + makeOnFinished + ); + core.loader._loadTilesets_afterLoad(); +}; loader.prototype._loadTilesets_afterLoad = function () { - // 检查宽高是32倍数,如果出错在控制台报错 - for (var imgName in core.material.images.tilesets) { - var img = core.material.images.tilesets[imgName]; - if (img.width % 32 != 0 || img.height % 32 != 0) { - console.warn("警告!" + imgName + "的宽或高不是32的倍数!"); - } - if (img.width * img.height > 32 * 32 * 3000) { - console.warn("警告!" + imgName + "上的图块素材个数大于3000!"); - } + // 检查宽高是32倍数,如果出错在控制台报错 + for (var imgName in core.material.images.tilesets) { + var img = core.material.images.tilesets[imgName]; + if (img.width % 32 != 0 || img.height % 32 != 0) { + console.warn("警告!" + imgName + "的宽或高不是32的倍数!"); } -} + if (img.width * img.height > 32 * 32 * 3000) { + console.warn("警告!" + imgName + "上的图块素材个数大于3000!"); + } + } +}; // ------ 实际加载一系列图片 ------ // loader.prototype.loadImages = function (dir, names, toSave, callback) { - if (!names || names.length == 0) { - if (callback) callback(); + if (!names || names.length == 0) { + if (callback) callback(); + return; + } + var items = 0; + for (var i = 0; i < names.length; i++) { + this.loadImage(dir, names[i], function (id, image) { + core.loader._setStartLoadTipText("正在加载图片 " + id + "..."); + if (toSave[id] !== undefined) { + if (image != null) toSave[id] = image; return; - } - var items = 0; - for (var i = 0; i < names.length; i++) { - this.loadImage(dir, names[i], function (id, image) { - core.loader._setStartLoadTipText('正在加载图片 ' + id + "..."); - if (toSave[id] !== undefined) { - if (image != null) - toSave[id] = image; - return; - } - toSave[id] = image; - items++; - core.loader._setStartProgressVal(items * (100 / names.length)); - if (items == names.length) { - if (callback) callback(); - } - }) - } -} + } + toSave[id] = image; + items++; + core.loader._setStartProgressVal(items * (100 / names.length)); + if (items == names.length) { + if (callback) callback(); + } + }); + } +}; loader.prototype.loadImage = function (dir, imgName, callback) { - try { - var name = imgName; - if (name.indexOf(".") < 0) - name = name + ".png"; - var image = new Image(); - image.onload = function () { - image.setAttribute('_width', image.width); - image.setAttribute('_height', image.height); - callback(imgName, image); - } - image.onerror = function () { - callback(imgName, null); - } - image.src = 'project/' + dir + '/' + name + "?v=" + main.version; - if (name.endsWith('.gif')) - callback(imgName, null); - } - catch (e) { - console.error(e); - } -} + try { + var name = imgName; + if (name.indexOf(".") < 0) name = name + ".png"; + var image = new Image(); + image.onload = function () { + image.setAttribute("_width", image.width); + image.setAttribute("_height", image.height); + callback(imgName, image); + }; + image.onerror = function () { + callback(imgName, null); + }; + image.src = "project/" + dir + "/" + name + "?v=" + main.version; + if (name.endsWith(".gif")) callback(imgName, null); + } catch (e) { + console.error(e); + } +}; // ------ 从zip中加载一系列图片 ------ // -loader.prototype.loadImagesFromZip = function (url, names, toSave, onprogress, onfinished) { - if (!names || names.length == 0) { - if (onfinished) onfinished(); - return; - } +loader.prototype.loadImagesFromZip = function ( + url, + names, + toSave, + onprogress, + onfinished +) { + if (!names || names.length == 0) { + if (onfinished) onfinished(); + return; + } - core.unzip(url + "?v=" + main.version, function (data) { - var cnt = 1; - names.forEach(function (name) { - var imgName = name; - if (imgName.indexOf('.') < 0) imgName += '.png'; - if (imgName in data) { - var img = new Image(); - var url = URL.createObjectURL(data[imgName]); - cnt++; - img.onload = function () { - cnt--; - URL.revokeObjectURL(url); - img.setAttribute('_width', img.width); - img.setAttribute('_height', img.height); - if (cnt == 0 && onfinished) onfinished(); - } - img.src = url; - toSave[name] = img; - } - }); - cnt--; - if (cnt == 0 && onfinished) onfinished(); - }, null, false, onprogress); -} + core.unzip( + url + "?v=" + main.version, + function (data) { + var cnt = 1; + names.forEach(function (name) { + var imgName = name; + if (imgName.indexOf(".") < 0) imgName += ".png"; + if (imgName in data) { + var img = new Image(); + var url = URL.createObjectURL(data[imgName]); + cnt++; + img.onload = function () { + cnt--; + URL.revokeObjectURL(url); + img.setAttribute("_width", img.width); + img.setAttribute("_height", img.height); + if (cnt == 0 && onfinished) onfinished(); + }; + img.src = url; + toSave[name] = img; + } + }); + cnt--; + if (cnt == 0 && onfinished) onfinished(); + }, + null, + false, + onprogress + ); +}; -loader.prototype._loadImagesFromChunks = async function (chunks, names, toSave, makeOnProgress, makeOnFinished) { - await Promise.all(chunks.map((chunk) => { - const onfinished = makeOnFinished(chunk); - const onprogress = makeOnProgress(chunk); - return new Promise((resolve) => { - this.loadImagesFromZip(chunk, names, toSave, onprogress, () => { - onfinished(); - resolve(); - }); +loader.prototype._loadImagesFromChunks = async function ( + chunks, + names, + toSave, + makeOnProgress, + makeOnFinished +) { + await Promise.all( + chunks.map((chunk) => { + const onfinished = makeOnFinished(chunk); + const onprogress = makeOnProgress(chunk); + return new Promise((resolve) => { + this.loadImagesFromZip(chunk, names, toSave, onprogress, () => { + onfinished(); + resolve(); }); - })); -} + }); + }) + ); +}; // ------ 加载动画文件 ------ // loader.prototype._loadAnimates_sync = function () { - this._setStartLoadTipText("正在加载动画文件..."); + this._setStartLoadTipText("正在加载动画文件..."); - if (main.supportBunch) { - if (core.animates.length > 0) { - core.http('GET', '__all_animates__?v=' + main.version + '&id=' + core.animates.join(','), null, function (content) { - var u = content.split('@@@~~~###~~~@@@'); - for (var i = 0; i < core.animates.length; ++i) { - if (u[i] != '') { - core.material.animates[core.animates[i]] = core.loader._loadAnimate(u[i]); - } else { - console.error('无法找到动画文件' + core.animates[i] + '!'); - } - } - }, "text/plain; charset=x-user-defined"); - } - return; + if (main.supportBunch) { + if (core.animates.length > 0) { + core.http( + "GET", + "__all_animates__?v=" + main.version + "&id=" + core.animates.join(","), + null, + function (content) { + var u = content.split("@@@~~~###~~~@@@"); + for (var i = 0; i < core.animates.length; ++i) { + if (u[i] != "") { + core.material.animates[core.animates[i]] = + core.loader._loadAnimate(u[i]); + } else { + console.error("无法找到动画文件" + core.animates[i] + "!"); + } + } + }, + "text/plain; charset=x-user-defined" + ); } + return; + } - core.animates.forEach(function (t) { - core.http('GET', 'project/animates/' + t + ".animate?v=" + main.version, null, function (content) { - core.material.animates[t] = core.loader._loadAnimate(content); - }, function (e) { - console.error(e); - core.material.animates[t] = null; - }, "text/plain; charset=x-user-defined") - }); -} + core.animates.forEach(function (t) { + core.http( + "GET", + "project/animates/" + t + ".animate?v=" + main.version, + null, + function (content) { + core.material.animates[t] = core.loader._loadAnimate(content); + }, + function (e) { + console.error(e); + core.material.animates[t] = null; + }, + "text/plain; charset=x-user-defined" + ); + }); +}; loader.prototype._loadAnimates_async = function (onprogress, onfinished) { - this._loadFileFromZip('project/animates/animates.h5data', this._saveAnimate, true, onprogress, onfinished); -} + this._loadFileFromZip( + "project/animates/animates.h5data", + this._saveAnimate, + true, + onprogress, + onfinished + ); +}; -loader.prototype._loadAnimates_chunked = function (chunks, makeOnProgress, makeOnFinished) { - this._loadFileFromChunks(chunks, this._saveAnimate, true, makeOnProgress, makeOnFinished); -} +loader.prototype._loadAnimates_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + this._loadFileFromChunks( + chunks, + this._saveAnimate, + true, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._saveAnimate = function (animates, onfinished) { - for (var name in animates) { - if (name.endsWith(".animate")) { - var t = name.substring(0, name.length - 8); - if (core.animates.indexOf(t) >= 0) - core.material.animates[t] = core.loader._loadAnimate(animates[name]); - } + for (var name in animates) { + if (name.endsWith(".animate")) { + var t = name.substring(0, name.length - 8); + if (core.animates.indexOf(t) >= 0) + core.material.animates[t] = core.loader._loadAnimate(animates[name]); } - onfinished(); -} + } + onfinished(); +}; loader.prototype._loadAnimate = function (content) { - try { - content = JSON.parse(content); - var data = {}; - data.ratio = content.ratio; - data.se = content.se; - data.pitch = content.pitch; - data.images = []; - content.bitmaps.forEach(function (t2) { - if (!t2) { - data.images.push(null); - } - else { - try { - var image = new Image(); - image.src = t2; - data.images.push(image); - } catch (e) { - console.error(e); - data.images.push(null); - } - } - }) - data.frame = content.frame_max; - data.frames = []; - content.frames.forEach(function (t2) { - var info = []; - t2.forEach(function (t3) { - info.push({ - 'index': t3[0], - 'x': t3[1], - 'y': t3[2], - 'zoom': t3[3], - 'opacity': t3[4], - 'mirror': t3[5] || 0, - 'angle': t3[6] || 0, - }) - }) - data.frames.push(info); + try { + content = JSON.parse(content); + var data = {}; + data.ratio = content.ratio; + data.se = content.se; + data.pitch = content.pitch; + data.images = []; + content.bitmaps.forEach(function (t2) { + if (!t2) { + data.images.push(null); + } else { + try { + var image = new Image(); + image.src = t2; + data.images.push(image); + } catch (e) { + console.error(e); + data.images.push(null); + } + } + }); + data.frame = content.frame_max; + data.frames = []; + content.frames.forEach(function (t2) { + var info = []; + t2.forEach(function (t3) { + info.push({ + index: t3[0], + x: t3[1], + y: t3[2], + zoom: t3[3], + opacity: t3[4], + mirror: t3[5] || 0, + angle: t3[6] || 0, }); - return data; - } - catch (e) { - console.error(e); - return null; - } -} + }); + data.frames.push(info); + }); + return data; + } catch (e) { + console.error(e); + return null; + } +}; // ------ 加载音乐和音效 ------ // loader.prototype._loadMusics = function () { - core.bgms.forEach(function (t) { - core.loader.loadOneMusic(t); - }); - // 直接开始播放 - core.playBgm(main.startBgm); -} + core.bgms.forEach(function (t) { + core.loader.loadOneMusic(t); + }); + // 直接开始播放 + core.playBgm(main.startBgm); +}; loader.prototype._loadSounds_sync = function () { - this._setStartLoadTipText("正在加载音效文件..."); - core.sounds.forEach(function (t) { - core.loader.loadOneSound(t); - }); -} + this._setStartLoadTipText("正在加载音效文件..."); + core.sounds.forEach(function (t) { + core.loader.loadOneSound(t); + }); +}; loader.prototype._loadSounds_async = function (onprogress, onfinished) { - this._loadFileFromZip('project/sounds/sounds.h5data', this._saveSounds, false, onprogress, onfinished); -} + this._loadFileFromZip( + "project/sounds/sounds.h5data", + this._saveSounds, + false, + onprogress, + onfinished + ); +}; -loader.prototype._loadSounds_chunked = function (chunks, makeOnProgress, makeOnFinished) { - this._loadFileFromChunks(chunks, this._saveSounds, false, makeOnProgress, makeOnFinished); -} +loader.prototype._loadSounds_chunked = function ( + chunks, + makeOnProgress, + makeOnFinished +) { + this._loadFileFromChunks( + chunks, + this._saveSounds, + false, + makeOnProgress, + makeOnFinished + ); +}; loader.prototype._saveSounds = function (data, onfinished) { - // 延迟解析 - setTimeout(function () { - for (var name in data) { - if (core.sounds.indexOf(name) >= 0) { - core.loader._loadOneSound_decodeData(name, data[name]); - } - } - onfinished(); - }); -} + // 延迟解析 + setTimeout(function () { + for (var name in data) { + if (core.sounds.indexOf(name) >= 0) { + core.loader._loadOneSound_decodeData(name, data[name]); + } + } + onfinished(); + }); +}; loader.prototype.loadOneMusic = function (name) { - var music = new Audio(); - music.preload = 'none'; - if (main.bgmRemote) music.src = main.bgmRemoteRoot + core.firstData.name + '/' + name; - else music.src = 'project/bgms/' + name; - music.loop = 'loop'; - core.material.bgms[name] = music; -} + /* var music = new Audio(); + music.preload = "none"; + if (main.bgmRemote) + music.src = main.bgmRemoteRoot + core.firstData.name + "/" + name; + else music.src = "project/bgms/" + name; + music.loop = "loop"; + core.material.bgms[name] = music;*/ +}; loader.prototype.loadOneSound = function (name) { - core.http('GET', 'project/sounds/' + name + "?v=" + main.version, null, function (data) { - core.loader._loadOneSound_decodeData(name, data); - }, function (e) { - console.error(e); - core.material.sounds[name] = null; - }, null, 'arraybuffer'); -} + core.http( + "GET", + "project/sounds/" + name + "?v=" + main.version, + null, + function (data) { + core.loader._loadOneSound_decodeData(name, data); + }, + function (e) { + console.error(e); + core.material.sounds[name] = null; + }, + null, + "arraybuffer" + ); +}; loader.prototype._loadOneSound_decodeData = function (name, data) { - if (data instanceof Blob) { - var blobReader = new zip.BlobReader(data); - blobReader.init(function () { - blobReader.readUint8Array(0, blobReader.size, function (uint8) { - core.loader._loadOneSound_decodeData(name, uint8.buffer); - }) - }); - return; - } - try { - core.musicStatus.audioContext.decodeAudioData(data, function (buffer) { - core.material.sounds[name] = buffer; - }, function (e) { - console.error(e); - core.material.sounds[name] = null; - }) - } - catch (e) { + if (data instanceof Blob) { + var blobReader = new zip.BlobReader(data); + blobReader.init(function () { + blobReader.readUint8Array(0, blobReader.size, function (uint8) { + core.loader._loadOneSound_decodeData(name, uint8.buffer); + }); + }); + return; + } + try { + core.musicStatus.audioContext.decodeAudioData( + data, + function (buffer) { + core.material.sounds[name] = buffer; + }, + function (e) { console.error(e); core.material.sounds[name] = null; - } -} + } + ); + } catch (e) { + console.error(e); + core.material.sounds[name] = null; + } +}; loader.prototype.loadBgm = function (name) { - name = core.getMappedName(name); - if (!core.material.bgms[name]) return; - // 如果没开启音乐,则不预加载 - if (!core.musicStatus.bgmStatus) return; - // 是否已经预加载过 - var index = core.musicStatus.cachedBgms.indexOf(name); - if (index >= 0) { - core.musicStatus.cachedBgms.splice(index, 1); + name = core.getMappedName(name); + if (!core.material.bgms[name]) return; + // 如果没开启音乐,则不预加载 + if (!core.musicStatus.bgmStatus) return; + // 是否已经预加载过 + var index = core.musicStatus.cachedBgms.indexOf(name); + if (index >= 0) { + core.musicStatus.cachedBgms.splice(index, 1); + } else { + // 预加载BGM + this._preloadBgm(core.material.bgms[name]); + // core.material.bgms[name].load(); + // 清理尾巴 + if (core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount) { + this.freeBgm(core.musicStatus.cachedBgms.pop()); } - else { - // 预加载BGM - this._preloadBgm(core.material.bgms[name]); - // core.material.bgms[name].load(); - // 清理尾巴 - if (core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount) { - this.freeBgm(core.musicStatus.cachedBgms.pop()); - } - } - // 移动到缓存最前方 - core.musicStatus.cachedBgms.unshift(name); -} + } + // 移动到缓存最前方 + core.musicStatus.cachedBgms.unshift(name); +}; loader.prototype._preloadBgm = function (bgm) { - bgm.volume = 0; - bgm.play(); -} + bgm.volume = 0; + bgm.play(); +}; loader.prototype.freeBgm = function (name) { - name = core.getMappedName(name); - if (!core.material.bgms[name]) return; - // 从cachedBgms中删除 - core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function (t) { - return t != name; - }); - // 清掉缓存 - core.material.bgms[name].removeAttribute("src"); - core.material.bgms[name].load(); - core.material.bgms[name] = null; - if (name == core.musicStatus.playingBgm) { - core.musicStatus.playingBgm = null; - } - // 三秒后重新加载 - setTimeout(function () { - core.loader.loadOneMusic(name); - }, 3000); -} + name = core.getMappedName(name); + if (!core.material.bgms[name]) return; + // 从cachedBgms中删除 + core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function ( + t + ) { + return t != name; + }); + // 清掉缓存 + core.material.bgms[name].removeAttribute("src"); + core.material.bgms[name].load(); + core.material.bgms[name] = null; + if (name == core.musicStatus.playingBgm) { + core.musicStatus.playingBgm = null; + } + // 三秒后重新加载 + setTimeout(function () { + core.loader.loadOneMusic(name); + }, 3000); +}; -loader.prototype._loadFileFromZip = function (url, save, convertToText, onprogress, onfinished) { - core.unzip(url + '?v=' + main.version, function (data) { - save(data, onfinished); - }, null, convertToText, onprogress); -} +loader.prototype._loadFileFromZip = function ( + url, + save, + convertToText, + onprogress, + onfinished +) { + core.unzip( + url + "?v=" + main.version, + function (data) { + save(data, onfinished); + }, + null, + convertToText, + onprogress + ); +}; -loader.prototype._loadFileFromChunks = async function (chunks, save, convertToText, makeOnProgress, makeOnFinished) { - await Promise.all(chunks.map((chunk) => { - const onfinished = makeOnFinished(chunk); - const onprogress = makeOnProgress(chunk); - return new Promise((resolve) => { - this._loadFileFromZip(chunk, save, convertToText, onprogress, () => { - onfinished(); - resolve(); - }); +loader.prototype._loadFileFromChunks = async function ( + chunks, + save, + convertToText, + makeOnProgress, + makeOnFinished +) { + await Promise.all( + chunks.map((chunk) => { + const onfinished = makeOnFinished(chunk); + const onprogress = makeOnProgress(chunk); + return new Promise((resolve) => { + this._loadFileFromZip(chunk, save, convertToText, onprogress, () => { + onfinished(); + resolve(); }); - })); -} + }); + }) + ); +}; diff --git a/libs/thirdparty/codec-parser.min.js b/libs/thirdparty/codec-parser.min.js new file mode 100644 index 0000000..fb4ac2e --- /dev/null +++ b/libs/thirdparty/codec-parser.min.js @@ -0,0 +1 @@ +var CodecParser=function(e){"use strict";const t=Symbol,s=(()=>{const e="left",t="center",s="right";return["","front ","side ","rear "].map((i=>[[e,s],[e,s,t],[e,t,s],[t,e,s],[t]].flatMap((e=>e.map((e=>i+e)).join(", ")))))})(),i="LFE",r="monophonic (mono)",n="stereo",a="surround",o=(e,...t)=>`${[r,n,`linear ${a}`,"quadraphonic",`5.0 ${a}`,`5.1 ${a}`,`6.1 ${a}`,`7.1 ${a}`][e-1]} (${t.join(", ")})`,h=[r,o(2,s[0][0]),o(3,s[0][2]),o(4,s[1][0],s[3][0]),o(5,s[1][2],s[3][0]),o(6,s[1][2],s[3][0],i),o(7,s[1][2],s[2][0],s[3][4],i),o(8,s[1][2],s[2][0],s[3][0],i)],c=48e3,l=44100,u=32e3,d=24e3,p=22050,_=16e3,m=8e3,g="absoluteGranulePosition",f="bandwidth",b="bitDepth",C="bitrate",y=C+"Maximum",S=C+"Minimum",w=C+"Nominal",P="buffer",k=P+"Fullness",v="codec",F=v+"Frames",x="coupledStreamCount",H="crc",I=H+"16",M=H+"32",U="data",O="description",N="duration",$="emphasis",A="hasOpusPadding",R="header",B="isContinuedPacket",L="isCopyrighted",D="isFirstPage",T="isHome",E="isLastPage",G="isOriginal",z="isPrivate",q="isVbr",V="layer",j="length",W="mode",J=W+"Extension",K="mpeg",Q=K+"Version",X="numberAACFrames",Y="outputGain",Z="preSkip",ee="profile",te=t(),se="protection",ie="rawData",re="segments",ne="subarray",ae="version",oe="vorbis",he=oe+"Comments",ce=oe+"Setup",le="block",ue=le+"ingStrategy",de=t(),pe=le+"Size",_e=le+"size0",me=le+"size1",ge=t(),fe="channel",be=fe+"MappingFamily",Ce=fe+"MappingTable",ye=fe+"Mode",Se=t(),we=fe+"s",Pe="copyright",ke=Pe+"Id",ve=Pe+"IdStart",Fe="frame",xe=Fe+"Count",He=Fe+"Length",Ie="Number",Me=Fe+Ie,Ue=Fe+"Padding",Oe=Fe+"Size",Ne="Rate",$e="inputSample"+Ne,Ae="page",Re=Ae+"Checksum",Be=t(),Le=Ae+"SegmentTable",De=Ae+"Sequence"+Ie,Te="sample",Ee=Te+Ie,Ge=Te+Ne,ze=t(),qe=Te+"s",Ve="stream",je=Ve+"Count",We=Ve+"Info",Je=Ve+"Serial"+Ie,Ke=Ve+"StructureVersion",Qe="total",Xe=Qe+"BytesOut",Ye=Qe+"Duration",Ze=Qe+"Samples",et=t(),tt=t(),st=t(),it=t(),rt=t(),nt=t(),at=t(),ot=t(),ht=t(),ct=t(),lt=t(),ut=t(),dt=t(),pt=t(),_t=t(),mt=t(),gt=t(),ft=t(),bt=Uint8Array,Ct=DataView,yt="reserved",St="bad",wt="free",Pt="none",kt="16bit CRC",vt=(e,t,s)=>{for(let i=0;i0;e--)r=s(r);e[i]=r}return e},Ft=vt(new bt(256),(e=>e),(e=>128&e?7^e<<1:e<<1)),xt=[vt(new Uint16Array(256),(e=>e<<8),(e=>e<<1^(32768&e?32773:0)))],Ht=[vt(new Uint32Array(256),(e=>e),(e=>e>>>1^3988292384*(1&e)))];for(let e=0;e<15;e++){xt.push(new Uint16Array(256)),Ht.push(new Uint32Array(256));for(let t=0;t<=255;t++)xt[e+1][t]=xt[0][xt[e][t]>>>8]^xt[e][t]<<8,Ht[e+1][t]=Ht[e][t]>>>8^Ht[0][255&Ht[e][t]]}const It=e=>{const t=e[j],s=t-16;let i=0,r=0;for(;r<=s;)i=Ht[15][255&(e[r++]^i)]^Ht[14][255&(e[r++]^i>>>8)]^Ht[13][255&(e[r++]^i>>>16)]^Ht[12][e[r++]^i>>>24]^Ht[11][e[r++]]^Ht[10][e[r++]]^Ht[9][e[r++]]^Ht[8][e[r++]]^Ht[7][e[r++]]^Ht[6][e[r++]]^Ht[5][e[r++]]^Ht[4][e[r++]]^Ht[3][e[r++]]^Ht[2][e[r++]]^Ht[1][e[r++]]^Ht[0][e[r++]];for(;r!==t;)i=Ht[0][255&(i^e[r++])]^i>>>8;return~i},Mt=(...e)=>{const t=new bt(e.reduce(((e,t)=>e+t[j]),0));return e.reduce(((e,s)=>(t.set(s,e),e+s[j])),0),t},Ut=e=>String.fromCharCode(...e),Ot=[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15],Nt=e=>Ot[15&e]<<4|Ot[e>>4];class $t{constructor(e){this._data=e,this._pos=8*e[j]}set position(e){this._pos=e}get position(){return this._pos}read(e){const t=Math.floor(this._pos/8),s=this._pos%8;this._pos-=e;return(Nt(this._data[t-1])<<8)+Nt(this._data[t])>>7-s&255}}class At{constructor(e,t){this._onCodecHeader=e,this._onCodecUpdate=t,this[_t]()}[mt](){this._isEnabled=!0}[_t](){this._headerCache=new Map,this._codecUpdateData=new WeakMap,this._codecHeaderSent=!1,this._codecShouldUpdate=!1,this._bitrate=null,this._isEnabled=!1}[pt](e,t){if(this._onCodecUpdate){this._bitrate!==e&&(this._bitrate=e,this._codecShouldUpdate=!0);const s=this._codecUpdateData.get(this._headerCache.get(this._currentHeader));this._codecShouldUpdate&&s&&this._onCodecUpdate({bitrate:e,...s},t),this._codecShouldUpdate=!1}}[ht](e){const t=this._headerCache.get(e);return t&&this._updateCurrentHeader(e),t}[ct](e,t,s){this._isEnabled&&(this._codecHeaderSent||(this._onCodecHeader({...t}),this._codecHeaderSent=!0),this._updateCurrentHeader(e),this._headerCache.set(e,t),this._codecUpdateData.set(t,s))}_updateCurrentHeader(e){this._onCodecUpdate&&e!==this._currentHeader&&(this._codecShouldUpdate=!0,this._currentHeader=e)}}const Rt=new WeakMap,Bt=new WeakMap;class Lt{constructor(e,t){this._codecParser=e,this._headerCache=t}*[at](){let e;for(;;){if(e=yield*this.Frame[lt](this._codecParser,this._headerCache,0),e)return e;this._codecParser[tt](1)}}*[ot](e){let t=yield*this[at]();const s=Bt.get(t)[j];if(e||this._codecParser._flushing||(yield*this.Header[ht](this._codecParser,this._headerCache,s)))return this._headerCache[mt](),this._codecParser[tt](s),this._codecParser[it](t),t;this._codecParser[rt](`Missing ${Fe} at ${s} bytes from current position.`,`Dropping current ${Fe} and trying again.`),this._headerCache[_t](),this._codecParser[tt](1)}}class Dt{constructor(e,t){Bt.set(this,{[R]:e}),this[U]=t}}class Tt extends Dt{static*[lt](e,t,s,i,r){const n=yield*e[ht](s,i,r);if(n){const e=Rt.get(n)[He],i=Rt.get(n)[qe];return new t(n,(yield*s[et](e,r))[ne](0,e),i)}return null}constructor(e,t,s){super(e,t),this[R]=e,this[qe]=s,this[N]=s/e[Ge]*1e3,this[Me]=null,this[Xe]=null,this[Ze]=null,this[Ye]=null,Bt.get(this)[j]=t[j]}}const Et="unsynchronizationFlag",Gt="extendedHeaderFlag",zt="experimentalFlag",qt="footerPresent";class Vt{static*getID3v2Header(e,t,s){const i={};let r=yield*e[et](3,s);if(73!==r[0]||68!==r[1]||51!==r[2])return null;if(r=yield*e[et](10,s),i[ae]=`id3v2.${r[3]}.${r[4]}`,15&r[5])return null;if(i[Et]=!!(128&r[5]),i[Gt]=!!(64&r[5]),i[zt]=!!(32&r[5]),i[qt]=!!(16&r[5]),128&r[6]||128&r[7]||128&r[8]||128&r[9])return null;const n=r[6]<<21|r[7]<<14|r[8]<<7|r[9];return i[j]=10+n,new Vt(i)}constructor(e){this[ae]=e[ae],this[Et]=e[Et],this[Gt]=e[Gt],this[zt]=e[zt],this[qt]=e[qt],this[j]=e[j]}}class jt{constructor(e){Rt.set(this,e),this[b]=e[b],this[C]=null,this[we]=e[we],this[ye]=e[ye],this[Ge]=e[Ge]}}const Wt={0:[wt,wt,wt,wt,wt],16:[32,32,32,32,8],240:[St,St,St,St,St]},Jt=(e,t,s)=>8*((e+s)%t+t)*(1<<(e+s)/t)-8*t*(t/8|0);for(let e=2;e<15;e++)Wt[e<<4]=[32*e,Jt(e,4,0),Jt(e,4,-1),Jt(e,8,4),Jt(e,8,0)];const Kt="bands ",Qt=" to 31",Xt={0:Kt+4+Qt,16:Kt+8+Qt,32:Kt+12+Qt,48:Kt+16+Qt},Yt="bitrateIndex",Zt="v2",es="v1",ts="Intensity stereo ",ss=", MS stereo ",is="on",rs="off",ns={0:ts+rs+ss+rs,16:ts+is+ss+rs,32:ts+rs+ss+is,48:ts+is+ss+is},as={0:{[O]:yt},2:{[O]:"Layer III",[Ue]:1,[J]:ns,[es]:{[Yt]:2,[qe]:1152},[Zt]:{[Yt]:4,[qe]:576}},4:{[O]:"Layer II",[Ue]:1,[J]:Xt,[qe]:1152,[es]:{[Yt]:1},[Zt]:{[Yt]:4}},6:{[O]:"Layer I",[Ue]:4,[J]:Xt,[qe]:384,[es]:{[Yt]:0},[Zt]:{[Yt]:3}}},os="MPEG Version ",hs="ISO/IEC ",cs={0:{[O]:`${os}2.5 (later extension of MPEG 2)`,[V]:Zt,[Ge]:{0:11025,4:12e3,8:m,12:yt}},8:{[O]:yt},16:{[O]:`${os}2 (${hs}13818-3)`,[V]:Zt,[Ge]:{0:p,4:d,8:_,12:yt}},24:{[O]:`${os}1 (${hs}11172-3)`,[V]:es,[Ge]:{0:l,4:c,8:u,12:yt}},length:j},ls={0:kt,1:Pt},us={0:Pt,1:"50/15 ms",2:yt,3:"CCIT J.17"},ds={0:{[we]:2,[O]:n},64:{[we]:2,[O]:"joint "+n},128:{[we]:2,[O]:"dual channel"},192:{[we]:1,[O]:r}};class ps extends jt{static*[ht](e,t,s){const i={},r=yield*Vt.getID3v2Header(e,t,s);r&&(yield*e[et](r[j],s),e[tt](r[j]));const n=yield*e[et](4,s),a=Ut(n[ne](0,4)),o=t[ht](a);if(o)return new ps(o);if(255!==n[0]||n[1]<224)return null;const h=cs[24&n[1]];if(h[O]===yt)return null;const c=6&n[1];if(as[c][O]===yt)return null;const l={...as[c],...as[c][h[V]]};if(i[Q]=h[O],i[V]=l[O],i[qe]=l[qe],i[se]=ls[1&n[1]],i[j]=4,i[C]=Wt[240&n[2]][l[Yt]],i[C]===St)return null;if(i[Ge]=h[Ge][12&n[2]],i[Ge]===yt)return null;if(i[Ue]=2&n[2]&&l[Ue],i[z]=!!(1&n[2]),i[He]=Math.floor(125*i[C]*i[qe]/i[Ge]+i[Ue]),!i[He])return null;const u=192&n[3];if(i[ye]=ds[u][O],i[we]=ds[u][we],i[J]=l[J][48&n[3]],i[L]=!!(8&n[3]),i[G]=!!(4&n[3]),i[$]=us[3&n[3]],i[$]===yt)return null;i[b]=16;{const{length:e,frameLength:s,samples:r,...n}=i;t[ct](a,i,n)}return new ps(i)}constructor(e){super(e),this[C]=e[C],this[$]=e[$],this[Ue]=e[Ue],this[L]=e[L],this[G]=e[G],this[z]=e[z],this[V]=e[V],this[J]=e[J],this[Q]=e[Q],this[se]=e[se]}}class _s extends Tt{static*[lt](e,t,s){return yield*super[lt](ps,_s,e,t,s)}constructor(e,t,s){super(e,t,s)}}class ms extends Lt{constructor(e,t,s){super(e,t),this.Frame=_s,this.Header=ps,s(this[v])}get[v](){return K}*[ut](){return yield*this[ot]()}}const gs={0:"MPEG-4",8:"MPEG-2"},fs={0:"valid",2:St,4:St,6:St},bs={0:kt,1:Pt},Cs={0:"AAC Main",64:"AAC LC (Low Complexity)",128:"AAC SSR (Scalable Sample Rate)",192:"AAC LTP (Long Term Prediction)"},ys={0:96e3,4:88200,8:64e3,12:c,16:l,20:u,24:d,28:p,32:_,36:12e3,40:11025,44:m,48:7350,52:yt,56:yt,60:"frequency is written explicitly"},Ss={0:{[we]:0,[O]:"Defined in AOT Specific Config"},64:{[we]:1,[O]:r},128:{[we]:2,[O]:o(2,s[0][0])},192:{[we]:3,[O]:o(3,s[1][3])},256:{[we]:4,[O]:o(4,s[1][3],s[3][4])},320:{[we]:5,[O]:o(5,s[1][3],s[3][0])},384:{[we]:6,[O]:o(6,s[1][3],s[3][0],i)},448:{[we]:8,[O]:o(8,s[1][3],s[2][0],s[3][0],i)}};class ws extends jt{static*[ht](e,t,s){const i={},r=yield*e[et](7,s),n=Ut([r[0],r[1],r[2],252&r[3]|3&r[6]]),a=t[ht](n);if(a)Object.assign(i,a);else{if(255!==r[0]||r[1]<240)return null;if(i[Q]=gs[8&r[1]],i[V]=fs[6&r[1]],i[V]===St)return null;const e=1&r[1];i[se]=bs[e],i[j]=e?7:9,i[te]=192&r[2],i[ze]=60&r[2];const s=2&r[2];if(i[ee]=Cs[i[te]],i[Ge]=ys[i[ze]],i[Ge]===yt)return null;i[z]=!!s,i[Se]=448&(r[2]<<8|r[3]),i[ye]=Ss[i[Se]][O],i[we]=Ss[i[Se]][we],i[G]=!!(32&r[3]),i[T]=!!(8&r[3]),i[ke]=!!(8&r[3]),i[ve]=!!(4&r[3]),i[b]=16,i[qe]=1024,i[X]=3&r[6];{const{length:e,channelModeBits:s,profileBits:r,sampleRateBits:a,frameLength:o,samples:h,numberAACFrames:c,...l}=i;t[ct](n,i,l)}}if(i[He]=8191&(r[3]<<11|r[4]<<3|r[5]>>5),!i[He])return null;const o=2047&(r[5]<<6|r[6]>>2);return i[k]=2047===o?"VBR":o,new ws(i)}constructor(e){super(e),this[ke]=e[ke],this[ve]=e[ve],this[k]=e[k],this[T]=e[T],this[G]=e[G],this[z]=e[z],this[V]=e[V],this[j]=e[j],this[Q]=e[Q],this[X]=e[X],this[ee]=e[ee],this[se]=e[se]}get audioSpecificConfig(){const e=Rt.get(this),t=e[te]+64<<5|e[ze]<<5|e[Se]>>3,s=new bt(2);return new Ct(s[P]).setUint16(0,t,!1),s}}class Ps extends Tt{static*[lt](e,t,s){return yield*super[lt](ws,Ps,e,t,s)}constructor(e,t,s){super(e,t,s)}}class ks extends Lt{constructor(e,t,s){super(e,t),this.Frame=Ps,this.Header=ws,s(this[v])}get[v](){return"aac"}*[ut](){return yield*this[ot]()}}class vs extends Tt{static _getFrameFooterCrc16(e){return(e[e[j]-2]<<8)+e[e[j]-1]}static[ft](e){const t=vs._getFrameFooterCrc16(e),s=(e=>{const t=e[j],s=t-16;let i=0,r=0;for(;r<=s;)i^=e[r++]<<8|e[r++],i=xt[15][i>>8]^xt[14][255&i]^xt[13][e[r++]]^xt[12][e[r++]]^xt[11][e[r++]]^xt[10][e[r++]]^xt[9][e[r++]]^xt[8][e[r++]]^xt[7][e[r++]]^xt[6][e[r++]]^xt[5][e[r++]]^xt[4][e[r++]]^xt[3][e[r++]]^xt[2][e[r++]]^xt[1][e[r++]]^xt[0][e[r++]];for(;r!==t;)i=(255&i)<<8^xt[0][i>>8^e[r++]];return i})(e[ne](0,-2));return t===s}constructor(e,t,s){t[We]=s,t[I]=vs._getFrameFooterCrc16(e),super(t,e,Rt.get(t)[qe])}}const Fs="get from STREAMINFO metadata block",xs={0:"Fixed",1:"Variable"},Hs={0:yt,16:192};for(let e=2;e<16;e++)Hs[e<<4]=e<6?576*2**(e-2):2**e;const Is={0:Fs,1:88200,2:176400,3:192e3,4:m,5:_,6:p,7:d,8:u,9:l,10:c,11:96e3,15:St},Ms={0:{[we]:1,[O]:r},16:{[we]:2,[O]:o(2,s[0][0])},32:{[we]:3,[O]:o(3,s[0][1])},48:{[we]:4,[O]:o(4,s[1][0],s[3][0])},64:{[we]:5,[O]:o(5,s[1][1],s[3][0])},80:{[we]:6,[O]:o(6,s[1][1],i,s[3][0])},96:{[we]:7,[O]:o(7,s[1][1],i,s[3][4],s[2][0])},112:{[we]:8,[O]:o(8,s[1][1],i,s[3][0],s[2][0])},128:{[we]:2,[O]:`${n} (left, diff)`},144:{[we]:2,[O]:`${n} (diff, right)`},160:{[we]:2,[O]:`${n} (avg, diff)`},176:yt,192:yt,208:yt,224:yt,240:yt},Us={0:Fs,2:8,4:12,6:yt,8:16,10:20,12:24,14:yt};class Os extends jt{static _decodeUTF8Int(e){if(e[0]>254)return null;if(e[0]<128)return{value:e[0],length:1};let t=1;for(let s=64;s&e[0];s>>=1)t++;let s=t-1,i=0,r=0;for(;s>0;r+=6,s--){if(128!=(192&e[s]))return null;i|=(63&e[s])<>t)<{let t=0;const s=e[j];for(let i=0;i!==s;i++)t=Ft[t^e[i]];return t})(i[ne](0,r[j]-1)))return null;if(!a){const{blockingStrategyBits:e,frameNumber:s,sampleNumber:i,samples:a,sampleRateBits:o,blockSizeBits:h,crc:c,length:l,...u}=r;t[ct](n,r,u)}return new Os(r)}constructor(e){super(e),this[I]=null,this[ue]=e[ue],this[pe]=e[pe],this[Me]=e[Me],this[Ee]=e[Ee],this[We]=null}}class Ns extends Lt{constructor(e,t,s){super(e,t),this.Frame=vs,this.Header=Os,s(this[v])}get[v](){return"flac"}*_getNextFrameSyncOffset(e){const t=yield*this._codecParser[et](2,0),s=t[j]-2;for(;e{const t=Os[gt](e,this._headerCache);if(t)return new vs(e,t,this._streamInfo);this._codecParser[rt]("Failed to parse Ogg FLAC frame","Skipping invalid FLAC frame")})).filter((e=>!!e))),e}}class $s{static*[ht](e,t,s){const i={};let r=yield*e[et](28,s);if(79!==r[0]||103!==r[1]||103!==r[2]||83!==r[3])return null;i[Ke]=r[4];if(248&r[5])return null;i[E]=!!(4&r[5]),i[D]=!!(2&r[5]),i[B]=!!(1&r[5]);const n=new Ct(bt.from(r[ne](0,28))[P]);i[g]=((e,t)=>{try{return e.getBigInt64(t,!0)}catch{const s=128&e.getUint8(t+7)?-1:1;let i=e.getUint32(t,!0),r=e.getUint32(t+4,!0);return-1===s&&(i=1+~i,r=1+~r),r>1048575&&console.warn("This platform does not support BigInt"),s*(i+r*2**32)}})(n,6),i[Je]=n.getInt32(14,!0),i[De]=n.getInt32(18,!0),i[Re]=n.getInt32(22,!0);const a=r[26];i[j]=a+27,r=yield*e[et](i[j],s),i[He]=0,i[Le]=[],i[Be]=bt.from(r[ne](27,i[j]));for(let e=0,t=0;e{const t=Ws[gt](this._identificationHeader,e,this._headerCache);if(t){null===this._preSkipRemaining&&(this._preSkipRemaining=t[Z]);let s=t[Oe]*t[xe]/1e3*t[Ge];return this._preSkipRemaining>0&&(this._preSkipRemaining-=s,s=this._preSkipRemaining<0?-this._preSkipRemaining:0),new Rs(e,t,s)}this._codecParser[nt]("Failed to parse Ogg Opus Header","Not a valid Ogg Opus file")}))),e}}class Ks extends Tt{constructor(e,t,s){super(t,e,s)}}const Qs={};for(let e=0;e<8;e++)Qs[e+6]=2**(6+e);class Xs extends jt{static[gt](e,t,s,i){if(e[j]<30)throw new Error("Out of data while inside an Ogg Page");const r=Ut(e[ne](0,30)),n=t[ht](r);if(n)return new Xs(n);const a={[j]:30};if("vorbis"!==r.substr(0,7))return null;a[U]=bt.from(e[ne](0,30));const o=new Ct(a[U][P]);if(a[ae]=o.getUint32(7,!0),0!==a[ae])return null;if(a[we]=e[11],a[ye]=h[a[we]-1]||"application defined",a[Ge]=o.getUint32(12,!0),a[y]=o.getInt32(16,!0),a[w]=o.getInt32(20,!0),a[S]=o.getInt32(24,!0),a[me]=Qs[(240&e[28])>>4],a[_e]=Qs[15&e[28]],a[_e]>a[me])return null;if(1!==e[29])return null;a[b]=32,a[ce]=i,a[he]=s;{const{length:e,data:s,version:i,vorbisSetup:n,vorbisComments:o,...h}=a;t[ct](r,a,h)}return new Xs(a)}constructor(e){super(e),this[y]=e[y],this[S]=e[S],this[w]=e[w],this[_e]=e[_e],this[me]=e[me],this[U]=e[U],this[he]=e[he],this[ce]=e[ce]}}class Ys extends Lt{constructor(e,t,s){super(e,t),this.Frame=Ks,s(this[v]),this._identificationHeader=null,this._setupComplete=!1,this._prevBlockSize=null}get[v](){return oe}[dt](e){e[F]=[];for(const t of Bt.get(e)[re])if(1===t[0])this._headerCache[mt](),this._identificationHeader=e[U],this._setupComplete=!1;else if(3===t[0])this._vorbisComments=t;else if(5===t[0])this._vorbisSetup=t,this._mode=this._parseSetupHeader(t),this._setupComplete=!0;else if(this._setupComplete){const s=Xs[gt](this._identificationHeader,this._headerCache,this._vorbisComments,this._vorbisSetup);s?e[F].push(new Ks(t,s,this._getSamples(t,s))):this._codecParser[logError]("Failed to parse Ogg Vorbis Header","Not a valid Ogg Vorbis file")}return e}_getSamples(e,t){const s=this._mode.blockFlags[e[0]>>1&this._mode.mask]?t[me]:t[_e],i=null===this._prevBlockSize?0:(this._prevBlockSize+s)/4;return this._prevBlockSize=s,i}_parseSetupHeader(e){const t=new $t(e),s={count:0,blockFlags:[]};for(;1&~t.read(1););let i;for(;s.count<64&&t.position>0;){Nt(t.read(8));let e=0;for(;0===t.read(8)&&e++<3;);if(4!==e){1+((126&Nt(i))>>1)!==s.count&&this._codecParser[rt]("vorbis derived mode count did not match actual mode count");break}i=t.read(7),s.blockFlags.unshift(1&i),t.position+=6,s.count++}return s.mask=(1<1&&e[De]>1&&this._codecParser[rt]("Unexpected gap in Ogg Page Sequence Number.",`Expected: ${this._pageSequenceNumber+1}, Got: ${e[De]}`),this._pageSequenceNumber=e[De]}_parsePage(e){null===this._isSupported&&(this._pageSequenceNumber=e[De],this._isSupported=this._checkCodecSupport(e)),this._checkPageSequenceNumber(e);const t=Bt.get(e),s=Rt.get(t[R]);let i=0;if(t[re]=s[Le].map((t=>e[U][ne](i,i+=t))),this._continuedPacket[j]&&(t[re][0]=Mt(this._continuedPacket,t[re][0]),this._continuedPacket=new bt),255===s[Be][s[Be][j]-1]&&(this._continuedPacket=Mt(this._continuedPacket,t[re].pop())),null!==this._previousAbsoluteGranulePosition&&(e[qe]=Number(e[g]-this._previousAbsoluteGranulePosition)),this._previousAbsoluteGranulePosition=e[g],this._isSupported){const t=this._parser[dt](e);return this._codecParser[it](t),t}return e}}class ei extends Lt{constructor(e,t,s){super(e,t),this._onCodec=s,this.Frame=As,this.Header=$s,this._streams=new Map,this._currentSerialNumber=null}get[v](){const e=this._streams.get(this._currentSerialNumber);return e?e.codec:""}*[ut](){const e=yield*this[ot](!0);this._currentSerialNumber=e[Je];let t=this._streams.get(this._currentSerialNumber);return t||(t=new Zs(this._codecParser,this._headerCache,this._onCodec),this._streams.set(this._currentSerialNumber,t)),e[E]&&this._streams.delete(this._currentSerialNumber),t._parsePage(e)}}const ti=()=>{};const si=g,ii=f,ri=b,ni=C,ai=y,oi=S,hi=w,ci=P,li=k,ui=v,di=F,pi=x,_i=H,mi=I,gi=M,fi=U,bi=O,Ci=N,yi=$,Si=A,wi=R,Pi=B,ki=L,vi=D,Fi=T,xi=E,Hi=G,Ii=z,Mi=q,Ui=V,Oi=j,Ni=W,$i=J,Ai=K,Ri=Q,Bi=X,Li=Y,Di=Z,Ti=ee,Ei=se,Gi=ie,zi=re,qi=ne,Vi=ae,ji=oe,Wi=he,Ji=ce,Ki=ue,Qi=pe,Xi=_e,Yi=me,Zi=be,er=Ce,tr=ye,sr=we,ir=ke,rr=ve,nr=Fe,ar=xe,or=He,hr=Me,cr=Ue,lr=Oe,ur=$e,dr=Re,pr=Le,_r=De,mr=Ee,gr=Ge,fr=qe,br=je,Cr=We,yr=Je,Sr=Ke,wr=Xe,Pr=Ye,kr=Ze;return e.CodecParser=class{constructor(e,{onCodec:t,onCodecHeader:s,onCodecUpdate:i,enableLogging:r=!1,enableFrameCRC32:n=!0}={}){this._inputMimeType=e,this._onCodec=t||ti,this._onCodecHeader=s||ti,this._onCodecUpdate=i,this._enableLogging=r,this._crc32=n?It:ti,this[_t]()}get[v](){return this._parser?this._parser[v]:""}[_t](){this._headerCache=new At(this._onCodecHeader,this._onCodecUpdate),this._generator=this._getGenerator(),this._generator.next()}*flush(){this._flushing=!0;for(let e=this._generator.next();e.value;e=this._generator.next())yield e.value;this._flushing=!1,this[_t]()}*parseChunk(e){for(let t=this._generator.next(e);t.value;t=this._generator.next())yield t.value}parseAll(e){return[...this.parseChunk(e),...this.flush()]}*_getGenerator(){if(this._inputMimeType.match(/aac/))this._parser=new ks(this,this._headerCache,this._onCodec);else if(this._inputMimeType.match(/mpeg/))this._parser=new ms(this,this._headerCache,this._onCodec);else if(this._inputMimeType.match(/flac/))this._parser=new Ns(this,this._headerCache,this._onCodec);else{if(!this._inputMimeType.match(/ogg/))throw new Error(`Unsupported Codec ${mimeType}`);this._parser=new ei(this,this._headerCache,this._onCodec)}for(this._frameNumber=0,this._currentReadPosition=0,this._totalBytesIn=0,this._totalBytesOut=0,this._totalSamples=0,this._sampleRate=void 0,this._rawData=new Uint8Array(0);;){const e=yield*this._parser[ut]();e&&(yield e)}}*[et](e=0,t=0){let s;for(;this._rawData[j]<=e+t;){if(s=yield,this._flushing)return this._rawData[ne](t);s&&(this._totalBytesIn+=s[j],this._rawData=Mt(this._rawData,s))}return this._rawData[ne](t)}[tt](e){this._currentReadPosition+=e,this._rawData=this._rawData[ne](e)}[st](e){this._sampleRate=e[R][Ge],e[R][C]=e[N]>0?8*Math.round(e[U][j]/e[N]):0,e[Me]=this._frameNumber++,e[Xe]=this._totalBytesOut,e[Ze]=this._totalSamples,e[Ye]=this._totalSamples/this._sampleRate*1e3,e[M]=this._crc32(e[U]),this._headerCache[pt](e[R][C],e[Ye]),this._totalBytesOut+=e[U][j],this._totalSamples+=e[qe]}[it](e){if(e[F]){if(e[E]){let t=e[qe];e[F].forEach((e=>{const s=e[qe];t0?t:0,e[N]=e[qe]/e[R][Ge]*1e3),t-=s,this[st](e)}))}else e[qe]=0,e[F].forEach((t=>{e[qe]+=t[qe],this[st](t)}));e[N]=e[qe]/this._sampleRate*1e3||0,e[Ze]=this._totalSamples,e[Ye]=this._totalSamples/this._sampleRate*1e3||0,e[Xe]=this._totalBytesOut}else this[st](e)}_log(e,t){if(this._enableLogging){const s=[`${v}: ${this[v]}`,`inputMimeType: ${this._inputMimeType}`,`readPosition: ${this._currentReadPosition}`,`totalBytesIn: ${this._totalBytesIn}`,`${Xe}: ${this._totalBytesOut}`],i=Math.max(...s.map((e=>e[j])));t.push(`--stats--${"-".repeat(i-9)}`,...s,"-".repeat(i)),e("codec-parser",t.reduce(((e,t)=>e+"\n "+t),""))}}[rt](...e){this._log(console.warn,e)}[nt](...e){this._log(console.error,e)}},e.absoluteGranulePosition=si,e.bandwidth=ii,e.bitDepth=ri,e.bitrate=ni,e.bitrateMaximum=ai,e.bitrateMinimum=oi,e.bitrateNominal=hi,e.blockSize=Qi,e.blockingStrategy=Ki,e.blocksize0=Xi,e.blocksize1=Yi,e.buffer=ci,e.bufferFullness=li,e.channelMappingFamily=Zi,e.channelMappingTable=er,e.channelMode=tr,e.channels=sr,e.codec=ui,e.codecFrames=di,e.copyrightId=ir,e.copyrightIdStart=rr,e.coupledStreamCount=pi,e.crc=_i,e.crc16=mi,e.crc32=gi,e.data=fi,e.description=bi,e.duration=Ci,e.emphasis=yi,e.frame=nr,e.frameCount=ar,e.frameLength=or,e.frameNumber=hr,e.framePadding=cr,e.frameSize=lr,e.hasOpusPadding=Si,e.header=wi,e.inputSampleRate=ur,e.isContinuedPacket=Pi,e.isCopyrighted=ki,e.isFirstPage=vi,e.isHome=Fi,e.isLastPage=xi,e.isOriginal=Hi,e.isPrivate=Ii,e.isVbr=Mi,e.layer=Ui,e.length=Oi,e.mode=Ni,e.modeExtension=$i,e.mpeg=Ai,e.mpegVersion=Ri,e.numberAACFrames=Bi,e.outputGain=Li,e.pageChecksum=dr,e.pageSegmentTable=pr,e.pageSequenceNumber=_r,e.preSkip=Di,e.profile=Ti,e.protection=Ei,e.rawData=Gi,e.sampleNumber=mr,e.sampleRate=gr,e.samples=fr,e.segments=zi,e.streamCount=br,e.streamInfo=Cr,e.streamSerialNumber=yr,e.streamStructureVersion=Sr,e.subarray=qi,e.totalBytesOut=wr,e.totalDuration=Pr,e.totalSamples=kr,e.version=Vi,e.vorbis=ji,e.vorbisComments=Wi,e.vorbisSetup=Ji,e}({}); diff --git a/libs/thirdparty/ogg-opus-decoder.min.js b/libs/thirdparty/ogg-opus-decoder.min.js new file mode 100644 index 0000000..9525201 Binary files /dev/null and b/libs/thirdparty/ogg-opus-decoder.min.js differ diff --git a/libs/thirdparty/ogg-vorbis-decoder.min.js b/libs/thirdparty/ogg-vorbis-decoder.min.js new file mode 100644 index 0000000..0f030ae --- /dev/null +++ b/libs/thirdparty/ogg-vorbis-decoder.min.js @@ -0,0 +1,195 @@ +/* Copyright 2021-2023 Ethan Halsall. This file is part of wasm-audio-decoders. https://github.com/eshaz/wasm-audio-decoders */ +var t,s;t=this,s=function(t,s){const i=(t,s=4294967295,i=79764919)=>{const e=new Int32Array(256);let r,n,h,o=s;for(r=0;r<256;r++){for(h=r<<24,n=8;n>0;--n)h=2147483648&h?h<<1^i:h<<1;e[r]=h}for(r=0;r>24^t[r])];return o},e=(t,s=i)=>{const e=t=>new Uint8Array(t.length/2).map(((s,i)=>parseInt(t.substring(2*i,2*(i+1)),16))),r=t=>e(t)[0],n=new Map;[,8364,,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,,381,,,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,,382,376].forEach(((t,s)=>n.set(t,s)));const h=new Uint8Array(t.length);let o,a,l,c=!1,u=0,U=42,d=t.length>13&&"dynEncode"===t.substring(0,9),f=0;d&&(f=11,a=r(t.substring(9,f)),a<=1&&(f+=2,U=r(t.substring(11,f))),1===a&&(f+=8,l=(t=>new DataView(e(t).buffer).getInt32(0,!0))(t.substring(13,f))));const p=256-U;for(let i=f;i255){const t=n.get(o);t&&(o=t+127)}c&&(c=!1,o-=64),h[u++]=o0?o+p:o-U}else c=!0;const M=h.subarray(0,u);if(d&&1===a){const t=s(M);if(t!==l){const s="Decode failed crc32 validation";throw console.error("`simple-yenc`\n",s+"\n","Expected: "+l+"; Got: "+t+"\n","Visit https://github.com/eshaz/simple-yenc for more information"),Error(s)}}return M};function r(){const t=Uint8Array,s=Float32Array;r.t||Object.defineProperties(r,{t:{value:new WeakMap},u:{value(t,s){r.t.set(t,Promise.resolve(s))}},U:{value(t,s){let i=r.t.get(t);return i||(s?i=WebAssembly.compile(e(s)):(s=t.M,i=r.Y(s).then((t=>WebAssembly.compile(t)))),r.t.set(t,i)),i}},T:{value(t,i){let e=new s(i),r=0,n=0;for(;r({O:t,channelData:s,samplesDecoded:i,sampleRate:e,bitDepth:r})},v:{value(t,s,i,e,n,h){let o,a,l=[];for(o=0;o{const e=String.raw`dynEncode0114db91da9bu‡*t“““t“““““t““““$#“U¤¤“U¤¤3yƒ†„‰zzss|yu„svu‡yÚ&ˆ“4<054<,5T44^T44<(6U~J(44< ~A544U~6J0444ˆ†545 444J0444‰J,4U“4ˆU“‡…Ò“7U45“4U4Z“4U4U^/6545T4T44BUˆ~64CU~O4U54U~5 U5T4B4Z!4U~5U5U5T4U~6U4ZTU5U5T44~4O4U2ZTU5T44Z!4B6T44Uˆ~64B6U~O44Uˆ~4O4U~54U~5 44~C4~54U~5 44~5454Uˆ4B6Ub!444~UO4U~5 “U5“4U4ZTUŠ#44U$4†64<4~B6^“4<444~Uˆ~B4U~54Uˆ544~544~Uˆ5 µ“Uä#UJUè#5TT4U0ZTTUX5U5T4T4Uà#~4OU4U $~Cˆ4~54U~5 T44$6U\!TTT4UaT4<6T4<64<Z!44~4N4<U~5 4U”Z!4U±_TUŠ#44U•Uˆ6UÔ~B$544$6U\!4Uˆ6U¤#~B44Uä#~B$~64<6_TU‰#444U”~B~6~54<Y!44<_!T4Y!4<64~444~AN44<U~6J4U5 44J4U”[!U#44UŠO4U~54U~5 U54 “7U6844J44J 4UJ4UJ04VK(44<J44<J$4U´~54U~5 4U¤~5!TTT4U$5"U“5TTTTTTT4U$"4VK,U54<(6U~64<$6_!4< 64~6A54A544U~6#J(U’54A4U‡[!44J(44#~A4Uˆ6U“‡UŠU…[!44†64~64_!4<64~54<6T4<4]TU5 T4Y!44~44~AN4U~54U~54U5 44J(44J UÄA!U5U”#UôJU"UÔJUœ#UÔ"JU˜#U´"JT4U´ZTU5T4UôZTU5T4UDZTU5T4U$[T44~UO4U~5 UÔUô4U~U´$.U5T4UP[T4U~4~UO4U~5 U˜#<Uœ#<4U~U2$.UÄUN 44 ~UO4U~5 44!~UO4U~5 4U~4~UO4U~5 44J44J(U5 44U¤~J@44Uä~J<44UD~J844U~J44U$54U$5U‘54U$54U1^4U1^†!4U•~54U~5U”54U~6U4U^/65T4T4U$54U~4BUˆ~4O4U54U~5 UU'464U'_/54UˆU”~5T4T4U~4BUˆ~UO4U54U~5 U54Uä~4U¤~4U~U'$!44~5U5T44\T44U<~$6U\!4U#aT4U~4Uˆ~4O4U~5 U5U5U5TTT4U$"4YTU5 4Uˆ4~C5U5 U5U5444$4~64~\TUŽ5 4U~4Uˆ~5T4Y!44O4U~54U~54U5 4CYTU‹5 4Uä~4U¤~4U~4$6TU54U\!44Bæ4Bä~[!4U~4UD~4U~4Uˆ~4$6TUŒ54U\!44B†4B„~[!44U<~4U4~$5 4U"U˜#$544"†Y!454U^!44<J44<(J454U~84­U”N!#%'+/37?GOWgw‡—·×÷Uä;U”9$%& !"#`;r.U(r,e).then((t=>WebAssembly.instantiate(t,{}))).then((({exports:e})=>{const r=new Map(Object.entries(e)),n=r.get("puff"),h=r.get("memory").buffer,o=new t(h),a=new DataView(h);let l=r.get("__heap_base");const c=s.length,u=l;l+=4,a.setInt32(u,c,!0);const U=l;l+=c,o.set(s,U);const d=l;l+=4,a.setInt32(d,o.byteLength-l,!0),n(l,d,U,u),i(o.slice(l,l+a.getInt32(d,!0)))}))}))}}}),Object.defineProperty(this,"M",{enumerable:!0,get:()=>this.B}),this.F=(t,s,i)=>{let e=[],r=0;for(;r{const e=this.B.V(s.BYTES_PER_ELEMENT*t);return i&&this.S.add(e),{H:e,$:t,C:new s(this.B.I,e,t)}},this.free=()=>{this.S.forEach((t=>{this.B.free(t)})),this.S.clear()},this.J=t=>{const s=[],i=new Uint8Array(this.B.I);for(let e=i[t];0!==e;e=i[++t])s.push(e);return String.fromCharCode.apply(null,s)},this.P=(t,s,i,e,r,n)=>{t.push({message:s,frameLength:i,frameNumber:e,inputBytes:r,outputSamples:n})},this.instantiate=(t,s)=>(s&&r.u(t,s),this.B=new t(r).instantiate(),this.S=new Set,this.B.ready.then((()=>this)))}class n extends((()=>globalThis.Worker||s)()){constructor(t,s,i,e){r.t||new r;let n=r.t.get(i);if(!n){let t,s="text/javascript",h=`'use strict';(${""+((t,s,i)=>{let e,r,n=new Promise((t=>{r=t}));self.onmessage=({data:{id:h,command:o,data:a}})=>{let l,c=n,u={id:h};"init"===o?(Object.defineProperties(t,{D:{value:s},N:{value:i},module:{value:a.module},Z:{value:!0}}),e=new t(a.options),r()):"free"===o?e.free():"ready"===o?c=c.then((()=>e.ready)):"reset"===o?c=c.then((()=>e.reset())):(Object.assign(u,e[o](Array.isArray(a)?a.map((t=>new Uint8Array(t))):new Uint8Array(a))),l=u.channelData?u.channelData.map((t=>t.buffer)):[]),c.then((()=>self.postMessage(u,l)))}})})(${i}, ${r}, ${e})`;try{t=void 0!==process.versions.node}catch{}n=t?`data:${s};base64,${Buffer.from(h).toString("base64")}`:URL.createObjectURL(new Blob([h],{type:s})),r.t.set(i,n)}super(n,{name:s}),this.K=Number.MIN_SAFE_INTEGER,this.R=new Map,this.onmessage=({data:t})=>{const{id:s,...i}=t;this.R.get(s)(i),this.R.delete(s)},new e(r).U().then((s=>{this.G("init",{module:s,options:t})}))}async G(t,s){return new Promise((i=>{this.postMessage({command:t,id:this.K,data:s}),this.R.set(this.K++,i)}))}get ready(){return this.G("ready")}async free(){await this.G("free").finally((()=>{this.terminate()}))}async reset(){await this.G("reset")}}const h=(t,s)=>{Object.defineProperty(t,"name",{value:s})},o=Symbol,a=(()=>{const t="left",s="center",i="right";return["","front ","side ","rear "].map((e=>[[t,i],[t,i,s],[t,s,i],[s,t,i],[s]].flatMap((t=>t.map((t=>e+t)).join(", ")))))})(),l="LFE",c="monophonic (mono)",u="stereo",U="surround",d=(t,...s)=>`${[c,u,"linear "+U,"quadraphonic","5.0 "+U,"5.1 "+U,"6.1 "+U,"7.1 "+U][t-1]} (${s.join(", ")})`,f=[c,d(2,a[0][0]),d(3,a[0][2]),d(4,a[1][0],a[3][0]),d(5,a[1][2],a[3][0]),d(6,a[1][2],a[3][0],l),d(7,a[1][2],a[2][0],a[3][4],l),d(8,a[1][2],a[2][0],a[3][0],l)],p=48e3,M=44100,y=32e3,m=24e3,w=22050,g=16e3,Y=8e3,T="absoluteGranulePosition",b="bandwidth",A="bitDepth",O="bitrate",v=O+"Maximum",B=O+"Minimum",F=O+"Nominal",_="buffer",V=_+"Fullness",k="codec",S=k+"Frames",q="coupledStreamCount",H="crc",$=H+"16",C=H+"32",I="data",j="description",J="duration",x="emphasis",P="hasOpusPadding",D="header",E="isContinuedPacket",N="isCopyrighted",Z="isFirstPage",z="isHome",K="isLastPage",Q="isOriginal",R="isPrivate",G="isVbr",X="layer",L="length",W="mode",tt=W+"Extension",st="mpeg",it=st+"Version",et="numberAACFrames",rt="outputGain",nt="preSkip",ht="profile",ot=o(),at="protection",lt="segments",ct="subarray",ut="version",Ut="vorbis",dt=Ut+"Comments",ft=Ut+"Setup",pt="block",Mt=pt+"ingStrategy",yt=o(),mt=pt+"Size",wt=pt+"size0",gt=pt+"size1",Yt=o(),Tt="channel",bt=Tt+"MappingFamily",At=Tt+"MappingTable",Ot=Tt+"Mode",vt=o(),Bt=Tt+"s",Ft="copyright",_t=Ft+"Id",Vt=Ft+"IdStart",kt="frame",St=kt+"Count",qt=kt+"Length",Ht="Number",$t=kt+Ht,Ct=kt+"Padding",It=kt+"Size",jt="Rate",Jt="inputSample"+jt,xt="page",Pt=xt+"Checksum",Dt=o(),Et=xt+"SegmentTable",Nt=xt+"Sequence"+Ht,Zt="sample",zt=Zt+Ht,Kt=Zt+jt,Qt=o(),Rt=Zt+"s",Gt="stream",Xt=Gt+"Count",Lt=Gt+"Info",Wt=Gt+"Serial"+Ht,ts=Gt+"StructureVersion",ss="total",is=ss+"BytesOut",es=ss+"Duration",rs=ss+"Samples",ns=o(),hs=o(),os=o(),as=o(),ls=o(),cs=o(),us=o(),Us=o(),ds=o(),fs=o(),ps=o(),Ms=o(),ys=o(),ms=o(),ws=o(),gs=o(),Ys=o(),Ts=o(),bs=Uint8Array,As=DataView,Os="reserved",vs="bad",Bs="free",Fs="none",_s="16bit CRC",Vs=(t,s,i)=>{for(let e=0;e0;t--)r=i(r);t[e]=r}return t},ks=Vs(new bs(256),(t=>t),(t=>128&t?7^t<<1:t<<1)),Ss=[Vs(new Uint16Array(256),(t=>t<<8),(t=>t<<1^(32768&t?32773:0)))],qs=[Vs(new Uint32Array(256),(t=>t),(t=>t>>>1^3988292384*(1&t)))];for(let Ye=0;Ye<15;Ye++){Ss.push(new Uint16Array(256)),qs.push(new Uint32Array(256));for(let t=0;t<=255;t++)Ss[Ye+1][t]=Ss[0][Ss[Ye][t]>>>8]^Ss[Ye][t]<<8,qs[Ye+1][t]=qs[Ye][t]>>>8^qs[0][255&qs[Ye][t]]}const Hs=t=>{const s=t[L],i=s-16;let e=0,r=0;for(;r<=i;)e=qs[15][255&(t[r++]^e)]^qs[14][255&(t[r++]^e>>>8)]^qs[13][255&(t[r++]^e>>>16)]^qs[12][t[r++]^e>>>24]^qs[11][t[r++]]^qs[10][t[r++]]^qs[9][t[r++]]^qs[8][t[r++]]^qs[7][t[r++]]^qs[6][t[r++]]^qs[5][t[r++]]^qs[4][t[r++]]^qs[3][t[r++]]^qs[2][t[r++]]^qs[1][t[r++]]^qs[0][t[r++]];for(;r!==s;)e=qs[0][255&(e^t[r++])]^e>>>8;return~e},$s=(...t)=>{const s=new bs(t.reduce(((t,s)=>t+s[L]),0));return t.reduce(((t,i)=>(s.set(i,t),t+i[L])),0),s},Cs=t=>String.fromCharCode(...t),Is=[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15],js=t=>Is[15&t]<<4|Is[t>>4];class Js{constructor(t){this.X=t,this.L=8*t[L]}set position(t){this.L=t}get position(){return this.L}read(t){const s=Math.floor(this.L/8),i=this.L%8;return this.L-=t,(js(this.X[s-1])<<8)+js(this.X[s])>>7-i&255}}class xs{constructor(t,s){this.W=t,this.tt=s,this[ws]()}[gs](){this.st=!0}[ws](){this.it=new Map,this.et=new WeakMap,this.rt=!1,this.nt=!1,this.ht=null,this.st=!1}[ms](t,s){if(this.tt){this.ht!==t&&(this.ht=t,this.nt=!0);const i=this.et.get(this.it.get(this.ot));this.nt&&i&&this.tt({lt:t,...i},s),this.nt=!1}}[ds](t){const s=this.it.get(t);return s&&this.ct(t),s}[fs](t,s,i){this.st&&(this.rt||(this.W({...s}),this.rt=!0),this.ct(t),this.it.set(t,s),this.et.set(s,i))}ct(t){this.tt&&t!==this.ot&&(this.nt=!0,this.ot=t)}}const Ps=new WeakMap,Ds=new WeakMap;class Es{constructor(t,s){this.ut=t,this.it=s}*[us](){let t;for(;;){if(t=yield*this.Ut[ps](this.ut,this.it,0),t)return t;this.ut[hs](1)}}*[Us](t){let s=yield*this[us]();const i=Ds.get(s)[L];if(t||this.ut.dt||(yield*this.ft[ds](this.ut,this.it,i)))return this.it[gs](),this.ut[hs](i),this.ut[as](s),s;this.ut[ls](`Missing ${kt} at ${i} bytes from current position.`,`Dropping current ${kt} and trying again.`),this.it[ws](),this.ut[hs](1)}}class Ns{constructor(t,s){Ds.set(this,{[D]:t}),this[I]=s}}class Zs extends Ns{static*[ps](t,s,i,e,r){const n=yield*t[ds](i,e,r);if(n){const t=Ps.get(n)[qt],e=Ps.get(n)[Rt];return new s(n,(yield*i[ns](t,r))[ct](0,t),e)}return null}constructor(t,s,i){super(t,s),this[D]=t,this[Rt]=i,this[J]=i/t[Kt]*1e3,this[$t]=null,this[is]=null,this[rs]=null,this[es]=null,Ds.get(this)[L]=s[L]}}const zs="unsynchronizationFlag",Ks="extendedHeaderFlag",Qs="experimentalFlag",Rs="footerPresent";class Gs{static*Mt(t,s,i){const e={};let r=yield*t[ns](3,i);if(73!==r[0]||68!==r[1]||51!==r[2])return null;if(r=yield*t[ns](10,i),e[ut]=`id3v2.${r[3]}.${r[4]}`,15&r[5])return null;if(e[zs]=!!(128&r[5]),e[Ks]=!!(64&r[5]),e[Qs]=!!(32&r[5]),e[Rs]=!!(16&r[5]),128&r[6]||128&r[7]||128&r[8]||128&r[9])return null;const n=r[6]<<21|r[7]<<14|r[8]<<7|r[9];return e[L]=10+n,new Gs(e)}constructor(t){this[ut]=t[ut],this[zs]=t[zs],this[Ks]=t[Ks],this[Qs]=t[Qs],this[Rs]=t[Rs],this[L]=t[L]}}class Xs{constructor(t){Ps.set(this,t),this[A]=t[A],this[O]=null,this[Bt]=t[Bt],this[Ot]=t[Ot],this[Kt]=t[Kt]}}const Ls={0:[Bs,Bs,Bs,Bs,Bs],16:[32,32,32,32,8],240:[vs,vs,vs,vs,vs]},Ws=(t,s,i)=>8*((t+i)%s+s)*(1<<(t+i)/s)-8*s*(s/8|0);for(let Ye=2;Ye<15;Ye++)Ls[Ye<<4]=[32*Ye,Ws(Ye,4,0),Ws(Ye,4,-1),Ws(Ye,8,4),Ws(Ye,8,0)];const ti="bands ",si=" to 31",ii={0:ti+4+si,16:ti+8+si,32:ti+12+si,48:ti+16+si},ei="bitrateIndex",ri="v2",ni="v1",hi="Intensity stereo ",oi=", MS stereo ",ai="on",li="off",ci={0:hi+li+oi+li,16:hi+ai+oi+li,32:hi+li+oi+ai,48:hi+ai+oi+ai},ui={0:{[j]:Os},2:{[j]:"Layer III",[Ct]:1,[tt]:ci,[ni]:{[ei]:2,[Rt]:1152},[ri]:{[ei]:4,[Rt]:576}},4:{[j]:"Layer II",[Ct]:1,[tt]:ii,[Rt]:1152,[ni]:{[ei]:1},[ri]:{[ei]:4}},6:{[j]:"Layer I",[Ct]:4,[tt]:ii,[Rt]:384,[ni]:{[ei]:0},[ri]:{[ei]:3}}},Ui="MPEG Version ",di="ISO/IEC ",fi={0:{[j]:Ui+"2.5 (later extension of MPEG 2)",[X]:ri,[Kt]:{0:11025,4:12e3,8:Y,12:Os}},8:{[j]:Os},16:{[j]:`${Ui}2 (${di}13818-3)`,[X]:ri,[Kt]:{0:w,4:m,8:g,12:Os}},24:{[j]:`${Ui}1 (${di}11172-3)`,[X]:ni,[Kt]:{0:M,4:p,8:y,12:Os}},length:L},pi={0:_s,1:Fs},Mi={0:Fs,1:"50/15 ms",2:Os,3:"CCIT J.17"},yi={0:{[Bt]:2,[j]:u},64:{[Bt]:2,[j]:"joint "+u},128:{[Bt]:2,[j]:"dual channel"},192:{[Bt]:1,[j]:c}};class mi extends Xs{static*[ds](t,s,i){const e={},r=yield*Gs.Mt(t,s,i);r&&(yield*t[ns](r[L],i),t[hs](r[L]));const n=yield*t[ns](4,i),h=Cs(n[ct](0,4)),o=s[ds](h);if(o)return new mi(o);if(255!==n[0]||n[1]<224)return null;const a=fi[24&n[1]];if(a[j]===Os)return null;const l=6&n[1];if(ui[l][j]===Os)return null;const c={...ui[l],...ui[l][a[X]]};if(e[it]=a[j],e[X]=c[j],e[Rt]=c[Rt],e[at]=pi[1&n[1]],e[L]=4,e[O]=Ls[240&n[2]][c[ei]],e[O]===vs)return null;if(e[Kt]=a[Kt][12&n[2]],e[Kt]===Os)return null;if(e[Ct]=2&n[2]&&c[Ct],e[R]=!!(1&n[2]),e[qt]=Math.floor(125*e[O]*e[Rt]/e[Kt]+e[Ct]),!e[qt])return null;const u=192&n[3];if(e[Ot]=yi[u][j],e[Bt]=yi[u][Bt],e[tt]=c[tt][48&n[3]],e[N]=!!(8&n[3]),e[Q]=!!(4&n[3]),e[x]=Mi[3&n[3]],e[x]===Os)return null;e[A]=16;{const{length:t,frameLength:i,yt:r,...n}=e;s[fs](h,e,n)}return new mi(e)}constructor(t){super(t),this[O]=t[O],this[x]=t[x],this[Ct]=t[Ct],this[N]=t[N],this[Q]=t[Q],this[R]=t[R],this[X]=t[X],this[tt]=t[tt],this[it]=t[it],this[at]=t[at]}}class wi extends Zs{static*[ps](t,s,i){return yield*super[ps](mi,wi,t,s,i)}constructor(t,s,i){super(t,s,i)}}class gi extends Es{constructor(t,s,i){super(t,s),this.Ut=wi,this.ft=mi,i(this[k])}get[k](){return st}*[Ms](){return yield*this[Us]()}}const Yi={0:"MPEG-4",8:"MPEG-2"},Ti={0:"valid",2:vs,4:vs,6:vs},bi={0:_s,1:Fs},Ai={0:"AAC Main",64:"AAC LC (Low Complexity)",128:"AAC SSR (Scalable Sample Rate)",192:"AAC LTP (Long Term Prediction)"},Oi={0:96e3,4:88200,8:64e3,12:p,16:M,20:y,24:m,28:w,32:g,36:12e3,40:11025,44:Y,48:7350,52:Os,56:Os,60:"frequency is written explicitly"},vi={0:{[Bt]:0,[j]:"Defined in AOT Specific Config"},64:{[Bt]:1,[j]:c},128:{[Bt]:2,[j]:d(2,a[0][0])},192:{[Bt]:3,[j]:d(3,a[1][3])},256:{[Bt]:4,[j]:d(4,a[1][3],a[3][4])},320:{[Bt]:5,[j]:d(5,a[1][3],a[3][0])},384:{[Bt]:6,[j]:d(6,a[1][3],a[3][0],l)},448:{[Bt]:8,[j]:d(8,a[1][3],a[2][0],a[3][0],l)}};class Bi extends Xs{static*[ds](t,s,i){const e={},r=yield*t[ns](7,i),n=Cs([r[0],r[1],r[2],252&r[3]|3&r[6]]),h=s[ds](n);if(h)Object.assign(e,h);else{if(255!==r[0]||r[1]<240)return null;if(e[it]=Yi[8&r[1]],e[X]=Ti[6&r[1]],e[X]===vs)return null;const t=1&r[1];e[at]=bi[t],e[L]=t?7:9,e[ot]=192&r[2],e[Qt]=60&r[2];const i=2&r[2];if(e[ht]=Ai[e[ot]],e[Kt]=Oi[e[Qt]],e[Kt]===Os)return null;e[R]=!!i,e[vt]=448&(r[2]<<8|r[3]),e[Ot]=vi[e[vt]][j],e[Bt]=vi[e[vt]][Bt],e[Q]=!!(32&r[3]),e[z]=!!(8&r[3]),e[_t]=!!(8&r[3]),e[Vt]=!!(4&r[3]),e[A]=16,e[Rt]=1024,e[et]=3&r[6];{const{length:t,wt:i,gt:r,Yt:h,frameLength:o,yt:a,Tt:l,...c}=e;s[fs](n,e,c)}}if(e[qt]=8191&(r[3]<<11|r[4]<<3|r[5]>>5),!e[qt])return null;const o=2047&(r[5]<<6|r[6]>>2);return e[V]=2047===o?"VBR":o,new Bi(e)}constructor(t){super(t),this[_t]=t[_t],this[Vt]=t[Vt],this[V]=t[V],this[z]=t[z],this[Q]=t[Q],this[R]=t[R],this[X]=t[X],this[L]=t[L],this[it]=t[it],this[et]=t[et],this[ht]=t[ht],this[at]=t[at]}get bt(){const t=Ps.get(this),s=t[ot]+64<<5|t[Qt]<<5|t[vt]>>3,i=new bs(2);return new As(i[_]).setUint16(0,s,!1),i}}class Fi extends Zs{static*[ps](t,s,i){return yield*super[ps](Bi,Fi,t,s,i)}constructor(t,s,i){super(t,s,i)}}class _i extends Es{constructor(t,s,i){super(t,s),this.Ut=Fi,this.ft=Bi,i(this[k])}get[k](){return"aac"}*[Ms](){return yield*this[Us]()}}class Vi extends Zs{static At(t){return(t[t[L]-2]<<8)+t[t[L]-1]}static[Ts](t){const s=Vi.At(t),i=(t=>{const s=t[L],i=s-16;let e=0,r=0;for(;r<=i;)e^=t[r++]<<8|t[r++],e=Ss[15][e>>8]^Ss[14][255&e]^Ss[13][t[r++]]^Ss[12][t[r++]]^Ss[11][t[r++]]^Ss[10][t[r++]]^Ss[9][t[r++]]^Ss[8][t[r++]]^Ss[7][t[r++]]^Ss[6][t[r++]]^Ss[5][t[r++]]^Ss[4][t[r++]]^Ss[3][t[r++]]^Ss[2][t[r++]]^Ss[1][t[r++]]^Ss[0][t[r++]];for(;r!==s;)e=(255&e)<<8^Ss[0][e>>8^t[r++]];return e})(t[ct](0,-2));return s===i}constructor(t,s,i){s[Lt]=i,s[$]=Vi.At(t),super(s,t,Ps.get(s)[Rt])}}const ki="get from STREAMINFO metadata block",Si={0:"Fixed",1:"Variable"},qi={0:Os,16:192};for(let Ye=2;Ye<16;Ye++)qi[Ye<<4]=Ye<6?576*2**(Ye-2):2**Ye;const Hi={0:ki,1:88200,2:176400,3:192e3,4:Y,5:g,6:w,7:m,8:y,9:M,10:p,11:96e3,15:vs},$i={0:{[Bt]:1,[j]:c},16:{[Bt]:2,[j]:d(2,a[0][0])},32:{[Bt]:3,[j]:d(3,a[0][1])},48:{[Bt]:4,[j]:d(4,a[1][0],a[3][0])},64:{[Bt]:5,[j]:d(5,a[1][1],a[3][0])},80:{[Bt]:6,[j]:d(6,a[1][1],l,a[3][0])},96:{[Bt]:7,[j]:d(7,a[1][1],l,a[3][4],a[2][0])},112:{[Bt]:8,[j]:d(8,a[1][1],l,a[3][0],a[2][0])},128:{[Bt]:2,[j]:u+" (left, diff)"},144:{[Bt]:2,[j]:u+" (diff, right)"},160:{[Bt]:2,[j]:u+" (avg, diff)"},176:Os,192:Os,208:Os,224:Os,240:Os},Ci={0:ki,2:8,4:12,6:Os,8:16,10:20,12:24,14:Os};class Ii extends Xs{static Ot(t){if(t[0]>254)return null;if(t[0]<128)return{value:t[0],length:1};let s=1;for(let n=64;n&t[0];n>>=1)s++;let i=s-1,e=0,r=0;for(;i>0;r+=6,i--){if(128!=(192&t[i]))return null;e|=(63&t[i])<>s)<{let s=0;const i=t[L];for(let e=0;e!==i;e++)s=ks[s^t[e]];return s})(e[ct](0,r[L]-1)))return null;if(!h){const{vt:t,frameNumber:i,Bt:e,yt:h,Yt:o,Ft:a,_t:l,length:c,...u}=r;s[fs](n,r,u)}return new Ii(r)}constructor(t){super(t),this[$]=null,this[Mt]=t[Mt],this[mt]=t[mt],this[$t]=t[$t],this[zt]=t[zt],this[Lt]=null}}class ji extends Es{constructor(t,s,i){super(t,s),this.Ut=Vi,this.ft=Ii,i(this[k])}get[k](){return"flac"}*Vt(t){const s=yield*this.ut[ns](2,0),i=s[L]-2;for(;t{const s=Ii[Ys](t,this.it);if(s)return new Vi(t,s,this.kt);this.ut[ls]("Failed to parse Ogg FLAC frame","Skipping invalid FLAC frame")})).filter((t=>!!t))),t}}class Ji{static*[ds](t,s,i){const e={};let r=yield*t[ns](28,i);if(79!==r[0]||103!==r[1]||103!==r[2]||83!==r[3])return null;if(e[ts]=r[4],248&r[5])return null;e[K]=!!(4&r[5]),e[Z]=!!(2&r[5]),e[E]=!!(1&r[5]);const n=new As(bs.from(r[ct](0,28))[_]);e[T]=(t=>{try{return t.getBigInt64(6,!0)}catch{const s=128&t.getUint8(13)?-1:1;let i=t.getUint32(6,!0),e=t.getUint32(10,!0);return-1===s&&(i=1+~i,e=1+~e),e>1048575&&console.warn("This platform does not support BigInt"),s*(i+e*2**32)}})(n),e[Wt]=n.getInt32(14,!0),e[Nt]=n.getInt32(18,!0),e[Pt]=n.getInt32(22,!0);const h=r[26];e[L]=h+27,r=yield*t[ns](e[L],i),e[qt]=0,e[Et]=[],e[Dt]=bs.from(r[ct](27,e[L]));for(let o=0,a=0;o{const s=Li[Ys](this.Ht,t,this.it);if(s){null===this.$t&&(this.$t=s[nt]);let i=s[It]*s[St]/1e3*s[Kt];return this.$t>0&&(this.$t-=i,i=this.$t<0?-this.$t:0),new Pi(t,s,i)}this.ut[cs]("Failed to parse Ogg Opus Header","Not a valid Ogg Opus file")}))),t}}class te extends Zs{constructor(t,s,i){super(s,t,i)}}const se={};for(let Ye=0;Ye<8;Ye++)se[Ye+6]=2**(6+Ye);class ie extends Xs{static[Ys](t,s,i,e){if(t[L]<30)throw Error("Out of data while inside an Ogg Page");const r=Cs(t[ct](0,30)),n=s[ds](r);if(n)return new ie(n);const h={[L]:30};if("vorbis"!==r.substr(0,7))return null;h[I]=bs.from(t[ct](0,30));const o=new As(h[I][_]);if(h[ut]=o.getUint32(7,!0),0!==h[ut])return null;if(h[Bt]=t[11],h[Ot]=f[h[Bt]-1]||"application defined",h[Kt]=o.getUint32(12,!0),h[v]=o.getInt32(16,!0),h[F]=o.getInt32(20,!0),h[B]=o.getInt32(24,!0),h[gt]=se[(240&t[28])>>4],h[wt]=se[15&t[28]],h[wt]>h[gt])return null;if(1!==t[29])return null;h[A]=32,h[ft]=e,h[dt]=i;{const{length:t,data:i,version:e,Ct:n,It:o,...a}=h;s[fs](r,h,a)}return new ie(h)}constructor(t){super(t),this[v]=t[v],this[B]=t[B],this[F]=t[F],this[wt]=t[wt],this[gt]=t[gt],this[I]=t[I],this[dt]=t[dt],this[ft]=t[ft]}}class ee extends Es{constructor(t,s,i){super(t,s),this.Ut=te,i(this[k]),this.Ht=null,this.jt=!1,this.Jt=null}get[k](){return Ut}[ys](t){t[S]=[];for(const s of Ds.get(t)[lt])if(1===s[0])this.it[gs](),this.Ht=t[I],this.jt=!1;else if(3===s[0])this.xt=s;else if(5===s[0])this.Pt=s,this.Dt=this.Et(s),this.jt=!0;else if(this.jt){const i=ie[Ys](this.Ht,this.it,this.xt,this.Pt);i?t[S].push(new te(s,i,this.Nt(s,i))):this.ut[logError]("Failed to parse Ogg Vorbis Header","Not a valid Ogg Vorbis file")}return t}Nt(t,s){const i=this.Dt.Zt[t[0]>>1&this.Dt.mask]?s[gt]:s[wt],e=null===this.Jt?0:(this.Jt+i)/4;return this.Jt=i,e}Et(t){const s=new Js(t),i={count:0,Zt:[]};for(;1&~s.read(1););let e;for(;i.count<64&&s.position>0;){js(s.read(8));let t=0;for(;0===s.read(8)&&t++<3;);if(4!==t){1+((126&js(e))>>1)!==i.count&&this.ut[ls]("vorbis derived mode count did not match actual mode count");break}e=s.read(7),i.Zt.unshift(1&e),s.position+=6,i.count++}return i.mask=(1<1&&t[Nt]>1&&this.ut[ls]("Unexpected gap in Ogg Page Sequence Number.",`Expected: ${this.ss+1}, Got: ${t[Nt]}`),this.ss=t[Nt]}es(t){null===this.Rt&&(this.ss=t[Nt],this.Rt=this.Wt(t)),this.ts(t);const s=Ds.get(t),i=Ps.get(s[D]);let e=0;if(s[lt]=i[Et].map((s=>t[I][ct](e,e+=s))),this.Kt[L]&&(s[lt][0]=$s(this.Kt,s[lt][0]),this.Kt=new bs),255===i[Dt][i[Dt][L]-1]&&(this.Kt=$s(this.Kt,s[lt].pop())),null!==this.Gt&&(t[Rt]=Number(t[T]-this.Gt)),this.Gt=t[T],this.Rt){const s=this.Lt[ys](t);return this.ut[as](s),s}return t}}class ne extends Es{constructor(t,s,i){super(t,s),this.zt=i,this.Ut=xi,this.ft=Ji,this.rs=new Map,this.ns=null}get[k](){const t=this.rs.get(this.ns);return t?t.hs:""}*[Ms](){const t=yield*this[Us](!0);this.ns=t[Wt];let s=this.rs.get(this.ns);return s||(s=new re(this.ut,this.it,this.zt),this.rs.set(this.ns,s)),t[K]&&this.rs.delete(this.ns),s.es(t)}}const he=()=>{};class oe{constructor(t,{os:s,ls:i,cs:e,us:r=!1,Us:n=!0}={}){this.ds=t,this.zt=s||he,this.W=i||he,this.tt=e,this.fs=r,this.ps=n?Hs:he,this[ws]()}get[k](){return this.Lt?this.Lt[k]:""}[ws](){this.it=new xs(this.W,this.tt),this.Ms=this.ys(),this.Ms.next()}*flush(){this.dt=!0;for(let t=this.Ms.next();t.value;t=this.Ms.next())yield t.value;this.dt=!1,this[ws]()}*ws(t){for(let s=this.Ms.next(t);s.value;s=this.Ms.next())yield s.value}parseAll(t){return[...this.ws(t),...this.flush()]}*ys(){if(this.ds.match(/aac/))this.Lt=new _i(this,this.it,this.zt);else if(this.ds.match(/mpeg/))this.Lt=new gi(this,this.it,this.zt);else if(this.ds.match(/flac/))this.Lt=new ji(this,this.it,this.zt);else{if(!this.ds.match(/ogg/))throw Error("Unsupported Codec "+mimeType);this.Lt=new ne(this,this.it,this.zt)}for(this.gs=0,this.Ys=0,this.Ts=0,this.bs=0,this.As=0,this.Os=void 0,this.vs=new Uint8Array(0);;){const t=yield*this.Lt[Ms]();t&&(yield t)}}*[ns](t=0,s=0){let i;for(;this.vs[L]<=t+s;){if(i=yield,this.dt)return this.vs[ct](s);i&&(this.Ts+=i[L],this.vs=$s(this.vs,i))}return this.vs[ct](s)}[hs](t){this.Ys+=t,this.vs=this.vs[ct](t)}[os](t){this.Os=t[D][Kt],t[D][O]=t[J]>0?8*Math.round(t[I][L]/t[J]):0,t[$t]=this.gs++,t[is]=this.bs,t[rs]=this.As,t[es]=this.As/this.Os*1e3,t[C]=this.ps(t[I]),this.it[ms](t[D][O],t[es]),this.bs+=t[I][L],this.As+=t[Rt]}[as](t){if(t[S]){if(t[K]){let s=t[Rt];t[S].forEach((t=>{const i=t[Rt];s0?s:0,t[J]=t[Rt]/t[D][Kt]*1e3),s-=i,this[os](t)}))}else t[Rt]=0,t[S].forEach((s=>{t[Rt]+=s[Rt],this[os](s)}));t[J]=t[Rt]/this.Os*1e3||0,t[rs]=this.As,t[es]=this.As/this.Os*1e3||0,t[is]=this.bs}else this[os](t)}Bs(t,s){if(this.fs){const i=[`${k}: ${this[k]}`,"inputMimeType: "+this.ds,"readPosition: "+this.Ys,"totalBytesIn: "+this.Ts,`${is}: ${this.bs}`],e=Math.max(...i.map((t=>t[L])));s.push("--stats--"+"-".repeat(e-9),...i,"-".repeat(e)),t("codec-parser",s.reduce(((t,s)=>t+"\n "+s),""))}}[ls](...t){this.Bs(console.warn,t)}[cs](...t){this.Bs(console.error,t)}}const ae=S,le=I,ce=D,ue=K,Ue=dt,de=ft,fe=rs;function pe(t){function s(){}for(var i=new Uint8Array(123),e=25;e>=0;--e)i[48+e]=52+e,i[65+e]=e,i[97+e]=26+e;var r,n;i[43]=62,i[47]=63,pe.M||Object.defineProperty(pe,"M",{get:()=>String.raw`dynEncode01a33fc84f8dïoØå§ä³¨s¢þéõ?§šæ—ƒQ¬·ñì>_•å”è£Mí'…ËÏÊí çåzmòeúaݐ§¢é,šî= 9z…ó¡= $.JõT¬K„'¨®ç ƒä“Ó·ßé‘àäà(u¾ŽÃ÷¯ÃìÍH¶3KQtíŒ;Çø=}ÉóX=}Çã»°£)½SÉVy{oEqûUHhéì8÷7ó[Ÿ”¼ˆiÖ¨A2º»ƒÈ(ä+Ú»‰Ðé*7šç}ìÏց@ü€¿À¿B;?=}A?>ýÿûüÿ~{xÎ#†ë5X.]J +=Mi=M°UH +˜5šâ’ª±ÀéOmrn¿¯2Ljª•˜{• ÝájÔֆ ±Û©bŸÕé)j{èüül8üàJr/¡™¨‘‡²Ýþ^UÜàÈO6܅jÙ5èâ×að1º€HH=M2Û6íÊóI̧[TÜïÚÉ)„ÁW|âßHeF,l Ì¥ 'ž0Äb8ÏK“ß è!Œe‘€J +vÑz–Œ& WrnV "5Êñ ýkwP”4Ãp¨‘¸RAx[p¼Ïóƒ;š7>ÃÑþ¨VU?°Rˆ›q9~ò‰Q”ڃw‡I=}­žœ• f›òÔ·rñ¾ª¸gðx7QE5-±®M߀ãl–?£Á•ãÃE óØ{ËÒÂÌ@µ –z5fñ‘}.;¾ê%Mi‡‰_³ZU@å.ɂñ‰î¾Þ€m„Ät†×¢. ,ä²BB;朤‘äûûZ_¡V)Œ‡ŒªAUµ¾BfÈéŸ Ò&§¦$¢Š»ôåÀk£z‹(Ÿ_zܟ^r>†ï ¾bˆ>ÁŽð/ªÄDTçQŽlÄIÒ°Q}:8_þŽ!@ßvñ!œOö +\”\ebVpȜ±Ö~\¥NÐ'eŸBœb·#ÈN¥ŸY ßà#W´0a]¼!þ½\nרT¿¿‡¶çÉS­îäx7óÎ6ñI-ììùpfåh¸Çú,cµÔeiÂeic ÓÂçˆ#ê²up¹aÛÝb0¼þ7–Ÿ™Ü”>F3ÞÔTþñfkï±bxö”€„öfٍ†ˆ±…6H„”ΟÊß6 šÒ°ÂyV¶Á?»‰‚@?{¨Q¥+=}¥±ÿԓÌá9%û!>Âì&¸Õ@Ó„Uùq÷?ñqt˜¿“çIU+÷g‚y+5sä +¼¬åí• GÖ®‡S1Kƒ;…B\©™f‹hX˜d)ºÐ¿²Uw ûûX1ƒ5°Ò1„LÁ”-Œ;j= piN:}îºB¯ÅÉwXtô§¶¸3Œy¶¯oJáàLž¸jÎn®În -ЏýûÄàsT ½ÎòÓÄes ´{OsèÚÎþ´ƒÇ“å9SekF†‰TV³úŽK-”š÷WE¾OÔ +µR½‹ø*ٞvVèJ°§†¼Å¤ªàCŠœsr²^Õvü3ããÔ¯/´ Poü|$ RÞ§KuÉ#þ‰[ªß{¦ÑVú>ý>Ôws~~š9ž=Mz¶-ږ•hiò>ñ²1ždüÿ!ü>ý>í¾¿ñ赙À ž/«~yæ¨Êwór„b0©ì!ˆ ~°»Ïžøj§Ý#ß88š÷AlÛ¦3¹ÇS8“oK:xÜ×'dAkÉÜ<É;–)3ÀbÐ{í«Û5?þ +ÈNøRÙᾙ¹/+ß>ۏ¾6åô}mzQ|p÷Mž¼ðjÑí©;2½&Ì#g×g|/[k*Zõ8ZvãXƒçàF–ª¯a*÷«ª+V,\¨rÏâ'É:G-àëˆW£óÿ‡ˆîŸ‚8rpÿ]k€=Mîéû|]´$Î"’îá“VìDŽ_d%~m¢>aj%U6¨^8"žb ]¥®}l†ì­ïèÈfõ lÔ֋çÝÜIÃqÜ;ñ‘°[‚ÙåTàÆä>í•÷™õ{¯oí½3*iú•D¿gÔæÁ@sÙ Ñèځ=MÉkáÑüçuêÕÙðw¨ À ³Fô~{ï_µ9Ѭ5,}í5×0ÿ>_6l*{îò)¯GjE7(aôrÃbôÚj˜Ç½ T°ÜÃÄgk;ß_߇Â֍ûÄRZðùÒ¸§=MX*gê[ÉXÚ©^uN„~u~® +:Õ_NøW‰ëP\^WpÀttØ÷2ÿ2wTØï2þ2v6y6;V˜ÌۆI÷?ªê„̶^&>&í£F]VBfŒ¨Tße|þîõ¹ù±úÁ$˜]ö wá†yƒÏV.îbÁۂŠÆ.Þð¡ØÛ†ïtnZ$þ:—KÌòñӘð?«Ÿ»…±l“â¶ +SӀÿZ·ƒ©'7 +s%»4äcL+øÈ{ +^ÑKCU¨n9ðÑ~g³/rӆV$ +[cÉ6 &›(¿ô‚qðx ú’Æ6ÞYSÇO×Èò{ ’-L;áèÚÆUhk(öyžÄ„è7´Þ1CY˜¤Dèé׃40,ä$Em9†¦S£"¨ü“ÇkU€ô¹ŠË UgÎ{>%[2\ösiUîçÓ.œÀ¨ãôÂÏûÇ~që¤ +˜$¼À&*ãhæM#Ïî8å#ûûU@·I‡§a†Âú[Hc°cŠ¥öém¶«è䪪ˆ#÷‡ˆñg;ß¾óºš/9í? g~ïB9¨'Süß.›),‡gi±Æèzåëf¹,Èâ^k¿|Ð= ”ÿÉUvˆñÚÍÖـ"&•|ª[Å¢lŽy‚D¸ÖÏñI´QCÑWõȉà°zÈ2_Ǹß(ËÒ¹pi}çkU̇-PV$MÍ)}éžD×q¹{¤aä†.|í+/ýºIë¸××I¥^bü½ö?Ñ/ưuCH¥g±•‚|¹MÞ#L²„ææûºÿ 'œîA-÷B¿7<ޙԭ 9ì&Ô¢fÓ1EãÈ/ cE%5ÙO‡£.uK~¨¸;Ëíô°ÿu7uRö¦×³…®= °~£3€0Èö‡ˆpI ìx‚ûŸ)þÏXËyey„o I%Ùý°ðà8­Kð!9¡ƒ‰C£'Ý Y0¶±Ú}îùÛÆze"ߦ[ÌM…ˆ÷qAš?¬;QW–et„ bW¬ýÛ)aW–et„+*˜¾­j¥h8Î +ÉëÎ +~øqù|ô*= DÑW©â +q'$iÇùçÆ®sç4|¶¢USæK|cÅÀ(46?µŠƒ#ËM0÷rYNAP÷r¦á«Ò×{²¶ÁØäpg´e—Ý|¸ìH=MïmÿOn@óå+(÷Ð MI3“ìñÈó倝Óz*^,áÿJ²Úz* [Òíxê|Žfp˜„ûÂûûBŒf4þs*þs*ö [ñ‘bG²ÐnjÄ%Àßñ«Zù\è¬è ‘ K-ÚÈ®”Û“×ΏVyT­´1˜bØüJÅZÕüJÅÚ=}›<ó´nul/6|@{æÔî½àb|é ª³½wTŒAª³uêÀ.¸šNvΘ‘æSUL-÷h›rH7ÙV +VÕ-pL¿ã.PÒ¿êÃÿqÎÁE­k…ÜŒ¦ÙÇéÙ²—l¥(t³p–OYúHp’cÖ¸ó„æÞy5½¶ÎÕ9Ȍ³˜³²ô³2§'6Š­´É‘»_9Ɏ^¿Ï«;ÙËa­&rb—f±_ZØÀª%#ŽÎh?̑;zÀVš‰j¿Ž2lúꋆGÂ^hì +ÊÀþߌðT†Gximü1Oå®&¥ïߗµe‰cË/9/ÍN͟ê¤MÎü´M +ƒ•]Fökj®òJ¤C©K•'îO§•GiÆb6ô¡ØfÒéþ‚h°¶˜À= µfŠaG€Hߵэ¬Ãà ÖO¥*–Ýh·s-#ýtúø*³D¡S6(t,ÀF0(´¡†¿nƒ,Ùádý˜Y@²íۄâÀnhé9ÿ{~@øJèT\†VåԞOó¢üdr턦ür… +¨& +ÝJB¸ŸV%tr­QžóӞO—Våâ SBi¾ÿڐçܘÄ6OLi.p·Å(›Õ“xD¨ +D¨¼¬ ؍ª¼L9¯¨ÌšÓn¤° BªbêtÓ«óÚ;[K°èî¦AÀ—Ο™0ý'ð§|ÌÒÌ÷´rq½ó ̎µazûû8œm´Ê/ŸœV:È&®¬ØÌZ& Uk£‡r¿Ãî9>ÊR‡rѤçśz"ÈBw&!Aúÿ’‘üd˜–&ù¤º¤ûë©ÿ?þlâSwÉ£kl¾2ž9²bÏáz«–­®k€(Ȫ-Ðgýuäƪa­ß÷Ðî5A3*®ÖÖ»­·G‚V@øb1r# éof:&z:ryG~qb˜f“ÜVš\Q°%¿¦cœåþ„¤6á0n"՘a•Õ:¬®{ ™$îN³ºüÜ~=}Ą6¬ÁÛÏÓ¥Y¬ŒÆ€m‚šÝÜÀ,ØAà64æ0kÐÇižL#=MMôk%9ÿ[þ|Ä[Á<0¯ ý¥þÖváÐ\yí¬-zÌOï1ä@ ¤†ÙÙ®»…ÏÈïõ¯•j¢×ì”=}G›þÈÌûû¢r5·5¥„ƒ×ZíõÅä֔þ&žRX*ƒü°Q:ýBÖ.ùžkô){©Ô™B­>´MLZØî’Rf," ŸÊ⟢¢p¦Ò"ìÖ!¡o4•ºÕ††z0ŸŠÎÆm0'$¦g,ˆžòߖö k†bßì°qºU‰L?R©@c‹4¯Öçî쐁 U ú˜Û‹(ZEO DXzÄC=}°×D$ãÞ)é]S²œÄz¿¾ß‚ÝEL·kÍMVañ„%FJ +4ôñ=Mچ™fÒ¶‡AÉÂíÁ|…Ô¤joÁÏ3ÜV5íÇ-:5rKÜ[uò¦\ŽÀÜ]3ނµÂ«âQÙúх åô=}*´TLß8Åî7>Â'±„:LCdh úÕe÷͏M73ëFrԉmÝР“†ÿÀ’ÓM|"6d‡@O…¹‘cs‚Z¡g%n’B³ý£UMŒKÅÖ0Ý8ÒõÏu·ø¶g͜¡ñš¾€ÚÓN Š0þR)h= †þ‘P{nøQ€I3Åß314™’ÐT‘= Ìy”Åy¾–l܅= ÚÃiUCg´WœQ(ŠÁ$^])Ù⑥þ 2­Û·>å˜ms&b¼úªèôQ'Yè¨FüyIr1ýÎmaî0' ÇÈýªÿ’#}^W_W}2QjAÂ*ϐšO¾“rûÿ +Dñöëß_\Z= Â)¡# ú„⟡]ôö¯öx1ÓȒ6γ5_x}']Ö+—ü\c°”O×ì9¯g_³Šd‘óai"©[9ûЀC¹^\:R¢ìŵ‡ýrt‡q׉Çܹ–‰'ÆY[7lÅ4ÓtÒ¡SÛà -W~ üx¯d…ãG@fýÉOsó–Í@O¹ g.æ ,ŒHåÑ?_w‰Š•XÜi~ZS(E¶²ü×¹RJ=M¹Å_=Mø˜ÑL^ålZcþ‹ëÙõðÛà„¸‚õ/ð±Üzé/™whW:ÍÐFÔ #ÉG´ÂÈWŸ²ÿÌM+ínríî#ÌDoñ•„L}ª.–ñ¸ŠçpƒÑ}Ê YW’õ]jãN¬k¸Áç÷F€Lã äªÇÔ)üõ¤ùæÈð} +æ® õ9~%žñõª÷èþæutµØî «ï‚h w3ZyVÖfÛÓÖ/fOP= =M»Ô4ßýa3‘øœ¿„‡$±äšFY\ò[¬)¢Rø¼‘fلO ü71w¿ŠæZlý֋° +ÓÚ? .)fsnW®Æù–«Iò‡Í?Uñš¥A1ƒ¢7+_꼉ßÝÙâÕЦ]s¿îs¿ðS9šÓšŽú ÞWLs_Iu™=M¨6ÛèÝë§bCgт {F¼©¦¶ÌKDZüMv•)Fº»ý»è eI ÏÚëÆ*$&Ù轔Öe´XSX×øØê½ñ4 ÍàG+ôgÒ  ÈVæT[å^~×?|#K·ÇlLÎØi;ùV'j÷œ0ðÀók—=MîAxyvšJbÞà0ŒVHÈA€¤M¸;O¸‘/(SÔ«¦üÆ3؍kU´Jf³)óg»1W¾‚lÄë§1ŠTõù݇’†d%=MaPu™í(pD\0Þ0;7àe“(ÙД´¬µ o6˪@L$Žë¸Ç×cL›Jß¼Òó,]þ&5µÒ‚&ñ´…tÉvâPŠx XŽÔ šÔ8ç‹ÖHëKÊ0]f ê8-rüºªå±­¼(óåНµÒ3äóOôIø—Áþìj# = —bF%4»XîÛð«!@$¹@Bl‘ý’U@O‘EDç/ }òªT3Á$È%nJµ’Æž„[gÊóÀ;=M5»Ã:_ÿq¿BßÀ¥1æ-e ×D¦»6*„Û¿×_ +ÔQ’¦sá0ޏêw—Š]ÂÕÌ6Y£>3CëxâF4!y'Èw†±Y¾ŽžñÕõ0ww‹*·ÕX•3ógg5^/’S–Z.´‚ËÆK†9éÓm"Ž}bŽ}âV|‰þPê¬t¤]pbŠ=M»tJ= ^¼-ÄÞ˜=}žWȼ"¾ix=}žØW.¢µ}d=}žÜôwŸ·}S‰!/þ·KÂãŽys}ؚ±Wwþ¿0—˜&)” +±}Èóðí×=M© ~šÜPAŠ9Z†”ƒ*Sό؜ñÑMN·c¶Hï–ëŠB¹]h_þq^&Z=}* „’! ÓœÿÉÊìíƒv‰™“×®>‹BŸŸ²Å2!´4œp_ÊݛÕ!©diŽtÓ7Ȳ¶–®â.;Ù1Ðëb¡º÷ñF"inˆ/­­¯YNÓ(ÐÿÄ<š–›(ÓC–9~õ-­"‹§7LQ‡<1Œ¢‡­ŸAäHÕ«´Dî‹ù–‘PŠ€= ñc{?ýW:Í;Ԃ]cán¿˜¼üÍJŸ£)™Glú!¯dئ:PNÂg½ÍŽ^–JÑjÅ^¿6f(ÄA?anD(°Hsn +$R§Ärkx÷ò­ÅáwۍÈo]?!$"A""÷ð lÄ–ä¾qLô;±óðŒýó;^ð=M,±ð(&²ÀMªªÍü"Kb(6tÒevö&h„ÌD}ÔeŒ¼<}TÑØõnzÞª 7º}óì.$¦‰„1Vå Ç=}5Mþü²!ìm¹™¼6ˆj¦š€›ƒDƒ©èÒ·e § ‚"ŠGœÑÜ%ɶÒÏYa[Jðe#¥ïÔ/;}¿:óöª +¨ÓGÄ< 3mN¢¥¶«Ÿ°XقK—Þ°2ÞŹð¤d|9c¹õ.“J3¼«+™|°*Oôž‘ æï1²„/½©°„ˆ¬·³'´öÛ~ö|õJÛOi¹Ê·û† Ø<¦í>;°HÜVßÒ= &XÀîŽ15 ¦ðöƒÊ0ÊÀùl†=}¯~ñkÄÁ’41qø?ùÕºÏO,K,N¥‘EPÕ§v4‰Íøþú•³¥Êˆ‹k+*5­çr#1DÛ<窣…´¯|{Ù1¬‰ÇÆIje¥Yàkadž°–ÓÊ 3$AßzŽHÇ·Åö­Ë6·Uœl þq5!¢×“EGm*°¥þ6¶ÔùWøJéWÅN$p õ}ÙÕ/}°•,+:Ù +µ'ãŸã²_‰6U˜Á|á÷*c»\ÆU,g*ðÜÆl1ud™ 8¯à“-y÷I ŒÌxÉü.ù†e=Mɔ=Mk«?<çNd2o:Sò°ÑXtÅÝjVZTÃïÎòê;èXúQÉ6ØØ91Ï=M1èpî®Å(è(P I³p¾[Ÿy)$ì$ö®…K÷„¥{®!nP‘Úvä6œÐ’ÈVþCr¶>èqvÉ2ÇtDd@«=M¤c¶ç¨·íi«5A‰›,¸Ôfª/ْX¬‚š×ƒò*2® å¸oô +{ë.»Üy½Ct EâaúÅç¶Gtœd‡nòÔQº5Ñ66/Ë1=}wk*—l$¡J_!JÄ©m,v›À„p£re /7P$Ç.6TAE%8Ō7RÓ]Vú¨µpžPßGOëüâëüÂGO2GO2HO2GO2=Mëe›HI@Kgg,p^›OSü5ÏÆyˤ˜&.‰+&Adëg=MÿšŸ‘O[¦çŒÀ‘mƒØa% É­V­8=MûŽPNfýú’‰0uÝ'|!·‚ÉñjŒÖañ÷eWÂÏÍø4M;ȅ0 À'ú4¨àª¦~F>Dïo6¼.r]“gO:¦]§½„”Xhg†õ(Ýۂ†š‰@´¨¯ß£éD˜üÄF§ƒÃ»y©õŽ@€= ´LM‰ô‚¯[y‡B3솆ÿºw•K)¢w¹ÆFY=MäՉñsÏGBGˆ'÷@Ki=Md¥”Ck¤­3v»Õ=M÷N®fºŠÍ;Çà“³8MG>†Œ(’pÅ ²fÌ ŒÇ$‡€î2Ô.ÿ8ˆ…doÿ£©æ.oŒÏóSÛpX¡ ێzÉw%šUµ¹ÍîԭہMÁ†5fg +ûîBÚþdŸâõ´ñŠB­,ײc‘ÒŽ Pþq×wŠÀ²©Ã= BOµ%DىϪðõ™üQqÀ5 +ÀRÃgèˈ‰øÅ7IÑÜ" eŸø;âqæÞ±g&:ã'sÆk®¨ÏíLàôoªH'÷:'E÷df5*îx= £ñlí®F$«wmٓõîUT¬—»™åÕHFÔ]ò&÷*$Þ)Ê<{\‘ΘÍ?Çâ›V¹"œpžAn·{‘²Îbu¾âaÍ«ªáéĊ9z_KW´ûS§%í ©BÆÝ®¿µt&ƒdùë³ïú7ô£ NÎ'ð µÅ©ïz0´™î¦êUtâKΣ¤=MdTrzU8vM[§óѳ±I„[‚ý¢wIÃÑyn·QÔÝUæµöېðÀ¶{}IC°¶"ë®ó ß›ƒ^vèZ\y}׳BE6’°Èʊ’вJQ$-9Çê~>t‰m w¿²ˆŠ¦¨®®(|nÈÛp».„ÛTÀ^æ©É6•:ݽ獲=}÷ ÕjÛ¼Œ!ÙñI¯Ž.y_ŒüØ5ku–á"P/qžÕ¡>FˆÕëfâ=Mg4‘_’q|= lrö™RCD‘žö™zê]ÚæšKN4_©vÚè}ò͜p[üÊãᮍÓʃ.ÆiñC˜ÿêÀž}2&[»ïmá­rÍ=}ĺ2x>ÄÂéèÖ{ÝÎæ—íǶáN!|Äώd[?9èH^ù—®µ;Z\º¬yI‡ì²p>œÚ¾POŽ?@†º“ý\zþ}53)¡ÐÁÍç6 O#¤ˆáÊcËc£ûÀ¨Û¥Û2¤y£ûVBر«£Š›_ÅcpF£–¤ƒŸËc=M¬ƒ¢g£(þf!yÛãO“í#·ƒm£ºÞñ#Ñ£ï:£áÛ©¢næâ¿ã#/àÁyÏW²C ‡'՟X؈%¦)Ü p¹€ü˜CQõãÓÛ}~¯$OîLàHJ¸cø:«7í­döº¥ºXJæ9Ô÷ÜÀ›ëé0þ“õÕÒÈkîщȺ–õK,þ‰H‡í‘3:?77nóŽKÔæÈÊÖ÷*¯Õw¼=Moøllÿ8#N5£ØÔQ]Vóú1(=}•®ëdɌüŽ×üNihó.ˆF¹Uø†bg…³n ûæyª(…âïþ¨5꯯;Þ_ï «Ö­&tÊBƒ¨Å|’ø ö×P = 4o™Q…”&@²ªÞ= Ê—;·iª*[€/³‰<“{O +ӊ(Ӄ &;Õ8 „8üÂÓoC“ý¢€¸ë€ÓQž;ÖËÖÒߨŽÄ)¯Ï«fqF¹ÀÆ1È>›'ô&9(T•j²õÚÙ¡%¸&ù(”F" ”–0†cÿ2S s +{“¦O¦>©Y'®ë=McsԁØÞ©ú;ò}›°1¯‡û{VH!t;¬OÃ?½‡Ü¶q £Î eÃpHXzÿÞ¿žýxÓê¬ P‡\šM'È¿…ë9þÿ„}‚#Î'́ƒ}”÷»é¥¾åzt僵´„ÈAú.C„\}!iÔjÛAڌ¶¾;’ðOŸ ÞÉ(àp’ø;åòXCy¹JùŒÛ51J.Nòvô.=M@ƒo”g1f”ë+³­1 +kË;´«ô7À® Eˆ»¹éôäxT/½1¸xâ{Û¹ûÝysäzü°>;‰{e«j'S†ßMqÊØ>ÔÏzöp‰ýP³5=MX= :¸Š[ð1·u1ºkĒÌï¬v+FÎoŒÍ0Ûçs•2Eî§tävòÐÒ×8Õ/ ž3ùŽ»¤.\i8“{Ô#¤)eÎç³^Hšòtéæ»e½¶g፻¶^À¤g4x޳©3èô;¸¹-Ks—Á%ÌÂ>Ð= /³Åas8,}F9ÔRšrsh¿Ø³ú1jé ]Oš+E¶™ÛM94”%k’˜H4v|ß‚Í±ÎØÑLN ¤0ãÀØjj®0 i+òwÝeD 缸¶ëûº?k1Zp½r¡ ¢ÍV=}OHV+?®r7šâÔúTÃ\´æ~ÓY^‘É\9<„¹ a§ñ$‘î;òîâ3öuJ?­"ã¡Ãoœ3ÿeKJŠ}T^f[ÞÖQõø|R÷©ìȌĎ랰Y8¦}òþr5IPò„8/0x¼v‰SP—|IëÞ(æ.ɇÕéH#2廗[_¯ÈHÇ·y”-1“c’©ÈQËàH‹(DÛËvšìR Œ„£Ú"/u¡D$uDT˜Â%Þûµ«HÝ>f·!Ô0ŠŸL‡3¼m!_“À÷4{Çýàrá©-¯ú”Êðÿ(jˆè€‹²ÅÎÃÌĖUÒ±T§#i(9í97­öºÛïH¥v•%!ßOWª·Ä~ãÀ½<€A i޶…/%ÝØ²1PŒÂé Ú/¨Ueiñ$ÛÚOw±·Ü9C±0o»>ôí±ã¥PuÔµ·Ü=}C±0o»ãУ¶åËgí…éð£"}3£Éx{F"S^¼±b^Ù v„wsõ×ý½cë=}P£i,Ðx' S¶¿£aDŠçH‚Oó>.ü,LœD…º‚Lý.œ6Іm…™¹ÿS~©'È3>§,à:FAú4{vìÆùHèâ~ëAú$çpq¬…%=}AúÐûV©¼rf9Ø y’Ñ0\î«ï= ©Hܓ‰±(äâ°6^€ÏOнڀ/}KŒZXÊ]w˜Òbþ/U}Ôn$q2èÚ3¡ˆdüzbP®µPÔ0‰Õ˞í6¡LK¢oЃE¬= Îèt¬ZóÉk+= ¬˜ý À²‚­qAå¬'þä²'þì[¶'2ã[6'㛯'Ӗ›v{Uj˜²^¸¹îŒ,¹<ªJm=MÖ¸ʎ5,ró±Â.Ó=}txHë2ÿë'±: ò>A6Ü3ÚȖùaÈÐ=M%Œmٌ$UÀ°²åœ4“ä ÝÞÇ8èðSæ\ö>qâ¯}ÑxO…üx͒¼É¦;çÒgÿ;»D.úâoÆì:Ñq|Ѝm}'¤@nÍ +Ác[)•Ôph¦ýI”Á­×Åà+(w9¥¨ìGkÁ,Í òש%t’°gX C°C€ ©}½g3¿´‹„Û±F£îÔòêÖú™¼ ÔlÝÂÓª±†FOkéûT•b–l›SOÀ"4²äqǽbê¥,ß*i\ô;S€‘FÀÿž$ªAÉÞF¸l”UKŸÑIè$u¾Oå]É×ʴ̊Œ´Tö>[çƒû ³Ü™¦dÍO =}¿fW,u&Gâþø¦ì>N=}ù»F‰…½.Ö]MÌÔ¡‘c·»vTø02ƃM1†«Mø°=MöÙr /*‚R +ÙÔ ä +\.ô¦Î0ƾ¸êÅé#îmQ‹k;ÞbUä€Jrr ý¬È˜ ¯Mo†,ܲìºBë®N­™äè $*{$ô²ùn]/!§¶­!ª ¢OÖ³©oIz¤4Áeîô[&ãvÃÉÎ{HÍë©Ò\Îú4¥¥ß£»‹œ±WðNÕÔs{BµN+Z‚,ôToI5yhÐ}naO,dèDqU È0q¶œÍRÝÒ4LÜ2¾á{å¬Ï]<º† +}QÅÿ«^pY½ŸŒ.ÓÖv•UÓ\)Œ›ƒ³ I’®Öй q̬vÔ­ "8w¾ñ +I°ÅîHõøì˜úÝwܤßi‹%aƒ0B*;Ó´±ï5Û|ƒK´ú¥²IéëÕ!¾úÆURD՟J7žFEz\û.*zlîAԓ¼…£·”Vä)•«zp!V[á»DBÿx³Ãœ‚Â%:WŽÄËÙ¦ˆ6ó{³Ûyµ2ã ~Ó= !°'c¥‹þóí1ÀëÚ2ÓG„«¦š[ÖÞm3Má0j»)†ÃæÃæMª¼Û]ŠÂ +“1œ½W¬ŸµAEçRè̵·×GÃ;ƒK£ø‹àÇê=}pöÄá²kéâ@§oÎDEÂÈ«™F¡U …v¨bò^ÄÏ×í*Y¿KÝÛގã=}ÆÊ<MâH¡·Ç˜ØßÃ.JpÀ)ñ*,Ë)ШŸÏݘk0-<Òq™ ÿd‘¤7¸¥ƒù¥…W'B.2WKà§Ìëz_و +Žäñ!J^žÇÀf Õ‹Ÿ£…ìµÜ¡ÓÅë Äî€öÉò¥Òimu³Ô(ÌB邒€"‘—,ßà"]!í»1ƒ§=MèCf/WrëF,O(ÄCC1Å*U$J\ŠìV]•AÁ†ò¬ÑÜ'‡Héô2Z>,©ï‰¶Hö¥VڀCJAuĞÿ“ÔKG”;Ë5Þ¿*ðÚûB{½ rèJK+”ˆÿ zþ âÏÔx½†ãõ'»ÞL+0¶Á¯²¸cšG‰:ù=  + +´æVüK¾ C0‚ÎSý‘4Å0= ší⠒-~Šˆ¥ mÒRU…ì8c¹sž\E²¼ïû n¦¸]͈60ÐÃù/Æìâ$Å}}#üİ^;¥ŠøKBÍùe…æ!™Ö ˆ lB9Zþ O>£ñop!= Ö)T]ŽÒ"•>(Š¡üâ>?–¾ !zöù†þá›Ta–\‡8 LI¾ºM‹Ä¼ÈÍ%Iãù끞Âz†^Úb{½æ@å@ j¯®[ÖrŸ’Åñú%®d‚m‹FvãüÓÇ},/3ÓÎr¾k:†>Dx²tÁ7_ÔfŸ²ÖJ¿=}òޑÕ|AõEÒ*ù"O& }¥Hˆ0çôWùØ!… +Çs®zã4‘æœr„ ŽPÅgû›lâɝøÑ@ þ~ʰ¶¨ú’퍾Y YÓ·¿~a…²ÆÛіS,‘|Œ6ól\ŸÌ—PË_Vy†Îù ±J¥½„ræÎ•ùìT®G[ù‰BnWôËieºNúûi¨°×@S¤••‘ˆaýP?ÒdçùN:"°”þÅÿŸ[òœp™dÄPÞ02Ùâ¾Þ†אŸŸw +ðƒAŒ, (–<´£é8oŽå¥’ ++»«4D‡¬Ø¥C¹À»ÍÒ°9KÓp*ÖB´¦£¶ÑDfœ’Eƒt8ÔÎÍY˜0ÍEW¢?Ÿ >ø¸ãè#Ûº?b҈®íq¯~Èëî·õ;œ‡î¼P£x~v/Ç!eÌ·5“Šî4_7ÕÊòÄÕËuPÔmN{ô~Ò:!%ªõ±Fc3ÑHüµç°ÅF)wf8—('¬Dc=}ƄH'"må/Á­£7p|© Ò  =}TÍ}œ¨6†jÐáèÔÝyh¸È¬Ôz®1ô2âô«+ùÏ$Ý 0±Á™ +­j›Œ–P–¶™\GB¬žÖ¾šOÂÖù¨½¨¸$%EX,=}ÉÓ(GAӓ=}8Ž%ÅÓmÎ= •Û@2=MÖõ“Ézr¹ý»Z+ïuûGï;ï&#ÇüüH]X•ååd¨r¯Œ*É՞ñéx&*¯ÕX¸ç7NO k™CaàOB„zrSEs®8·Œþ{:4G= —æô‚«Ò„éå©#EÜu]õßºSÑÍ£ðÙs¨G6ú‘!óñ‰gÔ" ÎLiý¦Qð +¤º,DÃ'óö¼Gâ{ü>Á’¬¹(¯â2©ë£ЄèïDI+Àgï k7iï8¥ؔ“í3ÿð(—èsnĨÀ†Ï•ꪦßHAu-/ë¦ÜX'mÞ=MÎçnKk fõMÓ<–ùŒ +͍ÆEÒ̚®fÌóV\È!”ÓñQq¹^4SyáèÏ-=}<¹×3ýy À’ ·ðmå6·¡­MI¾<Vrº2F}Õ²jAŠ¿«Êðå„w°F+i×?_˜}AÒð(ûï~wÖìzW|Ô]ÇA¥ˆ³l<@gúæ©GŸNà­ß·v›´Ósx)™<›ýޙƒóAЗ|d4hÐ\k +'Î6­óbö¶Eaó-”œdcóöçšë)<7*ãkcëÌ·ãk·ۄ¤ £·q¬²þŒ?Á2ÿ²m †>L š”ú=MxoèÌìŒÎº?€LŽ=M¬V·Â÷¢ñ÷¢0<èäÇå“Áü—ðxîG5,ñi¤Á×׿±\rˆx\.)¿À¾c{žùÀYKž$öGÍmÓa°ÿ)sJÒCÓØw‡øè²1yÞ±µü·æ«wê /¤"+œÅL‰œýÓª*¤.ÄxȂkâw%¦6…eºå¿æÃ.|„sƒ!-07ê¿#ð¸s*IY±'UZ¬@®óõ¦L·Î¢S&k@>øþ8g{O qèª ³ÄE&õ#«CIþóö‘HL)Cd±äbãûÁ úb¾àÇóQòOõ »¿Ç‘|c>/ã—˜H–û7».\ZiéÊÌÔÐ1syìæjƒÓ¼–Ô¤•dŸ—A·Ä;ïpÜÀãזìW7˜€·[~yäÔ=}é3Õ0¡ÀX¾Óqä@>Ä{°÷¯ÕøÃ=}Cã×ÿH»B»ÕB=MåÛ¬o=}ó'Cä®ö +'=}=}¦M…ÞÖ0Ts*he–óÁÃtÛVXÑÔSB+¹f}=}9”íÍþgҚ&ucõ›m6~ + ÀH÷ý:Q¼BÍ)³’#Ì'žDDšI,ˆ¨pDIºUŠ=Mѯ ±w'A¾ì¤ì4K+÷ò¤ˆ¤Û·&æ{«§ô‰:|U®õ"ûÿ~S+Yɋ¶±Z•˜|á,NÐoGIöçJ€-°º úIÉ8·Ù­®¡¹'_,È +Z±LORŠü Vpêh«RÜ IÀÑ¥o騋y㵤†æº ±dÒ@T¨àNۋ¶fòn×ÕçYӄ} Ö¶Ûø° ]_¤€ ¶ˆn ¥š†* °Þú¦=M/ ^N©òߌEŒ®Ý†ZÕs´ +1Wޔ.«:àÛ¶UMÖ'ø*TM̱ö딤Ïv]zœ‡t'I„5=}¶þ‰^cˆì^Q‡Ô—ÃÏöv;ïÂ-rŸ¯" ;»º»1è«[&@»R=M]-„*àç½µ×µä7כ@ ‹¼=}'ÀáŸæÄÃú‹\Näe-^ö•ìý¨8§pöè H ð£º&ËÆdt#Àȁñ²²w5kÊ_^RÓþ%c}ç:—DŠ6ƒN¹ø-+Nuº·‰cºY\kÔp]Ž´"É»K[¬‰=M 0Õÿ‘ÖÖ ×½¦)Dδ{Ôºõ´šÍm7º©l¸<ÞÎdú*Y@ Ž+ÔG;Aº5*L?¬/Ðý˜3ŽšUïUÇkh¬è£Q1 Ó~§ÏççŽ,i¹Åõxs£îþÀPû÷ÀoʑD6¬Ý= È¼DýMË34²C Š^‡¸¾£±¹hÁéKñ€˜ózŽ–¤/StÓ¹weP—ͱÆBů0²Í7ñ1ôfãËßúp[^pô’Ü8Ì2÷It0²‡>Â.Ì46bà†­/”YÀ–=}ŒáånӒ‘ÜûôQɹcœ$dJ´d*+©ytç¾ìVY1´©eo?s;’þÓ|i}kÀëöH‚§‡ZõFÜN(µŸâ¾Ì/C‡B,\¡g®E= z¦G ʁ\ÙZN¡ñ{:w”WQ½%zÎôÆýˆ:XNü®l2¾þï- €¼âë*6_E.²Ö>†¯§Ñ²«lÕ bo”ÿŠ›T¼=Mô¡¥5»Dðs‰ìz”7÷,Ç?]¸vŒÿ±v[Òð­Òù)h?/Xði³Ù¦î7Áš%Ë&ü\×/–Ò6@³xÈ7=}<ÂOR'ŸrJ!3ueh¼#H+[¶Ð!ã¢Ö¼È³ˆ¶»½±_Þ½‰÷Œywñ&C§&Aþ¦bÞe?Ä´jãÍÿ•µÁÇfø¶«ÜèEÀŒöñ(ÀâèèéÝw¼ ¦%(Ó?{Žò¥˜kŠÄ/©yxÓÂ;Š·•æ„74‰Ö5ٍ®jëËÊҍ>#g¬ûkMJOŸËHIÉuTä‚(tZr»“_‚§U‰¥_wßڂGNE‚m e(|¨Š“,=MYz»¿Ù™I*‡èf/k]i jÿ&rpP;~ß]û4Èv¹HCa,Jy1”Y+LÙT((CÀV‰ÙS‰ý1Ð8ÞnÊÉÆ<ÌòÎ'¹&ìT…̸BÖarÄÿîˆÝǰ¼9“°¨2¬ø—îÛ½³q;Ô5rë\“ù?€ÆÍâ²x©çè v‡÷BA©GE)ãà×›AõüP‡ÌÂe÷jIÔ鈁4pèUv=} þ¾‘¬œ;/ùç4ìôdzóÃÐ&³urÐÙòˆònUmh+ÍlÝEí¶m„¥åó!ë¹gK€áQ¹Š…t­jR…ª÷ÃÊ2Œíd¿bm’ËrÝÎíY­_»o-o½;úÞÔ +DSfí,Lú«&ÂûöW’'€K¨Òâ­IÌ_B†zQh^9šF˵éW:=}ïì×-²ÏðÑær€–c€üù¬Ñ/ԗÃDEù´“i¼QP4%Úíö”ð]¡åŠa–E×òg$€ éÇbÇìUbÔ¯Â×£¦Ã£c™lê¥õ3)yÉØïnÿš—Ùïnÿš—Ùïnÿš—ÙïnB°M]ù£)DÀˆñc±[^ŸÍÜ2ÃÌ8 +v†±l8‹22)vß îóÝÏ?xÎÄwêÚËéÂx÷ù…"¨xÆÑëÞ-ϒ-ü^Çgæ,r‰x"Վ2ípÔ±­Y}QË&¶g + oñÛ²[K(ý ™â8¬—Z¢‡Ò¸Î&\@¿®Å„úÊ Ü‚ª9ƞ÷.8‹VâöémÏ8pO{ÜT1Oâ‘p¬Ïj=M9Â=  *7ɲÐÖñ튕ý} µŠŒº-‰VžSlTüuŠ";M·y +jƹÿn±1=Mꁄ& OŒÛ½‡íf· •⇍T09*ÂD9qôq¾—ž/‡ŽatŠ6x…‚¥”u»™=M²–$€“r&áÛ߁¿fœ †¸{¤[Q ¾ß|±*‰q'¢<Üݐ¥ |‘ {ƒ06ô¡ëM±e0Á«Ì,£œéj}û›*Ksåʤ¶THiý°}xã-¹Ê]ﱅ;+là1gR¿ÎܙŸ‰€g”²*ïY£ÝiÍh+hém{OÿˆJ^:SUú4óˆÉe~ìo‡ÎèDö]ûÁœ÷xDZ¼}4è9±ޜǙ‰= ²î\+ÈzR +Y²šV¡Ÿ¯îv= l}aûiÍ>t(= iWƒæÊÝJØFfM· úCát¶ ;¦¨u<„éQHó–wƒ]=}¯uÚôõZ‡ ƒ£(2òD[]öØ.™‡ti¸Ë9âDÀ®t=}"átnPèwŸ{òý<øòb= >dÎóª&°ƒ·% šY;Úf·‚P]ƒ^ ²Ë®„,a+±½«ß» Š)deë'‡ýe+µ•¯’0ä~I”« .Ø 6ô ݸP"ñj5–Vó‘†#¹0T󐯔.Îïêpêö3ªMúDxÉÂєæZ£Ï Î«¨Z%„н-@Òf“ï§õÚç”fË÷wçHÏmð…3~³*w:ÍÀ-jñš§WÙñ' űûM0ä¹½;wƒ\©j=M„7Gh ~ýŸ94ï…[Bk¾j4¶¿FR7Š[ƒK͇»üddNÜ'1î°¿™ð¿¡ìmÇð¢x¡j/øù9n/Ož‚kXAš,Ì.íÌÀ-7-† efzñeTòΨ–öŒ%,î$’˜ÂdHîÊT!Kÿo¾ʑƒÒ±0ûÏ!_Vô_s”3{o¡_ûX“1Ɯ@[֘:ÖbÈÎSf* +ŒŽªÕ‚tiÛYÍ©n€Ø2Ð諾R °ÈîüzÂN<ìZÐÏŒÁ™W¢´™GÌ&ø¼Z ‡TjZ’U°¨HvÙÕO3ØrŸh¥éÙTc“9—= ¤H›XIIטú-v.qéšJo+dw +Œ«}?QCöHçI†¡Éz·Þsϝ8ˆë„‘– ºÝ¡È;9‡èt'ö¬„ˆ¥]Ž\']ùÑJ#xÎìØЌá‚ãœnYsÑY&ŸðÒ’ÆŽ"±4PvÔM¾=}éÝ)ÊLt¼Õ;ìÔ<Üw‘“¸}a˜½ý.éÐ= ê¼®Átêöu“º×=Mt¾mÿ™$ÑOå(¾"óqµ}“-ìNG”Š=MŒwH©U™5^o­ ¬Ô뺕 ‹©¾CÔŸý=}ú¾¯*±À=Mz´’K։m^eX +ם®Ôøàԑð»Ôf,=  OÀ#I\&ƒâw¥¦=}°ä2êæTö14AÆsL‚ˇÁ09O“YØÝŒ«ëÞÌ$¶äx£ /(‡[€?£†ÜÙ+.ÇRìSŸ×¼¡Ñös™„÷;TŒû" ©I‹r%@rÏmTj6Ü+=}.Ql1˜q¬L@3×h¸´¬~â²vQpj›²‘óùcõz®-ف»‚dªQTws²Ú½ŸsRsÂê©cŒçÃiO¯%RÓ¯®ä«¯(*ݯTFftLÓ¿ÖZé—;ëß ¿¬YË­.^èÆÖƽ·¦h»Gï.(–æ,¿Q‡h¢ ¸ï²Mø² ‹?Î+j—4¬Ë8# BµS÷ÅÑÒí'f ç›ófcô°j=M§¹ëzy½Ë×»7C¤H S™H©9Ýý{°x….= ¹€…Xs~LhHÏп ô•î.ɿѠÛ_§1?Œ¿½ò1®ô¿nºwPŠ‹>otØ(FÏjŒn¿¬ZÛ¿Á{âŠû”9æ™<†Œ‚1Ј¿Ê"í‚NÛyx'w÷zûÙûØ×…{È š*fòãò•øõÌ 3ŸœRTÒ$ OUÿ G "Þúôž@üM}À¸þ9I/Kõ™= õŒ¡Å| +ö$UèÊ<“ùÊOéÑ;T¶—ž®(Z¹®À7>'úž±¬‡šåžíÄÒìêÿsNP›õæïpÁÇaaÌ1ÂÖäoVAÈ1íºF',1p[›Ñ\;XP QZð5Yú¯ï7!íOyr´"ȺNÅÂ-ºa·€žÏ½qѶþ xAœ±‘eaôòØWÂÎoYY êSÞ ­‰Ô®OI= °.¢Ü(àÌ@p¡x|íòyø£vR² +î÷,Œ¥ùú= ;НY?X¢U5È:R°ÙTۜÙo +ºÞÒOÞkU‰Áüúv{·-pb1 o 2ŽÒVjRTaZ<&Ÿ¤ö‹ˆÖ”ُp¾yŠxêùžˆ¾~zóo/úÓVüxˆ}‚oÇçé¤@þópÀíKòîç´Ðý4¢ Ù‡a^àð2ë‰v^s²õ‘ìsB}a—_£Ü¢ñ=}mÄ×Uìñ4ÉF ëÂη8—f(tF¨Kèm- æþòIR¶JupˆÖ‹€|Wbfÿ…Aq'V÷äÆ¥_ uÀâÕ9ªô“1óØ+G^»íN÷ôè[=}5ÍÛ0më:›TüíÐþÒJ¶Òú3v„ÇM-è}bzóôJ×Eàðn~ë9ÞÙv*KPÖ Þ\°ìà0vE…àg’’ÈF6žLŠ9&õ ;U_2uS jlcÝ8K݀ %Y×ÞèêÍñö|JV‡A=}CvºV̄—è=}ŸÕ|BîÿHØ>QöBXÚ ðu]^Ñ€BùÐë0ŸÔ‰œ—çþã= œ=MƒÒl„½U›Ð(Ò ò@ùGÑÎâö“=}RGV„Þ= ÿëYº6ŒAõ•€ñ²ú33•.uÕMk—ï°¨ytd?‚™íÆ\™*¡ÅffRpƒ›= Üq  $ò(Д_몾-ÿE*ȝ»õ#Þh) '9èi{f§ZaXeÒPô¡T°_®žzÓ–ßu¤‘>%€+á@³6€¼Æq$æ=Múßâs°Šêl]Á+ü™ºIəç ûÒߖ°PæÂ~=}4EÒA±*\@žæê£ú±ãdj$Ëbâ« Ò;ƅ#¨ÁR½/ÔÔæ3†Ý·»â¯ÚªmÔpە¢À1¼œÆ˜oë¯{ß­¬tF4Ünµ)ü„N4¥²aÌSœ-ØÏZÎ4ÁÑCqé' )∯J–«•ðã'š»ç2¿®N †‘¡Û7¾2²A¶So…_žœÚa}:i¹0ÉåRhÇ@'ù.ÊæOÀ5¾“ß­õÆJE^hח¢×°ÚZñêF€¯=}$¤Ê EFžÏ ؾªV +¦!™“Ž#Qü±;†Ôª€˜‰ÅÃÑ =}ÆY8ÞåXy¬*ۆiÀ +/“ä<ÎÙhU› p°âÀŠÄCÁßx–”}kÀ¨~€ÔFbªI?—cHʉe 5ºÂ„qïßmš)F= ²_– óÜfº©š cy²úR›Äë„2ÀŒ¡;¹#0þ¥ƒQÂ+ïøÃ"²ç¾*ÃWr°e.€·/Ȱd¼%ÖÚæÃZ«h'xDKϰh;LÓò¬fü= —¯jl?—Ú0c›ƒ«»‰èÃTÇ©çÅÓÞµèéô‹Œµ¨&ôëP5QFYÕ½°œt{}ЩøÁԋÇ©hÔkÀµ.,Tëq+h@UûÁ¿* ¤Sâ·*Ғ†ƒsè(FÖø›WåÝÖÿùDðH­é¦†ô†¿2ŠN…4ÔÁ=}uïA#±6¶“ÌÙ¤ +šÊ€ §gyÇÃKúÅeÊÉÅÌÏ´ü>¶D6@+3š,K=MQi!=Mç{M´Rii¸=M·Áôƕ)½•Ò=M—I$ö²°Î×óryÃÍç&ön׳6Ø "]ásÖ.©ÎŽHÐi˜xSå®8@¹¹–WS¬z…åЕ٠ԋ#¹ÐòÔÊò®VjýÌ ÐOíXûÿR(&Áêé1ðàܗÏÛ¯Ðܙ1„[â<&àjòÚ11x¿²…Ûq1”nÜwÛßÚw‡žÜ·êÜ­vÛ B‰óÛ‡ kˆ;"&|À1‹ª¿&A¿ÐƒKd•é­ž1†—êÌaÒuž¿"ë-ÛíîÛmÛ¥¡ˆKQƒ“œha5FO-fK)FðÐê6‡üÀjq1ÌbÜíǍ©Ì_ÇW4ÆÕ[,ÆôõÆÔ¢fÒôìYëÕÇúȜ5²5Åì(GýõÒ 7× ‚¢¢ë P½€\4xj~\ùä(ïTC :ÅÞDëtœU<$o|ýt8˜z2Œy1ž®OhÕ +2ñm/ˆR¯Þˆvî¡m‡.8ÀÙ̈z±Ì†oÖ8qΑ͒=  R_HêóÞW¸}'˜³ÉX׺=}ý¬ìžÉ«®2pµ½©«¸¹„%†ÑW"SÿÛI^ñË÷¶‘lš¬vž¿º¥ +A¹]m´‰›‚³]qÇo2ȗ”è;PͺÍÀ¨ ”GZa[!{¢Æ«Á£f£#Ã#pY~Ÿ>¾X~Y~Y~Y8C€^ZtVf Ž.æÇJ%·ªrt4N—žÀ½Îãú%BvS¢Þ]5 8]: Hà"üËM;>uÛ'Œqá ýÌQë*œø,ðï6í,Ök3±Z>u—¼Î½9XF¸°ñˆFÞ¬ºöÝæ£@@²ÄÎBë}m¼êéz5 ~i¯Õ@kDP&(GÜôéF¾=M‹–Xéƒ F’½>ÀCl"÷6Úð\.l^·œú#–=M«˜Pèðt©[jéƒÙŸ–|,Ê!C½aªձfô_>â$i† +3•œß)ØÑ$ژÍÑQa,>‘ãl°{[‹ÄM»AC̆Ü1°¾b‘¶ñ¨!hðŸ'dÂ÷Ô# À®*UF2(¾pœÔõÌ'¦™ƒ9å{à܋RögnüÈ °Mƒ J½oýדRü®‘P݃y&¢+¤º¾fVÌáÂÚ*§ü–¿³X(X<à×EÀtw¯r0K]Ф´äÒ+[žCMd²ñž¦4žÚ»‚ÀæRÆ¿íúEëĩޭ†cß´î6ÔýA-~ÚÕ3A¨r<¿·V‡†ìäÄ ‘8ÕC¯Zñ÷ÅeQ½Ec|£Š= p{ƒ{­¢vÀó¬%y6g:˜†Ór³Ÿ90%|¿š‘ò¤0֛NÙ2¨%ƒ¤Cu§£cYzY""‘yY~Y ~Y~YÚVMBÛÊÇ;ÂÇ, S×ÒnÓÈô9Zvˆ\œý$=}ýè-yÍVnü(P¦xë\Fñå<©Îz˜ér^²¶•\âmU¦L]ß«P-dˑ½mugÏÀdƒ#4ûÒ½08n»r½ê@€ ñBë9€Ç=M ñ„Cn÷׺ðŠ9¢¯)Ñ@h3'|ÿ‚Ô:\–û¤A5.[¢!Ô¢éæú$?ýWˆ=MV’5Ñ&ø—¼=McèPH ÒF˜­é˜hêzxÏ~U¹1ÿ \$ÝPð»9‰€NPo€qc_À{â~h0\[ù[º–Zž4xÝkžæÏÚße‡ðj;N%æaʔ_=}üöqµø1ªbÒS~È9š= eigNÿÀ^ØÚŒù^pwFÛ[ÑFʂ†Km z‚Šu¦Ù[àgŸjÆ‚ ï•DÊûQ- ‰Ö…ªß +[›®mnÓØ¡Èø‘R» ›=}[º ]—9ú‚”h)o¢#‹2ÿõžg-‘ò_L›/ñ}º™*HyŒ¾È)‚Ô¢¦˜žâtÜ¢.o bl{“*h"4?¢2ì¶°ÁgÂømÈï~ej­ö=}oSî×ÊÛo%<á9WÛýDp€âً YžÎÞ%Á}–I¦²ÒÝ5u,Þ*?ÜV~¨nÐQïþŠézw˜àÛDŒ,…ÅÒ=MŠv)²ZɞÕ_ÂmF <Øß#ò&¦<àëHad¯¸e´Xóm8f›P»q֜«oÆ :1…]÷×6Èó7+Hb¿h…¹hFÐíCPÊ4‡AÇu5´˜GSÿ7->˰¦T¯=}hÕ¬·reýžÊl¿õGô:l†Cá¨OøËG÷T+ÚmhOóÐ#Ìp½‡˜ÑÊ= ¨| ÎL½û(—3=Mi°N˜+ý1MfïàȆ½»ÙT4Ð6>ÞX¼=Mò­ù„ï.Fq§¨\ƒ^y(ò9QËI[UH@¾~\tžP¾pÍ,a‡ñÿ/ªZÓud6¶ÖßÜud.a= _›•m®ž—ñVÚ{ªŽøá络×e:؂œ†jBî!/“j@â(ɤÓÅ#Ž¥K¯g ÃR¥&˵g£p-¨–•ìÓqŒÄû¯„[Ëù墽m>õËÜ© fë>¹iœbWK°ŠtŒ7´A´då0ëe=MżÕ5$‘ôÛï1EzšË¹êZâ=}ayÔ¯½½&z.»iÇhÕ ðÏô†;Î0t(ÛÕ= …üØÔAØÂ†lrï˜)§9É5Ïìi<çiÝʄ×ŬtvǕF5ÔÒ¼n‚l ‡JÓö­Ž]GuRÄ8Ò*õtÕî†åZןÒG´„7q*$Œç‚íÊgÞ&ŽÆÖ³ßoƒúãɦjU‰ìÉà&VØá®0Jü°mIŽ[Ýám (±Òꇉ±<‘\Â3îgHÿù|‡Tð8ê˜tßٌŠVKÙÂBPœwXÑÃË^#X®®ÛŸa#A·÷ÄjRºõþg¯ü´•àè_úï>±oÐi‡èÔ¥’µÙ™Ñ„4µñÌÈÑR7MHûßÎH2þ¼àø«:4€E¿R›y2̊hé®Íø÷dn¸/÷d¬^íù×÷…[]5gZ8•KåÏNåYT­€òø·ú&E=}f¾N˜D=}ðÁØ;ë=MSþöfh:Ø;ÞwuHI9\®=MÜ"J9è)»‰w„Ôa1:ʎ+òûàò]z†[TAQR<€c„E©Éð=MCpL©ïý×ÈC´ìÆáî½\V´pÉW=}ûwF,þ=}{™C,£àÄ”å?¬<= ék‰å‡ýÅQç-[R³ÔT+Š:èßÈ /2;>øqò·ÆÝà †ÞԖïțÉìó:ó_çe~®µ¿¡í‹Çù17n HþÈȉM7ap÷Ýl›;ÈfX2¯€HÕ9B8”ŸN/Î GTY,‡OAÏÊ:?¨²‡oNÃpød=}ï¨Þ^Ìórù“ b% ò·? JÇlèìr×ÈèÈÉΔ}Ig”)5.â8[>K«®øtE÷è2aÍ9oøÔR­F^ÍM¢Ÿ‚ç0ôS=}D¨=M9öÖ-½ð=M­r¢¢0½@±€»—2¤#X¦­¥Ë;ºwYÎMñ~Y€N€}YPCY~Y¢É^üf79)ámÖ°ÖÙ»ý@Ùß=Mk¼Tî\úgõb)ê.¼lÝjÕ&j¬n5ª9íâ϶ÛÑ +ËŒ ø‚WN†³j˜ü1¿Â±ÝÕdžۼ”7=}nÖEGJÀr0™AٍjÕЕ¿‚ƒÌ{vŒMJò™BApT¦Ôv©‡®ÇÇ[ CNc;$œ&¦ޅce$*¦Br§Ñ€±¯!¸›˜Æóá)sÅ<óÔ.“RCÓ½„äØÄ¶Äê„D’„lÄz¿Do­Ä‚©„‹„xÈĊàDgîÄ~º„ŒâÄgõÉô•JúM‰÷í¸ù…9óÙúó­zõiÚù™XôqøY—ö/ËlêÍöÊÍÒ Í ¹ÌùÌLyÌòYͶšÍl1̈́/“U•9•D¡(Ն= õ>•BÐ#¼Õ¯FÓ?~i7U~YŽqY~Y~Y +M¡z“›‘ž„AKö»×Òµýº¦Ð+*]Êä¼öDVŒ”= ±p-%Šé<•F…èó45ËðܗQ5žMFs9©Ëôöw]Èý{¹À+ñèžEÜ ó6¤Ë™³WÛmؽPÁ*ÅïåøJEôÖs]| ‚ßWÄýY§˜1-Påbyj’'ÙäLYFÄÞt8€Ëqá÷…#Áå 2CäjóR¶KtÌ7š/ŠBæÊqFºô-n z¸zæjRÞ"¶Ð= (å€äx’jàžá-³ˆ'MàéPACòô2 +Kfwƒ¨Í¡µH(¥béJe¾÷„Эš±Z)’ôk² Qœ+±ýLò‹/8Ÿ/™þ‰Òqþ‹RK(ÀTǂóÊÞ ôaFMÙfû?ÂK_°Y™wŸçOT°V¸Aý“Ë$Uùn}û¾Ö,PZ{ñ~È^šTàZú™q៝! ha|š"a–" ¢= ÂC†D]Ÿ©ý£H¢×N)®ÙòmdÙaŒàڑš?ÚcÚÎcÆÛD¥ýÛ= ¥/Ûï‡QۆHxÛjÆ£ÜKºÜ)8ÓÜ YîÜãj ܪ‡&Ü ÿ7ÜboHÜ©Ø[Üä8nÜ ‚Üà˜Ü[§d¦#»ë·¨S}Y¾–‚|OP~Y~Y~Y8GO ÁBZÖ°(ftA® (^oҝúÊ Ô¢š¶>ÃgQ¹ÍU¶=}o‰;´þWY²ÂÜր‚ û#Ë.Œ,ay¼ïüF+Tƒ½ùYb@àë½AÖ/b¨,>QƑrþ‹R*^ Š^¦7L/a9ADÑÿIʌÚl02ôp0B ’Bד¤ˆ ¢?7t<‰R‡Ÿ42IºçŒ?ÏÀqöɆµQsI[´ µáåiRϋ#>°ýññúÝz‡ì²\ŸKÔ+-àeŒ^»=MÞ4ëÎIõìXÑ.a¸ˆ6ú ¬ €ôì¢QNÊbžÐgÐvìMÜ × !'OÉ r߄”›¿þ(W,ØsÑþ2Œ‹ð{Œ\¸øYޓ>x_X~*¦ªD¿§)¸j”~—ÌÛ@ߪ: +º”:„¸;º*¡~Ûc²2õ«:ñŸ£ÒB4ܘ¾×§¢åê¢b‹· «0ˆò4”¥Ñڂƒóxõž/Q^¿[Úm06´Ÿ“ôµéqK5éh 7ø%VK­¥§xCÄK$EýÓ:täa]Á­o¯ˆ 'î¬ÉsMÕ&¢'¨™ü†¢’4f 2p‰1{>„/q¼úk‚—ãXCºI¦ sۍª­gGéÓqø'…“œ«7Îé„𯗑hæjÉ´"Òîä±½Ùù vB|k2nh"Z®Cºÿ§ŽH›Ð_¿”Ke °ÝAzf_^´n7ý™ãÞyèeø² ¹S³ÈòꓘۗFÊDÃß&V:ŠDtZ+È%ƒ¤S­££CY~™nY|±Â|YÔ~Y~Y^kàü†y®P¼ ›“_ÒòNžu£Ý%©•€u¯*Ó…ÓIaÀñ’Æ”´/…ÿ  ¥÷iÕK¿–¸ÊÓLŜÍ6õâ(Ùdי˜A$~<ÿBÛ>Hé+ÿÚ2d– Ä x.›–¬z +ÏF|ܵŠùE€S­NR›S!À^uy¶—Æö¹ êo¹Ù+Yu\Þ5sºnڐˆ’j“uäi/ào”‹Æÿ/8*ò³â‡·^Fñ–ƒ–üAÛrh<º Ñ= g°jÎ02Ê!Y§h°5«8éõþ9F‡Œõ´„õªLµóEi:ó°¹ý ”—†¯‚ˆpØÄ޲+ÔÿB-²²3”3cª2‹ÎoÿpÊoúmã( +'nßêø¨˜µÒÜҔ-bµR”4&b—þ/‡ÄR—AdÂ žÆH…òϝ<bcZR/t¡é+ŒÑÞ¡ÃošÊ¶E"T֖ڞΡSK†ÒÈæ¢–]ÙPÎÛ_êºd¨àÁ̎Ƙg#|b°ZØ;ÔE¶Þðt> 1 P¨nòý…Ih—yÿYSäÐe9N8oÁ„#šÍêy?…ac¼¢ÑŸ¯èY0DßTh6·ÌÒ]væ DÒÍF Ì|Ác8ãџ®… ӆ^åSþ´i,GaèÚ×5Žôïÿ¾&aåÏà—…û=}¹r5Ô,WÀì…z.©œJS꽺ë +&Ó&å:ïÇýUS;æSúšßG^•Ì|ükIŠè?²Ò ŠKõýq:ÄuÑÊO[%e8ø'®N´ªysÕU1úŽÜ ycE9éŚØVˆ®èPK +vN±åvÞ¼ÜD>£¯¥¤£™?~_Ä~ûQÐ~V~qØ~Yþ¢*¤o­½#€$@Ó«žCä[â;@6*ƒ»Ù'ªò)Û»…)ĕÛúº2‰«¹Í1gfËA82ep×^š/äM¯‰q¥?ÞÒkîäÄ}¥'ë Å/{¥´_Uç“óºè^»ô7^1艍Û;ÛA:†´9>c“P¶Ü‚ß´:ìo5†i߂juÀžT³à#„¤ÁG“fÄ/²Âii´Ž2ƒ¿·P×à1}}¶_½µ‚/6+^?užvëÁàfr=œu_’3éʉÏP9ŠSÁ> ºK>´(y..a'(xIb_åˆDN¯?Ò&R¯LU«]†'íÒàðm(I•¹dZ< *¾Ò‘u"—Á¨î’Ög¦ºâV¢æÓ'm.jo۔'‘8ò<ě¯ˆ +,qý*ºß4ì*oÎåG6ݎ°îªaÈEƒÐq¤’ëSr9ò œ4ªù¼Н,krB¡'6 +õâÆWž®r!DtúOðaêã1¶Â‡[sË*E/ßìL•~FãgÒ¨AÑöçõ4híO8ú…Jµ18´Ìói‹[­µ„ͯ~EíX^͘Vx³Ôó†{ _áKV_è@k>½qxã;É*eØ\_ø®°ÒЉVn÷>û´ÀÁ̋S]úª„Ê]/Ow‰Èà1HXBÔä ×@*¤p–¯,ÔØÇóo+çÆ©½Æ˜m»>© ×d҂'Jðü¼m[€ /˜Ú|©Ñ;†]c¥ôî®WÉýUën5O4ù{ YåT~-RòPÔOXɗ]°F­[Äîñ5ÐZ±{Ä» ê7[à‰âôý†#->¦Y®¿ìXm÷ÊŒÞôΏo®¸ +ɱđF®É€Ñ_‘mVéúá‚fQ0N‘Ïqêø}&äLÁK”/Êè^= ±™åä>ºb= ^dªÂŸú›uŠ…n4(!›|TyÚ!; †‡‡’¯Ø›ñ[{²ïØ"“üƒÊ7"Åڟºù"´Ú“Ú¥Â!DŠÚ¢ žÂ_B¡úvÍŸfO™Âú’›VauBlÚ¥³Ï°ãçÉ3\($]·g.Ã!?® ùÓU +åëﮢlóõ5æ\ϯ„gÓ%²*–ØÑ?ªÆû¹¶d[ 4/1-ç·vÅE{[Þ=}Ît‹/ÄÐÇ)|Þ¶¿îa÷¿*&…+5/Š ß赬«ëaçż¡,‹-Êqâ,H…l¯šòI=}·U¡H3çÍl¢õlÆ0I" «,JVqâÀ¼”¯/ Ök·r ãɲÈU«²kaÙM$|쉓ÓË*½LÿÁ©ŠuXà²83ß ’oÊÃ×Â|¨«)º“ÄòÅ­üaZ+kş™¸–Ä];fªí;¾þå’dõU†íœ[¯~'Õw29–ÑL?ªjÎ3ðLƒelíGv¡¢¸ŠÕM[ÏppO=MÁBN„ ñ°=Mº=MÔrNh–õÀĨLJTKAôU°oÌ#Ž0ë:ڕ— ¶ý8ð[€ÉM]}óu1øîÞâA³zyät.ñýÝݼ•]®t‘ÑIb Ú΁šSYb*˜ÂüÞS28BžûÛ[B žô›2D£+&¤c nYz]:Ö!oY8Ô~Y>€pYþvt…ú)¹ Wë®,AÙêUW,=Ms y´°‹3FæF±dj ÕwˆQÑ,f¼ÿ:þé'‰ŽÔ'Ážñ‹DEòù$áXƘ|€OrÞ¶¦®°³1ÕCõcµöæ1¸½• 7Ä}½æ¿o/«ÍÕÅ!W´ /k×ÖÉVk»d Øi›<<ezôÉÿú>S€w7”(IWÁí'}7òÉ ÒÓF’ëÖå=}p[ñaÜÄÆo áñF¹oäðö®¯2XClc¥P¿®ÚûŽS¨<9ÏkW‡PȜªÐF _Ìÿ’p4ºçªœÓT@²2¹›³!n*ñqaï6›UEÒÊòœtg2ÖÜ!P˜‘â"–ÆÔBZ= Ÿëñ©èTR·– +ètŽå·ô‰tp1I]Õ½.t/Àpš#»G¢jS ¯Zqg¿.Ïd&”}³.„vûQiÔò¹êœ›ÛÀ.F‰¿b††Œ}àAFî…T_¼òQ¥€­¶KLðCê¥ ‚Çó´3+žb,ÿ@?ë0Ý´ª@Ç ÈɁÆ,Qî5{à,²ùl[‰È¶<BÈFŠ««ãc(á¥]Òº“„)#±ù×¾O©æ¡ý‹²Ív»ÿ3é>m×µÚI”ˆ½î?u´·JKÝ@{pŒ/"?q¸Š¯oîÕ«Plé´2ÖSq‡ñôÉÖNÕì~;l<ª<·ÞTÜâ®fDüRpEj@ύOVLnmI¢U9 +F"Ð>°I܇H‰sà*'œÜ/Þ>fÜ@ÿ!j‡…sѺŠL\»ÀnˆqŠÿ¹¨‰ôÑr†Œ+ß]o†mVßŕŒ;rĜü˜šz–üýã¢7¥…^· + ¤ >®šX£èóÄ(ßÍgþÄA2­Y΅ú ´=}èwÒËe¢ï´¾! ûÔ°mñ0ËéÔQ2-”YÐdÍF' +àíûàJ§<]'ú틍mèÌ¡ØHWýþ톘õɼ8ÔÕQ/ÑPn+Àúi†wàÌfkQ?¤Œˆ?ù1ho519ö—Q?ÿš­å®Í›yR%°®ÍËâüdXÒ¸·œ­üý͇|ęî('A¸µŸæ+ø#+ވН¸4_ïg„VŅ"+;‹Ò‰õ<»@Ä¿:+TâЉjºÔ½¬èµžîûàò%ž¬¬¦‚ì{ŒÅˆ97ҀG;͈máÌîAëôûl›5ÇFUX/ºÆ5ôi­ÜÞ凳m<Óç14¿öX?h’‡›Üλ:Qƒê¨Ñ†¸«YÌk^HÃè, K5N¸í½©Ì?R•ôÈËlUôÔÓìh7¢÷o ót[í(•O­jr͙[¡;?¥ˆ­#»ý~Y^àXP pP~Y~Y~†ì•¾ª0Þ{º3/¦’骆QÜû•~deñ)zu5_6¸>@7_„qÂÊB^˂èêdèO.Q¾÷= Å™òºŽU^Lnpb>Ef€—ÿˆ  üڊá[\=}qf4-Á ™s\2*{–à/â‹Ät¶²D'y¹™J,:ÒU:r†_ƒxÈÒaÒ… —ÔM52@WŒˆuÂ^š›Û zj4"á9‰•Fw•6nŽ +jãâø¹œükr:ê!íi®sÝ#Q¦×šªËßÛcŽè¤IÀ­ó—ô#%Çp¶GæPÃFä9š®U3ü%‹Z&7Ÿ¸‡=M‰³$íÄZ²ôx±Ôõ+p¾å?ܺ…>³~6)¼üÛï= ©›fû¦™_;"ò;ôÚf›¹‰ÿ]«Šíê{}ßeÓÔåp„´ÁÏ1ÃÀ+’ñ'MâÆ—nÃS]/cD‰¥ª§$¸æ¨Ï·Ë^úƒm°¤šº$nLçí¸¶,Ù³ü…¸|€êr4>ç?¸Ì¢å‡ ÿ,±,8Ç ÆÔÿ9{Øï…¥,þ^Çñÿ4û“ñe6ûÉ <xUY:¼Cmÿ»Ñ6DïTÕ8Ñn·"Æ6Ï$eˆ¿­æÎ͇LS×O3!#%Õæ ©(~Ê·áß+ŒÂ­ÚöNOÌOÅwõìxì$I5[í¢͊YMÇßNõ‡,½†Ê8… Øõ·t[ôöª0µ-i™d½è + /C”;éŸ^½â·ìE6à:q2•ݪ=}‹»Á@7€I1yì[ójZð +ˆ @~²×È֛;nƒÿ& 0°½\¯A<©}&êV°=MÓ» gƒc°&ª¯jÙ7‡ë6,xð½ZÕŽÚŒv€‡žË¶Šß6¾ðÂÔì"fG“Ž;¡ºJT@rè® +.’НL¹Â©ûW?ÔLhœ¹Âòýga”ŽPhfûÙþu{ûœùS|ycI=MÊ>ø%ðEÙPi{¯>V@p™ Ù>Ñ{o F U̶Òm ôˆ2µZå7‘˜F ÂHóË-bþ7tfEÏ?™B#%¦.¤ƒ|YžL~Ùâ6}Y~Y~YXÔBjÓ7DjÏæ€ø)7^¯Úñ½×Ÿ•?Ÿ^92aXכjUÃ@ˆýnÐâwT‚{•Ênh¤9<†ÐxŠüû¼]~•xÌ9–òÞ¡"nôŽ®êr‚¿öÛÉ ¯Í ÷t4Fa†HI1¼@¿\©Û0‡?;ae”eÙê™f1)º¿¦’É¡Ašïjv’î2 p6Ñ\ŠÉr‹ŸAWßÇ“¬¹ßò–¿‡4AÄVßÖ9‰ퟒ–܈Ì"p–fÆra:¥°‚®_”øC~R$Š5©MG²or¸÷דhãdÝ$MµKxÍóQÖ#c +F¦jJ)§ž$WN¦Zɪ¥ªñ¨Õ°¯= Â[›ÿ‡ŠÚÆèá1[Æ!2Wð½44uÜÅ¢¹-ÒÀ<ùØõ_!‡9é=}X-ß|Èõ^nSkÚ¶Å8 +é©Ñ-OÿÀÜ_È!‡Tk–4œÚÅ@Âé­áÒ_™)ӊ¦Dƒ:elÂ(m"¬ž6¬Œu¬ V¬J–¬‚ºº­:ºG]sPaÓã'áp(ِ(=M€(× (º*®Îi¬˜J¬’p¶iÒ¸¡üÎïÅTê û{훝5ó‰Is˜$ӎ¼–nm$Zµ¡DUˆ®qšír‚7-¢ÍâHó1HøÝô¡kPOËK‡ÏDOÒJGMM/KPß8MI FŽG}öœJb5K5 W•¢çˆNŒmö8.7ÄÎ7uŽ7ZË®ÍșÎú2˕;„££å.‹Z~ylY~nY~Y~Yr]v0#b~$i2ޝèªu= ®}B,Ö.«â-Eb¬¢ÐÉè³NF-@Tg›êµTÅH»BñWæ·oÑ¡qÆñ·³ --Hg\E”ø0“ùêzóKL[xõ‡ÊIýߌÅu™·P-ܦh”D…xë”~Û´ 5ëÓðgBÈEp¶bϵr:-ÆÎh/XE|é4ƒ{ÄI’´è±'–t¢[+ݓ@¶¬Ò(}N…b>EŽÀ†akû¯ÉÑa·Ô-mÂgsroIÒp˜oºâ;¢"ٔ!Öl¡¯–¶¢"¶Ô5œÉM\¾€-ijذµ;7,p–G ä­öÐXœÜ@ü9d·Æw ÔÀUªÿÑvÒ2œábŒõsßÐ͸Öþí;KHð>U ò–Èöa-¼öp¿N´XðM]Iå †)„= Tüw×Áþ=}&Pp$YdòVñ ñêÖWV €x7µš×B˜Ù*;ô ¥r£¶óƒÁ°Ø *>ÎÆïrôÉq»VOÌÞá›A³ßðÕBñÔJ=}rJ*¿Öo†<þe‚ù>\T€ß~á×‘ْԐ°á™¨@ӒÚÂìZª3\f£#fÐz»u…~™9 i|±V~Y~~ +~y6pR]›"¼"’(W™ò™ûšha‹pF˜‰±=Mút?¶[¢v;bOèQ”jþqs6¢Ün¢Vò.Á·=M¡î(ô„ivGÒÓû:q.ـÛýú +7é@dUû= ýJáç P­¶×ÝɝHð5EA 3흘ÕÕ¼6M¼vÍp¿K3Q–%ý¼‘ªÄWxX򫔻 ¦D×qyi舿À@FgvËú:ŠÕ ×t= Ê5M‰þ¾N[ê½x®ø9(Ó%(ycûy(‚7õö¾’lçyAšÇ¶Ë2‹i»¹U@®_Ç'%ȑàPŒpëIT'¿ŠÝrœénj7³ËRKì¶Ýs0¤¯ß6;hÅ9T1P„³ÊÛj¸2jߊ°Â›o!”2óe,Å)µìÉ8×ÕkÇ>¿lÆB¥­äj*s–¤à£ןt.Õ£1£¢+®Ø:kdØóŒàÙZš?ÙэÙB~Y ~Y~Y~À®)±…}ŽdŸë¼%‹¡ŸX¼q ÜÆüÎÖ-5at+"ÁnwMkß=}ãqç‚?oj—ÌËB)‰7‘q‡ö”Ïà*9\k«o +m›(+‹ÑÅ" µ9§Ðˆ…˜ˆ_Kþdî”øÿ_)¸¡Ì\^ÁLa°oÕ'…tÐ×ø2m’~,xѷ׃’,= ÿ‘}jÇ^¦ßág”Üê“òÜm(†ßÞµXTJT.à&= eÜwRƒ|îoÒ= /R ø1Ÿ\1vL>/?>X¸2²œ¡´*òá‹U +{¯!¤èÒ¯!pۖZÿ3rRrÂ4]–¼d†\Z˜Þ.9ŸÇ=Mm±¢îzâIŸ +þ.£Ê¾¨ÜÒg,ÝYy,Ó\75©ÔÏ=}h\zÑd+Áì/ªìV G¯1¶üÝö±L蕷Qôp±èAÂùå˜%ÕQš÷+NíoØ%ˆwTÙsãoü6î„ýïotÉCô**Ƙ üCrr@©×ÿׇi¾Æ¿h0ŒÔÙ +CÌr•p³ÖêaȍžP3 pÞ´¾±þ{ÕÍy1#ÉosäÊGÝÖï|(²aQg÷[Ô=}ªz±ŕd®Æ ¿… »‹*¡ "¡â°ƒ_ ö…%«»µe&€D×!¯†FøÛèh´¿=}Â(up 5÷»?¿nEì”_3c©(ç‰ÈÉtàÜ(+NL+ ITÔÒ@‹È<ÿ 8è_ÙÞ]3â?êMáÕ®{SO+æB-ܵóeY¬ï= ñ4 ¨&MÛH=}–½šwõTAF¹° ¯ ŖÖÆ¿þûÝI0°r}ü¼wd›¨·¢Œi×^*Ηtò³ß£é¤££·Y~‰òzU~Y>~Y„ ~فžï'@àōfmþ \ÓaÂP´ »˜LâΩ?Ú# ½¦¼!³ç©mÓ9ò)“óÿv*•ë»ý*)V= ‚«qž0C‡ëMú0…œËQ<2ɕi»ÏI2HæÛ9«˜¯ÝàA#t¶Ëò;#_Ÿço2ï “l1>/V·/2ñƒK ‡ÉðX=}rqp7<‡ +qS”Ïo‘qi Œ¿Yxq6jÿOaoæäÓBUD®“ìüã2qåÒEœ·>º¸W'ðUî|¼9ÿX?¡áÎk3ûleÖN˛3È ÂD÷ +*¼2.eî2J»<àZqŸ$“ˆîµa†Lz/µ_„…Zïÿ›±d‡š‡² ãæzªy ‡ätʅuá5“(usR»"Æ}”Þñ¢cքª² ‡gò™ŸEòƒÒ/Y ‰&zGÙ+4Åilx…¯³J<§®Ç3ûÏlî썺ët Éh1œu<í– A¯ +ïÚò9öür:(\¿Îºm–cõA—h­ŸYôƒqèaÝË5Sý,Qíï}Koëúdßó¨$ã8L4MÏÝOivçØmòNÃ÷ê‰M©™œ½¯C,8ÉZ^𮀒}¯ÀK&6?±­†ÔxtH 1ÁRO˜ûaéB¼+‘Ùcß}#J¯¼?k+Þé¿KÕeŠ@ÔZèï³k; _Ì9©IÏþéTN¼eÀ‰+g; O¨ð\¹§âTÇOx5ÔÎA0T _$Øî‹’fÔôþµõ´bjn=MÞwb{öàw$}±«¹ÞUvv4úž?뢎g*^q¿‰%[®ý¶ÿ¼„-’éگŀ“[ƒñ¢Gâû„lýæòÑO”eØw.= Š_¼ù‰pCÒἈ.4,Ò—/Â6RœYBË,£ﮇ;öÃÚè&Sì²t.uª'³E¾å‘=}óyé(…Ð/šðß3®ê§¸á´ܸlA•뛸h6LtÇ^疋¯þ­{™Ø9z¶†k/†Šdq¸g–¥)6µ¼Š5+’4Ç×î5S8ïx/·‘JӄÍPXL/7¢fhÈ"´)¢è‘y⚟æô’âÜþ'¡Ò}~ש0î +DÝB1 +sZݦ"\ï:4·6hEê|[¯l„(±Z±‰Åø9îaÁr:‰VÍÙBò­Û×E³*åyBËELQ+xiτG¼ùÏð~ ]÷;÷Ðf” Õ mu~ÅnZ¶U/Ô6&áÜçÒn‚äANæ‡úÁ¨Â¨…ÉËS“H¥M„-ïBF+šÚèÉÎTHµîÇ7üÿKoQm_÷ödHä(j÷3ÕöbÍ!z÷œ‘Mi|t=MIi¡ó‘oôê*Ý(Œ½¿ÿJä#_ÉŠÎØŒÞKì#4¹}= ýkÿxåxð¾zT}w_w G±i.;ÆO.þaњYŽUëö2"þ˜ ÜJêB&áVꋜLṄ©/ÿ#/SÄ•°,| +E1´rÝ/[!l+ªQi+/ÚižPÔ&†ðau'üöaù<ՒKÌè9 ±ÙfŸ4¼yD‰'ÑÓJg%àè¹»VE4Èé¢ý“1È ¤ùgrTe0î$Ø´O ÕW âÙkXDÖs9B<ÅêTÀ-ª=Mr= $™_2ÿ'¦ÄîÀ»Îkj=Mêñݕn,œ?k"Š'ö-Öý>?tsdIn(w¾Ñïc8 +ÿ춆íL¾˜êsXŠ™ëY_ +UªnÚón62àA›”õSºµ.= »Ì0ø@ÚzrÖrp*aLáן—DFs:,ª ܈*eËâ=MœΰmY&+D⾪›vžwBO[£Ezª3O¼ë Ѩ•Ûß+C8äOú±iNÆ;–Ú&œâÛ'“HÄ»Ì'Es½-•˜óO¦fë¿i÷\×*6 Ð?ޤ´wÒ1ãîá5nÐ4Ï= Ál;CËéÏ0I×~Fœ!Î=}kS»9R/dûÐ98àTgß+è³¶j4˜Ïs, +…¢”ïÁr‡§‘òc{×41´, 3ë!µ²ÉÔ|á$‰C¯qbq! É&™ +u:hClüϳm‰Ù}:U ­k„‰U¿w€Bn' +\gI‰D= Ê2Ryœ_;;rÞä¤ÕبÿÑCàK3ήsÍl#Åÿ‚·Ñ^;¤*.,Ìd¬ÕÕHëY:Eb·B›Õ½Z:TpE¿X¬ˆŸÒKãGY%lúΓ°N‡†]홻÷Ôç¸ÆbùÔIO=}(ŠNÜ´ó&›M½5=MüÖG¹FòXÏËQfŽÀL +}-mW¾«¼u#ŽJ©ßí½,ázëã¶îúؔZ<'„p}/è®JÒXs¿}-ˆ)ù¾Z¾Ž¨OQ +ŠPiÃbV&§~ñ¹ñ’çýI.¢]]3!yh%oµ1Ɗx–*„#’åW›YPX‡‚Y0rnY–M|Y~Y~ib†æapڟ‰ j¡z¿a¶•‹ª¸Üâû÷/þa·oµ +}ìñm+FÁËñ JÛ~ÙìC˜ã%䯬A +îóÜø5ªêÇ µ:çú5œ5›R6…d̉¼ë4AÄ(y ‘¿5 .;×v GŒ4IP¯üëz:ÄÊæ)mlU—À5Q[Ï^ uÉ.lB·žlFB_m¡ìwWÏâ™.‚õb‹±›hVQw-¡‰ˆ†‚¯; éXƒÚ>‰k4!ý±T‚±:Fã±2P•+b5Š%@ßE¸•oûEcƒ¨=}ø¸K0úC!WÅ@¥èiôç{æ´ä6ŲzËDê,ç¦ÈÉÎ]Õij8Œ7ô‰+ÕA m+ôä H­ö÷óQóaSÍYúø|NDíì5ÍU†x{ã0}Â=MûM”[†rºø +o¶-Ðw¬Ñùj$©ýºØ3útƒú_©­×t|N,€Úðe= ØÌv…ÉÐßy…H(¹™hý×Ðs žÈ‡÷XÌîs ’ÛÀOšŽÓöï*B!ݟxH&‡â]ïQ.Q0ÑE¸]g®Ž”…]Á–W˜+ìvæ-á^2ŒÖåùBgó /©˜œ[f#.’°{ˆ=Mcé¦‰RØi âÙØDÄΉ¾TE´ +÷08 'ye²½vÈ/ 3ÔҞ/”{=Meðے%æ= ¬¶z;•A̜ÉI?Ï×Èa¼žÑ<´H i|ÖíÊ=}–”+ÜVo”­ØŠ‰3Ü6ü³™t%’Á¹XwÉîõAû lz­îQ-ûTž)¸N˜P;>hG|y/à +pÛIÉûV _°>±|ëm)Äٟ½WdJÐhÂ<ˆ nLÙþ·èë" jÞÞAú~´aeÁ„Þ™+¼~öør|¨±'*I¦A ±@‰ëƒìê1mÞ5º†kŽÔñïáƒ'6'¶º&@³½eJÖ²âÜVn<• +¢„€îº±Û]Ób(™ØQGàhne¸6Õú79]Äf0r©ožv–´b‡1%)Þ) ‘[ð–Ô7ª°­Áï.šjòÁÁ™çòi6wòÉ2“…wÁÒw"ô»ƒh)!Òg6 t>p v¢R²šž3„f„ÉÂ%ڛUŽLÒ¤YaP”È8Âú‘žô‘*ç<Â.矬[ŒrðÆ"i¹†TÓ#z¥;R¾ãý£m¥ÜÔ3ܽ$·J¨…Ûà«TÖäÿ÷±å×Ì+l6& áÁïIÿÓdTdÛ1®d›«=}UÄËê)CÛÍ·ˆ D ë)·½-= ó»¤%Óõ"'ôº»i;dÓù Ûja)–}Ò¿fµYêӗÔ%p´_‹-c!îǰ’ÅœjÆ5r4矾hoÚôß0ÅCÈ-|"ꖉ× ñt-i¯Bj“Ä)M»QP2ȘìÏʏ,N0ˆ›}ÛõÁhhÉ1UÛP1ŠR*” ýhVTÍA‹8¬^BcËn§͵ÛXÅ4A^,û;Êaß4tn6“^6g¾VÇÙ9ÈôÊ5/ ;ÉV\×uìqLñÁËu4,gWÑIAeãX.X p‹ ¢œ5x^\Atð˜OÁëV*üào?~.„ˆùŒ—…?vn™œ 'ÿ†+Âl ÿý{òd˜!¾—öøsr6h¦× ¢£R0© Ò½ƒ= “Ã@Úªœ•Jî©ÊÕ玐Ä;°ôÙg&ˆf7À‰=}hӌ¸fûq³µ7¡ÎÇûëŒP3ãè볎ÑÇ»4ÄÇ{|ÄÇ֎Ò$‰b§¢ Á#/ñޜJY™‘N~YÙ~Y4@}Ù¹XŸé’í洙äÅ=Mñ³”n©´¾q-[žõ'ºö^[;B¾.üÞûoX,o>g7ÞÒI’ÔÖ¿µ±:3“],'“ó¬XÊî»]üe?®µ±= 4“oÌhøí­pG½ÉˆBÌõù4…E7ŠHû€Õ-99tS\/¤f/<Íhù¼*UʆVþ1V/?%Ї÷ ññŽ ©IˆŸ@Ð +}ÜÎà­Y:ôE(%n‚ÌÛðd^W¥è1¥–ª¨%CÇ=}DÇîÈèaúõ=M]5Õ87pôõ„&5-%--¼ÍmZ÷ô™¸¼vø7k÷ôËêè•&-CCi4Dé~õpŠ’wß>I‰ýpŒØÞ‚Nb¡½I9t“ê®°= bvs=})/W)Y©|°Z€ý±7yU[\9â* âønZþXÛUWßNbîj—õݝÙvô!;±n·Àzڎû äj²÷Ô8wD,Aüæ—;GÊYìr@¹= uvlÃ÷ãƦ¶ª¼Kàd#&$p +¯"cØK+4D°/ç©»ÜÙykƒXé'öéáØutåkg%]É͗Ø7,Nï;1>û—kç)oT }wՖKJ<’¡ÚFû —Ö1ž KЧõ¹‰ùV³ y‚¹ß.Ðï{ä~eÎRFù]ùUDF8mbþüÞr- +Z8‚Qü\ÎUôÖ ü¾]YÙ]¢’ᄀÙ©ˆ}ۗd)úSvN/@o‰7fwB +m Þ:r~¬= Yvt‘Ôª:¾Ý²ó"?&bzÝëB““,¦d‹Gý¤Ê¦=MÞ.[lÉŽªÚŠJ^Ü8Ënp™ZyÝàoЄ²‚°•s_*Žß‡âˆd“wfæ&cdŸ¥¬¯ŽÌóŽâ¤¢õ$*ª§Y¹›ð‘Hw.aE:†= /ŸˆN +4šUØzŸÁÂêywê +2¦¶—û’æ}juJáͼ ‡‰švb9Âüò↢˜¶ÿ… +|!â(œ|˰óÕ¿\£(~©û#c/£†u¤Çü¤a¬3²õQû3¨°%kžªŒÛÝk™8ä¿ê&—_Â>Í'Ñ´Eüˆ³Þ)[–+ßå—{Áô+N’æÛ€=M7¯–†Ó.ª)ÜàÙo~x_jfžÓï®ð'dl«ÆMç;vÌe=}‚ÅB¶„ƒ™«ÊÆ?„OÎmLµô1×-Uã7ðEÏý¸ŸtËâ2uì¸F=MßéEõ¯ *»\âjûÚÖiB<Ô½h«a,z¹ +4Û Žhl‚Êq€¢†o½J„$ÛuþyíµW«É³4!n§¸)Ê[ßÌds°¬WJ¶o5Ã2álißìÕMÈ|tܬbÊìrìõ5ÈÜì’5Ÿë”O - ˜ö™ìÄ/ëÔ -¶žöçI»ÇqfÑ"ÁW»³ª£C¹»-!Ö~™V€lY~Y~Y~Y^ÝµËøìï$v§PµkÿCf¶$¨¢-?lǕÈZë}=}Å\],÷BÏu&kSVÅv,Ï0ÐTä7{ùó +à,= ÈÙp3û\ø‘È,ԒÈÇ3LRl·ÑÉÆ×9œ#o0ÜÕm—\Éö•VïUÇ­zï(ŒÈ¸M×öëÛû„s(q·U÷ۜøDÕ8g1m=}uÍèþK½EuDmҞ÷©õ,˜û0¢0á×áWs Û÷†å0ž× €u›^阇ݎ¿@¢m‹÷=MDÖ+qv¨Ý@‰Ú¹ x\ß1Zf7GÑ"þÑðî[¿Å™ŒÞnˆ…ù:Ϻýb|·~†îÙ²ÒBêN=}Á–]?¾’”Ž=M2Ïjß­à—K¢*ò2wáB| 9X“üÖ{ +€ßBxÞ ¹”<¡ +û_#±õãX¥¤w±ëÐƒ˜'#= N¦i¿®KÓÀÂÄZõ(ï˜åm7¬œVkM$Ä8Š'~™b»…_¬ÜµÎE=My+ª\Æ=}ú.|ÄE|‹+žîÆÍÂ+ÛÎe›½ ó¿£{«#Ãû~Y^<ƒwY~Y~Y~YÿÔÐ#’è¦÷Õ¥Oµƒúb£o£†Úª[Ù㕺¤/»sÒ¶OΦÚà+u½U±(-–Duñ ¼Ýa(A&—pÁGhÃM© táë04ä'h䕐°µ’3jÂ%í³Q³Ø%ÄUy«”K+œFæ÷½Å„¡³Þ' —Ìç?ç9‰±¶­(\õÆï6ñ2±v ;že_´‰hjÓØ¶éÛ=}Îå„'”xÆ_Œ³ä¿¸}…«ò™çËÐ垚´yi¶9Ãæè¤= -ãJY¥v*¬>Ò*c6.¥¬ç,ȵ֖¢ÐƵh¸œÿ‡l£4–ÖèYµ<ýGf¶´ˆRë}×µ2.ëO÷ÈýØ3kvö…qç,TNÇmÂ9þƒº,o,Y‡94&ÕºNlw Ò[ïX¨Õ +k§ÒmOÌ6ß)åJ¯­Šîˇٸ]ÚùÛþÄ¡·¨0e“Æ­’Ë_žE3ÄTíÛZíæ÷ùø<ùló8˜øY b +øÙßøü™úý=M0$(Ø=}l½í0Øa1tÛ]çŸÁ0mú×õ_tÛ¶ö +ãé@EÈ»Ý ½Œ‹HVE1UõŠ•¤@}Ú‘= ¢¢†½ÿqÃ:Ô{ ¾G=MsN2dXl©(ù¾—à…Iä52©ñß64üð™8Ô +>¢VÉ$áÉXÊ>ü՟Clw¾É–>Ï/ÔÒVhwõ¹fð.Ñ0Ï=MšW«ïSë^…. úÏé_YS{Çñ_KðhÉ">î@]1Uì\s x¾q|?† Y\;dqŠۋóUMfy±Ô©Ü×?„S@æ5F±ÞÏ ‹“ßQîQÏÑXî\/ØÿÙ\‚pȍû:¯.-¬AôB];b—‡Á4_ÁȔkù|Æî2º ß1ï”;\mFˆ$¢Ø2ÂRàYêš ByÊ +B®%òš½áŒ~œÀq—\VqJ|´BzÚ ý= šµNµxÖ÷… tí·5ÎÔ¡Â&…£Ãç£çt~Y| ~Y~Y~Y€“n³väCmÓ$lV¨‘³kïcbÐӞ&c\»Å"u-ÒÏõF]+R.— ÒÕ+k7<ÅÖy,ïâÏՔ)k3ZÅÀFí LÇmˆ:ëøü…PÇTZ8g“¡µJëgÌRçzîµüBî?ÐtÝTïo¿ÕVnk‡ÃVx:Ìv ~ <%®¹4ìõI–<ÎÂÆW;­&vÍÿÍK3QM%PËoÀdžÎç>Eó(%[êD–¨(Tò·¹¡óûºþ 8ÀhøYwõüMoCÕ+ín¼ÍØzKáC•ŒUm¡ŠÍf!NwëG´È>iY5½ðŽ ÇWØÙw Ó÷†Œ¯0×EÁs»!üƉ0¤b×áÊs”U‹?ËQ6Z9qÓæŠÞ@&]ñx|\办@%ŠêÝa-Ü@d~%©ôM»Ç5¯õXÓëv~ÈÛ&›®°¡Ù!oƒ—ð&ø¯©èÕ45=}l•E7l-ÝÉ$5M&lTäɐJ=}ÇüU:ì˜VÉz‘>[BïAéZ«öüptK_h©¹|ß.Ä@Б²XËáf“Í.Öϵ@ZKšÓ%"Y{µf‰!Í>‹U8ẐcIDU¬*{×@ †QS4|÷ÞöƒAð5²Ù’EÛ¿ð‰ÓÐ*&úmÄú* +]fŸÙ±åâ*k¶¿9ÒKX|„l´*Az¿…_;—vÄèß:lŒ…¹ŒötˆÆ:an=}qÑÔ)] vÿ9ÐZfHsÌ:yZ¹a\“zˆúå2¯<àm¸”³M'%ê*sFþz+À‰t!]êSeF”ñ2ÕJßu€™›™}†oÂ2ܬ=}—lþkŠèèB¨0=}á¢ÝÏ¼‡öUr há@Z›ç܍֕MòŸ +áÆaè©Wò¸Öúã(u¤=M¨ø¦=MY¯;uփyk#V¥‡ø¤F¨ß¸“‹ùã/z¤ü"ª7,ºõÊ+7ÒçÒºTæ§ÆGéŽ3…= æu0±œÞ·iM3^åA­LÎǁN36âf¢¯9¦[¸ô³#V~YŽrYy^ª||Y~Y~ّûBê¯-óË(d ©æ.¾L CLäÆnƒô¦;d~L©‘õ&*þ¯½¿Ô{|Æ&äB¯èÓl6cGò6æœïÅ:ØÌþjGþ6HalœáÉBê<Ç;5HìŒÀÉx1>w= ¹…JÉØa'Æü‡ð 4Ï&hR¹ÚSû~óÎ.}AèE¹:êû/@ô!éÙ0Ý}vÙ,©}ۆpT,U}Iiñ>ôj±Xœ¡{ÉnÊ>}„Àÿ*ÔLÀ¹ˆ{ÿ¸*f0åd2{s‚»*V¿?¸±8ZÜGᅓ™Efqž± ‚Ý“~„ê:Øìý,÷süü:-XX”:€ÿ*\Ÿ>ƒuAn~xÑP]¿Þ‰5†-n“*њ‚\D"lã¯2FìàE™KócFÊÁÎ=Mÿ=M‰”€“ë}hƂã2-àr• aFˆ¹2 ªàA–Ë~ƚ®2'àáè“ܾz +ôÍÂ@€J÷´B¸ŸsžŒ6f™\yxJ¢ÃB—†™o• [Šl ÂcŠ~<ó€ðB2ò oòáú¢œ70¸SÛüãgo¤Ð•ªOÎÀ“JýãHi¤f}ª¿±¥!š­kàÏCœG#¤–¥¹O­{VЃuD#ꊥ­›—ÏgB¥Ÿ®»öÄL +éd_%aȨ0M«UÚ³Ð{Š«©¶Óˇ2´O;Ä _ç“ += äl†%.:§À‘¬= · Í›½EîAÈ6×pÇÜ7ú5PGçlF5PÇfÐlhq5G ÈðéíÉï4¿<Ҝ_í5 >GŸäì^Ö5zȆÁì‰_8ϞÄü¸ìTÅQ­hwo-S­bGEè- иZ¯híHs ·è)ÌáòóO7•~8 ª7‘Ê8¡:7Z8´ò%!N—žI R×,=M70 +íçîßlo/Î wÎ +ÇNRÏ wŒ 猎 +×Âç?ÏB· ÿü W€} ›!†r”CÒ§¢)t‘D˜Hô•6T•:´Ü%vÍ)VÖ$¶ÆLvÓPªAqV_ñ]ñ–UqoMqT]qJIñEñtñæ²é2 ò9qyÏyQù¹I‘)¿Ý@–)h¤}±Ã©EX~Y~þ~Ya€ÇX~Y~YžÂ/*-:¥a¸ÃŸF£š©{›Ôã¢B¤m*ç,ƒÛ¾€ÔÅaF jj1œ|¿–܁ƒ»i4Y-ê8i1~P¿PÝÜ—Wސßkô"7†—çê¡<1(®¿ù§yޙg€ºWލ{i”’UF‡jƒê1 ÒÀâÛu¢w¬‰¼³yV×-Š rFçABÌàôÕµˆ“Gp’lÿw6H/ÊöòMýA›°à„þáZ–|ŽßVž¥æß¸êµò•_?„|ׂ†9•Q˜üTnv“Cʅ¬r9A©úàb ᕇŒÜ™öš>Š”Âòjóež«å:‹en[åVÇeH÷å”/eå/årÅe(5å)­åb=MeœÝå…iåN9em™äbQå½Ê׍Æï»Ç¿»Ä_ÁÊg?͇<ÐwýËѯÎo{ÏÏ~ÌÒâ͏ßÀgº&Ÿœ‰{îD~DqúĂÄñ«ˆûˆë=MïHÈõˆöÍ©HþÙÈÁˆ!äÔ(Õm.-m{íY]m|éí>¹mBYm[qí…AmÕô՚öy°±…4m•í5Ìm'íkžítÊ-_÷yaö‘ ùÅ¢÷•¡ö½(՝(ډçÔYj×qhÖÁÈÙáIÓ¡IØeÙŇÓʼnØe¸Õ%ºÖa8Õ7ÚQøÔ±w×9zÖéØÙÝWÓmWØ5ÕáÖ±ª/, ׋ÇÂßÁϽ×Ag<??‹¥Æõ†ŸíÆSq+Z|{Y€Kajc‹w+m;që|û€kjû Ã‹šw;šu+œq»Ÿl››p ›~Û·OÚ åš ë›ß/>¢¯9¦»¸ã³'V~YŽrY~_@~Y~YYqVò6Ò=}åÏ¢1Šk5{tÒ\†=Mꋯ1uü¿fÛ±‡΃ëúgôZ'¼j)­1ø¿â=Mۅw‡ ‹KswtWHFþjƒ11ÀvÝ šo8bªœ¢Ó22¯½Š˜É  9ZBŠ+Vk”L†íjIX14¾À°ZÝՒŸ|†Û!cÔ¡+F}¬ê/Ö1nŠÀÒÞíÿŸ_ˆû rôšDƇöj}º1M¿B‚ÞÉ"‘"ܽŸAF¾ æ¼„f¼öŽ”F½–»,…»V†¾Ô¶¾5¼äõ<ŠºéÃ&ôÑ.TÜ^´ÊZtÚBVC4N+Ôa[”G74J?ÔUEœA»ì»P¾޼’½½<=}½þ».þ^é'ñédQÁŽï +ß7´34Kô'ôWt?ÔEÔ-T]T9TQT"$ T‚n/¦Î0€/pŽ0¸>/|þ0tÞ/^0 ž/Uª0Ïê/ j0²Ê0 +/8Š0¤:/½ú0wÚ/Z/Æ0¤2àÕ…àØ‘ßډ_Ս_ØE"Óñ"•Ù0â/êb/¬"0ŸähFƒË4ÄOÛ¶W0Çå踖E.?Tg,ÛE”ßD‹AçŸðÉ)I·„u+Ԍç'/áV«4ð[¿…ÑtÅR[9·ÒÇÙ·¹”-,$ÈgvõEüTE_«üì×QÅù¶4- Xhy]Åç¦ôH4;€çß=MÉuY·þ.XhŽ™ÅðÊtW.;xðÿ‹Ä%š¹|žo,µÞ©+côKzÀÑm/·Pê.ÄhŸ”žç U«ï¸ÂI.ÃVçgÜÅqß4$ëXëGþÅÕϖ(ë^íGÿƵP¶Ôڛ]Ú,â>h~P…qJ{_þoŽ’âËíÀ¹L2-3jèƒ'{íï߯ý@¶œÑ+«:gnhøt]Ëö'[Ðñ´‘,­¤R–ó?Ç)á´(A,ÒrhM:E„´œP{šñW¢Ã"µªâ.yèG’v²ô :›—þïŸÎÕ¨Œr,C  ¿_â‚å— +K¡Ç­vB˜žö‹âš³¨k$¨ó×ñ}Y~Y~Y~Y~Y~ º’ÉŠ×îb=Mž!ªu©y=}©xj Ž(sfŒ >*ye +þ(vŒ +>éwn ét´ .é’9J9ÙX9 GAYþߐ Ðå^2¶|?ç6;÷JRpNR@6õn=}ýÎ;iá†W™¯JZ¾Û&Àk~c< !¹ðù@Ù"ÞÅJˆu¼‰T>ÛRáØBQØbéUCáS3_(CÍê–˜8z†±ÎD"ÐLzvˆÉÏFNÏN ÏzÐ~ ‘­Qúì¶üüªýèöûx”xßrþf˜ÜIYQX1 +ONÞOJw‘Ñ=MZU!šÆrt{Ÿ=}‹ü>Œ÷>^Ҟ=}¶Zw$YU>ür>^0ùvþG@9ôzþ_¦ÀpM6 j@àöº^*^=M^n9ÿоZ*ñ\JžH²wžáŠýÂÐ ֌ +Q ØFâZÀ ٝ‚ÿ&X<½ƒãæ€Öê) Ú*BÆ_Z4¡7iü¶Ÿ9Æ¿R°‘Óq /ÚÆ “®ïwGñalA-q4„¡v–ž4Øf:;Ùv¿WfT +>ÀV‰›˜ÿŠ<Šr¼Ö‚‚CZxµHpŊV­fhÜ:!;\o¯9ÇüSåî_õÆl_ø1<_iÿy]± zi˜aúӎ0QðYðQî>p‰HäAî9P®°YÜâfZØlNlPîáèð•ÖݐR‡´ç}Ž?ÇuÌRÇ != Ôܱ›!kóŽíaæ!Ç2!º|2 &ìNäeA2+j>‚ñ[±rKLáæö÷…Œ>j•.i\ÈúÌKæ—ýõ„_’0º×R_C/™à4ќÑ\å¹À—·áô„-³M;&gy舿lWt \åM¾Qh¸õ‹Gž1§ýŒ1¿Å5 ]ľ› 1Ù?¼ßÄ= !]ºê«JFQqA4ùò€(ŸDLÑoñ¶ñþ$,ÿÅUi]Õ6[ëPüé/ãòoBA‰ÐlWz˜Ç›cÒ¶=M®Ù—¤^·±º±ùô>né7i/9Z•çÉüô3à³ð_Ãóö˽÷PÖ]÷ÃÝ¡ ßýyÄ¿ÉiF”@ Âý0eèS¡¤7aâ¬= ›A$weZó‚šr4…ÚWT$-‚؅RnpÛvj¶ÚXŒÁ+= :«ß‰ù«›_¶qn¿#†:0jž*†· +ßA»ŒgR¯Ní= P{SÂò>9'¢ÛA$ +Š™ŠÛ"eÚ?ùèÈQ|éõÓmï- –ànüìŠj¤‡ñÒä?NåkZp@돣Õ]= Û¼ÔßAç5ݚú´†þksž¬7ç=MrqÎF5^&A6ژa4Zâ·}OV49IqsÆrÐqQ£]t͋\aÄWfƒñ×Ul£ÝwÛAMre 0é”ð Ê@T +¸À3= (QJH5‹ƒi¼wp!6©ø"ñâaŸí= ÑÎOKB4¨÷ÕVÀîàûœæ¹í£>œMath.atan(t),a:t=>Math.cos(t),d:t=>Math.exp(t),e:t=>Math.log(t),f:(t,s)=>Math.pow(t,s),c:t=>Math.sin(t),g:(t,s,i)=>r.copyWithin(t,s,s+i),h(t){r.length,(()=>{throw"OOM"})()}}};this.u=s=>{t.u(pe,s)},this.U=()=>t.U(pe),this.instantiate=()=>(this.U().then((t=>WebAssembly.instantiate(t,d))).then((t=>{const i=t.exports;var e;h=i.k,o=i.l,a=i.m,l=i.n,c=i.o,u=i.p,U=i.q,e=(n=i.i).buffer,r=new Uint8Array(e),(t=>{t.j()})(i),s()})),this.ready=new Promise((t=>{s=t})).then((()=>{this.I=n.buffer,this.V=o,this.free=U,this.Fs=h,this._s=a,this.Vs=l,this.ks=c,this.Ss=u})),this)}function Me(){return this.qs=()=>(new this.Hs).instantiate(this.$s,this.Cs).then((t=>{this.Is=t,this.js=this.Is._(this.Js,Uint8Array),this.xs=!0,this.Ps=this.Is._(1,Uint32Array),this.Ds=this.Is._(1,Uint32Array),this.Es=this.Is._(1,Uint32Array),this.Os=this.Is._(1,Uint32Array),this.Ns=this.Is._(1,Uint32Array),this.Zs=this.Is._(256,Uint32Array),this.zs=this.Is._(1,Int32Array),this.gs=0,this.Ks=0,this.Qs=0,this.Rs=this.Is.M.Fs(this.js.H,this.Ps.H,this.Ds.H,this.Es.H,this.Os.H,this.Ns.H,this.Zs.H,this.zs.H,256)})),Object.defineProperty(this,"ready",{enumerable:!0,get:()=>this.Gs}),this.reset=()=>(this.free(),this.qs()),this.free=()=>{this.Is.M.Ss(this.Rs),this.Is.free()},this.sendSetupHeader=t=>{this.js.C.set(t),this.Ps.C[0]=t.length,this.Is.M._s(this.Rs,this.xs),this.xs=!1},this.initDsp=()=>{this.Is.M.Vs(this.Rs)},this.decodePackets=t=>{let s=[],i=0,e=[];for(let r=0;r{if("vorbis"!==t)throw Error("@wasm-audio-decoders/ogg-vorbis does not support this codec "+t)},new r,this.qs(),this[ye](Me)}qs(){this.Ls=!0,this.Ws=0,this.ut=new oe("audio/ogg",{os:this.zt,Us:!1})}[ye](t){if(this.Rs){const t=this.Rs;t.ready.then((()=>t.free()))}this.Rs=new t,this.Gs=this.Rs.ready}get ready(){return this.Gs}async reset(){return this.qs(),this.Rs.reset()}free(){this.Rs.free()}async ti(t){const s=[];for(let r=0;rt[le])))}const i=await this.Rs.decodePackets(s);this.Ws+=i.samplesDecoded;const e=t[t.length-1];if(e&&e[ue]){const t=this.Ws-e[fe];if(t>0){for(let s=0;s= 0 || value.indexOf("flag:") >= 0 || value.indexOf('global:') >= 0)) { - if (value.indexOf('status:') >= 0) - value = value.replace(/status:([a-zA-Z0-9_]+)/g, "core.getStatus('$1')"); - if (value.indexOf('buff:') >= 0) - value = value.replace(/buff:([a-zA-Z0-9_]+)/g, "core.getBuff('$1')"); - if (value.indexOf('item:') >= 0) - value = value.replace(/item:([a-zA-Z0-9_]+)/g, "core.itemCount('$1')"); - if (value.indexOf('flag:') >= 0 || value.indexOf('flag:') >= 0) - value = value.replace(/flag[::]([a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]+)/g, "core.getFlag('$1', 0)"); - //if (value.indexOf('switch:' >= 0)) - // value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)"); - if (value.indexOf('global:') >= 0 || value.indexOf('global:') >= 0) - value = value.replace(/global[::]([a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]+)/g, "core.getGlobal('$1', 0)"); - if (value.indexOf('enemy:') >= 0) - value = value.replace(/enemy:([a-zA-Z0-9_]+)[\.:]([a-zA-Z0-9_]+)/g, "core.material.enemys['$1'].$2"); - if (value.indexOf('blockId:') >= 0) - value = value.replace(/blockId:(\d+),(\d+)/g, "core.getBlockId($1, $2)"); - if (value.indexOf('blockNumber:') >= 0) - value = value.replace(/blockNumber:(\d+),(\d+)/g, "core.getBlockNumber($1, $2)"); - if (value.indexOf('blockCls:') >= 0) - value = value.replace(/blockCls:(\d+),(\d+)/g, "core.getBlockCls($1, $2)"); - if (value.indexOf('equip:') >= 0) - value = value.replace(/equip:(\d)/g, "core.getEquip($1)"); - if (value.indexOf('temp:') >= 0) - value = value.replace(/temp:([a-zA-Z0-9_]+)/g, "core.getFlag('@temp@$1', 0)"); - } - return value; -} + if ( + typeof value == "string" && + (value.indexOf(":") >= 0 || + value.indexOf("flag:") >= 0 || + value.indexOf("global:") >= 0) + ) { + if (value.indexOf("status:") >= 0) + value = value.replace(/status:([a-zA-Z0-9_]+)/g, "core.getStatus('$1')"); + if (value.indexOf("buff:") >= 0) + value = value.replace(/buff:([a-zA-Z0-9_]+)/g, "core.getBuff('$1')"); + if (value.indexOf("item:") >= 0) + value = value.replace(/item:([a-zA-Z0-9_]+)/g, "core.itemCount('$1')"); + if (value.indexOf("flag:") >= 0 || value.indexOf("flag:") >= 0) + value = value.replace( + /flag[::]([a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]+)/g, + "core.getFlag('$1', 0)" + ); + //if (value.indexOf('switch:' >= 0)) + // value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)"); + if (value.indexOf("global:") >= 0 || value.indexOf("global:") >= 0) + value = value.replace( + /global[::]([a-zA-Z0-9_\u4E00-\u9FCC\u3040-\u30FF\u2160-\u216B\u0391-\u03C9]+)/g, + "core.getGlobal('$1', 0)" + ); + if (value.indexOf("enemy:") >= 0) + value = value.replace( + /enemy:([a-zA-Z0-9_]+)[\.:]([a-zA-Z0-9_]+)/g, + "core.material.enemys['$1'].$2" + ); + if (value.indexOf("blockId:") >= 0) + value = value.replace(/blockId:(\d+),(\d+)/g, "core.getBlockId($1, $2)"); + if (value.indexOf("blockNumber:") >= 0) + value = value.replace( + /blockNumber:(\d+),(\d+)/g, + "core.getBlockNumber($1, $2)" + ); + if (value.indexOf("blockCls:") >= 0) + value = value.replace( + /blockCls:(\d+),(\d+)/g, + "core.getBlockCls($1, $2)" + ); + if (value.indexOf("equip:") >= 0) + value = value.replace(/equip:(\d)/g, "core.getEquip($1)"); + if (value.indexOf("temp:") >= 0) + value = value.replace( + /temp:([a-zA-Z0-9_]+)/g, + "core.getFlag('@temp@$1', 0)" + ); + } + return value; +}; ////// 计算表达式的值 ////// utils.prototype.calValue = function (value, prefix) { - if (!core.isset(value)) return null; - if (typeof value === 'string') { - if (value.indexOf(':') >= 0 || value.indexOf("flag:") >= 0 || value.indexOf('global:') >= 0) { - if (value.indexOf('switch:') >= 0) - value = value.replace(/switch:([a-zA-Z0-9_]+)/g, "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)"); - value = this.replaceValue(value); - } - return eval(value); + if (!core.isset(value)) return null; + if (typeof value === "string") { + if ( + value.indexOf(":") >= 0 || + value.indexOf("flag:") >= 0 || + value.indexOf("global:") >= 0 + ) { + if (value.indexOf("switch:") >= 0) + value = value.replace( + /switch:([a-zA-Z0-9_]+)/g, + "core.getFlag('" + (prefix || ":f@x@y") + "@$1', 0)" + ); + value = this.replaceValue(value); } - if (value instanceof Function) { - return value(); - } - return value; -} + return eval(value); + } + if (value instanceof Function) { + return value(); + } + return value; +}; ////// 向某个数组前插入另一个数组或元素 ////// utils.prototype.unshift = function (a, b) { - if (!(a instanceof Array) || b == null) return; - if (b instanceof Array) { - core.clone(b).reverse().forEach(function (e) { - a.unshift(e); - }); - } - else a.unshift(b); - return a; -} + if (!(a instanceof Array) || b == null) return; + if (b instanceof Array) { + core + .clone(b) + .reverse() + .forEach(function (e) { + a.unshift(e); + }); + } else a.unshift(b); + return a; +}; ////// 向某个数组后插入另一个数组或元素 ////// utils.prototype.push = function (a, b) { - if (!(a instanceof Array) || b == null) return; - if (b instanceof Array) { - core.clone(b).forEach(function (e) { - a.push(e); - }); - } - else a.push(b); - return a; -} + if (!(a instanceof Array) || b == null) return; + if (b instanceof Array) { + core.clone(b).forEach(function (e) { + a.push(e); + }); + } else a.push(b); + return a; +}; utils.prototype.decompress = function (value) { - try { - var output = lzw_decode(value); - if (output) return JSON.parse(output); - } - catch (e) { - } - try { - var output = LZString.decompress(value); - if (output) return JSON.parse(output); - } - catch (e) { - } - try { - return JSON.parse(value); - } - catch (e) { - console.error(e); - } - return null; -} + try { + var output = lzw_decode(value); + if (output) return JSON.parse(output); + } catch (e) {} + try { + var output = LZString.decompress(value); + if (output) return JSON.parse(output); + } catch (e) {} + try { + return JSON.parse(value); + } catch (e) { + console.error(e); + } + return null; +}; ////// 设置本地存储 ////// utils.prototype.setLocalStorage = function (key, value) { - try { - if (value == null) { - this.removeLocalStorage(key); - return; - } - - var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { - return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) - }); - localStorage.setItem(core.firstData.name + "_" + key, str); - - if (key == 'autoSave') core.saves.ids[0] = true; - else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; - - return true; + try { + if (value == null) { + this.removeLocalStorage(key); + return; } - catch (e) { - console.error(e); - return false; - } -} + + var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { + return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4); + }); + localStorage.setItem(core.firstData.name + "_" + key, str); + + if (key == "autoSave") core.saves.ids[0] = true; + else if (/^save\d+$/.test(key)) + core.saves.ids[parseInt(key.substring(4))] = true; + + return true; + } catch (e) { + console.error(e); + return false; + } +}; ////// 获得本地存储 ////// utils.prototype.getLocalStorage = function (key, defaultValue) { - try { - var value = JSON.parse(localStorage.getItem(core.firstData.name + "_" + key)); - if (value == null) return defaultValue; - return value; - } catch (e) { - return defaultValue; - } -} + try { + var value = JSON.parse( + localStorage.getItem(core.firstData.name + "_" + key) + ); + if (value == null) return defaultValue; + return value; + } catch (e) { + return defaultValue; + } +}; ////// 移除本地存储 ////// utils.prototype.removeLocalStorage = function (key) { - localStorage.removeItem(core.firstData.name + "_" + key); - if (key == 'autoSave') delete core.saves.ids[0]; - else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))]; -} + localStorage.removeItem(core.firstData.name + "_" + key); + if (key == "autoSave") delete core.saves.ids[0]; + else if (/^save\d+$/.test(key)) + delete core.saves.ids[parseInt(key.substring(4))]; +}; -utils.prototype.setLocalForage = function (key, value, successCallback, errorCallback) { - if (value == null) { - this.removeLocalForage(key); - return; - } +utils.prototype.setLocalForage = function ( + key, + value, + successCallback, + errorCallback +) { + if (value == null) { + this.removeLocalForage(key); + return; + } - var name = core.firstData.name + "_" + key; - var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { - return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4) - }); - var callback = function (err) { - if (err) { - if (errorCallback) errorCallback(err); - } - else { - if (key == 'autoSave') core.saves.ids[0] = true; - else if (/^save\d+$/.test(key)) core.saves.ids[parseInt(key.substring(4))] = true; - if (successCallback) successCallback(); - } + var name = core.firstData.name + "_" + key; + var str = JSON.stringify(value).replace(/[\u007F-\uFFFF]/g, function (chr) { + return "\\u" + ("0000" + chr.charCodeAt(0).toString(16)).substr(-4); + }); + var callback = function (err) { + if (err) { + if (errorCallback) errorCallback(err); + } else { + if (key == "autoSave") core.saves.ids[0] = true; + else if (/^save\d+$/.test(key)) + core.saves.ids[parseInt(key.substring(4))] = true; + if (successCallback) successCallback(); } - this._setLocalForage_set(name, str, callback); -} + }; + this._setLocalForage_set(name, str, callback); +}; utils.prototype._setLocalForage_set = function (name, str, callback) { - if (window.jsinterface && window.jsinterface.setLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - core.saves.cache[name] = str; - window.jsinterface.setLocalForage(id, name, str); - } else { - var compressed = str.length > 100000 ? LZString.compress(str) : lzw_encode(str); - core.saves.cache[name] = compressed; - localforage.setItem(name, compressed, callback); - } -} + if (window.jsinterface && window.jsinterface.setLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + core.saves.cache[name] = str; + window.jsinterface.setLocalForage(id, name, str); + } else { + var compressed = + str.length > 100000 ? LZString.compress(str) : lzw_encode(str); + core.saves.cache[name] = compressed; + localforage.setItem(name, compressed, callback); + } +}; -utils.prototype.getLocalForage = function (key, defaultValue, successCallback, errorCallback) { - var name = core.firstData.name + "_" + key; - var callback = function (err, value) { - if (err) { - if (errorCallback) errorCallback(err); - } - else { - core.saves.cache[name] = value; - if (!successCallback) return; - if (value != null) { - var res = core.utils.decompress(value); - successCallback(res == null ? defaultValue : res); - return; - } - successCallback(defaultValue); - } - }; - if (core.saves.cache[name] != null) { - return callback(null, core.saves.cache[name]); +utils.prototype.getLocalForage = function ( + key, + defaultValue, + successCallback, + errorCallback +) { + var name = core.firstData.name + "_" + key; + var callback = function (err, value) { + if (err) { + if (errorCallback) errorCallback(err); + } else { + core.saves.cache[name] = value; + if (!successCallback) return; + if (value != null) { + var res = core.utils.decompress(value); + successCallback(res == null ? defaultValue : res); + return; + } + successCallback(defaultValue); } - this._getLocalForage_get(name, callback); -} + }; + if (core.saves.cache[name] != null) { + return callback(null, core.saves.cache[name]); + } + this._getLocalForage_get(name, callback); +}; utils.prototype._getLocalForage_get = function (name, callback) { - if (window.jsinterface && window.jsinterface.getLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - window.jsinterface.getLocalForage(id, name); - } else { - localforage.getItem(name, callback); - } -} + if (window.jsinterface && window.jsinterface.getLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + window.jsinterface.getLocalForage(id, name); + } else { + localforage.getItem(name, callback); + } +}; -utils.prototype.removeLocalForage = function (key, successCallback, errorCallback) { - var name = core.firstData.name + "_" + key; - var callback = function (err) { - if (err) { - if (errorCallback) errorCallback(err); - } - else { - if (key == 'autoSave') delete core.saves.ids[0]; - else if (/^save\d+$/.test(key)) delete core.saves.ids[parseInt(key.substring(4))]; - if (successCallback) successCallback(); - } +utils.prototype.removeLocalForage = function ( + key, + successCallback, + errorCallback +) { + var name = core.firstData.name + "_" + key; + var callback = function (err) { + if (err) { + if (errorCallback) errorCallback(err); + } else { + if (key == "autoSave") delete core.saves.ids[0]; + else if (/^save\d+$/.test(key)) + delete core.saves.ids[parseInt(key.substring(4))]; + if (successCallback) successCallback(); } - delete core.saves.cache[name]; - this._removeLocalForage_remove(name, callback); -} + }; + delete core.saves.cache[name]; + this._removeLocalForage_remove(name, callback); +}; utils.prototype._removeLocalForage_remove = function (name, callback) { - if (window.jsinterface && window.jsinterface.removeLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - window.jsinterface.removeLocalForage(id, name); - } else { - localforage.removeItem(name, callback); - } -} + if (window.jsinterface && window.jsinterface.removeLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + window.jsinterface.removeLocalForage(id, name); + } else { + localforage.removeItem(name, callback); + } +}; utils.prototype.clearLocalForage = function (callback) { - core.saves.cache = {}; - if (window.jsinterface && window.jsinterface.clearLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - window.jsinterface.clearLocalForage(id); - } else { - localforage.clear(callback); - } -} + core.saves.cache = {}; + if (window.jsinterface && window.jsinterface.clearLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + window.jsinterface.clearLocalForage(id); + } else { + localforage.clear(callback); + } +}; utils.prototype.iterateLocalForage = function (iter, callback) { - if (window.jsinterface && window.jsinterface.iterateLocalForage) { - var id = setTimeout(null); - core['__iter' + id] = iter; - core['__callback' + id] = callback; - window.jsinterface.iterateLocalForage(id); - } else { - localforage.iterate(iter, callback); - } -} + if (window.jsinterface && window.jsinterface.iterateLocalForage) { + var id = setTimeout(null); + core["__iter" + id] = iter; + core["__callback" + id] = callback; + window.jsinterface.iterateLocalForage(id); + } else { + localforage.iterate(iter, callback); + } +}; utils.prototype.keysLocalForage = function (callback) { - if (window.jsinterface && window.jsinterface.keysLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - window.jsinterface.keysLocalForage(id); - } else { - localforage.keys(callback); - } -} + if (window.jsinterface && window.jsinterface.keysLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + window.jsinterface.keysLocalForage(id); + } else { + localforage.keys(callback); + } +}; utils.prototype.lengthLocalForage = function (callback) { - if (window.jsinterface && window.jsinterface.lengthLocalForage) { - var id = setTimeout(null); - core['__callback' + id] = callback; - window.jsinterface.lengthLocalForage(id); - } else { - localforage.length(callback); - } -} + if (window.jsinterface && window.jsinterface.lengthLocalForage) { + var id = setTimeout(null); + core["__callback" + id] = callback; + window.jsinterface.lengthLocalForage(id); + } else { + localforage.length(callback); + } +}; utils.prototype.setGlobal = function (key, value) { - if (core.isReplaying()) return; - core.setLocalStorage(key, value); -} + if (core.isReplaying()) return; + core.setLocalStorage(key, value); +}; utils.prototype.getGlobal = function (key, defaultValue) { - var value; - if (core.isReplaying()) { - // 不考虑key不一致的情况 - var action = core.status.replay.toReplay.shift(); - if (action.indexOf("input2:") == 0) { - value = JSON.parse(core.decodeBase64(action.substring(7))); - core.setFlag('__global__' + key, value); - core.status.route.push("input2:" + core.encodeBase64(JSON.stringify(value))); - } - else { - // 录像兼容性:尝试从flag和localStorage获得 - // 注意这里不再二次记录 input2: 到录像 - core.status.replay.toReplay.unshift(action); - value = core.getFlag('__global__' + key, core.getLocalStorage(key, defaultValue)); - } + var value; + if (core.isReplaying()) { + // 不考虑key不一致的情况 + var action = core.status.replay.toReplay.shift(); + if (action.indexOf("input2:") == 0) { + value = JSON.parse(core.decodeBase64(action.substring(7))); + core.setFlag("__global__" + key, value); + core.status.route.push( + "input2:" + core.encodeBase64(JSON.stringify(value)) + ); + } else { + // 录像兼容性:尝试从flag和localStorage获得 + // 注意这里不再二次记录 input2: 到录像 + core.status.replay.toReplay.unshift(action); + value = core.getFlag( + "__global__" + key, + core.getLocalStorage(key, defaultValue) + ); } - else { - value = core.getLocalStorage(key, defaultValue); - core.setFlag('__global__' + key, value); - core.status.route.push("input2:" + core.encodeBase64(JSON.stringify(value))); - } - return value; -} + } else { + value = core.getLocalStorage(key, defaultValue); + core.setFlag("__global__" + key, value); + core.status.route.push( + "input2:" + core.encodeBase64(JSON.stringify(value)) + ); + } + return value; +}; ////// 深拷贝一个对象 ////// utils.prototype.clone = function (data, filter, recursion) { - if (!core.isset(data)) return null; - // date - if (data instanceof Date) { - var copy = new Date(); - copy.setTime(data.getTime()); - return copy; - } - // array - if (data instanceof Array) { - var copy = []; - for (var i in data) { - if (!filter || filter(i, data[i])) - copy[i] = core.clone(data[i], recursion ? filter : null, recursion); - } - return copy; - } - // 函数 - if (data instanceof Function) { - return data; - } - // object - if (data instanceof Object) { - var copy = {}; - for (var i in data) { - if (data.hasOwnProperty(i) && (!filter || filter(i, data[i]))) - copy[i] = core.clone(data[i], recursion ? filter : null, recursion); - } - return copy; + if (!core.isset(data)) return null; + // date + if (data instanceof Date) { + var copy = new Date(); + copy.setTime(data.getTime()); + return copy; + } + // array + if (data instanceof Array) { + var copy = []; + for (var i in data) { + if (!filter || filter(i, data[i])) + copy[i] = core.clone(data[i], recursion ? filter : null, recursion); } + return copy; + } + // 函数 + if (data instanceof Function) { return data; -} + } + // object + if (data instanceof Object) { + var copy = {}; + for (var i in data) { + if (data.hasOwnProperty(i) && (!filter || filter(i, data[i]))) + copy[i] = core.clone(data[i], recursion ? filter : null, recursion); + } + return copy; + } + return data; +}; ////// 深拷贝1D/2D数组优化 ////// utils.prototype.cloneArray = function (data) { - if (!(data instanceof Array)) return this.clone(data); - if (data[0] instanceof Array) { - return data.map(function (one) { return one.slice(); }); - } else { - return data.slice(); - } -} + if (!(data instanceof Array)) return this.clone(data); + if (data[0] instanceof Array) { + return data.map(function (one) { + return one.slice(); + }); + } else { + return data.slice(); + } +}; ////// 裁剪图片 ////// utils.prototype.splitImage = function (image, width, height) { - if (typeof image == "string") { - image = core.getMappedName(image); - image = core.material.images.images[image]; + if (typeof image == "string") { + image = core.getMappedName(image); + image = core.material.images.images[image]; + } + if (!image) return []; + width = width || 32; + height = height || width; + var canvas = document.createElement("canvas"); + var ctx = canvas.getContext("2d"); + var ans = []; + for (var j = 0; j < image.height; j += height) { + for (var i = 0; i < image.width; i += width) { + var w = Math.min(width, image.width - i), + h = Math.min(height, image.height - j); + canvas.width = w; + canvas.height = h; + core.drawImage(ctx, image, i, j, w, h, 0, 0, w, h); + var img = new Image(); + img.src = canvas.toDataURL("image/png"); + ans.push(img); } - if (!image) return []; - width = width || 32; - height = height || width; - var canvas = document.createElement("canvas"); - var ctx = canvas.getContext("2d"); - var ans = []; - for (var j = 0; j < image.height; j += height) { - for (var i = 0; i < image.width; i += width) { - var w = Math.min(width, image.width - i), h = Math.min(height, image.height - j); - canvas.width = w; canvas.height = h; - core.drawImage(ctx, image, i, j, w, h, 0, 0, w, h); - var img = new Image(); - img.src = canvas.toDataURL("image/png"); - ans.push(img); - } - } - return ans; -} + } + return ans; +}; ////// 格式化时间为字符串 ////// utils.prototype.formatDate = function (date) { - if (!date) date = new Date(); - return "" + date.getFullYear() + "-" + core.setTwoDigits(date.getMonth() + 1) + "-" + core.setTwoDigits(date.getDate()) + " " - + core.setTwoDigits(date.getHours()) + ":" + core.setTwoDigits(date.getMinutes()) + ":" + core.setTwoDigits(date.getSeconds()); -} + if (!date) date = new Date(); + return ( + "" + + date.getFullYear() + + "-" + + core.setTwoDigits(date.getMonth() + 1) + + "-" + + core.setTwoDigits(date.getDate()) + + " " + + core.setTwoDigits(date.getHours()) + + ":" + + core.setTwoDigits(date.getMinutes()) + + ":" + + core.setTwoDigits(date.getSeconds()) + ); +}; ////// 格式化时间为最简字符串 ////// utils.prototype.formatDate2 = function (date) { - if (!date) date = new Date(); - return "" + date.getFullYear() + core.setTwoDigits(date.getMonth() + 1) + core.setTwoDigits(date.getDate()) - + core.setTwoDigits(date.getHours()) + core.setTwoDigits(date.getMinutes()) + core.setTwoDigits(date.getSeconds()); -} + if (!date) date = new Date(); + return ( + "" + + date.getFullYear() + + core.setTwoDigits(date.getMonth() + 1) + + core.setTwoDigits(date.getDate()) + + core.setTwoDigits(date.getHours()) + + core.setTwoDigits(date.getMinutes()) + + core.setTwoDigits(date.getSeconds()) + ); +}; utils.prototype.formatTime = function (time) { - return core.setTwoDigits(parseInt(time / 3600000)) - + ":" + core.setTwoDigits(parseInt(time / 60000) % 60) - + ":" + core.setTwoDigits(parseInt(time / 1000) % 60); -} + return ( + core.setTwoDigits(parseInt(time / 3600000)) + + ":" + + core.setTwoDigits(parseInt(time / 60000) % 60) + + ":" + + core.setTwoDigits(parseInt(time / 1000) % 60) + ); +}; ////// 两位数显示 ////// utils.prototype.setTwoDigits = function (x) { - return (parseInt(x) < 10 && parseInt(x) >= 0) ? "0" + x : x; -} + return parseInt(x) < 10 && parseInt(x) >= 0 ? "0" + x : x; +}; utils.prototype.formatSize = function (size) { - if (size < 1024) return size + 'B'; - else if (size < 1024 * 1024) return (size / 1024).toFixed(2) + "KB"; - else return (size / 1024 / 1024).toFixed(2) + "MB"; -} + if (size < 1024) return size + "B"; + else if (size < 1024 * 1024) return (size / 1024).toFixed(2) + "KB"; + else return (size / 1024 / 1024).toFixed(2) + "MB"; +}; utils.prototype.formatBigNumber = function (x, digits) { - if (digits === true) digits = 5; // 兼容旧版onMap参数 - if (!digits || digits < 5) digits = 6; // 连同负号、小数点和后缀字母在内的总位数,至少需为5,默认为6 - x = Math.trunc(parseFloat(x)); // 尝试识别为小数,然后向0取整 - if (x == null || !Number.isFinite(x)) return '???'; // 无法识别的数或正负无穷大,显示'???' - var units = [ // 单位及其后缀字母,可自定义,如改成千进制下的K、M、G、T、P - { "val": 1e4, "suffix": "w" }, - { "val": 1e8, "suffix": "e" }, - { "val": 1e12, "suffix": "z" }, - { "val": 1e16, "suffix": "j" }, - { "val": 1e20, "suffix": "g" }, - ]; - if (Math.abs(x) > 1e20 * Math.pow(10, digits - 2)) - return x.toExponential(0); // 绝对值过大以致于失去精度的数,直接使用科学记数法,系数只保留整数 - var sign = x < 0 ? '-' : ''; - if (sign) --digits; // 符号位单独处理,负号要占一位 - x = Math.abs(x); + if (digits === true) digits = 5; // 兼容旧版onMap参数 + if (!digits || digits < 5) digits = 6; // 连同负号、小数点和后缀字母在内的总位数,至少需为5,默认为6 + x = Math.trunc(parseFloat(x)); // 尝试识别为小数,然后向0取整 + if (x == null || !Number.isFinite(x)) return "???"; // 无法识别的数或正负无穷大,显示'???' + var units = [ + // 单位及其后缀字母,可自定义,如改成千进制下的K、M、G、T、P + { val: 1e4, suffix: "w" }, + { val: 1e8, suffix: "e" }, + { val: 1e12, suffix: "z" }, + { val: 1e16, suffix: "j" }, + { val: 1e20, suffix: "g" }, + ]; + if (Math.abs(x) > 1e20 * Math.pow(10, digits - 2)) return x.toExponential(0); // 绝对值过大以致于失去精度的数,直接使用科学记数法,系数只保留整数 + var sign = x < 0 ? "-" : ""; + if (sign) --digits; // 符号位单独处理,负号要占一位 + x = Math.abs(x); - if (x < Math.pow(10, digits)) return sign + x; + if (x < Math.pow(10, digits)) return sign + x; - for (var i = 0; i < units.length; ++i) { - var each = units[i]; - var u = (x / each.val).toFixed(digits).substring(0, digits); - if (u.indexOf('.') < 0) continue; - u = u.substring(0, u[u.length - 2] == '.' ? u.length - 2 : u.length - 1); - return sign + u + each.suffix; - } - return sign + x.toExponential(0); -} + for (var i = 0; i < units.length; ++i) { + var each = units[i]; + var u = (x / each.val).toFixed(digits).substring(0, digits); + if (u.indexOf(".") < 0) continue; + u = u.substring(0, u[u.length - 2] == "." ? u.length - 2 : u.length - 1); + return sign + u + each.suffix; + } + return sign + x.toExponential(0); +}; ////// 变速移动 ////// utils.prototype.applyEasing = function (name) { - var list = { - "easeIn": function (t) { - return Math.pow(t, 3); - }, - "easeOut": function (t) { - return 1 - Math.pow(1 - t, 3); - }, - "easeInOut": function (t) { - // easeInOut试了一下感觉二次方效果明显点 - if (t < 0.5) return Math.pow(t, 2) * 2; - else return 1 - Math.pow(1 - t, 2) * 2; - }, - "linear": function (t) { - return t - } - } - if (name == 'random') { - var keys = Object.keys(list); - name = keys[Math.floor(Math.random() * keys.length)]; - } - return list[name] || list.linear; -} + var list = { + easeIn: function (t) { + return Math.pow(t, 3); + }, + easeOut: function (t) { + return 1 - Math.pow(1 - t, 3); + }, + easeInOut: function (t) { + // easeInOut试了一下感觉二次方效果明显点 + if (t < 0.5) return Math.pow(t, 2) * 2; + else return 1 - Math.pow(1 - t, 2) * 2; + }, + linear: function (t) { + return t; + }, + }; + if (name == "random") { + var keys = Object.keys(list); + name = keys[Math.floor(Math.random() * keys.length)]; + } + return list[name] || list.linear; +}; ////// 数组转RGB ////// utils.prototype.arrayToRGB = function (color) { - if (!(color instanceof Array)) return color; - var nowR = this.clamp(parseInt(color[0]), 0, 255), nowG = this.clamp(parseInt(color[1]), 0, 255), - nowB = this.clamp(parseInt(color[2]), 0, 255); - return "#" + ((1 << 24) + (nowR << 16) + (nowG << 8) + nowB).toString(16).slice(1); -} + if (!(color instanceof Array)) return color; + var nowR = this.clamp(parseInt(color[0]), 0, 255), + nowG = this.clamp(parseInt(color[1]), 0, 255), + nowB = this.clamp(parseInt(color[2]), 0, 255); + return ( + "#" + ((1 << 24) + (nowR << 16) + (nowG << 8) + nowB).toString(16).slice(1) + ); +}; utils.prototype.arrayToRGBA = function (color) { - if (!(color instanceof Array)) return color; - if (color[3] == null) color[3] = 1; - var nowR = this.clamp(parseInt(color[0]), 0, 255), nowG = this.clamp(parseInt(color[1]), 0, 255), - nowB = this.clamp(parseInt(color[2]), 0, 255), nowA = this.clamp(parseFloat(color[3]), 0, 1); - return "rgba(" + nowR + "," + nowG + "," + nowB + "," + nowA + ")"; -} + if (!(color instanceof Array)) return color; + if (color[3] == null) color[3] = 1; + var nowR = this.clamp(parseInt(color[0]), 0, 255), + nowG = this.clamp(parseInt(color[1]), 0, 255), + nowB = this.clamp(parseInt(color[2]), 0, 255), + nowA = this.clamp(parseFloat(color[3]), 0, 1); + return "rgba(" + nowR + "," + nowG + "," + nowB + "," + nowA + ")"; +}; ////// 加密路线 ////// utils.prototype.encodeRoute = function (route) { - var ans = "", lastMove = "", cnt = 0; + var ans = "", + lastMove = "", + cnt = 0; - route.forEach(function (t) { - if (t == 'up' || t == 'down' || t == 'left' || t == 'right') { - if (t != lastMove && cnt > 0) { - ans += lastMove.substring(0, 1).toUpperCase(); - if (cnt > 1) ans += cnt; - cnt = 0; - } - lastMove = t; - cnt++; - } - else { - if (cnt > 0) { - ans += lastMove.substring(0, 1).toUpperCase(); - if (cnt > 1) ans += cnt; - cnt = 0; - } - ans += core.utils._encodeRoute_encodeOne(t); - } - }); - if (cnt > 0) { + route.forEach(function (t) { + if (t == "up" || t == "down" || t == "left" || t == "right") { + if (t != lastMove && cnt > 0) { ans += lastMove.substring(0, 1).toUpperCase(); if (cnt > 1) ans += cnt; + cnt = 0; + } + lastMove = t; + cnt++; + } else { + if (cnt > 0) { + ans += lastMove.substring(0, 1).toUpperCase(); + if (cnt > 1) ans += cnt; + cnt = 0; + } + ans += core.utils._encodeRoute_encodeOne(t); } - return LZString.compressToBase64(ans); -} + }); + if (cnt > 0) { + ans += lastMove.substring(0, 1).toUpperCase(); + if (cnt > 1) ans += cnt; + } + return LZString.compressToBase64(ans); +}; utils.prototype._encodeRoute_id2number = function (id) { - var number = core.maps.getNumberById(id); - return number == 0 ? id : number; -} + var number = core.maps.getNumberById(id); + return number == 0 ? id : number; +}; utils.prototype._encodeRoute_encodeOne = function (t) { - if (t.indexOf('item:') == 0) - return "I" + this._encodeRoute_id2number(t.substring(5)) + ":"; - else if (t.indexOf('unEquip:') == 0) - return "u" + t.substring(8); - else if (t.indexOf('equip:') == 0) - return "e" + this._encodeRoute_id2number(t.substring(6)) + ":"; - else if (t.indexOf('saveEquip:') == 0) - return "s" + t.substring(10); - else if (t.indexOf('loadEquip:') == 0) - return "l" + t.substring(10); - else if (t.indexOf('fly:') == 0) - return "F" + t.substring(4) + ":"; - else if (t == 'choices:none') - return "c"; - else if (t.indexOf('choices:') == 0) - return "C" + t.substring(8); - else if (t.indexOf('shop:') == 0) - return "S" + t.substring(5) + ":"; - else if (t == 'turn') - return 'T'; - else if (t.indexOf('turn:') == 0) - return "t" + t.substring(5).substring(0, 1).toUpperCase() + ":"; - else if (t == 'getNext') - return 'G'; - else if (t == 'input:none') - return 'p'; - else if (t.indexOf('input:') == 0) - return "P" + t.substring(6); - else if (t.indexOf('input2:') == 0) - return "Q" + t.substring(7) + ":"; - else if (t == 'no') - return 'N'; - else if (t.indexOf('move:') == 0) - return "M" + t.substring(5); - else if (t.indexOf('key:') == 0) - return 'K' + t.substring(4); - else if (t.indexOf('click:') == 0) - return 'k' + t.substring(6); - else if (t.indexOf('random:') == 0) - return 'X' + t.substring(7); - return '(' + t + ')'; -} + if (t.indexOf("item:") == 0) + return "I" + this._encodeRoute_id2number(t.substring(5)) + ":"; + else if (t.indexOf("unEquip:") == 0) return "u" + t.substring(8); + else if (t.indexOf("equip:") == 0) + return "e" + this._encodeRoute_id2number(t.substring(6)) + ":"; + else if (t.indexOf("saveEquip:") == 0) return "s" + t.substring(10); + else if (t.indexOf("loadEquip:") == 0) return "l" + t.substring(10); + else if (t.indexOf("fly:") == 0) return "F" + t.substring(4) + ":"; + else if (t == "choices:none") return "c"; + else if (t.indexOf("choices:") == 0) return "C" + t.substring(8); + else if (t.indexOf("shop:") == 0) return "S" + t.substring(5) + ":"; + else if (t == "turn") return "T"; + else if (t.indexOf("turn:") == 0) + return "t" + t.substring(5).substring(0, 1).toUpperCase() + ":"; + else if (t == "getNext") return "G"; + else if (t == "input:none") return "p"; + else if (t.indexOf("input:") == 0) return "P" + t.substring(6); + else if (t.indexOf("input2:") == 0) return "Q" + t.substring(7) + ":"; + else if (t == "no") return "N"; + else if (t.indexOf("move:") == 0) return "M" + t.substring(5); + else if (t.indexOf("key:") == 0) return "K" + t.substring(4); + else if (t.indexOf("click:") == 0) return "k" + t.substring(6); + else if (t.indexOf("random:") == 0) return "X" + t.substring(7); + return "(" + t + ")"; +}; ////// 解密路线 ////// utils.prototype.decodeRoute = function (route) { - if (!route) return route; + if (!route) return route; - // 解压缩 - try { - var v = LZString.decompressFromBase64(route); - if (v != null && /^[-_a-zA-Z0-9+\/=:()]*$/.test(v)) { - if (v != "" || route.length < 8) - route = v; - } - } catch (e) { + // 解压缩 + try { + var v = LZString.decompressFromBase64(route); + if (v != null && /^[-_a-zA-Z0-9+\/=:()]*$/.test(v)) { + if (v != "" || route.length < 8) route = v; } + } catch (e) {} - var decodeObj = { route: route, index: 0, ans: [] }; - while (decodeObj.index < decodeObj.route.length) { - this._decodeRoute_decodeOne(decodeObj, decodeObj.route.charAt(decodeObj.index++)); - } - return decodeObj.ans; -} + var decodeObj = { route: route, index: 0, ans: [] }; + while (decodeObj.index < decodeObj.route.length) { + this._decodeRoute_decodeOne( + decodeObj, + decodeObj.route.charAt(decodeObj.index++) + ); + } + return decodeObj.ans; +}; utils.prototype._decodeRoute_getNumber = function (decodeObj, noparse) { - var num = ""; - var first = true; - while (true) { - var ch = decodeObj.route.charAt(decodeObj.index); - if (ch >= '0' && ch <= '9') num += ch; - else if (ch == '-' && first) num += ch; - else break; - first = false; - decodeObj.index++; - } - if (num.length == 0) num = "1"; - return noparse ? num : parseInt(num); -} + var num = ""; + var first = true; + while (true) { + var ch = decodeObj.route.charAt(decodeObj.index); + if (ch >= "0" && ch <= "9") num += ch; + else if (ch == "-" && first) num += ch; + else break; + first = false; + decodeObj.index++; + } + if (num.length == 0) num = "1"; + return noparse ? num : parseInt(num); +}; utils.prototype._decodeRoute_getString = function (decodeObj) { - var str = ""; - while (decodeObj.index < decodeObj.route.length && decodeObj.route.charAt(decodeObj.index) != ':') { - str += decodeObj.route.charAt(decodeObj.index++); - } - decodeObj.index++; - return str; -} + var str = ""; + while ( + decodeObj.index < decodeObj.route.length && + decodeObj.route.charAt(decodeObj.index) != ":" + ) { + str += decodeObj.route.charAt(decodeObj.index++); + } + decodeObj.index++; + return str; +}; utils.prototype._decodeRoute_number2id = function (number) { - if (/^\d+$/.test(number)) { - var info = core.maps.blocksInfo[number]; - if (info) return info.id; - } - return number; -} + if (/^\d+$/.test(number)) { + var info = core.maps.blocksInfo[number]; + if (info) return info.id; + } + return number; +}; utils.prototype._decodeRoute_decodeOne = function (decodeObj, c) { - // --- 特殊处理自定义项 - if (c == '(') { - var idx = decodeObj.route.indexOf(')', decodeObj.index); - if (idx >= 0) { - decodeObj.ans.push(decodeObj.route.substring(decodeObj.index, idx)); - decodeObj.index = idx + 1; - return; - } + // --- 特殊处理自定义项 + if (c == "(") { + var idx = decodeObj.route.indexOf(")", decodeObj.index); + if (idx >= 0) { + decodeObj.ans.push(decodeObj.route.substring(decodeObj.index, idx)); + decodeObj.index = idx + 1; + return; } - var nxt = (c == 'I' || c == 'e' || c == 'F' || c == 'S' || c == 'Q' || c == 't') ? - this._decodeRoute_getString(decodeObj) : this._decodeRoute_getNumber(decodeObj); + } + var nxt = + c == "I" || c == "e" || c == "F" || c == "S" || c == "Q" || c == "t" + ? this._decodeRoute_getString(decodeObj) + : this._decodeRoute_getNumber(decodeObj); - var mp = { "U": "up", "D": "down", "L": "left", "R": "right" }; + var mp = { U: "up", D: "down", L: "left", R: "right" }; - switch (c) { - case "U": - case "D": - case "L": - case "R": - for (var i = 0; i < nxt; i++) decodeObj.ans.push(mp[c]); - break; - case "I": - decodeObj.ans.push("item:" + this._decodeRoute_number2id(nxt)); - break; - case "u": - decodeObj.ans.push("unEquip:" + nxt); - break; - case "e": - decodeObj.ans.push("equip:" + this._decodeRoute_number2id(nxt)); - break; - case "s": - decodeObj.ans.push("saveEquip:" + nxt); - break; - case "l": - decodeObj.ans.push("loadEquip:" + nxt); - break; - case "F": - decodeObj.ans.push("fly:" + nxt); - break; - case 'c': - decodeObj.ans.push('choices:none'); - break; - case "C": - decodeObj.ans.push("choices:" + nxt); - break; - case "S": - decodeObj.ans.push("shop:" + nxt); - break; - case "T": - decodeObj.ans.push("turn"); - break; - case "t": - decodeObj.ans.push("turn:" + mp[nxt]); - break; - case "G": - decodeObj.ans.push("getNext"); - break; - case "p": - decodeObj.ans.push("input:none"); - break; - case "P": - decodeObj.ans.push("input:" + nxt); - break; - case "Q": - decodeObj.ans.push("input2:" + nxt); - break; - case "N": - decodeObj.ans.push("no"); - break; - case "M": - ++decodeObj.index; - decodeObj.ans.push("move:" + nxt + ":" + this._decodeRoute_getNumber(decodeObj)); - break; - case "K": - decodeObj.ans.push("key:" + nxt); - break; - case "k": - ++decodeObj.index; - var px = this._decodeRoute_getNumber(decodeObj); - ++decodeObj.index; - var py = this._decodeRoute_getNumber(decodeObj); - decodeObj.ans.push("click:" + nxt + ":" + px + ":" + py); - break; - case "X": - decodeObj.ans.push("random:" + nxt); - break; - } -} + switch (c) { + case "U": + case "D": + case "L": + case "R": + for (var i = 0; i < nxt; i++) decodeObj.ans.push(mp[c]); + break; + case "I": + decodeObj.ans.push("item:" + this._decodeRoute_number2id(nxt)); + break; + case "u": + decodeObj.ans.push("unEquip:" + nxt); + break; + case "e": + decodeObj.ans.push("equip:" + this._decodeRoute_number2id(nxt)); + break; + case "s": + decodeObj.ans.push("saveEquip:" + nxt); + break; + case "l": + decodeObj.ans.push("loadEquip:" + nxt); + break; + case "F": + decodeObj.ans.push("fly:" + nxt); + break; + case "c": + decodeObj.ans.push("choices:none"); + break; + case "C": + decodeObj.ans.push("choices:" + nxt); + break; + case "S": + decodeObj.ans.push("shop:" + nxt); + break; + case "T": + decodeObj.ans.push("turn"); + break; + case "t": + decodeObj.ans.push("turn:" + mp[nxt]); + break; + case "G": + decodeObj.ans.push("getNext"); + break; + case "p": + decodeObj.ans.push("input:none"); + break; + case "P": + decodeObj.ans.push("input:" + nxt); + break; + case "Q": + decodeObj.ans.push("input2:" + nxt); + break; + case "N": + decodeObj.ans.push("no"); + break; + case "M": + ++decodeObj.index; + decodeObj.ans.push( + "move:" + nxt + ":" + this._decodeRoute_getNumber(decodeObj) + ); + break; + case "K": + decodeObj.ans.push("key:" + nxt); + break; + case "k": + ++decodeObj.index; + var px = this._decodeRoute_getNumber(decodeObj); + ++decodeObj.index; + var py = this._decodeRoute_getNumber(decodeObj); + decodeObj.ans.push("click:" + nxt + ":" + px + ":" + py); + break; + case "X": + decodeObj.ans.push("random:" + nxt); + break; + } +}; ////// 判断某对象是否不为null也不为NaN ////// utils.prototype.isset = function (val) { - return val != null && !(typeof val == 'number' && isNaN(val)); -} + return val != null && !(typeof val == "number" && isNaN(val)); +}; ////// 获得子数组 ////// utils.prototype.subarray = function (a, b) { - if (!(a instanceof Array) || !(b instanceof Array) || a.length < b.length) - return null; - for (var i = 0; i < b.length; ++i) { - if (a[i] != b[i]) return null; - } - return a.slice(b.length); -} + if (!(a instanceof Array) || !(b instanceof Array) || a.length < b.length) + return null; + for (var i = 0; i < b.length; ++i) { + if (a[i] != b[i]) return null; + } + return a.slice(b.length); +}; utils.prototype.inArray = function (array, element) { - return (array instanceof Array) && array.indexOf(element) >= 0; -} + return array instanceof Array && array.indexOf(element) >= 0; +}; utils.prototype.clamp = function (x, a, b) { - var min = Math.min(a, b), max = Math.max(a, b); - return Math.min(Math.max(x || 0, min), max); -} + var min = Math.min(a, b), + max = Math.max(a, b); + return Math.min(Math.max(x || 0, min), max); +}; utils.prototype.getCookie = function (name) { - var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); - return match ? match[2] : null; -} + var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)")); + return match ? match[2] : null; +}; ////// 设置statusBar的innerHTML,会自动斜体和放缩,也可以增加自定义css ////// utils.prototype.setStatusBarInnerHTML = function (name, value, css) { - if (!core.statusBar[name]) return; - if (typeof value == 'number') value = this.formatBigNumber(value); - var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value); - var style = 'font-style: ' + (italic ? 'italic' : 'normal') + '; '; - style += 'text-shadow: #000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0; '; - // 判定是否需要缩放 - var length = this.strlen(value) || 1; - style += 'font-size: ' + Math.min(1, 7 / length) + 'em; '; - if (css) style += css; - var _style = core.statusBar[name].getAttribute('_style'); - var _value = core.statusBar[name].getAttribute('_value'); - if (_style == style) { - if (value == _value) return; - core.statusBar[name].children[0].innerText = value; - } else { - core.statusBar[name].innerHTML = ""; - core.statusBar[name].children[0].innerText = value; - core.statusBar[name].setAttribute('_style', style); - } - core.statusBar[name].setAttribute('_value', value);; -} + if (!core.statusBar[name]) return; + if (typeof value == "number") value = this.formatBigNumber(value); + var italic = /^[-a-zA-Z0-9`~!@#$%^&*()_=+\[{\]}\\|;:'",<.>\/?]*$/.test(value); + var style = "font-style: " + (italic ? "italic" : "normal") + "; "; + style += + "text-shadow: #000 1px 0 0, #000 0 1px 0, #000 -1px 0 0, #000 0 -1px 0; "; + // 判定是否需要缩放 + var length = this.strlen(value) || 1; + style += "font-size: " + Math.min(1, 7 / length) + "em; "; + if (css) style += css; + var _style = core.statusBar[name].getAttribute("_style"); + var _value = core.statusBar[name].getAttribute("_value"); + if (_style == style) { + if (value == _value) return; + core.statusBar[name].children[0].innerText = value; + } else { + core.statusBar[name].innerHTML = + ""; + core.statusBar[name].children[0].innerText = value; + core.statusBar[name].setAttribute("_style", style); + } + core.statusBar[name].setAttribute("_value", value); +}; utils.prototype.strlen = function (str) { - var count = 0; - for (var i = 0, len = str.length; i < len; i++) { - count += str.charCodeAt(i) < 256 ? 1 : 2; - } - return count; + var count = 0; + for (var i = 0, len = str.length; i < len; i++) { + count += str.charCodeAt(i) < 256 ? 1 : 2; + } + return count; }; utils.prototype.turnDirection = function (turn, direction) { - direction = direction || core.getHeroLoc('direction'); - var directionList = ["left", "leftup", "up", "rightup", "right", "rightdown", "down", "leftdown"]; - if (directionList.indexOf(turn) >= 0) return turn; - if (turn == ':hero') return core.getHeroLoc('direction'); - if (turn == ':backhero') return this.turnDirection(':back', core.getHeroLoc('direction')); - if (typeof turn === 'number' && turn % 45 == 0) turn /= 45; - else { - switch (turn) { - case ':left': turn = 6; break; // turn left - case ':right': turn = 2; break; // turn right - case ':back': turn = 4; break; // turn back - default: turn = 0; break; - } + direction = direction || core.getHeroLoc("direction"); + var directionList = [ + "left", + "leftup", + "up", + "rightup", + "right", + "rightdown", + "down", + "leftdown", + ]; + if (directionList.indexOf(turn) >= 0) return turn; + if (turn == ":hero") return core.getHeroLoc("direction"); + if (turn == ":backhero") + return this.turnDirection(":back", core.getHeroLoc("direction")); + if (typeof turn === "number" && turn % 45 == 0) turn /= 45; + else { + switch (turn) { + case ":left": + turn = 6; + break; // turn left + case ":right": + turn = 2; + break; // turn right + case ":back": + turn = 4; + break; // turn back + default: + turn = 0; + break; } - var index = directionList.indexOf(direction); - if (index < 0) return direction; - return directionList[(index + (turn || 0)) % directionList.length]; -} + } + var index = directionList.indexOf(direction); + if (index < 0) return direction; + return directionList[(index + (turn || 0)) % directionList.length]; +}; utils.prototype.matchWildcard = function (pattern, string) { - try { - return new RegExp('^' + pattern.split(/\*+/).map(function (s) { - return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'); - }).join('.*') + '$').test(string); - } catch (e) { - return false; - } -} + try { + return new RegExp( + "^" + + pattern + .split(/\*+/) + .map(function (s) { + return s.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"); + }) + .join(".*") + + "$" + ).test(string); + } catch (e) { + return false; + } +}; utils.prototype.matchRegex = function (pattern, string) { - try { - if (pattern.startsWith("^")) pattern = pattern.substring(1); - if (pattern.endsWith("$")) pattern = pattern.substring(0, pattern.length - 1); - return new RegExp("^" + pattern + "$").test(string); - } catch (e) { - return false; - } -} + try { + if (pattern.startsWith("^")) pattern = pattern.substring(1); + if (pattern.endsWith("$")) + pattern = pattern.substring(0, pattern.length - 1); + return new RegExp("^" + pattern + "$").test(string); + } catch (e) { + return false; + } +}; ////// Base64加密 ////// utils.prototype.encodeBase64 = function (str) { - return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { - return String.fromCharCode(parseInt(p1, 16)) - })) -} + return btoa( + encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { + return String.fromCharCode(parseInt(p1, 16)); + }) + ); +}; ////// Base64解密 ////// utils.prototype.decodeBase64 = function (str) { - return decodeURIComponent(atob(str).split('').map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }).join('')); -} + return decodeURIComponent( + atob(str) + .split("") + .map(function (c) { + return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join("") + ); +}; utils.prototype.rand = function (num) { - var rand = core.getFlag('__rand__'); - rand = this.__next_rand(rand); - core.setFlag('__rand__', rand); - var ans = rand / 2147483647; - if (num && num > 0) - return Math.floor(ans * num); - return ans; -} + var rand = core.getFlag("__rand__"); + rand = this.__next_rand(rand); + core.setFlag("__rand__", rand); + var ans = rand / 2147483647; + if (num && num > 0) return Math.floor(ans * num); + return ans; +}; ////// 生成随机数(录像方法) ////// utils.prototype.rand2 = function (num) { - num = num || 2147483648; - num = Math.abs(num); + num = num || 2147483648; + num = Math.abs(num); - var value; - if (core.isReplaying()) { - var action = core.status.replay.toReplay.shift(); - if (action.indexOf("random:") == 0) { - value = parseInt(action.substring(7)); - if (isNaN(value) || value >= num || value < 0) { - console.warn('错误!当前random:项超过范围。将重新随机生成!'); - value = Math.floor(Math.random() * num); - } - } - else { - console.warn('错误!当前需要一个random:项。将重新随机生成!'); - value = Math.floor(Math.random() * num); - } - } - else { + var value; + if (core.isReplaying()) { + var action = core.status.replay.toReplay.shift(); + if (action.indexOf("random:") == 0) { + value = parseInt(action.substring(7)); + if (isNaN(value) || value >= num || value < 0) { + console.warn("错误!当前random:项超过范围。将重新随机生成!"); value = Math.floor(Math.random() * num); + } + } else { + console.warn("错误!当前需要一个random:项。将重新随机生成!"); + value = Math.floor(Math.random() * num); } - core.status.route.push("random:" + value); - return value; -} + } else { + value = Math.floor(Math.random() * num); + } + core.status.route.push("random:" + value); + return value; +}; utils.prototype.__init_seed = function () { - var rand = new Date().getTime() % 34834795 + 3534; - rand = this.__next_rand(rand); - rand = this.__next_rand(rand); - rand = this.__next_rand(rand); - core.setFlag('__seed__', rand); - core.setFlag('__rand__', rand); -} + var rand = (new Date().getTime() % 34834795) + 3534; + rand = this.__next_rand(rand); + rand = this.__next_rand(rand); + rand = this.__next_rand(rand); + core.setFlag("__seed__", rand); + core.setFlag("__rand__", rand); +}; utils.prototype.__next_rand = function (_rand) { - _rand = (_rand % 127773) * 16807 - ~~(_rand / 127773) * 2836; - _rand += _rand < 0 ? 2147483647 : 0; - return _rand; -} + _rand = (_rand % 127773) * 16807 - ~~(_rand / 127773) * 2836; + _rand += _rand < 0 ? 2147483647 : 0; + return _rand; +}; ////// 读取一个本地文件内容 ////// utils.prototype.readFile = function (success, error, accept, readType) { + core.platform.successCallback = success; + core.platform.errorCallback = error; - core.platform.successCallback = success; - core.platform.errorCallback = error; + if (window.jsinterface) { + window.jsinterface.readFile(); + return; + } - if (window.jsinterface) { - window.jsinterface.readFile(); + // step 0: 不为http/https,直接不支持 + if (!core.platform.isOnline) { + alert("离线状态下不支持文件读取!"); + if (error) error(); + return; + } + + // Step 1: 如果不支持FileReader,直接不支持 + if (core.platform.fileReader == null) { + alert("当前浏览器不支持FileReader!"); + if (error) error(); + return; + } + + if (core.platform.fileInput == null) { + core.platform.fileInput = document.createElement("input"); + core.platform.fileInput.style.opacity = 0; + core.platform.fileInput.type = "file"; + core.platform.fileInput.onchange = function () { + var files = core.platform.fileInput.files; + if (files.length == 0) { + if (core.platform.errorCallback) core.platform.errorCallback(); return; - } + } + if (!readType) + core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); + else + core.platform.fileReader.readAsDataURL( + core.platform.fileInput.files[0] + ); + core.platform.fileInput.value = ""; + }; + } + core.platform.fileInput.value = ""; + if (accept) core.platform.fileInput.accept = accept; - // step 0: 不为http/https,直接不支持 - if (!core.platform.isOnline) { - alert("离线状态下不支持文件读取!"); - if (error) error(); - return; - } - - // Step 1: 如果不支持FileReader,直接不支持 - if (core.platform.fileReader == null) { - alert("当前浏览器不支持FileReader!"); - if (error) error(); - return; - } - - if (core.platform.fileInput == null) { - core.platform.fileInput = document.createElement("input"); - core.platform.fileInput.style.opacity = 0; - core.platform.fileInput.type = 'file'; - core.platform.fileInput.onchange = function () { - var files = core.platform.fileInput.files; - if (files.length == 0) { - if (core.platform.errorCallback) - core.platform.errorCallback(); - return; - } - if (!readType) core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); - else core.platform.fileReader.readAsDataURL(core.platform.fileInput.files[0]); - core.platform.fileInput.value = ''; - } - } - core.platform.fileInput.value = ''; - if (accept) core.platform.fileInput.accept = accept; - - core.platform.fileInput.click(); -} + core.platform.fileInput.click(); +}; ////// 读取文件完毕 ////// utils.prototype.readFileContent = function (content) { - var obj = null; - if (content.slice(0, 4) === 'data') { - if (core.platform.successCallback) - core.platform.successCallback(content); - return; - } - // 检查base64 + var obj = null; + if (content.slice(0, 4) === "data") { + if (core.platform.successCallback) core.platform.successCallback(content); + return; + } + // 检查base64 + try { + obj = JSON.parse(LZString.decompressFromBase64(content)); + } catch (e) {} + if (!obj) { try { - obj = JSON.parse(LZString.decompressFromBase64(content)); - } catch (e) { } - if (!obj) { - try { - obj = JSON.parse(content); - } catch (e) { - console.error(e) - } + obj = JSON.parse(content); + } catch (e) { + console.error(e); } + } - if (obj) { - if (core.platform.successCallback) - core.platform.successCallback(obj); - return; - } + if (obj) { + if (core.platform.successCallback) core.platform.successCallback(obj); + return; + } - if (core.platform.errorCallback) - core.platform.errorCallback(); -} + if (core.platform.errorCallback) core.platform.errorCallback(); +}; ////// 下载文件到本地 ////// utils.prototype.download = function (filename, content) { + if (window.jsinterface) { + window.jsinterface.download(filename, content); + return; + } - if (window.jsinterface) { - window.jsinterface.download(filename, content); - return; - } + // Step 0: 不为http/https,直接不支持 + if (!core.platform.isOnline) { + alert("离线状态下不支持下载操作!"); + return; + } - // Step 0: 不为http/https,直接不支持 - if (!core.platform.isOnline) { - alert("离线状态下不支持下载操作!"); - return; + // Step 1: 如果是iOS平台,直接不支持 + if (core.platform.isIOS) { + if (core.copy(content)) { + alert( + "iOS平台下不支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。" + ); + } else { + alert("iOS平台下不支持下载操作!"); } + return; + } - // Step 1: 如果是iOS平台,直接不支持 - if (core.platform.isIOS) { - if (core.copy(content)) { - alert("iOS平台下不支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。"); - } - else { - alert("iOS平台下不支持下载操作!"); - } - return; + // Step 2: 如果不是PC平台(Android),则只支持chrome + if (!core.platform.isPC) { + if ( + !core.platform.isChrome || + core.platform.isQQ || + core.platform.isWeChat + ) { + // 检测chrome + if (core.copy(content)) { + alert( + "移动端只有Chrome浏览器支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。" + ); + } else { + alert("该平台或浏览器暂不支持下载操作!"); + } + return; } + } - // Step 2: 如果不是PC平台(Android),则只支持chrome - if (!core.platform.isPC) { - if (!core.platform.isChrome || core.platform.isQQ || core.platform.isWeChat) { // 检测chrome - if (core.copy(content)) { - alert("移动端只有Chrome浏览器支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。"); - } - else { - alert("该平台或浏览器暂不支持下载操作!"); - } - return; - } - } + // Step 3: 如果是Safari浏览器,则提示并打开新窗口 + if (core.platform.isSafari) { + alert( + "你当前使用的是Safari浏览器,不支持直接下载文件。\n即将打开一个新窗口为应下载内容,请自行全选复制然后创建空白文件并粘贴。" + ); + var blob = new Blob([content], { type: "text/plain;charset=utf-8" }); + var href = window.URL.createObjectURL(blob); + var opened = window.open(href, "_blank"); + window.URL.revokeObjectURL(href); + return; + } - // Step 3: 如果是Safari浏览器,则提示并打开新窗口 - if (core.platform.isSafari) { - alert("你当前使用的是Safari浏览器,不支持直接下载文件。\n即将打开一个新窗口为应下载内容,请自行全选复制然后创建空白文件并粘贴。"); - var blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); - var href = window.URL.createObjectURL(blob); - var opened = window.open(href, "_blank"); - window.URL.revokeObjectURL(href); - return; - } - - // Step 4: 下载 - var blob = new Blob([content], { type: 'text/plain;charset=utf-8' }); - if (window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveBlob(blob, filename); - } - else { - var href = window.URL.createObjectURL(blob); - var elem = window.document.createElement('a'); - elem.href = href; - elem.download = filename; - document.body.appendChild(elem); - elem.click(); - document.body.removeChild(elem); - window.URL.revokeObjectURL(href); - } -} + // Step 4: 下载 + var blob = new Blob([content], { type: "text/plain;charset=utf-8" }); + if (window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveBlob(blob, filename); + } else { + var href = window.URL.createObjectURL(blob); + var elem = window.document.createElement("a"); + elem.href = href; + elem.download = filename; + document.body.appendChild(elem); + elem.click(); + document.body.removeChild(elem); + window.URL.revokeObjectURL(href); + } +}; ////// 复制一段内容到剪切板 ////// utils.prototype.copy = function (data) { + if (window.jsinterface) { + window.jsinterface.copy(data); + return true; + } - if (window.jsinterface) { - window.jsinterface.copy(data); - return true; - } + if (!core.platform.supportCopy) return false; - if (!core.platform.supportCopy) return false; + var textArea = document.createElement("textarea"); + textArea.style.position = "fixed"; + textArea.style.top = 0; + textArea.style.left = 0; + textArea.style.width = "2em"; + textArea.style.height = "2em"; + textArea.style.padding = 0; + textArea.style.border = "none"; + textArea.style.outline = "none"; + textArea.style.boxShadow = "none"; + textArea.style.background = "transparent"; + textArea.value = data; + document.body.appendChild(textArea); + textArea.focus(); + textArea.setSelectionRange(0, textArea.value.length); + var successful = false; + try { + successful = document.execCommand("copy"); + } catch (err) { + successful = false; + } - var textArea = document.createElement("textarea"); - textArea.style.position = 'fixed'; - textArea.style.top = 0; - textArea.style.left = 0; - textArea.style.width = '2em'; - textArea.style.height = '2em'; - textArea.style.padding = 0; - textArea.style.border = 'none'; - textArea.style.outline = 'none'; - textArea.style.boxShadow = 'none'; - textArea.style.background = 'transparent'; - textArea.value = data; - document.body.appendChild(textArea); - textArea.focus(); - textArea.setSelectionRange(0, textArea.value.length); - var successful = false; - try { - successful = document.execCommand('copy'); - } catch (err) { - successful = false; - } - - document.body.removeChild(textArea); - return successful; -} + document.body.removeChild(textArea); + return successful; +}; ////// 显示一段confirm ////// utils.prototype.myconfirm = function (hint, yesCallback, noCallback) { - main.dom.inputDiv.style.display = 'block'; - main.dom.inputMessage.innerHTML = hint.replace(/\n/g, '
'); - main.dom.inputBox.style.display = 'none'; - main.dom.inputYes.blur(); - main.dom.inputNo.blur(); - core.status.holdingKeys = []; + main.dom.inputDiv.style.display = "block"; + main.dom.inputMessage.innerHTML = hint.replace(/\n/g, "
"); + main.dom.inputBox.style.display = "none"; + main.dom.inputYes.blur(); + main.dom.inputNo.blur(); + core.status.holdingKeys = []; - core.platform.successCallback = yesCallback; - core.platform.errorCallback = noCallback; -} + core.platform.successCallback = yesCallback; + core.platform.errorCallback = noCallback; +}; ////// 让用户输入一段文字 ////// utils.prototype.myprompt = function (hint, value, callback) { - main.dom.inputDiv.style.display = 'block'; - main.dom.inputMessage.innerHTML = hint.replace(/\n/g, '
'); - main.dom.inputBox.style.display = 'block'; - main.dom.inputBox.value = value == null ? "" : value; - main.dom.inputYes.blur(); - main.dom.inputNo.blur(); - setTimeout(function () { - main.dom.inputBox.focus(); - }); - core.status.holdingKeys = []; + main.dom.inputDiv.style.display = "block"; + main.dom.inputMessage.innerHTML = hint.replace(/\n/g, "
"); + main.dom.inputBox.style.display = "block"; + main.dom.inputBox.value = value == null ? "" : value; + main.dom.inputYes.blur(); + main.dom.inputNo.blur(); + setTimeout(function () { + main.dom.inputBox.focus(); + }); + core.status.holdingKeys = []; - core.platform.successCallback = core.platform.errorCallback = callback; -} + core.platform.successCallback = core.platform.errorCallback = callback; +}; ////// 动画显示某对象 ////// utils.prototype.showWithAnimate = function (obj, speed, callback) { - obj.style.display = 'block'; - if (!speed || main.mode != 'play') { - obj.style.opacity = 1; - if (callback) callback(); - return; + obj.style.display = "block"; + if (!speed || main.mode != "play") { + obj.style.opacity = 1; + if (callback) callback(); + return; + } + obj.style.opacity = 0; + var opacityVal = 0; + var showAnimate = window.setInterval(function () { + opacityVal += 0.03; + obj.style.opacity = opacityVal; + if (opacityVal > 1) { + clearInterval(showAnimate); + if (callback) callback(); } - obj.style.opacity = 0; - var opacityVal = 0; - var showAnimate = window.setInterval(function () { - opacityVal += 0.03; - obj.style.opacity = opacityVal; - if (opacityVal > 1) { - clearInterval(showAnimate); - if (callback) callback(); - } - }, speed); -} + }, speed); +}; ////// 动画使某对象消失 ////// utils.prototype.hideWithAnimate = function (obj, speed, callback) { - if (!speed || main.mode != 'play') { - obj.style.display = 'none'; - if (callback) callback(); - return; + if (!speed || main.mode != "play") { + obj.style.display = "none"; + if (callback) callback(); + return; + } + obj.style.opacity = 1; + var opacityVal = 1; + var hideAnimate = window.setInterval(function () { + opacityVal -= 0.03; + obj.style.opacity = opacityVal; + if (opacityVal < 0) { + obj.style.display = "none"; + clearInterval(hideAnimate); + if (callback) callback(); } - obj.style.opacity = 1; - var opacityVal = 1; - var hideAnimate = window.setInterval(function () { - opacityVal -= 0.03; - obj.style.opacity = opacityVal; - if (opacityVal < 0) { - obj.style.display = 'none'; - clearInterval(hideAnimate); - if (callback) callback(); - } - }, speed); -} + }, speed); +}; ////// 生成浏览器唯一的 guid ////// utils.prototype.getGuid = function () { - var guid = localStorage.getItem('guid'); - if (guid != null) return guid; - guid = 'xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { - var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); - return v.toString(16); - }); - localStorage.setItem('guid', guid); - return guid; -} + var guid = localStorage.getItem("guid"); + if (guid != null) return guid; + guid = "xxxxxxxx_xxxx_4xxx_yxxx_xxxxxxxxxxxx".replace(/[xy]/g, function (c) { + var r = (Math.random() * 16) | 0, + v = c == "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); + localStorage.setItem("guid", guid); + return guid; +}; utils.prototype.hashCode = function (obj) { - if (typeof obj == 'string') { - var hash = 0, i, chr; - if (obj.length === 0) return hash; - for (i = 0; i < obj.length; i++) { - chr = obj.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash |= 0; - } - return hash; + if (typeof obj == "string") { + var hash = 0, + i, + chr; + if (obj.length === 0) return hash; + for (i = 0; i < obj.length; i++) { + chr = obj.charCodeAt(i); + hash = (hash << 5) - hash + chr; + hash |= 0; } - return this.hashCode(JSON.stringify(obj).split("").sort().join("")); -} + return hash; + } + return this.hashCode(JSON.stringify(obj).split("").sort().join("")); +}; utils.prototype.same = function (a, b) { - if (a == null && b == null) return true; - if (a == null || b == null) return false; - if (a === b) return true; - if (a instanceof Array && b instanceof Array) { - if (a.length != b.length) return false; - for (var i = 0; i < a.length; i++) { - if (!this.same(a[i], b[i])) return false; + if (a == null && b == null) return true; + if (a == null || b == null) return false; + if (a === b) return true; + if (a instanceof Array && b instanceof Array) { + if (a.length != b.length) return false; + for (var i = 0; i < a.length; i++) { + if (!this.same(a[i], b[i])) return false; + } + return true; + } + if (a instanceof Object && b instanceof Object) { + var obj = {}; + for (var i in a) obj[i] = true; + for (var i in b) obj[i] = true; + for (var i in obj) { + if (!this.same(a[i], b[i])) return false; + } + return true; + } + return false; +}; + +utils.prototype.unzip = function ( + blobOrUrl, + success, + error, + convertToText, + onprogress +) { + var _error = function (msg) { + console.error(msg); + if (error) error(msg); + }; + + if (!window.zip) { + return _error("zip.js not exists!"); + } + + if (typeof blobOrUrl == "string") { + return core.http( + "GET", + blobOrUrl, + null, + function (data) { + core.unzip(data, success, error, convertToText); + }, + _error, + null, + "blob", + onprogress + ); + } + + if (!(blobOrUrl instanceof Blob)) { + return _error("Should use Blob or URL as input"); + } + + zip.createReader( + new zip.BlobReader(blobOrUrl), + function (reader) { + reader.getEntries(function (entries) { + core.utils._unzip_readEntries( + entries, + function (data) { + reader.close(function () { + if (success) success(data); + }); + }, + convertToText + ); + }); + }, + _error + ); +}; + +utils.prototype._unzip_readEntries = function ( + entries, + success, + convertToText +) { + var results = {}; + if (entries == null || entries.length == 0) { + return success(results); + } + var length = entries.length; + entries.forEach(function (entry) { + entry.getData( + convertToText ? new zip.TextWriter("utf8") : new zip.BlobWriter(), + function (data) { + results[entry.filename] = data; + length--; + if (length == 0) { + success(results); } - return true; - } - if (a instanceof Object && b instanceof Object) { - var obj = {}; - for (var i in a) obj[i] = true; - for (var i in b) obj[i] = true; - for (var i in obj) { - if (!this.same(a[i], b[i])) return false; - } - return true; - } - return false; -} + } + ); + }); +}; -utils.prototype.unzip = function (blobOrUrl, success, error, convertToText, onprogress) { - var _error = function (msg) { - console.error(msg); - if (error) error(msg); +utils.prototype.http = function ( + type, + url, + formData, + success, + error, + mimeType, + responseType, + onprogress +) { + var xhr = new XMLHttpRequest(); + xhr.open(type, url, true); + if (mimeType) xhr.overrideMimeType(mimeType); + if (responseType) xhr.responseType = responseType; + xhr.onload = function (e) { + if (xhr.status == 200) { + if (success) success(xhr.response); + } else { + if (error) error("HTTP " + xhr.status); } - - if (!window.zip) { - return _error("zip.js not exists!"); + }; + xhr.onprogress = function (e) { + if (e.lengthComputable) { + if (onprogress) onprogress(e.loaded, e.total); } - - if (typeof blobOrUrl == 'string') { - return core.http('GET', blobOrUrl, null, function (data) { - core.unzip(data, success, error, convertToText); - }, _error, null, 'blob', onprogress); - } - - if (!(blobOrUrl instanceof Blob)) { - return _error("Should use Blob or URL as input"); - } - - zip.createReader(new zip.BlobReader(blobOrUrl), function (reader) { - reader.getEntries(function (entries) { - core.utils._unzip_readEntries(entries, function (data) { - reader.close(function () { - if (success) success(data); - }); - }, convertToText); - }); - }, _error); -} - -utils.prototype._unzip_readEntries = function (entries, success, convertToText) { - var results = {}; - if (entries == null || entries.length == 0) { - return success(results); - } - var length = entries.length; - entries.forEach(function (entry) { - entry.getData(convertToText ? new zip.TextWriter('utf8') : new zip.BlobWriter(), function (data) { - results[entry.filename] = data; - length--; - if (length == 0) { - success(results); - } - }); - }); -} - -utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType, onprogress) { - var xhr = new XMLHttpRequest(); - xhr.open(type, url, true); - if (mimeType) xhr.overrideMimeType(mimeType); - if (responseType) xhr.responseType = responseType; - xhr.onload = function (e) { - if (xhr.status == 200) { - if (success) success(xhr.response); - } - else { - if (error) error("HTTP " + xhr.status); - } - }; - xhr.onprogress = function (e) { - if (e.lengthComputable) { - if (onprogress) onprogress(e.loaded, e.total); - } - } - xhr.onabort = function () { - if (error) error("Abort"); - } - xhr.ontimeout = function () { - if (error) error("Timeout"); - } - xhr.onerror = function () { - if (error) error("Error on Connection"); - } - if (formData) - xhr.send(formData); - else xhr.send(); -} + }; + xhr.onabort = function () { + if (error) error("Abort"); + }; + xhr.ontimeout = function () { + if (error) error("Timeout"); + }; + xhr.onerror = function () { + if (error) error("Error on Connection"); + }; + if (formData) xhr.send(formData); + else xhr.send(); +}; // LZW-compress // https://gist.github.com/revolunet/843889 -function lzw_encode (s) { - var dict = {}; - var data = (s + "").split(""); - var out = []; - var currChar; - var phrase = data[0]; - var code = 256; - for (var i = 1; i < data.length; i++) { - currChar = data[i]; - if (dict[phrase + currChar] != null) { - phrase += currChar; - } - else { - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - dict[phrase + currChar] = code; - code++; - phrase = currChar; - } +function lzw_encode(s) { + var dict = {}; + var data = (s + "").split(""); + var out = []; + var currChar; + var phrase = data[0]; + var code = 256; + for (var i = 1; i < data.length; i++) { + currChar = data[i]; + if (dict[phrase + currChar] != null) { + phrase += currChar; + } else { + out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); + dict[phrase + currChar] = code; + code++; + phrase = currChar; } - out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); - for (var i = 0; i < out.length; i++) { - out[i] = String.fromCharCode(out[i]); - } - return out.join(""); + } + out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0)); + for (var i = 0; i < out.length; i++) { + out[i] = String.fromCharCode(out[i]); + } + return out.join(""); } // Decompress an LZW-encoded string -function lzw_decode (s) { - var dict = {}; - var data = (s + "").split(""); - var currChar = data[0]; - var oldPhrase = currChar; - var out = [currChar]; - var code = 256; - var phrase; - for (var i = 1; i < data.length; i++) { - var currCode = data[i].charCodeAt(0); - if (currCode < 256) { - phrase = data[i]; - } - else { - phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar); - } - out.push(phrase); - currChar = phrase.charAt(0); - dict[code] = oldPhrase + currChar; - code++; - oldPhrase = phrase; +function lzw_decode(s) { + var dict = {}; + var data = (s + "").split(""); + var currChar = data[0]; + var oldPhrase = currChar; + var out = [currChar]; + var code = 256; + var phrase; + for (var i = 1; i < data.length; i++) { + var currCode = data[i].charCodeAt(0); + if (currCode < 256) { + phrase = data[i]; + } else { + phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar; } - return out.join(""); + out.push(phrase); + currChar = phrase.charAt(0); + dict[code] = oldPhrase + currChar; + code++; + oldPhrase = phrase; + } + return out.join(""); } diff --git a/logo.png b/logo.png index 831e3a6..1755717 100644 Binary files a/logo.png and b/logo.png differ diff --git a/main.js b/main.js index a9242ca..0295c32 100644 --- a/main.js +++ b/main.js @@ -276,7 +276,7 @@ main.prototype.init = function (mode, callback) { coreData[t] = main[t]; }); main.core.init(coreData, callback); - main.core.resize(); + core.resize(); // 自动放缩最大化 if (!main.replayChecking) { if (core.getLocalStorage("autoScale") == null) { @@ -492,7 +492,6 @@ main.prototype.selectButton = function (index) { main.prototype.importFonts = function (fonts) { if (!(fonts instanceof Array) || fonts.length == 0) return; var style = document.createElement("style"); - style.type = "text/css"; var html = ""; fonts.forEach(function (font) { html += @@ -910,7 +909,7 @@ main.prototype.listen = function () { ////// 点击“开始游戏”时 ////// main.dom.playGame.onclick = function () { main.dom.startButtons.style.display = "none"; - main.core.control.checkBgm(); + main.core.checkBgm(); if (main.levelChoose.length == 0) { core.events.startGame(""); @@ -923,13 +922,13 @@ main.prototype.listen = function () { ////// 点击“载入游戏”时 ////// main.dom.loadGame.onclick = function () { - main.core.control.checkBgm(); + main.core.checkBgm(); main.core.load(); }; ////// 点击“录像回放”时 ////// main.dom.replayGame.onclick = function () { - main.core.control.checkBgm(); + main.core.checkBgm(); main.core.chooseReplayFile(); }; diff --git a/project/animates/hand.animate b/project/animates/hand.animate index 09c9514..2c4a168 100644 --- a/project/animates/hand.animate +++ b/project/animates/hand.animate @@ -1 +1 @@ -{"ratio":2,"se":"attack.mp3","bitmaps":["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA6+SURBVHhe7ZwPbFVVnsfJuENiQmKyCckkZs2YzO5m3HV1B0YdxDFjZEVhdHCKICOriILMrDLAbAZhBhjFURERQVhmkD+CdWyhtIXyp32F0pa29P+/R1va0pb+fe+1r+//ffffOd/93dvDi7WltgXpe2/uJzm5v3vueTSc37m/P+eecyZZWFhYWFhYWFhYWFhYWFjEEshcMU2IFjcTJM+/TYgjwrJe2yVEi5sJyqbdIcQRYVkrFCFaTASwLYcQxww/s/Qfhfj3DS/85weEOAhe+dCdQrwuyH513AqAbclMIVoMB6+b+agQrwtyloJnL50lbkcNP734J0K0MGBl/7ZTiGMC+UvA8pZkidtRw868IAnR4hrc/p8/EGIE3jbrbiEOCy6+BBS9NCYzxM8ufJpnPb9C3FpcA/YflQkxAmt78oAQhwWVS4CKl8ekAJx7btx+I64B5t+GxofXilsT3vH0HCEOC+qWAZeWg1e/eq+oGhEULFiG3PmWAq4Ha/7ZENsM5+JhoxXe+PpUXFkFo7CmNzJE9YigZCFY/nOjavt3CW994ies85lOcWvCXK+5hTiJd78zlXe/b0ZH6Nx4PxWgcwPQvnHIqGZtaz4Uogm7tCQRlYvBSxeN6m2JadTEaeOOseFYBO5aEglBWf/vI1EO7939GHPsLh2Qtz4N1zbA9RHg+GioAro27xYi+ZeNk9H0OlD/2rjMD09L+Fchxg7636YvDif9x4hRzHDQiN8J96pIR3Hve7Pg32r6Bt5/eCX6E81n3HtoBTyHgX4q7sNgfYe2GPUGvG/fBvTuWSZuJ7GOdwK4+keg+X/HrACe9ouVQow9lKTpi9Uj046J21EDL5kV/3uRqAihg2bHMW/ap/BnAM6cKSx4aicCZzBQMql9ptkGSJ4Mfzq49+gC8zfu/ZvRu5vekm1g7W+Nyf4jde6QyCzmkI9NX6mceAiwjW6CzQB+MiuhvYCUaJoyhDPA5ex7WCCvHVIhWKAwyELFEsIlQLiM2pUOXENFJBsln9qcK+T+MyvgPw54k+gt+QzcsXOe+QdGAUudHT8TfeETM95VzsyEkv3TYUcg616TxdtX3S5uJ7HA/mOQjwAKdTwvvB1KAZhcokCuBORa6uw6ul6m580DRTauV6g0UaF6mZ4rNdSOFEMKQzCblHB8kPnh7R9G/t5XMabCceLJMZuqqEe2PXpWyX8CatFTUMsTBs3FoH/jXbyfHKp/r2m3mZS6HepZQKPRrFVQsQN6I11bAPUqXTup9FBx0r2DrkYh2azrotJB9a1UDMVcIkWUkyIKvq6AIZN9yJ9/F2zPAhlPfU9UxRdS/hyvUp4A1f4i1KblLiP5Eo8mcf9BcCmFRi/ZczmPOpFMik6jXadOZO1UesA0Zx3T+t7lmnc256E7AdxGDmEK58H7uO5/lTFfCpiXfuOhQv+8bijEUIahCHtEAfCdGDLCecWvE3DxZfC85zeIqvhErv5vqA3LobX+HnrXZhq4O65y72eLeDAVPGyjzqJRr1ZRx5Ep0dvBWBcZ8J7vi5+PGlLIUmgeL/TeAUXobfTvNpByK8CCeV+KZias+d1DqFsLVrXCJaril3DVK3crjWugdrwD3bEDOoWRLEBRi3SOHG0xuEqjXmumjm//s/jJDQF47qe3pmXATBlvQyP9nQoztKSI6TbmPKyjaxfQsjn+7P71kK9salK7PoLmOkDWIpVGJHU+RTSczISuNeeKZjcVrve/AGb4DPIhKr1dEvmWIJk6z0lK5iiX6Np+l2gaX3Sfmj3VmTN/irg1MUae0rMXmvsYdH82KKQkBdTSyGz81pMepnW1mkpQyBxJ5JwDuWCe1PieH4J9/mRv8dJ0cWuiOP8Grf80KeACvQFVpID6n4lH3zpM6bJBoYhKNiKk0uuaHiMEFmLs01646vaAfR0CzVsLpc79GYoznXxkDimATE+o7iHR7JbBlFZSAvkaueovosoEsE9m/pJE4y0VVfFDoP6te0MtuxHu+hKK6zQpIB+avyJBPL7l6OqVVhYoozewlAKBgaL5SuPjc6Xj9NxhP3wHW/c3yd3HoPRmkwIKxvUt+GaiS3X8WucbRVTHB33ZCXe6C1651Fe5KpJ1Su2J6XJPBuS+s2FRNaFwuXmO5is2lXDN5uuBpgUI2uMnG/ZV/xGBhm0ItexHuPMoFOcZqO7cGeLxhKNJTT2GAvRAI5kgio7izf57696bFWzeA6n9C8jdx8n82JrEo6hAC9XNM3yB4rHromogVG7e+O+hy6vmBWuWbvCXLvyD78Izb/vOP5ntzXr8fdEsdpDaDpHzPWY6XtV1/hFRHTWo/uqQEZUpvcch9xxGuH0HpCt/QrBuNQJVL8NX8jz6834RVQNnCGqfbZXWa2tVXJk2Ci+XifKm7i8tjTg6CjtF86hC8xQ9q7rPknlMR7j7EKS2HQg2bkKg9rfwlb8Cz4VF94um0Q/6y+4gx6ZEOv0rRe8vLBHNog6lzwbZkYpwx0GErmwnv7UJ3qqV58Xj2EJq2bpAdZ0YogDVdyFq12Uqzkwa/SmQrh5AsJmChsvrvnGBcFShVP/m3nDj+kq59QMoHXuhOJKg9p0apADRNCpRek6mhDuPINS6L3byAfX8nJXyxecCatVSqPVroLa8DbVzF1TH59B6jemGfOje4phQQNhx8tVwR3J0dz42TvoOT53+T/rJR17Rsx4vUPPnetXihVyrXQ6taS209vehOfZC7zsK3ZMF3Wd8IC+hQil/oDy63wDnifukjiT4m/fo/roto/6AP6Eg59F/0Ep/laBdeq1JvbJO0zs/ht77GVj/cTDfOep0YxWDMd9SAR6qimoFwJk8RWpPQvDKX+Gv3wJv9Tr0F69Ab94LcGT/MqM78+fLujPmRPfGQM2xc5bmPiwx32nq+DzwIKX4oUqz87lUE90KoOTLeANCLXvhvfzesDt3Ygb02+7gwQLq9DIq1WbnGx9dxOOoJNR34k7hhMe86SNq4RKZHup8hO1mEdVRSdh5Zna46ygpYD8CjR8N+k4QsyBcQR1/TQGXotsJuzLflXtSKQ/4jPKAHfDXbYKvemXsLcz9KgMKMFazGZ//qKDsu+JR1KE6bXWyI50y4cPkBz5BsP5t+KvXwFu6DO6ChSNuFolKmJRfA7kUkKupkBLkOvID9tfF46hDdZ9D2Hli0Jqha3gLX5jtOT9vt9s255Coim6YNy0foRwa9cVUqqiQCZIvgcm1baJJVAFP0fc1z3mo7uOxv4WV9/3feiGa8FDZvGj3A6rvYpLuzYXmPgXKB+JrbSiXihZwiXIBoQQWtn8gHkUNLFBMWTspwHMKmutLKJ17zP0FMQ/3nvkBD+ZTIlZC4ehAMhZt+QALVf+ZBUvA/LnQvSeh9SZC69oF5cpbPaJJbKK79q1nnhQwXxaYoQT6T5pZMSVmTKrdI5pNOObACBkThjlgnuPQew9C79oOrWUD1Po3oFS8OGjDX0ygtv3JpXd/DN11sFLrSxl0ngMX80Jcrv2hqJow9GBtrpEsitsIWscHc7SWN5s0+3Jo5YugFj4D7dwT0R+KKmWLXpLty3Wt6XezRdUQ9EBRIQuWQw9UcFE1IXD50koerqbBUAY9lFspqodFvzB3g2Z7DNqpn0I9NiP6IiXkPPq9cM5Tw8bQX0f15lxl/ovmDKkeqC4W1bcUYy2q4YuMRJFLhWQes8lUpkS2to6Elvbg0+rR6W4l6UfRsedYPT5zUNj5TWjuk+TscsnmXqTRV0H+oOa0eHRLMNaicqkWerA8shGP+09NZZ7PM5jzk1ENomvwxGkP8KT7p4rbW8t4RoC53saRZMbbRthnhH+GDdbDNbfkTdBC1QkU9ZhmhwcvDhuN8ZY/xPb8z0hITe9nyB1/gepMhtZ/skH3562gEPBzIxLRpRr+bTpmzVe2Z+DLnPGFrpDCzvM0CE6NaPvjjuCldQg1b4msQDPQfPlhHio184SB6Yq6mxqiqr6CGYr7Ate8hWT6jG/U1PHeLOieE2DuJMp8D8TOmp8bwVv04tpAxf80iNsIzJdJIWnev3Bjw7U5cWcHlDowpeGGMma1/8IjsjtHUvtyoPadpWJDuCfzbtmV5tJ6U6A5P4fu+Cv07qFnTcQl7rwFQ5b2qc59V/X+I78xZB7KoyxZTN4pFKEo9eZWIlJEGw9ffn00U9mqr+hBtTcvSe3NgeKyQXJkhGVHBuSeNCopCDuTzJO54PxkitzxiaJd3QK9ZSPUy6vj+whM16m5Q/YCGKeYKB3bIltDeeA0OcccmMcNmNPYlWDh2kRzs7WhDNnYZtpASjJKHbW1UyhbQ/a8kkxKsbHfgEb5eSjOLOrsDIQ7UxFsHZhYk1oPbJeu7oN0de+gOZ5ww9rZav0qGKs69PJfTUhIPGGEG1aXC9GEe74A96cDwUxSQi51csFjRr0ROYESJgpXd5ub+aiwUM0WFiIFBSih8xZBceeb8zawJ08Ot6e4pPZEczn89Y4k+Dpq2eJPtYsJ0HLnbBZV8Y1Utngm7L+O7J7k3R9P5a5d5qEaxuEazJ8+aFMfCxbkC5FM1cACL81bJBlOVXOfo45OGtTRgcZdKwP1W+Gveecbj7+8BmyP36Gf/S9omY+Yio9rvn4+NG97M4F3vA30bINxvIyojvDVTRPMe/ZT46r1Z32o952mkDZ9WCfqLV8721OyasxbUPXjM07zpJkTk1xNFKxhxU7evBpoWw/e+daIiRDvSTIPglJ7k6dp3V9Abt93XQfal7dkXJsAedoD94z2EPG4QK9a1MntL4MUETkjbjRoLTsRbtw2pukDi2HghT8HL3mWLM3YRp1at4ki1vXx8fVqIuE5j4PlPhlxtKNFrfgtpLI34vOch1sFku+ZzM88PK5sVC0Y29HFFsPA06atZukPHhG3Y0I9+0tLATcKO3LfuD9+qyefiu6di7EA+/K+cY1+AyX9Meso4olES3k4cmCrxTggB3xDq9CU5BkvCdFiIlCTfhz7azljGST/OD7P+LSwsLCwsLCwsLCwsLCwsLCwiCMmTfp/Ne/YPCPMPC8AAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAlCSURBVHhe7dxrbBTXFQdw2qSJokRKhUSFoEJNU7UfWj5RVapUNVKlSFGTfEirlqoqFLDr1DwLGEEgBRIgFFqXp0l5FBNQwTbg4EeMn/ELjI3XD2yvX9g4NnaN32t7HzM7e86/d5eLVcc27NrG3tncnzTi3DtrI8+ZmXvu7MzMURRFURRFURRFURRFURTlK4R7oqJkOCnICF8iQ2UyqDsqU4aTQjkRh2WoTAY6ti7i7s0/l82AcNGaxZT7bp9sKpNFPZsKZBgQLl27FoWrIZvKZHHPlgXctvEF2fQbVaxLQvEalYDpQN1bEmXoN6re4ETZRnDRxoWyy2+cFPY9GSpe6Nz6HRn6DQ3bgOqtoNubo2WX3/jqil/IUHmEB7a/I0O/4N6HQP1O4M6OgE5DSPjNMzJUJosfRC/G/YNA8wGRhI8CSgAlRyTJ0C98bXlAO8ZXAvV+nIrOj4H2GKDliEjC4Z/JVSM4f/ubMhyFPlvtdwIo6Y+XZWguyH3tWRkGDEh44ikC/ReAXrF0nQM6YkEt/xozH+Dij5bJcARnbtqArPVjkjUeSl2VyOlhc2XTfLyVBqcsD7xCcZx67CEPe+p8DCcDtiSg/1Og5wrwIAGoSXhOfmQOrCdsfOfoFtkcgbxtfp+uxMZ/XYbmhdTwCLq+Kkc2/UbOiydkOAY5sofhzAUcYhkWiy1bJCJDJCJNHBEiOe1X8tByEdRw7rr8ER8u3R+Jkj1+JYDTVs6ToflRRngRciNFvb7a79qbnCke0tOOyeYI1m8vg24BtDKxlAMuETtui0TcAgaLgIECkQiRkAciGe3XRm1s1Ijx4s4/n5gALoh8TYahgwrWeVCyEVSxtV52PRbpnyfCXQjSip3sKVsKd9USuK3nyKj7kI3G19lRtwDAM8yVL7Jet5hddSvJXnWRhsp1DJWKRIiE9OSLIyL3Jd/va41rxb0L4qg45fH9BxNAyYYVMgwt3tobZVsA6/tA0z7g/j8i5Kpxkbs0CUYlyKg5JE7uvo0YCLbXvkXDlVbYSkB9+e3ozgL+mwxqi2uVHxmDqrfvR82ukXEk5HDV9jfRuBdojQY6Y0DdZzzcFj/uNSD2WMdUMJPB3PYCDd9JxmAJ0JcP6kl3ylWjoOmAhe/uWSqboYvu/b3bV7t3x4rTRDwwlALYs/Pk6qeGXY2v0mB5F4ZujR4XumLno+M0qP1ou+wKfb7avf+y2PifPaxkNLF36pVgbvqW/MhTQ07rURqyOGkw/yQG0sVRIcrY3kt+l6YhgfriEh9u/DxRxYhztLumVq6aEeysXQ6nqKCGb4idIAtkuxYrV02aGOPMNXbAISoUVynIVV0mu2YUa41vw1UpdoKbU9r7OXnFJmDO12TTPLz1O+nWTtmcFaw3LIdWOZIA2BPmy/CJOC1sB2f84UXZNB9R04syHl+XzVlDev1Rb5krlieeQrho41zKjrzFWeHfl13mxFrVTjaaguYSL+m1XeS0THiFFDV/3UbFmxxcuC7KVKcbfnD4HfSdBmwXRamZYoOrQFQ7FWJy1VgoPxIU2NX6KvQasKvY9y0Z2+Ln8oNPdqLtuJg5H3Rx9W4xgzThef4RGkz0wJkjNn4p4K4V5WZn0J07yV2fDK1C7CiFYocRFVr3JdD9k+1oOfRN+RFzgyZKPlHrk96ULruCinfGDL1WVEWiLB64blDvlQtijDLvXv9lrJVsgiH+QHQskl1Bh9x3rWQvd/NQ3q9kV2iBpymoZ5xsfPEWadVZshla2FX5ChlfxMhm0GK99kcyDB3eGhuGVQy+rT+UXUELaAmNQfcRcmXsh7sE8NSZ4oIXO1oXyDB0wH0bMBrMkQC95XcyDA3iCPiPuRLQtpic1loxKXtFdpkLd+79CfUePoGhs6KmvgxoGWLyZaJTkJgkeucDNFzENJDeQ93xxdxx5k/cFr0QubvGvdfJO0v2Lpy27nnZ9fTwtVU/oJRVVqSHgXLC2/lm5Ji7z7gv+g0MnrHAHi8ScN1UCfB+0Q+9DnAWA0OZQJ/YiTr/DWqJvk8Ne2K46v3f4vZfvis/HvygpeZBvylOQTUmOQJaF/iOAEdxJtvSzXtX3P9jLW8njDvmSIC7LfTuCfKCZrHJMKix0Wz+2xHHw3rRYhkGNTKaymUYethTvlyGQctbLpNumdKjs0GLjOKg3rt8l6QNq6jaikFa5qx+Xz3t2JUWCT0/qAdiMhqj2V2xBe7CJUDCc3AkLGHb+dB4mA9aIqBngt03V8suZaaw8+xSuOJEAlLEkmOKcjRkALueI3uMh7UL4z6vpTxlbIsO+tkkGTX7yCipkk1lJjE3LIRRJiqfG6L8zNgvu0Mfc/xcdmdO6V1B0wFGhdj4N8XYlAVoSSBH3AdyVWgjLS4WehJYy561O+TIqKyFu0hs/Gyx8UWB4EwAHJ+AhmMCfm+F6UA7L/7oy77KiLWMGU8CGxUjRQHcqUvYEb+B7OfqYT8FDB0BBg6a4trVpPDQkXlwnRaH+wW7SEIeaynvsZ45I9eKvDdbiT3/rGxOiHv37kDvbqB/68uyK3TQcHQL7MfF8X7yG7JrRrBR8wbc5WKwvTHq+eEnQc3qgB8SDGpkP/DY18uwVjCtt38zNz5PWlXhw+eLbwCurElNBr1PenLpmnDZNCfu/+BtGU4IyHqZtII+NizT8k4fcpfHQS8RG75ALBlioE1CIA9jfBnnRyzlnLBIWCJm9AieMUDus6JE/bFsBsT7s2TcPSSbI0T/S3BeFxs+UQyyl0C22GG5atK8341T0sqAXxY1K7xvR5ThlLBeGQZ3jajda8VSL5YG778WudrHl0Ct9JeyOQps5y3oPwP0nQB3RU/5SicnL/spJa74XDaDE5rXL0LX9A1k0IrFubzUt5DTMiS7R3ncK2+459jv8SAaaN8X+hcGYVm/iKxrp/UwpeEsDxw5YsKUzeTIOSC7A8KN++aheSeo8b2Tsiv0oDBiERX9WZfNaUO2qwdh+xTUf8090asO/EXVUR6u3Gzepx0fh7LDqp7GC/LYdnoues+Bes53y64poeL1p2Wo+Asdx0H3j2XIpjLT0Pw3cPPBX8umMtOoevctbpyBm2GV8XF5VNDfYxTSkBtiF8gURTEb070kKdTw1fBvy1CZDRM9s6UoiqIoiqIoiqIoiqIowWXOnP8B5gGFQj7+hj8AAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAgMSURBVHhe7d17bFvVHQfwwkZHN1CnAlJHJzY0aSDGY9qDSWhoD+2PbWh/7I8hjQlp2qRKpaWhY6ElXUlH24UupKWBDNKVhpJSiGFpmyYN5OXm5cSJY+fhPJqH0yTOw0kTu3Zsx3Z+v998ox/TXNuxr+W3z0eK9P2dm0rVPb73nnty7/EGQRAEQUhVVLt3M0chEbB17885ComAnQf3cBRiBbsP/4ajH+jLf5ejECswcGyJox8YLurkKMQKGU4SRz9gPOPgKMhFytwvclwXTZcG7QCa/zjoNiEEbMn+Gcd1kSn4TibzpYg7gGjDLRwzE3bmfA1VBZu4DAoWLzrIXPldLn2QrSaiDvAefbdnfAcQ0S2kPbKPy6DQcnkHWmv2c+mDHI2RdYD2sIYo91YuMxf05jfR4PFvchkULSuvcPRBK62yOwAH38oBff689AHgpsyF/cf/BCNvT5Om+DZuCogcgXc0uTtkdwCMveuAkXeOcZnZpJEQGE7bYKr0LDcFBK72PI4+yNMlqwPQdP4lmPrQhrPvf4WbBJgsrQBjmQfny7/NTWEjT4+sDoDFKhMsVFRzKUhwsmwLzFVYvTvnIjeFDdz9Qe+SAwFL4ypa6x7iMr1g/Y4nOMrm3fknYKnOe2FUfIGbwgKegX9yDAmdHTvBphpL64sv1O1cxfrnn+YybESa28DaaEZ724+4KSxEQ3dzDAlcumvo0P6ey4BCDU1RtWcbx+RFDbsJGrIcpPidvE+zre0dcHRc4jLqYEUv+wj7HPYczYLOV/u5TG6kyN1ITX8laN1rJk3ul7k5LODULRIpw5ojkgNx8E7wXD3KpSww/C8XDZyQPdxNKOnTD6oDCF2HmoKdcwMd7ujueRLdAz/hMmrAM1okt2Nx7vwzNF1GYDhjD3fiMOlAd94q6k/s5dJH0I7xXD3IMWoIJhQcwwLm+mpa+pTAVG6g8ZLbuTk1wdW3DcEubmhX/5ZjTMkZ+YBd3Q83WlbB0vCftBkx4cS5ezn6AVffZY4xgTj8JY4hkbN3O9g1BrS1PcpN6Y9Iv5HcYyFnRWNN+n947ysORTpSSnnkMgac848XqQM4CoLwP+DsykO7Ki6DBeH/gKe/F9x6I5fJg2q3b4a654qxYddT3JRW0D3xA3CPAHqGkvuxR2zcdT81/oWo9WXC9oN/5uaURjR9N8C1D7lMDaj62yPU6R299bxO3puuDlJGfy4nHlL+pov0b/yYhv9NYDiLMHPhXNrcRaYanCm7B2YuzcCSskp0QoKhrStzbumFxMJrJ+/HwcJs0B1tJE3ug9wsxBIuVT9LpgtExo8IRk/pYKiwGLvzH+bN8YWG0gc4ComE1+u2gbXtA1jWnUNX/3e4WRAEQRDSGo2/tZWjEGveu/xb0V5zL12veg1mPzHC+PtIoycJ9AWrpDtiAfWBEWzJ/gP/uhBrYtpFEARBEARBiCJpeCk92i6N+7lJSARE/RZw9hSAQ6Mlk/IObk5NROOp/cx9vEmHIU4WbIpkfYW1f4uTmxBnH0Y0fYubhXBg6/5vUEeughTyH9mW3nxE99VdsGqolx544mYhHKjaswWaXgy4PEA4wKkth5XeZi5TFq4MPySdLuM6z0MNu7/PUTa8Uf8ALLe9yWVaQM/Qr8CpmwWHWg021Wm01D+NxvK7eHPywMXKX3JMS2BtrybLFaLFGqI5fhLCUFLLm4V4AVPVBM18QjRRSjRykmigkEB7tIA3C/FAJsUdMHK6koaKiHpfJ9IeJu9ghVD1ctTfcY4YWpvSc1WSm6D2yD2k+fs+aMkZoeaXiK5kWXhTYtCSYjOZqv/IpRBPYHivXno6msu0gfNVWRyTE+peexwGjtu4TJhYTpjhZNnjOFYScPXGhAL1K0boerWSy4SSpjw4Rkx6UVu6i+fSD+nfsKA2Pzmub9Sc7b3y70ua8T/RtKzlcYKhpdrN670xj52Hn4L2nEW5ayJFFdTtrsTLz4e9DkM8SG+7R+MokOBsdcgHi6HpRTUoX/iIy/ih3OisOotO3U6OUSFdA3B1MuDDUERjsr/uhIxnQy6fsLY2Ut1z8/jZztR6mRuW23o5+pCzZkOgSTJYndBx9IHukSciWQ8Ch4p/yDEk+GxHnvQeNZfJC5dq9qO58Xtc+pD+8sQxJOmcf3MngGdUz9EH2nu+Ds6+vog6oS/vMY6pb22d0IXLC1z6AHd3CcewoGvwkZvP+eAc6uLoQ9rx4Ogwg0MT0dub2JJ9J8fUBlNlEGgH0LJ6Kyy3y5rUQlf/s+Ts+ymXa8DRcwKxO+DSxGBrNdCNZgJLcyM3ZRYcLs7C8fdyuPQBNqUaF1pkfcpgpftNWun2WewJUbWJnB2/4NIHWpQHyFxP3mFmaq2CGC0wUDjF0QeZKreCuXaSy7CBvaPe++P3lzuwNpdy9ANzFUjzlwjnypN7eiHaSJ+7Mdjyj2A6fwHmK2Wv6wnWlmG40eTfAQufHuLoh6YV95GxjGDqbGZ9ARCpcwO+PSI9aUHGDyw0XSHrLla6joC5btJ7OpG93hyNllyh0VOZeRq6GQ0VPwhjpwKO3dcjTRV4j5rrOHsxoqVyaLDQ24cZskDfel+6if3HnsShorBvdj4nLagKUx/bcOpcRAsroa5gG+nytnOZubD3H7/mKIv0LRgwdtpBY2fu4ybZUP1K8k0vx1skN0US7PZ2wHCRi0sh3tauAfoCD5dCIoD2kJujkAjQfqCVo5AIpMz6KkdBEARBEARBEIQUsGHDfwG4Vu3FAK5xRgAAAABJRU5ErkJggg==","","","","","","",""],"frame_max":8,"frames":[[[0,0,0,30,120]],[[0,0,0,50,255]],[[0,0,0,70,255]],[[1,0,0,80,255]],[[1,0,0,90,255]],[[2,0,0,90,120]],[],[]]} \ No newline at end of file +{"ratio":2,"se":"attack.opus","bitmaps":["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA6+SURBVHhe7ZwPbFVVnsfJuENiQmKyCckkZs2YzO5m3HV1B0YdxDFjZEVhdHCKICOriILMrDLAbAZhBhjFURERQVhmkD+CdWyhtIXyp32F0pa29P+/R1va0pb+fe+1r+//ffffOd/93dvDi7WltgXpe2/uJzm5v3vueTSc37m/P+eecyZZWFhYWFhYWFhYWFhYWFjEEshcMU2IFjcTJM+/TYgjwrJe2yVEi5sJyqbdIcQRYVkrFCFaTASwLYcQxww/s/Qfhfj3DS/85weEOAhe+dCdQrwuyH513AqAbclMIVoMB6+b+agQrwtyloJnL50lbkcNP734J0K0MGBl/7ZTiGMC+UvA8pZkidtRw868IAnR4hrc/p8/EGIE3jbrbiEOCy6+BBS9NCYzxM8ufJpnPb9C3FpcA/YflQkxAmt78oAQhwWVS4CKl8ekAJx7btx+I64B5t+GxofXilsT3vH0HCEOC+qWAZeWg1e/eq+oGhEULFiG3PmWAq4Ha/7ZENsM5+JhoxXe+PpUXFkFo7CmNzJE9YigZCFY/nOjavt3CW994ies85lOcWvCXK+5hTiJd78zlXe/b0ZH6Nx4PxWgcwPQvnHIqGZtaz4Uogm7tCQRlYvBSxeN6m2JadTEaeOOseFYBO5aEglBWf/vI1EO7939GHPsLh2Qtz4N1zbA9RHg+GioAro27xYi+ZeNk9H0OlD/2rjMD09L+Fchxg7636YvDif9x4hRzHDQiN8J96pIR3Hve7Pg32r6Bt5/eCX6E81n3HtoBTyHgX4q7sNgfYe2GPUGvG/fBvTuWSZuJ7GOdwK4+keg+X/HrACe9ouVQow9lKTpi9Uj046J21EDL5kV/3uRqAihg2bHMW/ap/BnAM6cKSx4aicCZzBQMql9ptkGSJ4Mfzq49+gC8zfu/ZvRu5vekm1g7W+Nyf4jde6QyCzmkI9NX6mceAiwjW6CzQB+MiuhvYCUaJoyhDPA5ex7WCCvHVIhWKAwyELFEsIlQLiM2pUOXENFJBsln9qcK+T+MyvgPw54k+gt+QzcsXOe+QdGAUudHT8TfeETM95VzsyEkv3TYUcg616TxdtX3S5uJ7HA/mOQjwAKdTwvvB1KAZhcokCuBORa6uw6ul6m580DRTauV6g0UaF6mZ4rNdSOFEMKQzCblHB8kPnh7R9G/t5XMabCceLJMZuqqEe2PXpWyX8CatFTUMsTBs3FoH/jXbyfHKp/r2m3mZS6HepZQKPRrFVQsQN6I11bAPUqXTup9FBx0r2DrkYh2azrotJB9a1UDMVcIkWUkyIKvq6AIZN9yJ9/F2zPAhlPfU9UxRdS/hyvUp4A1f4i1KblLiP5Eo8mcf9BcCmFRi/ZczmPOpFMik6jXadOZO1UesA0Zx3T+t7lmnc256E7AdxGDmEK58H7uO5/lTFfCpiXfuOhQv+8bijEUIahCHtEAfCdGDLCecWvE3DxZfC85zeIqvhErv5vqA3LobX+HnrXZhq4O65y72eLeDAVPGyjzqJRr1ZRx5Ep0dvBWBcZ8J7vi5+PGlLIUmgeL/TeAUXobfTvNpByK8CCeV+KZias+d1DqFsLVrXCJaril3DVK3crjWugdrwD3bEDOoWRLEBRi3SOHG0xuEqjXmumjm//s/jJDQF47qe3pmXATBlvQyP9nQoztKSI6TbmPKyjaxfQsjn+7P71kK9salK7PoLmOkDWIpVGJHU+RTSczISuNeeKZjcVrve/AGb4DPIhKr1dEvmWIJk6z0lK5iiX6Np+l2gaX3Sfmj3VmTN/irg1MUae0rMXmvsYdH82KKQkBdTSyGz81pMepnW1mkpQyBxJ5JwDuWCe1PieH4J9/mRv8dJ0cWuiOP8Grf80KeACvQFVpID6n4lH3zpM6bJBoYhKNiKk0uuaHiMEFmLs01646vaAfR0CzVsLpc79GYoznXxkDimATE+o7iHR7JbBlFZSAvkaueovosoEsE9m/pJE4y0VVfFDoP6te0MtuxHu+hKK6zQpIB+avyJBPL7l6OqVVhYoozewlAKBgaL5SuPjc6Xj9NxhP3wHW/c3yd3HoPRmkwIKxvUt+GaiS3X8WucbRVTHB33ZCXe6C1651Fe5KpJ1Su2J6XJPBuS+s2FRNaFwuXmO5is2lXDN5uuBpgUI2uMnG/ZV/xGBhm0ItexHuPMoFOcZqO7cGeLxhKNJTT2GAvRAI5kgio7izf57696bFWzeA6n9C8jdx8n82JrEo6hAC9XNM3yB4rHromogVG7e+O+hy6vmBWuWbvCXLvyD78Izb/vOP5ntzXr8fdEsdpDaDpHzPWY6XtV1/hFRHTWo/uqQEZUpvcch9xxGuH0HpCt/QrBuNQJVL8NX8jz6834RVQNnCGqfbZXWa2tVXJk2Ci+XifKm7i8tjTg6CjtF86hC8xQ9q7rPknlMR7j7EKS2HQg2bkKg9rfwlb8Cz4VF94um0Q/6y+4gx6ZEOv0rRe8vLBHNog6lzwbZkYpwx0GErmwnv7UJ3qqV58Xj2EJq2bpAdZ0YogDVdyFq12Uqzkwa/SmQrh5AsJmChsvrvnGBcFShVP/m3nDj+kq59QMoHXuhOJKg9p0apADRNCpRek6mhDuPINS6L3byAfX8nJXyxecCatVSqPVroLa8DbVzF1TH59B6jemGfOje4phQQNhx8tVwR3J0dz42TvoOT53+T/rJR17Rsx4vUPPnetXihVyrXQ6taS209vehOfZC7zsK3ZMF3Wd8IC+hQil/oDy63wDnifukjiT4m/fo/roto/6AP6Eg59F/0Ep/laBdeq1JvbJO0zs/ht77GVj/cTDfOep0YxWDMd9SAR6qimoFwJk8RWpPQvDKX+Gv3wJv9Tr0F69Ab94LcGT/MqM78+fLujPmRPfGQM2xc5bmPiwx32nq+DzwIKX4oUqz87lUE90KoOTLeANCLXvhvfzesDt3Ygb02+7gwQLq9DIq1WbnGx9dxOOoJNR34k7hhMe86SNq4RKZHup8hO1mEdVRSdh5Zna46ygpYD8CjR8N+k4QsyBcQR1/TQGXotsJuzLflXtSKQ/4jPKAHfDXbYKvemXsLcz9KgMKMFazGZ//qKDsu+JR1KE6bXWyI50y4cPkBz5BsP5t+KvXwFu6DO6ChSNuFolKmJRfA7kUkKupkBLkOvID9tfF46hDdZ9D2Hli0Jqha3gLX5jtOT9vt9s255Coim6YNy0foRwa9cVUqqiQCZIvgcm1baJJVAFP0fc1z3mo7uOxv4WV9/3feiGa8FDZvGj3A6rvYpLuzYXmPgXKB+JrbSiXihZwiXIBoQQWtn8gHkUNLFBMWTspwHMKmutLKJ17zP0FMQ/3nvkBD+ZTIlZC4ehAMhZt+QALVf+ZBUvA/LnQvSeh9SZC69oF5cpbPaJJbKK79q1nnhQwXxaYoQT6T5pZMSVmTKrdI5pNOObACBkThjlgnuPQew9C79oOrWUD1Po3oFS8OGjDX0ygtv3JpXd/DN11sFLrSxl0ngMX80Jcrv2hqJow9GBtrpEsitsIWscHc7SWN5s0+3Jo5YugFj4D7dwT0R+KKmWLXpLty3Wt6XezRdUQ9EBRIQuWQw9UcFE1IXD50koerqbBUAY9lFspqodFvzB3g2Z7DNqpn0I9NiP6IiXkPPq9cM5Tw8bQX0f15lxl/ovmDKkeqC4W1bcUYy2q4YuMRJFLhWQes8lUpkS2to6Elvbg0+rR6W4l6UfRsedYPT5zUNj5TWjuk+TscsnmXqTRV0H+oOa0eHRLMNaicqkWerA8shGP+09NZZ7PM5jzk1ENomvwxGkP8KT7p4rbW8t4RoC53saRZMbbRthnhH+GDdbDNbfkTdBC1QkU9ZhmhwcvDhuN8ZY/xPb8z0hITe9nyB1/gepMhtZ/skH3562gEPBzIxLRpRr+bTpmzVe2Z+DLnPGFrpDCzvM0CE6NaPvjjuCldQg1b4msQDPQfPlhHio184SB6Yq6mxqiqr6CGYr7Ate8hWT6jG/U1PHeLOieE2DuJMp8D8TOmp8bwVv04tpAxf80iNsIzJdJIWnev3Bjw7U5cWcHlDowpeGGMma1/8IjsjtHUvtyoPadpWJDuCfzbtmV5tJ6U6A5P4fu+Cv07qFnTcQl7rwFQ5b2qc59V/X+I78xZB7KoyxZTN4pFKEo9eZWIlJEGw9ffn00U9mqr+hBtTcvSe3NgeKyQXJkhGVHBuSeNCopCDuTzJO54PxkitzxiaJd3QK9ZSPUy6vj+whM16m5Q/YCGKeYKB3bIltDeeA0OcccmMcNmNPYlWDh2kRzs7WhDNnYZtpASjJKHbW1UyhbQ/a8kkxKsbHfgEb5eSjOLOrsDIQ7UxFsHZhYk1oPbJeu7oN0de+gOZ5ww9rZav0qGKs69PJfTUhIPGGEG1aXC9GEe74A96cDwUxSQi51csFjRr0ROYESJgpXd5ub+aiwUM0WFiIFBSih8xZBceeb8zawJ08Ot6e4pPZEczn89Y4k+Dpq2eJPtYsJ0HLnbBZV8Y1Utngm7L+O7J7k3R9P5a5d5qEaxuEazJ8+aFMfCxbkC5FM1cACL81bJBlOVXOfo45OGtTRgcZdKwP1W+Gveecbj7+8BmyP36Gf/S9omY+Yio9rvn4+NG97M4F3vA30bINxvIyojvDVTRPMe/ZT46r1Z32o952mkDZ9WCfqLV8721OyasxbUPXjM07zpJkTk1xNFKxhxU7evBpoWw/e+daIiRDvSTIPglJ7k6dp3V9Abt93XQfal7dkXJsAedoD94z2EPG4QK9a1MntL4MUETkjbjRoLTsRbtw2pukDi2HghT8HL3mWLM3YRp1at4ki1vXx8fVqIuE5j4PlPhlxtKNFrfgtpLI34vOch1sFku+ZzM88PK5sVC0Y29HFFsPA06atZukPHhG3Y0I9+0tLATcKO3LfuD9+qyefiu6di7EA+/K+cY1+AyX9Meso4olES3k4cmCrxTggB3xDq9CU5BkvCdFiIlCTfhz7azljGST/OD7P+LSwsLCwsLCwsLCwsLCwsLCwiCMmTfp/Ne/YPCPMPC8AAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAlCSURBVHhe7dxrbBTXFQdw2qSJokRKhUSFoEJNU7UfWj5RVapUNVKlSFGTfEirlqoqFLDr1DwLGEEgBRIgFFqXp0l5FBNQwTbg4EeMn/ELjI3XD2yvX9g4NnaN32t7HzM7e86/d5eLVcc27NrG3tncnzTi3DtrI8+ZmXvu7MzMURRFURRFURRFURRFURTlK4R7oqJkOCnICF8iQ2UyqDsqU4aTQjkRh2WoTAY6ti7i7s0/l82AcNGaxZT7bp9sKpNFPZsKZBgQLl27FoWrIZvKZHHPlgXctvEF2fQbVaxLQvEalYDpQN1bEmXoN6re4ETZRnDRxoWyy2+cFPY9GSpe6Nz6HRn6DQ3bgOqtoNubo2WX3/jqil/IUHmEB7a/I0O/4N6HQP1O4M6OgE5DSPjNMzJUJosfRC/G/YNA8wGRhI8CSgAlRyTJ0C98bXlAO8ZXAvV+nIrOj4H2GKDliEjC4Z/JVSM4f/ubMhyFPlvtdwIo6Y+XZWguyH3tWRkGDEh44ikC/ReAXrF0nQM6YkEt/xozH+Dij5bJcARnbtqArPVjkjUeSl2VyOlhc2XTfLyVBqcsD7xCcZx67CEPe+p8DCcDtiSg/1Og5wrwIAGoSXhOfmQOrCdsfOfoFtkcgbxtfp+uxMZ/XYbmhdTwCLq+Kkc2/UbOiydkOAY5sofhzAUcYhkWiy1bJCJDJCJNHBEiOe1X8tByEdRw7rr8ER8u3R+Jkj1+JYDTVs6ToflRRngRciNFvb7a79qbnCke0tOOyeYI1m8vg24BtDKxlAMuETtui0TcAgaLgIECkQiRkAciGe3XRm1s1Ijx4s4/n5gALoh8TYahgwrWeVCyEVSxtV52PRbpnyfCXQjSip3sKVsKd9USuK3nyKj7kI3G19lRtwDAM8yVL7Jet5hddSvJXnWRhsp1DJWKRIiE9OSLIyL3Jd/va41rxb0L4qg45fH9BxNAyYYVMgwt3tobZVsA6/tA0z7g/j8i5Kpxkbs0CUYlyKg5JE7uvo0YCLbXvkXDlVbYSkB9+e3ozgL+mwxqi2uVHxmDqrfvR82ukXEk5HDV9jfRuBdojQY6Y0DdZzzcFj/uNSD2WMdUMJPB3PYCDd9JxmAJ0JcP6kl3ylWjoOmAhe/uWSqboYvu/b3bV7t3x4rTRDwwlALYs/Pk6qeGXY2v0mB5F4ZujR4XumLno+M0qP1ou+wKfb7avf+y2PifPaxkNLF36pVgbvqW/MhTQ07rURqyOGkw/yQG0sVRIcrY3kt+l6YhgfriEh9u/DxRxYhztLumVq6aEeysXQ6nqKCGb4idIAtkuxYrV02aGOPMNXbAISoUVynIVV0mu2YUa41vw1UpdoKbU9r7OXnFJmDO12TTPLz1O+nWTtmcFaw3LIdWOZIA2BPmy/CJOC1sB2f84UXZNB9R04syHl+XzVlDev1Rb5krlieeQrho41zKjrzFWeHfl13mxFrVTjaaguYSL+m1XeS0THiFFDV/3UbFmxxcuC7KVKcbfnD4HfSdBmwXRamZYoOrQFQ7FWJy1VgoPxIU2NX6KvQasKvY9y0Z2+Ln8oNPdqLtuJg5H3Rx9W4xgzThef4RGkz0wJkjNn4p4K4V5WZn0J07yV2fDK1C7CiFYocRFVr3JdD9k+1oOfRN+RFzgyZKPlHrk96ULruCinfGDL1WVEWiLB64blDvlQtijDLvXv9lrJVsgiH+QHQskl1Bh9x3rWQvd/NQ3q9kV2iBpymoZ5xsfPEWadVZshla2FX5ChlfxMhm0GK99kcyDB3eGhuGVQy+rT+UXUELaAmNQfcRcmXsh7sE8NSZ4oIXO1oXyDB0wH0bMBrMkQC95XcyDA3iCPiPuRLQtpic1loxKXtFdpkLd+79CfUePoGhs6KmvgxoGWLyZaJTkJgkeucDNFzENJDeQ93xxdxx5k/cFr0QubvGvdfJO0v2Lpy27nnZ9fTwtVU/oJRVVqSHgXLC2/lm5Ji7z7gv+g0MnrHAHi8ScN1UCfB+0Q+9DnAWA0OZQJ/YiTr/DWqJvk8Ne2K46v3f4vZfvis/HvygpeZBvylOQTUmOQJaF/iOAEdxJtvSzXtX3P9jLW8njDvmSIC7LfTuCfKCZrHJMKix0Wz+2xHHw3rRYhkGNTKaymUYethTvlyGQctbLpNumdKjs0GLjOKg3rt8l6QNq6jaikFa5qx+Xz3t2JUWCT0/qAdiMhqj2V2xBe7CJUDCc3AkLGHb+dB4mA9aIqBngt03V8suZaaw8+xSuOJEAlLEkmOKcjRkALueI3uMh7UL4z6vpTxlbIsO+tkkGTX7yCipkk1lJjE3LIRRJiqfG6L8zNgvu0Mfc/xcdmdO6V1B0wFGhdj4N8XYlAVoSSBH3AdyVWgjLS4WehJYy561O+TIqKyFu0hs/Gyx8UWB4EwAHJ+AhmMCfm+F6UA7L/7oy77KiLWMGU8CGxUjRQHcqUvYEb+B7OfqYT8FDB0BBg6a4trVpPDQkXlwnRaH+wW7SEIeaynvsZ45I9eKvDdbiT3/rGxOiHv37kDvbqB/68uyK3TQcHQL7MfF8X7yG7JrRrBR8wbc5WKwvTHq+eEnQc3qgB8SDGpkP/DY18uwVjCtt38zNz5PWlXhw+eLbwCurElNBr1PenLpmnDZNCfu/+BtGU4IyHqZtII+NizT8k4fcpfHQS8RG75ALBlioE1CIA9jfBnnRyzlnLBIWCJm9AieMUDus6JE/bFsBsT7s2TcPSSbI0T/S3BeFxs+UQyyl0C22GG5atK8341T0sqAXxY1K7xvR5ThlLBeGQZ3jajda8VSL5YG778WudrHl0Ct9JeyOQps5y3oPwP0nQB3RU/5SicnL/spJa74XDaDE5rXL0LX9A1k0IrFubzUt5DTMiS7R3ncK2+459jv8SAaaN8X+hcGYVm/iKxrp/UwpeEsDxw5YsKUzeTIOSC7A8KN++aheSeo8b2Tsiv0oDBiERX9WZfNaUO2qwdh+xTUf8090asO/EXVUR6u3Gzepx0fh7LDqp7GC/LYdnoues+Bes53y64poeL1p2Wo+Asdx0H3j2XIpjLT0Pw3cPPBX8umMtOoevctbpyBm2GV8XF5VNDfYxTSkBtiF8gURTEb070kKdTw1fBvy1CZDRM9s6UoiqIoiqIoiqIoiqIowWXOnP8B5gGFQj7+hj8AAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAgMSURBVHhe7d17bFvVHQfwwkZHN1CnAlJHJzY0aSDGY9qDSWhoD+2PbWh/7I8hjQlp2qRKpaWhY6ElXUlH24UupKWBDNKVhpJSiGFpmyYN5OXm5cSJY+fhPJqH0yTOw0kTu3Zsx3Z+v998ox/TXNuxr+W3z0eK9P2dm0rVPb73nnty7/EGQRAEQUhVVLt3M0chEbB17885ComAnQf3cBRiBbsP/4ajH+jLf5ejECswcGyJox8YLurkKMQKGU4SRz9gPOPgKMhFytwvclwXTZcG7QCa/zjoNiEEbMn+Gcd1kSn4TibzpYg7gGjDLRwzE3bmfA1VBZu4DAoWLzrIXPldLn2QrSaiDvAefbdnfAcQ0S2kPbKPy6DQcnkHWmv2c+mDHI2RdYD2sIYo91YuMxf05jfR4PFvchkULSuvcPRBK62yOwAH38oBff689AHgpsyF/cf/BCNvT5Om+DZuCogcgXc0uTtkdwCMveuAkXeOcZnZpJEQGE7bYKr0LDcFBK72PI4+yNMlqwPQdP4lmPrQhrPvf4WbBJgsrQBjmQfny7/NTWEjT4+sDoDFKhMsVFRzKUhwsmwLzFVYvTvnIjeFDdz9Qe+SAwFL4ypa6x7iMr1g/Y4nOMrm3fknYKnOe2FUfIGbwgKegX9yDAmdHTvBphpL64sv1O1cxfrnn+YybESa28DaaEZ724+4KSxEQ3dzDAlcumvo0P6ey4BCDU1RtWcbx+RFDbsJGrIcpPidvE+zre0dcHRc4jLqYEUv+wj7HPYczYLOV/u5TG6kyN1ITX8laN1rJk3ul7k5LODULRIpw5ojkgNx8E7wXD3KpSww/C8XDZyQPdxNKOnTD6oDCF2HmoKdcwMd7ujueRLdAz/hMmrAM1okt2Nx7vwzNF1GYDhjD3fiMOlAd94q6k/s5dJH0I7xXD3IMWoIJhQcwwLm+mpa+pTAVG6g8ZLbuTk1wdW3DcEubmhX/5ZjTMkZ+YBd3Q83WlbB0vCftBkx4cS5ezn6AVffZY4xgTj8JY4hkbN3O9g1BrS1PcpN6Y9Iv5HcYyFnRWNN+n947ysORTpSSnnkMgac848XqQM4CoLwP+DsykO7Ki6DBeH/gKe/F9x6I5fJg2q3b4a654qxYddT3JRW0D3xA3CPAHqGkvuxR2zcdT81/oWo9WXC9oN/5uaURjR9N8C1D7lMDaj62yPU6R299bxO3puuDlJGfy4nHlL+pov0b/yYhv9NYDiLMHPhXNrcRaYanCm7B2YuzcCSskp0QoKhrStzbumFxMJrJ+/HwcJs0B1tJE3ug9wsxBIuVT9LpgtExo8IRk/pYKiwGLvzH+bN8YWG0gc4ComE1+u2gbXtA1jWnUNX/3e4WRAEQRDSGo2/tZWjEGveu/xb0V5zL12veg1mPzHC+PtIoycJ9AWrpDtiAfWBEWzJ/gP/uhBrYtpFEARBEARBiCJpeCk92i6N+7lJSARE/RZw9hSAQ6Mlk/IObk5NROOp/cx9vEmHIU4WbIpkfYW1f4uTmxBnH0Y0fYubhXBg6/5vUEeughTyH9mW3nxE99VdsGqolx544mYhHKjaswWaXgy4PEA4wKkth5XeZi5TFq4MPySdLuM6z0MNu7/PUTa8Uf8ALLe9yWVaQM/Qr8CpmwWHWg021Wm01D+NxvK7eHPywMXKX3JMS2BtrybLFaLFGqI5fhLCUFLLm4V4AVPVBM18QjRRSjRykmigkEB7tIA3C/FAJsUdMHK6koaKiHpfJ9IeJu9ghVD1ctTfcY4YWpvSc1WSm6D2yD2k+fs+aMkZoeaXiK5kWXhTYtCSYjOZqv/IpRBPYHivXno6msu0gfNVWRyTE+peexwGjtu4TJhYTpjhZNnjOFYScPXGhAL1K0boerWSy4SSpjw4Rkx6UVu6i+fSD+nfsKA2Pzmub9Sc7b3y70ua8T/RtKzlcYKhpdrN670xj52Hn4L2nEW5ayJFFdTtrsTLz4e9DkM8SG+7R+MokOBsdcgHi6HpRTUoX/iIy/ih3OisOotO3U6OUSFdA3B1MuDDUERjsr/uhIxnQy6fsLY2Ut1z8/jZztR6mRuW23o5+pCzZkOgSTJYndBx9IHukSciWQ8Ch4p/yDEk+GxHnvQeNZfJC5dq9qO58Xtc+pD+8sQxJOmcf3MngGdUz9EH2nu+Ds6+vog6oS/vMY6pb22d0IXLC1z6AHd3CcewoGvwkZvP+eAc6uLoQ9rx4Ogwg0MT0dub2JJ9J8fUBlNlEGgH0LJ6Kyy3y5rUQlf/s+Ts+ymXa8DRcwKxO+DSxGBrNdCNZgJLcyM3ZRYcLs7C8fdyuPQBNqUaF1pkfcpgpftNWun2WewJUbWJnB2/4NIHWpQHyFxP3mFmaq2CGC0wUDjF0QeZKreCuXaSy7CBvaPe++P3lzuwNpdy9ANzFUjzlwjnypN7eiHaSJ+7Mdjyj2A6fwHmK2Wv6wnWlmG40eTfAQufHuLoh6YV95GxjGDqbGZ9ARCpcwO+PSI9aUHGDyw0XSHrLla6joC5btJ7OpG93hyNllyh0VOZeRq6GQ0VPwhjpwKO3dcjTRV4j5rrOHsxoqVyaLDQ24cZskDfel+6if3HnsShorBvdj4nLagKUx/bcOpcRAsroa5gG+nytnOZubD3H7/mKIv0LRgwdtpBY2fu4ybZUP1K8k0vx1skN0US7PZ2wHCRi0sh3tauAfoCD5dCIoD2kJujkAjQfqCVo5AIpMz6KkdBEARBEARBEIQUsGHDfwG4Vu3FAK5xRgAAAABJRU5ErkJggg==","","","","","","",""],"frame_max":8,"frames":[[[0,0,0,30,120]],[[0,0,0,50,255]],[[0,0,0,70,255]],[[1,0,0,80,255]],[[1,0,0,90,255]],[[2,0,0,90,120]],[],[]]} \ No newline at end of file diff --git a/project/bgms/Ascension.opus b/project/bgms/Ascension.opus new file mode 100644 index 0000000..4ea0523 Binary files /dev/null and b/project/bgms/Ascension.opus differ diff --git a/project/bgms/Asphodelus_Ceui.mp3 b/project/bgms/Asphodelus_Ceui.mp3 deleted file mode 100644 index 718744a..0000000 Binary files a/project/bgms/Asphodelus_Ceui.mp3 and /dev/null differ diff --git a/project/bgms/Asphodelus_Ceui.opus b/project/bgms/Asphodelus_Ceui.opus new file mode 100644 index 0000000..55580e9 Binary files /dev/null and b/project/bgms/Asphodelus_Ceui.opus differ diff --git a/project/bgms/Blind_Alley.mp3 b/project/bgms/Blind_Alley.mp3 deleted file mode 100644 index ad5510c..0000000 Binary files a/project/bgms/Blind_Alley.mp3 and /dev/null differ diff --git a/project/bgms/Blind_Alley.opus b/project/bgms/Blind_Alley.opus new file mode 100644 index 0000000..0e37b2f Binary files /dev/null and b/project/bgms/Blind_Alley.opus differ diff --git a/project/bgms/Blood_Stain.opus b/project/bgms/Blood_Stain.opus new file mode 100644 index 0000000..8d34051 Binary files /dev/null and b/project/bgms/Blood_Stain.opus differ diff --git a/project/bgms/Crawler.mp3 b/project/bgms/Crawler.mp3 deleted file mode 100644 index befdc68..0000000 Binary files a/project/bgms/Crawler.mp3 and /dev/null differ diff --git a/project/bgms/Crawler.opus b/project/bgms/Crawler.opus new file mode 100644 index 0000000..877e0cf Binary files /dev/null and b/project/bgms/Crawler.opus differ diff --git a/project/bgms/Halbmond.opus b/project/bgms/Halbmond.opus new file mode 100644 index 0000000..cf8ae13 Binary files /dev/null and b/project/bgms/Halbmond.opus differ diff --git a/project/bgms/ed.opus b/project/bgms/ed.opus new file mode 100644 index 0000000..604d512 Binary files /dev/null and b/project/bgms/ed.opus differ diff --git a/project/bgms/op.mp3 b/project/bgms/op.mp3 deleted file mode 100644 index 84c7071..0000000 Binary files a/project/bgms/op.mp3 and /dev/null differ diff --git a/project/bgms/op.opus b/project/bgms/op.opus new file mode 100644 index 0000000..5a25f62 Binary files /dev/null and b/project/bgms/op.opus differ diff --git a/project/bgms/theme.mp3 b/project/bgms/theme.mp3 index efb307d..3d4eeb3 100644 Binary files a/project/bgms/theme.mp3 and b/project/bgms/theme.mp3 differ diff --git a/project/data.js b/project/data.js index ed372c6..9b00e13 100644 --- a/project/data.js +++ b/project/data.js @@ -11,11 +11,9 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "jiaotang", "shengnvhome", "shinvhome", - "jiedao", + "changguan2", "street01", "street02", - "guangchang", - "guangchang2", "xiaoxiang01", "xiaoxiang02", "xiaoxiang3", @@ -28,32 +26,55 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "yiqu7", "yiqu8", "yiqu9", - "yiqu10" + "yiqu10", + "changguan1", + "yushou", + "zhujuejia", + "guangchang", + "guangchang2", + "guangchang3", + "guangchang4", + "guangchang6", + "guangchang5" ], "floorPartitions": [], "images": [ + "005-Attack03.webp", + "012-Heal01.webp", + "015-Fire01.webp", "HPGaugeEnemy_A.webp", "HPGaugeEnemy_B.webp", + "LOGO.webp", "background.webp", "backgroundvertical.webp", + "bg_0000.png", "bg_1511.webp", "bg_1521.webp", "bg_2010.webp", "bg_2011.webp", "bg_2521.webp", + "bg_3021.webp", + "bg_3026.webp", + "bg_3028.webp", "bg_3042.webp", + "bg_3512.webp", + "bg_3522.webp", "bg_3531.webp", "bg_3551.webp", + "bg_3561.webp", "bg_3563.webp", "bg_3571.webp", "bg_3601.webp", + "bg_3602.webp", "bg_3721.webp", + "bg_3801.webp", "bg_5033.webp", "bg_5043.webp", "bg_5044.webp", "bg_6004.webp", "cao.webp", "d.webp", + "danqu.webp", "dl.webp", "dlr.webp", "dr.webp", @@ -155,23 +176,289 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "face_020157.webp", "face_020158.webp", "face_020159.webp", + "face_030101.webp", + "face_030102.webp", + "face_030103.webp", + "face_030104.webp", + "face_030105.webp", + "face_030107.webp", + "face_030121.webp", + "face_030122.webp", + "face_030123.webp", + "face_030124.webp", + "face_030125.webp", + "face_030127.webp", + "face_030129.webp", + "face_030131.webp", + "face_030132.webp", + "face_030141.webp", + "face_030142.webp", + "face_030143.webp", + "face_030144.webp", + "face_030145.webp", + "face_050101.webp", + "face_050102.webp", + "face_050103.webp", + "face_050104.webp", + "face_050105.webp", + "face_050106.webp", + "face_050107.webp", + "face_050108.webp", + "face_050111.webp", + "face_050112.webp", + "face_050113.webp", + "face_050116.webp", + "face_050121.webp", + "face_050122.webp", + "face_050123.webp", + "face_050124.webp", + "face_050125.webp", + "face_050126.webp", + "face_050127.webp", + "face_050128.webp", + "face_050129.webp", + "face_050130.webp", + "face_050131.webp", + "face_050132.webp", + "face_050134.webp", + "face_050135.webp", + "face_050136.webp", + "face_050137.webp", + "face_050141.webp", + "face_050142.webp", + "face_050143.webp", + "face_050144.webp", + "face_050145.webp", + "face_050146.webp", + "face_050147.webp", + "face_050148.webp", + "face_050150.webp", + "face_050151.webp", + "face_050152.webp", + "face_050201.webp", + "face_050202.webp", + "face_050203.webp", + "face_050204.webp", + "face_050205.webp", + "face_050206.webp", + "face_050210.webp", + "face_050212.webp", + "face_050213.webp", + "face_050214.webp", + "face_050215.webp", + "face_050216.webp", + "face_050221.webp", + "face_050222.webp", + "face_050223.webp", + "face_050224.webp", + "face_050225.webp", + "face_050226.webp", + "face_050229.webp", + "face_050230.webp", + "face_050232.webp", + "face_050234.webp", + "face_050235.webp", + "face_050237.webp", + "face_050241.webp", + "face_050242.webp", + "face_050243.webp", + "face_050244.webp", + "face_050245.webp", + "face_050246.webp", + "face_050249.webp", + "face_050250.webp", + "face_050252.webp", + "face_050301.webp", + "face_050302.webp", + "face_050303.webp", + "face_050304.webp", + "face_050305.webp", + "face_050306.webp", + "face_050307.webp", + "face_050308.webp", + "face_050309.webp", + "face_050310.webp", + "face_050311.webp", + "face_050313.webp", + "face_050314.webp", + "face_050315.webp", + "face_050316.webp", + "face_050317.webp", + "face_050321.webp", + "face_050322.webp", + "face_050323.webp", + "face_050324.webp", + "face_050325.webp", + "face_050326.webp", + "face_050327.webp", + "face_050328.webp", + "face_050329.webp", + "face_050330.webp", + "face_050331.webp", + "face_050332.webp", + "face_050333.webp", + "face_050334.webp", + "face_050335.webp", + "face_050336.webp", + "face_050337.webp", + "face_050338.webp", + "face_050341.webp", + "face_050342.webp", + "face_050343.webp", + "face_050344.webp", + "face_050345.webp", + "face_050346.webp", + "face_050347.webp", + "face_050348.webp", + "face_050349.webp", + "face_050350.webp", + "face_050351.webp", + "face_050352.webp", + "face_050353.webp", + "face_050441.webp", + "face_050442.webp", + "face_050443.webp", "face_050445.webp", + "face_050446.webp", + "face_050447.webp", + "face_050451.webp", + "face_050452.webp", + "face_120101.webp", + "face_120102.webp", + "face_120103.webp", + "face_120104.webp", + "face_120105.webp", + "face_120106.webp", "face_120107.webp", + "face_120108.webp", + "face_120111.webp", + "face_120112.webp", + "face_120113.webp", + "face_120121.webp", + "face_120122.webp", + "face_120123.webp", + "face_120124.webp", + "face_120125.webp", + "face_120126.webp", + "face_120127.webp", + "face_120128.webp", + "face_120131.webp", + "face_120132.webp", + "face_130101.webp", + "face_130102.webp", + "face_130103.webp", + "face_130104.webp", + "face_130105.webp", + "face_130106.webp", + "face_130107.webp", + "face_130108.webp", + "face_130109.webp", + "face_130110.webp", + "face_130111.webp", + "face_130112.webp", + "face_130113.webp", + "face_130121.webp", + "face_130122.webp", + "face_130123.webp", + "face_130124.webp", + "face_130125.webp", + "face_130126.webp", + "face_130127.webp", + "face_130128.webp", + "face_130129.webp", + "face_130130.webp", + "face_130131.webp", + "face_130132.webp", + "face_130201.webp", + "face_130202.webp", + "face_130203.webp", + "face_130204.webp", + "face_130205.webp", + "face_130206.webp", + "face_130207.webp", + "face_130208.webp", + "face_130209.webp", + "face_130211.webp", + "face_130212.webp", + "face_130213.webp", + "face_130221.webp", + "face_130222.webp", + "face_130223.webp", + "face_130224.webp", + "face_130225.webp", + "face_130226.webp", + "face_130227.webp", + "face_130228.webp", + "face_130229.webp", + "face_130230.webp", + "face_130231.webp", + "face_320101.webp", + "face_320102.webp", + "face_320103.webp", + "face_320104.webp", + "face_320105.webp", + "face_320106.webp", + "face_320107.webp", + "face_320108.webp", + "face_320109.webp", + "face_320121.webp", + "face_320122.webp", + "face_320123.webp", + "face_320124.webp", + "face_320125.webp", + "face_320127.webp", + "face_340101.webp", + "face_340102.webp", + "face_340103.webp", + "face_340104.webp", + "face_340105.webp", + "face_340106.webp", + "face_340107.webp", + "face_340108.webp", + "face_340109.webp", + "face_340110.webp", + "face_340111.webp", + "face_340112.webp", + "face_340113.webp", + "face_340114.webp", + "face_340115.webp", + "face_430101.webp", + "face_430102.webp", + "face_430103.webp", + "face_430104.webp", + "face_430105.webp", + "face_430106.webp", + "face_430107.webp", + "face_430108.webp", + "face_440101.webp", + "face_440102.webp", + "face_440103.webp", + "face_440104.webp", + "face_440105.webp", + "face_440106.webp", + "face_440107.webp", + "face_440108.webp", + "face_440109.webp", + "face_440110.webp", "green.webp", "hero.webp", + "jianji.webp", "l.webp", "lane1.webp", "light.webp", "lock.webp", "lr.webp", "maba.webp", + "miwu.webp", "null.webp", "other_0001.webp", "other_0002.webp", "other_0003.webp", "other_0004.webp", "r.webp", + "sound.webp", "status.webp", + "suiji.webp", "tati_020101.webp", "tati_020101a.webp", "tati_020101y.webp", @@ -251,8 +538,333 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "tati_020157.webp", "tati_020157a.webp", "tati_020158.webp", + "tati_050101.webp", + "tati_050101a.webp", + "tati_050101y.webp", + "tati_050102.webp", + "tati_050102y.webp", + "tati_050103.webp", + "tati_050103a.webp", + "tati_050103y.webp", + "tati_050104.webp", + "tati_050104a.webp", + "tati_050105.webp", + "tati_050105a.webp", + "tati_050105y.webp", + "tati_050106.webp", + "tati_050106y.webp", + "tati_050107.webp", + "tati_050107a.webp", + "tati_050107y.webp", + "tati_050110.webp", + "tati_050111.webp", + "tati_050111a.webp", + "tati_050111y.webp", + "tati_050112.webp", + "tati_050113y.webp", + "tati_050116.webp", + "tati_050116a.webp", + "tati_050116y.webp", + "tati_050117.webp", + "tati_050121.webp", + "tati_050121a.webp", + "tati_050121y.webp", + "tati_050122.webp", + "tati_050122y.webp", + "tati_050123.webp", + "tati_050123a.webp", + "tati_050123y.webp", + "tati_050124.webp", + "tati_050124a.webp", + "tati_050124y.webp", + "tati_050125.webp", + "tati_050125a.webp", + "tati_050125y.webp", + "tati_050126.webp", + "tati_050126y.webp", + "tati_050127.webp", + "tati_050127a.webp", + "tati_050128.webp", + "tati_050131.webp", + "tati_050131a.webp", + "tati_050131y.webp", + "tati_050132.webp", + "tati_050134.webp", + "tati_050134y.webp", + "tati_050135.webp", + "tati_050135y.webp", + "tati_050136.webp", + "tati_050137.webp", + "tati_050137y.webp", + "tati_050141.webp", + "tati_050141a.webp", + "tati_050141y.webp", + "tati_050142.webp", + "tati_050142a.webp", + "tati_050142y.webp", + "tati_050143.webp", + "tati_050143a.webp", + "tati_050143y.webp", + "tati_050144.webp", + "tati_050144a.webp", + "tati_050144y.webp", + "tati_050145.webp", "tati_050145a.webp", + "tati_050145y.webp", + "tati_050146.webp", + "tati_050146y.webp", + "tati_050147.webp", + "tati_050147y.webp", + "tati_050151.webp", + "tati_050151a.webp", + "tati_050151y.webp", + "tati_050152.webp", + "tati_050152y.webp", + "tati_050201.webp", + "tati_050201a.webp", + "tati_050201y.webp", + "tati_050202.webp", + "tati_050202a.webp", + "tati_050202y.webp", + "tati_050203.webp", + "tati_050203y.webp", + "tati_050204a.webp", + "tati_050204y.webp", + "tati_050205.webp", + "tati_050205a.webp", + "tati_050205y.webp", + "tati_050206.webp", + "tati_050206a.webp", + "tati_050206y.webp", + "tati_050210y.webp", + "tati_050215.webp", + "tati_050216.webp", + "tati_050221.webp", + "tati_050221a.webp", + "tati_050221y.webp", + "tati_050222.webp", + "tati_050222a.webp", + "tati_050222y.webp", + "tati_050223.webp", + "tati_050224a.webp", + "tati_050224y.webp", + "tati_050225.webp", + "tati_050225a.webp", + "tati_050225y.webp", + "tati_050226.webp", + "tati_050226a.webp", + "tati_050229.webp", + "tati_050230y.webp", + "tati_050232a.webp", + "tati_050234a.webp", + "tati_050237.webp", + "tati_050241.webp", + "tati_050241a.webp", + "tati_050241y.webp", + "tati_050242.webp", + "tati_050242a.webp", + "tati_050242y.webp", + "tati_050243.webp", + "tati_050243y.webp", + "tati_050244a.webp", + "tati_050244y.webp", + "tati_050245.webp", + "tati_050245a.webp", + "tati_050245y.webp", + "tati_050252.webp", + "tati_050252y.webp", + "tati_050301.webp", + "tati_050301a.webp", + "tati_050301y.webp", + "tati_050302.webp", + "tati_050303.webp", + "tati_050303y.webp", + "tati_050304.webp", + "tati_050304y.webp", + "tati_050305.webp", + "tati_050305a.webp", + "tati_050305y.webp", + "tati_050306.webp", + "tati_050306y.webp", + "tati_050307.webp", + "tati_050307a.webp", + "tati_050307y.webp", + "tati_050308.webp", + "tati_050309.webp", + "tati_050310.webp", + "tati_050311.webp", + "tati_050311y.webp", + "tati_050313.webp", + "tati_050314.webp", + "tati_050315.webp", + "tati_050316.webp", + "tati_050316y.webp", + "tati_050317.webp", + "tati_050321.webp", + "tati_050321a.webp", + "tati_050321y.webp", + "tati_050322.webp", + "tati_050322y.webp", + "tati_050323.webp", + "tati_050324.webp", + "tati_050324a.webp", + "tati_050324y.webp", + "tati_050325.webp", + "tati_050325a.webp", + "tati_050325y.webp", + "tati_050326.webp", + "tati_050327.webp", + "tati_050327y.webp", + "tati_050328.webp", + "tati_050329.webp", + "tati_050331.webp", + "tati_050331y.webp", + "tati_050332.webp", + "tati_050333.webp", + "tati_050334.webp", + "tati_050334a.webp", + "tati_050335.webp", + "tati_050337.webp", + "tati_050338.webp", + "tati_050338y.webp", + "tati_050341.webp", + "tati_050341a.webp", + "tati_050341y.webp", + "tati_050342.webp", + "tati_050343.webp", + "tati_050343y.webp", + "tati_050344.webp", + "tati_050345.webp", + "tati_050345a.webp", + "tati_050345y.webp", + "tati_050346.webp", + "tati_050347.webp", + "tati_050348.webp", + "tati_050349.webp", + "tati_050351.webp", + "tati_050351y.webp", + "tati_050352.webp", + "tati_050353.webp", + "tati_050353y.webp", + "tati_050441.webp", + "tati_050443.webp", + "tati_050443y.webp", + "tati_050445.webp", + "tati_050445a.webp", + "tati_050445y.webp", + "tati_050451.webp", + "tati_050451a.webp", + "tati_050452.webp", + "tati_050452y.webp", + "tati_120101.webp", + "tati_120101y.webp", + "tati_120102.webp", + "tati_120102y.webp", + "tati_120103.webp", + "tati_120103y.webp", + "tati_120104.webp", + "tati_120104y.webp", + "tati_120105.webp", + "tati_120105y.webp", + "tati_120106.webp", + "tati_120107.webp", + "tati_120107y.webp", + "tati_120108.webp", + "tati_120111.webp", + "tati_120111y.webp", + "tati_120112.webp", + "tati_120113.webp", + "tati_120113y.webp", + "tati_120121.webp", + "tati_120121y.webp", + "tati_120122.webp", + "tati_120123.webp", + "tati_120123y.webp", "tati_120124.webp", + "tati_120125.webp", + "tati_120125y.webp", + "tati_120126.webp", + "tati_120127.webp", + "tati_120127y.webp", + "tati_120128.webp", + "tati_120131.webp", + "tati_120132.webp", + "tati_310101.webp", + "tati_340101.webp", + "tati_340101a.webp", + "tati_340101y.webp", + "tati_340102.webp", + "tati_340102y.webp", + "tati_340103.webp", + "tati_340103y.webp", + "tati_340104.webp", + "tati_340104y.webp", + "tati_340105.webp", + "tati_340105a.webp", + "tati_340105y.webp", + "tati_340106.webp", + "tati_340106y.webp", + "tati_340107.webp", + "tati_340107y.webp", + "tati_340108.webp", + "tati_340108y.webp", + "tati_340109.webp", + "tati_340109y.webp", + "tati_340110.webp", + "tati_340110y.webp", + "tati_340111.webp", + "tati_340111y.webp", + "tati_340112.webp", + "tati_340112a.webp", + "tati_340112y.webp", + "tati_340113.webp", + "tati_340113y.webp", + "tati_340114.webp", + "tati_340114y.webp", + "tati_340115.webp", + "tati_430101.webp", + "tati_430101a.webp", + "tati_430101y.webp", + "tati_430102.webp", + "tati_430102a.webp", + "tati_430102y.webp", + "tati_430103.webp", + "tati_430103a.webp", + "tati_430103y.webp", + "tati_430104.webp", + "tati_430105.webp", + "tati_430105a.webp", + "tati_430105y.webp", + "tati_430106.webp", + "tati_430106a.webp", + "tati_430106y.webp", + "tati_430107.webp", + "tati_430107y.webp", + "tati_430108.webp", + "tati_430108a.webp", + "tati_430108y.webp", + "tati_440101.webp", + "tati_440101y.webp", + "tati_440103.webp", + "tati_440104.webp", + "tati_440105.webp", + "tati_440106.webp", + "tati_440108.webp", + "tati_z340101.webp", + "tati_z340102.webp", + "tati_z340103.webp", + "tati_z340104.webp", + "tati_z340105.webp", + "tati_z340106.webp", + "tati_z340107.webp", + "tati_z340108.webp", + "tati_z340109.webp", + "tati_z340110.webp", + "tati_z340111.webp", + "tati_z340112.webp", + "tati_z340113.webp", + "tati_z340114.webp", + "tati_z340115.webp", "u.webp", "ud.webp", "udl.webp", @@ -262,8 +874,11 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "ulr.webp", "unknow.webp", "ur.webp", + "winbackground.webp", + "winbackgroundVertical.webp", "winskin.webp", - "winskin1.webp" + "winskin1.webp", + "xunhuan.webp" ], "tilesets": [ "magictower.webp", @@ -285,7 +900,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "8.webp", "7.webp", "10.webp", - "C5.webp" + "C5.webp", + "c6.png" ], "animates": [ "hand", @@ -296,83 +912,575 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "zone" ], "bgms": [ - "Asphodelus_Ceui.mp3", - "Blind_Alley.mp3", - "Crawler.mp3", + "Ascension.opus", + "Asphodelus_Ceui.opus", + "Blind_Alley.opus", + "Blood_Stain.opus", + "Crawler.opus", + "Halbmond.opus", + "ed.opus", + "op.opus", "theme.mp3" ], "sounds": [ - "aiy010000010.mp3", - "aiy010000020.mp3", - "aiy010000030.mp3", - "aiy310000010.mp3", - "aiy310000020.mp3", - "aiy710000010.mp3", - "aiy710000020.mp3", - "aiy710000030.mp3", - "aiy710000040.mp3", - "aiy710000050.mp3", - "aiy710000060.mp3", - "attack.mp3", - "bomb.mp3", - "cancel.mp3", - "centerFly.mp3", - "confirm.mp3", - "cursor.mp3", - "door.mp3", - "equip.mp3", - "error.mp3", - "floor.mp3", - "gem.mp3", - "icePickaxe.mp3", - "item.mp3", - "jingbao.mp3", - "jump.mp3", - "load.mp3", - "open_ui.mp3", - "pickaxe.mp3", - "recovery.mp3", - "save.mp3", - "shop.mp3", - "zone.mp3" + "aiy010000010.opus", + "aiy010000020.opus", + "aiy010000030.opus", + "aiy020000005.opus", + "aiy020000010.opus", + "aiy020000020.opus", + "aiy020000030.opus", + "aiy020000040.opus", + "aiy020000050.opus", + "aiy020000060.opus", + "aiy020000070.opus", + "aiy020000080.opus", + "aiy020000090.opus", + "aiy020000100.opus", + "aiy020000110.opus", + "aiy020000120.opus", + "aiy020000130.opus", + "aiy020000140.opus", + "aiy020000150.opus", + "aiy020000160.opus", + "aiy020000170.opus", + "aiy020000180.opus", + "aiy020000190.ogg", + "aiy020000200.ogg", + "aiy020000210.ogg", + "aiy020000220.ogg", + "aiy020000230.ogg", + "aiy020000240.ogg", + "aiy020000250.ogg", + "aiy020000260.ogg", + "aiy020000270.ogg", + "aiy020000280.ogg", + "aiy020000290.ogg", + "aiy020000300.ogg", + "aiy020000310.ogg", + "aiy020000320.ogg", + "aiy020000330.ogg", + "aiy020000340.ogg", + "aiy020000350.ogg", + "aiy020000360.ogg", + "aiy020000370.ogg", + "aiy030000010.ogg", + "aiy030000020.ogg", + "aiy030000030.ogg", + "aiy030000050.ogg", + "aiy030000060.ogg", + "aiy030000070.ogg", + "aiy030000080.ogg", + "aiy030000090.ogg", + "aiy030000100.ogg", + "aiy030000110.ogg", + "aiy030000120.ogg", + "aiy030000130.ogg", + "aiy050000010.ogg", + "aiy050000020.ogg", + "aiy050000030.ogg", + "aiy050000040.ogg", + "aiy050000050.ogg", + "aiy050000060.ogg", + "aiy050000070.ogg", + "aiy050000080.ogg", + "aiy050000090.ogg", + "aiy050000100.ogg", + "aiy050000110.ogg", + "aiy050000120.ogg", + "aiy120000020.ogg", + "aiy120000030.ogg", + "aiy120000040.ogg", + "aiy120000050.ogg", + "aiy120000060.ogg", + "aiy120000070.ogg", + "aiy120000080.ogg", + "aiy120000090.ogg", + "aiy120000100.ogg", + "aiy120000110.ogg", + "aiy120000120.ogg", + "aiy120000130.ogg", + "aiy120000140.ogg", + "aiy120000150.ogg", + "aiy120000160.ogg", + "aiy120000170.ogg", + "aiy120000180.ogg", + "aiy120000190.ogg", + "aiy120000200.ogg", + "aiy120000210.ogg", + "aiy120000220.ogg", + "aiy120000230.ogg", + "aiy120000240.ogg", + "aiy120000250.ogg", + "aiy120000260.ogg", + "aiy120000270.ogg", + "aiy120000280.ogg", + "aiy120000290.ogg", + "aiy120000300.ogg", + "aiy120000310.ogg", + "aiy120000320.ogg", + "aiy120000330.ogg", + "aiy120000340.ogg", + "aiy120000350.ogg", + "aiy120000360.ogg", + "aiy120000370.ogg", + "aiy120000380.ogg", + "aiy120000390.ogg", + "aiy120000400.ogg", + "aiy120000410.ogg", + "aiy120000420.ogg", + "aiy120000430.ogg", + "aiy120000440.ogg", + "aiy120000450.ogg", + "aiy120000460.ogg", + "aiy120000470.ogg", + "aiy120000480.ogg", + "aiy120000490.ogg", + "aiy120000500.ogg", + "aiy120000510.ogg", + "aiy120000520.ogg", + "aiy120000530.ogg", + "aiy120000540.ogg", + "aiy120000550.ogg", + "aiy120000560.ogg", + "aiy120000570.ogg", + "aiy120000580.ogg", + "aiy120000590.ogg", + "aiy120000600.ogg", + "aiy120000610.ogg", + "aiy120000620.ogg", + "aiy120000630.ogg", + "aiy120000640.ogg", + "aiy120000650.ogg", + "aiy120000670.ogg", + "aiy120000680.ogg", + "aiy120000690.ogg", + "aiy130000010.ogg", + "aiy130000020.ogg", + "aiy150000010.ogg", + "aiy150000020.ogg", + "aiy150000030.ogg", + "aiy150000040.ogg", + "aiy150000050.ogg", + "aiy150000060.ogg", + "aiy150000070.ogg", + "aiy150000080.ogg", + "aiy150000090.ogg", + "aiy150000100.ogg", + "aiy150000110.ogg", + "aiy150000120.ogg", + "aiy150000130.ogg", + "aiy150000140.ogg", + "aiy150000150.ogg", + "aiy150000160.ogg", + "aiy150000170.ogg", + "aiy150000180.ogg", + "aiy150000190.ogg", + "aiy150000200.ogg", + "aiy150000210.ogg", + "aiy150000220.ogg", + "aiy150000230.ogg", + "aiy150000240.ogg", + "aiy150000250.ogg", + "aiy310000010.opus", + "aiy310000020.opus", + "aiy310000030.opus", + "aiy310000040.opus", + "aiy310000050.opus", + "aiy310000060.opus", + "aiy310000070.opus", + "aiy310000080.opus", + "aiy310000090.opus", + "aiy310000100.opus", + "aiy310000110.opus", + "aiy310000120.opus", + "aiy310000130.opus", + "aiy310000140.opus", + "aiy310000150.opus", + "aiy310000160.opus", + "aiy310000170.opus", + "aiy310000180.opus", + "aiy310000190.opus", + "aiy310000200.opus", + "aiy310000210.opus", + "aiy310000220.opus", + "aiy310000230.opus", + "aiy310000240.opus", + "aiy310000250.opus", + "aiy310000260.opus", + "aiy310000280.opus", + "aiy310000290.opus", + "aiy310000300.opus", + "aiy310000310.ogg", + "aiy310000320.ogg", + "aiy310000330.ogg", + "aiy310000340.ogg", + "aiy310000350.ogg", + "aiy310000360.ogg", + "aiy310000370.ogg", + "aiy310000380.ogg", + "aiy310000390.ogg", + "aiy310000400.ogg", + "aiy310000410.ogg", + "aiy310000420.ogg", + "aiy310000430.ogg", + "aiy310000440.ogg", + "aiy310000450.ogg", + "aiy310000460.ogg", + "aiy310000470.ogg", + "aiy310000480.ogg", + "aiy310000490.ogg", + "aiy310000510.ogg", + "aiy310000520.ogg", + "aiy310000530.ogg", + "aiy310000540.ogg", + "aiy310000550.ogg", + "aiy310000560.ogg", + "aiy310000570.ogg", + "aiy310000580.ogg", + "aiy310000590.ogg", + "aiy310000600.ogg", + "aiy310000610.ogg", + "aiy310000620.ogg", + "aiy310000630.ogg", + "aiy310000640.ogg", + "aiy310000650.ogg", + "aiy310000660.ogg", + "aiy310000670.ogg", + "aiy310000680.ogg", + "aiy310000690.ogg", + "aiy310000700.ogg", + "aiy310000710.ogg", + "aiy310000720.ogg", + "aiy310000730.ogg", + "aiy310000740.ogg", + "aiy310000750.ogg", + "aiy310000760.ogg", + "aiy310000770.ogg", + "aiy310000780.ogg", + "aiy310000790.ogg", + "aiy310000800.ogg", + "aiy310000810.ogg", + "aiy310000820.ogg", + "aiy310000830.ogg", + "aiy310000840.ogg", + "aiy310000850.ogg", + "aiy310000860.ogg", + "aiy310000870.ogg", + "aiy310000880.ogg", + "aiy310000890.ogg", + "aiy310000900.ogg", + "aiy310000910.ogg", + "aiy310000920.ogg", + "aiy310000930.ogg", + "aiy310000940.ogg", + "aiy310000950.ogg", + "aiy310000960.ogg", + "aiy310000970.ogg", + "aiy310000980.ogg", + "aiy310000990.ogg", + "aiy310001000.ogg", + "aiy310001010.ogg", + "aiy310001027.ogg", + "aiy310001030.ogg", + "aiy310001040.ogg", + "aiy310001050.ogg", + "aiy310001060.ogg", + "aiy310001070.ogg", + "aiy310001080.ogg", + "aiy310001090.ogg", + "aiy310001100.ogg", + "aiy310001110.ogg", + "aiy310001120.ogg", + "aiy310001130.ogg", + "aiy310001140.ogg", + "aiy310001150.ogg", + "aiy310001160.ogg", + "aiy310001170.ogg", + "aiy310001180.ogg", + "aiy310001190.ogg", + "aiy310001200.ogg", + "aiy310001210.ogg", + "aiy310001220.ogg", + "aiy310001230.ogg", + "aiy310001240.ogg", + "aiy310001250.ogg", + "aiy310001260.ogg", + "aiy310001270.ogg", + "aiy310001280.ogg", + "aiy310001290.ogg", + "aiy310001300.ogg", + "aiy310001310.ogg", + "aiy310001320.ogg", + "aiy310001330.ogg", + "aiy310001340.ogg", + "aiy310001350.ogg", + "aiy310001360.ogg", + "aiy310001370.ogg", + "aiy310001380.ogg", + "aiy310001390.ogg", + "aiy320000010.ogg", + "aiy320000020.ogg", + "aiy320000030.ogg", + "aiy320000040.ogg", + "aiy320000050.ogg", + "aiy320000060.ogg", + "aiy320000070.ogg", + "aiy320000080.ogg", + "aiy320000090.ogg", + "aiy320000100.ogg", + "aiy320000110.ogg", + "aiy320000120.ogg", + "aiy320000135.ogg", + "aiy320000140.ogg", + "aiy340000010.ogg", + "aiy340000020.ogg", + "aiy340000030.ogg", + "aiy340000040.ogg", + "aiy340000050.ogg", + "aiy340000060.ogg", + "aiy340000070.ogg", + "aiy340000080.ogg", + "aiy340000090.ogg", + "aiy340000100.ogg", + "aiy340000110.ogg", + "aiy340000120.ogg", + "aiy340000140.ogg", + "aiy340000150.ogg", + "aiy340000160.ogg", + "aiy340000170.ogg", + "aiy340000180.ogg", + "aiy340000190.ogg", + "aiy340000200.ogg", + "aiy340000210.ogg", + "aiy340000220.ogg", + "aiy340000230.ogg", + "aiy340000240.ogg", + "aiy340000250.ogg", + "aiy340000260.ogg", + "aiy340000270.ogg", + "aiy340000280.ogg", + "aiy340000290.ogg", + "aiy340000300.ogg", + "aiy340000310.ogg", + "aiy340000320.ogg", + "aiy340000330.ogg", + "aiy340000340.ogg", + "aiy340000350.ogg", + "aiy340000360.ogg", + "aiy340000370.ogg", + "aiy340000380.ogg", + "aiy340000390.ogg", + "aiy340000400.ogg", + "aiy340000410.ogg", + "aiy340000420.ogg", + "aiy340000430.ogg", + "aiy350000010.opus", + "aiy350000020.opus", + "aiy350000030.opus", + "aiy350000040.opus", + "aiy350000050.opus", + "aiy350000060.opus", + "aiy350000070.opus", + "aiy350000080.opus", + "aiy350000090.opus", + "aiy350000100.opus", + "aiy350000110.opus", + "aiy350000120.opus", + "aiy350000130.opus", + "aiy350000140.opus", + "aiy350000150.opus", + "aiy350000160.opus", + "aiy350000170.opus", + "aiy350000180.opus", + "aiy350000190.opus", + "aiy350000200.opus", + "aiy350000210.opus", + "aiy350000220.opus", + "aiy350000230.opus", + "aiy350000240.ogg", + "aiy350000250.ogg", + "aiy350000260.ogg", + "aiy430000010.ogg", + "aiy430000020.ogg", + "aiy430000030.ogg", + "aiy430000040.ogg", + "aiy430000050.ogg", + "aiy430000060.ogg", + "aiy430000070.ogg", + "aiy430000080.ogg", + "aiy430000090.ogg", + "aiy430000100.ogg", + "aiy430000110.ogg", + "aiy430000120.ogg", + "aiy430000130.ogg", + "aiy430000140.ogg", + "aiy430000150.ogg", + "aiy430000160.ogg", + "aiy430000170.ogg", + "aiy430000180.ogg", + "aiy430000190.ogg", + "aiy430000200.ogg", + "aiy430000210.ogg", + "aiy430000220.ogg", + "aiy430000230.ogg", + "aiy430000240.ogg", + "aiy430000250.ogg", + "aiy430000260.ogg", + "aiy430000270.ogg", + "aiy430000280.ogg", + "aiy430000290.ogg", + "aiy440000010.ogg", + "aiy440000020.ogg", + "aiy440000030.ogg", + "aiy440000040.ogg", + "aiy440000050.ogg", + "aiy440000060.ogg", + "aiy440000070.ogg", + "aiy440000080.ogg", + "aiy440000090.ogg", + "aiy440000100.ogg", + "aiy440000110.ogg", + "aiy440000120.ogg", + "aiy510000010.ogg", + "aiy510000020.ogg", + "aiy710000010.opus", + "aiy710000020.opus", + "aiy710000030.opus", + "aiy710000040.opus", + "aiy710000050.opus", + "aiy710000060.opus", + "aiy710000070.opus", + "aiy710000080.opus", + "aiy710000090.opus", + "aiy710000100.opus", + "aiy710000110.opus", + "aiy710000120.opus", + "aiy710000130.opus", + "aiy720000010.ogg", + "aiy730000010.ogg", + "aiy740000010.ogg", + "aiy750000010.ogg", + "aiy750000020.ogg", + "aiy750000030.ogg", + "aiy750000040.ogg", + "aiy750000050.ogg", + "aiy750000060.ogg", + "aiy750000070.ogg", + "aiy750000080.ogg", + "aiy750000090.ogg", + "aiy750000100.ogg", + "aiy750000110.ogg", + "aiy750000120.ogg", + "aiy750000130.ogg", + "aiy750000140.ogg", + "aiy750000150.ogg", + "aiy750000160.ogg", + "aiy750000170.ogg", + "aiy750000180.ogg", + "aiy750000190.ogg", + "aiy750000200.ogg", + "aiy750000210.ogg", + "aiy750000220.ogg", + "aiy750000230.ogg", + "aiy750000240.ogg", + "aiy750000250.ogg", + "aiy750000260.ogg", + "aiy750000270.ogg", + "aiy750000280.ogg", + "aiy750000290.ogg", + "aiy750000300.ogg", + "aiy750000310.ogg", + "aiy750000320.ogg", + "aiy750000330.ogg", + "aiy750000340.ogg", + "aiy800000010.ogg", + "aiy800000020.ogg", + "aiy800000030.ogg", + "aiy800000040.ogg", + "aiy800000050.ogg", + "aiy800000060.ogg", + "aiy800000070.ogg", + "aiy800000080.ogg", + "aiy800000090.ogg", + "aiy800000100.ogg", + "aiy810000010.ogg", + "aiy810000020.ogg", + "aiy810000030.ogg", + "aiy810000040.ogg", + "aiy810000050.ogg", + "aiy810000060.ogg", + "aiy810000070.ogg", + "aiy820000010.opus", + "aiy820000020.opus", + "aiy860000010.ogg", + "aiy860000020.ogg", + "aiy860000030.ogg", + "aiy860000040.ogg", + "aiy860000050.ogg", + "aiy860000060.ogg", + "attack.opus", + "bomb.opus", + "cancel.opus", + "centerFly.opus", + "confirm.opus", + "cursor.opus", + "door.opus", + "equip.opus", + "error.opus", + "floor.opus", + "gem.opus", + "icePickaxe.opus", + "item.opus", + "jingbao.opus", + "jump.opus", + "load.opus", + "open_ui.opus", + "pickaxe.opus", + "recovery.opus", + "save.opus", + "shop.opus", + "zone.opus" ], "fonts": [ "HATTEN", + "Verdana", "number", "pala", "simhei" ], "nameMap": { - "确定": "confirm.mp3", - "取消": "cancel.mp3", - "操作失败": "error.mp3", - "光标移动": "cursor.mp3", - "打开界面": "open_ui.mp3", - "读档": "load.mp3", - "存档": "save.mp3", - "获得道具": "item.mp3", - "回血": "recovery.mp3", - "炸弹": "bomb.mp3", - "飞行器": "centerFly.mp3", - "开关门": "door.mp3", - "上下楼": "floor.mp3", - "跳跃": "jump.mp3", - "破墙镐": "pickaxe.mp3", - "破冰镐": "icePickaxe.mp3", - "宝石": "gem.mp3", - "阻激夹域": "zone.mp3", - "穿脱装备": "equip.mp3", - "背景音乐": "bgm.mp3", - "攻击": "attack.mp3", + "确定": "confirm.opus", + "取消": "cancel.opus", + "操作失败": "error.opus", + "光标移动": "cursor.opus", + "打开界面": "open_ui.opus", + "读档": "load.opus", + "存档": "save.opus", + "获得道具": "item.opus", + "回血": "recovery.opus", + "炸弹": "bomb.opus", + "飞行器": "centerFly.opus", + "开关门": "door.opus", + "上下楼": "floor.opus", + "跳跃": "jump.opus", + "破墙镐": "pickaxe.opus", + "破冰镐": "icePickaxe.opus", + "宝石": "gem.opus", + "阻激夹域": "zone.opus", + "穿脱装备": "equip.opus", + "背景音乐": "bgm.opus", + "攻击": "attack.opus", "背景图": "bg.webp", - "商店": "shop.mp3", + "商店": "shop.opus", "领域": "zone" }, "levelChoose": null, "equipName": [ "武器", "武器", - "防具", + "护具", + "饰品", "饰品" ], "startBgm": "theme.mp3", @@ -405,25 +1513,26 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = ], "font": "pala" }, - "splitImages": null + "splitImages": [] }, "firstData": { "title": "秽翼的尤斯蒂娅", "name": "Eustia", "version": "鸽子窝造塔小队", - "floorId": "yiqu1", + "floorId": "guangchang", "hero": { "image": "hero.webp", "animate": false, - "name": "Caim", + "name": "凯伊姆", "lv": 1, "hpmax": 9999, "hp": 1000, "manamax": -1, "mana": 0, - "atk": 100, - "def": 100, - "mdef": 0, + "atk": 10, + "def": 10, + "mdef": 100, + "speed": 10, "money": 0, "exp": 0, "equipment": [], @@ -434,22 +1543,21 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = }, "loc": { "direction": "up", - "x": 5, + "x": 6, "y": 10 }, "flags": { "itemDetail": true, - "useBetweenLight": true + "useBetweenLight": true, + "__mdef_buff__": 0, + "popmove": true }, "followers": [], "steps": 0, "matk": 0, - "speed": 0, - "str": 10, - "agi": 10, - "int": 10, - "con": 10, - "magic": false + "spell": 0, + "spelldef": 0, + "mhp": 0 }, "startCanvas": [ { @@ -765,7 +1873,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = }, { "type": "function", - "function": "function(){\ncore.control.checkBgm()\n}" + "function": "function(){\ncore.checkBgm()\n}" }, { "type": "if", @@ -805,14 +1913,38 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = ], "startText": [ { - "type": "setValue", - "name": "item:book", - "value": "1" + "type": "setText" }, { - "type": "setValue", - "name": "item:fly", - "value": "1" + "type": "setHeroOpacity", + "opacity": 0 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 500, + "keep": true + }, + { + "type": "function", + "function": "function(){\ncore.getItem('book', 1);\ncore.getItem('fly', 1);\n}" + }, + { + "type": "insert", + "name": "战斗动画特效注册" + }, + { + "type": "insert", + "name": "强制横屏" + }, + { + "type": "insert", + "name": "chapter0" } ], "shops": [ diff --git a/project/enemys.js b/project/enemys.js index 931f40a..5e591b8 100644 --- a/project/enemys.js +++ b/project/enemys.js @@ -1,84 +1,84 @@ var enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80 = { - "greenSlime": {"name":"绿头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "redSlime": {"name":"红头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"value":10}, - "blackSlime": {"name":"青头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "slimelord": {"name":"怪王","hp":100,"atk":120,"def":0,"money":10,"exp":0,"point":0,"special":[1,9]}, - "bat": {"name":"小蝙蝠","hp":100,"atk":120,"def":0,"money":2,"exp":0,"point":0,"special":[1]}, - "bigBat": {"name":"大蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "redBat": {"name":"红蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, - "vampire": {"name":"冥灵魔王","hp":888,"atk":888,"def":888,"money":888,"exp":888,"point":0,"special":[6],"n":8}, - "skeleton": {"name":"骷髅人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "skeletonCaptain": {"name":"骷髅队长","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "zombie": {"name":"兽人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"magic":false}, - "zombieKnight": {"name":"兽人武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "rock": {"name":"石头人","hp":50,"atk":50,"def":0,"money":3,"exp":0,"point":0,"special":3}, - "bluePriest": {"name":"初级法师","hp":100,"atk":120,"def":0,"money":3,"exp":0,"point":1,"special":[9]}, - "redPriest": {"name":"高级法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "brownWizard": {"name":"初级巫师","hp":100,"atk":120,"def":0,"money":16,"exp":0,"point":0,"special":15,"value":100,"range":2}, - "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"exp":0,"point":0,"special":15,"value":200,"zoneSquare":true}, - "swordsman": {"name":"双手剑士","hp":100,"atk":120,"def":0,"money":6,"exp":3,"point":0,"special":4}, - "soldier": {"name":"冥战士","hp":120,"atk":50,"def":8,"money":10,"exp":7,"point":0,"special":0}, - "yellowKnight": {"name":"金骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "redKnight": {"name":"红骑士","hp":500,"atk":200,"def":50,"money":0,"exp":0,"point":0,"special":[7]}, - "darkKnight": {"name":"黑骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "blueKnight": {"name":"蓝骑士","hp":100,"atk":120,"def":0,"money":9,"exp":0,"point":0,"special":8}, - "goldSlime": {"name":"黄头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "poisonSkeleton": {"name":"紫骷髅","hp":50,"atk":60,"def":70,"money":80,"exp":0,"point":0,"special":13}, - "poisonBat": {"name":"紫蝙蝠","hp":100,"atk":120,"def":0,"money":14,"exp":0,"point":0,"special":13}, - "skeletonPriest": {"name":"骷髅法师","hp":100,"atk":100,"def":0,"money":0,"exp":0,"point":0,"special":18,"value":20}, - "skeletonKing": {"name":"骷髅王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "evilHero": {"name":"迷失勇者","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "demonPriest": {"name":"魔神法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "goldHornSlime": {"name":"金角怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "silverSlime": {"name":"银头怪","hp":100,"atk":120,"def":0,"money":15,"exp":0,"point":0,"special":14}, + "greenSlime": {"name":"绿头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "redSlime": {"name":"红头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"value":10,"mdef":0,"spell":0,"speed":1}, + "blackSlime": {"name":"青头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "slimelord": {"name":"怪王","hp":100,"atk":120,"def":0,"money":10,"exp":0,"point":0,"special":[1,9],"mdef":0,"spell":0,"speed":1}, + "bat": {"name":"小蝙蝠","hp":100,"atk":50,"def":30,"money":2,"exp":0,"point":0,"special":[1],"mdef":0,"speed":15,"spell":0}, + "bigBat": {"name":"大蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "redBat": {"name":"红蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"mdef":0,"spell":0,"speed":1}, + "vampire": {"name":"冥灵魔王","hp":888,"atk":888,"def":888,"money":888,"exp":888,"point":0,"special":[6],"n":8,"mdef":0,"spell":0,"speed":1}, + "skeleton": {"name":"骷髅人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "skeletonCaptain": {"name":"骷髅队长","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "zombie": {"name":"兽人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[22],"mdef":0,"spell":0,"speed":1}, + "zombieKnight": {"name":"兽人武士","hp":10000,"atk":100,"def":100,"money":0,"exp":0,"point":0,"special":[22],"speed":10,"mdef":0,"damage2":20,"spell":0}, + "rock": {"name":"石头人","hp":50,"atk":50,"def":0,"money":3,"exp":0,"point":0,"special":3,"damage2":15,"mdef":0,"spell":0,"speed":1}, + "bluePriest": {"name":"初级法师","hp":100,"atk":120,"def":0,"money":3,"exp":0,"point":1,"special":[9],"mdef":0,"spell":0,"speed":1}, + "redPriest": {"name":"高级法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "brownWizard": {"name":"初级巫师","hp":100,"atk":120,"def":0,"money":16,"exp":0,"point":0,"special":15,"value":100,"range":2,"mdef":0,"spell":0,"speed":1}, + "redWizard": {"name":"高级巫师","hp":1000,"atk":1200,"def":0,"money":160,"exp":0,"point":0,"special":15,"value":200,"zoneSquare":true,"mdef":0,"spell":0,"speed":1}, + "swordsman": {"name":"双手剑士","hp":100,"atk":120,"def":0,"money":6,"exp":3,"point":0,"special":4,"mdef":0,"spell":0,"speed":1}, + "soldier": {"name":"冥战士","hp":120,"atk":50,"def":8,"money":10,"exp":7,"point":0,"special":0,"mdef":0,"spell":0,"speed":8}, + "yellowKnight": {"name":"金骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "redKnight": {"name":"红骑士","hp":500,"atk":200,"def":50,"money":0,"exp":0,"point":0,"special":[7],"mdef":0,"spell":0,"speed":1}, + "darkKnight": {"name":"黑骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "blueKnight": {"name":"蓝骑士","hp":100,"atk":120,"def":0,"money":9,"exp":0,"point":0,"special":8,"mdef":0,"spell":0,"speed":1}, + "goldSlime": {"name":"黄头怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "poisonSkeleton": {"name":"紫骷髅","hp":50,"atk":60,"def":70,"money":80,"exp":0,"point":0,"special":13,"mdef":0,"spell":0,"speed":1}, + "poisonBat": {"name":"紫蝙蝠","hp":100,"atk":120,"def":0,"money":14,"exp":0,"point":0,"special":13,"mdef":0,"spell":0,"speed":1}, + "skeletonPriest": {"name":"骷髅法师","hp":100,"atk":100,"def":0,"money":0,"exp":0,"point":0,"special":18,"value":20,"mdef":0,"spell":0,"speed":1}, + "skeletonKing": {"name":"骷髅王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "evilHero": {"name":"迷失勇者","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "demonPriest": {"name":"魔神法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "goldHornSlime": {"name":"金角怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "silverSlime": {"name":"银头怪","hp":100,"atk":120,"def":0,"money":15,"exp":0,"point":0,"special":14,"mdef":0,"spell":0,"speed":1}, "whiteHornSlime": {"name":"尖角怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "redSwordsman": {"name":"剑王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[]}, - "poisonZombie": {"name":"绿兽人","hp":100,"atk":120,"def":0,"money":13,"exp":0,"point":0,"special":[12]}, - "octopus": {"name":"血影","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":null}, - "princessEnemy": {"name":"假公主","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "angel": {"name":"天使","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "elemental": {"name":"元素生物","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "steelGuard": {"name":"铁守卫","hp":50,"atk":50,"def":50,"money":0,"exp":0,"point":0,"special":[18],"value":20}, - "evilBat": {"name":"邪恶蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "silverSlimelord": {"name":"银怪王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "goldSlimelord": {"name":"金怪王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "skeletonWarrior": {"name":"骷髅士兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "whiteSlimeman": {"name":"水银战士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "slimeman": {"name":"影子战士","hp":100,"atk":0,"def":0,"money":11,"exp":0,"point":0,"special":[9],"atkValue":2,"defValue":3}, - "yellowGateKeeper": {"name":"初级卫兵","hp":80,"atk":25,"def":5,"money":3,"exp":1,"point":0,"special":0}, - "blueGateKeeper": {"name":"中级卫兵","hp":80,"atk":25,"def":5,"money":3,"exp":1,"point":0,"special":0}, - "redGateKeeper": {"name":"高级卫兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "magicMaster": {"name":"黑暗大法师","hp":100,"atk":120,"def":0,"money":12,"exp":0,"point":0,"special":11,"value":0.3333333333333333,"add":true,"notBomb":true}, - "devilWarrior": {"name":"魔神武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "fairyEnemy": {"name":"仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "dragon": {"name":"魔龙","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":null}, - "skeletonKnight": {"name":"骷髅武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "skeletonPresbyter": {"name":"骷髅巫师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "ironRock": {"name":"铁面人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "grayRock": {"name":"灰色石头人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "yellowPriest": {"name":"中级法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "evilPrincess": {"name":"痛苦魔女","hp":1000,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[10]}, + "redSwordsman": {"name":"剑王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"mdef":0,"spell":0,"speed":1}, + "poisonZombie": {"name":"绿兽人","hp":100,"atk":120,"def":0,"money":13,"exp":0,"point":0,"special":[12],"mdef":0,"spell":0,"speed":1}, + "octopus": {"name":"血影","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":null,"mdef":0,"spell":0,"speed":1}, + "princessEnemy": {"name":"假公主","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "angel": {"name":"天使","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "elemental": {"name":"元素生物","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "steelGuard": {"name":"铁守卫","hp":50,"atk":50,"def":50,"money":0,"exp":0,"point":0,"special":[18],"value":20,"mdef":0,"spell":0,"speed":1}, + "evilBat": {"name":"邪恶蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "silverSlimelord": {"name":"银怪王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "goldSlimelord": {"name":"金怪王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "skeletonWarrior": {"name":"骷髅士兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "whiteSlimeman": {"name":"水银战士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "slimeman": {"name":"影子战士","hp":100,"atk":0,"def":0,"money":11,"exp":0,"point":0,"special":[9],"atkValue":2,"defValue":3,"mdef":0,"spell":0,"speed":1}, + "yellowGateKeeper": {"name":"初级卫兵","hp":80,"atk":25,"def":5,"money":3,"exp":1,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "blueGateKeeper": {"name":"中级卫兵","hp":80,"atk":25,"def":5,"money":3,"exp":1,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "redGateKeeper": {"name":"高级卫兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "magicMaster": {"name":"黑暗大法师","hp":100,"atk":120,"def":0,"money":12,"exp":0,"point":0,"special":11,"value":0.3333333333333333,"add":true,"notBomb":true,"mdef":0,"spell":0,"speed":1}, + "devilWarrior": {"name":"魔神武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "fairyEnemy": {"name":"仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "dragon": {"name":"魔龙","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"bigImage":null,"mdef":0,"spell":0,"speed":1}, + "skeletonKnight": {"name":"骷髅武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "skeletonPresbyter": {"name":"骷髅巫师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "ironRock": {"name":"铁面人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "grayRock": {"name":"灰色石头人","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "yellowPriest": {"name":"中级法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "evilPrincess": {"name":"痛苦魔女","hp":1000,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[10],"mdef":0,"spell":0,"speed":1}, "blademaster": {"name":"剑圣","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "evilFairy": {"name":"黑暗仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "greenKnight": {"name":"强盾骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "bowman": {"name":"初级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "watcherSlime": {"name":"邪眼怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "devilKnight": {"name":"恶灵骑士","hp":150,"atk":100,"def":50,"money":0,"exp":0,"point":0,"special":[1,5,7,8]}, - "grayPriest": {"name":"混沌法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "greenGateKeeper": {"name":"卫兵队长","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "ghostSoldier": {"name":"冥队长","hp":200,"atk":100,"def":50,"money":0,"exp":0,"point":0,"special":8}, - "frostBat": {"name":"寒蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "blackKing": {"name":"黑衣魔王","hp":1000,"atk":500,"def":0,"money":1000,"exp":1000,"point":0,"special":0,"notBomb":true}, - "yellowKing": {"name":"黄衣魔王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "greenKing": {"name":"青衣武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "redKing": {"name":"红衣魔王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "blueKing": {"name":"白衣武士","hp":100,"atk":120,"def":0,"money":17,"exp":0,"point":0,"special":[16]}, - "keiskeiFairy": {"name":"铃兰花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "tulipFairy": {"name":"郁金香花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "purpleBowman": {"name":"高级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0}, - "bearDown": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"bigImage":"bear.png"}, - "bearLeft": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}}, - "bearRight": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}}, - "bearUp": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"}} + "evilFairy": {"name":"黑暗仙子","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "greenKnight": {"name":"强盾骑士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "bowman": {"name":"初级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "watcherSlime": {"name":"邪眼怪","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "devilKnight": {"name":"恶灵骑士","hp":150,"atk":100,"def":50,"money":0,"exp":0,"point":0,"special":[1,5,7,8],"mdef":0,"spell":0,"speed":1}, + "grayPriest": {"name":"混沌法师","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "greenGateKeeper": {"name":"卫兵队长","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "ghostSoldier": {"name":"冥队长","hp":200,"atk":100,"def":50,"money":0,"exp":0,"point":0,"special":8,"mdef":0,"spell":0,"speed":1}, + "frostBat": {"name":"寒蝙蝠","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "blackKing": {"name":"黑衣魔王","hp":1000,"atk":500,"def":0,"money":1000,"exp":1000,"point":0,"special":0,"notBomb":true,"mdef":0,"spell":0,"speed":1}, + "yellowKing": {"name":"黄衣魔王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "greenKing": {"name":"青衣武士","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "redKing": {"name":"红衣魔王","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "blueKing": {"name":"白衣武士","hp":100,"atk":120,"def":0,"money":17,"exp":0,"point":0,"special":[16],"mdef":0,"spell":0,"speed":1}, + "keiskeiFairy": {"name":"铃兰花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "tulipFairy": {"name":"郁金香花妖","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "purpleBowman": {"name":"高级弓兵","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":0,"mdef":0,"spell":0,"speed":1}, + "bearDown": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"bigImage":"bear.png","mdef":0,"spell":0,"speed":1}, + "bearLeft": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"mdef":0,"spell":0,"speed":1}, + "bearRight": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"mdef":0,"spell":0,"speed":1}, + "bearUp": {"name":"熊出没","hp":0,"atk":0,"def":0,"money":0,"exp":0,"point":0,"special":[],"faceIds":{"down":"bearDown","left":"bearLeft","right":"bearRight","up":"bearUp"},"mdef":0,"spell":0,"speed":1} } \ No newline at end of file diff --git a/project/events.js b/project/events.js index 355629a..9f5e38e 100644 --- a/project/events.js +++ b/project/events.js @@ -1,4365 +1,9728 @@ -var events_c12a15a8_c380_4b28_8144_256cba95f760 = { - commonEvent: { - 加点事件: [ - { - type: "comment", - text: "通过传参,flag:arg1 表示当前应该的加点数值", - }, - { - type: "choices", - choices: [ - { - text: "攻击+${1*flag:arg1}", - action: [ - { - type: "setValue", - name: "status:atk", - operator: "+=", - value: "1*flag:arg1", - }, - ], - }, - { - text: "防御+${2*flag:arg1}", - action: [ - { - type: "setValue", - name: "status:def", - operator: "+=", - value: "2*flag:arg1", - }, - ], - }, - { - text: "生命+${200*flag:arg1}", - action: [ - { - type: "setValue", - name: "status:hp", - operator: "+=", - value: "200*flag:arg1", - }, - ], - }, - ], - }, - ], - 回收钥匙商店: [ - { - type: "comment", - text: "此事件在全局商店中被引用了(全局商店keyShop)", - }, - { - type: "comment", - text: "解除引用前勿删除此事件", - }, - { - type: "comment", - text: "玩家在快捷列表(V键)中可以使用本公共事件", - }, - { - type: "while", - condition: "1", - data: [ - { - type: "choices", - text: "\t[商人,trader]你有多余的钥匙想要出售吗?", - choices: [ - { - text: "黄钥匙(10金币)", - color: [255, 255, 0, 1], - action: [ - { - type: "if", - condition: "item:yellowKey >= 1", - true: [ - { - type: "setValue", - name: "item:yellowKey", - operator: "-=", - value: "1", - }, - { - type: "setValue", - name: "status:money", - operator: "+=", - value: "10", - }, - ], - false: ["\t[商人,trader]你没有黄钥匙!"], - }, - ], - }, - { - text: "蓝钥匙(50金币)", - color: [0, 0, 255, 1], - action: [ - { - type: "if", - condition: "item:blueKey >= 1", - true: [ - { - type: "setValue", - name: "item:blueKey", - operator: "-=", - value: "1", - }, - { - type: "setValue", - name: "status:money", - operator: "+=", - value: "50", - }, - ], - false: ["\t[商人,trader]你没有蓝钥匙!"], - }, - ], - }, - { - text: "离开", - action: [ - { - type: "exit", - }, - ], - }, - ], - }, - ], - }, - ], - chapter0: [ - { - type: "playBgm", - name: "Crawler.mp3", - keep: true, - }, - { - type: "setText", - time: 50, - }, - { - type: "changebg", - img1: "", - memory1: false, - img2: "", - memory2: false, - time: 30, - style: "引入", - }, - { - type: "over", - text: "人生不如意事,十常居七八。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "世间的万物皆被装缀着不公的色彩。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "没错,就像——", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "十几年前的那一天,", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "在都市的角落,同许多的生命共同消逝一般。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "没错,就像——", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "十几年前的那天起以来,", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "无数的生命被那无法逃脱的污泥囚禁一样。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "人生不如意事,十常居七八。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "世间的万物皆被装缀着不公的色彩。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "没错,就像——", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "over", - text: "如今,这一天。", - image: "", - memory: false, - time: 50, - hidetime: 30, - sound: "", - textColor: [255, 255, 255, 1], - boldColor: [0, 0, 0, 1], - font: "bold 48px Verdana", - }, - { - type: "changebg", - img1: "", - memory1: false, - img2: "other_0001.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0001.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "这些天,街道不曾下雨。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0001.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "所以,那浸湿地面的,定是那些女孩们流落的鲜血无疑。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0001.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我蹲在充斥着铁锈味般恶臭的小巷中,悠闲地如是想着。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0001.webp", - memory1: false, - img2: "bg_3563.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "扑哧。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "耳旁再次响起象征着某个女孩子死去的声音。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "再一次——", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "再一次。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "女子们被肢解成单纯的肉块。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我任由流下的血浸满全身,屏住自己的呼吸。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "祈求自己能拥有从猎人手中逃脱的幸运。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3563.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "扑哧。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3563.webp", - memory1: false, - img2: "other_0002.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "直到刚才,我们还坐在去往娼馆的马车的路上。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "而在这之中的某些人,已经不在这个世上了。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "不,应该把“某些”换成“几乎所有”才更为恰当吧。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "恐怕,不久之后我也会变成小巷中血腥的装饰品。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我是为了得到这种死法,才辛苦苟活至今的吗?", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "来个人告诉我啊——", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "谁都好。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0002.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "来人啊!!", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0002.webp", - memory1: false, - img2: "other_0001.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0001.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "少女", - time: 30, - wait: 1000, - sound: "aiy010000010.mp3", - text: "「呃······!?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0001.webp", - memory1: false, - img2: "other_0003.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0003.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "漆黑的物体充斥了我的整个视野", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0003.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我很快意识到,那是只很大的脚。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0003.webp", - memory1: false, - img2: "", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "必须要出声求救。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "", - memory1: false, - img2: "other_0003.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0003.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "可是,耳中却只能听到自己的牙关不停交战的声音。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0003.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 50, - wait: 1000, - sound: "", - text: "我是如此的无助。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0003.webp", - memory1: false, - img2: "", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "逃跑也好,道歉也罢。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "就连抬头看一眼将要杀掉我的人的面孔都做不到。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "少女", - time: 30, - wait: 2000, - sound: "aiy010000020.mp3", - text: "「······被杀」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "会被杀。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "会被杀!!", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "来自内心深处的冰冷预感,渐渐地在体内蔓延开来。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "少女", - time: 30, - wait: 1000, - sound: "aiy010000030.mp3", - text: "「不,不要······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "playBgm", - name: "Blind_Alley.mp3", - keep: true, - }, - { - type: "changebg", - img1: "", - memory1: false, - img2: "bg_6004.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "浮游都市,《诺瓦斯·艾蒂尔》。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "《特别受灾地区》——", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "通称,《牢狱》", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "是被险峻的峭壁环绕,与世隔绝的,都市的最底部。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000010.mp3", - text: "「放开我!」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_6004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000020.mp3", - text: "「我只是在帮那个女人而已!」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_6004.webp", - memory1: false, - img2: "other_0004.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "other_0004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000030.mp3", - text: "「你们没听到吗!?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000040.mp3", - text: "「她是被受骗才会被卖到娼馆来的」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "other_0004.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000050.mp3", - text: "「用肮脏的手段把钱借给她父母的,就是你们这些家伙吧!?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "other_0004.webp", - memory1: false, - img2: "bg_3601.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000060.mp3", - text: "「给我说些什么啊」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000010.mp3", - text: "「这些话等到了娼馆再说吧」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000020.mp3", - text: "「我来抓你,只是受雇于人而已」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3601.webp", - memory1: false, - img2: "bg_3531.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我走进娼馆《莉莉乌姆》的接待室。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "正在桌旁整理账簿的奥兹停下手头的工作,抬起头向我看来。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000010.mp3", - text: "「这不是凯伊姆先生吗,辛苦了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000020.mp3", - text: "「委托已经完成了吗?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000030.mp3", - text: "「啊啊,是这家伙没错吧」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹用只要接触到就能杀人般的眼神在男人脸上搜过。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000030.mp3", - text: "「没错,就是这个人」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000040.mp3", - text: "「是么」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000070.mp3", - text: "「你,你们要对我做什么」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000040.mp3", - text: "「······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹用一个眼神,就让男人闭上了嘴。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "然后,向我这边转过身来。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000050.mp3", - text: "「抱歉啊,总是麻烦你去做这些无聊的事」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000060.mp3", - text: "「都怪我们这边的年轻人太没用」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000050.mp3", - text: "「客套话就免了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000070.mp3", - text: "「这还真是失礼了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000080.mp3", - text: "「喂,来个人」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "光头男人", - time: 30, - wait: 1000, - sound: "aiy820000010.mp3", - text: "「是」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000090.mp3", - text: "「凯伊姆先生做完工作回来了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "光头男人", - time: 30, - wait: 1000, - sound: "aiy820000020.mp3", - text: "「是,是,那个······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000100.mp3", - text: "「我是要你拿些酒来,这个蠢材!」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "喀!", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹扔出的烟灰缸砸中了手下的额头。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "鲜血四溅。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000060.mp3", - text: "「不用这么麻烦」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000070.mp3", - text: "「我接下来要去《菲诺列塔》」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000110.mp3", - text: "「喔唷」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000120.mp3", - text: "「既然如此,我就不留您在这里喝难饮的劣质酒了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹斜眼看着正捂住额头呻吟的手下,轻描淡写地说道。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000080.mp3", - text: "「用这些钱去买药」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我将几枚铜钱仍在那个手下的身前。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000130.mp3", - text: "「凯伊姆先生,不用对他们这么好」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000090.mp3", - text: "「无妨」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000100.mp3", - text: "「话说回来,那个要落跑的女人呢?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000140.mp3", - text: "「我把她交给那些年轻人了,现在应该正在体会人生的严苛吧」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000150.mp3", - text: "「正好,趁此机会凯伊姆先生也来享受一番如何?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000080.mp3", - text: "「你,你们这些家伙,要对她做什么!?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "咣!", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹给了他一拳。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "一击即倒。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "喀,咚,咯!", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹毫不留情地向男人的脸上踩去。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000090.mp3", - text: "「咕······呃咳······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "折断的牙齿伴着血泡被吐出。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "这份白色在鲜红色的液体中格外显眼。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000100.mp3", - text: "「你们以为做出这种事······卫兵会坐视不理吗······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000160.mp3", - text: "「啊啊,不会坐视不理的」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000170.mp3", - text: "「应该会拿出你的钱包,和我们商量如何瓜分吧」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000110.mp3", - text: "「那,那种事······」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "这在牢狱是理所当然的事。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 2000, - sound: "aiy350000180.mp3", - text: "「怎么,头一回来牢狱么?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "男人点了点头。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000190.mp3", - text: "「为了被骗的女人而来到牢狱,真是个规矩人啊」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000200.mp3", - text: "「······前提是,被骗的人不是你」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000120.mp3", - text: "「你说······我被骗了?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "年轻人", - time: 30, - wait: 1000, - sound: "aiy710000130.mp3", - text: "「那,那是怎么回事!?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000210.mp3", - text: "「不用急,今天晚上会好好告诉你的」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "奥兹抓起男人的脸。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "为引诱客人的怜悯之心而装纯,是娼妇的惯用手段。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "双亲被骗而借钱,结果作为抵押而将自己卖到这里,这是典型的说法。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "如果只是头脑发热而成为常客也就罢了,这次的男人热血过头,居然想出了要带女人私奔的计划。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "虽然女人半开玩笑地予以拒绝,但不知天高地厚的这家伙还是拉着她逃跑了。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "不过,想要逃脱追击本来就是不可能的任务。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "但即便如此,这种事情还是会一再的出现。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "说谎的女人和被骗的男人。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "在娼馆街,这是令人看到生厌的日常的风景。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000110.mp3", - text: "「我要走了」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000220.mp3", - text: "「好的,下次再麻烦您」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "奥兹", - time: 30, - wait: 1000, - sound: "aiy350000230.mp3", - text: "「之后吉克先生会将谢礼交给您的」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "aiy310000120.mp3", - text: "「啊啊」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "我背向奥兹走出娼馆。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「······?」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3531.webp", - memory1: false, - img2: "bg_3601.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "从远方传来微弱的歌声。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "是关卡广场的方向。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "对了。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "今天有觐见圣女的仪式。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "当代的圣女伊莲——", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "俗称《盲眼之圣女》,据说即使在历代的圣女中,人气也是数一数二的。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "广场上的人估计相当多吧。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "虽然我也想去看看她长什么样,不过要在人潮中挤来挤去就免了。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "还是老老实实去菲诺列塔喝烧酒吧。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "正当我这样想着的时候,一个身影自小巷的那头走来。", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3601.webp", - memory1: false, - img2: "bg_3531.webp", - memory2: false, - time: 30, - style: "场景切换", - }, - { - type: "cgtext", - bg: "bg_3531.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「艾莉斯」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3531.webp", - memory1: false, - img2: "", - memory2: false, - time: 30, - style: "引出", - }, - { - type: "comment", - text: "好多立绘,先更这点(吐槽一下)", - }, - ], - chapter01: [ - { - type: "changebg", - img1: "", - memory1: false, - img2: "bg_3601.webp", - memory2: false, - time: 30, - style: "引入", - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020106.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「啊,凯伊姆」", - bodyList: [ - { - name: "", - px: 100, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020141.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「正好,我还想要去找你呢」", - bodyList: [ - { - name: "tati_020141.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020157.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「没想到凯伊姆会主动出现······这是命运吗?」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「显然不是吧」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020107.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「啊,是么」", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "艾莉斯挑了挑整齐的双眉,微微地哼了一声。", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "虽然是个相当引人注目的美人,但她这个将亲切儿子丢入无底深渊的性格,为自己扣了不少的分", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "给人印象最深的,就是那潭水般的双瞳。", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "", - time: 30, - wait: 1000, - sound: "", - text: "在漆黑的瞳孔中,完全看不出感情的波动。", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020157.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「喜欢我的眼睛吗?」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020157.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「如果想要的话就给你吧?」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「用不着」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020111.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「阿拉,可惜」", - bodyList: [ - { - name: "tati_020111.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「那么,找我有什么事」", - bodyList: [ - { - name: "tati_020111.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020101.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「梅尔特的钱好像被偷了」", - bodyList: [ - { - name: "tati_020101.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「钱被偷了?都几岁了还这么没用」", - bodyList: [ - { - name: "tati_020101.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020107.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「不要对我说啊」", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「那家伙,该不会说要让我去抓那个小偷吧?」", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020157.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「就是这样」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「笨蛋吗」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「如果是小钱的话,就当做是买个教训吧」", - bodyList: [ - { - name: "tati_020157.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020125.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「说起来,被盗的是这个月的上纳金」", - bodyList: [ - { - name: "tati_020125.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「你说什么?」", - bodyList: [ - { - name: "tati_020125.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020121.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「用这些钱买教训,也太过奢侈了呢」", - bodyList: [ - { - name: "tati_020121.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「知道了,我去找」", - bodyList: [ - { - name: "tati_020121.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「小偷的特征呢」", - bodyList: [ - { - name: "tati_020121.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020105.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「男孩子」", - bodyList: [ - { - name: "tati_020105.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020103.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「······而且,背后有翅膀」", - bodyList: [ - { - name: "tati_020103.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020141.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「虽然姑且是藏在身后,但是仔细观察的话是很明显的」", - bodyList: [ - { - name: "tati_020141.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「羽化病吗」", - bodyList: [ - { - name: "tati_020141.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020105.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「那些人可是毫不留情的,所以即使是为了那个孩子,也要赶快抓到他」", - bodyList: [ - { - name: "tati_020105.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「注意到他逃窜的方向了吗?」", - bodyList: [ - { - name: "tati_020105.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020105.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「广场那边」", - bodyList: [ - { - name: "tati_020105.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020107.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「虽然刚才《不蚀金锁》的人去追了,不过多半是······」", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「偏偏还是广场吗」", - bodyList: [ - { - name: "tati_020107.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "face_020141.webp", - px: -300, - }, - name: "艾莉斯", - time: 30, - wait: 1000, - sound: "", - text: "「今天是觐见圣女大人的日子」", - bodyList: [ - { - name: "tati_020145.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「我知道」", - bodyList: [ - { - name: "tati_020145.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "cgtext", - bg: "bg_3601.webp", - memory: false, - WindowSkin: false, - head: { - name: "", - px: -300, - }, - name: "凯伊姆", - time: 30, - wait: 1000, - sound: "", - text: "「尽量找找看就好」", - bodyList: [ - { - name: "tati_020145.webp", - px: 600, - filter: false, - }, - ], - }, - { - type: "changebg", - img1: "bg_3601.webp", - memory1: false, - img2: "", - memory2: false, - time: 30, - style: "引出", - }, - ], - chapter02: null, - chapter03: null, - chapter04: null, - chapter05: null, - 强制横屏: [ - { - type: "if", - condition: "((!main.replayChecking )&&(!core.isReplaying()))", - true: [ - { - type: "if", - condition: - '((screen.orientation || {}).type ||\n screen.mozOrientation ||\n screen.msOrientation!=="landscape-primary")', - true: [ - { - type: "if", - condition: "(!core.platform.isPC)", - true: [ - { - type: "confirm", - default: true, - text: "手机用户横屏体验更佳,是否切换", - yes: [ - { - type: "function", - function: - "function(){\ncore.triggerFullscreen(true)\n}", - }, - ], - no: [], - }, - ], - }, - ], - }, - ], - }, - ], - }, - CommonEventTemplate: { - 检测音乐如果没有开启则系统提示开启: [ - { - type: "if", - condition: "!core.musicStatus.bgmStatus", - true: ["\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳"], - false: [], - }, - ], - 仿新新魔塔一次性商人: [ - { - type: "if", - condition: "switch:A", - true: [ - "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", - { - type: "comment", - text: "下一条指令可视情况使用或不使用", - }, - { - type: "hide", - remove: true, - time: 250, - loc: [[]], - }, - ], - false: [ - { - type: "confirm", - text: "我有3把黄钥匙,\n你出50金币就卖给你。", - yes: [ - { - type: "if", - condition: "status:money>=50", - true: [ - { - type: "setValue", - name: "status:money", - operator: "-=", - value: "50", - }, - { - type: "setValue", - name: "item:yellowKey", - operator: "+=", - value: "3", - }, - { - type: "playSound", - name: "确定", - stop: true, - }, - { - type: "setValue", - name: "switch:A", - value: "true", - }, - ], - false: [ - { - type: "playSound", - name: "操作失败", - }, - "\t[行商,trader]\b[this]你的金币不足!", - ], - }, - ], - no: [], - }, - ], - }, - ], - 全地图选中一个点: [ - { - type: "comment", - text: "全地图选中一个点,需要用鼠标或触屏操作", - }, - { - type: "setValue", - name: "temp:X", - value: "status:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "status:y", - }, - { - type: "tip", - text: "再次点击闪烁位置确认", - }, - { - type: "while", - condition: "true", - data: [ - { - type: "drawSelector", - image: "winskin.webp", - code: 1, - x: "32*temp:X", - y: "32*temp:Y", - width: 32, - height: 32, - }, - { - type: "wait", - }, - { - type: "if", - condition: "(flag:type === 1)", - true: [ - { - type: "if", - condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", - true: [ - { - type: "break", - n: 1, - }, - ], - }, - { - type: "setValue", - name: "temp:X", - value: "flag:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "flag:y", - }, - ], - }, - ], - }, - { - type: "drawSelector", - code: 1, - }, - { - type: "comment", - text: "流程进行到这里可以对[X,Y]点进行处理,比如", - }, - { - type: "closeDoor", - id: "yellowDoor", - loc: ["temp:X", "temp:Y"], - }, - ], - 多阶段Boss战斗: [ - { - type: "comment", - text: "多阶段boss,请直接作为战后事件使用", - }, - { - type: "setValue", - name: "switch:A", - operator: "+=", - value: "1", - }, - { - type: "switch", - condition: "switch:A", - caseList: [ - { - case: "1", - action: [ - { - type: "setBlock", - number: "redSlime", - loc: [[]], - }, - "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", - ], - }, - { - case: "2", - action: [ - { - type: "setBlock", - number: "blackSlime", - loc: [[]], - }, - "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", - ], - }, - { - case: "3", - action: [ - { - type: "setBlock", - number: "slimelord", - loc: [[]], - }, - "\t[4阶段boss,slimelord]\b[this]我还能打!", - ], - }, - { - case: "4", - action: ["\t[4阶段boss,slimelord]我一定会回来的!"], - }, - ], - }, - ], - 光标修改: [ - { - type: "changeMouse", - icon: "sword0", - div: "gameGroup", - translate: [0, 0], - scale: [1, 1], - angle: 0, - px: 0, - py: 0, - }, - { - type: "removeMouse", - div: "gameGroup", - }, - ], - 添加弹幕: [ - { - type: "addPop", - value: "这段话将在游戏中以弹幕显示", - px: 32, - py: 32, - color: [255, 0, 0, 1], - boldColor: [0, 0, 0, 1], - left: false, - jump: false, - time: 60, - show: 30, - font: "16px Verdana", - speed: 1, - }, - ], - }, -}; +var events_c12a15a8_c380_4b28_8144_256cba95f760 = +{ + "commonEvent": { + "加点事件": [ + { + "type": "comment", + "text": "通过传参,flag:arg1 表示当前应该的加点数值" + }, + { + "type": "choices", + "choices": [ + { + "text": "攻击+${1*flag:arg1}", + "action": [ + { + "type": "setValue", + "name": "status:atk", + "operator": "+=", + "value": "1*flag:arg1" + } + ] + }, + { + "text": "防御+${2*flag:arg1}", + "action": [ + { + "type": "setValue", + "name": "status:def", + "operator": "+=", + "value": "2*flag:arg1" + } + ] + }, + { + "text": "生命+${200*flag:arg1}", + "action": [ + { + "type": "setValue", + "name": "status:hp", + "operator": "+=", + "value": "200*flag:arg1" + } + ] + } + ] + } + ], + "回收钥匙商店": [ + { + "type": "comment", + "text": "此事件在全局商店中被引用了(全局商店keyShop)" + }, + { + "type": "comment", + "text": "解除引用前勿删除此事件" + }, + { + "type": "comment", + "text": "玩家在快捷列表(V键)中可以使用本公共事件" + }, + { + "type": "while", + "condition": "1", + "data": [ + { + "type": "choices", + "text": "\t[商人,trader]你有多余的钥匙想要出售吗?", + "choices": [ + { + "text": "黄钥匙(10金币)", + "color": [ + 255, + 255, + 0, + 1 + ], + "action": [ + { + "type": "if", + "condition": "item:yellowKey >= 1", + "true": [ + { + "type": "setValue", + "name": "item:yellowKey", + "operator": "-=", + "value": "1" + }, + { + "type": "setValue", + "name": "status:money", + "operator": "+=", + "value": "10" + } + ], + "false": [ + "\t[商人,trader]你没有黄钥匙!" + ] + } + ] + }, + { + "text": "蓝钥匙(50金币)", + "color": [ + 0, + 0, + 255, + 1 + ], + "action": [ + { + "type": "if", + "condition": "item:blueKey >= 1", + "true": [ + { + "type": "setValue", + "name": "item:blueKey", + "operator": "-=", + "value": "1" + }, + { + "type": "setValue", + "name": "status:money", + "operator": "+=", + "value": "50" + } + ], + "false": [ + "\t[商人,trader]你没有蓝钥匙!" + ] + } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] + } + ], + "chapter0": [ + { + "type": "playBgm", + "name": "Crawler.opus", + "keep": true + }, + { + "type": "setText", + "time": 50 + }, + { + "type": "confirm", + "text": "跳过傻逼不能点点点快进的旁白", + "yes": [], + "no": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "over", + "text": "人生不如意事,十常居七八。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "世间的万物皆被装缀着不公的色彩。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "没错,就像——", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "十几年前的那一天,", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "在都市的角落,同许多的生命共同消逝一般。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "没错,就像——", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "十几年前的那天起以来,", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "无数的生命被那无法逃脱的污泥囚禁一样。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "人生不如意事,十常居七八。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "世间的万物皆被装缀着不公的色彩。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "没错,就像——", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + }, + { + "type": "over", + "text": "如今,这一天。", + "image": "", + "memory": false, + "time": 50, + "hidetime": 30, + "sound": "", + "textColor": [ + 255, + 255, + 255, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "font": "bold 48px Verdana" + } + ] + }, + { + "type": "confirm", + "text": "我他妈要全跳了", + "yes": [], + "no": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "other_0001.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "playBgm", + "name": "Blood_Stain.opus", + "keep": true + }, + { + "type": "cgtextList", + "textList": "chapter000" + }, + { + "type": "cgtext", + "bg": "other_0001.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0001.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "1", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0001.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "2", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "other_0001.webp", + "memory1": false, + "img2": "bg_3563.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "4", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "5", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "7", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "8", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "9", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3563.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "10", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3563.webp", + "memory1": false, + "img2": "other_0002.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "11", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "12", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "13", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "14", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "15", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "16", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "17", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0002.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "18", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "other_0002.webp", + "memory1": false, + "img2": "other_0001.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "other_0001.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "19", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "other_0001.webp", + "memory1": false, + "img2": "other_0003.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "other_0003.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "20", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0003.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "21", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "other_0003.webp", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "22", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "other_0003.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "other_0003.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "23", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "other_0003.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "24", + "time": 50, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "other_0003.webp", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "25", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "26", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "27", + "time": 30, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "28", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "29", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "30", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "31", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + } + ] + }, + { + "type": "playBgm", + "name": "Blind_Alley.opus", + "keep": true + } + ], + "chapter01": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3601.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "cgtextList", + "textList": "chapter01" + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020106.webp", + "px": -300 + }, + "index": "0", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "playBgm", + "name": "Halbmond.opus" + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020141.webp", + "px": -300 + }, + "index": "1", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020141.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020157.webp", + "px": -300 + }, + "index": "2", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020107.webp", + "px": -300 + }, + "index": "4", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "5", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "7", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "8", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020157.webp", + "px": -300 + }, + "index": "9", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020157.webp", + "px": -300 + }, + "index": "10", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "11", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020111.webp", + "px": -300 + }, + "index": "12", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020111.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "13", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020111.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020101.webp", + "px": -300 + }, + "index": "14", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "15", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020107.webp", + "px": -300 + }, + "index": "16", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "17", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020157.webp", + "px": -300 + }, + "index": "18", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "19", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "20", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020157.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020125.webp", + "px": -300 + }, + "index": "21", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020125.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "22", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020125.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020121.webp", + "px": -300 + }, + "index": "23", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020121.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "24", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020121.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "25", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020121.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020105.webp", + "px": -300 + }, + "index": "26", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020103.webp", + "px": -300 + }, + "index": "27", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020103.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020141.webp", + "px": -300 + }, + "index": "28", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020141.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "29", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020141.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020105.webp", + "px": -300 + }, + "index": "30", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "31", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020105.webp", + "px": -300 + }, + "index": "32", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020107.webp", + "px": -300 + }, + "index": "33", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "34", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_020141.webp", + "px": -300 + }, + "index": "35", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020145.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "36", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020145.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3601.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "37", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_020145.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3601.webp", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "引出" + } + ], + "chapter02": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3561.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "cgtextList", + "textList": "chapter02" + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "1", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "2", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "4", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "5", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "7", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "8", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3561.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "9", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3561.webp", + "memory1": false, + "img2": "bg_3021.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "10", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "11", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "12", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "13", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "14", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "15", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "16", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3021.webp", + "memory1": false, + "img2": "bg_0000.png", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_0000.png", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "17", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_0000.png", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "18", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_0000.png", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "19", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_0000.png", + "memory1": false, + "img2": "bg_3021.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "comment", + "text": "这个神官草莓说是特效不是立绘,标记!" + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "20", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_440101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "21", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_440101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "22", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "tati_440101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "23", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440101.webp", + "px": -300 + }, + "index": "24", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440105.webp", + "px": -300 + }, + "index": "25", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440101.webp", + "px": -300 + }, + "index": "26", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440110.webp", + "px": -300 + }, + "index": "27", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440101.webp", + "px": -300 + }, + "index": "28", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440102.webp", + "px": -300 + }, + "index": "29", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "这里是音效,打个标签" + }, + { + "type": "changebg", + "img1": "bg_3021.webp", + "memory1": false, + "img2": "bg_3026.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "comment", + "text": "这里有一堆描述不知道加不加..." + }, + { + "type": "changebg", + "img1": "bg_3026.webp", + "memory1": false, + "img2": "eve_030101.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030102.webp", + "px": -300 + }, + "index": "30", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030101.webp", + "px": -300 + }, + "index": "31", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "这里是人声音效,打个标签" + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "32", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "33", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "34", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "35", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "36", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "37", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "38", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "39", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "40", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "41", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "这里是人声音效,打个标签" + }, + { + "type": "cgtext", + "bg": "eve_030101.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "42", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "eve_030101.webp", + "memory1": false, + "img2": "bg_3021.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "43", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "44", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "45", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "46", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3021.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "47", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3021.webp", + "memory1": false, + "img2": "bg_3026.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030107.webp", + "px": -300 + }, + "index": "48", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_130104.webp", + "px": -300 + }, + "index": "49", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440103.webp", + "px": -300 + }, + "index": "50", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030145.webp", + "px": -300 + }, + "index": "51", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440107.webp", + "px": -300 + }, + "index": "52", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030145.webp", + "px": -300 + }, + "index": "53", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "54", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320105.webp", + "px": -300 + }, + "index": "55", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "56", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320102.webp", + "px": -300 + }, + "index": "57", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030124.webp", + "px": -300 + }, + "index": "58", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320107.webp", + "px": -300 + }, + "index": "59", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030125.webp", + "px": -300 + }, + "index": "60", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030141.webp", + "px": -300 + }, + "index": "61", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320102.webp", + "px": -300 + }, + "index": "62", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440102.webp", + "px": -300 + }, + "index": "63", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440109.webp", + "px": -300 + }, + "index": "64", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "65", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320108.webp", + "px": -300 + }, + "index": "66", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030145.webp", + "px": -300 + }, + "index": "67", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "68", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320102.webp", + "px": -300 + }, + "index": "69", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030101.webp", + "px": -300 + }, + "index": "70", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "71", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030105.webp", + "px": -300 + }, + "index": "72", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440106.webp", + "px": -300 + }, + "index": "73", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "74", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_440102.webp", + "px": -300 + }, + "index": "75", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_030125.webp", + "px": -300 + }, + "index": "76", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_130124.webp", + "px": -300 + }, + "index": "77", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320102.webp", + "px": -300 + }, + "index": "78", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3026.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_320101.webp", + "px": -300 + }, + "index": "79", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3026.webp", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "引出" + } + ], + "chapter03": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3801.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "cgtextList", + "textList": "chapter03" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "1", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "2", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "4", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "5", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "7", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "8", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "9", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "10", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "11", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "12", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "13", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "画面上下抖动一下,cy" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "14", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "15", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "16", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "17", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "18", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "画面上下抖动一下,cy" + }, + { + "type": "comment", + "text": "下面这个弹幕说翻译有误,是“就是我偷的,谁会给你这种人”,我也没看过日文原文不太晓得,先cy" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "19", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "20", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "21", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "22", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "23", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "24", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "25", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "26", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "27", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "28", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "29", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "30", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "31", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "32", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "33", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "34", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "35", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "36", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "37", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "38", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "39", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "40", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "41", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "42", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "43", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "44", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "45", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "46", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "47", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "48", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "画面上下抖动一下,cy" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "49", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "50", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "51", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "52", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "53", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "54", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "画面上下抖动一下,cy" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430103.webp", + "px": -300 + }, + "index": "55", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430103.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "56", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "57", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3801.webp", + "memory1": false, + "img2": "bg_0000.png", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "changebg", + "img1": "bg_0000.png", + "memory1": false, + "img2": "bg_3801.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430106.webp", + "px": -300 + }, + "index": "58", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "59", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430101.webp", + "px": -300 + }, + "index": "60", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "61", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "62", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "63", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "64", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "65", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "66", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "67", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "68", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "69", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "70", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "71", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "72", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "73", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "74", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "75", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "76", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430101.webp", + "px": -300 + }, + "index": "77", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430108.webp", + "px": -300 + }, + "index": "78", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430108.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "79", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430108.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "80", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430108.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "81", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "82", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "83", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "84", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "85", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "86", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "87", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "88", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "89", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430107.webp", + "px": -300 + }, + "index": "90", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "91", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "92", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "93", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "94", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "95", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430107.webp", + "px": -300 + }, + "index": "96", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430108.webp", + "px": -300 + }, + "index": "97", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430108.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "98", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430108.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "99", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "100", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "101", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "102", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430102.webp", + "px": -300 + }, + "index": "103", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "104", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "105", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "106", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "107", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "108", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "109", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "110", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "111", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "112", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050101.webp", + "px": -300 + }, + "index": "113", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "114", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_430105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "115", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "116", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "117", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "118", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "119", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "120", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "121", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430105.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430141.webp", + "px": -300 + }, + "index": "122", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050141.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430105.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430106.webp", + "px": -300 + }, + "index": "123", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050141.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050221.webp", + "px": -300 + }, + "index": "124", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050221.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050223.webp", + "px": -300 + }, + "index": "125", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050223.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430104.webp", + "px": -300 + }, + "index": "126", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050223.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430104.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050101.webp", + "px": -300 + }, + "index": "127", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050105.webp", + "px": -300 + }, + "index": "128", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050105.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050103.webp", + "px": -300 + }, + "index": "129", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050103.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430106.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_430105.webp", + "px": -300 + }, + "index": "130", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050103.webp", + "px": 200, + "filter": false + }, + { + "name": "tati_430105.webp", + "px": 1000, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050101.webp", + "px": -300 + }, + "index": "131", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "132", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050126.webp", + "px": -300 + }, + "index": "133", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050126.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "134", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050126.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050101.webp", + "px": -300 + }, + "index": "135", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050105.webp", + "px": -300 + }, + "index": "136", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "137", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "138", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050105.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_050143.webp", + "px": -300 + }, + "index": "139", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050143.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "140", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050143.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3801.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "141", + "time": 30, + "wait": 1000, + "sound": "", + "bodyList": [ + { + "name": "tati_050143.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "changebg", + "img1": "bg_3801.webp", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "引出" + } + ], + "chapter04": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3512.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "changebg", + "img1": "bg_3512.webp", + "memory1": false, + "img2": "bg_3522.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "changebg", + "img1": "bg_3522.webp", + "memory1": false, + "img2": "bg_3602.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "changebg", + "img1": "bg_3602.webp", + "memory1": false, + "img2": "bg_3551.webp", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtextList", + "textList": "chapter04" + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120122.webp", + "px": -300 + }, + "index": "0", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120101.webp", + "px": -300 + }, + "index": "1", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120107.webp", + "px": -300 + }, + "index": "2", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120112.webp", + "px": -300 + }, + "index": "4", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120112.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120102.webp", + "px": -300 + }, + "index": "5", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120107.webp", + "px": -300 + }, + "index": "7", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120111.webp", + "px": -300 + }, + "index": "8", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120111.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "9", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120111.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120127.webp", + "px": -300 + }, + "index": "10", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120127.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "11", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120127.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120112.webp", + "px": -300 + }, + "index": "12", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120112.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "13", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "14", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "15", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120112.webp", + "px": -300 + }, + "index": "16", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120112.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "17", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "18", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120121.webp", + "px": -300 + }, + "index": "19", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120121.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120102.webp", + "px": -300 + }, + "index": "20", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120111.webp", + "px": -300 + }, + "index": "21", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120111.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "22", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "23", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120106.webp", + "px": -300 + }, + "index": "24", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120106.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "25", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120106.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "26", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120113.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "comment", + "text": "弹个脑崩" + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120122.webp", + "px": -300 + }, + "index": "27", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120122.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120107.webp", + "px": -300 + }, + "index": "28", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "29", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120107.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120112.webp", + "px": -300 + }, + "index": "30", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_120112.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "31", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "32", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "33", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "34", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "35", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "36", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340102.webp", + "px": -300 + }, + "index": "37", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "38", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340102.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340101.webp", + "px": -300 + }, + "index": "39", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "40", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_340101.webp", + "px": 600, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "41", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "42", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340104.webp", + "px": -300 + }, + "index": "43", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340104.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340107.webp", + "px": -300 + }, + "index": "44", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "45", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340108.webp", + "px": -300 + }, + "index": "46", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340108.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340114.webp", + "px": -300 + }, + "index": "47", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340114.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "48", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340114.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340102.webp", + "px": -300 + }, + "index": "49", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "50", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340104.webp", + "px": -300 + }, + "index": "51", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340104.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340107.webp", + "px": -300 + }, + "index": "52", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120132.webp", + "px": -300 + }, + "index": "53", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340104.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120132.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120101.webp", + "px": -300 + }, + "index": "54", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120101.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120121.webp", + "px": -300 + }, + "index": "55", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120121.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "56", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "57", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340101.webp", + "px": -300 + }, + "index": "58", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "59", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120102.webp", + "px": -300 + }, + "index": "60", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120102.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "61", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120102.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340102.webp", + "px": -300 + }, + "index": "62", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340102.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120102.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340110.webp", + "px": -300 + }, + "index": "63", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340110.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120102.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "64", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340110.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120113.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120101.webp", + "px": -300 + }, + "index": "65", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120101.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "66", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120101.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120121.webp", + "px": -300 + }, + "index": "67", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120121.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120132.webp", + "px": -300 + }, + "index": "68", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120132.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340106.webp", + "px": -300 + }, + "index": "69", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340106.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120132.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340112.webp", + "px": -300 + }, + "index": "70", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340106.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "71", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340106.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340108.webp", + "px": -300 + }, + "index": "72", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340108.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340105.webp", + "px": -300 + }, + "index": "73", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340105.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120107.webp", + "px": -300 + }, + "index": "74", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340105.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120107.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340107.webp", + "px": -300 + }, + "index": "75", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120107.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "76", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120107.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340103.webp", + "px": -300 + }, + "index": "77", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340103.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120107.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340101.webp", + "px": -300 + }, + "index": "78", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340101.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120107.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120113.webp", + "px": -300 + }, + "index": "79", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340105.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120113.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_120112.webp", + "px": -300 + }, + "index": "80", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340105.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3551.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "face_340107.webp", + "px": -300 + }, + "index": "81", + "time": 0, + "wait": 2000, + "sound": "", + "bodyList": [ + { + "name": "tati_z340107.webp", + "px": -200, + "filter": false + }, + { + "name": "tati_120112.webp", + "px": 1200, + "filter": false + } + ] + } + ], + "chapter05": null, + "强制横屏": [ + { + "type": "if", + "condition": "((!main.replayChecking )&&(!core.isReplaying()))", + "true": [ + { + "type": "if", + "condition": "((screen.orientation || {}).type ||\n screen.mozOrientation ||\n screen.msOrientation!==\"landscape-primary\")", + "true": [ + { + "type": "if", + "condition": "(!core.platform.isPC)", + "true": [ + { + "type": "confirm", + "default": true, + "text": "手机用户横屏体验更佳,是否切换", + "yes": [ + { + "type": "function", + "function": "function(){\ncore.triggerFullscreen(true)\n}" + } + ], + "no": [] + } + ] + } + ] + } + ] + } + ], + "战斗动画特效注册": [ + { + "type": "setanimate", + "name": "sword", + "px": 48, + "py": 48, + "width": 192, + "height": 192, + "allFarme": 15, + "imageList": [ + { + "image": "jianji.webp", + "beforefarme": 0, + "globalAlpha": 100, + "cx": 192, + "cy": 2112, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 3, + "acx": 192, + "acy": 2112, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "jianji.webp", + "beforefarme": 4, + "globalAlpha": 100, + "cx": 384, + "cy": 2112, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 6, + "acx": 384, + "acy": 2112, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "jianji.webp", + "beforefarme": 7, + "globalAlpha": 100, + "cx": 576, + "cy": 2112, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 9, + "acx": 576, + "acy": 2112, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "jianji.webp", + "beforefarme": 10, + "globalAlpha": 100, + "cx": 768, + "cy": 2112, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 12, + "acx": 768, + "acy": 2112, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "jianji.webp", + "beforefarme": 13, + "globalAlpha": 100, + "cx": 0, + "cy": 2304, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 15, + "acx": 0, + "acy": 2304, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + } + ], + "soundList": [ + { + "sound": "", + "startfarme": 0, + "stopbefore": false + } + ] + }, + { + "type": "setanimate", + "name": "Fire01", + "px": 48, + "py": 48, + "width": 192, + "height": 192, + "allFarme": 15, + "imageList": [ + { + "image": "015-Fire01.webp", + "beforefarme": 0, + "globalAlpha": 100, + "cx": 192, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 3, + "acx": 192, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 4, + "globalAlpha": 100, + "cx": 384, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 6, + "acx": 384, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 7, + "globalAlpha": 100, + "cx": 576, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 9, + "acx": 576, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 10, + "globalAlpha": 100, + "cx": 768, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 12, + "acx": 768, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 13, + "globalAlpha": 100, + "cx": 960, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 15, + "acx": 960, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + } + ], + "soundList": [ + { + "sound": "", + "startfarme": 0, + "stopbefore": false + } + ] + }, + { + "type": "setanimate", + "name": "Fire02", + "px": 48, + "py": 48, + "width": 192, + "height": 192, + "allFarme": 15, + "imageList": [ + { + "image": "015-Fire01.webp", + "beforefarme": 0, + "globalAlpha": 100, + "cx": 192, + "cy": 192, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 3, + "acx": 192, + "acy": 192, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 4, + "globalAlpha": 100, + "cx": 384, + "cy": 192, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 6, + "acx": 384, + "acy": 192, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 7, + "globalAlpha": 100, + "cx": 576, + "cy": 192, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 9, + "acx": 576, + "acy": 192, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 10, + "globalAlpha": 100, + "cx": 768, + "cy": 192, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 12, + "acx": 768, + "acy": 192, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "015-Fire01.webp", + "beforefarme": 13, + "globalAlpha": 100, + "cx": 960, + "cy": 192, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 15, + "acx": 960, + "acy": 192, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + } + ], + "soundList": [ + { + "sound": "", + "startfarme": 0, + "stopbefore": false + } + ] + }, + { + "type": "setanimate", + "name": "005-Attack03", + "px": 48, + "py": 48, + "width": 192, + "height": 192, + "allFarme": 15, + "imageList": [ + { + "image": "005-Attack03.webp", + "beforefarme": 0, + "globalAlpha": 100, + "cx": 0, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 3, + "acx": 0, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "005-Attack03.webp", + "beforefarme": 4, + "globalAlpha": 100, + "cx": 192, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 6, + "acx": 192, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "005-Attack03.webp", + "beforefarme": 7, + "globalAlpha": 100, + "cx": 384, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 9, + "acx": 384, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "005-Attack03.webp", + "beforefarme": 10, + "globalAlpha": 100, + "cx": 576, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 12, + "acx": 576, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "005-Attack03.webp", + "beforefarme": 13, + "globalAlpha": 100, + "cx": 768, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 15, + "acx": 768, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + } + ], + "soundList": [ + { + "sound": "", + "startfarme": 0, + "stopbefore": false + } + ] + }, + { + "type": "setanimate", + "name": "012-Heal01", + "px": 48, + "py": 48, + "width": 192, + "height": 192, + "allFarme": 15, + "imageList": [ + { + "image": "012-Heal01.webp", + "beforefarme": 0, + "globalAlpha": 100, + "cx": 0, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 3, + "acx": 0, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "012-Heal01.webp", + "beforefarme": 4, + "globalAlpha": 100, + "cx": 192, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 6, + "acx": 192, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "012-Heal01.webp", + "beforefarme": 7, + "globalAlpha": 100, + "cx": 384, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 9, + "acx": 384, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "012-Heal01.webp", + "beforefarme": 10, + "globalAlpha": 100, + "cx": 576, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 12, + "acx": 576, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + }, + { + "image": "012-Heal01.webp", + "beforefarme": 13, + "globalAlpha": 100, + "cx": 768, + "cy": 0, + "cw": 192, + "ch": 192, + "x": 0, + "y": 0, + "w": 96, + "h": 96, + "afterfarme": 15, + "acx": 768, + "acy": 0, + "acw": 192, + "ach": 192, + "ax": 0, + "ay": 0, + "aw": 96, + "ah": 96 + } + ], + "soundList": [ + { + "sound": "", + "startfarme": 0, + "stopbefore": false + } + ] + } + ], + "chapter06": null, + "chapter07": null, + "chapter000001": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "", + "memory2": false, + "time": 30, + "style": "场景切换" + }, + { + "type": "cgtextList", + "textList": "chapter001" + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "1", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "2", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 30, + "wait": 1000, + "bodyList": [ + { + "name": "", + "px": 100, + "filter": false + } + ] + } + ], + "chapter00002": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3531.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "cgtextList", + "textList": "chapter002" + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + } + ] + }, + "CommonEventTemplate": { + "检测音乐如果没有开启则系统提示开启": [ + { + "type": "if", + "condition": "!core.musicStatus.bgmStatus", + "true": [ + "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳" + ], + "false": [] + } + ], + "仿新新魔塔一次性商人": [ + { + "type": "if", + "condition": "switch:A", + "true": [ + "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", + { + "type": "comment", + "text": "下一条指令可视情况使用或不使用" + }, + { + "type": "hide", + "remove": true, + "time": 250, + "loc": [ + [] + ] + } + ], + "false": [ + { + "type": "confirm", + "text": "我有3把黄钥匙,\n你出50金币就卖给你。", + "yes": [ + { + "type": "if", + "condition": "status:money>=50", + "true": [ + { + "type": "setValue", + "name": "status:money", + "operator": "-=", + "value": "50" + }, + { + "type": "setValue", + "name": "item:yellowKey", + "operator": "+=", + "value": "3" + }, + { + "type": "playSound", + "name": "确定", + "stop": true + }, + { + "type": "setValue", + "name": "switch:A", + "value": "true" + } + ], + "false": [ + { + "type": "playSound", + "name": "操作失败" + }, + "\t[行商,trader]\b[this]你的金币不足!" + ] + } + ], + "no": [] + } + ] + } + ], + "全地图选中一个点": [ + { + "type": "comment", + "text": "全地图选中一个点,需要用鼠标或触屏操作" + }, + { + "type": "setValue", + "name": "temp:X", + "value": "status:x" + }, + { + "type": "setValue", + "name": "temp:Y", + "value": "status:y" + }, + { + "type": "tip", + "text": "再次点击闪烁位置确认" + }, + { + "type": "while", + "condition": "true", + "data": [ + { + "type": "drawSelector", + "image": "winskin.webp", + "code": 1, + "x": "32*temp:X", + "y": "32*temp:Y", + "width": 32, + "height": 32 + }, + { + "type": "wait" + }, + { + "type": "if", + "condition": "(flag:type === 1)", + "true": [ + { + "type": "if", + "condition": "((temp:X===flag:x)&&(temp:Y===flag:y))", + "true": [ + { + "type": "break", + "n": 1 + } + ] + }, + { + "type": "setValue", + "name": "temp:X", + "value": "flag:x" + }, + { + "type": "setValue", + "name": "temp:Y", + "value": "flag:y" + } + ] + } + ] + }, + { + "type": "drawSelector", + "code": 1 + }, + { + "type": "comment", + "text": "流程进行到这里可以对[X,Y]点进行处理,比如" + }, + { + "type": "closeDoor", + "id": "yellowDoor", + "loc": [ + "temp:X", + "temp:Y" + ] + } + ], + "多阶段Boss战斗": [ + { + "type": "comment", + "text": "多阶段boss,请直接作为战后事件使用" + }, + { + "type": "setValue", + "name": "switch:A", + "operator": "+=", + "value": "1" + }, + { + "type": "switch", + "condition": "switch:A", + "caseList": [ + { + "case": "1", + "action": [ + { + "type": "setBlock", + "number": "redSlime", + "loc": [ + [] + ] + }, + "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?" + ] + }, + { + "case": "2", + "action": [ + { + "type": "setBlock", + "number": "blackSlime", + "loc": [ + [] + ] + }, + "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!" + ] + }, + { + "case": "3", + "action": [ + { + "type": "setBlock", + "number": "slimelord", + "loc": [ + [] + ] + }, + "\t[4阶段boss,slimelord]\b[this]我还能打!" + ] + }, + { + "case": "4", + "action": [ + "\t[4阶段boss,slimelord]我一定会回来的!" + ] + } + ] + } + ], + "光标修改": [ + { + "type": "changeMouse", + "icon": "sword0", + "div": "gameGroup", + "translate": [ + 0, + 0 + ], + "scale": [ + 1, + 1 + ], + "angle": 0, + "px": 0, + "py": 0 + }, + { + "type": "removeMouse", + "div": "gameGroup" + } + ], + "添加弹幕": [ + { + "type": "addPop", + "value": "这段话将在游戏中以弹幕显示", + "px": 32, + "py": 32, + "color": [ + 255, + 0, + 0, + 1 + ], + "boldColor": [ + 0, + 0, + 0, + 1 + ], + "left": false, + "jump": false, + "time": 60, + "show": 30, + "font": "16px Verdana", + "speed": 1 + } + ] + } +} \ No newline at end of file diff --git a/project/floors/KTV.js b/project/floors/KTV.js index eceffe1..4d25a2e 100644 --- a/project/floors/KTV.js +++ b/project/floors/KTV.js @@ -11,11 +11,208 @@ main.floors.KTV= "images": [], "ratio": 1, "defaultGround": "grass", - "firstArrive": [], + "firstArrive": [ + { + "type": "changebg", + "img1": "", + "memory1": false, + "img2": "bg_3531.webp", + "memory2": false, + "time": 30, + "style": "引入" + }, + { + "type": "cgtextList", + "textList": "chapter002" + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "0", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "1", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "2", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "3", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "4", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "5", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "6", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "cgtext", + "bg": "bg_3531.webp", + "memory": false, + "WindowSkin": false, + "head": { + "name": "", + "px": -300 + }, + "index": "7", + "time": 0, + "wait": 2000, + "bodyList": [ + { + "name": "", + "px": 0, + "filter": false + } + ] + }, + { + "type": "setHeroOpacity", + "opacity": 1 + }, + { + "type": "setCurtain", + "time": 1000 + } + ], "eachArrive": [], "parallelDo": "", "events": {}, - "changeFloor": {}, + "changeFloor": { + "12,10": { + "floorId": "changguan2", + "loc": [ + 2, + 1 + ] + }, + "10,1": { + "floorId": "KTVF2", + "loc": [ + 10, + 4 + ] + } + }, "beforeBattle": {}, "afterBattle": {}, "afterGetItem": {}, @@ -32,7 +229,7 @@ main.floors.KTV= [ 17,71797,71797,71797,71797,71797,71797,71797,71797,71797, 90, 17, 0], [ 17,90211,90211,90211,90211,71877,90211,90211, 0,90587, 0, 17, 0], [ 17,90541,90542,90543, 17,71761, 17, 17,71288,71116, 0, 17, 0], - [ 17, 0,30216, 0, 0, 0, 0, 0, 0,71257, 0, 17, 0], + [ 17, 0,30216, 0, 0,123, 0, 0, 0,71257, 0, 17, 0], [ 17, 0, 0, 0,71568,71754,20167, 0, 0,71265, 0, 17, 0], [ 17, 0, 0, 0,71887, 0, 0, 0,60160,71265, 0, 17, 0], [ 17,71340, 17, 17, 0, 0, 0, 17, 17,70568, 0,71796,71797], diff --git a/project/floors/KTVF2.js b/project/floors/KTVF2.js index 78260da..62626a0 100644 --- a/project/floors/KTVF2.js +++ b/project/floors/KTVF2.js @@ -15,7 +15,15 @@ main.floors.KTVF2= "eachArrive": [], "parallelDo": "", "events": {}, - "changeFloor": {}, + "changeFloor": { + "10,4": { + "floorId": "KTV", + "loc": [ + 10, + 1 + ] + } + }, "beforeBattle": {}, "afterBattle": {}, "afterGetItem": {}, diff --git a/project/floors/changguan1.js b/project/floors/changguan1.js new file mode 100644 index 0000000..d9960dd --- /dev/null +++ b/project/floors/changguan1.js @@ -0,0 +1,140 @@ +main.floors.changguan1= +{ + "floorId": "changguan1", + "title": "主塔 10 层", + "name": "10", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "autoText", + "text": "通称——", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "changguan2", + "loc": [ + 0, + 0 + ] + } + ], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "6,0": { + "floorId": "guangchang", + "loc": [ + 6, + 12 + ] + }, + "5,12": { + "floorId": "changguan2", + "loc": [ + 5, + 0 + ] + }, + "6,12": { + "floorId": "changguan2", + "loc": [ + 6, + 0 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [210178,210178,210178,210178,210171, 0, 91, 0,210171,110272,110273,110274,110275], + [110241,110242,110243,110244,210187, 0, 0, 0,210187,110280,110281,110282,110283], + [110249,110250,110251,110252,210195, 0, 0, 0,210195,110288,110289,110290,110291], + [110257,110258,110259,200199, 0, 0, 0, 0, 0,110296,110297,110298,110299], + [110265,110266,110267,110268, 0, 0, 0, 0, 0,110304,110305,110306,110307], + [110273,110274,110275,110276, 0, 0, 0, 0, 0,110116,110313,110314,110315], + [110281,110282,110283,110284, 0, 0, 0, 0, 0,110132, 0, 0, 0], + [110289,110290,110291,110292, 0, 0, 0, 0, 0, 0,10254,10248, 94], + [110297,110298,110299,110300, 0, 0, 0, 0, 0,110116, 0, 0, 0], + [110305,110306,110307,110308, 0, 0, 0, 0, 0,110261,110262,110262,110263], + [110313,110314,110315,110316,110122,110122, 0,110122,110122,110269,110270,110270,110271], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,110277,110278,110278,110279], + [140,140186,120002,120003, 0, 93, 93, 0, 0,110285,110286,110286,110286] +], + "bgmap": [ + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078] +], + "fgmap": [ + [ 0, 0, 0,200175, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,200183, 0, 0, 0, 0,140086, 0, 0, 0, 0], + [ 0, 0, 0,200191, 0, 0, 0, 0,140094, 0, 0, 0, 0], + [ 0, 0, 0,110260, 0, 0, 0, 0,140102, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0,140110, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,110246,110246,110246,110246], + [140091,140092,140093, 0,110114,110114, 0,110114,110114, 0, 0, 0, 0], + [140099,140100,140101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140107,140108,140109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0,130046,130046,130046,130046,130046,210178, 0, 0,210178], + [210186,210186,210186,210186,130046,130046,130046,130046,130046, 0, 0, 0, 0], + [210194,210194,210194,210194,130054,130054,130054,130054,130054, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,110312, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/changguan2.js b/project/floors/changguan2.js new file mode 100644 index 0000000..05464ca --- /dev/null +++ b/project/floors/changguan2.js @@ -0,0 +1,148 @@ +main.floors.changguan2= +{ + "floorId": "changguan2", + "title": "街道", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X20003", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "autoText", + "text": "《牢狱》", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "KTV", + "loc": [ + 10, + 8 + ] + } + ], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "5,0": { + "floorId": "changguan1", + "loc": [ + 5, + 12 + ] + }, + "6,0": { + "floorId": "changguan1", + "loc": [ + 6, + 12 + ] + }, + "12,8": { + "floorId": "street01", + "loc": [ + 0, + 8 + ] + }, + "2,1": { + "floorId": "KTV", + "loc": [ + 12, + 10 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [140193,130178,120010,120011, 0, 91, 91, 0,140184,140,140,140,140186], + [140193,130178, 90, 0, 0, 0, 0, 0,140192,140,140,140,140194], + [140193,130178,40163,120019, 0, 0, 0, 0,140200,140195,140,140,140194], + [140193,143,143,120027, 0, 0, 0, 0,70128,140192,140,140,140194], + [140193,210148,143,143, 0, 0, 0,71826,70136,140192,140,140,140194], + [140193,143,143,143,71226, 0, 0, 0,50151,140200,140201,140201,140202], + [70165,70165,70165,70166,71819, 0, 0, 0, 0,70128,70129,70129,70130], + [140193,210153,143,70174,71827, 0, 0, 0,71826,120056,70137,70137,70138], + [140193,210153,210156,143,71695, 0, 0, 0, 0, 0, 0, 0, 94], + [140193,143,143,143, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140193,140193,130178,70130, 0, 0, 0, 0, 0, 0, 0,140,140], + [140193,140193,130178,40165,200199,71791,71791,71791, 0, 0,140192,140,140], + [140193,140193,130186,110114,110114, 0,143,143,143, 0,140192,140,140] +], + "areas": "牢狱", + "bgmap": [ + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078], + [90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078,90078] +], + "fgmap": [ + [140,140194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140,140,140186, 0, 0, 0,71818, 0, 0, 0, 0, 0], + [140,140,140,140194,71218, 0, 0, 0,71818, 0, 0, 0, 0], + [140201,140201,140201,140202, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,71685, 0, 0, 0,71818, 0,90587, 0, 0], + [140,140,140,140186,71844, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140,140,140194,200175, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140,140196,140202,200183, 0, 0, 0, 0, 0, 0, 0, 0], + [140,140,140194, 0,200191, 0, 0, 0, 0,71818,140184,140,140], + [140,140,140194, 0, 0, 0, 0, 0,71832,71833,140192,140,140], + [140,140,140194, 0, 0,140184,140,140,140,140186,140192,140,140] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0,110293,110294,110294,110294,110294], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0,71826, 0, 0, 0, 0], + [ 0, 0, 0, 0,71693, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,70136, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,120064, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,70138, 0, 0, 0, 0, 0,71826, 0, 0, 0], + [ 0, 0, 0,40173, 0,71799,71799,71799,71840,71841, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchang.js b/project/floors/guangchang.js index 2adfdaa..d2eda6c 100644 --- a/project/floors/guangchang.js +++ b/project/floors/guangchang.js @@ -10,27 +10,276 @@ main.floors.guangchang= "canUseQuickShop": true, "images": [], "ratio": 1, - "defaultGround": "grass2", - "firstArrive": [], + "defaultGround": "X90078", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "setText", + "position": "center" + }, + { + "type": "move", + "loc": [ + 6, + 7 + ], + "time": 500, + "keep": true, + "async": true, + "steps": [ + "up:1", + "left:1", + "up:2" + ] + }, + { + "type": "sleep", + "time": 400 + }, + { + "type": "move", + "loc": [ + 8, + 8 + ], + "time": 500, + "keep": true, + "async": true, + "steps": [ + "up:1", + "left:2" + ] + }, + { + "type": "sleep", + "time": 500 + }, + { + "type": "move", + "loc": [ + 4, + 9 + ], + "time": 500, + "keep": true, + "steps": [ + "right:1" + ] + }, + { + "type": "waitAsync" + }, + { + "type": "autoText", + "text": "浮游都市,《诺瓦斯·艾蒂尔》。", + "time": 2000 + }, + { + "type": "move", + "loc": [ + 6, + 5 + ], + "time": 500, + "keep": true, + "async": true, + "steps": [ + "up:2" + ] + }, + { + "type": "move", + "loc": [ + 6, + 7 + ], + "time": 500, + "keep": true, + "steps": [ + "up:1" + ] + }, + { + "type": "waitAsync" + }, + { + "type": "sleep", + "time": 2000 + }, + { + "type": "move", + "loc": [ + 6, + 3 + ], + "time": 500, + "async": true, + "steps": [ + "down:9" + ] + }, + { + "type": "move", + "loc": [ + 5, + 4 + ], + "time": 500, + "keep": true, + "async": true, + "steps": [ + "up:1", + "right:1" + ] + }, + { + "type": "move", + "loc": [ + 6, + 6 + ], + "time": 300, + "keep": true, + "async": true, + "steps": [ + "right:2" + ] + }, + { + "type": "sleep", + "time": 1000 + }, + { + "type": "move", + "loc": [ + 8, + 6 + ], + "time": 500, + "keep": true, + "steps": [ + "left:1" + ] + }, + { + "type": "sleep", + "time": 2000 + }, + { + "type": "waitAsync" + }, + { + "type": "jump", + "from": [ + 7, + 6 + ], + "to": [ + 7, + 6 + ], + "time": 500, + "keep": true, + "async": true + }, + { + "type": "move", + "loc": [ + 6, + 3 + ], + "time": 500, + "async": true, + "steps": [ + "up:2" + ] + }, + { + "type": "move", + "loc": [ + 7, + 9 + ], + "time": 500, + "async": true, + "steps": [ + "up:1", + "right:3" + ] + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "waitAsync" + }, + { + "type": "setBlock", + "number": "0", + "loc": [ + [ + 5, + 9 + ], + [ + 7, + 6 + ], + [ + 4, + 4 + ], + [ + 6, + 3 + ] + ] + }, + { + "type": "changeFloor", + "floorId": "guangchang2", + "loc": [ + 0, + 0 + ] + } + ], "eachArrive": [], "parallelDo": "", "events": {}, "changeFloor": { - "12,6": { - "floorId": "street02", - "loc": [ - 0, - 6 - ], - "direction": "right" - }, "6,12": { - "floorId": "guangchang2", + "floorId": "changguan1", "loc": [ 6, 0 + ] + }, + "6,0": { + "floorId": "guangchang5", + "loc": [ + 6, + 12 + ] + }, + "12,8": { + "floorId": "guangchang2", + "loc": [ + 0, + 8 ], - "direction": "down" + "direction": "right" } }, "beforeBattle": {}, @@ -41,29 +290,65 @@ main.floors.guangchang= "cannotMove": {}, "cannotMoveIn": {}, "map": [ - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,140], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,140], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,141], - [ 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0,140,141] + [120007,120007,120007,120007,120020, 0, 91, 0, 0,130187,130188,130189,130190], + [120015,120015,120015,120015,120028, 0, 0, 0, 0,120144,120145,120146,120147], + [130172,130173,130174,130175, 0, 0, 0, 0,71320,120152,120153,120154,120155], + [130180,130181,130182,130183,200199, 0, 0,122,71328,120160,120161,120162,120163], + [130188,130189,130190,130191,121, 0, 0, 0,71336,120168,120169,120170,120171], + [130196,130197,130198,130199,140087, 0,121, 0, 0,120176,140020,140020,140020], + [130204, 0,130206,130207,140095, 0, 0, 0, 0, 0,140028,140028,140028], + [ 0, 0,130214,130215,140103, 0,121, 0, 0, 0, 0, 0, 0], + [ 0, 0,130214,120172,140111, 0, 0, 0,123, 0, 0, 0, 94], + [ 0, 0, 0,120180,121, 0, 0,121, 0,200199, 0, 0, 0], + [140107,140108,140109,362,363, 0, 0, 0,361,362,362,362,362], + [210186,210186,210186,210186,210179, 0, 0, 0,210179,210185,210186,210186,210186], + [210178,210178,210178,210178,210171, 0, 93, 0,210171,210177,210178,210178,210178] ], "areas": "牢狱", "bgmap": [ - + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30055,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30055,30052], + [30052,30052,30052,30052,30055,30052,30052,30063,30062,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30055,30052,30062,30052,30052,30052,30052,30052,30052,30052,30055,30052,30052], + [30052,30052,30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30062,30052], + [30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [120177,120178,120179,30052,30052,30055,30052,30052,30055,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30062,30052,30052,30052,30052,30055,30052], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], "fgmap": [ - + [ 0, 0, 0, 0,200175, 0, 0, 0, 0,130187,130188,130189,130190], + [ 0, 0, 0, 0,200183, 0, 0, 0,140086,130195,130196,130197,130198], + [ 0, 0, 0, 0,200191, 0, 0, 0,140094,130203,130204,130205,130206], + [ 0, 0, 0, 0, 0, 0, 0, 0,140102,130211,130212,130213,130214], + [ 0, 0, 0, 0, 0, 0, 0, 0,140110, 0,140091,140092,140093], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140099,140100,140101], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,200175,140107,140108,140109], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,200183, 0, 0, 0], + [140091,140092,140093, 0, 0, 0, 0, 0, 0,200191, 0, 0, 0], + [140099,140100,140101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [362,362,362, 0, 0, 0, 0, 0, 0, 0, 0,110242, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110249,110250,110251], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,110256,110257,110258,110259] ], "bg2map": [ - + [200195,200196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [90652,80106,90653, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [120145,120146,120147, 0, 0, 0, 0, 0, 0, 0,120177,120178,120179], + [120153,120154,120155,120156, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [120161,120162,120163,120164,90642, 0, 0, 0, 0, 0, 0, 0, 0], + [120169,120170,120171, 0,90642, 0, 0, 0, 0, 0, 0, 0, 0], + [130007,130007,130007, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [130015,130015,130015, 0, 0, 0, 0, 0,110239,110239,110239,110239,110239], + [ 0, 0, 0, 0,130046,130046,130046,130046,130046, 0, 0, 0, 0], + [ 0, 0, 0, 0,130046,130046,130046,130046,130046, 0, 0, 0, 0] ], "fg2map": [ diff --git a/project/floors/guangchang2.js b/project/floors/guangchang2.js index 3d1af2e..a466df6 100644 --- a/project/floors/guangchang2.js +++ b/project/floors/guangchang2.js @@ -10,19 +10,46 @@ main.floors.guangchang2= "canUseQuickShop": true, "images": [], "ratio": 1, - "defaultGround": "grass2", - "firstArrive": [], + "defaultGround": "X90078", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "sleep", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "guangchang5", + "loc": [ + 0, + 0 + ] + } + ], "eachArrive": [], "parallelDo": "", "events": {}, "changeFloor": { - "6,0": { + "0,8": { "floorId": "guangchang", "loc": [ - 6, - 12 - ], - "direction": "up" + 12, + 8 + ] }, "12,10": { "floorId": "xiaoxiang01", @@ -30,6 +57,13 @@ main.floors.guangchang2= 0, 10 ] + }, + "2,0": { + "floorId": "guangchang6", + "loc": [ + 2, + 12 + ] } }, "beforeBattle": {}, @@ -40,29 +74,65 @@ main.floors.guangchang2= "cannotMove": {}, "cannotMoveIn": {}, "map": [ - [ 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0,143,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130192,130193], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130200,143], + [ 0, 0, 91, 0,210192,210194,210194,210175,210194,210194,210194,210192,143], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,143], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130192], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130200], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110189], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110197] + [120156, 0, 0, 0,90664,90648,90648, 0,90644,90648,90649, 0,143], + [120164, 0, 0, 0,90665,140110,122, 0,90645,140110,122, 0,120120], + [120172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120136], + [120180, 0, 0, 0,90656,90648,90649, 0,90636,90649,90648, 0,120137], + [ 0, 0, 0, 0,90657,140110,122, 0,90638,140110,122, 0,120145], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120160], + [ 92, 0, 0, 0,110384,110385,110376, 0,90652,90648,90649, 0,120168], + [ 0, 0, 0, 0,110384, 0,122, 0,90653, 0,122, 0,120176], + [362,362,363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94], + [210181,210181,210181, 0, 0, 0, 0, 0, 0, 0, 0, 0,110189], + [210186,210186,210186,361,362,362,362,362,362,362,362,362,110197] ], "areas": "牢狱", "bgmap": [ - + [30052,30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30062,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052], + [30052,30055,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [210209,210209,210209,30052,30052,30052,30062,30052,30055,30052,30052,30052,30052], + [210209,210209,210209,30062,30052,30052,30052,30052,30052,30052,30052,30052,30052] ], "fgmap": [ - + [130191, 0, 0, 0, 0,140086,140087, 0, 0,140086,140087, 0, 0], + [130199,140087, 0, 0, 0,140094,140095, 0, 0,140094,140095, 0, 0], + [130207,140095, 0, 0, 0,140102,140103, 0, 0,140102,140103, 0, 0], + [130215,140103, 0, 0, 0,140086,140087, 0, 0,140086,140087, 0, 0], + [ 0,140111, 0, 0, 0,140094,140095, 0, 0,140094,140095, 0, 0], + [ 0, 0, 0, 0, 0,140102,140103, 0, 0,140102,140103, 0, 0], + [ 0, 0, 0, 0, 0,140086,140087, 0, 0,140086,140087, 0, 0], + [ 0, 0, 0, 0, 0,140094,140095, 0, 0,140094,140095, 0, 0], + [ 0, 0, 0, 0, 0,140102,140103, 0, 0,140102,140103, 0, 0], + [ 0, 0, 0, 0, 0,140110,140111, 0, 0,140110,140111, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,364, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], "bg2map": [ - + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130192], + [ 0, 0, 0, 0, 0,140110,140111, 0, 0,140110,140111, 0,130200], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,140110,140111, 0, 0,140110,140111, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [110239,110239,110239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,110239,110239,110239,110239,110239,110239,110239,110239,110239, 0] ], "fg2map": [ diff --git a/project/floors/guangchang2_1.js b/project/floors/guangchang2_1.js new file mode 100644 index 0000000..c460473 --- /dev/null +++ b/project/floors/guangchang2_1.js @@ -0,0 +1,98 @@ +main.floors.guangchang2_1= +{ + "floorId": "guangchang2_1", + "title": "广场", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "6,12": { + "floorId": "guangchang", + "loc": [ + 6, + 0 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [210094,210095,210144,210145,210145,210145,210145,210145,210145,210145,210146,210092,210093], + [210102,210103,210152,210153,210153,210153,210153,210153,210153,210153,210154,210100,210101], + [210110,210111,210160,210161,210161,210161,210161,210161,210161,210161,210162,210108,210109], + [210118,210119,210168,210169,210169,210169,210169,210169,210169,210169,210170,210116,210117], + [210126,210127,210181,210181,210176,210183,210181,210181,210176,210183,210181,210124,210125], + [362,363, 0,210178,210184,210177,210178,210178,210184,210177, 0,361,362], + [210181,210181,210181,210178,210184,210177,210178,210178,210184,210177,210181,210181,210181], + [210178,210178,210178,210178,210184,210185,210186,210186,210192,210177,210178,210178,210178], + [210194,210194,210194,210194,210192,210193,210150,210194,210192,210193,210194,210194,210194], + [201037,201037,201037,201029, 0, 0, 0, 0, 0,201029,201037,201037,201037], + [210070,210071,210002,201029, 0, 0, 0, 0, 0,201029,210002,210068,210069], + [210078,210079,210002,201029, 0, 0, 93, 0, 0,201029,210002,210076,210077] +], + "areas": "牢狱", + "bgmap": [ + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [180025,180025, 0, 0, 0, 0, 0, 0, 0, 0, 0,180025,180025], + [180025,180025, 0, 0, 0, 0, 0, 0, 0, 0, 0,180025,180025], + [180025,180025, 0, 0, 0, 0, 0, 0, 0, 0, 0,180025,180025], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [190000,190000,190000,190000,210209,210209,210209,210209,210209,190000,190000,190000,190000], + [190000,190000,190000,190000,210209,210209,210209,210209,210209,190000,190000,190000,190000], + [190000,190000,190000,190000,210209,210209,210209,210209,210209,190000,190000,190000,190000], + [190000,190000,190000,190000,210209,210209,210209,210209,210209,190000,190000,190000,190000] +], + "fgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,210134, 0, 0, 0,210134, 0, 0, 0, 0], + [ 0, 0, 0, 0,210142, 0, 0, 0,210142, 0, 0, 0, 0], + [ 0, 0,210142, 0,210150, 0,210130, 0,210150, 0,210142, 0, 0], + [ 0, 0,210150, 0, 0, 0,210138, 0, 0, 0,210150, 0, 0], + [ 0, 0, 0, 0, 0, 0,210142, 0, 0, 0, 0, 0, 0], + [201021,201021,201021,201021, 0, 0, 0, 0, 0,201021,201021,201021,201021], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,210206, 0,210194, 0,210207, 0, 0, 0, 0], + [ 0, 0, 0, 0,210208, 0, 0, 0,210210, 0, 0, 0, 0], + [210002,210002, 0, 0,210208, 0, 0, 0,210210, 0, 0,210002,210002], + [ 0, 0, 0, 0,210208, 0, 0, 0,210210, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchang2_2.js b/project/floors/guangchang2_2.js new file mode 100644 index 0000000..a70e8c9 --- /dev/null +++ b/project/floors/guangchang2_2.js @@ -0,0 +1,105 @@ +main.floors.guangchang2_2= +{ + "floorId": "guangchang2_2", + "title": "广场", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "7,0": { + "floorId": "guangchang3", + "loc": [ + 7, + 12 + ] + }, + "6,12": { + "floorId": "guangchang2", + "loc": [ + 6, + 0 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [ 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 0,120160], + [210094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120168], + [210102,210103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120176], + [210110,210111,110231,110231,110231, 0, 0, 0,110231,110231,110231,110231,110231], + [210118,365,362,362,363, 0, 0, 0,361,362,362,362,362], + [210126,365,210177,210178,210176, 0, 0, 0,210176,210177,210178,210178,210178], + [362,363,210070,210071,210184, 0, 0, 0,210184,210068,210069,210178,210178], + [210181,210184,210078,210079,210192, 0, 0, 0,210192,210076,210077,210194,210194], + [210178,210184,210086,210087, 0, 0, 0, 0, 0,210084,210085,110239,110239], + [210194,210192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [201037,201037,201029, 0, 0, 0, 0, 0, 0,130171,130172,130173,130174], + [210002,210002,201029, 0, 0, 0, 0, 0, 0,130179,130180,130181,130182], + [210002,210002,201029, 0, 0, 0, 93, 0, 0,130187,130188,130189,130190] +], + "areas": "牢狱", + "bgmap": [ + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [180025,180025,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [180025,180025,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [180025,180025,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [190000,190000,190000,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [190000,190000,190000,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [190000,190000,190000,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209], + [190000,190000,190000,210209,210209,210209,210209,210209,210209,210209,210209,210209,210209] +], + "fgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110231,110231], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [201021,201021,201021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120160], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120168], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,120176], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,210119,110239,110239,110239, 0, 0, 0,110239,110239,110239,110239,110239], + [ 0,210127, 0, 0, 0,130046,130046,130046, 0, 0, 0, 0, 0], + [ 0, 0,210177,210178, 0,130046,130046,130046, 0,210177,210178, 0, 0], + [ 0, 0,210193,210194, 0,130054,130054,130054, 0,210193,210194, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [210217,210217,210217,210206, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,210208, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,210208, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,210208, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchang3.js b/project/floors/guangchang3.js new file mode 100644 index 0000000..87956ae --- /dev/null +++ b/project/floors/guangchang3.js @@ -0,0 +1,132 @@ +main.floors.guangchang3= +{ + "floorId": "guangchang3", + "title": "主塔 10 层", + "name": "10", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "sleep", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "guangchang4", + "loc": [ + 0, + 0 + ] + } + ], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "0,9": { + "floorId": "guangchang4", + "loc": [ + 12, + 9 + ] + }, + "6,12": { + "floorId": "guangchang5", + "loc": [ + 6, + 0 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [210161,210161,210162,210185,210186,210186,210186,210186,210186,210186,210160,210161,210161], + [210169,210169,210170,210185,210186,210186,210186,210186,210186,210186,210168,210169,210169], + [210178,210178,210176,210193,210194,210194,210194,210194,210194,210194,210176,210177,210178], + [210178,210167,210184, 0, 0, 0, 0, 0, 0, 0,210184,210159,210178], + [210178,210178,210184, 0, 0, 0,132, 0, 0, 0,210184,210177,210178], + [210186,210186,210184,362,363, 0, 0, 0,361,362,210184,210185,210186], + [210194,210194,210192,210186,210186,130046,130046,130046,210186,210186,210184,210193,210194], + [71795,71814,210192,210194,210194,130054,130054,130054,210194,210194,210192,50165, 0], + [ 0, 0, 0,71663, 0, 0, 0, 0, 0,71421,10168,71784,71785], + [ 92, 0, 0, 0, 0, 0, 0, 0, 0, 0,10176, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 0, 0], + [210145,210145,210146, 0, 0, 0, 0, 0, 0, 0, 0,71799, 0], + [210153,210153,210154, 0, 0, 0, 93, 0, 0, 0,90648,90657,90850] +], + "bgmap": [ + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,210209,210209,210209,210209,210209,210209,210209,30052,30052,30052], + [30052,30052,30052,210209,210209,210209,210209,210209,210209,210209,30052,30052,30052], + [30052,30052,30052,210209,210209,210209,210209,210209,210209,210209,30052,30052,30052], + [30052,30052,30052,210209,210209,210209,210209,210209,210209,210209,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30062,30052,30052,30052,30052,30052,30052,30052,30052,30052,30055,30052], + [30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30062,30052,30052,30052,30062,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30055,30052,30052,30052], + [30052,30055,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30052] +], + "fgmap": [ + [ 0, 0, 0, 0,210142, 0, 0, 0,210142, 0, 0, 0, 0], + [ 0, 0, 0, 0,210150, 0, 0, 0,210150, 0, 0, 0, 0], + [ 0,210142, 0, 0, 0, 0, 0, 0, 0, 0, 0,210142, 0], + [210131,210150, 0, 0, 0, 0, 0, 0, 0, 0, 0,210150,210131], + [210139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210139], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [71787,71806, 0, 0, 0, 0, 0, 0, 0, 0, 0,50157, 0], + [ 0, 0, 0,71655, 0, 0, 0, 0, 0,71413, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140086], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,50151,71217,140094], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71791,140102], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140110], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0,210194, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0,90849, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71792,71793], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71225,71328], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71336], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchang4.js b/project/floors/guangchang4.js new file mode 100644 index 0000000..9b2c73b --- /dev/null +++ b/project/floors/guangchang4.js @@ -0,0 +1,138 @@ +main.floors.guangchang4= +{ + "floorId": "guangchang4", + "title": "主塔 10 层", + "name": "10", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "autoText", + "text": "是被险峻的峭壁环绕,与世隔绝的,都市的最底部", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "changguan1", + "loc": [ + 0, + 0 + ] + } + ], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "12,9": { + "floorId": "guangchang3", + "loc": [ + 0, + 9 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [210161,210161,210161,210162,364,271, 0,271,365,210160,210161,210161,210161], + [210169,210169,210169,210170,364, 0,272, 0,365,210168,210169,210169,210169], + [210181,210181,210182,210176,361,362,362,362,363,210176,210180,210181,210181], + [210178,210178,210159,210184,210185,210186,210186,210186,210186,210184,210177,210178,210178], + [210178,210178,210178,210184,210177,10104,10105,10106,210167,210184,210177,210178,210178], + [210186,210186,210186,210184,210193,10112,10113,10114,210194,210184,210185,210186,210186], + [71834,71835,210194,210192,30167, 0, 0, 0,30167,210192,210175,210194,210194], + [130173,71835,130175, 0, 0, 0, 0, 0, 0, 0,71799,71799, 0], + [130181,130182,130183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [130189,130190,130191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94], + [130189,130190,130191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [130189,130190,130191, 0, 0, 0, 0, 0, 0, 0,210144,210145,210145], + [130197,130198,130199, 0, 0, 0, 93, 0, 0, 0,210152,210153,210153] +], + "bgmap": [ + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30062,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30062,30052,30052], + [30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30055,30052,30052,30052,30052,30052,30052,30062,30052,30052,30052,30055,30052], + [30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052,30052,30062] +], + "fgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0,210142, 0, 0, 0, 0, 0, 0, 0,210142, 0, 0], + [210131,210131,210150, 0,210142, 0, 0, 0,210142, 0,210150,210131,210131], + [210139,210139, 0, 0,210150, 0, 0, 0,210150, 0, 0,210139,210139], + [210142, 0, 0, 0,30159, 0, 0, 0,30159, 0, 0, 0,210142], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71791,71791,71786], + [ 0,130174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,71794], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0,210212,210212,210212,210212,210212, 0, 0, 0, 0], + [ 0, 0, 0, 0,210212,210212,210212,210212,210212, 0, 0, 0, 0], + [ 0, 0, 0, 0,210212,210212,210212,210212,210212, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,210178,210178,210178, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,210194,210194,210194, 0, 0, 0, 0, 0], + [210150,210194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [71842,71843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [120146,120147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,210150], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +] +} \ No newline at end of file diff --git a/project/floors/guangchang5.js b/project/floors/guangchang5.js new file mode 100644 index 0000000..2a4cf12 --- /dev/null +++ b/project/floors/guangchang5.js @@ -0,0 +1,141 @@ +main.floors.guangchang5= +{ + "floorId": "guangchang5", + "title": "广场", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [ + { + "type": "setCurtain", + "time": 1000 + }, + { + "type": "autoText", + "text": "《特别受灾地区》——", + "time": 2000 + }, + { + "type": "setCurtain", + "color": [ + 0, + 0, + 0, + 1 + ], + "time": 1000, + "keep": true + }, + { + "type": "changeFloor", + "floorId": "guangchang3", + "loc": [ + 0, + 0 + ] + } + ], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "6,12": { + "floorId": "guangchang", + "loc": [ + 6, + 0 + ] + }, + "6,0": { + "floorId": "guangchang3", + "loc": [ + 6, + 12 + ] + }, + "12,9": { + "floorId": "guangchang6", + "loc": [ + 0, + 9 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [210161,210157,210162, 0, 0, 0, 91, 0, 0, 0, 0, 0,140086], + [210164,210165,210170, 0, 0, 0, 0, 0, 0, 0, 0,20110,140094], + [210162, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 0,140102], + [210170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20110, 0], + [ 0,365,362,362,363, 0, 0, 0,361,362,362,362,362], + [ 0,365,210177,210178,210176, 0, 0, 0,210176,210167,210178,210178,210178], + [362,363,210070,210071,210184, 0, 0, 0,210184,210068,210069,210178,210166], + [210181,210184,210078,210079,210192, 0, 0, 0,210192,210076,210077,210194,210194], + [210178,210184,210086,210087, 0, 0, 0, 0, 0,210084,210085,110239,110239], + [210194,210192,120023,120023,120004, 0, 0, 0, 0, 0, 0, 0, 94], + [200171,200172,120031,120031,120020, 0, 0, 0, 0,130171,130172,130173,130174], + [200179,200180,122, 0, 0, 0, 0, 0,200199,130179,130180,130181,130182], + [200187,200188, 0, 0, 0, 0, 93, 0, 0,130187,130188,130189,130190] +], + "areas": "牢狱", + "bgmap": [ + [30052,30052,30055,30052,30052,30052,30052,30052,30052,30062,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30055,30052], + [30055,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30062,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [210209,210209,30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30052], + [210209,210209,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30055], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30062,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052], + [30052,30052,30052,30062,30052,30052,30052,30052,30052,30052,30052,30052,30052] +], + "fgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20102, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20102, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0,120080, 0, 0, 0, 0, 0, 0, 0, 0,120080, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [200115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110231,110231], + [200147,200124, 0, 0, 0, 0, 0, 0,200175, 0, 0, 0, 0], + [200147,200148, 0, 0, 0, 0, 0, 0,200183, 0, 0, 0, 0], + [200155,200156, 0, 0, 0, 0, 0, 0,200191, 0, 0, 0, 0], + [200163,200164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,120004, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,210178,210179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,210178,210195, 0, 0, 0, 0, 0, 0, 0, 0, 0,140110], + [210179,210178,110239,110239,110239, 0, 0, 0,110239,110239,110239,110239,110239], + [210171, 0, 0, 0, 0,130046,130046,130046, 0, 0, 0, 0, 0], + [210195, 0,210177,210178, 0,130046,130046,130046, 0,210177,210178, 0, 0], + [ 0, 0,210175,210194, 0,130054,130054,130054, 0,210193,210194, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0,200173, 0,120012, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0,200181, 0,120028, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0,200189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchang6.js b/project/floors/guangchang6.js new file mode 100644 index 0000000..7544481 --- /dev/null +++ b/project/floors/guangchang6.js @@ -0,0 +1,105 @@ +main.floors.guangchang6= +{ + "floorId": "guangchang6", + "title": "广场", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "2,12": { + "floorId": "guangchang2", + "loc": [ + 2, + 0 + ] + }, + "0,9": { + "floorId": "guangchang5", + "loc": [ + 12, + 9 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [140087,20102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140095,20110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140103,20102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140111,20110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [362,362,362,363, 0, 0,10171,10232,10240, 0, 0, 0, 0], + [210178,210178,210178,210167,364, 0, 0, 0, 0, 0, 0, 0, 0], + [210178,210178,210178,210178,364, 0, 0, 0,10254,10185,10245,10234, 0], + [210194,210175,210194,210194,364, 0, 0, 0, 0, 0, 0, 0, 0], + [110239, 0,126,71320,364, 0, 0,10272,10179,10171,10178,10273, 0], + [ 92, 0, 0,71328,364, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,71336,361,362,362,362,362,362,362,362,362], + [130183, 0, 0, 0,210176,210178,210178,210178,210178,210178,210167,210178,210178], + [130191, 0, 93, 0,210184,210178,210167,210178,210166,210178,210178,210178,210166] +], + "areas": "牢狱", + "bgmap": [ + [30055,30052,30052,30052,30052,30062,30052,30052,30052,30052,30052,30055,30052], + [30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30062,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052,30052], + [30052,30052,30052,30052,30052,30052,30052,30052,30055,30052,30052,30052,30052], + [30052,30052,30052,30052,30055,30052,30052,30052,30052,30052,30052,30052,30052] +], + "fgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [110231, 0, 0,140086, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,140094, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,140102, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0,140110, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [120103,120103,120103,120103, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,170026, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,170026, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,170026, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,170026, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,170026, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0,120103,120103,120103,120103,120103,120103,120103,120103,120103], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/guangchangquan.js b/project/floors/guangchangquan.js new file mode 100644 index 0000000..e5040e3 --- /dev/null +++ b/project/floors/guangchangquan.js @@ -0,0 +1,194 @@ +main.floors.guangchangquan= +{ + "floorId": "guangchangquan", + "title": "广场", + "name": "1", + "width": 26, + "height": 39, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "X90078", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [210178,210178,210178,210178,210171, 0, 0, 0,210171,210178,210178,210178,210178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [210178,210178,210178,210178,210171, 0, 0, 0,210171,210178,210178,210178,210178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "areas": "牢狱", + "bgmap": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,140061,140061,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,140061,140061,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fgmap": [ + +], + "bg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 84, 84, 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 84, 84, 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 84, 84, 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 84, 84, 84, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 86, 86, 86, 86,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0,140061,140061,140061,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,140061,140061,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0,140061, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "fg2map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0,20067,20067,20067, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +] +} \ No newline at end of file diff --git a/project/floors/street01.js b/project/floors/street01.js index f8d1d3c..62ca09a 100644 --- a/project/floors/street01.js +++ b/project/floors/street01.js @@ -10,7 +10,7 @@ main.floors.street01= "canUseQuickShop": true, "images": [], "ratio": 1, - "defaultGround": "X90001", + "defaultGround": "X90078", "firstArrive": [], "eachArrive": [], "parallelDo": "", @@ -28,8 +28,15 @@ main.floors.street01= ] }, "changeFloor": { + "12,9": { + "floorId": "zhujuejia", + "loc": [ + 0, + 9 + ] + }, "0,8": { - "floorId": "street02", + "floorId": "changguan2", "loc": [ 12, 8 @@ -62,27 +69,27 @@ main.floors.street01= [110124, 0,200176,200177,200178,200179,71786,90064,90064,90064, 0,90064,110125], [110124, 0,200088,200089,200004,200005,200006,71795, 0, 0, 0, 0,110125], [110118,110118,200096,110116,110020, 0,200014, 0, 0, 0, 0, 0,110125], - [ 92, 0, 0,110124, 0,201, 0, 0,110125,110122,110122,110122,110122], - [ 0, 0, 0,110118,110118,202,110118,110118,110122, 0, 0, 0, 94], - [130170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [130178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130168,130169], - [130225,130169,130169,130169,130169,130170,110122,110122,130168,130169,130169,130224,130177] + [ 92, 0, 0,110124, 0, 0, 0, 0,110125,110122,110122,110122,110122], + [ 0, 0, 0,110118,110118, 0,110118,110118,110122, 0, 0, 0, 94], + [140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,140,140], + [140,140,140,140,140,140186,110138,110138,140184,140,140,140,140] ], "areas": "牢狱", "bgmap": [ - [90001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90001], - [90001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90001], - [90001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90001], - [90001,71818,71819, 0, 0, 0, 0, 0, 0, 0,10036, 0,90001], - [90001,71826,71827, 0, 0, 0, 0, 0, 0, 0, 0, 0,90001], - [90001, 0, 0, 0, 0, 0,71786, 0,60135,60135,60135,60135, 0], - [90001, 0, 0, 0, 0, 0, 0, 0, 0,90001,90001,90001, 0], - [90001,90001,90001, 0, 0, 0, 0, 0,90001, 0, 0, 0, 0], - [70032,70032,70025, 0, 0,90244,90001,90001,90001, 0, 0, 0, 0], - [70025,70025,70025,90001,90001,90244,90001,90001,90001,70025,70025,70025,70025], - [ 0,70025,70025,70025,70025,70025,70025,70025,70025,70025,70025,70025,70025], - [ 0,70025,70025,70025,70025,70025,70025,70025,70025,70025,70025, 0, 0], - [ 0, 0, 0, 0, 0, 0,90001,90001, 0, 0, 0, 0, 0] + [90078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90078], + [90078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90078], + [90078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,90078], + [90078,71818,71819, 0, 0, 0, 0, 0, 0, 0,10036, 0,90078], + [90078,71826,71827, 0, 0, 0, 0, 0, 0, 0, 0, 0,90078], + [90078, 0, 0, 0, 0, 0,71786, 0,60135,60135,60135,60135,90078], + [90078, 0, 0, 0, 0, 0, 0, 0,90078,90078,90078,90078, 0], + [90078,90078,90078, 0, 0, 0, 0, 0,90078, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0,90244,90078,90078,90078, 0, 0, 0, 0], + [ 0, 0, 0,90078,90078,90244,90078,90078,90078, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0,90078,90078, 0, 0, 0, 0, 0] ], "fgmap": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,130076], @@ -95,8 +102,8 @@ main.floors.street01= [ 0, 0, 0, 0, 0, 0, 0, 0,110143,110114,110114,110114,110114], [ 0, 0, 0,110114,120095, 0,120095,120095,110114, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0,110114,110114, 0, 0, 0, 0, 0], + [ 0,140186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0,140194, 0, 0, 0, 0, 0, 0, 0, 0,140184, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], "bg2map": [ diff --git a/project/floors/xiaoxiang01.js b/project/floors/xiaoxiang01.js index c092a6c..85f6bd0 100644 --- a/project/floors/xiaoxiang01.js +++ b/project/floors/xiaoxiang01.js @@ -48,16 +48,16 @@ main.floors.xiaoxiang01= "map": [ [143,143,143,143,130193,130193,130193,130193,130193,143,143,143,143], [143,143,143,143,130060,130061,130062, 0,120074,143,143,143,143], - [130193,130193,130193,130194,130068,130069,130070,130090,120023,130192,130193,130193,143], - [143,50022,130201,130202,130015,120041,130099,130098,120031,130200,130201,130201,143], - [143, 30,201029, 0, 81, 0,221, 0,224, 0, 28, 27,130192], - [143,224,201037,225,201037, 31,201021, 0,110121,110122,110122,224,130200], - [143, 0, 32, 0,200199, 0,201029,225,110132,224, 0, 0,90675], - [143,225,200998,200999,201037, 81,201029, 0, 0, 0,110116, 0, 94], - [130194, 0,222, 0,221, 0,201029, 81,110116,225,110137,110138,90650], - [130202,201037,201037, 81,201037,201037,201037, 0,110124, 0, 81, 31,90658], - [ 92, 0, 32, 22, 32,80089, 31, 0,110132, 0,110122,110122,110197], - [110191, 21, 21, 21, 21,80089, 0, 0, 81, 0,222, 29,110197], + [143,130193,130193,130194,130068,130069,130070,130090,120023,130192,130193,130193,143], + [130194,130201,130201,130202,130015,120041,130099,130098,120031,130200,130201,130201,143], + [130202, 30,201029, 0, 81, 0,221, 0,224, 0, 28, 27,130192], + [120139,224,201037,225,201037, 31,201021, 0,110121,110122,110122,224,130200], + [120147, 0, 32, 0,200199, 0,201029,225,110132,224, 0, 0,90675], + [120164,225,200998,200999,201037, 81,201029, 0, 0, 0,110116, 0, 94], + [120172, 0,222, 0,221, 0,201029, 81,110116,225,110137,110138,90650], + [120180,201037,201037, 81,201037,201037,201037,246,110124, 0, 81, 31,90658], + [ 92, 32, 32, 22, 21,80089, 31, 0,110132, 0,110122,110122,110197], + [140,110191, 21, 21, 21,80089, 0,246, 81, 0,222, 29,110197], [140,140,140,110191,80083,80097, 93,110138,110138,140189,140,140,140] ], "areas": "牢狱", @@ -79,9 +79,9 @@ main.floors.xiaoxiang01= "fgmap": [ [ 0, 0, 0, 0, 0,120080, 0, 0,120066, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [60038, 0,60038, 0,130007, 0,130091, 0, 0, 0, 0, 0, 0], - [ 0, 0,60046, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0,201021, 0, 0, 0,110114,110114,110114, 0, 0], + [ 0, 0, 0, 0,130007, 0,130091, 0, 0, 0, 0, 0, 0], + [120124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [120132, 0, 0, 0,201021, 0, 0, 0,110114,110114,110114, 0, 0], [ 0, 0, 0, 0,200191, 0, 0, 0, 0, 0, 0, 0,90667], [ 0, 0,200990,200991,201021, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], diff --git a/project/floors/xiaoxiang3.js b/project/floors/xiaoxiang3.js index cf1a4d0..06871b2 100644 --- a/project/floors/xiaoxiang3.js +++ b/project/floors/xiaoxiang3.js @@ -74,21 +74,6 @@ main.floors.xiaoxiang3= "shadow": 0 }, "data": [] - }, - "6,12": { - "trigger": null, - "enable": false, - "noPass": null, - "displayDamage": true, - "opacity": 1, - "filter": { - "blur": 0, - "hue": 0, - "grayscale": 0, - "invert": false, - "shadow": 0 - }, - "data": [] } }, "changeFloor": { @@ -98,13 +83,6 @@ main.floors.xiaoxiang3= 6, 12 ] - }, - "6,12": { - "floorId": "yiqu1", - "loc": [ - 6, - 0 - ] } }, "beforeBattle": {}, @@ -144,11 +122,11 @@ main.floors.xiaoxiang3= "cannotMove": {}, "cannotMoveIn": {}, "map": [ - [ 0, 0, 0,140199,80091,80092, 91,110146,110146,140197,140,140,140], - [ 0, 0, 0,140,140,140, 0,140, 0, 0, 0, 0,140], - [ 0, 0, 0,140204,140206,140206,140206,140206,140206,140203,140,140,140], - [ 0, 0, 0,140199,170263,170252,170253,170254,170263,140197,140,140,140], - [ 0, 0, 0,140199,170263,170260, 0,170262,170263,140197,140,140,140], + [ 0, 0, 0,140199,80091,80092, 91,110146,110146,140197, 0, 0, 0], + [ 0, 0, 0,140,140,140, 0,140, 0, 0, 0, 0, 0], + [ 0, 0, 0,140204,140206,140206,140206,140206,140206,140203, 0, 0, 0], + [ 0, 0, 0,140199,170263,170252,170253,170254,170263,140197, 0, 0, 0], + [ 0, 0, 0,140199,170263,170260, 0,170262,170263,140197, 0, 0, 0], [ 0, 0, 0,140199,170263,170268, 83,170270,170263,140205,140206,140206,140206], [ 0, 0, 0,140199,71843,110122, 0,110122,90649,110208,110209,110209,110209], [140206,140206,140206,140207, 0, 0, 0, 0, 0,110189,140,140,140], @@ -156,7 +134,7 @@ main.floors.xiaoxiang3= [140,140,140,110191, 0, 0, 0, 0, 0,110197,140,140,140], [140,140,140,110199, 0, 34, 0, 28, 0,140,140,140,140], [140,140,140,110199,110199, 0, 0, 0,110197,110204,110206,110206,110206], - [140,140,140,110199,110207, 0, 93, 0,110197,110199,110225,110225,110225] + [140,140,140,110199,110207, 0, 0, 0,110197,110199,110225,110225,110225] ], "areas": "牢狱", "bgmap": [ diff --git a/project/floors/yiqu1.js b/project/floors/yiqu1.js index f0bc683..ec80832 100644 --- a/project/floors/yiqu1.js +++ b/project/floors/yiqu1.js @@ -22,13 +22,6 @@ main.floors.yiqu1= 12, 7 ] - }, - "6,0": { - "floorId": "xiaoxiang3", - "loc": [ - 6, - 12 - ] } }, "beforeBattle": {}, diff --git a/project/floors/yiqu10.js b/project/floors/yiqu10.js index 98f1172..f5b5689 100644 --- a/project/floors/yiqu10.js +++ b/project/floors/yiqu10.js @@ -1,29 +1,29 @@ main.floors.yiqu10= { -"floorId": "yiqu10", -"title": "主塔 10 层", -"name": "10", -"width": 13, -"height": 13, -"canFlyTo": true, -"canFlyFrom": true, -"canUseQuickShop": true, -"images": [], -"ratio": 1, -"defaultGround": "grass2", -"firstArrive": [], -"eachArrive": [], -"parallelDo": "", -"events": {}, -"changeFloor": {}, -"beforeBattle": {}, -"afterBattle": {}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"autoEvent": {}, -"cannotMove": {}, -"cannotMoveIn": {}, -"map": [ + "floorId": "yiqu10", + "title": "主塔 10 层", + "name": "10", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -38,4 +38,16 @@ main.floors.yiqu10= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] } \ No newline at end of file diff --git a/project/floors/yiqu3.js b/project/floors/yiqu3.js index 394234a..cf7a28a 100644 --- a/project/floors/yiqu3.js +++ b/project/floors/yiqu3.js @@ -1,29 +1,29 @@ main.floors.yiqu3= { -"floorId": "yiqu3", -"title": "主塔 3 层", -"name": "3", -"width": 13, -"height": 13, -"canFlyTo": true, -"canFlyFrom": true, -"canUseQuickShop": true, -"images": [], -"ratio": 1, -"defaultGround": "grass2", -"firstArrive": [], -"eachArrive": [], -"parallelDo": "", -"events": {}, -"changeFloor": {}, -"beforeBattle": {}, -"afterBattle": {}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"autoEvent": {}, -"cannotMove": {}, -"cannotMoveIn": {}, -"map": [ + "floorId": "yiqu3", + "title": "主塔 3 层", + "name": "3", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -38,4 +38,16 @@ main.floors.yiqu3= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] } \ No newline at end of file diff --git a/project/floors/yiqu7.js b/project/floors/yiqu7.js index d47401f..e2e082b 100644 --- a/project/floors/yiqu7.js +++ b/project/floors/yiqu7.js @@ -1,29 +1,29 @@ main.floors.yiqu7= { -"floorId": "yiqu7", -"title": "主塔 7 层", -"name": "7", -"width": 13, -"height": 13, -"canFlyTo": true, -"canFlyFrom": true, -"canUseQuickShop": true, -"images": [], -"ratio": 1, -"defaultGround": "grass2", -"firstArrive": [], -"eachArrive": [], -"parallelDo": "", -"events": {}, -"changeFloor": {}, -"beforeBattle": {}, -"afterBattle": {}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"autoEvent": {}, -"cannotMove": {}, -"cannotMoveIn": {}, -"map": [ + "floorId": "yiqu7", + "title": "主塔 7 层", + "name": "7", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -38,4 +38,16 @@ main.floors.yiqu7= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] } \ No newline at end of file diff --git a/project/floors/yiqu8.js b/project/floors/yiqu8.js index 3174759..18bb1e8 100644 --- a/project/floors/yiqu8.js +++ b/project/floors/yiqu8.js @@ -1,29 +1,29 @@ main.floors.yiqu8= { -"floorId": "yiqu8", -"title": "主塔 8 层", -"name": "8", -"width": 13, -"height": 13, -"canFlyTo": true, -"canFlyFrom": true, -"canUseQuickShop": true, -"images": [], -"ratio": 1, -"defaultGround": "grass2", -"firstArrive": [], -"eachArrive": [], -"parallelDo": "", -"events": {}, -"changeFloor": {}, -"beforeBattle": {}, -"afterBattle": {}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"autoEvent": {}, -"cannotMove": {}, -"cannotMoveIn": {}, -"map": [ + "floorId": "yiqu8", + "title": "主塔 8 层", + "name": "8", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": {}, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], @@ -38,4 +38,16 @@ main.floors.yiqu8= [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ], + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] } \ No newline at end of file diff --git a/project/floors/yushou.js b/project/floors/yushou.js new file mode 100644 index 0000000..5abf05c --- /dev/null +++ b/project/floors/yushou.js @@ -0,0 +1,62 @@ +main.floors.yushou= +{ + "floorId": "yushou", + "title": "广场", + "name": "1", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "images": [], + "ratio": 1, + "defaultGround": "grass2", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "9,0": { + "floorId": "guangchang2", + "loc": [ + 9, + 12 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "areas": "牢狱", + "bgmap": [ + +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/floors/zhujuejia.js b/project/floors/zhujuejia.js new file mode 100644 index 0000000..5e13867 --- /dev/null +++ b/project/floors/zhujuejia.js @@ -0,0 +1,75 @@ +main.floors.zhujuejia= +{ + "floorId": "zhujuejia", + "title": "新建楼层", + "name": "0", + "width": 13, + "height": 13, + "canFlyTo": true, + "canFlyFrom": true, + "canUseQuickShop": true, + "cannotViewMap": false, + "cannotMoveDirectly": false, + "images": [], + "ratio": 1, + "defaultGround": "ground", + "firstArrive": [], + "eachArrive": [], + "parallelDo": "", + "events": {}, + "changeFloor": { + "0,9": { + "floorId": "street01", + "loc": [ + 12, + 9 + ] + } + }, + "beforeBattle": {}, + "afterBattle": {}, + "afterGetItem": {}, + "afterOpenDoor": {}, + "autoEvent": {}, + "cannotMove": {}, + "cannotMoveIn": {}, + "map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], + "bgmap": [ + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308], + [308,308,308,308,308,308,308,308,308,308,308,308,308] +], + "fgmap": [ + +], + "bg2map": [ + +], + "fg2map": [ + +] +} \ No newline at end of file diff --git a/project/fonts/Verdana.ttf b/project/fonts/Verdana.ttf new file mode 100644 index 0000000..8f25a64 Binary files /dev/null and b/project/fonts/Verdana.ttf differ diff --git a/project/functions.js b/project/functions.js index 0719015..a9a00a6 100644 --- a/project/functions.js +++ b/project/functions.js @@ -2,177 +2,189 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { "events": { "resetGame": function (hero, hard, floorId, maps, values) { - // 重置整个游戏;此函数将在游戏开始时,或者每次读档时最先被调用 - // hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息 + // 重置整个游戏;此函数将在游戏开始时,或者每次读档时最先被调用 + // hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息 - // 清除游戏数据 - // 这一步会清空状态栏和全部画布内容,并删除所有动态创建的画布 - core.clearStatus(); - // 初始化status - core.status = core.clone(core.initStatus, function (name) { - return name != 'hero' && name != 'maps'; - }); - core.control._bindRoutePush(); - core.status.played = true; - // 初始化人物,图标,统计信息 - core.status.hero = core.clone(hero); - window.hero = core.status.hero; - window.flags = core.status.hero.flags; - core.events.setHeroIcon(core.status.hero.image, true); - core.control._initStatistics(core.animateFrame.totalTime); - core.status.hero.statistics.totalTime = core.animateFrame.totalTime = - Math.max(core.status.hero.statistics.totalTime, core.animateFrame.totalTime); - core.status.hero.statistics.start = null; - // 初始难度 - core.status.hard = hard || ""; - // 初始化地图 - core.status.floorId = floorId; - core.status.maps = maps; - core.maps._resetFloorImages(); - // 初始化怪物和道具 - core.material.enemys = core.enemys.getEnemys(); - core.material.items = core.items.getItems(); - // 初始化全局数值和全局开关 - core.values = core.clone(core.data.values); - for (var key in values || {}) - core.values[key] = values[key]; - core.flags = core.clone(core.data.flags); - var globalFlags = core.getFlag("globalFlags", {}); - for (var key in globalFlags) - core.flags[key] = globalFlags[key]; - core._init_sys_flags(); - // 初始化界面,状态栏等 - core.resize(); - // 状态栏是否显示 - if (core.hasFlag('hideStatusBar')) - core.hideStatusBar(core.hasFlag('showToolbox')); - else - core.showStatusBar(); - // 隐藏右下角的音乐按钮 - core.dom.musicBtn.style.display = 'none'; - }, + // 清除游戏数据 + // 这一步会清空状态栏和全部画布内容,并删除所有动态创建的画布 + core.clearStatus(); + // 初始化status + core.status = core.clone(core.initStatus, function (name) { + return name != "hero" && name != "maps"; + }); + core.control._bindRoutePush(); + core.status.played = true; + // 初始化人物,图标,统计信息 + core.status.hero = core.clone(hero); + window.hero = core.status.hero; + window.flags = core.status.hero.flags; + core.events.setHeroIcon(core.status.hero.image, true); + core.control._initStatistics(core.animateFrame.totalTime); + core.status.hero.statistics.totalTime = core.animateFrame.totalTime = + Math.max( + core.status.hero.statistics.totalTime, + core.animateFrame.totalTime + ); + core.status.hero.statistics.start = null; + // 初始难度 + core.status.hard = hard || ""; + // 初始化地图 + core.status.floorId = floorId; + core.status.maps = maps; + core.maps._resetFloorImages(); + // 初始化怪物和道具 + core.material.enemys = core.enemys.getEnemys(); + core.material.items = core.items.getItems(); + // 初始化全局数值和全局开关 + core.values = core.clone(core.data.values); + for (var key in values || {}) core.values[key] = values[key]; + core.flags = core.clone(core.data.flags); + var globalFlags = core.getFlag("globalFlags", {}); + for (var key in globalFlags) core.flags[key] = globalFlags[key]; + core._init_sys_flags(); + // 初始化界面,状态栏等 + core.resize(); + // 状态栏是否显示 + if (core.hasFlag("hideStatusBar")) + core.hideStatusBar(core.hasFlag("showToolbox")); + else core.showStatusBar(); + // 隐藏右下角的音乐按钮 + core.dom.musicBtn.style.display = "none"; + }, "win": function (reason, norank, noexit) { - // 游戏获胜事件 - // 请注意,成绩统计时是按照hp进行上传并排名 - // 可以先在这里对最终分数进行计算,比如将2倍攻击和5倍黄钥匙数量加到分数上 - // core.status.hero.hp += 2 * core.getRealStatus('atk') + 5 * core.itemCount('yellowKey'); + // 游戏获胜事件 + // 请注意,成绩统计时是按照hp进行上传并排名 + // 可以先在这里对最终分数进行计算,比如将2倍攻击和5倍黄钥匙数量加到分数上 + // core.status.hero.hp += 2 * core.getRealStatus('atk') + 5 * core.itemCount('yellowKey'); - // 如果不退出,则临时存储数据 - if (noexit) { - core.status.extraEvent = core.clone(core.status.event); - } + // 如果不退出,则临时存储数据 + if (noexit) { + core.status.extraEvent = core.clone(core.status.event); + } - // 游戏获胜事件 + // 游戏获胜事件 + core.ui.closePanel(); + var replaying = core.isReplaying(); + if (replaying) core.stopReplay(); + core.waitHeroToStop(function () { + if (!noexit) { + core.clearMap("all"); // 清空全地图 + core.deleteAllCanvas(); // 删除所有创建的画布 + core.dom.gif2.innerHTML = ""; + } + reason = core.replaceText(reason); + core.drawText( + ["\t[" + (reason || "恭喜通关") + "]你的分数是${status:hp}。"], + function () { + core.events.gameOver(reason || "", replaying, norank); + } + ); + }); + }, + "lose": function (reason) { + // 游戏失败事件 core.ui.closePanel(); var replaying = core.isReplaying(); - if (replaying) core.stopReplay(); + core.stopReplay(); core.waitHeroToStop(function () { - if (!noexit) { - core.clearMap('all'); // 清空全地图 - core.deleteAllCanvas(); // 删除所有创建的画布 - core.dom.gif2.innerHTML = ""; - } - reason = core.replaceText(reason); - core.drawText([ - "\t[" + (reason || "恭喜通关") + "]你的分数是${status:hp}。" - ], function () { - core.events.gameOver(reason || '', replaying, norank); - }) + core.drawText( + ["\t[" + (reason || "结局1") + "]你死了。\n如题。"], + function () { + core.events.gameOver(null, replaying); + } + ); }); }, - "lose": function (reason) { - // 游戏失败事件 - core.ui.closePanel(); - var replaying = core.isReplaying(); - core.stopReplay(); - core.waitHeroToStop(function () { - core.drawText([ - "\t[" + (reason || "结局1") + "]你死了。\n如题。" - ], function () { - core.events.gameOver(null, replaying); - }); - }) - }, "changingFloor": function (floorId, heroLoc) { - // 正在切换楼层过程中执行的操作;此函数的执行时间是“屏幕完全变黑“的那一刻 - // floorId为要切换到的楼层ID;heroLoc表示勇士切换到的位置 + // 正在切换楼层过程中执行的操作;此函数的执行时间是“屏幕完全变黑“的那一刻 + // floorId为要切换到的楼层ID;heroLoc表示勇士切换到的位置 - // ---------- 此时还没有进行切换,当前floorId还是原来的 ---------- // - var currentId = core.status.floorId || null; // 获得当前的floorId,可能为null - var fromLoad = core.hasFlag('__fromLoad__'); // 是否是读档造成的切换 - var isFlying = core.hasFlag('__isFlying__'); // 是否是楼传造成的切换 - if (!fromLoad && !(isFlying && currentId == floorId)) { - if (!core.hasFlag("__leaveLoc__")) core.setFlag("__leaveLoc__", {}); - if (currentId != null) core.getFlag("__leaveLoc__")[currentId] = core.clone(core.status.hero.loc); + // ---------- 此时还没有进行切换,当前floorId还是原来的 ---------- // + var currentId = core.status.floorId || null; // 获得当前的floorId,可能为null + var fromLoad = core.hasFlag("__fromLoad__"); // 是否是读档造成的切换 + var isFlying = core.hasFlag("__isFlying__"); // 是否是楼传造成的切换 + if (!fromLoad && !(isFlying && currentId == floorId)) { + if (!core.hasFlag("__leaveLoc__")) core.setFlag("__leaveLoc__", {}); + if (currentId != null) + core.getFlag("__leaveLoc__")[currentId] = core.clone( + core.status.hero.loc + ); + } + + // 可以对currentId进行判定,比如删除某些自定义图层等 + // if (currentId == 'MT0') { + // core.deleteAllCanvas(); + // } + + // 根据分区信息自动砍层与恢复 + if (core.autoRemoveMaps) core.autoRemoveMaps(floorId); + + // 重置画布尺寸 + core.maps.resizeMap(floorId); + // 设置勇士的位置 + heroLoc.direction = core.turnDirection(heroLoc.direction); + core.status.hero.loc = heroLoc; + // 检查重生怪并重置 + if (!fromLoad) { + core.extractBlocks(floorId); + core.status.maps[floorId].blocks.forEach(function (block) { + if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) { + block.disable = false; + core.setMapBlockDisabled(floorId, block.x, block.y, false); + core.maps._updateMapArray(floorId, block.x, block.y); } + }); + core.control.gatherFollowers(); + } - // 可以对currentId进行判定,比如删除某些自定义图层等 - // if (currentId == 'MT0') { - // core.deleteAllCanvas(); - // } + // ---------- 重绘新地图;这一步将会设置core.status.floorId ---------- // + core.drawMap(floorId); - // 根据分区信息自动砍层与恢复 - if (core.autoRemoveMaps) core.autoRemoveMaps(floorId); + // 切换楼层BGM + if (core.status.maps[floorId].bgm) { + var bgm = core.status.maps[floorId].bgm; + if (bgm instanceof Array) + bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个 + if (!core.hasFlag("__bgm__")) core.playBgm(bgm); + } else if (fromLoad && !core.hasFlag("__bgm__")) { + core.pauseBgm(); + } + // 更改画面色调 + var color = core.getFlag("__color__", null); + if (!color && core.status.maps[floorId].color) + color = core.status.maps[floorId].color; + core.clearMap("curtain"); + core.status.curtainColor = color; + if (color) + core.fillRect( + "curtain", + 0, + 0, + core._PX_ || core.__PIXELS__, + core._PY_ || core.__PIXELS__, + core.arrayToRGBA(color) + ); + // 更改天气 + var weather = core.getFlag("__weather__", null); + if (!weather && core.status.maps[floorId].weather) + weather = core.status.maps[floorId].weather; + if (weather) core.setWeather(weather[0], weather[1]); + else core.setWeather(); - // 重置画布尺寸 - core.maps.resizeMap(floorId); - // 设置勇士的位置 - heroLoc.direction = core.turnDirection(heroLoc.direction); - core.status.hero.loc = heroLoc; - // 检查重生怪并重置 - if (!fromLoad) { - core.extractBlocks(floorId); - core.status.maps[floorId].blocks.forEach(function (block) { - if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) { - block.disable = false; - core.setMapBlockDisabled(floorId, block.x, block.y, false); - core.maps._updateMapArray(floorId, block.x, block.y); - } - }); - core.control.gatherFollowers(); - } - - // ---------- 重绘新地图;这一步将会设置core.status.floorId ---------- // - core.drawMap(floorId); - - // 切换楼层BGM - if (core.status.maps[floorId].bgm) { - var bgm = core.status.maps[floorId].bgm; - if (bgm instanceof Array) bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个 - if (!core.hasFlag("__bgm__")) core.playBgm(bgm); - } else if (fromLoad && !core.hasFlag("__bgm__")) { - core.pauseBgm(); - } - // 更改画面色调 - var color = core.getFlag('__color__', null); - if (!color && core.status.maps[floorId].color) - color = core.status.maps[floorId].color; - core.clearMap('curtain'); - core.status.curtainColor = color; - if (color) core.fillRect('curtain', 0, 0, core._PX_ || core.__PIXELS__, core._PY_ || core.__PIXELS__, core.arrayToRGBA(color)); - // 更改天气 - var weather = core.getFlag('__weather__', null); - if (!weather && core.status.maps[floorId].weather) - weather = core.status.maps[floorId].weather; - if (weather) - core.setWeather(weather[0], weather[1]); - else core.setWeather(); - - // ...可以新增一些其他内容,比如创建个画布在右上角显示什么内容等等 - - }, + // ...可以新增一些其他内容,比如创建个画布在右上角显示什么内容等等 +}, "afterChangeFloor": function (floorId) { // 转换楼层结束的事件;此函数会在整个楼层切换完全结束后再执行 // floorId是切换到的楼层 // 如果是读档,则进行检查(是否需要恢复事件) - if (core.hasFlag('__fromLoad__')) { + if (core.hasFlag("__fromLoad__")) { core.events.recoverEvents(core.getFlag("__events__")); core.removeFlag("__events__"); } else { // 每次抵达楼层执行的事件 core.insertAction(core.floors[floorId].eachArrive); - core.ui.statusBar._update_map() + core.ui.statusBar._update_map(); // 首次抵达楼层时执行的事件(后插入,先执行) if (!core.hasVisitedFloor(floorId)) { core.insertAction(core.floors[floorId].firstArrive); @@ -188,9 +200,13 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = var fromId = core.status.floorId; // 检查能否飞行 - if (!core.status.maps[fromId].canFlyFrom || !core.status.maps[toId].canFlyTo || !core.hasVisitedFloor(toId)) { - core.playSound('操作失败'); - core.drawTip("无法飞往" + core.status.maps[toId].title + "!", 'fly'); + if ( + !core.status.maps[fromId].canFlyFrom || + !core.status.maps[toId].canFlyTo || + !core.hasVisitedFloor(toId) + ) { + core.playSound("操作失败"); + core.drawTip("无法飞往" + core.status.maps[toId].title + "!", "fly"); return false; } @@ -200,8 +216,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.flags.flyRecordPosition) { loc = core.getFlag("__leaveLoc__", {})[toId] || null; } - if (core.status.maps[toId].flyPoint != null && core.status.maps[toId].flyPoint.length == 2) { - stair = 'flyPoint'; + if ( + core.status.maps[toId].flyPoint != null && + core.status.maps[toId].flyPoint.length == 2 + ) { + stair = "flyPoint"; } if (stair == null && loc == null) { // 获得两个楼层的索引,以决定是上楼梯还是下楼梯 @@ -209,14 +228,15 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = toIndex = core.floorIds.indexOf(toId); var stair = fromIndex <= toIndex ? "downFloor" : "upFloor"; // 地下层:同层传送至上楼梯 - if (fromIndex == toIndex && core.status.maps[fromId].underGround) stair = "upFloor"; + if (fromIndex == toIndex && core.status.maps[fromId].underGround) + stair = "upFloor"; } // 记录录像 core.status.route.push("fly:" + toId); // 传送 core.ui.closePanel(); - core.setFlag('__isFlying__', true); + core.setFlag("__isFlying__", true); core.changeFloor(toId, stair, loc, null, function () { core.removeFlag("__isFlying__"); if (callback) callback(); @@ -225,42 +245,47 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return true; }, "beforeBattle": function (enemyId, x, y) { - // 战斗前触发的事件,可以加上一些战前特效(详见下面支援的例子) - // 此函数在“检测能否战斗和自动存档”【之后】执行。如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。 - // 返回true则将继续战斗,返回false将不再战斗。 + // 战斗前触发的事件,可以加上一些战前特效(详见下面支援的例子) + // 此函数在“检测能否战斗和自动存档”【之后】执行。如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。 + // 返回true则将继续战斗,返回false将不再战斗。 - // ------ 支援技能 ------ // - if (x != null && y != null) { - var index = x + "," + y, - cache = core.status.checkBlock.cache[index] || {}, - guards = cache.guards || []; - // 如果存在支援怪 - if (guards.length > 0) { - // 记录flag,当前要参与支援的怪物 - core.setFlag("__guards__" + x + "_" + y, guards); - var actions = [{ "type": "playSound", "name": "跳跃" }]; - // 增加支援的特效动画(图块跳跃) - guards.forEach(function (g) { - core.push(actions, { "type": "jump", "from": [g[0], g[1]], "to": [x, y], "time": 300, "keep": false, "async": true }); - }); - core.push(actions, [ - { "type": "waitAsync" }, // 等待所有异步事件执行完毕 - { "type": "setBlock", "number": enemyId, "loc": [[x, y]] }, // 重新设置怪物自身 - { "type": "battle", "loc": [x, y] } // 重要!重新触发本次战斗 - ]); - core.insertAction(actions); - return false; - } - } + // ------ 支援技能 ------ // + if (x != null && y != null) { + var index = x + "," + y, + cache = core.status.checkBlock.cache[index] || {}, + guards = cache.guards || []; + // 如果存在支援怪 + if (guards.length > 0) { + // 记录flag,当前要参与支援的怪物 + core.setFlag("__guards__" + x + "_" + y, guards); + var actions = [{ type: "playSound", name: "跳跃" }]; + // 增加支援的特效动画(图块跳跃) + guards.forEach(function (g) { + core.push(actions, { + type: "jump", + from: [g[0], g[1]], + to: [x, y], + time: 300, + keep: false, + async: true, + }); + }); + core.push(actions, [ + { type: "waitAsync" }, // 等待所有异步事件执行完毕 + { type: "setBlock", number: enemyId, loc: [[x, y]] }, // 重新设置怪物自身 + { type: "battle", loc: [x, y] }, // 重要!重新触发本次战斗 + ]); + core.insertAction(actions); + return false; + } + } - return true; - }, - "afterBattle": function (enemyId, x, y) { + return true; + }, + "afterBattle": async function (enemyId, x, y) { // 战斗结束后触发的事件 - - var enemy = core.material.enemys[enemyId]; + var enemy = core.getEnemyInfo(enemyId, hero, x, y) var special = enemy.special; - // 播放战斗音效和动画 // 默认播放的动画;你也可以使用 var animate = 'hand'; // 默认动画 @@ -270,19 +295,32 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = animate = core.material.items[equipId].equip.animate; // 你也可以在这里根据自己的需要,比如enemyId或special或flag来修改播放的动画效果 // if (enemyId == '...') animate = '...'; + if (core.getFlag('noAnimate')) { + // 检查该动画是否存在SE,如果不存在则使用默认音效 + if (!(core.material.animates[animate] || {}).se) + core.playSound('attack.mp3'); - // 检查该动画是否存在SE,如果不存在则使用默认音效 - if (!(core.material.animates[animate] || {}).se) - core.playSound('attack.mp3'); - - // 播放动画;如果不存在坐标(强制战斗)则播放到勇士自身 - if (x != null && y != null) - core.drawAnimate(animate, x, y); - else - core.drawHeroAnimate(animate); - + // 播放动画;如果不存在坐标(强制战斗)则播放到勇士自身 + if (x != null && y != null) + core.drawAnimate(animate, x, y); + else + core.drawHeroAnimate(animate); + } // 获得战斗伤害信息 var damageInfo = core.getDamageInfo(enemyId, null, x, y) || {}; + + if (!core.getFlag("noAnimate")) await core.attackAnimate( + enemyId, + damageInfo.start[0], + damageInfo.start[1], + damageInfo.start[2], + damageInfo.start[3], + damageInfo.start[4], + damageInfo.heroDiffList, + damageInfo.enemyDiffList, + damageInfo.heroanimateList, + damageInfo.enemyanimateList + ) // 战斗伤害 var damage = damageInfo.damage; // 当前战斗回合数,可用于战后所需的判定 @@ -427,61 +465,72 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }, "afterOpenDoor": function (doorId, x, y) { - // 开一个门后触发的事件 + // 开一个门后触发的事件 - var todo = []; - // 检查该点的开门后事件 - if (core.status.floorId) { - core.push(todo, core.floors[core.status.floorId].afterOpenDoor[x + "," + y]); - } - // 检查批量开门事件 - var door = core.getBlockById(doorId); - if (door && door.event.doorInfo) { - core.push(todo, door.event.doorInfo.afterOpenDoor); - } + var todo = []; + // 检查该点的开门后事件 + if (core.status.floorId) { + core.push( + todo, + core.floors[core.status.floorId].afterOpenDoor[x + "," + y] + ); + } + // 检查批量开门事件 + var door = core.getBlockById(doorId); + if (door && door.event.doorInfo) { + core.push(todo, door.event.doorInfo.afterOpenDoor); + } - if (todo.length > 0) core.insertAction(todo, x, y); + if (todo.length > 0) core.insertAction(todo, x, y); - if (core.status.event.id == null) - core.continueAutomaticRoute(); - else - core.clearContinueAutomaticRoute(); - }, + if (core.status.event.id == null) core.continueAutomaticRoute(); + else core.clearContinueAutomaticRoute(); + }, "afterGetItem": function (itemId, x, y, isGentleClick) { - // 获得一个道具后触发的事件 - // itemId:获得的道具ID;x和y是该道具所在的坐标 - // isGentleClick:是否是轻按触发的 - if (itemId.endsWith('Potion') && core.material.items[itemId].cls == 'items') - core.playSound('回血'); - else if (itemId.endsWith('Gem') && core.material.items[itemId].cls == 'items') - core.playSound('宝石') - else - core.playSound('获得道具'); + // 获得一个道具后触发的事件 + // itemId:获得的道具ID;x和y是该道具所在的坐标 + // isGentleClick:是否是轻按触发的 + if ( + itemId.endsWith("Potion") && + core.material.items[itemId].cls == "items" + ) + core.playSound("回血"); + else if ( + itemId.endsWith("Gem") && + core.material.items[itemId].cls == "items" + ) + core.playSound("宝石"); + else core.playSound("获得道具"); - var todo = []; - // 检查该点的获得道具后事件。 - if (core.status.floorId == null) return; - var event = core.floors[core.status.floorId].afterGetItem[x + "," + y]; - if (event && (event instanceof Array || !isGentleClick || !event.disableOnGentleClick)) { - if (event.data) event = event.data; - core.unshift(todo, event); - } + var todo = []; + // 检查该点的获得道具后事件。 + if (core.status.floorId == null) return; + var event = core.floors[core.status.floorId].afterGetItem[x + "," + y]; + if ( + event && + (event instanceof Array || + !isGentleClick || + !event.disableOnGentleClick) + ) { + if (event.data) event = event.data; + core.unshift(todo, event); + } - if (todo.length > 0) core.insertAction(todo, x, y); - }, + if (todo.length > 0) core.insertAction(todo, x, y); + }, "afterPushBox": function () { - // 推箱子后的事件 - if (core.searchBlock('box').length == 0) { - // 可以通过if语句来进行开门操作 - /* + // 推箱子后的事件 + if (core.searchBlock("box").length == 0) { + // 可以通过if语句来进行开门操作 + /* if (core.status.floorId=='xxx') { // 在某个楼层 core.insertAction([ // 插入一条事件 {"type": "openDoor", "loc": [x,y]} // 开门 ]) } */ - } - } + } + } }, "enemys": { "getSpecials": function () { @@ -491,36 +540,221 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 第五项为该特殊属性的标记;目前 1 代表是地图类技能(需要进行遍历全图) // 名字和描述可以直接写字符串,也可以写个function将怪物传进去 return [ - [1, "先攻", "怪物首先攻击", "#ffcc33"], - [3, "坚固", "怪物防御不小于角色攻击-1", "#c0b088"], - [6, function (enemy) { return (enemy.n || '') + "连击"; }, function (enemy) { return "怪物每回合攻击" + (enemy.n || 4) + "次"; }, "#ffee77"], - [7, "破甲", function (enemy) { return "战斗前,怪物附加角色防御的" + Math.floor(100 * (enemy.breakArmor || core.values.breakArmor || 0)) + "%作为伤害"; }, "#88c0ff"], - [8, "反击", function (enemy) { return "战斗时,怪物每回合附加角色攻击的" + Math.floor(100 * (enemy.counterAttack || core.values.counterAttack || 0)) + "%作为伤害,无视角色防御"; }, "#ffaa44"], - [9, "净化", function (enemy) { return "战斗前,怪物附加角色护盾的" + (enemy.purify || core.values.purify) + "倍作为伤害"; }, "#80eed6"], + [1, "先攻", "怪物首先攻击", "#ffcc33"], //√ + //[2, "魔攻", "怪物无视角色的防御", "#bbb0ff"], + [3, "坚固", "怪物防御不小于角色攻击-1", "#c0b088"], //√ + [ + 6, + function (enemy) { + return (enemy.n || "") + "连击"; + }, + function (enemy) { + return "怪物每回合攻击" + (enemy.n || 4) + "次"; + }, + "#ffee77", + ], //想改成“以XX%、XX%攻击力各攻击一次” + [ + 7, + "破甲", + function (enemy) { + return ( + "怪物无视角色防御的" + + Math.floor( + 100 * (enemy.breakArmor || core.values.breakArmor || 0) + ) + + "%" + ); + }, + "#88c0ff", + ], //√ + [ + 8, + "反击", + function (enemy) { + return ( + "战斗时,怪物每回合附加角色攻击的" + + Math.floor( + 100 * (enemy.counterAttack || core.values.counterAttack || 0) + ) + + "%作为伤害,无视角色防御" + ); + }, + "#ffaa44", + ], + [ + 9, + "净化", + function (enemy) { + return ( + "战斗前,怪物附加角色护盾的" + + (enemy.purify || core.values.purify) + + "倍作为伤害" + ); + }, + "#80eed6", + ], [10, "模仿", "怪物的攻防和角色攻防相等", "#b0c0dd"], - [11, "吸血", function (enemy) { return "战斗前,怪物首先吸取角色的" + Math.floor(100 * enemy.vampire || 0) + "%生命(约" + Math.floor((enemy.vampire || 0) * core.getStatus('hp')) + "点)作为伤害" + (enemy.add ? ",并把伤害数值加到自身生命上" : ""); }, "#dd4448"], - [12, "中毒", "战斗后,角色陷入中毒状态,每一步损失生命" + core.values.poisonDamage + "点", "#99ee88"], - [13, "衰弱", "战斗后,角色陷入衰弱状态,攻防暂时下降" + (core.values.weakValue >= 1 ? core.values.weakValue + "点" : parseInt(core.values.weakValue * 100) + "%"), "#f0bbcc"], - [14, "诅咒", "战斗后,角色陷入诅咒状态,战斗无法获得金币和经验", "#bbeef0"], - [15, "领域", function (enemy) { return "经过怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "范围内" + (enemy.range || 1) + "格时自动减生命" + (enemy.zone || 0) + "点"; }, "#c677dd"], + [ + 11, + "吸血", + function (enemy) { + return ( + "战斗前,怪物首先吸取角色的" + + Math.floor(100 * enemy.vampire || 0) + + "%生命(约" + + Math.floor((enemy.vampire || 0) * core.getStatus("hp")) + + "点)作为伤害" + + (enemy.add ? ",并把伤害数值加到自身生命上" : "") + ); + }, + "#dd4448", + ], + [ + 12, + "中毒", + "战斗后,角色陷入中毒状态,每一步损失生命" + + core.values.poisonDamage + + "点", + "#99ee88", + ], + [ + 13, + "衰弱", + "战斗后,角色陷入衰弱状态,攻防暂时下降" + + (core.values.weakValue >= 1 ? + core.values.weakValue + "点" : + parseInt(core.values.weakValue * 100) + "%"), + "#f0bbcc", + ], + [ + 14, + "诅咒", + "战斗后,角色陷入诅咒状态,战斗无法获得金币和经验", + "#bbeef0", + ], + [ + 15, + "领域", + function (enemy) { + return ( + "经过怪物周围" + + (enemy.zoneSquare ? "九宫格" : "十字") + + "范围内" + + (enemy.range || 1) + + "格时自动减生命" + + (enemy.zone || 0) + + "点" + ); + }, + "#c677dd", + ], [16, "夹击", "经过两只相同的怪物中间,角色生命值变成一半", "#bb99ee"], - [17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害;战斗后,释放一半的仇恨值。(每杀死一个怪物获得" + (core.values.hatred || 0) + "点仇恨值)", "#b0b666"], - [18, "阻击", function (enemy) { return "经过怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "时自动减生命" + (enemy.repulse || 0) + "点,同时怪物后退一格"; }, "#8888e6"], + [ + 17, + "仇恨", + "战斗前,怪物附加之前积累的仇恨值作为伤害;战斗后,释放一半的仇恨值。(每杀死一个怪物获得" + + (core.values.hatred || 0) + + "点仇恨值)", + "#b0b666", + ], + [ + 18, + "阻击", + function (enemy) { + return ( + "经过怪物周围" + + (enemy.zoneSquare ? "九宫格" : "十字") + + "时自动减生命" + + (enemy.repulse || 0) + + "点,同时怪物后退一格" + ); + }, + "#8888e6", + ], [19, "自爆", "战斗后角色的生命值变成1", "#ff6666"], [20, "无敌", "角色无法打败怪物,除非拥有十字架", "#aaaaaa"], - [21, "退化", function (enemy) { return "战斗后角色永久下降" + (enemy.atkValue || 0) + "点攻击和" + (enemy.defValue || 0) + "点防御"; }], - [22, "固伤", function (enemy) { return "战斗前,怪物对角色造成" + (enemy.damage || 0) + "点固定伤害,未开启负伤时无视角色护盾。"; }, "#ff9977"], + [ + 21, + "退化", + function (enemy) { + return ( + "战斗后角色永久下降" + + (enemy.atkValue || 0) + + "点攻击和" + + (enemy.defValue || 0) + + "点防御" + ); + }, + ], + [ + 22, + "固伤", + function (enemy) { + return ( + "战斗前,怪物对角色造成" + + (enemy.damage || 0) + + "点固定伤害,未开启负伤时无视角色护盾。" + ); + }, + "#ff9977", + ], [23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现", "#a0e0ff"], - [24, "激光", function (enemy) { return "经过怪物同行或同列时自动减生命" + (enemy.laser || 0) + "点"; }, "#dda0dd"], - [25, "光环", function (enemy) { return (enemy.range != null ? ((enemy.haloSquare ? "该怪物九宫格" : "该怪物十字") + enemy.haloRange + "格范围内") : "同楼层所有") + "怪物生命提升" + (enemy.hpBuff || 0) + "%,攻击提升" + (enemy.atkBuff || 0) + "%,防御提升" + (enemy.defBuff || 0) + "%," + (enemy.haloAdd ? "可叠加" : "不可叠加"); }, "#e6e099", 1], - [26, "支援", "当周围一圈的怪物受到攻击时将上前支援,并组成小队战斗。", "#77c0b6", 1], - [27, "捕捉", function (enemy) { return "当走到怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "时会强制进行战斗。"; }, "#c0ddbb"] + [ + 24, + "激光", + function (enemy) { + return "经过怪物同行或同列时自动减生命" + (enemy.laser || 0) + "点"; + }, + "#dda0dd", + ], + [ + 25, + "光环", + function (enemy) { + return ( + (enemy.range != null ? + (enemy.haloSquare ? "该怪物九宫格" : "该怪物十字") + + enemy.haloRange + + "格范围内" : + "同楼层所有") + + "怪物生命提升" + + (enemy.hpBuff || 0) + + "%,攻击提升" + + (enemy.atkBuff || 0) + + "%,防御提升" + + (enemy.defBuff || 0) + + "%," + + (enemy.haloAdd ? "可叠加" : "不可叠加") + ); + }, + "#e6e099", + 1, + ], + [ + 26, + "支援", + "当周围一圈的怪物受到攻击时将上前支援,并组成小队战斗。", + "#77c0b6", + 1, + ], + [ + 27, + "捕捉", + function (enemy) { + return ( + "当走到怪物周围" + + (enemy.zoneSquare ? "九宫格" : "十字") + + "时会强制进行战斗。" + ); + }, + "#c0ddbb", + ], ]; }, "getEnemyInfo": function (enemy, hero, x, y, floorId) { // 获得某个怪物变化后的数据;该函数将被伤害计算和怪物手册使用 // 例如:坚固、模仿、仿攻等等 - // + // // 参数说明: // enemy:该怪物信息 // hero_hp,hero_atk,hero_def,hero_mdef:勇士的生命攻防护盾数据 @@ -528,18 +762,25 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // floorId:该怪物所在的楼层 // 后面三个参数主要是可以在光环等效果上可以适用(也可以按需制作部分范围光环效果) floorId = floorId || core.status.floorId; - var hero_hp = core.getRealStatusOrDefault(hero, 'hp'), - hero_atk = core.getRealStatusOrDefault(hero, 'atk'), - hero_def = core.getRealStatusOrDefault(hero, 'def'), - hero_mdef = core.getRealStatusOrDefault(hero, 'mdef'); - - var mon_hp = core.getEnemyValue(enemy, 'hp', x, y, floorId), - mon_atk = core.getEnemyValue(enemy, 'atk', x, y, floorId), - mon_def = core.getEnemyValue(enemy, 'def', x, y, floorId), - mon_special = core.getEnemyValue(enemy, 'special', x, y, floorId); - var mon_money = core.getEnemyValue(enemy, 'money', x, y, floorId), - mon_exp = core.getEnemyValue(enemy, 'exp', x, y, floorId), - mon_point = core.getEnemyValue(enemy, 'point', x, y, floorId); + var hero_hp = core.getRealStatusOrDefault(hero, "hp"), + hero_atk = core.getRealStatusOrDefault(hero, "atk"), + hero_def = core.getRealStatusOrDefault(hero, "def"), + hero_mdef = core.getRealStatusOrDefault(hero, "mdef"), + hero_speed = core.getRealStatusOrDefault(hero, "speed"); + var mon_id = core.getEnemyValue(enemy, "id", x, y, floorId), + mon_name = core.getEnemyValue(enemy, "name", x, y, floorId); + var mon_hp = core.getEnemyValue(enemy, "hp", x, y, floorId), + mon_atk = core.getEnemyValue(enemy, "atk", x, y, floorId), + mon_def = core.getEnemyValue(enemy, "def", x, y, floorId), + mon_mdef = core.getEnemyValue(enemy, "mdef", x, y, floorId) || 0, + mon_spell = core.getEnemyValue(enemy, "spell", x, y, floorId) || 0, + mon_speed = core.getEnemyValue(enemy, "speed", x, y, floorId) || 1, + mon_special = core.getEnemyValue(enemy, "special", x, y, floorId); + var mon_money = core.getEnemyValue(enemy, "money", x, y, floorId), + mon_exp = core.getEnemyValue(enemy, "exp", x, y, floorId), + mon_point = core.getEnemyValue(enemy, "point", x, y, floorId); + var mon_barrier = 0, + mon_absorb_damage = 0; // 模仿 if (core.hasSpecial(mon_special, 10)) { mon_atk = hero_atk; @@ -563,7 +804,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 已经计算过的光环怪ID列表,用于判定叠加 var usedEnemyIds = {}; // 检查光环和支援的缓存 - var index = x != null && y != null ? (x + "," + y) : floorId; + var index = x != null && y != null ? x + "," + y : floorId; if (!core.status.checkBlock.cache) core.status.checkBlock.cache = {}; var cache = core.status.checkBlock.cache[index]; if (!cache) { @@ -583,7 +824,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = dy = Math.abs(block.y - y); // 检查十字和九宫格光环 if (dx + dy <= enemy.haloRange) inRange = true; - if (enemy.haloSquare && dx <= enemy.haloRange && dy <= enemy.haloRange) inRange = true; + if ( + enemy.haloSquare && + dx <= enemy.haloRange && + dy <= enemy.haloRange + ) + inRange = true; } // 检查是否可叠加 if (inRange && (enemy.haloAdd || !usedEnemyIds[enemy.id])) { @@ -594,10 +840,17 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } // 检查【支援】技能,数字26 - if (enemy && core.hasSpecial(enemy.special, 26) && + if ( + enemy && + core.hasSpecial(enemy.special, 26) && // 检查支援条件,坐标存在,距离为1,且不能是自己 // 其他类型的支援怪,比如十字之类的话.... 看着做是一样的 - x != null && y != null && Math.abs(block.x - x) <= 1 && Math.abs(block.y - y) <= 1 && !(x == block.x && y == block.y)) { + x != null && + y != null && + Math.abs(block.x - x) <= 1 && + Math.abs(block.y - y) <= 1 && + !(x == block.x && y == block.y) + ) { // 记录怪物的x,y,ID guards.push([block.x, block.y, id]); } @@ -607,7 +860,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } }); - core.status.checkBlock.cache[index] = { "hp_buff": hp_buff, "atk_buff": atk_buff, "def_buff": def_buff, "guards": guards }; + core.status.checkBlock.cache[index] = { + hp_buff: hp_buff, + atk_buff: atk_buff, + def_buff: def_buff, + guards: guards, + }; } else { // 直接使用缓存数据 hp_buff = cache.hp_buff; @@ -617,9 +875,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } // 增加比例;如果要增加数值可以直接在这里修改 - mon_hp *= (1 + hp_buff / 100); - mon_atk *= (1 + atk_buff / 100); - mon_def *= (1 + def_buff / 100); + mon_hp *= 1 + hp_buff / 100; + mon_atk *= 1 + atk_buff / 100; + mon_def *= 1 + def_buff / 100; } // TODO:可以在这里新增其他的怪物数据变化 @@ -630,19 +888,26 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 也可以按需增加各种自定义内容 return { - "hp": Math.floor(mon_hp), - "atk": Math.floor(mon_atk), - "def": Math.floor(mon_def), - "money": Math.floor(mon_money), - "exp": Math.floor(mon_exp), - "point": Math.floor(mon_point), - "special": mon_special, - "guards": guards, // 返回支援情况 + id: mon_id, + name: mon_name, + hp: Math.floor(mon_hp), + atk: Math.floor(mon_atk), + def: Math.floor(mon_def), + mdef: Math.floor(mon_mdef), + spell: Math.floor(mon_spell), + speed: Math.floor(mon_speed), + barrier: Math.floor(mon_barrier), + absorb: Math.floor(mon_absorb_damage), + money: Math.floor(mon_money), + exp: Math.floor(mon_exp), + point: Math.floor(mon_point), + special: mon_special, + guards: guards, // 返回支援情况 }; }, "getDamageInfo": function (enemy, hero, x, y, floorId) { // 获得战斗伤害信息(实际伤害计算函数) - // + // // 参数说明: // enemy:该怪物信息 // hero:勇士的当前数据;如果对应项不存在则会从core.status.hero中取。 @@ -651,43 +916,76 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 后面三个参数主要是可以在光环等效果上可以适用 floorId = floorId || core.status.floorId; - var hero_hp = core.getRealStatusOrDefault(hero, 'hp'), - hero_atk = core.getRealStatusOrDefault(hero, 'atk'), - hero_def = core.getRealStatusOrDefault(hero, 'def'), - hero_mdef = core.getRealStatusOrDefault(hero, 'mdef'), - origin_hero_hp = core.getStatusOrDefault(hero, 'hp'), - origin_hero_atk = core.getStatusOrDefault(hero, 'atk'), - origin_hero_def = core.getStatusOrDefault(hero, 'def'); - - // 勇士的负属性都按0计算 - hero_hp = Math.max(0, hero_hp); - hero_atk = Math.max(0, hero_atk); - hero_def = Math.max(0, hero_def); - hero_mdef = Math.max(0, hero_mdef); + var hero_hp = core.getRealStatusOrDefault(hero, "hp"), + hero_atk = core.getRealStatusOrDefault(hero, "atk"), + hero_def = core.getRealStatusOrDefault(hero, "def"), + hero_matk = core.getRealStatusOrDefault(hero, "matk"), + hero_mdef = core.getRealStatusOrDefault(hero, "mdef"), + hero_mhp = core.getRealStatusOrDefault(hero, "mhp"), + hero_speed = core.getRealStatusOrDefault(hero, "speed"), + hero_spell = core.getRealStatusOrDefault(hero, "spell"), + origin_hero_hp = core.getStatusOrDefault(hero, "hp"), + origin_hero_atk = core.getStatusOrDefault(hero, "atk"), + origin_hero_def = core.getStatusOrDefault(hero, "def"); + //编辑器特判 + if (main.mode == "editor") { + hero_hp = hero?.hp ?? core.status.hero.hp, + hero_atk = hero?.atk ?? core.status.hero.atk, + hero_def = hero?.def ?? core.status.hero.def, + hero_matk = hero?.matk ?? core.status.hero.matk, + hero_mdef = hero?.mdef ?? core.status.hero.mdef, + hero_mhp = hero?.mhp ?? core.status.hero.mhp, + hero_speed = hero?.speed ?? core.status.hero.speed, + hero_spell = hero?.spell ?? core.status.hero.spell; + } // 怪物的各项数据 // 对坚固模仿等处理扔到了脚本编辑-getEnemyInfo之中 var enemyInfo = core.enemys.getEnemyInfo(enemy, hero, x, y, floorId); var mon_hp = enemyInfo.hp, mon_atk = enemyInfo.atk, mon_def = enemyInfo.def, - mon_special = enemyInfo.special; - + mon_mdef = enemyInfo.mdef, + mon_spell = enemyInfo.spell, + mon_speed = enemyInfo.speed, + mon_special = enemyInfo.special, + mon_absorb_damage = enemyInfo.absorb, + mon_barrier = enemyInfo.barrier; + const { lcm, gcd } = core.plugin.utils + const equip0 = core.getEquip(0) + //---第一部分:静态属性修正--- + //此处写入静态影响勇士属性的勇士或怪物技能(静态影响怪物属性的技能于getEnemyInfo中写入) // 技能的处理 - if (core.getFlag('skill', 0) == 1) { // 开启了技能1:二倍斩 - hero_atk *= 2; // 计算时攻击力翻倍 + if (core.getFlag("skill", 0) == 1) { + // 开启了技能1:二倍斩 + hero_atk *= 2; // 计算时攻击力翻倍 } + // 破甲 + if (core.hasSpecial(mon_special, 7)) + hero_def -= Math.floor( + (enemy.breakArmor || core.values.breakArmor) * hero_def + ); + + //勇士属性取整 + hero_atk = Math.max(0, Math.floor(hero_atk)); + hero_def = Math.max(0, Math.floor(hero_def)); + hero_speed = Math.max(0, Math.floor(hero_speed)); + hero_spell = Math.max(0, Math.floor(hero_spell)); + hero_matk = Math.min(100, Math.max(0, Math.floor(hero_matk))); + hero_mdef = Math.min(100, Math.max(0, Math.floor(hero_mdef))); + hero_mhp = Math.min(100, Math.max(0, Math.floor(hero_mhp))); + // 如果是无敌属性,且勇士未持有十字架 if (core.hasSpecial(mon_special, 20) && !core.hasItem("cross")) return null; // 不可战斗 // 战前造成的额外伤害(可被护盾抵消) - var init_damage = 0; + let init_damage = 0; // 吸血 if (core.hasSpecial(mon_special, 11)) { - var vampire_damage = hero_hp * enemy.vampire; + let vampire_damage = hero_hp * enemy.vampire; // 如果有神圣盾免疫吸血等可以在这里写 // 也可以用hasItem和hasEquip来判定装备 @@ -695,105 +993,333 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = vampire_damage = Math.floor(vampire_damage) || 0; // 加到自身 - if (enemy.add) // 如果加到自身 + if (enemy.add) + // 如果加到自身 mon_hp += vampire_damage; init_damage += vampire_damage; } - // 每回合怪物对勇士造成的战斗伤害 - var per_damage = mon_atk - hero_def; + //——第二部分:变量定义和初始赋值—— - // 战斗伤害不能为负值 - if (per_damage < 0) per_damage = 0; + let hero_per_damage = Math.max(hero_atk - mon_def, 0), - // 连击 - if (core.hasSpecial(mon_special, 6)) per_damage *= (enemy.n || 2); + hero_per_mdamage = Math.floor((hero_spell * hero_matk / 100) * (100 - mon_mdef) / 100); - // 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合 - var counterDamage = 0; - if (core.hasSpecial(mon_special, 8)) - counterDamage += Math.floor((enemy.counterAttack || core.values.counterAttack) * hero_atk); + let damage = 0, + hero_turn = 0, + mon_turn = 0; + let equipInfo = [] //回合生效的装备列表 - // 先攻 - if (core.hasSpecial(mon_special, 1)) init_damage += per_damage; + for (let i = 0; i < 5; i++) { + const a = core.plugin.equip[core.getEquip(i)] + if (a) equipInfo.push(a) + } - // 破甲 - if (core.hasSpecial(mon_special, 7)) - init_damage += Math.floor((enemy.breakArmor || core.values.breakArmor) * hero_def); - - // 净化 - if (core.hasSpecial(mon_special, 9)) - init_damage += Math.floor((enemy.purify || core.values.purify) * hero_mdef); - - // 勇士每回合对怪物造成的伤害 - var hero_per_damage = Math.max(hero_atk - mon_def, 0); - - // 如果没有破防,则不可战斗 - if (hero_per_damage <= 0) return null; - - // 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整 - var turn = Math.ceil(mon_hp / hero_per_damage); - - // ------ 支援 ----- // - // 这个递归最好想明白为什么,flag:__extraTurn__是怎么用的 - var guards = core.getFlag("__guards__" + x + "_" + y, enemyInfo.guards); - var guard_before_current_enemy = false; // ------ 支援怪是先打(true)还是后打(false)? - turn += core.getFlag("__extraTurn__", 0); - if (guards.length > 0) { - if (!guard_before_current_enemy) { // --- 先打当前怪物,记录当前回合数 - core.setFlag("__extraTurn__", turn); + //处理回合条长度 + let oneTurn = [hero_speed, mon_speed]; + if (equipInfo.length > 0) { + for (let i = 0; i < equipInfo.length; i++) { + equipInfo[i].now = 0; + equipInfo[i].isAttack = false; + oneTurn.push(equipInfo[i].speed); } - // 获得那些怪物组成小队战斗 - for (var i = 0; i < guards.length; i++) { - var gx = guards[i][0], - gy = guards[i][1], - gid = guards[i][2]; - // 递归计算支援怪伤害信息,这里不传x,y保证不会重复调用 - // 这里的mdef传0,因为护盾应该只会被计算一次 - var info = core.enemys.getDamageInfo(core.material.enemys[gid], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); - if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null - core.removeFlag("__extraTurn__"); - return null; + } + //需要变更 + + const onegcd = gcd(...oneTurn) //最大公约数 + oneTurn = lcm(...oneTurn) //单次回合长度 + //在这里处理equip的初始位置now + equipInfo.forEach(v => { + switch (v.id) { + case "sword1": + default: + v.now = 0 + break + } + v.onAttack = false + if (v.now === oneTurn) v.onAttack = true //增加正在攻击的标志 + }) + const heroinfo = { hp: hero_hp, atk: hero_atk, def: hero_def, mdef: (!hero?.mdef || hero?.mdef === 100) ? hero_mdef : hero.mdef, spell: hero_spell, mhp: Math.floor(hero_spell * hero_mhp / 100), matk: Math.floor(hero_spell * hero_matk / 100), speed: hero_speed, now: 0, isAttack: false } //勇士属性 + const enemyinfo = { hp: mon_hp, atk: mon_atk, def: mon_def, mdef: mon_mdef, spell: mon_spell, speed: mon_speed, special: mon_special, now: 0, onAttack: false, isAttack: false } //怪物属性 + //先攻,先攻为怪物和勇士勇士行动前怪物出第一刀 + if (core.hasSpecial(mon_special, 1)) { + enemyinfo.now = oneTurn + enemyinfo.onAttack = true + } + const start = [core.clone(heroinfo), core.clone(enemyinfo), core.clone(equipInfo), oneTurn, onegcd] //记录开始战斗时的属性并转发 + //---第三部分:递归开始--- + + const heroDiffList = [], + enemyDiffList = [], + heroanimateList = [], + enemyanimateList = []; + + let beforehp = enemyinfo.hp + while ( + enemyinfo.hp > 0 + ) { + let onattack = false + const hero_diff = {}, + enemy_diff = {}, + hero_animate = [], + enemy_animate = []; + + if (enemyinfo.onAttack) { //怪物先攻的场合 + //这里计算怪物攻击时发生的各种变化,同时计入enemy_diff + let mon_damage = 0 + let hero_damage = 0 + //伤害计算 + let per_damage = Math.max(enemyinfo.atk - heroinfo.def, 0), + per_mdamage = Math.floor(enemyinfo.spell * (100 - heroinfo.mdef) / 100); + + //这里记录伤害触发后的属性变化和动画,同时计入diff、damage(不要在此直接修改heroinfo和enemyinfo) + if (core.hasSpecial(mon_special, 6)) { + hero_damage += per_damage * enemy.n + per_mdamage * enemy.n + } else { + hero_damage += per_damage + per_mdamage } - // 已经进行的回合数 - core.setFlag("__extraTurn__", info.turn); - init_damage += info.damage; + let animate = core.plugin.enemyanimate[enemy.id] ?? "sword" + //这里可通过if更改默认的怪物攻击特效 + hero_animate.push(animate) //勇士身上绘制sword动画 + if (heroinfo.mhp + (hero_diff.mhp ?? 0) - hero_damage >= 0) { + hero_diff.mhp = (hero_diff.mhp ?? 0) - hero_damage + hero_damage = 0 + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } else { + hero_damage -= heroinfo.mhp + (hero_diff.mhp ?? 0) + hero_diff.mhp = (hero_diff.mhp ?? 0) - heroinfo.mhp - (hero_diff.mhp ?? 0) + + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } + + damage += hero_damage + enemyinfo.onAttack = false + enemyinfo.now = 0 + onattack = true } - if (guard_before_current_enemy) { // --- 先打支援怪物,增加当前回合数 - turn += core.getFlag("__extraTurn__", 0); + equipInfo.forEach(v => { + if (v.onAttack) { + let mon_damage = 0 + let hero_damage = 0 + //这里写生效装备的技能效果,同时对双方属性的修改计入diff(不要在此直接修改heroinfo和enemyinfo) + let animate = core.plugin.equipanimate[v.id] ?? "sword" + //这里可通过if更改默认的道具特效 + enemy_animate.push(animate) //勇士身上绘制动画 + + v.now = 0 + v.onAttack = false + onattack = true + } + }) + if (onattack) { //先手处理完毕后的数据处理 + heroDiffList.push(hero_diff) + enemyDiffList.push(enemy_diff) + heroanimateList.push(hero_animate) + enemyanimateList.push(enemy_animate) + //处理属性变化 + for (let v in hero_diff) { + heroinfo[v] += hero_diff[v] + } + for (let v in enemy_diff) { + enemyinfo[v] += enemy_diff[v] + } + continue //进入下一循环 } + heroinfo.now += heroinfo.speed + enemyinfo.now += enemyinfo.speed + equipInfo.forEach(v => { + v.now += v.speed + }) + + if ( + heroinfo.now >= oneTurn + ) { + //勇士攻击的回合 + let mon_damage = 0 + let hero_damage = 0 + //这里计算勇士攻击时发生的各种变化 + + //伤害计算 + let per_damage = Math.max(heroinfo.atk - enemyinfo.def, 0) + let per_mdamage = Math.max(Math.floor(heroinfo.matk * (100 - enemyinfo.mdef) / 100), 0) + mon_damage = per_damage + per_mdamage + //这里记录伤害触发后的属性变化和动画,同时计入diff(不要在此直接修改heroinfo和enemyinfo) + let animate = core.plugin.heroanimate[equip0] ?? "sword" + //这里可通过if更改默认的武器攻击特效 + enemy_animate.push(animate) + + + enemy_diff.hp = (enemy_diff.hp ?? 0) - mon_damage + heroinfo.now -= oneTurn + hero_turn++ + onattack = true + } + + + if (enemyinfo.now >= oneTurn) { + //怪物攻击的回合 + let mon_damage = 0 + let hero_damage = 0 + //伤害计算 + let per_damage = Math.max(enemyinfo.atk - heroinfo.def, 0), + per_mdamage = Math.floor(enemyinfo.spell * (100 - heroinfo.mdef) / 100); + + //这里记录伤害触发后的属性变化和动画,同时计入diff、damage(不要在此直接修改heroinfo和enemyinfo) + if (core.hasSpecial(mon_special, 6)) { + hero_damage += per_damage * enemy.n + per_mdamage * enemy.n + } else { + hero_damage += per_damage + per_mdamage + } + let animate = core.plugin.enemyanimate[enemy.id] ?? "sword" + //这里可通过if更改默认的怪物攻击特效 + hero_animate.push(animate) //勇士身上绘制sword动画 + if (heroinfo.mhp + (hero_diff.mhp ?? 0) - hero_damage >= 0) { + hero_diff.mhp = (hero_diff.mhp ?? 0) - hero_damage + hero_damage = 0 + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } else { + hero_damage -= heroinfo.mhp + (hero_diff.mhp ?? 0) + hero_diff.mhp = (hero_diff.mhp ?? 0) - heroinfo.mhp - (hero_diff.mhp ?? 0) + + hero_diff.hp = (hero_diff.hp ?? 0) - hero_damage + } + + damage += hero_damage + enemyinfo.now -= oneTurn + mon_turn++ + onattack = true + } + equipInfo.forEach(v => { + if (v.now >= oneTurn) { + let mon_damage = 0 + let hero_damage = 0 + //这里写生效装备的技能效果,同时对双方属性的修改计入diff(不要在此直接修改heroinfo和enemyinfo) + let animate = core.plugin.equipanimate[v.id] ?? "sword" + //这里可通过if更改默认的道具特效 + enemy_animate.push(animate) //怪物身上绘制动画 + + v.now -= oneTurn + onattack = true + } + + }) + + //处理完毕后的数据处理 + heroDiffList.push(hero_diff) + enemyDiffList.push(enemy_diff) + heroanimateList.push(hero_animate) + enemyanimateList.push(enemy_animate) + //处理属性变化 + for (let v in hero_diff) { + heroinfo[v] += hero_diff[v] + } + for (let v in enemy_diff) { + enemyinfo[v] += enemy_diff[v] + } + + //出手50回合怪物生命未降低直接判负,避免死循环 + if (hero_turn === 50) { + + if (enemyinfo.hp >= beforehp) { + return null + } + } + } - core.removeFlag("__extraTurn__"); + + //下面这些还没修改,原有技能除先攻、连击外暂时全部移除,所有技能需要在上方的模拟循环中做修正 + /* + // 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合 + let counterDamage = 0; + if (core.hasSpecial(mon_special, 8)) + counterDamage += Math.floor( + (enemy.counterAttack || core.values.counterAttack) * hero_atk + ); + + + + // 净化 + if (core.hasSpecial(mon_special, 9)) + init_damage += Math.floor( + (enemy.purify || core.values.purify) * hero_mdef + ); + //上面这些还没修改 + //勇士护盾计算 + let barrier = Math.floor(hero_spell * hero_mhp / 100); + + + // ------ 支援 ----- // + // 这个递归最好想明白为什么,flag:__extraTurn__是怎么用的 + /*var guards = core.getFlag("__guards__" + x + "_" + y, enemyInfo.guards); + var guard_before_current_enemy = false; // ------ 支援怪是先打(true)还是后打(false)? + turn += core.getFlag("__extraTurn__", 0); + if (guards.length > 0) { + if (!guard_before_current_enemy) { // --- 先打当前怪物,记录当前回合数 + core.setFlag("__extraTurn__", turn); + } + // 获得那些怪物组成小队战斗 + for (var i = 0; i < guards.length; i++) { + var gx = guards[i][0], + gy = guards[i][1], + gid = guards[i][2]; + // 递归计算支援怪伤害信息,这里不传x,y保证不会重复调用 + // 这里的mdef传0,因为护盾应该只会被计算一次 + var info = core.enemys.getDamageInfo(core.material.enemys[gid], { hp: origin_hero_hp, atk: origin_hero_atk, def: origin_hero_def, mdef: 0 }); + if (info == null) { // 小队中任何一个怪物不可战斗,直接返回null + core.removeFlag("__extraTurn__"); + return null; + } + // 已经进行的回合数 + core.setFlag("__extraTurn__", info.turn); + init_damage += info.damage; + } + if (guard_before_current_enemy) { // --- 先打支援怪物,增加当前回合数 + turn += core.getFlag("__extraTurn__", 0); + } + } + core.removeFlag("__extraTurn__");*/ // ------ 支援END ------ // + /* + // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 + damage += init_damage + hero_turn * counterDamage; + // 再扣去护盾 + damage -= barrier; - // 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害 - var damage = init_damage + (turn - 1) * per_damage + turn * counterDamage; - // 再扣去护盾 - damage -= hero_mdef; - - // 检查是否允许负伤 - if (!core.flags.enableNegativeDamage) - damage = Math.max(0, damage); - - // 最后处理仇恨和固伤(因为这两个不能被护盾减伤) - if (core.hasSpecial(mon_special, 17)) { // 仇恨 - damage += core.getFlag('hatred', 0); - } - if (core.hasSpecial(mon_special, 22)) { // 固伤 - damage += enemy.damage || 0; - } + // 检查是否允许负伤 + if (!core.flags.enableNegativeDamage) damage = Math.max(0, damage); + // 最后处理仇恨和固伤(因为这两个不能被护盾减伤) + if (core.hasSpecial(mon_special, 17)) { + // 仇恨 + damage += core.getFlag("hatred", 0); + } + if (core.hasSpecial(mon_special, 22)) { + // 固伤 + damage += enemy.damage2 || 0; + } + */ return { - "mon_hp": Math.floor(mon_hp), - "mon_atk": Math.floor(mon_atk), - "mon_def": Math.floor(mon_def), - "init_damage": Math.floor(init_damage), - "per_damage": Math.floor(per_damage), - "hero_per_damage": Math.floor(hero_per_damage), - "turn": Math.floor(turn), - "damage": Math.floor(damage) + start: start, + mon_hp: Math.floor(mon_hp), + mon_atk: Math.floor(mon_atk), + mon_def: Math.floor(mon_def), + mon_mdef: Math.floor(mon_mdef), + mon_speed: Math.floor(mon_speed), + heroDiffList: heroDiffList, + enemyDiffList: enemyDiffList, + heroanimateList: heroanimateList, + enemyanimateList: enemyanimateList, + hero_turn: Math.floor(hero_turn), + mon_turn: Math.floor(mon_turn), + damage: Math.floor(damage) }; + /*TODO:怪物手册的修改(需要修改这里return的内容以及一些战后判断) + 1. 显示怪物是魔攻还是物攻(在怪物名字上做颜色变化,物攻是黄色,魔攻是蓝色) + 2. 一防减伤是物防还是魔防(由怪物是物攻还是魔攻来转换) + 3. 特殊战斗的怪物,在怪物手册里“伤害”写为“特殊战”*/ + /*TODO:怪物和勇士同时跑条到终点时,谁先出手的逻辑确定 + 怪物、勇士和装备同时跑条时的计算*/ } }, "actions": { @@ -807,7 +1333,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.isMoving()) return; // 商店长按时忽略 - if (core.status.onShopLongDown) return core.status.onShopLongDown = false; + if (core.status.onShopLongDown) + return (core.status.onShopLongDown = false); // Alt+0~9,快捷换上套装 if (altKey && keyCode >= 48 && keyCode <= 57) { @@ -824,7 +1351,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.openBook(true); break; case 71: // G:使用楼传器 - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + flags.canMoveFloor = core.canMoveFloor(); + core.useItem('fly', true) + core.status.route.push("key:71"); break; case 65: // A:读取自动存档(回退) core.doSL("autoSave", "load"); @@ -882,25 +1411,37 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.actions._clickGameInfo_openComments(); break; case 49: // 快捷键1: 破 - if (core.hasItem('pickaxe')) { + if (core.hasItem("pickaxe")) { core.status.route.push("key:49"); // 将按键记在录像中 - core.useItem('pickaxe', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像 + core.useItem("pickaxe", true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像 } break; case 50: // 快捷键2: 炸 - if (core.hasItem('bomb')) { + if (core.hasItem("bomb")) { core.status.route.push("key:50"); // 将按键记在录像中 - core.useItem('bomb', true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像 + core.useItem("bomb", true); // 第二个参数true代表该次使用道具是被按键触发的,使用过程不计入录像 } break; case 51: // 快捷键3: 飞 - if (core.hasItem('centerFly')) { + if (core.hasItem("centerFly")) { core.ui._drawCenterFly(); } break; case 52: // 快捷键4:破冰/冰冻/地震/上下楼器/... 其他道具依次判断 { - var list = ["icePickaxe", "freezeBadge", "earthquake", "upFly", "downFly", "jumpShoes", "lifeWand", "poisonWine", "weakWine", "curseWine", "superWine"]; + var list = [ + "icePickaxe", + "freezeBadge", + "earthquake", + "upFly", + "downFly", + "jumpShoes", + "lifeWand", + "poisonWine", + "weakWine", + "curseWine", + "superWine", + ]; for (var i = 0; i < list.length; i++) { var itemId = list[i]; if (core.canUseItem(itemId)) { @@ -926,9 +1467,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = break; case 70: // F:开启技能“二倍斩” // 检测是否拥有“二倍斩”这个技能道具 - if (core.hasItem('skill1')) { + if (core.hasItem("skill1")) { core.status.route.push("key:70"); - core.useItem('skill1', true); + core.useItem("skill1", true); } break; // 在这里可以任意新增或编辑已有的快捷键内容 @@ -946,33 +1487,32 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = break; */ } - }, "onStatusBarClick": function (px, py, vertical) { - // 点击状态栏时触发的事件,仅在自绘状态栏开启时生效 - // px和py为点击的像素坐标 - // vertical为录像播放过程中的横竖屏信息 - // - // 横屏模式下状态栏的画布大小是 129*416 (开启拓展装备栏后是 129*457) - // 竖屏模式下状态栏的画布大小是 416*(32*rows+9) 其中rows为状态栏行数,即全塔属性中statusCanvasRowsOnMobile值 - // 可以使用 _isVertical() 来判定当前是否是竖屏模式 + // 点击状态栏时触发的事件,仅在自绘状态栏开启时生效 + // px和py为点击的像素坐标 + // vertical为录像播放过程中的横竖屏信息 + // + // 横屏模式下状态栏的画布大小是 129*416 (开启拓展装备栏后是 129*457) + // 竖屏模式下状态栏的画布大小是 416*(32*rows+9) 其中rows为状态栏行数,即全塔属性中statusCanvasRowsOnMobile值 + // 可以使用 _isVertical() 来判定当前是否是竖屏模式 - // 判定当前是否是竖屏模式。录像播放过程中可能会记录当时的横竖屏信息以覆盖。 - var _isVertical = function () { - if (core.isReplaying() && vertical != null) return vertical; - return core.domStyle.isVertical; - } + // 判定当前是否是竖屏模式。录像播放过程中可能会记录当时的横竖屏信息以覆盖。 + var _isVertical = function () { + if (core.isReplaying() && vertical != null) return vertical; + return core.domStyle.isVertical; + }; - // 如果正在执行事件,则忽略 - if (core.status.lockControl) return; - // 如果当前正在行走,则忽略;也可以使用 core.waitHeroToStop(callback) 来停止行走再回调执行脚本 - if (core.isMoving()) return; + // 如果正在执行事件,则忽略 + if (core.status.lockControl) return; + // 如果当前正在行走,则忽略;也可以使用 core.waitHeroToStop(callback) 来停止行走再回调执行脚本 + if (core.isMoving()) return; - // 判定px和py来执行自己的脚本内容.... 注意横竖屏 - // console.log("onStatusBarClick: ", px, py, _isVertical()); + // 判定px和py来执行自己的脚本内容.... 注意横竖屏 + // console.log("onStatusBarClick: ", px, py, _isVertical()); - // 样例一:点击某个区域后使用一个道具 - /* + // 样例一:点击某个区域后使用一个道具 + /* if (core.hasItem("pickaxe")) { if (_isVertical()) { // 竖屏模式下 @@ -988,8 +1528,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } */ - // 样例二:点击某个区域后执行一段公共事件或脚本 - /* + // 样例二:点击某个区域后执行一段公共事件或脚本 + /* if (core.hasFlag("xxx")) { if (_isVertical()) { // 竖屏模式下 @@ -1014,160 +1554,177 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } */ - - } + } }, "control": { "saveData": function () { - // 存档操作,此函数应该返回“具体要存档的内容” + // 存档操作,此函数应该返回“具体要存档的内容” - // 差异化存储values - var values = {}; - for (var key in core.values) { - if (!core.same(core.values[key], core.data.values[key])) - values[key] = core.clone(core.values[key]); - } + // 差异化存储values + var values = {}; + for (var key in core.values) { + if (!core.same(core.values[key], core.data.values[key])) + values[key] = core.clone(core.values[key]); + } - // 要存档的内容 - var data = { - 'floorId': core.status.floorId, - 'hero': core.clone(core.status.hero), - 'hard': core.status.hard, - 'maps': core.clone(core.maps.saveMap()), - 'route': core.encodeRoute(core.status.route), - 'values': values, - 'version': core.firstData.version, - 'guid': core.getGuid(), - "time": new Date().getTime() - }; - return data; -}, + // 要存档的内容 + var data = { + floorId: core.status.floorId, + hero: core.clone(core.status.hero), + hard: core.status.hard, + maps: core.clone(core.maps.saveMap()), + route: core.encodeRoute(core.status.route), + values: values, + version: core.firstData.version, + guid: core.getGuid(), + time: new Date().getTime(), + 'material': core.clone(core.material.enemys) + }; + return data; + }, "loadData": function (data, callback) { - // 读档操作;从存储中读取了内容后的行为 - const play = core.status.played - // 重置游戏和路线 - core.resetGame(data.hero, data.hard, data.floorId, core.maps.loadMap(data.maps, null, data.hero.flags), data.values); - core.status.route = core.decodeRoute(data.route); - core.control._bindRoutePush(); - // 文字属性,全局属性 - core.status.textAttribute = core.getFlag('textAttribute', core.status.textAttribute); - var toAttribute = core.getFlag('globalAttribute', core.status.globalAttribute); - if (!core.same(toAttribute, core.status.globalAttribute)) { - core.status.globalAttribute = toAttribute; - core.resize(); - } - // 重置音量 - core.events.setVolume(core.getFlag("__volume__", 1), 0); - // 加载勇士图标 - var icon = core.status.hero.image; - icon = core.getMappedName(icon); - if (core.material.images.images[icon]) { - core.material.images.hero = core.material.images.images[icon]; - core.material.icons.hero.width = core.material.images.images[icon].width / 4; - core.material.icons.hero.height = core.material.images.images[icon].height / 4; - } - core.setFlag('__fromLoad__', true); + // 读档操作;从存储中读取了内容后的行为 + const play = core.status.played; + // 重置游戏和路线 + core.resetGame( + data.hero, + data.hard, + data.floorId, + core.maps.loadMap(data.maps, null, data.hero.flags), + data.values + ); + //如果作者造塔想随时修改怪物属性平衡数值,请注释下面这行。该行作用为保存怪物当前属性,用以储存临时修改的怪物属性。 + core.material.enemys = data.material ?? core.material.enemys; + core.status.route = core.decodeRoute(data.route); + core.control._bindRoutePush(); + // 文字属性,全局属性 + core.status.textAttribute = core.getFlag( + "textAttribute", + core.status.textAttribute + ); + var toAttribute = core.getFlag( + "globalAttribute", + core.status.globalAttribute + ); + if (!core.same(toAttribute, core.status.globalAttribute)) { + core.status.globalAttribute = toAttribute; + core.resize(); + } + // 重置音量 + core.events.setVolume(core.getFlag("__volume__", 1), 0); + // 加载勇士图标 + var icon = core.status.hero.image; + icon = core.getMappedName(icon); + if (core.material.images.images[icon]) { + core.material.images.hero = core.material.images.images[icon]; + core.material.icons.hero.width = + core.material.images.images[icon].width / 4; + core.material.icons.hero.height = + core.material.images.images[icon].height / 4; + } + core.setFlag("__fromLoad__", true); - // TODO:增加自己的一些读档处理 - core.ui.statusBar.clearItemInfo() - core.ui.statusBar.update(); - core.plugin.playing.clear() - // 切换到对应的楼层 - core.changeFloor(data.floorId, null, data.hero.loc, 0, function () { - // TODO:可以在这里设置读档后播放BGM - if (core.hasFlag("__bgm__")) { // 持续播放 - core.playBgm(core.getFlag("__bgm__")); - } + // TODO:增加自己的一些读档处理 + core.ui.statusBar.clearItemInfo(); + core.ui.statusBar.update(); + core.plugin.playing.clear(); + // 切换到对应的楼层 + core.changeFloor(data.floorId, null, data.hero.loc, 0, function () { + // TODO:可以在这里设置读档后播放BGM + if (core.hasFlag("__bgm__")) { + // 持续播放 + core.playBgm(core.getFlag("__bgm__")); + } - core.removeFlag('__fromLoad__'); - if (!play) core.insertCommonEvent('强制横屏') - if (callback) callback(); - }); - if (play) core.doAction() - - -}, + core.removeFlag("__fromLoad__"); + if (!play) core.insertCommonEvent("强制横屏"); + if (callback) callback(); + }); + if (play) core.doAction(); + }, "getStatusLabel": function (name) { - // 返回某个状态英文名的对应中文标签,如atk -> 攻击,def -> 防御等。 - // 请注意此项仅影响 libs/ 下的内容(如绘制怪物手册、数据统计等) - // 自行定义的(比如获得道具效果)中用到的“攻击+3”等需要自己去对应地方修改 + // 返回某个状态英文名的对应中文标签,如atk -> 攻击,def -> 防御等。 + // 请注意此项仅影响 libs/ 下的内容(如绘制怪物手册、数据统计等) + // 自行定义的(比如获得道具效果)中用到的“攻击+3”等需要自己去对应地方修改 - return { - name: "名称", - lv: "等级", - hpmax: "生命上限", - hp: "生命", - manamax: "魔力上限", - mana: "魔力", - atk: "攻击", - def: "防御", - mdef: "护盾", - money: "金币", - exp: "经验", - point: "加点", - steps: "步数", - }[name] || name; - }, + return ({ + name: "名称", + lv: "等级", + hpmax: "生命上限", + hp: "生命", + manamax: "魔力上限", + mana: "魔力", + atk: "攻击", + def: "防御", + spell: "法强", + matk: "魔攻比例", + mhp: "护盾比例", + mdef: "法抗", + speed: "速度", + money: "金币", + exp: "经验", + point: "加点", + steps: "步数", + } [name] || name); +}, "triggerDebuff": function (action, type) { - // 毒衰咒效果的获得与解除 - // action:获得还是解除;'get'表示获得,'remove'表示解除 - // type:一个数组表示获得了哪些毒衰咒效果;poison, weak,curse - if (!(type instanceof Array)) type = [type]; + // 毒衰咒效果的获得与解除 + // action:获得还是解除;'get'表示获得,'remove'表示解除 + // type:一个数组表示获得了哪些毒衰咒效果;poison, weak,curse + if (!(type instanceof Array)) type = [type]; - if (action == 'get') { - if (core.inArray(type, 'poison') && !core.hasFlag("poison")) { - // 获得毒效果 - core.setFlag('poison', true); - } - if (core.inArray(type, 'weak') && !core.hasFlag('weak')) { - // 获得衰效果 - core.setFlag('weak', true); - if (core.values.weakValue >= 1) { - // >=1,直接扣数值 - core.addStatus('atk', -core.values.weakValue); - core.addStatus('def', -core.values.weakValue); - } else { - // <1,扣比例 - core.addBuff('atk', -core.values.weakValue); - core.addBuff('def', -core.values.weakValue); - } - } - if (core.inArray(type, 'curse') && !core.hasFlag('curse')) { - // 获得咒效果 - core.setFlag('curse', true); - } - } else if (action == 'remove') { - var success = false; - if (core.inArray(type, "poison") && core.hasFlag("poison")) { - success = true; - // 移除毒效果 - core.setFlag("poison", false); - } - if (core.inArray(type, "weak") && core.hasFlag("weak")) { - success = true; - // 移除衰效果 - core.setFlag("weak", false); - if (core.values.weakValue >= 1) { - // >=1,直接扣数值 - core.addStatus('atk', core.values.weakValue); - core.addStatus('def', core.values.weakValue); - } else { - // <1,扣比例 - core.addBuff('atk', core.values.weakValue); - core.addBuff('def', core.values.weakValue); - } - } - if (core.inArray(type, "curse") && core.hasFlag("curse")) { - success = true; - // 移除咒效果 - core.setFlag("curse", false); - } - if (success) core.playSound('回血'); - } - }, + if (action == "get") { + if (core.inArray(type, "poison") && !core.hasFlag("poison")) { + // 获得毒效果 + core.setFlag("poison", true); + } + if (core.inArray(type, "weak") && !core.hasFlag("weak")) { + // 获得衰效果 + core.setFlag("weak", true); + if (core.values.weakValue >= 1) { + // >=1,直接扣数值 + core.addStatus("atk", -core.values.weakValue); + core.addStatus("def", -core.values.weakValue); + } else { + // <1,扣比例 + core.addBuff("atk", -core.values.weakValue); + core.addBuff("def", -core.values.weakValue); + } + } + if (core.inArray(type, "curse") && !core.hasFlag("curse")) { + // 获得咒效果 + core.setFlag("curse", true); + } + } else if (action == "remove") { + var success = false; + if (core.inArray(type, "poison") && core.hasFlag("poison")) { + success = true; + // 移除毒效果 + core.setFlag("poison", false); + } + if (core.inArray(type, "weak") && core.hasFlag("weak")) { + success = true; + // 移除衰效果 + core.setFlag("weak", false); + if (core.values.weakValue >= 1) { + // >=1,直接扣数值 + core.addStatus("atk", core.values.weakValue); + core.addStatus("def", core.values.weakValue); + } else { + // <1,扣比例 + core.addBuff("atk", core.values.weakValue); + core.addBuff("def", core.values.weakValue); + } + } + if (core.inArray(type, "curse") && core.hasFlag("curse")) { + success = true; + // 移除咒效果 + core.setFlag("curse", false); + } + if (success) core.playSound("回血"); + } + }, "updateStatusBar": function () { - //更新属性映射 - core.updateStatus() // 更新状态栏 core.ui.statusBar.update(); // 更新阻激夹域的伤害值 @@ -1176,216 +1733,257 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.updateDamage(); }, "updateCheckBlock": function (floorId) { - // 领域、夹击、阻击等的伤害值计算 - floorId = floorId || core.status.floorId; - if (!floorId || !core.status.maps) return; + // 领域、夹击、阻击等的伤害值计算 + floorId = floorId || core.status.floorId; + if (!floorId || !core.status.maps) return; - var width = core.floors[floorId].width, - height = core.floors[floorId].height; - var blocks = core.getMapBlocksObj(floorId); + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + var blocks = core.getMapBlocksObj(floorId); - var damage = {}, // 每个点的伤害值 - type = {}, // 每个点的伤害类型 - repulse = {}, // 每个点的阻击怪信息 - ambush = {}; // 每个点的捕捉信息 - var betweenAttackLocs = {}; // 所有可能的夹击点 - var needCache = false; - var canGoDeadZone = core.flags.canGoDeadZone; - core.flags.canGoDeadZone = true; + var damage = {}, // 每个点的伤害值 + type = {}, // 每个点的伤害类型 + repulse = {}, // 每个点的阻击怪信息 + ambush = {}; // 每个点的捕捉信息 + var betweenAttackLocs = {}; // 所有可能的夹击点 + var needCache = false; + var canGoDeadZone = core.flags.canGoDeadZone; + core.flags.canGoDeadZone = true; - // 计算血网和领域、阻击、激光的伤害,计算捕捉信息 - for (var loc in blocks) { - var block = blocks[loc], - x = block.x, - y = block.y, - id = block.event.id, - enemy = core.material.enemys[id]; - if (block.disable) continue; + // 计算血网和领域、阻击、激光的伤害,计算捕捉信息 + for (var loc in blocks) { + var block = blocks[loc], + x = block.x, + y = block.y, + id = block.event.id, + enemy = core.material.enemys[id]; + if (block.disable) continue; - type[loc] = type[loc] || {}; + type[loc] = type[loc] || {}; - // 血网 - // 如需调用当前楼层的ratio可使用 core.status.maps[floorId].ratio - if (id == 'lavaNet' && !core.hasItem('amulet')) { - damage[loc] = (damage[loc] || 0) + core.values.lavaDamage; - type[loc][(block.event.name || "血网") + "伤害"] = true; - } + // 血网 + // 如需调用当前楼层的ratio可使用 core.status.maps[floorId].ratio + if (id == "lavaNet" && !core.hasItem("amulet")) { + damage[loc] = (damage[loc] || 0) + core.values.lavaDamage; + type[loc][(block.event.name || "血网") + "伤害"] = true; + } - // 领域 - // 如果要防止领域伤害,可以直接简单的将 flag:no_zone 设为true - if (enemy && core.hasSpecial(enemy.special, 15) && !core.hasFlag('no_zone')) { - // 领域范围,默认为1 - var range = enemy.range || 1; - // 是否是九宫格领域 - var zoneSquare = false; - if (enemy.zoneSquare != null) zoneSquare = enemy.zoneSquare; - // 在范围内进行搜索,增加领域伤害值 - for (var dx = -range; dx <= range; dx++) { - for (var dy = -range; dy <= range; dy++) { - if (dx == 0 && dy == 0) continue; - var nx = x + dx, - ny = y + dy, - currloc = nx + "," + ny; - if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; - // 如果是十字领域,则还需要满足 |dx|+|dy|<=range - if (!zoneSquare && Math.abs(dx) + Math.abs(dy) > range) continue; - damage[currloc] = (damage[currloc] || 0) + (enemy.zone || 0); - type[currloc] = type[currloc] || {}; - type[currloc]["领域伤害"] = true; - } - } - } + // 领域 + // 如果要防止领域伤害,可以直接简单的将 flag:no_zone 设为true + if ( + enemy && + core.hasSpecial(enemy.special, 15) && + !core.hasFlag("no_zone") + ) { + // 领域范围,默认为1 + var range = enemy.range || 1; + // 是否是九宫格领域 + var zoneSquare = false; + if (enemy.zoneSquare != null) zoneSquare = enemy.zoneSquare; + // 在范围内进行搜索,增加领域伤害值 + for (var dx = -range; dx <= range; dx++) { + for (var dy = -range; dy <= range; dy++) { + if (dx == 0 && dy == 0) continue; + var nx = x + dx, + ny = y + dy, + currloc = nx + "," + ny; + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + // 如果是十字领域,则还需要满足 |dx|+|dy|<=range + if (!zoneSquare && Math.abs(dx) + Math.abs(dy) > range) continue; + damage[currloc] = (damage[currloc] || 0) + (enemy.zone || 0); + type[currloc] = type[currloc] || {}; + type[currloc]["领域伤害"] = true; + } + } + } - // 阻击 - // 如果要防止阻击伤害,可以直接简单的将 flag:no_repulse 设为true - if (enemy && core.hasSpecial(enemy.special, 18) && !core.hasFlag('no_repulse')) { - var scan = enemy.zoneSquare ? core.utils.scan2 : core.utils.scan; - for (var dir in scan) { - var nx = x + scan[dir].x, - ny = y + scan[dir].y, - currloc = nx + "," + ny; - if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; - damage[currloc] = (damage[currloc] || 0) + (enemy.repulse || 0); - type[currloc] = type[currloc] || {}; - type[currloc]["阻击伤害"] = true; + // 阻击 + // 如果要防止阻击伤害,可以直接简单的将 flag:no_repulse 设为true + if ( + enemy && + core.hasSpecial(enemy.special, 18) && + !core.hasFlag("no_repulse") + ) { + var scan = enemy.zoneSquare ? core.utils.scan2 : core.utils.scan; + for (var dir in scan) { + var nx = x + scan[dir].x, + ny = y + scan[dir].y, + currloc = nx + "," + ny; + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + damage[currloc] = (damage[currloc] || 0) + (enemy.repulse || 0); + type[currloc] = type[currloc] || {}; + type[currloc]["阻击伤害"] = true; - var rdir = core.turnDirection(":back", dir); - // 检查下一个点是否存在事件(从而判定是否移动) - var rnx = x + scan[rdir].x, - rny = y + scan[rdir].y; - if (rnx < 0 || rnx >= width || rny < 0 || rny >= height) continue; - // 如需禁止阻击被推到已隐藏的事件处(如重生怪处),可将这一句的false改为true - if (core.getBlock(rnx, rny, floorId, false) != null) continue; - if (core.utils.scan[rdir] && !core.canMoveHero(x, y, rdir, floorId)) continue; - repulse[currloc] = (repulse[currloc] || []).concat([ - [x, y, id, rdir] - ]); - } - } + var rdir = core.turnDirection(":back", dir); + // 检查下一个点是否存在事件(从而判定是否移动) + var rnx = x + scan[rdir].x, + rny = y + scan[rdir].y; + if (rnx < 0 || rnx >= width || rny < 0 || rny >= height) continue; + // 如需禁止阻击被推到已隐藏的事件处(如重生怪处),可将这一句的false改为true + if (core.getBlock(rnx, rny, floorId, false) != null) continue; + if (core.utils.scan[rdir] && !core.canMoveHero(x, y, rdir, floorId)) + continue; + repulse[currloc] = (repulse[currloc] || []).concat([ + [x, y, id, rdir], + ]); + } + } - // 激光 - // 如果要防止激光伤害,可以直接简单的将 flag:no_laser 设为true - if (enemy && core.hasSpecial(enemy.special, 24) && !core.hasFlag("no_laser")) { - for (var nx = 0; nx < width; nx++) { - var currloc = nx + "," + y; - if (nx != x) { - damage[currloc] = (damage[currloc] || 0) + (enemy.laser || 0); - type[currloc] = type[currloc] || {}; - type[currloc]["激光伤害"] = true; - } - } - for (var ny = 0; ny < height; ny++) { - var currloc = x + "," + ny; - if (ny != y) { - damage[currloc] = (damage[currloc] || 0) + (enemy.laser || 0); - type[currloc] = type[currloc] || {}; - type[currloc]["激光伤害"] = true; - } - } - } + // 激光 + // 如果要防止激光伤害,可以直接简单的将 flag:no_laser 设为true + if ( + enemy && + core.hasSpecial(enemy.special, 24) && + !core.hasFlag("no_laser") + ) { + for (var nx = 0; nx < width; nx++) { + var currloc = nx + "," + y; + if (nx != x) { + damage[currloc] = (damage[currloc] || 0) + (enemy.laser || 0); + type[currloc] = type[currloc] || {}; + type[currloc]["激光伤害"] = true; + } + } + for (var ny = 0; ny < height; ny++) { + var currloc = x + "," + ny; + if (ny != y) { + damage[currloc] = (damage[currloc] || 0) + (enemy.laser || 0); + type[currloc] = type[currloc] || {}; + type[currloc]["激光伤害"] = true; + } + } + } - // 捕捉 - // 如果要防止捕捉效果,可以直接简单的将 flag:no_ambush 设为true - if (enemy && core.enemys.hasSpecial(enemy.special, 27) && !core.hasFlag("no_ambush")) { - var scan = enemy.zoneSquare ? core.utils.scan2 : core.utils.scan; - // 给周围格子加上【捕捉】记号 - for (var dir in scan) { - var nx = x + scan[dir].x, - ny = y + scan[dir].y, - currloc = nx + "," + ny; - if (nx < 0 || nx >= width || ny < 0 || ny >= height || (core.utils.scan[dir] && !core.canMoveHero(x, y, dir, floorId))) continue; - ambush[currloc] = (ambush[currloc] || []).concat([ - [x, y, id, dir] - ]); - } - } + // 捕捉 + // 如果要防止捕捉效果,可以直接简单的将 flag:no_ambush 设为true + if ( + enemy && + core.enemys.hasSpecial(enemy.special, 27) && + !core.hasFlag("no_ambush") + ) { + var scan = enemy.zoneSquare ? core.utils.scan2 : core.utils.scan; + // 给周围格子加上【捕捉】记号 + for (var dir in scan) { + var nx = x + scan[dir].x, + ny = y + scan[dir].y, + currloc = nx + "," + ny; + if ( + nx < 0 || + nx >= width || + ny < 0 || + ny >= height || + (core.utils.scan[dir] && !core.canMoveHero(x, y, dir, floorId)) + ) + continue; + ambush[currloc] = (ambush[currloc] || []).concat([[x, y, id, dir]]); + } + } - // 夹击;在这里提前计算所有可能的夹击点,具体计算逻辑在下面 - // 如果要防止夹击伤害,可以简单的将 flag:no_betweenAttack 设为true - if (enemy && core.enemys.hasSpecial(enemy.special, 16) && !core.hasFlag('no_betweenAttack')) { - for (var dir in core.utils.scan) { - var nx = x + core.utils.scan[dir].x, - ny = y + core.utils.scan[dir].y, - currloc = nx + "," + ny; - if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; - betweenAttackLocs[currloc] = true; - } - } + // 夹击;在这里提前计算所有可能的夹击点,具体计算逻辑在下面 + // 如果要防止夹击伤害,可以简单的将 flag:no_betweenAttack 设为true + if ( + enemy && + core.enemys.hasSpecial(enemy.special, 16) && + !core.hasFlag("no_betweenAttack") + ) { + for (var dir in core.utils.scan) { + var nx = x + core.utils.scan[dir].x, + ny = y + core.utils.scan[dir].y, + currloc = nx + "," + ny; + if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue; + betweenAttackLocs[currloc] = true; + } + } - // 检查地图范围类技能 - var specialFlag = core.getSpecialFlag(enemy); - if (specialFlag & 1) needCache = true; - if (core.status.event.id == 'viewMaps') needCache = true; - if ((core.status.event.id == 'book' || core.status.event.id == 'bool-detail') && core.status.event.ui) needCache = true; - } + // 检查地图范围类技能 + var specialFlag = core.getSpecialFlag(enemy); + if (specialFlag & 1) needCache = true; + if (core.status.event.id == "viewMaps") needCache = true; + if ( + (core.status.event.id == "book" || + core.status.event.id == "bool-detail") && + core.status.event.ui + ) + needCache = true; + } - // 对每个可能的夹击点计算夹击伤害 - for (var loc in betweenAttackLocs) { - var xy = loc.split(","), - x = parseInt(xy[0]), - y = parseInt(xy[1]); - // 夹击怪物的ID - var enemyId1 = null, - enemyId2 = null; - // 检查左右夹击 - var leftBlock = blocks[(x - 1) + "," + y], - rightBlock = blocks[(x + 1) + "," + y]; - var leftId = core.getFaceDownId(leftBlock), - rightId = core.getFaceDownId(rightBlock); - if (leftBlock && !leftBlock.disable && rightBlock && !rightBlock.disable && leftId == rightId) { - if (core.hasSpecial(leftId, 16)) - enemyId1 = leftId; - } - // 检查上下夹击 - var topBlock = blocks[x + "," + (y - 1)], - bottomBlock = blocks[x + "," + (y + 1)]; - var topId = core.getFaceDownId(topBlock), - bottomId = core.getFaceDownId(bottomBlock); - if (topBlock && !topBlock.disable && bottomBlock && !bottomBlock.disable && topId == bottomId) { - if (core.hasSpecial(topId, 16)) - enemyId2 = topId; - } + // 对每个可能的夹击点计算夹击伤害 + for (var loc in betweenAttackLocs) { + var xy = loc.split(","), + x = parseInt(xy[0]), + y = parseInt(xy[1]); + // 夹击怪物的ID + var enemyId1 = null, + enemyId2 = null; + // 检查左右夹击 + var leftBlock = blocks[x - 1 + "," + y], + rightBlock = blocks[x + 1 + "," + y]; + var leftId = core.getFaceDownId(leftBlock), + rightId = core.getFaceDownId(rightBlock); + if ( + leftBlock && + !leftBlock.disable && + rightBlock && + !rightBlock.disable && + leftId == rightId + ) { + if (core.hasSpecial(leftId, 16)) enemyId1 = leftId; + } + // 检查上下夹击 + var topBlock = blocks[x + "," + (y - 1)], + bottomBlock = blocks[x + "," + (y + 1)]; + var topId = core.getFaceDownId(topBlock), + bottomId = core.getFaceDownId(bottomBlock); + if ( + topBlock && + !topBlock.disable && + bottomBlock && + !bottomBlock.disable && + topId == bottomId + ) { + if (core.hasSpecial(topId, 16)) enemyId2 = topId; + } - if (enemyId1 != null || enemyId2 != null) { - var leftHp = core.status.hero.hp - (damage[loc] || 0); - if (leftHp > 1) { - // 夹击伤害值 - var value = Math.floor(leftHp / 2); - // 是否不超过怪物伤害值 - if (core.flags.betweenAttackMax) { - var enemyDamage1 = core.getDamage(enemyId1, x, y, floorId); - if (enemyDamage1 != null && enemyDamage1 < value) - value = enemyDamage1; - var enemyDamage2 = core.getDamage(enemyId2, x, y, floorId); - if (enemyDamage2 != null && enemyDamage2 < value) - value = enemyDamage2; - } - if (value > 0) { - damage[loc] = (damage[loc] || 0) + value; - type[loc] = type[loc] || {}; - type[loc]["夹击伤害"] = true; - } - } - } - } + if (enemyId1 != null || enemyId2 != null) { + var leftHp = core.status.hero.hp - (damage[loc] || 0); + if (leftHp > 1) { + // 夹击伤害值 + var value = Math.floor(leftHp / 2); + // 是否不超过怪物伤害值 + if (core.flags.betweenAttackMax) { + var enemyDamage1 = core.getDamage(enemyId1, x, y, floorId); + if (enemyDamage1 != null && enemyDamage1 < value) + value = enemyDamage1; + var enemyDamage2 = core.getDamage(enemyId2, x, y, floorId); + if (enemyDamage2 != null && enemyDamage2 < value) + value = enemyDamage2; + } + if (value > 0) { + damage[loc] = (damage[loc] || 0) + value; + type[loc] = type[loc] || {}; + type[loc]["夹击伤害"] = true; + } + } + } + } - // 取消注释下面这一段可以让护盾抵御阻激夹域伤害 - /* + // 取消注释下面这一段可以让护盾抵御阻激夹域伤害 + /* for (var loc in damage) { damage[loc] = Math.max(0, damage[loc] - core.getRealStatus('mdef')); } */ - core.flags.canGoDeadZone = canGoDeadZone; - core.status.checkBlock = { - damage: damage, - type: type, - repulse: repulse, - ambush: ambush, - needCache: needCache, - cache: {} // clear cache - }; - }, + core.flags.canGoDeadZone = canGoDeadZone; + core.status.checkBlock = { + damage: damage, + type: type, + repulse: repulse, + ambush: ambush, + needCache: needCache, + cache: {}, // clear cache + }; + }, "moveOneStep": function (callback) { // 勇士每走一步后执行的操作。callback为行走完毕后的回调 // 这个函数执行在“刚走完”的时候,即还没有检查该点的事件和领域伤害等。 @@ -1400,7 +1998,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.updateFollowers(); core.drawHero(); // 检查中毒状态的扣血和死亡 - if (core.hasFlag('poison')) { + if (core.hasFlag("poison")) { core.status.hero.statistics.poisonDamage += core.values.poisonDamage; core.status.hero.hp -= core.values.poisonDamage; if (core.status.hero.hp <= 0) { @@ -1422,12 +2020,15 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // ------ 检查目标点事件 ------ // // 无事件的道具(如血瓶)需要优先于阻激夹域判定 - var nowx = core.getHeroLoc('x'), - nowy = core.getHeroLoc('y'); + var nowx = core.getHeroLoc("x"), + nowy = core.getHeroLoc("y"); var block = core.getBlock(nowx, nowy); var hasTrigger = false; - if (block != null && block.event.trigger == 'getItem' && - !core.floors[core.status.floorId].afterGetItem[nowx + "," + nowy]) { + if ( + block != null && + block.event.trigger == "getItem" && + !core.floors[core.status.floorId].afterGetItem[nowx + "," + nowy] + ) { hasTrigger = true; core.trigger(nowx, nowy, callback); } @@ -1435,13 +2036,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.checkBlock(); // 执行目标点的script和事件 - if (!hasTrigger) - core.trigger(nowx, nowy, callback); + if (!hasTrigger) core.trigger(nowx, nowy, callback); // 检查该点是否是滑冰 if (core.onSki()) { // 延迟到事件最后执行,因为这之前可能有阻激夹域动画 - core.insertAction({ "type": "moveAction" }, null, null, null, true); + core.insertAction({ type: "moveAction" }, null, null, null, true); } // ------ 检查目标点事件 END ------ // @@ -1457,19 +2057,23 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (ignoreSteps == null) ignoreSteps = core.canMoveDirectly(x, y); if (ignoreSteps >= 0) { // 中毒也允许瞬移 - if (core.hasFlag('poison')) { + if (core.hasFlag("poison")) { var damage = ignoreSteps * core.values.poisonDamage; if (damage >= core.status.hero.hp) return false; core.status.hero.statistics.poisonDamage += damage; core.status.hero.hp -= damage; } - core.clearMap('hero'); - if ((core.bigmap.width * 32) === (core.bigmap.height * 32) && (core.bigmap.width * 32) === core.__PIXELS__) core.addPopMove(32 * core.status.hero.loc.x + 16, 32 * core.status.hero.loc.y + 16, 32 * x + 16, 32 * y + 16) + core.clearMap("hero"); + if ( + core.bigmap.width * 32 === core.bigmap.height * 32 && + core.bigmap.width * 32 === core.__PIXELS__ + ) + if (core.getFlag('popmove')) core.addPopMove(32 * core.status.hero.loc.x + 16, 32 * core.status.hero.loc.y + 16, 32 * x + 16, 32 * y + 16); // 获得勇士最后的朝向 var lastDirection = core.status.route[core.status.route.length - 1]; - if (['left', 'right', 'up', 'down'].indexOf(lastDirection) >= 0) - core.setHeroLoc('direction', lastDirection); + if (["left", "right", "up", "down"].indexOf(lastDirection) >= 0) + core.setHeroLoc("direction", lastDirection); // 设置坐标,并绘制 core.control._moveDirectyFollowers(x, y); core.status.hero.loc.x = x; @@ -1480,7 +2084,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 统计信息 core.status.hero.statistics.moveDirectly++; core.status.hero.statistics.ignoreSteps += ignoreSteps; - if (core.hasFlag('poison')) { + if (core.hasFlag("poison")) { core.updateStatusBar(false, true); } @@ -1490,148 +2094,266 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return false; }, "parallelDo": function (timestamp) { - // 并行事件处理,可以在这里写任何需要并行处理的脚本或事件 - // 该函数将被系统反复执行,每次执行间隔视浏览器或设备性能而定,一般约为16.6ms一次 - // 参数timestamp为“从游戏资源加载完毕到当前函数执行时”的时间差,以毫秒为单位 + // 并行事件处理,可以在这里写任何需要并行处理的脚本或事件 + // 该函数将被系统反复执行,每次执行间隔视浏览器或设备性能而定,一般约为16.6ms一次 + // 参数timestamp为“从游戏资源加载完毕到当前函数执行时”的时间差,以毫秒为单位 - // 检查当前是否处于游戏开始状态 - if (!core.isPlaying()) return; + // 检查当前是否处于游戏开始状态 + if (!core.isPlaying()) return; - // 执行当前楼层的并行事件处理 - if (core.status.floorId) { - try { - eval(core.floors[core.status.floorId].parallelDo); - } catch (e) { - console.error(e); - } - } - } + // 执行当前楼层的并行事件处理 + if (core.status.floorId) { + try { + eval(core.floors[core.status.floorId].parallelDo); + } catch (e) { + console.error(e); + } + } + } }, "ui": { "getToolboxItems": function (cls) { - // 获得道具栏中当前某类型道具的显示项和显示顺序 - // cls为道具类型,只可能是 tools, constants 和 equips - // 返回一个数组,代表当前某类型道具的显示内容和顺序 - // 默认按id升序排列,您可以取消下面的注释改为按名称排列 + // 获得道具栏中当前某类型道具的显示项和显示顺序 + // cls为道具类型,只可能是 tools, constants 和 equips + // 返回一个数组,代表当前某类型道具的显示内容和顺序 + // 默认按id升序排列,您可以取消下面的注释改为按名称排列 - return Object.keys(core.status.hero.items[cls] || {}) - .filter(function (id) { return !core.material.items[id].hideInToolbox; }) - .sort( /*function (id1, id2) { return core.material.items[id1].name <= core.material.items[id2].name ? -1 : 1 }*/ ); -}, + return Object.keys(core.status.hero.items[cls] || {}) + .filter(function (id) { + return !core.material.items[id].hideInToolbox; + }) + .sort(/*function (id1, id2) { return core.material.items[id1].name <= core.material.items[id2].name ? -1 : 1 }*/); + }, "drawStatusBar": function () { // 这真的是人能写出来的东西? - var ctx, fill = function (text, x, y, style) { - core.ui.setFont(ctx, (/\w+/.test(text) ? 'italic ' : '') + 'bold 18px Verdana'); - core.ui.fillBoldText(ctx, text, x, y, style); - }; - if (core.flags.statusCanvas) { // 系统开关「自绘状态栏」开启 - core.ui.clearMap(ctx = core.dom.statusCanvasCtx); // 清空状态栏 + var ctx, + fill = function (text, x, y, style) { + core.ui.setFont( + ctx, + (/\w+/.test(text) ? "italic " : "") + "bold 18px Verdana" + ); + core.ui.fillBoldText(ctx, text, x, y, style); + }; + if (core.flags.statusCanvas) { + // 系统开关「自绘状态栏」开启 + core.ui.clearMap((ctx = core.dom.statusCanvasCtx)); // 清空状态栏 core.ui.setFillStyle(ctx, core.status.globalAttribute.statusBarColor); - if (core.domStyle.isVertical) { // 竖屏 + if (core.domStyle.isVertical) { + // 竖屏 core.drawImage(ctx, core.statusBar.icons.floor, 6, 6, 25, 25); fill((core.status.thisMap || {}).name || "Loading", 42, 26); core.drawImage(ctx, core.statusBar.icons.hp, 137, 6, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('hp')), 173, 26); + fill(core.formatBigNumber(core.getRealStatus("hp")), 173, 26); core.drawImage(ctx, core.statusBar.icons.atk, 268, 6, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('atk')), 304, 26); + fill(core.formatBigNumber(core.getRealStatus("atk")), 304, 26); core.drawImage(ctx, core.statusBar.icons.def, 6, 38, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('def')), 42, 58); + fill(core.formatBigNumber(core.getRealStatus("def")), 42, 58); core.drawImage(ctx, core.statusBar.icons.mdef, 137, 38, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('mdef')), 173, 58); + fill(core.formatBigNumber(core.getRealStatus("mdef")), 173, 58); core.drawImage(ctx, core.statusBar.icons.money, 268, 38, 25, 25); fill(core.formatBigNumber(core.status.hero.money), 304, 58); core.drawImage(ctx, core.statusBar.icons.exp, 6, 70, 25, 25); fill(core.formatBigNumber(core.status.hero.exp), 42, 90); - } else if (!core.flags.hideLeftStatusBar) { // 横屏且未隐藏状态栏 + } else if (!core.flags.hideLeftStatusBar) { + // 横屏且未隐藏状态栏 core.drawImage(ctx, core.statusBar.icons.floor, 6, 9, 25, 25); fill((core.status.thisMap || {}).name || "Loading", 42, 29); core.drawImage(ctx, core.statusBar.icons.hp, 6, 43, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('hp')), 42, 63); + fill(core.formatBigNumber(core.getRealStatus("hp")), 42, 63); core.drawImage(ctx, core.statusBar.icons.atk, 6, 77, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('atk')), 42, 97); + fill(core.formatBigNumber(core.getRealStatus("atk")), 42, 97); core.drawImage(ctx, core.statusBar.icons.def, 6, 111, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('def')), 42, 131); + fill(core.formatBigNumber(core.getRealStatus("def")), 42, 131); core.drawImage(ctx, core.statusBar.icons.mdef, 6, 145, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('mdef')), 42, 165); + fill(core.formatBigNumber(core.getRealStatus("mdef")), 42, 165); core.drawImage(ctx, core.statusBar.icons.money, 6, 179, 25, 25); fill(core.formatBigNumber(core.status.hero.money), 42, 199); core.drawImage(ctx, core.statusBar.icons.exp, 6, 213, 25, 25); fill(core.formatBigNumber(core.status.hero.exp), 42, 233); - fill(core.setTwoDigits(core.itemCount('yellowKey')), 11, 267, '#FFCCAA'); - fill(core.setTwoDigits(core.itemCount('blueKey')), 46, 267, '#AAAADD'); - fill(core.setTwoDigits(core.itemCount('redKey')), 81, 267, '#FF8888'); + fill( + core.setTwoDigits(core.itemCount("yellowKey")), + 11, + 267, + "#FFCCAA" + ); + fill( + core.setTwoDigits(core.itemCount("blueKey")), + 46, + 267, + "#AAAADD" + ); + fill(core.setTwoDigits(core.itemCount("redKey")), 81, 267, "#FF8888"); } - } else if (core.flags.hideLeftStatusBar && !core.domStyle.isVertical) { // 横屏且隐藏状态栏 - if (!core.dymCanvas['status']) - core.ui.createCanvas('status', 0, 0, core._PX_, core._PY_, 66); // 刚好盖过显伤层 - core.ui.clearMap(ctx = core.dymCanvas['status']); + } else if (core.flags.hideLeftStatusBar && !core.domStyle.isVertical) { + // 横屏且隐藏状态栏 + if (!core.dymCanvas["status"]) + core.ui.createCanvas("status", 0, 0, core._PX_, core._PY_, 66); // 刚好盖过显伤层 + core.ui.clearMap((ctx = core.dymCanvas["status"])); core.ui.setFillStyle(ctx, core.status.globalAttribute.statusBarColor); - var offset = core.status.hero.loc.x - core.bigmap.offsetX / 32 >= core._HEIGHT_ ? 0 : core._PY_; + var offset = + core.status.hero.loc.x - core.bigmap.offsetX / 32 >= core._HEIGHT_ ? + 0 : + core._PY_; core.ui.setAlpha(ctx, 0.75); - core.ui.drawWindowSkin('winskin.webp', ctx, offset, 0, core._PX_ - core._PY_, core._PY_); + core.ui.drawWindowSkin( + "winskin.webp", + ctx, + offset, + 0, + core._PX_ - core._PY_, + core._PY_ + ); core.ui.setAlpha(ctx, 1); core.drawImage(ctx, core.statusBar.icons.floor, 6 + offset, 9, 25, 25); fill((core.status.thisMap || {}).name || "Loading", 42 + offset, 29); core.drawImage(ctx, core.statusBar.icons.hp, 6 + offset, 43, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('hp')), 42 + offset, 63); + fill(core.formatBigNumber(core.getRealStatus("hp")), 42 + offset, 63); core.drawImage(ctx, core.statusBar.icons.atk, 6 + offset, 77, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('atk')), 42 + offset, 97); + fill(core.formatBigNumber(core.getRealStatus("atk")), 42 + offset, 97); core.drawImage(ctx, core.statusBar.icons.def, 6 + offset, 111, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('def')), 42 + offset, 131); + fill(core.formatBigNumber(core.getRealStatus("def")), 42 + offset, 131); core.drawImage(ctx, core.statusBar.icons.mdef, 6 + offset, 145, 25, 25); - fill(core.formatBigNumber(core.getRealStatus('mdef')), 42 + offset, 165); - core.drawImage(ctx, core.statusBar.icons.money, 6 + offset, 179, 25, 25); + fill( + core.formatBigNumber(core.getRealStatus("mdef")), + 42 + offset, + 165 + ); + core.drawImage( + ctx, + core.statusBar.icons.money, + 6 + offset, + 179, + 25, + 25 + ); fill(core.formatBigNumber(core.status.hero.money), 42 + offset, 199); core.drawImage(ctx, core.statusBar.icons.exp, 6 + offset, 213, 25, 25); fill(core.formatBigNumber(core.status.hero.exp), 42 + offset, 233); - fill(core.setTwoDigits(core.itemCount('yellowKey')), 11 + offset, 267, '#FFCCAA'); - fill(core.setTwoDigits(core.itemCount('blueKey')), 46 + offset, 267, '#AAAADD'); - fill(core.setTwoDigits(core.itemCount('redKey')), 81 + offset, 267, '#FF8888'); + fill( + core.setTwoDigits(core.itemCount("yellowKey")), + 11 + offset, + 267, + "#FFCCAA" + ); + fill( + core.setTwoDigits(core.itemCount("blueKey")), + 46 + offset, + 267, + "#AAAADD" + ); + fill( + core.setTwoDigits(core.itemCount("redKey")), + 81 + offset, + 267, + "#FF8888" + ); } }, "drawStatistics": function () { - // 浏览地图时参与的统计项目 + // 浏览地图时参与的统计项目 - return [ - 'yellowDoor', 'blueDoor', 'redDoor', 'greenDoor', 'steelDoor', - 'yellowKey', 'blueKey', 'redKey', 'greenKey', 'steelKey', - 'redGem', 'blueGem', 'greenGem', 'yellowGem', - 'redPotion', 'bluePotion', 'greenPotion', 'yellowPotion', 'superPotion', - 'pickaxe', 'bomb', 'centerFly', 'icePickaxe', 'freezeBadge', - 'earthquake', 'upFly', 'downFly', 'jumpShoes', 'lifeWand', - 'poisonWine', 'weakWine', 'curseWine', 'superWine', - 'sword1', 'sword2', 'sword3', 'sword4', 'sword5', - 'shield1', 'shield2', 'shield3', 'shield4', 'shield5', - // 在这里可以增加新的ID来进行统计个数,只能增加道具ID - ]; - }, + return [ + "yellowDoor", + "blueDoor", + "redDoor", + "greenDoor", + "steelDoor", + "yellowKey", + "blueKey", + "redKey", + "greenKey", + "steelKey", + "redGem", + "blueGem", + "greenGem", + "yellowGem", + "redPotion", + "bluePotion", + "greenPotion", + "yellowPotion", + "superPotion", + "pickaxe", + "bomb", + "centerFly", + "icePickaxe", + "freezeBadge", + "earthquake", + "upFly", + "downFly", + "jumpShoes", + "lifeWand", + "poisonWine", + "weakWine", + "curseWine", + "superWine", + "sword1", + "sword2", + "sword3", + "sword4", + "sword5", + "shield1", + "shield2", + "shield3", + "shield4", + "shield5", + // 在这里可以增加新的ID来进行统计个数,只能增加道具ID + ]; + }, "drawAbout": function () { - // 绘制“关于”界面 - core.ui.closePanel(); - core.lockControl(); - core.status.event.id = 'about'; + // 绘制“关于”界面 + core.ui.closePanel(); + core.lockControl(); + core.status.event.id = "about"; - var left = 48, - top = 36, - right = (core._PX_ || core.__PIXELS__) - 2 * left, - bottom = (core._PY_ || core.__PIXELS__) - 2 * top; + var left = 48, + top = 36, + right = (core._PX_ || core.__PIXELS__) - 2 * left, + bottom = (core._PY_ || core.__PIXELS__) - 2 * top; - core.setAlpha('ui', 0.85); - core.fillRect('ui', left, top, right, bottom, '#000000'); - core.setAlpha('ui', 1); - core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); + core.setAlpha("ui", 0.85); + core.fillRect("ui", left, top, right, bottom, "#000000"); + core.setAlpha("ui", 1); + core.strokeRect( + "ui", + left - 1, + top - 1, + right + 1, + bottom + 1, + "#FFFFFF", + 2 + ); - var text_start = left + 24; + var text_start = left + 24; - // 名称 - core.setTextAlign('ui', 'left'); - var globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; - core.fillText('ui', "HTML5 魔塔样板", text_start, top + 35, globalAttribute.selectColor, "bold 22px " + globalAttribute.font); - core.fillText('ui', "版本: " + main.__VERSION__, text_start, top + 80, "#FFFFFF", "bold 17px " + globalAttribute.font); - core.fillText('ui', "作者: 艾之葵", text_start, top + 112); - core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top + 112 + 32); - // TODO: 写自己的“关于”页面,每次增加32像素即可 - core.playSound('打开界面'); - } + // 名称 + core.setTextAlign("ui", "left"); + var globalAttribute = + core.status.globalAttribute || core.initStatus.globalAttribute; + core.fillText( + "ui", + "HTML5 魔塔样板", + text_start, + top + 35, + globalAttribute.selectColor, + "bold 22px " + globalAttribute.font + ); + core.fillText( + "ui", + "版本: " + main.__VERSION__, + text_start, + top + 80, + "#FFFFFF", + "bold 17px " + globalAttribute.font + ); + core.fillText("ui", "作者: 艾之葵", text_start, top + 112); + core.fillText( + "ui", + "HTML5魔塔交流群:539113091", + text_start, + top + 112 + 32 + ); + // TODO: 写自己的“关于”页面,每次增加32像素即可 + core.playSound("打开界面"); + } } } \ No newline at end of file diff --git a/project/icons.js b/project/icons.js index f44bfe9..73914d5 100644 --- a/project/icons.js +++ b/project/icons.js @@ -113,7 +113,12 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "T392": 81, "T393": 82, "T394": 83, - "T395": 84 + "T395": 84, + "T361": 85, + "T362": 86, + "T363": 87, + "T364": 88, + "T365": 89 }, "animates": { "star": 0, @@ -310,7 +315,18 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 = "jumpShoes": 49, "skill1": 30, "wand": 10, - "pack": 46 + "pack": 46, + "I366": 5, + "I367": 7, + "I368": 26, + "I369": 31, + "I370": 32, + "I371": 34, + "I372": 35, + "I373": 36, + "I374": 37, + "I375": 38, + "I396": 39 }, "autotile": { "autotile": 0, diff --git a/project/images/005-Attack03.webp b/project/images/005-Attack03.webp new file mode 100644 index 0000000..09df0ff Binary files /dev/null and b/project/images/005-Attack03.webp differ diff --git a/project/images/012-Heal01.webp b/project/images/012-Heal01.webp new file mode 100644 index 0000000..23c2c6d Binary files /dev/null and b/project/images/012-Heal01.webp differ diff --git a/project/images/015-Fire01.webp b/project/images/015-Fire01.webp new file mode 100644 index 0000000..acd799f Binary files /dev/null and b/project/images/015-Fire01.webp differ diff --git a/project/images/LOGO.webp b/project/images/LOGO.webp new file mode 100644 index 0000000..890e5fd Binary files /dev/null and b/project/images/LOGO.webp differ diff --git a/project/images/backgroundvertical.webp b/project/images/backgroundvertical.webp index 95588f7..7968c21 100644 Binary files a/project/images/backgroundvertical.webp and b/project/images/backgroundvertical.webp differ diff --git a/project/images/bg_0000.png b/project/images/bg_0000.png new file mode 100644 index 0000000..dec8909 Binary files /dev/null and b/project/images/bg_0000.png differ diff --git a/project/images/bg_3021.webp b/project/images/bg_3021.webp new file mode 100644 index 0000000..c87f60b Binary files /dev/null and b/project/images/bg_3021.webp differ diff --git a/project/images/bg_3026.webp b/project/images/bg_3026.webp new file mode 100644 index 0000000..8bd0aa3 Binary files /dev/null and b/project/images/bg_3026.webp differ diff --git a/project/images/bg_3028.webp b/project/images/bg_3028.webp new file mode 100644 index 0000000..28fb42c Binary files /dev/null and b/project/images/bg_3028.webp differ diff --git a/project/images/bg_3512.webp b/project/images/bg_3512.webp new file mode 100644 index 0000000..9feaa2f Binary files /dev/null and b/project/images/bg_3512.webp differ diff --git a/project/images/bg_3522.webp b/project/images/bg_3522.webp new file mode 100644 index 0000000..da43179 Binary files /dev/null and b/project/images/bg_3522.webp differ diff --git a/project/images/bg_3561.webp b/project/images/bg_3561.webp new file mode 100644 index 0000000..96a778b Binary files /dev/null and b/project/images/bg_3561.webp differ diff --git a/project/images/bg_3602.webp b/project/images/bg_3602.webp new file mode 100644 index 0000000..19c22f8 Binary files /dev/null and b/project/images/bg_3602.webp differ diff --git a/project/images/bg_3801.webp b/project/images/bg_3801.webp new file mode 100644 index 0000000..57849f5 Binary files /dev/null and b/project/images/bg_3801.webp differ diff --git a/project/images/danqu.webp b/project/images/danqu.webp new file mode 100644 index 0000000..f38b54f Binary files /dev/null and b/project/images/danqu.webp differ diff --git a/project/images/face_030101.webp b/project/images/face_030101.webp new file mode 100644 index 0000000..46c41ed Binary files /dev/null and b/project/images/face_030101.webp differ diff --git a/project/images/face_030102.webp b/project/images/face_030102.webp new file mode 100644 index 0000000..c2b5ac7 Binary files /dev/null and b/project/images/face_030102.webp differ diff --git a/project/images/face_030103.webp b/project/images/face_030103.webp new file mode 100644 index 0000000..d314fca Binary files /dev/null and b/project/images/face_030103.webp differ diff --git a/project/images/face_030104.webp b/project/images/face_030104.webp new file mode 100644 index 0000000..6175ca9 Binary files /dev/null and b/project/images/face_030104.webp differ diff --git a/project/images/face_030105.webp b/project/images/face_030105.webp new file mode 100644 index 0000000..9935bfa Binary files /dev/null and b/project/images/face_030105.webp differ diff --git a/project/images/face_030107.webp b/project/images/face_030107.webp new file mode 100644 index 0000000..1c87a84 Binary files /dev/null and b/project/images/face_030107.webp differ diff --git a/project/images/face_030121.webp b/project/images/face_030121.webp new file mode 100644 index 0000000..a04c087 Binary files /dev/null and b/project/images/face_030121.webp differ diff --git a/project/images/face_030122.webp b/project/images/face_030122.webp new file mode 100644 index 0000000..19801ae Binary files /dev/null and b/project/images/face_030122.webp differ diff --git a/project/images/face_030123.webp b/project/images/face_030123.webp new file mode 100644 index 0000000..0fd9160 Binary files /dev/null and b/project/images/face_030123.webp differ diff --git a/project/images/face_030124.webp b/project/images/face_030124.webp new file mode 100644 index 0000000..ac6e273 Binary files /dev/null and b/project/images/face_030124.webp differ diff --git a/project/images/face_030125.webp b/project/images/face_030125.webp new file mode 100644 index 0000000..48eb565 Binary files /dev/null and b/project/images/face_030125.webp differ diff --git a/project/images/face_030127.webp b/project/images/face_030127.webp new file mode 100644 index 0000000..5bd993b Binary files /dev/null and b/project/images/face_030127.webp differ diff --git a/project/images/face_030129.webp b/project/images/face_030129.webp new file mode 100644 index 0000000..b71b74f Binary files /dev/null and b/project/images/face_030129.webp differ diff --git a/project/images/face_030131.webp b/project/images/face_030131.webp new file mode 100644 index 0000000..6faf82e Binary files /dev/null and b/project/images/face_030131.webp differ diff --git a/project/images/face_030132.webp b/project/images/face_030132.webp new file mode 100644 index 0000000..6d02061 Binary files /dev/null and b/project/images/face_030132.webp differ diff --git a/project/images/face_030141.webp b/project/images/face_030141.webp new file mode 100644 index 0000000..db4120e Binary files /dev/null and b/project/images/face_030141.webp differ diff --git a/project/images/face_030142.webp b/project/images/face_030142.webp new file mode 100644 index 0000000..bf889f3 Binary files /dev/null and b/project/images/face_030142.webp differ diff --git a/project/images/face_030143.webp b/project/images/face_030143.webp new file mode 100644 index 0000000..7d23764 Binary files /dev/null and b/project/images/face_030143.webp differ diff --git a/project/images/face_030144.webp b/project/images/face_030144.webp new file mode 100644 index 0000000..b53077e Binary files /dev/null and b/project/images/face_030144.webp differ diff --git a/project/images/face_030145.webp b/project/images/face_030145.webp new file mode 100644 index 0000000..3c55682 Binary files /dev/null and b/project/images/face_030145.webp differ diff --git a/project/images/face_050101.webp b/project/images/face_050101.webp new file mode 100644 index 0000000..10d4b8c Binary files /dev/null and b/project/images/face_050101.webp differ diff --git a/project/images/face_050102.webp b/project/images/face_050102.webp new file mode 100644 index 0000000..5c97cde Binary files /dev/null and b/project/images/face_050102.webp differ diff --git a/project/images/face_050103.webp b/project/images/face_050103.webp new file mode 100644 index 0000000..0d3d811 Binary files /dev/null and b/project/images/face_050103.webp differ diff --git a/project/images/face_050104.webp b/project/images/face_050104.webp new file mode 100644 index 0000000..0767d99 Binary files /dev/null and b/project/images/face_050104.webp differ diff --git a/project/images/face_050105.webp b/project/images/face_050105.webp new file mode 100644 index 0000000..21a2fe5 Binary files /dev/null and b/project/images/face_050105.webp differ diff --git a/project/images/face_050106.webp b/project/images/face_050106.webp new file mode 100644 index 0000000..8a3bc4e Binary files /dev/null and b/project/images/face_050106.webp differ diff --git a/project/images/face_050107.webp b/project/images/face_050107.webp new file mode 100644 index 0000000..f838238 Binary files /dev/null and b/project/images/face_050107.webp differ diff --git a/project/images/face_050108.webp b/project/images/face_050108.webp new file mode 100644 index 0000000..d330016 Binary files /dev/null and b/project/images/face_050108.webp differ diff --git a/project/images/face_050111.webp b/project/images/face_050111.webp new file mode 100644 index 0000000..e192d48 Binary files /dev/null and b/project/images/face_050111.webp differ diff --git a/project/images/face_050112.webp b/project/images/face_050112.webp new file mode 100644 index 0000000..ec560a3 Binary files /dev/null and b/project/images/face_050112.webp differ diff --git a/project/images/face_050113.webp b/project/images/face_050113.webp new file mode 100644 index 0000000..344da43 Binary files /dev/null and b/project/images/face_050113.webp differ diff --git a/project/images/face_050116.webp b/project/images/face_050116.webp new file mode 100644 index 0000000..1cea83d Binary files /dev/null and b/project/images/face_050116.webp differ diff --git a/project/images/face_050121.webp b/project/images/face_050121.webp new file mode 100644 index 0000000..1ae1b7b Binary files /dev/null and b/project/images/face_050121.webp differ diff --git a/project/images/face_050122.webp b/project/images/face_050122.webp new file mode 100644 index 0000000..b7b6467 Binary files /dev/null and b/project/images/face_050122.webp differ diff --git a/project/images/face_050123.webp b/project/images/face_050123.webp new file mode 100644 index 0000000..1e7c47a Binary files /dev/null and b/project/images/face_050123.webp differ diff --git a/project/images/face_050124.webp b/project/images/face_050124.webp new file mode 100644 index 0000000..fc5e21f Binary files /dev/null and b/project/images/face_050124.webp differ diff --git a/project/images/face_050125.webp b/project/images/face_050125.webp new file mode 100644 index 0000000..a5651ae Binary files /dev/null and b/project/images/face_050125.webp differ diff --git a/project/images/face_050126.webp b/project/images/face_050126.webp new file mode 100644 index 0000000..1f1d570 Binary files /dev/null and b/project/images/face_050126.webp differ diff --git a/project/images/face_050127.webp b/project/images/face_050127.webp new file mode 100644 index 0000000..ea1297d Binary files /dev/null and b/project/images/face_050127.webp differ diff --git a/project/images/face_050128.webp b/project/images/face_050128.webp new file mode 100644 index 0000000..8a191f7 Binary files /dev/null and b/project/images/face_050128.webp differ diff --git a/project/images/face_050129.webp b/project/images/face_050129.webp new file mode 100644 index 0000000..571b5ac Binary files /dev/null and b/project/images/face_050129.webp differ diff --git a/project/images/face_050130.webp b/project/images/face_050130.webp new file mode 100644 index 0000000..056379e Binary files /dev/null and b/project/images/face_050130.webp differ diff --git a/project/images/face_050131.webp b/project/images/face_050131.webp new file mode 100644 index 0000000..5a51170 Binary files /dev/null and b/project/images/face_050131.webp differ diff --git a/project/images/face_050132.webp b/project/images/face_050132.webp new file mode 100644 index 0000000..25d18fe Binary files /dev/null and b/project/images/face_050132.webp differ diff --git a/project/images/face_050134.webp b/project/images/face_050134.webp new file mode 100644 index 0000000..837fdd5 Binary files /dev/null and b/project/images/face_050134.webp differ diff --git a/project/images/face_050135.webp b/project/images/face_050135.webp new file mode 100644 index 0000000..a96d4db Binary files /dev/null and b/project/images/face_050135.webp differ diff --git a/project/images/face_050136.webp b/project/images/face_050136.webp new file mode 100644 index 0000000..0812a79 Binary files /dev/null and b/project/images/face_050136.webp differ diff --git a/project/images/face_050137.webp b/project/images/face_050137.webp new file mode 100644 index 0000000..38e6649 Binary files /dev/null and b/project/images/face_050137.webp differ diff --git a/project/images/face_050141.webp b/project/images/face_050141.webp new file mode 100644 index 0000000..04ac926 Binary files /dev/null and b/project/images/face_050141.webp differ diff --git a/project/images/face_050142.webp b/project/images/face_050142.webp new file mode 100644 index 0000000..adf6280 Binary files /dev/null and b/project/images/face_050142.webp differ diff --git a/project/images/face_050143.webp b/project/images/face_050143.webp new file mode 100644 index 0000000..ee524ca Binary files /dev/null and b/project/images/face_050143.webp differ diff --git a/project/images/face_050144.webp b/project/images/face_050144.webp new file mode 100644 index 0000000..8df7199 Binary files /dev/null and b/project/images/face_050144.webp differ diff --git a/project/images/face_050145.webp b/project/images/face_050145.webp new file mode 100644 index 0000000..63b24ee Binary files /dev/null and b/project/images/face_050145.webp differ diff --git a/project/images/face_050146.webp b/project/images/face_050146.webp new file mode 100644 index 0000000..bf2f02b Binary files /dev/null and b/project/images/face_050146.webp differ diff --git a/project/images/face_050147.webp b/project/images/face_050147.webp new file mode 100644 index 0000000..fa89346 Binary files /dev/null and b/project/images/face_050147.webp differ diff --git a/project/images/face_050148.webp b/project/images/face_050148.webp new file mode 100644 index 0000000..8b615eb Binary files /dev/null and b/project/images/face_050148.webp differ diff --git a/project/images/face_050150.webp b/project/images/face_050150.webp new file mode 100644 index 0000000..46e228a Binary files /dev/null and b/project/images/face_050150.webp differ diff --git a/project/images/face_050151.webp b/project/images/face_050151.webp new file mode 100644 index 0000000..5bab333 Binary files /dev/null and b/project/images/face_050151.webp differ diff --git a/project/images/face_050152.webp b/project/images/face_050152.webp new file mode 100644 index 0000000..3d2954f Binary files /dev/null and b/project/images/face_050152.webp differ diff --git a/project/images/face_050201.webp b/project/images/face_050201.webp new file mode 100644 index 0000000..12dd2ff Binary files /dev/null and b/project/images/face_050201.webp differ diff --git a/project/images/face_050202.webp b/project/images/face_050202.webp new file mode 100644 index 0000000..0114c03 Binary files /dev/null and b/project/images/face_050202.webp differ diff --git a/project/images/face_050203.webp b/project/images/face_050203.webp new file mode 100644 index 0000000..fbaff96 Binary files /dev/null and b/project/images/face_050203.webp differ diff --git a/project/images/face_050204.webp b/project/images/face_050204.webp new file mode 100644 index 0000000..2c256b4 Binary files /dev/null and b/project/images/face_050204.webp differ diff --git a/project/images/face_050205.webp b/project/images/face_050205.webp new file mode 100644 index 0000000..7df8178 Binary files /dev/null and b/project/images/face_050205.webp differ diff --git a/project/images/face_050206.webp b/project/images/face_050206.webp new file mode 100644 index 0000000..96ae26d Binary files /dev/null and b/project/images/face_050206.webp differ diff --git a/project/images/face_050210.webp b/project/images/face_050210.webp new file mode 100644 index 0000000..abed1e3 Binary files /dev/null and b/project/images/face_050210.webp differ diff --git a/project/images/face_050212.webp b/project/images/face_050212.webp new file mode 100644 index 0000000..0f59bfe Binary files /dev/null and b/project/images/face_050212.webp differ diff --git a/project/images/face_050213.webp b/project/images/face_050213.webp new file mode 100644 index 0000000..564bd98 Binary files /dev/null and b/project/images/face_050213.webp differ diff --git a/project/images/face_050214.webp b/project/images/face_050214.webp new file mode 100644 index 0000000..169a477 Binary files /dev/null and b/project/images/face_050214.webp differ diff --git a/project/images/face_050215.webp b/project/images/face_050215.webp new file mode 100644 index 0000000..b1df32f Binary files /dev/null and b/project/images/face_050215.webp differ diff --git a/project/images/face_050216.webp b/project/images/face_050216.webp new file mode 100644 index 0000000..15ffca8 Binary files /dev/null and b/project/images/face_050216.webp differ diff --git a/project/images/face_050221.webp b/project/images/face_050221.webp new file mode 100644 index 0000000..1ae1b7b Binary files /dev/null and b/project/images/face_050221.webp differ diff --git a/project/images/face_050222.webp b/project/images/face_050222.webp new file mode 100644 index 0000000..b7b6467 Binary files /dev/null and b/project/images/face_050222.webp differ diff --git a/project/images/face_050223.webp b/project/images/face_050223.webp new file mode 100644 index 0000000..1e7c47a Binary files /dev/null and b/project/images/face_050223.webp differ diff --git a/project/images/face_050224.webp b/project/images/face_050224.webp new file mode 100644 index 0000000..fc5e21f Binary files /dev/null and b/project/images/face_050224.webp differ diff --git a/project/images/face_050225.webp b/project/images/face_050225.webp new file mode 100644 index 0000000..a5651ae Binary files /dev/null and b/project/images/face_050225.webp differ diff --git a/project/images/face_050226.webp b/project/images/face_050226.webp new file mode 100644 index 0000000..1f1d570 Binary files /dev/null and b/project/images/face_050226.webp differ diff --git a/project/images/face_050229.webp b/project/images/face_050229.webp new file mode 100644 index 0000000..571b5ac Binary files /dev/null and b/project/images/face_050229.webp differ diff --git a/project/images/face_050230.webp b/project/images/face_050230.webp new file mode 100644 index 0000000..056379e Binary files /dev/null and b/project/images/face_050230.webp differ diff --git a/project/images/face_050232.webp b/project/images/face_050232.webp new file mode 100644 index 0000000..25d18fe Binary files /dev/null and b/project/images/face_050232.webp differ diff --git a/project/images/face_050234.webp b/project/images/face_050234.webp new file mode 100644 index 0000000..837fdd5 Binary files /dev/null and b/project/images/face_050234.webp differ diff --git a/project/images/face_050235.webp b/project/images/face_050235.webp new file mode 100644 index 0000000..a96d4db Binary files /dev/null and b/project/images/face_050235.webp differ diff --git a/project/images/face_050237.webp b/project/images/face_050237.webp new file mode 100644 index 0000000..38e6649 Binary files /dev/null and b/project/images/face_050237.webp differ diff --git a/project/images/face_050241.webp b/project/images/face_050241.webp new file mode 100644 index 0000000..04ac926 Binary files /dev/null and b/project/images/face_050241.webp differ diff --git a/project/images/face_050242.webp b/project/images/face_050242.webp new file mode 100644 index 0000000..adf6280 Binary files /dev/null and b/project/images/face_050242.webp differ diff --git a/project/images/face_050243.webp b/project/images/face_050243.webp new file mode 100644 index 0000000..ee524ca Binary files /dev/null and b/project/images/face_050243.webp differ diff --git a/project/images/face_050244.webp b/project/images/face_050244.webp new file mode 100644 index 0000000..8df7199 Binary files /dev/null and b/project/images/face_050244.webp differ diff --git a/project/images/face_050245.webp b/project/images/face_050245.webp new file mode 100644 index 0000000..63b24ee Binary files /dev/null and b/project/images/face_050245.webp differ diff --git a/project/images/face_050246.webp b/project/images/face_050246.webp new file mode 100644 index 0000000..bf2f02b Binary files /dev/null and b/project/images/face_050246.webp differ diff --git a/project/images/face_050249.webp b/project/images/face_050249.webp new file mode 100644 index 0000000..2f77e72 Binary files /dev/null and b/project/images/face_050249.webp differ diff --git a/project/images/face_050250.webp b/project/images/face_050250.webp new file mode 100644 index 0000000..46e228a Binary files /dev/null and b/project/images/face_050250.webp differ diff --git a/project/images/face_050252.webp b/project/images/face_050252.webp new file mode 100644 index 0000000..3d2954f Binary files /dev/null and b/project/images/face_050252.webp differ diff --git a/project/images/face_050301.webp b/project/images/face_050301.webp new file mode 100644 index 0000000..8ed9e9c Binary files /dev/null and b/project/images/face_050301.webp differ diff --git a/project/images/face_050302.webp b/project/images/face_050302.webp new file mode 100644 index 0000000..dc5c9db Binary files /dev/null and b/project/images/face_050302.webp differ diff --git a/project/images/face_050303.webp b/project/images/face_050303.webp new file mode 100644 index 0000000..993e16a Binary files /dev/null and b/project/images/face_050303.webp differ diff --git a/project/images/face_050304.webp b/project/images/face_050304.webp new file mode 100644 index 0000000..8be3448 Binary files /dev/null and b/project/images/face_050304.webp differ diff --git a/project/images/face_050305.webp b/project/images/face_050305.webp new file mode 100644 index 0000000..caeaa80 Binary files /dev/null and b/project/images/face_050305.webp differ diff --git a/project/images/face_050306.webp b/project/images/face_050306.webp new file mode 100644 index 0000000..f84a944 Binary files /dev/null and b/project/images/face_050306.webp differ diff --git a/project/images/face_050307.webp b/project/images/face_050307.webp new file mode 100644 index 0000000..908a9bf Binary files /dev/null and b/project/images/face_050307.webp differ diff --git a/project/images/face_050308.webp b/project/images/face_050308.webp new file mode 100644 index 0000000..d716999 Binary files /dev/null and b/project/images/face_050308.webp differ diff --git a/project/images/face_050309.webp b/project/images/face_050309.webp new file mode 100644 index 0000000..3c7799f Binary files /dev/null and b/project/images/face_050309.webp differ diff --git a/project/images/face_050310.webp b/project/images/face_050310.webp new file mode 100644 index 0000000..47ff979 Binary files /dev/null and b/project/images/face_050310.webp differ diff --git a/project/images/face_050311.webp b/project/images/face_050311.webp new file mode 100644 index 0000000..5302cd3 Binary files /dev/null and b/project/images/face_050311.webp differ diff --git a/project/images/face_050313.webp b/project/images/face_050313.webp new file mode 100644 index 0000000..797d3d1 Binary files /dev/null and b/project/images/face_050313.webp differ diff --git a/project/images/face_050314.webp b/project/images/face_050314.webp new file mode 100644 index 0000000..5e80e7d Binary files /dev/null and b/project/images/face_050314.webp differ diff --git a/project/images/face_050315.webp b/project/images/face_050315.webp new file mode 100644 index 0000000..c663bef Binary files /dev/null and b/project/images/face_050315.webp differ diff --git a/project/images/face_050316.webp b/project/images/face_050316.webp new file mode 100644 index 0000000..1d359df Binary files /dev/null and b/project/images/face_050316.webp differ diff --git a/project/images/face_050317.webp b/project/images/face_050317.webp new file mode 100644 index 0000000..4dce220 Binary files /dev/null and b/project/images/face_050317.webp differ diff --git a/project/images/face_050321.webp b/project/images/face_050321.webp new file mode 100644 index 0000000..533f0ea Binary files /dev/null and b/project/images/face_050321.webp differ diff --git a/project/images/face_050322.webp b/project/images/face_050322.webp new file mode 100644 index 0000000..5a03bc7 Binary files /dev/null and b/project/images/face_050322.webp differ diff --git a/project/images/face_050323.webp b/project/images/face_050323.webp new file mode 100644 index 0000000..dd02280 Binary files /dev/null and b/project/images/face_050323.webp differ diff --git a/project/images/face_050324.webp b/project/images/face_050324.webp new file mode 100644 index 0000000..4faa9a0 Binary files /dev/null and b/project/images/face_050324.webp differ diff --git a/project/images/face_050325.webp b/project/images/face_050325.webp new file mode 100644 index 0000000..a0378a5 Binary files /dev/null and b/project/images/face_050325.webp differ diff --git a/project/images/face_050326.webp b/project/images/face_050326.webp new file mode 100644 index 0000000..8d23302 Binary files /dev/null and b/project/images/face_050326.webp differ diff --git a/project/images/face_050327.webp b/project/images/face_050327.webp new file mode 100644 index 0000000..5350f93 Binary files /dev/null and b/project/images/face_050327.webp differ diff --git a/project/images/face_050328.webp b/project/images/face_050328.webp new file mode 100644 index 0000000..75b8723 Binary files /dev/null and b/project/images/face_050328.webp differ diff --git a/project/images/face_050329.webp b/project/images/face_050329.webp new file mode 100644 index 0000000..35f592d Binary files /dev/null and b/project/images/face_050329.webp differ diff --git a/project/images/face_050330.webp b/project/images/face_050330.webp new file mode 100644 index 0000000..9256890 Binary files /dev/null and b/project/images/face_050330.webp differ diff --git a/project/images/face_050331.webp b/project/images/face_050331.webp new file mode 100644 index 0000000..9d6e3fe Binary files /dev/null and b/project/images/face_050331.webp differ diff --git a/project/images/face_050332.webp b/project/images/face_050332.webp new file mode 100644 index 0000000..1ef6645 Binary files /dev/null and b/project/images/face_050332.webp differ diff --git a/project/images/face_050333.webp b/project/images/face_050333.webp new file mode 100644 index 0000000..f4c7896 Binary files /dev/null and b/project/images/face_050333.webp differ diff --git a/project/images/face_050334.webp b/project/images/face_050334.webp new file mode 100644 index 0000000..7bbeeda Binary files /dev/null and b/project/images/face_050334.webp differ diff --git a/project/images/face_050335.webp b/project/images/face_050335.webp new file mode 100644 index 0000000..0c4208e Binary files /dev/null and b/project/images/face_050335.webp differ diff --git a/project/images/face_050336.webp b/project/images/face_050336.webp new file mode 100644 index 0000000..1d36bf1 Binary files /dev/null and b/project/images/face_050336.webp differ diff --git a/project/images/face_050337.webp b/project/images/face_050337.webp new file mode 100644 index 0000000..8ecf407 Binary files /dev/null and b/project/images/face_050337.webp differ diff --git a/project/images/face_050338.webp b/project/images/face_050338.webp new file mode 100644 index 0000000..afed9a4 Binary files /dev/null and b/project/images/face_050338.webp differ diff --git a/project/images/face_050341.webp b/project/images/face_050341.webp new file mode 100644 index 0000000..825cd77 Binary files /dev/null and b/project/images/face_050341.webp differ diff --git a/project/images/face_050342.webp b/project/images/face_050342.webp new file mode 100644 index 0000000..f9f8384 Binary files /dev/null and b/project/images/face_050342.webp differ diff --git a/project/images/face_050343.webp b/project/images/face_050343.webp new file mode 100644 index 0000000..5854061 Binary files /dev/null and b/project/images/face_050343.webp differ diff --git a/project/images/face_050344.webp b/project/images/face_050344.webp new file mode 100644 index 0000000..2e67cd9 Binary files /dev/null and b/project/images/face_050344.webp differ diff --git a/project/images/face_050345.webp b/project/images/face_050345.webp new file mode 100644 index 0000000..9a58f26 Binary files /dev/null and b/project/images/face_050345.webp differ diff --git a/project/images/face_050346.webp b/project/images/face_050346.webp new file mode 100644 index 0000000..27a2a09 Binary files /dev/null and b/project/images/face_050346.webp differ diff --git a/project/images/face_050347.webp b/project/images/face_050347.webp new file mode 100644 index 0000000..d937b33 Binary files /dev/null and b/project/images/face_050347.webp differ diff --git a/project/images/face_050348.webp b/project/images/face_050348.webp new file mode 100644 index 0000000..f8bb7f7 Binary files /dev/null and b/project/images/face_050348.webp differ diff --git a/project/images/face_050349.webp b/project/images/face_050349.webp new file mode 100644 index 0000000..59992cd Binary files /dev/null and b/project/images/face_050349.webp differ diff --git a/project/images/face_050350.webp b/project/images/face_050350.webp new file mode 100644 index 0000000..27d1e0e Binary files /dev/null and b/project/images/face_050350.webp differ diff --git a/project/images/face_050351.webp b/project/images/face_050351.webp new file mode 100644 index 0000000..b9da1fc Binary files /dev/null and b/project/images/face_050351.webp differ diff --git a/project/images/face_050352.webp b/project/images/face_050352.webp new file mode 100644 index 0000000..0eacd03 Binary files /dev/null and b/project/images/face_050352.webp differ diff --git a/project/images/face_050353.webp b/project/images/face_050353.webp new file mode 100644 index 0000000..75cc486 Binary files /dev/null and b/project/images/face_050353.webp differ diff --git a/project/images/face_050441.webp b/project/images/face_050441.webp new file mode 100644 index 0000000..04ac926 Binary files /dev/null and b/project/images/face_050441.webp differ diff --git a/project/images/face_050442.webp b/project/images/face_050442.webp new file mode 100644 index 0000000..adf6280 Binary files /dev/null and b/project/images/face_050442.webp differ diff --git a/project/images/face_050443.webp b/project/images/face_050443.webp new file mode 100644 index 0000000..ee524ca Binary files /dev/null and b/project/images/face_050443.webp differ diff --git a/project/images/face_050446.webp b/project/images/face_050446.webp new file mode 100644 index 0000000..bf2f02b Binary files /dev/null and b/project/images/face_050446.webp differ diff --git a/project/images/face_050447.webp b/project/images/face_050447.webp new file mode 100644 index 0000000..fa89346 Binary files /dev/null and b/project/images/face_050447.webp differ diff --git a/project/images/face_050451.webp b/project/images/face_050451.webp new file mode 100644 index 0000000..5bab333 Binary files /dev/null and b/project/images/face_050451.webp differ diff --git a/project/images/face_050452.webp b/project/images/face_050452.webp new file mode 100644 index 0000000..3d2954f Binary files /dev/null and b/project/images/face_050452.webp differ diff --git a/project/images/face_120101.webp b/project/images/face_120101.webp new file mode 100644 index 0000000..bc440ef Binary files /dev/null and b/project/images/face_120101.webp differ diff --git a/project/images/face_120102.webp b/project/images/face_120102.webp new file mode 100644 index 0000000..d88d401 Binary files /dev/null and b/project/images/face_120102.webp differ diff --git a/project/images/face_120103.webp b/project/images/face_120103.webp new file mode 100644 index 0000000..b1a6b80 Binary files /dev/null and b/project/images/face_120103.webp differ diff --git a/project/images/face_120104.webp b/project/images/face_120104.webp new file mode 100644 index 0000000..1b676d7 Binary files /dev/null and b/project/images/face_120104.webp differ diff --git a/project/images/face_120105.webp b/project/images/face_120105.webp new file mode 100644 index 0000000..a90ab21 Binary files /dev/null and b/project/images/face_120105.webp differ diff --git a/project/images/face_120106.webp b/project/images/face_120106.webp new file mode 100644 index 0000000..c9dc845 Binary files /dev/null and b/project/images/face_120106.webp differ diff --git a/project/images/face_120108.webp b/project/images/face_120108.webp new file mode 100644 index 0000000..ca624d5 Binary files /dev/null and b/project/images/face_120108.webp differ diff --git a/project/images/face_120111.webp b/project/images/face_120111.webp new file mode 100644 index 0000000..880953f Binary files /dev/null and b/project/images/face_120111.webp differ diff --git a/project/images/face_120112.webp b/project/images/face_120112.webp new file mode 100644 index 0000000..90c5083 Binary files /dev/null and b/project/images/face_120112.webp differ diff --git a/project/images/face_120113.webp b/project/images/face_120113.webp new file mode 100644 index 0000000..f012da0 Binary files /dev/null and b/project/images/face_120113.webp differ diff --git a/project/images/face_120121.webp b/project/images/face_120121.webp new file mode 100644 index 0000000..3a5a791 Binary files /dev/null and b/project/images/face_120121.webp differ diff --git a/project/images/face_120122.webp b/project/images/face_120122.webp new file mode 100644 index 0000000..17087be Binary files /dev/null and b/project/images/face_120122.webp differ diff --git a/project/images/face_120123.webp b/project/images/face_120123.webp new file mode 100644 index 0000000..bb97d21 Binary files /dev/null and b/project/images/face_120123.webp differ diff --git a/project/images/face_120124.webp b/project/images/face_120124.webp new file mode 100644 index 0000000..2208131 Binary files /dev/null and b/project/images/face_120124.webp differ diff --git a/project/images/face_120125.webp b/project/images/face_120125.webp new file mode 100644 index 0000000..2aa827b Binary files /dev/null and b/project/images/face_120125.webp differ diff --git a/project/images/face_120126.webp b/project/images/face_120126.webp new file mode 100644 index 0000000..b48d08c Binary files /dev/null and b/project/images/face_120126.webp differ diff --git a/project/images/face_120127.webp b/project/images/face_120127.webp new file mode 100644 index 0000000..997d46f Binary files /dev/null and b/project/images/face_120127.webp differ diff --git a/project/images/face_120128.webp b/project/images/face_120128.webp new file mode 100644 index 0000000..97208ac Binary files /dev/null and b/project/images/face_120128.webp differ diff --git a/project/images/face_120131.webp b/project/images/face_120131.webp new file mode 100644 index 0000000..610ca15 Binary files /dev/null and b/project/images/face_120131.webp differ diff --git a/project/images/face_120132.webp b/project/images/face_120132.webp new file mode 100644 index 0000000..3c0e085 Binary files /dev/null and b/project/images/face_120132.webp differ diff --git a/project/images/face_130101.webp b/project/images/face_130101.webp new file mode 100644 index 0000000..181b18e Binary files /dev/null and b/project/images/face_130101.webp differ diff --git a/project/images/face_130102.webp b/project/images/face_130102.webp new file mode 100644 index 0000000..c2d4499 Binary files /dev/null and b/project/images/face_130102.webp differ diff --git a/project/images/face_130103.webp b/project/images/face_130103.webp new file mode 100644 index 0000000..5c14feb Binary files /dev/null and b/project/images/face_130103.webp differ diff --git a/project/images/face_130104.webp b/project/images/face_130104.webp new file mode 100644 index 0000000..37a7ca6 Binary files /dev/null and b/project/images/face_130104.webp differ diff --git a/project/images/face_130105.webp b/project/images/face_130105.webp new file mode 100644 index 0000000..e8a31dd Binary files /dev/null and b/project/images/face_130105.webp differ diff --git a/project/images/face_130106.webp b/project/images/face_130106.webp new file mode 100644 index 0000000..0658862 Binary files /dev/null and b/project/images/face_130106.webp differ diff --git a/project/images/face_130107.webp b/project/images/face_130107.webp new file mode 100644 index 0000000..2e88e47 Binary files /dev/null and b/project/images/face_130107.webp differ diff --git a/project/images/face_130108.webp b/project/images/face_130108.webp new file mode 100644 index 0000000..32e28b1 Binary files /dev/null and b/project/images/face_130108.webp differ diff --git a/project/images/face_130109.webp b/project/images/face_130109.webp new file mode 100644 index 0000000..4f87b11 Binary files /dev/null and b/project/images/face_130109.webp differ diff --git a/project/images/face_130110.webp b/project/images/face_130110.webp new file mode 100644 index 0000000..d16f85b Binary files /dev/null and b/project/images/face_130110.webp differ diff --git a/project/images/face_130111.webp b/project/images/face_130111.webp new file mode 100644 index 0000000..fa141f4 Binary files /dev/null and b/project/images/face_130111.webp differ diff --git a/project/images/face_130112.webp b/project/images/face_130112.webp new file mode 100644 index 0000000..bdbb1fb Binary files /dev/null and b/project/images/face_130112.webp differ diff --git a/project/images/face_130113.webp b/project/images/face_130113.webp new file mode 100644 index 0000000..b5c4f3f Binary files /dev/null and b/project/images/face_130113.webp differ diff --git a/project/images/face_130121.webp b/project/images/face_130121.webp new file mode 100644 index 0000000..c5024f1 Binary files /dev/null and b/project/images/face_130121.webp differ diff --git a/project/images/face_130122.webp b/project/images/face_130122.webp new file mode 100644 index 0000000..a97578e Binary files /dev/null and b/project/images/face_130122.webp differ diff --git a/project/images/face_130123.webp b/project/images/face_130123.webp new file mode 100644 index 0000000..3595d7e Binary files /dev/null and b/project/images/face_130123.webp differ diff --git a/project/images/face_130124.webp b/project/images/face_130124.webp new file mode 100644 index 0000000..4ce2fdf Binary files /dev/null and b/project/images/face_130124.webp differ diff --git a/project/images/face_130125.webp b/project/images/face_130125.webp new file mode 100644 index 0000000..8c6790b Binary files /dev/null and b/project/images/face_130125.webp differ diff --git a/project/images/face_130126.webp b/project/images/face_130126.webp new file mode 100644 index 0000000..3d9c572 Binary files /dev/null and b/project/images/face_130126.webp differ diff --git a/project/images/face_130127.webp b/project/images/face_130127.webp new file mode 100644 index 0000000..7eff9ba Binary files /dev/null and b/project/images/face_130127.webp differ diff --git a/project/images/face_130128.webp b/project/images/face_130128.webp new file mode 100644 index 0000000..9286671 Binary files /dev/null and b/project/images/face_130128.webp differ diff --git a/project/images/face_130129.webp b/project/images/face_130129.webp new file mode 100644 index 0000000..b63370c Binary files /dev/null and b/project/images/face_130129.webp differ diff --git a/project/images/face_130130.webp b/project/images/face_130130.webp new file mode 100644 index 0000000..37a0caf Binary files /dev/null and b/project/images/face_130130.webp differ diff --git a/project/images/face_130131.webp b/project/images/face_130131.webp new file mode 100644 index 0000000..a7c34c8 Binary files /dev/null and b/project/images/face_130131.webp differ diff --git a/project/images/face_130132.webp b/project/images/face_130132.webp new file mode 100644 index 0000000..41d2160 Binary files /dev/null and b/project/images/face_130132.webp differ diff --git a/project/images/face_130201.webp b/project/images/face_130201.webp new file mode 100644 index 0000000..8428c50 Binary files /dev/null and b/project/images/face_130201.webp differ diff --git a/project/images/face_130202.webp b/project/images/face_130202.webp new file mode 100644 index 0000000..12f397b Binary files /dev/null and b/project/images/face_130202.webp differ diff --git a/project/images/face_130203.webp b/project/images/face_130203.webp new file mode 100644 index 0000000..47a4336 Binary files /dev/null and b/project/images/face_130203.webp differ diff --git a/project/images/face_130204.webp b/project/images/face_130204.webp new file mode 100644 index 0000000..8e826ff Binary files /dev/null and b/project/images/face_130204.webp differ diff --git a/project/images/face_130205.webp b/project/images/face_130205.webp new file mode 100644 index 0000000..d78ff3c Binary files /dev/null and b/project/images/face_130205.webp differ diff --git a/project/images/face_130206.webp b/project/images/face_130206.webp new file mode 100644 index 0000000..88ae09f Binary files /dev/null and b/project/images/face_130206.webp differ diff --git a/project/images/face_130207.webp b/project/images/face_130207.webp new file mode 100644 index 0000000..f2b7e46 Binary files /dev/null and b/project/images/face_130207.webp differ diff --git a/project/images/face_130208.webp b/project/images/face_130208.webp new file mode 100644 index 0000000..80c45d1 Binary files /dev/null and b/project/images/face_130208.webp differ diff --git a/project/images/face_130209.webp b/project/images/face_130209.webp new file mode 100644 index 0000000..968938d Binary files /dev/null and b/project/images/face_130209.webp differ diff --git a/project/images/face_130211.webp b/project/images/face_130211.webp new file mode 100644 index 0000000..91cd1ff Binary files /dev/null and b/project/images/face_130211.webp differ diff --git a/project/images/face_130212.webp b/project/images/face_130212.webp new file mode 100644 index 0000000..bacab45 Binary files /dev/null and b/project/images/face_130212.webp differ diff --git a/project/images/face_130213.webp b/project/images/face_130213.webp new file mode 100644 index 0000000..2277d0c Binary files /dev/null and b/project/images/face_130213.webp differ diff --git a/project/images/face_130221.webp b/project/images/face_130221.webp new file mode 100644 index 0000000..3527add Binary files /dev/null and b/project/images/face_130221.webp differ diff --git a/project/images/face_130222.webp b/project/images/face_130222.webp new file mode 100644 index 0000000..5244eac Binary files /dev/null and b/project/images/face_130222.webp differ diff --git a/project/images/face_130223.webp b/project/images/face_130223.webp new file mode 100644 index 0000000..eeea6dd Binary files /dev/null and b/project/images/face_130223.webp differ diff --git a/project/images/face_130224.webp b/project/images/face_130224.webp new file mode 100644 index 0000000..6aaf352 Binary files /dev/null and b/project/images/face_130224.webp differ diff --git a/project/images/face_130225.webp b/project/images/face_130225.webp new file mode 100644 index 0000000..d59cbe4 Binary files /dev/null and b/project/images/face_130225.webp differ diff --git a/project/images/face_130226.webp b/project/images/face_130226.webp new file mode 100644 index 0000000..465ecd7 Binary files /dev/null and b/project/images/face_130226.webp differ diff --git a/project/images/face_130227.webp b/project/images/face_130227.webp new file mode 100644 index 0000000..c9b80f0 Binary files /dev/null and b/project/images/face_130227.webp differ diff --git a/project/images/face_130228.webp b/project/images/face_130228.webp new file mode 100644 index 0000000..ab9a7e0 Binary files /dev/null and b/project/images/face_130228.webp differ diff --git a/project/images/face_130229.webp b/project/images/face_130229.webp new file mode 100644 index 0000000..28a8d6d Binary files /dev/null and b/project/images/face_130229.webp differ diff --git a/project/images/face_130230.webp b/project/images/face_130230.webp new file mode 100644 index 0000000..e350061 Binary files /dev/null and b/project/images/face_130230.webp differ diff --git a/project/images/face_130231.webp b/project/images/face_130231.webp new file mode 100644 index 0000000..7646d12 Binary files /dev/null and b/project/images/face_130231.webp differ diff --git a/project/images/face_320101.webp b/project/images/face_320101.webp new file mode 100644 index 0000000..125a136 Binary files /dev/null and b/project/images/face_320101.webp differ diff --git a/project/images/face_320102.webp b/project/images/face_320102.webp new file mode 100644 index 0000000..c4f770e Binary files /dev/null and b/project/images/face_320102.webp differ diff --git a/project/images/face_320103.webp b/project/images/face_320103.webp new file mode 100644 index 0000000..0bb5290 Binary files /dev/null and b/project/images/face_320103.webp differ diff --git a/project/images/face_320104.webp b/project/images/face_320104.webp new file mode 100644 index 0000000..69f8d08 Binary files /dev/null and b/project/images/face_320104.webp differ diff --git a/project/images/face_320105.webp b/project/images/face_320105.webp new file mode 100644 index 0000000..583df87 Binary files /dev/null and b/project/images/face_320105.webp differ diff --git a/project/images/face_320106.webp b/project/images/face_320106.webp new file mode 100644 index 0000000..e35e192 Binary files /dev/null and b/project/images/face_320106.webp differ diff --git a/project/images/face_320107.webp b/project/images/face_320107.webp new file mode 100644 index 0000000..cf1e0b0 Binary files /dev/null and b/project/images/face_320107.webp differ diff --git a/project/images/face_320108.webp b/project/images/face_320108.webp new file mode 100644 index 0000000..9d6178a Binary files /dev/null and b/project/images/face_320108.webp differ diff --git a/project/images/face_320109.webp b/project/images/face_320109.webp new file mode 100644 index 0000000..17dff8d Binary files /dev/null and b/project/images/face_320109.webp differ diff --git a/project/images/face_320121.webp b/project/images/face_320121.webp new file mode 100644 index 0000000..e78fb80 Binary files /dev/null and b/project/images/face_320121.webp differ diff --git a/project/images/face_320122.webp b/project/images/face_320122.webp new file mode 100644 index 0000000..53e5827 Binary files /dev/null and b/project/images/face_320122.webp differ diff --git a/project/images/face_320123.webp b/project/images/face_320123.webp new file mode 100644 index 0000000..03d4a51 Binary files /dev/null and b/project/images/face_320123.webp differ diff --git a/project/images/face_320124.webp b/project/images/face_320124.webp new file mode 100644 index 0000000..27d82a7 Binary files /dev/null and b/project/images/face_320124.webp differ diff --git a/project/images/face_320125.webp b/project/images/face_320125.webp new file mode 100644 index 0000000..ae2783c Binary files /dev/null and b/project/images/face_320125.webp differ diff --git a/project/images/face_320127.webp b/project/images/face_320127.webp new file mode 100644 index 0000000..4835679 Binary files /dev/null and b/project/images/face_320127.webp differ diff --git a/project/images/face_340101.webp b/project/images/face_340101.webp new file mode 100644 index 0000000..1eaf8fd Binary files /dev/null and b/project/images/face_340101.webp differ diff --git a/project/images/face_340102.webp b/project/images/face_340102.webp new file mode 100644 index 0000000..49d188e Binary files /dev/null and b/project/images/face_340102.webp differ diff --git a/project/images/face_340103.webp b/project/images/face_340103.webp new file mode 100644 index 0000000..da0a15f Binary files /dev/null and b/project/images/face_340103.webp differ diff --git a/project/images/face_340104.webp b/project/images/face_340104.webp new file mode 100644 index 0000000..6355dba Binary files /dev/null and b/project/images/face_340104.webp differ diff --git a/project/images/face_340105.webp b/project/images/face_340105.webp new file mode 100644 index 0000000..b92a56a Binary files /dev/null and b/project/images/face_340105.webp differ diff --git a/project/images/face_340106.webp b/project/images/face_340106.webp new file mode 100644 index 0000000..4e785ff Binary files /dev/null and b/project/images/face_340106.webp differ diff --git a/project/images/face_340107.webp b/project/images/face_340107.webp new file mode 100644 index 0000000..3c10a9d Binary files /dev/null and b/project/images/face_340107.webp differ diff --git a/project/images/face_340108.webp b/project/images/face_340108.webp new file mode 100644 index 0000000..f61f0f5 Binary files /dev/null and b/project/images/face_340108.webp differ diff --git a/project/images/face_340109.webp b/project/images/face_340109.webp new file mode 100644 index 0000000..ea81797 Binary files /dev/null and b/project/images/face_340109.webp differ diff --git a/project/images/face_340110.webp b/project/images/face_340110.webp new file mode 100644 index 0000000..4d3f3a1 Binary files /dev/null and b/project/images/face_340110.webp differ diff --git a/project/images/face_340111.webp b/project/images/face_340111.webp new file mode 100644 index 0000000..88a5708 Binary files /dev/null and b/project/images/face_340111.webp differ diff --git a/project/images/face_340112.webp b/project/images/face_340112.webp new file mode 100644 index 0000000..d3f11ec Binary files /dev/null and b/project/images/face_340112.webp differ diff --git a/project/images/face_340113.webp b/project/images/face_340113.webp new file mode 100644 index 0000000..f548732 Binary files /dev/null and b/project/images/face_340113.webp differ diff --git a/project/images/face_340114.webp b/project/images/face_340114.webp new file mode 100644 index 0000000..756c346 Binary files /dev/null and b/project/images/face_340114.webp differ diff --git a/project/images/face_340115.webp b/project/images/face_340115.webp new file mode 100644 index 0000000..47615b8 Binary files /dev/null and b/project/images/face_340115.webp differ diff --git a/project/images/face_430101.webp b/project/images/face_430101.webp new file mode 100644 index 0000000..1e769d8 Binary files /dev/null and b/project/images/face_430101.webp differ diff --git a/project/images/face_430102.webp b/project/images/face_430102.webp new file mode 100644 index 0000000..f147014 Binary files /dev/null and b/project/images/face_430102.webp differ diff --git a/project/images/face_430103.webp b/project/images/face_430103.webp new file mode 100644 index 0000000..93a9925 Binary files /dev/null and b/project/images/face_430103.webp differ diff --git a/project/images/face_430104.webp b/project/images/face_430104.webp new file mode 100644 index 0000000..9c9cb04 Binary files /dev/null and b/project/images/face_430104.webp differ diff --git a/project/images/face_430105.webp b/project/images/face_430105.webp new file mode 100644 index 0000000..a24dee1 Binary files /dev/null and b/project/images/face_430105.webp differ diff --git a/project/images/face_430106.webp b/project/images/face_430106.webp new file mode 100644 index 0000000..b5cfa7e Binary files /dev/null and b/project/images/face_430106.webp differ diff --git a/project/images/face_430107.webp b/project/images/face_430107.webp new file mode 100644 index 0000000..75d9b5e Binary files /dev/null and b/project/images/face_430107.webp differ diff --git a/project/images/face_430108.webp b/project/images/face_430108.webp new file mode 100644 index 0000000..48f8965 Binary files /dev/null and b/project/images/face_430108.webp differ diff --git a/project/images/face_440101.webp b/project/images/face_440101.webp new file mode 100644 index 0000000..37539c6 Binary files /dev/null and b/project/images/face_440101.webp differ diff --git a/project/images/face_440102.webp b/project/images/face_440102.webp new file mode 100644 index 0000000..96b1027 Binary files /dev/null and b/project/images/face_440102.webp differ diff --git a/project/images/face_440103.webp b/project/images/face_440103.webp new file mode 100644 index 0000000..76c6b72 Binary files /dev/null and b/project/images/face_440103.webp differ diff --git a/project/images/face_440104.webp b/project/images/face_440104.webp new file mode 100644 index 0000000..0092336 Binary files /dev/null and b/project/images/face_440104.webp differ diff --git a/project/images/face_440105.webp b/project/images/face_440105.webp new file mode 100644 index 0000000..536aff5 Binary files /dev/null and b/project/images/face_440105.webp differ diff --git a/project/images/face_440106.webp b/project/images/face_440106.webp new file mode 100644 index 0000000..7e53532 Binary files /dev/null and b/project/images/face_440106.webp differ diff --git a/project/images/face_440107.webp b/project/images/face_440107.webp new file mode 100644 index 0000000..a0e9fa5 Binary files /dev/null and b/project/images/face_440107.webp differ diff --git a/project/images/face_440108.webp b/project/images/face_440108.webp new file mode 100644 index 0000000..fa6aeab Binary files /dev/null and b/project/images/face_440108.webp differ diff --git a/project/images/face_440109.webp b/project/images/face_440109.webp new file mode 100644 index 0000000..f9713c4 Binary files /dev/null and b/project/images/face_440109.webp differ diff --git a/project/images/face_440110.webp b/project/images/face_440110.webp new file mode 100644 index 0000000..a5a91c8 Binary files /dev/null and b/project/images/face_440110.webp differ diff --git a/project/images/jianji.webp b/project/images/jianji.webp new file mode 100644 index 0000000..40504a4 Binary files /dev/null and b/project/images/jianji.webp differ diff --git a/project/images/miwu.webp b/project/images/miwu.webp new file mode 100644 index 0000000..84e72cc Binary files /dev/null and b/project/images/miwu.webp differ diff --git a/project/images/sound.webp b/project/images/sound.webp new file mode 100644 index 0000000..1fed120 Binary files /dev/null and b/project/images/sound.webp differ diff --git a/project/images/suiji.webp b/project/images/suiji.webp new file mode 100644 index 0000000..34b2a06 Binary files /dev/null and b/project/images/suiji.webp differ diff --git a/project/images/tati_050101.webp b/project/images/tati_050101.webp new file mode 100644 index 0000000..7e7b8bd Binary files /dev/null and b/project/images/tati_050101.webp differ diff --git a/project/images/tati_050101a.webp b/project/images/tati_050101a.webp new file mode 100644 index 0000000..261a3f1 Binary files /dev/null and b/project/images/tati_050101a.webp differ diff --git a/project/images/tati_050101y.webp b/project/images/tati_050101y.webp new file mode 100644 index 0000000..26fef52 Binary files /dev/null and b/project/images/tati_050101y.webp differ diff --git a/project/images/tati_050102.webp b/project/images/tati_050102.webp new file mode 100644 index 0000000..519308e Binary files /dev/null and b/project/images/tati_050102.webp differ diff --git a/project/images/tati_050102y.webp b/project/images/tati_050102y.webp new file mode 100644 index 0000000..46a5f3d Binary files /dev/null and b/project/images/tati_050102y.webp differ diff --git a/project/images/tati_050103.webp b/project/images/tati_050103.webp new file mode 100644 index 0000000..f655203 Binary files /dev/null and b/project/images/tati_050103.webp differ diff --git a/project/images/tati_050103a.webp b/project/images/tati_050103a.webp new file mode 100644 index 0000000..4d1a43b Binary files /dev/null and b/project/images/tati_050103a.webp differ diff --git a/project/images/tati_050103y.webp b/project/images/tati_050103y.webp new file mode 100644 index 0000000..243883a Binary files /dev/null and b/project/images/tati_050103y.webp differ diff --git a/project/images/tati_050104.webp b/project/images/tati_050104.webp new file mode 100644 index 0000000..8894735 Binary files /dev/null and b/project/images/tati_050104.webp differ diff --git a/project/images/tati_050104a.webp b/project/images/tati_050104a.webp new file mode 100644 index 0000000..4d58e4a Binary files /dev/null and b/project/images/tati_050104a.webp differ diff --git a/project/images/tati_050105.webp b/project/images/tati_050105.webp new file mode 100644 index 0000000..df6359e Binary files /dev/null and b/project/images/tati_050105.webp differ diff --git a/project/images/tati_050105a.webp b/project/images/tati_050105a.webp new file mode 100644 index 0000000..49f7c84 Binary files /dev/null and b/project/images/tati_050105a.webp differ diff --git a/project/images/tati_050105y.webp b/project/images/tati_050105y.webp new file mode 100644 index 0000000..3df3405 Binary files /dev/null and b/project/images/tati_050105y.webp differ diff --git a/project/images/tati_050106.webp b/project/images/tati_050106.webp new file mode 100644 index 0000000..86dc7c8 Binary files /dev/null and b/project/images/tati_050106.webp differ diff --git a/project/images/tati_050106y.webp b/project/images/tati_050106y.webp new file mode 100644 index 0000000..728f894 Binary files /dev/null and b/project/images/tati_050106y.webp differ diff --git a/project/images/tati_050107.webp b/project/images/tati_050107.webp new file mode 100644 index 0000000..354acde Binary files /dev/null and b/project/images/tati_050107.webp differ diff --git a/project/images/tati_050107a.webp b/project/images/tati_050107a.webp new file mode 100644 index 0000000..08e5d3d Binary files /dev/null and b/project/images/tati_050107a.webp differ diff --git a/project/images/tati_050107y.webp b/project/images/tati_050107y.webp new file mode 100644 index 0000000..a46ed5b Binary files /dev/null and b/project/images/tati_050107y.webp differ diff --git a/project/images/tati_050110.webp b/project/images/tati_050110.webp new file mode 100644 index 0000000..ad26d10 Binary files /dev/null and b/project/images/tati_050110.webp differ diff --git a/project/images/tati_050111.webp b/project/images/tati_050111.webp new file mode 100644 index 0000000..1956c65 Binary files /dev/null and b/project/images/tati_050111.webp differ diff --git a/project/images/tati_050111a.webp b/project/images/tati_050111a.webp new file mode 100644 index 0000000..ab59b9e Binary files /dev/null and b/project/images/tati_050111a.webp differ diff --git a/project/images/tati_050111y.webp b/project/images/tati_050111y.webp new file mode 100644 index 0000000..14012b2 Binary files /dev/null and b/project/images/tati_050111y.webp differ diff --git a/project/images/tati_050112.webp b/project/images/tati_050112.webp new file mode 100644 index 0000000..7752e4a Binary files /dev/null and b/project/images/tati_050112.webp differ diff --git a/project/images/tati_050113y.webp b/project/images/tati_050113y.webp new file mode 100644 index 0000000..2636fb3 Binary files /dev/null and b/project/images/tati_050113y.webp differ diff --git a/project/images/tati_050116.webp b/project/images/tati_050116.webp new file mode 100644 index 0000000..cba90ef Binary files /dev/null and b/project/images/tati_050116.webp differ diff --git a/project/images/tati_050116a.webp b/project/images/tati_050116a.webp new file mode 100644 index 0000000..48e2c94 Binary files /dev/null and b/project/images/tati_050116a.webp differ diff --git a/project/images/tati_050116y.webp b/project/images/tati_050116y.webp new file mode 100644 index 0000000..a3d1fa5 Binary files /dev/null and b/project/images/tati_050116y.webp differ diff --git a/project/images/tati_050117.webp b/project/images/tati_050117.webp new file mode 100644 index 0000000..153d707 Binary files /dev/null and b/project/images/tati_050117.webp differ diff --git a/project/images/tati_050121.webp b/project/images/tati_050121.webp new file mode 100644 index 0000000..0acc15b Binary files /dev/null and b/project/images/tati_050121.webp differ diff --git a/project/images/tati_050121a.webp b/project/images/tati_050121a.webp new file mode 100644 index 0000000..a802414 Binary files /dev/null and b/project/images/tati_050121a.webp differ diff --git a/project/images/tati_050121y.webp b/project/images/tati_050121y.webp new file mode 100644 index 0000000..cc5f03d Binary files /dev/null and b/project/images/tati_050121y.webp differ diff --git a/project/images/tati_050122.webp b/project/images/tati_050122.webp new file mode 100644 index 0000000..0ce76a0 Binary files /dev/null and b/project/images/tati_050122.webp differ diff --git a/project/images/tati_050122y.webp b/project/images/tati_050122y.webp new file mode 100644 index 0000000..3acdec6 Binary files /dev/null and b/project/images/tati_050122y.webp differ diff --git a/project/images/tati_050123.webp b/project/images/tati_050123.webp new file mode 100644 index 0000000..eb60f3a Binary files /dev/null and b/project/images/tati_050123.webp differ diff --git a/project/images/tati_050123a.webp b/project/images/tati_050123a.webp new file mode 100644 index 0000000..d2a7a6b Binary files /dev/null and b/project/images/tati_050123a.webp differ diff --git a/project/images/tati_050123y.webp b/project/images/tati_050123y.webp new file mode 100644 index 0000000..347ee03 Binary files /dev/null and b/project/images/tati_050123y.webp differ diff --git a/project/images/tati_050124.webp b/project/images/tati_050124.webp new file mode 100644 index 0000000..d7a8298 Binary files /dev/null and b/project/images/tati_050124.webp differ diff --git a/project/images/tati_050124a.webp b/project/images/tati_050124a.webp new file mode 100644 index 0000000..b2931cf Binary files /dev/null and b/project/images/tati_050124a.webp differ diff --git a/project/images/tati_050124y.webp b/project/images/tati_050124y.webp new file mode 100644 index 0000000..9ea35ee Binary files /dev/null and b/project/images/tati_050124y.webp differ diff --git a/project/images/tati_050125.webp b/project/images/tati_050125.webp new file mode 100644 index 0000000..ceeff74 Binary files /dev/null and b/project/images/tati_050125.webp differ diff --git a/project/images/tati_050125a.webp b/project/images/tati_050125a.webp new file mode 100644 index 0000000..f847625 Binary files /dev/null and b/project/images/tati_050125a.webp differ diff --git a/project/images/tati_050125y.webp b/project/images/tati_050125y.webp new file mode 100644 index 0000000..18d2682 Binary files /dev/null and b/project/images/tati_050125y.webp differ diff --git a/project/images/tati_050126.webp b/project/images/tati_050126.webp new file mode 100644 index 0000000..245c05b Binary files /dev/null and b/project/images/tati_050126.webp differ diff --git a/project/images/tati_050126y.webp b/project/images/tati_050126y.webp new file mode 100644 index 0000000..2b5f2b6 Binary files /dev/null and b/project/images/tati_050126y.webp differ diff --git a/project/images/tati_050127.webp b/project/images/tati_050127.webp new file mode 100644 index 0000000..19850d9 Binary files /dev/null and b/project/images/tati_050127.webp differ diff --git a/project/images/tati_050127a.webp b/project/images/tati_050127a.webp new file mode 100644 index 0000000..e3f69ce Binary files /dev/null and b/project/images/tati_050127a.webp differ diff --git a/project/images/tati_050128.webp b/project/images/tati_050128.webp new file mode 100644 index 0000000..179fbaf Binary files /dev/null and b/project/images/tati_050128.webp differ diff --git a/project/images/tati_050131.webp b/project/images/tati_050131.webp new file mode 100644 index 0000000..509ddfd Binary files /dev/null and b/project/images/tati_050131.webp differ diff --git a/project/images/tati_050131a.webp b/project/images/tati_050131a.webp new file mode 100644 index 0000000..58406d2 Binary files /dev/null and b/project/images/tati_050131a.webp differ diff --git a/project/images/tati_050131y.webp b/project/images/tati_050131y.webp new file mode 100644 index 0000000..92dbc60 Binary files /dev/null and b/project/images/tati_050131y.webp differ diff --git a/project/images/tati_050132.webp b/project/images/tati_050132.webp new file mode 100644 index 0000000..6a25ddd Binary files /dev/null and b/project/images/tati_050132.webp differ diff --git a/project/images/tati_050134.webp b/project/images/tati_050134.webp new file mode 100644 index 0000000..f1ea445 Binary files /dev/null and b/project/images/tati_050134.webp differ diff --git a/project/images/tati_050134y.webp b/project/images/tati_050134y.webp new file mode 100644 index 0000000..f09f864 Binary files /dev/null and b/project/images/tati_050134y.webp differ diff --git a/project/images/tati_050135.webp b/project/images/tati_050135.webp new file mode 100644 index 0000000..adab376 Binary files /dev/null and b/project/images/tati_050135.webp differ diff --git a/project/images/tati_050135y.webp b/project/images/tati_050135y.webp new file mode 100644 index 0000000..1266015 Binary files /dev/null and b/project/images/tati_050135y.webp differ diff --git a/project/images/tati_050136.webp b/project/images/tati_050136.webp new file mode 100644 index 0000000..a1a40d6 Binary files /dev/null and b/project/images/tati_050136.webp differ diff --git a/project/images/tati_050137.webp b/project/images/tati_050137.webp new file mode 100644 index 0000000..ca1fefc Binary files /dev/null and b/project/images/tati_050137.webp differ diff --git a/project/images/tati_050137y.webp b/project/images/tati_050137y.webp new file mode 100644 index 0000000..d536486 Binary files /dev/null and b/project/images/tati_050137y.webp differ diff --git a/project/images/tati_050141.webp b/project/images/tati_050141.webp new file mode 100644 index 0000000..a94ba95 Binary files /dev/null and b/project/images/tati_050141.webp differ diff --git a/project/images/tati_050141a.webp b/project/images/tati_050141a.webp new file mode 100644 index 0000000..57f3957 Binary files /dev/null and b/project/images/tati_050141a.webp differ diff --git a/project/images/tati_050141y.webp b/project/images/tati_050141y.webp new file mode 100644 index 0000000..e3df30e Binary files /dev/null and b/project/images/tati_050141y.webp differ diff --git a/project/images/tati_050142.webp b/project/images/tati_050142.webp new file mode 100644 index 0000000..499b32a Binary files /dev/null and b/project/images/tati_050142.webp differ diff --git a/project/images/tati_050142a.webp b/project/images/tati_050142a.webp new file mode 100644 index 0000000..93f43c9 Binary files /dev/null and b/project/images/tati_050142a.webp differ diff --git a/project/images/tati_050142y.webp b/project/images/tati_050142y.webp new file mode 100644 index 0000000..3e84bc5 Binary files /dev/null and b/project/images/tati_050142y.webp differ diff --git a/project/images/tati_050143.webp b/project/images/tati_050143.webp new file mode 100644 index 0000000..8244d15 Binary files /dev/null and b/project/images/tati_050143.webp differ diff --git a/project/images/tati_050143a.webp b/project/images/tati_050143a.webp new file mode 100644 index 0000000..9d7e93a Binary files /dev/null and b/project/images/tati_050143a.webp differ diff --git a/project/images/tati_050143y.webp b/project/images/tati_050143y.webp new file mode 100644 index 0000000..f7e03e0 Binary files /dev/null and b/project/images/tati_050143y.webp differ diff --git a/project/images/tati_050144.webp b/project/images/tati_050144.webp new file mode 100644 index 0000000..6ebae4b Binary files /dev/null and b/project/images/tati_050144.webp differ diff --git a/project/images/tati_050144a.webp b/project/images/tati_050144a.webp new file mode 100644 index 0000000..e0a932a Binary files /dev/null and b/project/images/tati_050144a.webp differ diff --git a/project/images/tati_050144y.webp b/project/images/tati_050144y.webp new file mode 100644 index 0000000..1beb0d4 Binary files /dev/null and b/project/images/tati_050144y.webp differ diff --git a/project/images/tati_050145.webp b/project/images/tati_050145.webp new file mode 100644 index 0000000..705ea09 Binary files /dev/null and b/project/images/tati_050145.webp differ diff --git a/project/images/tati_050145y.webp b/project/images/tati_050145y.webp new file mode 100644 index 0000000..e5e3e82 Binary files /dev/null and b/project/images/tati_050145y.webp differ diff --git a/project/images/tati_050146.webp b/project/images/tati_050146.webp new file mode 100644 index 0000000..2cc72ed Binary files /dev/null and b/project/images/tati_050146.webp differ diff --git a/project/images/tati_050146y.webp b/project/images/tati_050146y.webp new file mode 100644 index 0000000..1df3fe3 Binary files /dev/null and b/project/images/tati_050146y.webp differ diff --git a/project/images/tati_050147.webp b/project/images/tati_050147.webp new file mode 100644 index 0000000..ae5953d Binary files /dev/null and b/project/images/tati_050147.webp differ diff --git a/project/images/tati_050147y.webp b/project/images/tati_050147y.webp new file mode 100644 index 0000000..a2bf1c2 Binary files /dev/null and b/project/images/tati_050147y.webp differ diff --git a/project/images/tati_050151.webp b/project/images/tati_050151.webp new file mode 100644 index 0000000..867f631 Binary files /dev/null and b/project/images/tati_050151.webp differ diff --git a/project/images/tati_050151a.webp b/project/images/tati_050151a.webp new file mode 100644 index 0000000..0a6b036 Binary files /dev/null and b/project/images/tati_050151a.webp differ diff --git a/project/images/tati_050151y.webp b/project/images/tati_050151y.webp new file mode 100644 index 0000000..30399ac Binary files /dev/null and b/project/images/tati_050151y.webp differ diff --git a/project/images/tati_050152.webp b/project/images/tati_050152.webp new file mode 100644 index 0000000..fa61d27 Binary files /dev/null and b/project/images/tati_050152.webp differ diff --git a/project/images/tati_050152y.webp b/project/images/tati_050152y.webp new file mode 100644 index 0000000..d56f1f1 Binary files /dev/null and b/project/images/tati_050152y.webp differ diff --git a/project/images/tati_050201.webp b/project/images/tati_050201.webp new file mode 100644 index 0000000..126c435 Binary files /dev/null and b/project/images/tati_050201.webp differ diff --git a/project/images/tati_050201a.webp b/project/images/tati_050201a.webp new file mode 100644 index 0000000..5964960 Binary files /dev/null and b/project/images/tati_050201a.webp differ diff --git a/project/images/tati_050201y.webp b/project/images/tati_050201y.webp new file mode 100644 index 0000000..be1adf8 Binary files /dev/null and b/project/images/tati_050201y.webp differ diff --git a/project/images/tati_050202.webp b/project/images/tati_050202.webp new file mode 100644 index 0000000..fd9311d Binary files /dev/null and b/project/images/tati_050202.webp differ diff --git a/project/images/tati_050202a.webp b/project/images/tati_050202a.webp new file mode 100644 index 0000000..935244c Binary files /dev/null and b/project/images/tati_050202a.webp differ diff --git a/project/images/tati_050202y.webp b/project/images/tati_050202y.webp new file mode 100644 index 0000000..a15791f Binary files /dev/null and b/project/images/tati_050202y.webp differ diff --git a/project/images/tati_050203.webp b/project/images/tati_050203.webp new file mode 100644 index 0000000..4b0d2fc Binary files /dev/null and b/project/images/tati_050203.webp differ diff --git a/project/images/tati_050203y.webp b/project/images/tati_050203y.webp new file mode 100644 index 0000000..64c6173 Binary files /dev/null and b/project/images/tati_050203y.webp differ diff --git a/project/images/tati_050204a.webp b/project/images/tati_050204a.webp new file mode 100644 index 0000000..199883d Binary files /dev/null and b/project/images/tati_050204a.webp differ diff --git a/project/images/tati_050204y.webp b/project/images/tati_050204y.webp new file mode 100644 index 0000000..4d7672c Binary files /dev/null and b/project/images/tati_050204y.webp differ diff --git a/project/images/tati_050205.webp b/project/images/tati_050205.webp new file mode 100644 index 0000000..f58e1e1 Binary files /dev/null and b/project/images/tati_050205.webp differ diff --git a/project/images/tati_050205a.webp b/project/images/tati_050205a.webp new file mode 100644 index 0000000..549877e Binary files /dev/null and b/project/images/tati_050205a.webp differ diff --git a/project/images/tati_050205y.webp b/project/images/tati_050205y.webp new file mode 100644 index 0000000..6351984 Binary files /dev/null and b/project/images/tati_050205y.webp differ diff --git a/project/images/tati_050206.webp b/project/images/tati_050206.webp new file mode 100644 index 0000000..cd51e96 Binary files /dev/null and b/project/images/tati_050206.webp differ diff --git a/project/images/tati_050206a.webp b/project/images/tati_050206a.webp new file mode 100644 index 0000000..4435f23 Binary files /dev/null and b/project/images/tati_050206a.webp differ diff --git a/project/images/tati_050206y.webp b/project/images/tati_050206y.webp new file mode 100644 index 0000000..0b9a04b Binary files /dev/null and b/project/images/tati_050206y.webp differ diff --git a/project/images/tati_050210y.webp b/project/images/tati_050210y.webp new file mode 100644 index 0000000..2504e2c Binary files /dev/null and b/project/images/tati_050210y.webp differ diff --git a/project/images/tati_050215.webp b/project/images/tati_050215.webp new file mode 100644 index 0000000..adefc64 Binary files /dev/null and b/project/images/tati_050215.webp differ diff --git a/project/images/tati_050216.webp b/project/images/tati_050216.webp new file mode 100644 index 0000000..4fd50a0 Binary files /dev/null and b/project/images/tati_050216.webp differ diff --git a/project/images/tati_050221.webp b/project/images/tati_050221.webp new file mode 100644 index 0000000..6ed3bde Binary files /dev/null and b/project/images/tati_050221.webp differ diff --git a/project/images/tati_050221a.webp b/project/images/tati_050221a.webp new file mode 100644 index 0000000..683f2a6 Binary files /dev/null and b/project/images/tati_050221a.webp differ diff --git a/project/images/tati_050221y.webp b/project/images/tati_050221y.webp new file mode 100644 index 0000000..3984fe1 Binary files /dev/null and b/project/images/tati_050221y.webp differ diff --git a/project/images/tati_050222.webp b/project/images/tati_050222.webp new file mode 100644 index 0000000..3aac4c8 Binary files /dev/null and b/project/images/tati_050222.webp differ diff --git a/project/images/tati_050222a.webp b/project/images/tati_050222a.webp new file mode 100644 index 0000000..c3facb0 Binary files /dev/null and b/project/images/tati_050222a.webp differ diff --git a/project/images/tati_050222y.webp b/project/images/tati_050222y.webp new file mode 100644 index 0000000..522e0e6 Binary files /dev/null and b/project/images/tati_050222y.webp differ diff --git a/project/images/tati_050223.webp b/project/images/tati_050223.webp new file mode 100644 index 0000000..3f3151e Binary files /dev/null and b/project/images/tati_050223.webp differ diff --git a/project/images/tati_050224a.webp b/project/images/tati_050224a.webp new file mode 100644 index 0000000..3e3f828 Binary files /dev/null and b/project/images/tati_050224a.webp differ diff --git a/project/images/tati_050224y.webp b/project/images/tati_050224y.webp new file mode 100644 index 0000000..e647df5 Binary files /dev/null and b/project/images/tati_050224y.webp differ diff --git a/project/images/tati_050225.webp b/project/images/tati_050225.webp new file mode 100644 index 0000000..59c7c5c Binary files /dev/null and b/project/images/tati_050225.webp differ diff --git a/project/images/tati_050225a.webp b/project/images/tati_050225a.webp new file mode 100644 index 0000000..2bc0246 Binary files /dev/null and b/project/images/tati_050225a.webp differ diff --git a/project/images/tati_050225y.webp b/project/images/tati_050225y.webp new file mode 100644 index 0000000..6ff5676 Binary files /dev/null and b/project/images/tati_050225y.webp differ diff --git a/project/images/tati_050226.webp b/project/images/tati_050226.webp new file mode 100644 index 0000000..efd597a Binary files /dev/null and b/project/images/tati_050226.webp differ diff --git a/project/images/tati_050226a.webp b/project/images/tati_050226a.webp new file mode 100644 index 0000000..c652554 Binary files /dev/null and b/project/images/tati_050226a.webp differ diff --git a/project/images/tati_050229.webp b/project/images/tati_050229.webp new file mode 100644 index 0000000..a0915ef Binary files /dev/null and b/project/images/tati_050229.webp differ diff --git a/project/images/tati_050230y.webp b/project/images/tati_050230y.webp new file mode 100644 index 0000000..ac60ecf Binary files /dev/null and b/project/images/tati_050230y.webp differ diff --git a/project/images/tati_050232a.webp b/project/images/tati_050232a.webp new file mode 100644 index 0000000..e55f89b Binary files /dev/null and b/project/images/tati_050232a.webp differ diff --git a/project/images/tati_050234a.webp b/project/images/tati_050234a.webp new file mode 100644 index 0000000..3186bef Binary files /dev/null and b/project/images/tati_050234a.webp differ diff --git a/project/images/tati_050237.webp b/project/images/tati_050237.webp new file mode 100644 index 0000000..e56f654 Binary files /dev/null and b/project/images/tati_050237.webp differ diff --git a/project/images/tati_050241.webp b/project/images/tati_050241.webp new file mode 100644 index 0000000..97d09ab Binary files /dev/null and b/project/images/tati_050241.webp differ diff --git a/project/images/tati_050241a.webp b/project/images/tati_050241a.webp new file mode 100644 index 0000000..710adc3 Binary files /dev/null and b/project/images/tati_050241a.webp differ diff --git a/project/images/tati_050241y.webp b/project/images/tati_050241y.webp new file mode 100644 index 0000000..60df1c1 Binary files /dev/null and b/project/images/tati_050241y.webp differ diff --git a/project/images/tati_050242.webp b/project/images/tati_050242.webp new file mode 100644 index 0000000..cb969b8 Binary files /dev/null and b/project/images/tati_050242.webp differ diff --git a/project/images/tati_050242a.webp b/project/images/tati_050242a.webp new file mode 100644 index 0000000..070640d Binary files /dev/null and b/project/images/tati_050242a.webp differ diff --git a/project/images/tati_050242y.webp b/project/images/tati_050242y.webp new file mode 100644 index 0000000..e5c4840 Binary files /dev/null and b/project/images/tati_050242y.webp differ diff --git a/project/images/tati_050243.webp b/project/images/tati_050243.webp new file mode 100644 index 0000000..4371e03 Binary files /dev/null and b/project/images/tati_050243.webp differ diff --git a/project/images/tati_050243y.webp b/project/images/tati_050243y.webp new file mode 100644 index 0000000..d87f357 Binary files /dev/null and b/project/images/tati_050243y.webp differ diff --git a/project/images/tati_050244a.webp b/project/images/tati_050244a.webp new file mode 100644 index 0000000..4ba656b Binary files /dev/null and b/project/images/tati_050244a.webp differ diff --git a/project/images/tati_050244y.webp b/project/images/tati_050244y.webp new file mode 100644 index 0000000..a710959 Binary files /dev/null and b/project/images/tati_050244y.webp differ diff --git a/project/images/tati_050245.webp b/project/images/tati_050245.webp new file mode 100644 index 0000000..e8a0755 Binary files /dev/null and b/project/images/tati_050245.webp differ diff --git a/project/images/tati_050245a.webp b/project/images/tati_050245a.webp new file mode 100644 index 0000000..ef94266 Binary files /dev/null and b/project/images/tati_050245a.webp differ diff --git a/project/images/tati_050245y.webp b/project/images/tati_050245y.webp new file mode 100644 index 0000000..2b86e8b Binary files /dev/null and b/project/images/tati_050245y.webp differ diff --git a/project/images/tati_050252.webp b/project/images/tati_050252.webp new file mode 100644 index 0000000..192f1ae Binary files /dev/null and b/project/images/tati_050252.webp differ diff --git a/project/images/tati_050252y.webp b/project/images/tati_050252y.webp new file mode 100644 index 0000000..7b55af9 Binary files /dev/null and b/project/images/tati_050252y.webp differ diff --git a/project/images/tati_050301.webp b/project/images/tati_050301.webp new file mode 100644 index 0000000..e0a5682 Binary files /dev/null and b/project/images/tati_050301.webp differ diff --git a/project/images/tati_050301a.webp b/project/images/tati_050301a.webp new file mode 100644 index 0000000..598ab9f Binary files /dev/null and b/project/images/tati_050301a.webp differ diff --git a/project/images/tati_050301y.webp b/project/images/tati_050301y.webp new file mode 100644 index 0000000..1cf7669 Binary files /dev/null and b/project/images/tati_050301y.webp differ diff --git a/project/images/tati_050302.webp b/project/images/tati_050302.webp new file mode 100644 index 0000000..8eb4f7b Binary files /dev/null and b/project/images/tati_050302.webp differ diff --git a/project/images/tati_050303.webp b/project/images/tati_050303.webp new file mode 100644 index 0000000..561ff6d Binary files /dev/null and b/project/images/tati_050303.webp differ diff --git a/project/images/tati_050303y.webp b/project/images/tati_050303y.webp new file mode 100644 index 0000000..916859e Binary files /dev/null and b/project/images/tati_050303y.webp differ diff --git a/project/images/tati_050304.webp b/project/images/tati_050304.webp new file mode 100644 index 0000000..091d36b Binary files /dev/null and b/project/images/tati_050304.webp differ diff --git a/project/images/tati_050304y.webp b/project/images/tati_050304y.webp new file mode 100644 index 0000000..7587939 Binary files /dev/null and b/project/images/tati_050304y.webp differ diff --git a/project/images/tati_050305.webp b/project/images/tati_050305.webp new file mode 100644 index 0000000..7f6b7e2 Binary files /dev/null and b/project/images/tati_050305.webp differ diff --git a/project/images/tati_050305a.webp b/project/images/tati_050305a.webp new file mode 100644 index 0000000..0266053 Binary files /dev/null and b/project/images/tati_050305a.webp differ diff --git a/project/images/tati_050305y.webp b/project/images/tati_050305y.webp new file mode 100644 index 0000000..7ae4e59 Binary files /dev/null and b/project/images/tati_050305y.webp differ diff --git a/project/images/tati_050306.webp b/project/images/tati_050306.webp new file mode 100644 index 0000000..323b501 Binary files /dev/null and b/project/images/tati_050306.webp differ diff --git a/project/images/tati_050306y.webp b/project/images/tati_050306y.webp new file mode 100644 index 0000000..385c0f1 Binary files /dev/null and b/project/images/tati_050306y.webp differ diff --git a/project/images/tati_050307.webp b/project/images/tati_050307.webp new file mode 100644 index 0000000..b566868 Binary files /dev/null and b/project/images/tati_050307.webp differ diff --git a/project/images/tati_050307a.webp b/project/images/tati_050307a.webp new file mode 100644 index 0000000..f9d248b Binary files /dev/null and b/project/images/tati_050307a.webp differ diff --git a/project/images/tati_050307y.webp b/project/images/tati_050307y.webp new file mode 100644 index 0000000..bc14c5d Binary files /dev/null and b/project/images/tati_050307y.webp differ diff --git a/project/images/tati_050308.webp b/project/images/tati_050308.webp new file mode 100644 index 0000000..18e3096 Binary files /dev/null and b/project/images/tati_050308.webp differ diff --git a/project/images/tati_050309.webp b/project/images/tati_050309.webp new file mode 100644 index 0000000..7ffbd5d Binary files /dev/null and b/project/images/tati_050309.webp differ diff --git a/project/images/tati_050310.webp b/project/images/tati_050310.webp new file mode 100644 index 0000000..5e856aa Binary files /dev/null and b/project/images/tati_050310.webp differ diff --git a/project/images/tati_050311.webp b/project/images/tati_050311.webp new file mode 100644 index 0000000..f186eda Binary files /dev/null and b/project/images/tati_050311.webp differ diff --git a/project/images/tati_050311y.webp b/project/images/tati_050311y.webp new file mode 100644 index 0000000..59af9d8 Binary files /dev/null and b/project/images/tati_050311y.webp differ diff --git a/project/images/tati_050313.webp b/project/images/tati_050313.webp new file mode 100644 index 0000000..4660d8b Binary files /dev/null and b/project/images/tati_050313.webp differ diff --git a/project/images/tati_050314.webp b/project/images/tati_050314.webp new file mode 100644 index 0000000..4bf2a0e Binary files /dev/null and b/project/images/tati_050314.webp differ diff --git a/project/images/tati_050315.webp b/project/images/tati_050315.webp new file mode 100644 index 0000000..0ac2d72 Binary files /dev/null and b/project/images/tati_050315.webp differ diff --git a/project/images/tati_050316.webp b/project/images/tati_050316.webp new file mode 100644 index 0000000..cf4128a Binary files /dev/null and b/project/images/tati_050316.webp differ diff --git a/project/images/tati_050316y.webp b/project/images/tati_050316y.webp new file mode 100644 index 0000000..0b4df60 Binary files /dev/null and b/project/images/tati_050316y.webp differ diff --git a/project/images/tati_050317.webp b/project/images/tati_050317.webp new file mode 100644 index 0000000..3d3ce57 Binary files /dev/null and b/project/images/tati_050317.webp differ diff --git a/project/images/tati_050321.webp b/project/images/tati_050321.webp new file mode 100644 index 0000000..a9a8012 Binary files /dev/null and b/project/images/tati_050321.webp differ diff --git a/project/images/tati_050321a.webp b/project/images/tati_050321a.webp new file mode 100644 index 0000000..002e810 Binary files /dev/null and b/project/images/tati_050321a.webp differ diff --git a/project/images/tati_050321y.webp b/project/images/tati_050321y.webp new file mode 100644 index 0000000..6a8331a Binary files /dev/null and b/project/images/tati_050321y.webp differ diff --git a/project/images/tati_050322.webp b/project/images/tati_050322.webp new file mode 100644 index 0000000..1e7d827 Binary files /dev/null and b/project/images/tati_050322.webp differ diff --git a/project/images/tati_050322y.webp b/project/images/tati_050322y.webp new file mode 100644 index 0000000..3043a92 Binary files /dev/null and b/project/images/tati_050322y.webp differ diff --git a/project/images/tati_050323.webp b/project/images/tati_050323.webp new file mode 100644 index 0000000..9b2a380 Binary files /dev/null and b/project/images/tati_050323.webp differ diff --git a/project/images/tati_050324.webp b/project/images/tati_050324.webp new file mode 100644 index 0000000..ab2f3ce Binary files /dev/null and b/project/images/tati_050324.webp differ diff --git a/project/images/tati_050324a.webp b/project/images/tati_050324a.webp new file mode 100644 index 0000000..ac7fc74 Binary files /dev/null and b/project/images/tati_050324a.webp differ diff --git a/project/images/tati_050324y.webp b/project/images/tati_050324y.webp new file mode 100644 index 0000000..2e579cc Binary files /dev/null and b/project/images/tati_050324y.webp differ diff --git a/project/images/tati_050325.webp b/project/images/tati_050325.webp new file mode 100644 index 0000000..47ef3fb Binary files /dev/null and b/project/images/tati_050325.webp differ diff --git a/project/images/tati_050325a.webp b/project/images/tati_050325a.webp new file mode 100644 index 0000000..2f09eb1 Binary files /dev/null and b/project/images/tati_050325a.webp differ diff --git a/project/images/tati_050325y.webp b/project/images/tati_050325y.webp new file mode 100644 index 0000000..bd791d8 Binary files /dev/null and b/project/images/tati_050325y.webp differ diff --git a/project/images/tati_050326.webp b/project/images/tati_050326.webp new file mode 100644 index 0000000..0e866dc Binary files /dev/null and b/project/images/tati_050326.webp differ diff --git a/project/images/tati_050327.webp b/project/images/tati_050327.webp new file mode 100644 index 0000000..09dd7e9 Binary files /dev/null and b/project/images/tati_050327.webp differ diff --git a/project/images/tati_050327y.webp b/project/images/tati_050327y.webp new file mode 100644 index 0000000..837cbf5 Binary files /dev/null and b/project/images/tati_050327y.webp differ diff --git a/project/images/tati_050328.webp b/project/images/tati_050328.webp new file mode 100644 index 0000000..d8ad714 Binary files /dev/null and b/project/images/tati_050328.webp differ diff --git a/project/images/tati_050329.webp b/project/images/tati_050329.webp new file mode 100644 index 0000000..d8224a3 Binary files /dev/null and b/project/images/tati_050329.webp differ diff --git a/project/images/tati_050331.webp b/project/images/tati_050331.webp new file mode 100644 index 0000000..6a571cf Binary files /dev/null and b/project/images/tati_050331.webp differ diff --git a/project/images/tati_050331y.webp b/project/images/tati_050331y.webp new file mode 100644 index 0000000..86ccedd Binary files /dev/null and b/project/images/tati_050331y.webp differ diff --git a/project/images/tati_050332.webp b/project/images/tati_050332.webp new file mode 100644 index 0000000..f9b0ae2 Binary files /dev/null and b/project/images/tati_050332.webp differ diff --git a/project/images/tati_050333.webp b/project/images/tati_050333.webp new file mode 100644 index 0000000..0134380 Binary files /dev/null and b/project/images/tati_050333.webp differ diff --git a/project/images/tati_050334.webp b/project/images/tati_050334.webp new file mode 100644 index 0000000..2c6a11d Binary files /dev/null and b/project/images/tati_050334.webp differ diff --git a/project/images/tati_050334a.webp b/project/images/tati_050334a.webp new file mode 100644 index 0000000..11c3544 Binary files /dev/null and b/project/images/tati_050334a.webp differ diff --git a/project/images/tati_050335.webp b/project/images/tati_050335.webp new file mode 100644 index 0000000..f92b052 Binary files /dev/null and b/project/images/tati_050335.webp differ diff --git a/project/images/tati_050337.webp b/project/images/tati_050337.webp new file mode 100644 index 0000000..2a4e430 Binary files /dev/null and b/project/images/tati_050337.webp differ diff --git a/project/images/tati_050338.webp b/project/images/tati_050338.webp new file mode 100644 index 0000000..0497a5f Binary files /dev/null and b/project/images/tati_050338.webp differ diff --git a/project/images/tati_050338y.webp b/project/images/tati_050338y.webp new file mode 100644 index 0000000..076f83c Binary files /dev/null and b/project/images/tati_050338y.webp differ diff --git a/project/images/tati_050341.webp b/project/images/tati_050341.webp new file mode 100644 index 0000000..04d340e Binary files /dev/null and b/project/images/tati_050341.webp differ diff --git a/project/images/tati_050341a.webp b/project/images/tati_050341a.webp new file mode 100644 index 0000000..875a3f9 Binary files /dev/null and b/project/images/tati_050341a.webp differ diff --git a/project/images/tati_050341y.webp b/project/images/tati_050341y.webp new file mode 100644 index 0000000..72dba58 Binary files /dev/null and b/project/images/tati_050341y.webp differ diff --git a/project/images/tati_050342.webp b/project/images/tati_050342.webp new file mode 100644 index 0000000..62510c3 Binary files /dev/null and b/project/images/tati_050342.webp differ diff --git a/project/images/tati_050343.webp b/project/images/tati_050343.webp new file mode 100644 index 0000000..5a281c6 Binary files /dev/null and b/project/images/tati_050343.webp differ diff --git a/project/images/tati_050343y.webp b/project/images/tati_050343y.webp new file mode 100644 index 0000000..0604b3f Binary files /dev/null and b/project/images/tati_050343y.webp differ diff --git a/project/images/tati_050344.webp b/project/images/tati_050344.webp new file mode 100644 index 0000000..07ad5a8 Binary files /dev/null and b/project/images/tati_050344.webp differ diff --git a/project/images/tati_050345.webp b/project/images/tati_050345.webp new file mode 100644 index 0000000..a54aecf Binary files /dev/null and b/project/images/tati_050345.webp differ diff --git a/project/images/tati_050345a.webp b/project/images/tati_050345a.webp new file mode 100644 index 0000000..2242854 Binary files /dev/null and b/project/images/tati_050345a.webp differ diff --git a/project/images/tati_050345y.webp b/project/images/tati_050345y.webp new file mode 100644 index 0000000..6df2797 Binary files /dev/null and b/project/images/tati_050345y.webp differ diff --git a/project/images/tati_050346.webp b/project/images/tati_050346.webp new file mode 100644 index 0000000..cbb5b61 Binary files /dev/null and b/project/images/tati_050346.webp differ diff --git a/project/images/tati_050347.webp b/project/images/tati_050347.webp new file mode 100644 index 0000000..4f8265f Binary files /dev/null and b/project/images/tati_050347.webp differ diff --git a/project/images/tati_050348.webp b/project/images/tati_050348.webp new file mode 100644 index 0000000..8ffccb9 Binary files /dev/null and b/project/images/tati_050348.webp differ diff --git a/project/images/tati_050349.webp b/project/images/tati_050349.webp new file mode 100644 index 0000000..3ac485f Binary files /dev/null and b/project/images/tati_050349.webp differ diff --git a/project/images/tati_050351.webp b/project/images/tati_050351.webp new file mode 100644 index 0000000..7b70249 Binary files /dev/null and b/project/images/tati_050351.webp differ diff --git a/project/images/tati_050351y.webp b/project/images/tati_050351y.webp new file mode 100644 index 0000000..d2a0b93 Binary files /dev/null and b/project/images/tati_050351y.webp differ diff --git a/project/images/tati_050352.webp b/project/images/tati_050352.webp new file mode 100644 index 0000000..018c49d Binary files /dev/null and b/project/images/tati_050352.webp differ diff --git a/project/images/tati_050353.webp b/project/images/tati_050353.webp new file mode 100644 index 0000000..0f17f24 Binary files /dev/null and b/project/images/tati_050353.webp differ diff --git a/project/images/tati_050353y.webp b/project/images/tati_050353y.webp new file mode 100644 index 0000000..c422640 Binary files /dev/null and b/project/images/tati_050353y.webp differ diff --git a/project/images/tati_050441.webp b/project/images/tati_050441.webp new file mode 100644 index 0000000..2e7df0f Binary files /dev/null and b/project/images/tati_050441.webp differ diff --git a/project/images/tati_050443.webp b/project/images/tati_050443.webp new file mode 100644 index 0000000..a4189d0 Binary files /dev/null and b/project/images/tati_050443.webp differ diff --git a/project/images/tati_050443y.webp b/project/images/tati_050443y.webp new file mode 100644 index 0000000..4273394 Binary files /dev/null and b/project/images/tati_050443y.webp differ diff --git a/project/images/tati_050445.webp b/project/images/tati_050445.webp new file mode 100644 index 0000000..1a0313e Binary files /dev/null and b/project/images/tati_050445.webp differ diff --git a/project/images/tati_050445a.webp b/project/images/tati_050445a.webp new file mode 100644 index 0000000..a3e4da3 Binary files /dev/null and b/project/images/tati_050445a.webp differ diff --git a/project/images/tati_050445y.webp b/project/images/tati_050445y.webp new file mode 100644 index 0000000..99c60db Binary files /dev/null and b/project/images/tati_050445y.webp differ diff --git a/project/images/tati_050451.webp b/project/images/tati_050451.webp new file mode 100644 index 0000000..6020b87 Binary files /dev/null and b/project/images/tati_050451.webp differ diff --git a/project/images/tati_050451a.webp b/project/images/tati_050451a.webp new file mode 100644 index 0000000..9d970c7 Binary files /dev/null and b/project/images/tati_050451a.webp differ diff --git a/project/images/tati_050452.webp b/project/images/tati_050452.webp new file mode 100644 index 0000000..315d2cb Binary files /dev/null and b/project/images/tati_050452.webp differ diff --git a/project/images/tati_050452y.webp b/project/images/tati_050452y.webp new file mode 100644 index 0000000..6718c6d Binary files /dev/null and b/project/images/tati_050452y.webp differ diff --git a/project/images/tati_120101.webp b/project/images/tati_120101.webp new file mode 100644 index 0000000..b029f25 Binary files /dev/null and b/project/images/tati_120101.webp differ diff --git a/project/images/tati_120101y.webp b/project/images/tati_120101y.webp new file mode 100644 index 0000000..7e62b74 Binary files /dev/null and b/project/images/tati_120101y.webp differ diff --git a/project/images/tati_120102.webp b/project/images/tati_120102.webp new file mode 100644 index 0000000..15fb1ca Binary files /dev/null and b/project/images/tati_120102.webp differ diff --git a/project/images/tati_120102y.webp b/project/images/tati_120102y.webp new file mode 100644 index 0000000..57ea32c Binary files /dev/null and b/project/images/tati_120102y.webp differ diff --git a/project/images/tati_120103.webp b/project/images/tati_120103.webp new file mode 100644 index 0000000..1352df3 Binary files /dev/null and b/project/images/tati_120103.webp differ diff --git a/project/images/tati_120103y.webp b/project/images/tati_120103y.webp new file mode 100644 index 0000000..9af9fc8 Binary files /dev/null and b/project/images/tati_120103y.webp differ diff --git a/project/images/tati_120104.webp b/project/images/tati_120104.webp new file mode 100644 index 0000000..1435e70 Binary files /dev/null and b/project/images/tati_120104.webp differ diff --git a/project/images/tati_120104y.webp b/project/images/tati_120104y.webp new file mode 100644 index 0000000..112259f Binary files /dev/null and b/project/images/tati_120104y.webp differ diff --git a/project/images/tati_120105.webp b/project/images/tati_120105.webp new file mode 100644 index 0000000..40980f7 Binary files /dev/null and b/project/images/tati_120105.webp differ diff --git a/project/images/tati_120105y.webp b/project/images/tati_120105y.webp new file mode 100644 index 0000000..100d3f1 Binary files /dev/null and b/project/images/tati_120105y.webp differ diff --git a/project/images/tati_120106.webp b/project/images/tati_120106.webp new file mode 100644 index 0000000..d9f065d Binary files /dev/null and b/project/images/tati_120106.webp differ diff --git a/project/images/tati_120107.webp b/project/images/tati_120107.webp new file mode 100644 index 0000000..ac25b28 Binary files /dev/null and b/project/images/tati_120107.webp differ diff --git a/project/images/tati_120107y.webp b/project/images/tati_120107y.webp new file mode 100644 index 0000000..baf03db Binary files /dev/null and b/project/images/tati_120107y.webp differ diff --git a/project/images/tati_120108.webp b/project/images/tati_120108.webp new file mode 100644 index 0000000..e33b955 Binary files /dev/null and b/project/images/tati_120108.webp differ diff --git a/project/images/tati_120111.webp b/project/images/tati_120111.webp new file mode 100644 index 0000000..18fcb9f Binary files /dev/null and b/project/images/tati_120111.webp differ diff --git a/project/images/tati_120111y.webp b/project/images/tati_120111y.webp new file mode 100644 index 0000000..8d69d91 Binary files /dev/null and b/project/images/tati_120111y.webp differ diff --git a/project/images/tati_120112.webp b/project/images/tati_120112.webp new file mode 100644 index 0000000..6c662fd Binary files /dev/null and b/project/images/tati_120112.webp differ diff --git a/project/images/tati_120113.webp b/project/images/tati_120113.webp new file mode 100644 index 0000000..01e30af Binary files /dev/null and b/project/images/tati_120113.webp differ diff --git a/project/images/tati_120113y.webp b/project/images/tati_120113y.webp new file mode 100644 index 0000000..e91fd21 Binary files /dev/null and b/project/images/tati_120113y.webp differ diff --git a/project/images/tati_120121.webp b/project/images/tati_120121.webp new file mode 100644 index 0000000..d0ddee1 Binary files /dev/null and b/project/images/tati_120121.webp differ diff --git a/project/images/tati_120121y.webp b/project/images/tati_120121y.webp new file mode 100644 index 0000000..7b2d0e5 Binary files /dev/null and b/project/images/tati_120121y.webp differ diff --git a/project/images/tati_120122.webp b/project/images/tati_120122.webp new file mode 100644 index 0000000..3207f82 Binary files /dev/null and b/project/images/tati_120122.webp differ diff --git a/project/images/tati_120123.webp b/project/images/tati_120123.webp new file mode 100644 index 0000000..7d3d768 Binary files /dev/null and b/project/images/tati_120123.webp differ diff --git a/project/images/tati_120123y.webp b/project/images/tati_120123y.webp new file mode 100644 index 0000000..5b7df9e Binary files /dev/null and b/project/images/tati_120123y.webp differ diff --git a/project/images/tati_120125.webp b/project/images/tati_120125.webp new file mode 100644 index 0000000..8cfd59c Binary files /dev/null and b/project/images/tati_120125.webp differ diff --git a/project/images/tati_120125y.webp b/project/images/tati_120125y.webp new file mode 100644 index 0000000..e7e2fe9 Binary files /dev/null and b/project/images/tati_120125y.webp differ diff --git a/project/images/tati_120126.webp b/project/images/tati_120126.webp new file mode 100644 index 0000000..3e0f874 Binary files /dev/null and b/project/images/tati_120126.webp differ diff --git a/project/images/tati_120127.webp b/project/images/tati_120127.webp new file mode 100644 index 0000000..c010e67 Binary files /dev/null and b/project/images/tati_120127.webp differ diff --git a/project/images/tati_120127y.webp b/project/images/tati_120127y.webp new file mode 100644 index 0000000..020fcf8 Binary files /dev/null and b/project/images/tati_120127y.webp differ diff --git a/project/images/tati_120128.webp b/project/images/tati_120128.webp new file mode 100644 index 0000000..f1de7ab Binary files /dev/null and b/project/images/tati_120128.webp differ diff --git a/project/images/tati_120131.webp b/project/images/tati_120131.webp new file mode 100644 index 0000000..9e88925 Binary files /dev/null and b/project/images/tati_120131.webp differ diff --git a/project/images/tati_120132.webp b/project/images/tati_120132.webp new file mode 100644 index 0000000..f67a394 Binary files /dev/null and b/project/images/tati_120132.webp differ diff --git a/project/images/tati_310101.webp b/project/images/tati_310101.webp new file mode 100644 index 0000000..e5a5dce Binary files /dev/null and b/project/images/tati_310101.webp differ diff --git a/project/images/tati_340101.webp b/project/images/tati_340101.webp new file mode 100644 index 0000000..96724ce Binary files /dev/null and b/project/images/tati_340101.webp differ diff --git a/project/images/tati_340101a.webp b/project/images/tati_340101a.webp new file mode 100644 index 0000000..add8ba2 Binary files /dev/null and b/project/images/tati_340101a.webp differ diff --git a/project/images/tati_340101y.webp b/project/images/tati_340101y.webp new file mode 100644 index 0000000..bb04825 Binary files /dev/null and b/project/images/tati_340101y.webp differ diff --git a/project/images/tati_340102.webp b/project/images/tati_340102.webp new file mode 100644 index 0000000..769f51b Binary files /dev/null and b/project/images/tati_340102.webp differ diff --git a/project/images/tati_340102y.webp b/project/images/tati_340102y.webp new file mode 100644 index 0000000..7b6d59e Binary files /dev/null and b/project/images/tati_340102y.webp differ diff --git a/project/images/tati_340103.webp b/project/images/tati_340103.webp new file mode 100644 index 0000000..2a383eb Binary files /dev/null and b/project/images/tati_340103.webp differ diff --git a/project/images/tati_340103y.webp b/project/images/tati_340103y.webp new file mode 100644 index 0000000..6145491 Binary files /dev/null and b/project/images/tati_340103y.webp differ diff --git a/project/images/tati_340104.webp b/project/images/tati_340104.webp new file mode 100644 index 0000000..9728246 Binary files /dev/null and b/project/images/tati_340104.webp differ diff --git a/project/images/tati_340104y.webp b/project/images/tati_340104y.webp new file mode 100644 index 0000000..5482404 Binary files /dev/null and b/project/images/tati_340104y.webp differ diff --git a/project/images/tati_340105.webp b/project/images/tati_340105.webp new file mode 100644 index 0000000..dd76fb8 Binary files /dev/null and b/project/images/tati_340105.webp differ diff --git a/project/images/tati_340105a.webp b/project/images/tati_340105a.webp new file mode 100644 index 0000000..681610a Binary files /dev/null and b/project/images/tati_340105a.webp differ diff --git a/project/images/tati_340105y.webp b/project/images/tati_340105y.webp new file mode 100644 index 0000000..bad076a Binary files /dev/null and b/project/images/tati_340105y.webp differ diff --git a/project/images/tati_340106.webp b/project/images/tati_340106.webp new file mode 100644 index 0000000..4be5842 Binary files /dev/null and b/project/images/tati_340106.webp differ diff --git a/project/images/tati_340106y.webp b/project/images/tati_340106y.webp new file mode 100644 index 0000000..d9b8110 Binary files /dev/null and b/project/images/tati_340106y.webp differ diff --git a/project/images/tati_340107.webp b/project/images/tati_340107.webp new file mode 100644 index 0000000..6923456 Binary files /dev/null and b/project/images/tati_340107.webp differ diff --git a/project/images/tati_340107y.webp b/project/images/tati_340107y.webp new file mode 100644 index 0000000..05fb151 Binary files /dev/null and b/project/images/tati_340107y.webp differ diff --git a/project/images/tati_340108.webp b/project/images/tati_340108.webp new file mode 100644 index 0000000..46e1ce1 Binary files /dev/null and b/project/images/tati_340108.webp differ diff --git a/project/images/tati_340108y.webp b/project/images/tati_340108y.webp new file mode 100644 index 0000000..a5faccc Binary files /dev/null and b/project/images/tati_340108y.webp differ diff --git a/project/images/tati_340109.webp b/project/images/tati_340109.webp new file mode 100644 index 0000000..7929c9a Binary files /dev/null and b/project/images/tati_340109.webp differ diff --git a/project/images/tati_340109y.webp b/project/images/tati_340109y.webp new file mode 100644 index 0000000..90a58f3 Binary files /dev/null and b/project/images/tati_340109y.webp differ diff --git a/project/images/tati_340110.webp b/project/images/tati_340110.webp new file mode 100644 index 0000000..bc4d976 Binary files /dev/null and b/project/images/tati_340110.webp differ diff --git a/project/images/tati_340110y.webp b/project/images/tati_340110y.webp new file mode 100644 index 0000000..20491bf Binary files /dev/null and b/project/images/tati_340110y.webp differ diff --git a/project/images/tati_340111.webp b/project/images/tati_340111.webp new file mode 100644 index 0000000..e8d251d Binary files /dev/null and b/project/images/tati_340111.webp differ diff --git a/project/images/tati_340111y.webp b/project/images/tati_340111y.webp new file mode 100644 index 0000000..1681178 Binary files /dev/null and b/project/images/tati_340111y.webp differ diff --git a/project/images/tati_340112.webp b/project/images/tati_340112.webp new file mode 100644 index 0000000..2786dcc Binary files /dev/null and b/project/images/tati_340112.webp differ diff --git a/project/images/tati_340112a.webp b/project/images/tati_340112a.webp new file mode 100644 index 0000000..37a492c Binary files /dev/null and b/project/images/tati_340112a.webp differ diff --git a/project/images/tati_340112y.webp b/project/images/tati_340112y.webp new file mode 100644 index 0000000..f20b1e4 Binary files /dev/null and b/project/images/tati_340112y.webp differ diff --git a/project/images/tati_340113.webp b/project/images/tati_340113.webp new file mode 100644 index 0000000..08b5954 Binary files /dev/null and b/project/images/tati_340113.webp differ diff --git a/project/images/tati_340113y.webp b/project/images/tati_340113y.webp new file mode 100644 index 0000000..0316326 Binary files /dev/null and b/project/images/tati_340113y.webp differ diff --git a/project/images/tati_340114.webp b/project/images/tati_340114.webp new file mode 100644 index 0000000..3f7da16 Binary files /dev/null and b/project/images/tati_340114.webp differ diff --git a/project/images/tati_340114y.webp b/project/images/tati_340114y.webp new file mode 100644 index 0000000..ee21221 Binary files /dev/null and b/project/images/tati_340114y.webp differ diff --git a/project/images/tati_340115.webp b/project/images/tati_340115.webp new file mode 100644 index 0000000..f8cd30d Binary files /dev/null and b/project/images/tati_340115.webp differ diff --git a/project/images/tati_430101.webp b/project/images/tati_430101.webp new file mode 100644 index 0000000..82d2e68 Binary files /dev/null and b/project/images/tati_430101.webp differ diff --git a/project/images/tati_430101a.webp b/project/images/tati_430101a.webp new file mode 100644 index 0000000..153d99f Binary files /dev/null and b/project/images/tati_430101a.webp differ diff --git a/project/images/tati_430101y.webp b/project/images/tati_430101y.webp new file mode 100644 index 0000000..fa51d26 Binary files /dev/null and b/project/images/tati_430101y.webp differ diff --git a/project/images/tati_430102.webp b/project/images/tati_430102.webp new file mode 100644 index 0000000..428e27f Binary files /dev/null and b/project/images/tati_430102.webp differ diff --git a/project/images/tati_430102a.webp b/project/images/tati_430102a.webp new file mode 100644 index 0000000..045891a Binary files /dev/null and b/project/images/tati_430102a.webp differ diff --git a/project/images/tati_430102y.webp b/project/images/tati_430102y.webp new file mode 100644 index 0000000..7f0c790 Binary files /dev/null and b/project/images/tati_430102y.webp differ diff --git a/project/images/tati_430103.webp b/project/images/tati_430103.webp new file mode 100644 index 0000000..3328371 Binary files /dev/null and b/project/images/tati_430103.webp differ diff --git a/project/images/tati_430103a.webp b/project/images/tati_430103a.webp new file mode 100644 index 0000000..5954ed6 Binary files /dev/null and b/project/images/tati_430103a.webp differ diff --git a/project/images/tati_430103y.webp b/project/images/tati_430103y.webp new file mode 100644 index 0000000..852203c Binary files /dev/null and b/project/images/tati_430103y.webp differ diff --git a/project/images/tati_430104.webp b/project/images/tati_430104.webp new file mode 100644 index 0000000..63618c6 Binary files /dev/null and b/project/images/tati_430104.webp differ diff --git a/project/images/tati_430105.webp b/project/images/tati_430105.webp new file mode 100644 index 0000000..3b913ca Binary files /dev/null and b/project/images/tati_430105.webp differ diff --git a/project/images/tati_430105a.webp b/project/images/tati_430105a.webp new file mode 100644 index 0000000..62279c2 Binary files /dev/null and b/project/images/tati_430105a.webp differ diff --git a/project/images/tati_430105y.webp b/project/images/tati_430105y.webp new file mode 100644 index 0000000..d2c47f7 Binary files /dev/null and b/project/images/tati_430105y.webp differ diff --git a/project/images/tati_430106.webp b/project/images/tati_430106.webp new file mode 100644 index 0000000..38e047f Binary files /dev/null and b/project/images/tati_430106.webp differ diff --git a/project/images/tati_430106a.webp b/project/images/tati_430106a.webp new file mode 100644 index 0000000..a448e29 Binary files /dev/null and b/project/images/tati_430106a.webp differ diff --git a/project/images/tati_430106y.webp b/project/images/tati_430106y.webp new file mode 100644 index 0000000..3fb8ee5 Binary files /dev/null and b/project/images/tati_430106y.webp differ diff --git a/project/images/tati_430107.webp b/project/images/tati_430107.webp new file mode 100644 index 0000000..5ee8605 Binary files /dev/null and b/project/images/tati_430107.webp differ diff --git a/project/images/tati_430107y.webp b/project/images/tati_430107y.webp new file mode 100644 index 0000000..d8dd713 Binary files /dev/null and b/project/images/tati_430107y.webp differ diff --git a/project/images/tati_430108.webp b/project/images/tati_430108.webp new file mode 100644 index 0000000..088b83f Binary files /dev/null and b/project/images/tati_430108.webp differ diff --git a/project/images/tati_430108a.webp b/project/images/tati_430108a.webp new file mode 100644 index 0000000..5699299 Binary files /dev/null and b/project/images/tati_430108a.webp differ diff --git a/project/images/tati_430108y.webp b/project/images/tati_430108y.webp new file mode 100644 index 0000000..a2a6fc4 Binary files /dev/null and b/project/images/tati_430108y.webp differ diff --git a/project/images/tati_440101.webp b/project/images/tati_440101.webp new file mode 100644 index 0000000..13b1e48 Binary files /dev/null and b/project/images/tati_440101.webp differ diff --git a/project/images/tati_440101y.webp b/project/images/tati_440101y.webp new file mode 100644 index 0000000..2b632ae Binary files /dev/null and b/project/images/tati_440101y.webp differ diff --git a/project/images/tati_440103.webp b/project/images/tati_440103.webp new file mode 100644 index 0000000..5e96a78 Binary files /dev/null and b/project/images/tati_440103.webp differ diff --git a/project/images/tati_440104.webp b/project/images/tati_440104.webp new file mode 100644 index 0000000..0953eba Binary files /dev/null and b/project/images/tati_440104.webp differ diff --git a/project/images/tati_440105.webp b/project/images/tati_440105.webp new file mode 100644 index 0000000..abbd82e Binary files /dev/null and b/project/images/tati_440105.webp differ diff --git a/project/images/tati_440106.webp b/project/images/tati_440106.webp new file mode 100644 index 0000000..e8fe7e5 Binary files /dev/null and b/project/images/tati_440106.webp differ diff --git a/project/images/tati_440108.webp b/project/images/tati_440108.webp new file mode 100644 index 0000000..412223f Binary files /dev/null and b/project/images/tati_440108.webp differ diff --git a/project/images/tati_z340101.webp b/project/images/tati_z340101.webp new file mode 100644 index 0000000..5387c08 Binary files /dev/null and b/project/images/tati_z340101.webp differ diff --git a/project/images/tati_z340102.webp b/project/images/tati_z340102.webp new file mode 100644 index 0000000..e3db89f Binary files /dev/null and b/project/images/tati_z340102.webp differ diff --git a/project/images/tati_z340103.webp b/project/images/tati_z340103.webp new file mode 100644 index 0000000..1850508 Binary files /dev/null and b/project/images/tati_z340103.webp differ diff --git a/project/images/tati_z340104.webp b/project/images/tati_z340104.webp new file mode 100644 index 0000000..1300940 Binary files /dev/null and b/project/images/tati_z340104.webp differ diff --git a/project/images/tati_z340105.webp b/project/images/tati_z340105.webp new file mode 100644 index 0000000..505a09c Binary files /dev/null and b/project/images/tati_z340105.webp differ diff --git a/project/images/tati_z340106.webp b/project/images/tati_z340106.webp new file mode 100644 index 0000000..0911177 Binary files /dev/null and b/project/images/tati_z340106.webp differ diff --git a/project/images/tati_z340107.webp b/project/images/tati_z340107.webp new file mode 100644 index 0000000..2241f44 Binary files /dev/null and b/project/images/tati_z340107.webp differ diff --git a/project/images/tati_z340108.webp b/project/images/tati_z340108.webp new file mode 100644 index 0000000..f4c6f2b Binary files /dev/null and b/project/images/tati_z340108.webp differ diff --git a/project/images/tati_z340109.webp b/project/images/tati_z340109.webp new file mode 100644 index 0000000..7e836f5 Binary files /dev/null and b/project/images/tati_z340109.webp differ diff --git a/project/images/tati_z340110.webp b/project/images/tati_z340110.webp new file mode 100644 index 0000000..61c5610 Binary files /dev/null and b/project/images/tati_z340110.webp differ diff --git a/project/images/tati_z340111.webp b/project/images/tati_z340111.webp new file mode 100644 index 0000000..e7b3efd Binary files /dev/null and b/project/images/tati_z340111.webp differ diff --git a/project/images/tati_z340112.webp b/project/images/tati_z340112.webp new file mode 100644 index 0000000..c46c0c0 Binary files /dev/null and b/project/images/tati_z340112.webp differ diff --git a/project/images/tati_z340113.webp b/project/images/tati_z340113.webp new file mode 100644 index 0000000..2284cda Binary files /dev/null and b/project/images/tati_z340113.webp differ diff --git a/project/images/tati_z340114.webp b/project/images/tati_z340114.webp new file mode 100644 index 0000000..1c1f0dc Binary files /dev/null and b/project/images/tati_z340114.webp differ diff --git a/project/images/tati_z340115.webp b/project/images/tati_z340115.webp new file mode 100644 index 0000000..9a1621c Binary files /dev/null and b/project/images/tati_z340115.webp differ diff --git a/project/images/winbackground.webp b/project/images/winbackground.webp new file mode 100644 index 0000000..67efc83 Binary files /dev/null and b/project/images/winbackground.webp differ diff --git a/project/images/winbackgroundVertical.webp b/project/images/winbackgroundVertical.webp new file mode 100644 index 0000000..3d05864 Binary files /dev/null and b/project/images/winbackgroundVertical.webp differ diff --git a/project/images/winskin.webp b/project/images/winskin.webp index fb44533..00580fe 100644 Binary files a/project/images/winskin.webp and b/project/images/winskin.webp differ diff --git a/project/images/xunhuan.webp b/project/images/xunhuan.webp new file mode 100644 index 0000000..a588af0 Binary files /dev/null and b/project/images/xunhuan.webp differ diff --git a/project/items.js b/project/items.js index 05dcc9c..53d1d78 100644 --- a/project/items.js +++ b/project/items.js @@ -146,14 +146,14 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "sword1": { "cls": "equips", "name": "铁剑", - "text": "一把很普通的铁剑", + "text": "一把普通的铁剑", "equip": { "type": 0, "animate": "sword", - "value": { - "atk": 10 - }, - "percentage": {} + "value": {}, + "percentage": { + "mdef": 10 + } }, "itemEffect": "core.status.hero.atk += 10", "itemEffectTip": ",攻击+10", @@ -166,10 +166,10 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "equip": { "type": "武器", "animate": "sword", - "value": { - "atk": 20 - }, - "percentage": {} + "value": {}, + "percentage": { + "mdef": 20 + } }, "itemEffect": "core.status.hero.atk += 20", "itemEffectTip": ",攻击+20", @@ -224,17 +224,22 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "equipCls": "匕首" }, "shield0": { - "cls": "items", + "cls": "equips", "name": "破旧的盾", "text": "一个很破旧的铁盾", "equip": { - "type": 1, + "type": 2, "value": { - "def": 0 + "mdef": -5, + "def": 10 + }, + "percentage": { + "def": 10 } }, "itemEffect": "core.status.hero.def += 0", - "itemEffectTip": ",防御+0" + "itemEffectTip": ",防御+0", + "equipCls": "护具" }, "shield1": { "cls": "equips", @@ -242,10 +247,10 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "text": "一个很普通的铁盾", "equip": { "type": 1, - "value": { - "def": 10 - }, - "percentage": {} + "value": {}, + "percentage": { + "mdef": 10 + } }, "itemEffect": "core.status.hero.def += 10", "itemEffectTip": ",防御+10", @@ -305,13 +310,15 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "itemEffectTip": ",防御+100,护盾+100" }, "superPotion": { - "cls": "items", + "cls": "tools", "name": "圣水", "itemEffect": "core.status.hero.hp *= 2", "itemEffectTip": ",生命值翻倍", "useItemEffect": "core.status.hero.hp *= 2;core.playSound('回血');", "canUseItemEffect": "true", - "text": "生命值翻倍" + "text": "生命值翻倍", + "canBatchUse": "true", + "hideInReplay": true }, "book": { "cls": "constants", @@ -327,7 +334,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "text": "可以自由往来去过的楼层", "hideInReplay": true, "hideInToolbox": true, - "useItemEffect": "//core.ui.drawFly(core.floorIds.indexOf(core.status.floorId));\ncore.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId));", + "useItemEffect": "//core.ui.drawFly(core.floorIds.indexOf(core.status.floorId));\nflags.canMoveFloor = core.canMoveFloor()\nif (!main.replayChecking && !core.isReplaying()) core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId));", "canUseItemEffect": "(function () {\n\tif (core.flags.flyNearStair && !core.nearStair() && !core.canMoveFloor())\n\t\treturn false;\n\treturn core.status.maps[core.status.floorId].canFlyFrom;\n})();" }, "coin": { @@ -541,5 +548,60 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "name": "钱袋", "itemEffect": "core.status.hero.money += 500", "itemEffectTip": ",金币+500" + }, + "I366": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I367": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I368": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I369": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I370": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I371": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I372": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I373": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I374": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I375": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" + }, + "I396": { + "cls": "items", + "name": "新物品", + "canUseItemEffect": "true" } } \ No newline at end of file diff --git a/project/maps.js b/project/maps.js index 6367155..d1b42f0 100644 --- a/project/maps.js +++ b/project/maps.js @@ -1,11 +1,11 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = { - "1": {"cls":"animates","id":"yellowWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, - "2": {"cls":"animates","id":"whiteWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, - "3": {"cls":"animates","id":"blueWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, + "1": {"cls":"animates","id":"yellowWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{}}}, + "2": {"cls":"animates","id":"whiteWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{}}}, + "3": {"cls":"animates","id":"blueWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{}}}, "4": {"cls":"animates","id":"star","name":"星空"}, "5": {"cls":"animates","id":"lava","name":"岩浆"}, - "6": {"cls":"animates","id":"ice","doorInfo":{"time":160,"openSound":"破冰镐","closeSound":"door.mp3","keys":{"icePickaxe":1}},"animate":1}, + "6": {"cls":"animates","id":"ice","doorInfo":{"time":160,"openSound":"破冰镐","closeSound":"door.opus","keys":{"icePickaxe":1}},"animate":1}, "7": {"cls":"terrains","id":"blueShopLeft"}, "8": {"cls":"terrains","id":"blueShopRight"}, "9": {"cls":"terrains","id":"pinkShopLeft"}, @@ -68,12 +68,12 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "71": {"cls":"items","id":"shield0"}, "72": {"cls":"items","id":"skill1"}, "73": {"cls":"items","id":"wand"}, - "81": {"cls":"animates","id":"yellowDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"yellowKey":1}},"name":"黄门"}, - "82": {"cls":"animates","id":"blueDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"blueKey":1}},"name":"蓝门"}, - "83": {"cls":"animates","id":"redDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"redKey":1}},"name":"红门"}, - "84": {"cls":"animates","id":"greenDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"greenKey":1}},"name":"绿门"}, - "85": {"cls":"animates","id":"specialDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"specialKey":1}},"name":"机关门"}, - "86": {"cls":"animates","id":"steelDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"steelKey":1}},"name":"铁门"}, + "81": {"cls":"animates","id":"yellowDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"yellowKey":1}},"name":"黄门"}, + "82": {"cls":"animates","id":"blueDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"blueKey":1}},"name":"蓝门"}, + "83": {"cls":"animates","id":"redDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"redKey":1}},"name":"红门"}, + "84": {"cls":"animates","id":"greenDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"greenKey":1}},"name":"绿门"}, + "85": {"cls":"animates","id":"specialDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"specialKey":1}},"name":"机关门"}, + "86": {"cls":"animates","id":"steelDoor","trigger":"openDoor","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"steelKey":1}},"name":"铁门"}, "87": {"cls":"terrains","id":"upFloor","canPass":true}, "88": {"cls":"terrains","id":"downFloor","canPass":true}, "89": {"cls":"animates","id":"portal","canPass":true}, @@ -86,7 +86,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "102": {"cls":"animates","id":"crystalBottom"}, "103": {"cls":"animates","id":"fire"}, "104": {"cls":"animates","id":"switch"}, - "109": {"cls":"animates","id":"magentaWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{}}}, + "109": {"cls":"animates","id":"magentaWall","canBreak":true,"animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{}}}, "121": {"cls":"npcs","id":"man"}, "122": {"cls":"npcs","id":"trader"}, "123": {"cls":"npcs","id":"thief"}, @@ -217,12 +217,12 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "316": {"cls":"terrains","id":"sWallTLR","name":"薄墙-上左右","cannotOut":["up","left","right"],"cannotIn":["up","left","right"]}, "317": {"cls":"terrains","id":"sWallTBR","name":"薄墙-上下右","cannotOut":["up","down","right"],"cannotIn":["up","down","right"]}, "318": {"cls":"terrains","id":"sWallTBL","name":"薄墙-上下左","cannotOut":["up","down","left"],"cannotIn":["up","down","left"]}, - "319": {"cls":"npc48","id":"tallYellowDoor","trigger":"openDoor","name":"高黄门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"yellowKey":1}}}, - "320": {"cls":"npc48","id":"tallBlueDoor","trigger":"openDoor","name":"高蓝门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"blueKey":1}}}, - "321": {"cls":"npc48","id":"tallRedDoor","trigger":"openDoor","name":"高红门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"redKey":1}}}, - "322": {"cls":"npc48","id":"tallGreenDoor","trigger":"openDoor","name":"高绿门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"greenKey":1}}}, - "323": {"cls":"npc48","id":"tallSpecialDoor","trigger":"openDoor","name":"高机关门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"specialKey":1}}}, - "324": {"cls":"npc48","id":"tallSteelDoor","trigger":"openDoor","name":"高铁门","animate":1,"doorInfo":{"time":160,"openSound":"door.mp3","closeSound":"door.mp3","keys":{"steelKey":1}}}, + "319": {"cls":"npc48","id":"tallYellowDoor","trigger":"openDoor","name":"高黄门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"yellowKey":1}}}, + "320": {"cls":"npc48","id":"tallBlueDoor","trigger":"openDoor","name":"高蓝门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"blueKey":1}}}, + "321": {"cls":"npc48","id":"tallRedDoor","trigger":"openDoor","name":"高红门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"redKey":1}}}, + "322": {"cls":"npc48","id":"tallGreenDoor","trigger":"openDoor","name":"高绿门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"greenKey":1}}}, + "323": {"cls":"npc48","id":"tallSpecialDoor","trigger":"openDoor","name":"高机关门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"specialKey":1}}}, + "324": {"cls":"npc48","id":"tallSteelDoor","trigger":"openDoor","name":"高铁门","animate":1,"doorInfo":{"time":160,"openSound":"door.opus","closeSound":"door.opus","keys":{"steelKey":1}}}, "325": {"cls":"enemys","id":"keiskeiFairy"}, "326": {"cls":"enemys","id":"tulipFairy"}, "327": {"cls":"enemy48","id":"bearDown"}, @@ -259,6 +259,21 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "358": {"cls":"terrains","id":"T358"}, "359": {"cls":"terrains","id":"T359"}, "360": {"cls":"terrains","id":"T360"}, + "361": {"cls":"terrains","id":"T361"}, + "362": {"cls":"terrains","id":"T362"}, + "363": {"cls":"terrains","id":"T363"}, + "364": {"cls":"terrains","id":"T364"}, + "365": {"cls":"terrains","id":"T365"}, + "366": {"cls":"items","id":"I366"}, + "367": {"cls":"items","id":"I367"}, + "368": {"cls":"items","id":"I368"}, + "369": {"cls":"items","id":"I369"}, + "370": {"cls":"items","id":"I370"}, + "371": {"cls":"items","id":"I371"}, + "372": {"cls":"items","id":"I372"}, + "373": {"cls":"items","id":"I373"}, + "374": {"cls":"items","id":"I374"}, + "375": {"cls":"items","id":"I375"}, "376": {"cls":"terrains","id":"T376"}, "377": {"cls":"terrains","id":"T377"}, "378": {"cls":"terrains","id":"T378"}, @@ -279,6 +294,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e = "393": {"cls":"terrains","id":"T393"}, "394": {"cls":"terrains","id":"T394"}, "395": {"cls":"terrains","id":"T395"}, + "396": {"cls":"items","id":"I396"}, "20034": {"cls":"tileset","id":"X20034","canPass":true}, "20154": {"cls":"tileset","id":"X20154","canPass":true}, "20216": {"cls":"tileset","id":"X20216","canPass":true}, diff --git a/project/materials/terrains.png b/project/materials/terrains.png index 378c4bf..fd82855 100644 Binary files a/project/materials/terrains.png and b/project/materials/terrains.png differ diff --git a/project/plugins.js b/project/plugins.js index e08da62..9c9b7f3 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -1,213 +1,268 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = { "init": function () { - this._afterLoadResources = function () { - // 本函数将在所有资源加载完毕后,游戏开启前被执行 - core.ui.statusBar.init(); - core.registerEvent("changeMouse", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.changeMouse( - data.icon, - data.div, - data.translate[0], - data.translate[1], - data.scale[0], - data.scale[1], - data.angel, - data.px, - data.py - ); - core.doAction(); - }); - core.registerEvent("removeMouse", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.removeMouse(data.div); - core.doAction(); - }); - core.registerEvent("addPop", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.value = core.replaceText(data.value); - core.addPop( - data.value, - data.px, - data.py, - data.color, - data.boldColor, - data.left, - data.jump, - data.time, - data.show, - data.font, - data.speed - ); - } - core.doAction(); - }); - core.registerEvent("drawWarning", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.text = core.replaceText(data.text); - data.text2 = core.replaceText(data.text2); - core.drawWarning( - data.x, - data.y, - data.size, - data?.text, - data?.text2, - data?.warning - ); - setTimeout(() => core.doAction(), 3100); - } else { - core.doAction(); - } - }); - core.registerEvent("playStereo", function (data) { - if (!main.replayChecking && !core.isReplaying()) - core.playStereo(data.name, data.left, data.right, data.split); - core.doAction(); - }); - core.registerEvent("moveStereo", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - const id = core.playStereo( - data.name, - data.left, - data.right, - data.split - ); - core.moveStereo(id, data.leftTo, data.rightTo, data.time); - } - core.doAction(); - }); - core.registerEvent("over", function (data) { - let image = data.image ?? ""; - let time = data.time ?? 3000; - let sound = data.sound ?? ""; - let textColor = data.textColor ?? "#FFFFFF"; - let boldColor = data.boldColor ?? "#000000"; - let font = data.font ?? "bold 48px Verdana"; - let text = data.text ?? ""; - let hidetime = data.hidetime ?? 100; - if (!main.replayChecking && !core.isReplaying()) { - core.over( - image, - data.memory, - time, - hidetime, - sound, - textColor, - boldColor, - font, - text - ); - } else { - core.doAction(); - } - }); - core.registerEvent("changebg", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.changebg( - data.img1, - data.memory1, - data.img2, - data.memory2, - data.time, - data.style - ); - } else { - core.doAction(); - } - }); - core.registerEvent("overlist", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.overlist( - data.image, - data.memory, - data.hidetime || 30, - data.list || [{ - text: "", - sound: "", - time: 50, - textColor: "#FFFFFF", - boldColor: "#000000", - font: "bold 48px Verdana", - frame: 0, - }, ] - ); - } else { - core.doAction(); - } - }); - core.registerEvent("op", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.openvideo(); - } else { - core.doAction(); - } - }); - core.registerEvent("animationDrawable", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.animationDrawable( - data.allFarme, - data.color, - data.globalAlpha, - data.imageList, - data.soundList - ); - } else { - core.doAction(); - } - }); - core.registerEvent("setanimate", function (data) { + this._afterLoadResources = function () { + // 本函数将在所有资源加载完毕后,游戏开启前被执行 + core.ui.statusBar.init(); + core.dom.playGame.style.fontFamily = "pala"; + core.dom.loadGame.style.fontFamily = "pala"; + core.dom.CGMode.style.fontFamily = "pala"; + core.dom.musicMode.style.fontFamily = "pala"; + core.dom.replayGame.style.fontFamily = "pala"; + core.registerEvent("changeMouse", function (data) { + if (!main.replayChecking && !core.isReplaying()) + core.changeMouse( + data.icon, + data.div, + data.translate[0], + data.translate[1], + data.scale[0], + data.scale[1], + data.angel, + data.px, + data.py + ); + core.doAction(); + }); + core.registerEvent("removeMouse", function (data) { + if (!main.replayChecking && !core.isReplaying()) + core.removeMouse(data.div); + core.doAction(); + }); + core.registerEvent("addPop", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.value = core.replaceText(data.value); + core.addPop( + data.value, + data.px, + data.py, + data.color, + data.boldColor, + data.left, + data.jump, + data.time, + data.show, + data.font, + data.speed + ); + } + core.doAction(); + }); + core.registerEvent("drawWarning", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.text = core.replaceText(data.text); + data.text2 = core.replaceText(data.text2); + core.drawWarning( + data.x, + data.y, + data?.text, + data?.text2, + data?.warning, + data.large, + data.size + ); - data.px = data.px ?? 0; - data.py = data.py ?? 0; - core.setanimate(data.name, data.px, data.py, data.width, data.height, data.allFarme, data.imageList, data.soundList) - core.doAction(); + setTimeout(() => core.doAction(), 3100); + } else { + core.doAction(); + } + }); + core.registerEvent("over", function (data) { + let image = data.image ?? ""; + let time = data.time ?? 3000; + let sound = data.sound ?? ""; + let textColor = data.textColor ?? "#FFFFFF"; + let boldColor = data.boldColor ?? "#000000"; + let font = data.font ?? "bold 48px Verdana"; + let text = data.text ?? ""; + let hidetime = data.hidetime ?? 100; + if (!main.replayChecking && !core.isReplaying()) { + core.over( + image, + data.memory, + time, + hidetime, + sound, + textColor, + boldColor, + font, + text + ); + } else { + core.doAction(); + } + }); + core.registerEvent("changebg", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.changebg( + data.img1, + data.memory1, + data.img2, + data.memory2, + data.time, + data.style + ); + } else { + core.doAction(); + } + }); + core.registerEvent("overlist", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.overlist( + data.image, + data.memory, + data.hidetime || 30, + data.list || [ + { + text: "", + sound: "", + time: 50, + textColor: "#FFFFFF", + boldColor: "#000000", + font: "bold 48px Verdana", + frame: 0, + }, + ] + ); + } else { + core.doAction(); + } + }); + core.registerEvent("op", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.openvideo(); + } else { + core.doAction(); + } + }); + core.registerEvent("animationDrawable", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.animationDrawable( + data.allFarme, + data.color, + data.globalAlpha, + data.imageList, + data.soundList + ); + } else { + core.doAction(); + } + }); + core.registerEvent("setanimate", function (data) { + data.px = data.px ?? 0; + data.py = data.py ?? 0; + core.setanimate( + data.name, + data.px, + data.py, + data.width, + data.height, + data.allFarme, + data.imageList, + data.soundList + ); + core.doAction(); + }); + core.registerEvent("clearanimate", function (data) { + core.plugin.playing.clear(); - }); - core.registerEvent("clearanimate", function (data) { - core.plugin.playing.clear() + core.doAction(); + }); + core.registerEvent("deleteanimate", function (data) { + core.deleteanimate(data.name); + core.doAction(); + }); + core.registerEvent("playanimate", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + data.x = data.x ?? 0; + data.y = data.y ?? 0; + data.scalex = data.scalex ?? 1; + data.scaley = data.scaley ?? 1; + core.playanimate( + data.name, + data.x, + data.y, + data.hero, + data.scalex, + data.scaley + ); + core.doAction(); + } else { + core.doAction(); + } + }); + core.registerEvent("cgtextList", function (data) { + core.ui.cgText.textList = core.plugin[data.textList]; + core.doAction(); + }); + core.registerEvent("cgtext", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.ui.cgText.image = data.bg; + core.ui.cgText.nobg = data.nobg ?? false; + core.ui.cgText.memory = data.memory; + core.ui.cgText.head = core.clone(data.head); + core.ui.cgText.index = data.index; + core.ui.cgText.name = core.ui.cgText.textList[data.index][0]; + core.ui.cgText.text = data.text + ? data.text + : core.ui.cgText.textList[data.index][1]; + core.ui.cgText.time = data.time; + core.ui.cgText.wait = data.wait; + core.ui.cgText.WindowSkin = data.WindowSkin; + core.ui.cgText.sound = + data.sound === "" + ? data.sound + : core.ui.cgText.textList[data.index][2] || ""; + core.ui.cgText.bodyList = core.clone(data.bodyList); + main.dom.cgText.style.display = "block"; + core.ui.cgText.update(); + } else { + core.doAction(); + } + }); + core.registerEvent("introAndLoop", function (data) { + if (!main.replayChecking && !core.isReplaying()) { + core.plugin.introAndLoop(data.intro, data.time, data.loop); + core.doAction(); + } else { + core.doAction(); + } + }); + core.registerEvent("setq", function (data) { + core.setFlag("任务地点", data.id); - core.doAction(); + core.doAction(); + }); - - }); - core.registerEvent("deleteanimate", function (data) { - core.deleteanimate(data.name) - core.doAction(); - }); - core.registerEvent("playanimate", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - data.x = data.x ?? 0 - data.y = data.y ?? 0 - data.scalex = data.scalex ?? 1 - data.scaley = data.scaley ?? 1 - core.playanimate(data.name, data.x, data.y, data.hero, data.scalex, data.scaley) - core.doAction(); - } else { - core.doAction(); - } - }); - core.registerEvent("cgtext", function (data) { - if (!main.replayChecking && !core.isReplaying()) { - core.ui.cgText.image = data.bg; - core.ui.cgText.memory = data.memory; - core.ui.cgText.head = core.clone(data.head); - core.ui.cgText.name = data.name; - core.ui.cgText.text = data.text; - core.ui.cgText.time = data.time; - core.ui.cgText.wait = data.wait; - core.ui.cgText.WindowSkin = data.WindowSkin; - core.ui.cgText.sound = data.sound || ""; - core.ui.cgText.bodyList = core.clone(data.bodyList); - main.dom.cgText.style.display = "block"; - core.ui.cgText.update(); - } else { - core.doAction(); - } - }); - }; -}, + core.registerEvent("setmusics", function (data) { + if ( + (core.getLocalStorage("musics") && + core.getLocalStorage("musics").length === 0) || + !core.getLocalStorage("musics") + ) + core.setLocalStorage("musics", ["theme.mp3"]); + let a = core.getLocalStorage("musics"); + if (!data.bgm) { + core.setLocalStorage("musics", ["theme.mp3"]); + } else { + if (!a.includes(data.bgm)) a.push(data.bgm); + core.setLocalStorage("musics", a); + } + core.doAction(); + }); + core.registerEvent("setcgs", function (data) { + if (!data.img) { + core.setLocalStorage("cgs", []); + } else { + let a = core.getLocalStorage("cgs") ?? []; + if (!a.includes(data.img)) a.push(data.img); + core.setLocalStorage("cgs", a); + } + core.doAction(); + }); + }; + }, "drawLight": function () { // 绘制灯光/漆黑层效果。调用方式 core.plugin.drawLight(...) // 【参数说明】 @@ -251,8 +306,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); lightDec = core.clamp(lightDec, 0, 1); - - // 绘制每个灯光效果 ctx.globalCompositeOperation = "destination-out"; lights.forEach(function (light) { // 坐标,半径,中心不透明度 @@ -2487,7 +2540,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = const BORDER_HEIGHT = 0; //游戏画面上侧偏移距离 const ITEM_BOX_LEFT = 549 * 3; //横屏道具栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const ITEM_BOX_TOP = 155 * 3; //横屏道具栏上侧距离 + const ITEM_BOX_TOP = 175 * 3; //横屏道具栏上侧距离 const ITEM_BOX_LEFT_VERTICAL = 160 * 3; //竖屏道具栏左侧距离 const ITEM_BOX_TOP_VERTICAL = 549 * 3; //竖屏道具栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) @@ -2502,12 +2555,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = const MAP_BLOCK_TOP_VERTICAL = 551 * 3; //竖屏小地图上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) const KEY_BLOCK_LEFT = EQUIP_BLOCK_LEFT; //横屏钥匙栏左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const KEY_BLOCK_TOP = 110 * 3; //横屏钥匙栏上侧距离 + const KEY_BLOCK_TOP = 130 * 3; //横屏钥匙栏上侧距离 const KEY_BLOCK_LEFT_VERTICAL = 110 * 3; //竖屏钥匙栏左侧距离 const KEY_BLOCK_TOP_VERTICAL = EQUIP_BLOCK_TOP_VERTICAL; //竖屏钥匙栏上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) const INFO_BLOCK_LEFT = 10 * 3; //横屏道具说明左侧距离(右侧边栏需增加BAR_WIDTH+GAMEVIEW_HEIGHT) - const INFO_BLOCK_TOP = 180 * 3; //横屏道具说明上侧距离 + const INFO_BLOCK_TOP = 290 * 3; //横屏道具说明上侧距离 const INFO_BLOCK_LEFT_VERTICAL = 113 * 3; //竖屏道具说明左侧距离 const INFO_BLOCK_TOP_VERTICAL = 8 * 3; //竖屏道具说明上侧距离(下侧边栏需增加BAR_HEIGHT_VERTICAL+GAMEVIEW_WIDTH_VERTICAL) @@ -2631,10 +2684,18 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = main.dom.cgText.style.width = obj.totalWidth + 3 + "px"; main.dom.cgText.style.height = obj.totalHeight + 3 + "px"; } + if (main.dom.logcanvas) { + main.dom.logcanvas.style.width = obj.totalWidth + 3 + "px"; + main.dom.logcanvas.style.height = obj.totalHeight + 3 + "px"; + } if (main.dom.over) { main.dom.over.style.width = obj.totalWidth + 3 + "px"; main.dom.over.style.height = obj.totalHeight + 3 + "px"; } + if (main.dom.book) { + main.dom.book.style.width = obj.totalWidth + 3 + "px"; + main.dom.book.style.height = obj.totalHeight + 3 + "px"; + } if (main.dom.video) { main.dom.video.style.width = obj.totalWidth + 3 + "px"; main.dom.video.style.height = obj.totalHeight + 3 + "px"; @@ -2655,6 +2716,30 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = main.dom.video1.style.height = obj.totalHeight + 3 + "px"; } + main.dom.boss1.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss1.style.height = obj.totalHeight + 3 + "px"; + + main.dom.boss2.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss2.style.height = obj.totalHeight + 3 + "px"; + + main.dom.boss3.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss3.style.height = obj.totalHeight + 3 + "px"; + + main.dom.boss4.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss4.style.height = obj.totalHeight + 3 + "px"; + + main.dom.boss5.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss5.style.height = obj.totalHeight + 3 + "px"; + main.dom.boss6.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss6.style.height = obj.totalHeight + 3 + "px"; + main.dom.boss7.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss7.style.height = obj.totalHeight + 3 + "px"; + main.dom.boss8.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss8.style.height = obj.totalHeight + 3 + "px"; + + main.dom.boss.style.width = obj.totalWidth + 3 + "px"; + main.dom.boss.style.height = obj.totalHeight + 3 + "px"; + const innerSize = obj.canvasWidth * core.domStyle.scale + "px"; for (let i = 0; i < core.dom.gameCanvas.length; ++i) core.dom.gameCanvas[i].style.width = core.dom.gameCanvas[ @@ -2818,6 +2903,10 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.ui.music.update(); if (main.dom.cgText && main.dom.cgText.style.display === "block") core.ui.cgText.update(); + if (main.dom.logcanvas && main.dom.logcanvas.style.display === "block") + core.ui.cgText.update(); + if (main.dom.boss1 && main.dom.boss1.style.display === "block") + core.ui.boss.update(); }; class StatusBar { @@ -2846,16 +2935,22 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ]; this.replayAction = [ [core.triggerReplay, core.stopReplay, core.rewindReplay], - [core.speedDownReplay, core.speedUpReplay, core.saveReplay], + [ + core.speedDownReplay, + core.speedUpReplay, + function () { + core.control._replay_SL(); + }, + ], ]; } //更新 update() { this._update_background(); //更新背景 this._update_props(); //更新属性 - //this._update_items(); //更新道具 + this._update_items(); //更新道具 //this._update_equips(); //更新装备 - //this._update_keys(); //更新钥匙 + this._update_keys(); //更新钥匙 //this._update_infoWindow(); //更新道具说明 this._update_toolBox(); //更新工具栏 this._redrawMap(); @@ -2945,33 +3040,66 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (!updatedFloorTitle && core.status.floorId) { updatedFloorTitle = core.status.maps[core.status.floorId].title; } - const statusList = ["hp", "atk", "def", "money"]; //属性列表,图标在函数复写core.statusBar.icons中声明,数字为project\materials\icons.png中的图标序号(可使用便捷ps追加,第一个序号为0) + const statusList = [ + "hp", + "atk", + "def", + "spell", + "mdef", + "matk", + "mhp", + "speed", + "money", + ]; //属性列表,图标在函数复写core.statusBar.icons中声明,数字为project\materials\icons.png中的图标序号(可使用便捷ps追加,第一个序号为0) const drawStatusList = (baseX, baseY) => { let curh = baseY; core.setTextAlign("outerUI", "right"); statusList.forEach((item) => { // 绘制图标 - core.drawIcon( - "outerUI", - item, - baseX - 95 * 3, - curh - 18 * 3, - 22 * 3, - 22 * 3 - ); - - // 四舍五入 - core.status.hero[item] = Math.round(core.status.hero[item]); - // 大数据格式化 + /*core.drawIcon( + "outerUI", + item, + baseX - 95 * 3, + curh - 18 * 3, + 22 * 3, + 22 * 3 + );*/ + core.strokeRect("outerUI", baseX - 96 * 3, + curh - 16 * 3, 100 * 3, 22 * 3, "#FFFFFF", 3) + core.setFont("outerUI", "bold 24px Verdana"); core.fillBoldText1( "outerUI", - core.getRealStatus(item), + core.getStatusLabel(item), + baseX - 65 * 3, + curh - 4 * 3, + TEXT_COLOR, + "#000000", + 6 + ); + core.setFont("outerUI", "bold 36px Verdana"); + // 四舍五入 + core.status.hero[item] = Math.round(core.status.hero[item]); + let text = core.getRealStatus(item); + // 大数据格式化 + switch (item) { + case "mdef": + text += "%"; + break; + case "matk": + case "mhp": + text += `(${core.status.hero[item]})%`; + break; + } + core.fillBoldText1( + "outerUI", + text, baseX, curh, TEXT_COLOR, "#000000", 6 ); + curh += 24 * 3; if (curh > 130 * 3 && core.domStyle.isVertical) { curh = 24 * 3; @@ -2994,9 +3122,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 6 ); } - //drawStatusList(96 * 3, 46 * 3); + drawStatusList(96 * 3, 46 * 3); //core.drawImage("outerUI", "lane1.png", 0, 0) - core.drawImage("outerUI", "cao.webp", 0, 0); + //core.drawImage("outerUI", "cao.webp", 0, 0); } else { core.clearMap("outerUI", 10 * 3, 40 * 3, 105 * 3, 250 * 3); core.setFont("outerUI", "bold 48px Verdana"); @@ -3011,8 +3139,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 6 ); } - //drawStatusList(110 * 3, 93 * 3); - //core.drawImage("outerUI", "lane1.png", 0, 30) + drawStatusList(110 * 3, 93 * 3); + //core.drawImage("outerUI", "lane1.png", 0, 30); core.drawImage( "outerUI", "cao.webp", @@ -3375,7 +3503,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = top: INFO_BLOCK_TOP_VERTICAL + 40 * 3, maxWidth: 275 * 3, color: "#D1CEFF", - fontSize: 36, + fontSize: 24, }); } } else { @@ -3386,7 +3514,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 115 * 3, 230 * 3 ); - + core.setFont("outerUI", "bold 36px Verdana") if (this.selectedItem) { const icon = core.material.icons.items[itemId]; core.setTextAlign("outerUI", "center"); @@ -3414,7 +3542,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = top: INFO_BLOCK_TOP + 60 * 3, maxWidth: 105 * 3, color: "#D1CEFF", - fontSize: 36, + fontSize: 24, }); } } @@ -3511,7 +3639,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }); break; case "fly": - core.useItem(itemId, true); + core.useItem(itemId); break; default: core.useItem(itemId); @@ -3563,6 +3691,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 31 * 3, 31 * 3, ]); + if (core.status.lockControl || core.isMoving()) return; if (core.isReplaying()) { this.replayAction[col][row].call(core); } else if (core.isPlaying()) { @@ -3587,7 +3716,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.isMoving() ) return; - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + core.useItem("fly"); return; } /*const equipBox = makeBox([EQUIP_BLOCK_LEFT_VERTICAL, EQUIP_BLOCK_TOP_VERTICAL], [90 * 3, 130 * 3]) @@ -3605,7 +3734,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.isMoving() ) return; - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + core.useItem("fly"); return; } /* @@ -3649,6 +3778,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 31 * 3, 31 * 3, ]); + if (core.status.lockControl || core.isMoving()) return; if (core.isReplaying()) { this.replayAction[col][row].call(core); } else if (core.isPlaying()) { @@ -3674,355 +3804,705 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = // init() called in `afterLoadResources`. }, "override": function () { - core.statusBar.icons = { - floor: 0, - name: null, - lv: 1, - hpmax: 2, - hp: 3, - atk: 4, - def: 5, - mdef: 6, - money: 7, - exp: 8, - up: 9, - book: 10, - fly: 11, - toolbox: 12, - keyboard: 13, - shop: 14, - save: 15, - load: 16, - settings: 17, - play: 18, - pause: 19, - stop: 20, - speedDown: 21, - speedUp: 22, - rewind: 23, - equipbox: 24, - mana: 25, - skill: 26, - exit: 27, - btn1: 28, - btn2: 29, - btn3: 30, - btn4: 31, - btn5: 32, - btn6: 33, - btn7: 34, - alt: 35, - keys: 36, - help: 37, - battle: 38, - }; - core.actions._getClickLoc = function (x, y) { - var size = 32 * core.domStyle.scale; - var left = main.dom.gameDraw.offsetLeft + main.dom.gameGroup.offsetLeft; - var top = main.dom.gameDraw.offsetTop + main.dom.gameGroup.offsetTop; - var loc = { - x: Math.max(x - left, 0), - y: Math.max(y - top, 0), - size: size, - }; - return loc; - }; - core.ui._drawWindowSelector = function (background, x, y, w, h) { - w = Math.round(w) + 48; - h = Math.round(h); - var ctx = core.ui.createCanvas("_selector", x - 24, y, w, h, 165); - ctx.canvas.id = ""; - this._drawSelector(ctx, background, w, h); - }; + core.statusBar.icons = { + floor: 0, + name: null, + lv: 1, + hpmax: 2, + hp: 3, + atk: 4, + def: 5, + mdef: 6, + money: 7, + exp: 8, + up: 9, + book: 10, + fly: 11, + toolbox: 12, + keyboard: 13, + shop: 14, + save: 15, + load: 16, + settings: 17, + play: 18, + pause: 19, + stop: 20, + speedDown: 21, + speedUp: 22, + rewind: 23, + equipbox: 24, + mana: 25, + skill: 26, + exit: 27, + btn1: 28, + btn2: 29, + btn3: 30, + btn4: 31, + btn5: 32, + btn6: 33, + btn7: 34, + alt: 35, + keys: 36, + help: 37, + battle: 38, + }; + core.actions._getClickLoc = function (x, y) { + var size = 32 * core.domStyle.scale; + var left = main.dom.gameDraw.offsetLeft + main.dom.gameGroup.offsetLeft; + var top = main.dom.gameDraw.offsetTop + main.dom.gameGroup.offsetTop; + var loc = { + x: Math.max(x - left, 0), + y: Math.max(y - top, 0), + size: size, + }; + return loc; + }; + /* core.ui._drawWindowSelector = function (background, x, y, w, h) { + w = Math.round(w) + 48; + h = Math.round(h); + var ctx = core.ui.createCanvas("_selector", x - 24, y, w, h, 165); + ctx.canvas.id = ""; + this._drawSelector(ctx, background, w, h); + }; - core.ui._drawSelector = function (ctx, background, w, h, left, top) { - left = left || 0; - top = top || 0; - ctx = this.getContextByName(ctx); - if (!ctx) return; - if (typeof background == "string") - background = core.material.images.images[background]; - if (!(background instanceof Image)) return; - // badge - ctx.drawImage(background, 132, 68, 24, 24, left + 4, top + 4, 24, 24); - ctx.drawImage( - background, - 132, - 68, - 24, - 24, - w - left - 28, - top + 4, - 24, - 24 - ); - }; + core.ui._drawSelector = function (ctx, background, w, h, left, top) { + left = left || 0; + top = top || 0; + ctx = this.getContextByName(ctx); + if (!ctx) return; + if (typeof background == "string") + background = core.material.images.images[background]; + if (!(background instanceof Image)) return; + // badge + ctx.drawImage(background, 132, 68, 24, 24, left + 4, top + 4, 24, 24); + ctx.drawImage( + background, + 132, + 68, + 24, + 24, + w - left - 28, + top + 4, + 24, + 24 + ); + };*/ - enemys.prototype._nextCriticals_useBinarySearch = function ( - enemy, - info, - number, - x, - y, - floorId - ) { - var mon_hp = info.mon_hp, - hero_atk = core.status.hero.atk, - mon_def = info.mon_def, - pre = info.damage; - var list = []; - var start_atk = hero_atk; - if (info.__over__) { - start_atk += info.__overAtk__; - list.push([info.__overAtk__, -info.damage]); - } - var calNext = function (currAtk, maxAtk) { - var start = Math.floor(currAtk), - end = Math.floor(maxAtk); - if (start > end) return null; + enemys.prototype._nextCriticals_useBinarySearch = function ( + enemy, + info, + number, + x, + y, + floorId + ) { + var mon_hp = info.mon_hp, + hero_atk = core.status.hero.atk, + mon_def = info.mon_def, + pre = info.damage; + var list = []; + var start_atk = hero_atk; + if (info.__over__) { + start_atk += info.__overAtk__; + list.push([info.__overAtk__, -info.damage]); + } + var calNext = function (currAtk, maxAtk) { + var start = Math.floor(currAtk), + end = Math.floor(maxAtk); + if (start > end) return null; - while (start < end) { - var mid = Math.floor((start + end) / 2); - if (mid - start > end - mid) mid--; - var nextInfo = core.enemys.getDamageInfo( - enemy, - { atk: mid }, - x, - y, - floorId - ); - if (nextInfo == null || typeof nextInfo == "number") return null; - if (pre > nextInfo.damage) end = mid; - else start = mid + 1; - } - var nextInfo = core.enemys.getDamageInfo( - enemy, - { atk: start }, - x, - y, - floorId - ); - return nextInfo == null || - typeof nextInfo == "number" || - nextInfo.damage >= pre - ? null - : [start, nextInfo.damage]; - }; - var currAtk = start_atk; - while (true) { - var next = calNext(currAtk + 1, Number.MAX_SAFE_INTEGER, pre); - if (next == null) break; - currAtk = next[0]; - pre = next[1]; - list.push([currAtk - hero_atk, info.damage - pre]); - if (pre <= 0 && !core.flags.enableNegativeDamage) break; - if (list.length >= number) break; - } - if (list.length == 0) list.push([0, 0]); - return list; - }; - core.ui.clearMap = function (name, x, y, width, height) { - if (name == "all") { - for (var m in core.canvas) { - core.canvas[m].clearRect( - -32, - -32, - core.canvas[m].canvas.width + 32, - core.canvas[m].canvas.height + 32 - ); - } - core.clearMap("outerUI"); - core.dom.gif.innerHTML = ""; - core.removeGlobalAnimate(); - core.deleteCanvas(function (one) { - return one.startsWith("_bigImage_"); - }); - core.setWeather(null); - } else { - var ctx = this.getContextByName(name); - if (ctx) - ctx.clearRect( - x || 0, - y || 0, - width || ctx.canvas.width, - height || ctx.canvas.height - ); - } - }; - events.prototype.openBook = function (fromUserAction) { - if (core.isReplaying()) return; - // 如果能恢复事件(从callBook事件触发) - if ( - core.status.event.id == "book" && - core.events.recoverEvents(core.status.event.interval) - ) - return; - // 当前是book,且从“浏览地图”打开 - if (core.status.event.id == "book" && core.status.event.ui) { - core.status.boxAnimateObjs = []; - core.ui._drawViewMaps(core.status.event.ui); - return; - } - // 从“浏览地图”页面打开 - if (core.status.event.id == "viewMaps" || core.status.event.id == "fly") { - fromUserAction = false; - core.status.event.ui = core.status.event.data; - } - if (!this._checkStatus("book", fromUserAction, true)) return; - core.playSound("打开界面"); - core.useItem("book", true); - }; - ////// 怪物手册界面时,放开某个键的操作 ////// - core.actions._keyUpBook = function (keycode) { - if (keycode == 27 || keycode == 88) { - core.playSound("取消"); - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } else if (core.status.event.ui != null) { - core.status.boxAnimateObjs = []; - if (typeof core.status.event.ui === "number") { - core.status.event.id = "fly"; - core.ui.drawFly(core.status.event.ui); - } else { - core.ui._drawViewMaps(core.status.event.ui); - } - } else core.ui.closePanel(); - return; - } - if (keycode == 13 || keycode == 32 || keycode == 67) { - var data = core.status.event.data; - if (data != null) { - core.ui._drawBookDetail(data); - } - return; - } - }; - ////// 怪物手册界面的点击操作 ////// - actions.prototype._clickBook = function (x, y) { - var pageinfo = core.ui._drawBook_pageinfo(); - // 上一页 - if ( - (x == this._HX_ - 2 || x == this._HX_ - 3) && - y === core._HEIGHT_ - 1 - ) { - core.playSound("光标移动"); - core.ui.drawBook(core.status.event.data - pageinfo.per_page); - return; - } - // 下一页 - if ( - (x == this._HX_ + 2 || x == this._HX_ + 3) && - y === core._HEIGHT_ - 1 - ) { - core.playSound("光标移动"); - core.ui.drawBook(core.status.event.data + pageinfo.per_page); - return; - } - // 返回 - if (x >= this.LAST - 2 && y === core._HEIGHT_ - 1) { - core.playSound("取消"); - if (core.events.recoverEvents(core.status.event.interval)) { - return; - } else if (core.status.event.ui != null) { - core.status.boxAnimateObjs = []; - if (typeof core.status.event.ui === "number") { - core.status.event.id = "fly"; - core.ui.drawFly(core.status.event.ui); - } else { - core.ui._drawViewMaps(core.status.event.ui); - } - } else core.ui.closePanel(); - return; - } - // 怪物信息 - var data = core.status.event.data; - if (data != null && y < core._HEIGHT_ - 1) { - var per_page = pageinfo.per_page, - page = parseInt(data / per_page); - var u = (core._HEIGHT_ - 1) / per_page; - for (var i = 0; i < per_page; ++i) { - if (y >= u * i && y < u * (i + 1)) { - var index = per_page * page + i; - core.ui.drawBook(index); - core.ui._drawBookDetail(index); - break; - } - } - return; - } - return; - }; + while (start < end) { + var mid = Math.floor((start + end) / 2); + if (mid - start > end - mid) mid--; + var nextInfo = core.enemys.getDamageInfo( + enemy, { atk: mid }, + x, + y, + floorId + ); + if (nextInfo == null || typeof nextInfo == "number") return null; + if (pre > nextInfo.damage) end = mid; + else start = mid + 1; + } + var nextInfo = core.enemys.getDamageInfo( + enemy, { atk: start }, + x, + y, + floorId + ); + return nextInfo == null || + typeof nextInfo == "number" || + nextInfo.damage >= pre ? + null : + [start, nextInfo.damage]; + }; + var currAtk = start_atk; + while (true) { + var next = calNext(currAtk + 1, Number.MAX_SAFE_INTEGER, pre); + if (next == null) break; + currAtk = next[0]; + pre = next[1]; + list.push([currAtk - hero_atk, info.damage - pre]); + if (pre <= 0 && !core.flags.enableNegativeDamage) break; + if (list.length >= number) break; + } + if (list.length == 0) list.push([0, 0]); + return list; + }; + core.ui.clearMap = function (name, x, y, width, height) { + if (name == "all") { + for (var m in core.canvas) { + core.canvas[m].clearRect( + -32, + -32, + core.canvas[m].canvas.width + 32, + core.canvas[m].canvas.height + 32 + ); + } + core.clearMap("outerUI"); + core.dom.gif.innerHTML = ""; + core.removeGlobalAnimate(); + core.deleteCanvas(function (one) { + return one.startsWith("_bigImage_"); + }); + core.setWeather(null); + } else { + var ctx = this.getContextByName(name); + if (ctx) + ctx.clearRect( + x || 0, + y || 0, + width || ctx.canvas.width, + height || ctx.canvas.height + ); + } + }; + events.prototype.openBook = function (fromUserAction) { + if (core.isReplaying()) return; + // 如果能恢复事件(从callBook事件触发) + if ( + core.status.event.id == "book" && + core.events.recoverEvents(core.status.event.interval) + ) + return; + // 当前是book,且从“浏览地图”打开 + if (core.status.event.id == "book" && core.status.event.ui) { + core.status.boxAnimateObjs = []; + core.ui._drawViewMaps(core.status.event.ui); + return; + } + // 从“浏览地图”页面打开 + if (core.status.event.id == "viewMaps" || core.status.event.id == "fly") { + fromUserAction = false; + core.status.event.ui = core.status.event.data; + } + if (!this._checkStatus("book", fromUserAction, true)) return; + core.playSound("打开界面"); + core.useItem("book", true); + }; + ////// 怪物手册界面时,放开某个键的操作 ////// + core.actions._keyUpBook = function (keycode) { + if (keycode == 27 || keycode == 88) { + core.playSound("取消"); + if (core.events.recoverEvents(core.status.event.interval)) { + return; + } else if (core.status.event.ui != null) { + core.status.boxAnimateObjs = []; + if (typeof core.status.event.ui === "number") { + core.status.event.id = "fly"; + core.ui.drawFly(core.status.event.ui); + } else { + core.ui._drawViewMaps(core.status.event.ui); + } + } else core.ui.closePanel(); + return; + } + if (keycode == 13 || keycode == 32 || keycode == 67) { + var data = core.status.event.data; + if (data != null) { + core.ui._drawBookDetail(data); + } + return; + } + }; + ////// 怪物手册界面的点击操作 ////// + actions.prototype._clickBook = function (x, y) { + var pageinfo = core.ui._drawBook_pageinfo(); + // 上一页 + if ( + (x == this._HX_ - 2 || x == this._HX_ - 3) && + y === core._HEIGHT_ - 1 + ) { + core.playSound("光标移动"); + core.ui.drawBook(core.status.event.data - pageinfo.per_page); + return; + } + // 下一页 + if ( + (x == this._HX_ + 2 || x == this._HX_ + 3) && + y === core._HEIGHT_ - 1 + ) { + core.playSound("光标移动"); + core.ui.drawBook(core.status.event.data + pageinfo.per_page); + return; + } + // 返回 + if (x >= this.LAST - 2 && y === core._HEIGHT_ - 1) { + core.playSound("取消"); + if (core.events.recoverEvents(core.status.event.interval)) { + return; + } else if (core.status.event.ui != null) { + core.status.boxAnimateObjs = []; + if (typeof core.status.event.ui === "number") { + core.status.event.id = "fly"; + core.ui.drawFly(core.status.event.ui); + } else { + core.ui._drawViewMaps(core.status.event.ui); + } + } else core.ui.closePanel(); + return; + } + // 怪物信息 + var data = core.status.event.data; + if (data != null && y < core._HEIGHT_ - 1) { + var per_page = pageinfo.per_page, + page = parseInt(data / per_page); + var u = (core._HEIGHT_ - 1) / per_page; + for (var i = 0; i < per_page; ++i) { + if (y >= u * i && y < u * (i + 1)) { + var index = per_page * page + i; + core.ui.drawBook(index); + core.ui._drawBookDetail(index); + break; + } + } + return; + } + return; + }; - ////// 执行当前自定义事件列表中的下一个事件 ////// - events.prototype.doAction = function () { - // 清空boxAnimate和UI层 - clearInterval(core.status.event.interval); - clearTimeout(core.status.event.interval); - clearInterval(core.status.event.animateUI); - core.status.event.interval = null; - delete core.status.event.aniamteUI; - if (core.status.gameOver || core.status.replay.failed) return; - // 判定是否执行完毕 - if (this._doAction_finishEvents()) return; - core.clearUI(); - var floorId = core.status.event.data.floorId || core.status.floorId; - // 当前点坐标和前缀 - var x = core.status.event.data.x, - y = core.status.event.data.y; - var prefix = [ - floorId || ":f", - x != null ? x : "x", - y != null ? y : "y", - ].join("@"); - var current = core.status.event.data.list[0]; - if (this._popEvents(current, prefix)) return; - // 当前要执行的事件 - var data = current.todo.shift(); - core.status.event.data.current = data; - if (typeof data == "string") data = { type: "text", text: data }; - // 该事件块已经被禁用 - if (data._disabled) return core.doAction(); - if (data.type !== "cgtext") { - core.unregisterAnimationFrame("skip"); - core.setFlag("skip", false); - } - data.floorId = data.floorId || floorId; - core.status.event.data.type = data.type; - this.doEvent(data, x, y, prefix); - return; - }; + ////// 执行当前自定义事件列表中的下一个事件 ////// + events.prototype.doAction = function () { + // 清空boxAnimate和UI层 + clearInterval(core.status.event.interval); + clearTimeout(core.status.event.interval); + clearInterval(core.status.event.animateUI); + core.status.event.interval = null; + delete core.status.event.aniamteUI; + if (core.status.gameOver || core.status.replay.failed) return; + // 判定是否执行完毕 + if (this._doAction_finishEvents()) return; + core.clearUI(); + var floorId = core.status.event.data.floorId || core.status.floorId; + // 当前点坐标和前缀 + var x = core.status.event.data.x, + y = core.status.event.data.y; + var prefix = [ + floorId || ":f", + x != null ? x : "x", + y != null ? y : "y", + ].join("@"); + var current = core.status.event.data.list[0]; + if (this._popEvents(current, prefix)) return; + // 当前要执行的事件 + var data = current.todo.shift(); + core.status.event.data.current = data; + if (typeof data == "string") data = { type: "text", text: data }; + // 该事件块已经被禁用 + if (data._disabled) return core.doAction(); + if (data.type !== "cgtext") { + core.unregisterAnimationFrame("skip"); + core.setFlag("skip", false); + } + data.floorId = data.floorId || floorId; + core.status.event.data.type = data.type; + this.doEvent(data, x, y, prefix); + return; + }; - ////// 在某个canvas上绘制粗体 ////// - core.fillBoldText1 = function ( - name, - text, - x, - y, - style, - strokeStyle, - lineWidth, - font, - maxWidth - ) { - var ctx = this.getContextByName(name); - if (!ctx) return; - if (font) ctx.font = font; - if (!style) style = ctx.fillStyle; - style = core.arrayToRGBA(style); - if (!strokeStyle) strokeStyle = "#000000"; - strokeStyle = core.arrayToRGBA(strokeStyle); - if (maxWidth != null) { - this.setFontForMaxWidth(ctx, text, maxWidth); - } - ctx.strokeStyle = strokeStyle; + ////// 在某个canvas上绘制粗体 ////// + core.fillBoldText1 = function ( + name, + text, + x, + y, + style, + strokeStyle, + lineWidth, + font, + maxWidth + ) { + var ctx = this.getContextByName(name); + if (!ctx) return; + if (font) ctx.font = font; + if (!style) style = ctx.fillStyle; + style = core.arrayToRGBA(style); + if (!strokeStyle) strokeStyle = "#000000"; + strokeStyle = core.arrayToRGBA(strokeStyle); + if (maxWidth != null) { + this.setFontForMaxWidth(ctx, text, maxWidth); + } + ctx.strokeStyle = strokeStyle; - if (!lineWidth) lineWidth = 2; - ctx.lineWidth = lineWidth; - ctx.strokeText(text, x, y); - ctx.fillStyle = style; - ctx.fillText(text, x, y); - }; - }, + if (!lineWidth) lineWidth = 2; + ctx.lineWidth = lineWidth; + ctx.strokeText(text, x, y); + ctx.fillStyle = style; + ctx.fillText(text, x, y); + }; + ////// 绘制 WindowSkin + ui.prototype.drawWindowSkin = function ( + background, + ctx, + x, + y, + w, + h, + direction, + px, + py, + size = 1 + ) { + background = background || core.status.textAttribute.background; + + // 仿RM窗口皮肤 ↓ + // 绘制背景 + core.drawImage( + ctx, + background, + 0, + 0, + 128, + 128, + x + 2 * size, + y + 2 * size, + w - 4 * size, + h - 4 * size + ); + // 绘制边框 + // 上方 + core.drawImage( + ctx, + background, + 128, + 0, + 16, + 16, + x, + y, + 16 * size, + 16 * size + ); + for (var dx = 0; dx < w - 64 * size; dx += 32 * size) { + core.drawImage( + ctx, + background, + 144, + 0, + 32, + 16, + x + dx + 16 * size, + y, + 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 144, + 48, + 32, + 16, + x + dx + 16 * size, + y + h - 16 * size, + 32 * size, + 16 * size + ); + } + core.drawImage( + ctx, + background, + 144, + 0, + (w - dx - 32 * size) / size, + 16, + x + dx + 16 * size, + y, + w - dx - 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 144, + 48, + (w - dx - 32 * size) / size, + 16, + x + dx + 16 * size, + y + h - 16 * size, + w - dx - 32 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 176, + 0, + 16, + 16, + x + w - 16 * size, + y, + 16 * size, + 16 * size + ); + // 左右 + for (var dy = 0; dy < h - 64 * size; dy += 32 * size) { + core.drawImage( + ctx, + background, + 128, + 16, + 16, + 32, + x, + y + dy + 16 * size, + 16 * size, + 32 * size + ); + core.drawImage( + ctx, + background, + 176, + 16, + 16, + 32, + x + w - 16 * size, + y + dy + 16 * size, + 16 * size, + 32 * size + ); + } + core.drawImage( + ctx, + background, + 128, + 16, + 16, + (h - dy - 32 * size) / size, + x, + y + dy + 16 * size, + 16 * size, + h - dy - 32 * size + ); + core.drawImage( + ctx, + background, + 176, + 16, + 16, + (h - dy - 32 * size) / size, + x + w - 16 * size, + y + dy + 16 * size, + 16 * size, + h - dy - 32 * size + ); + //下方 + core.drawImage( + ctx, + background, + 128, + 48, + 16, + 16, + x, + y + h - 16 * size, + 16 * size, + 16 * size + ); + core.drawImage( + ctx, + background, + 176, + 48, + 16, + 16, + x + w - 16 * size, + y + h - 16 * size, + 16 * size, + 16 * size + ); + + // arrow + if (px != null && py != null) { + if (direction == "up") { + core.drawImage( + ctx, + background, + 128, + 96, + 32, + 32, + px, + y + h - 3 * size, + 32 * size, + 32 * size + ); + } else if (direction == "down") { + core.drawImage( + ctx, + background, + 160, + 96, + 32, + 32, + px, + y - 29 * size, + 32 * size, + 32 * size + ); + } + } + // 仿RM窗口皮肤 ↑ + }; + events.prototype.battle = function (id, x, y, force, callback) { + core.saveAndStopAutomaticRoute(); + id = id || core.getBlockId(x, y); + const cls = core.getClsFromId(id); + if (!id || !cls || !(cls === "enemys" || cls === "enemy48")) + return core.clearContinueAutomaticRoute(callback); + // 非强制战斗 + if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) { + core.stopSound(); + core.playSound("操作失败"); + core.drawTip("你打不过此怪物!", id); + return core.clearContinueAutomaticRoute(callback); + } + // 自动存档 + if (!core.status.event.id) core.autosave(true); + // 战前事件 + if (!this.beforeBattle(id, x, y)) + return core.clearContinueAutomaticRoute(callback); + // 战后事件 + this.afterBattle(id, x, y); + if (callback) callback(); + }; + actions.prototype._sys_ondown_lockControl = function (x, y, px, py) { + if (core.status.played && !core.status.lockControl) return false; + + switch (core.status.event.id) { + case "battle": + core.plugin.battle_onclick(x, y, px, py); + break; + case "centerFly": + this._clickCenterFly(x, y, px, py); + break; + case "book": + this._clickBook(x, y, px, py); + break; + case "book-detail": + this._clickBookDetail(x, y, px, py); + break; + case "fly": + this._clickFly(x, y, px, py); + break; + case "viewMaps": + this._clickViewMaps(x, y, px, py); + break; + case "switchs": + this._clickSwitchs(x, y, px, py); + break; + case "switchs-sounds": + this._clickSwitchs_sounds(x, y, px, py); + break; + case "switchs-display": + this._clickSwitchs_display(x, y, px, py); + break; + case "switchs-action": + this._clickSwitchs_action(x, y, px, py); + break; + case "settings": + this._clickSettings(x, y, px, py); + break; + case "selectShop": + this._clickQuickShop(x, y, px, py); + break; + case "equipbox": + this._clickEquipbox(x, y, px, py); + break; + case "toolbox": + this._clickToolbox(x, y, px, py); + break; + case "save": + case "load": + case "replayLoad": + case "replayRemain": + case "replaySince": + this._clickSL(x, y, px, py); + break; + case "confirmBox": + this._clickConfirmBox(x, y, px, py); + break; + case "keyBoard": + this._clickKeyBoard(x, y, px, py); + break; + case "action": + this._clickAction(x, y, px, py); + break; + case "text": + core.drawText(); + break; + case "notes": + this._clickNotes(x, y, px, py); + break; + case "syncSave": + this._clickSyncSave(x, y, px, py); + break; + case "syncSelect": + this._clickSyncSelect(x, y, px, py); + break; + case "localSaveSelect": + this._clickLocalSaveSelect(x, y, px, py); + break; + case "storageRemove": + this._clickStorageRemove(x, y, px, py); + break; + case "cursor": + this._clickCursor(x, y, px, py); + break; + case "replay": + this._clickReplay(x, y, px, py); + break; + case "gameInfo": + this._clickGameInfo(x, y, px, py); + break; + case "about": + case "help": + core.ui.closePanel(); + break; + } + + // --- 长按判定 + if (core.timeout.onDownTimeout == null) { + core.timeout.onDownTimeout = setTimeout(function () { + if (core.interval.onDownInterval == null) { + core.interval.onDownInterval = setInterval(function () { + if (!core.actions.longClick(x, y, px, py)) { + clearInterval(core.interval.onDownInterval); + core.interval.onDownInterval = null; + } + }, 40); + } + }, 500); + } + return true; + }; + core.registerAction( + "ondown", + "_sys_ondown_lockControl", + core.actions._sys_ondown_lockControl, + 30 + ); +}, "额外信息": function () { /* 宝石血瓶左下角显示数值 * 注意!!!不要在道具属性中直接操作flags,使用core.status.hero.flags或core.setFlag系列函数代替! @@ -4180,280 +4660,532 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } } }, - "编辑器显伤": function () { + "跳伤": function () { // 在此增加新插件 - /////// 用户设置 /////// - // 将__enable置为false将关闭插件 - var __enable = true; - // 魔防攻速之类的属性可以在这里加 ['atk', 'def', 'mdef'] - var heroStatus = ["atk", "def", "mdef", "hp"]; - // saveHero为true 将会把每次造塔测试时的角色数据存下来 否则会读取初始属性 - // 用不着可以关了 节约缓存空间 (虽然根本没多少 还没一个存档大 - // 也可以手动清理 控制台输入core.removeLocalStorage('editorHero')即可 - var saveHero = true; - - // 下为具体实现 懒得写注释了 大概就是写HTML然后注册交互 - if (!__enable || main.mode != "editor") return; - core.plugin.initEditorDamage = false; - if (heroStatus.length >= 4 && !editor.isMobile) - editor.dom.mid2.style.top = 650 + 30 * (heroStatus.length - 3) + "px"; - editor.statusRatio = core.getLocalStorage("statusRatio", 1); - editor.saveHero = saveHero; - editor._heroStatus = heroStatus; - editor.dom.mapEdit.appendChild(core.canvas.damage.canvas); - var HTML = - ""; - - //if (heroStatus.length >= 4 && !editor.isMobile) editor.dom.mid2.style.top = 650 + 30 * (heroStatus.length - 3) + 'px'; - heroStatus.forEach(function (status) { - var id = status + "set", - id2 = status + "add", - id3 = status + "rec", - id4 = status + "help"; - HTML += - "
"; - }); - document.getElementById("viewportButtons").innerHTML = HTML; - ["set", "add", "rec", "help"].forEach(function (e) { - heroStatus.forEach(function (status) { - editor.dom[status + e] = document.getElementById(status + e); - }); - }); - var _hasItem = core.items.hasItem; - core.items.hasItem = function (itemId) { - if (itemId == "book" && main.mode == "editor") return true; - return _hasItem.call(core.items, itemId); - }; - if (main.mode == "editor") { - var applyList = [ - "getDamageString", - "nextCriticals", - "getEnemyInfo", - "getEnemyValue", - ]; - applyList.forEach(function (name) { - var func = core.enemys[name]; - core.enemys[name] = function () { - var args = - arguments.length === 1 - ? [arguments[0]] - : Array.apply(null, arguments); - if (typeof args[0] == "string") args[0] = core.enemys.enemys[args[0]]; - return func.apply(core.enemys, args); - }; - }); + /** + 函数使用说明 + Dove.MorePerform.ShowDamagePop.PopDamage( + 'ui', // 画布名称或画布2d上下文对象 + 100, 200, // 位置 (x, y) + -50, // 伤害值 + 24, // 字体大小 + "宋体",//字体 + '#FF0000', // 字体颜色 + '#000000', // 描边颜色 + 0.5, // 水平速度 (speedX) + -10, // 垂直速度 (speedY) + 0.5, // 重力 (gravity) + 120 // 显示时长(帧数) + */ + if (!core.registerAnimationFrame) { + throw new Error("require 2.6.1 or higher version"); } - ////// 获得勇士属性 ////// - core.control.getStatus = function (name) { - if (!core.status.hero) return null; - if (name == "x" || name == "y" || name == "direction") - return this.getHeroLoc(name); - /*if ( main.mode == 'editor' && !core.hasFlag('__statistics__')) { - return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; - }*/ - return core.status.hero[name]; - }; + window.Dove = window.Dove || {}; + Dove.MorePerform = Dove.MorePerform || {}; - core.control.updateDamage = function (floorId, ctx) { - floorId = floorId || core.status.floorId; - if (!floorId || core.status.gameOver) return; - var onMap = ctx == null; - if (main.mode == "editor") { - ctx = core.canvas.damage; - core.updateCheckBlock(); - core.clearMap(ctx); - if (editor.uivalues.bigmap) return; - } + Dove.MorePerform.ShowDamagePop = {}; + Dove.MorePerform.ShowDamagePop.version = 1.0; - // 没有怪物手册 - if (!core.hasItem("book")) return; - core.status.damage.posX = core.bigmap.posX; - core.status.damage.posY = core.bigmap.posY; - if (!onMap) { - var width = core.floors[floorId].width, - height = core.floors[floorId].height; - // 地图过大的缩略图不绘制显伤 - if (width * height > core.bigmap.threshold) return; - } - this._updateDamage_damage(floorId, onMap); - this._updateDamage_extraDamage(floorId, onMap); - this.drawDamage(ctx); - }; + Dove.MorePerform.ShowDamagePop.AllPopingCanvas = []; - core.control.drawDamage = function (ctx) { - if ( - core.status.gameOver || - !core.status.damage /* || main.mode != 'play'*/ - ) - return; - var onMap = false; - if (ctx == null) { - ctx = core.canvas.damage; - core.clearMap("damage"); - onMap = true; - } - - if (onMap && core.bigmap.v2) { - // 检查是否需要重算... - if ( - Math.abs(core.bigmap.posX - core.status.damage.posX) >= - core.bigmap.extend - 1 || - Math.abs(core.bigmap.posY - core.status.damage.posY) >= - core.bigmap.extend - 1 - ) { - return this.updateDamage(); - } - } - return this._drawDamage_draw(ctx, onMap); - }; - - ////// 以x,y的形式返回每个点的事件 ////// - core.maps.getMapBlocksObj = function (floorId, noCache) { - floorId = floorId || core.status.floorId; - if ( - core.status.mapBlockObjs[floorId] && - !noCache && - main.mode != "editor" - ) - return core.status.mapBlockObjs[floorId]; - - var obj = {}; - core.extractBlocks(floorId); - core.status.maps[floorId].blocks.forEach(function (block) { - obj[block.x + "," + block.y] = block; + // 每帧的处理 + Dove.MorePerform.ShowDamagePop.Update = function () { + this.AllPopingCanvas = this.AllPopingCanvas.filter(function (spr) { + spr.update(); + return spr.isAlive(); }); - core.status.mapBlockObjs[floorId] = obj; - return obj; + if (!this.AllPopingCanvas.length) PopSprite._count = 0; }; - this.bignum = function (num, defaultValue) { - if (num == null || num == "") return defaultValue; - num = num + ""; - var list = { - w: 1e4, - e: 1e8, - z: 1e12, - j: 1e16, - g: 1e20, - }; - // 浮点数问题 - function checkFloat(num) { - if (!core.isset(num)) return 0; - num = num + ""; - var index = num.indexOf("."); - if (index < 0) return 0; - else return num.slice(index + 1).length; + // 弹出伤害气泡 + Dove.MorePerform.ShowDamagePop.PopDamage = function ( + canvasName, + x, + y, + damageValue, + fontSize, + font, + fontColor, + outlineColor, + speedX, + speedY, + gravity, + duration + ) { + if (damageValue) { + var poper = new PopSprite( + canvasName, + x, + y, + damageValue, + fontSize, + font, + fontColor, + outlineColor, + speedX, + speedY, + gravity, + duration + ); + Dove.MorePerform.ShowDamagePop.AllPopingCanvas.push(poper); } - var index = num.search(/w|e|z|j|g/); - if (index <= 0) { - num = parseInt(num); - if (core.isset(num)) return num; - else { - alert("不正确的输入"); - return defaultValue; + }; + + // 战斗发生前后记录生命值并处理 + Dove.MorePerform.ShowDamagePop.OnBattle = core.events.battle; + core.events.battle = function () { + var hpBeforeBattle = core.status.hero.hp; + Dove.MorePerform.ShowDamagePop.OnBattle.apply(core.events, arguments); + if (core.getFlag("noAnimate")) + Dove.MorePerform.ShowDamagePop.PopDamage( + "ui", // 默认画布名称 + core.getHeroLoc("x") * 32, // 英雄位置 x + core.getHeroLoc("y") * 32, // 英雄位置 y + Math.floor(core.status.hero.hp - hpBeforeBattle), // 伤害值 + 16, // 默认字体大小 + "Arial", //默认字体 + null, // 默认颜色 + null, // 默认描边颜色 + null, // 默认水平速度 + null, // 默认垂直速度 + null, // 默认重力 + 90 // 默认显示时长(帧数) + ); + }; + let time = 0; + // 注册每帧事件 + core.registerAnimationFrame("ShowDamagePop", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + + Dove.MorePerform.ShowDamagePop.Update.bind( + Dove.MorePerform.ShowDamagePop + )(); + } + }); + + // 弹出精灵类 + function PopSprite( + canvasName, + x, + y, + damage, + fontSize, + font, + fontColor, + outlineColor, + speedX, + speedY, + gravity, + duration + ) { + this.initialize.apply(this, arguments); + } + + PopSprite.prototype = Object.create(Object.prototype); + PopSprite.prototype.constructor = PopSprite; + + // 常量 + PopSprite._count = 0; + PopSprite._baseZOrder = 50; + PopSprite._floorDis = 20; + + // 初始化 + PopSprite.prototype.initialize = function ( + canvasName, + x, + y, + damage, + fontSize, + font, + fontColor, + outlineColor, + speedX, + speedY, + gravity, + duration + ) { + this._canvasName = canvasName ?? "ui"; // 默认画布名称 + this._x = x; + this._y = y; + this._damage = damage; + this._fontSize = fontSize ?? 16; // 默认字体大小 + this._font = font ?? "Arial"; + this._fontColor = fontColor ?? (damage > 0 ? "#22FF44" : "lightcoral"); // 默认颜色 + this._outlineColor = outlineColor ?? "#FFFFFF"; // 默认描边颜色 + this._speedX = speedX ?? -1 + Math.random() * 2; // 水平速度,默认随机 + this._speedY = speedY ?? -3 - Math.random() * 4; // 垂直速度,默认随机 + this._gravity = gravity ?? 0.3; // 重力加速度,默认 0.3 + this._duration = duration ?? 180; // 显示时长(帧数),默认 180 帧 + this.initAllMembers(); + this.requestCanvas(); + }; + + // 自更新 + PopSprite.prototype.update = function () { + if (this._timer < this._duration) { + // 使用传入的显示时长 + this._x += this._vx; + this._y += this._vy; + this._vy += this._gravity; + if (this._y >= this._floorY) { + this._y = this._floorY; + this._vy *= -0.75; // 反弹衰减 } + core.relocateCanvas(this._symbol, this._x, this._y); + core.setOpacity(this._symbol, 1 - this._timer / this._duration); // 根据显示时长设置透明度 + } else { + this.dispose(); } - for (; index > 0; index = num.search(/w|e|z|j|g/)) { - var p = num[index], - q = list[p], - n = num.slice(0, index), - m = Math.pow(10, checkFloat(n)); - num = (n * m * q) / m + num.slice(index + 1); - } - return parseInt(num); + this._timer++; }; - this.updateEditorDamage = function (noSave) { - core.updateDamage(); - heroStatus.forEach(function (status) { - editor.dom[status + "set"].value = core.status.hero[status]; - }); - if (!noSave && editor.saveHero) - core.setLocalStorage("editorHero", core.status.hero); + // 申请并描绘canvas + PopSprite.prototype.requestCanvas = function () { + core.createCanvas( + this._symbol, + this._x, + this._y, + this._width + 4, + this._height + 4, + this._z + ); + + var canvas = core.getContextByName(this._symbol); + canvas.font = this._fontSize + "px " + this._font; // 动态设置字体大小 + canvas.fillStyle = this._fontColor; // 动态设置字体颜色 + canvas.strokeStyle = this._outlineColor; // 动态设置描边颜色 + canvas.strokeText(this._text, 2, this._height); + canvas.fillText(this._text, 2, this._height); }; - var _resizeMap = core.maps.resizeMap; - core.maps.resizeMap = function (floorId) { - _resizeMap.call(core.maps, floorId); - if (!core.plugin.initEditorDamage && main.mode == "editor") { - core.plugin.initEditorDamage = true; - var editorHero = core.getLocalStorage("editorHero"); - if (editorHero && saveHero) core.status.hero = editorHero; - else core.removeLocalStorage("editorHero"); - editor._heroStatus.forEach(function (e) { - editor.dom[e + "set"].onchange = function () { - var status = this.id.slice(0, -3); - core.status.hero[status] = core.bignum( - this.value, - core.status.hero[status] - ); - core.updateEditorDamage(); - }; - editor.dom[e + "add"].onclick = function () { - var status = this.id.slice(0, -3); - core.status.hero[status] += editor.statusRatio; - core.updateEditorDamage(); - }; - editor.dom[e + "rec"].onclick = function () { - var status = this.id.slice(0, -3); - core.status.hero[status] -= editor.statusRatio; - core.updateEditorDamage(); - }; - editor.dom[e + "help"].onclick = function () { - var status = this.id.slice(0, -4), - name = core.getStatusLabel(status); - var ratio = parseInt( - prompt( - "当前属性:" + - name + - "\n现在的点击按钮变化值:" + - editor.statusRatio + - ",请输入按下一次+/-按钮的属性变化量,可以写4w 10.2e这种字母缩写" - ) - ); - if (!core.isset(ratio)) { - printe("不合法的输入"); - return; - } - editor.statusRatio = ratio; - core.setLocalStorage("statusRatio", ratio); - }; - }); - var _updateMap = editor.updateMap; - editor.updateMap = function () { - _updateMap.call(editor); - core.updateEditorDamage(true); - }; - editor.mode.onmode = function (mode, callback) { - if (editor_mode.mode != mode) { - if (mode === "save") { - editor_mode.doActionList( - editor_mode.mode, - editor_mode.actionList, - function () { - if (callback) callback(); - core.updateEditorDamage(); - } - ); - } - if (editor_mode.mode === "nextChange" && mode) - editor_mode.showMode(mode); - if (mode !== "save") editor_mode.mode = mode; - editor_mode.actionList = []; - } - }; - } + // 初始化所有成员变量 + PopSprite.prototype.initAllMembers = function () { + this._text = String(this._damage); + var uiContext = core.ui.getContextByName(this._canvasName); // 使用指定画布 + uiContext.font = this._fontSize + "px " + this._font; // 动态设置字体大小 + var textRect = uiContext.measureText(this._text); + this._width = textRect.width + 4; + this._height = this._fontSize + 4; // 动态设置高度 + this._z = uiContext.canvas.style.zIndex + ? Number(uiContext.canvas.style.zIndex) + PopSprite._count + : PopSprite._baseZOrder + PopSprite._count; + this._symbol = "popSprite" + PopSprite._count++; + this._alive = true; + this._vx = this._speedX; // 使用传入的水平速度 + this._vy = this._speedY; // 使用传入的垂直速度 + this._floorY = this._y + PopSprite._floorDis; + this._timer = 0; + }; + + // 判断是否存活 + PopSprite.prototype.isAlive = function () { + return this._alive; + }; + + // 释放 + PopSprite.prototype.dispose = function () { + this._alive = false; + core.deleteCanvas(this._symbol); }; }, + "编辑器显伤": function () { + // 在此增加新插件 + /////// 用户设置 /////// + // 将__enable置为false将关闭插件 + var __enable = true; + // 魔防攻速之类的属性可以在这里加 ['atk', 'def', 'mdef'] + var heroStatus = [ + "atk", + "def", + "spell", + "mdef", + "matk", + "mhp", + "speed", + "hp", + ]; + // saveHero为true 将会把每次造塔测试时的角色数据存下来 否则会读取初始属性 + // 用不着可以关了 节约缓存空间 (虽然根本没多少 还没一个存档大 + // 也可以手动清理 控制台输入core.removeLocalStorage('editorHero')即可 + var saveHero = true; + + // 下为具体实现 懒得写注释了 大概就是写HTML然后注册交互 + if (!__enable || main.mode != "editor") return; + core.plugin.initEditorDamage = false; + if (heroStatus.length >= 4 && !editor.isMobile) { + editor.dom.mid2.style.top = 650 + 30 * (heroStatus.length - 3) + "px"; + editor.dom.mid.style.height = 730 + "px"; + document.querySelector("#mid .tools").style.height = 280 + "px"; + } + editor.statusRatio = core.getLocalStorage("statusRatio", 1); + editor.saveHero = saveHero; + editor._heroStatus = heroStatus; + editor.dom.mapEdit.appendChild(core.canvas.damage.canvas); + const viewportButtons = document.getElementById("viewportButtons"); + + var HTML = + ""; + + //if (heroStatus.length >= 4 && !editor.isMobile) editor.dom.mid2.style.top = 650 + 30 * (heroStatus.length - 3) + 'px'; + heroStatus.forEach(function (status) { + var id = status + "set", + id2 = status + "add", + id3 = status + "rec", + id4 = status + "help"; + HTML += + "
" + + core.getStatusLabel(status) + + ""; + }); + document.getElementById("viewportButtons").innerHTML = HTML; + ["set", "add", "rec", "help"].forEach(function (e) { + heroStatus.forEach(function (status) { + editor.dom[status + e] = document.getElementById(status + e); + }); + }); + var _hasItem = core.items.hasItem; + core.items.hasItem = function (itemId) { + if (itemId == "book" && main.mode == "editor") return true; + return _hasItem.call(core.items, itemId); + }; + if (main.mode == "editor") { + var applyList = [ + "getDamageString", + "nextCriticals", + "getEnemyInfo", + "getEnemyValue", + ]; + applyList.forEach(function (name) { + var func = core.enemys[name]; + core.enemys[name] = function () { + var args = + arguments.length === 1 ? + [arguments[0]] : + Array.apply(null, arguments); + if (typeof args[0] == "string") args[0] = core.enemys.enemys[args[0]]; + return func.apply(core.enemys, args); + }; + }); + } + + ////// 获得勇士属性 ////// + core.control.getStatus = function (name) { + if (!core.status.hero) return null; + if (name == "x" || name == "y" || name == "direction") + return this.getHeroLoc(name); + /*if ( main.mode == 'editor' && !core.hasFlag('__statistics__')) { + return data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.hero[name]; + }*/ + return core.status.hero[name]; + }; + + core.control.updateDamage = function (floorId, ctx) { + floorId = floorId || core.status.floorId; + if (!floorId || core.status.gameOver) return; + var onMap = ctx == null; + if (main.mode == "editor") { + ctx = core.canvas.damage; + core.updateCheckBlock(); + core.clearMap(ctx); + if (editor.uivalues.bigmap) return; + } + + // 没有怪物手册 + if (!core.hasItem("book")) return; + core.status.damage.posX = core.bigmap.posX; + core.status.damage.posY = core.bigmap.posY; + if (!onMap) { + var width = core.floors[floorId].width, + height = core.floors[floorId].height; + // 地图过大的缩略图不绘制显伤 + if (width * height > core.bigmap.threshold) return; + } + this._updateDamage_damage(floorId, onMap); + this._updateDamage_extraDamage(floorId, onMap); + this.drawDamage(ctx); + }; + + core.control.drawDamage = function (ctx) { + if ( + core.status.gameOver || + !core.status.damage /* || main.mode != 'play'*/ + ) + return; + var onMap = false; + if (ctx == null) { + ctx = core.canvas.damage; + core.clearMap("damage"); + onMap = true; + } + + if (onMap && core.bigmap.v2) { + // 检查是否需要重算... + if ( + Math.abs(core.bigmap.posX - core.status.damage.posX) >= + core.bigmap.extend - 1 || + Math.abs(core.bigmap.posY - core.status.damage.posY) >= + core.bigmap.extend - 1 + ) { + return this.updateDamage(); + } + } + return this._drawDamage_draw(ctx, onMap); + }; + + ////// 以x,y的形式返回每个点的事件 ////// + core.maps.getMapBlocksObj = function (floorId, noCache) { + floorId = floorId || core.status.floorId; + if ( + core.status.mapBlockObjs[floorId] && + !noCache && + main.mode != "editor" + ) + return core.status.mapBlockObjs[floorId]; + + var obj = {}; + core.extractBlocks(floorId); + core.status.maps[floorId].blocks.forEach(function (block) { + obj[block.x + "," + block.y] = block; + }); + core.status.mapBlockObjs[floorId] = obj; + return obj; + }; + + this.bignum = function (num, defaultValue) { + if (num == null || num == "") return defaultValue; + num = num + ""; + var list = { + w: 1e4, + e: 1e8, + z: 1e12, + j: 1e16, + g: 1e20, + }; + // 浮点数问题 + function checkFloat(num) { + if (!core.isset(num)) return 0; + num = num + ""; + var index = num.indexOf("."); + if (index < 0) return 0; + else return num.slice(index + 1).length; + } + var index = num.search(/w|e|z|j|g/); + if (index <= 0) { + num = parseInt(num); + if (core.isset(num)) return num; + else { + alert("不正确的输入"); + return defaultValue; + } + } + for (; index > 0; index = num.search(/w|e|z|j|g/)) { + var p = num[index], + q = list[p], + n = num.slice(0, index), + m = Math.pow(10, checkFloat(n)); + num = (n * m * q) / m + num.slice(index + 1); + } + return parseInt(num); + }; + + this.updateEditorDamage = function (noSave) { + core.updateDamage(); + heroStatus.forEach(function (status) { + editor.dom[status + "set"].value = core.status.hero[status]; + }); + if (!noSave && editor.saveHero) + core.setLocalStorage("editorHero", core.status.hero); + }; + + var _resizeMap = core.maps.resizeMap; + core.maps.resizeMap = function (floorId) { + _resizeMap.call(core.maps, floorId); + if (!core.plugin.initEditorDamage && main.mode == "editor") { + core.plugin.initEditorDamage = true; + var editorHero = core.getLocalStorage("editorHero"); + if (editorHero && saveHero) core.status.hero = editorHero; + else core.removeLocalStorage("editorHero"); + editor._heroStatus.forEach(function (e) { + editor.dom[e + "set"].onchange = function () { + var status = this.id.slice(0, -3); + core.status.hero[status] = core.bignum( + this.value, + core.status.hero[status] + ); + if (status === "mdef" && core.status.hero[status] > 100) + core.status.hero[status] = 100; + core.updateEditorDamage(); + }; + editor.dom[e + "add"].onclick = function () { + var status = this.id.slice(0, -3); + core.status.hero[status] += editor.statusRatio; + if (status === "mdef" && core.status.hero[status] > 100) + core.status.hero[status] = 100; + core.updateEditorDamage(); + }; + editor.dom[e + "rec"].onclick = function () { + var status = this.id.slice(0, -3); + core.status.hero[status] -= editor.statusRatio; + core.updateEditorDamage(); + }; + editor.dom[e + "help"].onclick = function () { + var status = this.id.slice(0, -4), + name = core.getStatusLabel(status); + var ratio = parseInt( + prompt( + "当前属性:" + + name + + "\n现在的点击按钮变化值:" + + editor.statusRatio + + ",请输入按下一次+/-按钮的属性变化量,可以写4w 10.2e这种字母缩写" + ) + ); + if (!core.isset(ratio)) { + printe("不合法的输入"); + return; + } + editor.statusRatio = ratio; + core.setLocalStorage("statusRatio", ratio); + }; + }); + var _updateMap = editor.updateMap; + editor.updateMap = function () { + _updateMap.call(editor); + core.updateEditorDamage(true); + }; + editor.mode.onmode = function (mode, callback) { + if (editor_mode.mode != mode) { + if (mode === "save") { + editor_mode.doActionList( + editor_mode.mode, + editor_mode.actionList, + function () { + if (callback) callback(); + core.updateEditorDamage(); + } + ); + } + if (editor_mode.mode === "nextChange" && mode) + editor_mode.showMode(mode); + if (mode !== "save") editor_mode.mode = mode; + editor_mode.actionList = []; + } + }; + } + }; +}, "手册区分特殊属性": function () { // 在此增加新插件 this.arrsame = function (Arraya, Arrayb) { @@ -4881,7 +5613,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "新道具栏/装备栏": function () { - // 在此增加新插件 + // 这个插件有点离谱 个人觉得参数过多只会降低可读性,还不如硬编码 + // 注:///// *** 裹起来的区域: 该区域内参数可以随意更改调整ui绘制 不会影响总体布局 // 请尽量修改该区域而不是其他区域 修改的时候最好可以对照现有ui修改 @@ -4896,7 +5629,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ///// *** // 背景设置 - this.drawBoxBackground = function (ctx) { + function drawBoxBackground(ctx) { core.setTextAlign(ctx, "left"); core.clearMap(ctx); core.deleteCanvas("_selector"); @@ -4978,7 +5711,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var arrow_width = 20; var arrow_style = "white"; // 暂时只能是1 否则不太行 等待新样板(2.7.3)之后对drawArrow做优化 - var arrow_lineWidth = 1; + var arrow_lineWidth = 2; // 右箭头 var rightArrow_right = leftbar_right - 10; // 道具内栏顶部坐标 本质是通过该项 控制(道具栏顶部文字和箭头)与道具内栏顶部的间隔 @@ -5039,7 +5772,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var bottomSpace = 8; ///// *** - core.drawItemListbox_setPageBtn( + drawItemListbox_setPageBtn( ctx, pageBtn_left, pageBtn_right, @@ -5051,7 +5784,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var page = info.page || 1; var pageFontSize = pageBtn_radius * 2 - 4; var pageFont = core.ui._buildFont(pageFontSize); - core.setPageItems(page); + setPageItems(page); var num = itemNum; if (core.status.event.id == "equipbox") num -= 5; var maxPage = info.maxPage; @@ -5066,7 +5799,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = pageText_color, pageFont ); - core.addUIEventListener( + addUIEventListener( start_x, start_y, leftbar_right - start_x, @@ -5095,9 +5828,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = oneItemHeight: oneItemHeight, }, }; - }; + } - this.drawItemListbox = function (ctx, obj) { + function drawItemListbox(ctx, obj) { ctx = ctx || core.canvas.ui; var itembar_x = obj.x, itembar_y = obj.y, @@ -5139,7 +5872,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = itembar_style ); core.setAlpha(ctx, 1); - var pageItems = core.setPageItems(page); + var pageItems = setPageItems(page); var marginHeight = itembar_marginHeightRatio * oneItemHeight; core.setTextBaseline(ctx, "middle"); var originColor = itemName_color; @@ -5148,7 +5881,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var item = pageItems[i]; // 设置某个的字体颜色的一个例子 // if (item.id == "xxx") itemName_color = "green"; - core.drawItemListbox_drawItem( + drawItemListbox_drawItem( ctx, item_x, item_right, @@ -5169,9 +5902,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); item_y += oneItemHeight; } - }; + } - this.drawToolboxRightbar = function (ctx, obj) { + function drawToolboxRightbar(ctx, obj) { ctx = ctx || core.canvas.ui; var info = core.status.thisUIEventInfo || {}; var page = info.page || 1, @@ -5248,7 +5981,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = cls: "equips", name: "未知装备", text: "一无所有,又何尝不是一种装备", - equipCls: "无", equip: { type: "装备", }, @@ -5262,8 +5994,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = itemName = item.name, itemText = item.text; itemText = core.replaceText(itemText); - if (itemText[0] == "," || itemText[0] == ",") - itemText = itemText.substring(1); + if (!itemText) itemText = "该道具无描述。"; /* 一个根据道具id修改道具名字(右栏)的例子 * if (item.id == "xxx") itemNameColor = "red"; */ @@ -5291,6 +6022,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); core.setTextAlign(ctx, "left"); core.setTextBaseline(ctx, "middle"); + if (itemCls === "equips" && item.id) { + itemName = "【" + item.equipCls + "】" + itemName; + } core.fillText( ctx, itemName, @@ -5300,45 +6034,105 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = itemNameFont, itemNameMaxWidth ); - core.fillText( - ctx, - "【" + itemClsName + "】", - itemCls_x, - itemCls_middle, - itemClsColor, - itemClsFont - ); - var statusText = "【装备类型】" + item.equipCls + "\n\n"; - /*if (core.status.event.id == "equipbox") { - var type = item.equip.type; - if (typeof type == "string") type = core.getEquipTypeByName(type); - var compare = core.compareEquipment(item.id, core.getEquip(type)); - if (info.select.action == "unload") compare = core.compareEquipment(null, item.id); - // --- 变化值... - for (var name in core.status.hero) { - if (typeof core.status.hero[name] != 'number') continue; - var nowValue = core.getRealStatus(name); - // 查询新值 - var newValue = Math.floor((core.getStatus(name) + (compare.value[name] || 0)) * - (core.getBuff(name) * 100 + (compare.percentage[name] || 0)) / 100); - if (nowValue == newValue) continue; - var color = newValue > nowValue ? '#00FF00' : '#FF0000'; - nowValue = core.formatBigNumber(nowValue); - newValue = core.formatBigNumber(newValue); - statusText += core.getStatusLabel(name) + " " + nowValue + "->\r[" + color + "]" + newValue + "\r\n"; - } - }*/ + if (!item.equip) + core.fillText( + ctx, + "【" + itemClsName + "】", + itemCls_x, + itemCls_middle, + itemClsColor, + itemClsFont + ); + + var statusText = ""; + if (core.status.event.id == "equipbox") { + var type = item.equip.type; + if (typeof type == "string") type = core.getEquipTypeByName(type); + var compare = core.compareEquipment(item.id, core.getEquip(type)); + var compare2; + if (item.equipCls === "双手剑") + compare2 = core.compareEquipment(null, core.getEquip(1)); + if ( + item.equipCls === "盾牌" && + core.material.items[core.getEquip(0)]?.equipCls === "双手剑" + ) + compare2 = core.compareEquipment(null, core.getEquip(0)); + if (info.select.action == "unload") + compare = core.compareEquipment(null, item.id); + // --- 变化值... + for (var name in core.status.hero) { + if (typeof core.status.hero[name] != "number") continue; + var nowValue = core.getRealStatus(name); + // 查询新值 + var newValue = Math.floor( + ((core.getStatus(name) + + (compare.value[name] || 0) + + (compare2?.value[name] || 0)) * + (core.getBuff(name) * 100 + + (compare.percentage[name] || 0) + + (compare2?.percentage[name] || 0))) / + 100 + ); + if (name === "mdef") { + var nowValue = core.getRealStatus(name); + var newValue = Math.round( + (core.getStatus(name) - + (compare.value[name] || 0) - + (compare2?.value[name] || 0)) * + (1 - + (1 - core.getBuff(name)) * + (compare.percentage[name] || 1) * + (compare2?.percentage[name] || 1)) + ); + } + if (nowValue == newValue) continue; + var color = newValue > nowValue ? "#00FF00" : "#FF0000"; + nowValue = core.formatBigNumber(nowValue); + newValue = core.formatBigNumber(newValue); + + if (name === "mdef") { + nowValue += "%"; + newValue += "%"; + } + statusText += + core.getStatusLabel(name) + + " " + + nowValue + + "->\r[" + + color + + "]" + + newValue + + "\r\n"; + } + } itemText = statusText + itemText; - core.drawTextContent(ctx, itemText, { - left: itemText_x, - top: itemText_y, - bold: false, - color: "white", - align: "left", - fontSize: itemTextFontSize, - maxWidth: - rightbar_width - (itemText_x - rightbar_x) * 2 + itemTextFontSize / 2, - }); + if (item.equip) { + core.drawTextContent(ctx, itemText, { + left: itemText_x, + top: itemCls_middle, + bold: false, + color: "white", + align: "left", + fontSize: itemTextFontSize, + maxWidth: + rightbar_width - + (itemText_x - rightbar_x) * 2 + + itemTextFontSize / 2, + }); + } else { + core.drawTextContent(ctx, itemText, { + left: itemText_x, + top: itemText_y, + bold: false, + color: "white", + align: "left", + fontSize: itemTextFontSize, + maxWidth: + rightbar_width - + (itemText_x - rightbar_x) * 2 + + itemTextFontSize / 2, + }); + } ///// *** 退出按钮设置 var btnRadius = 10; @@ -5349,9 +6143,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ///// *** // 获取圆心位置 - var btn_x = btnRight - btnRadius - btnBorderWidth / 2, - btn_y = btnBottom - btnRadius - btnBorderWidth / 2; - core.drawToolbox_setExitBtn( + var btn_x = btnRight - btnRadius - btnBorderWidth / 2; + btn_y = btnBottom - btnRadius - btnBorderWidth / 2; + drawToolbox_setExitBtn( ctx, btn_x, btn_y, @@ -5363,14 +6157,16 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ///// *** 使用按钮设置 var useBtnHeight = btnRadius * 2; // 这里不设置useBtnWidth而是根据各项数据自动得出width - var useBtnRadius = useBtnHeight / 2; + var useBtnRadius = useBtnHeight / 4; var useBtn_x = rightbar_x + 4, useBtn_y = btnBottom - useBtnHeight; var useBtnBorderStyle = "#fff"; var useBtnBorderWidth = btnBorderWidth; + const batchUseBtn_x = useBtn_x + 50; // 个人觉得,搞这么多参数还不如硬编码 + const hideBtn_y = useBtn_y - useBtnHeight - 8; ///// *** - core.drawToolbox_setUseBtn( + drawToolbox_setUseBtn( ctx, useBtn_x, useBtn_y, @@ -5379,9 +6175,36 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = useBtnBorderStyle, useBtnBorderWidth ); - }; + if (core.status.event.id === "toolbox") { + drawToolbox_setBatchUseBtn( + ctx, + batchUseBtn_x, + useBtn_y, + useBtnRadius, + useBtnHeight, + useBtnBorderStyle, + useBtnBorderWidth + ); + } + drawToolbox_setHideBtn( + ctx, + useBtn_x, + hideBtn_y, + useBtnRadius, + useBtnHeight, + useBtnBorderStyle, + useBtnBorderWidth + ); + drawToolbox_setShowHideBtn( + ctx, + rightbar_x, + useBtn_y, + useBtnHeight, + useBtnBorderStyle + ); + } - this.drawEquipbox_drawOthers = function (ctx, obj) { + function drawEquipbox_drawOthers(ctx, obj) { var info = core.status.thisUIEventInfo; ///// *** 装备格设置 @@ -5411,7 +6234,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = len = toDrawList.length; ///// *** 装备格设置 - var maxItem = 4; + var maxItem = 2; var box_width = 32, box_height = 32, box_borderStyle = "#fff", @@ -5437,8 +6260,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); var box_x = equipList_x + space_x, - box_y = equipList_y + space_y; - for (var i = 0; i < len; i++) { + box_y = equipList_y + space_y + 12; + for (var i = 0; i < 2; i++) { var id = core.getEquip(i), name = toDrawList[i]; if (i === 0) name = "主手"; @@ -5448,7 +6271,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var borderStyle = selectBorder ? box_selectBorderStyle : box_borderStyle; - core.drawEquipbox_drawOne( + drawEquipbox_drawOne( ctx, name, id, @@ -5465,7 +6288,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var todo = new Function( "core.clickOneEquipbox('" + id + "'," + i + ")" ); - core.addUIEventListener( + addUIEventListener( box_x - box_borderWidth / 2, box_y - box_borderWidth / 2, oneBoxWidth, @@ -5482,38 +6305,100 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawLine( ctx, equipList_x + space_x + space_x + oneBoxWidth, - equipList_y + space_y, + equipList_y + space_y + 12, equipList_x + space_x + space_x + oneBoxWidth + box_width + box_borderWidth, - equipList_y + space_y + box_height + equipList_y + space_y + box_height + 12 ); core.drawLine( ctx, equipList_x + space_x + space_x + oneBoxWidth, - equipList_y + space_y + box_height, + equipList_y + space_y + box_height + 12, equipList_x + space_x + space_x + oneBoxWidth + box_width + box_borderWidth, - equipList_y + space_y + equipList_y + space_y + 12 ); } - }; + ///// *** 装备格设置 + var maxItem = 3; + var box_width = 32, + box_height = 32, + box_borderStyle = "#fff", + box_selectBorderStyle = "gold", // 选中的装备格的颜色 + box_borderWidth = 2; + var boxName_fontSize = 14, + boxName_space = 2, + boxName_color = "#fff"; // 装备格名称与上面的装备格框的距离 + var maxLine = Math.ceil(len / maxItem); + ///// *** + var l = Math.sqrt(len); + if (Math.pow(l) == len && len != 4) { + if (l <= maxItem) maxItem = l; + } + maxItem = Math.min(toDrawList.length, maxItem); + info.equips = maxItem; + + var boxName_font = core.ui._buildFont(boxName_fontSize); + // 总宽高减去所有装备格宽高得到空隙大小 + var oneBoxWidth = box_width + box_borderWidth * 2; + var oneBoxHeight = + box_height + boxName_fontSize + boxName_space + 2 * box_borderWidth; + var space_y = (equipList_height - maxLine * oneBoxHeight) / (1 + maxLine), + space_x = (equipList_width - maxItem * oneBoxWidth) / (1 + maxItem); + var box_x = equipList_x + space_x, + box_y = equipList_y + space_y + space_y + oneBoxHeight; + for (var i = 2; i < len; i++) { + var id = core.getEquip(i), + name = toDrawList[i]; + var selectBorder = false; + if (core.status.thisUIEventInfo.select.type == i) selectBorder = true; + var borderStyle = selectBorder + ? box_selectBorderStyle + : box_borderStyle; + drawEquipbox_drawOne( + ctx, + name, + id, + box_x, + box_y, + box_width, + box_height, + boxName_space, + boxName_font, + boxName_color, + borderStyle, + box_borderWidth + ); + var todo = new Function( + "core.clickOneEquipbox('" + id + "'," + i + ")" + ); + addUIEventListener( + box_x - box_borderWidth / 2, + box_y - box_borderWidth / 2, + oneBoxWidth, + oneBoxHeight, + todo + ); + box_x += space_x + oneBoxWidth; + } + } this.drawToolbox = function (ctx) { ctx = ctx || core.canvas.ui; core.status.thisEventClickArea = []; - var info = core.drawBoxBackground(ctx); + var info = drawBoxBackground(ctx); info.itemNum = itemNum; - core.drawItemListbox(ctx, info.obj); - core.drawToolboxRightbar(ctx, info); + drawItemListbox(ctx, info.obj); + drawToolboxRightbar(ctx, info); core.setTextBaseline(ctx, "alphabetic"); core.setTextAlign("left"); }; @@ -5522,18 +6407,18 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = this.drawEquipbox = function (ctx) { ctx = ctx || core.canvas.ui; core.status.thisEventClickArea = []; - var info = core.drawBoxBackground(ctx); + var info = drawBoxBackground(ctx); info.itemNum = itemNum - reduceItem; info.obj.y += info.obj.oneItemHeight * reduceItem; info.obj.height -= info.obj.oneItemHeight * reduceItem; - core.drawItemListbox(ctx, info.obj); - core.drawEquipbox_drawOthers(ctx, info); - core.drawToolboxRightbar(ctx, info); + drawItemListbox(ctx, info.obj); + drawEquipbox_drawOthers(ctx, info); + drawToolboxRightbar(ctx, info); core.setTextBaseline(ctx, "alphabetic"); core.setTextAlign("left"); }; - this.drawEquipbox_drawOne = function ( + function drawEquipbox_drawOne( ctx, name, id, @@ -5570,11 +6455,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var tx = (x + x + lineWidth / 2 + width) / 2, ty = y + height + (lineWidth / 2) * 3 + space; core.fillText(ctx, name, tx, ty, color, font); + + core.setAlpha(ctx, 1); + core.setTextBaseline(ctx, "alphabetic"); core.setTextAlign("left"); - }; + } - this.drawItemListbox_drawItem = function ( + function drawItemListbox_drawItem( ctx, left, right, @@ -5601,6 +6489,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = style, core.ui._buildFont(fontSize) ); + + const hideInfo = core.getFlag("hideInfo", {}); + if ( + item && + (hideInfo.hasOwnProperty(id) ? hideInfo[id] : item.hideInToolbox) + ) + core.setAlpha(ctx, 0.5); + if (name != "???") core.drawIcon( ctx, @@ -5622,18 +6518,21 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.ui._buildFont(fontSize), maxWidth ); - var todo = new Function("core.clickItemFunc('" + id + "');"); - core.addUIEventListener(left, top, right - left, height, todo); - }; + core.setAlpha(ctx, 1); - this.setPageItems = function (page) { + var todo = new Function("core.clickItemFunc('" + id + "');"); + addUIEventListener(left, top, right - left, height, todo); + } + + function setPageItems(page) { var num = itemNum; if (core.status.event.id == "equipbox") num -= reduceItem; var info = core.status.thisUIEventInfo; if (!info) return; page = page || info.page; var items = core.getToolboxItems( - core.status.event.id == "toolbox" ? "all" : "equips" + core.status.event.id == "toolbox" ? "all" : "equips", + core.getFlag("showHideItem", false) ); info.allItems = items; var maxPage = Math.ceil(items.length / num); @@ -5644,12 +6543,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (items.length == 0 && pageItems.length == 0) info.index = null; if (pageItems.length == 0 && info.page > 1) { info.page = Math.max(1, info.page - 1); - return core.setPageItems(info.page); + return setPageItems(info.page); } return pageItems; - }; + } - this.drawToolbox_setExitBtn = function (ctx, x, y, r, style, lineWidth) { + function drawToolbox_setExitBtn(ctx, x, y, r, style, lineWidth) { core.strokeCircle(ctx, x, y, r, style, lineWidth); ctx.textAlign = "center"; ctx.textBaseline = "middle"; @@ -5669,10 +6568,10 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var todo = function () { core.closePanel(); }; - core.addUIEventListener(x - r, y - r, r * 2, r * 2, todo); - }; + addUIEventListener(x - r, y - r, r * 2, r * 2, todo); + } - this.drawToolbox_setUseBtn = function (ctx, x, y, r, h, style, lineWidth) { + function drawToolbox_setUseBtn(ctx, x, y, r, h, style, lineWidth) { core.setTextAlign(ctx, "left"); core.setTextBaseline(ctx, "top"); var fontSize = h - 4; @@ -5687,10 +6586,182 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var todo = function () { core.useSelectItemInBox(); }; - core.addUIEventListener(x, y, w, h, todo); + addUIEventListener(x, y, w, h, todo); + } + + function getSelectedItem() { + var info = core.status.thisUIEventInfo; + if ( + !( + info && + info.select.id && + ["toolbox", "equipbox"].includes(core.status.event.id) + ) + ) { + core.drawFailTip("发生了未知错误!"); + return; + } + return info.select.id; + } + + function batchUse(item, count) { + try { + const itemCount = core.itemCount(item); + if (count > itemCount) count = itemCount; + core.closePanel(); + for (let i = 0; i < count; i++) { + if (core.canUseItem(item)) core.useItem(item); + else return; + } + } catch (e) { + console.error(e); + core.drawFailTip("批量使用时出现未知错误!"); + } + } + + function drawToolbox_setBatchUseBtn(ctx, x, y, r, h, style, lineWidth) { + try { + const selectedItem = getSelectedItem(); + let canBatchUse = eval(core.material.items[selectedItem]?.canBatchUse); + if (!canBatchUse) return; + } catch (error) { + console.error(error); + return; + } + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 4; + var font = core.ui._buildFont(fontSize); + var text = "批量使用"; + var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; + + core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); + core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); + + var todo = function () { + core.utils.myprompt("输入要使用该物品的次数(0~99)。", null, (value) => { + value = parseInt(value); + const id = getSelectedItem(); + + if (Number.isNaN(value) || value < 0 || value > 99) { + core.drawFailTip("输入不合法!"); + return; + } + if (!core.canUseItem(id)) { + core.drawFailTip("当前无法使用该道具!"); + return; + } + core.closePanel(); + batchUse(id, value); + }); + }; + addUIEventListener(x, y, w, h, todo); + } + + function drawToolbox_setHideBtn(ctx, x, y, r, h, style, lineWidth) { + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 4; + var font = core.ui._buildFont(fontSize); + var text = "显示/隐藏"; + var w = core.calWidth(ctx, text, font) + 2 * r + lineWidth / 2; + + core.strokeRoundRect(ctx, x, y, w, h, r, style, lineWidth); + core.fillText(ctx, text, x + r, y + lineWidth / 2 + 2, style, font); + + var todo = function () { + //debugger; + var id = getSelectedItem(); + let hideInfo = core.getFlag("hideInfo", {}); + console.log(id); + if (hideInfo.hasOwnProperty(id)) { + hideInfo[id] = !hideInfo[id]; + core.setFlag("hideInfo", hideInfo); + } else { + hideInfo[id] = !core.material.items[id].hideInToolbox; + core.setFlag("hideInfo", hideInfo); + } + if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); + else if (core.status.event.id === "equipbox") + core.plugin.drawEquipbox(); + }; + addUIEventListener(x, y, w, h, todo); + } + + ui.prototype.getToolboxItems = function (cls, showHide) { + let list = Object.keys(core.status.hero.items[cls] || {}); + if (cls === "all") { + for (let name in core.status.hero.items) { + if (name == "equips") continue; + list = list.concat(Object.keys(core.status.hero.items[name])); + } + if (!showHide) + list = list.filter(function (id2) { + const hideInfo = core.getFlag("hideInfo", {}); + if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; + else return !core.material.items[id2].hideInToolbox; + }); + list = list.sort(); + return list; + } + if (cls === "equips") { + if (!showHide) + list = list.filter(function (id2) { + const hideInfo = core.getFlag("hideInfo", {}); + if (hideInfo.hasOwnProperty(id2)) return !hideInfo[id2]; + else return !core.material.items[id2].hideInToolbox; + }); + + list = list.sort(); + return list; + } + if (this.uidata.getToolboxItems) { + return this.uidata.getToolboxItems(cls, showHide); + } + if (!showHide) + list = list.filter(function (id2) { + return !core.material.items[id2].hideInToolbox; + }); + list = list.sort(); + return list; }; - this.drawItemListbox_setPageBtn = function ( + function drawToolbox_setShowHideBtn(ctx, x, y, h, style) { + core.setTextAlign(ctx, "left"); + core.setTextBaseline(ctx, "top"); + var fontSize = h - 6; + var font = core.ui._buildFont(fontSize); + var text = "显示隐藏"; + var w = core.calWidth(ctx, text, font); + h += 4; + const squareSize = h - 6; + + x -= w + squareSize + 26; + + const border = 2; + core.fillRect(ctx, x, y, squareSize, squareSize, " #F5F5F5"); + if (core.hasFlag("showHideItem")) { + core.fillRect( + ctx, + x + border, + y + border, + squareSize - 2 * border, + squareSize - 2 * border, + "lime" + ); + } + core.fillText(ctx, text, x + squareSize + 2, y + 4, style, font); + + var todo = function () { + core.setFlag("showHideItem", !core.getFlag("showHideItem", false)); + if (core.status.event.id === "toolbox") core.plugin.drawToolbox(); + else if (core.status.event.id === "equipbox") + core.plugin.drawEquipbox(); + }; + addUIEventListener(x, y, w, h, todo); + } + + function drawItemListbox_setPageBtn( ctx, left, right, @@ -5717,7 +6788,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var todo = function () { core.addItemListboxPage(-1); }; - core.addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); + addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); x = right - offset; core.fillPolygon( @@ -5733,8 +6804,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var todo = function () { core.addItemListboxPage(1); }; - core.addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); - }; + addUIEventListener(x - r - 2, y - r - 2, r * 2 + 4, r * 2 + 4, todo); + } this.clickItemFunc = function (id) { var info = core.status.thisUIEventInfo; @@ -5743,7 +6814,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = info.select = {}; info.select.id = id; core.setIndexAndSelect("index"); - core.refreshBox(); + refreshBox(); }; this.clickOneEquipbox = function (id, type) { @@ -5757,31 +6828,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = type: type, action: "unload", }; - return core.refreshBox(); - }; - - core.ui.getToolboxItems = function (cls) { - var list = Object.keys(core.status.hero.items[cls] || {}); - if (cls == "all") { - for (var name in core.status.hero.items) { - if (name == "equips") continue; - list = list.concat(Object.keys(core.status.hero.items[name])); - } - return list - .filter(function (id) { - return !core.material.items[id].hideInToolbox; - }) - .sort(); - } - - if (this.uidata.getToolboxItems) { - return this.uidata.getToolboxItems(cls); - } - return list - .filter(function (id) { - return !core.material.items[id].hideInToolbox; - }) - .sort(); + return refreshBox(); }; this.useSelectItemInBox = function () { @@ -5800,43 +6847,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = let equipClsid = core.material.items[id]?.equipCls; let equipCls0 = core.material.items[core.getEquip(0)]?.equipCls; let equipCls1 = core.material.items[core.getEquip(1)]?.equipCls; - if (equipCls0 === "双手剑") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - } - if (equipClsid === "单手剑") { - if ( - equipCls1 !== "单手剑" && - equipCls1 !== "匕首" && - equipCls1 !== "盾牌" - ) { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } else if (equipCls0 !== "单手剑") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - } - } - if (equipClsid === "法杖") { - if (equipCls1 !== "匕首" && equipCls1 !== "盾牌") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } else { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - } - } if (equipClsid === "双手剑") { core.unloadEquip(0, function () { core.status.route.push("unEquip:" + 0); @@ -5845,33 +6855,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.status.route.push("unEquip:" + 1); }); } - if (equipClsid === "匕首") { - if (equipCls0 !== "匕首") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } else { - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } - } - if (equipClsid === "盾牌") { - if (equipCls0 !== "单手剑" && equipCls0 !== "法杖") { - core.unloadEquip(0, function () { - core.status.route.push("unEquip:" + 0); - }); - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } else { - core.unloadEquip(1, function () { - core.status.route.push("unEquip:" + 1); - }); - } + if ( + equipCls0 === "双手剑" && + !(equipClsid === "饰品" || equipClsid === "护具") + ) { + core.unloadEquip(0, function () { + core.status.route.push("unEquip:" + 0); + }); } core.loadEquip(id, function () { core.status.route.push("equip:" + id); @@ -5884,7 +6874,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.unloadEquip(type, function () { core.status.route.push("unEquip:" + type); info.select.type = type; - //info.select.action = 'load' + info.select.action = "load"; core.setIndexAndSelect("select"); core.drawEquipbox(); }); @@ -5892,28 +6882,18 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } core.updateStatusBar(); }; + this.setIndexAndSelect = function (toChange) { var info = core.status.thisUIEventInfo; if (!info) return; - core.setPageItems(info.page); + setPageItems(info.page); var index = info.index || 1; var items = info.pageItems; - if (info.select.type != null) { - var type = info.select.type; - id = core.getEquip(type); - info.index = null; - info.select = { - id: id, - action: "unload", - type: type, - }; - return; - } else { - info.select.action = null; - info.select.type = null; - if (toChange == "index") info.index = items.indexOf(info.select.id) + 1; - info.select.id = items[info.index - 1]; - } + + info.select.action = null; + info.select.type = null; + if (toChange == "index") info.index = items.indexOf(info.select.id) + 1; + info.select.id = items[info.index - 1]; }; this.addItemListboxPage = function (num) { @@ -5925,9 +6905,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (info.page <= 0) info.page = maxPage; if (info.page > maxPage) info.page = 1; info.index = 1; - core.setPageItems(info.page); + setPageItems(info.page); core.setIndexAndSelect("select"); - core.refreshBox(); + refreshBox(); }; this.addItemListboxIndex = function (num) { @@ -5939,7 +6919,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (info.index <= 0) info.index = 1; if (info.index > maxItem) info.index = maxItem; core.setIndexAndSelect("select"); - core.refreshBox(); + refreshBox(); }; this.addEquipboxType = function (num) { @@ -5956,7 +6936,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var m = Math.abs(info.select.type); if (info.select.type < 0) info.select.type = max - m; core.setIndexAndSelect("select"); - core.refreshBox(); + refreshBox(); return; } }; @@ -6020,7 +7000,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (info.index == 1) { info.select.type = core.status.globalAttribute.equipName.length - 1; core.setIndexAndSelect(); - return core.refreshBox(); + return refreshBox(); } if (info.index) return core.addItemListboxIndex(-1); return core.addEquipboxType(-1 * info.equips); @@ -6066,7 +7046,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = "inEventClickAction", function (x, y, px, py) { if (!core.status.thisEventClickArea) return false; - // console.log(px + "," + py); var info = core.status.thisEventClickArea; for (var i = 0; i < info.length; i++) { var obj = info[i]; @@ -6093,7 +7072,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 51 ); - this.addUIEventListener = function (x, y, width, height, todo) { + function addUIEventListener(x, y, width, height, todo) { if (!core.status.thisEventClickArea) return; var obj = { x: x, @@ -6103,7 +7082,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = todo: todo, }; core.status.thisEventClickArea.push(obj); - }; + } this.initThisEventInfo = function () { core.status.thisUIEventInfo = { @@ -6113,11 +7092,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.status.thisEventClickArea = []; }; - this.refreshBox = function () { + function refreshBox() { if (!core.status.event.id) return; if (core.status.event.id == "toolbox") core.drawToolbox(); else core.drawEquipbox(); - }; + } core.ui.closePanel = function () { if (core.status.hero && core.status.hero.flags) { @@ -6206,13 +7185,16 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.status.event.id = "toolbox"; core.initThisEventInfo(); var info = core.status.thisUIEventInfo; - var items = core.getToolboxItems("all"); - core.setPageItems(1); + var items = core.getToolboxItems( + "all", + core.getFlag("showHideItem", false) + ); + setPageItems(1); var index = items.indexOf(itemId) + 1; info.page = Math.ceil(index / info.maxItem); info.index = index % info.maxItem || info.maxItem; core.setIndexAndSelect("select"); - core.setPageItems(info.page); + setPageItems(info.page); core.drawToolbox(); setTimeout(function () { core.ui.closePanel(); @@ -6224,29 +7206,46 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.control._replayAction_equip = function (action) { if (action.indexOf("equip:") != 0) return false; var itemId = action.substring(6); - var items = core.getToolboxItems("equips"); + var items = core.getToolboxItems( + "equips", + core.getFlag("showHideItem", false) + ); var index = items.indexOf(itemId) + 1; - if (index < 1) return false; + if (index < 1) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } + + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); + } + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); + core.status.route.push(action); if ( core.material.items[itemId].hideInReplay || core.status.replay.speed == 24 ) { - core.loadEquip(itemId, core.replay); + core.loadEquip(itemId, cb); return true; } core.status.event.id = "equipbox"; core.initThisEventInfo(); var info = core.status.thisUIEventInfo; - core.setPageItems(1); + setPageItems(1); info.page = Math.ceil(index / info.maxItem); info.index = index % info.maxItem || info.maxItem; core.setIndexAndSelect("select"); - core.setPageItems(info.page); + setPageItems(info.page); core.drawEquipbox(); setTimeout(function () { core.ui.closePanel(); - core.loadEquip(itemId, core.replay); + core.loadEquip(itemId, cb); }, core.control.__replay_getTimeout()); return true; }; @@ -6254,26 +7253,39 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.control._replayAction_unEquip = function (action) { if (action.indexOf("unEquip:") != 0) return false; var equipType = parseInt(action.substring(8)); - if (!core.isset(equipType)) return false; + if (!core.isset(equipType)) { + core.removeFlag("__doNotCheckAutoEvents__"); + return false; + } + + var cb = function () { + var next = core.status.replay.toReplay[0] || ""; + if (!next.startsWith("equip:") && !next.startsWith("unEquip:")) { + core.removeFlag("__doNotCheckAutoEvents__"); + core.checkAutoEvents(); + } + core.replay(); + }; + core.setFlag("__doNotCheckAutoEvents__", true); + core.status.route.push(action); if (core.status.replay.speed == 24) { - core.unloadEquip(equipType, core.replay); + core.unloadEquip(equipType, cb); return true; } core.status.event.id = "equipbox"; core.initThisEventInfo(); var info = core.status.thisUIEventInfo; - core.setPageItems(1); + setPageItems(1); info.select.type = equipType; core.setIndexAndSelect(); core.drawEquipbox(); setTimeout(function () { core.ui.closePanel(); - core.unloadEquip(equipType, core.replay); + core.unloadEquip(equipType, cb); }, core.control.__replay_getTimeout()); return true; }; - core.registerReplayAction("item", core.control._replayAction_item); core.registerReplayAction("equip", core.control._replayAction_equip); core.registerReplayAction("unEquip", core.control._replayAction_unEquip); @@ -7323,51 +8335,46 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (main.replayChecking) return (core.plugin.animate = {}); var M = Object.defineProperty; - var E = (n, s, t) => - s in n - ? M(n, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) - : (n[s] = t); - var o = (n, s, t) => (E(n, typeof s != "symbol" ? s + "" : s, t), t); - let b = []; + var E = (n, i, t) => + i in n + ? M(n, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) + : (n[i] = t); + var o = (n, i, t) => (E(n, typeof i != "symbol" ? i + "" : i, t), t); + let w = []; const k = (n) => { - for (const s of b) - if (s.status === "running") + for (const i of w) + if (i.status === "running") try { - for (const t of s.funcs) t(n - s.startTime); + for (const t of i.funcs) t(n - i.startTime); } catch (t) { - s.destroy(), console.error(t); + i.destroy(), console.error(t); } requestAnimationFrame(k); }; requestAnimationFrame(k); class I { constructor() { - o(this, "funcs", []); + o(this, "funcs", /* @__PURE__ */ new Set()); o(this, "status", "stop"); o(this, "startTime", 0); (this.status = "running"), - b.push(this), - requestAnimationFrame((s) => (this.startTime = s)); + w.push(this), + requestAnimationFrame((i) => (this.startTime = i)); } - add(s, t = !1) { - return t ? this.funcs.unshift(s) : this.funcs.push(s), this; + add(i) { + return this.funcs.add(i), this; } - remove(s) { - const t = this.funcs.findIndex((e) => e === s); - if (t === -1) - throw new ReferenceError( - "You are going to remove nonexistent ticker function." - ); - return this.funcs.splice(t, 1), this; + remove(i) { + return this.funcs.delete(i), this; } clear() { - this.funcs = []; + this.funcs.clear(); } destroy() { this.clear(), this.stop(); } stop() { - (this.status = "stop"), (b = b.filter((s) => s !== this)); + (this.status = "stop"), (w = w.filter((i) => i !== this)); } } class F { @@ -7380,70 +8387,70 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = o(this, "ticker", new I()); o(this, "value", {}); o(this, "listener", {}); - this.timing = (s) => s; + this.timing = (i) => i; } async all() { - if (Object.values(this.applying).every((s) => s === !0)) + if (Object.values(this.applying).every((i) => i === !0)) throw new ReferenceError("There is no animates to be waited."); - await new Promise((s) => { + await new Promise((i) => { const t = () => { Object.values(this.applying).every((e) => e === !1) && - (this.unlisten("end", t), s("all animated.")); + (this.unlisten("end", t), i("all animated.")); }; this.listen("end", t); }); } - async n(s) { - const t = Object.values(this.applying).filter((i) => i === !0).length; - if (t < s) + async n(i) { + const t = Object.values(this.applying).filter((s) => s === !0).length; + if (t < i) throw new ReferenceError( - `You are trying to wait ${s} animate, but there are only ${t} animate animating.` + `You are trying to wait ${i} animate, but there are only ${t} animate animating.` ); let e = 0; - await new Promise((i) => { + await new Promise((s) => { const r = () => { - e++, e === s && (this.unlisten("end", r), i(`${s} animated.`)); + e++, e === i && (this.unlisten("end", r), s(`${i} animated.`)); }; this.listen("end", r); }); } - async w(s) { - if (this.applying[s] === !1) - throw new ReferenceError(`The ${s} animate is not animating.`); + async w(i) { + if (this.applying[i] === !1) + throw new ReferenceError(`The ${i} animate is not animating.`); await new Promise((t) => { const e = () => { - this.applying[s] === !1 && - (this.unlisten("end", e), t(`${s} animated.`)); + this.applying[i] === !1 && + (this.unlisten("end", e), t(`${i} animated.`)); }; this.listen("end", e); }); } - listen(s, t) { - var e, i; - (i = (e = this.listener)[s]) != null || (e[s] = []), - this.listener[s].push(t); + listen(i, t) { + var e, s; + (s = (e = this.listener)[i]) != null || (e[i] = []), + this.listener[i].push(t); } - unlisten(s, t) { - const e = this.listener[s].findIndex((i) => i === t); + unlisten(i, t) { + const e = this.listener[i].findIndex((s) => s === t); if (e === -1) throw new ReferenceError( "You are trying to remove a nonexistent listener." ); - this.listener[s].splice(e, 1); + this.listener[i].splice(e, 1); } - hook(...s) { - const t = Object.entries(this.listener).filter((e) => s.includes(e[0])); - for (const [e, i] of t) for (const r of i) r(this, e); + hook(...i) { + const t = Object.entries(this.listener).filter((e) => i.includes(e[0])); + for (const [e, s] of t) for (const r of s) r(this, e); } } - function T(n) { + function y(n) { return n != null; } async function R(n) { - return new Promise((s) => setTimeout(s, n)); + return new Promise((i) => setTimeout(i, n)); } - class Y extends F { + class j extends F { constructor() { super(); o(this, "shakeTiming"); @@ -7491,7 +8498,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }), this.ticker.add(() => { const { running: t } = this.listener; - if (T(t)) for (const e of t) e(this, "running"); + if (y(t)) for (const e of t) e(this, "running"); }); } get x() { @@ -7550,58 +8557,58 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = shake(t, e) { this.applying.shake === !0 && this.end(!0, "shake"), (this.applying.shake = !0); - const { easeTime: i, shakeTiming: r } = this, - h = this.getTime(); - if ((this.hook("start", "shakestart"), i <= 0)) + const { easeTime: s, shakeTiming: r } = this, + l = this.getTime(); + if ((this.hook("start", "shakestart"), s <= 0)) return this.end(!1, "shake"), this; - const l = () => { - const c = this.getTime() - h; - if (c > i) { - this.ticker.remove(l), + const a = () => { + const c = this.getTime() - l; + if (c > s) { + this.ticker.remove(a), (this.applying.shake = !1), (this.sx = 0), (this.sy = 0), this.hook("end", "shakeend"); return; } - const a = c / i, - m = r(a); + const h = c / s, + m = r(h); (this.sx = m * t), (this.sy = m * e); }; - return this.ticker.add(l), (this.animateFn.system.shake = l), this; + return this.ticker.add(a), (this.animateFn.system.shake = a), this; } moveAs(t) { this.applying.moveAs && this.end(!0, "moveAs"), (this.applying.moveAs = !0), (this.path = t); - const { easeTime: e, relation: i, timing: r } = this, - h = this.getTime(), - [l, u] = [this.x, this.y], - [c, a] = (() => { - if (i === "absolute") return t(1); + const { easeTime: e, relation: s, timing: r } = this, + l = this.getTime(), + [a, u] = [this.x, this.y], + [c, h] = (() => { + if (s === "absolute") return t(1); { const [d, f] = t(1); - return [l + d, u + f]; + return [a + d, u + f]; } })(); if ((this.hook("start", "movestart"), e <= 0)) return this.end(!1, "moveAs"), this; const m = () => { - const f = this.getTime() - h; + const f = this.getTime() - l; if (f > e) { this.end(!0, "moveAs"); return; } - const v = f / e, - [g, w] = t(r(v)); - i === "absolute" - ? ((this.ox = g), (this.oy = w)) - : ((this.ox = l + g), (this.oy = u + w)); + const g = f / e, + [v, x] = t(r(g)); + s === "absolute" + ? ((this.ox = v), (this.oy = x)) + : ((this.ox = a + v), (this.oy = u + x)); }; return ( - this.ticker.add(m, !0), + this.ticker.add(m), (this.animateFn.system.moveAs = m), - (this.targetValue.system.moveAs = [c, a]), + (this.targetValue.system.moveAs = [c, h]), this ); } @@ -7613,97 +8620,97 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); (this.value[t] = e), (this.applying[t] = !1); } - apply(t, e, i = !1) { + apply(t, e) { this.applying[t] === !0 && this.end(!1, t), t in this.value || this.error(`You are trying to execute nonexistent property ${t}.`), (this.applying[t] = !0); - const r = this.value[t], - h = this.getTime(), - { timing: l, relation: u, easeTime: c } = this, - a = u === "absolute" ? e - r : e; - if ((this.hook("start"), c <= 0)) return this.end(!1, t), this; - const m = () => { - const f = this.getTime() - h; - if (f > c) { + const s = this.value[t], + r = this.getTime(), + { timing: l, relation: a, easeTime: u } = this, + c = a === "absolute" ? e - s : e; + if ((this.hook("start"), u <= 0)) return this.end(!1, t), this; + const h = () => { + const d = this.getTime() - r; + if (d > u) { this.end(!1, t); return; } - const v = f / c, - g = l(v); - this.value[t] = r + g * a; + const f = d / u, + g = l(f); + this.value[t] = s + g * c; }; return ( - this.ticker.add(m, i), - (this.animateFn.custom[t] = m), - (this.targetValue.custom[t] = a + r), + this.ticker.add(h), + (this.animateFn.custom[t] = h), + (this.targetValue.custom[t] = c + s), this ); } - applyMulti(t = !1) { + applyMulti() { this.applying["@@bind"] === !0 && this.end(!1, "@@bind"), (this.applying["@@bind"] = !0); - const e = this.bindInfo, - i = e.map((m) => this.value[m]), - r = this.getTime(), - { multiTiming: h, relation: l, easeTime: u } = this, - c = h(1); - if (c.length !== i.length) + const t = this.bindInfo, + e = t.map((h) => this.value[h]), + s = this.getTime(), + { multiTiming: r, relation: l, easeTime: a } = this, + u = r(1); + if (u.length !== e.length) throw new TypeError( - `The number of binded animate attributes and timing function returns's length does not match. binded: ${e.length}, timing: ${c.length}` + `The number of binded animate attributes and timing function returns's length does not match. binded: ${t.length}, timing: ${u.length}` ); - if ((this.hook("start"), u <= 0)) return this.end(!1, "@@bind"), this; - const a = () => { - const d = this.getTime() - r; - if (d > u) { + if ((this.hook("start"), a <= 0)) return this.end(!1, "@@bind"), this; + const c = () => { + const m = this.getTime() - s; + if (m > a) { this.end(!1, "@@bind"); return; } - const f = d / u, - v = h(f); - e.forEach((g, w) => { + const d = m / a, + f = r(d); + t.forEach((g, v) => { l === "absolute" - ? (this.value[g] = v[w]) - : (this.value[g] = i[w] + v[w]); + ? (this.value[g] = f[v]) + : (this.value[g] = e[v] + f[v]); }); }; return ( - this.ticker.add(a, t), - (this.animateFn.custom["@@bind"] = a), - (this.targetValue.system["@@bind"] = c), + this.ticker.add(c), + (this.animateFn.custom["@@bind"] = c), + (this.targetValue.system["@@bind"] = u), this ); } - applySys(t, e, i) { - i !== "move" && this.applying[i] === !0 && this.end(!0, i), - (this.applying[i] = !0); + applySys(t, e, s) { + s !== "move" && this.applying[s] === !0 && this.end(!0, s), + (this.applying[s] = !0); const r = this[t], - h = this.getTime(), - l = this.timing, + l = this.getTime(), + a = this.timing, u = this.relation, c = this.easeTime, - a = u === "absolute" ? e - r : e; - if ((this.hook("start", `${i}start`), c <= 0)) return this.end(!1, i); + h = u === "absolute" ? e - r : e; + if ((this.hook("start", `${s}start`), c <= 0)) return this.end(!0, s); const m = () => { - const f = this.getTime() - h; + const f = this.getTime() - l; if (f > c) { - this.end(!0, i); + this.end(!0, s); return; } - const v = f / c, - g = l(v); - (this[t] = r + a * g), t !== "oy" && this.hook(i); + const g = f / c, + v = a(g); + (this[t] = r + h * v), t !== "oy" && this.hook(s); }; - this.ticker.add(m, !0), + this.ticker.add(m), t === "ox" ? (this.animateFn.system.move[0] = m) : t === "oy" ? (this.animateFn.system.move[1] = m) - : (this.animateFn.system[i] = m), - i === "move" - ? (t === "ox" && (this.targetValue.system.move[0] = a + r), - t === "oy" && (this.targetValue.system.move[1] = a + r)) - : i !== "shake" && (this.targetValue.system[i] = a + r); + : (this.animateFn.system[s] = m), + s === "move" + ? (t === "ox" && (this.targetValue.system.move[0] = h + r), + t === "oy" && (this.targetValue.system.move[1] = h + r)) + : s !== "shake" && (this.targetValue.system[s] = h + r); } error(t, e) { throw e === "repeat" @@ -7726,11 +8733,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = : this.ticker.remove(this.animateFn.system[e]), e === "move") ) { - const [i, r] = this.targetValue.system.move; - (this.ox = i), (this.oy = r), this.hook("moveend", "end"); + const [s, r] = this.targetValue.system.move; + (this.ox = s), (this.oy = r), this.hook("moveend", "end"); } else if (e === "moveAs") { - const [i, r] = this.targetValue.system.moveAs; - (this.ox = i), (this.oy = r), this.hook("moveend", "end"); + const [s, r] = this.targetValue.system.moveAs; + (this.ox = s), (this.oy = r), this.hook("moveend", "end"); } else e === "rotate" ? ((this.angle = this.targetValue.system.rotate), @@ -7739,8 +8746,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ? ((this.size = this.targetValue.system.resize), this.hook("resizeend", "end")) : e === "@@bind" - ? this.bindInfo.forEach((r, h) => { - this.value[r] = this.targetValue.system["@@bind"][h]; + ? this.bindInfo.forEach((r, l) => { + this.value[r] = this.targetValue.system["@@bind"][l]; }) : ((this.sx = 0), (this.sy = 0), this.hook("shakeend", "end")); else @@ -7750,14 +8757,14 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = this.hook("end"); } } - class j extends F { + class O extends F { constructor() { super(); o(this, "now", {}); o(this, "target", {}); o(this, "transitionFn", {}); o(this, "value"); - o(this, "handleSet", (t, e, i) => (this.transition(e, i), !0)); + o(this, "handleSet", (t, e, s) => (this.transition(e, s), !0)); o(this, "handleGet", (t, e) => this.now[e]); (this.timing = (t) => t), (this.value = new Proxy(this.target, { @@ -7779,34 +8786,35 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } transition(t, e) { if (e === this.target[t]) return this; - if (!T(this.now[t])) return (this.now[t] = e), this; + if (!y(this.now[t])) return (this.now[t] = e), this; this.applying[t] && this.end(t, !0), (this.applying[t] = !0), this.hook("start"); - const i = this.getTime(), + const s = this.getTime(), r = this.easeTime, - h = this.timing, - l = this.now[t], - u = e + (this.relation === "absolute" ? 0 : l), - c = u - l; + l = this.timing, + a = this.now[t], + u = e + (this.relation === "absolute" ? 0 : a), + c = u - a; this.target[t] = u; - const a = () => { - const d = this.getTime() - i; + const h = () => { + const d = this.getTime() - s; if (d >= r) { this.end(t); return; } const f = d / r; - (this.now[t] = h(f) * c + l), this.hook("running"); + (this.now[t] = l(f) * c + a), this.hook("running"); }; return ( - (this.transitionFn[t] = a), - r <= 0 ? (this.end(t), this) : (this.ticker.add(a), this) + (this.transitionFn[t] = h), + this.ticker.add(h), + r <= 0 ? (this.end(t), this) : this ); } end(t, e = !1) { - const i = this.transitionFn[t]; - if (!T(i)) + const s = this.transitionFn[t]; + if (!y(s)) throw new ReferenceError( `You are trying to end an ended transition: ${t}` ); @@ -7817,146 +8825,145 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = e || (this.now[t] = this.target[t]); } } - const x = (...n) => n.reduce((s, t) => s + t, 0), - y = (n) => { + const T = (...n) => n.reduce((i, t) => i + t, 0), + b = (n) => { if (n === 0) return 1; - let s = n; - for (; n > 1; ) n--, (s *= n); - return s; + let i = n; + for (; n > 1; ) n--, (i *= n); + return i; }, - A = (n, s) => Math.round(y(s) / (y(n) * y(s - n))), - p = (n, s, t = (e) => 1 - s(1 - e)) => + A = (n, i) => Math.round(b(i) / (b(n) * b(i - n))), + p = (n, i, t = (e) => 1 - i(1 - e)) => n === "in" - ? s + ? i : n === "out" ? t : n === "in-out" - ? (e) => (e < 0.5 ? s(e * 2) / 2 : 0.5 + t((e - 0.5) * 2) / 2) - : (e) => (e < 0.5 ? t(e * 2) / 2 : 0.5 + s((e - 0.5) * 2) / 2), + ? (e) => (e < 0.5 ? i(e * 2) / 2 : 0.5 + t((e - 0.5) * 2) / 2) + : (e) => (e < 0.5 ? t(e * 2) / 2 : 0.5 + i((e - 0.5) * 2) / 2), $ = Math.cosh(2), z = Math.acosh(2), V = Math.tanh(3), P = Math.atan(5); - function O() { + function Y() { return (n) => n; } function q(...n) { - const s = [0].concat(n); - s.push(1); - const t = s.length, + const i = [0].concat(n); + i.push(1); + const t = i.length, e = Array(t) .fill(0) - .map((i, r) => A(r, t - 1)); - return (i) => { - const r = e.map((h, l) => h * s[l] * (1 - i) ** (t - l - 1) * i ** l); - return x(...r); + .map((s, r) => A(r, t - 1)); + return (s) => { + const r = e.map((l, a) => l * i[a] * (1 - s) ** (t - a - 1) * s ** a); + return T(...r); }; } - function U(n, s) { + function U(n, i) { if (n === "sin") { - const t = (i) => Math.sin((i * Math.PI) / 2); - return p(s, (i) => 1 - t(1 - i), t); + const t = (s) => Math.sin((s * Math.PI) / 2); + return p(i, (s) => 1 - t(1 - s), t); } if (n === "sec") { - const t = (i) => 1 / Math.cos(i); - return p(s, (i) => t((i * Math.PI) / 3) - 1); + const t = (s) => 1 / Math.cos(s); + return p(i, (s) => t((s * Math.PI) / 3) - 1); } throw new TypeError( "Unexpected parameters are delivered in trigo timing function." ); } - function C(n, s) { + function C(n, i) { if (!Number.isInteger(n)) throw new TypeError( "The first parameter of power timing function only allow integer." ); - return p(s, (e) => e ** n); + return p(i, (e) => e ** n); } - function G(n, s) { - if (n === "sin") return p(s, (e) => (Math.cosh(e * 2) - 1) / ($ - 1)); + function G(n, i) { + if (n === "sin") return p(i, (e) => (Math.cosh(e * 2) - 1) / ($ - 1)); if (n === "tan") { - const t = (i) => (Math.tanh(i * 3) * 1) / V; - return p(s, (i) => 1 - t(1 - i), t); + const t = (s) => (Math.tanh(s * 3) * 1) / V; + return p(i, (s) => 1 - t(1 - s), t); } if (n === "sec") { - const t = (i) => 1 / Math.cosh(i); - return p(s, (i) => 1 - (t(i * z) - 0.5) * 2); + const t = (s) => 1 / Math.cosh(s); + return p(i, (s) => 1 - (t(s * z) - 0.5) * 2); } throw new TypeError( "Unexpected parameters are delivered in hyper timing function." ); } - function N(n, s) { + function N(n, i) { if (n === "sin") { - const t = (i) => (Math.asin(i) / Math.PI) * 2; - return p(s, (i) => 1 - t(1 - i), t); + const t = (s) => (Math.asin(s) / Math.PI) * 2; + return p(i, (s) => 1 - t(1 - s), t); } if (n === "tan") { - const t = (i) => Math.atan(i * 5) / P; - return p(s, (i) => 1 - t(1 - i), t); + const t = (s) => Math.atan(s * 5) / P; + return p(i, (s) => 1 - t(1 - s), t); } throw new TypeError( "Unexpected parameters are delivered in inverse trigo timing function." ); } - function B(n, s = () => 1) { + function B(n, i = () => 1) { let t = -1; return (e) => ( - (t *= -1), e < 0.5 ? n * s(e * 2) * t : n * s((1 - e) * 2) * t + (t *= -1), e < 0.5 ? n * i(e * 2) * t : n * i((1 - e) * 2) * t ); } - function D(n, s = 1, t = [0, 0], e = 0, i = (h) => 1, r = !1) { - return (h) => { - const l = s * h * Math.PI * 2 + (e * Math.PI) / 180, - u = Math.cos(l), - c = Math.sin(l), - a = n * i(i(r ? 1 - h : h)); - return [a * u + t[0], a * c + t[1]]; + function D(n, i = 1, t = [0, 0], e = 0, s = (l) => 1, r = !1) { + return (l) => { + const a = i * l * Math.PI * 2 + (e * Math.PI) / 180, + u = Math.cos(a), + c = Math.sin(a), + h = n * s(s(r ? 1 - l : l)); + return [h * u + t[0], h * c + t[1]]; }; } - function H(n, s, ...t) { + function H(n, i, ...t) { const e = [n].concat(t); - e.push(s); - const i = e.length, - r = Array(i) + e.push(i); + const s = e.length, + r = Array(s) .fill(0) - .map((h, l) => A(l, i - 1)); - return (h) => { - const l = r.map( - (c, a) => c * e[a][0] * (1 - h) ** (i - a - 1) * h ** a + .map((l, a) => A(a, s - 1)); + return (l) => { + const a = r.map( + (c, h) => c * e[h][0] * (1 - l) ** (s - h - 1) * l ** h ), - u = r.map((c, a) => c * e[a][1] * (1 - h) ** (i - a - 1) * h ** a); - return [x(...l), x(...u)]; + u = r.map((c, h) => c * e[h][1] * (1 - l) ** (s - h - 1) * l ** h); + return [T(...a), T(...u)]; }; } - if ("animate" in core.plugin) throw new ReferenceError(`插件中已存在名为animate的属性!`); core.plugin.animate = { - Animation: Y, + Animation: j, AnimationBase: F, Ticker: I, - Transition: j, - sleep: R, - circle: D, - bezierPath: H, - linear: O, + Transition: O, bezier: q, - trigo: U, - power: C, + bezierPath: H, + circle: D, hyper: G, - inverseTrigo: N, + linear: Y, + power: C, shake: B, + sleep: R, + trigo: U, + inverseTrigo: N, }; }, "func": function () { @@ -7985,7 +8992,42 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = return arr; } } + /** + * 图片叠加滤镜 + * @param {img} image 需要叠加的图片, + * @param {color} style 需要叠加的颜色 + */ + function imagelighter(image, style) { + // 创建一个canvas元素 + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + // 设置canvas的尺寸与图片相同 + canvas.width = image.width; + canvas.height = image.height; + ctx.drawImage(image, 0, 0); + // 创建一个临时canvas用于红色滤镜 + const tempCanvas = document.createElement("canvas"); + const tempCtx = tempCanvas.getContext("2d"); + tempCanvas.width = image.width; + tempCanvas.height = image.height; + + // 在临时canvas上绘制红色滤镜 + tempCtx.fillStyle = style ?? "rgba(255, 0, 0, 0.5)"; // 半透明红色 + tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height); + // 使用lighter混合模式叠加红色滤镜 + ctx.globalCompositeOperation = "lighter"; + ctx.drawImage(tempCanvas, 0, 0); + // 使用destination-in混合模式保留原始图片的透明度 + ctx.globalCompositeOperation = "destination-in"; + ctx.drawImage(image, 0, 0); + + // 恢复默认混合模式 + ctx.globalCompositeOperation = "source-over"; + + // 返回处理后的canvas + return canvas; + } /** * 获取一个方向的反方向 * @example backDir('up'); // 'down' @@ -8339,6 +9381,35 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = yellowgreen: "#9acd32", transparent: "#0000", }; + // 计算两个数的最大公约数 + function gcdOfTwo(a, b) { + while (b !== 0) { + let temp = b; + b = a % b; + a = temp; + } + return a; + } + + // 计算任意项整数的最大公约数 + function gcd(...numbers) { + if (numbers.length < 2) { + throw new Error("至少需要两个数"); + } + return numbers.reduce((a, b) => gcdOfTwo(a, b)); + } + // 计算两个数的最小公倍数 + function lcmOfTwo(a, b) { + return (a * b) / gcdOfTwo(a, b); + } + + // 计算任意项整数的最小公倍数 + function lcm(...numbers) { + if (numbers.length < 2) { + throw new Error("至少需要两个数"); + } + return numbers.reduce((a, b) => lcmOfTwo(a, b)); + } if (has(core.plugin.utils)) { throw new ReferenceError( @@ -8346,6 +9417,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); } core.plugin.utils = { + imagelighter, + gcdOfTwo, + lcmOfTwo, + gcd, + lcm, has, slide, backDir, @@ -8399,266 +9475,2109 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } }; }, - "怪物碎裂特效": function () { + "音频系统": function () { // 在此增加新插件 - // -------------------- 安装说明 -------------------- // - // 先安装两个在插件简介中说明的前置插件 - // 然后再将本插件复制到插件编写中即可 - // 插件自带一个打怪后显示碎裂特效的功能 - // -------------------- 使用说明 -------------------- // - /* + /*首先,在造塔群下载所需的库文件,然后放置在塔目录下的 libs/thirdparty 或其他目录下,之后在 index.html 的最后加上下面这几行: + + - 本插件的核心是一个名为 applyFragWith 的函数,打怪后的碎裂特效也是由它执行的。 - 我们来说明一下这个函数的使用方式。 - 1. 引入 - 你可以使用 const { applyFragWith } = core.plugin.frag; 在任何地方来引入这个函数。 - - 2. 函数的参数 - 该函数有三个参数,分别是canvas, length, time。 - 其中,第一个参数意思是,在执行碎裂时,其内容由该画布决定,这个特效并不会修改传入的画布,因此原画布的内容会依然存在 - 第二个参数指的是每个碎片的边长,虽然原则上每个碎片都是正方形,但边缘一周的碎片可能不是正方形,但中间的碎片一定是 - 第三个参数指的是这个特效要执行多长时间 - 第四个参数是一个对象,包含四种配置量,均为可选,分别是maxMoveLength,moveFlush,maxRotate,fragTiming - 当这些不存在时会默认取同名的常量作为默认值。这些值有什么用可以看下面的常量注释。 - - 3. 函数的返回值 - 这个函数会返回一个特效控制器对象,这个控制器共有三个属性。 - animation: 指的是当前特效的高级动画对象 - onEnd: 一个Promise,当这个特效执行完毕后会被 fulfilled - canvas: 特效所显示的画布。这个画布不会自动部署到样板中,需要你手动使用appendChild来部署,具体可参考打怪后碎裂的样例 - - 4. 修改一些常量 - 在下面有四个有注释的常量MAX_MOVE_LENGTH ~ FRAG_TIMING,你可以根据你自己的需要来更改。 + + */ + // 将__enable置为false将关闭插件 + let __enable = true; + if (!__enable || main.mode === "editor") return; + const { OggOpusDecoderWebWorker } = window["ogg-opus-decoder"]; + const { OggVorbisDecoderWebWorker } = window["ogg-vorbis-decoder"]; + const { CodecParser } = window.CodecParser; + const { Transition, linear } = core.plugin.animate; - if (main.replayChecking) return (core.plugin.frag = {}); - - const { Animation, linear, sleep } = core.plugin.animate; - const { has } = core.plugin.utils; - - /** 最大移动距离,最终位置距离中心的距离变成原来的几倍 */ - const MAX_MOVE_LENGTH = 1.15; - /** 移动距离波动,在最大移动距离的基础上加上多少倍距离的波动距离 */ - const MOVE_FLUSH = 0.7; - /** 最大旋转角,单位是弧度,每个碎片都会有自己的旋转程度,是随机的 */ - const MAX_ROTATE = 0.5; - /** 碎裂动画的速率曲线函数 */ - const FRAG_TIMING = linear(); - + const audio = new Audio(); + const AudioStatus = { + Playing: 0, + Pausing: 1, + Paused: 2, + Stoping: 3, + Stoped: 4, + }; + const supportMap = new Map(); + const AudioType = { + Mp3: "audio/mpeg", + Wav: 'audio/wav; codecs="1"', + Flac: "audio/flac", + Opus: 'audio/ogg; codecs="opus"', + Ogg: 'audio/ogg; codecs="vorbis"', + Aac: "audio/aac", + }; /** - * @param {HTMLCanvasElement} canvas 要执行特效的画布 - * @param {number} length 切分成的碎片的边长,碎片为正方形 - * @param {number} time 特效持续时长 - * @returns 返回一个碎裂特效控制器,是一个对象,详见开头的使用注释 + * 检查一种音频类型是否能被播放 + * @param type 音频类型 AudioType */ - function applyFragWith(canvas, length = 4, time = 2000, config = {}) { - // 先切分图片 - const imgs = splitCanvas(canvas, length); - const cx = canvas.width / 2; - const cy = canvas.height / 2; - - let maxX = 0; - let maxY = 0; - const toMove = imgs.map((v) => { - const centerX = v.x + v.canvas.width / 2; - const centerY = v.y + v.canvas.height / 2; - const onX = centerX === cx; - const onY = centerY === cy; - const mml = config.maxMoveLength ?? MAX_MOVE_LENGTH; - const mf = config.moveFlush ?? MOVE_FLUSH; - const rate = mml - 1 + Math.random() ** 3 * mf; - let endX = onY ? 0 : (centerX - cx) * rate; - let endY = onX ? 0 : (centerY - cy) * rate; - const mx = Math.abs(endX + centerX) + Math.abs(v.canvas.width); - const my = Math.abs(endY + centerY) + Math.abs(v.canvas.height); - if (mx > maxX) maxX = mx; - if (my > maxY) maxY = my; - const r = config.maxRotate ?? MAX_ROTATE; - const endRad = Math.random() * r * 2 - r; - - return { - deltaX: endX, - deltaY: endY, - endRad, - x: centerX, - y: centerY, - canvas: v.canvas, - }; - }); - - // 再执行动画 - const frag = document.createElement("canvas"); - const ctx = frag.getContext("2d"); - const ani = new Animation(); - ani.register("rate", 0); - const ft = config.fragTiming ?? FRAG_TIMING; - ani.absolute().time(time).mode(ft).apply("rate", 1); - frag.width = maxX * 2; - frag.height = maxY * 2; - ctx.save(); - const dw = maxX - canvas.width / 2; - const dh = maxY - canvas.height / 2; - - const fragFn = () => { - const rate = ani.value.rate; - const opacity = 1 - rate; - ctx.globalAlpha = opacity; - ctx.clearRect(0, 0, frag.width, frag.height); - toMove.forEach((v) => { - ctx.save(); - const nx = v.deltaX * rate; - const ny = v.deltaY * rate; - const rotate = v.endRad * rate; - - ctx.translate(nx + v.x + dw, ny + v.y + dh); - ctx.rotate(rotate); - ctx.drawImage( - v.canvas, - nx - v.canvas.width / 2, - ny - v.canvas.height / 2 - ); - ctx.restore(); - }); - }; - const onEnd = () => {}; - ani.ticker.add(fragFn); - - return makeFragManager(frag, ani, time, onEnd); - } - - function makeFragManager(canvas, ani, time, onEnd) { - const promise = sleep(time + 50); - - return { - animation: ani, - onEnd: promise.then(() => { - ani.ticker.destroy(); - onEnd(); - }), - canvas, - }; - } - - function withImage(image, sx, sy, sw, sh) { - const canvas = document.createElement("canvas"); - const ctx = canvas.getContext("2d"); - canvas.width = sw; - canvas.height = sh; - ctx.drawImage(image, sx, sy, sw, sh, 0, 0, sw, sh); - return { canvas, x: sx, y: sy }; - } - - /** - * 切分画布 - * @param canvas 要被切分的画布 - * @param l 切分小块的边长 - */ - function splitCanvas(canvas, l) { - if (canvas.width / l < 2 || canvas.height / l < 2) { - console.warn("切分画布要求切分边长大于等于画布长宽的一半!"); - return []; + function isAudioSupport(type) { + if (supportMap.has(type)) return supportMap.get(type); + else { + const support = audio.canPlayType(type); + const canPlay = support === "maybe" || support === "probably"; + supportMap.set(type, canPlay); + return canPlay; } - const w = canvas.width; - const h = canvas.height; - const numX = Math.floor(w / l); - const numY = Math.floor(h / l); - const rw = (w - numX * l) / 2; - const rh = (h - numY * l) / 2; + } - const res = []; + const typeMap = new Map([ + ["ogg", AudioType.Ogg], + ["mp3", AudioType.Mp3], + ["wav", AudioType.Wav], + ["flac", AudioType.Flac], + ["opus", AudioType.Opus], + ["aac", AudioType.Aac], + ]); - if (rw > 0) { - if (rh > 0) { - res.push( - withImage(canvas, 0, 0, rw, rh), - withImage(canvas, 0, canvas.height - rh, rw, rh), - withImage(canvas, canvas.width - rw, 0, rw, rh), - withImage(canvas, canvas.width - rw, canvas.height - rh, rw, rh) - ); - } - for (const x of [0, canvas.width - rw]) { - for (let ny = 0; ny < numY; ny++) { - res.push(withImage(canvas, x, rh + l * ny, rw, l)); + /** + * 根据文件名拓展猜测其类型 + * @param file 文件名 string + */ + function guessTypeByExt(file) { + const ext = /\.[a-zA-Z\d]+$/.exec(file); + if (!ext?.[0]) return ""; + const type = ext[0].slice(1); + return typeMap.get(type.toLocaleLowerCase()) ?? ""; + } + + isAudioSupport(AudioType.Ogg); + isAudioSupport(AudioType.Mp3); + isAudioSupport(AudioType.Wav); + isAudioSupport(AudioType.Flac); + isAudioSupport(AudioType.Opus); + isAudioSupport(AudioType.Aac); + + function isNil(value) { + return value === void 0 || value === null; + } + + function sleep(time) { + return new Promise((res) => setTimeout(res, time)); + } + class AudioEffect { + constructor(ac) {} + /** + * 连接至其他效果器 + * @param target 目标输入 IAudioInput + * @param output 当前效果器输出通道 Number + * @param input 目标效果器的输入通道 Number + */ + connect(target, output, input) { + this.output.connect(target.input, output, input); + } + + /** + * 与其他效果器取消连接 + * @param target 目标输入 IAudioInput + * @param output 当前效果器输出通道 Number + * @param input 目标效果器的输入通道 Number + */ + disconnect(target, output, input) { + if (!target) { + if (!isNil(output)) { + this.output.disconnect(output); + } else { + this.output.disconnect(); + } + } else { + if (!isNil(output)) { + if (!isNil(input)) { + this.output.disconnect(target.input, output, input); + } else { + this.output.disconnect(target.input, output); + } + } else { + this.output.disconnect(target.input); } } } - if (rh > 0) { - for (const y of [0, canvas.height - rh]) { - for (let nx = 0; nx < numX; nx++) { - res.push(withImage(canvas, rw + l * nx, y, l, rh)); + } + + class StereoEffect extends AudioEffect { + constructor(ac) { + super(ac); + const panner = ac.createPanner(); + this.input = panner; + this.output = panner; + } + + /** + * 设置音频朝向,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 朝向x坐标 Number + * @param y 朝向y坐标 Number + * @param z 朝向z坐标 Number + */ + setOrientation(x, y, z) { + this.output.orientationX.value = x; + this.output.orientationY.value = y; + this.output.orientationZ.value = z; + } + /** + * 设置音频位置,x正方形水平向右,y正方形垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 位置x坐标 Number + * @param y 位置y坐标 Number + * @param z 位置z坐标 Number + */ + setPosition(x, y, z) { + this.output.positionX.value = x; + this.output.positionY.value = y; + this.output.positionZ.value = z; + } + end() {} + + start() {} + } + class VolumeEffect extends AudioEffect { + constructor(ac) { + super(ac); + const gain = ac.createGain(); + this.input = gain; + this.output = gain; + } + + /** + * 设置音量大小 + * @param volume 音量大小 Number + */ + setVolume(volume) { + this.output.gain.value = volume; + } + + /** + * 获取音量大小 Number + */ + getVolume() { + return this.output.gain.value; + } + + end() {} + + start() {} + } + class ChannelVolumeEffect extends AudioEffect { + /** 所有的音量控制节点 */ + + constructor(ac) { + super(ac); + /** 所有的音量控制节点 */ + this.gain = []; + const splitter = ac.createChannelSplitter(); + const merger = ac.createChannelMerger(); + this.output = merger; + this.input = splitter; + for (let i = 0; i < 6; i++) { + const gain = ac.createGain(); + splitter.connect(gain, i); + gain.connect(merger, 0, i); + this.gain.push(gain); + } + } + + /** + * 设置某个声道的音量大小 + * @param channel 要设置的声道,可填0-5 Number + * @param volume 这个声道的音量大小 Number + */ + setVolume(channel, volume) { + if (!this.gain[channel]) return; + this.gain[channel].gain.value = volume; + } + + /** + * 获取某个声道的音量大小,可填0-5 + * @param channel 要获取的声道 Number + */ + getVolume(channel) { + if (!this.gain[channel]) return 0; + return this.gain[channel].gain.value; + } + + end() {} + + start() {} + } + class DelayEffect extends AudioEffect { + constructor(ac) { + super(ac); + + const delay = ac.createDelay(); + this.input = delay; + this.output = delay; + } + + /** + * 设置延迟时长 + * @param delay 延迟时长,单位秒 Number + */ + setDelay(delay) { + this.output.delayTime.value = delay; + } + + /** + * 获取延迟时长 + */ + getDelay() { + return this.output.delayTime.value; + } + + end() {} + + start() {} + } + class EchoEffect extends AudioEffect { + constructor(ac) { + super(ac); + /** 当前增益 */ + this.gain = 0.5; + /** 是否正在播放 */ + this.playing = false; + const delay = ac.createDelay(); + const gain = ac.createGain(); + gain.gain.value = 0.5; + delay.delayTime.value = 0.05; + delay.connect(gain); + gain.connect(delay); + /** 延迟节点 */ + this.delay = delay; + /** 反馈增益节点 */ + this.gainNode = gain; + + this.input = gain; + this.output = gain; + } + + /** + * 设置回声反馈增益大小 + * @param gain 增益大小,范围 0-1,大于等于1的视为0.5,小于0的视为0 Number + */ + setFeedbackGain(gain) { + const resolved = gain >= 1 ? 0.5 : gain < 0 ? 0 : gain; + this.gain = resolved; + if (this.playing) this.gainNode.gain.value = resolved; + } + + /** + * 设置回声间隔时长 + * @param delay 回声时长,范围 0.01-Infinity,小于0.01的视为0.01 Number + */ + setEchoDelay(delay) { + const resolved = delay < 0.01 ? 0.01 : delay; + this.delay.delayTime.value = resolved; + } + + /** + * 获取反馈节点增益 + */ + getFeedbackGain() { + return this.gain; + } + + /** + * 获取回声间隔时长 + */ + getEchoDelay() { + return this.delay.delayTime.value; + } + + end() { + this.playing = false; + const echoTime = Math.ceil(Math.log(0.001) / Math.log(this.gain)) + 10; + sleep(this.delay.delayTime.value * echoTime).then(() => { + if (!this.playing) this.gainNode.gain.value = 0; + }); + } + + start() { + this.playing = true; + this.gainNode.gain.value = this.gain; + } + } + + class StreamLoader { + constructor(url) { + /** 传输目标 Set*/ + this.target = new Set(); + this.loading = false; + } + + /** + * 将加载流传递给字节流读取对象 + * @param reader 字节流读取对象 IStreamReader + */ + pipe(reader) { + if (this.loading) { + console.warn( + "Cannot pipe new StreamReader object when stream is loading." + ); + return; + } + this.target.add(reader); + reader.piped(this); + return this; + } + + async start() { + if (this.loading) return; + this.loading = true; + const response = await window.fetch(this.url); + const stream = response.body; + if (!stream) { + console.error("Cannot get reader when fetching '" + this.url + "'."); + return; + } + // 获取读取器 + this.stream = stream; + const reader = response.body?.getReader(); + const targets = [...this.target]; + + await Promise.all(targets.map((v) => v.start(stream, this, response))); + if (reader && reader.read) { + // 开始流传输 + while (true) { + const { value, done } = await reader.read(); + await Promise.all( + targets.map((v) => v.pump(value, done, response)) + ); + if (done) break; + } + } else { + // 如果不支持流传输 + const buffer = await response.arrayBuffer(); + const data = new Uint8Array(buffer); + await Promise.all(targets.map((v) => v.pump(data, true, response))); + } + + this.loading = false; + targets.forEach((v) => v.end(true)); + + // + } + + cancel(reason) { + if (!this.stream) return; + this.stream.cancel(reason); + this.loading = false; + this.target.forEach((v) => v.end(false, reason)); + } + } + const fileSignatures = [ + [AudioType.Mp3, [0x49, 0x44, 0x33]], + [AudioType.Ogg, [0x4f, 0x67, 0x67, 0x53]], + [AudioType.Wav, [0x52, 0x49, 0x46, 0x46]], + [AudioType.Flac, [0x66, 0x4c, 0x61, 0x43]], + [AudioType.Aac, [0xff, 0xf1]], + [AudioType.Aac, [0xff, 0xf9]], + ]; + const oggHeaders = [ + [AudioType.Opus, [0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64]], + ]; + + function checkAudioType(data) { + let audioType = ""; + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + for (const [type, value] of fileSignatures) { + if (value.every((v, i) => toCheck[i] === v)) { + audioType = type; + break; + } + } + if (audioType === AudioType.Ogg) { + // 如果是ogg的话,进一步判断是不是opus + for (const [key, value] of oggHeaders) { + const has = toCheck.some((_, i) => { + return value.every((v, ii) => toCheck[i + ii] === v); + }); + if (has) { + audioType = key; + break; } } } - for (let nx = 0; nx < numX; nx++) { - for (let ny = 0; ny < numY; ny++) { - res.push(withImage(canvas, rw + l * nx, rh + l * ny, l, l)); + + return audioType; + } + class AudioDecoder { + /** + * 注册一个解码器 + * @param type 要注册的解码器允许解码的类型 + * @param decoder 解码器对象 + */ + static registerDecoder(type, decoder) { + if (!this.decoderMap) this.decoderMap = new Map(); + if (this.decoderMap.has(type)) { + console.warn( + "Audio stream decoder for audio type '" + + type + + "' has already existed." + ); + return; + } + + this.decoderMap.set(type, decoder); + } + + /** + * 解码音频数据 + * @param data 音频文件数据 + * @param player AudioPlayer实例 + */ + static async decodeAudioData(data, player) { + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + const type = checkAudioType(data); + if (type === "") { + console.error( + "Unknown audio type. Header: '" + + [...toCheck] + .map((v) => v.toString().padStart(2, "0")) + .join(" ") + .toUpperCase() + + "'" + ); + return null; + } + if (isAudioSupport(type)) { + if (data.buffer instanceof ArrayBuffer) { + return player.ac.decodeAudioData(data.buffer); + } else { + return null; + } + } else { + const Decoder = this.decoderMap.get(type); + if (!Decoder) { + return null; + } else { + const decoder = new Decoder(); + await decoder.create(); + const decodedData = await decoder.decode(data); + if (!decodedData) return null; + const buffer = player.ac.createBuffer( + decodedData.channelData.length, + decodedData.channelData[0].length, + decodedData.sampleRate + ); + decodedData.channelData.forEach((v, i) => { + buffer.copyToChannel(v, i); + }); + decoder.destroy(); + return buffer; + } } } - - return res; } - const origin = core.events.afterBattle; - core.events.afterBattle = function (enemyId, x, y) { - // 打怪特效 - if (has(x) && has(y)) { - const frame = core.status.globalAnimateStatus % 2; - // 生成怪物图像 - const canvas = document.createElement("canvas"); - canvas.width = 32; - canvas.height = 32; - core.drawIcon(canvas, enemyId, 0, 0, 32, 32, frame); - // 执行动画 - const manager = applyFragWith(canvas); - const frag = manager.canvas; - // 设置特效画布的css属性 - frag.style.imageRendering = "pixelated"; - frag.style.width = `${frag.width * core.domStyle.scale}px`; - frag.style.height = `${frag.height * core.domStyle.scale}px`; - const left = - (x * 32 + 16 - frag.width / 2 - core.bigmap.offsetX) * - core.domStyle.scale; - const top = - (y * 32 + 16 - frag.height / 2 - core.bigmap.offsetY) * - core.domStyle.scale; - frag.style.left = `${left}px`; - frag.style.top = `${top}px`; - frag.style.zIndex = "45"; - frag.style.position = "absolute"; - // 将特效画布部署到样板上 - core.dom.gameDraw.appendChild(frag); - // 当特效执行完毕后移除这个特效画布 - manager.onEnd.then(() => { - frag.remove(); - }); + class VorbisDecoder { + /** + * 创建音频解码器 + */ + async create() { + this.decoder = new OggVorbisDecoderWebWorker(); + await this.decoder.ready; } - return origin.apply(this, arguments); + /** + * 摧毁这个解码器 + */ + destroy() { + this.decoder?.free(); + } + /** + * 解码流数据 + * @param data 流数据 + */ + + async decode(data) { + return this.decoder?.decode(data); + } + /** + * 解码整个文件 + * @param data 文件数据 + */ + async decodeAll(data) { + return this.decoder?.decodeFile(data); + } + /** + * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 + */ + async flush() { + return this.decoder?.flush(); + } + } + + class OpusDecoder { + /** + * 创建音频解码器 + */ + async create() { + this.decoder = new OggOpusDecoderWebWorker(); + await this.decoder.ready; + } + /** + * 摧毁这个解码器 + */ + destroy() { + this.decoder?.free(); + } + /** + * 解码流数据 + * @param data 流数据 + */ + async decode(data) { + return this.decoder?.decode(data); + } + /** + * 解码整个文件 + * @param data 文件数据 + */ + async decodeAll(data) { + return this.decoder?.decodeFile(data); + } + /** + * 当音频解码完成后,会调用此函数,需要返回之前还未解析或未返回的音频数据。调用后,该解码器将不会被再次使用 + */ + async flush() { + return await this.decoder?.flush(); + } + } + const mimeTypeMap = { + [AudioType.Aac]: "audio/aac", + [AudioType.Flac]: "audio/flac", + [AudioType.Mp3]: "audio/mpeg", + [AudioType.Ogg]: "application/ogg", + [AudioType.Opus]: "application/ogg", + [AudioType.Wav]: "application/ogg", }; - if ("frag" in core.plugin) { - throw new ReferenceError(`core.plugin上已存在名为frag的属性!`); + function isOggPage(data) { + return !isNil(data.isFirstPage); } - core.plugin.frag = { - applyFragWith, + class AudioStreamSource { + constructor(context) { + this.output = context.createBufferSource(); + /** 是否已经完全加载完毕 */ + this.loaded = false; + /** 是否正在播放 */ + this.playing = false; + /** 已经缓冲了多长时间,如果缓冲完那么跟歌曲时长一致 */ + this.buffered = 0; + /** 已经缓冲的采样点数量 */ + this.bufferedSamples = 0; + /** 歌曲时长,加载完毕之前保持为 0 */ + this.duration = 0; + /** 在流传输阶段,至少缓冲多长时间的音频之后才开始播放,单位秒 */ + this.bufferPlayDuration = 1; + /** 音频的采样率,未成功解析出之前保持为 0 */ + this.sampleRate = 0; + //是否循环播放 + this.loop = false; + /** 上一次播放是从何时开始的 */ + this.lastStartWhen = 0; + /** 开始播放时刻 */ + this.lastStartTime = 0; + /** 上一次播放的缓存长度 */ + this.lastBufferSamples = 0; + + /** 是否已经获取到头文件 */ + this.headerRecieved = false; + /** 音频类型 */ + this.audioType = ""; + /** 每多长时间组成一个缓存 Float32Array */ + this.bufferChunkSize = 10; + /** 缓存音频数据,每 bufferChunkSize 秒钟组成一个 Float32Array,用于流式解码 */ + this.audioData = []; + + this.errored = false; + this.ac = context; + } + /** 当前已经播放了多长时间 */ + get currentTime() { + return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; + } + /** + * 设置每个缓存数据的大小,默认为10秒钟一个缓存数据 + * @param size 每个缓存数据的时长,单位秒 + */ + setChunkSize(size) { + if (this.controller?.loading || this.loaded) return; + this.bufferChunkSize = size; + } + + piped(controller) { + this.controller = controller; + } + + async pump(data, done) { + if (!data || this.errored) return; + if (!this.headerRecieved) { + // 检查头文件获取音频类型,仅检查前256个字节 + const toCheck = data.slice(0, 256); + this.audioType = checkAudioType(data); + if (!this.audioType) { + console.error( + "Unknown audio type. Header: '" + + [...toCheck] + .map((v) => v.toString(16).padStart(2, "0")) + .join(" ") + .toUpperCase() + + "'" + ); + return; + } + // 创建解码器 + const Decoder = AudioDecoder.decoderMap.get(this.audioType); + if (!Decoder) { + this.errored = true; + console.error( + "Cannot decode stream source type of '" + + this.audioType + + "', since there is no registered decoder for that type." + ); + return Promise.reject( + `Cannot decode stream source type of '${this.audioType}', since there is no registered decoder for that type.` + ); + } + this.decoder = new Decoder(); + // 创建数据解析器 + const mime = mimeTypeMap[this.audioType]; + const parser = new CodecParser(mime); + this.parser = parser; + await this.decoder.create(); + this.headerRecieved = true; + } + + const decoder = this.decoder; + const parser = this.parser; + if (!decoder || !parser) { + this.errored = true; + return Promise.reject( + "No parser or decoder attached in this AudioStreamSource" + ); + } + + await this.decodeData(data, decoder, parser); + if (done) await this.decodeFlushData(decoder, parser); + this.checkBufferedPlay(); + } + + /** + * 检查采样率,如果还未解析出采样率,那么将设置采样率,如果当前采样率与之前不同,那么发出警告 + */ + checkSampleRate(info) { + for (const one of info) { + const frame = isOggPage(one) ? one.codecFrames[0] : one; + if (frame) { + const rate = frame.header.sampleRate; + if (this.sampleRate === 0) { + this.sampleRate = rate; + break; + } else { + if (rate !== this.sampleRate) { + console.warn("Sample rate in stream audio must be constant."); + } + } + } + } + } + + /** + * 解析音频数据 + */ + async decodeData(data, decoder, parser) { + // 解析音频数据 + const audioData = await decoder.decode(data); + if (!audioData) return; + // @ts-expect-error 库类型声明错误 + const audioInfo = [...parser.parseChunk(data)]; + + // 检查采样率 + this.checkSampleRate(audioInfo); + // 追加音频数据 + this.appendDecodedData(audioData, audioInfo); + } + + /** + * 解码剩余数据 + */ + async decodeFlushData(decoder, parser) { + const audioData = await decoder.flush(); + if (!audioData) return; + // @ts-expect-error 库类型声明错误 + const audioInfo = [...parser.flush()]; + + this.checkSampleRate(audioInfo); + this.appendDecodedData(audioData, audioInfo); + } + + /** + * 追加音频数据 + */ + appendDecodedData(data, info) { + const channels = data.channelData.length; + if (channels === 0) return; + if (this.audioData.length !== channels) { + this.audioData = []; + for (let i = 0; i < channels; i++) { + this.audioData.push([]); + } + } + // 计算出应该放在哪 + const chunk = this.sampleRate * this.bufferChunkSize; + const sampled = this.bufferedSamples; + const pushIndex = Math.floor(sampled / chunk); + const bufferIndex = sampled % chunk; + const dataLength = data.channelData[0].length; + let buffered = 0; + let nowIndex = pushIndex; + let toBuffer = bufferIndex; + while (buffered < dataLength) { + const rest = toBuffer !== 0 ? chunk - bufferIndex : chunk; + + for (let i = 0; i < channels; i++) { + const audioData = this.audioData[i]; + if (!audioData[nowIndex]) { + audioData.push(new Float32Array(chunk)); + } + const toPush = data.channelData[i].slice(buffered, buffered + rest); + + audioData[nowIndex].set(toPush, toBuffer); + } + buffered += rest; + nowIndex++; + toBuffer = 0; + } + + this.buffered += + info.reduce((prev, curr) => prev + curr.duration, 0) / 1000; + this.bufferedSamples += info.reduce( + (prev, curr) => prev + curr.samples, + 0 + ); + } + + /** + * 检查已缓冲内容,并在未开始播放时播放 + */ + checkBufferedPlay() { + if (this.playing || this.sampleRate === 0) return; + const played = this.lastBufferSamples / this.sampleRate; + const dt = this.buffered - played; + if (this.loaded) { + this.playAudio(played); + return; + } + if (dt < this.bufferPlayDuration) return; + + this.lastBufferSamples = this.bufferedSamples; + // 需要播放 + this.mergeBuffers(); + if (!this.buffer) return; + if (this.playing) this.output.stop(); + this.createSourceNode(this.buffer); + this.output.loop = false; + this.output.start(0, played); + this.lastStartTime = this.ac.currentTime; + this.playing = true; + this.output.addEventListener("ended", () => { + this.playing = false; + this.checkBufferedPlay(); + }); + } + + mergeBuffers() { + const buffer = this.ac.createBuffer( + this.audioData.length, + this.bufferedSamples, + this.sampleRate + ); + const chunk = this.sampleRate * this.bufferChunkSize; + const bufferedChunks = Math.floor(this.bufferedSamples / chunk); + const restLength = this.bufferedSamples % chunk; + for (let i = 0; i < this.audioData.length; i++) { + const audio = this.audioData[i]; + const data = new Float32Array(this.bufferedSamples); + for (let j = 0; j < bufferedChunks; j++) { + data.set(audio[j], chunk * j); + } + if (restLength !== 0) { + data.set( + audio[bufferedChunks].slice(0, restLength), + chunk * bufferedChunks + ); + } + + buffer.copyToChannel(data, i, 0); + } + this.buffer = buffer; + } + + async start() { + delete this.buffer; + this.headerRecieved = false; + this.audioType = ""; + this.errored = false; + this.buffered = 0; + this.sampleRate = 0; + this.bufferedSamples = 0; + this.duration = 0; + this.loaded = false; + if (this.playing) this.output.stop(); + this.playing = false; + this.lastStartTime = this.ac.currentTime; + } + + end(done, reason) { + if (done && this.buffer) { + this.loaded = true; + delete this.controller; + this.mergeBuffers(); + + this.duration = this.buffered; + this.audioData = []; + this.decoder?.destroy(); + delete this.decoder; + delete this.parser; + } else { + console.warn( + "Unexpected end when loading stream audio, reason: '" + + (reason ?? "") + + "'" + ); + } + } + + playAudio(when) { + if (!this.buffer) return; + this.lastStartTime = this.ac.currentTime; + if (this.playing) this.output.stop(); + if (this.route.status !== AudioStatus.Playing) { + this.route.status = AudioStatus.Playing; + } + this.createSourceNode(this.buffer); + this.output.start(0, when); + this.playing = true; + + this.output.addEventListener("ended", () => { + this.playing = false; + if (this.route.status === AudioStatus.Playing) { + this.route.status = AudioStatus.Stoped; + } + if (this.loop && !this.output.loop) this.play(0); + }); + } + /** + * 开始播放这个音频源 + */ + play(when) { + if (this.playing || this.errored) return; + if (this.loaded && this.buffer) { + this.playing = true; + this.playAudio(when); + } else { + this.controller?.start(); + } + } + + createSourceNode(buffer) { + if (!this.target) return; + const node = this.ac.createBufferSource(); + node.buffer = buffer; + if (this.playing) this.output.stop(); + this.playing = false; + this.output = node; + node.connect(this.target.input); + node.loop = this.loop; + } + /** + * 停止播放这个音频源 + * @returns 音频暂停的时刻 number + */ + stop() { + if (this.playing) this.output.stop(); + this.playing = false; + return this.ac.currentTime - this.lastStartTime; + } + /** + * 连接到音频路由图上,每次调用播放的时候都会执行一次 + * @param target 连接至的目标 IAudioInput + */ + connect(target) { + this.target = target; + } + /** + * 设置是否循环播放 + * @param loop 是否循环 boolean) + */ + setLoop(loop) { + this.loop = loop; + } + } + class AudioElementSource { + constructor(context) { + const audio = new Audio(); + audio.preload = "none"; + this.output = context.createMediaElementSource(audio); + this.audio = audio; + this.ac = context; + audio.addEventListener("play", () => { + this.playing = true; + if (this.route.status !== AudioStatus.Playing) { + this.route.status = AudioStatus.Playing; + } + }); + audio.addEventListener("ended", () => { + this.playing = false; + if (this.route.status === AudioStatus.Playing) { + this.route.status = AudioStatus.Stoped; + } + }); + } + get duration() { + return this.audio.duration; + } + get currentTime() { + return this.audio.currentTime; + } + /** + * 设置音频源的路径 + * @param url 音频路径 + */ + setSource(url) { + this.audio.src = url; + } + + play(when = 0) { + if (this.playing) return; + this.audio.currentTime = when; + this.audio.play(); + } + + stop() { + this.audio.pause(); + this.playing = false; + if (this.route.status === AudioStatus.Playing) { + this.route.status = AudioStatus.Stoped; + } + return this.audio.currentTime; + } + + connect(target) { + this.output.connect(target.input); + } + + setLoop(loop) { + this.audio.loop = loop; + } + } + class AudioBufferSource { + constructor(context) { + this.output = context.createBufferSource(); + /** 是否循环 */ + this.loop = false; + /** 上一次播放是从何时开始的 */ + this.lastStartWhen = 0; + /** 播放开始时刻 */ + this.lastStartTime = 0; + this.duration = 0; + this.ac = context; + } + get currentTime() { + return this.ac.currentTime - this.lastStartTime + this.lastStartWhen; + } + + /** + * 设置音频源数据 + * @param buffer 音频源,可以是未解析的 ArrayBuffer,也可以是已解析的 AudioBuffer + */ + async setBuffer(buffer) { + if (buffer instanceof ArrayBuffer) { + this.buffer = await this.ac.decodeAudioData(buffer); + } else { + this.buffer = buffer; + } + this.duration = this.buffer.duration; + } + + play(when) { + if (this.playing || !this.buffer) return; + this.playing = true; + this.lastStartTime = this.ac.currentTime; + if (this.route.status !== AudioStatus.Playing) { + this.route.status = AudioStatus.Playing; + } + this.createSourceNode(this.buffer); + this.output.start(0, when); + this.output.addEventListener("ended", () => { + this.playing = false; + if (this.route.status === AudioStatus.Playing) { + this.route.status = AudioStatus.Stoped; + } + if (this.loop && !this.output.loop) this.play(0); + }); + } + + createSourceNode(buffer) { + if (!this.target) return; + const node = this.ac.createBufferSource(); + node.buffer = buffer; + this.output = node; + node.connect(this.target.input); + node.loop = this.loop; + } + + stop() { + this.output.stop(); + return this.ac.currentTime - this.lastStartTime; + } + + connect(target) { + this.target = target; + } + + setLoop(loop) { + this.loop = loop; + } + } + class AudioPlayer { + constructor() { + /** 音频播放上下文 */ + this.ac = new AudioContext(); + /** 音量节点 */ + this.gain = this.ac.createGain(); + this.gain.connect(this.ac.destination); + this.audioRoutes = new Map(); + } + /** + * 解码音频数据 + * @param data 音频数据 + */ + decodeAudioData(data) { + return AudioDecoder.decodeAudioData(data, this); + } + /** + * 设置音量 + * @param volume 音量 + */ + setVolume(volume) { + this.gain.gain.value = volume; + } + + /** + * 获取音量 + */ + getVolume() { + return this.gain.gain.value; + } + + /** + * 创建一个音频源 + * @param Source 音频源类 + */ + createSource(Source) { + return new Source(this.ac); + } + + /** + * 创建一个兼容流式音频源,可以与流式加载相结合,主要用于处理 opus ogg 不兼容的情况 + */ + createStreamSource() { + return new AudioStreamSource(this.ac); + } + + /** + * 创建一个通过 audio 元素播放的音频源 + */ + createElementSource() { + return new AudioElementSource(this.ac); + } + + /** + * 创建一个通过 AudioBuffer 播放的音频源 + */ + createBufferSource() { + return new AudioBufferSource(this.ac); + } + + /** + * 获取音频目的地 + */ + getDestination() { + return this.gain; + } + + /** + * 创建一个音频效果器 + * @param Effect 效果器类 + */ + createEffect(Effect) { + return new Effect(this.ac); + } + + /** + * 创建一个修改音量的效果器 + * ```txt + * |----------| + * Input ----> | GainNode | ----> Output + * |----------| + * ``` + */ + createVolumeEffect() { + return new VolumeEffect(this.ac); + } + + /** + * 创建一个立体声效果器 + * ```txt + * |------------| + * Input ----> | PannerNode | ----> Output + * |------------| + * ``` + */ + createStereoEffect() { + return new StereoEffect(this.ac); + } + + /** + * 创建一个修改单个声道音量的效果器 + * ```txt + * |----------| + * -> | GainNode | \ + * |--------------| / |----------| -> |------------| + * Input ----> | SplitterNode | ...... | MergerNode | ----> Output + * |--------------| \ |----------| -> |------------| + * -> | GainNode | / + * |----------| + * ``` + */ + createChannelVolumeEffect() { + return new ChannelVolumeEffect(this.ac); + } + + /** + * 创建一个延迟效果器 + * |-----------| + * Input ----> | DelayNode | ----> Output + * |-----------| + */ + createDelay() { + return new DelayEffect(this.ac); + } + + /** + * 创建一个回声效果器 + * ```txt + * |----------| + * Input ----> | GainNode | ----> Output + * ^ |----------| | + * | | + * | |------------| ↓ + * |-- | Delay Node | <-- + * |------------| + * ``` + */ + createEchoEffect() { + return new EchoEffect(this.ac); + } + + /** + * 创建一个音频播放路由 + * @param source 音频源 + */ + createRoute(source) { + return new AudioRoute(source, this); + } + + /** + * 添加一个音频播放路由,可以直接被播放 + * @param id 这个音频播放路由的名称 + * @param route 音频播放路由对象 + */ + addRoute(id, route) { + if (!this.audioRoutes) this.audioRoutes = new Map(); + if (this.audioRoutes.has(id)) { + console.warn( + "Audio route with id of '" + + id + + "' has already existed. New route will override old route." + ); + } + this.audioRoutes.set(id, route); + } + + /** + * 根据名称获取音频播放路由对象 + * @param id 音频播放路由的名称 + */ + getRoute(id) { + return this.audioRoutes.get(id); + } + /** + * 移除一个音频播放路由 + * @param id 要移除的播放路由的名称 + */ + removeRoute(id) { + this.audioRoutes.delete(id); + } + /** + * 播放音频 + * @param id 音频名称 + * @param when 从音频的哪个位置开始播放,单位秒 + */ + play(id, when) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot play audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + + route.play(when); + } + + /** + * 暂停音频播放 + * @param id 音频名称 + * @returns 当音乐真正停止时兑现 + */ + pause(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot pause audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + return route.pause(); + } + + /** + * 停止音频播放 + * @param id 音频名称 + * @returns 当音乐真正停止时兑现 + */ + stop(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot stop audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + return route.stop(); + } + + /** + * 继续音频播放 + * @param id 音频名称 + */ + resume(id) { + const route = this.getRoute(id); + if (!route) { + console.warn( + "Cannot pause audio route '" + + id + + "', since there is not added route named it." + ); + return; + } + route.resume(); + } + + /** + * 设置听者位置,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 位置x坐标 + * @param y 位置y坐标 + * @param z 位置z坐标 + */ + setListenerPosition(x, y, z) { + const listener = this.ac.listener; + listener.positionX.value = x; + listener.positionY.value = y; + listener.positionZ.value = z; + } + + /** + * 设置听者朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 朝向x坐标 + * @param y 朝向y坐标 + * @param z 朝向z坐标 + */ + setListenerOrientation(x, y, z) { + const listener = this.ac.listener; + listener.forwardX.value = x; + listener.forwardY.value = y; + listener.forwardZ.value = z; + } + + /** + * 设置听者头顶朝向,x正方向水平向右,y正方向垂直于地面向上,z正方向垂直屏幕远离用户 + * @param x 头顶朝向x坐标 + * @param y 头顶朝向y坐标 + * @param z 头顶朝向z坐标 + */ + setListenerUp(x, y, z) { + const listener = this.ac.listener; + listener.upX.value = x; + listener.upY.value = y; + listener.upZ.value = z; + } + } + class AudioRoute { + constructor(source, player) { + source.route = this; + this.output = source.output; + + /** 效果器路由图 */ + this.effectRoute = []; + + /** 结束时长,当音频暂停或停止时,会经过这么长时间之后才真正终止播放,期间可以做音频淡入淡出等效果 */ + this.endTime = 0; + /** 暂停时播放了多长时间 */ + this.pauseCurrentTime = 0; + /** 当前播放状态 */ + this.player = player; + this.status = AudioStatus.Stoped; + + this.shouldStop = false; + /** + * 每次暂停或停止时自增,用于判断当前正在处理的情况。 + * 假如暂停后很快播放,然后很快暂停,那么需要根据这个来判断实际是否应该执行暂停后操作 + */ + this.stopIdentifier = 0; + /** 暂停时刻 */ + this.pauseTime = 0; + this.source = source; + this.source.player = player; + } + /** 音频时长,单位秒 */ + get duration() { + return this.source.duration; + } + /** 当前播放了多长时间,单位秒 */ + get currentTime() { + if (this.status === AudioStatus.Paused) { + return this.pauseCurrentTime; + } else { + return this.source.currentTime; + } + } + set currentTime(time) { + this.source.stop(); + this.source.play(time); + } + /** + * 设置结束时间,暂停或停止时,会经过这么长时间才终止音频的播放,这期间可以做一下音频淡出的效果。 + * @param time 暂停或停止时,经过多长时间之后才会结束音频的播放 + */ + setEndTime(time) { + this.endTime = time; + } + + /** + * 当音频播放时执行的函数,可以用于音频淡入效果 + * @param fn 音频开始播放时执行的函数 + */ + onStart(fn) { + this.audioStartHook = fn; + } + + /** + * 当音频暂停或停止时执行的函数,可以用于音频淡出效果 + * @param fn 音频在暂停或停止时执行的函数,不填时表示取消这个钩子。 + * 包含两个参数,第一个参数是结束时长,第二个参数是当前音频播放路由对象 + */ + onEnd(fn) { + this.audioEndHook = fn; + } + + /** + * 开始播放这个音频 + * @param when 从音频的什么时候开始播放,单位秒 + */ + async play(when = 0) { + if (this.status === AudioStatus.Playing) return; + this.link(); + await this.player.ac.resume(); + if (this.effectRoute.length > 0) { + const first = this.effectRoute[0]; + this.source.connect(first); + const last = this.effectRoute.at(-1); + last.connect({ input: this.player.getDestination() }); + } else { + this.source.connect({ input: this.player.getDestination() }); + } + this.source.play(when); + this.status = AudioStatus.Playing; + this.pauseTime = 0; + this.audioStartHook?.(this); + this.startAllEffect(); + if (this.status !== AudioStatus.Playing) { + this.status = AudioStatus.Playing; + } + } + + /** + * 暂停音频播放 + */ + async pause() { + if (this.status !== AudioStatus.Playing) return; + this.status = AudioStatus.Pausing; + this.stopIdentifier++; + const identifier = this.stopIdentifier; + if (this.audioEndHook) { + this.audioEndHook(this.endTime, this); + await sleep(this.endTime); + } + if ( + this.status !== AudioStatus.Pausing || + this.stopIdentifier !== identifier + ) { + return; + } + this.pauseCurrentTime = this.source.currentTime; + const time = this.source.stop(); + this.pauseTime = time; + if (this.shouldStop) { + this.status = AudioStatus.Stoped; + this.endAllEffect(); + + this.shouldStop = false; + } else { + this.status = AudioStatus.Paused; + this.endAllEffect(); + } + this.endAllEffect(); + } + + /** + * 继续音频播放 + */ + resume() { + if (this.status === AudioStatus.Playing) return; + if ( + this.status === AudioStatus.Pausing || + this.status === AudioStatus.Stoping + ) { + this.audioStartHook?.(this); + + return; + } + if (this.status === AudioStatus.Paused) { + this.play(this.pauseTime); + } else { + this.play(0); + } + this.status = AudioStatus.Playing; + this.pauseTime = 0; + this.audioStartHook?.(this); + this.startAllEffect(); + } + + /** + * 停止音频播放 + */ + async stop() { + if (this.status !== AudioStatus.Playing) { + if (this.status === AudioStatus.Pausing) { + this.shouldStop = true; + } + return; + } + this.status = AudioStatus.Stoping; + this.stopIdentifier++; + const identifier = this.stopIdentifier; + if (this.audioEndHook) { + this.audioEndHook(this.endTime, this); + await sleep(this.endTime); + } + if ( + this.status !== AudioStatus.Stoping || + this.stopIdentifier !== identifier + ) { + return; + } + this.source.stop(); + this.status = AudioStatus.Stoped; + this.pauseTime = 0; + this.endAllEffect(); + } + + /** + * 添加效果器 + * @param effect 要添加的效果,可以是数组,表示一次添加多个 + * @param index 从哪个位置开始添加,如果大于数组长度,那么加到末尾,如果小于0,那么将会从后面往前数。默认添加到末尾 + */ + addEffect(effect, index) { + if (isNil(index)) { + if (effect instanceof Array) { + this.effectRoute.push(...effect); + } else { + this.effectRoute.push(effect); + } + } else { + if (effect instanceof Array) { + this.effectRoute.splice(index, 0, ...effect); + } else { + this.effectRoute.splice(index, 0, effect); + } + } + this.setOutput(); + if (this.source.playing) this.link(); + } + + /** + * 移除一个效果器 + * @param effect 要移除的效果 + */ + removeEffect(effect) { + const index = this.effectRoute.indexOf(effect); + if (index === -1) return; + this.effectRoute.splice(index, 1); + effect.disconnect(); + this.setOutput(); + if (this.source.playing) this.link(); + } + + setOutput() { + const effect = this.effectRoute.at(-1); + if (!effect) this.output = this.source.output; + else this.output = effect.output; + } + + /** + * 连接音频路由图 + */ + link() { + this.effectRoute.forEach((v) => v.disconnect()); + this.effectRoute.forEach((v, i) => { + const next = this.effectRoute[i + 1]; + if (next) { + v.connect(next); + } + }); + } + + startAllEffect() { + this.effectRoute.forEach((v) => v.start()); + } + + endAllEffect() { + this.effectRoute.forEach((v) => v.end()); + } + } + + const audioPlayer = new AudioPlayer(); + + class BgmController { + constructor(player) { + this.mainGain = player.createVolumeEffect(); + this.player = player; + /** bgm音频名称的前缀 */ + this.prefix = "bgms."; + /** 每个 bgm 的音量控制器 */ + this.gain = new Map(); + + /** 正在播放的 bgm */ + this.playingBgm = ""; + /** 是否正在播放 */ + this.playing = false; + + /** 是否已经启用 */ + this.enabled = true; + /** 是否屏蔽所有的音乐切换 */ + this.blocking = false; + /** 渐变时长 */ + this.transitionTime = 2000; + } + + /** + * 设置音频渐变时长 + * @param time 渐变时长 + */ + setTransitionTime(time) { + this.transitionTime = time; + for (const [, value] of this.gain) { + value.transition.time(time); + } + } + + /** + * 屏蔽音乐切换 + */ + blockChange() { + this.blocking = true; + } + + /** + * 取消屏蔽音乐切换 + */ + unblockChange() { + this.blocking = false; + } + + /** + * 设置总音量大小 + * @param volume 音量大小 + */ + setVolume(volume) { + this.mainGain.setVolume(volume); + this._volume = volume; + } + /** + * 获取总音量大小 + */ + getVolume() { + return this.mainGain.getVolume(); + } + /** + * 设置是否启用 + * @param enabled 是否启用 + */ + setEnabled(enabled) { + if (enabled) this.resume(); + else this.stop(); + this.enabled = enabled; + } + + /** + * 设置 bgm 音频名称的前缀 + */ + setPrefix(prefix) { + this.prefix = prefix; + } + + getId(name) { + return `${this.prefix}${name}`; + } + + /** + * 根据 bgm 名称获取其 AudioRoute 实例 + * @param id 音频名称 + */ + get(id) { + return this.player.getRoute(this.getId(id)); + } + + /** + * 添加一个 bgm + * @param id 要添加的 bgm 的名称 + * @param url 指定 bgm 的加载地址 + */ + addBgm(id, url = `project/bgms/${id}`) { + const type = guessTypeByExt(id); + if (!type) { + console.warn( + "Unknown audio extension name: '" + + id.split(".").slice(0, -1).join(".") + + "'" + ); + return; + } + const gain = this.player.createVolumeEffect(); + if (isAudioSupport(type)) { + const source = audioPlayer.createElementSource(); + source.setSource(url); + source.setLoop(true); + const route = new AudioRoute(source, audioPlayer); + route.addEffect([gain, this.mainGain]); + audioPlayer.addRoute(this.getId(id), route); + this.setTransition(id, route, gain); + } else { + const source = audioPlayer.createStreamSource(); + const stream = new StreamLoader(url); + stream.pipe(source); + source.setLoop(true); + const route = new AudioRoute(source, audioPlayer); + route.addEffect([gain, this.mainGain]); + audioPlayer.addRoute(this.getId(id), route); + this.setTransition(id, route, gain); + } + } + + /** + * 移除一个 bgm + * @param id 要移除的 bgm 的名称 + */ + removeBgm(id) { + this.player.removeRoute(this.getId(id)); + const gain = this.gain.get(id); + gain?.transition.ticker.destroy(); + this.gain.delete(id); + } + + setTransition(id, route, gain) { + const transition = new Transition(); + transition + .time(this.transitionTime) + .mode(linear()) + .transition("volume", 0); + + const tick = () => { + gain.setVolume(transition.value.volume); + }; + + /** + * @param expect 在结束时应该是正在播放还是停止 + */ + const setTick = async (expect) => { + transition.ticker.remove(tick); + transition.ticker.add(tick); + const identifier = route.stopIdentifier; + await sleep(this.transitionTime + 500); + if (route.status === expect && identifier === route.stopIdentifier) { + transition.ticker.remove(tick); + if (route.status === AudioStatus.Playing) { + gain.setVolume(1); + } else { + gain.setVolume(0); + } + } + }; + + route.onStart(async () => { + transition.transition("volume", 1); + setTick(AudioStatus.Playing); + }); + route.onEnd(() => { + transition.transition("volume", 0); + setTick(AudioStatus.Paused); + }); + route.setEndTime(this.transitionTime); + + this.gain.set(id, { effect: gain, transition }); + } + + /** + * 播放一个 bgm + * @param id 要播放的 bgm 名称 + */ + play(id, when) { + if (this.blocking) return; + if (id !== this.playingBgm && this.playingBgm) { + this.player.pause(this.getId(this.playingBgm)); + } + this.playingBgm = id; + if (!this.enabled) return; + this.player.play(this.getId(id), when); + this.playing = true; + } + + /** + * 继续当前的 bgm + */ + resume() { + if (this.blocking || !this.enabled || this.playing) return; + if (this.playingBgm) { + this.player.resume(this.getId(this.playingBgm)); + } + this.playing = true; + } + + /** + * 暂停当前的 bgm + */ + pause() { + if (this.blocking || !this.enabled) return; + if (this.playingBgm) { + this.player.pause(this.getId(this.playingBgm)); + } + this.playing = false; + } + + /** + * 停止当前的 bgm + */ + stop() { + if (this.blocking || !this.enabled) return; + if (this.playingBgm) { + this.player.stop(this.getId(this.playingBgm)); + } + this.playing = false; + } + } + const bgmController = new BgmController(audioPlayer); + + class SoundPlayer { + constructor(player) { + /** 每个音效的唯一标识符 */ + this.num = 0; + this.enabled = true; + this.gain = player.createVolumeEffect(); + /** 每个音效的数据 */ + this.buffer = new Map(); + /** 所有正在播放的音乐 */ + this.playing = new Set(); + this.player = player; + } + /** + * 设置是否启用音效 + * @param enabled 是否启用音效 + */ + setEnabled(enabled) { + if (!enabled) this.stopAllSounds(); + this.enabled = enabled; + } + + /** + * 设置音量大小 + * @param volume 音量大小 + */ + setVolume(volume) { + this.gain.setVolume(volume); + } + /** + * 获取音量大小 + */ + getVolume() { + return this.gain.getVolume(); + } + /** + * 添加一个音效 + * @param id 音效名称 + * @param data 音效的Uint8Array数据 + */ + async add(id, data) { + const buffer = await this.player.decodeAudioData(data); + if (!buffer) { + console.warn( + "Cannot decode sound '" + + id + + "', since audio file may not supported by 2.b." + ); + return; + } + this.buffer.set(id, buffer); + } + + /** + * 播放一个音效 + * @param id 音效名称 + * @param position 音频位置,[0, 0, 0]表示正中心,x轴指向水平向右,y轴指向水平向上,z轴指向竖直向上 + * @param orientation 音频朝向,[0, 1, 0]表示朝向前方 + */ + play(id, position = [0, 0, 0], orientation = [1, 0, 0]) { + if (!this.enabled || !id) return -1; + const buffer = this.buffer.get(id); + if (!buffer) { + console.warn( + "Cannot play sound '" + + id + + "', since there is no added data named it." + ); + return -1; + } + const soundNum = this.num++; + + const source = this.player.createBufferSource(); + source.setBuffer(buffer); + const route = this.player.createRoute(source); + const stereo = this.player.createStereoEffect(); + stereo.setPosition(position[0], position[1], position[2]); + stereo.setOrientation(orientation[0], orientation[1], orientation[2]); + route.addEffect([stereo, this.gain]); + this.player.addRoute(`sounds.${soundNum}`, route); + route.play(); + source.output.addEventListener("ended", () => { + this.playing.delete(soundNum); + }); + this.playing.add(soundNum); + return soundNum; + } + + /** + * 停止一个音效 + * @param num 音效的唯一 id + */ + stop(num) { + const id = `sounds.${num}`; + const route = this.player.getRoute(id); + if (route) { + route.stop(); + this.player.removeRoute(id); + this.playing.delete(num); + } + } + + /** + * 停止播放所有音效 + */ + stopAllSounds() { + this.playing.forEach((v) => { + const id = `sounds.${v}`; + const route = this.player.getRoute(id); + if (route) { + route.stop(); + this.player.removeRoute(id); + } + }); + this.playing.clear(); + } + } + const soundPlayer = new SoundPlayer(audioPlayer); + + function loadAllBgm() { + const data = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d; + for (const bgm of data.main.bgms) { + bgmController.addBgm(bgm); + } + } + loadAllBgm(); + AudioDecoder.registerDecoder(AudioType.Ogg, VorbisDecoder); + AudioDecoder.registerDecoder(AudioType.Opus, OpusDecoder); + + core.plugin.audioSystem = { + AudioType, + AudioDecoder, + AudioStatus, + checkAudioType, + isAudioSupport, + audioPlayer, + soundPlayer, + bgmController, + guessTypeByExt, + BgmController, + SoundPlayer, + EchoEffect, + DelayEffect, + ChannelVolumeEffect, + VolumeEffect, + StereoEffect, + AudioEffect, + AudioPlayer, + AudioRoute, + AudioStreamSource, + AudioElementSource, + AudioBufferSource, + loadAllBgm, + StreamLoader, + }; + //bgm相关复写 + control.prototype.playBgm = (bgm, when) => { + bgm = core.getMappedName(bgm); + bgmController.play(bgm, when); + core.setMusicBtn(); + }; + control.prototype.pauseBgm = () => { + bgmController.pause(); + core.setMusicBtn(); + }; + + control.prototype.resumeBgm = function () { + bgmController.resume(); + core.setMusicBtn(); + }; + control.prototype.checkBgm = function () { + core.playBgm(bgmController.playingBgm || main.startBgm); + }; + control.prototype.triggerBgm = function () { + core.musicStatus.bgmStatus = !core.musicStatus.bgmStatus; + if (bgmController.playing) bgmController.pause(); + else bgmController.resume(); + core.setMusicBtn(); + core.setLocalStorage("bgmStatus", core.musicStatus.bgmStatus); + }; + //sound相关复写 + control.prototype.playSound = function ( + sound, + _pitch, + callback, + position, + orientation + ) { + if (main.mode != "play" || !core.musicStatus.soundStatus) return; + const name = core.getMappedName(sound); + const num = soundPlayer.play(name, position, orientation); + const route = audioPlayer.getRoute(`sounds.${num}`); + if (!route) { + callback?.(); + return -1; + } else { + sleep(route.duration * 1000).then(() => callback?.()); + return num; + } + }; + control.prototype.stopSound = function (id) { + if (isNil(id)) { + soundPlayer.stopAllSounds(); + } else { + soundPlayer.stop(id); + } + }; + control.prototype.getPlayingSounds = function () { + return [...soundPlayer.playing]; + }; + //sound加载复写 + loader.prototype._loadOneSound_decodeData = function (name, data) { + if (data instanceof Blob) { + var blobReader = new zip.BlobReader(data); + blobReader.init(function () { + blobReader.readUint8Array(0, blobReader.size, function (uint8) { + //core.loader._loadOneSound_decodeData(name, uint8.buffer); + soundPlayer.add(name, uint8); + }); + }); + return; + } + if (data instanceof ArrayBuffer) { + const uint8 = new Uint8Array(data); + soundPlayer.add(name, uint8); + } + }; + //音量控制复写 + soundPlayer.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + bgmController.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + actions.prototype._clickSwitchs_sounds_userVolume = function (delta) { + var value = Math.round(Math.sqrt(100 * core.musicStatus.userVolume)); + if (value == 0 && delta < 0) return; + core.musicStatus.userVolume = core.clamp( + Math.pow(value + delta, 2) / 100, + 0, + 1 + ); + //audioContext 音效 不受designVolume 影响 + if (core.musicStatus.gainNode != null) + core.musicStatus.gainNode.gain.value = core.musicStatus.userVolume; + soundPlayer.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + bgmController.setVolume( + core.musicStatus.userVolume * core.musicStatus.designVolume + ); + core.setLocalStorage("userVolume", core.musicStatus.userVolume); + core.playSound("确定"); + core.ui._drawSwitchs_sounds(); }; }, "自定义常用事件": function () { - // editorBlocklyconfigPlus.js - // 自訂常見事件模板插件 - // 本插件引用了通用函數插件(Utility.js) - // 適用樣板:2.10.3 - // 請注意: - // 此插件對事件編輯器(editor_blocklyconfig)進行複寫,若還有其它針對事件編輯器做複寫的插件,請謹慎使用! - // 此插件對表格操作行為(editor_mode.doActionList)進行複寫,若還有其它對表格操作行為做複寫的插件,請謹慎使用! - // 使用方法: - // 現在在主頁下拉選單多了個常用事件模版,在那邊可以自由設定常用事件模板。 - // 設定完後按F5刷新,再到事件編輯器看就有你設定好的常用事件模板了。 + // editorBlocklyconfigPlus.js + // 自訂常見事件模板插件 + // 本插件引用了通用函數插件(Utility.js) + // 適用樣板:2.10.3 + // 請注意: + // 此插件對事件編輯器(editor_blocklyconfig)進行複寫,若還有其它針對事件編輯器做複寫的插件,請謹慎使用! + // 此插件對表格操作行為(editor_mode.doActionList)進行複寫,若還有其它對表格操作行為做複寫的插件,請謹慎使用! + // 使用方法: + // 現在在主頁下拉選單多了個常用事件模版,在那邊可以自由設定常用事件模板。 + // 設定完後按F5刷新,再到事件編輯器看就有你設定好的常用事件模板了。 - if (main.mode == "editor") { - //#region 配置表格初始化 - let TableFileName = "project/table/CommonEventTemplate_comment.js"; - let TableRow = ` + if (main.mode == "editor") { + //#region 配置表格初始化 + let TableFileName = "project/table/CommonEventTemplate_comment.js"; + let TableRow = ` var CommonEventTemplate_comment = {"_type": "object", "_data": { "CommonEventTemplate": { @@ -8701,221 +11620,241 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } }} `; - if (!events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { - /** - * @type {{[EvnetName:actionParserJson]}} - */ - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate = { - 检测音乐如果没有开启则系统提示开启: [{ - type: "if", - condition: "!core.musicStatus.bgmStatus", - true: [ - "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳", - ], - false: [], - }, ], - 仿新新魔塔一次性商人: [{ - type: "if", - condition: "switch:A", - true: [ - "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", - { - type: "comment", - text: "下一条指令可视情况使用或不使用", - }, - { - type: "hide", - remove: true, - time: 250, - }, - ], - false: [{ - type: "confirm", - text: "我有3把黄钥匙,\n你出50金币就卖给你。", - yes: [{ - type: "if", - condition: "status:money>=50", - true: [{ - type: "setValue", - name: "status:money", - operator: "-=", - value: "50", - }, - { - type: "setValue", - name: "item:yellowKey", - operator: "+=", - value: "3", - }, - { - type: "playSound", - name: "确定", - stop: true, - }, - { - type: "setValue", - name: "switch:A", - value: "true", - }, - ], - false: [{ - type: "playSound", - name: "操作失败", - }, - "\t[行商,trader]\b[this]你的金币不足!", - ], - }, ], - no: [], - }, ], - }, ], - 全地图选中一个点: [{ - type: "comment", - text: "全地图选中一个点,需要用鼠标或触屏操作", - }, - { - type: "setValue", - name: "temp:X", - value: "status:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "status:y", - }, - { - type: "tip", - text: "再次点击闪烁位置确认", - }, - { - type: "while", - condition: "true", - data: [{ - type: "drawSelector", - image: "winskin.webp", - code: 1, - x: "32*temp:X", - y: "32*temp:Y", - width: 32, - height: 32, - }, - { - type: "wait", - }, - { - type: "if", - condition: "(flag:type === 1)", - true: [{ - type: "if", - condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", - true: [{ - type: "break", - n: 1, - }, ], - }, - { - type: "setValue", - name: "temp:X", - value: "flag:x", - }, - { - type: "setValue", - name: "temp:Y", - value: "flag:y", - }, - ], - }, - ], - }, - { - type: "drawSelector", - code: 1, - }, - { - type: "comment", - text: "流程进行到这里可以对[X,Y]点进行处理,比如", - }, - { - type: "closeDoor", - id: "yellowDoor", - loc: ["temp:X", "temp:Y"], - }, - ], - 多阶段Boss战斗: [{ - type: "comment", - text: "多阶段boss,请直接作为战后事件使用", - }, - { - type: "setValue", - name: "switch:A", - operator: "+=", - value: "1", - }, - { - type: "switch", - condition: "switch:A", - caseList: [{ - case: "1", - action: [{ - type: "setBlock", - number: "redSlime", - }, - "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", - ], - }, - { - case: "2", - action: [{ - type: "setBlock", - number: "blackSlime", - }, - "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", - ], - }, - { - case: "3", - action: [{ - type: "setBlock", - number: "slimelord", - }, - "\t[4阶段boss,slimelord]\b[this]我还能打!", - ], - }, - { - case: "4", - action: ["\t[4阶段boss,slimelord]我一定会回来的!"], - }, - ], - }, - ], - }; - } - //#endregion + if (!events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { + /** + * @type {{[EvnetName:actionParserJson]}} + */ + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate = { + 检测音乐如果没有开启则系统提示开启: [ + { + type: "if", + condition: "!core.musicStatus.bgmStatus", + true: [ + "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳", + ], + false: [], + }, + ], + 仿新新魔塔一次性商人: [ + { + type: "if", + condition: "switch:A", + true: [ + "\t[行商,trader]\b[this]这是购买我的道具后我给玩家的提示。", + { + type: "comment", + text: "下一条指令可视情况使用或不使用", + }, + { + type: "hide", + remove: true, + time: 250, + }, + ], + false: [ + { + type: "confirm", + text: "我有3把黄钥匙,\n你出50金币就卖给你。", + yes: [ + { + type: "if", + condition: "status:money>=50", + true: [ + { + type: "setValue", + name: "status:money", + operator: "-=", + value: "50", + }, + { + type: "setValue", + name: "item:yellowKey", + operator: "+=", + value: "3", + }, + { + type: "playSound", + name: "确定", + stop: true, + }, + { + type: "setValue", + name: "switch:A", + value: "true", + }, + ], + false: [ + { + type: "playSound", + name: "操作失败", + }, + "\t[行商,trader]\b[this]你的金币不足!", + ], + }, + ], + no: [], + }, + ], + }, + ], + 全地图选中一个点: [ + { + type: "comment", + text: "全地图选中一个点,需要用鼠标或触屏操作", + }, + { + type: "setValue", + name: "temp:X", + value: "status:x", + }, + { + type: "setValue", + name: "temp:Y", + value: "status:y", + }, + { + type: "tip", + text: "再次点击闪烁位置确认", + }, + { + type: "while", + condition: "true", + data: [ + { + type: "drawSelector", + image: "winskin.webp", + code: 1, + x: "32*temp:X", + y: "32*temp:Y", + width: 32, + height: 32, + }, + { + type: "wait", + }, + { + type: "if", + condition: "(flag:type === 1)", + true: [ + { + type: "if", + condition: "((temp:X===flag:x)&&(temp:Y===flag:y))", + true: [ + { + type: "break", + n: 1, + }, + ], + }, + { + type: "setValue", + name: "temp:X", + value: "flag:x", + }, + { + type: "setValue", + name: "temp:Y", + value: "flag:y", + }, + ], + }, + ], + }, + { + type: "drawSelector", + code: 1, + }, + { + type: "comment", + text: "流程进行到这里可以对[X,Y]点进行处理,比如", + }, + { + type: "closeDoor", + id: "yellowDoor", + loc: ["temp:X", "temp:Y"], + }, + ], + 多阶段Boss战斗: [ + { + type: "comment", + text: "多阶段boss,请直接作为战后事件使用", + }, + { + type: "setValue", + name: "switch:A", + operator: "+=", + value: "1", + }, + { + type: "switch", + condition: "switch:A", + caseList: [ + { + case: "1", + action: [ + { + type: "setBlock", + number: "redSlime", + }, + "\t[2阶段boss,redSlime]\b[this]你以为你已经打败我了吗?没听说过史莱姆有九条命吗?", + ], + }, + { + case: "2", + action: [ + { + type: "setBlock", + number: "blackSlime", + }, + "\t[3阶段boss,blackSlime]\b[this]不能消灭我的,只会让我更强大!", + ], + }, + { + case: "3", + action: [ + { + type: "setBlock", + number: "slimelord", + }, + "\t[4阶段boss,slimelord]\b[this]我还能打!", + ], + }, + { + case: "4", + action: ["\t[4阶段boss,slimelord]我一定会回来的!"], + }, + ], + }, + ], + }; + } + //#endregion - // 新增模板選項 - let editModeSelect = document.getElementById("editModeSelect"); - let newEditModeOption = document.createElement("option"); - newEditModeOption.value = "CommonEventTemplate"; - newEditModeOption.text = "常見事件模板"; - editModeSelect.add(newEditModeOption); + // 新增模板選項 + let editModeSelect = document.getElementById("editModeSelect"); + let newEditModeOption = document.createElement("option"); + newEditModeOption.value = "CommonEventTemplate"; + newEditModeOption.text = "常見事件模板"; + editModeSelect.add(newEditModeOption); - //檢查可用的編輯模板ID - let leftIDNumber = 11 - 1; - let ExistLeftElement = document.querySelector(".main"); - while (ExistLeftElement) { - leftIDNumber++; - ExistLeftElement = document.getElementById(`left${leftIDNumber}`); - } + //檢查可用的編輯模板ID + let leftIDNumber = 11 - 1; + let ExistLeftElement = document.querySelector(".main"); + while (ExistLeftElement) { + leftIDNumber++; + ExistLeftElement = document.getElementById(`left${leftIDNumber}`); + } - //新增編輯模板 - let MainDiv = document.querySelector(".main"); + //新增編輯模板 + let MainDiv = document.querySelector(".main"); - let CommonEventTemplateMainDiv = document.createElement("div"); - CommonEventTemplateMainDiv.id = `left${leftIDNumber}`; - CommonEventTemplateMainDiv.className = "leftTab"; - CommonEventTemplateMainDiv.style.zIndex = "-1"; - CommonEventTemplateMainDiv.style.opacity = "0"; + let CommonEventTemplateMainDiv = document.createElement("div"); + CommonEventTemplateMainDiv.id = `left${leftIDNumber}`; + CommonEventTemplateMainDiv.className = "leftTab"; + CommonEventTemplateMainDiv.style.zIndex = "-1"; + CommonEventTemplateMainDiv.style.opacity = "0"; - CommonEventTemplateMainDiv.innerHTML = ` + CommonEventTemplateMainDiv.innerHTML = `

常見事件模板   @@ -8938,958 +11877,980 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =

`; - MainDiv.appendChild(CommonEventTemplateMainDiv); + MainDiv.appendChild(CommonEventTemplateMainDiv); - (async function () { - //等待編輯器初始化 - while (!editor_mode.ids) { - await Sleep(100); - } - //新增編輯模板ID - editor_mode.ids["CommonEventTemplate"] = `left${leftIDNumber}`; - editor_mode.init_dom_ids(); - //切換至常見事件模板 - editor_mode.CommonEventTemplate = function (callback) { - var objs = []; - editor.file.editCommonEventTemplate([], function (objs_) { - objs = objs_; - //console.log(objs_) - }); - //只查询不修改时,内部实现不是异步的,所以可以这么写 - var tableinfo = editor.table.objToTable(objs[0], objs[1]); - document.getElementById( - "table_298572d8-93dd-4c6e-a278-6a7d49831e3a" - ).innerHTML = tableinfo.HTML; - tableinfo.listen(tableinfo.guids); - if (Boolean(callback)) callback(); - }; + (async function () { + //等待編輯器初始化 + while (!editor_mode.ids) { + await Sleep(100); + } + //新增編輯模板ID + editor_mode.ids["CommonEventTemplate"] = `left${leftIDNumber}`; + editor_mode.init_dom_ids(); + //切換至常見事件模板 + editor_mode.CommonEventTemplate = function (callback) { + var objs = []; + editor.file.editCommonEventTemplate([], function (objs_) { + objs = objs_; + //console.log(objs_) + }); + //只查询不修改时,内部实现不是异步的,所以可以这么写 + var tableinfo = editor.table.objToTable(objs[0], objs[1]); + document.getElementById( + "table_298572d8-93dd-4c6e-a278-6a7d49831e3a" + ).innerHTML = tableinfo.HTML; + tableinfo.listen(tableinfo.guids); + if (Boolean(callback)) callback(); + }; - //檢查配置表格存在 - let TableRowExist = null; - fs.readFile(TableFileName, "base64", function (err, data) { - if (err) { - console.log(`察覺常見事件模板配置表格不存在,原因:${err}`); - console.log("新建一個常見事件模板配置表格。"); - TableRowExist = false; - } else { - TableRowExist = true; - } - }); - //等待配置表格載入完畢(最多0.3秒,超過則視為失敗) - for (let i = 0; i < 3; i++) { - if (TableRowExist == null) { - await Sleep(100); - } - } - //配置表格初始化 - if (TableRowExist != true) { - fs.mkdir("project/table", function (err, data) { - if (err) throw `常見事件模板配置表格目錄初始化失敗,原因:${err}`; - }); - fs.writeFile( - TableFileName, - editor.util.encode64(TableRow || ""), - "base64", - function (err, data) { - if (err) throw `常見事件模板配置表格文件初始化失敗,原因:${err}`; - } - ); - } - //載入配置表格 - //editor.file.loadCommentjs(callback); - (function () { - var key = "CommonEventTemplate_comment"; - var script = document.createElement("script"); - script.src = "project/table/" + key + ".js"; - document.body.appendChild(script); - script.onload = function () { - editor.file[key] = eval(key.replace(".", "_")); - var loaded = Boolean(editor.file[key]); - }; - })(); - //按下配置表格 - editor_multi.CommonEventTemplateEditCommentJs = function (mod) { - editor_multi.lintAutocomplete = true; - editor_multi.setLint(); - editor_multi.importFile(TableFileName); - }; + //檢查配置表格存在 + let TableRowExist = null; + fs.readFile(TableFileName, "base64", function (err, data) { + if (err) { + console.log(`察覺常見事件模板配置表格不存在,原因:${err}`); + console.log("新建一個常見事件模板配置表格。"); + TableRowExist = false; + } else { + TableRowExist = true; + } + }); + //等待配置表格載入完畢(最多0.3秒,超過則視為失敗) + for (let i = 0; i < 3; i++) { + if (TableRowExist == null) { + await Sleep(100); + } + } + //配置表格初始化 + if (TableRowExist != true) { + fs.mkdir("project/table", function (err, data) { + if (err) throw `常見事件模板配置表格目錄初始化失敗,原因:${err}`; + }); + fs.writeFile( + TableFileName, + editor.util.encode64(TableRow || ""), + "base64", + function (err, data) { + if (err) throw `常見事件模板配置表格文件初始化失敗,原因:${err}`; + } + ); + } + //載入配置表格 + //editor.file.loadCommentjs(callback); + (function () { + var key = "CommonEventTemplate_comment"; + var script = document.createElement("script"); + script.src = "project/table/" + key + ".js"; + document.body.appendChild(script); + script.onload = function () { + editor.file[key] = eval(key.replace(".", "_")); + var loaded = Boolean(editor.file[key]); + }; + })(); + //按下配置表格 + editor_multi.CommonEventTemplateEditCommentJs = function (mod) { + editor_multi.lintAutocomplete = true; + editor_multi.setLint(); + editor_multi.importFile(TableFileName); + }; - //定義表格操作行為 - editor_mode.OriginDoActionList = editor_mode.doActionList; - editor_mode.doActionList = function (mode, actionList, callback) { - if (editor_mode.mode == "CommonEventTemplate") { - if (actionList.length == 0) return; - printf("修改中..."); - var cb = function (objs_) { - if (objs_.slice(-1)[0] != null) { - printe(objs_.slice(-1)[0]); - throw objs_.slice(-1)[0]; - } - var str = "修改成功!"; - if ( - data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == - "template" - ) - str += "
请注意:全塔属性的name尚未修改,请及时予以设置。"; - printf(str); - if (callback) callback(); - }; - editor.file.editCommonEventTemplate(actionList, cb); - } else { - editor_mode.OriginDoActionList(mode, actionList, callback); - } - }; - //添加表格列 - editor.table.CommonEventTemplateAddFunc = function () { - let obj = events_c12a15a8_c380_4b28_8144_256cba95f760; + //定義表格操作行為 + editor_mode.OriginDoActionList = editor_mode.doActionList; + editor_mode.doActionList = function (mode, actionList, callback) { + if (editor_mode.mode == "CommonEventTemplate") { + if (actionList.length == 0) return; + printf("修改中..."); + var cb = function (objs_) { + if (objs_.slice(-1)[0] != null) { + printe(objs_.slice(-1)[0]); + throw objs_.slice(-1)[0]; + } + var str = "修改成功!"; + if ( + data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.firstData.name == + "template" + ) + str += "
请注意:全塔属性的name尚未修改,请及时予以设置。"; + printf(str); + if (callback) callback(); + }; + editor.file.editCommonEventTemplate(actionList, cb); + } else { + editor_mode.OriginDoActionList(mode, actionList, callback); + } + }; + //添加表格列 + editor.table.CommonEventTemplateAddFunc = function () { + let obj = events_c12a15a8_c380_4b28_8144_256cba95f760; - // 1.输入id - let newid = prompt("请输入新项的ID(支持中文)"); - if (newid == null || newid.length == 0) { - return; - } + // 1.输入id + let newid = prompt("请输入新项的ID(支持中文)"); + if (newid == null || newid.length == 0) { + return; + } - // 2.检查id是否符合规范或与已有id重复 - var conflict = true; - var basefield = "".replace(/\[[^\[]*\]$/, ""); + // 2.检查id是否符合规范或与已有id重复 + var conflict = true; + var basefield = "".replace(/\[[^\[]*\]$/, ""); - try { - var baseobj = eval("obj" + basefield); - conflict = newid in baseobj; - } catch (ee) { - // 理论上这里不会发生错误 - printe(ee); - throw ee; - } + try { + var baseobj = eval("obj" + basefield); + conflict = newid in baseobj; + } catch (ee) { + // 理论上这里不会发生错误 + printe(ee); + throw ee; + } - if (conflict) { - printe("id已存在, 请直接修改该项的值"); - return; - } + if (conflict) { + printe("id已存在, 请直接修改该项的值"); + return; + } - // 3.添加 - editor_mode.addAction(["add", basefield + "['" + newid + "']", null]); - editor_mode.onmode("save", function () { - printf("添加成功,刷新后生效;也可以继续新增其他项目。"); - }); //自动保存 删掉此行的话点保存按钮才会保存 - }; - //對表格的存讀 - editor.file.editCommonEventTemplate = function (actionList, callback) { - /*actionList:[ + // 3.添加 + editor_mode.addAction(["add", basefield + "['" + newid + "']", null]); + editor_mode.onmode("save", function () { + printf("添加成功,刷新后生效;也可以继续新增其他项目。"); + }); //自动保存 删掉此行的话点保存按钮才会保存 + }; + //對表格的存讀 + editor.file.editCommonEventTemplate = function (actionList, callback) { + /*actionList:[ ["change","['test']",['123']], ] 为[]时只查询不修改 */ - var data_obj = - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate; - checkCallback(callback); - if (isset(actionList) && actionList.length > 0) { - actionList.forEach(function (value) { - value[1] = "['CommonEventTemplate']" + value[1]; - }); - editor.file.saveSetting("events", actionList, function (err) { - callback([err]); - }); - } else { - callback([ - Object.assign({}, data_obj), - editor.file.CommonEventTemplate_comment._data.CommonEventTemplate, - null, - ]); - } - }; - })(); + var data_obj = + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate; + checkCallback(callback); + if (isset(actionList) && actionList.length > 0) { + actionList.forEach(function (value) { + value[1] = "['CommonEventTemplate']" + value[1]; + }); + editor.file.saveSetting("events", actionList, function (err) { + callback([err]); + }); + } else { + callback([ + Object.assign({}, data_obj), + editor.file.CommonEventTemplate_comment._data.CommonEventTemplate, + null, + ]); + } + }; + })(); - //複寫事件編輯器(editor_blocklyconfig) - editor_blocklyconfig = function () { - // start mark sfergsvae + //複寫事件編輯器(editor_blocklyconfig) + editor_blocklyconfig = function () { + // start mark sfergsvae - (function () { - var getCategory = function (name, custom) { - for (var node of document.getElementById("toolbox").children) { - if (node.getAttribute("name") == name) return node; - } - var node = document.createElement("category"); - node.setAttribute("name", name); - if (custom) node.setAttribute("custom", custom); - document.getElementById("toolbox").appendChild(node); - return node; - }; + (function () { + var getCategory = function (name, custom) { + for (var node of document.getElementById("toolbox").children) { + if (node.getAttribute("name") == name) return node; + } + var node = document.createElement("category"); + node.setAttribute("name", name); + if (custom) node.setAttribute("custom", custom); + document.getElementById("toolbox").appendChild(node); + return node; + }; - var toolboxObj = { - 入口方块: [ - '', - MotaActionFunctions.actionParser.parse( - [ - "欢迎使用事件编辑器", - "本事件触发一次后会消失", - { type: "hide", time: 500 }, - ], - "event" - ), - MotaActionFunctions.actionParser.parse({ - condition: "flag:__door__===2", - currentFloor: true, - priority: 0, - delayExecute: false, - multiExecute: false, - data: [{ type: "openDoor", loc: [10, 5] }], - }, - "autoEvent" - ), - MotaActionBlocks["changeFloor_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [{ - id: "shop1", - text: "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", - textInList: "1F金币商店", - choices: [{ - text: "生命+800", - need: "status:money>=20+2*flag:shop1", - action: [{ - type: "comment", - text: "新版商店中需要手动扣减金币和增加访问次数", - }, - { - type: "setValue", - name: "status:money", - operator: "-=", - value: "20+2*flag:shop1", - }, - { - type: "setValue", - name: "flag:shop1", - operator: "+=", - value: "1", - }, - { - type: "setValue", - name: "status:hp", - operator: "+=", - value: "800", - }, - ], - }, ], - }, - { - id: "itemShop", - item: true, - textInList: "道具商店", - choices: [{ id: "yellowKey", number: 10, money: 10 }], - }, - { - id: "keyShop1", - textInList: "回收钥匙商店", - commonEvent: "回收钥匙商店", - args: "", - }, - ], - "shop" - ), - MotaActionBlocks["common_m"].xmlText(), - MotaActionBlocks["beforeBattle_m"].xmlText(), - MotaActionBlocks["afterBattle_m"].xmlText(), - MotaActionBlocks["afterGetItem_m"].xmlText(), - MotaActionBlocks["afterOpenDoor_m"].xmlText(), - MotaActionBlocks["firstArrive_m"].xmlText(), - MotaActionBlocks["eachArrive_m"].xmlText(), - MotaActionBlocks["level_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [ - ["MTx", ""] - ], - "floorPartition" - ), - MotaActionBlocks["commonEvent_m"].xmlText(), - MotaActionBlocks["item_m"].xmlText(), - MotaActionFunctions.actionParser.parse( - [{ - title: "简单", - name: "Easy", - hard: 1, - action: [ - { type: "comment", text: "在这里写该难度需执行的事件" }, - ], - }, ], - "levelChoose" - ), - MotaActionFunctions.actionParser.parse({ - type: 0, - value: { atk: 10 }, - percentage: { speed: 10 }, - }, - "equip" - ), - MotaActionFunctions.actionParser.parse( - [{ - name: "bg.webp", - x: 0, - y: 0, - canvas: "bg", - }, ], - "floorImage" - ), - MotaActionFunctions.actionParser.parse({ - time: 160, - openSound: "door.mp3", - closeSound: "door.mp3", - keys: { yellowKey: 1, orangeKey: 1 }, - }, - "doorInfo" - ), - MotaActionBlocks["faceIds_m"].xmlText(), - MotaActionBlocks["mainStyle_m"].xmlText(), - MotaActionFunctions.actionParser.parse({ - 背景音乐: "bgm.mp3", - 确定: "confirm.mp3", - 攻击: "attack.mp3", - 背景图: "bg.webp", - 领域: "zone", - 文件名: "file.jpg", - }, - "nameMap" - ), - MotaActionFunctions.actionParser.parse( - [{ name: "hero.webp", width: 32, height: 32, prefix: "hero_" }], - "splitImages" - ), - ], - 显示文字: [ - MotaActionBlocks["text_0_s"].xmlText(), - MotaActionBlocks["text_1_s"].xmlText(), - MotaActionFunctions.actionParser.parseList( - "\t[小妖精,fairy]\f[fairy.webp,0,0]欢迎使用事件编辑器(双击方块可直接预览)" - ), - MotaActionBlocks["over_s"].xmlText(), - MotaActionFunctions.actionParser.parseList([{ - type: "overlist", - image: "bg_5043.webp", - memory: false, - hidetime: 30, - list: [{ - text: "", - sound: "", - time: 50, - textColor: "255,255,255,1", - boldColor: "0,0,0,1", - font: "bold 48px Verdana", - frame: 0, - }, ], - }, ]), - MotaActionFunctions.actionParser.parseList([{ - type: "cgtext", - bg: "bg_5043.webp", - memory: false, - WindowSkin: false, - head: { name: "face_050445.webp", px: -300 }, - name: "菲奥奈", - time: 0, - wait: 2000, - sound: "", - text: "这句话显示在对话框内", - bodyList: [ - { name: "tati_050145a.webp", px: 100, filter: false }, - ], - }, ]), - MotaActionBlocks["moveTextBox_s"].xmlText(), - MotaActionBlocks["clearTextBox_s"].xmlText(), - MotaActionBlocks["comment_s"].xmlText(), - MotaActionBlocks["autoText_s"].xmlText(), - MotaActionBlocks["scrollText_s"].xmlText(), - MotaActionBlocks["setText_s"].xmlText(), - MotaActionBlocks["tip_s"].xmlText(), - MotaActionBlocks["addPop_s"].xmlText(), - MotaActionBlocks["confirm_s"].xmlText(), - MotaActionBlocks["choices_s"].xmlText([ - "选择剑或者盾", - "流浪者", - "man", - 0, - "", - MotaActionBlocks["choicesContext"].xmlText([ - "剑", - "", - "", - null, - "", - "", - MotaActionFunctions.actionParser.parseList([ - { type: "openDoor", loc: [3, 3] }, - ]), - ]), - ]), - MotaActionBlocks["win_s"].xmlText(), - MotaActionBlocks["lose_s"].xmlText(), - MotaActionBlocks["restart_s"].xmlText(), - ], - 数据相关: [ - MotaActionBlocks["setValue_s"].xmlText([ - MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), - "=", - "", - false, - ]), - MotaActionBlocks["setEnemy_s"].xmlText(), - MotaActionBlocks["setEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["resetEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["moveEnemyOnPoint_s"].xmlText(), - MotaActionBlocks["moveEnemyOnPoint_1_s"].xmlText(), - MotaActionBlocks["setEquip_s"].xmlText(), - MotaActionBlocks["setFloor_s"].xmlText(), - MotaActionBlocks["setGlobalAttribute_s"].xmlText(), - MotaActionBlocks["setGlobalValue_s"].xmlText(), - MotaActionBlocks["setGlobalFlag_s"].xmlText(), - MotaActionBlocks["setNameMap_s"].xmlText(), - MotaActionBlocks["input_s"].xmlText(), - MotaActionBlocks["input2_s"].xmlText(), - MotaActionBlocks["update_s"].xmlText(), - MotaActionBlocks["moveAction_s"].xmlText(), - MotaActionBlocks["changeFloor_s"].xmlText(), - MotaActionBlocks["changePos_s"].xmlText(), - MotaActionBlocks["battle_s"].xmlText(), - MotaActionBlocks["useItem_s"].xmlText(), - MotaActionBlocks["loadEquip_s"].xmlText(), - MotaActionBlocks["unloadEquip_s"].xmlText(), - MotaActionBlocks["openShop_s"].xmlText(), - MotaActionBlocks["disableShop_s"].xmlText(), - MotaActionBlocks["setHeroIcon_s"].xmlText(), - MotaActionBlocks["follow_s"].xmlText(), - MotaActionBlocks["unfollow_s"].xmlText(), - ], - 地图处理: [ - MotaActionBlocks["battle_1_s"].xmlText(), - MotaActionBlocks["openDoor_s"].xmlText(), - MotaActionBlocks["closeDoor_s"].xmlText(), - MotaActionBlocks["show_s"].xmlText(), - MotaActionBlocks["hide_s"].xmlText(), - MotaActionBlocks["setBlock_s"].xmlText(), - MotaActionBlocks["setBlockOpacity_s"].xmlText(), - MotaActionBlocks["setBlockFilter_s"].xmlText(), - MotaActionBlocks["turnBlock_s"].xmlText(), - MotaActionBlocks["moveHero_s"].xmlText(), - MotaActionBlocks["move_s"].xmlText(), - MotaActionBlocks["jumpHero_s"].xmlText(), - MotaActionBlocks["jumpHero_1_s"].xmlText(), - MotaActionBlocks["jump_s"].xmlText(), - MotaActionBlocks["jump_1_s"].xmlText(), - MotaActionBlocks["showBgFgMap_s"].xmlText(), - MotaActionBlocks["hideBgFgMap_s"].xmlText(), - MotaActionBlocks["setBgFgBlock_s"].xmlText(), - MotaActionBlocks["showFloorImg_s"].xmlText(), - MotaActionBlocks["hideFloorImg_s"].xmlText(), - ], - 事件控制: [ - MotaActionBlocks["if_1_s"].xmlText(), - MotaActionBlocks["if_s"].xmlText(), - MotaActionFunctions.actionParser.parseList({ - type: "switch", - condition: "判别值", - caseList: [{ - action: [ - { type: "comment", text: "当判别值是值的场合执行此事件" }, - ], - }, - { - case: "default", - action: [{ - type: "comment", - text: "当没有符合的值的场合执行default事件", - }, ], - }, - ], - }), - MotaActionFunctions.actionParser.parseList({ - type: "for", - name: "temp:A", - from: "0", - to: "12", - step: "1", - data: [], - }), - MotaActionFunctions.actionParser.parseList({ - type: "forEach", - name: "temp:A", - list: ["status:atk", "status:def"], - data: [], - }), - MotaActionBlocks["while_s"].xmlText(), - MotaActionBlocks["dowhile_s"].xmlText(), - MotaActionBlocks["break_s"].xmlText(), - MotaActionBlocks["continue_s"].xmlText(), - MotaActionBlocks["exit_s"].xmlText(), - MotaActionBlocks["trigger_s"].xmlText(), - MotaActionBlocks["insert_1_s"].xmlText(), - MotaActionBlocks["insert_2_s"].xmlText(), - ], - 特效表现: [ - MotaActionBlocks["sleep_s"].xmlText(), - MotaActionBlocks["changebg_s"].xmlText(), - MotaActionFunctions.actionParser.parseList({ - type: "wait", - timeout: 0, - data: [{ - case: "keyboard", - keycode: "13,32", - action: [{ - type: "comment", - text: "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout", - }, ], - }, - { - case: "mouse", - px: [0, 32], - py: [0, 32], - action: [{ - type: "comment", - text: "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout", - }, ], - }, - { - case: "condition", - condition: "flag:type==0\n&&flag:keycode==13", - action: [{ - type: "comment", - text: "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout", - }, ], - }, - { - case: "timeout", - action: [ - { type: "comment", text: "当超时未操作时执行此事件" }, - ], - }, - ], - }), - MotaActionBlocks["waitAsync_s"].xmlText(), - MotaActionBlocks["stopAsync_s"].xmlText(), - MotaActionBlocks["op_s"].xmlText(), - MotaActionBlocks["drawWarning_s"].xmlText(), - MotaActionBlocks["changeMouse_s"].xmlText(), - MotaActionBlocks["removeMouse_s"].xmlText(), - MotaActionBlocks["vibrate_s"].xmlText(), - MotaActionBlocks["setanimate_s"].xmlText(), - MotaActionBlocks["deleteanimate_s"].xmlText(), - MotaActionBlocks["playanimate_s"].xmlText(), - MotaActionBlocks["clearanimate_s"].xmlText(), - MotaActionBlocks["animate_s"].xmlText(), - MotaActionBlocks["animate_1_s"].xmlText(), - MotaActionBlocks["stopAnimate_s"].xmlText(), - MotaActionBlocks["setViewport_s"].xmlText(), - MotaActionBlocks["setViewport_1_s"].xmlText(), - MotaActionBlocks["lockViewport_s"].xmlText(), - MotaActionBlocks["showStatusBar_s"].xmlText(), - MotaActionBlocks["hideStatusBar_s"].xmlText(), - MotaActionBlocks["setHeroOpacity_s"].xmlText(), - MotaActionBlocks["setCurtain_0_s"].xmlText(), - MotaActionBlocks["setCurtain_1_s"].xmlText(), - MotaActionBlocks["screenFlash_s"].xmlText(), - MotaActionBlocks["setWeather_s"].xmlText(), - MotaActionBlocks["callBook_s"].xmlText(), - MotaActionBlocks["callSave_s"].xmlText(), - MotaActionBlocks["autoSave_s"].xmlText(), - MotaActionBlocks["forbidSave_s"].xmlText(), - MotaActionBlocks["callLoad_s"].xmlText(), - ], - 音像处理: [ - MotaActionBlocks["animationDrawable_s"].xmlText(), - MotaActionBlocks["setanimate_s"].xmlText(), - MotaActionBlocks["deleteanimate_s"].xmlText(), - MotaActionBlocks["playanimate_s"].xmlText(), - MotaActionBlocks["clearanimate_s"].xmlText(), - MotaActionBlocks["showImage_s"].xmlText(), - MotaActionBlocks["showImage_1_s"].xmlText(), - MotaActionBlocks["hideImage_s"].xmlText(), - MotaActionBlocks["showTextImage_s"].xmlText(), - MotaActionBlocks["moveImage_s"].xmlText(), - MotaActionBlocks["rotateImage_s"].xmlText(), - MotaActionBlocks["scaleImage_s"].xmlText(), - MotaActionBlocks["showGif_s"].xmlText(), - MotaActionBlocks["playBgm_s"].xmlText(), - MotaActionBlocks["playStereo_s"].xmlText(), - MotaActionBlocks["moveStereo_s"].xmlText(), - MotaActionBlocks["pauseBgm_s"].xmlText(), - MotaActionBlocks["resumeBgm_s"].xmlText(), - MotaActionBlocks["loadBgm_s"].xmlText(), - MotaActionBlocks["freeBgm_s"].xmlText(), - MotaActionBlocks["playSound_s"].xmlText(), - MotaActionBlocks["playSound_1_s"].xmlText(), - MotaActionBlocks["stopSound_s"].xmlText(), - MotaActionBlocks["setVolume_s"].xmlText(), - MotaActionBlocks["setBgmSpeed_s"].xmlText(), - ], - UI绘制: [ - MotaActionBlocks["previewUI_s"].xmlText(), - MotaActionBlocks["clearMap_s"].xmlText(), - MotaActionBlocks["setAttribute_s"].xmlText(), - MotaActionBlocks["setFilter_s"].xmlText(), - MotaActionBlocks["fillText_s"].xmlText(), - MotaActionBlocks["fillBoldText_s"].xmlText(), - MotaActionBlocks["drawTextContent_s"].xmlText(), - MotaActionBlocks["fillRect_s"].xmlText(), - MotaActionBlocks["strokeRect_s"].xmlText(), - MotaActionBlocks["drawLine_s"].xmlText(), - MotaActionBlocks["drawArrow_s"].xmlText(), - MotaActionBlocks["fillPolygon_s"].xmlText(), - MotaActionBlocks["strokePolygon_s"].xmlText(), - MotaActionBlocks["fillEllipse_s"].xmlText(), - MotaActionBlocks["strokeEllipse_s"].xmlText(), - MotaActionBlocks["fillArc_s"].xmlText(), - MotaActionBlocks["strokeArc_s"].xmlText(), - MotaActionBlocks["drawImage_s"].xmlText(), - MotaActionBlocks["drawImage_1_s"].xmlText(), - MotaActionBlocks["drawIcon_s"].xmlText(), - MotaActionBlocks["drawBackground_s"].xmlText(), - MotaActionBlocks["drawSelector_s"].xmlText(), - MotaActionBlocks["drawSelector_1_s"].xmlText(), - ], - 原生脚本: [ - MotaActionBlocks["function_s"].xmlText(), - MotaActionBlocks["unknown_s"].xmlText(), - ], - 值块: [ - MotaActionBlocks["setValue_s"].xmlText([ - MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), - "=", - "", - false, - ]), - MotaActionBlocks["expression_arithmetic_0"].xmlText(), - MotaActionBlocks["idFlag_e"].xmlText(), - MotaActionBlocks["idTemp_e"].xmlText(), - MotaActionBlocks["negate_e"].xmlText(), - MotaActionBlocks["unaryOperation_e"].xmlText(), - MotaActionBlocks["bool_e"].xmlText(), - MotaActionBlocks["idString_e"].xmlText(), - MotaActionBlocks["idIdList_e"].xmlText(), - MotaActionBlocks["idFixedList_e"].xmlText(), - MotaActionBlocks["enemyattr_e"].xmlText(), - MotaActionBlocks["blockId_e"].xmlText(), - MotaActionBlocks["blockNumber_e"].xmlText(), - MotaActionBlocks["blockCls_e"].xmlText(), - MotaActionBlocks["hasEquip_e"].xmlText(), - MotaActionBlocks["equip_e"].xmlText(), - MotaActionBlocks["nextXY_e"].xmlText(), - MotaActionBlocks["isReplaying_e"].xmlText(), - MotaActionBlocks["hasVisitedFloor_e"].xmlText(), - MotaActionBlocks["isShopVisited_e"].xmlText(), - MotaActionBlocks["canBattle_e"].xmlText(), - MotaActionBlocks["damage_e"].xmlText(), - MotaActionBlocks["damage_1_e"].xmlText(), - MotaActionBlocks["rand_e"].xmlText(), - MotaActionBlocks["evalString_e"].xmlText(), - ], - 常见事件模板: [ - '', - ], - 最近使用事件: [ - '', - ], - }; - var toolboxgap = ''; - //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') - //MotaActionBlocks['idString_e'].xmlText() + var toolboxObj = { + 入口方块: [ + '', + MotaActionFunctions.actionParser.parse( + [ + "欢迎使用事件编辑器", + "本事件触发一次后会消失", + { type: "hide", time: 500 }, + ], + "event" + ), + MotaActionFunctions.actionParser.parse( + { + condition: "flag:__door__===2", + currentFloor: true, + priority: 0, + delayExecute: false, + multiExecute: false, + data: [{ type: "openDoor", loc: [10, 5] }], + }, + "autoEvent" + ), + MotaActionBlocks["changeFloor_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [ + { + id: "shop1", + text: "\t[贪婪之神,moneyShop]勇敢的武士啊, 给我${20+2*flag:shop1}金币就可以:", + textInList: "1F金币商店", + choices: [ + { + text: "生命+800", + need: "status:money>=20+2*flag:shop1", + action: [ + { + type: "comment", + text: "新版商店中需要手动扣减金币和增加访问次数", + }, + { + type: "setValue", + name: "status:money", + operator: "-=", + value: "20+2*flag:shop1", + }, + { + type: "setValue", + name: "flag:shop1", + operator: "+=", + value: "1", + }, + { + type: "setValue", + name: "status:hp", + operator: "+=", + value: "800", + }, + ], + }, + ], + }, + { + id: "itemShop", + item: true, + textInList: "道具商店", + choices: [{ id: "yellowKey", number: 10, money: 10 }], + }, + { + id: "keyShop1", + textInList: "回收钥匙商店", + commonEvent: "回收钥匙商店", + args: "", + }, + ], + "shop" + ), + MotaActionBlocks["common_m"].xmlText(), + MotaActionBlocks["beforeBattle_m"].xmlText(), + MotaActionBlocks["afterBattle_m"].xmlText(), + MotaActionBlocks["afterGetItem_m"].xmlText(), + MotaActionBlocks["afterOpenDoor_m"].xmlText(), + MotaActionBlocks["firstArrive_m"].xmlText(), + MotaActionBlocks["eachArrive_m"].xmlText(), + MotaActionBlocks["level_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [["MTx", ""]], + "floorPartition" + ), + MotaActionBlocks["commonEvent_m"].xmlText(), + MotaActionBlocks["item_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + [ + { + title: "简单", + name: "Easy", + hard: 1, + action: [ + { type: "comment", text: "在这里写该难度需执行的事件" }, + ], + }, + ], + "levelChoose" + ), + MotaActionFunctions.actionParser.parse( + { + type: 0, + value: { atk: 10 }, + percentage: { speed: 10 }, + }, + "equip" + ), + MotaActionFunctions.actionParser.parse( + [ + { + name: "bg.webp", + x: 0, + y: 0, + canvas: "bg", + }, + ], + "floorImage" + ), + MotaActionFunctions.actionParser.parse( + { + time: 160, + openSound: "door.opus", + closeSound: "door.opus", + keys: { yellowKey: 1, orangeKey: 1 }, + }, + "doorInfo" + ), + MotaActionBlocks["faceIds_m"].xmlText(), + MotaActionBlocks["mainStyle_m"].xmlText(), + MotaActionFunctions.actionParser.parse( + { + 背景音乐: "bgm.opus", + 确定: "confirm.opus", + 攻击: "attack.opus", + 背景图: "bg.webp", + 领域: "zone", + 文件名: "file.jpg", + }, + "nameMap" + ), + MotaActionFunctions.actionParser.parse( + [{ name: "hero.webp", width: 32, height: 32, prefix: "hero_" }], + "splitImages" + ), + ], + 显示文字: [ + MotaActionBlocks["text_0_s"].xmlText(), + MotaActionBlocks["text_1_s"].xmlText(), + MotaActionFunctions.actionParser.parseList( + "\t[小妖精,fairy]\f[fairy.webp,0,0]欢迎使用事件编辑器(双击方块可直接预览)" + ), + MotaActionBlocks["over_s"].xmlText(), + MotaActionFunctions.actionParser.parseList([ + { + type: "overlist", + image: "bg_5043.webp", + memory: false, + hidetime: 30, + list: [ + { + text: "", + sound: "", + time: 50, + textColor: "255,255,255,1", + boldColor: "0,0,0,1", + font: "bold 48px Verdana", + frame: 0, + }, + ], + }, + ]), + MotaActionBlocks["cgtextList_s"].xmlText(), + MotaActionFunctions.actionParser.parseList([ + { + type: "cgtext", + bg: "bg_5043.webp", + memory: false, + WindowSkin: false, + index: 0, + head: { name: "face_050445.webp", px: -300 }, - //#region 動態常見事件模板 - let CommonEventTemplateHTML = []; + time: 0, + wait: 2000, + sound: "", - for (let commonEventName in events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { - if ( - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate.hasOwnProperty( - commonEventName - ) - ) { - let actionParserJson = Array.from( - events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate[ - commonEventName - ] ?? [] - ); + bodyList: [ + { name: "tati_050145a.webp", px: 100, filter: false }, + ], + }, + ]), + MotaActionBlocks["moveTextBox_s"].xmlText(), + MotaActionBlocks["clearTextBox_s"].xmlText(), + MotaActionBlocks["comment_s"].xmlText(), + MotaActionBlocks["autoText_s"].xmlText(), + MotaActionBlocks["scrollText_s"].xmlText(), + MotaActionBlocks["setText_s"].xmlText(), + MotaActionBlocks["tip_s"].xmlText(), + MotaActionBlocks["addPop_s"].xmlText(), + MotaActionBlocks["confirm_s"].xmlText(), + MotaActionBlocks["choices_s"].xmlText([ + "选择剑或者盾", + "流浪者", + "man", + 0, + "", + MotaActionBlocks["choicesContext"].xmlText([ + "剑", + "", + "", + null, + "", + "", + MotaActionFunctions.actionParser.parseList([ + { type: "openDoor", loc: [3, 3] }, + ]), + ]), + ]), + MotaActionBlocks["win_s"].xmlText(), + MotaActionBlocks["lose_s"].xmlText(), + MotaActionBlocks["restart_s"].xmlText(), + ], + 数据相关: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["setEnemy_s"].xmlText(), + MotaActionBlocks["setEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["resetEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_s"].xmlText(), + MotaActionBlocks["moveEnemyOnPoint_1_s"].xmlText(), + MotaActionBlocks["setEquip_s"].xmlText(), + MotaActionBlocks["setFloor_s"].xmlText(), + MotaActionBlocks["setGlobalAttribute_s"].xmlText(), + MotaActionBlocks["setGlobalValue_s"].xmlText(), + MotaActionBlocks["setGlobalFlag_s"].xmlText(), + MotaActionBlocks["setNameMap_s"].xmlText(), + MotaActionBlocks["input_s"].xmlText(), + MotaActionBlocks["input2_s"].xmlText(), + MotaActionBlocks["update_s"].xmlText(), + MotaActionBlocks["moveAction_s"].xmlText(), + MotaActionBlocks["changeFloor_s"].xmlText(), + MotaActionBlocks["changePos_s"].xmlText(), + MotaActionBlocks["battle_s"].xmlText(), + MotaActionBlocks["useItem_s"].xmlText(), + MotaActionBlocks["loadEquip_s"].xmlText(), + MotaActionBlocks["unloadEquip_s"].xmlText(), + MotaActionBlocks["openShop_s"].xmlText(), + MotaActionBlocks["disableShop_s"].xmlText(), + MotaActionBlocks["setHeroIcon_s"].xmlText(), + MotaActionBlocks["follow_s"].xmlText(), + MotaActionBlocks["unfollow_s"].xmlText(), + ], + 地图处理: [ + MotaActionBlocks["battle_1_s"].xmlText(), + MotaActionBlocks["openDoor_s"].xmlText(), + MotaActionBlocks["closeDoor_s"].xmlText(), + MotaActionBlocks["show_s"].xmlText(), + MotaActionBlocks["hide_s"].xmlText(), + MotaActionBlocks["setBlock_s"].xmlText(), + MotaActionBlocks["setBlockOpacity_s"].xmlText(), + MotaActionBlocks["setBlockFilter_s"].xmlText(), + MotaActionBlocks["turnBlock_s"].xmlText(), + MotaActionBlocks["moveHero_s"].xmlText(), + MotaActionBlocks["move_s"].xmlText(), + MotaActionBlocks["jumpHero_s"].xmlText(), + MotaActionBlocks["jumpHero_1_s"].xmlText(), + MotaActionBlocks["jump_s"].xmlText(), + MotaActionBlocks["jump_1_s"].xmlText(), + MotaActionBlocks["showBgFgMap_s"].xmlText(), + MotaActionBlocks["hideBgFgMap_s"].xmlText(), + MotaActionBlocks["setBgFgBlock_s"].xmlText(), + MotaActionBlocks["showFloorImg_s"].xmlText(), + MotaActionBlocks["hideFloorImg_s"].xmlText(), + ], + 事件控制: [ + MotaActionBlocks["if_1_s"].xmlText(), + MotaActionBlocks["if_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "switch", + condition: "判别值", + caseList: [ + { + action: [ + { type: "comment", text: "当判别值是值的场合执行此事件" }, + ], + }, + { + case: "default", + action: [ + { + type: "comment", + text: "当没有符合的值的场合执行default事件", + }, + ], + }, + ], + }), + MotaActionFunctions.actionParser.parseList({ + type: "for", + name: "temp:A", + from: "0", + to: "12", + step: "1", + data: [], + }), + MotaActionFunctions.actionParser.parseList({ + type: "forEach", + name: "temp:A", + list: ["status:atk", "status:def"], + data: [], + }), + MotaActionBlocks["while_s"].xmlText(), + MotaActionBlocks["dowhile_s"].xmlText(), + MotaActionBlocks["break_s"].xmlText(), + MotaActionBlocks["continue_s"].xmlText(), + MotaActionBlocks["exit_s"].xmlText(), + MotaActionBlocks["trigger_s"].xmlText(), + MotaActionBlocks["insert_1_s"].xmlText(), + MotaActionBlocks["insert_2_s"].xmlText(), + ], + 特效表现: [ + MotaActionBlocks["sleep_s"].xmlText(), + MotaActionBlocks["setq_s"].xmlText(), + MotaActionBlocks["setcgs_s"].xmlText(), + MotaActionBlocks["setmusics_s"].xmlText(), + MotaActionBlocks["changebg_s"].xmlText(), + MotaActionFunctions.actionParser.parseList({ + type: "wait", + timeout: 0, + data: [ + { + case: "keyboard", + keycode: "13,32", + action: [ + { + type: "comment", + text: "当按下回车(keycode=13)或空格(keycode=32)时执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "mouse", + px: [0, 32], + py: [0, 32], + action: [ + { + type: "comment", + text: "当点击地图左上角时执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "condition", + condition: "flag:type==0\n&&flag:keycode==13", + action: [ + { + type: "comment", + text: "当满足自定义条件时会执行此事件\n超时剩余时间会写入flag:timeout", + }, + ], + }, + { + case: "timeout", + action: [ + { type: "comment", text: "当超时未操作时执行此事件" }, + ], + }, + ], + }), + MotaActionBlocks["waitAsync_s"].xmlText(), + MotaActionBlocks["stopAsync_s"].xmlText(), + MotaActionBlocks["op_s"].xmlText(), + MotaActionBlocks["drawWarning_s"].xmlText(), + MotaActionBlocks["changeMouse_s"].xmlText(), + MotaActionBlocks["removeMouse_s"].xmlText(), + MotaActionBlocks["vibrate_s"].xmlText(), + MotaActionBlocks["animate_s"].xmlText(), + MotaActionBlocks["animate_1_s"].xmlText(), + MotaActionBlocks["stopAnimate_s"].xmlText(), + MotaActionBlocks["setViewport_s"].xmlText(), + MotaActionBlocks["setViewport_1_s"].xmlText(), + MotaActionBlocks["lockViewport_s"].xmlText(), + MotaActionBlocks["showStatusBar_s"].xmlText(), + MotaActionBlocks["hideStatusBar_s"].xmlText(), + MotaActionBlocks["setHeroOpacity_s"].xmlText(), + MotaActionBlocks["setCurtain_0_s"].xmlText(), + MotaActionBlocks["setCurtain_1_s"].xmlText(), + MotaActionBlocks["screenFlash_s"].xmlText(), + MotaActionBlocks["setWeather_s"].xmlText(), + MotaActionBlocks["callBook_s"].xmlText(), + MotaActionBlocks["callSave_s"].xmlText(), + MotaActionBlocks["autoSave_s"].xmlText(), + MotaActionBlocks["forbidSave_s"].xmlText(), + MotaActionBlocks["callLoad_s"].xmlText(), + ], + 音像处理: [ + MotaActionBlocks["animationDrawable_s"].xmlText(), + MotaActionBlocks["introAndLoop_s"].xmlText(), + MotaActionBlocks["setanimate_s"].xmlText(), + MotaActionBlocks["deleteanimate_s"].xmlText(), + MotaActionBlocks["playanimate_s"].xmlText(), + MotaActionBlocks["clearanimate_s"].xmlText(), + MotaActionBlocks["showImage_s"].xmlText(), + MotaActionBlocks["showImage_1_s"].xmlText(), + MotaActionBlocks["hideImage_s"].xmlText(), + MotaActionBlocks["showTextImage_s"].xmlText(), + MotaActionBlocks["moveImage_s"].xmlText(), + MotaActionBlocks["rotateImage_s"].xmlText(), + MotaActionBlocks["scaleImage_s"].xmlText(), + MotaActionBlocks["showGif_s"].xmlText(), + MotaActionBlocks["playBgm_s"].xmlText(), + MotaActionBlocks["pauseBgm_s"].xmlText(), + MotaActionBlocks["resumeBgm_s"].xmlText(), + MotaActionBlocks["loadBgm_s"].xmlText(), + MotaActionBlocks["freeBgm_s"].xmlText(), + MotaActionBlocks["playSound_s"].xmlText(), + MotaActionBlocks["playSound_1_s"].xmlText(), + MotaActionBlocks["stopSound_s"].xmlText(), + MotaActionBlocks["setVolume_s"].xmlText(), + MotaActionBlocks["setBgmSpeed_s"].xmlText(), + ], + UI绘制: [ + MotaActionBlocks["previewUI_s"].xmlText(), + MotaActionBlocks["clearMap_s"].xmlText(), + MotaActionBlocks["setAttribute_s"].xmlText(), + MotaActionBlocks["setFilter_s"].xmlText(), + MotaActionBlocks["fillText_s"].xmlText(), + MotaActionBlocks["fillBoldText_s"].xmlText(), + MotaActionBlocks["drawTextContent_s"].xmlText(), + MotaActionBlocks["fillRect_s"].xmlText(), + MotaActionBlocks["strokeRect_s"].xmlText(), + MotaActionBlocks["drawLine_s"].xmlText(), + MotaActionBlocks["drawArrow_s"].xmlText(), + MotaActionBlocks["fillPolygon_s"].xmlText(), + MotaActionBlocks["strokePolygon_s"].xmlText(), + MotaActionBlocks["fillEllipse_s"].xmlText(), + MotaActionBlocks["strokeEllipse_s"].xmlText(), + MotaActionBlocks["fillArc_s"].xmlText(), + MotaActionBlocks["strokeArc_s"].xmlText(), + MotaActionBlocks["drawImage_s"].xmlText(), + MotaActionBlocks["drawImage_1_s"].xmlText(), + MotaActionBlocks["drawIcon_s"].xmlText(), + MotaActionBlocks["drawBackground_s"].xmlText(), + MotaActionBlocks["drawSelector_s"].xmlText(), + MotaActionBlocks["drawSelector_1_s"].xmlText(), + ], + 原生脚本: [ + MotaActionBlocks["function_s"].xmlText(), + MotaActionBlocks["unknown_s"].xmlText(), + ], + 值块: [ + MotaActionBlocks["setValue_s"].xmlText([ + MotaActionBlocks["idIdList_e"].xmlText(["status", "生命"]), + "=", + "", + false, + ]), + MotaActionBlocks["expression_arithmetic_0"].xmlText(), + MotaActionBlocks["idFlag_e"].xmlText(), + MotaActionBlocks["idTemp_e"].xmlText(), + MotaActionBlocks["negate_e"].xmlText(), + MotaActionBlocks["unaryOperation_e"].xmlText(), + MotaActionBlocks["bool_e"].xmlText(), + MotaActionBlocks["idString_e"].xmlText(), + MotaActionBlocks["idIdList_e"].xmlText(), + MotaActionBlocks["idFixedList_e"].xmlText(), + MotaActionBlocks["enemyattr_e"].xmlText(), + MotaActionBlocks["blockId_e"].xmlText(), + MotaActionBlocks["blockNumber_e"].xmlText(), + MotaActionBlocks["blockCls_e"].xmlText(), + MotaActionBlocks["hasEquip_e"].xmlText(), + MotaActionBlocks["equip_e"].xmlText(), + MotaActionBlocks["nextXY_e"].xmlText(), + MotaActionBlocks["isReplaying_e"].xmlText(), + MotaActionBlocks["hasVisitedFloor_e"].xmlText(), + MotaActionBlocks["isShopVisited_e"].xmlText(), + MotaActionBlocks["canBattle_e"].xmlText(), + MotaActionBlocks["damage_e"].xmlText(), + MotaActionBlocks["damage_1_e"].xmlText(), + MotaActionBlocks["rand_e"].xmlText(), + MotaActionBlocks["evalString_e"].xmlText(), + ], + 常见事件模板: [ + '', + ], + 最近使用事件: [ + '', + ], + }; + var toolboxgap = ''; + //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') + //MotaActionBlocks['idString_e'].xmlText() - let labelHTML = ""; - let blockHTML = ""; + //#region 動態常見事件模板 + let CommonEventTemplateHTML = []; - labelHTML = ``; + for (let commonEventName in events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate) { + if ( + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate.hasOwnProperty( + commonEventName + ) + ) { + let actionParserJson = Array.from( + events_c12a15a8_c380_4b28_8144_256cba95f760.CommonEventTemplate[ + commonEventName + ] ?? [] + ); - if (actionParserJson.length > 1) { - actionParserJson = { - type: "if", - condition: "true", - true: actionParserJson, - }; - } else if (actionParserJson.length < 1) { - actionParserJson = [ - "空的常用事件模板。\n請在主頁下拉菜單中,選擇常用事件模板,進行編輯。\n編輯後需按F5刷新事件編輯器。", - ]; - } - blockHTML = - MotaActionFunctions.actionParser.parseList(actionParserJson); + let labelHTML = ""; + let blockHTML = ""; - CommonEventTemplateHTML.push(labelHTML); - CommonEventTemplateHTML.push(blockHTML); - } - } + labelHTML = ``; - toolboxObj["常见事件模板"] = CommonEventTemplateHTML; - //#endregion + if (actionParserJson.length > 1) { + actionParserJson = { + type: "if", + condition: "true", + true: actionParserJson, + }; + } else if (actionParserJson.length < 1) { + actionParserJson = [ + "空的常用事件模板。\n請在主頁下拉菜單中,選擇常用事件模板,進行編輯。\n編輯後需按F5刷新事件編輯器。", + ]; + } + blockHTML = + MotaActionFunctions.actionParser.parseList(actionParserJson); - for (var name in toolboxObj) { - var custom = null; - if (name == "最近使用事件") custom = "searchBlockCategory"; - if (name == "入口方块") custom = "entranceCategory"; - getCategory(name, custom).innerHTML = - toolboxObj[name].join(toolboxgap); - } + CommonEventTemplateHTML.push(labelHTML); + CommonEventTemplateHTML.push(blockHTML); + } + } - var blocklyArea = document.getElementById("blocklyArea"); - var blocklyDiv = document.getElementById("blocklyDiv"); - var workspace = Blockly.inject(blocklyDiv, { - media: "_server/blockly/media/", - toolbox: document.getElementById("toolbox"), - zoom: { - controls: true, - wheel: false, //滚轮改为上下(shift:左右)翻滚 - startScale: 1.0, - maxScale: 3, - minScale: 0.3, - scaleSpeed: 1.08, - }, - trashcan: false, - }); + toolboxObj["常见事件模板"] = CommonEventTemplateHTML; + //#endregion - editor_blockly.isCommonEntry = function () { - var commonEntries = [ - "beforeBattle", - "afterBattle", - "afterOpenDoor", - "firstArrive", - "eachArrive", - "commonEvent", - "item", - ]; - return commonEntries.indexOf(editor_blockly.entryType) >= 0; - }; + for (var name in toolboxObj) { + var custom = null; + if (name == "最近使用事件") custom = "searchBlockCategory"; + if (name == "入口方块") custom = "entranceCategory"; + getCategory(name, custom).innerHTML = + toolboxObj[name].join(toolboxgap); + } - editor_blockly.entranceCategoryCallback = function (workspace) { - var list = toolboxObj["入口方块"]; - var xmlList = []; - var eventType = - (editor_blockly.isCommonEntry() ? - "common" : - editor_blockly.entryType) + "_m"; - for (var ii = 0, blockText; - (blockText = list[ii]); ii++) { - if ( - new RegExp('').exec(blockText) - ) { - var block = Blockly.Xml.textToDom( - "" + blockText + "" - ).firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); - } - } - return xmlList; - }; + var blocklyArea = document.getElementById("blocklyArea"); + var blocklyDiv = document.getElementById("blocklyDiv"); + var workspace = Blockly.inject(blocklyDiv, { + media: "_server/blockly/media/", + toolbox: document.getElementById("toolbox"), + zoom: { + controls: true, + wheel: false, //滚轮改为上下(shift:左右)翻滚 + startScale: 1.0, + maxScale: 3, + minScale: 0.3, + scaleSpeed: 1.08, + }, + trashcan: false, + }); - workspace.registerToolboxCategoryCallback( - "entranceCategory", - editor_blockly.entranceCategoryCallback - ); + editor_blockly.isCommonEntry = function () { + var commonEntries = [ + "beforeBattle", + "afterBattle", + "afterOpenDoor", + "firstArrive", + "eachArrive", + "commonEvent", + "item", + ]; + return commonEntries.indexOf(editor_blockly.entryType) >= 0; + }; - editor_blockly.searchBlockCategoryCallback = function (workspace) { - var xmlList = []; - var labels = editor_blockly.searchBlock(); - for (var i = 0; i < labels.length; i++) { - var blockText = - "" + MotaActionBlocks[labels[i]].xmlText() + ""; - var block = Blockly.Xml.textToDom(blockText).firstChild; - block.setAttribute("gap", 5); - xmlList.push(block); - } - return xmlList; - }; + editor_blockly.entranceCategoryCallback = function (workspace) { + var list = toolboxObj["入口方块"]; + var xmlList = []; + var eventType = + (editor_blockly.isCommonEntry() + ? "common" + : editor_blockly.entryType) + "_m"; + for (var ii = 0, blockText; (blockText = list[ii]); ii++) { + if ( + new RegExp('').exec(blockText) + ) { + var block = Blockly.Xml.textToDom( + "" + blockText + "" + ).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + } + return xmlList; + }; - workspace.registerToolboxCategoryCallback( - "searchBlockCategory", - editor_blockly.searchBlockCategoryCallback - ); + workspace.registerToolboxCategoryCallback( + "entranceCategory", + editor_blockly.entranceCategoryCallback + ); - var onresize = function (e) { - blocklyDiv.style.width = blocklyArea.offsetWidth + "px"; - blocklyDiv.style.height = blocklyArea.offsetHeight + "px"; - Blockly.svgResize(workspace); - }; - if (typeof editor !== "undefined" && !editor.isMobile) - window.addEventListener("resize", onresize, false); - onresize(); - //Blockly.svgResize(workspace); + editor_blockly.searchBlockCategoryCallback = function (workspace) { + var xmlList = []; + var labels = editor_blockly.searchBlock(); + for (var i = 0; i < labels.length; i++) { + var blockText = + "" + MotaActionBlocks[labels[i]].xmlText() + ""; + var block = Blockly.Xml.textToDom(blockText).firstChild; + block.setAttribute("gap", 5); + xmlList.push(block); + } + return xmlList; + }; - //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); - document.getElementById("blocklyDiv").onmousewheel = function (e) { - //console.log(e); - e.preventDefault(); - var hvScroll = e.shiftKey ? "hScroll" : "vScroll"; - var mousewheelOffsetValue = - (20 / 380) * workspace.scrollbar[hvScroll].handleLength_ * 3; - workspace.scrollbar[hvScroll].handlePosition_ += - (e.deltaY || 0) + (e.detail || 0) > 0 ? - mousewheelOffsetValue : - -mousewheelOffsetValue; - workspace.scrollbar[hvScroll].onScroll_(); - // workspace.setScale(workspace.scale); - }; + workspace.registerToolboxCategoryCallback( + "searchBlockCategory", + editor_blockly.searchBlockCategoryCallback + ); - var doubleClickCheck = [ - [0, "abc"] - ]; + var onresize = function (e) { + blocklyDiv.style.width = blocklyArea.offsetWidth + "px"; + blocklyDiv.style.height = blocklyArea.offsetHeight + "px"; + Blockly.svgResize(workspace); + }; + if (typeof editor !== "undefined" && !editor.isMobile) + window.addEventListener("resize", onresize, false); + onresize(); + //Blockly.svgResize(workspace); - function omitedcheckUpdateFunction(event) { - if (event.type === "create") { - editor_blockly.addIntoLastUsedType(event.blockId); - } - if (event.type === "ui" && event.element == "click") { - var newClick = [new Date().getTime(), event.blockId]; - var lastClick = doubleClickCheck.shift(); - doubleClickCheck.push(newClick); - if (newClick[0] - lastClick[0] < 500) { - if (newClick[1] === lastClick[1]) { - editor_blockly.doubleClickBlock(newClick[1]); - } - } - } - // Only handle these events - if (["create", "move", "change", "delete"].indexOf(event.type) < 0) - return; - if (editor_blockly.workspace.topBlocks_.length >= 2) { - editor_blockly.setValue("入口方块只能有一个"); - return; - } - var eventType = editor_blockly.entryType; - if (editor_blockly.workspace.topBlocks_.length == 1) { - var blockType = editor_blockly.workspace.topBlocks_[0].type; - if ( - blockType !== eventType + "_m" && - !(editor_blockly.isCommonEntry() && blockType == "common_m") - ) { - editor_blockly.setValue("入口方块类型错误"); - return; - } - } - try { - var code = Blockly.JavaScript.workspaceToCode(workspace).replace( - /\\(i|c|d|e|g|z)/g, - "\\\\$1" - ); - editor_blockly.setValue(code); - } catch (error) { - editor_blockly.setValue(String(error)); - if (error instanceof OmitedError) { - var blockName = error.blockName; - var varName = error.varName; - var block = error.block; - } - // console.log(error); - } - } + //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); + document.getElementById("blocklyDiv").onmousewheel = function (e) { + //console.log(e); + e.preventDefault(); + var hvScroll = e.shiftKey ? "hScroll" : "vScroll"; + var mousewheelOffsetValue = + (20 / 380) * workspace.scrollbar[hvScroll].handleLength_ * 3; + workspace.scrollbar[hvScroll].handlePosition_ += + (e.deltaY || 0) + (e.detail || 0) > 0 + ? mousewheelOffsetValue + : -mousewheelOffsetValue; + workspace.scrollbar[hvScroll].onScroll_(); + // workspace.setScale(workspace.scale); + }; - workspace.addChangeListener(omitedcheckUpdateFunction); + var doubleClickCheck = [[0, "abc"]]; - workspace.addChangeListener(Blockly.Events.disableOrphans); + function omitedcheckUpdateFunction(event) { + if (event.type === "create") { + editor_blockly.addIntoLastUsedType(event.blockId); + } + if (event.type === "ui" && event.element == "click") { + var newClick = [new Date().getTime(), event.blockId]; + var lastClick = doubleClickCheck.shift(); + doubleClickCheck.push(newClick); + if (newClick[0] - lastClick[0] < 500) { + if (newClick[1] === lastClick[1]) { + editor_blockly.doubleClickBlock(newClick[1]); + } + } + } + // Only handle these events + if (["create", "move", "change", "delete"].indexOf(event.type) < 0) + return; + if (editor_blockly.workspace.topBlocks_.length >= 2) { + editor_blockly.setValue("入口方块只能有一个"); + return; + } + var eventType = editor_blockly.entryType; + if (editor_blockly.workspace.topBlocks_.length == 1) { + var blockType = editor_blockly.workspace.topBlocks_[0].type; + if ( + blockType !== eventType + "_m" && + !(editor_blockly.isCommonEntry() && blockType == "common_m") + ) { + editor_blockly.setValue("入口方块类型错误"); + return; + } + } + try { + var code = Blockly.JavaScript.workspaceToCode(workspace).replace( + /\\(i|c|d|e|g|z)/g, + "\\\\$1" + ); + editor_blockly.setValue(code); + } catch (error) { + editor_blockly.setValue(String(error)); + if (error instanceof OmitedError) { + var blockName = error.blockName; + var varName = error.varName; + var block = error.block; + } + // console.log(error); + } + } - editor_blockly.workspace = workspace; + workspace.addChangeListener(omitedcheckUpdateFunction); - MotaActionFunctions.workspace = function () { - return editor_blockly.workspace; - }; + workspace.addChangeListener(Blockly.Events.disableOrphans); - // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 - MotaActionFunctions.xmlText = function ( - ruleName, - inputs, - isShadow, - comment, - collapsed, - disabled - ) { - var rule = MotaActionBlocks[ruleName]; - var blocktext = isShadow ? "shadow" : "block"; - var xmlText = []; - xmlText.push( - "<" + - blocktext + - ' type="' + - ruleName + - '"' + - (collapsed ? ' collapsed="true"' : "") + - (disabled ? ' disabled="true"' : "") + - ">" - ); - if (!inputs) inputs = []; - for (var ii = 0, inputType; - (inputType = rule.argsType[ii]); ii++) { - var input = inputs[ii]; - var _input = ""; - var noinput = input === null || input === undefined; - if ( - noinput && - inputType === "field" && - MotaActionBlocks[rule.argsGrammarName[ii]].type !== - "field_dropdown" - ) - continue; - if (noinput && inputType === "field") { - noinput = false; - input = rule.fieldDefault(rule.args[ii]); - } - if (noinput) input = ""; - if ( - inputType === "field" && - MotaActionBlocks[rule.argsGrammarName[ii]].type === - "field_checkbox" - ) - input = input ? "TRUE" : "FALSE"; - if (inputType !== "field") { - var subList = false; - var subrulename = rule.argsGrammarName[ii]; - var subrule = MotaActionBlocks[subrulename]; - if (subrule instanceof Array) { - subrulename = subrule[subrule.length - 1]; - subrule = MotaActionBlocks[subrulename]; - subList = true; - } - _input = subrule.xmlText([], true); - if (noinput && !subList && !isShadow) { - //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 - input = subrule.xmlText(); - } - } - xmlText.push("<" + inputType + ' name="' + rule.args[ii] + '">'); - xmlText.push(_input + input); - xmlText.push(""); - } - if (comment) { - xmlText.push(""); - xmlText.push(comment); - xmlText.push(""); - } - var next = inputs[rule.args.length]; - if (next) { - //next - xmlText.push(""); - xmlText.push(next); - xmlText.push(""); - } - xmlText.push(""); - return xmlText.join(""); - }; - })(); + editor_blockly.workspace = workspace; - // end mark sfergsvae - } - .toString() - .split("// start mark sfergsvae")[1] - .split("// end mark sfergsvae")[0]; - } -}, + MotaActionFunctions.workspace = function () { + return editor_blockly.workspace; + }; + + // 因为在editor_blockly.parse里已经HTML转义过一次了,所以这里要覆盖掉以避免在注释中出现<等 + MotaActionFunctions.xmlText = function ( + ruleName, + inputs, + isShadow, + comment, + collapsed, + disabled + ) { + var rule = MotaActionBlocks[ruleName]; + var blocktext = isShadow ? "shadow" : "block"; + var xmlText = []; + xmlText.push( + "<" + + blocktext + + ' type="' + + ruleName + + '"' + + (collapsed ? ' collapsed="true"' : "") + + (disabled ? ' disabled="true"' : "") + + ">" + ); + if (!inputs) inputs = []; + for (var ii = 0, inputType; (inputType = rule.argsType[ii]); ii++) { + var input = inputs[ii]; + var _input = ""; + var noinput = input === null || input === undefined; + if ( + noinput && + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type !== + "field_dropdown" + ) + continue; + if (noinput && inputType === "field") { + noinput = false; + input = rule.fieldDefault(rule.args[ii]); + } + if (noinput) input = ""; + if ( + inputType === "field" && + MotaActionBlocks[rule.argsGrammarName[ii]].type === + "field_checkbox" + ) + input = input ? "TRUE" : "FALSE"; + if (inputType !== "field") { + var subList = false; + var subrulename = rule.argsGrammarName[ii]; + var subrule = MotaActionBlocks[subrulename]; + if (subrule instanceof Array) { + subrulename = subrule[subrule.length - 1]; + subrule = MotaActionBlocks[subrulename]; + subList = true; + } + _input = subrule.xmlText([], true); + if (noinput && !subList && !isShadow) { + //无输入的默认行为是: 如果语句块的备选方块只有一个,直接代入方块 + input = subrule.xmlText(); + } + } + xmlText.push("<" + inputType + ' name="' + rule.args[ii] + '">'); + xmlText.push(_input + input); + xmlText.push(""); + } + if (comment) { + xmlText.push(""); + xmlText.push(comment); + xmlText.push(""); + } + var next = inputs[rule.args.length]; + if (next) { + //next + xmlText.push(""); + xmlText.push(next); + xmlText.push(""); + } + xmlText.push(""); + return xmlText.join(""); + }; + })(); + + // end mark sfergsvae + } + .toString() + .split("// start mark sfergsvae")[1] + .split("// end mark sfergsvae")[0]; + } + }, "夹击激光动画": function () { function createCanvas(name, zIndex) { if (!name) return; @@ -10122,81 +13083,81 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "瞬移轨迹": function () { - // 在此增加新插件 - function popMove() { - var ctx = core.getContextByName("popMove"); - if (!ctx) - ctx = core.createCanvas( - "popMove", - 0, - 0, - core.__PIXELS__, - core.__PIXELS__, - 71 - ); - ctx.canvas.classList.add('gameCanvas', 'anti-aliasing') - core.clearMap(ctx); - if (core.status.replay.speed <= 3 && !flags.stopPop) { - var list = core.status.popMove || []; - var count = 0; - list.forEach(function (one) { - // 由frame计算出dy + // 在此增加新插件 + function popMove() { + var ctx = core.getContextByName("popMove"); + if (!ctx) + ctx = core.createCanvas( + "popMove", + 0, + 0, + core.__PIXELS__, + core.__PIXELS__, + 71 + ); + ctx.canvas.classList.add("gameCanvas", "anti-aliasing"); + core.clearMap(ctx); + if (core.status.replay.speed <= 3 && !flags.stopPop) { + var list = core.status.popMove || []; + var count = 0; + list.forEach(function (one) { + // 由frame计算出dy - one.frame++; - // 绘制 + one.frame++; + // 绘制 - if (one.frame >= 0) core.setAlpha(ctx, 1 - one.frame / 30); - else core.setAlpha(ctx, 1); + if (one.frame >= 0) core.setAlpha(ctx, 1 - one.frame / 30); + else core.setAlpha(ctx, 1); - var length = Math.sqrt( - Math.pow(one.px2 - one.px, 2) + Math.pow(one.py2 - one.py, 2) - ); - //console.log(length) - var li = length / 16; - var lx = (one.px2 - one.px) / li; - var ly = (one.py2 - one.py) / li; - for (var i = 0; i < li; i += 1) { - core.setAlpha(ctx, (1 - one.frame / 30) * ((i / li) * 0.8 + 0.2)); - core.drawLine( - "popMove", - one.px + i * lx, - one.py + i * ly, - one.px + (i + 0.5) * lx, - one.py + (i + 0.5) * ly, - "#E1E1E1", - 6 - ); - if (i == 0) - core.strokeCircle("popMove", one.px, one.py, 6, "#E1E1E1", 3); - } - core.strokeCircle("popMove", one.px2, one.py2, 6, "#E1E1E1", 3); - core.strokeCircle( - "popMove", - one.px2, - one.py2, - 6 + (16 * one.frame) / 30, - "#E1E1E1", - 6 * (1 - one.frame / 30) - ); - //core.drawLine('popMove', one.px, one.py, one.px2, one.py2, '#E1E1E1', 6); + var length = Math.sqrt( + Math.pow(one.px2 - one.px, 2) + Math.pow(one.py2 - one.py, 2) + ); + //console.log(length) + var li = length / 16; + var lx = (one.px2 - one.px) / li; + var ly = (one.py2 - one.py) / li; + for (var i = 0; i < li; i += 1) { + core.setAlpha(ctx, (1 - one.frame / 30) * ((i / li) * 0.8 + 0.2)); + core.drawLine( + "popMove", + one.px + i * lx, + one.py + i * ly, + one.px + (i + 0.5) * lx, + one.py + (i + 0.5) * ly, + "#E1E1E1", + 6 + ); + if (i == 0) + core.strokeCircle("popMove", one.px, one.py, 6, "#E1E1E1", 3); + } + core.strokeCircle("popMove", one.px2, one.py2, 6, "#E1E1E1", 3); + core.strokeCircle( + "popMove", + one.px2, + one.py2, + 6 + (16 * one.frame) / 30, + "#E1E1E1", + 6 * (1 - one.frame / 30) + ); + //core.drawLine('popMove', one.px, one.py, one.px2, one.py2, '#E1E1E1', 6); - if (one.frame >= 30) count++; - }); - if (count > 0) list.splice(0, count); - } - } + if (one.frame >= 30) count++; + }); + if (count > 0) list.splice(0, count); + } + } - if (!main.replayChecking) { - core.registerAnimationFrame("popMove", true, popMove); - } - this.addPopMove = function (px, py, px2, py2, frame) { - var data = { px: px, py: py, px2: px2, py2: py2, frame: frame || 0 }; - if (core.status.replay.speed <= 3) { - if (!core.status.popMove) core.status.popMove = [data]; - else core.status.popMove.push(data); - } - }; -}, + if (!main.replayChecking) { + core.registerAnimationFrame("popMove", true, popMove); + } + this.addPopMove = function (px, py, px2, py2, frame) { + var data = { px: px, py: py, px2: px2, py2: py2, frame: frame || 0 }; + if (core.status.replay.speed <= 3) { + if (!core.status.popMove) core.status.popMove = [data]; + else core.status.popMove.push(data); + } + }; + }, "墓碑(编辑器)": function () { // 在此增加新插件 if (main.mode != "editor") return; // 编辑器模式下使用 @@ -10329,6 +13290,10 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = let allChangeEntries = Object.entries(defaultChange); + this.setq = function (floorId) { + core.setFlag("任务地点", floorId); + }; + const reset = core.events.resetGame; this.bfs = function () { areas = []; @@ -10637,8 +13602,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.drawImage(ctx, img, 0, 0, 60, 60, fx, fy, w, h); const layer = info.upOrDown[id]; const min = Math.min(w, h); - if (core.getFlag("任务地点") && core.getFlag("任务地点") === id) - ctx.drawImage(tesk, fx + min / 4, fy + min / 4, min / 2, min / 2); + if (layer?.includes("upFloor")) core.drawIcon( ctx, @@ -10657,7 +13621,21 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = min / 2, min / 2 ); - + if (core.getFlag("任务地点") && core.getFlag("任务地点") === id) + ctx.drawImage(tesk, fx + min / 4, fy + min / 4, min / 2, min / 2); + if (id === core.status.floorId) + core.drawImage( + ctx, + "hero.webp", + 0, + 0, + 32, + 19, + fx + min / 4, + fy + (min * 5) / 16, + 32, + 19 + ); // 显示漏怪数量 if (core.getFlag("showEnemy")) { ctx.textAlign = "center"; @@ -10680,6 +13658,17 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); ctx.shadowBlur = 0; } + if (!core.hasVisitedFloor(id)) { + core.fillRect(ctx, fx, fy, w, h, "rgba(0,0,0,0.7)"); + core.fillText( + ctx, + "?", + fx + min / 2, + fy + (min * 3) / 4, + "#FFFFFF", + "bold 42px Verdana" + ); + } } }; }, @@ -10712,6 +13701,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ////// 绘制浏览地图界面 ////// ui.prototype._drawViewMaps = function (index, x, y) { core.lockControl(); + core.clearMap("data"); core.status.event.id = "viewMaps"; this.clearUI(); @@ -11068,20 +14058,30 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if ( !core.status.maps[core.floorIds[page]].canFlyTo || !core.hasVisitedFloor(core.floorIds[page]) - ) + ) { + /*core.fillRect("ui", 58, + 58, + size - 50, + size - 50, "rgba(0,0,0,0.5)")*/ + core.getContextByName("ui").globalAlpha = 0.7; + core.drawImage( "ui", - "lock.webp", + "miwu.webp", 0, 0, size, size, 58, 58, - size - 8, - size - 8 + size - 50, + size - 50 ); - + core.getContextByName("ui").globalAlpha = 1; + /*core.fillText("ui", '?', 188, + 278, + "rgba(255,255,255,0.2)", this._buildFont(250, true))*/ + } core.fillRoundRect( "ui", 15 + 44 - 2, @@ -11307,7 +14307,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = title, 15 - 4 + size - 4 + 45, 85, - "#FFFFFF", + core.hasVisitedFloor(floorId) ? "#FFFFFF" : "#444444", "#000000", 18 ); @@ -11440,7 +14440,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ////// 点击楼层传送器时的打开操作 ////// events.prototype.useFly = function (fromUserAction) { - if (core.isReplaying()) return; + if (!core.isPlaying()) return; if (!core.status.maps[core.status.floorId].canFlyFrom) { core.drawTip(core.material.items["fly"].name + "好像失效了", "fly"); return; @@ -11453,7 +14453,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } else if ( core.flags.flyNearStair && !core.nearStair() && - !core.canMoveFloor() + !flags.canMoveFloor ) { core.playSound("操作失败"); core.drawTip( @@ -11462,6 +14462,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); } else { core.flyTo(core.status.event.data.floorId); + core.updateStatusBar(); } return; } @@ -11471,7 +14472,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if ( (core.flags.flyNearStair && !core.nearStair()) || - !core.canMoveFloor() + !flags.canMoveFloor ) { core.playSound("操作失败"); core.drawTip( @@ -11493,6 +14494,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = } core.playSound("打开界面"); core.useItem("fly", true); + core.updateStatusBar(); return; }; ////// 系统菜单栏界面时的点击操作 ////// @@ -11516,7 +14518,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = case 2: // core.playSound('确定'); core.clearUI(); - core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); + core.useItem("fly"); break; case 3: core.status.event.selection = 0; @@ -11583,6 +14585,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.ui.closePanel(); core.getItemDetail(); core.redrawMap(); + core.updateStatusBar(); core.ui.statusBar._update_map(); return; } else if (px >= 55 && px <= 317 && py >= 11 && py <= 54) { @@ -11610,7 +14613,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = px <= 317 && py >= 55 && py <= 317 && - !core.isReplaying() + core.isPlaying() ) { core.useFly(false); return; @@ -11633,7 +14636,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = var toIndex = core.floorIds.indexOf(floorId); if ( !core.canUseItem("fly") || - (core.flags.flyNearStair && !core.nearStair()) + (core.flags.flyNearStair && !core.nearStair() && !flags.canMoveFloor) ) return false; core.ui._drawViewMaps(toIndex); @@ -11650,6 +14653,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; core.registerReplayAction("fly", replayAction_fly); ////// 查看地图界面时,放开某个键的操作 ////// + actions.prototype._keyUpViewMaps = function (keycode) { if (core.status.event.data == null) { core.ui._drawViewMaps(core.floorIds.indexOf(core.status.floorId)); @@ -11664,20 +14668,22 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.getItemDetail(); core.redrawMap(); core.ui.statusBar._update_map(); + core.updateStatusBar(); return; } - if (keycode == 88) { - core.openBook(true); - return; - } + if (keycode == 86) { core.status.event.data.damage = !core.status.event.data.damage; core.playSound("光标移动"); core.ui._drawViewMaps(core.status.event.data); return; } - if (keycode == 66) { - core.openBook(false); + if (keycode == 66 || keycode == 88) { + if (core.isReplaying()) { + core.control._replay_book(); + } else { + core.openBook(false); + } return; } if ( @@ -11792,526 +14798,511 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); }, "CG回廊": function () { - // 在此增加新插件 - const CGUI = document.createElement("canvas"); //CGui画布设置 - CGUI.style.position = "absolute"; - CGUI.style.zIndex = 300; - CGUI.style.display = "none"; - CGUI.id = "CGUI"; - main.dom.gameGroup.insertAdjacentElement("afterend", CGUI); - CGUI.style.top = "50%"; - CGUI.style.left = "50%"; - CGUI.style.transform = "translate(-50%,-50%)"; - const ctx = CGUI.getContext("2d"); - main.dom.CGUI = CGUI; - let page = 0; //初始页面 - let show = false; //展示状态 - CGUI.onclick = function (e) { - try { - e.preventDefault(); - if (core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.CG.onclick(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; + // 在此增加新插件 + const CGUI = document.createElement("canvas"); //CGui画布设置 + CGUI.style.position = "absolute"; + CGUI.style.zIndex = 300; + CGUI.style.display = "none"; + CGUI.id = "CGUI"; + main.dom.gameGroup.insertAdjacentElement("afterend", CGUI); + CGUI.style.top = "50%"; + CGUI.style.left = "50%"; + CGUI.style.transform = "translate(-50%,-50%)"; + const ctx = CGUI.getContext("2d"); + main.dom.CGUI = CGUI; + let page = 0; //初始页面 + let show = false; //展示状态 + CGUI.onclick = function (e) { + try { + e.preventDefault(); + if (core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.CG.onclick(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; - class CG { - constructor() { - //cg列表 - this.UIMx = [ - //空位用‘none’填充,当前ui至多4列6行 - [ - ["eve_010102.webp", "eve_010203.webp", "eve_010304.webp"], - ["eve_010501.webp", "eve_010601.webp", "eve_010701.webp"], - ], - [ - ["eve_010801.webp", "eve_010902.webp", "eve_011001.webp"], - ["eve_011101.webp", "eve_011202.webp", "eve_011302.webp"], - ], - [ - ["eve_011402.webp", "eve_020102.webp", "eve_020201.webp"], - ["eve_020301.webp", "eve_020401.webp", "eve_020501.webp"], - ], - [ - ["eve_020605.webp", "eve_020701.webp", "eve_020801.webp"], - ["eve_030101.webp", "eve_030206.webp", "eve_030302.webp"], - ], - [ - ["eve_030508.webp", "eve_030601.webp", "eve_030801.webp"], - ["eve_030901.webp", "eve_031002.webp", "eve_031101.webp"], - ], - [ - ["eve_040201.webp", "eve_040401.webp", "eve_040501.webp"], - ["eve_040601.webp", "eve_040702.webp", "eve_040801.webp"], - ], - [ - ["eve_050101.webp", "eve_050201.webp", "eve_050401.webp"], - ["eve_050501.webp", "eve_050601.webp", "eve_050704.webp"], - ], - [ - ["eve_050801.webp", "eve_070101.webp", "bg_1511.webp"], - ["bg_1521.webp", "bg_2011.webp", "bg_2521.webp"], - ], - [ - ["bg_3042.webp", "bg_3551.webp", "bg_3571.webp"], - ["bg_3721.webp", "bg_5033.webp", "bg_5044.webp"], - ], - ]; - } + class CG { + constructor() { + this.cgs; + //cg列表 + this.UIMx = [ + //空位用‘none’填充,当前ui3*2 + [ + ["eve_010102.webp", "eve_010203.webp", "eve_010304.webp"], + ["eve_010501.webp", "eve_010601.webp", "eve_010701.webp"], + ], + [ + ["eve_010801.webp", "eve_010902.webp", "eve_011001.webp"], + ["eve_011101.webp", "eve_011202.webp", "eve_011302.webp"], + ], + [ + ["eve_011402.webp", "eve_020102.webp", "eve_020201.webp"], + ["eve_020301.webp", "eve_020401.webp", "eve_020501.webp"], + ], + [ + ["eve_020605.webp", "eve_020701.webp", "eve_020801.webp"], + ["eve_030101.webp", "eve_030206.webp", "eve_030302.webp"], + ], + [ + ["eve_030508.webp", "eve_030601.webp", "eve_030801.webp"], + ["eve_030901.webp", "eve_031002.webp", "eve_031101.webp"], + ], + [ + ["eve_040201.webp", "eve_040401.webp", "eve_040501.webp"], + ["eve_040601.webp", "eve_040702.webp", "eve_040801.webp"], + ], + [ + ["eve_050101.webp", "eve_050201.webp", "eve_050401.webp"], + ["eve_050501.webp", "eve_050601.webp", "eve_050704.webp"], + ], + [ + ["eve_050801.webp", "eve_070101.webp", "bg_1511.webp"], + ["bg_1521.webp", "bg_2011.webp", "bg_2521.webp"], + ], + [ + ["bg_3042.webp", "bg_3551.webp", "bg_3571.webp"], + ["bg_3721.webp", "bg_5033.webp", "bg_5044.webp"], + ], + ]; + } - //更新 - update() { - this.background(); - this.drawUI(); - } - background() { - //画布大小设置 - if (core.domStyle.isVertical) { - CGUI.width = 1248; - CGUI.height = 2028; - } else { - CGUI.width = 2028; - CGUI.height = 1248; - } - core.setTextAlign(ctx, "center"); - } - onclick(px, py) { - //点击 - if (show) { - show = !show; - core.clearMap(ctx); - this.update(); - return; - } - const makeBox = ([x, y], [w, h]) => { - return [ - [x, y], - [x + w, y + h], - ]; - }; - const inRect = ([x, y], [[sx, sy], [dx, dy]]) => { - return sx <= x && x <= dx && sy <= y && y <= dy; - }; - const pos = [px, py]; - const backbox = makeBox([45, 45], [120, 80]); - if (inRect(pos, backbox)) { - //离开按钮是一致的,其余的记区分横竖屏 - CGUI.style.display = "none"; - core.clearMap(ctx); - core.restart(); - return; - } - if (core.domStyle.isVertical) { - //竖屏 - const pageupbox = makeBox([30, 380], [144, 144]); - const pagedownbox = makeBox([30, 1080], [144, 144]); + //更新 + update() { + this.background(); + this.drawUI(); + } + background() { + //画布大小设置 + if (core.domStyle.isVertical) { + CGUI.width = 1248; + CGUI.height = 2028; + } else { + CGUI.width = 2028; + CGUI.height = 1248; + } + core.setTextAlign(ctx, "center"); + } + onclick(px, py) { + //点击 - const imagebox0 = makeBox([200, 300], [480, 320]); - const imagebox1 = makeBox([200, 750], [480, 320]); - const imagebox2 = makeBox([200, 1200], [480, 320]); + if (show) { + show = !show; + core.clearMap(ctx); + this.update(); + return; + } + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + const backbox = makeBox([15, 35], [210, 90]); + if (inRect(pos, backbox)) { + //离开按钮是一致的,其余的记区分横竖屏 + CGUI.style.display = "none"; + core.clearMap(ctx); + core.restart(); + return; + } + if (core.domStyle.isVertical) { + //竖屏 + const pageupbox = makeBox([200, 1830], [200, 100]); + const pagedownbox = makeBox([900, 1830], [200, 100]); - const imagebox3 = makeBox([700, 300], [480, 320]); - const imagebox4 = makeBox([700, 750], [480, 320]); - const imagebox5 = makeBox([700, 1200], [480, 320]); - if (inRect(pos, pagedownbox)) { - //2代表当前最大页数-1 - if (page < this.UIMx.length - 1) { - page++; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, pageupbox)) { - if (page > 0) { - page--; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, imagebox0)) { - const img = core.material.images.images[this.UIMx[page][0][0]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } else if (inRect(pos, imagebox1)) { - const img = core.material.images.images[this.UIMx[page][0][1]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } else if (inRect(pos, imagebox2)) { - const img = core.material.images.images[this.UIMx[page][0][2]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } else if (inRect(pos, imagebox3)) { - const img = core.material.images.images[this.UIMx[page][1][0]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } else if (inRect(pos, imagebox4)) { - const img = core.material.images.images[this.UIMx[page][1][1]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } else if (inRect(pos, imagebox5)) { - const img = core.material.images.images[this.UIMx[page][1][2]]; - if (img) { - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.restore(); //重置画布设置 - show = !show; - } - } - } else { - const pageupbox = makeBox([30, 340], [144, 144]); - const pagedownbox = makeBox([30, 840], [144, 144]); - const imagebox0 = makeBox([300, 300], [480, 320]); - const imagebox1 = makeBox([800, 300], [480, 320]); - const imagebox2 = makeBox([1300, 300], [480, 320]); - const imagebox3 = makeBox([300, 750], [480, 320]); - const imagebox4 = makeBox([800, 750], [480, 320]); - const imagebox5 = makeBox([1300, 750], [480, 320]); - if (inRect(pos, pagedownbox)) { - if (page < this.UIMx.length - 1) { - page++; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, pageupbox)) { - if (page > 0) { - page--; - core.clearMap(ctx); - this.update(); - } - } else if (inRect(pos, imagebox0)) { - const img = core.material.images.images[this.UIMx[page][0][0]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } else if (inRect(pos, imagebox1)) { - const img = core.material.images.images[this.UIMx[page][0][1]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } else if (inRect(pos, imagebox2)) { - const img = core.material.images.images[this.UIMx[page][0][2]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } else if (inRect(pos, imagebox3)) { - const img = core.material.images.images[this.UIMx[page][1][0]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } else if (inRect(pos, imagebox4)) { - const img = core.material.images.images[this.UIMx[page][1][1]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } else if (inRect(pos, imagebox5)) { - const img = core.material.images.images[this.UIMx[page][1][2]]; - if (img) { - ctx.drawImage(img, 0, 0, 2028, 1248); - show = !show; - } - } - } - } - drawUI() { - //绘制页面 - core.clearMap(CGUI); - const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 - const bg = core.material.images.images["bg_5043.webp"]; //横屏背景 - if (core.domStyle.isVertical) { - //竖屏 + const imagebox0 = makeBox([50, 200], [560, 420]); + const imagebox1 = makeBox([50, 750], [560, 420]); + const imagebox2 = makeBox([50, 1300], [560, 420]); - core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 - if (bgVertical) - ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 + const imagebox3 = makeBox([650, 200], [560, 420]); + const imagebox4 = makeBox([650, 750], [560, 420]); + const imagebox5 = makeBox([650, 1300], [560, 420]); + if (inRect(pos, pagedownbox)) { + //2代表当前最大页数-1 + if (page < this.UIMx.length - 1) { + page++; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, pageupbox)) { + if (page > 0) { + page--; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, imagebox0)) { + if (this.cgs.includes(this.UIMx[page][0][0])) { + const img = core.material.images.images[this.UIMx[page][0][0]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox1)) { + if (this.cgs.includes(this.UIMx[page][0][1])) { + const img = core.material.images.images[this.UIMx[page][0][1]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox2)) { + if (this.cgs.includes(this.UIMx[page][0][2])) { + const img = core.material.images.images[this.UIMx[page][0][2]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox3)) { + if (this.cgs.includes(this.UIMx[page][1][0])) { + const img = core.material.images.images[this.UIMx[page][1][0]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox4)) { + if (this.cgs.includes(this.UIMx[page][1][1])) { + const img = core.material.images.images[this.UIMx[page][1][1]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } else if (inRect(pos, imagebox5)) { + if (this.cgs.includes(this.UIMx[page][1][2])) { + const img = core.material.images.images[this.UIMx[page][1][2]]; + if (img) { + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.restore(); //重置画布设置 + show = !show; + } + } + } + } else { + const pageupbox = makeBox([200, 1110], [200, 100]); + const pagedownbox = makeBox([1600, 1110], [200, 100]); + const imagebox0 = makeBox([75, 150], [600, 450]); + const imagebox1 = makeBox([725, 150], [600, 450]); + const imagebox2 = makeBox([1300, 150], [600, 450]); + const imagebox3 = makeBox([75, 650], [600, 450]); + const imagebox4 = makeBox([725, 650], [600, 450]); + const imagebox5 = makeBox([1375, 650], [600, 450]); + if (inRect(pos, pagedownbox)) { + if (page < this.UIMx.length - 1) { + page++; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, pageupbox)) { + if (page > 0) { + page--; + core.clearMap(ctx); + this.update(); + } + } else if (inRect(pos, imagebox0)) { + if (this.cgs.includes(this.UIMx[page][0][0])) { + const img = core.material.images.images[this.UIMx[page][0][0]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox1)) { + if (this.cgs.includes(this.UIMx[page][0][1])) { + const img = core.material.images.images[this.UIMx[page][0][1]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox2)) { + if (this.cgs.includes(this.UIMx[page][0][2])) { + const img = core.material.images.images[this.UIMx[page][0][2]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox3)) { + if (this.cgs.includes(this.UIMx[page][1][0])) { + const img = core.material.images.images[this.UIMx[page][1][0]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox4)) { + if (this.cgs.includes(this.UIMx[page][1][1])) { + const img = core.material.images.images[this.UIMx[page][1][1]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } else if (inRect(pos, imagebox5)) { + if (this.cgs.includes(this.UIMx[page][1][2])) { + const img = core.material.images.images[this.UIMx[page][1][2]]; + if (img) { + ctx.drawImage(img, 0, 0, 2028, 1248); + show = !show; + } + } + } + } + } + drawUI() { + //绘制页面 + core.clearMap(CGUI); + const bgVertical = core.material.images.images["bg_2010.webp"]; //竖屏背景 + const bg = core.material.images.images["bg_5043.webp"]; //横屏背景 - core.setTextAlign(ctx, "center"); - core.fillRoundRect( - ctx, - 45 - 6, - 45 - 6, - 120 + 12, - 80 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 45 - 12, - 120 + 24, - 80 + 24, - 12, - "#444444", - 3 - ); - core.fillBoldText1( - ctx, - "<离开", - 110, - 100, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(33, true) - ); - // 添加向上翻页和向下翻页的按钮 - core.fillRoundRect( - ctx, - 45 - 6, - 400 - 6, - 120 + 12, - 120 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 400 - 12, - 120 + 24, - 120 + 24, - 12, - "#444444", - 3 - ); - core.fillRoundRect( - ctx, - 45 - 6, - 1100 - 6, - 120 + 12, - 120 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 1100 - 12, - 120 + 24, - 120 + 24, - 12, - "#444444", - 3 - ); - core.fillBoldText1( - ctx, - "向上翻页", - 100, - 450, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(24, true) - ); - core.fillBoldText1( - ctx, - "向下翻页", - 100, - 1150, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(24, true) - ); + if (core.domStyle.isVertical) { + //竖屏 - // 添加3*2个4:3的画框,及图片 - for (let i = 0; i < 3; i++) { - for (let j = 0; j < 2; j++) { - const img = core.material.images.images[this.UIMx[page][j][i]]; - core.strokeRect( - ctx, - 200 + j * 500, - 300 + i * 450, - 480, - 320, - "#444444", - 5 - ); - if (img) - ctx.drawImage( - img, - 200 + j * 500 + 15, - 300 + i * 450 + 15, - 480 - 30, - 320 - 30 - ); - } - } - } else { - //横屏 - core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 - if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 - ctx.globalAlpha = 1; //恢复为不透明 - //core.drawWindowSkin('winskin1.png', ctx, 0, 0, 2028, 1248); - core.setTextAlign(ctx, "center"); - core.fillRoundRect( - ctx, - 45 - 6, - 45 - 6, - 120 + 12, - 80 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 45 - 12, - 120 + 24, - 80 + 24, - 12, - "#444444", - 3 - ); - core.fillBoldText1( - ctx, - "<离开", - 110, - 100, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(33, true) - ); + core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 + ctx.globalAlpha = 0.5; //透明度 + if (bgVertical) + ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 - // 添加向上翻页和向下翻页的按钮 - core.fillRoundRect( - ctx, - 45 - 6, - 350 - 6, - 120 + 12, - 120 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 350 - 12, - 120 + 24, - 120 + 24, - 12, - "#444444", - 3 - ); - core.fillBoldText1( - ctx, - "向上翻页", - 100, - 400, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(24, true) - ); - core.fillRoundRect( - ctx, - 45 - 6, - 850 - 6, - 120 + 12, - 120 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 850 - 12, - 120 + 24, - 120 + 24, - 12, - "#444444", - 3 - ); - core.fillBoldText1( - ctx, - "向下翻页", - 100, - 900, - "#FFFFFF", - "#000000", - 6, - core.ui._buildFont(24, true) - ); + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "◀离开", + 100, + 110, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); - // 添加3*2个4:3的画框 - for (let i = 0; i < 2; i++) { - for (let j = 0; j < 3; j++) { - core.strokeRect( - ctx, - 300 + j * 500, - 300 + i * 450, - 480, - 320, - "#444444", - 2 - ); - const img = core.material.images.images[this.UIMx[page][i][j]]; - if (img) - ctx.drawImage( - img, - 300 + j * 500 + 15, - 300 + i * 450 + 15, - 480 - 30, - 320 - 30 - ); - } - } - } - } - } - core.ui.CG = new CG(); - main.dom.CGMode.onclick = function () { - //点击开始页面的CG MODE进入cg回廊 - main.core.control.checkBgm(); - page = 0; - CGUI.style.display = "block"; - main.core.ui.CG.update(); - }; - }, + core.fillBoldText1( + ctx, + "上一页", + 300, + 1900, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.UIMx.length, + 650, + 1900, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1000, + 1900, + page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + // 添加向上翻页和向下翻页的按钮 + + // 添加3*2个4:3的画框,及图片 + for (let i = 0; i < 3; i++) { + for (let j = 0; j < 2; j++) { + const img = core.material.images.images[this.UIMx[page][j][i]]; + core.strokeRect( + ctx, + 50 + j * 600, + 200 + i * 550, + 560, + 420, + "#444444", + 5 + ); + if (this.cgs.includes(this.UIMx[page][j][i])) { + if (img) + ctx.drawImage( + img, + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + } else { + ctx.fillStyle = "#000000"; + ctx.fillRect( + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + const img = core.material.images.images["LOGO.webp"]; + if (img) + ctx.drawImage( + img, + 50 + j * 600 + 15, + 200 + i * 550 + 15, + 560 - 30, + 420 - 30 + ); + } + } + } + } else { + //横屏 + core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 + ctx.globalAlpha = 0.5; //透明度 + if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 + ctx.globalAlpha = 1; //恢复为不透明 + + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + // 添加向上翻页和向下翻页的按钮 + core.fillBoldText1( + ctx, + "上一页", + 300, + 1180, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.UIMx.length, + 1000, + 1180, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1700, + 1180, + page === this.UIMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + // 添加3*2个4:3的画框 + for (let i = 0; i < 2; i++) { + for (let j = 0; j < 3; j++) { + core.strokeRect( + ctx, + 75 + j * 650, + 150 + i * 500, + 600, + 450, + "#444444", + 2 + ); + if (this.cgs.includes(this.UIMx[page][i][j])) { + const img = core.material.images.images[this.UIMx[page][i][j]]; + if (img) + ctx.drawImage( + img, + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + } else { + ctx.fillStyle = "#000000"; + ctx.fillRect( + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + const img = core.material.images.images["LOGO.webp"]; + if (img) + ctx.drawImage( + img, + 75 + j * 650 + 15, + 150 + i * 500 + 15, + 600 - 30, + 450 - 30 + ); + } + } + } + } + } + } + this.setcgs = function (img) { + const a = core.getLocalStorage("cgs", []); + if (img) { + if (!a.includes(img)) a.push(img); + core.setLocalStorage("cgs", a); + } else core.setLocalStorage("cgs"); + }; + core.ui.CG = new CG(); + main.dom.CGMode.onclick = function () { + //点击开始页面的CG MODE进入cg回廊 + main.core.control.checkBgm(); + page = 0; + main.core.ui.CG.cgs = core.getLocalStorage("cgs", []); + CGUI.style.display = "block"; + main.core.ui.CG.update(); + }; +}, "光标设置": function () { // 在此增加新插件 this.changeMouse = function ( @@ -12350,270 +15341,226 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "信息弹出": function () { - // 在此增加新插件 - /* 弹出显示某个内容 - * 使用方法:core.addPop(px, py, value, color, boldColor, left, jump, time, show, font, speed) - * 参数说明: - * px & py: number 弹出位置 - * value: string 显示内容 - * color: string 填充颜色 - * boldColor: string 描边颜色 - */ - - // 默认字体 - var fontD = "16px Verdana"; - // 默认颜色 - var colorD = "red"; - // 默认描边颜色 - var boldColorD = "black"; - - /** 血量弹出 */ - function pop() { - var ctx = core.getContextByName("pop"); - if (!ctx) - ctx = core.createCanvas( - "pop", - 0, - 0, - core.__PIXELS__, - core.__PIXELS__, - 90 - ); - ctx.canvas.classList.add('gameCanvas', 'anti-aliasing') - core.clearMap(ctx); - core.setTextAlign("pop", "left"); - var list = core.status.pop || []; - var count = 0; - list.forEach(function (one) { - // 由frame计算出dy - var dy = 6 - one.frame * 0.2; - var dx = one.speed; - if (one.jump) { - one.py -= dy; - } - if (!one.left) { - one.px += dx; - } else { - one.px -= dx; - } - one.frame++; - // 绘制 - if (one.frame >= one.time) - core.setAlpha(ctx, 1 - (one.frame - one.time) / one.show); - else core.setAlpha(ctx, 1); - core.fillBoldText1( - ctx, - one.value, - one.px, - one.py, - one.color || "red", - one.boldColor || "black", - 2, - one.font - ); - if (one.frame >= one.time + one.show) count++; - }); - if (count > 0) list.splice(0, count); - } - if (!main.replayChecking) core.registerAnimationFrame("pop", true, pop); - - /** 添加弹出内容 */ - this.addPop = function ( - value, - px, - py, - color, - boldColor, - left, - jump, - time, - show, - font, - speed - ) { - var data = { - px: px, - py: py, - value: value, - color: color || colorD, - boldColor: boldColor || boldColorD, - frame: 0, - left: left || false, - jump: jump || false, - time: time || 60, - show: show || 30, - font: font || fontD, - speed: speed || 1, - }; - if (!core.status.pop) core.status.pop = [data]; - else core.status.pop.push(data); - }; -}, - "warning": function () { - // 在此增加新插件 - // 默认音效名 - var defaultSound = "jingbao.mp3"; - // 默认字体名 - var defaultFont = "Verdana"; - - var timeout; - /** warning提示 - * @param {number} x 横坐标 - * @param {number} y 纵坐标 - * @param {string} text 显示的文字 - */ - this.drawWarning = function (x, y, size, text, text2, warning) { - if (timeout) return; - x = x ?? 6; - y = y ?? 6; - text = text || "boss"; - text += "
"; - for (var i = 0; i < 10; i++) text += " "; - text += text2; - // 生成文字 - var elements = document.querySelectorAll(".gameCanvas"); - var t = document.createElement("p"); - t.innerHTML = text; - t.style.position = "absolute"; - t.style.fontSize = size * core.domStyle.scale + "px"; - t.style.left = -(300 * core.domStyle.scale) + "px"; - t.style.top = parseInt(elements[0].style.height) / 2 - 100 + "px"; - t.style.zIndex = "300"; - t.style.color = "#f11"; - t.style.fontFamily = defaultFont; - t.style.overflow = "none"; - t.style.width = "100%"; - t.classList.add("warning"); - core.dom.gameDraw.appendChild(t); - setTimeout(function () { - t.style.left = 416 * core.domStyle.scale + "px"; - }, 50); - // 计算偏移量 - var px = ((6 - x) / 12) * 50; - var py = ((6 - y) / 12) * 50; - // 修改画布的scale和transform - elements.forEach(function (v) { - if (v instanceof HTMLCanvasElement) { - v.style.transform = "scale(2)translate(" + px + "%, " + py + "%)"; - } - }); - if (!warning) core.playSound(defaultSound); - // 拉回镜头 - timeout = setTimeout(function () { - timeout = setTimeout(function () { - timeout = void 0; - core.dom.gameDraw.removeChild(t); - }, 1500); - elements.forEach(function (v) { - if (v instanceof HTMLCanvasElement) { - v.style.transform = "none"; - } - }); - }, 1600); - }; -}, - "立体声音效": function () { // 在此增加新插件 - // 音效双声道播放 - var can = true; - if (!AudioContext) { - console.warn("该浏览器不支持AudioContext,无法播放立体声"); - can = false; - } - if (can) var ac = new AudioContext(); - var datas = {}; - - /** 播放立体声 参考:https://developer.mozilla.org/zh-CN/docs/Web/API/BaseAudioContext/createChannelSplitter - * @param {number} name 音效名 - * @param {number} left 左声道音量,默认为1 - * @param {number} right 右声道音量,默认为1 - * @param {boolean} split 音效为双声道,请填true,为单声道,请填false或不填 - * @returns 该音效的唯一id + /* 弹出显示某个内容 + * 使用方法:core.addPop(px, py, value, color, boldColor, left, jump, time, show, font, speed) + * 参数说明: + * px & py: number 弹出位置 + * value: string 显示内容 + * color: string 填充颜色 + * boldColor: string 描边颜色 */ - this.playStereo = function (name, left, right, split) { - if (!can) return core.playSound(name); - var sound = core.getMappedName(name); - if ( - main.mode != "play" || - !core.musicStatus.soundStatus || - !core.material.sounds[sound] - ) - return; - if (!core.status.stereo) core.status.stereo = {}; - var buffer = core.material.sounds[sound]; - var source = ac.createBufferSource(); - source.buffer = buffer; - var splitter = ac.createChannelSplitter(2); - source.connect(splitter); - var merger = ac.createChannelMerger(2); - /* 大致流程 - gain(L) - / \ - source ---- splitter merger ---- destination - \ / - gain(R) - */ + // 默认字体 + var fontD = "16px Verdana"; + // 默认颜色 + var colorD = "red"; + // 默认描边颜色 + var boldColorD = "black"; - var L = ac.createGain(); - var R = ac.createGain(); - L.gain.value = left * core.musicStatus.userVolume; - R.gain.value = right * core.musicStatus.userVolume; - splitter.connect(L, 0, 0); - if (!split) splitter.connect(R, 0, 0); - else splitter.connect(R, 1, 0); - - var id = setTimeout(null); - core.status.stereo[id] = { source: source, L: L, R: R }; - - L.connect(merger, 0, 0); - R.connect(merger, 0, 1); - - var dest = ac.destination; - - source.onended = function () { - delete datas[id]; - source = void 0; - }; - - merger.connect(dest); - source.start(0); - return id; - }; - - /** 移动声源(渐变调整左右声道音量) - * @param {number} id 为playStereo返回的id - * @param {number} left 要渐变到的左声道音量 - * @param {number} right 要渐变到的右声道音量 - * @param {number} time 渐变时间 - */ - this.moveStereo = function (id, left, right, time) { - if (!can) return; - if (main.mode != "play" || !core.musicStatus.soundStatus) return; - var stereo = core.status.stereo[id]; - datas[id] = { - time: time, - curr: 0, - dL: - ((left - stereo.L.gain.value) / time) * - 10 * - core.musicStatus.userVolume, - dR: - ((right - stereo.R.gain.value) / time) * - 10 * - core.musicStatus.userVolume, - }; - var interval = setInterval(function () { - var data = datas[id]; - if (!data) return clearInterval(interval); - data.curr += 10; - if (data.curr >= data.time) { - clearInterval(interval); - datas[id] = void 0; + /** 血量弹出 */ + function pop() { + var ctx = core.getContextByName("pop"); + if (!ctx) + ctx = core.createCanvas( + "pop", + 0, + 0, + core.__PIXELS__, + core.__PIXELS__, + 90 + ); + ctx.canvas.classList.add("gameCanvas", "anti-aliasing"); + core.clearMap(ctx); + core.setTextAlign("pop", "left"); + var list = core.status.pop || []; + var count = 0; + list.forEach(function (one) { + // 由frame计算出dy + var dy = 6 - one.frame * 0.2; + var dx = one.speed; + if (one.jump) { + one.py -= dy; } - stereo.L.gain.value += data.dL; - stereo.R.gain.value += data.dR; - }, 10); + if (!one.left) { + one.px += dx; + } else { + one.px -= dx; + } + one.frame++; + // 绘制 + if (one.frame >= one.time) + core.setAlpha(ctx, 1 - (one.frame - one.time) / one.show); + else core.setAlpha(ctx, 1); + core.fillBoldText1( + ctx, + one.value, + one.px, + one.py, + one.color || "red", + one.boldColor || "black", + 2, + one.font + ); + if (one.frame >= one.time + one.show) count++; + }); + if (count > 0) list.splice(0, count); + } + let now = 0; + if (!main.replayChecking) + core.registerAnimationFrame("pop", true, (temptime) => { + if (temptime - now > 1000 / 60) { + now = temptime; + pop(); + } + }); + + /** 添加弹出内容 */ + this.addPop = function ( + value, + px, + py, + color, + boldColor, + left, + jump, + time, + show, + font, + speed + ) { + var data = { + px: px, + py: py, + value: value, + color: color || colorD, + boldColor: boldColor || boldColorD, + frame: 0, + left: left || false, + jump: jump || false, + time: time || 60, + show: show || 30, + font: font || fontD, + speed: speed || 1, + }; + if (!core.status.pop) core.status.pop = [data]; + else core.status.pop.push(data); + }; + }, + "warning": function () { + // 默认音效名 + var defaultSound = "jingbao.mp3"; + // 默认字体名 + var defaultFont = "Verdana"; + + var timeout; + /** warning提示 + * @param {number} x 横坐标 + * @param {number} y 纵坐标 + * @param {string} text 显示的文字 + */ + this.drawWarning = function ( + x, + y, + text, + text2, + warning, + large = 2, + size = 36 + ) { + if (timeout) return; + x = x ?? 6; + y = y ?? 6; + text = text || "boss"; + text += "
"; + for (var i = 0; i < 10; i++) text += " "; + text += text2; + // 生成文字 + var elements = document.querySelectorAll(".gameCanvas"); + var t = document.createElement("p"); + t.innerHTML = text; + t.style.position = "absolute"; + t.style.fontSize = size * core.domStyle.scale + "px"; + t.style.left = -(300 * core.domStyle.scale) + "px"; + t.style.top = parseInt(elements[0].style.height) / 2 - 100 + "px"; + t.style.zIndex = "300"; + t.style.color = "#f11"; + t.style.fontFamily = defaultFont; + t.style.overflow = "none"; + t.style.width = "100%"; + t.classList.add("warning"); + core.dom.gameDraw.appendChild(t); + setTimeout(function () { + t.style.left = 416 * core.domStyle.scale + "px"; + }, 50); + // 计算偏移量 + var px = ((6 - x) / 12) * (100 - 100 / large + 2); + var py = ((6 - y) / 12) * (100 - 100 / large + 2); + // 修改画布的scale和transform + let time = 0; + let s = 1; + let sx = 0; + let sy = 0; + let cishu = 1; + core.registerAnimationFrame("big", true, function (temptime) { + if (temptime - time > 10) { + time = temptime; + s += (large - 1) / 30; + sx += px / 30; + sy += py / 30; + elements.forEach(function (v) { + if (v instanceof HTMLCanvasElement) { + v.style.transform = + "scale(" + s + ")translate(" + sx + "%, " + sy + "%)"; + } + }); + cishu++; + if (cishu == 30) { + core.unregisterAnimationFrame("big"); + } + } + }); + if (!warning) core.playSound(defaultSound); + // 拉回镜头 + timeout = setTimeout(function () { + // timeout = setTimeout(function () { + // timeout = void 0; + // core.dom.gameDraw.removeChild(t); + // }, 1500); + let time2 = 0; + let s2 = large - (large - 1) / 30; + let sx2 = px; + let sy2 = py; + let cishu2 = 1; + core.registerAnimationFrame("small", true, function (temptime) { + if (temptime - time2 > 10) { + time2 = temptime; + s2 -= (large - 1) / 30; + sx2 -= px / 30; + sy2 -= py / 30; + elements.forEach(function (v) { + if (v instanceof HTMLCanvasElement) { + v.style.transform = + "scale(" + s2 + ")translate(" + sx2 + "%, " + sy2 + "%)"; + } + }); + cishu2++; + if (cishu2 == 30) { + core.unregisterAnimationFrame("small"); + elements.forEach(function (v) { + if (v instanceof HTMLCanvasElement) { + v.style.transform = "none"; + } + }); + } + } + }); + // elements.forEach(function (v) { + // if (v instanceof HTMLCanvasElement) { + // v.style.transform = "none"; + // } + // }); + }, 1600); }; }, "滑动转场": function () { @@ -12668,6 +15615,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.clearContinueAutomaticRoute(); core.status.replay.animate = true; clearInterval(core.interval.onDownInterval); + delete core.animateFrame.tip; core.interval.onDownInterval = "tmp"; this._changeFloor_beforeChange(info, block, callback); @@ -12682,7 +15630,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = block && block?.event && !main.replayChecking && - !core.isReplaying() + !core.isReplaying() && + !core.getFlag("__isFlying__", false) ) { const dirEntries = allChangeEntries.find( (v) => v[1] === block.event.id @@ -12807,519 +15756,930 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "剧情cg": function () { - // 在此增加新插件 - const cg = document.createElement("canvas"); //cg画布设置 - cg.style.position = "absolute"; - cg.style.zIndex = 300; - cg.style.display = "none"; - cg.id = "cgText"; - main.dom.gameGroup.insertAdjacentElement("afterend", cg); - cg.style.top = "50%"; - cg.style.left = "50%"; - cg.style.transform = "translate(-50%,-50%)"; - const ctx = cg.getContext("2d"); - main.dom.cgText = cg; + // 在此增加新插件 + // 在此增加新插件 + const cg = document.createElement("canvas"); //cg画布设置 + cg.style.position = "absolute"; + cg.style.zIndex = 300; + cg.style.display = "none"; + cg.id = "cgText"; + main.dom.gameGroup.insertAdjacentElement("afterend", cg); + cg.style.top = "50%"; + cg.style.left = "50%"; + cg.style.transform = "translate(-50%,-50%)"; + const ctx = cg.getContext("2d"); + main.dom.cgText = cg; + const logcanvas = document.createElement("canvas"); //cg画布设置 + logcanvas.style.position = "absolute"; + logcanvas.style.zIndex = 301; + logcanvas.style.display = "none"; + logcanvas.id = "cgText"; + main.dom.gameGroup.insertAdjacentElement("afterend", logcanvas); + logcanvas.style.top = "50%"; + logcanvas.style.left = "50%"; + logcanvas.style.transform = "translate(-50%,-50%)"; + const logctx = logcanvas.getContext("2d"); + main.dom.logcanvas = logcanvas; + logcanvas.onmouseup = function (e) { + //鼠标抬起 - cg.onmouseup = function (e) { - //鼠标抬起 + try { + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - core.unregisterAnimationFrame("skip"); - let a = core.getFlag("skip", false); - core.setFlag("skip", false); - if (a) { - const data = core.clone(core.status.event.data.current); + core.insertAction(data); + core.doAction(); + } + } catch (ee) { + console.error(ee); + } + }; + logcanvas.onmousedown = function (e) { + //鼠标按下 + try { + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; + logcanvas.ontouchend = function (e) { + //触摸抬起 - core.insertAction(data); - core.doAction(); - } - } catch (ee) { - console.error(ee); - } - }; - cg.onmousedown = function (e) { - //鼠标按下 - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.cgText.click(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; - cg.ontouchend = function (e) { - //触摸抬起 + try { + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + core.setFlag("skip", false); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - core.unregisterAnimationFrame("skip"); - core.setFlag("skip", false); - let a = core.getFlag("skip", false); - core.setFlag("skip", false); - if (a) { - const data = core.clone(core.status.event.data.current); + core.insertAction(data); + core.doAction(); + } + } catch (ee) {} + }; + logcanvas.ontouchstart = function (e) { + //触摸按下 + try { + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.targetTouches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor( + (e.targetTouches[0].clientY - top) / core.domStyle.scale + ); + core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; + cg.onmouseup = function (e) { + //鼠标抬起 - core.insertAction(data); - core.doAction(); - } - } catch (ee) { - console.error(ee); - } - }; - cg.ontouchstart = function (e) { - //触摸按下 - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor( - (e.targetTouches[0].clientX - left) / core.domStyle.scale - ), - py = Math.floor( - (e.targetTouches[0].clientY - top) / core.domStyle.scale - ); - core.ui.cgText.click(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; - let auto = false; - class cgText { - constructor() { - //绘制需要的变量 - this.image = ""; - this.head = { name: "face_050445.webp", px: -300 }; - this.bodyList = [ - { name: "tati_050145a.webp", px: 100, filter: false }, - { name: "tati_120124.webp", px: 1100, filter: true }, - ]; - this.name = ""; - this.text = ""; - this.time = 0; - this.WindowSkin = false; - this.sound = ""; - this.beforeSound = 0; - this.wait = 200; - this.memory = false; - } - click(px, py) { - //点击效果 + try { + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); - const makeBox = ([x, y], [w, h]) => { - return [ - [x, y], - [x + w, y + h], - ]; - }; - const inRect = ([x, y], [[sx, sy], [dx, dy]]) => { - return sx <= x && x <= dx && sy <= y && y <= dy; - }; - const pos = [px, py]; - const savebox = makeBox([1700, 1100], [192, 96]); - const saveboxVertical = makeBox([52, 1700], [96, 192]); - const skipbox = makeBox([1400, 1100], [192, 96]); - const skipboxVertical = makeBox([52, 1400], [96, 192]); - const autobox = makeBox([1700, 900], [192, 96]); - const autoboxVertical = makeBox([256, 1700], [96, 192]); - if ( - (core.domStyle.isVertical && - inRect(pos, skipboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, skipbox)) - ) { - auto = false; - let time = 0; - core.stopSound(this.beforeSound); - core.registerAnimationFrame("skip", true, (timestamp) => { - if (timestamp > time + 50) { - time = timestamp; - if ( - core.status.event.id == "action" && - core.status.event.data.type == "cgtext" - ) { - core.setFlag("skip", true); - main.dom.cgText.style.display = "none"; - core.doAction(); - } - } - }); - } else if ( - (core.domStyle.isVertical && - inRect(pos, autoboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, autobox)) - ) { - auto = !auto; + core.insertAction(data); + core.doAction(); + } + } catch (ee) { + console.error(ee); + } + }; + cg.onmousedown = function (e) { + //鼠标按下 + try { + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; + cg.ontouchend = function (e) { + //触摸抬起 - const data = core.clone(core.status.event.data.current); - data.showAll = true; - data.time = 0; - data.text = data.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除打字机暂停效果 - data.sound = ""; - core.insertAction(data); - core.doAction(); - } else if ( - (core.domStyle.isVertical && - inRect(pos, saveboxVertical) && - !this.WindowSkin) || - (!core.domStyle.isVertical && - !this.WindowSkin && - inRect(pos, savebox)) - ) { - //存档 - auto = false; - if (core.status.event.animateUI) return; - if (core.status.event.interval != null) return; - const current = core.clone(core.status.event.data.current); - current.showAll = true; - current.time = 0; - current.sound = ""; - current.text = current.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除当前事件所有打字机效果 - cg.style.display = "none"; - const data = [{ type: "callSave" }, current]; //插入存档事件 - core.insertAction(data); + try { + if (!core.isPlaying()) return false; + core.unregisterAnimationFrame("skip"); + core.setFlag("skip", false); + let a = core.getFlag("skip", false); + core.setFlag("skip", false); + if (a) { + const data = core.clone(core.status.event.data.current); - core.doAction(); - } else if (!core.status.event.data) { - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); - } else { - // 正在淡入淡出的话不执行 - if (core.status.event.animateUI) return; - auto = false; + core.insertAction(data); + core.doAction(); + } + } catch (ee) { + console.error(ee); + } + }; + cg.ontouchstart = function (e) { + //触摸按下 + try { + if (!core.isPlaying()) return false; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.targetTouches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor( + (e.targetTouches[0].clientY - top) / core.domStyle.scale + ); + core.ui.cgText.click(px * 3, py * 3); + } catch (ee) { + main.log(ee); + } + }; + let auto = false; - // 打字机效果显示全部文字 - if (core.status.event.interval != null) { - const data = core.clone(core.status.event.data?.current); - data.showAll = true; - data.time = 0; - data.text = data.text.replace(/(\\(z))(\[.*?])?/g, ""); //去除打字机暂停效果 - data.sound = ""; - core.insertAction(data); - core.doAction(); - return; - } else { - core.stopSound(this.beforeSound); - } + class cgText { + constructor() { + this.nobg = false; + //绘制需要的变量 + this.image = ""; + this.head = { name: "face_050445.webp", px: -300 }; + this.bodyList = [ + { name: "tati_050145a.webp", px: 100, filter: false }, + { name: "tati_120124.webp", px: 1100, filter: true }, + ]; + this.name = ""; + this.text = ""; + this.time = 0; + this.WindowSkin = false; + this.sound = ""; + this.beforeSound = 0; + this.wait = 1000; + this.memory = false; + this.textList = []; + this.page = 1; + this.overpage = 1; + this.log = false; + this.index = 0; + } + click(px, py) { + //点击效果 - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); - } - } + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + const savebox = makeBox([1700, 1100], [192, 96]); + const saveboxVertical = makeBox([52, 1700], [96, 192]); + const skipbox = makeBox([1700, 1000], [192, 96]); + const skipboxVertical = makeBox([152, 1700], [96, 192]); + const autobox = makeBox([1700, 900], [192, 96]); + const autoboxVertical = makeBox([252, 1700], [96, 192]); + const textbox = makeBox([1700, 800], [192, 96]); + const textboxVertical = makeBox([352, 1700], [96, 192]); + const backbox = makeBox([15, 35], [210, 90]); + const backboxVertical = makeBox([1123, 15], [90, 210]); + const pageupbox = makeBox([300, 1130], [200, 100]); + const pageupboxVertical = makeBox([18, 300], [100, 200]); + const pagedownbox = makeBox([1500, 1130], [200, 100]); + const pagedownboxVertical = makeBox([18, 1500], [100, 200]); + const soundbox = makeBox([550, 150], [100, 900]); + const soundboxVertical = makeBox([198, 550], [900, 100]); + if (this.log) { + if ( + (core.domStyle.isVertical && inRect(pos, backboxVertical)) || + (!core.domStyle.isVertical && inRect(pos, backbox)) + ) { + core.clearMap(logctx); + core.stopSound(); + main.dom.logcanvas.style.display = "none"; + this.log = false; + } else if ( + (core.domStyle.isVertical && inRect(pos, pageupboxVertical)) || + (!core.domStyle.isVertical && inRect(pos, pageupbox)) + ) { + core.clearMap(logctx); + if (this.page > 1) this.page--; + this.logdraw(this.page); + } else if ( + (core.domStyle.isVertical && inRect(pos, pagedownboxVertical)) || + (!core.domStyle.isVertical && inRect(pos, pagedownbox)) + ) { + core.clearMap(logctx); + if (this.page < this.overpage) this.page++; + this.logdraw(this.page); + } else if ( + (core.domStyle.isVertical && inRect(pos, soundboxVertical)) || + (!core.domStyle.isVertical && inRect(pos, soundbox)) + ) { + if (core.domStyle.isVertical) { + const sound = + this.textList[ + (this.page - 1) * 6 + + Math.min(Math.floor((px - 198) / 150), 5) + ][2]; + core.stopSound(); + core.playSound(sound); + } else { + const sound = + this.textList[ + (this.page - 1) * 6 + + Math.min(Math.floor((py - 150) / 150), 5) + ][2]; + core.stopSound(); + core.playSound(sound); + } + } + } else { + if ( + (core.domStyle.isVertical && + inRect(pos, skipboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, skipbox)) + ) { + auto = false; + let time = 0; + core.stopSound(this.beforeSound); + core.registerAnimationFrame("skip", true, (timestamp) => { + if (timestamp > time + 50) { + time = timestamp; + if ( + core.status.event.id == "action" && + core.status.event.data.type == "cgtext" + ) { + core.setFlag("skip", true); + main.dom.cgText.style.display = "none"; + core.doAction(); + } + } + }); + } else if ( + (core.domStyle.isVertical && + inRect(pos, textboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, textbox)) + ) { + auto = false; + this.log = true; + this.overpage = Math.floor(this.index / 6) + 1; + this.page = this.overpage; + logcanvas.style.display = "block"; + const data = core.clone(core.status.event.data.current); + data.showAll = true; + data.time = 0; + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 + data.sound = ""; + core.insertAction(data); + core.doAction(); + this.logdraw(this.page); + } else if ( + (core.domStyle.isVertical && + inRect(pos, autoboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, autobox)) + ) { + auto = !auto; - drawTextContent(ctx, content, config) { - //绘制多行文字并执行打字机效果 + const data = core.clone(core.status.event.data.current); + data.showAll = true; + data.time = 0; + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 + data.sound = ""; + core.insertAction(data); + core.doAction(); + } else if ( + (core.domStyle.isVertical && + inRect(pos, saveboxVertical) && + !this.WindowSkin) || + (!core.domStyle.isVertical && + !this.WindowSkin && + inRect(pos, savebox)) + ) { + //存档 + auto = false; + if (core.status.event.animateUI) return; + if (core.status.event.interval != null) return; + const current = core.clone(core.status.event.data.current); + current.showAll = true; + current.time = 0; + current.sound = ""; + current.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除当前事件所有打字机效果 + cg.style.display = "none"; + const data = [{ type: "callSave" }, current]; //插入存档事件 + core.insertAction(data); - ctx = core.getContextByName(ctx); - // 设置默认配置项 - var textAttribute = - core.status.textAttribute || core.initStatus.textAttribute; - var globalAttribute = - core.status.globalAttribute || core.initStatus.globalAttribute; - config = core.clone(config || {}); - config.left = config.left || 0; - config.right = - config.left + (config.maxWidth == null ? core._PX_ : config.maxWidth); - config.top = config.top || 0; - config.color = core.arrayToRGBA(config.color || textAttribute.text); - if (config.bold == null) config.bold = textAttribute.bold; - config.italic = config.italic || false; - config.align = config.align || textAttribute.align || "left"; - config.fontSize = config.fontSize || textAttribute.textfont; - config.lineHeight = config.lineHeight || config.fontSize * 1.3; - config.defaultFont = config.font = config.font || globalAttribute.font; - config.time = config.time || 0; - config.letterSpacing = - config.letterSpacing == null - ? textAttribute.letterSpacing || 0 - : config.letterSpacing; + core.doAction(); + } else if (!core.status.event.data) { + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } else { + // 正在淡入淡出的话不执行 + if (core.status.event.animateUI) return; + auto = false; - config.index = 0; - config.currcolor = config.color; - config.currfont = config.fontSize; - config.lineMargin = Math.max( - Math.round(config.fontSize / 4), - config.lineHeight - config.fontSize - ); - config.topMargin = parseInt(config.lineMargin / 2); - config.lineMaxHeight = config.lineMargin + config.fontSize; - config.offsetX = 0; - config.offsetY = 0; - config.line = 0; - config.blocks = []; - config.isHD = ctx == null || ctx.canvas.hasAttribute("isHD"); + // 打字机效果显示全部文字 + if (core.status.event.interval != null) { + const data = core.clone(core.status.event.data?.current); + data.showAll = true; + data.time = 0; + data.text = this.text.replaceAll(/(\\(z))(\[.*?\])?/g, ""); //去除打字机暂停效果 + data.sound = ""; + core.insertAction(data); + core.doAction(); + return; + } else { + core.stopSound(this.beforeSound); + } - // 创建一个新的临时画布 - var tempCtx = document.createElement("canvas").getContext("2d"); - if (config.isHD && ctx) { - core.maps._setHDCanvasSize( - tempCtx, - ctx.canvas.width, - ctx.canvas.height - ); - } else { - tempCtx.canvas.width = ctx == null ? 1 : ctx.canvas.width; - tempCtx.canvas.height = ctx == null ? 1 : ctx.canvas.height; - } + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } + } + } - tempCtx.textBaseline = "top"; - tempCtx.font = core.ui._buildFont( - config.fontSize, - config.bold, - config.italic, - config.font - ); - tempCtx.fillStyle = config.color; - config = this._drawTextContent_draw(ctx, tempCtx, content, config); - return config; - } - _drawTextContent_draw(ctx, tempCtx, content, config) { - // Step 1: 绘制到tempCtx上,并记录下图块信息 - while (core.ui._drawTextContent_next(tempCtx, content, config)); + drawTextContent(ctx, content, config) { + //绘制多行文字并执行打字机效果 - if (ctx == null) return config; + ctx = core.getContextByName(ctx); + // 设置默认配置项 + var textAttribute = + core.status.textAttribute || core.initStatus.textAttribute; + var globalAttribute = + core.status.globalAttribute || core.initStatus.globalAttribute; + config = core.clone(config || {}); + config.left = config.left || 0; + config.right = + config.left + (config.maxWidth == null ? core._PX_ : config.maxWidth); + config.top = config.top || 0; + config.color = core.arrayToRGBA(config.color || textAttribute.text); + if (config.bold == null) config.bold = textAttribute.bold; + config.italic = config.italic || false; + config.align = config.align || textAttribute.align || "left"; + config.fontSize = config.fontSize || textAttribute.textfont; + config.lineHeight = config.lineHeight || config.fontSize * 1.3; + config.defaultFont = config.font = config.font || globalAttribute.font; + config.time = config.time || 0; + config.letterSpacing = + config.letterSpacing == null ? + textAttribute.letterSpacing || 0 : + config.letterSpacing; - // Step 2: 从tempCtx绘制到画布上 - config.index = 0; - var _drawNext = function () { - if (config.index >= config.blocks.length) return false; - var block = config.blocks[config.index++]; - if (block != null) { - // It works, why? - const scale = config.isHD - ? devicePixelRatio * core.domStyle.scale - : 1; - ctx.restore(); - ctx.save(); //保存设置 - if (core.domStyle.isVertical) { - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - } - ctx.drawImage( - tempCtx.canvas, - block.left * scale, - block.top * scale, - block.width * scale, - block.height * scale, - config.left + block.left + block.marginLeft, - config.top + block.top + block.marginTop, - block.width, - block.height - ); - ctx.restore(); - } - return true; - }; + config.index = 0; + config.currcolor = config.color; + config.currfont = config.fontSize; + config.lineMargin = Math.max( + Math.round(config.fontSize / 4), + config.lineHeight - config.fontSize + ); + config.topMargin = parseInt(config.lineMargin / 2); + config.lineMaxHeight = config.lineMargin + config.fontSize; + config.offsetX = 0; + config.offsetY = 0; + config.line = 0; + config.blocks = []; + config.isHD = ctx == null || ctx.canvas.hasAttribute("isHD"); - if (config.time == 0) { - while (_drawNext()); - if ( - (auto && !this.WindowSkin && !core.ui.cgText.sound) || - (core.ui.cgText.sound && !core.musicStatus.soundStatus) - ) { - setTimeout(() => { - if (auto) { - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); - } - }, core.ui.cgText.wait); - } - } else { - clearInterval(core.status.event.interval); - core.status.event.interval = setInterval(function () { - if (!_drawNext()) { - clearInterval(core.status.event.interval); - core.status.event.interval = null; - if ( - (auto && !this.WindowSkin && !core.ui.cgText.sound) || - (core.ui.cgText.sound && !core.musicStatus.soundStatus) - ) - setTimeout(() => { - if (auto) { - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); - } - }, core.ui.cgText.wait); - } - }, config.time); - } + // 创建一个新的临时画布 + var tempCtx = document.createElement("canvas").getContext("2d"); + if (config.isHD && ctx) { + core.maps._setHDCanvasSize( + tempCtx, + ctx.canvas.width, + ctx.canvas.height + ); + } else { + tempCtx.canvas.width = ctx == null ? 1 : ctx.canvas.width; + tempCtx.canvas.height = ctx == null ? 1 : ctx.canvas.height; + } - return config; - } + tempCtx.textBaseline = "top"; + tempCtx.font = core.ui._buildFont( + config.fontSize, + config.bold, + config.italic, + config.font + ); + tempCtx.fillStyle = config.color; + config = this._drawTextContent_draw(ctx, tempCtx, content, config); + return config; + } + _drawTextContent_draw(ctx, tempCtx, content, config) { + // Step 1: 绘制到tempCtx上,并记录下图块信息 + while (core.ui._drawTextContent_next(tempCtx, content, config)); - update() { - this.background(); - } - background() { - const img = core.material.images.images?.[this.image]; + if (ctx == null) return config; - if (core.domStyle.isVertical) { - ctx.canvas.width = 1248; - ctx.canvas.height = 2028; - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - } else { - ctx.canvas.width = 2028; - ctx.canvas.height = 1248; - } + // Step 2: 从tempCtx绘制到画布上 + config.index = 0; + var _drawNext = function () { + if (config.index >= config.blocks.length) return false; + var block = config.blocks[config.index++]; + if (block != null) { + // It works, why? + const scale = config.isHD ? + devicePixelRatio * core.domStyle.scale : + 1; + ctx.restore(); + ctx.save(); //保存设置 + if (core.domStyle.isVertical) { + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } + ctx.drawImage( + tempCtx.canvas, + block.left * scale, + block.top * scale, + block.width * scale, + block.height * scale, + config.left + block.left + block.marginLeft, + config.top + block.top + block.marginTop, + block.width, + block.height + ); + ctx.restore(); + } + return true; + }; - if (img) { - //绘制背景 - if (this.memory) ctx.filter = "sepia(50%)"; - ctx.drawImage(img, 0, 0, 2028, 1248); - ctx.filter = "none"; - } else { - core.fillRect(ctx, 0, 0, 2028, 1248); - } - this.bodyList.forEach((v) => { - //绘制立绘 - const body = core.material.images.images?.[v.name]; - if (v.filter) ctx.filter = "brightness(50%)"; - if (body) { - ctx.drawImage( - body, - 0, - 0, - body.width, - body.height, - v.px, - 1248 - body.height * 1.7, - body.width * 1.7, - body.height * 1.7 - ); - } - ctx.filter = "none"; - }); - if (core.isPlaying() && !this.WindowSkin) - core.drawWindowSkin("winskin.webp", ctx, 30, 802, 1968, 416); //绘制对话框 - const head = core.material.images.images?.[this.head.name]; - if (head) { - //绘制头像 - ctx.drawImage( - head, - 0, - 0, - head.width, - head.height, - this.head.px, - 1248 - head.height * 2, - head.width * 2, - head.height * 2 - ); - } - if (core.isPlaying() && !this.WindowSkin) { - core.drawWindowSkin("winskin.webp", ctx, 1700, 1100, 192, 96); - core.fillBoldText1( - ctx, - "存 档", - 1736, - 1166, - "#FFFFFF", - "#000000", - 6, - "bold 48px Verdana" - ); - core.drawWindowSkin("winskin.webp", ctx, 1400, 1100, 192, 96); - core.fillBoldText1( - ctx, - "▶▶", - 1456, - 1166, - "#FFFFFF", - "#000000", - 6, - "bold 48px Verdana" - ); - core.drawWindowSkin("winskin.webp", ctx, 1700, 900, 192, 96); - let autoText = "AUTO"; - if (auto) autoText = "STOP"; - core.fillBoldText1( - ctx, - autoText, - 1722, - 966, - "#FFFFFF", - "#000000", - 6, - "bold 48px Verdana" - ); - } - if (this.name) - core.fillBoldText1( - ctx, - `【${this.name}】`, - 500, - 880, - "#FFFFFF", - "#000000", - 6, - "bold 48px Verdana" - ); //绘制名字 - if ( - this.sound && - core.material.sounds[this.sound] && - !core.getFlag("skip", false) && - core.musicStatus.soundStatus - ) { - this.beforeSound = core.playSound(this.sound, null, () => { - if ( - this.sound && - auto && - !this.WindowSkin && - core.musicStatus.soundStatus - ) { - setTimeout(() => { - if (auto) { - cg.style.display = "none"; - core.ui._animateUI("hide", null, () => { - core.doAction(); - }); - } - }, core.ui.cgText.wait); - } - }); - } - if (this.text && !core.getFlag("skip", false)) { - //绘制对话 - this.drawTextContent(ctx, this.text, { - left: 500, - top: 950, - bold: true, - color: "#FFFFFF", - align: "left", - fontSize: 48, - time: this.time || 0, - font: "Verdana", - maxWidth: 1000, - }); - } + if (config.time == 0) { + while (_drawNext()); - ctx.restore(); - } - } - core.ui.cgText = new cgText(); - }, + if ( + (auto && !core.ui.cgText.WindowSkin && !core.ui.cgText.sound) || + (core.ui.cgText.sound && !core.musicStatus.soundStatus) + ) { + setTimeout(() => { + if (auto) { + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } + }, core.ui.cgText.wait); + } + } else { + clearInterval(core.status.event.interval); + core.status.event.interval = setInterval(function () { + if (!_drawNext()) { + clearInterval(core.status.event.interval); + core.status.event.interval = null; + + if ( + (auto && !core.ui.cgText.WindowSkin && !core.ui.cgText.sound) || + (core.ui.cgText.sound && !core.musicStatus.soundStatus) + ) + setTimeout(() => { + if (auto) { + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } + }, core.ui.cgText.wait); + } + }, config.time); + } + + return config; + } + + update() { + this.background(); + if (this.log) this.logdraw(this.page); + } + logdraw(page) { + if (core.domStyle.isVertical) { + logctx.canvas.width = 1248; + logctx.canvas.height = 2028; + logctx.save(); //保存设置 + logctx.translate(1248, 0); //重新定位右上角为基准 + logctx.rotate(Math.PI / 2); //旋转90度 + } else { + logctx.canvas.width = 2028; + logctx.canvas.height = 1248; + } + core.fillRect(logctx, 0, 0, 2028, 1248, "rgba(0,0,0,0.5)"); + core.setTextAlign(logctx, "center"); + core.fillBoldText1( + logctx, + "◀离开", + 110, + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + logctx.strokeStyle = "#FFFFFF"; + logctx.lineWidth = 3; + logctx.beginPath(); + logctx.moveTo(100, 150); + logctx.lineTo(1928, 150); + + logctx.stroke(); + let posy = 150; + const indexList = this.textList; + core.setTextAlign(logctx, "left"); + for ( + let i = (page - 1) * 6; i <= Math.min(this.index, page * 6 - 1); i++ + ) { + const text = this.textList[i][1].replaceAll( + /(\\(d|e|f|g|i|n|r|b|c|t|z))(\[.*?\])?/g, + "" + ); //取消打字机 + const name = this.textList[i][0] ? + "【" + this.textList[i][0] + "】" : + ""; + const sound = this.textList[i][2]; + if (name) { + core.fillBoldText1( + logctx, + name, + 150, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } + if (sound) core.drawImage(logctx, "sound.webp", 550, posy + 30); + if (text.length < 30) { + core.fillBoldText1( + logctx, + text, + 650, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } else { + let text1 = text.slice(0, 30); + core.fillBoldText1( + logctx, + text1, + 650, + posy + 50, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + if (text.length > 60) { + let text2 = text.slice(30, 60); + let text3 = text.slice(60); + core.fillBoldText1( + logctx, + text2, + 650, + posy + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + core.fillBoldText1( + logctx, + text3, + 650, + posy + 150, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } else { + let text2 = text.slice(30); + core.fillBoldText1( + logctx, + text2, + 650, + posy + 100, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(42, true) + ); + } + } + + logctx.strokeStyle = "#FFFFFF"; + logctx.lineWidth = 3; + logctx.beginPath(); + logctx.moveTo(100, posy); + logctx.lineTo(1928, posy); + logctx.stroke(); + + posy += 160; + } + logctx.beginPath(); + logctx.moveTo(100, 1120); + logctx.lineTo(1928, 1120); + logctx.moveTo(100, 1110); + logctx.lineTo(1928, 1110); + logctx.stroke(); + core.fillBoldText1( + logctx, + "上一页", + 300, + 1200, + page === 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + logctx, + page + "/" + this.overpage, + 1000, + 1200, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + logctx, + "下一页", + 1500, + 1200, + page === this.overpage ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + } + background() { + const img = core.material.images.images?.[this.image]; + + if (core.domStyle.isVertical) { + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; + } + if (this.nobg) {} else { + if (img) { + //绘制背景 + if (this.memory) ctx.filter = "sepia(50%)"; + ctx.drawImage(img, 0, 0, 2028, 1248); + ctx.filter = "none"; + } else { + core.fillRect(ctx, 0, 0, 2028, 1248); + } + } + this.bodyList.forEach((v) => { + //绘制立绘 + const body = core.material.images.images?.[v.name]; + if (v.filter) ctx.filter = "brightness(50%)"; + if (body) { + if (!v.w && !v.h && !v.scale) v.scale = 1.7; + if (!v.w && !v.h) { + ctx.drawImage( + body, + 0, + 0, + body.width, + body.height, + v.px, + 1248 - body.height * v.scale, + body.width * v.scale, + body.height * v.scale + ); + } else { + ctx.drawImage( + body, + 0, + 0, + body.width, + body.height, + v.px, + 1248 - (v.h ?? body.height), + v.w ?? body.width, + v.h ?? body.height + ); + } + } + ctx.filter = "none"; + }); + if (core.isPlaying() && !this.WindowSkin) + core.drawWindowSkin( + "winskin.webp", + ctx, + 30, + 780, + 1968, + 436, + null, + null, + null, + 3 + ); //绘制对话框 + const head = core.material.images.images?.[this.head.name]; + if (head) { + //绘制头像 + ctx.drawImage( + head, + 0, + 0, + head.width, + head.height, + this.head.px, + 1248 - head.height * 2.2, + head.width * 2.2, + head.height * 2.2 + ); + } + if (core.isPlaying() && !this.WindowSkin) { + core.drawWindowSkin( + "winskin.webp", + ctx, + 1700, + 800, + 192, + 96, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx, + "记 录", + 1736, + 866, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + core.drawWindowSkin( + "winskin.webp", + ctx, + 1700, + 1100, + 192, + 96, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx, + "存 档", + 1736, + 1166, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + core.drawWindowSkin( + "winskin.webp", + ctx, + 1700, + 1000, + 192, + 96, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx, + "▶▶", + 1756, + 1066, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + core.drawWindowSkin( + "winskin.webp", + ctx, + 1700, + 900, + 192, + 96, + null, + null, + null, + 3 + ); + let autoText = "AUTO"; + if (auto) autoText = "STOP"; + core.fillBoldText1( + ctx, + autoText, + 1722, + 966, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + } + if (this.name) + core.fillBoldText1( + ctx, + `【${this.name}】`, + 550, + 880, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); //绘制名字 + + if ( + this.sound && + core.sounds && + !core.getFlag("skip", false) && + core.musicStatus.soundStatus + ) { + this.beforeSound = core.playSound(this.sound, null, () => { + if ( + this.sound && + auto && + !this.WindowSkin && + core.musicStatus.soundStatus + ) { + setTimeout(() => { + if (auto) { + cg.style.display = "none"; + core.ui._animateUI("hide", null, () => { + core.doAction(); + }); + } + }, this.wait); + } + }); + } + if (this.text && !core.getFlag("skip", false)) { + //绘制对话 + this.drawTextContent(ctx, this.text, { + left: 550, + top: 950, + bold: true, + color: "#FFFFFF", + align: "left", + fontSize: 48, + time: this.time || 0, + font: "Verdana", + maxWidth: 1000, + }); + } + + ctx.restore(); + } + } + core.ui.cgText = new cgText(); +}, "旁白": function () { // 在此增加新插件 const over = document.createElement("canvas"); //over画布设置 @@ -13384,9 +16744,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = if (frame > hidetime + time && frame <= hidetime * 2 + time) core.setAlpha(ctx, 1 - (frame - hidetime - time) / hidetime); const lisen = - sound && - core.material.sounds[sound] && - core.musicStatus.soundStatus; + sound && core.sounds[sound] && core.musicStatus.soundStatus; if (frame == hidetime && lisen) { sod = core.playSound(sound); } @@ -13556,9 +16914,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.stopSound(sod); } const lisenb = - b.sound && - core.material.sounds[b.sound] && - core.musicStatus.soundStatus; + b.sound && core.sounds[b.sound] && core.musicStatus.soundStatus; if (b.frame && lisenb) { sod = core.playSound(sound); } @@ -13809,430 +17165,2555 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = break; } }; - }, - "属性映射": function () { - // 在此增加新插件 - this.statusEquip = function () { - const hero = core.status.hero; - //装备具体效果在这里写,道具填写道具类型为equip并选择装备类型,道具的装备属性中装备类型遵循以下填写方式: - //固定装备孔的填写0/1/2/3,分别对应主手、副手、防具、饰品 - //主副手同时可使用的,填写 武器 - //具体的换装时装备切换操作写在新道具栏/物品栏插件 - //当前仅完善法杖、单手剑、双手剑、匕首、盾牌的多孔切换操作 - //主武器效果 - if (core.getEquip[0]) { - switch (core.getEquip[0]) { - case "sword1": - hero.atk = hero.str + hero.agi; - hero.magic = false; - break; - } - } - //副手效果 - if (core.getEquip[1]) { - switch (core.getEquip[1]) { - case "sword1": - hero.atk += hero.agi; - break; - } - } - //防具效果 - if (core.getEquip[2]) { - switch (core.getEquip[2]) { - case "sword1": - hero.def = hero.con + hero.agi; - hero.hpmax = 2.5 * hero.con; - break; - } - } - //饰品效果 - if (core.getEquip[3]) { - switch (core.getEquip[3]) { - case "sword1": - hero.speed += 0.4 * hero.int + 0.6 * hero.agi; - break; - } - } - }; - this.updateStatus = function () { - const hero = core.status.hero; - //默认映射关系 - hero.hpmax = hero.str * 50 + hero.con * 50; - hero.atk = hero.str * 0.5 + hero.int * 0.5; - hero.manamax = hero.agi * 0.5 + hero.int * 0.5; - hero.def = hero.con * 0.5 + hero.agi * 0.5; - hero.mdef = hero.con * 0.5 + hero.int * 0.5; - hero.speed = hero.str * 0.5 + hero.agi * 0.5; - hero.magic = false; - this.statusEquip(); //处理装备效果 - for (let v in hero) { - //归整 - if (typeof hero[v] === "number") { - hero[v] = Math.floor(hero[v]); - } - } - hero.hp = Math.min(hero.hp, hero.hpmax); - hero.mana = Math.min(hero.mana, hero.manamax); - core.status.hero = hero; - }; }, "回合制boss战": function () { - // 在此增加新插件 - const boss = document.createElement("canvas"); //boss战画布设置 - boss.style.position = "absolute"; - boss.style.zIndex = 300; - boss.style.display = "none"; - boss.id = "boss"; - main.dom.gameGroup.insertAdjacentElement("afterend", boss); - boss.style.top = "50%"; - boss.style.left = "50%"; - boss.style.transform = "translate(-50%,-50%)"; - const ctx = boss.getContext("2d"); - main.dom.boss = boss; - boss.onclick = function (e) { - try { - e.preventDefault(); - if (core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.boss.onclick(px * 3, py * 3); - } catch (ee) { - main.log(ee); - } - }; - class boss1 { - constructor() { - this.bg = ""; - } - cavans() { - if (core.domStyle.isVertical) { - ctx.canvas.width = 1248; - ctx.canvas.height = 2028; - - core.setTextAlign(ctx, "center"); - } else { - ctx.canvas.width = 2028; - ctx.canvas.height = 1248; - - core.setTextAlign(ctx, "center"); - } - } - start() {} - onclick(px, py) {} - } - core.ui.boss = new boss1(); - }, - "剧情视频引用": function () { // 在此增加新插件 - let a; - let bgm; + const boss = document.createElement("canvas"); //boss战画布设置 + boss.style.position = "absolute"; + boss.style.zIndex = 310; + boss.style.display = "none"; + boss.id = "boss"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss); + boss.style.top = "50%"; + boss.style.left = "50%"; + boss.style.transform = "translate(-50%,-50%)"; + const ctx = boss.getContext("2d"); + main.dom.boss = boss; + const boss1 = document.createElement("canvas"); //boss战画布设置 + boss1.style.position = "absolute"; + boss1.style.zIndex = 300; + boss1.style.display = "none"; + boss1.id = "boss1"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss1); + boss1.style.top = "50%"; + boss1.style.left = "50%"; + boss1.style.transform = "translate(-50%,-50%)"; + const ctx1 = boss1.getContext("2d"); + main.dom.boss1 = boss1; + const boss2 = document.createElement("canvas"); //boss战画布设置 + boss2.style.position = "absolute"; + boss2.style.zIndex = 301; + boss2.style.display = "none"; + boss2.id = "boss2"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss2); + boss2.style.top = "50%"; + boss2.style.left = "50%"; + boss2.style.transform = "translate(-50%,-50%)"; + main.dom.boss2 = boss2; + const ctx2 = boss2.getContext("2d"); + const boss3 = document.createElement("canvas"); //boss战画布设置 + boss3.style.position = "absolute"; + boss3.style.zIndex = 302; + boss3.style.display = "none"; + boss3.id = "boss3"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss3); + boss3.style.top = "50%"; + boss3.style.left = "50%"; + boss3.style.transform = "translate(-50%,-50%)"; + main.dom.boss3 = boss3; + const ctx3 = boss3.getContext("2d"); + const boss4 = document.createElement("canvas"); //boss战画布设置 + boss4.style.position = "absolute"; + boss4.style.zIndex = 303; + boss4.style.display = "none"; + boss4.id = "boss4"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss4); + boss4.style.top = "50%"; + boss4.style.left = "50%"; + boss4.style.transform = "translate(-50%,-50%)"; + const ctx4 = boss4.getContext("2d"); + main.dom.boss4 = boss4; + const boss5 = document.createElement("canvas"); //boss战画布设置 + boss5.style.position = "absolute"; + boss5.style.zIndex = 304; + boss5.style.display = "none"; + boss5.id = "boss5"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss5); + boss5.style.top = "50%"; + boss5.style.left = "50%"; + boss5.style.transform = "translate(-50%,-50%)"; + const ctx5 = boss5.getContext("2d"); + main.dom.boss5 = boss5; - function gtouchstart() { - timeOutEvent = setTimeout(() => { - video.remove(); - video1.remove(); - core.doAction(); - clearTimeout(a); - core.playBgm(bgm); - core.resumeBgm(); - }, 2000); //这里设置定时器,定义长按500毫秒触发长按事件,时间可以自己改,个人感觉500毫秒非常合适 - return false; - } + const boss6 = document.createElement("canvas"); //boss战画布设置 + boss6.style.position = "absolute"; + boss6.style.zIndex = 305; + boss6.style.display = "none"; + boss6.id = "boss6"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss6); + boss6.style.top = "50%"; + boss6.style.left = "50%"; + boss6.style.transform = "translate(-50%,-50%)"; + const ctx6 = boss6.getContext("2d"); + main.dom.boss6 = boss6; + const boss7 = document.createElement("canvas"); //boss战画布设置 + boss7.style.position = "absolute"; + boss7.style.zIndex = 306; + boss7.style.display = "none"; + boss7.id = "boss7"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss7); + boss7.style.top = "50%"; + boss7.style.left = "50%"; + boss7.style.transform = "translate(-50%,-50%)"; + const ctx7 = boss7.getContext("2d"); + main.dom.boss7 = boss7; + const boss8 = document.createElement("canvas"); //boss战画布设置 + boss8.style.position = "absolute"; + boss8.style.zIndex = 307; + boss8.style.display = "none"; + boss8.id = "boss8"; + main.dom.gameGroup.insertAdjacentElement("afterend", boss8); + boss8.style.top = "50%"; + boss8.style.left = "50%"; + boss8.style.transform = "translate(-50%,-50%)"; + const ctx8 = boss8.getContext("2d"); + main.dom.boss8 = boss8; + const { imagelighter } = core.plugin.utils; - //手释放,如果在500毫秒内就释放,则取消长按事件,此时可以执行onclick应该执行的事件 - function gtouchend() { - if (timeOutEvent != 0) { - //这里写要执行的内容(尤如onclick事件) - console.log("你这是点击,不是长按"); - } - clearTimeout(timeOutEvent); //清除定时器 - return false; - } + function getClick() { + return new Promise((resolve) => { + function handleBossClick(e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; - this.openvideo = function () { - if (!core.isPlaying()) return; - const video = document.createElement("iframe"); //iframe设置 - video.style.position = "absolute"; - video.style.zIndex = 320; - video.style.display = "block"; - video.id = "video"; - main.dom.gameGroup.insertAdjacentElement("afterend", video); - video.style.top = "50%"; - video.style.left = "50%"; - video.style.transform = "translate(-50%,-50%)"; - main.dom.video = video; - const video1 = document.createElement("canvas"); //video1画布设置 - video1.style.position = "absolute"; - video1.style.zIndex = 330; - video1.style.display = "block"; - video1.id = "video1"; - main.dom.gameGroup.insertAdjacentElement("afterend", video1); - video1.style.top = "50%"; - video1.style.left = "50%"; - video1.style.transform = "translate(-50%,-50%)"; - const ctx = video1.getContext("2d"); - main.dom.video1 = video1; - if (core.domStyle.isVertical) { - video.width = 416 * 3; - video.height = 676 * 3; - video.style.transform = "translate(-50%,-50%) rotate(90deg)"; //重新定位右上角为基准 - } else { - video.width = 676 * 3; - video.height = 416 * 3; - video.style.transform = "translate(-50%,-50%)"; - } - video1.ontouchstart = function (e) { - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - gtouchstart(); - } catch (ee) { - main.log(ee); - } - }; - video1.ontouchend = function (e) { - try { - e.preventDefault(); - if (!core.isPlaying()) return false; - gtouchend(); - } catch (ee) { - main.log(ee); - } - }; + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); - video1.onmouseup = function (e) { - //鼠标抬起 - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - gtouchend(); - } catch (ee) { - console.error(ee); - } - }; - video1.onmousedown = function (e) { - //鼠标按下 - try { - e.stopPropagation(); - if (!core.isPlaying()) return false; - gtouchstart(); - } catch (ee) { - main.log(ee); - } - }; - let globalAlpha = 0; - let frame = 1; - let al = 0; - core.registerAnimationFrame("beforeop", true, function () { - al++; - core.clearMap(ctx) - ctx.globalAlpha = al / 30; - core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); - ctx.globalAlpha = 1; - core.fillBoldText1( - ctx, - "Loading...", - 1014, - 624, - "#FFFFFF", - "#000000", - 6, - "bold 72px Verdana" - ); - }); - core.control.resize(); + let x, y; + if (core.domStyle.isVertical) { + x = py * 3; + y = 1248 - px * 3; + } else { + x = px * 3; + y = py * 3; + } + core.ui.boss.click(x, y); - //player.bilibili.com/player.html - //www.bilibili.com/blackboard/html5mobileplayer.html - // - video.src = - "///www.bilibili.com/blackboard/html5mobileplayer.html?isOutside=true&aid=6484104&bvid=BV1cs411b7cH&cid=10546155&p=1&poster=0&autoplay=1&high_quality=1&muted=0&danmaku=0"; - video.scrolling = "no"; - video.border = "0"; - video.crossorigin = true; - video.frameborder = "no"; - video.framespacing = "0"; - video.allowfullscreen = false; - - video.sandbox = - "allow-top-navigation allow-same-origin allow-forms allow-scripts"; - //gsl_play_mask - - video.addEventListener("load", function () { - core.unregisterAnimationFrame("beforeop"); - core.registerAnimationFrame("op", true, function () { - core.clearMap(ctx); - if (core.domStyle.isVertical) { - ctx.canvas.width = 416 * 3; - ctx.canvas.height = 676 * 3; - ctx.save(); //保存设置 - ctx.translate(416 * 3, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 - } else { - ctx.canvas.width = 676 * 3; - ctx.canvas.height = 416 * 3; + if ( + x > 1050 && + x < 1450 && + y > 250 && + y < 390 && + !core.ui.boss.show && + core.ui.boss.hasEnemy() + ) { + // 移除事件监听器 + boss.removeEventListener("click", handleBossClick); + resolve("普通攻击"); //有小怪时点击普通攻击 + return; // 退出函数 + } + if ( + x > 850 && + x < 1250 && + y > 250 && + y < 390 && + !core.ui.boss.show && + !core.ui.boss.hasEnemy() + ) { + // 移除事件监听器 + boss.removeEventListener("click", handleBossClick); + resolve("普通攻击"); //无小怪时点击普通攻击 + return; // 退出函数 + } + } catch (ee) { + main.log(ee); } - ctx.globalAlpha = 1; - core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); + } + boss.addEventListener("click", handleBossClick); + }); + } + const { sleep } = core.plugin.utils; - ctx.globalAlpha = globalAlpha / 30; - core.setTextAlign(ctx, "center"); + class Boss { + constructor() { + //绘制需要的变量 + this.enemyfarme = 0; + this.bg = "bg_3512.webp"; + this.heroImage = "tati_310101.webp"; + this.hero = { + id: "hero", + name: "凯伊姆", + hp: 1000, + atk: 150, + def: 100, + spell: 100, + speed: 10, + mdef: 10, + }; + this.boss = { + name: "菲奥奈", + id: "angel", + image: "tati_050143.webp", + hp: 1000, + atk: 200, + def: 100, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }; + this.enemy = []; + this.enemy = [{ + name: "小蝙蝠", + id: "bat", + image: "tati_020125a.webp", + hp: 1000, + atk: 100, + def: 20, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + { + name: "红蝙蝠", + id: "redBat", + image: "tati_050301.webp", + hp: 1000, + atk: 100, + def: 120, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + { + name: "大蝙蝠", + id: "bigBat", + image: "tati_120101.webp", + hp: 1000, + atk: 100, + def: 100, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + { + name: "绿色史莱姆", + id: "greenSlime", + image: "tati_340115.webp", + hp: 1000, + atk: 100, + def: 100, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + { + name: "红色史莱姆", + id: "redSlime", + image: "tati_430101.webp", + hp: 1000, + atk: 100, + def: 100, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + { + name: "黑色史莱姆", + id: "blackSlime", + image: "tati_440101.webp", + hp: 1000, + atk: 100, + def: 100, + speed: 10, + mdef: 10, + skill: ["普通攻击", "重斩"], + index: 0, + }, + ]; + this.selection = "boss"; + this.herobuff = [ + { id: "sword1", count: 1 }, + { id: "fly", count: 30 }, + ]; + this.bossbuff = [ + { id: "fly", count: 2 }, + { id: "book", count: 12, hp: 100 }, + ]; + this.enemybuff = [ + [], + [], + [], + [], + [], + [] + ]; + this.skills = { + //技能列表,便于调用(可通过this.skills[name]调用) + 菲奥奈: ["普通攻击", "重斩"], + }; + this.skillShow = { + //技能说明 + 普通攻击: "常规攻击形式,伤害为自身攻击-对手防御", + }; + + this.turn = 0; + this.playingAnimate = new Set(); + this.playerTurn = false; + this.show = false; + } + buffshow(a) { + //buff说明(均未实装,之后改为实际需要的buff) + let text = ""; + switch (a.id) { + case "sword1": + text = `\r[rgb(30,66,30)]剑气:\r造成伤害提升\r[red]${ + 10 * a.count + }%\r`; + break; + case "fly": + text = `羽翼守护:接下来\r[gold]${a.count}回合\r不受速度差值影响`; + break; + case "book": + text = `恢复之书:接下来\r[#000033]${a.count}回合\r,每回合行动时回复\r[green]${a.hp}\r点生命`; + break; + } + return text; + } + shake(hero) { + let time = 0, + farme = 0; + + const xlist = [Math.random() * 40 + 10, Math.random() * -40 - 10, 0]; + return new Promise((resolve) => { + core.registerAnimationFrame("shake", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + + const x = xlist[Math.floor(farme / 5) % 3]; + if (hero) { + const img = imagelighter( + core.material.images.images[this.heroImage] + ); + core.clearMap(ctx2); + if (core.domStyle.isVertical) { + ctx2.canvas.width = 1248; + ctx2.canvas.height = 2028; + ctx2.save(); //保存设置 + ctx2.translate(1248, 0); //重新定位右上角为基准 + ctx2.rotate(Math.PI / 2); //旋转90度 + } else { + ctx2.canvas.width = 2028; + ctx2.canvas.height = 1248; + } + + core.drawImage(ctx2, img, x, 168, 750, 1080); + ctx2.restore(); + } else { + core.clearMap(ctx3); + if (core.domStyle.isVertical) { + ctx3.canvas.width = 1248; + ctx3.canvas.height = 2028; + ctx3.save(); //保存设置 + ctx3.translate(1248, 0); //重新定位右上角为基准 + ctx3.rotate(Math.PI / 2); //旋转90度 + } else { + ctx3.canvas.width = 2028; + ctx3.canvas.height = 1248; + } + if (this.selection === "boss" || this.selection === "") { + const img = imagelighter( + core.material.images.images[this.boss.image] + ); + core.drawImage(ctx3, img, 1400 + x, 168, 750, 1080); + } else { + const img = imagelighter( + core.material.images.images[ + this.enemy[this.selection].image + ] + ); + core.drawImage(ctx3, img, 1400 + x, 168, 750, 1080); + } + + ctx3.restore(); + } + farme++; + if (farme > 30) { + core.unregisterAnimationFrame("shake"); + + this.drawhero(); + this.drawboss(); + resolve(); + } + } + }); + }); + } + popDamage(damage, onhero) { + if (core.domStyle.isVertical) { + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; + } + let color = "#FFFFFF"; + if (typeof damage === "number") { + color = damage < 0 ? "#22FF44" : "lightcoral"; + } + let farme = 0, + time = 0; + let posx = onhero ? 300 : 1800; + const speed = 9; + return new Promise((resolve) => { + core.registerAnimationFrame("popDamageonboss", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx); + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + damage, + posx, + 800 - speed * farme, + color, + "#000000", + 6, + "bold 72px Arial" + ); + farme++; + ctx2.restore(); + if (farme > 30) { + core.unregisterAnimationFrame("popDamageonboss"); + + core.clearMap(ctx); + resolve(); + } + } + }); + }); + } + async skill(sk, a, b) { + //a为发起方属性,sk为技能名 + let damage = 0; + switch ( + sk //所有技能效果及动画写在这里 + ) { + case "普通攻击": + damage = Math.max(a.atk - b.def, 0); //基础伤害 + damage = Math.floor((damage * a.speed) / b.speed); //速度比值伤害加成 + b.hp -= damage; //承受伤害 + if (b.id === "hero") + core.status.hero.statistics.battleDamage += damage; //数据统计记录伤害 + if (damage === 0) damage = "抵抗"; + + switch ( + a.id //根据id选取不同的特效 + ) { + case "hero": + this.popDamage(damage, false); + if (damage > 0 && typeof damage !== "string") this.shake(false); + await this.playanimate("sword", 1800, 800); + break; + case "angel": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("sword", 350, 800); //播放动画sword + + break; + case "bat": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("sword", 350, 800); //播放动画sword + + break; + case "redBat": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("Fire01", 350, 800); //播放动画Fire01 + break; + case "bigBat": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("Fire02", 350, 800); //播放动画Fire02 + break; + case "greenSlime": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("005-Attack03", 350, 800); //播放动画005-Attack03 + break; + case "redSlime": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("012-Heal01", 350, 800); //播放动画012-Heal01 + break; + case "blackSlime": + this.popDamage(damage, true); + if (damage > 0 && typeof damage !== "string") this.shake(true); + await this.playanimate("sword", 350, 800); //播放动画sword + break; + } + break; //下面写其余技能 + } + await sleep(500); //等待1000ms + } + + click(px, py) { + //点击效果 + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + if (main.replayChecking || core.isReplaying()) return; + const enemyStatusBox = makeBox([50, 50], [1900, 200]), + heroStatusBox = makeBox([600, 920], [900, 300]), + bossBox = makeBox([800, 300], [100, 150]), + enemyBox = makeBox([700, 500], [300, 300]), + imageBox = makeBox([1500, 250], [550, 1000]); + if (this.show) { + //清除展示画面 + this.show = !this.show; + core.clearMap(ctx8); + } else { + if ( + inRect(pos, enemyStatusBox) && + this.selection !== "" && + this.selection !== "boss" && + this.hasEnemy() + ) { + //绘制怪物详情 + this.show = !this.show; + this.moreShow(this.selection); + } else if ( + inRect(pos, enemyStatusBox) && + (!this.hasEnemy() || this.selection === "boss") + ) { + //绘制boss详情 + this.show = !this.show; + this.moreShow("boss"); + } else if (inRect(pos, heroStatusBox)) { + //绘制勇士详情 + this.show = !this.show; + this.moreShow("hero"); + } else if (inRect(pos, bossBox) && this.hasEnemy()) { + //切换selection为boss + this.selection = "boss"; + this.update(); + } else if (inRect(pos, enemyBox) && this.hasEnemy()) { + //切换selection为enemy + const symbol = + Math.floor((px - 700) / 100) + Math.floor((py - 500) / 150) * 3; + + if (this.enemy[symbol] && this.enemy[symbol].hp > 0) { + this.selection = symbol; + this.update(); + } + } + } + } + drawchoose() { + if (core.domStyle.isVertical) { + ctx7.canvas.width = 1248; + ctx7.canvas.height = 2028; + ctx7.save(); //保存设置 + ctx7.translate(1248, 0); //重新定位右上角为基准 + ctx7.rotate(Math.PI / 2); //旋转90度 + } else { + ctx7.canvas.width = 2028; + ctx7.canvas.height = 1248; + } + boss7.style.display = "block"; + core.clearMap(ctx7); + if (this.hasEnemy()) { + core.drawWindowSkin( + "winskin.webp", + ctx7, + 1050, + 250, + 400, + 660, + null, + null, + null, + 3 + ); core.fillBoldText1( - ctx, - "长按2秒后跳过op", - 1014, - 624, + ctx7, + "普通攻击", + 1120, + 350, + "#FFFFFF", + "#000000", + 6, + "bold 64px Verdana" + ); + core.drawLine(ctx7, 1050, 390, 1450, 390, "#FFFFFF", 6); + } else { + core.drawWindowSkin( + "winskin.webp", + ctx7, + 850, + 250, + 400, + 660, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx7, + "普通攻击", + 920, + 350, + "#FFFFFF", + "#000000", + 6, + "bold 64px Verdana" + ); + core.drawLine(ctx7, 850, 390, 1250, 390, "#FFFFFF", 6); + } + } + moreShow(select) { + if (core.domStyle.isVertical) { + ctx8.canvas.width = 1248; + ctx8.canvas.height = 2028; + ctx8.save(); //保存设置 + ctx8.translate(1248, 0); //重新定位右上角为基准 + ctx8.rotate(Math.PI / 2); //旋转90度 + } else { + ctx8.canvas.width = 2028; + ctx8.canvas.height = 1248; + } + core.clearMap(ctx8); + core.fillRect(ctx8, 100, 100, 1800, 1000, "rgba(0,0,0,0.7)"); + core.drawWindowSkin( + "winskin.webp", + ctx8, + 100, + 100, + 1800, + 1000, + null, + null, + null, + 3 + ); + let posy = 200; + switch (select) { + case "hero": + //勇士技能/buff + core.fillBoldText1( + ctx8, + this.hero.name, + 1000, + posy, "#FFFFFF", "#000000", 6, "bold 48px Verdana" ); - globalAlpha += frame; - if (globalAlpha > 29) frame = -1; - ctx.restore(); - if (frame === -1 && globalAlpha < 0) { - core.clearMap(ctx); - core.unregisterAnimationFrame("op"); + posy += 100; + if (this.herobuff.length === 0) { + core.fillBoldText1( + ctx8, + "当前无特殊状态", + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + } else { + this.herobuff.forEach((v) => { + core.drawTextContent(ctx8, this.buffshow(v), { + left: 200, + top: posy, + bold: true, + color: "#FFFFFF", + align: "left", + fontSize: 48, + time: 0, + font: "Verdana", + maxWidth: 1600, + }); + posy += 100; + }); } - }); - bgm = core.musicStatus.playingBgm; - core.playBgm("op.mp3"); - a = setTimeout(() => { - video.remove(); - video1.remove(); - core.playBgm(bgm); - core.doAction(); - }, 127500); - }); - }; -}, - "帧动画/图片叠拼": function () { - // 在此增加新插件 - this.animationDrawable = function ( - allFarme, - color, - globalAlpha, - imageList, - soundList - ) { - if (!core.isPlaying()) { - return core.doAction(); + posy += 50; + core.fillBoldText1( + ctx8, + "技能说明", + 1000, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + core.fillBoldText1( + ctx8, + "普通攻击:" + this.skillShow["普通攻击"], + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + break; + case "boss": + core.fillBoldText1( + ctx8, + this.boss.name, + 1000, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + //boss技能/buff + if (this.bossbuff.length === 0) { + core.fillBoldText1( + ctx8, + "当前无特殊状态", + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + } else { + this.bossbuff.forEach((v) => { + core.drawTextContent(ctx8, this.buffshow(v), { + left: 200, + top: posy, + bold: true, + color: "#FFFFFF", + align: "left", + fontSize: 48, + time: 0, + font: "Verdana", + maxWidth: 1600, + }); + posy += 100; + }); + } + posy += 50; + core.fillBoldText1( + ctx8, + "当前技能", + 1000, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + core.fillBoldText1( + ctx8, + this.boss.skill[this.boss.index] + + this.skillShow[this.boss.skill[this.boss.index]], + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + break; + default: + const enemy = this.enemy[select]; + const enemybuff = this.enemybuff[select]; + core.fillBoldText1( + ctx8, + enemy.name, + 1000, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + if (enemybuff.length === 0) { + core.fillBoldText1( + ctx8, + "当前无特殊状态", + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + } else { + enemybuff.forEach((v) => { + core.drawTextContent(ctx8, this.buffshow(v), { + left: 200, + top: posy, + bold: true, + color: "#FFFFFF", + align: "left", + fontSize: 48, + time: 0, + font: "Verdana", + maxWidth: 1600, + }); + posy += 100; + }); + } + posy += 50; + core.fillBoldText1( + ctx8, + "当前技能", + 1000, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + posy += 100; + core.fillBoldText1( + ctx8, + enemy.skill[enemy.index] + + this.skillShow[enemy.skill[enemy.index]], + 200, + posy, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + break; + } + ctx8.restore(); } - const over = main.dom.over; - const ctx = over.getContext("2d"); - over.style.display = "block"; + hasEnemy() { + let enemy = false; + this.enemy.forEach((v) => { + if (v.hp > 0) enemy = true; + }); + return enemy; + } + async bossStart() { + boss.style.display = "block"; + this.selection = "boss"; + this.playerturn = false; + this.show = false; + this.turn = 0; + core.lockControl(); + await this.blackBg(); + this.moveboss(); + await this.movehero(); + await this.moveStatus(); + this.update(); + this.fight(); + } + async bossEnd() { + hero.hp = this.hero.hp; + this.selection = "boss"; + await this.close(); - let farme = 0; - let now = 0; - core.registerAnimationFrame( - "animationDrawable", - true, - function (timestamp) { - if (timestamp - now > 1000 / 60) { - now = timestamp; + core.unlockControl(); + core.updateStatusBar(); + if (hero.hp <= 0) { + hero.hp = 0; + core.events.lose("BOSS战失败"); + } + } + async fight() { + await this.drawturn(); + const fightList = []; + fightList.push(["hero", this.hero.speed]); + if (this.boss.hp > 0) fightList.push(["boss", this.boss.speed]); + this.enemy.forEach((v, i) => { + if (v.id && v.hp > 0) fightList.push([i, v.speed]); + }); + fightList.sort((a, b) => b[1] - a[1]); + let damage; + for (const v of fightList) { + switch (v[0]) { + case "hero": + this.drawchoose(); + const skill = await getClick(); + let select = this.boss; + if (this.selection !== "" && this.selection !== "boss") + select = this.enemy[this.selection]; + this.skill(skill, this.hero, select); + + core.clearMap(ctx7); + break; + case "boss": + if (this.boss.hp > 0) { + this.selection = "boss"; + this.update(); + await sleep(500); //等待500ms + //这里写boss技能的效果 + this.skill( + this.boss.skill[this.boss.index], + this.boss, + this.hero + ); + + this.boss.index++; + if (this.boss.index >= this.boss.skill.length) + this.boss.index = 0; + } + break; + default: + const enemy = this.enemy[v[0]]; + if (enemy.hp > 0) { + this.selection = v[0]; + this.update(); + await sleep(500); //等待500ms + this.skill(enemy.skill[enemy.index], enemy, this.hero); + enemy.index++; + if (enemy.index >= enemy.skill.length) enemy.index = 0; + } + break; + } + await sleep(1000); + this.selection = ""; + this.update(); + } + let end = true; + if (this.boss.hp > 0) end = false; + this.enemy.forEach((v) => { + if (v.hp > 0) end = false; + }); + + if (this.hero.hp <= 0) end = true; + if (end) { + this.bossEnd(); + } else { + this.fight(); + } + } + drawturn() { + boss8.style.display = "block"; + this.turn += 1; + let time = 0, + frame = 0, + frame2 = 0, + right = 1, + once = 10; + return new Promise((resolve) => { + core.registerAnimationFrame("drawturn", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + frame += 1 * right; + core.clearMap(ctx); + if (core.domStyle.isVertical) { + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; + } + + core.fillRect( + ctx, + 0, + 624 - once * frame, + 2028, + once * frame * 2, + "rgba(0,0,0,0.7)" + ); + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "ROUND " + this.turn, + 1014, + 624, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(frame * 5, true) + ); + if (1014 - once * frame * 7 <= 0) { + frame -= 1; + frame2++; + + if (frame2 > 30) right = -1; + } + if (frame < 0) { + core.clearMap(ctx); + core.unregisterAnimationFrame("drawturn"); + resolve(); + } + } + }); + }); + } + drawenemy() { + let block, + time = 0; + + boss5.style.display = "block"; + core.registerAnimationFrame("enemyanimate", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + this.enemyfarme += 1; + let animate = Math.floor(this.enemyfarme / 30), + posx = 700, + posy = 500; + core.clearMap(ctx5); if (core.domStyle.isVertical) { - over.width = 1248; - over.height = 2028; - ctx.save(); //保存设置 - ctx.translate(1248, 0); //重新定位右上角为基准 - ctx.rotate(Math.PI / 2); //旋转90度 + ctx5.canvas.width = 1248; + ctx5.canvas.height = 2028; + ctx5.save(); //保存设置 + ctx5.translate(1248, 0); //重新定位右上角为基准 + ctx5.rotate(Math.PI / 2); //旋转90度 } else { - over.width = 2028; - over.height = 1248; + ctx5.canvas.width = 2028; + ctx5.canvas.height = 1248; } - ctx.globalAlpha = (globalAlpha ?? 100) / 100; - core.fillRect(ctx, 0, 0, 2028, 1248, color); + if (this.hasEnemy()) { + core.drawWindowSkin( + "winskin.webp", + ctx5, + 650, + 250, + 400, + 660, + null, + null, + null, + 3 + ); + if (this.selection === "boss") + core.strokeRect(ctx5, 800, 300, 100, 150, "yellow", 6); + const bossBlock = core.getBlockInfo(this.boss.id); + core.drawImage( + ctx5, + bossBlock.image, + 32 * (animate % 4), + bossBlock.posY * 48, + 32, + 48, + 800, + 300, + 96, + 144 + ); + core.drawImage( + ctx5, + "hero.webp", + 32 * (animate % 4), + 144, + 32, + 48, + 800, + 750, + 96, + 144 + ); + for (let i = 0; i < this.enemy.length; i++) { + if (this.enemy[i].id && this.enemy[i].hp > 0) { + block = core.getBlockInfo(this.enemy[i].id); + } else { + posx += 100; + if (i === 2) { + posx = 700; + posy += 150; + } + continue; + } - imageList.forEach(function (one) { - if ( - farme >= (one.beforefarme ?? 0) && - farme <= (one.afterfarme ?? allFarme) - ) { - const img = core.material.images.images?.[one.image]; - if (img) { - const gla = one.globalAlpha ?? 100; - const agla = one.aglobalAlpha ?? gla, - beforefarme = one.beforefarme ?? 0; - const afterfarme = one.afterfarme ?? allFarme; + if (block.cls === "enemys") { + core.drawImage( + ctx5, + block.image, + 32 * (animate % 2), + block.posY * 32, + 32, + 32, + posx, + posy, + 96, + 96 + ); + if (this.selection === i) + core.strokeRect(ctx5, posx, posy, 100, 100, "yellow", 6); + } else { + core.drawImage( + ctx5, + block.image, + 32 * (animate % 4), + block.posY * 48, + 32, + 48, + posx, + posy, + 96, + 144 + ); + if (this.selection === i) + core.strokeRect(ctx5, posx, posy, 100, 150, "yellow", 6); + } - ctx.globalAlpha = - (gla + - ((agla - gla) * (farme - beforefarme)) / - (afterfarme - beforefarme || 1)) / - 100; - - const cx = - (one.cx ?? 0) + - (((one.acx ?? 0) - (one.cx ?? 0)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - cy = - (one.cy ?? 0) + - (((one.acy ?? 0) - (one.cy ?? 0)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - cw = - (one.cw ?? img.width) + - (((one.acw ?? img.width) - (one.cw ?? img.width)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - ch = - (one.ch ?? img.height) + - (((one.acw ?? img.height) - (one.cw ?? img.height)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - x = - (one.x ?? 0) + - (((one.ax ?? 0) - (one.x ?? 0)) * (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - y = - (one.y ?? 0) + - (((one.ay ?? 0) - (one.y ?? 0)) * (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - w = - (one.w ?? 2028) + - (((one.aw ?? 2028) - (one.w ?? 2028)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1), - h = - (one.h ?? 1248) + - (((one.aw ?? 1248) - (one.w ?? 1248)) * - (farme - beforefarme)) / - (afterfarme - beforefarme || 1); - ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h); + posx += 100; + if (i === 2) { + posx = 700; + posy += 150; } } - }); - soundList.forEach(function (one) { - const lisen = - one.sound && - core.material.sounds[one.sound] && - core.musicStatus.soundStatus; - if (farme == one.startfarme && lisen) { - if (one.stopbefore) core.stopSound(); - core.playSound(one.sound); - } - }); - farme++; - ctx.globalAlpha = 1; - ctx.restore(); - - if (farme > allFarme) { - core.unregisterAnimationFrame("animationDrawable"); - over.style.display = "none"; - core.doAction(); } + + ctx5.restore(); + } + }); + } + drawhero() { + core.clearMap(ctx2); + if (core.domStyle.isVertical) { + ctx2.canvas.width = 1248; + ctx2.canvas.height = 2028; + ctx2.save(); //保存设置 + ctx2.translate(1248, 0); //重新定位右上角为基准 + ctx2.rotate(Math.PI / 2); //旋转90度 + } else { + ctx2.canvas.width = 2028; + ctx2.canvas.height = 1248; + } + core.drawImage(ctx2, this.heroImage, 0, 168, 750, 1080); + ctx2.restore(); + } + movehero() { + boss2.style.display = "block"; + core.clearMap(ctx2); + let time = 0, + px = -200; + return new Promise((resolve) => { + core.registerAnimationFrame("moveheroImage", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx2); + if (core.domStyle.isVertical) { + ctx2.canvas.width = 1248; + ctx2.canvas.height = 2028; + ctx2.save(); //保存设置 + ctx2.translate(1248, 0); //重新定位右上角为基准 + ctx2.rotate(Math.PI / 2); //旋转90度 + } else { + ctx2.canvas.width = 2028; + ctx2.canvas.height = 1248; + } + core.drawImage(ctx2, this.heroImage, px, 168, 750, 1080); + px += 10; + ctx2.restore(); + if (px >= 0) { + core.unregisterAnimationFrame("moveheroImage"); + this.drawhero(); + resolve(); + } + } + }); + }); + } + update() { + core.drawImage(ctx1, this.bg, 0, 0, 2028, 1248); + this.drawboss(); + this.drawhero(); + this.drawStatus(); + let dodraw = false; + for (let i = 0; i < this.enemy.length; i++) { + if (this.enemy[i].id && this.enemy[i].hp > 0) { + dodraw = true; } } - ); - }; + if (dodraw === true) this.drawenemy(); + } + playanimate(name, x, y, scalex = 10, scaley = 10) { + const one = { + name: name, + x: x, + y: y, + scalex: scalex, + scaley: scaley, + farme: 0, + }; + let time = 0; + boss6.style.display = "block"; + return new Promise((resolve) => { + core.registerAnimationFrame("animateboss", true, (timestamp) => { + if (timestamp - time > 1000 / 60) { + time = timestamp; + core.clearMap(ctx6); + + const data = flags["animate_" + one.name]; + if (core.domStyle.isVertical) { + ctx6.canvas.width = 1248; + ctx6.canvas.height = 2028; + ctx6.save(); //保存设置 + ctx6.translate(1248, 0); //重新定位右上角为基准 + ctx6.rotate(Math.PI / 2); //旋转90度 + } else { + ctx6.canvas.width = 2028; + ctx6.canvas.height = 1248; + } + + if (!data) { + core.unregisterAnimationFrame("animateboss"); + resolve(); + } else { + data.imageList.forEach(function (image) { + if ( + one.farme >= (image.beforefarme ?? 0) && + one.farme <= (image.afterfarme ?? data.allFarme) + ) { + const img = core.material.images.images?.[image.image]; + if (img) { + const gla = image.globalAlpha ?? 100; + const agla = image.aglobalAlpha ?? gla, + beforefarme = image.beforefarme ?? 0; + const afterfarme = image.afterfarme ?? data.allFarme; + + ctx6.globalAlpha = + (gla + + ((agla - gla) * (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1)) / + 100; + + const cx = + (image.cx ?? 0) + + (((image.acx ?? 0) - (image.cx ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cy = + (image.cy ?? 0) + + (((image.acy ?? 0) - (image.cy ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cw = + (image.cw ?? img.width) + + (((image.acw ?? img.width) - + (image.cw ?? img.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + ch = + (image.ch ?? img.height) + + (((image.acw ?? img.height) - + (image.cw ?? img.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + x = + (image.x ?? 0) + + (((image.ax ?? 0) - (image.x ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + y = + (image.y ?? 0) + + (((image.ay ?? 0) - (image.y ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + w = + (image.w ?? one.width) + + (((image.aw ?? one.width) - (image.w ?? one.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + h = + (image.h ?? one.height) + + (((image.aw ?? one.height) - + (image.w ?? one.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + angle = + (Math.PI * + ((image.image.angle ?? 0) + + (((image.aangle ?? 0) - + (image.image.angle ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1))) / + 180; + + core.drawImage( + ctx6, + img, + cx, + cy, + cw, + ch, + one.x + (x - data.px) * one.scalex, + one.y + (y - data.py) * one.scaley, + w * one.scalex, + h * one.scaley, + angle + ); + } + } + }); + data.soundList.forEach(function (sound) { + const lisen = + sound.sound && + core.sounds[sound.sound] && + core.musicStatus.soundStatus; + if (one.farme == sound.startfarme && lisen) { + if (sound.stopbefore) core.stopSound(); + core.playSound(sound.sound); + } + }); + one.farme++; + ctx6.restore(); + if (one.farme > data.allFarme) { + core.clearMap(ctx6); + core.unregisterAnimationFrame("animateboss"); + resolve(); + } + } + } + }); + }); + } + + drawboss() { + core.clearMap(ctx3); + if (core.domStyle.isVertical) { + ctx3.canvas.width = 1248; + ctx3.canvas.height = 2028; + ctx3.save(); //保存设置 + ctx3.translate(1248, 0); //重新定位右上角为基准 + ctx3.rotate(Math.PI / 2); //旋转90度 + } else { + ctx3.canvas.width = 2028; + ctx3.canvas.height = 1248; + } + if (this.selection === "boss" || this.selection === "") { + core.drawImage(ctx3, this.boss.image, 1400, 168, 750, 1080); + } else { + core.drawImage( + ctx3, + this.enemy[this.selection].image, + 1400, + 168, + 750, + 1080 + ); + } + + ctx3.restore(); + } + moveboss() { + boss3.style.display = "block"; + core.clearMap(ctx3); + let time = 0, + px = 1600; + return new Promise((resolve) => { + core.registerAnimationFrame("movebossImage", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx3); + if (core.domStyle.isVertical) { + ctx3.canvas.width = 1248; + ctx3.canvas.height = 2028; + ctx3.save(); //保存设置 + ctx3.translate(1248, 0); //重新定位右上角为基准 + ctx3.rotate(Math.PI / 2); //旋转90度 + } else { + ctx3.canvas.width = 2028; + ctx3.canvas.height = 1248; + } + core.drawImage(ctx3, this.boss.image, px, 168, 750, 1080); + px -= 10; + ctx3.restore(); + if (px <= 1400) { + core.unregisterAnimationFrame("movebossImage"); + this.drawboss(); + resolve(); + } + } + }); + }); + } + drawStatus() { + core.clearMap(ctx4); + if (core.domStyle.isVertical) { + ctx4.canvas.width = 1248; + ctx4.canvas.height = 2028; + ctx4.save(); //保存设置 + ctx4.translate(1248, 0); //重新定位右上角为基准 + ctx4.rotate(Math.PI / 2); //旋转90度 + } else { + ctx4.canvas.width = 2028; + ctx4.canvas.height = 1248; + } + core.drawWindowSkin( + "winskin.webp", + ctx4, + 600, + 920, + 900, + 300, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + hero.name, + 630, + 1000, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 880, + 1000, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.hero.hp, + 630, + 1070, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.hero.atk, + 630, + 1120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.hero.def, + 630, + 1170, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法强 " + this.hero.spell, + 1080, + 1070, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.hero.mdef + "%", + 1080, + 1120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.hero.speed, + 1080, + 1170, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 980; + this.herobuff.forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 950, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 1000, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + + if (this.selection === "boss" || !this.hasEnemy()) { + core.drawWindowSkin( + "winskin.webp", + ctx4, + 50, + 50, + 1900, + 200, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + this.boss.name, + 100, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 500, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "当前技能", + 1400, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + const bosstext = this.boss.skill[this.boss.index]; + core.fillBoldText1( + ctx4, + bosstext, + 1600, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.boss.hp, + 100, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.boss.atk, + 500, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.boss.def, + 900, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.boss.mdef + "%", + 1300, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.boss.speed, + 1700, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 600; + this.bossbuff.forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 80, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 130, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + } else if (this.selection === "") {} else { + core.drawWindowSkin( + "winskin.webp", + ctx4, + 50, + 50, + 1900, + 200, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + this.enemy[this.selection].name, + 100, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 500, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "当前技能", + 1400, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + const enemytext = + this.enemy[this.selection].skill[this.enemy[this.selection].index]; + core.fillBoldText1( + ctx4, + enemytext, + 1600, + 120, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.enemy[this.selection].hp, + 100, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.enemy[this.selection].atk, + 500, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.enemy[this.selection].def, + 900, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.enemy[this.selection].mdef + "%", + 1300, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.enemy[this.selection].speed, + 1700, + 220, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 600; + this.enemybuff[this.selection].forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 80, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 130, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + } + ctx4.restore(); + } + moveStatus() { + boss4.style.display = "block"; + let time = 0, + posy = 400; + return new Promise((resolve) => { + core.registerAnimationFrame("moveStatus", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx4); + if (core.domStyle.isVertical) { + ctx4.canvas.width = 1248; + ctx4.canvas.height = 2028; + ctx4.save(); //保存设置 + ctx4.translate(1248, 0); //重新定位右上角为基准 + ctx4.rotate(Math.PI / 2); //旋转90度 + } else { + ctx4.canvas.width = 2028; + ctx4.canvas.height = 1248; + } + core.drawWindowSkin( + "winskin.webp", + ctx4, + 600, + 920 + posy, + 900, + 300, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + hero.name, + 630, + 1000 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 880, + 1000 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.hero.hp, + 630, + 1070 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.hero.atk, + 630, + 1120 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.hero.def, + 630, + 1170 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法强 " + this.hero.spell, + 1080, + 1070 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.hero.mdef + "%", + 1080, + 1120 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.hero.speed, + 1080, + 1170 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 980; + this.herobuff.forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 950 + posy, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 1000 + posy, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + if (this.selection === "boss") { + core.drawWindowSkin( + "winskin.webp", + ctx4, + 50, + 50 - posy / 2, + 1900, + 200, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + this.boss.name, + 100, + 120 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 500, + 120 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.boss.hp, + 100, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.boss.atk, + 500, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.boss.def, + 900, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.boss.mdef + "%", + 1300, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.boss.speed, + 1700, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 600; + this.bossbuff.forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 80 - posy / 2, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 130 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + } else if (this.selection === "") {} else { + core.drawWindowSkin( + "winskin.webp", + ctx4, + 50, + 50 - posy / 2, + 1900, + 200, + null, + null, + null, + 3 + ); + core.fillBoldText1( + ctx4, + this.enemy[this.selection].name, + 100, + 120 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "状态", + 500, + 120 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "生命 " + this.enemy[this.selection].hp, + 100, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "攻击 " + this.enemy[this.selection].atk, + 500, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "防御 " + this.enemy[this.selection].def, + 900, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "法抗 " + this.enemy[this.selection].mdef + "%", + 1300, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + core.fillBoldText1( + ctx4, + "速度 " + this.enemy[this.selection].speed, + 1700, + 220 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(44, true) + ); + let posx = 600; + this.enemybuff[this.selection].forEach((v) => { + if (v) { + core.drawIcon(ctx4, v.id, posx, 80 - posy / 2, 64, 64); + core.setTextAlign(ctx4, "right"); + core.fillBoldText1( + ctx4, + v.count, + posx + 50, + 130 - posy / 2, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(24, true) + ); + core.setTextAlign(ctx4, "left"); + posx += 80; + } + }); + } + ctx4.restore(); + posy -= 10; + if (posy <= 0) { + core.unregisterAnimationFrame("moveStatus"); + this.drawStatus(); + resolve(); + } + } + }); + }); + } + close() { + let globalAlpha = 0, + time = 0; + return new Promise((resolve) => { + core.registerAnimationFrame("closeblack", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx); + if (core.domStyle.isVertical) { + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; + } + + ctx.globalAlpha = globalAlpha; + + core.fillRect(ctx, 0, 0, 2028, 1248); + globalAlpha += 1 / 30; + ctx.restore(); + if (globalAlpha > 1) { + time = 0; + globalAlpha = 1; + core.unregisterAnimationFrame("closeblack"); + core.unregisterAnimationFrame("enemyanimate"); + boss1.style.display = "none"; + boss2.style.display = "none"; + boss3.style.display = "none"; + boss4.style.display = "none"; + boss5.style.display = "none"; + boss6.style.display = "none"; + boss7.style.display = "none"; + boss8.style.display = "none"; + + core.registerAnimationFrame("closeblack2", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx); + if (core.domStyle.isVertical) { + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; + } + ctx.globalAlpha = globalAlpha; + core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); + ctx.restore(); + globalAlpha -= 1 / 30; + if (globalAlpha < 0) { + core.unregisterAnimationFrame("closeblack2"); + + boss.style.display = "none"; + + resolve(); + } + } + }); + } + } + }); + }); + } + + blackBg() { + let globalAlpha = 0, + time = 0, + img = core.material.images.images[this.bg]; + boss1.style.display = "block"; + return new Promise((resolve) => { + core.registerAnimationFrame("bossblack", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx1); + if (core.domStyle.isVertical) { + ctx1.canvas.width = 1248; + ctx1.canvas.height = 2028; + ctx1.save(); //保存设置 + ctx1.translate(1248, 0); //重新定位右上角为基准 + ctx1.rotate(Math.PI / 2); //旋转90度 + } else { + ctx1.canvas.width = 2028; + ctx1.canvas.height = 1248; + } + + ctx1.globalAlpha = globalAlpha; + + core.fillRect(ctx1, 0, 0, 2028, 1248); + globalAlpha += 1 / 30; + ctx1.restore(); + if (globalAlpha > 1) { + time = 0; + globalAlpha = 0; + core.unregisterAnimationFrame("bossblack"); + core.registerAnimationFrame("bossBg", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + core.clearMap(ctx1); + if (core.domStyle.isVertical) { + ctx1.canvas.width = 1248; + ctx1.canvas.height = 2028; + ctx1.save(); //保存设置 + ctx1.translate(1248, 0); //重新定位右上角为基准 + ctx1.rotate(Math.PI / 2); //旋转90度 + } else { + ctx1.canvas.width = 2028; + ctx1.canvas.height = 1248; + } + + ctx1.globalAlpha = 1; + core.fillRect(ctx1, 0, 0, 2028, 1248); + ctx1.globalAlpha = globalAlpha; + if (img) ctx1.drawImage(img, 0, 0, 2028, 1248); + ctx1.restore(); + globalAlpha += 1 / 30; + if (globalAlpha > 1) { + core.unregisterAnimationFrame("bossBg"); + resolve(); + } + } + }); + } + } + }); + }); + } + } + core.ui.boss = new Boss(); }, + "剧情视频引用": function () { + // 在此增加新插件 + let a; + let bgm; + + function gtouchstart() { + timeOutEvent = setTimeout(() => { + video.remove(); + video1.remove(); + core.doAction(); + clearTimeout(a); + core.playBgm(bgm); + }, 2000); //这里设置定时器,定义长按500毫秒触发长按事件,时间可以自己改,个人感觉500毫秒非常合适 + return false; + } + + //手释放,如果在500毫秒内就释放,则取消长按事件,此时可以执行onclick应该执行的事件 + function gtouchend() { + if (timeOutEvent != 0) { + //这里写要执行的内容(尤如onclick事件) + console.log("你这是点击,不是长按"); + } + clearTimeout(timeOutEvent); //清除定时器 + return false; + } + + this.openvideo = function () { + if (!core.isPlaying()) return; + const video = document.createElement("iframe"); //iframe设置 + video.style.position = "absolute"; + video.style.zIndex = 320; + video.style.display = "block"; + video.id = "video"; + main.dom.gameGroup.insertAdjacentElement("afterend", video); + video.style.top = "50%"; + video.style.left = "50%"; + video.style.transform = "translate(-50%,-50%)"; + main.dom.video = video; + const video1 = document.createElement("canvas"); //video1画布设置 + video1.style.position = "absolute"; + video1.style.zIndex = 330; + video1.style.display = "block"; + video1.id = "video1"; + main.dom.gameGroup.insertAdjacentElement("afterend", video1); + video1.style.top = "50%"; + video1.style.left = "50%"; + video1.style.transform = "translate(-50%,-50%)"; + const ctx = video1.getContext("2d"); + main.dom.video1 = video1; + if (core.domStyle.isVertical) { + video.width = 416 * 3; + video.height = 676 * 3; + video.style.transform = "translate(-50%,-50%) rotate(90deg)"; //重新定位右上角为基准 + } else { + video.width = 676 * 3; + video.height = 416 * 3; + video.style.transform = "translate(-50%,-50%)"; + } + video1.ontouchstart = function (e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; + gtouchstart(); + } catch (ee) { + main.log(ee); + } + }; + video1.ontouchend = function (e) { + try { + e.preventDefault(); + if (!core.isPlaying()) return false; + gtouchend(); + } catch (ee) { + main.log(ee); + } + }; + + video1.onmouseup = function (e) { + //鼠标抬起 + try { + e.stopPropagation(); + if (!core.isPlaying()) return false; + gtouchend(); + } catch (ee) { + console.error(ee); + } + }; + video1.onmousedown = function (e) { + //鼠标按下 + try { + e.stopPropagation(); + if (!core.isPlaying()) return false; + gtouchstart(); + } catch (ee) { + main.log(ee); + } + }; + let globalAlpha = 0; + let frame = 1; + let al = 0; + core.registerAnimationFrame("beforeop", true, function () { + al++; + core.clearMap(ctx); + ctx.globalAlpha = al / 30; + core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); + ctx.globalAlpha = 1; + core.fillBoldText1( + ctx, + "Loading...", + 1014, + 624, + "#FFFFFF", + "#000000", + 6, + "bold 72px Verdana" + ); + }); + core.control.resize(); + + //player.bilibili.com/player.html + //www.bilibili.com/blackboard/html5mobileplayer.html + // + video.src = + "///www.bilibili.com/blackboard/html5mobileplayer.html?isOutside=true&aid=6484104&bvid=BV1cs411b7cH&cid=10546155&p=1&poster=0&autoplay=1&high_quality=1&muted=0&danmaku=0"; + video.scrolling = "no"; + video.border = "0"; + video.crossorigin = true; + video.frameborder = "no"; + video.framespacing = "0"; + video.allowfullscreen = false; + + video.sandbox = + "allow-top-navigation allow-same-origin allow-forms allow-scripts"; + //gsl_play_mask + + video.addEventListener("load", function () { + core.unregisterAnimationFrame("beforeop"); + core.registerAnimationFrame("op", true, function () { + core.clearMap(ctx); + if (core.domStyle.isVertical) { + ctx.canvas.width = 416 * 3; + ctx.canvas.height = 676 * 3; + ctx.save(); //保存设置 + ctx.translate(416 * 3, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 676 * 3; + ctx.canvas.height = 416 * 3; + } + ctx.globalAlpha = 1; + core.fillRect(ctx, 0, 0, video1.width, video1.height, "#000000"); + + ctx.globalAlpha = globalAlpha / 30; + core.setTextAlign(ctx, "center"); + core.fillBoldText1( + ctx, + "长按2秒后跳过op", + 1014, + 624, + "#FFFFFF", + "#000000", + 6, + "bold 48px Verdana" + ); + globalAlpha += frame; + if (globalAlpha > 29) frame = -1; + ctx.restore(); + if (frame === -1 && globalAlpha < 0) { + core.clearMap(ctx); + core.unregisterAnimationFrame("op"); + } + }); + bgm = core.musicStatus.playingBgm; + core.playBgm("op.opus"); + a = setTimeout(() => { + video.remove(); + video1.remove(); + core.playBgm(bgm); + core.doAction(); + }, 127500); + }); + }; + }, + "帧动画/图片叠拼": function () { + // 在此增加新插件 + this.animationDrawable = function ( + allFarme, + color, + globalAlpha, + imageList, + soundList + ) { + if (!core.isPlaying()) { + return core.doAction(); + } + const over = main.dom.over; + const ctx = over.getContext("2d"); + over.style.display = "block"; + + let farme = 0; + let now = 0; + core.registerAnimationFrame( + "animationDrawable", + true, + function (timestamp) { + if (timestamp - now > 1000 / 60) { + now = timestamp; + if (core.domStyle.isVertical) { + over.width = 1248; + over.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + over.width = 2028; + over.height = 1248; + } + + ctx.globalAlpha = (globalAlpha ?? 100) / 100; + core.fillRect(ctx, 0, 0, 2028, 1248, color); + + imageList.forEach(function (one) { + if ( + farme >= (one.beforefarme ?? 0) && + farme <= (one.afterfarme ?? allFarme) + ) { + const img = core.material.images.images?.[one.image]; + if (img) { + const gla = one.globalAlpha ?? 100; + const agla = one.aglobalAlpha ?? gla, + beforefarme = one.beforefarme ?? 0; + const afterfarme = one.afterfarme ?? allFarme; + + ctx.globalAlpha = + (gla + + ((agla - gla) * (farme - beforefarme)) / + (afterfarme - beforefarme || 1)) / + 100; + + const cx = + (one.cx ?? 0) + + (((one.acx ?? 0) - (one.cx ?? 0)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cy = + (one.cy ?? 0) + + (((one.acy ?? 0) - (one.cy ?? 0)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cw = + (one.cw ?? img.width) + + (((one.acw ?? img.width) - (one.cw ?? img.width)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + ch = + (one.ch ?? img.height) + + (((one.acw ?? img.height) - (one.cw ?? img.height)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + x = + (one.x ?? 0) + + (((one.ax ?? 0) - (one.x ?? 0)) * (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + y = + (one.y ?? 0) + + (((one.ay ?? 0) - (one.y ?? 0)) * (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + w = + (one.w ?? 2028) + + (((one.aw ?? 2028) - (one.w ?? 2028)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1), + h = + (one.h ?? 1248) + + (((one.aw ?? 1248) - (one.w ?? 1248)) * + (farme - beforefarme)) / + (afterfarme - beforefarme || 1); + ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h); + } + } + }); + soundList.forEach(function (one) { + const lisen = + one.sound && + core.sounds[one.sound] && + core.musicStatus.soundStatus; + if (farme == one.startfarme && lisen) { + if (one.stopbefore) core.stopSound(); + core.playSound(one.sound); + } + }); + farme++; + ctx.globalAlpha = 1; + ctx.restore(); + + if (farme > allFarme) { + core.unregisterAnimationFrame("animationDrawable"); + over.style.display = "none"; + core.doAction(); + } + } + } + ); + }; + }, "musicMode": function () { // 在此增加新插件 - const music = document.createElement("canvas"); //CGui画布设置 + const music = document.createElement("canvas"); music.style.position = "absolute"; music.style.zIndex = 300; music.style.display = "none"; @@ -14243,38 +19724,109 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = music.style.transform = "translate(-50%,-50%)"; const ctx = music.getContext("2d"); main.dom.music = music; + + const audio = core.plugin.audioSystem.bgmController; + let page = 0; //初始页面 - let show = false; //展示状态 - music.onclick = function (e) { - try { - e.preventDefault(); - if (core.isPlaying()) return false; - const left = core.dom.gameGroup.offsetLeft; - const top = core.dom.gameGroup.offsetTop; - const px = Math.floor((e.clientX - left) / core.domStyle.scale), - py = Math.floor((e.clientY - top) / core.domStyle.scale); - core.ui.music.onclick(px * 3, py * 3); - } catch (ee) { - main.log(ee); + + let isvolume = false; + + function shuffle(arr) { + let n = arr.length, + random; + while (n) { + random = (Math.random() * n--) >>> 0; + [arr[n], arr[random]] = [arr[random], arr[n]]; } - }; + return arr; + } + music.addEventListener("mousedown", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.music.mousedown(px * 3, py * 3); + }); + music.addEventListener("mousemove", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + core.ui.music.mousemove(px * 3, py * 3); + }); + music.addEventListener("mouseup", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("mouseleave", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("touchstart", function (e) { + e.preventDefault(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.touches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); + core.ui.music.mousedown(px * 3, py * 3); + }); + music.addEventListener("touchmove", function (e) { + e.stopPropagation(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor( + (e.touches[0].clientX - left) / core.domStyle.scale + ), + py = Math.floor((e.touches[0].clientY - top) / core.domStyle.scale); + core.ui.music.mousemove(px * 3, py * 3); + }); + music.addEventListener("touchend", function (e) { + e.stopPropagation(); + + isvolume = false; + }); + music.addEventListener("touchcancel", function (e) { + e.stopPropagation(); + + isvolume = false; + }); class musicclass { constructor() { + this.musics = ["theme.mp3"]; //music列表 //需全塔属性注册并保存在bgms文件夹,每个数组为显示的一页内容 this.musicMx = [ - ["Asphodelus_Ceui.mp3", "Blind_Alley.mp3"], - ["Crawler.mp3", "op.mp3", "theme.mp3"], + [ + "Crawler.opus", + "Blood_Stain.opus", + "Blind_Alley.opus", + "Halbmond.opus", + ], + ["theme.mp3", "op.opus", "Asphodelus_Ceui.opus", "ed.opus"], ]; //音乐别名(将在播放器内显示的音乐名,music列表内的都要有对应歌名) this.musicname = { - "Asphodelus_Ceui.mp3": "Asphodelus", - "Blind_Alley.mp3": "Blind", - "Crawler.mp3": "Crawler", - "op.mp3": "op", - "theme.mp3": "theme", + "Asphodelus_Ceui.opus": "Asphodelus (Full.ver)", + "Blind_Alley.opus": "Blind Alley", + "Crawler.opus": "Crawler", + "op.opus": "Asphodelus", + "theme.mp3": "One of Episodes", + "ed.opus": "親愛なる世界へ", + "Blood_Stain.opus": "Blood Stain", + "Halbmond.opus": "Halbmond", }; + this.selection = [0, 0]; + this.stop = false; + this.type = "xunhuan"; + this.randomList = []; + this.random = 0; } //更新 @@ -14292,14 +19844,10 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = music.height = 1248; } } - onclick(px, py) { - //点击 - if (show) { - show = !show; - core.clearMap(ctx); - this.update(); - return; - } + + mousedown(px, py) { + //鼠标按下时 + const makeBox = ([x, y], [w, h]) => { return [ [x, y], @@ -14310,15 +19858,544 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = return sx <= x && x <= dx && sy <= y && y <= dy; }; const pos = [px, py]; - const backbox = makeBox([45, 45], [120, 80]); + const backbox = makeBox([15, 35], [210, 90]); if (inRect(pos, backbox)) { //离开按钮是一致的,其余的记区分横竖屏 music.style.display = "none"; core.clearMap(ctx); + + core.unregisterAnimationFrame("music"); core.restart(); + return; } + if (core.domStyle.isVertical) { + //竖屏 + + const pageupbox = makeBox([100, 1230], [200, 100]); + const pagedownbox = makeBox([950, 1230], [200, 100]); + const musicbox = makeBox( + [100, 200], + [1048, this.musicMx[page].length * 100] + ); + const beforebox = makeBox([120, 1620], [100, 100]); + const afterbox = makeBox([780, 1620], [100, 100]); + const playbox = makeBox([420, 1580], [200, 200]); + const typebox = makeBox([1040, 1600], [120, 120]); + + const volumebox = makeBox([250, 1940], [1050, 20]); + if (inRect(pos, pageupbox)) { + if (page !== 0) page -= 1; + return; + } + if (inRect(pos, pagedownbox)) { + if (page !== this.musicMx.length - 1) page += 1; + return; + } + if (inRect(pos, playbox)) { + if (this.stop) { + this.stop = !this.stop; + + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + return; + } + if (inRect(pos, beforebox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + page = this.selection[0]; + + break; + case "xunhuan": + for (;;) { + if (this.selection[1] === 0) { + if (this.selection[0] === 0) { + this.selection[0] = this.musicMx.length - 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } else { + this.selection[0] -= 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } + } else { + this.selection[1] -= 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + case "suiji": + for (;;) { + if (this.random > 0) { + this.random -= 1; + } else { + this.random = this.randomList.length - 1; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + } + return; + } + if (inRect(pos, afterbox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + page = this.selection[0]; + break; + case "xunhuan": + for (;;) { + if ( + this.selection[1] === + this.musicMx[this.selection[0]].length - 1 + ) { + if (this.selection[0] === this.musicMx.length - 1) { + this.selection[0] = 0; + this.selection[1] = 0; + } else { + this.selection[0] += 1; + this.selection[1] = 0; + } + } else { + this.selection[1] += 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + case "suiji": + for (;;) { + if (this.random < this.randomList.length - 1) { + this.random += 1; + } else { + this.random = 0; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + } + return; + } + if (inRect(pos, typebox)) { + switch (this.type) { + case "danqu": + this.type = "xunhuan"; + break; + case "xunhuan": + this.type = "suiji"; + break; + case "suiji": + this.type = "danqu"; + break; + } + return; + } + if (inRect(pos, musicbox)) { + const index = Math.floor((py - 200) / 100); + if (page !== this.selection[0] || index !== this.selection[1]) { + if ( + this.musics.includes(this.musicMx[page][index]) || + page !== this.musicMx.length - 1 + ) { + this.selection[0] = page; + + this.selection[1] = index; + this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + this.stop = false; + } + } else { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + } + return; + } + + if (inRect(pos, volumebox)) { + const time = Math.min(Math.max((px - 250) / 800, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + isvolume = true; + } + } else { + //横屏 + const pageupbox = makeBox([1050, 1100], [200, 100]); + const pagedownbox = makeBox([1550, 1100], [200, 100]); + const musicbox = makeBox( + [900, 100], + [1000, this.musicMx[page].length * 100] + ); + const beforebox = makeBox([60, 620], [100, 100]); + const afterbox = makeBox([450, 620], [100, 100]); + const playbox = makeBox([200, 570], [200, 200]); + const typebox = makeBox([620, 600], [120, 120]); + + const volumebox = makeBox([100, 990], [600, 20]); + if (inRect(pos, pageupbox)) { + if (page !== 0) page -= 1; + return; + } + if (inRect(pos, pagedownbox)) { + if (page !== this.musicMx.length - 1) page += 1; + return; + } + if (inRect(pos, playbox)) { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + return; + } + if (inRect(pos, beforebox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + page = this.selection[0]; + + break; + case "xunhuan": + for (;;) { + if (this.selection[1] === 0) { + if (this.selection[0] === 0) { + this.selection[0] = this.musicMx.length - 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } else { + this.selection[0] -= 1; + this.selection[1] = + this.musicMx[this.selection[0]].length - 1; + } + } else { + this.selection[1] -= 1; + } + this.random = this.randomList.indexOf( + this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + case "suiji": + for (;;) { + if (this.random > 0) { + this.random -= 1; + } else { + this.random = this.randomList.length - 1; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + this.randomList[this.random] + ); + + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + } + return; + } + if (inRect(pos, afterbox)) { + this.stop = false; + switch (this.type) { + case "danqu": + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + page = this.selection[0]; + break; + case "xunhuan": + for (;;) { + if ( + this.selection[1] === + this.musicMx[this.selection[0]].length - 1 + ) { + if (this.selection[0] === this.musicMx.length - 1) { + this.selection[0] = 0; + this.selection[1] = 0; + } else { + this.selection[0] += 1; + this.selection[1] = 0; + } + } else { + this.selection[1] += 1; + } + this.randomList.findIndex( + (v) => + v === this.musicMx[this.selection[0]][this.selection[1]] + ); + page = this.selection[0]; + + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + case "suiji": + for (;;) { + if (this.random < this.randomList.length - 1) { + this.random += 1; + } else { + this.random = 0; + } + this.selection[0] = this.musicMx.findIndex((v) => + v.includes(this.randomList[this.random]) + ); + this.selection[1] = this.musicMx[this.selection[0]].indexOf( + main.core.ui.music.randomList[main.core.ui.music.random] + ); + + page = this.selection[0]; + if ( + this.musics.includes( + this.musicMx[this.selection[0]][this.selection[1]] + ) || + page !== this.musicMx.length - 1 + ) + break; + } + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + break; + } + return; + } + if (inRect(pos, typebox)) { + switch (this.type) { + case "danqu": + this.type = "xunhuan"; + break; + case "xunhuan": + this.type = "suiji"; + break; + case "suiji": + this.type = "danqu"; + break; + } + return; + } + if (inRect(pos, musicbox)) { + const index = Math.floor((py - 100) / 100); + if (page !== this.selection[0] || index !== this.selection[1]) { + if ( + this.musics.includes(this.musicMx[page][index]) || + page !== this.musicMx.length - 1 + ) { + this.selection[0] = page; + this.selection[1] = index; + this.randomList.indexOf( + (v) => + v === this.musicMx[this.selection[0]][this.selection[1]] + ); + + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + this.stop = false; + } + } else { + if (this.stop) { + this.stop = !this.stop; + core.resumeBgm(); + } else { + this.stop = !this.stop; + core.pauseBgm(); + } + } + return; + } + + if (inRect(pos, volumebox)) { + const time = Math.min(Math.max((px - 100) / 600, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + isvolume = true; + } + } } + mousemove(px, py) { + if (isvolume) { + if (core.domStyle.isVertical) { + const time = Math.min(Math.max((px - 250) / 800, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + } else { + const time = Math.min(Math.max((px - 100) / 600, 0), 1); + audio.setVolume(time); + core.plugin.audioSystem.soundPlayer.setVolume(time); + } + } + } + drawUI() { //绘制页面 core.clearMap(music); @@ -14328,76 +20405,387 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = //竖屏 core.fillRect(ctx, 0, 0, 1248, 2028, "#000000"); //黑色背景 - ctx.globalAlpha = 0.5; //透明度 + ctx.globalAlpha = 0.3; //透明度 if (bgVertical) ctx.drawImage(bgVertical, 0, 0, 1280, 1500, 0, 0, 1248, 2028); //绘制半透明背景图片 ctx.globalAlpha = 1; //恢复为不透明 core.setTextAlign(ctx, "center"); - core.fillRoundRect( - ctx, - 45 - 6, - 45 - 6, - 120 + 12, - 80 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 45 - 12, - 120 + 24, - 80 + 24, - 12, - "#444444", - 3 - ); core.fillBoldText1( ctx, - "<离开", + "◀离开", 110, 100, "#FFFFFF", "#000000", 6, - core.ui._buildFont(33, true) + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(100, 200); + ctx.lineTo(1148, 200); + + ctx.stroke(); + let posy = 300; + const indexList = this.musicMx[page]; + core.setTextAlign(ctx, "left"); + for (let i = 0; i < indexList.length; i++) { + const text = this.musicname[indexList[i]]; + if ( + this.musics.includes(this.musicMx[page][i]) || + page !== this.musicMx.length - 1 + ) { + core.fillBoldText1( + ctx, + text, + 150, + posy - 30, + page === this.selection[0] && i === this.selection[1] + ? "#FFFFFF" + : "#444444", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(100, posy); + ctx.lineTo(1148, posy); + ctx.stroke(); + } + posy += 100; + } + ctx.beginPath(); + ctx.moveTo(100, 1210); + ctx.lineTo(1148, 1210); + ctx.moveTo(100, 1200); + ctx.lineTo(1148, 1200); + ctx.stroke(); + + core.fillBoldText1( + ctx, + "上一页", + 100, + 1300, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.musicMx.length, + 580, + 1300, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 950, + 1300, + page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 3; + + core.fillBoldText( + ctx, + "|", + 100, + 1697, + "#FFFFFF", + 6, + core.ui._buildFont(96, true) + ); + core.fillBoldText( + ctx, + "◀", + 115, + 1700, + "#FFFFFF", + 6, + core.ui._buildFont(96, true) + ); + + ctx.beginPath(); + ctx.arc(505, 1670, 80, 0, 3 * Math.PI); + ctx.stroke(); + core.fillText( + ctx, + "|", + 835, + 1697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "▶", + 785, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + if (this.stop) { + core.fillText( + ctx, + "▶", + 473, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } else { + core.fillText( + ctx, + "||", + 453, + 1700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } + + const img = core.material.images.images[this.type + ".webp"]; + if (img) ctx.drawImage(img, 1000, 1555, 200, 200); + core.setTextAlign(ctx, "center"); + ctx.font = "bold 52px Verdana"; + ctx.fillText("当前歌曲", 625, 1397); + ctx.fillText( + this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], + 625, + 1507 + ); + + ctx.fillStyle = "#ffffff"; + ctx.font = "bold 48px Verdana"; + ctx.fillText("音量", 150, 1970); + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(250, 1950); + ctx.lineTo(1050, 1950); + ctx.stroke(); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 9; + ctx.fillStyle = "rgba(255,255,255,0.5)"; + + ctx.beginPath(); + ctx.moveTo(250, 1950); + ctx.lineTo(800 * audio.getVolume() + 250, 1950); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(800 * audio.getVolume() + 250, 1950, 10, 0, 2 * Math.PI); + ctx.fill(); + core.fillBoldText1( + ctx, + Math.floor(100 * audio.getVolume()), + 1120, + 1970, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(56, true) ); } else { //横屏 + core.fillRect(ctx, 0, 0, 2028, 1248, "#000000"); //黑色背景 ctx.globalAlpha = 0.5; //透明度 if (bg) ctx.drawImage(bg, 0, 0, 1280, 720, 0, 0, 2028, 1248); //绘制半透明背景图片 ctx.globalAlpha = 1; //恢复为不透明 core.setTextAlign(ctx, "center"); - core.fillRoundRect( - ctx, - 45 - 6, - 45 - 6, - 120 + 12, - 80 + 12, - 6, - "#444444" - ); - core.strokeRoundRect( - ctx, - 45 - 12, - 45 - 12, - 120 + 24, - 80 + 24, - 12, - "#444444", - 3 - ); + core.fillBoldText1( ctx, - "<离开", + "◀离开", 110, 100, "#FFFFFF", "#000000", 6, - core.ui._buildFont(33, true) + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(800, 100); + ctx.lineTo(800, 1148); + ctx.moveTo(900, 100); + ctx.lineTo(1900, 100); + ctx.stroke(); + let posy = 200; + const indexList = this.musicMx[page]; + core.setTextAlign(ctx, "left"); + for (let i = 0; i < indexList.length; i++) { + const text = this.musicname[indexList[i]]; + if ( + this.musics.includes(this.musicMx[page][i]) || + page !== this.musicMx.length - 1 + ) { + core.fillBoldText1( + ctx, + text, + 950, + posy - 30, + page === this.selection[0] && i === this.selection[1] + ? "#FFFFFF" + : "#444444", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + ctx.strokeStyle = "#FFFFFF"; + ctx.lineWidth = 3; + ctx.beginPath(); + ctx.moveTo(900, posy); + ctx.lineTo(1900, posy); + ctx.stroke(); + } + posy += 100; + } + core.fillBoldText1( + ctx, + "上一页", + 1050, + 1200 - 30, + page === 0 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + + core.fillBoldText1( + ctx, + page + 1 + "/" + this.musicMx.length, + 1350, + 1200 - 30, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + core.fillBoldText1( + ctx, + "下一页", + 1550, + 1200 - 30, + page === this.musicMx.length - 1 ? "#444444" : "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(66, true) + ); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 3; + + core.fillText( + ctx, + "|", + 55, + 697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "◀", + 70, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + ctx.beginPath(); + ctx.arc(295, 670, 80, 0, 2 * Math.PI); + ctx.stroke(); + if (this.stop) { + core.fillText( + ctx, + "▶", + 265, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } else { + core.fillText( + ctx, + "||", + 245, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + } + core.fillText( + ctx, + "|", + 495, + 697, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + core.fillText( + ctx, + "▶", + 450, + 700, + "#FFFFFF", + core.ui._buildFont(96, true) + ); + + ctx.font = "bold 48px Verdana"; + ctx.fillText("音量", 350, 900); + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(700, 1000); + ctx.stroke(); + ctx.strokeStyle = "#ffffff"; + ctx.lineWidth = 9; + ctx.fillStyle = "rgba(255,255,255,0.5)"; + + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(600 * audio.getVolume() + 100, 1000); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(600 * audio.getVolume() + 100, 1000, 10, 0, 2 * Math.PI); + ctx.fill(); + core.fillBoldText1( + ctx, + Math.floor(100 * audio.getVolume()), + 720, + 1010, + "#FFFFFF", + "#000000", + 6, + core.ui._buildFont(56, true) + ); + const img = core.material.images.images[this.type + ".webp"]; + if (img) ctx.drawImage(img, 580, 560, 200, 200); + core.setTextAlign(ctx, "center"); + ctx.font = "bold 48px Verdana"; + ctx.fillText("当前歌曲", 400, 297); + ctx.fillText( + this.musicname[this.musicMx[this.selection[0]][this.selection[1]]], + 400, + 397 ); } } @@ -14405,10 +20793,67 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.ui.music = new musicclass(); main.dom.musicMode.onclick = function () { //点击开始页面的CG MODE进入cg回廊 - main.core.control.checkBgm(); + if ( + (core.getLocalStorage("musics") && + core.getLocalStorage("musics").length === 0) || + !core.getLocalStorage("musics") + ) + core.setLocalStorage("musics", ["theme.mp3"]); + core.ui.music.musics = core.getLocalStorage("musics"); + core.playBgm( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ], + 0 + ); + + const arr = main.core.ui.music.musicMx.flat(Infinity); + main.core.ui.music.randomList = shuffle(arr); + main.core.ui.music.random = main.core.ui.music.randomList.indexOf( + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ); page = 0; music.style.display = "block"; - main.core.ui.music.update(); + let time = 0; + core.registerAnimationFrame("music", null, (temptime) => { + if (temptime > time + 1000 / 60) { + time = temptime; + main.core.ui.music.update(); + const duration = + core.plugin.audioSystem.bgmController.player.getRoute( + "bgms." + + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ).duration; + + const currentTime = + core.plugin.audioSystem.bgmController.player.getRoute( + "bgms." + + main.core.ui.music.musicMx[main.core.ui.music.selection[0]][ + main.core.ui.music.selection[1] + ] + ).currentTime; + if (currentTime && duration && duration - currentTime < 0.05) { + if (core.domStyle.isVertical) { + core.ui.music.mousedown(830, 1770); + } else { + core.ui.music.mousedown(475, 765); + } + } + } + }); + }; + loader.prototype.loadOneMusic = function (name) { + /* var music = new Audio(); + music.preload = "none"; + if (main.bgmRemote) + music.src = main.bgmRemoteRoot + core.firstData.name + "/" + name; + else music.src = "project/bgms/" + name; + music.loop = "loop"; + core.material.bgms[name] = music;*/ }; }, "横屏切换": function () { @@ -14450,178 +20895,2651 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = }; }, "图片压缩webp导出": function () { + // 在此增加新插件 + //使用方法:进入游戏后开始游戏,F12打开控制台,输入core.towebp(image),image为已在全塔属性中注册过的图片名字,需要""括起来 + this.towebp = function (image) { + const canvas = document.createElement("canvas"); //背景画布设置 + const ctx = canvas.getContext("2d"); + const img = core.material.images.images[image]; + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage(img, 0, 0); + const webpDataURL = canvas.toDataURL("image/webp", 0.85); //第二个参数为画面质量,范围为0-1,1为无损 + console.log(webpDataURL); + const link = document.createElement("a"); + link.href = webpDataURL; + const name = image.substring(0, image.indexOf(".")); + link.download = name + ".webp"; + link.click(); + }; + this.towebpall = function () { + const canvas = document.createElement("canvas"); //背景画布设置 + const ctx = canvas.getContext("2d"); + for (const image in core.material.images.images) { + this.towebp(image); + } + }; + this.towebpsome = function (images) { + images.forEach((image) => { + core.towebp(image); + }); + }; + }, + "帧动画特效(游戏界面)": function () { + // 在此增加新插件 + const animate2 = document.createElement("canvas"); //画布设置 + animate2.style.zIndex = 91; + animate2.id = "animate2"; + animate2.classList.add("gameCanvas", "anti-aliasing"); + animate2.style.display = "block"; + animate2.width = 416; + animate2.height = 416; + animate2.style.width = core.__PIXELS__ * core.domStyle.scale + "px"; + animate2.style.height = core.__PIXELS__ * core.domStyle.scale + "px"; + main.dom.animate2 = animate2; + const anctx = animate2.getContext("2d"); + + main.dom.gameDraw.appendChild(animate2); + + core.plugin.playing = new Set(); + + this.setanimate = function ( + name, + px, + py, + width, + height, + allFarme, + imageList, + soundList + ) { + const data = { + px: px, + py: py, + width: width, + height: height, + allFarme: allFarme, + imageList: imageList, + soundList: soundList, + }; + core.setFlag("animate_" + name, data); + }; + this.deleteanimate = function (name) { + core.setFlag("animate_" + name); + }; + let thistime = 0; + this.playanimate = function (name, x, y, hero, scalex, scaley, callback) { + const data = { + name: name, + x: x, + y: y, + hero: hero, + scalex: scalex, + scaley: scaley, + farme: 0, + callback, + }; + + core.plugin.playing.add(data); + }; + core.registerAnimationFrame("animateonmap", true, function (timestamp) { + if (timestamp - thistime > 1000 / 30) { + thistime = timestamp; + core.clearMap(anctx); + core.plugin.playing.forEach((one) => { + const data = flags["animate_" + one.name]; + if (!data) { + core.plugin.playing.delete(one); + } else { + data.imageList.forEach(function (image) { + if ( + one.farme >= (image.beforefarme ?? 0) && + one.farme <= (image.afterfarme ?? data.allFarme) + ) { + const img = core.material.images.images?.[image.image]; + if (img) { + const gla = image.globalAlpha ?? 100; + const agla = image.aglobalAlpha ?? gla, + beforefarme = image.beforefarme ?? 0; + const afterfarme = image.afterfarme ?? data.allFarme; + + anctx.globalAlpha = + (gla + + ((agla - gla) * (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1)) / + 100; + + const cx = + (image.cx ?? 0) + + (((image.acx ?? 0) - (image.cx ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cy = + (image.cy ?? 0) + + (((image.acy ?? 0) - (image.cy ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cw = + (image.cw ?? img.width) + + (((image.acw ?? img.width) - (image.cw ?? img.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + ch = + (image.ch ?? img.height) + + (((image.acw ?? img.height) - (image.cw ?? img.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + x = + (image.x ?? 0) + + (((image.ax ?? 0) - (image.x ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + y = + (image.y ?? 0) + + (((image.ay ?? 0) - (image.y ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + w = + (image.w ?? one.width) + + (((image.aw ?? one.width) - (image.w ?? one.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + h = + (image.h ?? one.height) + + (((image.aw ?? one.height) - (image.w ?? one.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + angle = + (Math.PI * + ((image.image.angle ?? 0) + + (((image.aangle ?? 0) - (image.image.angle ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1))) / + 180; + + if (one.hero) { + let sx, sy; + if (core.status.heroMoving < 0) { + sx = 0; + sy = 0; + } else { + sx = + core.utils.scan[core.status.hero.loc.direction].x * + 4 * + core.status.heroMoving; + sy = + core.utils.scan[core.status.hero.loc.direction].y * + 4 * + core.status.heroMoving; + } + const herox = core.status.hero.loc.x * 32 + 16 + sx; + const heroy = core.status.hero.loc.y * 32 + 16 + sy; + core.drawImage( + anctx, + img, + cx, + cy, + cw, + ch, + herox + (x - data.px) * one.scalex, + heroy + (y - data.py) * one.scaley, + w * one.scalex, + h * one.scaley, + angle + ); + } else { + core.drawImage( + anctx, + img, + cx, + cy, + cw, + ch, + one.x + (x - data.px) * one.scalex, + one.y + (y - data.py) * one.scaley, + w * one.scalex, + h * one.scaley, + angle + ); + } + } + } + }); + data.soundList.forEach(function (sound) { + const lisen = + sound.sound && + core.sounds[sound.sound] && + core.musicStatus.soundStatus; + if (one.farme == sound.startfarme && lisen) { + if (sound.stopbefore) core.stopSound(); + core.playSound(sound.sound); + } + }); + one.farme++; + if (one.farme > data.allFarme) { + core.plugin.playing.delete(one); + if (one.callback) { + one.callback(); + } + } + } + }); + } + }); + }, + "intro&loop": function () { + // 在此增加新插件 + this.introAndLoop = function (intro, time, loop) { + core.playBgm(intro); + setTimeout(() => { + core.playBgm(loop); + }, time * 1000); + }; + }, + "开局选项悬停": function () { + // 在此增加新插件 + + main.dom.playGame.addEventListener("mouseenter", () => { + core.dom.playGame.style.backgroundColor = "#808080"; + }); + main.dom.playGame.addEventListener("mouseleave", () => { + core.dom.playGame.style.backgroundColor = "transparent"; + }); + main.dom.playGame.addEventListener("touchmove", () => { + core.dom.playGame.style.backgroundColor = "#808080"; + }); + main.dom.playGame.addEventListener("touchend", () => { + core.dom.playGame.style.backgroundColor = "transparent"; + }); + main.dom.playGame.addEventListener("touchcancel", () => { + core.dom.playGame.style.backgroundColor = "transparent"; + }); + + main.dom.loadGame.addEventListener("mouseenter", () => { + core.dom.loadGame.style.backgroundColor = "#808080"; + }); + main.dom.loadGame.addEventListener("mouseleave", () => { + core.dom.loadGame.style.backgroundColor = "transparent"; + }); + main.dom.loadGame.addEventListener("touchmove", () => { + core.dom.loadGame.style.backgroundColor = "#808080"; + }); + main.dom.loadGame.addEventListener("touchend", () => { + core.dom.loadGame.style.backgroundColor = "transparent"; + }); + main.dom.loadGame.addEventListener("touchcancel", () => { + core.dom.loadGame.style.backgroundColor = "transparent"; + }); + + main.dom.CGMode.addEventListener("mouseenter", () => { + core.dom.CGMode.style.backgroundColor = "#808080"; + }); + main.dom.CGMode.addEventListener("mouseleave", () => { + core.dom.CGMode.style.backgroundColor = "transparent"; + }); + main.dom.CGMode.addEventListener("touchmove", () => { + core.dom.CGMode.style.backgroundColor = "#808080"; + }); + main.dom.CGMode.addEventListener("touchend", () => { + core.dom.CGMode.style.backgroundColor = "transparent"; + }); + main.dom.CGMode.addEventListener("touchcancel", () => { + core.dom.CGMode.style.backgroundColor = "transparent"; + }); + + main.dom.musicMode.addEventListener("mouseenter", () => { + core.dom.musicMode.style.backgroundColor = "#808080"; + }); + main.dom.musicMode.addEventListener("mouseleave", () => { + core.dom.musicMode.style.backgroundColor = "transparent"; + }); + main.dom.musicMode.addEventListener("touchmove", () => { + core.dom.musicMode.style.backgroundColor = "#808080"; + }); + main.dom.musicMode.addEventListener("touchend", () => { + core.dom.musicMode.style.backgroundColor = "transparent"; + }); + main.dom.musicMode.addEventListener("touchcancel", () => { + core.dom.musicMode.style.backgroundColor = "transparent"; + }); + + main.dom.replayGame.addEventListener("mouseenter", () => { + core.dom.replayGame.style.backgroundColor = "#808080"; + }); + main.dom.replayGame.addEventListener("mouseleave", () => { + core.dom.replayGame.style.backgroundColor = "transparent"; + }); + main.dom.replayGame.addEventListener("touchmove", () => { + core.dom.replayGame.style.backgroundColor = "#808080"; + }); + main.dom.replayGame.addEventListener("touchend", () => { + core.dom.replayGame.style.backgroundColor = "transparent"; + }); + main.dom.replayGame.addEventListener("touchcancel", () => { + core.dom.replayGame.style.backgroundColor = "transparent"; + }); + }, + "天气叠加": function () { + //使用方法:使用core.setWeather(天气,等级)来增加天气,使用core.setWeather()来清空天气 + // 天气叠加功能 + ////// 更改天气效果 ////// + control.prototype.setWeather = function (type, level) { + // 非雨雪 + if (type == null) { + Object.keys(core.control.weathers).forEach(function (one) { + core.deleteCanvas("weather" + one); + }); + core.animateFrame.weather.type = []; + core.animateFrame.weather.nodes = {}; + core.animateFrame.weather.level = {}; + core.animateFrame.weather.time = {}; + return; + } + if (!core.animateFrame.weather.level || level == null) + core.animateFrame.weather.level = {}; + if (!core.animateFrame.weather.type) core.animateFrame.weather.type = []; + level = core.clamp(parseInt(level) || 5, 1, 10); + // 当前天气:则忽略 + if ( + core.animateFrame.weather.type.includes(type) && + level == core.animateFrame.weather.level[type] + ) + return; + if (core.animateFrame.weather.nodes[type]) return; + // 计算当前的宽高 + core.createCanvas( + "weather" + type, + 0, + 0, + core.__PIXELS__, + core.__PIXELS__, + 80 + ); + core.animateFrame.weather.type.push(type); + core.animateFrame.weather.level[type] = level; + this._setWeather_createNodes(type, level); + }; + control.prototype._setWeather_createNodes = function (type, level) { + var number = + level * + parseInt( + (20 * core.bigmap.width * core.bigmap.height) / + (core.__SIZE__ * core.__SIZE__) + ); + if (!core.animateFrame.weather.nodes[type]) + core.animateFrame.weather.nodes[type] = []; + switch (type) { + case "rain": + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.rain.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + l: Math.random() * 2.5, + xs: -4 + Math.random() * 4 + 2, + ys: Math.random() * 10 + 10, + }); + } + break; + case "snow": + for (var a = 0; a < number; a++) { + core.animateFrame.weather.nodes.snow.push({ + x: Math.random() * core.bigmap.width * 32, + y: Math.random() * core.bigmap.height * 32, + r: Math.random() * 5 + 1, + d: Math.random() * Math.min(level, 200), + }); + } + break; + case "fog": + if (core.animateFrame.weather.fog) { + core.animateFrame.weather.nodes[type] = [ + { + level: number, + x: 0, + y: -core.__PIXELS__ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; + } + break; + case "cloud": + if (core.animateFrame.weather.cloud) { + core.animateFrame.weather.nodes[type] = [ + { + level: number, + x: 0, + y: -core.__PIXELS__ / 2, + dx: -Math.random() * 1.5, + dy: Math.random(), + delta: 0.001, + }, + ]; + } + break; + case "sun": + if (core.animateFrame.weather.sun) { + // 直接绘制 + core.clearMap("weather" + type); + core.setAlpha("weather" + type, level / 10); + core.drawImage( + "weather" + type, + core.animateFrame.weather.sun, + 0, + 0, + core.animateFrame.weather.sun.width, + core.animateFrame.weather.sun.height, + 0, + 0, + core.__PIXELS__, + core.__PIXELS__ + ); + core.setAlpha("weather" + type, 1); + } + break; + } + }; + core.registerAnimationFrame("weather", true, function (timestamp) { + var weather = core.animateFrame.weather; + if (!weather.type) return; + weather.type.forEach(function (one) { + if ( + timestamp - weather.time[one] <= 30 || + !core.dymCanvas["weather" + one] + ) + return; + core.control["_animationFrame_weather_" + one](); + weather.time[one] = timestamp; + }); + }); + // 雨 + control.prototype._animationFrame_weather_rain = function () { + var ctx = core.dymCanvas.weatherrain, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weatherrain"); + ctx.strokeStyle = "rgba(174,194,224,0.8)"; + ctx.lineWidth = 1; + ctx.lineCap = "round"; + core.animateFrame.weather.nodes.rain.forEach(function (p) { + ctx.beginPath(); + ctx.moveTo(p.x - ox, p.y - oy); + ctx.lineTo(p.x + p.l * p.xs - ox, p.y + p.l * p.ys - oy); + ctx.stroke(); + p.x += p.xs; + p.y += p.ys; + if (p.x > core.bigmap.width * 32 || p.y > core.bigmap.height * 32) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } + }); + ctx.fill(); + }; + // 雪 + control.prototype._animationFrame_weather_snow = function () { + var ctx = core.dymCanvas.weathersnow, + ox = core.bigmap.offsetX, + oy = core.bigmap.offsetY; + core.clearMap("weathersnow"); + ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; + ctx.beginPath(); + if (!core.animateFrame.weather.data) core.animateFrame.weather.data = {}; + core.animateFrame.weather.data.snow = + core.animateFrame.weather.data.snow || 0; + core.animateFrame.weather.data.snow += 0.01; + var angle = core.animateFrame.weather.data.snow; + core.animateFrame.weather.nodes.snow.forEach(function (p) { + ctx.moveTo(p.x - ox, p.y - oy); + ctx.arc(p.x - ox, p.y - oy, p.r, 0, Math.PI * 2, true); + // update + p.x += Math.sin(angle) * core.animateFrame.weather.level.snow; + p.y += Math.cos(angle + p.d) + 1 + p.r / 2; + if ( + p.x > core.bigmap.width * 32 + 5 || + p.x < -5 || + p.y > core.bigmap.height * 32 + ) { + if (Math.random() > 1 / 3) { + p.x = Math.random() * core.bigmap.width * 32; + p.y = -10; + } else { + if (Math.sin(angle) > 0) p.x = -5; + else p.x = core.bigmap.width * 32 + 5; + p.y = Math.random() * core.bigmap.height * 32; + } + } + }); + ctx.fill(); + }; + // 图片天气 + control.prototype.__animateFrame_weather_image = function (image, type) { + if (!image) return; + var node = core.animateFrame.weather.nodes[type][0]; + core.setAlpha("weather" + type, node.level / 500); + var wind = 1.5; + var width = image.width, + height = image.height; + node.x += node.dx * wind; + node.y += (2 * node.dy - 1) * wind; + if (node.x + 3 * width <= core.__PIXELS__) { + node.x += 4 * width; + while (node.x > 0) node.x -= width; + } + node.dy += node.delta; + if (node.dy >= 1) { + node.delta = -0.001; + } else if (node.dy <= 0) { + node.delta = 0.001; + } + if (node.y + 3 * height <= core.__PIXELS__) { + node.y += 4 * height; + while (node.y > 0) node.y -= height; + } else if (node.y >= 0) { + node.y -= height; + } + for (var i = 0; i < 3; ++i) { + for (var j = 0; j < 3; ++j) { + if ( + node.x + (i + 1) * width <= 0 || + node.x + i * width >= core.__PIXELS__ || + node.y + (j + 1) * height <= 0 || + node.y + j * height >= core.__PIXELS__ + ) + continue; + core.drawImage( + "weather" + type, + image, + node.x + i * width, + node.y + j * height + ); + } + } + core.setAlpha("weather" + type, 1); + }; + // 雾 + control.prototype._animationFrame_weather_fog = function () { + core.clearMap("weatherfog"); + this.__animateFrame_weather_image(core.animateFrame.weather.fog, "fog"); + }; + // 云 + control.prototype._animationFrame_weather_cloud = function () { + core.clearMap("weathercloud"); + this.__animateFrame_weather_image( + core.animateFrame.weather.cloud, + "cloud" + ); + }; + }, + "回合战斗动画": function () { // 在此增加新插件 - //使用方法:进入游戏后开始游戏,F12打开控制台,输入core.towebp(image),image为已在全塔属性中注册过的图片名字,需要""括起来 - this.towebp = function (image) { - const canvas = document.createElement("canvas"); //背景画布设置 - const ctx = canvas.getContext("2d"); - const img = core.material.images.images[image]; - canvas.width = img.width; - canvas.height = img.height; - ctx.drawImage(img, 0, 0); - const webpDataURL = canvas.toDataURL("image/webp", 0.85); //第二个参数为画面质量,范围为0-1,1为无损 - console.log(webpDataURL); - const link = document.createElement("a"); - link.href = webpDataURL; - const name = image.substring(0, image.indexOf(".")); - link.download = name + ".webp"; - link.click(); - }; - this.towebpall = function () { - const canvas = document.createElement("canvas"); //背景画布设置 - const ctx = canvas.getContext("2d"); - for (const image in core.material.images.images) { - this.towebp(image); + const animateAttack = document.createElement("canvas"); //画布设置 + animateAttack.style.zIndex = 80; + animateAttack.id = "animateAttack"; + animateAttack.classList.add("gameCanvas", "anti-aliasing"); + animateAttack.style.display = "block"; + animateAttack.width = 416; + animateAttack.height = 416; + animateAttack.style.width = core.__PIXELS__ * core.domStyle.scale + "px"; + animateAttack.style.height = core.__PIXELS__ * core.domStyle.scale + "px"; + main.dom.animateAttack = animateAttack; + const ctx = animateAttack.getContext("2d"); + core.plugin.playingattack = new Set(); + const ctx6 = main.dom.animate2.getContext("2d"); + let easy = false; + const { imagelighter } = core.plugin.utils; + + function playanimate(name, x, y, scalex = 1, scaley = 1) { + const data = { + name: name, + x: x, + y: y, + scalex: scalex, + scaley: scaley, + farme: 0, + }; + core.plugin.playingattack.add(data); + } + + function playinganimate() { + let time = 0; + if (core.plugin.playingattack.size === 0) return Promise.resolve(); + return new Promise((resolve) => { + core.registerAnimationFrame("animateenemyattack", true, (timestamp) => { + if (timestamp - time > 1000 / 60) { + time = timestamp; + core.clearMap(ctx6); + + core.plugin.playingattack.forEach((one) => { + const data = flags["animate_" + one.name]; + + if (!data) { + core.plugin.playingattack.delete(one); + if (core.plugin.playingattack.size === 0) { + core.unregisterAnimationFrame("animateenemyattack"); + resolve(); + } + } else { + data.imageList.forEach(function (image) { + if ( + one.farme >= (image.beforefarme ?? 0) && + one.farme <= (image.afterfarme ?? data.allFarme) + ) { + const img = core.material.images.images?.[image.image]; + if (img) { + const gla = image.globalAlpha ?? 100; + const agla = image.aglobalAlpha ?? gla, + beforefarme = image.beforefarme ?? 0; + const afterfarme = image.afterfarme ?? data.allFarme; + + ctx6.globalAlpha = + (gla + + ((agla - gla) * (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1)) / + 100; + + const cx = + (image.cx ?? 0) + + (((image.acx ?? 0) - (image.cx ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cy = + (image.cy ?? 0) + + (((image.acy ?? 0) - (image.cy ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + cw = + (image.cw ?? img.width) + + (((image.acw ?? img.width) - + (image.cw ?? img.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + ch = + (image.ch ?? img.height) + + (((image.acw ?? img.height) - + (image.cw ?? img.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + x = + (image.x ?? 0) + + (((image.ax ?? 0) - (image.x ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + y = + (image.y ?? 0) + + (((image.ay ?? 0) - (image.y ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + w = + (image.w ?? one.width) + + (((image.aw ?? one.width) - (image.w ?? one.width)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + h = + (image.h ?? one.height) + + (((image.aw ?? one.height) - + (image.w ?? one.height)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1), + angle = + (Math.PI * + ((image.image.angle ?? 0) + + (((image.aangle ?? 0) - + (image.image.angle ?? 0)) * + (one.farme - beforefarme)) / + (afterfarme - beforefarme || 1))) / + 180; + + core.drawImage( + ctx6, + img, + cx, + cy, + cw, + ch, + one.x + (x - data.px) * one.scalex, + one.y + (y - data.py) * one.scaley, + w * one.scalex, + h * one.scaley, + angle + ); + } + } + }); + data.soundList.forEach(function (sound) { + const lisen = + sound.sound && + core.sounds[sound.sound] && + core.musicStatus.soundStatus; + if (one.farme == sound.startfarme && lisen) { + if (sound.stopbefore) core.stopSound(); + core.playSound(sound.sound); + } + }); + one.farme++; + ctx6.restore(); + if (one.farme > data.allFarme) { + core.clearMap(ctx6); + core.plugin.playingattack.delete(one); + if (core.plugin.playingattack.size === 0) { + core.unregisterAnimationFrame("animateenemyattack"); + resolve(); + } + } + } + }); + } + }); + }); + } + + main.dom.gameDraw.appendChild(animateAttack); + const { lcm, gcd } = core.plugin.utils; + + function animateOnAttack(name, onenemy) { + if (onenemy) { + playanimate(name, 290, 180); + } else { + playanimate(name, 130, 180); } - }; - this.towebpsome = function (images) { - images.forEach((image) => { - core.towebp(image); + } + + this.attackAnimate = function ( + enemyId, + heroInfo, + enemyInfo, + equipInfo, + oneTurn, + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList + ) { + //参数分别为怪物id、真实属性,战斗信息,特殊装备(如火焰风衣)属性特殊装备属性为以元组{equipId,oneDamage,speed,now:0}构成的数组(列出每个需要计算的特殊装备,没有则为空数组或不填) + core.lockControl(); + core.clearMap(ctx); + core.status.event.id = "attackAnimate"; + let turn = 0; + enemyInfo.id = enemyId; + enemyInfo.cls = core.getClsFromId(enemyId); + enemyInfo.name = core.material.enemys[enemyId].name; + + if (oneTurn < 120) oneTurn *= Math.round(120 / oneTurn); + let time = 0, + farme = 0; + return new Promise((res) => { + core.plugin.battle_onclick = function (x, y, px, py) { + const makeBox = ([x, y], [w, h]) => { + return [ + [x, y], + [x + w, y + h], + ]; + }; + const inRect = ([x, y], [ + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + const pos = [px, py]; + const easybox = makeBox([90, 232], [80, 22]), + easyclosebox = makeBox([290, 232], [40, 22]), + uneasybox = makeBox([265, 330], [65, 20]), + uneasyclosebox = makeBox([290, 350], [40, 20]); + if (inRect(pos, easybox) && easy) { + easy = false; + } else if (inRect(pos, uneasybox) && !easy) { + easy = true; + } else if ( + (inRect(pos, easyclosebox) && easy) || + (inRect(pos, uneasyclosebox) && !easy) + ) { + core.status.event.id = ""; + core.unregisterAnimationFrame("attackAnimate"); + core.clearMap(ctx); + core.closePanel(); + res(); + } + }; + async function drawAttackAnimate( + heroInfo, + oneTurn, + enemyInfo, + equipInfo, + farme, + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList + ) { + core.lockControl(); + core.status.event.id = "battle"; + + let attack = false; + if (heroInfo.isAttack) attack = true; + if (enemyInfo.isAttack) attack = true; + equipInfo.forEach(function (v) { + if (v.isAttack) attack = true; + }); + let onattack = false; + if (heroInfo.onAttack) onattack = true; + if (enemyInfo.onAttack) onattack = true; + equipInfo.forEach(function (v) { + if (v.onAttack) onattack = true; + }); + core.clearMap(ctx); + let animate = Math.floor(farme / 30); + if (easy) { + core.fillRect(ctx, 64, 52, 288, 212, "rgba(0,0,0,0.5)"); + core.strokeRect(ctx, 64, 52, 288, 212, "rgba(255,255,255,0.5)", 4); + core.setTextAlign(ctx, "center"); + core.fillBoldText( + ctx, + hero.name, + 127, + 148, + "#FFFFFF", + "#000000", + "bold 14px Verdana" + ); + core.setTextAlign(ctx, "left"); + core.drawIcon(ctx, "hp", 70, 210, 16, 16); + core.fillBoldText( + ctx, + "生命 " + core.formatBigNumber(heroInfo.hp, true), + 90, + 225, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + + core.fillBoldText( + ctx, + "详细模式", + 90, + 250, + "#FFFF60", + "#000000", + "bold 18px Verdana" + ); + + core.strokeRect(ctx, 112, 159, 32, 48, "rgba(255,255,255,1)", 1); + let img = + attack && heroDiffList[turn].hp < 0 ? + imagelighter(core.material.images.images["hero.webp"]) : + attack && heroDiffList[turn].hp > 0 ? + imagelighter( + core.material.images.images["hero.webp"], + "rgba(0, 255, 0, 0.5)" + ) : + core.material.images.images["hero.webp"]; + core.drawImage( + ctx, + img, + 32 * (animate % 4), + 0, + 32, + 48, + 112, + 159, + 32, + 48 + ); + + core.setTextAlign(ctx, "center"); + core.fillBoldText( + ctx, + enemyInfo.name, + 289, + 148, + "#FFFFFF", + "#000000", + "bold 14px Verdana" + ); + + core.setTextAlign(ctx, "right"); + if (enemyInfo.cls === "enemys") { + core.strokeRect(ctx, 272, 175, 32, 32, "rgba(255,255,255,1)", 1); + let img = + attack && enemyDiffList[turn].hp < 0 ? + imagelighter(core.getBlockInfo(enemyInfo.id).image) : + attack && enemyDiffList[turn].hp > 0 ? + imagelighter( + core.getBlockInfo(enemyInfo.id).image, + "rgba(0, 255, 0, 0.5)" + ) : + core.getBlockInfo(enemyInfo.id).image; + core.drawImage( + ctx, + img, + 32 * (animate % 2), + core.getBlockInfo(enemyInfo.id).posY * 32, + 32, + 32, + 272, + 175, + 32, + 32 + ); + } else { + core.strokeRect(ctx, 272, 159, 32, 48, "rgba(255,255,255,1)", 1); + let img = + attack && enemyDiffList[turn].hp < 0 ? + imagelighter(core.getBlockInfo(enemyInfo.id).image) : + attack && enemyDiffList[turn].hp > 0 ? + imagelighter( + core.getBlockInfo(enemyInfo.id).image, + "rgba(0, 255, 0, 0.5)" + ) : + core.getBlockInfo(enemyInfo.id).image; + core.drawImage( + ctx, + img, + 32 * (animate % 4), + core.getBlockInfo(enemyInfo.id).posY * 48, + 32, + 48, + 272, + 159, + 32, + 48 + ); + } + core.drawIcon(ctx, "hp", 330, 210, 16, 16); + + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.hp, true) + " 生命", + 330, + 225, + "#FFFFFF", + "#000000", + "bold 14px Verdana" + ); + core.fillBoldText( + ctx, + "跳过", + 330, + 250, + "#FFFF60", + "#000000", + "bold 18px Verdana" + ); + + core.fillBoldText( + ctx, + "V", + 219, + 183, + "#FFFFFF", + "#000000", + "bold 48px pala" + ); + core.fillBoldText( + ctx, + "s", + 231, + 183, + "#FFFFFF", + "#000000", + "bold 36px pala" + ); + + if (!attack && !onattack) enemyInfo.now += enemyInfo.speed / onegcd; + let enemynow = Math.min(100 + (enemyInfo.now / oneTurn) * 215, 315); + ctx.fillStyle = "#FFFFFF"; + ctx.beginPath(); + ctx.moveTo(enemynow, 120); + ctx.lineTo(enemynow + 5, 110); + ctx.lineTo(enemynow - 5, 110); + ctx.closePath(); + ctx.fill(); + + if (enemyInfo.cls === "enemys") { + core.drawImage( + ctx, + core.getBlockInfo(enemyInfo.id).image, + 32, + core.getBlockInfo(enemyInfo.id).posY * 32, + 32, + 32, + enemynow - 16, + 74, + 32, + 32 + ); + } else { + core.drawImage( + ctx, + core.getBlockInfo(enemyInfo.id).image, + 32, + core.getBlockInfo(enemyInfo.id).posY * 48, + 32, + 48, + enemynow - 16, + 58, + 32, + 48 + ); + } + core.drawLine(ctx, 100, 125, 315, 125, "#FFFFFF", 5); + equipInfo.forEach(function (v) { + if (!attack && !onattack) v.now += v.speed / onegcd; + let vnow = Math.min(100 + (v.now / oneTurn) * 215, 315); + ctx.beginPath(); + ctx.moveTo(vnow, 120); + ctx.lineTo(vnow + 5, 110); + ctx.lineTo(vnow - 5, 110); + ctx.closePath(); + + ctx.fill(); + + core.drawIcon(ctx, v.id, vnow - 16, 54, 32, 32); + }); + if (!attack && !onattack) heroInfo.now += hero.speed / onegcd; + let heronow = Math.min(100 + (heroInfo.now / oneTurn) * 215, 315); + ctx.beginPath(); + ctx.moveTo(heronow, 120); + ctx.lineTo(heronow + 5, 110); + ctx.lineTo(heronow - 5, 110); + ctx.closePath(); + + ctx.fill(); + core.drawImage( + ctx, + "hero.webp", + 0, + 0, + 32, + 48, + heronow - 16, + 58, + 32, + 48 + ); + } else { + core.fillRect(ctx, 64, 52, 288, 320, "rgba(0,0,0,0.5)"); + core.strokeRect(ctx, 64, 52, 288, 320, "rgba(255,255,255,0.5)", 4); + core.setTextAlign(ctx, "center"); + core.fillBoldText( + ctx, + hero.name, + 127, + 148, + "#FFFFFF", + "#000000", + "bold 14px Verdana" + ); + core.setTextAlign(ctx, "left"); + core.drawIcon(ctx, "hp", 70, 210, 16, 16); + core.drawIcon(ctx, "atk", 70, 230, 16, 16); + core.drawIcon(ctx, "def", 70, 250, 16, 16); + core.drawIcon(ctx, "I374", 70, 270, 16, 16); + core.drawIcon(ctx, "I375", 70, 290, 16, 16); + core.drawIcon(ctx, "mdef", 70, 310, 16, 16); + core.drawIcon(ctx, "amulet", 70, 330, 16, 16); + core.drawIcon(ctx, "jumpShoes", 70, 350, 16, 16); + core.fillBoldText( + ctx, + "生命 " + core.formatBigNumber(heroInfo.hp, true), + 90, + 225, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + + core.fillBoldText( + ctx, + "攻击 " + core.formatBigNumber(heroInfo.atk), + 90, + 245, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "防御 " + core.formatBigNumber(heroInfo.def), + 90, + 265, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "法强 " + core.formatBigNumber(heroInfo.spell), + 90, + 285, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "法攻 " + core.formatBigNumber(heroInfo.matk), + 90, + 305, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "护盾 " + core.formatBigNumber(heroInfo.mhp), + 90, + 325, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "法抗 " + heroInfo.mdef + "%", + 90, + 345, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "速度 " + core.formatBigNumber(heroInfo.speed), + 90, + 365, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + + core.strokeRect(ctx, 112, 159, 32, 48, "rgba(255,255,255,1)", 1); + let img = + attack && heroDiffList[turn].hp < 0 ? + imagelighter(core.material.images.images["hero.webp"]) : + attack && heroDiffList[turn].hp > 0 ? + imagelighter( + core.material.images.images["hero.webp"], + "rgba(0, 255, 0, 0.5)" + ) : + core.material.images.images["hero.webp"]; + core.drawImage( + ctx, + img, + 32 * (animate % 4), + 0, + 32, + 48, + 112, + 159, + 32, + 48 + ); + + core.setTextAlign(ctx, "center"); + core.fillBoldText( + ctx, + enemyInfo.name, + 289, + 148, + "#FFFFFF", + "#000000", + "bold 14px Verdana" + ); + + core.setTextAlign(ctx, "right"); + if (enemyInfo.cls === "enemys") { + core.strokeRect(ctx, 272, 175, 32, 32, "rgba(255,255,255,1)", 1); + let img = + attack && enemyDiffList[turn].hp < 0 ? + imagelighter(core.getBlockInfo(enemyInfo.id).image) : + attack && enemyDiffList[turn].hp > 0 ? + imagelighter( + core.getBlockInfo(enemyInfo.id).image, + "rgba(0, 255, 0, 0.5)" + ) : + core.getBlockInfo(enemyInfo.id).image; + core.drawImage( + ctx, + img, + 32 * (animate % 2), + core.getBlockInfo(enemyInfo.id).posY * 32, + 32, + 32, + 272, + 175, + 32, + 32 + ); + } else { + core.strokeRect(ctx, 272, 159, 32, 48, "rgba(255,255,255,1)", 1); + let img = + attack && enemyDiffList[turn].hp < 0 ? + imagelighter(core.getBlockInfo(enemyInfo.id).image) : + attack && enemyDiffList[turn].hp > 0 ? + imagelighter( + core.getBlockInfo(enemyInfo.id).image, + "rgba(0, 255, 0, 0.5)" + ) : + core.getBlockInfo(enemyInfo.id).image; + core.drawImage( + ctx, + img, + 32 * (animate % 4), + core.getBlockInfo(enemyInfo.id).posY * 48, + 32, + 48, + 272, + 159, + 32, + 48 + ); + } + core.drawIcon(ctx, "hp", 330, 210, 16, 16); + core.drawIcon(ctx, "atk", 330, 230, 16, 16); + core.drawIcon(ctx, "def", 330, 250, 16, 16); + core.drawIcon(ctx, "I374", 330, 270, 16, 16); + core.drawIcon(ctx, "amulet", 330, 290, 16, 16); + core.drawIcon(ctx, "jumpShoes", 330, 310, 16, 16); + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.hp, true) + " 生命", + 330, + 225, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.atk) + " 攻击", + 330, + 245, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.def) + " 防御", + 330, + 265, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + (enemyInfo.spell ?? 0) + " 法强", + 330, + 285, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + (enemyInfo.mdef ?? 0) * 100 + "% 法抗", + 330, + 305, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + core.formatBigNumber(enemyInfo.speed) + " 速度", + 330, + 325, + "#FFFFFF", + "#000000", + "bold 14px Arial" + ); + core.fillBoldText( + ctx, + "简易模式", + 330, + 345, + "#FFFF60", + "#000000", + "bold 16px Verdana" + ); + core.fillBoldText( + ctx, + "跳过", + 330, + 365, + "#FFFF60", + "#000000", + "bold 16px Verdana" + ); + + core.fillBoldText( + ctx, + "V", + 219, + 183, + "#FFFFFF", + "#000000", + "bold 48px pala" + ); + core.fillBoldText( + ctx, + "s", + 231, + 183, + "#FFFFFF", + "#000000", + "bold 36px pala" + ); + + if (!attack && !onattack) enemyInfo.now += enemyInfo.speed / onegcd; + let enemynow = Math.min(100 + (enemyInfo.now / oneTurn) * 215, 315); + ctx.fillStyle = "#FFFFFF"; + ctx.beginPath(); + ctx.moveTo(enemynow, 120); + ctx.lineTo(enemynow + 5, 110); + ctx.lineTo(enemynow - 5, 110); + ctx.closePath(); + ctx.fill(); + + if (enemyInfo.cls === "enemys") { + core.drawImage( + ctx, + core.getBlockInfo(enemyInfo.id).image, + 32, + core.getBlockInfo(enemyInfo.id).posY * 32, + 32, + 32, + enemynow - 16, + 74, + 32, + 32 + ); + } else { + core.drawImage( + ctx, + core.getBlockInfo(enemyInfo.id).image, + 32, + core.getBlockInfo(enemyInfo.id).posY * 48, + 32, + 19, + enemynow - 16, + 58, + 32, + 48 + ); + } + core.drawLine(ctx, 100, 125, 315, 125, "#FFFFFF", 5); + equipInfo.forEach(function (v) { + if (!attack && !onattack) v.now += v.speed / onegcd; + let vnow = Math.min(100 + (v.now / oneTurn) * 215, 315); + ctx.beginPath(); + ctx.moveTo(vnow, 120); + ctx.lineTo(vnow + 5, 110); + ctx.lineTo(vnow - 5, 110); + ctx.closePath(); + + ctx.fill(); + + core.drawIcon(ctx, v.id, vnow - 16, 54, 32, 32); + }); + if (!attack && !onattack) heroInfo.now += hero.speed / onegcd; + let heronow = Math.min(100 + (heroInfo.now / oneTurn) * 215, 315); + ctx.beginPath(); + ctx.moveTo(heronow, 120); + ctx.lineTo(heronow + 5, 110); + ctx.lineTo(heronow - 5, 110); + ctx.closePath(); + + ctx.fill(); + core.drawImage( + ctx, + "hero.webp", + 0, + 0, + 32, + 48, + heronow - 16, + 58, + 32, + 48 + ); + } + let nowattacking = false; + if (heroInfo.now >= oneTurn && !heroInfo.isAttack) { + heroInfo.onattack = false; + heroInfo.isAttack = true; + nowattacking = true; + } + if (enemyInfo.now >= oneTurn && !enemyInfo.isAttack) { + enemyInfo.onattack = false; + enemyInfo.isAttack = true; + nowattacking = true; + } + const equipanimate = []; + equipInfo.forEach((v) => { + if (v.now >= oneTurn && !v.isAttack) { + v.isAttack = true; + v.onattack = false; + nowattacking = true; + equipanimate.push(v); + } + }); + if (!attack && nowattacking) { + let herodamage = enemyDiffList[turn].hp; + if (herodamage > 0) herodamage = "+" + herodamage; + let text = herodamage === 0 ? "抵抗" : herodamage; + + Dove.MorePerform.ShowDamagePop.PopDamage( + ctx, // 默认画布名称 + 270, // 英雄位置 x + 160, // 英雄位置 y + text, // 伤害值 + 18, // 默认字体大小 + "Arial", //默认字体 + typeof text === "string" && text.startsWith("+") ? + "#22FF44" : + typeof text === "string" ? + "#FFFFFF" : + null, // 默认颜色 + text === "抵抗" ? "#000000" : null, // 默认描边颜色 + 0, // 默认水平速度 + -1, // 默认垂直速度 + 0, // 默认重力 + 90 // 默认显示时长(帧数) + ); + for (const v in enemyDiffList[turn]) { + enemyInfo[v] += enemyDiffList[turn][v]; + } + enemyanimateList[turn].forEach((v) => animateOnAttack(v, true)); + let enemydamage = heroDiffList[turn].hp; + if (enemydamage > 0) enemydamage = "+" + enemydamage; + text = enemydamage === 0 ? "抵抗" : enemydamage; + Dove.MorePerform.ShowDamagePop.PopDamage( + ctx, // 默认画布名称 + 110, // 英雄位置 x + 160, // 英雄位置 y + text, // 伤害值 + 18, // 默认字体大小 + "Arial", //默认字体 + typeof text === "string" && text.startsWith("+") ? + "#22FF44" : + typeof text === "string" ? + "#FFFFFF" : + null, // 默认颜色 + text === "抵抗" ? "#000000" : null, // 默认描边颜色 + 0, // 默认水平速度 + -1, // 默认垂直速度 + 0, // 默认重力 + 90 // 默认显示时长(帧数) + ); + for (const v in heroDiffList[turn]) { + heroInfo[v] += heroDiffList[turn][v]; + } + heroanimateList[turn].forEach((v) => animateOnAttack(v, false)); + + if (enemyDiffList[turn] < 0) enemyInfo.inAttack = true; + if (heroDiffList[turn] < 0) heroInfo.inAttack = true; + if (heroInfo.hp < 0) heroInfo.hp = 0; + if (enemyInfo.hp < 0) enemyInfo.hp = 0; + await Promise.all([ + await playinganimate(), + new Promise((resolve) => { + if (heroInfo.isAttack) { + heroInfo.now = 0; + heroInfo.isAttack = false; + } + resolve(); + }), + new Promise((resolve) => { + if (enemyInfo.isAttack) { + enemyInfo.now = 0; + enemyInfo.isAttack = false; + } + resolve(); + }), + new Promise((resolve) => { + if (equipanimate.length > 0) { + equipanimate.forEach((v) => { + v.now = 0; + v.isAttack = false; + }); + } + resolve(); + }), + new Promise((resolve) => { + turn++; + resolve(); + }), + ]); + + if (heroInfo.hp <= 0 || enemyInfo.hp <= 0) { + core.status.event.id = ""; + core.unregisterAnimationFrame("attackAnimate"); + core.clearMap(ctx); + core.closePanel(); + res(); + } + } + } + core.registerAnimationFrame("attackAnimate", true, (temptime) => { + if (temptime - time > 1000 / 60) { + time = temptime; + drawAttackAnimate( + heroInfo, + oneTurn, + enemyInfo, + equipInfo, + farme, + onegcd, + heroDiffList, + enemyDiffList, + heroanimateList, + enemyanimateList + ); + + farme++; + } + }); }); }; }, - "帧动画特效(游戏界面)": function () { + "剧情内容": function () { + // 每项为一个数组,第一项是名字,第二项是对话内容,第三项为音频文件名(没有则不需要第三项) + // 回放只会在同一个this下回放,进入剧情前请以事件块声明进入哪个剧情数组 + this.chapter000 = [ + ["", "这些天,街道不曾下雨。"], + ["", "所以,那浸湿地面的,定是那些女孩们流落的鲜血无疑。"], + ["", "我蹲在充斥着铁锈味般恶臭的小巷中,悠闲地如是想着。"], + ["", "扑哧。"], + ["", "耳旁再次响起象征着某个女孩子死去的声音。"], + ["", "再一次——"], + ["", "再一次。"], + ["", "女子们被肢解成单纯的肉块。"], + ["", "我任由流下的血浸满全身,屏住自己的呼吸。"], + ["", "祈求自己能拥有从猎人手中逃脱的幸运。"], + ["", "扑哧。"], + ["", "直到刚才,我们还坐在去往娼馆的马车的路上。"], + ["", "而在这之中的某些人,已经不在这个世上了。"], + ["", "不,应该把“某些”换成“几乎所有”才更为恰当吧。"], + ["", "恐怕,不久之后我也会变成小巷中血腥的装饰品。"], + ["", "我是为了得到这种死法,才辛苦苟活至今的吗?"], + ["", "来个人告诉我啊——"], + ["", "谁都好。"], + ["", "来人啊!!"], + ["少女", "「呃······!?」", "aiy010000010.opus"], //小动物01 + ["", "漆黑的物体充斥了我的整个视野"], + ["", "我很快意识到,那是只很大的脚。"], + ["", "必须要出声求救。"], + ["", "可是,耳中却只能听到自己的牙关不停交战的声音。"], + ["", "我是如此的无助。"], + ["", "逃跑也好,道歉也罢。"], + ["", "就连抬头看一眼将要杀掉我的人的面孔都做不到。"], + ["少女", "「······被杀」", "aiy010000020.opus"], //小动物02 + ["", "会被杀。"], + ["", "会被杀!!"], + ["", "来自内心深处的冰冷预感,渐渐地在体内蔓延开来。"], + ["少女", "「不,不要······」", "aiy010000030.opus"], //小动物03 + ] + this.chapter001 = [ + ["", "浮游都市,《诺瓦斯·艾蒂尔》。"], + ["", "《特别受灾地区》——"], + ["", "通称,《牢狱》"], + ["", "是被险峻的峭壁环绕,与世隔绝的,都市的最底部。"], + ] + this.chapter002 = [ + ["年轻人", "「放开我!」", "aiy710000010.opus"], //龙套1-01 + ["年轻人", "「我只是在帮那个女人而已!」", "aiy710000020.opus"], //龙套1-02 + ["年轻人", "「你们没听到吗!?」", "aiy710000030.opus"], //龙套1-03 + ["年轻人", "「她是被受骗才会被卖到娼馆来的」", "aiy710000040.opus"], //龙套1-04 + [ + "年轻人", + "「用肮脏的手段把钱借给她父母的,就是你们这些家伙吧!?」", + "aiy710000050.opus", + ], //龙套1-05 + ["年轻人", "「给我说些什么啊」", "aiy710000060.opus"], //龙套1-06 + ["凯伊姆", "「这些话等到了娼馆再说吧」", "aiy310000010.opus"], //男主01 + ["凯伊姆", "「我来抓你,只是受雇于人而已」", "aiy310000020.opus"], //男主02 + ["", "我走进娼馆《莉莉乌姆》的接待室。"], + ["", "正在桌旁整理账簿的奥兹停下手头的工作,抬起头向我看来。"], + ["奥兹", "「这不是凯伊姆先生吗,辛苦了」", "aiy350000010.opus"], //金锁高官01 + ["奥兹", "「委托已经完成了吗?」", "aiy350000020.opus"], //金锁高官02 + ["凯伊姆", "「啊啊,是这家伙没错吧」", "aiy310000030.opus"], //男主03 + ["", "奥兹用只要接触到就能杀人般的眼神在男人脸上搜过。"], + ["奥兹", "「没错,就是这个人」", "aiy350000030.opus"], //金锁高官03 + ["凯伊姆", "「是么」", "aiy310000040.opus"], //男主04 + ["年轻人", "「你,你们要对我做什么」", "aiy710000070.opus"], //龙套1-07 + ["奥兹", "「······」", "aiy350000040.opus"], //金锁高官04 + ["", "奥兹用一个眼神,就让男人闭上了嘴。"], + ["", "然后,向我这边转过身来。"], + ["奥兹", "「抱歉啊,总是麻烦你去做这些无聊的事」", "aiy350000050.opus"], //金锁高官05 + ["奥兹", "「都怪我们这边的年轻人太没用」", "aiy350000060.opus"], //金锁高官06 + ["凯伊姆", "「客套话就免了」", "aiy310000050.opus"], //男主05 + ["奥兹", "「这还真是失礼了」", "aiy350000070.opus"], //金锁高官07 + ["奥兹", "「喂,来个人」", "aiy350000080.opus"], //金锁高官08 + ["光头男人", "「是」", "aiy820000010.opus"], //龙套2-01 + ["奥兹", "「凯伊姆先生做完工作回来了」", "aiy350000090.opus"], //金锁高官09 + ["光头男人", "「是,是,那个······」", "aiy820000020.opus"], //龙套2-02 + ["奥兹", "「我是要你拿些酒来,这个蠢材!」", "aiy350000100.opus"], //金锁高官10 + ["", "喀!"], + ["", "奥兹扔出的烟灰缸砸中了手下的额头。"], + ["", "鲜血四溅。"], + ["凯伊姆", "「不用这么麻烦」", "aiy310000060.opus"], //男主06 + ["凯伊姆", "「我接下来要去《菲诺列塔》」", "aiy310000070.opus"], //男主07 + ["奥兹", "「喔唷」", "aiy350000110.opus"], //金锁高官11 + [ + "奥兹", + "「既然如此,我就不留您在这里喝难饮的劣质酒了」", + "aiy350000120.opus", + ], //金锁高官12 + ["", "奥兹斜眼看着正捂住额头呻吟的手下,轻描淡写地说道。"], + ["凯伊姆", "「用这些钱去买药」", "aiy310000080.opus"], //男主08 + ["", "我将几枚铜钱仍在那个手下的身前。"], + ["奥兹", "「凯伊姆先生,不用对他们这么好」", "aiy350000130.opus"], //金锁高官13 + ["凯伊姆", "「无妨」", "aiy310000090.opus"], //男主09 + ["凯伊姆", "「话说回来,那个要落跑的女人呢?」", "aiy310000100.opus"], //男主10 + [ + "奥兹", + "「我把她交给那些年轻人了,现在应该正在体会人生的严苛吧」", + "aiy350000140.opus", + ], //金锁高官14 + [ + "奥兹", + "「正好,趁此机会凯伊姆先生也来享受一番如何?」", + "aiy350000150.opus", + ], //金锁高官15 + ["年轻人", "「你,你们这些家伙,要对她做什么!?」", "aiy710000080.opus"], //龙套1-08 + ["", "咣!"], + ["", "奥兹给了他一拳。"], + ["", "一击即倒。"], + ["", "喀,咚,咯!"], + ["", "奥兹毫不留情地向男人的脸上踩去。"], + ["年轻人", "「咕······呃咳······」", "aiy710000090.opus"], //龙套1-09 + ["", "折断的牙齿伴着血泡被吐出。"], + ["", "这份白色在鲜红色的液体中格外显眼。"], + [ + "年轻人", + "「你们以为做出这种事······卫兵会坐视不理吗······」", + "aiy710000100.opus", + ], //龙套1-10 + ["奥兹", "「啊啊,不会坐视不理的」", "aiy350000160.opus"], //金锁高官16 + [ + "奥兹", + "「应该会拿出你的钱包,和我们商量如何瓜分吧」", + "aiy350000170.opus", + ], //金锁高官17 + ["年轻人", "「那,那种事······」", "aiy710000110.opus"], //龙套1-11 + ["", "这在牢狱是理所当然的事。"], + ["奥兹", "「怎么,头一回来牢狱么?」", "aiy350000180.opus"], //金锁高官18 + ["", "男人点了点头。"], + [ + "奥兹", + "「为了被骗的女人而来到牢狱,真是个规矩人啊」", + "aiy350000190.opus", + ], //金锁高官19 + ["奥兹", "「······前提是,被骗的人不是你」", "aiy350000200.opus"], //金锁高官20 + ["年轻人", "「你说······我被骗了?」", "aiy710000120.opus"], //龙套1-12 + ["年轻人", "「那,那是怎么回事!?」", "aiy710000130.opus"], //龙套1-13 + ["奥兹", "「不用急,今天晚上会好好告诉你的」", "aiy350000210.opus"], //金锁高官21 + ["", "奥兹抓起男人的脸。"], + ["", "为引诱客人的怜悯之心而装纯,是娼妇的惯用手段。"], + ["", "双亲被骗而借钱,结果作为抵押而将自己卖到这里,这是典型的说法。"], + [ + "", + "如果只是头脑发热而成为常客也就罢了,这次的男人热血过头,居然想出了要带女人私奔的计划。", + ], + [ + "", + "虽然女人半开玩笑地予以拒绝,但不知天高地厚的这家伙还是拉着她逃跑了。", + ], + ["", "不过,想要逃脱追击本来就是不可能的任务。"], + ["", "但即便如此,这种事情还是会一再的出现。"], + ["", "说谎的女人和被骗的男人。"], + ["", "在娼馆街,这是令人看到生厌的日常的风景。"], + ["凯伊姆", "「我要走了」", "aiy310000110.opus"], //男主11 + ["奥兹", "「好的,下次再麻烦您」", "aiy350000220.opus"], //金锁高官22 + ["奥兹", "「之后吉克先生会将谢礼交给您的」", "aiy350000230.opus"], //金锁高官23 + ["凯伊姆", "「啊啊」", "aiy310000120.opus"], //男主12 + ["", "我背向奥兹走出娼馆。"], + ["凯伊姆", "「······?」", "aiy310000130.opus"], //男主13 + ["", "从远方传来微弱的歌声。"], + ["", "是关卡广场的方向。"], + ["", "对了。"], + ["", "今天有觐见圣女的仪式。"], + ["", "当代的圣女伊莲——"], + ["", "俗称《盲眼之圣女》,据说即使在历代的圣女中,人气也是数一数二的。"], + ["", "广场上的人估计相当多吧。"], + ["", "虽然我也想去看看她长什么样,不过要在人潮中挤来挤去就免了。"], + ["", "还是老老实实去菲诺列塔喝烧酒吧。"], + ["", "正当我这样想着的时候,一个身影自小巷的那头走来。"], + ["凯伊姆", "「艾莉斯」", "aiy310000140.opus"], //男主14 + ]; + this.chapter01 = [ + ["艾莉斯", "「啊,凯伊姆」", "aiy020000005.opus"], //医生00.5 + ["艾莉斯", "「正好,我还想要去找你呢」", "aiy020000010.opus"], //医生01 + [ + "艾莉斯", + "「没想到凯伊姆会主动出现······这是命运吗?」", + "aiy020000020.opus", + ], //医生02 + ["凯伊姆", "「显然不是吧」", "aiy310000150.opus"], //男主15 + ["艾莉斯", "「啊,是么」", "aiy020000030.opus"], //医生03 + ["", "艾莉斯挑了挑整齐的双眉,微微地哼了一声。"], + [ + "", + "虽然是个相当引人注目的美人,但她这个将亲切儿子丢入无底深渊的性格,为自己扣了不少的分", + ], + ["", "给人印象最深的,就是那潭水般的双瞳。"], + ["", "在漆黑的瞳孔中,完全看不出感情的波动。"], + ["艾莉斯", "「喜欢我的眼睛吗?」", "aiy020000040.opus"], //医生04 + ["艾莉斯", "「如果想要的话就给你吧?」", "aiy020000050.opus"], //医生05 + ["凯伊姆", "「用不着」", "aiy310000160.opus"], //男主16 + ["艾莉斯", "「阿拉,可惜」", "aiy020000060.opus"], //医生06 + ["凯伊姆", "「那么,找我有什么事」", "aiy310000170.opus"], //男主17 + ["艾莉斯", "「梅尔特的钱好像被偷了」", "aiy020000070.opus"], //医生07 + ["凯伊姆", "「钱被偷了?都几岁了还这么没用」", "aiy310000180.opus"], //男主18 + ["艾莉斯", "「不要对我说啊」", "aiy020000080.opus"], //医生08 + [ + "凯伊姆", + "「那家伙,该不会说要让我去抓那个小偷吧?」", + "aiy310000190.opus", + ], //男主19 + ["艾莉斯", "「就是这样」", "aiy020000090.opus"], //医生09 + ["凯伊姆", "「笨蛋吗」", "aiy310000200.opus"], //男主20 + ["凯伊姆", "「如果是小钱的话,就当做是买个教训吧」", "aiy310000210.opus"], //男主21 + ["艾莉斯", "「说起来,被盗的是这个月的上纳金」", "aiy020000100.opus"], //医生10 + ["凯伊姆", "「你说什么?」", "aiy310000220.opus"], //男主22 + ["艾莉斯", "「用这些钱买教训,也太过奢侈了呢」", "aiy020000110.opus"], //医生11 + ["凯伊姆", "「知道了,我去找」", "aiy310000230.opus"], //男主23 + ["凯伊姆", "「小偷的特征呢」", "aiy310000240.opus"], //男主24 + ["艾莉斯", "「男孩子」", "aiy020000120.opus"], //医生12 + ["艾莉斯", "「······而且,背后有翅膀」", "aiy020000130.opus"], //医生13 + [ + "艾莉斯", + "「虽然姑且是藏在身后,但是仔细观察的话是很明显的」", + "aiy020000140.opus", + ], //医生14 + ["凯伊姆", "「羽化病吗」", "aiy310000250.opus"], //男主25 + [ + "艾莉斯", + "「那些人可是毫不留情的,所以即使是为了那个孩子,也要赶快抓到他」", + "aiy020000150.opus", + ], //医生15 + ["凯伊姆", "「注意到他逃窜的方向了吗?」", "aiy310000260.opus"], //男主26 + ["艾莉斯", "「广场那边」", "aiy020000160.opus"], //医生16 + [ + "艾莉斯", + "「虽然刚才《不蚀金锁》的人去追了,不过多半是······」", + "aiy020000170.opus", + ], //医生17 + ["凯伊姆", "「偏偏还是广场吗」", "aiy310000280.opus"], //男主28 + ["艾莉斯", "「今天是觐见圣女大人的日子」", "aiy020000180.opus"], //医生18 + ["凯伊姆", "「我知道」", "aiy310000290.opus"], //男主29 + ["凯伊姆", "「尽量找找看就好」", "aiy310000300.opus"], //男主30 + ]; + this.chapter02 = [ + ["不蚀金锁成员", "「凯伊姆先生,凯伊姆先生」", "aiy860000010.ogg"], + [ + "不蚀金锁成员", + "「您已经和艾莉斯大夫见过面了吗?」", + "aiy860000020.ogg", + ], + ["凯伊姆", "「啊啊,所以才会追过来的」", "aiy310000310.ogg"], //男主31 + ["凯伊姆", "「看到小偷了吗?」", "aiy310000320.ogg"], //男主32 + [ + "不蚀金锁成员", + "「没有,他向广场那边逃了过去,今天这么拥挤,我们也只能放弃了」", + "aiy860000030.ogg", + ], + [ + "不蚀金锁成员", + "「不过,我也只是刚好在店里所以才追了过去,并不是受人所托」", + "aiy860000040.ogg", + ], + ["不蚀金锁成员", "「我已经准备撤退了」", "aiy860000050.ogg"], + ["不蚀金锁成员", "「凯伊姆先生还要继续追吗?」", "aiy860000060.ogg"], + ["凯伊姆", "「啊啊」", "aiy310000330.ogg"], //男主33 + ["", "做完情报交换之后,我跟男人道别。"], + ["凯伊姆", "「和我想的一样啊······」", "aiy310000340.ogg"], //男主34 + ["", "在牢狱中最大的广场上,聚集着看不到尽头的人群。"], + ["", "就算是来参见圣女祈祷,这人数也太多了点吧。"], + ["", "自然,我也找不到逃跑的孩子。"], + ["", "是混杂到人群中了吧。"], + ["", "如果已经从广场上脱身了的话,就更难发现了。"], + ["", "只好赌他还在这里了。"], + ["", "我先移动到了一个视野良好的地方。"], + ["", "从这里,一眼就可以看到人群的变化。"], + ["", "广场还是沸腾起来。"], + ["", "抬头望去,原来是在天台之上出现了一个人影"], + ["", "但是,与周围的期待不同,现身的是一名中年的神官。"], + ["", "骂声四溢。"], + ["", "神官则是笑着摆正衣领"], + ["神官", "「从现在开始,举行谒见的仪式」", "aiy440000010.ogg"], //神官01 + [ + "神官", + "「在参见那位大人之前,我希望牢狱的诸位再次思考这个《诺瓦斯·艾蒂尔》存在的意义······」", + "aiy440000020.ogg", + ], //神官02 + [ + "神官", + "「初代圣女伊莲大人,便是也难怪这崇高的祈祷之力,令《诺瓦斯·艾蒂尔》浮在空中,拯救了我们的祖先」", + "aiy440000030.ogg", + ], //神官03 + [ + "神官", + "「这之后的几百年来,传承了初代大人力量的历代圣女伊莲大人,让这里留在了空中」", + "aiy440000040.ogg", + ], //神官04 + [ + "神官", + "「这座都市是被圣女大人守护的人类最后的圣域,而我们则是被选召的虔诚的信徒」", + "aiy440000050.ogg", + ], //神官05 + [ + "神官", + "「怀着对圣女的感激祈祷吧,感谢圣女伊莲吧!并献上祈祷!」", + "aiy440000060.ogg", + ], //神官06 + ["圣女", "「不忘感谢与祈祷,神才会拯救我们」", "aiy030000010.ogg"], //圣女01 + ["圣女", "「与我一起,向神虔诚地祈祷吧」", "aiy030000020.ogg"], //圣女02 + ["", "广场上欢声雷动。"], + ["", "圣女没有回应喧嚣的人声,而是静静地合上双眼面向广场。"], + ["", "虽然感觉有些冷淡,但总比像个傻瓜似的笑着向这群人挥手要强。"], + ["", "她掌握着这条街道,还有在这条街上生活的人的命运。"], + ["", "比起揽得人气,她更想要为了街道的继续存在而献出全力。"], + ["", "也是为了不让《大崩落》的惨剧再度发生。"], + ["", "十几年前的那场悲剧。"], + [ + "", + "虽然在我脑海中的记忆已经相当模糊,但哪怕只是稍有触及,不快的感觉都会在胸口蔓延开。", + ], + ["凯伊姆", "「······」", "aiy310000350.ogg"], //男主35 + ["", "这时我才想起,现在不是我在这里看圣女的时候。"], + ["女声", "「——っ!?」", "aiy510000010.ogg"], + ["围观的女人", "「羽,羽化病人!?」", "aiy510000020.ogg"], + ["围观的中年人", "「喂,谁去叫下羽狩」", "aiy720000010.ogg"], + [ + "惊慌的观众", + "「你这家伙不要靠近我,要是传染了可怎么办」", + "aiy730000010.ogg", + ], + ["粗鲁的观众", "「你这小鬼赶快滚开」", "aiy740000010.ogg"], + ["凯伊姆", "「接下来」", "aiy310000360.ogg"], //男主36 + ["圣女", "「发生什么事了?看上去似乎很嘈杂」", "aiy030000030.ogg"], //圣女03 + [ + "随从", + "「似乎是某个人逃跑了······具体的我也不是很清楚」", + "aiy130000010.ogg", + ], //侍从01 + [ + "神官", + "「圣女大人,继续待在天台上可能会出事,请您先回到室内吧」", + "aiy440000070.ogg", + ], //神官07 + [ + "圣女", + "「不用在意我,比起那个,我更关心究竟发生了什么事」", + "aiy030000050.ogg", + ], //圣女05 + ["神官", "「对不起,我真的不知道」", "aiy440000080.ogg"], //神官08 + ["圣女", "「······是吗」", "aiy030000060.ogg"], //圣女06 + ["男", "「恕我僭越,请准许我说明情况」", "aiy320000010.ogg"], //男主他哥01 + ["男", "「在来觐见的人群中出现了《羽化病》的患者」", "aiy320000020.ogg"], //男主他哥02 + ["男", "「围观的人群因而产生了骚动」", "aiy320000030.ogg"], //男主他哥03 + [ + "男", + "「现在,《防疫局》已经派遣了部队。我想不久之后,他们就会安静下来了」", + "aiy320000040.ogg", + ], //男主他哥04 + ["圣女", "「羽化病······」", "aiy030000070.ogg"], //圣女07 + ["男", "「怎么了?」", "aiy320000050.ogg"], //男主他哥05 + ["圣女", "「没什么」", "aiy030000080.ogg"], //圣女08 + ["圣女", "「辛苦了,你的名字是?」", "aiy030000090.ogg"], //圣女09 + [ + "男", + "「属下是在防疫局任职的,鲁基乌斯· 迪斯·米利尤」", + "aiy320000060.ogg", + ], //男主他哥06 + [ + "神官", + "「噢噢,阁下就是鲁基乌斯卿吗,我听说过你的传闻」", + "aiy440000090.ogg", + ], //神官09 + ["神官", "「阁下是在工作上相当出色的人呢」", "aiy440000100.ogg"], //神官10 + ["鲁基乌斯", "「不敢当」", "aiy320000070.ogg"], //男主他哥07 + [ + "鲁基乌斯", + "「话说回来,这次是属下警备工作的失职。让圣女大人见到这不成体统的一面,请您见谅」", + "aiy320000080.ogg", + ], //男主他哥08 + [ + "圣女", + "「即使是目不见物的我,也能感受到聚集于此的民众数量之多。警备工作难以展开也在情理之中」", + "aiy030000100.ogg", + ], //圣女10 + ["鲁基乌斯", "「属下不胜惶恐」", "aiy320000090.ogg"], //男主他哥09 + [ + "鲁基乌斯", + "「接下来属下还要回到工作岗位上,在这里就先告退了」", + "aiy320000100.ogg", + ], //男主他哥10 + ["圣女", "「鲁基乌斯先生」", "aiy030000110.ogg"], //圣女11 + ["鲁基乌斯", "「属下在」", "aiy320000110.ogg"], //男主他哥11 + ["圣女", "「你是怎样看待羽狩的工作的呢?」", "aiy030000120.ogg"], //圣女12 + ["神官", "「圣,圣女大人」", "aiy440000110.ogg"], //神官11 + [ + "鲁基乌斯", + "「防疫局的工作是国王陛下赐予的重要职务。属下非常荣幸能够为这个都市的繁荣尽一份微薄之力」", + "aiy320000120.ogg", + ], //男主他哥12 + ["神官", "「不,不亏是鲁基乌斯卿,相当优秀的想法」", "aiy440000120.ogg"], //神官12 + ["圣女", "「是吗。辛苦你了」", "aiy030000130.ogg"], //圣女13 + ["随从", "「圣女大人······」", "aiy130000020.ogg"], //侍从02 + ["鲁基乌斯", "「······」", "aiy320000135.ogg"], //男主他哥13 + ["鲁基乌斯", "「那么,属下就回岗位去了」", "aiy320000140.ogg"], //男主他哥14 + ]; + this.chapter03 = [ + ["", "从羽化病的少年纷乱的足音中,可以听得出相当的疲劳。"], + ["", "显然,他并没有想到我会捷足先登吧。"], + ["", "少年惶恐地回头看了一眼后,微微露出安心的表情,双手拄在膝盖上。。"], + ["凯伊姆", "「辛苦你了」", "aiy310000370.ogg"], //男主37 + ["羽化病患少年", "「稀!?」", "aiy750000010.ogg"], + ["凯伊姆", "「逃到贫民区是个不错的想法」", "aiy310000380.ogg"], //男主38 + ["羽化病患少年", "「你,你是,羽狩吗?」", "aiy750000020.ogg"], + ["凯伊姆", "「不是」", "aiy310000390.ogg"], //男主39 + [ + "羽化病患少年", + "「什,什么啊······混蛋,不要吓我啊」", + "aiy750000030.ogg", + ], + ["凯伊姆", "「我对令你受惊这件事致以歉意」", "aiy310000400.ogg"], //男主40 + ["凯伊姆", "「作为回报,麻烦你把从店里偷的钱交出来吧」", "aiy310000410.ogg"], //男主41 + ["羽化病患少年", "「钱?你在说什么」", "aiy750000040.ogg"], + ["凯伊姆", "「你要找的腰上的东西,掉在你身后了」", "aiy310000420.ogg"], //男主42 + ["羽化病患少年", "「哎?」", "aiy750000050.ogg"], + ["羽化病患少年", "「呃呀」", "aiy750000060.ogg"], + ["羽化病患少年", "「你······你这混蛋」", "aiy750000070.ogg"], + ["凯伊姆", "「······」", "aiy310000430.ogg"], //男主43 + ["凯伊姆", "「把偷的钱交出来」", "aiy310000440.ogg"], //男主44 + ["羽化病患少年", "「我不知道你在······咕」", "aiy750000080.ogg"], + [ + "羽化病患少年", + "「你,你说是我偷的······有什么证据吗」", + "aiy750000090.ogg", + ], + ["凯伊姆", "「你还挺倔的啊」", "aiy310000450.ogg"], //男主45 + ["凯伊姆", "「不过,给我听好了」", "aiy310000460.ogg"], //男主46 + ["凯伊姆", "「你偷的那些钱,是要上缴给《不蚀金锁》的上纳金」", "aiy310000470.ogg"], //男主47 + ["凯伊姆", "「而且,钱的主人是从前和吉克颇有渊源的女人」", "aiy310000480.ogg"], //男主48 + ["羽化病患少年", "「吉克?」", "aiy750000100.ogg"], + ["凯伊姆", "「他是《不蚀金锁》的主人,这么说你就明白了吧」", "aiy310000490.ogg"], //男主49 + ["羽化病患少年", "「哎?哎?怎么会······」", "aiy750000110.ogg"], + ["凯伊姆", "「再问你一遍,钱在哪里?」", "aiy310000510.ogg"], //男主51 + ["羽化病患少年", "「是,是,是,在我的怀里」", "aiy750000120.ogg"], + ["凯伊姆", "「你没有擅自拿掉一部分吧」", "aiy310000520.ogg"], //男主52 + ["羽化病患少年", "「是,是的」", "aiy7500000130.ogg"], + [ + "羽化病患少年", + "「那,那个,您是《不蚀金锁》的人吗?」", + "aiy750000140.ogg", + ], + ["凯伊姆", "「算是吧」", "aiy310000530.ogg"], //男主53 + [ + "羽化病患少年", + "「我什么都可以做,请您一定要帮帮我」", + "aiy750000150.ogg", + ], + ["凯伊姆", "「抱歉,我并没有兴趣去帮助他人」", "aiy310000540.ogg"], //男主54 + [ + "羽化病患少年", + "「我什么······什么,都会做的······」", + "aiy750000160.ogg", + ], + ["羽化病患少年", "「我一直都是生活在下层的」", "aiy750000170.ogg"], + [ + "羽化病患少年", + "「可是,不知何时染上了羽化病······背后长出了翅膀······」", + "aiy750000180.ogg", + ], + [ + "羽化病患少年", + "「被寄宿工作的店赶了出来,只得流落到牢狱这里」", + "aiy750000190.ogg", + ], + [ + "羽化病患少年", + "「因为独自实在是饿的不行了,所以才会偷这些钱的」", + "aiy750000200.ogg", + ], + [ + "羽化病患少年", + "「我明明没有做任何坏事······为什么······会遇到这种事······」", + "aiy750000210.ogg", + ], + ["凯伊姆", "「谁知道」", "aiy310000550.ogg"], //男主55 + [ + "羽化病患少年", + "「呜······呜呜······接下来,要对我做什么?」", + "aiy750000220.ogg", + ], + ["凯伊姆", "「我要把你带到组织那里」", "aiy310000560.ogg"], //男主56 + ["羽化病患少年", "「怎,怎么这样」", "aiy750000230.ogg"], + ["凯伊姆", "「不过,那样做的前提是你不是羽化病人」", "aiy310000570.ogg"], //男主57 + ["凯伊姆", "「组织也没有笨到把羽化病人招待到家里的程度」", "aiy310000580.ogg"], //男主58 + ["羽化病患少年", "「那么,是要放我逃走吗?」", "aiy750000240.ogg"], + ["凯伊姆", "「我要让你学到教训」", "aiy310000590.ogg"], //男主59 + ["凯伊姆", "「如果换做是组织的制裁,至少要有断条胳膊的觉悟」", "aiy310000600.ogg"], //男主60 + ["凯伊姆", "「你的运气不错」", "aiy310000610.ogg"], //男主61 + ["羽化病患少年", "「唔······啊,是的······」", "aiy750000250.ogg"], + ["凯伊姆", "「滚」", "aiy310000620.ogg"], //男主62 + ["羽化病患少年", "「非常感谢」", "aiy750000260.ogg"], + ["羽化病患少年", "「唔啊!?」", "aiy750000270.ogg"], + ["男", "「到这里就结束了,羽化病人」", "aiy430000010.ogg"], //兰格01 + ["男", "「确认他的翅膀」", "aiy430000020.ogg"], //兰格02 + ["", "趁还没有被卷入麻烦的事情之前,赶快离开这里吧"], + ["羽狩的指挥者", "「那边的那个人」", "aiy430000030.ogg"], //兰格03 + ["凯伊姆", "「······有什么事?」", "aiy310000630.ogg"], //男主63 + ["羽狩的指挥者", "「可以稍微让我问几句话吗」", "aiy430000040.ogg"], //兰格04 + ["凯伊姆", "「······」", "aiy310000640.ogg"], //男主64 + ["凯伊姆", "「啊啊,无妨」", "aiy310000650.ogg"], //男主65 + ["羽狩的指挥者", "「感谢您的合作」", "aiy430000050.ogg"], //兰格05 + ["", "队长殷勤地致以谢礼。"], + ["", "而在他的眼前,少年的衣服已经被他的补下们扯破。"], + ["", "在瘦骨嶙峋的裸露后背上,长有纯白的羽翼。"], + ["红发的羽狩", "「副队长,确认翅膀的持有了」"], + ["羽狩的副队长", "「保护他」", "aiy430000060.ogg"], //兰格06 + ["羽化病患少年", "「不要······请原谅,我······」", "aiy750000280.ogg"], + [ + "羽狩的副队长", + "「我们只是要带你去治愈院治疗羽化病,不是什么应该感到害怕的事情」", + "aiy430000070.ogg", + ], //兰格07 + ["羽化病患少年", "「可是,可是」", "aiy750000290.ogg"], + ["羽狩的副队长", "「没关系的」", "aiy430000080.ogg"], //兰格08 + ["羽化病患少年", "「······哥,哥哥」", "aiy750000300.ogg"], + ["羽狩的副队长", "「你是羽化病人的亲属吗?」", "aiy430000090.ogg"], //兰格09 + ["凯伊姆", "「只是路人而已」", "aiy310000660.ogg"], //男主66 + ["凯伊姆", "「顺带一提,我也没有打算找你们的麻烦」", "aiy310000670.ogg"], //男主67 + [ + "羽狩的副队长", + "「前几天,有个和你说了同样的话的人,在我们背向他的瞬间对我们发动了袭击」", + "aiy430000100.ogg", + ], //兰格10 + ["羽狩的副队长", "「我的一个部下就此永久失去了半截胳膊」", "aiy430000110.ogg"], //兰格11 + ["凯伊姆", "「我表示同情」", "aiy310000680.ogg"], //男主68 + ["凯伊姆", "「我马上就会消失的,这样就没问题了吧?」", "aiy310000690.ogg"], //男主69 + ["羽狩的副队长", "「嘛,不要这么慌张」", "aiy430000120.ogg"], //兰格12 + ["", "副队长看着羽化的少年。"], + ["羽狩的副队长", "「你与这个人是什么关系?没有被他殴打吗?」", "aiy430000130.ogg"], //兰格13 + ["羽化病患少年", "「没,没有」", "aiy750000310.ogg"], + [ + "羽狩的副队长", + "「如何对我们保持合作,你就可以在治愈院得到优先的治疗」", + "aiy430000140.ogg", + ], //兰格14 + ["羽化病患少年", "「······」", "aiy750000320.ogg"], + [ + "羽化病患少年", + "「那个人,是《不蚀金锁》的组织成员······」", + "aiy750000330.ogg", + ], + [ + "羽化病患少年", + "「突然说让我拿出钱来,我刚一拒绝他就打我」", + "aiy750000340.ogg", + ], + ["羽狩的副队长", "「原来如此······」", "aiy430000150.ogg"], //兰格15 + [ + "羽狩的副队长", + "「那位少年说你是《不蚀金锁》的一员,不知此事是否属实?」", + "aiy430000160.ogg", + ], //兰格16 + ["凯伊姆", "「当然不是」", "aiy310000700.ogg"], //男主70 + ["凯伊姆", "「我只是从那里接受工作而已,并不是他们的成员」", "aiy310000710.ogg"], //男主71 + ["羽狩的副队长", "「你的意思是说,少年在说谎吗?」", "aiy430000170.ogg"], //兰格17 + ["凯伊姆", "「啊啊」", "aiy310000720.ogg"], //男主72 + [ + "凯伊姆", + "「如果你们和组织有关系的话,只要问问我是不是那里的成员就能明白事实了吧」", + "aiy310000730.ogg", + ], //男主73 + ["羽狩的副队长", "「就算我去询问,也无法从他们那里得到事实」", "aiy430000180.ogg"], //兰格18 + [ + "羽狩的副队长", + "「《不蚀金锁》的那些人一向都不对我们合作,我对此深感困扰」", + "aiy430000190.ogg", + ], //兰格19 + ["凯伊姆", "「真是辛苦啊」", "aiy310000740.ogg"], //男主74 + ["羽狩的副队长", "「说的是啊」", "aiy430000200.ogg"], //兰格20 + ["羽狩的副队长", "「其实,砍下我部下胳膊的似乎也是组织的成员呢」", "aiy430000210.ogg"], //兰格21 + [ + "羽狩的副队长", + "「无需如此警戒,我只是想在看守所向你咨询一些事情而已」", + "aiy430000220.ogg", + ], //兰格22 + [ + "羽狩的副队长", + "「如果能够知晓牢狱与组织的事情,我们也可以尽可能地对更多的羽化病人进行保护」", + "aiy430000230.ogg", + ], //兰格23 + ["羽狩的副队长", "「那和整条街道的和平也是紧密相关的吧?」", "aiy430000240.ogg"], //兰格24 + ["凯伊姆", "「我知道,你们有逮捕干扰狩猎羽化病人的权力」", "aiy310000750.ogg"], //男主75 + [ + "凯伊姆", + "「但是,我没有对你们做出任何干扰,为什么要对我如此纠缠不休呢」", + "aiy310000760.ogg", + ], //男主76 + ["羽狩的副队长", "「那些话,我们会在看守所对你详细说明的」", "aiy430000250.ogg"], //兰格25 + ["凯伊姆", "「······」", "aiy310000770.ogg"], //男主77 + ["", "在这里起争执的话,就会被羽狩加害。"], + ["", "就算能从这里脱身,今后只要碰面就会产生纠纷也是摆明的事情。"], + ["", "就算逃跑,也没有好的结果。"], + ["", "正当我想要打圆场的时候,刚才的气氛一瞬间产生了转变。"], + ["", "发生了什么事······"], + ["???", "「我认为,那位先生是正确的」", "aiy050000010.ogg"], //菲奥奈01 + ["", "羽狩们一起回头。"], + ["", "而在他们视线的焦点处,"], + ["", "伫立着一位女性。"], + ["", "在端正的容颜下,代表着强烈意志的双眉十分显眼。"], + ["", "身体的柔软与紧紧包裹在其身上的羽狩制服,两者显得十分的不搭配。"], + ["", "我还是第一次看到女性的羽狩。"], + ["羽狩的副队长", "「队长,这是获得《不蚀金锁》情报的好机会」", "aiy430000260.ogg"], //兰格26 + [ + "羽狩的队长", + "「兰格副队长,就算是为了获得情报,也不能做出恫吓的发言啊」", + "aiy050000020.ogg", + ], //菲奥奈02 + ["兰格副队长", "「我并没有打算去恫吓他······」", "aiy430000270.ogg"], //兰格27 + ["羽狩的队长", "「告诉我那个被砍掉胳膊的队员的名字」", "aiy050000030.ogg"], //菲奥奈03 + ["羽狩的队长", "「我会去探望他的」", "aiy050000040.ogg"], //菲奥奈04 + ["兰格副队长", "「那个是······」", "aiy430000280.ogg"], //兰格28 + ["羽狩的队长", "「我知道,你一直在为有所收获而努力工作」", "aiy050000050.ogg"], //菲奥奈05 + ["羽狩的队长", "「但是,正因为我们的工作是为民众提供帮助」", "aiy050000060.ogg"], //菲奥奈06 + ["羽狩的队长", "「所以就更不能损害人与人之间的信赖」", "aiy050000070.ogg"], //菲奥奈07 + ["兰格副队长", "「我会铭记在心」", "aiy430000290.ogg"], //兰格29 + ["羽狩的队长", "「这位先生,我的部下失礼了」", "aiy050000080.ogg"], //菲奥奈08 + ["凯伊姆", "「只要不对我再来一次就好」", "aiy310000780.ogg"], //男主78 + ["羽狩的队长", "「请稍等」", "aiy050000090.ogg"], //菲奥奈09 + ["凯伊姆", "「有什么事?」", "aiy310000790.ogg"], //男主79 + ["羽狩的队长", "「我想确认一件事」", "aiy050000100.ogg"], //菲奥奈10 + ["羽狩的队长", "「你真的不是《不蚀金锁》的成员吗?」", "aiy050000110.ogg"], //菲奥奈11 + ["凯伊姆", "「真的」", "aiy310000800.ogg"], //男主80 + ["凯伊姆", "「如果我说是的话,你有什么打算?」", "aiy310000810.ogg"], //男主81 + ["羽狩的队长", "「我听过传闻,说他们是用依靠暴力而得的钱在生活」", "aiy050000120.ogg"], //菲奥奈12 + ["凯伊姆", "「······这样啊」", "aiy310000820.ogg"], //男主82 + ["凯伊姆", "「如果能有收获就好了啊」", "aiy310000830.ogg"], //男主83 + ]; + this.chapter04 = [ + ["梅尔特", "「欢迎光临」", "aiy120000020.ogg"], //老板娘01,文件序号是以2开始,后续全部加1 + ["梅尔特", "「辛苦了」", "aiy120000030.ogg"], //老板娘02 + ["梅尔特", "「抱歉,又拜托给你了个这么麻烦的工作」", "aiy120000040.ogg"], //老板娘03 + ["凯伊姆", "「没什么,比想象中完成的更容易」", "aiy310000840.ogg"], //男主84 + ["梅尔特", "「那就好」", "aiy120000050.ogg"], //老板娘04 + ["梅尔特", "「这是我的一点谢意」", "aiy120000060.ogg"], //老板娘05 + ["凯伊姆", "「味道有些变化啊」", "aiy310000850.ogg"], //男主85 + ["梅尔特", "「啊,被发现了?」", "aiy120000070.ogg"], //老板娘06 + ["梅尔特", "「最近,没能到手什么好的原料呢」", "aiy120000080.ogg"], //老板娘07 + ["凯伊姆", "「去拜托吉克如何?」", "aiy310000860.ogg"], //男主86 + [ + "梅尔特", + "「话是这么说,但是总不能用店里采购的这种小事去麻烦他吧······」", + "aiy120000090.ogg" + ], //老板娘08 + ["凯伊姆", "「那希望你也不要来麻烦我」", "aiy310000870.ogg"], //男主87 + ["梅尔特", "「那 是 两 码 事」", "aiy120000100.ogg"], //老板娘09 + ["梅尔特", "「再说,凯伊姆是靠着工作来生活的吧」", "aiy120000110.ogg"], //老板娘10 + [ + "梅尔特", + "「而且,自己的钱被偷了这么害羞的事,向凯伊姆以外的其他人都说不出口」", + "aiy120000120.ogg" + ], //老板娘11 + ["凯伊姆", "「反正,也已经传到吉克的耳朵里了」", "aiy310000880.ogg"], //男主88 + ["梅尔特", "「这是面子问题啊,面子问题」", "aiy120000130.ogg"], //老板娘12 + ["凯伊姆", "「嘛,算了」", "aiy310000890.ogg"], //男主89 + ["凯伊姆", "「这样就好了吧?」", "aiy310000900.ogg"], //男主90 + ["梅尔特", "「这是钱包呢」", "aiy120000140.ogg"], //老板娘13 + ["梅尔特", "「嗯,东西没少」", "aiy120000150.ogg"], //老板娘14 + ["梅尔特", "「太好啦—这个月的上纳金,我可全部都放在里面了呢」", "aiy120000160.ogg"], //老板娘15 + ["梅尔特", "「如果没有找到的话,说不定就又会被送到娼馆里了呢」", "aiy120000170.ogg"], //老板娘16 + ["凯伊姆", "「在那边不是来钱更快吗?」", "aiy310000910.ogg"], //男主91 + ["梅尔特", "「阿拉,你是在说我还能有魅力吗?」", "aiy120000180.ogg"], //老板娘17 + ["凯伊姆", "「这是客套话而已」", "aiy310000920.ogg"], //男主92 + ["梅尔特", "「欺负人」", "aiy120000190.ogg"], //老板娘18 + ["梅尔特", "「总而言之,今天帮大忙了」", "aiy120000200.ogg"], //老板娘19 + ["梅尔特", "「谢礼嘛······」", "aiy120000210.ogg"], //老板娘20 + ["凯伊姆", "「就记在账单上吧」", "aiy310000930.ogg"], //男主93 + ["梅尔特", "「了解—盛谢惠顾了哦?」", "aiy120000220.ogg"], //老板娘21 + ["", "喀啷喀啷"], + ["", "门铃响起"], + ["", "喧哗瞬间安静下来。"], + ["", "进来的人是吉克。"], + ["", "是掌控着牢狱的组织之一,《不蚀金锁》的头目。"], + ["", "不仅组织的成员,就连店内一般的客人也对他以注目礼表示敬意。"], + ["吉克", "「各位继续吧」", "aiy340000010.ogg"], //吉克01 + ["", "仿佛停滞的时钟重新转动了一般,店内恢复了热闹的气氛。"], + ["吉克", "「抱歉,今天拜托你去做了无聊的工作」。", "aiy340000020.ogg"], //吉克02 + ["凯伊姆", "「不用介意」", "aiy310000940.ogg"], //男主94 + ["", "吉克轻轻点了点头,在我右边坐了下来"], + ["凯伊姆", "「逃跑的男人怎么样了?」", "aiy310000950.ogg"], //男主95 + ["吉克", "「嗯?已经不在这个世上了」。", "aiy340000030.ogg"], //吉克03 + ["吉克", "「有什么想要知道的事吗?」", "aiy340000040.ogg"], //吉克04 + ["凯伊姆", "「不,没什么」", "aiy310000960.ogg"], //男主96 + ["吉克", "「那个无聊的家伙,完全没有趣味呢」", "aiy340000050.ogg"], //吉克05 + ["吉克", "「真希望他也替我负责清扫的部下也考虑考虑」", "aiy340000060.ogg"], //吉克06 + ["凯伊姆", "「真是灾难啊」", "aiy310000970.ogg"], //男主97 + ["吉克", "「比起那个,我听说了哦。你去追羽化病人了啊」", "aiy340000070.ogg"], //吉克07 + ["凯伊姆", "「消息真灵通」", "aiy310000980.ogg"], //男主98 + ["吉克", "「梅尔特也注意点」", "aiy340000080.ogg"], //吉克08 + ["吉克", "「你丢钱已经不是一回两回了」", "aiy340000090.ogg"], //吉克09 + ["梅尔特", "「好的—我会注意的。」", "aiy120000230.ogg"], //老板娘22 + ["梅尔特", "「吉克还是平常的点单吧」", "aiy120000240.ogg"], //老板娘23 + ["梅尔特", "「凯伊姆要再来一杯吗?」", "aiy120000250.ogg"], //老板娘24 + ["", "我们用眼神点头示意后,梅尔特开始准备起酒来。"], + ["", "悠然地吐出眼圈后,吉克取出一个纸包放在柜台上。"], + ["吉克", "「这是抓捕逃跑男人的报酬」", "aiy340000100.ogg"], //吉克10 + ["凯伊姆", "「下次有什么事再告诉我」", "aiy310000990.ogg"], //男主99 + ["梅尔特", "「来,久等了」", "aiy120000260.ogg"], //老板娘25 + ["凯伊姆", "「话说回来梅尔特,为什么会被那种孩子偷到钱?」", "aiy310001000.ogg"], //男主100 + ["吉克", "「让我猜猜看」", "aiy340000110.ogg"], //吉克11 + ["吉克", "「是那个吧,看某个特立独行的男人入迷了,所以就有了空隙?」", "aiy340000120.ogg"], //吉克12 + ["梅尔特", "「可惜—」", "aiy120000270.ogg"], //老板娘26 + ["梅尔特", "「事实恰恰相反,是那家伙一直在纠缠我」", "aiy120000280.ogg"], //老板娘27 + ["凯伊姆", "「完全把你当成新进的女佣了么」", "aiy310001010.ogg"], //男主101 + ["梅尔特", "「我从前可是很有名的,不会被当成这种下人吧」", "aiy120000290.ogg"], //老板娘28 + ["梅尔特", "「······而且,我没法对对我这么钟情的人发火啊」", "aiy120000300.ogg"], //老板娘29 + ["凯伊姆&吉克", "「你傻啊」", "aiy310001027.ogg"], //男主102.7,吉克13.5 + ["梅尔特", "「异口同声呢,不亏是兄弟」", "aiy120000310.ogg"], //老板娘30 + ["凯伊姆", "「别用这种称呼,怪恶心的」", "aiy310001030.ogg"], //男主103 + ["吉克", "「说得没错」", "aiy340000140.ogg"], //吉克14 + ["吉克", "「······说起来······」", "aiy340000150.ogg"], //吉克15 + ["梅尔特", "「怎么了?」", "aiy120000320.ogg"], //老板娘31 + ["吉克", "「有件事我一直很在意,我和凯伊姆,哪个是哥哥啊?」", "aiy340000160.ogg"], //吉克16 + ["凯伊姆", "「你也说这么无聊的话题」", "aiy310001040.ogg"], //男主104 + ["吉克", "「不,这是很重要的事情」", "aiy340000170.ogg"], //吉克17 + ["吉克", "「梅尔特,事实是怎么样的?」", "aiy340000180.ogg"], //吉克18 + ["梅尔特", "「啊~是怎么样的呢~」", "aiy120000330.ogg"], //老板娘32 + ["梅尔特", "「我忘记了」", "aiy120000340.ogg"], //老板娘33 + ["吉克", "「骗人」", "aiy340000190.ogg"], //吉克19 + ["梅尔特", "「我说真的」", "aiy120000350.ogg"], //老板娘34 + ["梅尔特", "「嘛,如果想起来了的话,就算是卸载艺术上我也会公诸于众的」", "aiy120000360.ogg"], //老板娘35 + ["吉克", "「喔唷」", "aiy340000200.ogg"], //吉克20 + ["吉克", "「那么,我就不能比你先死了啊」", "aiy340000210.ogg"], //吉克21 + ["梅尔特", "「蒙你费心」", "aiy120000370.ogg"], //老板娘36 + ["梅尔特", "「顺带一提,有传言说吃过我们这里的料理后可以长生不老哦?」", "aiy120000380.ogg"], //老板娘37 + ["吉克", "「好,来两份炖菜,记得加腊肠」", "aiy340000220.ogg"], //吉克22 + ["梅尔特", "「多谢惠顾」", "aiy120000390.ogg"], //老板娘38 + ["", "微微一笑后,梅尔特去厨房传达点单。"], + ["凯伊姆", "「吉克······」", "aiy310001050.ogg"], //男主105 + ["吉克", "「啊,不好了」", "aiy340000230.ogg"], //吉克23 + ["凯伊姆", "「话题扯远了」", "aiy310001060.ogg"], //男主106 + ["梅尔特", "「什么话题来着?」", "aiy120000400.ogg"], //老板娘39 + ["凯伊姆", "「关于为什么你的钱会被偷这件事」", "aiy310001070.ogg"], //男主107 + ["凯伊姆", "「丢钱的时候以你来说,应该不会全无察觉吧?」", "aiy310001080.ogg"], //男主108 + ["梅尔特", "「算是吧,被偷的时候确实也想过要抓住他」", "aiy120000410.ogg"], //老板娘40 + ["梅尔特", "「但是,我注意到了那个孩子背后的鼓起呢」", "aiy120000420.ogg"], //老板娘41 + ["凯伊姆", "「所以就不由自主地放他逃跑了?」", "aiy310001090.ogg"], //男主109 + ["吉克", "「就算你想羽化病人施恩,也不会得到任何回报哦」", "aiy340000240.ogg"], //吉克24 + ["梅尔特", "「我知道」", "aiy120000430.ogg"], //老板娘42 + ["梅尔特", "「正因为知道,所以之后才会拜托凯伊姆去将钱取回的」", "aiy120000440.ogg"], //老板娘43 + ["梅尔特", "「可是,呢······」", "aiy120000450.ogg"], //老板娘44 + ["梅尔特", "「果然还是很矛盾呢」", "aiy120000460.ogg"], //老板娘45 + ["梅尔特", "「明明是自己放他逃跑的,之后又拜托别人去抓他」", "aiy120000470.ogg"], //老板娘46 + ["梅尔特", "「但是,在那一刹那······应该说是,突然露出了真心吧」", "aiy120000480.ogg"], //老板娘47 + ["梅尔特", "「真的,只是自我满足而已」", "aiy120000490.ogg"], //老板娘48 + ["凯伊姆", "「对于那个孩子来说不是很幸运么」", "aiy310001100.ogg"], //男主110 + ["凯伊姆", "「在被《不蚀金锁》抓到之前,就被羽狩保护了」", "aiy310001110.ogg"], //男主111 + ["凯伊姆", "「现在应该已经躺在治愈院的床上了」", "aiy310001120.ogg"], //男主112 + ["吉克", "「如果被我们抓到的话,嘛,至少也会断掉一根胳膊吧」", "aiy340000250.ogg"], //吉克25 + ["凯伊姆", "「比起失去胳膊,这不是个很好地结局吗」", "aiy310001130.ogg"], //男主113 + ["吉克", "「多亏梅尔特的一念之善,那个小子的胳膊被救下来了」", "aiy340000260.ogg"], //吉克26 + ["吉克", "「对我来说,不能去管教他稍微有点可惜就是了」", "aiy340000270.ogg"], //吉克27 + ["凯伊姆", "「我姑且是给了他两三拳」", "aiy310001140.ogg"], //男主114 + ["吉克", "「你这不是很善解人意么」", "aiy340000280.ogg"], //吉克28 + ["梅尔特", "「没有帮他的忙啊」", "aiy120000500.ogg"], //老板娘49 + ["凯伊姆", "「你给我用常识考虑考虑」", "aiy310001150.ogg"], //男主115 + ["梅尔特", "「本来,就算羽化病人不被羽狩带走而导致羽化病扩散,在牢狱里死亡的理由也要多少就有多少」", "aiy120000510.ogg"], //老板娘50 + ["梅尔特", "「没事到如今多一个病人,也不会有什么改变的吧」", "aiy120000520.ogg"], //老板娘51 + ["梅尔特", "「那么,那么些羽化病人为什么就不能和我们一起开心地生活呢」", "aiy120000530.ogg"], //老板娘52 + ["吉克", "「像梅尔特这样思考的人少之又少」", "aiy340000290.ogg"], //吉克29 + ["凯伊姆", "「就算早晚都会死去,为了今日的苟活而努力拼搏也是人之常情」", "aiy310001160.ogg"], //男主116 + ["梅尔特", "「我知道」", "aiy120000540.ogg"], //老板娘53 + ["梅尔特", "「别介意,我刚才只是顺口说说」", "aiy120000550.ogg"], //老板娘54 + ["", "喀啷喀啷"], + ["梅尔特", "「辛苦了,艾莉斯」", "aiy120000560.ogg"], //老板娘55 + ["艾莉斯", "「嗯」", "aiy020000190.ogg"], //医生19 + ["", "用不可爱的声音随口回应后,艾莉斯理所当然般地在我左边的座位坐下"], + ["", "梅尔特什么都没有问,就开始准备起茶来"], + ["梅尔特", "「多亏你去帮忙叫凯伊姆了呢」", "aiy120000570.ogg"], //老板娘56 + ["艾莉斯", "「不客气」", "aiy020000200.ogg"], //医生20 + ["艾莉斯", "「我从店里出去以后不久就看到他了,这是我们被命运之绳紧紧相连的证明呢」", "aiy020000210.ogg"], //医生21 + ["凯伊姆", "「那还真是糟糕」", "aiy310001170.ogg"], //男主117 + ["艾莉斯", "「用不着这么害羞的」", "aiy020000220.ogg"], //医生22 + ["凯伊姆", "「用茶堵上你的嘴吧」", "aiy310001180.ogg"], //男主118 + ["艾莉斯", "「好」", "aiy020000230.ogg"], //医生23 + ["梅尔特", "「司空见惯的风景呢」", "aiy120000580.ogg"], //老板娘57 + ["凯伊姆", "「你在那之后去做什么了?」", "aiy310001190.ogg"], //男主119 + ["艾莉斯", "「去莉莉乌姆照顾患病的女孩子了」", "aiy020000240.ogg"], //医生24 + ["艾莉斯", "「好像是毒品上瘾,费了很大劲才止住她的胡闹」", "aiy020000250.ogg"], //医生25 + ["艾莉斯", "「希望你能好好管理下自己店里的娼妇呢」", "aiy020000260.ogg"], //医生26 + ["吉克", "「抱歉啊」", "aiy340000300.ogg"], //吉克30 + ["吉克", "「为表歉意,就让我来给艾莉斯诊疗一下吧」", "aiy340000310.ogg"], //吉克31 + ["艾莉斯", "「去死吧」", "aiy020000270.ogg"], //医生27 + ["梅尔特", "「是什么药?」", "aiy120000590.ogg"], //老板娘58 + ["吉克", "「是最近上市的一种药」", "aiy340000320.ogg"], //吉克32 + ["吉克", "「虽然中毒的可能性很低,但只要中毒便会一发而不可收拾」", "aiy340000330.ogg"], //吉克33 + ["艾莉斯", "「知道了」", "aiy020000280.ogg"], //医生28 + ["吉克", "「虽然我也许没有时间去管教她,不过我还是会注意的」", "aiy340000340.ogg"], //吉克34 + ["艾莉斯", "「毒药的主人是吉克吗?」", "aiy020000290.ogg"], //医生29 + ["吉克", "「《不蚀金锁》不卖药,这是从先代定下的规矩」", "aiy340000350.ogg"], //吉克35 + ["艾莉斯", "「抱歉,开玩笑的」", "aiy020000300.ogg"], //医生30 + ["吉克", "「关于药的出处,这边也会调查的」", "aiy340000360.ogg"], //吉克36 + ["吉克", "「如果有什么传闻的话记得告诉我」", "aiy340000370.ogg"], //吉克37 + ["艾莉斯", "「知道了」", "aiy020000310.ogg"], //医生31 + ["艾莉斯", "「麻药中毒的人真麻烦呢,又不能完全治好」", "aiy020000320.ogg"], //医生32 + ["艾莉斯", "「既然要悄悄的打,那就也悄悄地去死不就好了」", "aiy020000330.ogg"], //医生33 + ["", "喀啷喀啷"], + ["奥兹", "「吉克大人,抱歉打扰你开心的时光」", "aiy350000240.ogg"], //金锁高官24 + ["吉克", "「怎么了」", "aiy340000380.ogg"], //吉克38 + ["奥兹", "「请将耳朵凑过来」", "aiy350000250.ogg"], //金锁高官25 + ["吉克", "「······知道了」", "aiy340000390.ogg"], //吉克39 + ["吉克", "「凯伊姆,一会到娼馆来一趟」", "aiy340000400.ogg"], //吉克40 + ["凯伊姆", "「啊啊」", "aiy310001200.ogg"], //男主120 + ["吉克", "「噢,我都给忘了」", "aiy340000410.ogg"], //吉克41 + ["吉克", "「让这里的大家都开心一下」", "aiy340000420.ogg"], //吉克42 + ["梅尔特", "「收到」", "aiy120000600.ogg"], //老板娘59 + ["吉克", "「我走了」", "aiy340000430.ogg"], //吉克43 + ["奥兹", "「好」", "aiy350000260.ogg"], //金锁高官26 + ["", "梆梆"], + ["梅尔特", "「大家静静,有个好消息」", "aiy120000610.ogg"], //老板娘60 + ["梅尔特", "「今天有个『大人物』要请客哦」", "aiy120000620.ogg"], //老板娘61 + ["艾莉斯", "「吉克还是一如既往的大方」", "aiy020000340.ogg"], //医生34 + ["梅尔特", "「果然,头目就应该像这样呢」", "aiy120000630.ogg"], //老板娘62 + ["凯伊姆", "「他的做法是继承先代的」", "aiy310001210.ogg"], //男主121 + ["梅尔特", "「又来了又来了」", "aiy120000640.ogg"], //老板娘63 + ["梅尔特", "「他想要赶上先代还早了十年呢」", "aiy120000650.ogg"], //老板娘64 + ["凯伊姆", "「有些太严厉了吧」", "aiy310001220.ogg"], //男主122 + ["艾莉斯", "「说起来,吉克有什么事」", "aiy020000350.ogg"], //医生35 + ["梅尔特", "「既然要叫上凯伊姆,再怎么说也不是什么小事吧?」", "aiy120000670.ogg"], //老板娘66 + ["凯伊姆", "「说的也是」", "aiy310001230.ogg"], //男主123 + ["艾莉斯", "「我期待看到你光荣负伤的样子」", "aiy020000360.ogg"], //医生36 + ["凯伊姆", "「不要为人的不幸祈求啊」", "aiy310001240.ogg"], //男主124 + ["梅尔特", "「来,喝完这杯就去加油工作吧」", "aiy120000680.ogg"], //老板娘67 + ["凯伊姆", "「啊啊」", "aiy310001250.ogg"], //男主125 + ["凯伊姆", "「我走了」", "aiy310001260.ogg"], //男主126 + ["艾莉斯", "「加油(受伤)吧」", "aiy020000370.ogg"], //医生37 + ["梅尔特", "「一路走好」", "aiy120000690.ogg"], //老板娘68 + ]; + this.chapter05 = [ + ["", "今晚的娼馆街比平常来得更加热闹"], + ["", "视线中可以看到很多生客。"], + ["莉莎", "「呀——!」", "aiy150000010.ogg"], //三小只C01 + ["莉莎", "「呐,凯伊姆凯伊姆凯伊姆」", "aiy150000020.ogg"], //三小只C02 + ["莉莎", "「我难道没有魅力吗?」", "aiy150000030.ogg"], //三小只C03 + ["凯伊姆", "「突然之间怎么了」", "aiy310001270.ogg"], //男主127 + ["莉莎", "「因为因为因为,明明这么热闹,却只有我没有接到客人」", "aiy150000040.ogg"], //三小只C04 + ["莉莎", "「亏我还对他们说,我会用超绝的技巧让他们舒服得如同化作夜明的流星般呢」", "aiy150000050.ogg"], //三小只C05 + ["凯伊姆", "「那个台词太糟糕了」", "aiy310001280.ogg"], //男主128 + ["莉莎", "「哎—什么啊,这可是我昨天花了一晚上考虑出来的呢」", "aiy150000060.ogg"], //三小只C06 + ["凯伊姆", "「去睡觉,不要用你那空空如也的脑袋去考虑这种无聊事」", "aiy310001290.ogg"], //男主129 + ["莉莎", "「好过分!?」", "aiy150000070.ogg"], //三小只C07 + ["凯伊姆", "「你看看周围,今天有很多新客人吧?」", "aiy310001300.ogg"], //男主130 + ["莉莎", "「嗯~~」", "aiy150000080.ogg"], //三小只C08 + ["莉莎", "「啊,你这么一说还真是」", "aiy150000090.ogg"], //三小只C09 + ["凯伊姆", "「他们心里都很紧张,不可能会被你这种强拉的手法钓上钩吧」", "aiy310001310.ogg"], //男主131 + ["莉莎", "「这样啊,是不想欲仙欲死吗?」", "aiy150000100.ogg"], //三小只C10 + ["凯伊姆", "「不,没有男人不会希望那样的」", "aiy310001320.ogg"], //男主132 + ["凯伊姆", "「不过,强来是不行的。去让他们被温柔地包容着化作流星吧」", "aiy310001330.ogg"], //男主133 + ["莉莎", "「原—来如此」", "aiy150000110.ogg"], //三小只C11 + ["莉莎", "「凯伊姆肯定很有娼妇的才能哦」", "aiy150000120.ogg"], //三小只C12 + ["凯伊姆", "「没有」", "aiy310001340.ogg"], //男主134 + ["凯伊姆", "「好了,你赶紧去赚钱吧」", "aiy310001350.ogg"], //男主135 + ["莉莎", "「收到—」", "aiy150000130.ogg"], //三小只C13 + ["", "莉莎精神满满地回答后,就啪嗒啪嗒地跑开了。"], + ["莉莎", "「呐—那边的大哥哥,和我一起化作星光吧—」", "aiy150000140.ogg"], //三小只C14 + ["", "这家伙"], + ["", "非要用这么麻烦的说法么。"], + ["", "咚"], + ["莉莎", "「呀」", "aiy150000150.ogg"], //三小只C15 + ["大胡子醉汉", "「好疼」", "aiy800000010.ogg"], + ["", "突然,莉莎与一个男人相撞。"], + ["", "虽然男人可以摆出派头,但从那虚浮的脚步可以看出他相当的醉意。"], + ["莉莎", "「好疼疼,对不起」", "aiy150000160.ogg"], //三小只C16 + ["大胡子醉汉", "「这不是道歉就能了事的事吧,大姐—」", "aiy800000020.ogg"], + ["大胡子醉汉", "「哟,穿得相当清凉啊,喂」", "aiy800000030.ogg"], + ["大肚子的醉汉", "「喂—怎么了?」", "aiy810000010.ogg"], + ["大胡子醉汉", "「这位小姐特意往我身上撞呢」", "aiy800000040.ogg"], + ["大肚子的醉汉", "「喂喂喂喂,你是要做什么」", "aiy810000020.ogg"], + ["莉莎", "「呜哎—所以我都说对不起了啊」", "aiy150000170.ogg"], //三小只C17 + ["莉莎", "「对,对了。作为冲撞的补偿,我会给您提供很好的服务的,怎么样?」", "aiy150000180.ogg"], //三小只C18 + ["大胡子醉汉", "「是免费的吧?」", "aiy800000050.ogg"], + ["莉莎", "「那个······这,这姑且也是工作······免费就太」", "aiy150000190.ogg"], //三小只C19 + ["大肚子的醉汉", "「真是的,娼妇就是这种人。钱,钱,钱,完全没有做人的诚意」", "aiy810000030.ogg"], + ["大胡子醉汉", "「好—你这家伙。我给你钱,你现在就在这里给我服务」", "aiy800000060.ogg"], + ["莉莎", "「这,这该怎么说呢,稍微有些过了吧,在这里做很害羞的」", "aiy150000200.ogg"], //三小只C20 + ["大胡子醉汉", "「你除了晃腰以外还有用得着脑子的地方吗?别说这种像个人说的话啊」", "aiy800000070.ogg"], + ["大肚子的醉汉", "「啊啊?这些钱不够吗?」", "aiy810000040.ogg"], + ["大胡子醉汉", "「来,赶快把脚张开让我O,你们最喜欢这种事了吧?」", "aiy800000080.ogg"], + ["莉莎", "「是,是认真的吗······这些人」", "aiy150000210.ogg"], //三小只C21 + ["大肚子的醉汉", "「赶快做」", "aiy810000050.ogg"], + ["莉莎", "「呃······」", "aiy150000220.ogg"], //三小只C22 + ["凯伊姆", "「喂」", "aiy310001360.ogg"], //男主136 + ["大肚子的醉汉", "「啊?」", "aiy810000060.ogg"], + ["凯伊姆", "「即便是娼妇,也有不能出售的东西」", "aiy310001370.ogg"], //男主137 + ["", "喀"], + ["", "我一拳击中男人被酒精染红的脸,"], + ["大胡子醉汉", "「咦」", "aiy800000090.ogg"], + ["", "嘎"], + ["", "再一拳击中另一个人的腹部。"], + ["大肚子的醉汉", "「咕······」", "aiy810000070.ogg"], + ["大胡子醉汉", "「唔······」", "aiy800000100.ogg"], + ["", "两人像两只毛虫般躺在地上蠕动着挣扎"], + ["", "一时半会应该起不来了吧"], + ["莉莎", "「凯伊姆先生,太迟了太迟了太迟了」", "aiy150000230.ogg"], //三小只C23 + ["凯伊姆", "「都是你闯出的祸吧」", "aiy310001380.ogg"], //男主138 + ["莉莎", "「话是,那么说,可是」", "aiy150000240.ogg"], //三小只C24 + ["凯伊姆", "「赶快回莉莉乌姆去」", "aiy310001390.ogg"], //男主139 + ["莉莎", "「唔,嗯。谢了,凯伊姆。再见」", "aiy150000250.ogg"], //三小只C25 + ["", "久留无用"], + ]; + this.chapter06 = [ + ["", "漂浮的紫烟与甜美香醇的空气。"], + + + ]; +}, + "动画及周期装备映射": function () { + // 在此增加新插件 + this.equip = { + //所有回合中的装备及速度 + sword1: { id: "sword1", speed: 10 }, + }; + this.heroanimate = { + //勇士武器对应的动画(key为主手武器ID,value为帧动画名) + sword1: "sword", + }; + this.enemyanimate = { + //怪物对应的动画(key为怪物ID,value为帧动画名) + bat: "sword", + }; + this.equipanimate = { + //勇士周期性装备对应的动画(key为装备Id,value为帧动画名) + shield0: "sword", + }; + }, + "勇士法抗乘算叠加": function () { + // 在此增加新插件 + items.prototype.compareEquipment = function ( + compareEquipId, + beComparedEquipId + ) { + var result = { value: {}, percentage: {} }; + var first = core.material.items[compareEquipId], + second = core.material.items[beComparedEquipId]; + for (var one in result) { + for (var name in core.status.hero) { + if (name === "mdef" && one === "percentage") { + var ans = 1; + if (first?.equip?.[one]?.[name]) + ans *= 1 - (first.equip[one][name] || 0) / 100; + + if (second?.equip?.[one]?.[name]) + ans /= 1 - (second.equip[one][name] || 0) / 100; + + if (ans != 1) result[one][name] = ans; + } else if (name === "mdef" && one === "value") { + var ans = 0; + if (first) ans -= ((first.equip || {})[one] || {})[name] || 0; + if (second) ans += ((second.equip || {})[one] || {})[name] || 0; + if (ans != 0) result[one][name] = ans; + } else { + if (typeof core.status.hero[name] == "number") { + var ans = 0; + if (first) ans += ((first.equip || {})[one] || {})[name] || 0; + if (second) ans -= ((second.equip || {})[one] || {})[name] || 0; + if (ans != 0) result[one][name] = ans; + } + } + } + } + return result; + }; + let a = 1; + items.prototype._loadEquipEffect = function (equipId, unloadEquipId) { + // 比较能力值 + var result = core.compareEquipment(equipId, unloadEquipId); + + for (var name in result.percentage) { + if (name === "mdef") { + a *= result.percentage[name]; + core.setBuff(name, 1 - a); + } else { + core.addBuff(name, result.percentage[name] / 100); + } + } + for (var name in result.value) + core.status.hero[name] += result.value[name]; + }; + }, + "手册(临时)": function () { // 在此增加新插件 - const animate2 = document.createElement("canvas"); //画布设置 - animate2.style.zIndex = 71; - animate2.id = "animate2"; - animate2.classList.add('gameCanvas', 'anti-aliasing') - animate2.style.display = "block" - animate2.width = 416 - animate2.height = 416 - animate2.style.width = core.__PIXELS__ * core.domStyle.scale + 'px' - animate2.style.height = core.__PIXELS__ * core.domStyle.scale + 'px' - main.dom.animate2 = animate2; - const anctx = animate2.getContext('2d') + ui.prototype._drawBook_drawContent = function (index, enemy, top, left) { + var width = core._PX_ - left; // 9 : 8 : 8 划分三列 + this._drawBook_drawRow1(index, enemy, top, left, width, top + 20); + this._drawBook_drawRow4(index, enemy, top, left, width, top + 38); + this._drawBook_drawRow2(index, enemy, top, left, width, top + 56); + this._drawBook_drawRow3(index, enemy, top, left, width, top + 74); + this._drawBook_drawRow5(index, enemy, top, left, width, top + 90); + } + ui.prototype._drawBook_drawRow4 = function (index, enemy, top, left, width, position) { + // 绘制第一行 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), + f13 = this._buildFont(13, false); + var col1 = left, + col2 = left + width * 9 / 25, + col3 = left + width * 17 / 25; + core.fillText('ui', core.getStatusLabel('speed'), col1, position, '#DDDDDD', f13); + core.fillText('ui', core.formatBigNumber(enemy.speed || 0), col1 + 30, position, null, b13); + core.fillText('ui', core.getStatusLabel('spell'), col2, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.spell || 0), col2 + 30, position, null, b13); + core.fillText('ui', core.getStatusLabel('mdef'), col3, position, null, f13); + core.fillText('ui', core.formatBigNumber(enemy.mdef || 0) + "%", col3 + 30, position, null, b13); + } + ui.prototype._drawBook_drawRow5 = function (index, enemy, top, left, width, position) { + // 绘制第一行 + core.setTextAlign('ui', 'left'); + var b13 = this._buildFont(13, true), + f13 = this._buildFont(13, false); + var col1 = left, + col2 = left + width * 13 / 25; - main.dom.gameDraw.appendChild(animate2); + core.fillText('ui', "勇士出手次数", col1, position, '#DDDDDD', f13); + core.fillText('ui', core.getDamageInfo(enemy, null) ? core.getDamageInfo(enemy, null).hero_turn : '???', col1 + 80, position, null, b13); + core.fillText('ui', "怪物出手次数", col2, position, null, f13); + core.fillText('ui', core.getDamageInfo(enemy, null) ? core.getDamageInfo(enemy, null).mon_turn : '???', col2 + 80, position, null, b13); - core.plugin.playing = new Set() + } + ui.prototype._drawBook_pageinfo = function () { + var per_page = 4; + var padding_top = 12; // 距离顶端像素 + var per_height = (core._PY_ - 32 - padding_top) / per_page; + return { per_page: per_page, padding_top: padding_top, per_height: per_height }; + } +}, + "新怪物手册": function () { + // 在此增加新插件 + const book = document.createElement("canvas"); //创建怪物手册画布 + book.style.position = "absolute"; + book.style.zIndex = 400; + book.style.display = "none"; + book.id = "book"; + main.dom.gameGroup.insertAdjacentElement("afterend", book); + book.style.top = "50%"; + book.style.left = "50%"; + book.style.transform = "translate(-50%,-50%)"; + const ctx = book.getContext("2d"); + main.dom.book = book - this.setanimate = function (name, - px, - py, - width, - height, - allFarme, - imageList, - soundList) { - const data = { - px: px, - py: py, - width: width, - height: height, - allFarme: allFarme, - imageList: imageList, - soundList: soundList + book.onclick = function (e) { //画布点击监听 + try { + e.preventDefault(); + const left = core.dom.gameGroup.offsetLeft; + const top = core.dom.gameGroup.offsetTop; + const px = Math.floor((e.clientX - left) / core.domStyle.scale), + py = Math.floor((e.clientY - top) / core.domStyle.scale); + + let x, y; + if (core.domStyle.isVertical) { //对竖屏进行坐标转换 + x = py * 3; + y = 1248 - px * 3; + } else { + x = px * 3; + y = py * 3; + } + bookclick(x, y) + } catch (ee) { + main.log(ee); } - core.setFlag("animate_" + name, data) - } - this.deleteanimate = function (name) { - core.setFlag("animate_" + name) + function bookclick(x, y) { //点击画布(x,y)触发的效果 + const makeBox = ([x, y], [w, h]) => { //创建点击检测区域 + return [ + [x, y], + [x + w, y + h], + ]; + }; + const pos = [x, y]; //创建点击坐标pos + const inRect = ([x, y], [ //检测点击坐标是否在检测区域中 + [sx, sy], + [dx, dy] + ]) => { + return sx <= x && x <= dx && sy <= y && y <= dy; + }; + /** + * 使用范例 + *const backbox = makeBox([15, 35], [210, 90]); + *if(inRect(pos,backbox)){} + */ } - let thistime = 0 - this.playanimate = function (name, x, y, hero, scalex, scaley) { - const data = { name: name, x: x, y: y, hero: hero, scalex: scalex, scaley: scaley, farme: 0 } - - core.plugin.playing.add(data) - - } - core.registerAnimationFrame("animateonmap", true, function (timestamp) { - if (timestamp - thistime > 1000 / 60) { - thistime = timestamp; - core.clearMap(anctx) - core.plugin.playing.forEach(one => { - const data = flags["animate_" + one.name] - if (!data) { - core.plugin.playing.delete(one) - } else { - data.imageList.forEach(function (image) { - if (one.farme >= (image.beforefarme ?? 0) && - one.farme <= (image.afterfarme ?? data.allFarme) - ) { - const img = core.material.images.images?.[image.image]; - if (img) { - const gla = image.globalAlpha ?? 100; - const agla = image.aglobalAlpha ?? gla, - beforefarme = image.beforefarme ?? 0; - const afterfarme = image.afterfarme ?? data.allFarme; - - anctx.globalAlpha = - (gla + - ((agla - gla) * (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1)) / - 100; - - const cx = - (image.cx ?? 0) + - (((image.acx ?? 0) - (image.cx ?? 0)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - cy = - (image.cy ?? 0) + - (((image.acy ?? 0) - (image.cy ?? 0)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - cw = - (image.cw ?? img.width) + - (((image.acw ?? img.width) - (image.cw ?? img.width)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - ch = - (image.ch ?? img.height) + - (((image.acw ?? img.height) - (image.cw ?? img.height)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - x = - (image.x ?? 0) + - (((image.ax ?? 0) - (image.x ?? 0)) * (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - y = - (image.y ?? 0) + - (((image.ay ?? 0) - (image.y ?? 0)) * (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - w = - (image.w ?? one.width) + - (((image.aw ?? one.width) - (image.w ?? one.width)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - h = - (image.h ?? one.height) + - (((image.aw ?? one.height) - (image.w ?? one.height)) * - (one.farme - beforefarme)) / - (afterfarme - beforefarme || 1), - angle = (Math.PI * (image.angel ?? 0) / 180) + ((Math.PI * (image.aangel ?? 0) / 180) - ((Math.PI * (image.angel ?? 0) / 180)) * (one.farme - beforefarme)) / (afterfarme - beforefarme || 1); - if (one.hero) { - let sx, sy; - if (core.status.heroMoving < 0) { sx = 0; - sy = 0 } else { - sx = core.utils.scan[core.status.hero.loc.direction].x * 4 * core.status.heroMoving - sy = core.utils.scan[core.status.hero.loc.direction].y * 4 * core.status.heroMoving - } - const herox = core.status.hero.loc.x * 32 + 16 + sx - const heroy = core.status.hero.loc.y * 32 + 16 + sy - core.drawImage(anctx, img, cx, cy, cw, ch, herox + (x - data.px) * one.scalex, heroy + (y - data.py) * one.scaley, w * one.scalex, h * one.scaley, angle) - } else { core.drawImage(anctx, img, cx, cy, cw, ch, one.x + (x - data.px) * one.scalex, one.y + (y - data.py) * one.scaley, w * one.scalex, h * one.scaley, angle); } - } - } - }) - data.soundList.forEach(function (sound) { - const lisen = sound.sound && core.material.sounds[sound.sound] && core.musicStatus.soundStatus; - if (one.farme == sound.startfarme && lisen) { - if (sound.stopbefore) core.stopSound(); - core.playSound(sound.sound); - } - }) - one.farme++; - if (one.farme > data.allFarme) core.plugin.playing.delete(one) - } - }) + this.drawBook = function (floorId = core.status.floorId) { + if (core.domStyle.isVertical) { //对竖屏进行绘制坐标变换,只需要考虑横屏绘制,竖屏将自适应转置 + ctx.canvas.width = 1248; + ctx.canvas.height = 2028; + ctx.save(); //保存设置 + ctx.translate(1248, 0); //重新定位右上角为基准 + ctx.rotate(Math.PI / 2); //旋转90度 + } else { + ctx.canvas.width = 2028; + ctx.canvas.height = 1248; } + //在这里写绘制内容,只写横屏就行 - }) - + ctx.restore(); //恢复变换前的坐标,否则将连续转置 + } } } \ No newline at end of file diff --git a/project/sounds/aiy010000010.mp3 b/project/sounds/aiy010000010.mp3 deleted file mode 100644 index 4389b53..0000000 Binary files a/project/sounds/aiy010000010.mp3 and /dev/null differ diff --git a/project/sounds/aiy010000010.opus b/project/sounds/aiy010000010.opus new file mode 100644 index 0000000..0574c82 Binary files /dev/null and b/project/sounds/aiy010000010.opus differ diff --git a/project/sounds/aiy010000020.mp3 b/project/sounds/aiy010000020.mp3 deleted file mode 100644 index 77111c6..0000000 Binary files a/project/sounds/aiy010000020.mp3 and /dev/null differ diff --git a/project/sounds/aiy010000020.opus b/project/sounds/aiy010000020.opus new file mode 100644 index 0000000..a5768d9 Binary files /dev/null and b/project/sounds/aiy010000020.opus differ diff --git a/project/sounds/aiy010000030.mp3 b/project/sounds/aiy010000030.mp3 deleted file mode 100644 index c2b47e7..0000000 Binary files a/project/sounds/aiy010000030.mp3 and /dev/null differ diff --git a/project/sounds/aiy010000030.opus b/project/sounds/aiy010000030.opus new file mode 100644 index 0000000..450cf99 Binary files /dev/null and b/project/sounds/aiy010000030.opus differ diff --git a/project/sounds/aiy020000005.opus b/project/sounds/aiy020000005.opus new file mode 100644 index 0000000..5e05539 Binary files /dev/null and b/project/sounds/aiy020000005.opus differ diff --git a/project/sounds/aiy020000010.opus b/project/sounds/aiy020000010.opus new file mode 100644 index 0000000..257f445 Binary files /dev/null and b/project/sounds/aiy020000010.opus differ diff --git a/project/sounds/aiy020000020.opus b/project/sounds/aiy020000020.opus new file mode 100644 index 0000000..4ef0df5 Binary files /dev/null and b/project/sounds/aiy020000020.opus differ diff --git a/project/sounds/aiy020000030.opus b/project/sounds/aiy020000030.opus new file mode 100644 index 0000000..680d345 Binary files /dev/null and b/project/sounds/aiy020000030.opus differ diff --git a/project/sounds/aiy020000040.opus b/project/sounds/aiy020000040.opus new file mode 100644 index 0000000..7d8b8dd Binary files /dev/null and b/project/sounds/aiy020000040.opus differ diff --git a/project/sounds/aiy020000050.opus b/project/sounds/aiy020000050.opus new file mode 100644 index 0000000..54e571a Binary files /dev/null and b/project/sounds/aiy020000050.opus differ diff --git a/project/sounds/aiy020000060.opus b/project/sounds/aiy020000060.opus new file mode 100644 index 0000000..a574a48 Binary files /dev/null and b/project/sounds/aiy020000060.opus differ diff --git a/project/sounds/aiy020000070.opus b/project/sounds/aiy020000070.opus new file mode 100644 index 0000000..c4250aa Binary files /dev/null and b/project/sounds/aiy020000070.opus differ diff --git a/project/sounds/aiy020000080.opus b/project/sounds/aiy020000080.opus new file mode 100644 index 0000000..5002cc3 Binary files /dev/null and b/project/sounds/aiy020000080.opus differ diff --git a/project/sounds/aiy020000090.opus b/project/sounds/aiy020000090.opus new file mode 100644 index 0000000..cedb5f0 Binary files /dev/null and b/project/sounds/aiy020000090.opus differ diff --git a/project/sounds/aiy020000100.opus b/project/sounds/aiy020000100.opus new file mode 100644 index 0000000..deded59 Binary files /dev/null and b/project/sounds/aiy020000100.opus differ diff --git a/project/sounds/aiy020000110.opus b/project/sounds/aiy020000110.opus new file mode 100644 index 0000000..574f59c Binary files /dev/null and b/project/sounds/aiy020000110.opus differ diff --git a/project/sounds/aiy020000120.opus b/project/sounds/aiy020000120.opus new file mode 100644 index 0000000..0e982bc Binary files /dev/null and b/project/sounds/aiy020000120.opus differ diff --git a/project/sounds/aiy020000130.opus b/project/sounds/aiy020000130.opus new file mode 100644 index 0000000..837d498 Binary files /dev/null and b/project/sounds/aiy020000130.opus differ diff --git a/project/sounds/aiy020000140.opus b/project/sounds/aiy020000140.opus new file mode 100644 index 0000000..b57af22 Binary files /dev/null and b/project/sounds/aiy020000140.opus differ diff --git a/project/sounds/aiy020000150.opus b/project/sounds/aiy020000150.opus new file mode 100644 index 0000000..4ab93aa Binary files /dev/null and b/project/sounds/aiy020000150.opus differ diff --git a/project/sounds/aiy020000160.opus b/project/sounds/aiy020000160.opus new file mode 100644 index 0000000..14cf9f9 Binary files /dev/null and b/project/sounds/aiy020000160.opus differ diff --git a/project/sounds/aiy020000170.opus b/project/sounds/aiy020000170.opus new file mode 100644 index 0000000..fbf0b94 Binary files /dev/null and b/project/sounds/aiy020000170.opus differ diff --git a/project/sounds/aiy020000180.opus b/project/sounds/aiy020000180.opus new file mode 100644 index 0000000..2dfcfc2 Binary files /dev/null and b/project/sounds/aiy020000180.opus differ diff --git a/project/sounds/aiy020000190.ogg b/project/sounds/aiy020000190.ogg new file mode 100644 index 0000000..8212ba6 Binary files /dev/null and b/project/sounds/aiy020000190.ogg differ diff --git a/project/sounds/aiy020000200.ogg b/project/sounds/aiy020000200.ogg new file mode 100644 index 0000000..8f710f0 Binary files /dev/null and b/project/sounds/aiy020000200.ogg differ diff --git a/project/sounds/aiy020000210.ogg b/project/sounds/aiy020000210.ogg new file mode 100644 index 0000000..e4f719f Binary files /dev/null and b/project/sounds/aiy020000210.ogg differ diff --git a/project/sounds/aiy020000220.ogg b/project/sounds/aiy020000220.ogg new file mode 100644 index 0000000..cf59706 Binary files /dev/null and b/project/sounds/aiy020000220.ogg differ diff --git a/project/sounds/aiy020000230.ogg b/project/sounds/aiy020000230.ogg new file mode 100644 index 0000000..c7469e0 Binary files /dev/null and b/project/sounds/aiy020000230.ogg differ diff --git a/project/sounds/aiy020000240.ogg b/project/sounds/aiy020000240.ogg new file mode 100644 index 0000000..dc062c2 Binary files /dev/null and b/project/sounds/aiy020000240.ogg differ diff --git a/project/sounds/aiy020000250.ogg b/project/sounds/aiy020000250.ogg new file mode 100644 index 0000000..19608c4 Binary files /dev/null and b/project/sounds/aiy020000250.ogg differ diff --git a/project/sounds/aiy020000260.ogg b/project/sounds/aiy020000260.ogg new file mode 100644 index 0000000..fc86122 Binary files /dev/null and b/project/sounds/aiy020000260.ogg differ diff --git a/project/sounds/aiy020000270.ogg b/project/sounds/aiy020000270.ogg new file mode 100644 index 0000000..8a9e875 Binary files /dev/null and b/project/sounds/aiy020000270.ogg differ diff --git a/project/sounds/aiy020000280.ogg b/project/sounds/aiy020000280.ogg new file mode 100644 index 0000000..804c47b Binary files /dev/null and b/project/sounds/aiy020000280.ogg differ diff --git a/project/sounds/aiy020000290.ogg b/project/sounds/aiy020000290.ogg new file mode 100644 index 0000000..46e1502 Binary files /dev/null and b/project/sounds/aiy020000290.ogg differ diff --git a/project/sounds/aiy020000300.ogg b/project/sounds/aiy020000300.ogg new file mode 100644 index 0000000..d5445c7 Binary files /dev/null and b/project/sounds/aiy020000300.ogg differ diff --git a/project/sounds/aiy020000310.ogg b/project/sounds/aiy020000310.ogg new file mode 100644 index 0000000..e197805 Binary files /dev/null and b/project/sounds/aiy020000310.ogg differ diff --git a/project/sounds/aiy020000320.ogg b/project/sounds/aiy020000320.ogg new file mode 100644 index 0000000..eadca46 Binary files /dev/null and b/project/sounds/aiy020000320.ogg differ diff --git a/project/sounds/aiy020000330.ogg b/project/sounds/aiy020000330.ogg new file mode 100644 index 0000000..24af673 Binary files /dev/null and b/project/sounds/aiy020000330.ogg differ diff --git a/project/sounds/aiy020000340.ogg b/project/sounds/aiy020000340.ogg new file mode 100644 index 0000000..34d7e41 Binary files /dev/null and b/project/sounds/aiy020000340.ogg differ diff --git a/project/sounds/aiy020000350.ogg b/project/sounds/aiy020000350.ogg new file mode 100644 index 0000000..25d0572 Binary files /dev/null and b/project/sounds/aiy020000350.ogg differ diff --git a/project/sounds/aiy020000360.ogg b/project/sounds/aiy020000360.ogg new file mode 100644 index 0000000..e46bc3e Binary files /dev/null and b/project/sounds/aiy020000360.ogg differ diff --git a/project/sounds/aiy020000370.ogg b/project/sounds/aiy020000370.ogg new file mode 100644 index 0000000..f929ecb Binary files /dev/null and b/project/sounds/aiy020000370.ogg differ diff --git a/project/sounds/aiy030000010.ogg b/project/sounds/aiy030000010.ogg new file mode 100644 index 0000000..9b9d46d Binary files /dev/null and b/project/sounds/aiy030000010.ogg differ diff --git a/project/sounds/aiy030000020.ogg b/project/sounds/aiy030000020.ogg new file mode 100644 index 0000000..a0f4ebb Binary files /dev/null and b/project/sounds/aiy030000020.ogg differ diff --git a/project/sounds/aiy030000030.ogg b/project/sounds/aiy030000030.ogg new file mode 100644 index 0000000..14a2ca8 Binary files /dev/null and b/project/sounds/aiy030000030.ogg differ diff --git a/project/sounds/aiy030000050.ogg b/project/sounds/aiy030000050.ogg new file mode 100644 index 0000000..9bc3077 Binary files /dev/null and b/project/sounds/aiy030000050.ogg differ diff --git a/project/sounds/aiy030000060.ogg b/project/sounds/aiy030000060.ogg new file mode 100644 index 0000000..ff055c2 Binary files /dev/null and b/project/sounds/aiy030000060.ogg differ diff --git a/project/sounds/aiy030000070.ogg b/project/sounds/aiy030000070.ogg new file mode 100644 index 0000000..2e7dcba Binary files /dev/null and b/project/sounds/aiy030000070.ogg differ diff --git a/project/sounds/aiy030000080.ogg b/project/sounds/aiy030000080.ogg new file mode 100644 index 0000000..efc3d38 Binary files /dev/null and b/project/sounds/aiy030000080.ogg differ diff --git a/project/sounds/aiy030000090.ogg b/project/sounds/aiy030000090.ogg new file mode 100644 index 0000000..8f9fb91 Binary files /dev/null and b/project/sounds/aiy030000090.ogg differ diff --git a/project/sounds/aiy030000100.ogg b/project/sounds/aiy030000100.ogg new file mode 100644 index 0000000..0dbf5bc Binary files /dev/null and b/project/sounds/aiy030000100.ogg differ diff --git a/project/sounds/aiy030000110.ogg b/project/sounds/aiy030000110.ogg new file mode 100644 index 0000000..f722e49 Binary files /dev/null and b/project/sounds/aiy030000110.ogg differ diff --git a/project/sounds/aiy030000120.ogg b/project/sounds/aiy030000120.ogg new file mode 100644 index 0000000..53ac3bf Binary files /dev/null and b/project/sounds/aiy030000120.ogg differ diff --git a/project/sounds/aiy030000130.ogg b/project/sounds/aiy030000130.ogg new file mode 100644 index 0000000..aa157af Binary files /dev/null and b/project/sounds/aiy030000130.ogg differ diff --git a/project/sounds/aiy050000010.ogg b/project/sounds/aiy050000010.ogg new file mode 100644 index 0000000..6a9a4a2 Binary files /dev/null and b/project/sounds/aiy050000010.ogg differ diff --git a/project/sounds/aiy050000020.ogg b/project/sounds/aiy050000020.ogg new file mode 100644 index 0000000..9b9cdf8 Binary files /dev/null and b/project/sounds/aiy050000020.ogg differ diff --git a/project/sounds/aiy050000030.ogg b/project/sounds/aiy050000030.ogg new file mode 100644 index 0000000..d328ca8 Binary files /dev/null and b/project/sounds/aiy050000030.ogg differ diff --git a/project/sounds/aiy050000040.ogg b/project/sounds/aiy050000040.ogg new file mode 100644 index 0000000..cc11d60 Binary files /dev/null and b/project/sounds/aiy050000040.ogg differ diff --git a/project/sounds/aiy050000050.ogg b/project/sounds/aiy050000050.ogg new file mode 100644 index 0000000..590349f Binary files /dev/null and b/project/sounds/aiy050000050.ogg differ diff --git a/project/sounds/aiy050000060.ogg b/project/sounds/aiy050000060.ogg new file mode 100644 index 0000000..a77d3ba Binary files /dev/null and b/project/sounds/aiy050000060.ogg differ diff --git a/project/sounds/aiy050000070.ogg b/project/sounds/aiy050000070.ogg new file mode 100644 index 0000000..9213193 Binary files /dev/null and b/project/sounds/aiy050000070.ogg differ diff --git a/project/sounds/aiy050000080.ogg b/project/sounds/aiy050000080.ogg new file mode 100644 index 0000000..29a2c70 Binary files /dev/null and b/project/sounds/aiy050000080.ogg differ diff --git a/project/sounds/aiy050000090.ogg b/project/sounds/aiy050000090.ogg new file mode 100644 index 0000000..b0e5931 Binary files /dev/null and b/project/sounds/aiy050000090.ogg differ diff --git a/project/sounds/aiy050000100.ogg b/project/sounds/aiy050000100.ogg new file mode 100644 index 0000000..59e7ebc Binary files /dev/null and b/project/sounds/aiy050000100.ogg differ diff --git a/project/sounds/aiy050000110.ogg b/project/sounds/aiy050000110.ogg new file mode 100644 index 0000000..e198a48 Binary files /dev/null and b/project/sounds/aiy050000110.ogg differ diff --git a/project/sounds/aiy050000120.ogg b/project/sounds/aiy050000120.ogg new file mode 100644 index 0000000..ac4bf72 Binary files /dev/null and b/project/sounds/aiy050000120.ogg differ diff --git a/project/sounds/aiy120000020.ogg b/project/sounds/aiy120000020.ogg new file mode 100644 index 0000000..10d2ae0 Binary files /dev/null and b/project/sounds/aiy120000020.ogg differ diff --git a/project/sounds/aiy120000030.ogg b/project/sounds/aiy120000030.ogg new file mode 100644 index 0000000..2a0dc02 Binary files /dev/null and b/project/sounds/aiy120000030.ogg differ diff --git a/project/sounds/aiy120000040.ogg b/project/sounds/aiy120000040.ogg new file mode 100644 index 0000000..f9f0f66 Binary files /dev/null and b/project/sounds/aiy120000040.ogg differ diff --git a/project/sounds/aiy120000050.ogg b/project/sounds/aiy120000050.ogg new file mode 100644 index 0000000..0cb03e6 Binary files /dev/null and b/project/sounds/aiy120000050.ogg differ diff --git a/project/sounds/aiy120000060.ogg b/project/sounds/aiy120000060.ogg new file mode 100644 index 0000000..bdf482e Binary files /dev/null and b/project/sounds/aiy120000060.ogg differ diff --git a/project/sounds/aiy120000070.ogg b/project/sounds/aiy120000070.ogg new file mode 100644 index 0000000..c8822ac Binary files /dev/null and b/project/sounds/aiy120000070.ogg differ diff --git a/project/sounds/aiy120000080.ogg b/project/sounds/aiy120000080.ogg new file mode 100644 index 0000000..3cd1ff4 Binary files /dev/null and b/project/sounds/aiy120000080.ogg differ diff --git a/project/sounds/aiy120000090.ogg b/project/sounds/aiy120000090.ogg new file mode 100644 index 0000000..306c3d4 Binary files /dev/null and b/project/sounds/aiy120000090.ogg differ diff --git a/project/sounds/aiy120000100.ogg b/project/sounds/aiy120000100.ogg new file mode 100644 index 0000000..d6597f6 Binary files /dev/null and b/project/sounds/aiy120000100.ogg differ diff --git a/project/sounds/aiy120000110.ogg b/project/sounds/aiy120000110.ogg new file mode 100644 index 0000000..a322097 Binary files /dev/null and b/project/sounds/aiy120000110.ogg differ diff --git a/project/sounds/aiy120000120.ogg b/project/sounds/aiy120000120.ogg new file mode 100644 index 0000000..acb82fb Binary files /dev/null and b/project/sounds/aiy120000120.ogg differ diff --git a/project/sounds/aiy120000130.ogg b/project/sounds/aiy120000130.ogg new file mode 100644 index 0000000..8f231aa Binary files /dev/null and b/project/sounds/aiy120000130.ogg differ diff --git a/project/sounds/aiy120000140.ogg b/project/sounds/aiy120000140.ogg new file mode 100644 index 0000000..d3bbbb2 Binary files /dev/null and b/project/sounds/aiy120000140.ogg differ diff --git a/project/sounds/aiy120000150.ogg b/project/sounds/aiy120000150.ogg new file mode 100644 index 0000000..47f6a04 Binary files /dev/null and b/project/sounds/aiy120000150.ogg differ diff --git a/project/sounds/aiy120000160.ogg b/project/sounds/aiy120000160.ogg new file mode 100644 index 0000000..214c63b Binary files /dev/null and b/project/sounds/aiy120000160.ogg differ diff --git a/project/sounds/aiy120000170.ogg b/project/sounds/aiy120000170.ogg new file mode 100644 index 0000000..35d2f1b Binary files /dev/null and b/project/sounds/aiy120000170.ogg differ diff --git a/project/sounds/aiy120000180.ogg b/project/sounds/aiy120000180.ogg new file mode 100644 index 0000000..3417af8 Binary files /dev/null and b/project/sounds/aiy120000180.ogg differ diff --git a/project/sounds/aiy120000190.ogg b/project/sounds/aiy120000190.ogg new file mode 100644 index 0000000..37a6a52 Binary files /dev/null and b/project/sounds/aiy120000190.ogg differ diff --git a/project/sounds/aiy120000200.ogg b/project/sounds/aiy120000200.ogg new file mode 100644 index 0000000..18eefb3 Binary files /dev/null and b/project/sounds/aiy120000200.ogg differ diff --git a/project/sounds/aiy120000210.ogg b/project/sounds/aiy120000210.ogg new file mode 100644 index 0000000..67784d0 Binary files /dev/null and b/project/sounds/aiy120000210.ogg differ diff --git a/project/sounds/aiy120000220.ogg b/project/sounds/aiy120000220.ogg new file mode 100644 index 0000000..1e9d440 Binary files /dev/null and b/project/sounds/aiy120000220.ogg differ diff --git a/project/sounds/aiy120000230.ogg b/project/sounds/aiy120000230.ogg new file mode 100644 index 0000000..dc4d494 Binary files /dev/null and b/project/sounds/aiy120000230.ogg differ diff --git a/project/sounds/aiy120000240.ogg b/project/sounds/aiy120000240.ogg new file mode 100644 index 0000000..88a9404 Binary files /dev/null and b/project/sounds/aiy120000240.ogg differ diff --git a/project/sounds/aiy120000250.ogg b/project/sounds/aiy120000250.ogg new file mode 100644 index 0000000..44e9970 Binary files /dev/null and b/project/sounds/aiy120000250.ogg differ diff --git a/project/sounds/aiy120000260.ogg b/project/sounds/aiy120000260.ogg new file mode 100644 index 0000000..c93d37b Binary files /dev/null and b/project/sounds/aiy120000260.ogg differ diff --git a/project/sounds/aiy120000270.ogg b/project/sounds/aiy120000270.ogg new file mode 100644 index 0000000..97235e0 Binary files /dev/null and b/project/sounds/aiy120000270.ogg differ diff --git a/project/sounds/aiy120000280.ogg b/project/sounds/aiy120000280.ogg new file mode 100644 index 0000000..7153660 Binary files /dev/null and b/project/sounds/aiy120000280.ogg differ diff --git a/project/sounds/aiy120000290.ogg b/project/sounds/aiy120000290.ogg new file mode 100644 index 0000000..8c4db5b Binary files /dev/null and b/project/sounds/aiy120000290.ogg differ diff --git a/project/sounds/aiy120000300.ogg b/project/sounds/aiy120000300.ogg new file mode 100644 index 0000000..875d1f7 Binary files /dev/null and b/project/sounds/aiy120000300.ogg differ diff --git a/project/sounds/aiy120000310.ogg b/project/sounds/aiy120000310.ogg new file mode 100644 index 0000000..8720a02 Binary files /dev/null and b/project/sounds/aiy120000310.ogg differ diff --git a/project/sounds/aiy120000320.ogg b/project/sounds/aiy120000320.ogg new file mode 100644 index 0000000..c86806b Binary files /dev/null and b/project/sounds/aiy120000320.ogg differ diff --git a/project/sounds/aiy120000330.ogg b/project/sounds/aiy120000330.ogg new file mode 100644 index 0000000..0f21adc Binary files /dev/null and b/project/sounds/aiy120000330.ogg differ diff --git a/project/sounds/aiy120000340.ogg b/project/sounds/aiy120000340.ogg new file mode 100644 index 0000000..a055a78 Binary files /dev/null and b/project/sounds/aiy120000340.ogg differ diff --git a/project/sounds/aiy120000350.ogg b/project/sounds/aiy120000350.ogg new file mode 100644 index 0000000..0711a4f Binary files /dev/null and b/project/sounds/aiy120000350.ogg differ diff --git a/project/sounds/aiy120000360.ogg b/project/sounds/aiy120000360.ogg new file mode 100644 index 0000000..358c450 Binary files /dev/null and b/project/sounds/aiy120000360.ogg differ diff --git a/project/sounds/aiy120000370.ogg b/project/sounds/aiy120000370.ogg new file mode 100644 index 0000000..6381050 Binary files /dev/null and b/project/sounds/aiy120000370.ogg differ diff --git a/project/sounds/aiy120000380.ogg b/project/sounds/aiy120000380.ogg new file mode 100644 index 0000000..b80c4f0 Binary files /dev/null and b/project/sounds/aiy120000380.ogg differ diff --git a/project/sounds/aiy120000390.ogg b/project/sounds/aiy120000390.ogg new file mode 100644 index 0000000..c608bba Binary files /dev/null and b/project/sounds/aiy120000390.ogg differ diff --git a/project/sounds/aiy120000400.ogg b/project/sounds/aiy120000400.ogg new file mode 100644 index 0000000..656ae27 Binary files /dev/null and b/project/sounds/aiy120000400.ogg differ diff --git a/project/sounds/aiy120000410.ogg b/project/sounds/aiy120000410.ogg new file mode 100644 index 0000000..5f04e20 Binary files /dev/null and b/project/sounds/aiy120000410.ogg differ diff --git a/project/sounds/aiy120000420.ogg b/project/sounds/aiy120000420.ogg new file mode 100644 index 0000000..86e91fa Binary files /dev/null and b/project/sounds/aiy120000420.ogg differ diff --git a/project/sounds/aiy120000430.ogg b/project/sounds/aiy120000430.ogg new file mode 100644 index 0000000..957e986 Binary files /dev/null and b/project/sounds/aiy120000430.ogg differ diff --git a/project/sounds/aiy120000440.ogg b/project/sounds/aiy120000440.ogg new file mode 100644 index 0000000..45231db Binary files /dev/null and b/project/sounds/aiy120000440.ogg differ diff --git a/project/sounds/aiy120000450.ogg b/project/sounds/aiy120000450.ogg new file mode 100644 index 0000000..ad04858 Binary files /dev/null and b/project/sounds/aiy120000450.ogg differ diff --git a/project/sounds/aiy120000460.ogg b/project/sounds/aiy120000460.ogg new file mode 100644 index 0000000..d35ded8 Binary files /dev/null and b/project/sounds/aiy120000460.ogg differ diff --git a/project/sounds/aiy120000470.ogg b/project/sounds/aiy120000470.ogg new file mode 100644 index 0000000..546a039 Binary files /dev/null and b/project/sounds/aiy120000470.ogg differ diff --git a/project/sounds/aiy120000480.ogg b/project/sounds/aiy120000480.ogg new file mode 100644 index 0000000..65f673a Binary files /dev/null and b/project/sounds/aiy120000480.ogg differ diff --git a/project/sounds/aiy120000490.ogg b/project/sounds/aiy120000490.ogg new file mode 100644 index 0000000..36a5df2 Binary files /dev/null and b/project/sounds/aiy120000490.ogg differ diff --git a/project/sounds/aiy120000500.ogg b/project/sounds/aiy120000500.ogg new file mode 100644 index 0000000..db40172 Binary files /dev/null and b/project/sounds/aiy120000500.ogg differ diff --git a/project/sounds/aiy120000510.ogg b/project/sounds/aiy120000510.ogg new file mode 100644 index 0000000..0da2bbd Binary files /dev/null and b/project/sounds/aiy120000510.ogg differ diff --git a/project/sounds/aiy120000520.ogg b/project/sounds/aiy120000520.ogg new file mode 100644 index 0000000..30618ea Binary files /dev/null and b/project/sounds/aiy120000520.ogg differ diff --git a/project/sounds/aiy120000530.ogg b/project/sounds/aiy120000530.ogg new file mode 100644 index 0000000..63424e5 Binary files /dev/null and b/project/sounds/aiy120000530.ogg differ diff --git a/project/sounds/aiy120000540.ogg b/project/sounds/aiy120000540.ogg new file mode 100644 index 0000000..a491c40 Binary files /dev/null and b/project/sounds/aiy120000540.ogg differ diff --git a/project/sounds/aiy120000550.ogg b/project/sounds/aiy120000550.ogg new file mode 100644 index 0000000..1adb571 Binary files /dev/null and b/project/sounds/aiy120000550.ogg differ diff --git a/project/sounds/aiy120000560.ogg b/project/sounds/aiy120000560.ogg new file mode 100644 index 0000000..eafe149 Binary files /dev/null and b/project/sounds/aiy120000560.ogg differ diff --git a/project/sounds/aiy120000570.ogg b/project/sounds/aiy120000570.ogg new file mode 100644 index 0000000..f25d9d2 Binary files /dev/null and b/project/sounds/aiy120000570.ogg differ diff --git a/project/sounds/aiy120000580.ogg b/project/sounds/aiy120000580.ogg new file mode 100644 index 0000000..503d4e0 Binary files /dev/null and b/project/sounds/aiy120000580.ogg differ diff --git a/project/sounds/aiy120000590.ogg b/project/sounds/aiy120000590.ogg new file mode 100644 index 0000000..0fa071e Binary files /dev/null and b/project/sounds/aiy120000590.ogg differ diff --git a/project/sounds/aiy120000600.ogg b/project/sounds/aiy120000600.ogg new file mode 100644 index 0000000..6d22156 Binary files /dev/null and b/project/sounds/aiy120000600.ogg differ diff --git a/project/sounds/aiy120000610.ogg b/project/sounds/aiy120000610.ogg new file mode 100644 index 0000000..95b2a7d Binary files /dev/null and b/project/sounds/aiy120000610.ogg differ diff --git a/project/sounds/aiy120000620.ogg b/project/sounds/aiy120000620.ogg new file mode 100644 index 0000000..f03cf8f Binary files /dev/null and b/project/sounds/aiy120000620.ogg differ diff --git a/project/sounds/aiy120000630.ogg b/project/sounds/aiy120000630.ogg new file mode 100644 index 0000000..5420074 Binary files /dev/null and b/project/sounds/aiy120000630.ogg differ diff --git a/project/sounds/aiy120000640.ogg b/project/sounds/aiy120000640.ogg new file mode 100644 index 0000000..a204879 Binary files /dev/null and b/project/sounds/aiy120000640.ogg differ diff --git a/project/sounds/aiy120000650.ogg b/project/sounds/aiy120000650.ogg new file mode 100644 index 0000000..257b817 Binary files /dev/null and b/project/sounds/aiy120000650.ogg differ diff --git a/project/sounds/aiy120000670.ogg b/project/sounds/aiy120000670.ogg new file mode 100644 index 0000000..b603efe Binary files /dev/null and b/project/sounds/aiy120000670.ogg differ diff --git a/project/sounds/aiy120000680.ogg b/project/sounds/aiy120000680.ogg new file mode 100644 index 0000000..32f2bdd Binary files /dev/null and b/project/sounds/aiy120000680.ogg differ diff --git a/project/sounds/aiy120000690.ogg b/project/sounds/aiy120000690.ogg new file mode 100644 index 0000000..89a831c Binary files /dev/null and b/project/sounds/aiy120000690.ogg differ diff --git a/project/sounds/aiy130000010.ogg b/project/sounds/aiy130000010.ogg new file mode 100644 index 0000000..fe0e4e2 Binary files /dev/null and b/project/sounds/aiy130000010.ogg differ diff --git a/project/sounds/aiy130000020.ogg b/project/sounds/aiy130000020.ogg new file mode 100644 index 0000000..6e13850 Binary files /dev/null and b/project/sounds/aiy130000020.ogg differ diff --git a/project/sounds/aiy150000010.ogg b/project/sounds/aiy150000010.ogg new file mode 100644 index 0000000..0659452 Binary files /dev/null and b/project/sounds/aiy150000010.ogg differ diff --git a/project/sounds/aiy150000020.ogg b/project/sounds/aiy150000020.ogg new file mode 100644 index 0000000..798a9fc Binary files /dev/null and b/project/sounds/aiy150000020.ogg differ diff --git a/project/sounds/aiy150000030.ogg b/project/sounds/aiy150000030.ogg new file mode 100644 index 0000000..9022052 Binary files /dev/null and b/project/sounds/aiy150000030.ogg differ diff --git a/project/sounds/aiy150000040.ogg b/project/sounds/aiy150000040.ogg new file mode 100644 index 0000000..c6e6233 Binary files /dev/null and b/project/sounds/aiy150000040.ogg differ diff --git a/project/sounds/aiy150000050.ogg b/project/sounds/aiy150000050.ogg new file mode 100644 index 0000000..8764aee Binary files /dev/null and b/project/sounds/aiy150000050.ogg differ diff --git a/project/sounds/aiy150000060.ogg b/project/sounds/aiy150000060.ogg new file mode 100644 index 0000000..e305004 Binary files /dev/null and b/project/sounds/aiy150000060.ogg differ diff --git a/project/sounds/aiy150000070.ogg b/project/sounds/aiy150000070.ogg new file mode 100644 index 0000000..e2d173a Binary files /dev/null and b/project/sounds/aiy150000070.ogg differ diff --git a/project/sounds/aiy150000080.ogg b/project/sounds/aiy150000080.ogg new file mode 100644 index 0000000..8bed0cf Binary files /dev/null and b/project/sounds/aiy150000080.ogg differ diff --git a/project/sounds/aiy150000090.ogg b/project/sounds/aiy150000090.ogg new file mode 100644 index 0000000..8c35672 Binary files /dev/null and b/project/sounds/aiy150000090.ogg differ diff --git a/project/sounds/aiy150000100.ogg b/project/sounds/aiy150000100.ogg new file mode 100644 index 0000000..0fda997 Binary files /dev/null and b/project/sounds/aiy150000100.ogg differ diff --git a/project/sounds/aiy150000110.ogg b/project/sounds/aiy150000110.ogg new file mode 100644 index 0000000..2e7da86 Binary files /dev/null and b/project/sounds/aiy150000110.ogg differ diff --git a/project/sounds/aiy150000120.ogg b/project/sounds/aiy150000120.ogg new file mode 100644 index 0000000..1e6adc7 Binary files /dev/null and b/project/sounds/aiy150000120.ogg differ diff --git a/project/sounds/aiy150000130.ogg b/project/sounds/aiy150000130.ogg new file mode 100644 index 0000000..bdbefb9 Binary files /dev/null and b/project/sounds/aiy150000130.ogg differ diff --git a/project/sounds/aiy150000140.ogg b/project/sounds/aiy150000140.ogg new file mode 100644 index 0000000..5ec6eda Binary files /dev/null and b/project/sounds/aiy150000140.ogg differ diff --git a/project/sounds/aiy150000150.ogg b/project/sounds/aiy150000150.ogg new file mode 100644 index 0000000..28fad01 Binary files /dev/null and b/project/sounds/aiy150000150.ogg differ diff --git a/project/sounds/aiy150000160.ogg b/project/sounds/aiy150000160.ogg new file mode 100644 index 0000000..54bb342 Binary files /dev/null and b/project/sounds/aiy150000160.ogg differ diff --git a/project/sounds/aiy150000170.ogg b/project/sounds/aiy150000170.ogg new file mode 100644 index 0000000..44543c4 Binary files /dev/null and b/project/sounds/aiy150000170.ogg differ diff --git a/project/sounds/aiy150000180.ogg b/project/sounds/aiy150000180.ogg new file mode 100644 index 0000000..16682cc Binary files /dev/null and b/project/sounds/aiy150000180.ogg differ diff --git a/project/sounds/aiy150000190.ogg b/project/sounds/aiy150000190.ogg new file mode 100644 index 0000000..74b719a Binary files /dev/null and b/project/sounds/aiy150000190.ogg differ diff --git a/project/sounds/aiy150000200.ogg b/project/sounds/aiy150000200.ogg new file mode 100644 index 0000000..c6c73df Binary files /dev/null and b/project/sounds/aiy150000200.ogg differ diff --git a/project/sounds/aiy150000210.ogg b/project/sounds/aiy150000210.ogg new file mode 100644 index 0000000..bb1182b Binary files /dev/null and b/project/sounds/aiy150000210.ogg differ diff --git a/project/sounds/aiy150000220.ogg b/project/sounds/aiy150000220.ogg new file mode 100644 index 0000000..3babde5 Binary files /dev/null and b/project/sounds/aiy150000220.ogg differ diff --git a/project/sounds/aiy150000230.ogg b/project/sounds/aiy150000230.ogg new file mode 100644 index 0000000..a51169e Binary files /dev/null and b/project/sounds/aiy150000230.ogg differ diff --git a/project/sounds/aiy150000240.ogg b/project/sounds/aiy150000240.ogg new file mode 100644 index 0000000..6ff7544 Binary files /dev/null and b/project/sounds/aiy150000240.ogg differ diff --git a/project/sounds/aiy150000250.ogg b/project/sounds/aiy150000250.ogg new file mode 100644 index 0000000..1b3acf8 Binary files /dev/null and b/project/sounds/aiy150000250.ogg differ diff --git a/project/sounds/aiy310000010.mp3 b/project/sounds/aiy310000010.mp3 deleted file mode 100644 index d6bf306..0000000 Binary files a/project/sounds/aiy310000010.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000010.opus b/project/sounds/aiy310000010.opus new file mode 100644 index 0000000..9955fab Binary files /dev/null and b/project/sounds/aiy310000010.opus differ diff --git a/project/sounds/aiy310000020.mp3 b/project/sounds/aiy310000020.mp3 deleted file mode 100644 index 84ad00e..0000000 Binary files a/project/sounds/aiy310000020.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000020.opus b/project/sounds/aiy310000020.opus new file mode 100644 index 0000000..99fe711 Binary files /dev/null and b/project/sounds/aiy310000020.opus differ diff --git a/project/sounds/aiy310000030.mp3 b/project/sounds/aiy310000030.mp3 deleted file mode 100644 index ca51c6c..0000000 Binary files a/project/sounds/aiy310000030.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000030.opus b/project/sounds/aiy310000030.opus new file mode 100644 index 0000000..e62ade9 Binary files /dev/null and b/project/sounds/aiy310000030.opus differ diff --git a/project/sounds/aiy310000040.mp3 b/project/sounds/aiy310000040.mp3 deleted file mode 100644 index 139b9c4..0000000 Binary files a/project/sounds/aiy310000040.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000040.opus b/project/sounds/aiy310000040.opus new file mode 100644 index 0000000..ecd0f9b Binary files /dev/null and b/project/sounds/aiy310000040.opus differ diff --git a/project/sounds/aiy310000050.mp3 b/project/sounds/aiy310000050.mp3 deleted file mode 100644 index b0b68b9..0000000 Binary files a/project/sounds/aiy310000050.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000050.opus b/project/sounds/aiy310000050.opus new file mode 100644 index 0000000..12f5233 Binary files /dev/null and b/project/sounds/aiy310000050.opus differ diff --git a/project/sounds/aiy310000060.mp3 b/project/sounds/aiy310000060.mp3 deleted file mode 100644 index 9773718..0000000 Binary files a/project/sounds/aiy310000060.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000060.opus b/project/sounds/aiy310000060.opus new file mode 100644 index 0000000..4e36bcd Binary files /dev/null and b/project/sounds/aiy310000060.opus differ diff --git a/project/sounds/aiy310000070.mp3 b/project/sounds/aiy310000070.mp3 deleted file mode 100644 index 3b2667c..0000000 Binary files a/project/sounds/aiy310000070.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000070.opus b/project/sounds/aiy310000070.opus new file mode 100644 index 0000000..db9d0e7 Binary files /dev/null and b/project/sounds/aiy310000070.opus differ diff --git a/project/sounds/aiy310000080.mp3 b/project/sounds/aiy310000080.mp3 deleted file mode 100644 index 392969d..0000000 Binary files a/project/sounds/aiy310000080.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000080.opus b/project/sounds/aiy310000080.opus new file mode 100644 index 0000000..c303fb3 Binary files /dev/null and b/project/sounds/aiy310000080.opus differ diff --git a/project/sounds/aiy310000090.mp3 b/project/sounds/aiy310000090.mp3 deleted file mode 100644 index 7ace161..0000000 Binary files a/project/sounds/aiy310000090.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000090.opus b/project/sounds/aiy310000090.opus new file mode 100644 index 0000000..63289e6 Binary files /dev/null and b/project/sounds/aiy310000090.opus differ diff --git a/project/sounds/aiy310000100.mp3 b/project/sounds/aiy310000100.mp3 deleted file mode 100644 index 57907d8..0000000 Binary files a/project/sounds/aiy310000100.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000100.opus b/project/sounds/aiy310000100.opus new file mode 100644 index 0000000..e62de21 Binary files /dev/null and b/project/sounds/aiy310000100.opus differ diff --git a/project/sounds/aiy310000110.mp3 b/project/sounds/aiy310000110.mp3 deleted file mode 100644 index 955cda3..0000000 Binary files a/project/sounds/aiy310000110.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000110.opus b/project/sounds/aiy310000110.opus new file mode 100644 index 0000000..3c6a541 Binary files /dev/null and b/project/sounds/aiy310000110.opus differ diff --git a/project/sounds/aiy310000120.mp3 b/project/sounds/aiy310000120.mp3 deleted file mode 100644 index d387bdd..0000000 Binary files a/project/sounds/aiy310000120.mp3 and /dev/null differ diff --git a/project/sounds/aiy310000120.opus b/project/sounds/aiy310000120.opus new file mode 100644 index 0000000..3961d24 Binary files /dev/null and b/project/sounds/aiy310000120.opus differ diff --git a/project/sounds/aiy310000130.opus b/project/sounds/aiy310000130.opus new file mode 100644 index 0000000..e5dab39 Binary files /dev/null and b/project/sounds/aiy310000130.opus differ diff --git a/project/sounds/aiy310000140.opus b/project/sounds/aiy310000140.opus new file mode 100644 index 0000000..e7bf71f Binary files /dev/null and b/project/sounds/aiy310000140.opus differ diff --git a/project/sounds/aiy310000150.opus b/project/sounds/aiy310000150.opus new file mode 100644 index 0000000..b6fe0bd Binary files /dev/null and b/project/sounds/aiy310000150.opus differ diff --git a/project/sounds/aiy310000160.opus b/project/sounds/aiy310000160.opus new file mode 100644 index 0000000..1de7696 Binary files /dev/null and b/project/sounds/aiy310000160.opus differ diff --git a/project/sounds/aiy310000170.opus b/project/sounds/aiy310000170.opus new file mode 100644 index 0000000..55df5b4 Binary files /dev/null and b/project/sounds/aiy310000170.opus differ diff --git a/project/sounds/aiy310000180.opus b/project/sounds/aiy310000180.opus new file mode 100644 index 0000000..dc9a85c Binary files /dev/null and b/project/sounds/aiy310000180.opus differ diff --git a/project/sounds/aiy310000190.opus b/project/sounds/aiy310000190.opus new file mode 100644 index 0000000..821e276 Binary files /dev/null and b/project/sounds/aiy310000190.opus differ diff --git a/project/sounds/aiy310000200.opus b/project/sounds/aiy310000200.opus new file mode 100644 index 0000000..51ba4fc Binary files /dev/null and b/project/sounds/aiy310000200.opus differ diff --git a/project/sounds/aiy310000210.opus b/project/sounds/aiy310000210.opus new file mode 100644 index 0000000..4fe0fa9 Binary files /dev/null and b/project/sounds/aiy310000210.opus differ diff --git a/project/sounds/aiy310000220.opus b/project/sounds/aiy310000220.opus new file mode 100644 index 0000000..169de30 Binary files /dev/null and b/project/sounds/aiy310000220.opus differ diff --git a/project/sounds/aiy310000230.opus b/project/sounds/aiy310000230.opus new file mode 100644 index 0000000..db0f37d Binary files /dev/null and b/project/sounds/aiy310000230.opus differ diff --git a/project/sounds/aiy310000240.opus b/project/sounds/aiy310000240.opus new file mode 100644 index 0000000..597e491 Binary files /dev/null and b/project/sounds/aiy310000240.opus differ diff --git a/project/sounds/aiy310000250.opus b/project/sounds/aiy310000250.opus new file mode 100644 index 0000000..e8ada96 Binary files /dev/null and b/project/sounds/aiy310000250.opus differ diff --git a/project/sounds/aiy310000260.opus b/project/sounds/aiy310000260.opus new file mode 100644 index 0000000..1d7bae9 Binary files /dev/null and b/project/sounds/aiy310000260.opus differ diff --git a/project/sounds/aiy310000280.opus b/project/sounds/aiy310000280.opus new file mode 100644 index 0000000..649f1fd Binary files /dev/null and b/project/sounds/aiy310000280.opus differ diff --git a/project/sounds/aiy310000290.opus b/project/sounds/aiy310000290.opus new file mode 100644 index 0000000..f4222de Binary files /dev/null and b/project/sounds/aiy310000290.opus differ diff --git a/project/sounds/aiy310000300.opus b/project/sounds/aiy310000300.opus new file mode 100644 index 0000000..32c2f49 Binary files /dev/null and b/project/sounds/aiy310000300.opus differ diff --git a/project/sounds/aiy310000310.ogg b/project/sounds/aiy310000310.ogg new file mode 100644 index 0000000..7d1eda9 Binary files /dev/null and b/project/sounds/aiy310000310.ogg differ diff --git a/project/sounds/aiy310000320.ogg b/project/sounds/aiy310000320.ogg new file mode 100644 index 0000000..2793e41 Binary files /dev/null and b/project/sounds/aiy310000320.ogg differ diff --git a/project/sounds/aiy310000330.ogg b/project/sounds/aiy310000330.ogg new file mode 100644 index 0000000..f3806c3 Binary files /dev/null and b/project/sounds/aiy310000330.ogg differ diff --git a/project/sounds/aiy310000340.ogg b/project/sounds/aiy310000340.ogg new file mode 100644 index 0000000..a640644 Binary files /dev/null and b/project/sounds/aiy310000340.ogg differ diff --git a/project/sounds/aiy310000350.ogg b/project/sounds/aiy310000350.ogg new file mode 100644 index 0000000..ea5352e Binary files /dev/null and b/project/sounds/aiy310000350.ogg differ diff --git a/project/sounds/aiy310000360.ogg b/project/sounds/aiy310000360.ogg new file mode 100644 index 0000000..5eefa11 Binary files /dev/null and b/project/sounds/aiy310000360.ogg differ diff --git a/project/sounds/aiy310000370.ogg b/project/sounds/aiy310000370.ogg new file mode 100644 index 0000000..91a7a46 Binary files /dev/null and b/project/sounds/aiy310000370.ogg differ diff --git a/project/sounds/aiy310000380.ogg b/project/sounds/aiy310000380.ogg new file mode 100644 index 0000000..7ba0311 Binary files /dev/null and b/project/sounds/aiy310000380.ogg differ diff --git a/project/sounds/aiy310000390.ogg b/project/sounds/aiy310000390.ogg new file mode 100644 index 0000000..3c877e9 Binary files /dev/null and b/project/sounds/aiy310000390.ogg differ diff --git a/project/sounds/aiy310000400.ogg b/project/sounds/aiy310000400.ogg new file mode 100644 index 0000000..df3e50c Binary files /dev/null and b/project/sounds/aiy310000400.ogg differ diff --git a/project/sounds/aiy310000410.ogg b/project/sounds/aiy310000410.ogg new file mode 100644 index 0000000..69ad557 Binary files /dev/null and b/project/sounds/aiy310000410.ogg differ diff --git a/project/sounds/aiy310000420.ogg b/project/sounds/aiy310000420.ogg new file mode 100644 index 0000000..1a50529 Binary files /dev/null and b/project/sounds/aiy310000420.ogg differ diff --git a/project/sounds/aiy310000430.ogg b/project/sounds/aiy310000430.ogg new file mode 100644 index 0000000..980b7af Binary files /dev/null and b/project/sounds/aiy310000430.ogg differ diff --git a/project/sounds/aiy310000440.ogg b/project/sounds/aiy310000440.ogg new file mode 100644 index 0000000..68e063a Binary files /dev/null and b/project/sounds/aiy310000440.ogg differ diff --git a/project/sounds/aiy310000450.ogg b/project/sounds/aiy310000450.ogg new file mode 100644 index 0000000..991e23c Binary files /dev/null and b/project/sounds/aiy310000450.ogg differ diff --git a/project/sounds/aiy310000460.ogg b/project/sounds/aiy310000460.ogg new file mode 100644 index 0000000..7208098 Binary files /dev/null and b/project/sounds/aiy310000460.ogg differ diff --git a/project/sounds/aiy310000470.ogg b/project/sounds/aiy310000470.ogg new file mode 100644 index 0000000..fe71d8f Binary files /dev/null and b/project/sounds/aiy310000470.ogg differ diff --git a/project/sounds/aiy310000480.ogg b/project/sounds/aiy310000480.ogg new file mode 100644 index 0000000..11bc4fe Binary files /dev/null and b/project/sounds/aiy310000480.ogg differ diff --git a/project/sounds/aiy310000490.ogg b/project/sounds/aiy310000490.ogg new file mode 100644 index 0000000..4a8c1a5 Binary files /dev/null and b/project/sounds/aiy310000490.ogg differ diff --git a/project/sounds/aiy310000510.ogg b/project/sounds/aiy310000510.ogg new file mode 100644 index 0000000..5f98abb Binary files /dev/null and b/project/sounds/aiy310000510.ogg differ diff --git a/project/sounds/aiy310000520.ogg b/project/sounds/aiy310000520.ogg new file mode 100644 index 0000000..5dbe058 Binary files /dev/null and b/project/sounds/aiy310000520.ogg differ diff --git a/project/sounds/aiy310000530.ogg b/project/sounds/aiy310000530.ogg new file mode 100644 index 0000000..317a75e Binary files /dev/null and b/project/sounds/aiy310000530.ogg differ diff --git a/project/sounds/aiy310000540.ogg b/project/sounds/aiy310000540.ogg new file mode 100644 index 0000000..ebdceab Binary files /dev/null and b/project/sounds/aiy310000540.ogg differ diff --git a/project/sounds/aiy310000550.ogg b/project/sounds/aiy310000550.ogg new file mode 100644 index 0000000..735881c Binary files /dev/null and b/project/sounds/aiy310000550.ogg differ diff --git a/project/sounds/aiy310000560.ogg b/project/sounds/aiy310000560.ogg new file mode 100644 index 0000000..a631836 Binary files /dev/null and b/project/sounds/aiy310000560.ogg differ diff --git a/project/sounds/aiy310000570.ogg b/project/sounds/aiy310000570.ogg new file mode 100644 index 0000000..cd365e2 Binary files /dev/null and b/project/sounds/aiy310000570.ogg differ diff --git a/project/sounds/aiy310000580.ogg b/project/sounds/aiy310000580.ogg new file mode 100644 index 0000000..1ff4d98 Binary files /dev/null and b/project/sounds/aiy310000580.ogg differ diff --git a/project/sounds/aiy310000590.ogg b/project/sounds/aiy310000590.ogg new file mode 100644 index 0000000..d6d161a Binary files /dev/null and b/project/sounds/aiy310000590.ogg differ diff --git a/project/sounds/aiy310000600.ogg b/project/sounds/aiy310000600.ogg new file mode 100644 index 0000000..3afd47d Binary files /dev/null and b/project/sounds/aiy310000600.ogg differ diff --git a/project/sounds/aiy310000610.ogg b/project/sounds/aiy310000610.ogg new file mode 100644 index 0000000..fdcb28b Binary files /dev/null and b/project/sounds/aiy310000610.ogg differ diff --git a/project/sounds/aiy310000620.ogg b/project/sounds/aiy310000620.ogg new file mode 100644 index 0000000..b9d5791 Binary files /dev/null and b/project/sounds/aiy310000620.ogg differ diff --git a/project/sounds/aiy310000630.ogg b/project/sounds/aiy310000630.ogg new file mode 100644 index 0000000..b564e34 Binary files /dev/null and b/project/sounds/aiy310000630.ogg differ diff --git a/project/sounds/aiy310000640.ogg b/project/sounds/aiy310000640.ogg new file mode 100644 index 0000000..d976e60 Binary files /dev/null and b/project/sounds/aiy310000640.ogg differ diff --git a/project/sounds/aiy310000650.ogg b/project/sounds/aiy310000650.ogg new file mode 100644 index 0000000..ea7b117 Binary files /dev/null and b/project/sounds/aiy310000650.ogg differ diff --git a/project/sounds/aiy310000660.ogg b/project/sounds/aiy310000660.ogg new file mode 100644 index 0000000..95f02d0 Binary files /dev/null and b/project/sounds/aiy310000660.ogg differ diff --git a/project/sounds/aiy310000670.ogg b/project/sounds/aiy310000670.ogg new file mode 100644 index 0000000..17df42a Binary files /dev/null and b/project/sounds/aiy310000670.ogg differ diff --git a/project/sounds/aiy310000680.ogg b/project/sounds/aiy310000680.ogg new file mode 100644 index 0000000..032a9b8 Binary files /dev/null and b/project/sounds/aiy310000680.ogg differ diff --git a/project/sounds/aiy310000690.ogg b/project/sounds/aiy310000690.ogg new file mode 100644 index 0000000..9d99453 Binary files /dev/null and b/project/sounds/aiy310000690.ogg differ diff --git a/project/sounds/aiy310000700.ogg b/project/sounds/aiy310000700.ogg new file mode 100644 index 0000000..7cefbff Binary files /dev/null and b/project/sounds/aiy310000700.ogg differ diff --git a/project/sounds/aiy310000710.ogg b/project/sounds/aiy310000710.ogg new file mode 100644 index 0000000..dc5eb5a Binary files /dev/null and b/project/sounds/aiy310000710.ogg differ diff --git a/project/sounds/aiy310000720.ogg b/project/sounds/aiy310000720.ogg new file mode 100644 index 0000000..fd37fd3 Binary files /dev/null and b/project/sounds/aiy310000720.ogg differ diff --git a/project/sounds/aiy310000730.ogg b/project/sounds/aiy310000730.ogg new file mode 100644 index 0000000..94a4631 Binary files /dev/null and b/project/sounds/aiy310000730.ogg differ diff --git a/project/sounds/aiy310000740.ogg b/project/sounds/aiy310000740.ogg new file mode 100644 index 0000000..db5f537 Binary files /dev/null and b/project/sounds/aiy310000740.ogg differ diff --git a/project/sounds/aiy310000750.ogg b/project/sounds/aiy310000750.ogg new file mode 100644 index 0000000..90573c8 Binary files /dev/null and b/project/sounds/aiy310000750.ogg differ diff --git a/project/sounds/aiy310000760.ogg b/project/sounds/aiy310000760.ogg new file mode 100644 index 0000000..43f2522 Binary files /dev/null and b/project/sounds/aiy310000760.ogg differ diff --git a/project/sounds/aiy310000770.ogg b/project/sounds/aiy310000770.ogg new file mode 100644 index 0000000..fccf1f1 Binary files /dev/null and b/project/sounds/aiy310000770.ogg differ diff --git a/project/sounds/aiy310000780.ogg b/project/sounds/aiy310000780.ogg new file mode 100644 index 0000000..d1d04ee Binary files /dev/null and b/project/sounds/aiy310000780.ogg differ diff --git a/project/sounds/aiy310000790.ogg b/project/sounds/aiy310000790.ogg new file mode 100644 index 0000000..2cfa70b Binary files /dev/null and b/project/sounds/aiy310000790.ogg differ diff --git a/project/sounds/aiy310000800.ogg b/project/sounds/aiy310000800.ogg new file mode 100644 index 0000000..4400a66 Binary files /dev/null and b/project/sounds/aiy310000800.ogg differ diff --git a/project/sounds/aiy310000810.ogg b/project/sounds/aiy310000810.ogg new file mode 100644 index 0000000..4066404 Binary files /dev/null and b/project/sounds/aiy310000810.ogg differ diff --git a/project/sounds/aiy310000820.ogg b/project/sounds/aiy310000820.ogg new file mode 100644 index 0000000..29c5807 Binary files /dev/null and b/project/sounds/aiy310000820.ogg differ diff --git a/project/sounds/aiy310000830.ogg b/project/sounds/aiy310000830.ogg new file mode 100644 index 0000000..84770ef Binary files /dev/null and b/project/sounds/aiy310000830.ogg differ diff --git a/project/sounds/aiy310000840.ogg b/project/sounds/aiy310000840.ogg new file mode 100644 index 0000000..5b44741 Binary files /dev/null and b/project/sounds/aiy310000840.ogg differ diff --git a/project/sounds/aiy310000850.ogg b/project/sounds/aiy310000850.ogg new file mode 100644 index 0000000..0900773 Binary files /dev/null and b/project/sounds/aiy310000850.ogg differ diff --git a/project/sounds/aiy310000860.ogg b/project/sounds/aiy310000860.ogg new file mode 100644 index 0000000..e31d562 Binary files /dev/null and b/project/sounds/aiy310000860.ogg differ diff --git a/project/sounds/aiy310000870.ogg b/project/sounds/aiy310000870.ogg new file mode 100644 index 0000000..5c9f936 Binary files /dev/null and b/project/sounds/aiy310000870.ogg differ diff --git a/project/sounds/aiy310000880.ogg b/project/sounds/aiy310000880.ogg new file mode 100644 index 0000000..0938bb7 Binary files /dev/null and b/project/sounds/aiy310000880.ogg differ diff --git a/project/sounds/aiy310000890.ogg b/project/sounds/aiy310000890.ogg new file mode 100644 index 0000000..89e43c5 Binary files /dev/null and b/project/sounds/aiy310000890.ogg differ diff --git a/project/sounds/aiy310000900.ogg b/project/sounds/aiy310000900.ogg new file mode 100644 index 0000000..e809e52 Binary files /dev/null and b/project/sounds/aiy310000900.ogg differ diff --git a/project/sounds/aiy310000910.ogg b/project/sounds/aiy310000910.ogg new file mode 100644 index 0000000..ffb6b5b Binary files /dev/null and b/project/sounds/aiy310000910.ogg differ diff --git a/project/sounds/aiy310000920.ogg b/project/sounds/aiy310000920.ogg new file mode 100644 index 0000000..f470e54 Binary files /dev/null and b/project/sounds/aiy310000920.ogg differ diff --git a/project/sounds/aiy310000930.ogg b/project/sounds/aiy310000930.ogg new file mode 100644 index 0000000..494d15f Binary files /dev/null and b/project/sounds/aiy310000930.ogg differ diff --git a/project/sounds/aiy310000940.ogg b/project/sounds/aiy310000940.ogg new file mode 100644 index 0000000..de36a9d Binary files /dev/null and b/project/sounds/aiy310000940.ogg differ diff --git a/project/sounds/aiy310000950.ogg b/project/sounds/aiy310000950.ogg new file mode 100644 index 0000000..9abfea9 Binary files /dev/null and b/project/sounds/aiy310000950.ogg differ diff --git a/project/sounds/aiy310000960.ogg b/project/sounds/aiy310000960.ogg new file mode 100644 index 0000000..394ddcb Binary files /dev/null and b/project/sounds/aiy310000960.ogg differ diff --git a/project/sounds/aiy310000970.ogg b/project/sounds/aiy310000970.ogg new file mode 100644 index 0000000..aefe802 Binary files /dev/null and b/project/sounds/aiy310000970.ogg differ diff --git a/project/sounds/aiy310000980.ogg b/project/sounds/aiy310000980.ogg new file mode 100644 index 0000000..9c7ea85 Binary files /dev/null and b/project/sounds/aiy310000980.ogg differ diff --git a/project/sounds/aiy310000990.ogg b/project/sounds/aiy310000990.ogg new file mode 100644 index 0000000..5808076 Binary files /dev/null and b/project/sounds/aiy310000990.ogg differ diff --git a/project/sounds/aiy310001000.ogg b/project/sounds/aiy310001000.ogg new file mode 100644 index 0000000..2dba8fb Binary files /dev/null and b/project/sounds/aiy310001000.ogg differ diff --git a/project/sounds/aiy310001010.ogg b/project/sounds/aiy310001010.ogg new file mode 100644 index 0000000..a647a12 Binary files /dev/null and b/project/sounds/aiy310001010.ogg differ diff --git a/project/sounds/aiy310001027.ogg b/project/sounds/aiy310001027.ogg new file mode 100644 index 0000000..9d31c17 Binary files /dev/null and b/project/sounds/aiy310001027.ogg differ diff --git a/project/sounds/aiy310001030.ogg b/project/sounds/aiy310001030.ogg new file mode 100644 index 0000000..c0f363e Binary files /dev/null and b/project/sounds/aiy310001030.ogg differ diff --git a/project/sounds/aiy310001040.ogg b/project/sounds/aiy310001040.ogg new file mode 100644 index 0000000..2d36a51 Binary files /dev/null and b/project/sounds/aiy310001040.ogg differ diff --git a/project/sounds/aiy310001050.ogg b/project/sounds/aiy310001050.ogg new file mode 100644 index 0000000..7b3d406 Binary files /dev/null and b/project/sounds/aiy310001050.ogg differ diff --git a/project/sounds/aiy310001060.ogg b/project/sounds/aiy310001060.ogg new file mode 100644 index 0000000..5a7c2c1 Binary files /dev/null and b/project/sounds/aiy310001060.ogg differ diff --git a/project/sounds/aiy310001070.ogg b/project/sounds/aiy310001070.ogg new file mode 100644 index 0000000..4ecc17a Binary files /dev/null and b/project/sounds/aiy310001070.ogg differ diff --git a/project/sounds/aiy310001080.ogg b/project/sounds/aiy310001080.ogg new file mode 100644 index 0000000..d97e943 Binary files /dev/null and b/project/sounds/aiy310001080.ogg differ diff --git a/project/sounds/aiy310001090.ogg b/project/sounds/aiy310001090.ogg new file mode 100644 index 0000000..dc60205 Binary files /dev/null and b/project/sounds/aiy310001090.ogg differ diff --git a/project/sounds/aiy310001100.ogg b/project/sounds/aiy310001100.ogg new file mode 100644 index 0000000..13d7d7d Binary files /dev/null and b/project/sounds/aiy310001100.ogg differ diff --git a/project/sounds/aiy310001110.ogg b/project/sounds/aiy310001110.ogg new file mode 100644 index 0000000..040c120 Binary files /dev/null and b/project/sounds/aiy310001110.ogg differ diff --git a/project/sounds/aiy310001120.ogg b/project/sounds/aiy310001120.ogg new file mode 100644 index 0000000..458e4f7 Binary files /dev/null and b/project/sounds/aiy310001120.ogg differ diff --git a/project/sounds/aiy310001130.ogg b/project/sounds/aiy310001130.ogg new file mode 100644 index 0000000..7daea21 Binary files /dev/null and b/project/sounds/aiy310001130.ogg differ diff --git a/project/sounds/aiy310001140.ogg b/project/sounds/aiy310001140.ogg new file mode 100644 index 0000000..7d54e19 Binary files /dev/null and b/project/sounds/aiy310001140.ogg differ diff --git a/project/sounds/aiy310001150.ogg b/project/sounds/aiy310001150.ogg new file mode 100644 index 0000000..b06bdc9 Binary files /dev/null and b/project/sounds/aiy310001150.ogg differ diff --git a/project/sounds/aiy310001160.ogg b/project/sounds/aiy310001160.ogg new file mode 100644 index 0000000..3ec510b Binary files /dev/null and b/project/sounds/aiy310001160.ogg differ diff --git a/project/sounds/aiy310001170.ogg b/project/sounds/aiy310001170.ogg new file mode 100644 index 0000000..d96b1e2 Binary files /dev/null and b/project/sounds/aiy310001170.ogg differ diff --git a/project/sounds/aiy310001180.ogg b/project/sounds/aiy310001180.ogg new file mode 100644 index 0000000..88cffb2 Binary files /dev/null and b/project/sounds/aiy310001180.ogg differ diff --git a/project/sounds/aiy310001190.ogg b/project/sounds/aiy310001190.ogg new file mode 100644 index 0000000..e35c481 Binary files /dev/null and b/project/sounds/aiy310001190.ogg differ diff --git a/project/sounds/aiy310001200.ogg b/project/sounds/aiy310001200.ogg new file mode 100644 index 0000000..9c30d38 Binary files /dev/null and b/project/sounds/aiy310001200.ogg differ diff --git a/project/sounds/aiy310001210.ogg b/project/sounds/aiy310001210.ogg new file mode 100644 index 0000000..cfe51c7 Binary files /dev/null and b/project/sounds/aiy310001210.ogg differ diff --git a/project/sounds/aiy310001220.ogg b/project/sounds/aiy310001220.ogg new file mode 100644 index 0000000..e7d5e61 Binary files /dev/null and b/project/sounds/aiy310001220.ogg differ diff --git a/project/sounds/aiy310001230.ogg b/project/sounds/aiy310001230.ogg new file mode 100644 index 0000000..4aa7064 Binary files /dev/null and b/project/sounds/aiy310001230.ogg differ diff --git a/project/sounds/aiy310001240.ogg b/project/sounds/aiy310001240.ogg new file mode 100644 index 0000000..9342811 Binary files /dev/null and b/project/sounds/aiy310001240.ogg differ diff --git a/project/sounds/aiy310001250.ogg b/project/sounds/aiy310001250.ogg new file mode 100644 index 0000000..15a6960 Binary files /dev/null and b/project/sounds/aiy310001250.ogg differ diff --git a/project/sounds/aiy310001260.ogg b/project/sounds/aiy310001260.ogg new file mode 100644 index 0000000..dab5516 Binary files /dev/null and b/project/sounds/aiy310001260.ogg differ diff --git a/project/sounds/aiy310001270.ogg b/project/sounds/aiy310001270.ogg new file mode 100644 index 0000000..d531b49 Binary files /dev/null and b/project/sounds/aiy310001270.ogg differ diff --git a/project/sounds/aiy310001280.ogg b/project/sounds/aiy310001280.ogg new file mode 100644 index 0000000..2e749a4 Binary files /dev/null and b/project/sounds/aiy310001280.ogg differ diff --git a/project/sounds/aiy310001290.ogg b/project/sounds/aiy310001290.ogg new file mode 100644 index 0000000..c2e81a6 Binary files /dev/null and b/project/sounds/aiy310001290.ogg differ diff --git a/project/sounds/aiy310001300.ogg b/project/sounds/aiy310001300.ogg new file mode 100644 index 0000000..904940f Binary files /dev/null and b/project/sounds/aiy310001300.ogg differ diff --git a/project/sounds/aiy310001310.ogg b/project/sounds/aiy310001310.ogg new file mode 100644 index 0000000..a7f25b0 Binary files /dev/null and b/project/sounds/aiy310001310.ogg differ diff --git a/project/sounds/aiy310001320.ogg b/project/sounds/aiy310001320.ogg new file mode 100644 index 0000000..1b06256 Binary files /dev/null and b/project/sounds/aiy310001320.ogg differ diff --git a/project/sounds/aiy310001330.ogg b/project/sounds/aiy310001330.ogg new file mode 100644 index 0000000..8525810 Binary files /dev/null and b/project/sounds/aiy310001330.ogg differ diff --git a/project/sounds/aiy310001340.ogg b/project/sounds/aiy310001340.ogg new file mode 100644 index 0000000..44b81fe Binary files /dev/null and b/project/sounds/aiy310001340.ogg differ diff --git a/project/sounds/aiy310001350.ogg b/project/sounds/aiy310001350.ogg new file mode 100644 index 0000000..2291f96 Binary files /dev/null and b/project/sounds/aiy310001350.ogg differ diff --git a/project/sounds/aiy310001360.ogg b/project/sounds/aiy310001360.ogg new file mode 100644 index 0000000..2114e7b Binary files /dev/null and b/project/sounds/aiy310001360.ogg differ diff --git a/project/sounds/aiy310001370.ogg b/project/sounds/aiy310001370.ogg new file mode 100644 index 0000000..d7df9be Binary files /dev/null and b/project/sounds/aiy310001370.ogg differ diff --git a/project/sounds/aiy310001380.ogg b/project/sounds/aiy310001380.ogg new file mode 100644 index 0000000..fac86f0 Binary files /dev/null and b/project/sounds/aiy310001380.ogg differ diff --git a/project/sounds/aiy310001390.ogg b/project/sounds/aiy310001390.ogg new file mode 100644 index 0000000..e543b6f Binary files /dev/null and b/project/sounds/aiy310001390.ogg differ diff --git a/project/sounds/aiy320000010.ogg b/project/sounds/aiy320000010.ogg new file mode 100644 index 0000000..54d6db5 Binary files /dev/null and b/project/sounds/aiy320000010.ogg differ diff --git a/project/sounds/aiy320000020.ogg b/project/sounds/aiy320000020.ogg new file mode 100644 index 0000000..d98d94e Binary files /dev/null and b/project/sounds/aiy320000020.ogg differ diff --git a/project/sounds/aiy320000030.ogg b/project/sounds/aiy320000030.ogg new file mode 100644 index 0000000..574f903 Binary files /dev/null and b/project/sounds/aiy320000030.ogg differ diff --git a/project/sounds/aiy320000040.ogg b/project/sounds/aiy320000040.ogg new file mode 100644 index 0000000..613c27f Binary files /dev/null and b/project/sounds/aiy320000040.ogg differ diff --git a/project/sounds/aiy320000050.ogg b/project/sounds/aiy320000050.ogg new file mode 100644 index 0000000..b35ca98 Binary files /dev/null and b/project/sounds/aiy320000050.ogg differ diff --git a/project/sounds/aiy320000060.ogg b/project/sounds/aiy320000060.ogg new file mode 100644 index 0000000..0365def Binary files /dev/null and b/project/sounds/aiy320000060.ogg differ diff --git a/project/sounds/aiy320000070.ogg b/project/sounds/aiy320000070.ogg new file mode 100644 index 0000000..52e3d11 Binary files /dev/null and b/project/sounds/aiy320000070.ogg differ diff --git a/project/sounds/aiy320000080.ogg b/project/sounds/aiy320000080.ogg new file mode 100644 index 0000000..9a2afef Binary files /dev/null and b/project/sounds/aiy320000080.ogg differ diff --git a/project/sounds/aiy320000090.ogg b/project/sounds/aiy320000090.ogg new file mode 100644 index 0000000..608f2e1 Binary files /dev/null and b/project/sounds/aiy320000090.ogg differ diff --git a/project/sounds/aiy320000100.ogg b/project/sounds/aiy320000100.ogg new file mode 100644 index 0000000..b97a61c Binary files /dev/null and b/project/sounds/aiy320000100.ogg differ diff --git a/project/sounds/aiy320000110.ogg b/project/sounds/aiy320000110.ogg new file mode 100644 index 0000000..f15348f Binary files /dev/null and b/project/sounds/aiy320000110.ogg differ diff --git a/project/sounds/aiy320000120.ogg b/project/sounds/aiy320000120.ogg new file mode 100644 index 0000000..3adda1d Binary files /dev/null and b/project/sounds/aiy320000120.ogg differ diff --git a/project/sounds/aiy320000135.ogg b/project/sounds/aiy320000135.ogg new file mode 100644 index 0000000..79ed386 Binary files /dev/null and b/project/sounds/aiy320000135.ogg differ diff --git a/project/sounds/aiy320000140.ogg b/project/sounds/aiy320000140.ogg new file mode 100644 index 0000000..0b7add2 Binary files /dev/null and b/project/sounds/aiy320000140.ogg differ diff --git a/project/sounds/aiy340000010.ogg b/project/sounds/aiy340000010.ogg new file mode 100644 index 0000000..1687505 Binary files /dev/null and b/project/sounds/aiy340000010.ogg differ diff --git a/project/sounds/aiy340000020.ogg b/project/sounds/aiy340000020.ogg new file mode 100644 index 0000000..f05a1e8 Binary files /dev/null and b/project/sounds/aiy340000020.ogg differ diff --git a/project/sounds/aiy340000030.ogg b/project/sounds/aiy340000030.ogg new file mode 100644 index 0000000..915b664 Binary files /dev/null and b/project/sounds/aiy340000030.ogg differ diff --git a/project/sounds/aiy340000040.ogg b/project/sounds/aiy340000040.ogg new file mode 100644 index 0000000..72259c5 Binary files /dev/null and b/project/sounds/aiy340000040.ogg differ diff --git a/project/sounds/aiy340000050.ogg b/project/sounds/aiy340000050.ogg new file mode 100644 index 0000000..ca136d2 Binary files /dev/null and b/project/sounds/aiy340000050.ogg differ diff --git a/project/sounds/aiy340000060.ogg b/project/sounds/aiy340000060.ogg new file mode 100644 index 0000000..8bcb94b Binary files /dev/null and b/project/sounds/aiy340000060.ogg differ diff --git a/project/sounds/aiy340000070.ogg b/project/sounds/aiy340000070.ogg new file mode 100644 index 0000000..364be3b Binary files /dev/null and b/project/sounds/aiy340000070.ogg differ diff --git a/project/sounds/aiy340000080.ogg b/project/sounds/aiy340000080.ogg new file mode 100644 index 0000000..6e6f1da Binary files /dev/null and b/project/sounds/aiy340000080.ogg differ diff --git a/project/sounds/aiy340000090.ogg b/project/sounds/aiy340000090.ogg new file mode 100644 index 0000000..1da2a78 Binary files /dev/null and b/project/sounds/aiy340000090.ogg differ diff --git a/project/sounds/aiy340000100.ogg b/project/sounds/aiy340000100.ogg new file mode 100644 index 0000000..718db86 Binary files /dev/null and b/project/sounds/aiy340000100.ogg differ diff --git a/project/sounds/aiy340000110.ogg b/project/sounds/aiy340000110.ogg new file mode 100644 index 0000000..46d5be6 Binary files /dev/null and b/project/sounds/aiy340000110.ogg differ diff --git a/project/sounds/aiy340000120.ogg b/project/sounds/aiy340000120.ogg new file mode 100644 index 0000000..f1003c3 Binary files /dev/null and b/project/sounds/aiy340000120.ogg differ diff --git a/project/sounds/aiy340000140.ogg b/project/sounds/aiy340000140.ogg new file mode 100644 index 0000000..7a475e9 Binary files /dev/null and b/project/sounds/aiy340000140.ogg differ diff --git a/project/sounds/aiy340000150.ogg b/project/sounds/aiy340000150.ogg new file mode 100644 index 0000000..01b5107 Binary files /dev/null and b/project/sounds/aiy340000150.ogg differ diff --git a/project/sounds/aiy340000160.ogg b/project/sounds/aiy340000160.ogg new file mode 100644 index 0000000..710abca Binary files /dev/null and b/project/sounds/aiy340000160.ogg differ diff --git a/project/sounds/aiy340000170.ogg b/project/sounds/aiy340000170.ogg new file mode 100644 index 0000000..7fc073b Binary files /dev/null and b/project/sounds/aiy340000170.ogg differ diff --git a/project/sounds/aiy340000180.ogg b/project/sounds/aiy340000180.ogg new file mode 100644 index 0000000..575d8b4 Binary files /dev/null and b/project/sounds/aiy340000180.ogg differ diff --git a/project/sounds/aiy340000190.ogg b/project/sounds/aiy340000190.ogg new file mode 100644 index 0000000..155b411 Binary files /dev/null and b/project/sounds/aiy340000190.ogg differ diff --git a/project/sounds/aiy340000200.ogg b/project/sounds/aiy340000200.ogg new file mode 100644 index 0000000..bf6dc4a Binary files /dev/null and b/project/sounds/aiy340000200.ogg differ diff --git a/project/sounds/aiy340000210.ogg b/project/sounds/aiy340000210.ogg new file mode 100644 index 0000000..3b4e1b1 Binary files /dev/null and b/project/sounds/aiy340000210.ogg differ diff --git a/project/sounds/aiy340000220.ogg b/project/sounds/aiy340000220.ogg new file mode 100644 index 0000000..1b46e59 Binary files /dev/null and b/project/sounds/aiy340000220.ogg differ diff --git a/project/sounds/aiy340000230.ogg b/project/sounds/aiy340000230.ogg new file mode 100644 index 0000000..a2462c7 Binary files /dev/null and b/project/sounds/aiy340000230.ogg differ diff --git a/project/sounds/aiy340000240.ogg b/project/sounds/aiy340000240.ogg new file mode 100644 index 0000000..91690e5 Binary files /dev/null and b/project/sounds/aiy340000240.ogg differ diff --git a/project/sounds/aiy340000250.ogg b/project/sounds/aiy340000250.ogg new file mode 100644 index 0000000..321f997 Binary files /dev/null and b/project/sounds/aiy340000250.ogg differ diff --git a/project/sounds/aiy340000260.ogg b/project/sounds/aiy340000260.ogg new file mode 100644 index 0000000..137c284 Binary files /dev/null and b/project/sounds/aiy340000260.ogg differ diff --git a/project/sounds/aiy340000270.ogg b/project/sounds/aiy340000270.ogg new file mode 100644 index 0000000..b94bbb4 Binary files /dev/null and b/project/sounds/aiy340000270.ogg differ diff --git a/project/sounds/aiy340000280.ogg b/project/sounds/aiy340000280.ogg new file mode 100644 index 0000000..e685598 Binary files /dev/null and b/project/sounds/aiy340000280.ogg differ diff --git a/project/sounds/aiy340000290.ogg b/project/sounds/aiy340000290.ogg new file mode 100644 index 0000000..6965511 Binary files /dev/null and b/project/sounds/aiy340000290.ogg differ diff --git a/project/sounds/aiy340000300.ogg b/project/sounds/aiy340000300.ogg new file mode 100644 index 0000000..f0c9ccd Binary files /dev/null and b/project/sounds/aiy340000300.ogg differ diff --git a/project/sounds/aiy340000310.ogg b/project/sounds/aiy340000310.ogg new file mode 100644 index 0000000..886e7ba Binary files /dev/null and b/project/sounds/aiy340000310.ogg differ diff --git a/project/sounds/aiy340000320.ogg b/project/sounds/aiy340000320.ogg new file mode 100644 index 0000000..c7b1ab1 Binary files /dev/null and b/project/sounds/aiy340000320.ogg differ diff --git a/project/sounds/aiy340000330.ogg b/project/sounds/aiy340000330.ogg new file mode 100644 index 0000000..b07b430 Binary files /dev/null and b/project/sounds/aiy340000330.ogg differ diff --git a/project/sounds/aiy340000340.ogg b/project/sounds/aiy340000340.ogg new file mode 100644 index 0000000..07fab33 Binary files /dev/null and b/project/sounds/aiy340000340.ogg differ diff --git a/project/sounds/aiy340000350.ogg b/project/sounds/aiy340000350.ogg new file mode 100644 index 0000000..4fff4de Binary files /dev/null and b/project/sounds/aiy340000350.ogg differ diff --git a/project/sounds/aiy340000360.ogg b/project/sounds/aiy340000360.ogg new file mode 100644 index 0000000..1d9fa8f Binary files /dev/null and b/project/sounds/aiy340000360.ogg differ diff --git a/project/sounds/aiy340000370.ogg b/project/sounds/aiy340000370.ogg new file mode 100644 index 0000000..a0e6e1e Binary files /dev/null and b/project/sounds/aiy340000370.ogg differ diff --git a/project/sounds/aiy340000380.ogg b/project/sounds/aiy340000380.ogg new file mode 100644 index 0000000..0f4b917 Binary files /dev/null and b/project/sounds/aiy340000380.ogg differ diff --git a/project/sounds/aiy340000390.ogg b/project/sounds/aiy340000390.ogg new file mode 100644 index 0000000..021d193 Binary files /dev/null and b/project/sounds/aiy340000390.ogg differ diff --git a/project/sounds/aiy340000400.ogg b/project/sounds/aiy340000400.ogg new file mode 100644 index 0000000..3f217a7 Binary files /dev/null and b/project/sounds/aiy340000400.ogg differ diff --git a/project/sounds/aiy340000410.ogg b/project/sounds/aiy340000410.ogg new file mode 100644 index 0000000..95f46c9 Binary files /dev/null and b/project/sounds/aiy340000410.ogg differ diff --git a/project/sounds/aiy340000420.ogg b/project/sounds/aiy340000420.ogg new file mode 100644 index 0000000..7ed6067 Binary files /dev/null and b/project/sounds/aiy340000420.ogg differ diff --git a/project/sounds/aiy340000430.ogg b/project/sounds/aiy340000430.ogg new file mode 100644 index 0000000..cfc1202 Binary files /dev/null and b/project/sounds/aiy340000430.ogg differ diff --git a/project/sounds/aiy350000010.mp3 b/project/sounds/aiy350000010.mp3 deleted file mode 100644 index 57c17f9..0000000 Binary files a/project/sounds/aiy350000010.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000010.opus b/project/sounds/aiy350000010.opus new file mode 100644 index 0000000..0f41912 Binary files /dev/null and b/project/sounds/aiy350000010.opus differ diff --git a/project/sounds/aiy350000020.mp3 b/project/sounds/aiy350000020.mp3 deleted file mode 100644 index 6ebb9bc..0000000 Binary files a/project/sounds/aiy350000020.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000020.opus b/project/sounds/aiy350000020.opus new file mode 100644 index 0000000..b99c603 Binary files /dev/null and b/project/sounds/aiy350000020.opus differ diff --git a/project/sounds/aiy350000030.mp3 b/project/sounds/aiy350000030.mp3 deleted file mode 100644 index 2f57a03..0000000 Binary files a/project/sounds/aiy350000030.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000030.opus b/project/sounds/aiy350000030.opus new file mode 100644 index 0000000..773d947 Binary files /dev/null and b/project/sounds/aiy350000030.opus differ diff --git a/project/sounds/aiy350000040.mp3 b/project/sounds/aiy350000040.mp3 deleted file mode 100644 index 13d4523..0000000 Binary files a/project/sounds/aiy350000040.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000040.opus b/project/sounds/aiy350000040.opus new file mode 100644 index 0000000..df657bf Binary files /dev/null and b/project/sounds/aiy350000040.opus differ diff --git a/project/sounds/aiy350000050.mp3 b/project/sounds/aiy350000050.mp3 deleted file mode 100644 index 5c763e4..0000000 Binary files a/project/sounds/aiy350000050.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000050.opus b/project/sounds/aiy350000050.opus new file mode 100644 index 0000000..d520d2e Binary files /dev/null and b/project/sounds/aiy350000050.opus differ diff --git a/project/sounds/aiy350000060.mp3 b/project/sounds/aiy350000060.mp3 deleted file mode 100644 index 790d096..0000000 Binary files a/project/sounds/aiy350000060.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000060.opus b/project/sounds/aiy350000060.opus new file mode 100644 index 0000000..47f1642 Binary files /dev/null and b/project/sounds/aiy350000060.opus differ diff --git a/project/sounds/aiy350000070.mp3 b/project/sounds/aiy350000070.mp3 deleted file mode 100644 index 236c48a..0000000 Binary files a/project/sounds/aiy350000070.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000070.opus b/project/sounds/aiy350000070.opus new file mode 100644 index 0000000..b02685c Binary files /dev/null and b/project/sounds/aiy350000070.opus differ diff --git a/project/sounds/aiy350000080.mp3 b/project/sounds/aiy350000080.mp3 deleted file mode 100644 index f6753db..0000000 Binary files a/project/sounds/aiy350000080.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000080.opus b/project/sounds/aiy350000080.opus new file mode 100644 index 0000000..868a458 Binary files /dev/null and b/project/sounds/aiy350000080.opus differ diff --git a/project/sounds/aiy350000090.mp3 b/project/sounds/aiy350000090.mp3 deleted file mode 100644 index 869aea1..0000000 Binary files a/project/sounds/aiy350000090.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000090.opus b/project/sounds/aiy350000090.opus new file mode 100644 index 0000000..26a24b1 Binary files /dev/null and b/project/sounds/aiy350000090.opus differ diff --git a/project/sounds/aiy350000100.mp3 b/project/sounds/aiy350000100.mp3 deleted file mode 100644 index f87b58f..0000000 Binary files a/project/sounds/aiy350000100.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000100.opus b/project/sounds/aiy350000100.opus new file mode 100644 index 0000000..45199fe Binary files /dev/null and b/project/sounds/aiy350000100.opus differ diff --git a/project/sounds/aiy350000110.mp3 b/project/sounds/aiy350000110.mp3 deleted file mode 100644 index 553ac12..0000000 Binary files a/project/sounds/aiy350000110.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000110.opus b/project/sounds/aiy350000110.opus new file mode 100644 index 0000000..ef10116 Binary files /dev/null and b/project/sounds/aiy350000110.opus differ diff --git a/project/sounds/aiy350000120.mp3 b/project/sounds/aiy350000120.mp3 deleted file mode 100644 index 57f9899..0000000 Binary files a/project/sounds/aiy350000120.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000120.opus b/project/sounds/aiy350000120.opus new file mode 100644 index 0000000..5c9fd50 Binary files /dev/null and b/project/sounds/aiy350000120.opus differ diff --git a/project/sounds/aiy350000130.mp3 b/project/sounds/aiy350000130.mp3 deleted file mode 100644 index 62e68dc..0000000 Binary files a/project/sounds/aiy350000130.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000130.opus b/project/sounds/aiy350000130.opus new file mode 100644 index 0000000..c07b760 Binary files /dev/null and b/project/sounds/aiy350000130.opus differ diff --git a/project/sounds/aiy350000140.mp3 b/project/sounds/aiy350000140.mp3 deleted file mode 100644 index b4ff73c..0000000 Binary files a/project/sounds/aiy350000140.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000140.opus b/project/sounds/aiy350000140.opus new file mode 100644 index 0000000..50ddd6d Binary files /dev/null and b/project/sounds/aiy350000140.opus differ diff --git a/project/sounds/aiy350000150.mp3 b/project/sounds/aiy350000150.mp3 deleted file mode 100644 index b8d9ce2..0000000 Binary files a/project/sounds/aiy350000150.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000150.opus b/project/sounds/aiy350000150.opus new file mode 100644 index 0000000..7626306 Binary files /dev/null and b/project/sounds/aiy350000150.opus differ diff --git a/project/sounds/aiy350000160.mp3 b/project/sounds/aiy350000160.mp3 deleted file mode 100644 index 563717f..0000000 Binary files a/project/sounds/aiy350000160.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000160.opus b/project/sounds/aiy350000160.opus new file mode 100644 index 0000000..6a0e778 Binary files /dev/null and b/project/sounds/aiy350000160.opus differ diff --git a/project/sounds/aiy350000170.mp3 b/project/sounds/aiy350000170.mp3 deleted file mode 100644 index 23266c1..0000000 Binary files a/project/sounds/aiy350000170.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000170.opus b/project/sounds/aiy350000170.opus new file mode 100644 index 0000000..264c29b Binary files /dev/null and b/project/sounds/aiy350000170.opus differ diff --git a/project/sounds/aiy350000180.mp3 b/project/sounds/aiy350000180.mp3 deleted file mode 100644 index 0a52d64..0000000 Binary files a/project/sounds/aiy350000180.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000180.opus b/project/sounds/aiy350000180.opus new file mode 100644 index 0000000..f30c59e Binary files /dev/null and b/project/sounds/aiy350000180.opus differ diff --git a/project/sounds/aiy350000190.mp3 b/project/sounds/aiy350000190.mp3 deleted file mode 100644 index 5379fbb..0000000 Binary files a/project/sounds/aiy350000190.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000190.opus b/project/sounds/aiy350000190.opus new file mode 100644 index 0000000..c2a045a Binary files /dev/null and b/project/sounds/aiy350000190.opus differ diff --git a/project/sounds/aiy350000200.mp3 b/project/sounds/aiy350000200.mp3 deleted file mode 100644 index 7bf86fd..0000000 Binary files a/project/sounds/aiy350000200.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000200.opus b/project/sounds/aiy350000200.opus new file mode 100644 index 0000000..d964326 Binary files /dev/null and b/project/sounds/aiy350000200.opus differ diff --git a/project/sounds/aiy350000210.mp3 b/project/sounds/aiy350000210.mp3 deleted file mode 100644 index 01426ec..0000000 Binary files a/project/sounds/aiy350000210.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000210.opus b/project/sounds/aiy350000210.opus new file mode 100644 index 0000000..dcf95ec Binary files /dev/null and b/project/sounds/aiy350000210.opus differ diff --git a/project/sounds/aiy350000220.mp3 b/project/sounds/aiy350000220.mp3 deleted file mode 100644 index 7687c76..0000000 Binary files a/project/sounds/aiy350000220.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000220.opus b/project/sounds/aiy350000220.opus new file mode 100644 index 0000000..ba965cf Binary files /dev/null and b/project/sounds/aiy350000220.opus differ diff --git a/project/sounds/aiy350000230.mp3 b/project/sounds/aiy350000230.mp3 deleted file mode 100644 index ef72218..0000000 Binary files a/project/sounds/aiy350000230.mp3 and /dev/null differ diff --git a/project/sounds/aiy350000230.opus b/project/sounds/aiy350000230.opus new file mode 100644 index 0000000..88cd8a9 Binary files /dev/null and b/project/sounds/aiy350000230.opus differ diff --git a/project/sounds/aiy350000240.ogg b/project/sounds/aiy350000240.ogg new file mode 100644 index 0000000..e549bdd Binary files /dev/null and b/project/sounds/aiy350000240.ogg differ diff --git a/project/sounds/aiy350000250.ogg b/project/sounds/aiy350000250.ogg new file mode 100644 index 0000000..3994c71 Binary files /dev/null and b/project/sounds/aiy350000250.ogg differ diff --git a/project/sounds/aiy350000260.ogg b/project/sounds/aiy350000260.ogg new file mode 100644 index 0000000..f8e3492 Binary files /dev/null and b/project/sounds/aiy350000260.ogg differ diff --git a/project/sounds/aiy430000010.ogg b/project/sounds/aiy430000010.ogg new file mode 100644 index 0000000..356ddcd Binary files /dev/null and b/project/sounds/aiy430000010.ogg differ diff --git a/project/sounds/aiy430000020.ogg b/project/sounds/aiy430000020.ogg new file mode 100644 index 0000000..9efe052 Binary files /dev/null and b/project/sounds/aiy430000020.ogg differ diff --git a/project/sounds/aiy430000030.ogg b/project/sounds/aiy430000030.ogg new file mode 100644 index 0000000..c67ff9b Binary files /dev/null and b/project/sounds/aiy430000030.ogg differ diff --git a/project/sounds/aiy430000040.ogg b/project/sounds/aiy430000040.ogg new file mode 100644 index 0000000..b05463e Binary files /dev/null and b/project/sounds/aiy430000040.ogg differ diff --git a/project/sounds/aiy430000050.ogg b/project/sounds/aiy430000050.ogg new file mode 100644 index 0000000..5374b90 Binary files /dev/null and b/project/sounds/aiy430000050.ogg differ diff --git a/project/sounds/aiy430000060.ogg b/project/sounds/aiy430000060.ogg new file mode 100644 index 0000000..6b44c40 Binary files /dev/null and b/project/sounds/aiy430000060.ogg differ diff --git a/project/sounds/aiy430000070.ogg b/project/sounds/aiy430000070.ogg new file mode 100644 index 0000000..68fbcc8 Binary files /dev/null and b/project/sounds/aiy430000070.ogg differ diff --git a/project/sounds/aiy430000080.ogg b/project/sounds/aiy430000080.ogg new file mode 100644 index 0000000..f3ab8e1 Binary files /dev/null and b/project/sounds/aiy430000080.ogg differ diff --git a/project/sounds/aiy430000090.ogg b/project/sounds/aiy430000090.ogg new file mode 100644 index 0000000..a0487d9 Binary files /dev/null and b/project/sounds/aiy430000090.ogg differ diff --git a/project/sounds/aiy430000100.ogg b/project/sounds/aiy430000100.ogg new file mode 100644 index 0000000..3b111ed Binary files /dev/null and b/project/sounds/aiy430000100.ogg differ diff --git a/project/sounds/aiy430000110.ogg b/project/sounds/aiy430000110.ogg new file mode 100644 index 0000000..472e8ea Binary files /dev/null and b/project/sounds/aiy430000110.ogg differ diff --git a/project/sounds/aiy430000120.ogg b/project/sounds/aiy430000120.ogg new file mode 100644 index 0000000..16e11b0 Binary files /dev/null and b/project/sounds/aiy430000120.ogg differ diff --git a/project/sounds/aiy430000130.ogg b/project/sounds/aiy430000130.ogg new file mode 100644 index 0000000..87aaa6e Binary files /dev/null and b/project/sounds/aiy430000130.ogg differ diff --git a/project/sounds/aiy430000140.ogg b/project/sounds/aiy430000140.ogg new file mode 100644 index 0000000..460a7de Binary files /dev/null and b/project/sounds/aiy430000140.ogg differ diff --git a/project/sounds/aiy430000150.ogg b/project/sounds/aiy430000150.ogg new file mode 100644 index 0000000..a33a5bd Binary files /dev/null and b/project/sounds/aiy430000150.ogg differ diff --git a/project/sounds/aiy430000160.ogg b/project/sounds/aiy430000160.ogg new file mode 100644 index 0000000..24971e2 Binary files /dev/null and b/project/sounds/aiy430000160.ogg differ diff --git a/project/sounds/aiy430000170.ogg b/project/sounds/aiy430000170.ogg new file mode 100644 index 0000000..a76c57b Binary files /dev/null and b/project/sounds/aiy430000170.ogg differ diff --git a/project/sounds/aiy430000180.ogg b/project/sounds/aiy430000180.ogg new file mode 100644 index 0000000..aaf40ca Binary files /dev/null and b/project/sounds/aiy430000180.ogg differ diff --git a/project/sounds/aiy430000190.ogg b/project/sounds/aiy430000190.ogg new file mode 100644 index 0000000..81ef542 Binary files /dev/null and b/project/sounds/aiy430000190.ogg differ diff --git a/project/sounds/aiy430000200.ogg b/project/sounds/aiy430000200.ogg new file mode 100644 index 0000000..57f8c8d Binary files /dev/null and b/project/sounds/aiy430000200.ogg differ diff --git a/project/sounds/aiy430000210.ogg b/project/sounds/aiy430000210.ogg new file mode 100644 index 0000000..6a02c00 Binary files /dev/null and b/project/sounds/aiy430000210.ogg differ diff --git a/project/sounds/aiy430000220.ogg b/project/sounds/aiy430000220.ogg new file mode 100644 index 0000000..cc0e4be Binary files /dev/null and b/project/sounds/aiy430000220.ogg differ diff --git a/project/sounds/aiy430000230.ogg b/project/sounds/aiy430000230.ogg new file mode 100644 index 0000000..a8ef1f3 Binary files /dev/null and b/project/sounds/aiy430000230.ogg differ diff --git a/project/sounds/aiy430000240.ogg b/project/sounds/aiy430000240.ogg new file mode 100644 index 0000000..6236846 Binary files /dev/null and b/project/sounds/aiy430000240.ogg differ diff --git a/project/sounds/aiy430000250.ogg b/project/sounds/aiy430000250.ogg new file mode 100644 index 0000000..806ecfb Binary files /dev/null and b/project/sounds/aiy430000250.ogg differ diff --git a/project/sounds/aiy430000260.ogg b/project/sounds/aiy430000260.ogg new file mode 100644 index 0000000..8872913 Binary files /dev/null and b/project/sounds/aiy430000260.ogg differ diff --git a/project/sounds/aiy430000270.ogg b/project/sounds/aiy430000270.ogg new file mode 100644 index 0000000..2d61e3e Binary files /dev/null and b/project/sounds/aiy430000270.ogg differ diff --git a/project/sounds/aiy430000280.ogg b/project/sounds/aiy430000280.ogg new file mode 100644 index 0000000..142bcbe Binary files /dev/null and b/project/sounds/aiy430000280.ogg differ diff --git a/project/sounds/aiy430000290.ogg b/project/sounds/aiy430000290.ogg new file mode 100644 index 0000000..808500c Binary files /dev/null and b/project/sounds/aiy430000290.ogg differ diff --git a/project/sounds/aiy440000010.ogg b/project/sounds/aiy440000010.ogg new file mode 100644 index 0000000..a8dad86 Binary files /dev/null and b/project/sounds/aiy440000010.ogg differ diff --git a/project/sounds/aiy440000020.ogg b/project/sounds/aiy440000020.ogg new file mode 100644 index 0000000..c9a14fd Binary files /dev/null and b/project/sounds/aiy440000020.ogg differ diff --git a/project/sounds/aiy440000030.ogg b/project/sounds/aiy440000030.ogg new file mode 100644 index 0000000..fe311cc Binary files /dev/null and b/project/sounds/aiy440000030.ogg differ diff --git a/project/sounds/aiy440000040.ogg b/project/sounds/aiy440000040.ogg new file mode 100644 index 0000000..2b98283 Binary files /dev/null and b/project/sounds/aiy440000040.ogg differ diff --git a/project/sounds/aiy440000050.ogg b/project/sounds/aiy440000050.ogg new file mode 100644 index 0000000..65e8f38 Binary files /dev/null and b/project/sounds/aiy440000050.ogg differ diff --git a/project/sounds/aiy440000060.ogg b/project/sounds/aiy440000060.ogg new file mode 100644 index 0000000..7911ca1 Binary files /dev/null and b/project/sounds/aiy440000060.ogg differ diff --git a/project/sounds/aiy440000070.ogg b/project/sounds/aiy440000070.ogg new file mode 100644 index 0000000..79ceecd Binary files /dev/null and b/project/sounds/aiy440000070.ogg differ diff --git a/project/sounds/aiy440000080.ogg b/project/sounds/aiy440000080.ogg new file mode 100644 index 0000000..d165741 Binary files /dev/null and b/project/sounds/aiy440000080.ogg differ diff --git a/project/sounds/aiy440000090.ogg b/project/sounds/aiy440000090.ogg new file mode 100644 index 0000000..816a91f Binary files /dev/null and b/project/sounds/aiy440000090.ogg differ diff --git a/project/sounds/aiy440000100.ogg b/project/sounds/aiy440000100.ogg new file mode 100644 index 0000000..e0cbe17 Binary files /dev/null and b/project/sounds/aiy440000100.ogg differ diff --git a/project/sounds/aiy440000110.ogg b/project/sounds/aiy440000110.ogg new file mode 100644 index 0000000..475cf95 Binary files /dev/null and b/project/sounds/aiy440000110.ogg differ diff --git a/project/sounds/aiy440000120.ogg b/project/sounds/aiy440000120.ogg new file mode 100644 index 0000000..ebdc162 Binary files /dev/null and b/project/sounds/aiy440000120.ogg differ diff --git a/project/sounds/aiy510000010.ogg b/project/sounds/aiy510000010.ogg new file mode 100644 index 0000000..5ab3fc0 Binary files /dev/null and b/project/sounds/aiy510000010.ogg differ diff --git a/project/sounds/aiy510000020.ogg b/project/sounds/aiy510000020.ogg new file mode 100644 index 0000000..57f77d7 Binary files /dev/null and b/project/sounds/aiy510000020.ogg differ diff --git a/project/sounds/aiy710000010.mp3 b/project/sounds/aiy710000010.mp3 deleted file mode 100644 index 6e08794..0000000 Binary files a/project/sounds/aiy710000010.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000010.opus b/project/sounds/aiy710000010.opus new file mode 100644 index 0000000..bcf6341 Binary files /dev/null and b/project/sounds/aiy710000010.opus differ diff --git a/project/sounds/aiy710000020.mp3 b/project/sounds/aiy710000020.mp3 deleted file mode 100644 index d025b23..0000000 Binary files a/project/sounds/aiy710000020.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000020.opus b/project/sounds/aiy710000020.opus new file mode 100644 index 0000000..f4de94a Binary files /dev/null and b/project/sounds/aiy710000020.opus differ diff --git a/project/sounds/aiy710000030.mp3 b/project/sounds/aiy710000030.mp3 deleted file mode 100644 index ad200f2..0000000 Binary files a/project/sounds/aiy710000030.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000030.opus b/project/sounds/aiy710000030.opus new file mode 100644 index 0000000..c6f5d74 Binary files /dev/null and b/project/sounds/aiy710000030.opus differ diff --git a/project/sounds/aiy710000040.mp3 b/project/sounds/aiy710000040.mp3 deleted file mode 100644 index dbdbbd2..0000000 Binary files a/project/sounds/aiy710000040.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000040.opus b/project/sounds/aiy710000040.opus new file mode 100644 index 0000000..02e9b14 Binary files /dev/null and b/project/sounds/aiy710000040.opus differ diff --git a/project/sounds/aiy710000050.mp3 b/project/sounds/aiy710000050.mp3 deleted file mode 100644 index f304d67..0000000 Binary files a/project/sounds/aiy710000050.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000050.opus b/project/sounds/aiy710000050.opus new file mode 100644 index 0000000..a37c230 Binary files /dev/null and b/project/sounds/aiy710000050.opus differ diff --git a/project/sounds/aiy710000060.mp3 b/project/sounds/aiy710000060.mp3 deleted file mode 100644 index 1366af4..0000000 Binary files a/project/sounds/aiy710000060.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000060.opus b/project/sounds/aiy710000060.opus new file mode 100644 index 0000000..2fae4fc Binary files /dev/null and b/project/sounds/aiy710000060.opus differ diff --git a/project/sounds/aiy710000070.mp3 b/project/sounds/aiy710000070.mp3 deleted file mode 100644 index 1528e54..0000000 Binary files a/project/sounds/aiy710000070.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000070.opus b/project/sounds/aiy710000070.opus new file mode 100644 index 0000000..ce2b71c Binary files /dev/null and b/project/sounds/aiy710000070.opus differ diff --git a/project/sounds/aiy710000080.mp3 b/project/sounds/aiy710000080.mp3 deleted file mode 100644 index 600011d..0000000 Binary files a/project/sounds/aiy710000080.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000080.opus b/project/sounds/aiy710000080.opus new file mode 100644 index 0000000..0673c92 Binary files /dev/null and b/project/sounds/aiy710000080.opus differ diff --git a/project/sounds/aiy710000090.mp3 b/project/sounds/aiy710000090.mp3 deleted file mode 100644 index b091686..0000000 Binary files a/project/sounds/aiy710000090.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000090.opus b/project/sounds/aiy710000090.opus new file mode 100644 index 0000000..9990f15 Binary files /dev/null and b/project/sounds/aiy710000090.opus differ diff --git a/project/sounds/aiy710000100.mp3 b/project/sounds/aiy710000100.mp3 deleted file mode 100644 index 3f84955..0000000 Binary files a/project/sounds/aiy710000100.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000100.opus b/project/sounds/aiy710000100.opus new file mode 100644 index 0000000..28b109b Binary files /dev/null and b/project/sounds/aiy710000100.opus differ diff --git a/project/sounds/aiy710000110.mp3 b/project/sounds/aiy710000110.mp3 deleted file mode 100644 index 1095ffa..0000000 Binary files a/project/sounds/aiy710000110.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000110.opus b/project/sounds/aiy710000110.opus new file mode 100644 index 0000000..ad02c45 Binary files /dev/null and b/project/sounds/aiy710000110.opus differ diff --git a/project/sounds/aiy710000120.mp3 b/project/sounds/aiy710000120.mp3 deleted file mode 100644 index 81be490..0000000 Binary files a/project/sounds/aiy710000120.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000120.opus b/project/sounds/aiy710000120.opus new file mode 100644 index 0000000..0985ea1 Binary files /dev/null and b/project/sounds/aiy710000120.opus differ diff --git a/project/sounds/aiy710000130.mp3 b/project/sounds/aiy710000130.mp3 deleted file mode 100644 index bde952f..0000000 Binary files a/project/sounds/aiy710000130.mp3 and /dev/null differ diff --git a/project/sounds/aiy710000130.opus b/project/sounds/aiy710000130.opus new file mode 100644 index 0000000..07881d1 Binary files /dev/null and b/project/sounds/aiy710000130.opus differ diff --git a/project/sounds/aiy720000010.ogg b/project/sounds/aiy720000010.ogg new file mode 100644 index 0000000..5ae9b67 Binary files /dev/null and b/project/sounds/aiy720000010.ogg differ diff --git a/project/sounds/aiy730000010.ogg b/project/sounds/aiy730000010.ogg new file mode 100644 index 0000000..ab0d410 Binary files /dev/null and b/project/sounds/aiy730000010.ogg differ diff --git a/project/sounds/aiy740000010.ogg b/project/sounds/aiy740000010.ogg new file mode 100644 index 0000000..b5b010f Binary files /dev/null and b/project/sounds/aiy740000010.ogg differ diff --git a/project/sounds/aiy750000010.ogg b/project/sounds/aiy750000010.ogg new file mode 100644 index 0000000..0b8ceb4 Binary files /dev/null and b/project/sounds/aiy750000010.ogg differ diff --git a/project/sounds/aiy750000020.ogg b/project/sounds/aiy750000020.ogg new file mode 100644 index 0000000..f260c12 Binary files /dev/null and b/project/sounds/aiy750000020.ogg differ diff --git a/project/sounds/aiy750000030.ogg b/project/sounds/aiy750000030.ogg new file mode 100644 index 0000000..93faa55 Binary files /dev/null and b/project/sounds/aiy750000030.ogg differ diff --git a/project/sounds/aiy750000040.ogg b/project/sounds/aiy750000040.ogg new file mode 100644 index 0000000..7592d4b Binary files /dev/null and b/project/sounds/aiy750000040.ogg differ diff --git a/project/sounds/aiy750000050.ogg b/project/sounds/aiy750000050.ogg new file mode 100644 index 0000000..bf95779 Binary files /dev/null and b/project/sounds/aiy750000050.ogg differ diff --git a/project/sounds/aiy750000060.ogg b/project/sounds/aiy750000060.ogg new file mode 100644 index 0000000..b0f81b8 Binary files /dev/null and b/project/sounds/aiy750000060.ogg differ diff --git a/project/sounds/aiy750000070.ogg b/project/sounds/aiy750000070.ogg new file mode 100644 index 0000000..d2edb4d Binary files /dev/null and b/project/sounds/aiy750000070.ogg differ diff --git a/project/sounds/aiy750000080.ogg b/project/sounds/aiy750000080.ogg new file mode 100644 index 0000000..a0ffff8 Binary files /dev/null and b/project/sounds/aiy750000080.ogg differ diff --git a/project/sounds/aiy750000090.ogg b/project/sounds/aiy750000090.ogg new file mode 100644 index 0000000..aefcdb3 Binary files /dev/null and b/project/sounds/aiy750000090.ogg differ diff --git a/project/sounds/aiy750000100.ogg b/project/sounds/aiy750000100.ogg new file mode 100644 index 0000000..4057d0c Binary files /dev/null and b/project/sounds/aiy750000100.ogg differ diff --git a/project/sounds/aiy750000110.ogg b/project/sounds/aiy750000110.ogg new file mode 100644 index 0000000..e76d3be Binary files /dev/null and b/project/sounds/aiy750000110.ogg differ diff --git a/project/sounds/aiy750000120.ogg b/project/sounds/aiy750000120.ogg new file mode 100644 index 0000000..41d7788 Binary files /dev/null and b/project/sounds/aiy750000120.ogg differ diff --git a/project/sounds/aiy750000130.ogg b/project/sounds/aiy750000130.ogg new file mode 100644 index 0000000..161f900 Binary files /dev/null and b/project/sounds/aiy750000130.ogg differ diff --git a/project/sounds/aiy750000140.ogg b/project/sounds/aiy750000140.ogg new file mode 100644 index 0000000..fda459c Binary files /dev/null and b/project/sounds/aiy750000140.ogg differ diff --git a/project/sounds/aiy750000150.ogg b/project/sounds/aiy750000150.ogg new file mode 100644 index 0000000..8422fce Binary files /dev/null and b/project/sounds/aiy750000150.ogg differ diff --git a/project/sounds/aiy750000160.ogg b/project/sounds/aiy750000160.ogg new file mode 100644 index 0000000..62f8163 Binary files /dev/null and b/project/sounds/aiy750000160.ogg differ diff --git a/project/sounds/aiy750000170.ogg b/project/sounds/aiy750000170.ogg new file mode 100644 index 0000000..b9fe06e Binary files /dev/null and b/project/sounds/aiy750000170.ogg differ diff --git a/project/sounds/aiy750000180.ogg b/project/sounds/aiy750000180.ogg new file mode 100644 index 0000000..b7fb85f Binary files /dev/null and b/project/sounds/aiy750000180.ogg differ diff --git a/project/sounds/aiy750000190.ogg b/project/sounds/aiy750000190.ogg new file mode 100644 index 0000000..1d7b4a8 Binary files /dev/null and b/project/sounds/aiy750000190.ogg differ diff --git a/project/sounds/aiy750000200.ogg b/project/sounds/aiy750000200.ogg new file mode 100644 index 0000000..68d41da Binary files /dev/null and b/project/sounds/aiy750000200.ogg differ diff --git a/project/sounds/aiy750000210.ogg b/project/sounds/aiy750000210.ogg new file mode 100644 index 0000000..faf634b Binary files /dev/null and b/project/sounds/aiy750000210.ogg differ diff --git a/project/sounds/aiy750000220.ogg b/project/sounds/aiy750000220.ogg new file mode 100644 index 0000000..1b931cf Binary files /dev/null and b/project/sounds/aiy750000220.ogg differ diff --git a/project/sounds/aiy750000230.ogg b/project/sounds/aiy750000230.ogg new file mode 100644 index 0000000..3c31602 Binary files /dev/null and b/project/sounds/aiy750000230.ogg differ diff --git a/project/sounds/aiy750000240.ogg b/project/sounds/aiy750000240.ogg new file mode 100644 index 0000000..ad8501c Binary files /dev/null and b/project/sounds/aiy750000240.ogg differ diff --git a/project/sounds/aiy750000250.ogg b/project/sounds/aiy750000250.ogg new file mode 100644 index 0000000..3ebaffe Binary files /dev/null and b/project/sounds/aiy750000250.ogg differ diff --git a/project/sounds/aiy750000260.ogg b/project/sounds/aiy750000260.ogg new file mode 100644 index 0000000..c45ca4d Binary files /dev/null and b/project/sounds/aiy750000260.ogg differ diff --git a/project/sounds/aiy750000270.ogg b/project/sounds/aiy750000270.ogg new file mode 100644 index 0000000..ad0c25d Binary files /dev/null and b/project/sounds/aiy750000270.ogg differ diff --git a/project/sounds/aiy750000280.ogg b/project/sounds/aiy750000280.ogg new file mode 100644 index 0000000..2b1a3bc Binary files /dev/null and b/project/sounds/aiy750000280.ogg differ diff --git a/project/sounds/aiy750000290.ogg b/project/sounds/aiy750000290.ogg new file mode 100644 index 0000000..11d69ae Binary files /dev/null and b/project/sounds/aiy750000290.ogg differ diff --git a/project/sounds/aiy750000300.ogg b/project/sounds/aiy750000300.ogg new file mode 100644 index 0000000..145e3b3 Binary files /dev/null and b/project/sounds/aiy750000300.ogg differ diff --git a/project/sounds/aiy750000310.ogg b/project/sounds/aiy750000310.ogg new file mode 100644 index 0000000..aac984e Binary files /dev/null and b/project/sounds/aiy750000310.ogg differ diff --git a/project/sounds/aiy750000320.ogg b/project/sounds/aiy750000320.ogg new file mode 100644 index 0000000..175ab60 Binary files /dev/null and b/project/sounds/aiy750000320.ogg differ diff --git a/project/sounds/aiy750000330.ogg b/project/sounds/aiy750000330.ogg new file mode 100644 index 0000000..dd13862 Binary files /dev/null and b/project/sounds/aiy750000330.ogg differ diff --git a/project/sounds/aiy750000340.ogg b/project/sounds/aiy750000340.ogg new file mode 100644 index 0000000..46c6c87 Binary files /dev/null and b/project/sounds/aiy750000340.ogg differ diff --git a/project/sounds/aiy800000010.ogg b/project/sounds/aiy800000010.ogg new file mode 100644 index 0000000..f7c1058 Binary files /dev/null and b/project/sounds/aiy800000010.ogg differ diff --git a/project/sounds/aiy800000020.ogg b/project/sounds/aiy800000020.ogg new file mode 100644 index 0000000..e5233c7 Binary files /dev/null and b/project/sounds/aiy800000020.ogg differ diff --git a/project/sounds/aiy800000030.ogg b/project/sounds/aiy800000030.ogg new file mode 100644 index 0000000..4b9d26c Binary files /dev/null and b/project/sounds/aiy800000030.ogg differ diff --git a/project/sounds/aiy800000040.ogg b/project/sounds/aiy800000040.ogg new file mode 100644 index 0000000..64cca36 Binary files /dev/null and b/project/sounds/aiy800000040.ogg differ diff --git a/project/sounds/aiy800000050.ogg b/project/sounds/aiy800000050.ogg new file mode 100644 index 0000000..20c4b22 Binary files /dev/null and b/project/sounds/aiy800000050.ogg differ diff --git a/project/sounds/aiy800000060.ogg b/project/sounds/aiy800000060.ogg new file mode 100644 index 0000000..baf6f0a Binary files /dev/null and b/project/sounds/aiy800000060.ogg differ diff --git a/project/sounds/aiy800000070.ogg b/project/sounds/aiy800000070.ogg new file mode 100644 index 0000000..09b6793 Binary files /dev/null and b/project/sounds/aiy800000070.ogg differ diff --git a/project/sounds/aiy800000080.ogg b/project/sounds/aiy800000080.ogg new file mode 100644 index 0000000..42f1925 Binary files /dev/null and b/project/sounds/aiy800000080.ogg differ diff --git a/project/sounds/aiy800000090.ogg b/project/sounds/aiy800000090.ogg new file mode 100644 index 0000000..0d1df0d Binary files /dev/null and b/project/sounds/aiy800000090.ogg differ diff --git a/project/sounds/aiy800000100.ogg b/project/sounds/aiy800000100.ogg new file mode 100644 index 0000000..6f1ecbc Binary files /dev/null and b/project/sounds/aiy800000100.ogg differ diff --git a/project/sounds/aiy810000010.ogg b/project/sounds/aiy810000010.ogg new file mode 100644 index 0000000..141c976 Binary files /dev/null and b/project/sounds/aiy810000010.ogg differ diff --git a/project/sounds/aiy810000020.ogg b/project/sounds/aiy810000020.ogg new file mode 100644 index 0000000..f755114 Binary files /dev/null and b/project/sounds/aiy810000020.ogg differ diff --git a/project/sounds/aiy810000030.ogg b/project/sounds/aiy810000030.ogg new file mode 100644 index 0000000..ece7da3 Binary files /dev/null and b/project/sounds/aiy810000030.ogg differ diff --git a/project/sounds/aiy810000040.ogg b/project/sounds/aiy810000040.ogg new file mode 100644 index 0000000..d600ea7 Binary files /dev/null and b/project/sounds/aiy810000040.ogg differ diff --git a/project/sounds/aiy810000050.ogg b/project/sounds/aiy810000050.ogg new file mode 100644 index 0000000..b3975f8 Binary files /dev/null and b/project/sounds/aiy810000050.ogg differ diff --git a/project/sounds/aiy810000060.ogg b/project/sounds/aiy810000060.ogg new file mode 100644 index 0000000..f6cf315 Binary files /dev/null and b/project/sounds/aiy810000060.ogg differ diff --git a/project/sounds/aiy810000070.ogg b/project/sounds/aiy810000070.ogg new file mode 100644 index 0000000..0944056 Binary files /dev/null and b/project/sounds/aiy810000070.ogg differ diff --git a/project/sounds/aiy820000010.mp3 b/project/sounds/aiy820000010.mp3 deleted file mode 100644 index 04b2978..0000000 Binary files a/project/sounds/aiy820000010.mp3 and /dev/null differ diff --git a/project/sounds/aiy820000010.opus b/project/sounds/aiy820000010.opus new file mode 100644 index 0000000..4503491 Binary files /dev/null and b/project/sounds/aiy820000010.opus differ diff --git a/project/sounds/aiy820000020.mp3 b/project/sounds/aiy820000020.mp3 deleted file mode 100644 index ef06278..0000000 Binary files a/project/sounds/aiy820000020.mp3 and /dev/null differ diff --git a/project/sounds/aiy820000020.opus b/project/sounds/aiy820000020.opus new file mode 100644 index 0000000..e405674 Binary files /dev/null and b/project/sounds/aiy820000020.opus differ diff --git a/project/sounds/aiy860000010.ogg b/project/sounds/aiy860000010.ogg new file mode 100644 index 0000000..d6ffe53 Binary files /dev/null and b/project/sounds/aiy860000010.ogg differ diff --git a/project/sounds/aiy860000020.ogg b/project/sounds/aiy860000020.ogg new file mode 100644 index 0000000..8157a6f Binary files /dev/null and b/project/sounds/aiy860000020.ogg differ diff --git a/project/sounds/aiy860000030.ogg b/project/sounds/aiy860000030.ogg new file mode 100644 index 0000000..f428615 Binary files /dev/null and b/project/sounds/aiy860000030.ogg differ diff --git a/project/sounds/aiy860000040.ogg b/project/sounds/aiy860000040.ogg new file mode 100644 index 0000000..cd1a1eb Binary files /dev/null and b/project/sounds/aiy860000040.ogg differ diff --git a/project/sounds/aiy860000050.ogg b/project/sounds/aiy860000050.ogg new file mode 100644 index 0000000..e0cf702 Binary files /dev/null and b/project/sounds/aiy860000050.ogg differ diff --git a/project/sounds/aiy860000060.ogg b/project/sounds/aiy860000060.ogg new file mode 100644 index 0000000..c540697 Binary files /dev/null and b/project/sounds/aiy860000060.ogg differ diff --git a/project/sounds/attack.mp3 b/project/sounds/attack.mp3 deleted file mode 100644 index 16098f7..0000000 Binary files a/project/sounds/attack.mp3 and /dev/null differ diff --git a/project/sounds/attack.opus b/project/sounds/attack.opus new file mode 100644 index 0000000..acd40a4 Binary files /dev/null and b/project/sounds/attack.opus differ diff --git a/project/sounds/bomb.mp3 b/project/sounds/bomb.mp3 deleted file mode 100644 index 8a98067..0000000 Binary files a/project/sounds/bomb.mp3 and /dev/null differ diff --git a/project/sounds/bomb.opus b/project/sounds/bomb.opus new file mode 100644 index 0000000..443e6af Binary files /dev/null and b/project/sounds/bomb.opus differ diff --git a/project/sounds/cancel.mp3 b/project/sounds/cancel.mp3 deleted file mode 100644 index 3842eee..0000000 Binary files a/project/sounds/cancel.mp3 and /dev/null differ diff --git a/project/sounds/cancel.opus b/project/sounds/cancel.opus new file mode 100644 index 0000000..da26056 Binary files /dev/null and b/project/sounds/cancel.opus differ diff --git a/project/sounds/centerFly.mp3 b/project/sounds/centerFly.mp3 deleted file mode 100644 index 8246763..0000000 Binary files a/project/sounds/centerFly.mp3 and /dev/null differ diff --git a/project/sounds/centerFly.opus b/project/sounds/centerFly.opus new file mode 100644 index 0000000..fd94f13 Binary files /dev/null and b/project/sounds/centerFly.opus differ diff --git a/project/sounds/confirm.mp3 b/project/sounds/confirm.mp3 deleted file mode 100644 index 138beeb..0000000 Binary files a/project/sounds/confirm.mp3 and /dev/null differ diff --git a/project/sounds/confirm.opus b/project/sounds/confirm.opus new file mode 100644 index 0000000..821a7dc Binary files /dev/null and b/project/sounds/confirm.opus differ diff --git a/project/sounds/cursor.mp3 b/project/sounds/cursor.mp3 deleted file mode 100644 index 652bf07..0000000 Binary files a/project/sounds/cursor.mp3 and /dev/null differ diff --git a/project/sounds/cursor.opus b/project/sounds/cursor.opus new file mode 100644 index 0000000..7eec58d Binary files /dev/null and b/project/sounds/cursor.opus differ diff --git a/project/sounds/door.mp3 b/project/sounds/door.mp3 deleted file mode 100644 index ea6706d..0000000 Binary files a/project/sounds/door.mp3 and /dev/null differ diff --git a/project/sounds/door.opus b/project/sounds/door.opus new file mode 100644 index 0000000..dce3824 Binary files /dev/null and b/project/sounds/door.opus differ diff --git a/project/sounds/equip.mp3 b/project/sounds/equip.mp3 deleted file mode 100644 index 36bbd02..0000000 Binary files a/project/sounds/equip.mp3 and /dev/null differ diff --git a/project/sounds/equip.opus b/project/sounds/equip.opus new file mode 100644 index 0000000..2bd2c63 Binary files /dev/null and b/project/sounds/equip.opus differ diff --git a/project/sounds/error.mp3 b/project/sounds/error.mp3 deleted file mode 100644 index 329cca4..0000000 Binary files a/project/sounds/error.mp3 and /dev/null differ diff --git a/project/sounds/error.opus b/project/sounds/error.opus new file mode 100644 index 0000000..973ee32 Binary files /dev/null and b/project/sounds/error.opus differ diff --git a/project/sounds/floor.mp3 b/project/sounds/floor.mp3 deleted file mode 100644 index 96dc4fa..0000000 Binary files a/project/sounds/floor.mp3 and /dev/null differ diff --git a/project/sounds/floor.opus b/project/sounds/floor.opus new file mode 100644 index 0000000..0f603d3 Binary files /dev/null and b/project/sounds/floor.opus differ diff --git a/project/sounds/gem.mp3 b/project/sounds/gem.mp3 deleted file mode 100644 index c29b9df..0000000 Binary files a/project/sounds/gem.mp3 and /dev/null differ diff --git a/project/sounds/gem.opus b/project/sounds/gem.opus new file mode 100644 index 0000000..f7bbf6c Binary files /dev/null and b/project/sounds/gem.opus differ diff --git a/project/sounds/icePickaxe.mp3 b/project/sounds/icePickaxe.mp3 deleted file mode 100644 index 29ed9b0..0000000 Binary files a/project/sounds/icePickaxe.mp3 and /dev/null differ diff --git a/project/sounds/icePickaxe.opus b/project/sounds/icePickaxe.opus new file mode 100644 index 0000000..479b8e5 Binary files /dev/null and b/project/sounds/icePickaxe.opus differ diff --git a/project/sounds/item.mp3 b/project/sounds/item.mp3 deleted file mode 100644 index 5d82178..0000000 Binary files a/project/sounds/item.mp3 and /dev/null differ diff --git a/project/sounds/item.opus b/project/sounds/item.opus new file mode 100644 index 0000000..9a488f0 Binary files /dev/null and b/project/sounds/item.opus differ diff --git a/project/sounds/jingbao.mp3 b/project/sounds/jingbao.mp3 deleted file mode 100644 index c2c4aaa..0000000 Binary files a/project/sounds/jingbao.mp3 and /dev/null differ diff --git a/project/sounds/jingbao.opus b/project/sounds/jingbao.opus new file mode 100644 index 0000000..b2a57e1 Binary files /dev/null and b/project/sounds/jingbao.opus differ diff --git a/project/sounds/jump.mp3 b/project/sounds/jump.mp3 deleted file mode 100644 index b8ce8f7..0000000 Binary files a/project/sounds/jump.mp3 and /dev/null differ diff --git a/project/sounds/jump.opus b/project/sounds/jump.opus new file mode 100644 index 0000000..b1c8c01 Binary files /dev/null and b/project/sounds/jump.opus differ diff --git a/project/sounds/load.mp3 b/project/sounds/load.mp3 deleted file mode 100644 index e680f4d..0000000 Binary files a/project/sounds/load.mp3 and /dev/null differ diff --git a/project/sounds/load.opus b/project/sounds/load.opus new file mode 100644 index 0000000..215881f Binary files /dev/null and b/project/sounds/load.opus differ diff --git a/project/sounds/open_ui.mp3 b/project/sounds/open_ui.mp3 deleted file mode 100644 index 0282a08..0000000 Binary files a/project/sounds/open_ui.mp3 and /dev/null differ diff --git a/project/sounds/open_ui.opus b/project/sounds/open_ui.opus new file mode 100644 index 0000000..dbad758 Binary files /dev/null and b/project/sounds/open_ui.opus differ diff --git a/project/sounds/pickaxe.mp3 b/project/sounds/pickaxe.mp3 deleted file mode 100644 index f6dc258..0000000 Binary files a/project/sounds/pickaxe.mp3 and /dev/null differ diff --git a/project/sounds/pickaxe.opus b/project/sounds/pickaxe.opus new file mode 100644 index 0000000..2a9924d Binary files /dev/null and b/project/sounds/pickaxe.opus differ diff --git a/project/sounds/recovery.mp3 b/project/sounds/recovery.mp3 deleted file mode 100644 index 76b67f3..0000000 Binary files a/project/sounds/recovery.mp3 and /dev/null differ diff --git a/project/sounds/recovery.opus b/project/sounds/recovery.opus new file mode 100644 index 0000000..07091c8 Binary files /dev/null and b/project/sounds/recovery.opus differ diff --git a/project/sounds/save.mp3 b/project/sounds/save.mp3 deleted file mode 100644 index 295dbf2..0000000 Binary files a/project/sounds/save.mp3 and /dev/null differ diff --git a/project/sounds/save.opus b/project/sounds/save.opus new file mode 100644 index 0000000..58f2c9a Binary files /dev/null and b/project/sounds/save.opus differ diff --git a/project/sounds/shop.mp3 b/project/sounds/shop.mp3 deleted file mode 100644 index b654aa2..0000000 Binary files a/project/sounds/shop.mp3 and /dev/null differ diff --git a/project/sounds/shop.opus b/project/sounds/shop.opus new file mode 100644 index 0000000..1accbf1 Binary files /dev/null and b/project/sounds/shop.opus differ diff --git a/project/sounds/zone.mp3 b/project/sounds/zone.mp3 deleted file mode 100644 index 414b287..0000000 Binary files a/project/sounds/zone.mp3 and /dev/null differ diff --git a/project/sounds/zone.opus b/project/sounds/zone.opus new file mode 100644 index 0000000..ccdade8 Binary files /dev/null and b/project/sounds/zone.opus differ diff --git a/project/tilesets/C5.webp b/project/tilesets/C5.webp index 641de3c..bbb361e 100644 Binary files a/project/tilesets/C5.webp and b/project/tilesets/C5.webp differ diff --git a/project/tilesets/c6.png b/project/tilesets/c6.png new file mode 100644 index 0000000..ecec049 Binary files /dev/null and b/project/tilesets/c6.png differ diff --git a/project/types/action.d.ts b/project/types/action.d.ts new file mode 100644 index 0000000..17464a1 --- /dev/null +++ b/project/types/action.d.ts @@ -0,0 +1,137 @@ +/** + * 鼠标与触屏操作的函数 + */ +type MotaMouseFunc = (x: number, y: number, px: number, py: number) => boolean; + +/** + * 按键操作的函数 + */ +type MotaKeyboardFunc = (e: KeyboardEvent) => boolean; + +/** + * 没有最乱,只有更乱 + */ +interface RegisteredActionMap { + keyDown: (keyCode: number) => boolean; + keyDownCtrl: () => boolean; + keyUp: (keyCode: number, altKey: boolean, fromReplay: boolean) => boolean; + longClick: MotaMouseFunc; + onStatusBarClick: (px: number, py: number, vertical: boolean) => boolean; + ondown: MotaMouseFunc; + onkeyDown: MotaKeyboardFunc; + onkeyUp: MotaKeyboardFunc; + onmousewheel: (direct: 1 | -1) => boolean; + onmove: MotaMouseFunc; + onup: MotaMouseFunc; + pressKey: (keyCode: number) => boolean; +} + +type ActionKey = keyof RegisteredActionMap; + +/** + * 将注册的函数的返回值变成void就变成了actions上的函数... + */ +type VoidedActionFuncs = { + [P in ActionKey]: (...params: Parameters) => void; +}; + +/** + * 点击位置 + */ +interface ClickLoc extends Loc { + /** + * 格子的大小(这不是32还能是其它的吗?? + */ + size: 32; +} + +interface RegisteredActionOf { + /** + * 交互的类型 + */ + action: K; + + /** + * 交互的唯一标识符 + */ + name: string; + + /** + * 优先级,越高越优先执行 + */ + priority: number; + + /** + * 交互函数 + */ + func: RegisteredActionMap[K]; +} + +/** + * 交互模块 + */ +interface Actions extends VoidedActionFuncs { + /** + * 横向的最后一个格子的横坐标 + */ + readonly LAST: number; + + /** + * 格子长度的一半 + */ + readonly _HX_: number; + + /** + * 格子高度的一半 + */ + readonly _HY_: number; + + /** + * 脚本编辑中的交互函数 + */ + readonly actionsdata: ActionData; + + /** + * 所有已注册的交互操作 + */ + readonly actions: { + [P in ActionKey]: RegisteredActionOf

[]; + }; + + /** + * 此函数将注册一个用户交互行为。 + * @param action 要注册的交互类型 + * @param name 自定义名称,可被注销使用 + * @param func 执行函数,如果func返回true,则不会再继续执行其他的交互函数 + * @param priority 优先级,优先级高的将会被执行。此项可不填,默认为0 + */ + registerAction( + action: K, + name: string, + func: RegisteredActionMap[K], + priority?: number + ): void; + + /** + * 注销一个用户交互行为 + * @param action 要注销的交互类型 + * @param name 要注销的自定义名称 + */ + unregisterAction(action: ActionKey, name: string): void; + + /** + * 执行一个用户交互行为 + */ + doRegisteredAction( + action: K, + ...params: Parameters + ): void; + + /** + * 判断一个横坐标是否在(_HX_ - 2, _HX_ + 2)范围外 + * @param x 要判断的横坐标 + */ + _out(x: number): boolean; +} + +declare const actions: new () => Actions; diff --git a/project/types/control.d.ts b/project/types/control.d.ts new file mode 100644 index 0000000..321b45a --- /dev/null +++ b/project/types/control.d.ts @@ -0,0 +1,1104 @@ +/** + * 帧动画函数 + */ +type FrameFunc = (time: number) => void; + +/** + * 录像操作函数,返回true表示执行成功 + */ +type ReplayFunc = (action: string) => boolean; + +/** + * 游戏画面大小变化时执行的函数 + */ +type ResizeFunc = (obj: DeepReadonly) => void; + +/** + * 勇士属性中的数字属性 + */ +type NumbericHeroStatus = SelectType; + +/** + * 存读档类型 + */ +type SLType = + | 'save' + | 'load' + | 'reload' + | 'replayLoad' + | 'replayRemain' + | 'replaySince'; + +/** + * 天气等级 + */ +type WeatherLevel = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + +/** + * resize函数的参数 + */ +interface ResizeObj { + /** + * body元素的宽度 + */ + clientWidth: number; + + /** + * body元素的高度 + */ + clientHeight: number; + + /** + * 边框的宽度 + */ + BORDER: 3; + + /** + * 状态栏的宽度 + */ + BAR_WIDTH: number; + + /** + * 工具栏的高度 + */ + TOOLBAR_HEIGHT: 38; + + /** + * 计算边框之后的游戏画面的宽度 + */ + outerWidth: number; + + /** + * 计算边框之后的游戏画面的高度 + */ + outerHeight: number; + + /** + * 全局属性 + */ + globalAttribute: GlobalAttribute; + + /** + * 边框样式,css字符串 + */ + border: string; + + /** + * 状态栏显示的状态项 + */ + statusDisplayArr: string[]; + + /** + * 状态栏显示的状态项数 + */ + count: number; + + /** + * 状态栏显示的行数 + */ + col: number; + + /** + * 竖屏下状态栏的高度 + */ + statusBarHeightInVertical: number; + + /** + * 竖屏下工具栏的高度 + */ + toolbarHeightInVertical: number; + + /** + * 是否开启底部工具栏 + */ + extendToolbar: number; + + /** + * @deprecated + * 是否是15x15 + */ + is15x15: false; +} + +interface RenderFrame { + /** + * 帧动画的名称 + */ + name: string; + + /** + * 是否需要进入游戏后才执行 + */ + needPlaying: boolean; + + /** + * 每帧执行的函数 + */ + func: FrameFunc; +} + +interface ReplayAction { + /** + * 录像操作的名称 + */ + name: string; + + /** + * 录像操作执行的函数 + */ + func: ReplayFunc; +} + +interface ResizeAction { + /** + * resize操作的名称 + */ + name: string; + + /** + * 游戏画面变化时执行的函数 + */ + func: ResizeFunc; +} + +interface WeatherAction { + /** + * 天气每帧执行的函数 + */ + frameFunc?: (time: number, level: WeatherLevel) => void; + + /** + * 天气的初始化函数 + */ + initFunc: (level: WeatherLevel) => void; +} + +interface FrameObj { + angle: number; + index: number; + mirror: number; + opacity: number; + x: number; + y: number; + zoom: number; +} + +/** + * 主要用来进行游戏控制,比如行走控制、自动寻路、存读档等等游戏核心内容 + */ +interface Control { + /** + * 刷新状态栏时是否不执行自动事件 + */ + readonly noAutoEvent: boolean; + + /** + * 注册的帧动画 + */ + readonly renderFrameFunc: RenderFrame[]; + + /** + * 注册的录像操作 + */ + readonly replayActions: ReplayAction[]; + + /** + * 注册的resize操作 + */ + readonly resizes: ResizeAction[]; + + /** + * 注册的天气 + */ + readonly weathers: Record; + + /** + * 脚本编辑的control函数列表 + */ + readonly controlData: ControlData; + + /** + * 注册一个animationFrame + * @param name 名称,可用来作为注销使用 + * @param needPlaying 是否只在游戏运行时才执行(在标题界面不执行) + * @param func 要执行的函数,传入time(从页面加载完毕到当前所经过的时间)作为参数 + */ + registerAnimationFrame( + name: string, + needPlaying: boolean, + func: FrameFunc + ): void; + + /** + * 注销一个animationFrame + * @param name 要注销的函数名称 + */ + unregisterAnimationFrame(name: string): void; + + /** + * 进入标题画面 + * @example core.showStartAnimate(); // 重启游戏但不重置bgm + * @param noAnimate 是否不由黑屏淡入而是立即亮屏 + * @param callback 完全亮屏后的回调函数 + */ + showStartAnimate(noAnimate?: boolean, callback?: () => void): void; + + /** + * 淡出标题画面 + * @example core.hideStartAnimate(core.startGame); // 淡出标题画面并开始新游戏,跳过难度选择 + * @param callback 标题画面完全淡出后的回调函数 + */ + hideStartAnimate(callback?: () => void): void; + + /** + * 判断游戏是否已经开始 + */ + isPlaying(): boolean; + + /** + * 清除游戏状态和数据 + */ + clearStatus(): void; + + /** + * 清除地图上绘制的自动寻路路线 + */ + clearAutomaticRouteNode(x: number, y: number): void; + + /** + * 停止自动寻路操作 + */ + stopAutomaticRoute(): void; + + /** + * 保存剩下的寻路,并停止 + */ + saveAndStopAutomaticRoute(): void; + + /** + * 继续剩下的自动寻路操作 + */ + continueAutomaticRoute(): void; + + /** + * 清空剩下的自动寻路列表 + */ + clearContinueAutomaticRoute(callback?: () => any): void; + + /** + * 半自动寻路,用于鼠标或手指拖动 + * @param destX 鼠标或手指的起拖点横坐标 + * @param destY 鼠标或手指的起拖点纵坐标 + * @param stepPostfix 拖动轨迹的数组表示,每项为一步的方向和目标点。 + */ + setAutomaticRoute(destX: number, destY: number, stepPostfix: Loc[]): void; + + /** + * 连续行走 + * @param steps 压缩的步伐数组,每项表示朝某方向走多少步 + */ + setAutoHeroMove(steps: CompressedStep[]): void; + + /** + * 设置行走的效果动画 + */ + setHeroMoveInterval(callback?: () => any): void; + + /** + * 每移动一格后执行的函数 + */ + moveOneStep(callback?: () => any): void; + + /** + * 尝试前进一步,如果面前不可被踏入就会直接触发该点事件 + * @example core.moveAction(core.doAction); // 尝试前进一步,然后继续事件处理 + * @param callback 走一步后的回调函数 + */ + moveAction(callback?: () => void): void; + + /** + * 连续前进,不撞南墙不回头 + * @example core.moveHero(); // 连续前进 + * @param direction 移动的方向,不设置就是勇士当前的方向 + * @param callback 回调函数,设置了就只走一步 + */ + moveHero(direction?: Dir, callback?: () => void): void; + + /** + * 当前是否正在移动 + */ + isMoving(): boolean; + + /** + * 停止勇士的一切行动并等待勇士停下 + * @example core.waitHeroToStop(core.vibrate); // 等待勇士停下,然后视野左右抖动1秒 + * @param callback 勇士停止后的回调函数 + */ + waitHeroToStop(callback?: () => void): void; + + /** + * 主角转向并计入录像,不会导致跟随者聚集,会导致视野重置到以主角为中心 + * @example core.turnHero(); // 主角顺时针旋转,即单击主角或按下Z键的效果 + * @param direction 主角的新朝向,可为up, down, left, right, :left, :right, :back七种之一,不填视为:right + */ + turnHero(direction?: TurnDir): void; + + /** + * 瞬移到某一点 + * @param x 瞬移至的横坐标 + * @param y 瞬移至的纵坐标 + * @param ignoreSteps 忽略的步数,不填则会自动计算 + */ + moveDirectly(x: number, y: number, ignoreSteps?: number): boolean; + + /** + * 尝试瞬移,如果该点有图块/事件/阻激夹域捕则会瞬移到它旁边再走一步(不可踏入的话当然还是触发该点事件),这一步的方向优先和瞬移前主角的朝向一致 + * @example core.tryMoveDirectly(6, 0); // 尝试瞬移到地图顶部的正中央,以样板0层为例,实际效果是瞬移到了上楼梯下面一格然后向上走一步并触发上楼事件 + * @param destX 目标点的横坐标 + * @param destY 目标点的纵坐标 + */ + tryMoveDirectly(destX: number, destY: number): boolean; + + /** + * 绘制主角和跟随者并重置视野到以主角为中心 + * @example core.drawHero(); // 原地绘制主角的静止帧 + * @param status 绘制状态 + * @param offset 相对主角逻辑位置的偏移量,不填视为无偏移 + * @param frame 绘制第几帧 + */ + drawHero( + status?: Exclude, + offset?: number, + frame?: number + ): void; + + /** + * 改变勇士的不透明度 + * @param opacity 要设置成的不透明度 + * @param moveMode 动画的缓动模式 + * @param time 动画时间,不填视为无动画 + * @param callback 动画执行完毕的回调函数 + */ + setHeroOpacity( + opacity: number, + moveMode?: EaseMode, + time?: any, + callback?: () => any + ): void; + + /** + * 设置游戏系统画布的偏移量 + * @param canvasId 字符串或数字,根据ts的说法应该只能填数字,但是浏览器会提高字符串的方式。 + * 但是还是建议填数字,排列顺序一般是纵深从低到高排列 + * @param x 偏移横坐标 + * @param y 偏移纵坐标 + */ + setGameCanvasTranslate( + canvasId: string | number, + x: number, + y: number + ): void; + + /** + * 加减所有游戏系统画布的偏移 + * @param x 增加的横坐标 + * @param y 增加的纵坐标 + */ + addGameCanvasTranslate(x: number, y: number): void; + + /** + * 更新大地图的可见区域 + */ + updateViewport(): void; + + /** + * 设置视野范围 + * @param px 相对大地图左上角的偏移横坐标,单位像素 + * @param py 相对大地图左上角的偏移纵坐标,单位像素 + */ + setViewport(px?: number, py?: number): void; + + /** + * 移动视野范围,这东西真的有人用吗...高级动画 + setViewport就完事了( + * @param x 移动的横坐标,单位格子 + * @param y 移动的纵坐标,单位格子 + * @param moveMode 缓动方式 + * @param time 动画时间 + * @param callback 动画完毕后的回调函数 + */ + moveViewport( + x: number, + y: number, + moveMode?: EaseMode, + time?: number, + callback?: () => void + ): void; + + /** + * 获取主角面前第n格的横坐标 + * @example core.closeDoor(core.nextX(), core.nextY(), 'yellowDoor', core.turnHero); // 在主角面前关上一扇黄门,然后主角顺时针旋转90° + * @param n 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1 + */ + nextX(n?: number): number; + + /** + * 获取主角面前第n格的纵坐标 + * @example core.jumpHero(core.nextX(2), core.nextY(2)); // 主角向前跃过一格,即跳跃靴道具的使用效果 + * @param n 目标格与主角的距离,面前为正数,背后为负数,脚下为0,不填视为1 + */ + nextY(n?: number): number; + + /** + * 判定主角是否身处某个点的锯齿领域(取曼哈顿距离) + * @example core.nearHero(6, 6, 6); // 判定主角是否身处点(6,6)的半径为6的锯齿领域 + * @param x 领域的中心横坐标 + * @param y 领域的中心纵坐标 + * @param n 领域的半径,不填视为1 + */ + nearHero(x: number, y: number, n?: number): boolean; + + /** + * 立刻聚集所有的跟随者 + */ + gatherFollowers(): void; + + /** + * 更新跟随者坐标 + */ + updateFollowers(): void; + + /** + * 更新领域、夹击、阻击的伤害地图 + * @param floorId 更新的地图id + */ + updateCheckBlock(floorId?: FloorIds): void; + + /** + * 检查并执行领域、夹击、阻击事件 + */ + checkBlock(): void; + + /** + * @deprecated 使用core.updateStatusBar代替。重算并绘制地图显伤 + * @example core.updateDamage(); // 更新当前地图的显伤,绘制在显伤层(废话) + * @param floorId 地图id,不填视为当前地图。预览地图时填写 + * @param ctx 绘制到的画布,如果填写了就会画在该画布而不是显伤层 + */ + updateDamage(floorId?: FloorIds, ctx?: CtxRefer): void; + + /** + * 重绘地图显伤 + * @param ctx 绘制到的画布 + */ + drawDamage(ctx?: CtxRefer): void; + + /** + * 选择录像文件 + */ + chooseReplayFile(): void; + + /** + * 开始播放一个录像 + */ + startReplay(list: string[]): void; + + /** + * 更改播放状态,暂停还是播放 + */ + triggerReplay(): void; + + /** + * 暂停播放 + */ + pauseReplay(): void; + + /** + * 恢复播放 + */ + resumeReplay(): void; + + /** + * 单步播放 + */ + stepReplay(): void; + + /** + * 加速播放 + */ + speedUpReplay(): void; + + /** + * 减速播放 + */ + speedDownReplay(): void; + + /** + * 设置播放速度 + */ + setReplaySpeed(speed: number): void; + + /** + * 停止录像播放 + * @param force 是否是强制停止播放(例如点击停止播放按钮) + */ + stopReplay(force?: boolean): void; + + /** + * 回退录像播放 + */ + rewindReplay(): void; + + /** + * 是否正在播放录像 + */ + isReplaying(): boolean; + + /** + * 回放下一个操作 + */ + replay(): void; + + /** + * 注册一个录像行为 + * @param name 自定义名称,可用于注销使用 + * @param func 具体执行录像的函数,可为一个函数或插件中的函数名; + * 需要接受一个action参数,代表录像回放时的下一个操作 + * func返回true代表成功处理了此录像行为,false代表没有处理此录像行为。 + */ + registerReplayAction(name: string, func: ReplayFunc): void; + + /** + * 注销一个录像行为 + * @param 要注销的录像行为 + */ + unregisterReplayAction(name: string): void; + + /** + * 自动存档 + * @param removeLast 是否移除位于自动存档栈底部的存档 + */ + autosave(removeLast?: any): void; + + /** + * 实际进行自动存档 + */ + checkAutosave(): void; + + /** + * 实际进行存读档事件 + */ + doSL(id: string, type: SLType): void; + + /** + * 同步存档到服务器 + * @param type 同步的类型,填all表示所有都同步,否则只同步当前存档 + */ + syncSave(type?: 'all'): void; + + /** + * 从服务器加载存档 + */ + syncLoad(): void; + + /** + * 存档到本地 + */ + saveData(): Save; + + /** + * 从本地读档 + */ + loadData(data: Save, callback?: () => void): void; + + /** + * 获得某个存档内容 + */ + getSave(index: number, callback?: (data?: Save) => void): void; + + /** + * 获得某些存档内容 + */ + getSaves(ids: number, callback?: (data?: Save) => void): void; + getSaves( + ids: number[], + callback?: (data?: Record) => void + ): void; + + /** + * 获得所有存档内容 + */ + getAllSaves(callback?: (data?: Save[]) => void): void; + + /** + * 获得所有存在存档的存档位 + */ + getSaveIndexes(callback?: (data: Record) => void): void; + + /** + * 判断某个存档位是否存在存档 + */ + hasSave(index: number): boolean; + + /** + * 删除某个存档 + */ + removeSave(index: number, callback?: () => void): void; + + /** + * 设置主角的某个属性 + * @example core.setStatus('loc', {x : 0, y : 0, direction : 'up'}); // 设置主角位置为地图左上角,脸朝上 + * @param name 属性名 + * @param value 属性的新值 + */ + setStatus(name: K, value: HeroStatus[K]): void; + + /** + * 增减主角的某个属性,等价于core.setStatus(name, core.getStatus(name) + value) + * @example core.addStatus('name', '酱'); // 在主角的名字后加一个“酱”字 + * @param name 属性名 + * @param value 属性的增量,请注意旧量和增量中只要有一个是字符串就会把两者连起来成为一个更长的字符串 + */ + addStatus>( + name: K, + value: HeroStatus[K] + ): void; + + /** + * 读取主角的某个属性,不包括百分比修正 + * @example core.getStatus('loc'); // 读取主角的坐标和朝向 + * @param name 属性名 + * @returns 属性值 + */ + getStatus(name: K): HeroStatus[K]; + + /** + * 从status中获得属性,如果不存在则从勇士属性中获取 + * @param status 要从中获取的属性对象 + * @param name 属性名 + */ + getStatusOrDefault( + status?: DeepPartial, + name?: K + ): HeroStatus[K]; + + /** + * 计算主角的某个属性,包括百分比修正 + * @example core.getRealStatus('atk'); // 计算主角的攻击力,包括百分比修正。战斗使用的就是这个值 + * @param name 属性名,注意只能用于数值类属性 + */ + getRealStatus(name: K): number; + + /** + * 从status中获得增幅后的属性,如果不存在则从勇士属性中获取 + * @param status 要从中获取的属性对象 + * @param name 属性名 + */ + getRealStatusOrDefault( + status?: DeepPartial, + name?: K + ): number; + + /** + * 获得勇士原始属性(无装备和衰弱影响) + * @param name 获取的属性名 + */ + getNakedStatus(name?: keyof NumbericHeroStatus): number; + + /** + * 获得某个状态的中文名 + * @param name 要获取的属性名 + */ + getStatusLabel(name: string): string; + + /** + * 设置主角某个属性的百分比修正倍率,初始值为1, + * 倍率存放在flag: `__${name}_${buff}__` 中 + * @example core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半 + * @param name 属性名,注意只能用于数值类属性 + * @param value 新的百分比修正倍率,不填(效果上)视为1 + */ + setBuff(name: K, value?: number): void; + + /** + * 增减主角某个属性的百分比修正倍率,加减法叠加和抵消。等价于 core.setBuff(name, core.getBuff(name) + value) + * @example core.addBuff('atk', -0.1); // 主角获得一层“攻击力减一成”的负面效果 + * @param name 属性名,注意只能用于数值类属性 + * @param value 倍率的增量 + */ + addBuff(name: K, value: number): void; + + /** + * 读取主角某个属性的百分比修正倍率,初始值为1 + * @example core.getBuff('atk'); // 主角当前能发挥出多大比例的攻击力 + * @param name 属性的英文名 + */ + getBuff(name: keyof NumbericHeroStatus): number; + + /** + * 变更勇士的debuff + * @param action 触发的类型,get表示获得debuff,remove表示移除debuff + * @param type 获取的debuff列表 + */ + triggerDebuff(action: string, type: string | string[]): void; + + /** + * 设置勇士位置 + * 值得注意的是,这句话虽然会使勇士改变位置,但并不会使界面重新绘制; + * 如需立刻重新绘制地图还需调用:core.clearMap('hero'); core.drawHero(); 来对界面进行更新。 + * @example core.setHeroLoc('x', 5) // 将勇士当前位置的横坐标设置为5。 + * @param name 要设置的坐标属性 + * @param value 新值 + * @param noGather 是否聚集跟随者 + */ + setHeroLoc(name: 'x' | 'y', value: number, noGather?: boolean): void; + setHeroLoc(name: 'direction', value: Dir, noGather?: boolean): void; + + /** + * 获取主角的位置,朝向 + * @example core.getHeroLoc(); // 获取主角的位置和朝向 + * @param name 要读取横坐标还是纵坐标还是朝向还是都读取 + */ + getHeroLoc(): Loc; + getHeroLoc(name: K): Loc[K]; + + /** + * 根据级别的数字获取对应的名称,后者定义在全塔属性 + * @example core.getLvName(); // 获取主角当前级别的名称,如“下级佣兵” + * @param lv 级别的数字,不填则视为主角当前的级别 + * @returns 级别的名称,如果不存在就还是返回字符串类型的数字 + */ + getLvName(lv?: number): string; + + /** + * 获得下次升级需要的经验值。 + * 升级扣除模式下会返回经验差值;非扣除模式下会返回总共需要的经验值。 + * 如果无法进行下次升级,返回null。 + */ + getNextLvUpNeed(): number | null; + + /** + * 设置一个flag变量 + * @example core.setFlag('poison', true); // 令主角中毒 + * @param name 变量名,支持中文,这东西用中文就是不规范( + * @param value 变量的新值,不填或填null视为删除 + */ + setFlag(name: string, value?: any): void; + + /** + * 增减一个flag变量,等价于 core.setFlag(name, core.getFlag(name, 0) + value) + * @example core.addFlag('hatred', 1); // 增加1点仇恨值 + * @param name 变量名,支持中文 + * @param value 变量的增量 + */ + addFlag(name: string, value: number | string): void; + + /** + * 获取一个flag变量 + * @param name 变量名,支持中文,这东西用中文就是不规范( + * @param defaultValue 当变量不存在时的返回值,可选(事件流中默认填0)。 + * @returns flags[name] ?? defaultValue + */ + getFlag(name: string, defaultValue?: T): T; + + /** + * 判定一个flag变量是否不为falsy + * @example core.hasFlag('poison'); // 判断主角当前是否中毒 + * @param name 变量名,支持中文,这东西用中文就是不规范( + */ + hasFlag(name: string): boolean; + + /** + * 删除某个flag + * @param name 要删除的变量名 + */ + removeFlag(name: string): void; + + /** + * 设置某个独立开关 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 独立开关的名称 + * @param value 要设置成的值 + */ + setSwitch( + x?: number, + y?: number, + floorId?: FloorIds, + name?: string, + value?: any + ): void; + + /** + * 获得某个独立开关 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 独立开关的名称 + * @param value 默认值 + */ + getSwitch( + x?: number, + y?: number, + floorId?: FloorIds, + name?: string, + defaultValue?: T + ): T; + + /** + * 增加某个独立开关 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 独立开关的名称 + * @param value 增加的值 + */ + addSwitch( + x?: number, + y?: number, + floorId?: FloorIds, + name?: string, + value?: number | string + ): void; + + /** + * 是否存在某个独立开关 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 独立开关的名称 + */ + hasSwitch( + x?: number, + y?: number, + floorId?: FloorIds, + name?: string + ): boolean; + + /** + * 删除某个独立开关 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 独立开关的名称 + */ + removeSwitch( + x?: number, + y?: number, + floorId?: FloorIds, + name?: string + ): void; + + /** + * 锁定用户控制,常常用于事件处理 + */ + lockControl(): void; + + /** + * 解锁用户控制 + */ + unlockControl(): void; + + /** + * 开启调试模式, 此模式下可以按Ctrl键进行穿墙, 并忽略一切事件。 + * 此模式下不可回放录像和上传成绩。 + */ + debug(): void; + + /** + * 清空录像折叠信息 + */ + clearRouteFolding(): void; + + /** + * 检查录像折叠信息 + */ + checkRouteFolding(): void; + + /** + * 获得映射文件名 + */ + getMappedName(name: K): NameMap[K]; + + /** + * 设置天气,不计入存档。如需长期生效请使用core.events._action_setWeather()函数 + * @example core.setWeather('fog', 10); // 设置十级大雾天 + * @param type 新天气的类型,不填视为无天气 + * @param level 新天气(晴天除外)的级别,必须为不大于10的正整数,不填视为5 + */ + setWeather(type?: string, level?: WeatherLevel): void; + + /** + * 注册一个天气 + * @param name 天气的名称 + * @param initFunc 初始化函数 + * @param frameFunc 每帧执行的函数 + */ + registerWeather( + name: string, + initFunc: WeatherAction['initFunc'], + frameFunc?: WeatherAction['frameFunc'] + ): void; + + /** + * 注销一个天气 + * @param name 要注销的天气名称 + */ + unregisterWeather(name: string): void; + + /** + * 更改画面色调,不计入存档。如需长期生效请使用core.events._action_setCurtain()函数 + * @example core.setCurtain(); // 恢复画面色调,用时四分之三秒 + * @param color 颜色数组,不填视为[0, 0, 0, 0] + * @param time 渐变时间,单位为毫秒。不填视为750ms + * @param moveMode 缓动模式 + * @param callback 更改完毕后的回调函数 + */ + setCurtain( + color?: RGBArray, + time?: number, + moveMode?: EaseMode, + callback?: () => void + ): void; + + /** + * 画面闪烁 + * @example core.screenFlash([255, 0, 0, 1], 3); // 红屏一闪而过 + * @param color 颜色数组 + * @param time 单次闪烁时长,实际闪烁效果为先花其三分之一的时间渐变到目标色调,再花剩余三分之二的时间渐变回去 + * @param times 闪烁的总次数,不填或填0都视为1 + * @param moveMode 缓动模式 + * @param callback 闪烁全部完毕后的回调函数 + */ + screenFlash( + color: RGBArray, + time: number, + times?: number, + moveMode?: string, + callback?: () => void + ): void; + + /** + * 播放背景音乐,中途开播但不计入存档且只会持续到下次场景切换。如需长期生效请将背景音乐的文件名赋值给flags.__bgm__ + * @example core.playBgm('bgm.mp3', 30); // 播放bgm.mp3,并跳过前半分钟 + * @param bgm 背景音乐的文件名,支持全塔属性中映射前的中文名 + * @param startTime 跳过前多少秒 + */ + playBgm(bgm: BgmIds | NameMapIn, startTime?: number): void; + + /** + * 设置背景音乐的播放速度和音调 + * @param speed 要设置到的速度,100是原速 + * @param usePitch 是否允许声调改变 + */ + setBgmSpeed(speed: number, usePitch?: boolean): void; + + /** + * 暂停背景音乐的播放 + */ + pauseBgm(): void; + + /** + * 恢复背景音乐的播放 + */ + resumeBgm(resumeTime?: number): void; + + /** + * 设置音乐图标的开启关闭状态 + */ + setMusicBtn(): void; + + /** + * 开启或关闭背景音乐的播放 + */ + triggerBgm(): void; + + /** + * 播放一个音效 + * @param sound 音效名 + * @param pitch 音调,同时会修改播放速度,100为原速 + * @param callback 回调函数 + * @returns 音效的唯一标识符,用于停止音效等操作 + */ + playSound( + sound: SoundIds | NameMapIn, + pitch?: number, + callback?: () => void + ): number; + + /** + * 停止音频 + * @param id 停止的音频标识符,不填则停止所有 + */ + stopSound(id?: number): void; + + /** + * 获得正在播放的所有音效的id列表 + * @param name 要获得的音效名 + */ + getPlayingSounds(name?: SoundIds | NameMapIn): number[]; + + /** + * 检查bgm状态,没有播放的话就播放 + */ + checkBgm(): void; + + /** + * 设置屏幕放缩 + * @param delta 在所有可用放缩数组中增加的下标数 + */ + setDisplayScale(delta: number): void; + + /** + * 清空状态栏 + */ + clearStatusBar(): void; + + /** + * 更新状态栏和地图显伤,会在下一个动画帧更新 + * @param doNotCheckAutoEvents 是否不检查自动事件 + * @param immediate 是否立刻刷新,而非延迟到下一动画帧刷新 + */ + updateStatusBar(doNotCheckAutoEvents?: boolean, immediate?: boolean): void; + + /** + * 显示状态栏 + */ + showStatusBar(): void; + + /** + * 隐藏状态栏 + * @param showToolbox 是否显示工具栏 + */ + hideStatusBar(showToolbox?: boolean): void; + + /** + * 更新状态栏的勇士图标 + */ + updateHeroIcon(name: ImageIds): void; + + /** + * 改变工具栏为按钮1-8 + * @param useButton 是否显示为按钮1-8 + */ + setToolbarButton(useButton?: boolean): void; + + /** + * 注册一个resize函数 + * @param name 名称,可供注销使用 + * @param func 游戏画面发生变化时执行的函数 + */ + registerResize(name: string, func: ResizeFunc): void; + + /** + * 注销一个resize函数 + */ + unregisterResize(name: string): void; + + /** + * 屏幕分辨率改变后执行的函数 + */ + resize(): void; +} + +declare const control: new () => Control; diff --git a/project/types/core.d.ts b/project/types/core.d.ts new file mode 100644 index 0000000..84c0492 --- /dev/null +++ b/project/types/core.d.ts @@ -0,0 +1,1450 @@ +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +type MaterialIcon = { + [C in Exclude]: { + [P in AllIdsOf]: number; + }; +} & { + /** + * 勇士的图标信息 + */ + hero: { + /** + * 各个方向的图标信息 + */ + [D in Dir2]: { + /** + * 行数 + */ + loc: number; + + /** + * 第一列 + */ + stop: number; + + /** + * 第二列 + */ + leftFoot: number; + + /** + * 第三列 + */ + midFoot: number; + + /** + * 第四列 + */ + rightFoot: number; + }; + } & { + /** + * 勇士的宽度 + */ + width: number; + + /** + * 勇士的高度 + */ + height: number; + }; +}; + +type MaterialImages = { + /** + * 各个类型的图块的图片 + */ + [C in Exclude]: HTMLImageElement; +} & { + /** + * 空气墙 + */ + airwall: HTMLImageElement; + + /** + * 自动元件 + */ + autotile: Record, HTMLImageElement>; + + /** + * 全塔属性注册的图片 + */ + images: Record; + + /** + * 额外素材 + */ + tilesets: Record; +}; + +interface Material { + /** + * 动画信息 + */ + readonly animates: Record; + + /** + * 素材的图片信息 + */ + readonly images: MaterialImages; + + /** + * 音乐信息 + */ + readonly bgms: Record; + + /** + * 音效信息 + */ + readonly sounds: Record; + + /** + * 怪物信息 + * @example core.material.enemys.greenSlime // 获得绿色史莱姆的属性数据 + */ + readonly enemys: { + [P in EnemyIds]: Enemy

; + }; + + /** + * 道具信息 + */ + readonly items: { + [P in AllIdsOf<'items'>]: Item

; + }; + + /** + * 图标信息 + */ + readonly icons: DeepReadonly; + + /** + * @deprecated + * core定义了,但在代码中完全没有找到这个东西?用处未知 + */ + readonly ground: CanvasRenderingContext2D; + + /** + * 楼层背景的画布context + */ + readonly groundCanvas: CanvasRenderingContext2D; + + /** + * 楼层背景的canvas样式 + */ + readonly groundPattern: CanvasPattern; + + /** + * 自动元件的父子关系 + */ + readonly autotileEdges: Record< + AllNumbersOf<'autotile'>, + AllNumbersOf<'autotile'>[] + >; +} + +interface Timeout { + /** + * 单击勇士时的计时器,用于判断双击 + */ + turnHeroTimeout?: number; + + /** + * 按住500ms后进行长按判定的计时器 + */ + onDownTimeout?: number; + + /** + * 长按跳过等待事件的计时器 + */ + sleepTimeout?: number; +} + +interface Interval { + /** + * 勇士移动的定时器 + */ + heroMoveInterval?: number; + + /** + * 长按计时器 + */ + onDownInterval?: number; +} + +interface AnimateFrame { + /** + * 游戏总时间 + */ + readonly totalTime: number; + + /** + * 本次游戏开始的时间 + */ + readonly totalTimeStart: number; + + /** + * @deprecated + * 样板没有出现过 + */ + globalAnimate: boolean; + + /** + * 当前raf的时间戳,即从游戏加载完毕到现在经过的时间 + */ + readonly globalTime: number; + + /** + * @deprecated + * 样板没有出现过 + */ + selectorTime: number; + + /** + * @deprecated + * 样板没有出现过 + */ + selectorUp: boolean; + + /** + * 上一次全局动画的时间(怪物、npc等抖动一下的时间) + */ + readonly animateTime: number; + + /** + * 勇士移动的时候上一次的换腿时间 + */ + readonly moveTime: number; + + /** + * @deprecated + * 样板没有出现过 + */ + lastLegTime: number; + + /** + * 当前是否在左腿上,使用了四帧插件时无效 + */ + readonly leftLeg: boolean; + + /** + * 当前天气信息 + */ + readonly weather: Weather; + + /** + * 左上角提示 + */ + readonly tip?: Readonly; + + /** + * 异步信息,想不到吧,这玩意是一个以number为索引的回调函数列表 + */ + readonly asyncId: Record void>; + + /** + * 上一个异步事件的id + */ + readonly lastAsyncId: number; +} + +interface Weather { + /** + * 当前的raf时间戳,同globalTime,但只有部分天气有用 + */ + time: number; + + /** + * 当前天气类型 + */ + type: string; + + /** + * 谁会去用这个玩意??? + */ + nodes: any[]; + + /** + * 谁会去用这个玩意??? + */ + data: any; + + /** + * 当前的天气等级 + */ + readonly level: number; + + /** + * 雾的图片信息 + */ + readonly fog: HTMLImageElement; + + /** + * 多云的图片信息 + */ + readonly cloud: HTMLImageElement; + + /** + * 晴天的图片信息 + */ + readonly sun: HTMLImageElement; +} + +interface Tip { + /** + * 显示的文字 + */ + text: string; + + /** + * 文字的左边像素位置 + */ + textX: 21 | 45; + + /** + * 提示的宽度 + */ + width: number; + + /** + * 当前的不透明度,会在显示提示时不断变化 + */ + opacity: number; + + /** + * 在显示阶段还是常亮阶段还是消失阶段 + */ + stage: number; + + /** + * 图标的帧数,即显示图标的第几帧 + */ + frame: number; + + /** + * 当前的raf时间戳 + */ + time: number; + + /** + * 在提示进入常亮阶段后经过了多长时间 + */ + displayTime: number; +} + +interface MusicStatus { + /** + * AudioContext信息,注意如果浏览器不支持的话会是null + */ + audioContext: AudioContext; + + /** + * 是否允许播放BGM + */ + bgmStatus: boolean; + + /** + * 是否允许播放SE + */ + soundStatus: boolean; + + /** + * 正在播放的BGM + */ + playingBgm: string; + + /** + * 上次播放的bgm + */ + lastBgm: string; + + /** + * 音量控制节点,只对音效有效,但为什么样板只有一个呢 + */ + gainNode: GainNode; + + /** + * 正在播放的SE,这个__name是音效名 + */ + playingSounds: Record; + + /** + * 用户音量 + */ + userVolume: number; + + /** + * 设计音量,好吧其实不能设计,只有淡入淡出的时候有用 + */ + designVolume: number; + + /** + * 音乐播放速度 + */ + bgmSpeed: number; + + /** + * 修改音乐播放速度时是否修改音调 + */ + bgmUsePitch: boolean; + + /** + * 缓存过BGM内容 + */ + cachedBgms: string[]; + + /** + * 缓存的bgm数量 + */ + cachedBgmCount: 8; +} + +interface CorePlatform { + /** + * 是否http + */ + isOnline: boolean; + + /** + * 是否是PC + */ + isPC: boolean; + + /** + * 是否是Android + */ + isAndroid: boolean; + + /** + * 是否是iOS + */ + isIOS: boolean; + + /** + * 平台信息 + */ + string: 'PC' | 'Android' | 'IOS' | ''; + + /** + * 是否是微信 + */ + isWeChat: boolean; + + /** + * 是否是QQ + */ + isQQ: boolean; + + /** + * 是否是Chrome + */ + isChrome: boolean; + + /** + * 是否是safari浏览器 + */ + isSafari: boolean; + + /** + * 是否支持复制到剪切板 + */ + supportCopy: boolean; + + /** + * 读取文件时的input元素(我也不知道干啥的 + */ + fileInput: HTMLInputElement; + + /** + * FileReader示例 + */ + fileReader: FileReader; + + /** + * 读取成功 + */ + successCallback?: (obj: any) => void; + + /** + * 读取失败 + */ + errorCallback?: () => void; +} + +/** + * dom信息,没有全部标注,只标注了一部分特例 + */ +type MainDom = { + /** + * 所有的状态信息 + */ + status: HTMLCollectionOf; + + /** + * 所有的工具栏图片 + */ + tools: HTMLCollectionOf; + + /** + * 所有的游戏画布 + */ + gameCanvas: HTMLCollectionOf; + + /** + * 所有的状态显示信息,有的是

有的是就挺离谱 + */ + statusLabels: HTMLCollectionOf; + + /** + *

标签的状态显示文字 + */ + statusText: HTMLCollectionOf; + + /** + * 自绘状态栏画布的context + */ + statusCanvasCtx: CanvasRenderingContext2D; + + [key: string]: HTMLElement; +}; + +interface DomStyle { + /** + * 当前缩放大小 + */ + scale: number; + + /** + * 就是window.devicePixelRatio + */ + ratio: number; + + /** + * 高清画布列表 + */ + hdCanvas: string[]; + + /** + * 可以缩放到的缩放比例,是 [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5] 的子数组 + */ + availableScale: number[]; + + /** + * 是否是竖屏 + */ + isVertical: boolean; + + /** + * 是否显示状态栏 + */ + showStatusBar: boolean; + + /** + * 当前道具栏是否是数字键 + */ + toolbarBtn: boolean; +} + +interface CoreBigmap { + /** + * 大地图中会跟随勇士移动的画布 + */ + canvas: string[]; + + /** + * 大地图的横向偏移量,单位像素 + */ + offsetX: number; + + /** + * 大地图的纵向偏移量,单位像素 + */ + offsetY: number; + + /** + * v2优化下的横向偏移格子数 + */ + posX: number; + + /** + * v2优化下的纵向偏移格子数 + */ + posY: number; + + /** + * 地图宽度,单位格子 + */ + width: number; + + /** + * 地图高度,单位格子 + */ + height: number; + + /** + * 是否使用v2优化 + */ + v2: boolean; + + /** + * 判定为超大的图的地图面积临界,使用了显示宝石血瓶详细信息插件的话是256 + */ + threshold: 1024; + + /** + * v2优化下,显示超出的格子数,例如样板是10,那么13*13的样板就是33*33,还用于判断是否进行更新等 + */ + extend: 10; + + /** + * @deprecated + * 又出现了!样板中没有的东西 + */ + scale: 1; + + /** + * 绘制缩略图时的临时画布 + */ + tempCanvas: CanvasRenderingContext2D; + + /** + * 绘制地图时的双缓冲层 + */ + cacheCanvas: CanvasRenderingContext2D; +} + +interface CoreSave { + /** + * 当前存档页面显示的页码数 + */ + saveIndex: number; + + /** + * 当前存在存档的存档位 + */ + ids: Record; + + /** + * 自动存档信息 + */ + autosave: Readonly; + + /** + * 收藏的存档 + */ + favorite: number[]; + + /** + * 保存的存档名称 + */ + favoriteName: Record; +} + +interface Autosave { + /** + * 当前自动存档位 + */ + now: number; + + /** + * 当前存档信息 + */ + data?: Save[]; + + /** + * 自动存档位的最大值 + */ + max: 20; + + /** + * 是否将自动存档写入本地文件 + */ + storage: true; + + /** + * @deprecated + * 每5秒钟会被设置一次的raf时间戳,不知道干什么的。。。 + */ + time: number; + + /** + * @deprecated + * 样板在不停设置这个东西,但不知道什么用处,因为没有调用它的地方 + */ + updated: boolean; + + /** + * 不太清楚干什么的,看起来好像与存档无关,是与本地存储有关的 + */ + cache: Record; +} + +interface CoreValues { + /** + * 血网伤害 + */ + lavaDamage: number; + + /** + * 中毒伤害 + */ + poisonDamage: number; + + /** + * 衰弱状态下攻防减少的数值。如果此项不小于1,则作为实际下降的数值(比如10就是攻防各下降10 + * 如果在0到1之间则为下降的比例(比如0.3就是下降30%的攻防) + */ + weakValue: number; + + /** + * 红宝石加攻数值 + */ + redGem: number; + + /** + * 蓝宝石加防数值 + */ + blueGem: number; + + /** + * 绿宝石加魔防数值 + */ + greenGem: number; + + /** + * 红血瓶加血数值 + */ + redPotion: number; + + /** + * 蓝血瓶加血数值 + */ + bluePotion: number; + + /** + * 黄血瓶加血数值 + */ + yellowPotion: number; + + /** + * 绿血瓶加血数值 + */ + greenPotion: number; + + /** + * 默认的破甲比例 + */ + breakArmor: number; + + /** + * 默认的反击比例 + */ + counterAttack: number; + + /** + * 默认的净化比例 + */ + purify: number; + + /** + * 仇恨属性中,每杀一个怪增加的仇恨值 + */ + hatred: number; + + /** + * 全局动画速度 + */ + animateSpeed: number; + + /** + * 勇士移动速度 + */ + moveSpeed: number; + + /** + * 竖屏下状态栏显示行数 + */ + statusCanvasRowsOnMobile: 1 | 2 | 3 | 4 | 5; + + /** + * 楼层切换时间 + */ + floorChangeTime: number; +} + +type CoreStatusBarElements = { + /** + * 状态栏图标信息 + */ + readonly icons: Record; + + /** + * 状态栏的图标元素 + */ + readonly image: Record; + + readonly [key: string]: HTMLElement; +}; + +type Materails = [ + 'animates', + 'enemys', + 'items', + 'npcs', + 'terrains', + 'enemy48', + 'npc48', + 'icons' +]; + +type CoreFlagProperties = + | 'autoScale' + | 'betweenAttackMax' + | 'blurFg' + | 'canGoDeadZone' + | 'disableShopOnDamage' + | 'displayCritical' + | 'displayEnemyDamage' + | 'displayExtraDamage' + | 'enableAddPoint' + | 'enableEnemyPoint' + | 'enableGentleClick' + | 'enableHDCanvas' + | 'enableMoveDirectly' + | 'enableNegativeDamage' + | 'enableRouteFolding' + | 'equipboxButton' + | 'extendToolbar' + | 'flyNearStair' + | 'flyRecordPosition' + | 'ignoreChangeFloor' + | 'itemFirstText' + | 'leftHandPrefer' + | 'startUsingCanvas' + | 'statusCanvas'; + +type CoreFlags = { + [P in CoreFlagProperties]: boolean; +} & { + /** + * 地图伤害的显示模式 + */ + extraDamageType: number; + + /** + * 当前的状态栏显示项 + */ + statusBarItems: string[]; +}; + +type CoreDataFromMain = + | 'dom' + | 'statusBar' + | 'canvas' + | 'images' + | 'tilesets' + | 'materials' + | 'animates' + | 'bgms' + | 'sounds' + | 'floorIds' + | 'floors' + | 'floorPartitions'; + +/** + * 样板的core的类型,不得不感叹样板的结构真的很神奇(简称粪),两个看似毫无关联的东西都会有着千丝万缕的联系 + */ +interface Core extends Pick { + /** + * 地图的格子宽度 + */ + readonly _WIDTH_: number; + + /** + * 地图的格子高度 + */ + readonly _HEIGHT_: number; + + /** + * 地图的像素宽度 + */ + readonly _PX_: number; + + /** + * 地图的像素高度 + */ + readonly _PY_: number; + + /** + * 地图宽度的一半 + */ + readonly _HALF_WIDTH_: number; + + /** + * 地图高度的一半 + */ + readonly _HALF_HEIGHT_: number; + + /** + * @deprecated + * 地图可视部分大小 + */ + readonly __SIZE__: number; + + /** + * @deprecated + * 地图像素 + */ + readonly __PIXELS__: number; + + /** + * @deprecated + * 地图像素的一半 + */ + readonly __HALF_SIZE__: number; + + /** + * 游戏素材 + */ + readonly material: Material; + + /** + * 计时器(样板的神秘操作 + */ + readonly timeout: Timeout; + + /** + * 定时器 + */ + readonly interval: Interval; + + /** + * 全局动画信息 + */ + readonly animateFrame: AnimateFrame; + + /** + * 音乐状态 + */ + readonly musicStatus: Readonly; + + /** + * 当前游戏平台 + */ + readonly platform: Readonly; + + /** + * dom样式 + */ + readonly domStyle: Readonly; + + /** + * 大地图信息 + */ + readonly bigmap: Readonly; + + /** + * 存档信息 + */ + readonly saves: Readonly; + + /** + * 全局数值信息 + */ + readonly values: CoreValues; + + /** + * 游戏的初始状态 + */ + readonly initStatus: DeepReadonly; + + /** + * 所有的自定义画布 + */ + readonly dymCanvas: Record; + + /** + * 游戏状态 + */ + readonly status: GameStatus; + + /** + * 设置信息 + */ + readonly flags: CoreFlags; + + /** + * 获得所有楼层的信息 + * @example core.floors[core.status.floorId].events // 获得本楼层的所有自定义事件 + */ + readonly floors: DeepReadonly<{ + [P in FloorIds]: ResolvedFloor

; + }>; + + /** + * 游戏主要逻辑模块 + */ + readonly control: Control; + + /** + * 游戏的全塔属性信息 + */ + readonly data: Omit; + + /** + * 游戏加载模块 + */ + readonly loader: Loader; + + /** + * 游戏的事件模块 + */ + readonly events: Events; + + /** + * 游戏的怪物模块 + */ + readonly enemys: Enemys; + + /** + * 游戏的物品模块 + */ + readonly items: Items; + + /** + * 游戏的地图模块 + */ + readonly maps: Maps; + + /** + * 游戏的ui模块 + */ + readonly ui: Ui; + + /** + * 游戏的工具模块 + */ + readonly utils: Utils; + + /** + * 游戏的图标模块 + */ + readonly icons: Icons; + + /** + * 游戏的交互模块 + */ + readonly actions: Actions; + + /** + * 游戏的插件模块 + */ + readonly plugin: PluginDeclaration; + + /** + * 进行游戏初始化 + * @param coreData 初始化信息 + * @param callback 初始化完成后的回调函数 + */ + init(coreData: MainData, callback?: () => void): void; + + /** + * @deprecated + * 在一个上下文下执行函数(真的有人会用这个东西吗? + * @param func 要执行的函数 + * @param _this 执行函数的上下文 + * @param params 函数的参数 + */ + doFunc( + func: F, + _this: any, + ...params: Parameters + ): ReturnType; +} + +type CoreMixin = Core & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward & + Forward; + +interface MainStyle extends Readonly { + /** + * 初始界面的背景图 + */ + readonly startBackground: string; + + /** + * 竖屏下初始界面的背景图 + */ + readonly startVerticalBackground: string; + + /** + * 初始界面的文字样式 + */ + readonly startLogoStyle: string; + + /** + * 初始界面的选项样式 + */ + readonly startButtonsStyle: string; +} + +interface SplitImageData { + /** + * 要切分的图片id + */ + readonly name: ImageIds; + + /** + * 每个小图的宽度 + */ + readonly width: number; + + /** + * 每个小图的高度 + */ + readonly height: number; + + /** + * 切分成的小图的前缀名 + */ + readonly prefix: string; +} + +interface Main extends MainData { + /** + * 是否在录像验证中 + */ + readonly replayChecking: boolean; + + /** + * @deprecated + * 就是core,应该没人会用main.core吧( + */ + readonly core: CoreMixin; + + /** + * 游戏的dom信息 + */ + readonly dom: Readonly; + + /** + * 游戏版本,发布后会被随机为数字,请勿使用该属性 + */ + readonly version: string; + + /** + * 是否使用压缩文件 + */ + readonly useCompress: boolean; + + /** + * 存档页数 + */ + readonly savePages: number; + + /** + * 循环临界的分界 + */ + readonly criticalUseLoop: number; + + /** + * 当前游戏模式,是编辑器还是游玩界面 + */ + readonly mode: 'play' | 'editor'; + + /** + * 是否使用远程bgm + */ + readonly bgmRemote: boolean; + + /** + * 远程bgm目录 + */ + readonly bgmRemoteRoot: string; + + /** + * 所有的系统画布 + */ + readonly canvas: Record; + + /** + * 获得所有楼层的信息,等同于core.floors,但两者不是引用关系 + */ + readonly floors: DeepReadonly<{ + [P in FloorIds]: ResolvedFloor

; + }>; + + /** + * 所有的素材图片名称 + */ + readonly materials: Materials; + + /** + * 要加载的project目录下的文件 + */ + readonly pureData: string[]; + + /** + * 要加载的libs目录下的文件 + */ + readonly loadList: string[]; + + /** + * 开始界面中当前选中的按钮 + */ + readonly selectedButton: number; + + /** + * 当前启动服务是否支持高层塔优化 + */ + readonly supportBunch: boolean; + + /** + * 状态栏的图标信息 + */ + readonly statusBar: CoreStatusBarElements; + + /** + * 游戏版本 + */ + readonly __VERSION__: string; + + /** + * 游戏版本代码 + */ + readonly __VERSION_CODE__: number; + + /** + * 初始化游戏 + * @param mode 初始化游戏的模式,游玩还是编辑器 + * @param callback 初始化完成后的回调函数 + */ + init(mode: 'play' | 'editor', callback: () => void): void; + + /** + * 动态加载js文件 + * @param dir 加载的js文件的目录 + * @param loadList 加载的js文件的文件名数组,不带后缀 + * @param callback 加载完毕后的回调函数 + */ + loadJs(dir: string, loadList: string[], callback: () => void): void; + + /** + * 动态加载一个js文件 + * @param dir 加载的js文件的目录 + * @param modName 加载的js文件的名称,不带后缀名,如果是使用压缩文件会自动加上.min + * @param callback 加载完毕后的回调函数,传入的参数是modName + */ + loadMod( + dir: string, + modName: string, + callback: (name: string) => void + ): void; + + /** + * 动态加载所有楼层 + * @param callback 加载完成后的回调函数 + */ + loadFloors(callback: () => void): void; + + /** + * 动态加载一个楼层 + * @param floorId 加载的楼层id + * @param callback 加载完成后的回调函数,传入的参数是加载的楼层id + */ + loadFloor( + floorId: F, + callback: (floorId: F) => void + ): void; + + /** + * 设置加载界面的加载提示文字 + */ + setMainTipsText(text: string): void; + + /** + * @deprecated + * 输出内容(极不好用,建议换成console,我甚至不知道样板为什么会有这个东西) + * @param e 输出内容 + * @param error 输出内容是否是报错 + */ + log(e: string | Error, error?: boolean): void; + + /** + * 生成选择光标的keyframes + */ + createOnChoiceAnimation(): void; + + /** + * 选中开始界面的一个按钮 + * @param index 要选中的按钮 + */ + selectButton(index: number): void; + + /** + * 加载一系列字体 + * @param fonts 要加载的字体列表 + */ + importFonts(fonts: FontIds[]): void; + + /** + * 执行样板的所有监听 + */ + listen(): void; +} + +interface Flags { + /** + * 当前的难度代码 + */ + readonly hard: number; + + /** + * 本次游戏的种子 + */ + readonly __seed__: number; + + /** + * 当前的随机数 + */ + readonly __rand__: number; + + /** + * 难度的颜色,css字符串 + */ + readonly __hardColor__: Color; + + /** + * 平面楼传下,每个楼层的离开位置 + */ + readonly __leaveLoc__: Record; + + /** + * 剧情文本属性 + */ + readonly textAttribute: TextAttribute; + + /** + * 楼层是否到达过 + */ + readonly __visited__: Record; + + [key: string]: any; +} + +interface MapDataOf { + /** + * 图块的id + */ + id: NumberToId[T]; + + /** + * 图块的类型 + */ + cls: ClsOf; +} + +/** + * 样板的主对象 + */ +declare const main: Main; + +/** + * 样板的核心对象 + */ +declare const core: CoreMixin; + +/** + * 所有的变量 + */ +declare let flags: Flags; + +/** + * 勇士信息 + */ +declare let hero: HeroStatus; + +// 让你总是拼错!(不过现在有ts了应该拼不错了 +declare const ture: true; +declare const flase: false; +declare const on: true; +declare const off: false; + +/** + * 全塔属性 + */ +declare const data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d: DataCore; + +/** + * 所有的怪物信息 + */ +declare const enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80: { + [P in EnemyIds]: Enemy

; +}; + +/** + * 所有的公共事件 + */ +declare const events_c12a15a8_c380_4b28_8144_256cba95f760: { + commonEvent: Record; +}; + +/** + * 脚本编辑 + */ +declare const functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a: FunctionsData; + +/** + * 所有的图标信息 + */ +declare const icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1: MaterialIcon; + +/** + * 所有的道具信息 + */ +declare const items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a: { + [P in AllIdsOf<'items'>]: Item

; +}; + +/** + * 所有的图块信息 + */ +declare const maps_90f36752_8815_4be8_b32b_d7fad1d0542e: { + [P in keyof NumberToId]: MapDataOf

; +}; + +/** + * 插件信息 + */ +declare const plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1: PluginDeclaration; diff --git a/project/types/data.d.ts b/project/types/data.d.ts new file mode 100644 index 0000000..157fead --- /dev/null +++ b/project/types/data.d.ts @@ -0,0 +1,140 @@ +interface MainData { + /** + * 所有的楼层id + */ + readonly floorIds: FloorIds[]; + + /** + * 分区指定 + */ + readonly floorPatitions: [FloorIds, FloorIds?][]; + + /** + * 所有的额外素材 + */ + readonly tilesets: string[]; + + /** + * 所有的动画 + */ + readonly animates: AnimationIds[]; + + /** + * 所有的bgm + */ + readonly bgms: BgmIds[]; + + /** + * 所有的音效 + */ + readonly sounds: SoundIds[]; + + /** + * 所有的字体 + */ + readonly fonts: FontIds[]; + + /** + * 文件别名 + */ + readonly nameMap: NameMap; + + /** + * 难度选择 + */ + readonly levelChoose: LevelChooseEvent[]; + + /** + * 装备孔的名称 + */ + readonly equipName: string[]; + + /** + * 初始界面的bgm + */ + readonly startBgm: BgmIds; + + /** + * 主样式 + */ + readonly styles: MainStyle; + + /** + * 图片切分信息 + */ + readonly splitImages: SplitImageData; +} + +interface FirstData { + /** + * 游戏标题 + */ + title: string; + + /** + * 游戏英文名,应当与mota.config.ts中的一致 + */ + name: string; + + /** + * 游戏版本 + */ + version: string; + + /** + * 初始地图 + */ + floorId: FloorIds; + + /** + * 勇士的初始信息 + */ + hero: HeroStatus; + + /** + * 标题界面事件化 + */ + startCanvas: MotaEvent; + + /** + * 初始剧情 + */ + startText: MotaEvent; + + /** + * 全局商店信息 + */ + shops: ShopEventOf[]; + + /** + * 升级事件 + */ + levelUp: LevelUpEvent; +} + +/** + * 全塔属性信息 + */ +interface DataCore { + /** + * 全塔属性的main信息 + */ + readonly main: MainData; + + /** + * 初始化信息 + */ + readonly firstData: FirstData; + + /** + * 全局数值 + */ + readonly values: CoreValues; + + /** + * 全局变量 + */ + readonly flags: CoreFlags; +} + +declare const data: new () => Omit; diff --git a/project/types/enemy.d.ts b/project/types/enemy.d.ts new file mode 100644 index 0000000..543a099 --- /dev/null +++ b/project/types/enemy.d.ts @@ -0,0 +1,382 @@ +type PartialNumbericEnemyProperty = + | 'value' + | 'zone' + | 'repulse' + | 'laser' + | 'breakArmor' + | 'counterAttack' + | 'vampire' + | 'hpBuff' + | 'atkBuff' + | 'defBuff' + | 'range' + | 'haloRange' + | 'n' + | 'purify' + | 'atkValue' + | 'defValue' + | 'damage'; + +type BooleanEnemyProperty = + | 'zoneSquare' + | 'haloSquare' + | 'notBomb' + | 'add' + | 'haloAdd'; + +type Enemy = { + /** + * 怪物id + */ + id: I; + + /** + * 怪物名称 + */ + name: string; + + /** + * 在怪物手册中映射到的怪物ID。如果此项不为null,则在怪物手册中,将用目标ID来替换该怪物原本的ID。 + * 常被运用在同一个怪物的多朝向上 + */ + displayIdInBook: EnemyIds; + + /** + * 战前事件 + */ + beforeBattle: MotaEvent; + + /** + * 战后事件 + */ + afterBattle: MotaEvent; +} & { + [P in PartialNumbericEnemyProperty]?: number; +} & { + [P in BooleanEnemyProperty]: boolean; +} & EnemyInfoBase; + +/** + * 怪物的特殊属性定义 + */ +type EnemySpecialDeclaration = [ + id: number, + name: string | ((enemy: Enemy) => string), + desc: string | ((enemy: Enemy) => string), + color: Color, + extra?: number +]; + +interface DamageString { + /** + * 伤害字符串 + */ + damage: string; + + /** + * 伤害颜色 + */ + color: Color; +} + +interface EnemyInfoBase { + /** + * 生命值 + */ + hp: number; + + /** + * 攻击力 + */ + atk: number; + + /** + * 防御力 + */ + def: number; + + /** + * 金币 + */ + money: number; + + /** + * 经验 + */ + exp: number; + + /** + * 加点量 + */ + point: number; + + /** + * 特殊属性列表 + */ + special: number[]; +} + +interface EnemyInfo extends EnemyInfoBase { + /** + * 支援信息 + */ + guards: [x: number, y: number, id: EnemyIds]; +} + +interface DamageInfo { + /** + * 怪物生命值 + */ + mon_hp: number; + + /** + * 怪物攻击力 + */ + mon_atk: number; + + /** + * 怪物防御力 + */ + mon_def: number; + + /** + * 先攻伤害 + */ + init_damage: number; + + /** + * 怪物的每回合伤害 + */ + per_damage: number; + + /** + * 勇士的每回合伤害 + */ + hero_per_damage: number; + + /** + * 战斗的回合数 + */ + turn: number; + + /** + * 勇士损失的生命值 + */ + damage: number; +} + +interface BookEnemyInfo extends Enemy, EnemyInfo { + /** + * 怪物的坐标列表 + */ + locs?: [x: number, y: number][]; + + /** + * 怪物的中文名 + */ + name: string; + + /** + * 特殊属性名称列表 + */ + specialText: string[]; + + /** + * 特殊属性的颜色列表 + */ + specialColor: Color[]; + + /** + * 怪物的伤害 + */ + damage: number; + + /** + * 第一个临界的加攻的值 + */ + critical: number; + + /** + * 临界的减伤值 + */ + criticalDamage: number; + + /** + * ratio防减伤 + */ + defDamage: number; +} + +/** + * 怪物模块 + */ +interface Enemys extends EnemyData { + /** + * 所有的怪物信息 + */ + readonly enemys: { + [P in EnemyIds]: Enemy

; + }; + + /** + * 脚本编辑的怪物相关 + */ + readonly enemydata: EnemyData; + + /** + * 获得所有怪物原始数据的一个副本 + */ + getEnemys(): { + [P in EnemyIds]: Enemy

; + }; + + /** + * 获得某种敌人的全部特殊属性名称 + * @example core.getSpecialText('greenSlime') // ['先攻', '3连击', '破甲', '反击'] + * @param enemy 敌人id或敌人对象,如core.material.enemys.greenSlime + * @returns 字符串数组 + */ + getSpecialText(enemy: EnemyIds | Enemy): string[]; + + /** + * 获得所有特殊属性的颜色 + * @param enemy 敌人id或敌人对象,如core.material.enemys.greenSlime + */ + getSpecialColor(enemy: EnemyIds | Enemy): Color[]; + + /** + * 获得所有特殊属性的额外标记 + * @param enemy 敌人id或敌人对象,如core.material.enemys.greenSlime + */ + getSpecialFlag(enemy: EnemyIds | Enemy): number[]; + + /** + * 获得某种敌人的某种特殊属性的介绍 + * @example core.getSpecialHint('bat', 1) // '先攻:怪物首先攻击' + * @param enemy 敌人id或敌人对象,用于确定属性的具体数值 + * @param special 属性编号,可以是该敌人没有的属性 + * @returns 属性的介绍,以属性名加中文冒号开头 + */ + getSpecialHint(enemy: EnemyIds | Enemy, special: number): string; + + /** + * 获得某个敌人的某项属性值 + * @param enemy 敌人id或敌人对象 + * @param name 获取的敌人属性 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在楼层 + */ + getEnemyValue( + enemy: EnemyIds | Enemy, + name: K, + x?: number, + y?: number, + floorId?: FloorIds + ): Enemy[K]; + + /** + * 判定主角当前能否打败某只敌人 + * @example core.canBattle('greenSlime',0,0,'MT0') // 能否打败主塔0层左上角的绿头怪(假设有) + * @param enemy 敌人id或敌人对象 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + * @returns true表示可以打败,false表示无法打败 + */ + canBattle( + enemy: EnemyIds | Enemy, + x?: number, + y?: number, + floorId?: FloorIds + ): boolean; + + /** + * 获得某只敌人的地图显伤,包括颜色 + * @example core.getDamageString('greenSlime', 0, 0, 'MT0') // 绿头怪的地图显伤 + * @param enemy 敌人id或敌人对象 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + */ + getDamageString( + enemy: EnemyIds | Enemy, + x?: number, + y?: number, + floorId?: FloorIds + ): DamageString; + + /** + * 获得某只敌人接下来的若干个临界及其减伤,算法基于useLoop开关选择回合法或二分法 + * @example core.nextCriticals('greenSlime', 9, 0, 0, 'MT0') // 绿头怪接下来的9个临界 + * @param enemy 敌人id或敌人对象 + * @param number 要计算的临界数量,默认为1 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + * @returns 两列的二维数组,每行表示一个临界及其减伤 + */ + nextCriticals( + enemy: EnemyIds | Enemy, + number?: number, + x?: number, + y?: number, + floorId?: FloorIds + ): [critical: number, damage: number][]; + + /** + * 计算再加若干点防御能使某只敌人对主角的总伤害降低多少 + * @example core.nextCriticals('greenSlime', 10, 0, 0, 'MT0') // 再加10点防御能使绿头怪的伤害降低多少 + * @param enemy 敌人id或敌人对象 + * @param k 假设主角增加的防御力,默认为1 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + * @returns 总伤害的减少量 + */ + getDefDamage( + enemy: EnemyIds | Enemy, + k?: number, + x?: number, + y?: number, + floorId?: FloorIds + ): number; + + /** + * 获得某只敌人对主角的总伤害 + * @example core.getDamage('greenSlime',0,0,'MT0') // 绿头怪的总伤害 + * @param enemy 敌人id或敌人对象 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + * @returns 总伤害,如果因为没有破防或无敌怪等其他原因无法战斗,则返回null + */ + getDamage( + enemy: EnemyIds | Enemy, + x?: number, + y?: number, + floorId?: FloorIds + ): number; + + /** + * 获得某张地图的敌人集合,用于手册绘制 + * @example core.getCurrentEnemys('MT0') // 主塔0层的敌人集合 + * @param floorId 地图id + * @returns 敌人集合,按伤害升序排列,支持多朝向怪合并 + */ + getCurrentEnemys(floorId?: FloorIds): Enemy[]; + + /** + * 检查某些楼层是否还有漏打的(某种)敌人 + * @example core.hasEnemyLeft('greenSlime', ['sample0', 'sample1']) // 样板0层和1层是否有漏打的绿头怪 + * @param enemyId 敌人id,可选,默认为任意敌人 + * @param floorId 地图id或其数组,可选,默认为当前地图 + * @returns true表示有敌人被漏打,false表示敌人已死光 + */ + hasEnemyLeft( + enemyId?: EnemyIds | EnemyIds[], + floorId?: FloorIds | FloorIds[] + ): boolean; +} + +declare const enemys: new () => Enemys; diff --git a/project/types/event.d.ts b/project/types/event.d.ts new file mode 100644 index 0000000..9b6b21d --- /dev/null +++ b/project/types/event.d.ts @@ -0,0 +1,763 @@ +/** + * 注册的系统事件函数 + */ +type SystemEventFunc = (data: any, callback: (...params: any[]) => any) => void; + +/** + * 注册的事件函数 + */ +type EventFunc = (data: any, x?: number, y?: number, prefix?: string) => void; + +/** + * 处理所有和事件相关的操作 + */ +interface Events extends EventData { + /** + * 脚本编辑中的事件相关内容 + */ + eventdata: EventData; + + /** + * 公共事件信息 + */ + commonEvent: Record; + + /** + * 所有的系统事件 + */ + systemEvent: Record; + + /** + * 注册的自定义事件 + */ + actions: Record; + + /** + * 开始新游戏 + * @example core.startGame('咸鱼乱撞', 0, ''); // 开始一局咸鱼乱撞难度的新游戏,随机种子为0 + * @param hard 难度名,会显示在左下角(横屏)或右下角(竖屏) + * @param seed 随机种子,相同的种子保证了录像的可重复性 + * @param route 经由base64压缩后的录像,用于从头开始的录像回放 + * @param callback 回调函数 + */ + startGame( + hard: string, + seed: number, + route?: string, + callback?: () => void + ): void; + + /** + * 游戏结束 + * @example core.gameOver(); // 游戏失败 + * @param ending 结局名,省略表示失败 + * @param fromReplay true表示在播放录像 + * @param norank true表示不计入榜单 + */ + gameOver(ending?: string, fromReplay?: boolean, norank?: boolean): void; + + /** + * 重新开始游戏;此函数将回到标题页面 + */ + restart(): void; + + /** + * 询问是否需要重新开始 + */ + confirmRestart(): void; + + /** + * 注册一个系统事件 + * @param type 事件名 + * @param func 为事件的处理函数,可接受(data,callback)参数 + */ + registerSystemEvent(type: string, func: SystemEventFunc): void; + + /** + * 注销一个系统事件 + * @param type 事件名 + */ + unregisterSystemEvent(type: string): void; + + /** + * 执行一个系统事件 + * @param type 执行的事件名 + * @param data 数据信息 + * @param callback 传入事件处理函数的回调函数 + */ + doSystemEvent( + type: string, + data: any, + callback?: (...params: any[]) => any + ): void; + + /** + * 触发(x,y)点的系统事件;会执行该点图块的script属性,同时支持战斗(会触发战后)、道具(会触发道具后)、楼层切换等等 + * @param x 横坐标 + * @param y 纵坐标 + * @param callback 回调函数 + */ + trigger(x: number, y: number, callback?: () => void): void; + + /** + * 战斗,如果填写了坐标就会删除该点的敌人并触发战后事件 + * @example core.battle('greenSlime'); // 和从天而降的绿头怪战斗(如果打得过) + * @param id 敌人id,必填 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param force true表示强制战斗 + * @param callback 回调函数 + */ + battle( + id: AllIdsOf<'enemys' | 'enemy48'>, + x?: number, + y?: number, + force?: boolean, + callback?: () => void + ): void; + + /** + * 开门(包括三种基础墙) + * @example core.openDoor(0, 0, true, core.jumpHero); // 打开左上角的门,需要钥匙,然后主角原地跳跃半秒 + * @param x 门的横坐标 + * @param y 门的纵坐标 + * @param needKey true表示需要钥匙,会导致机关门打不开 + * @param callback 门完全打开后或打不开时的回调函数 + */ + openDoor( + x: number, + y: number, + needKey?: boolean, + callback?: () => void + ): void; + + /** + * 获得道具并提示,如果填写了坐标就会删除该点的该道具 + * @example core.getItem('book'); // 获得敌人手册并提示 + * @param id 道具id,必填 + * @param num 获得的数量,不填视为1,填了就别填坐标了 + * @param x 道具的横坐标 + * @param y 道具的纵坐标 + * @param callback 回调函数 + */ + getItem( + id: AllIdsOf<'items'>, + num?: number, + x?: number, + y?: number, + callback?: () => void + ): void; + + /** + * 轻按获得面前的物品或周围唯一物品 + * @param noRoute 若为true则不计入录像 + */ + getNextItem(noRoute?: boolean): void; + + /** + * 场景切换 + * @example core.changeFloor('MT0'); // 传送到主塔0层,主角坐标和朝向不变,黑屏时间取用户设置值 + * @param floorId 传送的目标地图id,可以填':before'和':after'分别表示楼下或楼上 + * @param stair 传送的位置,可以填':now'(保持不变,可省略),':symmetry'(中心对称),':symmetry_x'(左右对称),':symmetry_y'(上下对称)或图块id(该图块最好在目标层唯一,一般为'downFloor'或'upFloor') + * @param heroLoc 传送的坐标(如果填写了,就会覆盖上述的粗略目标位置)和传送后主角的朝向(不填表示保持不变) + * @param time 传送的黑屏时间,单位为毫秒。不填为用户设置值 + * @param callback 黑屏结束后的回调函数 + */ + changeFloor( + floorId: FloorIds, + stair?: FloorChangeStair | AllIds, + heroLoc?: Partial, + time?: number, + callback?: () => void + ): void; + + /** + * 是否到达过某个楼层 + * @param floorId 楼层id + */ + hasVisitedFloor(floorId?: FloorIds): boolean; + + /** + * 到达某楼层 + * @param floorId 楼层id + */ + visitFloor(floorId?: FloorIds): void; + + /** + * 推箱子 + * @param data 图块信息 + */ + pushBox(data?: Block): void; + + /** + * 当前是否在冰上 + */ + onSki(number?: number): boolean; + + /** + * 注册一个自定义事件 + * @param type 事件类型 + * @param func 事件的处理函数,可接受(data, x, y, prefix)参数 + * data为事件内容,x和y为当前点坐标(可为null),prefix为当前点前缀 + */ + registerEvent(type: string, func: EventFunc): void; + + /** + * 注销一个自定义事件 + * @param type 事件类型 + */ + unregisterEvent(type: string): void; + + /** + * 执行一个自定义事件 + * @param data 事件信息 + * @param x 事件横坐标 + * @param y 事件纵坐标 + * @param prefix 当前点前缀 + */ + doEvent(data: any, x?: number, y?: number, prefix?: string): void; + + /** + * 直接设置事件列表 + * @param list 事件信息 + * @param x 横坐标 + * @param y 纵坐标 + * @param callback 事件执行完毕后的回调函数 + */ + setEvents( + list: MotaEvent, + x?: number, + y?: number, + callback?: () => void + ): void; + + /** + * 开始执行一系列自定义事件 + * @param list 事件信息 + * @param x 横坐标 + * @param y 纵坐标 + * @param callback 事件执行完毕后的回调函数 + */ + startEvents( + list?: MotaEvent, + x?: number, + y?: number, + callback?: () => void + ): void; + + /** + * 执行下一个事件指令,常作为回调 + * @example + * // 事件中的原生脚本,配合勾选“不自动执行下一个事件”来达到此改变色调只持续到下次场景切换的效果 + * core.setCurtain([0,0,0,1], undefined, null, core.doAction); + */ + doAction(): void; + + /** + * 插入一段事件;此项不可插入公共事件,请用 core.insertCommonEvent + * @example core.insertAction('一段文字'); // 插入一个显示文章 + * @param action 单个事件指令,或事件指令数组 + * @param x 新的当前点横坐标 + * @param y 新的当前点纵坐标 + * @param callback 新的回调函数 + * @param addToLast 插入的位置,true表示插入到末尾,否则插入到开头 + */ + insertAction( + action: MotaEvent | MotaAction, + x?: number, + y?: number, + callback?: () => void, + addToLast?: boolean + ): void; + + /** + * 插入一个公共事件 + * @example core.insertCommonEvent('加点事件', [3]); + * @param name 公共事件名;如果公共事件不存在则直接忽略 + * @param args 参数列表,为一个数组,将依次赋值给 flag:arg1, flag:arg2, ... + * @param x 新的当前点横坐标 + * @param y 新的当前点纵坐标 + * @param callback 新的回调函数 + * @param addToLast 插入的位置,true表示插入到末尾,否则插入到开头 + */ + insertCommonEvent( + name: EventDeclaration, + args?: any[], + x?: number, + y?: number, + callback?: () => void, + addToLast?: boolean + ): void; + + /** + * 获得一个公共事件 + * @param name 公共事件名称 + */ + getCommonEvent(name: EventDeclaration): any; + + /** + * 恢复一个事件 + * @param data 事件信息 + */ + recoverEvents(data?: any): void; + + /** + * 检测自动事件 + */ + checkAutoEvents(): void; + + /** + * 当前是否在执行某个自动事件 + * @param symbol 自动事件的标识符 + * @param value 不太清楚有什么用 + */ + autoEventExecuting(symbol?: string, value?: any): boolean; + + /** + * 当前是否执行过某个自动事件 + * @param symbol 自动事件的标识符 + * @param value 不太清楚有什么用 + */ + autoEventExecuted(symbol?: string, value?: any): boolean; + + /** + * 将当前点坐标入栈 + */ + pushEventLoc(x: number, y: number, floorId?: FloorIds): void; + + /** + * 弹出事件坐标点 + */ + popEventLoc(): void; + + /** + * 预编辑事件 + * @param data 事件信息 + */ + precompile(data?: any): any; + + /** + * 点击怪物手册时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + openBook(fromUserAction?: boolean): void; + + /** + * 点击楼层传送器时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + useFly(fromUserAction?: boolean): void; + + /** 点击装备栏时的打开操作 */ + openEquipbox(fromUserAction?: boolean): void; + + /** + * 点击工具栏时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + openToolbox(fromUserAction?: boolean): void; + + /** + * 点击快捷商店按钮时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + openQuickShop(fromUserAction?: boolean): void; + + /** + * 点击虚拟键盘时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + openKeyBoard(fromUserAction?: boolean): void; + + /** + * 点击存档按钮时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + save(fromUserAction?: boolean): void; + + /** + * 点击读档按钮时的打开操作 + * @param fromUserAction 是否是用户开启的 + */ + load(fromUserAction?: boolean): void; + + /** + * 点击设置按钮时的操作 + * @param fromUserAction 是否是用户开启的 + */ + openSettings(fromUserAction?: boolean): void; + + /** + * 当前是否有未处理完毕的异步事件(不包含动画和音效) + */ + hasAsync(): boolean; + + /** + * 立刻停止所有异步事件 + */ + stopAsync(): void; + + /** + * 是否有异步动画 + */ + hasAsyncAnimate(): boolean; + + /** + * 跟随 + * @param name 要跟随的一个合法的4x4的行走图名称,需要在全塔属性注册 + */ + follow(name: ImageIds | NameMapIn): void; + + /** + * 取消跟随 + * @param name 取消跟随的行走图,不填则取消全部跟随者 + */ + unfollow(name?: ImageIds | NameMapIn): void; + + /** + * 数值操作 + * @param name 操作的数值的名称 + * @param operator 操作运算符 + * @param value 值 + * @param prefix 独立开关前缀 + */ + setValue( + name: `${EventValuePreffix}:${string}`, + operator: MotaOperator, + value: number, + prefix?: string + ): void; + + /** + * 设置一项敌人属性并计入存档 + * @example core.setEnemy('greenSlime', 'def', 0); // 把绿头怪的防御设为0 + * @param id 敌人id + * @param name 属性的英文缩写 + * @param value 属性的新值 + * @param operator 操作符 + * @param prefix 独立开关前缀,一般不需要 + * @param norefresh 是否不刷新状态栏 + */ + setEnemy( + id: AllIdsOf<'enemys' | 'enemy48'>, + name: K, + value: Enemy[K], + operator?: MotaOperator, + prefix?: string, + norefresh?: boolean + ): void; + + /** + * 设置某个点的敌人属性 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param name 属性的英文缩写 + * @param value 属性的新值 + * @param operator 操作符 + * @param prefix 独立开关前缀,一般不需要 + * @param norefresh 是否不刷新状态栏 + */ + setEnemyOnPoint( + x: number, + y: number, + floorId: FloorIds, + name: K, + value: Enemy[K], + operator?: MotaOperator, + prefix?: string, + norefresh?: boolean + ): void; + + /** + * 重置某个点的敌人属性 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param norefresh 是否不刷新状态栏 + */ + resetEnemyOnPoint( + x: number, + y: number, + floorId?: FloorIds, + norefresh?: boolean + ): void; + + /** + * 将某个点已经设置的敌人属性移动到其他点 + * @param fromX 起始横坐标 + * @param fromY 起始纵坐标 + * @param toX 目标横坐标 + * @param toY 目标纵坐标 + * @param floorId 楼层id + * @param norefresh 是否不刷新状态栏 + */ + moveEnemyOnPoint( + fromX: number, + fromY: number, + toX: number, + toY: number, + floorId?: FloorIds, + norefresh?: boolean + ): void; + + /** + * 设置一项楼层属性并刷新状态栏 + * @example core.setFloorInfo('ratio', 2, 'MT0'); // 把主塔0层的血瓶和宝石变为双倍效果 + * @param name 要求改的属性名 + * @param values 属性的新值 + * @param floorId 楼层id,不填视为当前层 + * @param prefix 独立开关前缀,一般不需要,下同 + */ + setFloorInfo( + name: K, + values?: Floor[K], + floorId?: FloorIds, + prefix?: string + ): void; + + /** + * 设置全塔属性 + * @param name 属性名 + * @param value 属性值 + */ + setGlobalAttribute( + name: K, + value: GlobalAttribute[K] + ): void; + + /** + * 设置一个系统开关 + * @example core.setGlobalFlag('steelDoorWithoutKey', true); // 使全塔的所有铁门都不再需要钥匙就能打开 + * @param name 系统开关的英文名 + * @param value 开关的新值,您可以用!core.flags[name]简单地表示将此开关反转 + */ + setGlobalFlag( + name: K, + value: CoreFlags[K] + ): void; + + /** + * 设置文件别名 + * @param name 别名 + * @param value 别名对应的文件名 + */ + setNameMap(name: string, value?: SourceIds): void; + + /** + * 设置剧情文本的属性 + */ + setTextAttribute(data: Partial): void; + + /** + * 移动对话框 + * @param code 对话框的代码 + * @param loc 目标位置 + * @param relative 是否是相对模式 + * @param moveMode 缓动模式 + * @param time 动画时间 + * @param callback 移动完毕的回调函数 + */ + moveTextBox( + code: number, + loc: LocArr, + relative?: boolean, + moveMode?: EaseMode, + time?: number, + callback?: () => void + ): void; + + /** + * 清除对话框 + * @param code 对话框的代码 + * @param callback 回调函数 + */ + clearTextBox(code: number, callback: () => void): void; + + /** + * 关门,目标点必须为空地 + * @example core.closeDoor(0, 0, 'yellowWall', core.jumpHero); // 在左上角关掉一堵黄墙,然后主角原地跳跃半秒 + * @param x 横坐标 + * @param y 纵坐标 + * @param id 门的id,也可以用三种基础墙 + * @param callback 门完全关上后的回调函数 + */ + closeDoor( + x: number, + y: number, + id: AllIdsOf>, + callback?: () => void + ): void; + + /** + * 显示一张图片 + * @example + * // 裁剪winskin.png的最左边128×128px,放大到铺满整个视野,1秒内淡入到50%透明,编号为1 + * core.showImage(1, core.material.images.images['winskin.png'], [0,0,128,128], [0,0,416,416], 0.5, 1000); + * @param code 图片编号,为不大于50的正整数,加上100后就是对应画布层的z值,较大的会遮罩较小的,注意色调层的z值为125,UI层为140 + * @param image 图片文件名(可以是全塔属性中映射前的中文名)或图片对象(见上面的例子) + * @param sloc 一行且至多四列的数组,表示从原图裁剪的左上角坐标和宽高 + * @param loc 一行且至多四列的数组,表示图片在视野中的左上角坐标和宽高 + * @param opacityVal 不透明度,为小于1的正数。不填视为1 + * @param time 淡入时间,单位为毫秒。不填视为0 + * @param callback 图片完全显示出来后的回调函数 + */ + showImage( + code: number, + image: ImageIds | NameMapIn | ImageSource, + sloc?: [number, number, number, number], + loc?: [number, number, number?, number?], + opacityVal?: number, + time?: number, + callback?: () => void + ): void; + + /** + * 隐藏一张图片 + * @example core.hideImage(1, 1000, core.jumpHero); // 1秒内淡出1号图片,然后主角原地跳跃半秒 + * @param code 图片编号 + * @param time 淡出时间,单位为毫秒 + * @param callback 图片完全消失后的回调函数 + */ + hideImage(code: number, time?: number, callback?: () => void): void; + + /** + * 移动一张图片并/或改变其透明度 + * @example core.moveImage(1, null, 0.5); // 1秒内把1号图片变为50%透明 + * @param code 图片编号 + * @param to 新的左上角坐标,省略表示原地改变透明度 + * @param opacityVal 新的透明度,省略表示不变 + * @param moveMode 移动模式 + * @param time 移动用时,单位为毫秒。不填视为1秒 + * @param callback 图片移动完毕后的回调函数 + */ + moveImage( + code: number, + to?: LocArr, + opacityVal?: number, + moveMode?: string, + time?: number, + callback?: () => void + ): void; + + /** + * 旋转一张图片 + * @param code 图片编号 + * @param center 旋转中心像素(以屏幕为基准);不填视为图片本身中心 + * @param angle 旋转角度;正数为顺时针,负数为逆时针 + * @param moveMode 旋转模式 + * @param time 移动用时,单位为毫秒。不填视为1秒 + * @param callback 图片移动完毕后的回调函数 + */ + rotateImage( + code: number, + center?: LocArr, + angle?: number, + moveMode?: EaseMode, + time?: number, + callback?: () => void + ): void; + + /** + * 放缩一张图片 + * @param code 图片编号 + * @param center 旋转中心像素(以屏幕为基准);不填视为图片本身中心 + * @param scale 放缩至的比例 + * @param moveMode 旋转模式 + * @param time 移动用时,单位为毫秒。不填视为1秒 + * @param callback 图片移动完毕后的回调函数 + */ + scaleImage( + code: number, + center?: LocArr, + scale?: number, + moveMode?: string, + time?: number, + callback?: () => void + ): void; + + /** + * 绘制一张动图或擦除所有动图 + * @example core.showGif(); // 擦除所有动图 + * @param name 动图文件名,可以是全塔属性中映射前的中文名 + * @param x 动图在视野中的左上角横坐标 + * @param y 动图在视野中的左上角纵坐标 + */ + showGif( + name?: + | Extract> + | NameMapIn>>, + x?: number, + y?: number + ): void; + + /** + * 调节bgm的音量 + * @example core.setVolume(0, 100, core.jumpHero); // 0.1秒内淡出bgm,然后主角原地跳跃半秒 + * @param value 新的音量,为0或不大于1的正数。注意系统设置中是这个值的平方根的十倍 + * @param time 渐变用时,单位为毫秒。不填或小于100毫秒都视为0 + * @param callback 渐变完成后的回调函数 + */ + setVolume(value: number, time?: number, callback?: () => void): void; + + /** + * 视野抖动 + * @example core.vibrate(); // 视野左右抖动1秒 + * @param direction 抖动方向 + * @param time 抖动时长,单位为毫秒 + * @param speed 抖动速度 + * @param power 抖动幅度 + * @param callback 抖动平息后的回调函数 + */ + vibrate( + direction?: string, + time?: number, + speed?: number, + power?: number, + callback?: () => void + ): void; + + /** + * 强制移动主角(包括后退),这个函数的作者已经看不懂这个函数了 + * @example core.eventMoveHero(['forward'], 125, core.jumpHero); // 主角强制前进一步,用时1/8秒,然后主角原地跳跃半秒 + * @param steps 步伐数组,注意后退时跟随者的行为会很难看 + * @param time 每步的用时,单位为毫秒。0或不填则取主角的移速,如果后者也不存在就取0.1秒 + * @param callback 移动完毕后的回调函数 + */ + eventMoveHero(steps: Step[], time?: number, callback?: () => void): void; + + /** + * 主角跳跃,跳跃勇士。ex和ey为目标点的坐标,可以为null表示原地跳跃。time为总跳跃时间。 + * @example core.jumpHero(); // 主角原地跳跃半秒 + * @param ex 跳跃后的横坐标 + * @param ey 跳跃后的纵坐标 + * @param time 跳跃时长,单位为毫秒。不填视为半秒 + * @param callback 跳跃完毕后的回调函数 + */ + jumpHero( + ex?: number, + ey?: number, + time?: number, + callback?: () => void + ): void; + + /** + * 更改主角行走图 + * @example core.setHeroIcon('npc48.png', true); // 把主角从阳光变成样板0层左下角的小姐姐,但不立即刷新 + * @param name 新的行走图文件名,可以是全塔属性中映射前的中文名。映射后会被存入core.status.hero.image + * @param noDraw true表示不立即刷新(刷新会导致大地图下视野重置到以主角为中心) + */ + setHeroIcon(name: string, noDraw?: boolean): void; + + /** 检查升级事件 */ + checkLvUp(): void; + + /** + * 尝试使用一个道具 + * @example core.tryUseItem('pickaxe'); // 尝试使用破墙镐 + * @param itemId 道具id,其中敌人手册、传送器和飞行器会被特殊处理 + */ + tryUseItem(itemId: ItemIdOf<'tools' | 'constants'>): void; +} + +declare const events: new () => Events; diff --git a/project/types/eventDec.d.ts b/project/types/eventDec.d.ts new file mode 100644 index 0000000..296ce3b --- /dev/null +++ b/project/types/eventDec.d.ts @@ -0,0 +1,313 @@ +type MotaAction = any; +type MotaEvent = any[]; + +/** + * 某种类型的商店 + */ +type ShopEventOf = ShopEventMap[T]; + +interface ShopEventMap { + /** + * 普通商店 + */ + common: CommonShopEvent; + + /** + * 道具商店 + */ + item: ItemShopEvent; + + /** + * 公共事件商店 + */ + event: CommonEventShopEvent; +} + +interface ShopEventBase { + /** + * 商店的id + */ + id: string; + + /** + * 商店快捷名称 + */ + textInList: string; + + /** + * 是否在未开启状态下快捷商店不显示该商店 + */ + mustEnable: boolean; + + /** + * 是否不可预览 + */ + disablePreview: boolean; +} + +/** + * 普通商店的一个商店选项 + */ +interface CommonShopChoice { + /** + * 选项文字 + */ + text: string; + + /** + * 选项需求,需要是一个表达式 + */ + need: string; + + /** + * 图标 + */ + icon: AllIds; + + /** + * 文字的颜色 + */ + color: Color; + + /** + * 该选项被选中时执行的事件 + */ + action: MotaEvent; +} + +/** + * 普通商店 + */ +interface CommonShopEvent extends ShopEventBase { + /** + * 商店中显示的文字 + */ + text: string; + + /** + * 普通商店的选项 + */ + choices: CommonShopChoice[]; +} + +/** + * 道具商店的一个选项 + */ +interface ItemShopChoice { + /** + * 该选项的道具id + */ + id: AllIdsOf<'items'>; + + /** + * 道具存量 + */ + number: number; + + /** + * 购买时消耗的资源数量,是字符串大概是因为这玩意可以用${} + */ + money: string; + + /** + * 卖出时获得的资源数量 + */ + sell: string; + + /** + * 出现条件 + */ + condition: string; +} + +/** + * 道具商店 + */ +interface ItemShopEvent extends ShopEventBase { + /** + * 道具商店标识 + */ + item: true; + + /** + * 购买消耗什么东西,金币还是经验 + */ + use: 'money' | 'exp'; + + /** + * 每个选项 + */ + choices: ItemShopChoice[]; +} + +interface CommonEventShopEvent { + /** + * 使用的公共事件 + */ + commonEvent: EventDeclaration; +} + +interface AutoEventBase { + /** + * 自动事件的触发条件 + */ + condition: string; + + /** + * 是否只在当前层检测 + */ + currentFloor: boolean; + + /** + * 优先级,优先级越高越优先执行 + */ + priority: number; + + /** + * 是否在事件流中延迟执行 + */ + delayExecute: boolean; + + /** + * 是否允许多次执行 + */ + multiExecute: boolean; + + /** + * 当条件满足时执行的事件 + */ + data: MotaEvent; +} + +interface AutoEvent extends AutoEventBase { + /** + * 当前的楼层id + */ + floorId: FloorIds; + + /** + * 自动事件的索引 + */ + index: string; + + /** + * 事件所在的横坐标 + */ + x: number; + + /** + * 事件所在的纵坐标 + */ + y: number; + + /** + * 事件的唯一标识符 + */ + symbol: string; +} + +interface LevelChooseEvent { + /** + * 难度名称 + */ + title: string; + + /** + * 难度简称 + */ + name: string; + + /** + * 难度的hard值 + */ + hard: number; + + /** + * 难度的颜色 + */ + color: RGBArray; + + /** + * 选择该难度时执行的事件 + */ + action: MotaEvent; +} + +interface LevelUpEvent { + /** + * 升级所需经验 + */ + need: number; + + /** + * 这个等级的等级名 + */ + title: string; + + /** + * 升级时执行的事件 + */ + action: MotaEvent; +} + +/** + * 门信息 + */ +interface DoorInfo { + /** + * 开门时间 + */ + time: number; + + /** + * 开门音效 + */ + openSound: SoundIds; + + /** + * 关门音效 + */ + closeSound: SoundIds; + + /** + * 需要的钥匙 + */ + keys: Partial | `${ItemIdOf<'tools'>}:o`, number>>; + + /** + * 开门后事件 + */ + afterOpenDoor?: MotaEvent; +} + +interface ChangeFloorEvent { + /** + * 到达的楼层 + */ + floorId: ':before' | ':after' | ':now' | FloorIds; + + /** + * 到达的坐标,填了的话stair就无效了 + */ + loc?: LocArr; + + /** + * 到达的坐标 + */ + stair?: FloorChangeStair; + + /** + * 勇士朝向 + */ + direction?: HeroTurnDir; + + /** + * 楼层转换时间 + */ + time?: number; + + /** + * 是否不可穿透 + */ + ignoreChangeFloor?: boolean; +} diff --git a/project/types/eventStatus.d.ts b/project/types/eventStatus.d.ts new file mode 100644 index 0000000..5a13d10 --- /dev/null +++ b/project/types/eventStatus.d.ts @@ -0,0 +1,456 @@ +interface EventStatusDataMap { + /** + * 执行事件中 + */ + action: ActionStatusData; + + /** + * 怪物手册的信息,是当前选择了哪个怪物 + */ + book: number; + + /** + * 楼层传送器中当前楼层索引 + */ + fly: number; + + /** + * 浏览地图时的信息 + */ + viewMaps: ViewMapStatusData; + + /** + * 装备栏的信息 + */ + equipbox: EquipboxStatusData; + + /** + * 道具栏的信息 + */ + toolbox: ToolboxStatusData; + + /** + * 存档界面的信息 + */ + save: SaveStatusData; + load: SaveStatusData; + replayLoad: SaveStatusData; + replayRemain: SaveStatusData; + replaySince: SaveStatusData; + + /** + * 文本框界面的信息 + */ + text: TextStatusData; + + /** + * 确认框界面的信息 + */ + confirmBox: ConfirmStatusData; + + /** + * 关于界面,帮助界面,怪物手册详细信息界面,虚拟键盘界面,系统设置界面,系统选项栏界面, + * 快捷商店界面,存档笔记界面,同步存档界面,光标界面,录像回放界面,游戏信息界面,没有东西 + */ + about: null; + help: null; + 'book-detail': null; + keyBoard: null; + switchs: null; + 'switchs-sounds': null; + 'switchs-display': null; + 'switchs-action': null; + settings: null; + selectShop: null; + notes: null; + syncSave: null; + syncSelect: null; + localSaveSelect: null; + storageRemove: null; + cursor: null; + replay: null; + gameInfo: null; +} + +interface _EventStatusSelectionMap { + /** + * 执行事件中,一般是选择框的当前选中项 + */ + action: number; + + /** + * 装备栏中当前选中了哪个装备 + */ + equipbox: number; + + /** + * 道具栏中当前选中了哪个道具 + */ + toolbox: number; + + /** + * 当前是否是删除模式 + */ + save: boolean; + load: boolean; + + /** + * 当前选择了确认(0)还是取消(1) + */ + confirmBox: 0 | 1; + + /** + * 系统设置界面,存档笔记界面,同步存档界面,录像回放界面,游戏信息界面,当前的选择项 + */ + switchs: number; + 'switchs-sounds': number; + 'switchs-display': number; + 'switchs-action': number; + settings: number; + notes: number; + syncSave: number; + syncSelect: number; + localSaveSelect: number; + storageRemove: number; + replay: number; + gameInfo: number; +} + +interface _EventStatusUiMap { + /** + * 执行事件中,一般是与选择框有关的 + */ + action: ActionStatusUi; + + /** + * 如果是从浏览地图界面呼出的怪物手册,该项是当前正在浏览的地图的索引(注意不是id) + */ + book: number; + + /** + * 确认框中显示的文字 + */ + confirmBox: string; + + /** + * 显示设置的选择信息 + */ + 'switchs-display': SwitchsStatusData; + + /** + * 系统选项栏的选择信息 + */ + settings: SwitchsStatusData; + + /** + * 快捷商店界面,存档笔记界面,同步存档界面,录像回放界面,游戏信息界面的绘制信息 + */ + selectShop: SelectShopStatusUi; + notes: SelectShopStatusUi; + syncSave: SelectShopStatusUi; + syncSelect: SelectShopStatusUi; + localSaveSelect: SelectShopStatusUi; + storageRemove: SelectShopStatusUi; + gameInfo: SelectShopStatusUi; +} + +interface _EventStatusIntervalMap { + /** + * 执行事件中,一般用于呼出某个界面时暂存当前事件信息(? + */ + action: ActionStatusData; + + /** + * 如果是从事件中呼出的,用于存储当前事件信息,当退出怪物手册时恢复事件 + */ + book: ActionStatusData; + + /** + * 如果是从事件中呼出的,用于存储当前事件信息,当退出存档节目时恢复事件 + */ + save: ActionStatusData; + load: ActionStatusData; +} + +interface _EventStatusTimeoutMap { + /** + * 执行事件中,一般是等待用户操作事件等事件中的超时时间的判定 + */ + action: number; +} + +interface _EventStatusAnimateUiMap { + /** + * 执行事件中,一般是对话框事件的动画定时器 + */ + action: number; +} + +type EventStatus = keyof EventStatusDataMap; + +type _FillEventStatus = { + [P in EventStatus]: P extends keyof T ? T[P] : null; +}; + +type EventStatusSelectionMap = _FillEventStatus<_EventStatusSelectionMap>; +type EventStatusUiMap = _FillEventStatus<_EventStatusUiMap>; +type EventStatusIntervalMap = _FillEventStatus<_EventStatusIntervalMap>; +type EventStatusTimeoutMap = _FillEventStatus<_EventStatusTimeoutMap>; +type EventStatusAnimateUiMap = _FillEventStatus<_EventStatusAnimateUiMap>; + +/** + * 某个事件状态下的信息 + */ +interface EventStatusOf { + /** + * 当前事件状态的类型 + */ + id: T; + + /** + * 当前事件状态的信息 + */ + data: EventStatusDataMap[T]; + + /** + * 当前事件状态的选择信息 + */ + selection: EventStatusSelectionMap[T]; + + /** + * 当前事件状态的ui信息 + */ + ui: EventStatusUiMap[T]; + + /** + * 当前事件状态的定时器信息 + */ + interval: EventStatusIntervalMap[T]; + + /** + * 当前事件状态的计时器信息 + */ + timeout: EventStatusTimeoutMap[T]; + + /** + * 当前事件状态的动画信息 + */ + animateUi: EventStatusAnimateUiMap[T]; +} + +interface ActionStatusEventList { + /** + * 要执行的事件列表 + */ + todo: MotaEvent; + + /** + * 全部的事件列表 + */ + total: MotaEvent; + + /** + * 执行条件 + */ + contidion: string; +} + +interface ActionLocStackInfo { + /** + * 横坐标 + */ + x: number; + + /** + * 纵坐标 + */ + y: number; + + /** + * 楼层id + */ + floorId: FloorIds; +} + +/** + * 执行事件中 + */ +interface ActionStatusData { + /** + * 当前的事件列表 + */ + list: DeepReadonly; + + /** + * 事件执行的横坐标,或者对话框的横坐标 + */ + x?: number; + + /** + * 事件执行的纵坐标,或者对话框的纵坐标 + */ + y?: number; + + /** + * 事件执行完毕的回调函数 + */ + callback?: () => void; + + /** + * 不太清楚用处,可能是与自动事件有关的 + */ + appendingEvents: MotaEvent[]; + + /** + * 事件的坐标栈 + */ + locStack: any[]; + + /** + * 当前的事件类型 + */ + type: EventType; + + /** + * 当前事件 + */ + current: MotaAction; +} + +interface ActionStatusUi { + /** + * 显示文字事件的文字,包括确认框等 + */ + text: string; + + /** + * 确认框中确定时执行的事件 + */ + yes?: MotaEvent; + + /** + * 确认框中取消时执行的事件 + */ + no?: MotaEvent; + + /** + * 当前是选择事件时所有的选项 + */ + choices?: string[]; + + /** + * 当前是选择事件时选项框的宽度 + */ + width?: number; +} + +interface ViewMapStatusData { + /** + * 当前浏览的楼层索引 + */ + index: number; + + /** + * 是否显示伤害 + */ + damage: boolean; + + /** + * 大地图是否显示全部地图 + */ + all: boolean; + + /** + * 大地图不显示全部地图时当前的横坐标,单位格子 + */ + x: number; + + /** + * 大地图不显示全部地图时当前的纵坐标,单位格子 + */ + y: number; +} + +interface EquipboxStatusData { + /** + * 拥有装备的当前页数 + */ + page: number; + + /** + * 当前选中的装备 + */ + selectId: ItemIdOf<'equips'>; +} + +interface ToolboxStatusData { + /** + * 消耗道具的当前页码数 + */ + toolsPage: number; + + /** + * 永久道具的当前页码数 + */ + constantsPage: number; + + /** + * 当前选中的道具id + */ + selectId: ItemIdOf<'constants' | 'tools'>; +} + +interface SaveStatusData { + /** + * 当前存读档界面的页码数 + */ + page: number; + + /** + * 选择的框的偏移量,在不同状态下意义不同 + */ + offset: number; + + /** + * 当前存读档界面的模式,fav表示收藏,all表示所有存档 + */ + mode: 'fav' | 'all'; +} + +interface TextStatusData { + /** + * 文本框要显示的文字列表 + */ + list: string[]; + + /** + * 文字显示完毕后的回调函数 + */ + callback: () => void; +} + +interface ConfirmStatusData { + /** + * 点击确认时 + */ + yes: () => void; + + /** + * 点击取消时 + */ + no: () => void; +} + +interface SwitchsStatusData { + /** + * 选择项 + */ + choices: string[]; +} + +interface SelectShopStatusUi { + /** + * 选择框的偏移量 + */ + offset: number; +} diff --git a/project/types/function.d.ts b/project/types/function.d.ts new file mode 100644 index 0000000..86c1e1c --- /dev/null +++ b/project/types/function.d.ts @@ -0,0 +1,282 @@ +interface ActionData { + /** + * 当按键弹起时 + * @param keyCode 按键的keyCode + * @param altKey 当前是否按下了alt键 + */ + onKeyUp(keyCode: number, altKey: boolean): boolean; + + /** + * 当点击状态栏时 + * @param px 点击的横坐标 + * @param py 点击的纵坐标 + * @param vertical 当前是否是竖屏 + */ + onClickStatusBar(px: number, py: number, vertical: boolean): boolean; +} + +interface ControlData { + /** + * 获取保存信息 + */ + saveData(): Save; + + /** + * 读取一个存档 + * @param data 存档信息 + * @param callback 读取完毕后的回调函数 + */ + loadData(data: Save, callback?: () => void): void; + + /** + * 获取一个属性对应的中文名 + * @param name 要获取的状态名称 + */ + getStatusLabel(name: string): string; + + /** + * 变更勇士的debuff + * @param action 触发的类型,get表示获得debuff,remove表示移除debuff + * @param type 获取的debuff列表 + */ + triggerDebuff(action: 'get' | 'remove', type: string | string[]): void; + + /** + * 立即仅更新状态栏 + */ + updateStatusBar(): void; + + /** + * 更新一个地图的地图伤害 + * @param floorId 要更新的楼层id + */ + updateCheckBlock(floorId: FloorIds): void; + + /** + * 每步移动后执行的函数 + * @param callback 回调函数(好像没什么必要吧 + */ + moveOneStep(callback?: () => void): void; + + /** + * 瞬移到某一点 + * @param x 瞬移至的横坐标 + * @param y 瞬移至的纵坐标 + * @param ignoreSteps 忽略的步数,不填则会自动计算 + */ + moveDirectly(x: number, y: number, ignoreSteps?: number): boolean; + + /** + * 并行脚本 + * @param time 距离游戏加载完毕经过的时间 + */ + parallelDo(time: number): void; +} + +interface EnemyData { + /** + * 获得所有特殊属性定义 + */ + getSpecials(): EnemySpecialDeclaration[]; + + /** + * 获得怪物真实属性 + * @param enemy 敌人id或敌人对象 + * @param hero 勇士信息,不填则从core.status.hero获取 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + */ + getEnemyInfo( + enemy: EnemyIds | Enemy, + hero?: HeroStatus, + x?: number, + y?: number, + floorId?: FloorIds + ): EnemyInfo; + + /** + * 获得战斗伤害信息(实际伤害计算函数) + * @param enemy 敌人id或敌人对象 + * @param hero 勇士信息,不填则从core.status.hero获取 + * @param x 敌人的横坐标 + * @param y 敌人的纵坐标 + * @param floorId 敌人所在的地图 + */ + getDamageInfo( + enemy: EnemyIds | Enemy, + hero?: HeroStatus, + x?: number, + y?: number, + floorId?: FloorIds + ): DamageInfo; + + /** + * 判定某种特殊属性的有无 + * @example core.hasSpecial('greenSlime', 1) // 判定绿头怪有无先攻属性 + * @param special 敌人id或敌人对象或正整数数组或自然数 + * @param test 待检查的属性编号 + * @returns 若special为数组或数且含有test或相等、或special为敌人id或对象且具有此属性,则返回true + */ + hasSpecial( + special: number | number[] | EnemyIds | Enemy, + test: number + ): boolean; +} + +interface UiData { + /** + * 获取道具栏要显示的道具 + * @param cls 要获取的类型 + */ + getToolboxItems>(cls: T): ItemIdOf[]; + + /** + * 绘制状态栏 + */ + drawStatusBar(): void; + + /** + * 数据统计界面统计的道具数量 + */ + drawStatistics(): AllIdsOf<'items'>[]; + + /** + * 绘制关于界面 + */ + drawAbout(): void; +} + +interface EventData { + /** + * 重置游戏 + * @param hero 勇士信息 + * @param hard 难度信息 + * @param floorId 勇士所在楼层 + * @param maps 所有的地图信息 + * @param values 全局数值信息 + */ + resetGame( + hero: HeroStatus, + hard: string, + floorId: FloorIds, + maps: GameStatus['maps'], + values: Partial + ): void; + + /** + * 游戏获胜 + * @param reason 胜利原因 + * @param norank 是否不计榜 + * @param noexit 是否不退出 + */ + win(reason: string, norank?: boolean, noexit?: boolean): void; + + /** + * 游戏失败 + * @param reason 失败原因 + */ + lose(reason: string): void; + + /** + * 切换楼层中,即屏幕完全变黑的那一刻 + * @param floorId 目标楼层 + * @param heroLoc 勇士到达的位置 + */ + changingFloor(floorId: FloorIds, heroLoc: Loc): void; + + /** + * 切换楼层后 + * @param floorId 目标楼层 + */ + afterChangeFloor(floorId: FloorIds): void; + + /** + * 飞往某个楼层 + * @param toId 目标楼层 + * @param callback 飞到后的回调函数 + */ + flyTo(toId: FloorIds, callback: () => void): void; + + /** + * 与怪物战斗前 + * @param enemyId 打败的怪物 + * @param x 怪物横坐标 + * @param y 怪物纵坐标 + */ + beforeBattle( + enemyId: AllIdsOf<'enemys' | 'enemy48'>, + x?: number, + y?: number + ): void; + + /** + * 与怪物战斗后 + * @param enemyId 打败的怪物 + * @param x 怪物横坐标 + * @param y 怪物纵坐标 + */ + afterBattle( + enemyId: AllIdsOf<'enemys' | 'enemy48'>, + x?: number, + y?: number + ): void; + + /** + * 开门后 + * @param doorId 门的id + * @param x 门的横坐标 + * @param y 门的纵坐标 + */ + afterOpenDoor( + doorId: AllIdsOf>, + x: number, + y: number + ): void; + + /** + * 获得道具后 + * @param itemId 道具id + * @param x 道具横坐标 + * @param y 道具纵坐标 + * @param isGentleClick 是否是轻按 + */ + afterGetItem( + itemId: AllIdsOf<'items'>, + x: number, + y: number, + isGentleClick?: boolean + ): void; + + /** + * 推箱子后 + */ + afterPushBox(): void; +} + +interface FunctionsData { + /** + * 交互信息 + */ + actions: ActionData; + + /** + * 游戏的逻辑信息 + */ + control: ControlData; + + /** + * 怪物信息 + */ + enemys: EnemyData; + + /** + * ui信息 + */ + ui: UiData; + + /** + * 事件信息 + */ + events: EventData; +} diff --git a/project/types/icon.d.ts b/project/types/icon.d.ts new file mode 100644 index 0000000..47bfaef --- /dev/null +++ b/project/types/icon.d.ts @@ -0,0 +1,71 @@ +type IconIds = + | keyof MaterialIcon['animates'] + | keyof MaterialIcon['autotile'] + | keyof MaterialIcon['enemy48'] + | keyof MaterialIcon['enemys'] + | keyof MaterialIcon['hero'] + | keyof MaterialIcon['items'] + | keyof MaterialIcon['items'] + | keyof MaterialIcon['npc48'] + | keyof MaterialIcon['npcs'] + | keyof MaterialIcon['terrains']; + +interface IconOffsetInfo { + /** + * 图块所在额外素材的id + */ + image: string; + + /** + * 图块所在图片位于额外素材的横坐标 + */ + x: number; + + /** + * 图块所在图片位于额外素材的纵坐标 + */ + y: number; +} + +/** + * 和图标相关的内容 + */ +interface Icons { + /** + * 图标信息 + */ + readonly icons: MaterialIcon; + + /** + * 额外素材偏移起点 + */ + readonly tilesetStartOffset: 10000; + + /** + * 图标的id + */ + readonly allIconIds: IconIds; + + /** + * 获得所有图标类型 + */ + getIcons(): MaterialIcon; + + /** + * 根据ID获得图块类型 + */ + getClsFromId(id: T): ClsOf; + + /** + * 获得所有图标的ID + */ + getAllIconIds(): IconIds; + + /** + * 根据图块数字或ID获得所在的tileset和坐标信息 + * @param id 图块数字或id + */ + getTilesetOffset(id: string | number): IconOffsetInfo | null; +} + +declare const icons: new () => Icons; diff --git a/project/types/item.d.ts b/project/types/item.d.ts new file mode 100644 index 0000000..aca1067 --- /dev/null +++ b/project/types/item.d.ts @@ -0,0 +1,281 @@ +interface Item> { + /** + * 道具id + */ + id: I; + + /** + * 道具的类型 + */ + cls: ItemClsOf; + + /** + * 道具的名称 + */ + name: string; + + /** + * 道具的描述 + */ + text?: string; + + /** + * 是否在道具栏隐藏 + */ + hideInToolBox: boolean; + + /** + * 装备信息 + */ + equip: ItemClsOf extends 'equips' ? Equip : never; + + /** + * 回放使用时是否不先打开道具栏再使用 + */ + hideInReplay: boolean; + + /** + * 即捡即用效果 + */ + itemEffect?: string; + + /** + * 即捡即用道具捡过之后的提示 + */ + itemEffectTip?: string; + + /** + * 使用道具时执行的事件 + */ + useItemEvent?: MotaEvent; + + /** + * 使用道具时执行的代码 + */ + useItemEffect?: string; + + /** + * 能否使用道具 + */ + canUseItemEffect?: string | boolean; +} + +interface EquipBase { + /** + * 装备增加的数值 + */ + value: Record, number>; + + /** + * 装备增加的百分比 + */ + percentage: Record, number>; +} + +interface Equip extends EquipBase { + /** + * 可以装备到的装备孔 + */ + type: number | string; + + /** + * 穿上装备时执行的事件 + */ + equipEvent: MotaEvent; + + /** + * 脱下装备时执行的事件 + */ + unequipEvent: MotaEvent; +} + +/** + * 道具相关的内容 + */ +interface Items { + /** + * 获得所有道具 + */ + getItems(): { + [P in AllIdsOf<'items'>]: Item

; + }; + + /** + * 执行即捡即用类的道具获得时的效果 + * @example core.getItemEffect('redPotion', 10) // 执行获得10瓶红血的效果 + * @param itemId 道具id + * @param itemNum 道具数量,默认为1 + */ + getItemEffect(itemId: AllIdsOf<'items'>, itemNum?: number): void; + + /** + * 即捡即用类的道具获得时的额外提示 + * @example core.getItemEffectTip(redPotion) // (获得 红血瓶)',生命+100' + * @param itemId 道具id + * @returns 图块属性itemEffectTip的内容 + */ + getItemEffectTip(itemId: AllIdsOf<'items'>): string; + + /** + * 使用一个道具 + * @example core.useItem('pickaxe', true) // 使用破墙镐,不计入录像,无回调 + * @param itemId 道具id + * @param noRoute 是否不计入录像,快捷键使用的请填true,否则可省略 + * @param callback 道具使用完毕或使用失败后的回调函数,好像没什么意义吧( + */ + useItem( + itemId: ItemIdOf<'tools' | 'constants'>, + noRoute?: boolean, + callback?: () => void + ): void; + + /** + * 检查能否使用某种道具 + * @example core.canUseItem('pickaxe') // 能否使用破墙镐 + * @param itemId 道具id + * @returns true表示可以使用 + */ + canUseItem(itemId: AllIdsOf<'items'>): boolean; + + /** + * 统计某种道具的持有量 + * @example core.itemCount('yellowKey') // 持有多少把黄钥匙 + * @param itemId 道具id + * @returns 该种道具的持有量,不包括已穿戴的装备 + */ + itemCount(itemId: AllIdsOf<'items'>): number; + + /** + * 检查主角是否持有某种道具(不包括已穿戴的装备) + * @example core.hasItem('yellowKey') // 主角是否持有黄钥匙 + * @param itemId 道具id + * @returns true表示持有 + */ + hasItem(itemId: AllIdsOf<'items'>): boolean; + + /** + * 检查主角是否穿戴着某件装备 + * @example core.hasEquip('sword5') // 主角是否装备了神圣剑 + * @param itemId 装备id + * @returns true表示已装备 + */ + hasEquip(itemId: ItemIdOf<'equips'>): boolean; + + /** + * 检查主角某种类型的装备目前是什么 + * @example core.getEquip(1) // 主角目前装备了什么盾牌 + * @param equipType 装备类型,自然数 + * @returns 装备id,null表示未穿戴 + */ + getEquip(equipType: number): ItemIdOf<'equips'> | null; + + /** + * 设置某种道具的持有量 + * @example core.setItem('yellowKey', 3) // 设置黄钥匙为3把 + * @param itemId 道具id + * @param itemNum 新的持有量,可选,自然数,默认为0 + */ + setItem(itemId: AllIdsOf<'items'>, itemNum?: number): void; + + /** + * 静默增减某种道具的持有量 不会更新游戏画面或是显示提示 + * @example core.addItem('yellowKey', -2) // 没收两把黄钥匙 + * @param itemId 道具id + * @param itemNum 增加量,负数表示减少 + */ + addItem(itemId: AllIdsOf<'items'>, itemNum?: number): void; + + /** + * @deprecated 使用addItem代替。 + * 删除某个物品一定的数量,相当于addItem(itemId, -n); + * @param itemId 道具id + * @param itemNum 减少量,负数表示增加 + */ + removeItem(itemId?: AllIdsOf<'items'>, itemNum?: number): void; + + /** + * 根据类型获得一个可用的装备孔 + * @param equipId 道具名称 + */ + getEquipTypeByName(name?: ItemIdOf<'equips'>): number; + + /** + * 判定某件装备的类型 + * @example core.getEquipTypeById('shield5') // 1(盾牌) + * @param equipId 装备id + * @returns 类型编号,自然数 + */ + getEquipTypeById(equipId: ItemIdOf<'equips'>): number; + + /** + * 检查能否穿上某件装备 + * @example core.canEquip('sword5', true) // 主角可以装备神圣剑吗,如果不能会有提示 + * @param equipId 装备id + * @param hint 无法穿上时是否提示(比如是因为未持有还是别的什么原因) + * @returns true表示可以穿上,false表示无法穿上 + */ + canEquip(equipId: ItemIdOf<'equips'>, hint?: boolean): boolean; + + /** + * 尝试穿上某件背包里的装备并提示 + * @example core.loadEquip('sword5') // 尝试装备上背包里的神圣剑,无回调 + * @param equipId 装备id + * @param callback 穿戴成功或失败后的回调函数 + */ + loadEquip(equipId: ItemIdOf<'equips'>, callback?: () => void): void; + + /** + * 脱下某个类型的装备 + * @example core.unloadEquip(1) // 卸下盾牌,无回调 + * @param equipType 装备类型编号,自然数 + * @param callback 卸下装备后的回调函数 + */ + unloadEquip(equipType: number, callback?: () => void): void; + + /** + * 比较两件(类型可不同)装备的优劣 + * @example core.compareEquipment('sword5', 'shield5') // 比较神圣剑和神圣盾的优劣 + * @param compareEquipId 装备甲的id + * @param beComparedEquipId 装备乙的id + * @returns 两装备的各属性差,甲减乙,0省略 + */ + compareEquipment>( + compareEquipId: F, + beComparedEquipId: Exclude, F> + ): EquipBase; + + /** + * 保存当前套装 + * @example core.quickSaveEquip(1) // 将当前套装保存为1号套装 + * @param index 套装编号,自然数 + */ + quickSaveEquip(index: number): void; + + /** + * 快速换装 + * @example core.quickLoadEquip(1) // 快速换上1号套装 + * @param index 套装编号,自然数 + */ + quickLoadEquip(index: number): void; + + /** + * 设置某个装备的属性并计入存档 + * @example core.setEquip('sword1', 'value', 'atk', 300, '+='); // 设置铁剑的攻击力数值再加300 + * @param equipId 装备id + * @param valueType 增幅类型,只能是value(数值)或percentage(百分比) + * @param name 要修改的属性名称,如atk + * @param value 要修改到的属性数值 + * @param operator 操作符,如+=表示在原始值上增加 + * @param prefix 独立开关前缀,一般不需要 + */ + setEquip( + equipId: ItemIdOf<'equips'>, + valueType: 'value' | 'percentage', + name: keyof SelectType, + value: number, + operator?: MotaOperator, + prefix?: string + ): void; +} + +declare const items: new () => Items; diff --git a/project/types/loader.d.ts b/project/types/loader.d.ts new file mode 100644 index 0000000..ae8f95a --- /dev/null +++ b/project/types/loader.d.ts @@ -0,0 +1,65 @@ +/** + * 负责资源的加载 + */ +interface Loader { + /** + * 加载一系列图片 + * @param dir 图片所在目录 + * @param names 图片名称列表 + * @param toSave 要保存到的对象 + * @param callback 加载完毕后的回调函数 + */ + loadImages( + dir: string, + names: string[], + toSave: Record, + callback?: () => void + ): void; + + /** + * 加载某一张图片 + * @param dir 图片所在目录 + * @param imgName 图片名称 + * @param callback 加载完毕的回调函数 + */ + loadImage(dir: string, imgName: string, callback?: () => void): void; + + /** + * 从zip中加载一系列图片 + * @param url 图片所在目录 + * @param names 图片名称列表 + */ + loadImagesFromZip( + url: string, + names: string, + toSave: Record, + onprogress?: (loaded: number, total: number) => void, + onfinished?: () => void + ): void; + + /** + * 加载一个音乐 + * @param name 要加载的音乐的名称 + */ + loadOneMusic(name: BgmIds): void; + + /** + * 加载一个音效 + * @param name 要加载的音效的名称 + */ + loadOneSound(name: SoundIds): void; + + /** + * 加载一个bgm + * @param name 加载的bgm的id或名称 + */ + loadBgm(name: BgmIds | NameMapIn): void; + + /** + * 释放一个bgm的缓存 + * @param name 要释放的bgm的id或名称 + */ + freeBgm(name: BgmIds | NameMapIn): void; +} + +declare const loader: new () => Loader; diff --git a/project/types/map.d.ts b/project/types/map.d.ts new file mode 100644 index 0000000..42a05aa --- /dev/null +++ b/project/types/map.d.ts @@ -0,0 +1,1349 @@ +type NotCopyPropertyInCompressedMap = + | 'firstArrive' + | 'eachArrive' + | 'blocks' + | 'parallelDo' + | 'map' + | 'bgmap' + | 'fgmap' + | 'events' + | 'changeFloor' + | 'beforeBattle' + | 'afterBattle' + | 'afterGetItem' + | 'afterOpenDoor' + | 'cannotMove' + | 'cannotMoveIn'; + +/** + * 压缩后的地图 + */ +type CompressedMap = Omit< + Floor, + NotCopyPropertyInCompressedMap +>; + +interface Block { + /** + * 横坐标 + */ + x: number; + + /** + * 纵坐标 + */ + y: number; + + /** + * 图块数字 + */ + id: N; + + /** + * 事件信息 + */ + event: { + /** + * 图块类型 + */ + cls: ClsOf; + + /** + * 图块id + */ + id: NumberToId[N]; + + /** + * 图块动画帧数 + */ + animate: FrameOf>; + + /** + * 图块是否不可通行 + */ + nopass: boolean; + + /** + * 图块高度 + */ + height: 32 | 48; + + /** + * 触发器 + */ + trigger?: MotaTrigger; + + /** + * 是否可被破 + */ + canBreak?: boolean; + + /** + * 门信息 + */ + doorInfo?: DoorInfo; + }; +} + +interface FloorBase { + /** + * 楼层id + */ + floorId: T; + + /** + * 楼层在状态栏的名称 + */ + name: string; + + /** + * 地图宝石倍率 + */ + ratio: number; + + /** + * 地图的宽度 + */ + width: number; + + /** + * 地图的高度 + */ + height: number; + + /** + * 地板样式 + */ + defaultGround: AllIds; + + /** + * 楼层贴图 + */ + image: FloorAnimate[]; + + /** + * 楼层名称 + */ + title: string; + + /** + * 是否能飞出 + */ + canFlyFrom: boolean; + + /** + * 是否能飞到 + */ + canFlyTo: boolean; + + /** + * 是否能使用快捷商店 + */ + canUseQuickShop: boolean; + + /** + * 是否不可浏览 + */ + cannotViewMap?: boolean; + + /** + * 是否是地下层 + */ + underGround?: boolean; + + /** + * 自动事件 + */ + autoEvent: Record; + + /** + * 天气 + */ + weather?: [type: string, level: WeatherLevel]; + + /** + * 事件层地图 + */ + map: number[][]; + + /** + * 并行脚本 + */ + parallelDo?: string; + + /** + * 色调 + */ + color?: Color; + + /** + * 背景音乐 + */ + bgm?: BgmIds | BgmIds[]; +} + +interface Floor extends FloorBase { + /** + * 图块信息 + */ + blocks: Block[]; +} + +interface ResolvedFloor extends FloorBase { + /** + * 战后事件 + */ + afterBattle: Record; + + /** + * 获得道具后事件 + */ + afterGetItem: Record; + + /** + * 开门后事件 + */ + afterOpenDoor: Record; + + /** + * 战前事件 + */ + beforeBattle: Record; + + /** + * 不可出方向 + */ + cannotMove: Record; + + /** + * 不可入方向 + */ + cannotMoveIn: Record; + + /** + * 普通事件 + */ + events: Record; + + /** + * 背景层 + */ + bgmap: number[][]; + + /** + * 前景层 + */ + fgmap: number[][]; + + /** + * 楼层切换 + */ + changeFloor: Record; + + /** + * 首次到达事件 + */ + firstArrive?: MotaEvent; + + /** + * 每次到达事件 + */ + eachArrive?: MotaEvent; +} + +interface BlockInfo { + /** + * 图块数字 + */ + number: T; + + /** + * 图块id + */ + id: NumberToId[T]; + + /** + * 图块类型 + */ + cls: ClsOf; + + /** + * 图块名称 + */ + name: string; + + /** + * 图片信息 + */ + image: HTMLImageElement; + + /** + * 图块所在图片的横坐标 + */ + posX: number; + + /** + * 图块所在图片的纵坐标 + */ + posY: number; + + /** + * 门信息 + */ + doorInfo: DoorInfo; + + /** + * 图片的高度 + */ + height: 32 | 48; + + /** + * faceId信息 + */ + faceIds: Record; + + /** + * 动画帧数 + */ + animate: FrameOf>; + + /** + * 朝向 + */ + face: Dir; + + /** + * 大怪物信息 + */ + bigImage: HTMLImageElement; +} + +interface DrawMapConfig { + /** + * 是否是重绘 + */ + redraw: boolean; + + /** + * 要绘制到的画布 + */ + ctx: CtxRefer; + + /** + * 是否是在地图画布上绘制的 + */ + onMap: boolean; +} + +interface DrawThumbnailConfig { + /** + * 勇士的位置 + */ + heroLoc: LocArr; + + /** + * 勇士的图标 + */ + heroIcon: ImageIds; + + /** + * 是否绘制显伤 + */ + damage: boolean; + + /** + * 变量信息,存读档时使用,可以无视 + */ + flags: Flags; + + /** + * 绘制到的画布 + */ + ctx: CtxRefer; + + /** + * 绘制位置的横坐标 + */ + x: number; + + /** + * 绘制位置的纵坐标 + */ + y: number; + + /** + * 绘制大小,比例数字,例如1代表与实际地图大小相同 + */ + size: number; + + /** + * 绘制全图 + */ + all: boolean; + + /** + * 绘制的视野中心横坐标 + */ + centerX: number; + + /** + * 绘制的视野中心纵坐标 + */ + centerY: number; + + /** + * 是否不是高清画布,存读档时使用,可以无视 + */ + noHD: boolean; + + /** + * 是否使用v2优化 + */ + v2: boolean; +} + +interface BlockFilter { + /** + * 高斯模糊 + */ + blur: number; + + /** + * 色相旋转 + */ + hue: number; + + /** + * 饱和度 + */ + grayscale: number; + + /** + * 反色 + */ + invert: boolean; + + /** + * 阴影 + */ + shadow: boolean; +} + +interface SearchedBlock { + /** + * 横坐标 + */ + x: number; + + /** + * 纵坐标 + */ + y: number; + + /** + * 楼层id + */ + floorId: FloorIds; + + /** + * 图块信息 + */ + block: Block; +} + +/** + * 负责一切和地图相关的处理内容 + */ +interface Maps { + /** + * 图块信息 + */ + blocksInfo: { + [P in keyof NumberToId]: MapDataOf

; + }; + + /** + * 加载某个楼层 + * @param floorId 楼层id + * @param map 地图信息,不填表示直接从原地图中获取 + */ + loadFloor( + floorId: T, + map?: number[][] | { map: number[][] } + ): ResolvedFloor; + + /** + * 解析地图信息 + * @param map 地图id或地图对象 + */ + extractBlocks(map?: FloorIds | ResolvedFloor): void; + + /** + * 根据需求为UI解析出blocks + * @param map 地图信息 + * @param flags 变量信息 + */ + extractBlocksForUI(map?: ResolvedFloor, flags?: Record): void; + + /** + * 根据图块id得到数字(地图矩阵中的值) + * @example core.getNumberById('yellowWall'); // 1 + * @param id 图块id + * @returns 图块的数字 + */ + getNumberById(id: T): IdToNumber[T]; + + /** + * 根据数字获得图块 + * @param number 图块数字 + */ + getBlockByNumber(number: T): Block; + + /** + * 根据ID获得图块 + * @param id 图块的id + */ + getBlockById(id: T): Block; + + /** + * 获得当前事件点的ID + */ + getIdOfThis(id?: 'this' | AllIds): string; + + /** + * 初始化一个图块 + * @param x 横坐标 + * @param y 纵坐标 + * @param id 图块的id + * @param addInfo 是否添加触发器信息等 + * @param eventFloor 所在地图信息 + */ + initBlock( + x: number, + y: number, + id: AllIds | AllNumbers, + addInfo?: boolean, + eventFloor?: ResolvedFloor + ): Block; + + /** + * 压缩地图 + * @param mapArr 地图数组 + * @param floorId 地图id + */ + compressMap(mapArr?: number[][], floorId?: FloorIds): number[][]; + + /** + * 设置图块的不透明度 + * @param opacity 不透明度 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + */ + setBlockOpacity( + opacity: number, + x: number, + y: number, + floorId?: FloorIds + ): void; + + /** + * 设置图块的滤镜 + * @param filter 滤镜信息 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + */ + setBlockFilter( + filter: string, + x: number, + y: number, + floorId?: FloorIds + ): void; + + /** + * 获取某个图块是否被强制启用或禁用 + * @param floorId 楼层id + * @param x 横坐标 + * @param y 纵坐标 + * @param flags 变量信息 + */ + isMapBlockDisabled( + floorId: FloorIds, + x: number, + y: number, + flags?: Record + ); + + /** + * 设置某个点的图块强制启用/禁用状态 + * @param floorId 楼层id + * @param x 横坐标 + * @param y 纵坐标 + * @param disable 是否禁用 + */ + setMapBlockDisabled( + floorId: FloorIds, + x: number, + y: number, + disable: boolean + ); + + /** + * 解压缩地图 + * @param mapArr 地图信息 + * @param floorId 地图id + */ + decompressMap(mapArr?: number[][], floorId: FloorIds): number[][]; + + /** + * 将所有地图重新变成数字,以便于存档 + */ + saveMap(): { [P in FloorIds]?: Partial> }; + /** + * 将某个地图重新变成数字,以便于存档 + */ + saveMap(floorId: FloorIds): Partial; + + /** + * 将存档中的地图信息重新读取出来 + * @param data 多个楼层的信息 + * @param floorId 在这里没有用 + * @param flags 变量信息 + */ + loadMap( + data: { [P in T]: Partial> }, + floorId?: undefined, + flags?: Record + ): { [P in T]: ResolvedFloor }; + /** + * 加载某个楼层的信息 + * @param data 多个楼层的信息 + * @param floorId 加载的楼层 + */ + loadMap( + data: { [P in T]?: Partial> }, + floorId: T + ): ResolvedFloor; + + /** + * 更改地图画布的尺寸 + * @param floorId 楼层id + */ + resizeMap(floorId?: FloorIds): void; + + /** + * 生成事件层矩阵 + * @example core.getMapArray('MT0'); // 生成主塔0层的事件层矩阵,隐藏的图块视为0 + * @param floorId 地图id,不填视为当前地图 + * @param noCache 是否清空缓存 + * @returns 事件层矩阵,注意对其阵元的访问是[y][x] + */ + getMapArray(floorId?: FloorIds, noCache?: boolean): AllNumbers[][]; + + /** + * 获取图块的事件层数字 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param noCache 是否清空缓存 + */ + getMapNumber( + x: number, + y: number, + floorId?: FloorIds, + noCache?: boolean + ): AllNumbers; + + /** + * 以x,y的形式返回每个点的事件 + * @param floorId 楼层id + * @param noCache 是否不使用缓存 + */ + getMapBlocksObj( + floorId?: FloorIds, + noCache?: boolean + ): Record; + + /** + * 获取背景层的图块矩阵 + * @param floorId 楼层id + */ + getBgMapArray(floorId: FloorIds): AllNumbers[][]; + + /** + * 获取前景层的图块矩阵 + * @param floorId 楼层id + */ + getFgMapArray(floorId: FloorIds): AllNumbers[][]; + + /** + * 判定背景层的一个位置是什么 + * @example core.getBgNumber(); // 判断主角脚下的背景层图块的数字 + * @param x 横坐标,不填为当前勇士坐标 + * @param y 纵坐标,不填为当前勇士坐标 + * @param floorId 地图id,不填视为当前地图 + * @param noCache 是否不使用缓存 + */ + getBgNumber( + x?: number, + y?: number, + floorId?: FloorIds, + noCache?: boolean + ): AllNumbers; + + /** + * 判定前景层的一个位置是什么 + * @example core.getFgNumber(); // 判断主角脚下的前景层图块的数字 + * @param x 横坐标,不填为当前勇士坐标 + * @param y 纵坐标,不填为当前勇士坐标 + * @param floorId 地图id,不填视为当前地图 + * @param noCache 是否不使用缓存 + */ + getFgNumber( + x?: number, + y?: number, + floorId?: FloorIds, + noCache?: boolean + ): AllNumbers; + + /** + * 可通行性判定 + * @example core.generateMovableArray(); // 判断当前地图主角从各点能向何方向移动 + * @param floorId 地图id,不填视为当前地图 + * @returns 从各点可移动方向的三维数组 + */ + generateMovableArray(floorId?: FloorIds): Dir[][][]; + + /** + * 单点单朝向的可通行性判定,不判断nopass + * @exmaple core.canMoveHero(); // 判断主角是否可以前进一步 + * @param x 起点横坐标,不填视为主角当前的 + * @param y 起点纵坐标,不填视为主角当前的 + * @param direction 移动的方向,不填视为主角面对的方向 + * @param floorId 地图id,不填视为当前地图 + * @returns true表示可移动,false表示不可移动 + */ + canMoveHero( + x?: number, + y?: number, + direction?: Dir, + floorId?: FloorIds + ): boolean; + + /** + * 能否瞬移到某点,并求出节约的步数。 + * @example core.canMoveDirectly(0, 0); // 能否瞬移到地图左上角 + * @param destX 目标点的横坐标 + * @param destY 目标点的纵坐标 + * @returns 正数表示节约的步数,-1表示不可瞬移 + */ + canMoveDirectly(destX: number, destY: number): number; + + /** + * 获得某些点可否通行的信息 + * @param locs 目标路径 + * @param canMoveArray 可通行信息 + */ + canMoveDirectlyArray(locs: LocArr[], canMoveArray?: Dir[][][]): number[]; + + /** + * 自动寻路 + * @example core.automaticRoute(0, 0); // 自动寻路到地图左上角 + * @param destX 目标点的横坐标 + * @param destY 目标点的纵坐标 + * @returns 每步走完后主角的loc属性组成的一维数组 + */ + automaticRoute(destX: number, destY: number): DiredLoc[]; + + /** + * 绘制一个图块 + * @param block 要绘制的图块 + * @param animate 绘制图块的第几帧 + * @param ctx 绘制到的画布 + */ + drawBlock(block?: Block, animate?: number, ctx?: CtxRefer): void; + + /** + * 生成groundPattern + * @param floorId 楼层id + */ + generateGroundPattern(floorId?: FloorIds): void; + + /** + * 地图绘制 + * @example core.drawMap(); // 绘制当前地图 + * @param floorId 地图id,不填表示当前楼层 + */ + drawMap(floorId?: FloorIds): void; + + /** + * 重绘地图 + */ + redrawMap(): void; + + /** + * 绘制背景层(含贴图,其与背景层矩阵的绘制顺序可通过复写此函数来改变) + * @example core.drawBg(); // 绘制当前地图的背景层 + * @param floorId 地图id,不填视为当前地图 + * @param config 配置信息 + */ + drawBg(floorId?: FloorIds, config?: Partial): void; + + /** + * 绘制事件层 + * @example core.drawEvents(); // 绘制当前地图的事件层 + * @param floorId 地图id,不填视为当前地图 + * @param blocks 一般不需要 + * @param config 配置信息 + */ + drawEvents( + floorId?: FloorIds, + blocks?: Block[], + config?: Partial + ): void; + + /** + * 绘制前景层(含贴图,其与前景层矩阵的绘制顺序可通过复写此函数来改变) + * @example core.drawFg(); // 绘制当前地图的前景层 + * @param floorId 地图id,不填视为当前地图 + * @param config 配置信息 + */ + drawFg(floorId?: FloorIds, config?: Partial): void; + + /** + * 绘制缩略图 + * @example core.drawThumbnail(); // 绘制当前地图的缩略图 + * @param floorId 地图id,不填视为当前地图 + * @param blocks 一般不需要 + * @param options 额外的绘制项,可以增绘主角位置和朝向、采用不同于游戏中的主角行走图、增绘显伤、提供flags用于存读档 + */ + drawThumbnail( + floorId?: FloorIds, + blocks?: Block[], + options?: Partial + ): void; + + /** + * 判定某个点是否不可被踏入(不基于主角生命值和图块cannotIn属性) + * @example core.noPass(0, 0); // 判断地图左上角能否被踏入 + * @param x 目标点的横坐标 + * @param y 目标点的纵坐标 + * @param floorId 目标点所在的地图id,不填视为当前地图 + */ + noPass(x: number, y: number, floorId?: FloorIds): boolean; + + /** + * 某个点是否存在NPC + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + */ + npcExists(x: number, y: number, floorId?: FloorIds): boolean; + + /** + * 某个点是否存在(指定的)地形 + * @param x 横坐标 + * @param y 纵坐标 + * @param id 地形的id + * @param floorId 楼层id + */ + terrainExists( + x: number, + y: number, + id?: AllIdsOf<'terrains'>, + floorId?: FloorIds + ): boolean; + + /** + * 某个点是否存在楼梯 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + */ + stairExists(x: number, y: number, floorId?: FloorIds): boolean; + + /** + * 当前位置是否在楼梯边;在楼传平面塔模式下对箭头也有效 + */ + nearStair(): boolean; + + /** + * 某个点是否存在(指定的)怪物 + * @param x 横坐标 + * @param y 纵坐标 + * @param id 怪物的id + * @param floorId 楼层id + */ + enemyExists( + x: number, + y: number, + id?: AllIdsOf<'enemys' | 'enemy48'>, + floorId?: FloorIds + ): boolean; + + /** + * 获得某个点的block + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param showDisable 被禁用的图块是否也能被获取 + */ + getBlock( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): Block; + + /** + * 判定某个点的图块id + * @example + * // 一个简单的机关门事件,打败或炸掉这一对绿头怪和红头怪就开门 + * if ( + * core.getBlockId(x1, y1) !== 'greenSlime' && + * core.getBlockId(x2, y2) !== 'redSlime' + * ) + * core.openDoor(x3, y3); + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 被禁用的图块是否也能被获取 + * @returns 图块id,该点无图块则返回null + */ + getBlockId( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): AllIds | null; + + /** + * 判定某个点的图块数字 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 被禁用的图块是否也能被获取 + */ + getBlockNumber( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): AllNumbers; + + /** + * 判定某个点的图块类型 + * @example + * // 另一个简单的机关门事件,打败或炸掉这一对不同身高的敌人就开门 + * if (core.getBlockCls(x1, y1) !== 'enemys' && core.getBlockCls(x2, y2) !== 'enemy48') core.openDoor(x3, y3); + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 被禁用的图块是否也能被获取 + */ + getBlockCls( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): Cls | null; + + /** + * 获取图块的不透明度 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 被禁用的图块是否也能被获取 + */ + getBlockOpacity( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): number | null; + + /** + * 获取图块的滤镜 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 被禁用的图块是否也能被获取 + */ + getBlockFilter( + x: number, + y: number, + floorId?: FloorIds, + showDisable?: boolean + ): BlockFilter | null; + + /** + * 获得某个图块或素材的信息 + * @param block 图块信息,可以填图块,数字,id + */ + getBlockInfo( + block?: Block | NumberToId[T] | T + ): BlockInfo; + + /** + * 搜索图块, 支持通配符 + * @example core.searchBlock('*Door'); // 搜索当前地图的所有门 + * @param id 图块id,支持星号表示任意多个(0个起)字符 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 隐藏点是否计入,true表示计入 + */ + searchBlock( + id: string, + floorId?: FloorIds | FloorIds[], + showDisable?: boolean + ): SearchedBlock[]; + + /** + * 根据给定的筛选函数搜索全部满足条件的图块 + * @example + * // 搜索当前地图的所有门 + * core.searchBlockWithFilter(function (block) { return block.event.id.endsWith('Door'); }); + * @param blockFilter 筛选函数,可接受block输入,应当返回一个boolean值 + * @param floorId 地图id,不填视为当前地图 + * @param showDisable 隐藏点是否计入,true表示计入 + * @returns 一个详尽的数组 + */ + searchBlockWithFilter( + blockFilter: (block: Block) => boolean, + floorId?: FloorIds | FloorIds[], + showDisable?: boolean + ): SearchedBlock[]; + + /** + * 获得某个图块对应行走图朝向向下的那一项的id,如果不存在行走图绑定则返回自身id + * @param block 要获得的图块 + */ + getFaceDownId(block: Block | AllIds | AllNumbers): AllIds; + + /** + * 显示(隐藏或显示的)图块,此函数将被“显示事件”指令和勾选了“不消失”的“移动/跳跃事件”指令(如阻击怪)的终点调用 + * @example core.showBlock(0, 0); // 显示地图左上角的图块 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + */ + showBlock(x: number, y: number, floorId?: FloorIds): void; + + /** + * 隐藏一个图块,对应于「隐藏事件」且不删除 + * @example core.hideBlock(0, 0); // 隐藏地图左上角的图块 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + */ + hideBlock(x: number, y: number, floorId?: FloorIds): void; + + /** + * 根据图块的索引来隐藏图块 + * @param index 要隐藏的图块的索引 + * @param floorId 地图id + */ + hideBlockByIndex(index: number, floorId?: FloorIds): void; + + /** + * 一次性隐藏多个block + * @param indexes 索引列表 + * @param floorId 地图id + */ + hideBlockByIndexes(indexes: number[], floorId?: FloorIds): void; + + /** + * 删除一个图块,对应于「隐藏事件」并同时删除 + * @example core.removeBlock(0, 0); // 尝试删除地图左上角的图块 + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + * @returns 有没有删除成功 + */ + removeBlock(x: number, y: number, floorId?: FloorIds): boolean; + + /** + * 根据block的索引(尽可能)删除该块 + * @param index 要删除的图块的索引 + * @param floorId 地图id + */ + removeBlockByIndex(index: number, floorId?: FloorIds): void; + + /** + * 一次性删除多个block + * @param indexes 索引列表 + * @param floorId 地图id + */ + removeBlockByIndexes(indexes: number[], floorId?: FloorIds): void; + + /** + * 显示前景/背景地图 + * @param name 图层名 + * @param loc 要显示的坐标列表 + * @param floorId 楼层id + * @param callback 显示完毕的回调函数 + */ + showBgFgMap( + name: 'bg' | 'bg2' | 'fg' | 'fg2', + loc: LocArr | LocArr[], + floorId?: FloorIds, + callback?: () => void + ): void; + + /** + * 隐藏前景/背景地图 + * @param name 图层名 + * @param loc 要显示的坐标列表 + * @param floorId 楼层id + * @param callback 显示完毕的回调函数 + */ + hideBgFgMap( + name: 'bg' | 'bg2' | 'fg' | 'fg2', + loc: LocArr | LocArr[], + floorId?: FloorIds, + callback?: () => void + ): void; + + /** + * 显示一个楼层贴图 + * @param loc 楼层贴图的位置 + * @param floorId 楼层id + * @param callback 显示完毕后的回调函数 + */ + showFloorImage( + loc?: LocArr | LocArr[], + floorId?: FloorIds, + callback?: () => void + ): void; + + /** + * 隐藏一个楼层贴图 + * @param loc 楼层贴图的位置 + * @param floorId 楼层id + * @param callback 显示完毕后的回调函数 + */ + hideFloorImage( + loc?: LocArr | LocArr[], + floorId?: FloorIds, + callback?: () => void + ): void; + + /** + * 转变图块 + * @example core.setBlock(1, 0, 0); // 把地图左上角变成黄墙 + * @param number 新图块的数字或id + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + */ + setBlock( + number: AllIds | AllNumbers | `${AllNumbers}`, + x: number, + y: number, + floorId?: FloorIds + ): void; + + /** + * 动画形式转变某点图块 + * @param number 要转变成的图块的数字或id + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 楼层id + * @param time 转变时间 + * @param callback 转变开始或完成后的回调函数 + */ + animateSetBlock( + number: AllIds | AllNumbers | `${AllNumbers}`, + x: number, + y: number, + floorId?: FloorIds, + time?: number, + callback?: () => void + ): void; + + /** + * 动画形式转变若干点图块 + * @param number 要转变成的图块的数字或id + * @param locs 坐标数组 + * @param floorId 楼层id + * @param time 转变时间 + * @param callback 转变开始或完成后的回调函数 + */ + animateSetBlocks( + number: AllIds | AllNumbers | `${AllNumbers}`, + locs: LocArr | LocArr[], + floorId?: FloorIds, + time?: number, + callback?: () => void + ): void; + + /** + * 某个图块转向 + * @param direction 转向的方向 + * @param x 图块所在横坐标 + * @param y 图块所在纵坐标 + * @param floorId 楼层id + */ + turnBlock( + direction: HeroTurnDir, + x: number, + y: number, + floorId?: FloorIds + ): void; + + /** + * 批量替换图块 + * @example core.replaceBlock(21, 22, core.floorIds); // 把游戏中地上当前所有的黄钥匙都变成蓝钥匙 + * @param fromNumber 旧图块的数字 + * @param toNumber 新图块的数字 + * @param floorId 地图id或其数组,不填视为当前地图 + */ + replaceBlock( + fromNumber: AllNumbers, + toNumber: AllNumbers, + floorId?: FloorIds | FloorIds[] + ): void; + + /** + * 转变图层块 + * @example core.setBgFgBlock('bg', 167, 6, 6); // 把当前地图背景层的中心块改为滑冰 + * @param name 背景还是前景 + * @param number 新图层块的数字或id + * @param x 横坐标 + * @param y 纵坐标 + * @param floorId 地图id,不填视为当前地图 + */ + setBgFgBlock( + name: 'bg' | 'fg' | 'bg2' | 'fg2', + number: AllIds | AllNumbers | `${AllNumbers}`, + x: number, + y: number, + floorId?: FloorIds + ): void; + + /** + * 重置地图,注意该功能原则上只用于调试,游戏中不应当出现 + * @param floorId 楼层id或数组 + */ + resetMap(floorId?: FloorIds | FloorIds[]): void; + + /** + * 移动图块 + * @example core.moveBlock(0, 0, ['down']); // 令地图左上角的图块下移一格,用时半秒,再花半秒淡出 + * @param x 起点的横坐标 + * @param y 起点的纵坐标 + * @param steps 步伐数组 + * @param time 单步和淡出用时,单位为毫秒。不填视为半秒 + * @param keep 是否不淡出,true表示不淡出 + * @param callback 移动或淡出后的回调函数 + */ + moveBlock( + x: number, + y: number, + steps: Step[], + time?: number, + keep?: boolean, + callback?: () => void + ): void; + + /** + * 跳跃图块;从V2.7开始不再有音效 + * @example core.jumpBlock(0, 0, 0, 0); // 令地图左上角的图块原地跳跃半秒,再花半秒淡出 + * @param sx 起点的横坐标 + * @param sy 起点的纵坐标 + * @param ex 终点的横坐标 + * @param ey 终点的纵坐标 + * @param time 单步和淡出用时,单位为毫秒。不填视为半秒 + * @param keep 是否不淡出,true表示不淡出 + * @param callback 落地或淡出后的回调函数 + */ + jumpBlock( + sx: number, + sy: number, + ex: number, + ey: number, + time?: number, + keep?: boolean, + callback?: () => void + ): void; + + /** + * 显示/隐藏某个块时的动画效果 + * @param loc 要显示或隐藏的坐标数组 + * @param type 显示还是隐藏还是移除,填数字表示设置不透明度 + * @param time 动画时间 + * @param callback 动画完毕后的回调函数 + */ + animateBlock( + loc: LocArr | LocArr[], + type: 'show' | 'hide' | 'remove' | number, + time: number, + callback?: () => void + ): void; + + /** + * 添加一个全局动画 + * @param block 图块信息 + */ + addGlobalAnimate(block?: Block): void; + + /** + * 删除所有全局动画 + */ + removeGlobalAnimate(): void; + /** + * 删除一个全局动画 + * @param x 横坐标 + * @param y 纵坐标 + */ + removeGlobalAnimate(x?: number, y?: number): void; + + /** + * 绘制UI层的box动画 + */ + drawBoxAnimate(): void; + + /** + * 播放动画,注意即使指定了主角的坐标也不会跟随主角移动,如有需要请使用core.drawHeroAnimate(name, callback)函数 + * @example core.drawAnimate('attack', core.nextX(), core.nextY(), false, core.vibrate); // 在主角面前一格播放普攻动画,动画停止后视野左右抖动1秒 + * @param name 动画文件名,不含后缀 + * @param x 绝对横坐标 + * @param y 绝对纵坐标 + * @param alignWindow 是否是相对窗口的坐标 + * @param callback 动画停止后的回调函数 + * @returns 一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数) + */ + drawAnimate( + name: AnimationIds | NameMapIn, + x: number, + y: number, + alignWindow: boolean, + callback?: () => void + ): number; + + /** + * 播放跟随勇士的动画 + * @param name 动画名 + * @param callback 动画停止后的回调函数 + * @returns 一个数字,可作为core.stopAnimate()的参数来立即停止播放(届时还可选择是否执行此次播放的回调函数) + */ + drawHeroAnimate( + name: AnimationIds | NameMapIn, + callback?: () => void + ): number; + + /** + * 获得当前正在播放的所有(指定)动画的id列表 + * @param name 指定名称 + */ + getPlayingAnimates(name?: AnimationIds): number[]; + + /** + * 立刻停止一个动画播放 + * @param id 播放动画的编号,即drawAnimate或drawHeroAnimate返回值,不填则停止所有的 + * @param doCallback 是否执行该动画的回调函数 + */ + stopAnimate(id?: number, doCallback?: boolean): void; +} + +declare const maps: new () => Maps; diff --git a/project/types/plugin.d.ts b/project/types/plugin.d.ts new file mode 100644 index 0000000..1562327 --- /dev/null +++ b/project/types/plugin.d.ts @@ -0,0 +1,191 @@ +// 这里包含所有插件导出的函数及变量声明,声明的函数会在类型标注中标注到core上 + +interface PluginDeclaration { + /** + * 添加函数 例:添加弹出文字,像这个就可以使用core.addPop或core.plugin.addPop调用 + * @param px 弹出的横坐标 + * @param py 弹出的纵坐标 + * @param value 弹出的文字 + */ + addPop(px: number, py: number, value: string): void; + + /** + * 添加变量 例:所有的正在弹出的文字,像这个就可以使用core.plugin.pop获取 + */ + pop: any[]; +} + +type Forward = { + [K in keyof T as T[K] extends Function + ? K extends `_${string}` + ? never + : K + : never]: T[K]; +}; + +type ForwardKeys = keyof Forward; + +type SpriteMouseEvent = (px: number, py: number) => void; + +type SpritKeyEvent = ( + key: string, + keyCode: number, + altKey: boolean, + ctrlKey: boolean, + shiftKey: boolean +) => void; + +type SpriteWheelEvent = ( + deltaY: number, + deltaX: number, + deltaZ: number +) => void; + +type SpriteTouchEvent = (...locs: [number, number][]) => void; + +interface SpriteEvent { + click: SpriteMouseEvent; + mousedown: SpriteMouseEvent; + mouseup: SpriteMouseEvent; + mouseenter: SpriteMouseEvent; + mouseleave: SpriteMouseEvent; + mousemove: SpriteMouseEvent; + keydown: SpritKeyEvent; + keyup: SpritKeyEvent; + keypress: SpritKeyEvent; + wheel: SpriteWheelEvent; + touchstart: SpriteTouchEvent; + touchend: SpriteTouchEvent; + touchmove: SpriteTouchEvent; + touchcancel: SpriteTouchEvent; +} + +declare class Sprite { + /** + * 递增的sprite标识符 + */ + static count: number; + + /** + * sprite的左上角横坐标 + */ + x: number; + + /** + * sprite的左上角纵坐标 + */ + y: number; + + /** + * sprite的宽度 + */ + width: number; + + /** + * sprite的高度 + */ + height: number; + + /** + * sprite的纵深 + */ + zIndex: number; + + /** + * sprite的相对模式,相对游戏还是相对窗口 + */ + reference: 'game' | 'window'; + + /** + * sprite的canvas元素 + */ + canvas: HTMLCanvasElement; + + /** + * sprite的context + */ + context: CanvasRenderingContext2D; + + /** + * sprite的名称 + */ + name: string; + + /** + * spirte的唯一标识符 + */ + readonly count: number; + + /** + * 创建一个sprite画布 + * @param reference 参考系,游戏画面或者窗口 + * @param name 可选,sprite的名称,方便通过core.dymCanvas获取 + */ + constructor( + x: number, + y: number, + w: number, + h: number, + z: number, + reference?: 'game' | 'window', + name?: string + ); + + /** + * 初始化 + */ + init(): void; + + /** + * @deprecated + * 设置css特效,使用css()代替 + */ + setCss(css: string): Sprite; + + /** + * 设置css特效 + */ + css(css: string): Sprite; + + /** + * 移动sprite + * @param isDelta 是否是相对位置,如果是,那么sprite会相对于原先的位置进行移动 + */ + move(x: number, y: number, isDelta?: boolean): Sprite; + + /** + * 重新设置sprite的大小 + * @param {boolean} styleOnly 是否只修改css效果,如果是,那么将会不高清,如果不是,那么会清空画布 + */ + resize(w: number, h: number, styleOnly?: boolean): Sprite; + + /** + * 旋转画布 + */ + rotate(angle: number, cx?: number, cy?: number): Sprite; + + /** + * 擦除画布 + */ + clear(x?: number, y?: number, w?: number, h?: number): Sprite; + + /** + * 删除 + */ + destroy(): void; + + /** + * 监听事件,与registerAction类似 + */ + on(type: K, handler: SpriteEvent[K]): void; + + /** + * 添加事件监听器 + */ + addEventListener: HTMLCanvasElement['addEventListener']; + + /** + * 删除事件监听器 + */ + removeEventListenr: HTMLCanvasElement['removeEventListener']; +} diff --git a/project/types/source.d.ts b/project/types/source.d.ts new file mode 100644 index 0000000..4fbcebd --- /dev/null +++ b/project/types/source.d.ts @@ -0,0 +1,98 @@ +/** + * 图块类型 + */ +type Cls = + | 'autotile' + | 'animates' + | 'enemys' + | 'items' + | 'npcs' + | 'terrains' + | 'enemy48' + | 'npc48' + | 'tilesets'; + +/** + * 所有的可动画图块类型 + */ +type AnimatableCls = Exclude; + +/** + * 道具类型 + */ +type ItemCls = 'tools' | 'items' | 'equips' | 'constants'; + +/** + * 所有的道具id + */ +type AllIds = keyof IdToNumber; + +/** + * 所有的道具数字 + */ +type AllNumbers = keyof NumberToId | 0; + +/** + * 某种类型的图块的id + */ +type AllIdsOf = keyof { + [P in keyof IdToCls as IdToCls[P] extends T ? P : never]: P; +}; + +/** + * 某种类型的道具的id + */ +type ItemIdOf = keyof { + [P in keyof ItemDeclaration as ItemDeclaration[P] extends T ? P : never]: P; +}; + +/** + * 某个道具的类型 + */ +type ItemClsOf> = ItemDeclaration[T]; + +/** + * 获取某个图块的类型 + */ +type ClsOf = IdToCls[T]; + +/** + * 某种类型的图块数字 + */ +type AllNumbersOf = IdToNumber[AllIdsOf]; + +/** + * 选取在一段字符串中的映射名称 + */ +type NameMapIn = keyof { + [P in keyof NameMap as NameMap[P] extends T ? P : never]: NameMap[P]; +}; + +/** + * 所有的怪物id + */ +type EnemyIds = AllIdsOf<'enemys' | 'enemy48'>; + +/** + * 各种图块的动画数量 + */ +interface FrameNumbers { + autotile: 4; + animates: 4; + enemys: 2; + items: 1; + npcs: 2; + terrains: 1; + enemy48: 4; + npc48: 4; +} + +/** + * 动画帧数 + */ +type FrameOf = FrameNumbers[T]; + +/** + * 所有的文件名 + */ +type SourceIds = ImageIds | AnimationIds | SoundIds | BgmIds | FontIds; diff --git a/project/types/status.d.ts b/project/types/status.d.ts new file mode 100644 index 0000000..9cfce80 --- /dev/null +++ b/project/types/status.d.ts @@ -0,0 +1,963 @@ +/** + * 怪物buff缓存 + */ +interface EnemyBuffCache { + /** + * 生命值提升量 + */ + hp_buff: number; + + /** + * 攻击提升量 + */ + atk_buff: number; + + /** + * 防御提升量 + */ + def_buff: number; + + /** + * 支援信息 + */ + guards: [number, number, string][]; +} + +interface CheckBlockStatus { + /** + * 捕捉信息 + */ + ambush: Record; + + /** + * 阻击信息 + */ + repulse: Record; + + /** + * 每点的伤害,小于等于0会不显示 + */ + damage: Record; + + /** + * 是否需要重算 + */ + needCache: boolean; + + /** + * 每点的伤害类型 + */ + type: Record>; + + /** + * 缓存信息,是每个怪物受到的光环加成 + */ + cache: Record>; +} + +interface DamageStatus { + /** + * v2优化下当前的偏移横坐标,单位格子 + */ + posX: number; + + /** + * v2优化下当前的偏移纵坐标,单位格子 + */ + posY: number; + + /** + * 显示的伤害信息 + */ + data: DamageStatusData[]; + + /** + * 地图伤害或其它在地图上显示的文字 + */ + extraData: DamageStatusExtraData[]; +} + +interface DamageStatusData { + /** + * 显示的文字 + */ + text: string; + + /** + * 显示横坐标,单位像素 + */ + px: number; + + /** + * 显示纵坐标,单位像素 + */ + py: number; + + /** + * 文字的颜色 + */ + color: Color; +} + +interface DamageStatusExtraData extends DamageStatusData { + /** + * 文字的不透明度 + */ + alpha: number; +} + +interface AutomaticRouteStatus { + /** + * 勇士是否正在移动 + */ + autoHeroMove: boolean; + + /** + * 不太清楚用处 + */ + autoStep: number; + + /** + * 自动寻路中已经走过的步数 + */ + movedStep: number; + + /** + * 自动寻路的总步数 + */ + destStep: number; + + /** + * 自动寻路的目标横坐标 + */ + destX: number; + + /** + * 自动寻路的目标纵坐标 + */ + destY: number; + + /** + * 自动寻路绘图时的偏移横坐标,单位像素 + */ + offsetX: number; + + /** + * 自动寻路绘图时的偏移纵坐标,单位像素 + */ + offsetY: number; + + /** + * 自动寻路的路线 + */ + autoStepRoutes: AutoStep[]; + + /** + * 剩下的自动寻路路线 + */ + moveStepBeforeStop: AutoStep[]; + + /** + * 上一步的勇士方向 + */ + lastDirection: Dir; + + /** + * 光标界面(按下E时的界面)的光标横坐标 + */ + cursorX: number; + + /** + * 光标界面(按下E时的界面)的光标纵坐标 + */ + cursorY: number; + + /** + * 是否瞬间移动 + */ + moveDirectly: boolean; +} + +interface AutoStep { + /** + * 当前步的步数 + */ + step: number; + + /** + * 当前步走向的方向 + */ + direction: Dir; +} + +interface ReplaySaveBase { + /** + * 录像播放时,剩下的要播放的录像内容 + */ + toReplay: string[]; + + /** + * 录像播放时,录像的完整信息 + */ + totalList: string[]; + + /** + * 不太清楚用处,应该是与录像回退有关的 + */ + steps: number; +} + +interface ReplayStatus extends ReplaySaveBase { + /** + * 当前是否正在播放录像,同core.isReplaying() + */ + replaying: boolean; + + /** + * 当前录像有没有暂停 + */ + pausing: boolean; + + /** + * 当前是否正在某段动画中 + */ + animate: boolean; + + /** + * 录像播放是否失败 + */ + failed: boolean; + + /** + * 当前的录像播放速度 + */ + speed: number; + + /** + * 录像的回退信息 + */ + save: ReplaySave[]; +} + +interface ReplaySave { + /** + * 回退的存档信息 + */ + data: Save; + + /** + * 回退的录像信息 + */ + replay: ReplaySaveBase; +} + +interface TextAttribute { + /** + * 文本框的位置 + */ + position: TextPosition; + + /** + * 文本的左右对齐方式 + */ + align: 'left' | 'center' | 'right'; + + /** + * 偏移像素 + */ + offset: number; + + /** + * 标题颜色 + */ + title: RGBArray; + + /** + * 背景颜色 + */ + background: RGBArray | ImageIds; + + /** + * 文字颜色 + */ + text: RGBArray; + + /** + * 标题字体大小 + */ + titlefont: number; + + /** + * 正文字体大小 + */ + textfont: number; + + /** + * 是否加粗 + */ + bold: boolean; + + /** + * 打字机时间,每隔多少毫秒显示一个字 + */ + time: number; + + /** + * 字符间距 + */ + letterSpacing: number; + + /** + * 淡入淡出时间 + */ + animateTime: number; + + /** + * 行距 + */ + lineHeight: number; +} + +interface StatusStyle { + /** + * 左侧状态栏背景,css的background属性 + */ + statusLeftBackground: string; + + /** + * 上部状态栏背景,css的background属性 + */ + statusTopBackground: string; + + /** + * 竖屏下的工具栏背景,css的background属性 + */ + toolsBackground: string; + + /** + * 游戏的边框颜色 + */ + borderColor: Color; + + /** + * 状态栏文字的颜色 + */ + statusBarColor: Color; + + /** + * 楼层切换样式,css字符串 + */ + floorChangingStyle: string; + + /** + * 全局字体 + */ + font: string; +} + +interface GlobalAttribute extends StatusStyle { + /** + * 装备栏名称 + */ + equipName: string[]; +} + +interface FloorAnimate { + /** + * 图片的目标画布 + */ + canvas: 'bg' | 'fg'; + + /** + * 图片的名称 + */ + name: ImageIds; + + /** + * 绘制横坐标 + */ + x: number; + + /** + * 绘制纵坐标 + */ + y: number; + + /** + * 裁剪横坐标 + */ + sx?: number; + + /** + * 裁剪纵坐标 + */ + sy?: number; + + /** + * 裁剪宽度 + */ + w?: number; + + /** + * 裁剪高度 + */ + h?: number; + + /** + * 绘制帧数 + */ + frame?: number; + + /** + * 图片翻转 + */ + reverse?: ':x' | ':y' | ':o'; + + /** + * 是否禁用 + */ + disable?: boolean; +} + +interface BoxAnimate { + /** + * 动画的帧数 + */ + animate: number; + + /** + * 背景的高度 + */ + bgHeight: number; + + /** + * 背景的宽度 + */ + bgWidth: number; + + /** + * 背景的左上角横坐标 + */ + bgx: number; + + /** + * 背景的左上角纵坐标 + */ + bgy: number; + + /** + * 动画图片的高度 + */ + height: 32 | 48; + + /** + * 图片信息 + */ + img: HTMLImageElement; + + /** + * 这个图块的图片在其素材图片的纵坐标 + */ + pos: number; + + /** + * 图块的横坐标 + */ + x: number; + + /** + * 图块的纵坐标 + */ + y: number; +} + +interface BigImageBoxAnimate { + /** + * 大图片的贴图信息 + */ + bigImage: HTMLImageElement; + + /** + * 贴图的朝向 + */ + face: Dir; + + /** + * 中心横坐标 + */ + centerX: number; + + /** + * 中心纵坐标 + */ + centerY: number; + + /** + * 最大宽度 + */ + max_width: number; + + /** + * 绘制到的画布 + */ + ctx: CtxRefer; +} + +interface AnimateObj { + /** + * 动画名称 + */ + name: AnimationIds; + + /** + * 动画的唯一标识符 + */ + id: number; + + /** + * 动画信息 + */ + animate: Animate; + + /** + * 中心横坐标 + */ + centerX: number; + + /** + * 中心纵坐标 + */ + centerY: number; + + /** + * 当前帧数 + */ + index: number; + + /** + * 回调函数 + */ + callback: () => void; +} + +interface ActionsPreview { + /** + * 大地图中当前是否正在拖拽 + */ + dragging: boolean; + + /** + * 大地图中是否允许拖拽 + */ + enabled: boolean; + + /** + * 大地图中当前是否已经按下了鼠标 + */ + prepareDragging: boolean; + + /** + * 当前鼠标的横坐标 + */ + px: number; + + /** + * 当前鼠标的纵坐标 + */ + py: number; +} + +interface RouteFolding { + /** + * 录像折叠信息中的勇士信息 + */ + hero: Omit, 'steps'>; + + /** + * 折叠的长度 + */ + length: number; +} + +/** + * 初始游戏状态 + */ +interface InitGameStatus { + /** + * 是否开始了游戏 + */ + played: false; + + /** + * 游戏是否结束 + */ + gameOver: false; + + /** + * 当前勇士状态信息。例如core.status.hero.atk就是当前勇士的攻击力数值 + */ + hero: {}; + + /** + * 当前层的floorId + */ + floorId: null; + + /** + * 所有楼层的地图信息 + */ + maps: { + [P in FloorIds]: Floor

; + }; + + /** + * 获得当前楼层信息,等价于core.status.maps[core.status.floorId] + */ + thisMap: null; + + /** + * 背景图块 + */ + bgmaps: Record; + + /** + * 前景图块 + */ + fgmaps: Record; + + /** + * 以坐标列举的图块 + */ + mapBlockObjs: Record>; + + /** + * 地图伤害 + */ + checkBlock: {}; + + /** + * 伤害显示信息 + */ + damage: DeepReadonly; + + /** + * 是否锁定了用户控制 + */ + lockControl: false; + + /** + * 勇士移动状态,每个数字干啥的自己去libs翻,这东西太复杂了,不过应该不会有人用这个东西吧( + */ + heroMoving: number; + + /** + * 勇士是否停下了 + */ + heroStop: boolean; + + /** + * 自动寻路状态 + */ + automaticRoute: DeepReadonly; + + /** + * 按键按下的时间,用于判定双击 + */ + downTime: number; + + /** + * ctrl键是否倍按下 + */ + ctrlDown: boolean; + + /** + * 当前录像信息 + */ + route: string[]; + + /** + * 当前的回放状态 + */ + replay: DeepReadonly; + + /** + * 当前的所有全局商店 + */ + shops: Record>; + + /** + * 当前的事件状态,样板最大的败笔之一,离谱到逆天 + */ + event: EventStatusOf; + + /** + * 当前的所有自动事件 + */ + autoEvents: DeepReadonly; + + /** + * 当前的全局剧情文本设置 + */ + textAttribute: TextAttribute; + + /** + * 部分全局属性,会跟随存档 + */ + globalAttribute: GlobalAttribute; + + /** + * 色调的颜色 + */ + curtainColor: Color; + + /** + * 全局动画对象 + */ + globalAnimateObjs: Block>>[]; + + /** + * 楼层贴图 + */ + floorAnimateObjs: FloorAnimate[]; + + /** + * 所有的BoxAnimate信息 + */ + boxAnimateObjs: (BoxAnimate | BigImageBoxAnimate)[]; + + /** + * 所有的自动元件动画 + */ + autotileAnimateObjs: Block>[]; + + /** + * 全局动画状态,每经过一个全局动画时间便加一 + */ + globalAnimateStatus: number; + + /** + * 所有绘制的动画 + */ + animateObjs: AnimateObj[]; + + /** + * 当前难度 + */ + hard: string; + + /** + * 勇士的中心 + */ + heroCenter: Record<'px' | 'py', number>; + + /** + * 当前按下的按键 + */ + holdingKeys: number[]; + + /** + * id转数字 + */ + id2number: IdToNumber; + + /** + * 数字转图块 + */ + number2block: { + [P in AllNumbers]: Block

; + }; + + /** + * 大地图中的拖拽处理 + */ + preview: ActionsPreview; + + /** + * 录像折叠信息 + */ + routeFolding: Record<`${LocString},${FirstCharOf

}`, RouteFolding>; +} + +/** + * 运行时的游戏状态 + */ +interface GameStatus extends InitGameStatus { + played: boolean; + gameOver: boolean; + floorId: FloorIds; + thisMap: ResolvedFloor; + checkBlock: Readonly; + lockControl: boolean; + hero: HeroStatus; +} + +interface Follower { + /** + * 跟随者的图片id + */ + name: ImageIds; +} + +interface HeroStatistics { + /** + * 击败的怪物数量 + */ + battle: number; + + /** + * 由于战斗损失的生命值 + */ + battleDamage: number; + + /** + * 当前游戏时间 + */ + currentTime: number; + + /** + * 获得的总经验值 + */ + exp: number; + + /** + * 由于地图伤害损失的生命值 + */ + extraDamage: number; + + /** + * 总共损失的生命值 + */ + hp: number; + + /** + * 由于瞬移少走的步数 + */ + ignoreSteps: number; + + /** + * 总共获得的金币数 + */ + money: number; + + /** + * 瞬移次数 + */ + moveDirectly: number; + + /** + * 中毒损失的生命值 + */ + poisonDamage: number; + + /** + * 本次游戏的开始时间 + */ + startTime: number; + + /** + * 游戏总时间 + */ + totalTime: number; +} + +/** + * 勇士状态 + */ +interface HeroStatus { + /** + * 勇士停止时及对话框中是否启用帧动画 + */ + animate: boolean; + + /** + * 勇士生命值 + */ + hp: number; + + /** + * 勇士生命上限 + */ + hpmax: number; + + /** + * 勇士的攻击 + */ + atk: number; + + /** + * 勇士的防御 + */ + def: number; + + /** + * 勇士的魔防 + */ + mdef: number; + + /** + * 勇士的等级 + */ + lv: number; + + /** + * 勇士的经验 + */ + exp: number; + + /** + * 勇士的金币 + */ + money: number; + + /** + * 勇士的魔法 + */ + mana: number; + + /** + * 勇士的魔法上限 + */ + manamax: number; + + /** + * 勇士的名称 + */ + name: string; + + /** + * 勇士移动过的步数 + */ + steps: number; + + /** + * 勇士的图片 + */ + image: ImageIds; + + /** + * 当前勇士的装备 + */ + equipment: ItemIdOf<'equips'>[]; + + /** + * 勇士当前的位置 + */ + loc: Loc; + + /** + * 当前的变量 + */ + flags: Flags; + + /** + * 勇士的跟随者 + */ + followers: Follower[]; + + /** + * 勇士拥有的道具 + */ + items: { + [P in Exclude]: Record, number>; + }; +} diff --git a/project/types/ui.d.ts b/project/types/ui.d.ts new file mode 100644 index 0000000..fb301dc --- /dev/null +++ b/project/types/ui.d.ts @@ -0,0 +1,827 @@ +/** + * 可以设置成的画布填充描边样式 + */ +type CanvasStyle = string | CanvasGradient | CanvasPattern; + +type ImageSource = + | CanvasImageSource + | ImageIds + | `${ImageIds}${ImageReverse}` + | NameMapIn + | `${NameMapIn}${ImageReverse}`; + +interface BackgroundPosInfo { + /** + * 横坐标 + */ + px: number; + + /** + * 纵坐标 + */ + py: number; + + /** + * 是否没有位置 + */ + noPeak: boolean; + + /** + * 横坐标偏移值 + */ + xoffset: number; + + /** + * 纵坐标偏移值 + */ + yoffset: number; + + /** + * 画布,默认是ui + */ + ctx: CtxRefer; + + /** + * 箭头指向是朝上还是朝下 + */ + position: 'up' | 'bottom'; +} + +interface TextContentConfig { + left: number; + top: number; + + /** + * 最大宽度 + */ + maxWidth: number; + + /** + * 颜色,不影响\r + */ + color: Color; + + /** + * 对齐方式 + */ + align: 'left' | 'center' | 'right'; + + /** + * 字体大小 + */ + fontSize: number; + + /** + * 行高 + */ + lineHeight: number; + + /** + * 打字机间隔 + */ + time: number; + + /** + * 字体名 + */ + font: string; + + /** + * 字符间距 + */ + letterSpacing: number; + + /** + * 是否加粗 + */ + bold: boolean; + + /** + * 是否斜体 + */ + italic: boolean; +} + +interface TextContentBlock { + left: number; + top: number; + width: number; + height: number; + line: number; + marginLeft: number; + marginTop: number; +} + +interface ReturnedTextContentConfig extends TextContentConfig { + right: number; + + /** + * 默认字体 + */ + defaultFont: string; + + /** + * 当前绘制的文字索引 + */ + index: number; + + /** + * 当前颜色 + */ + currcolor: Color; + + /** + * 当前字体 + */ + currfont: string; + + /** + * 每一行的间距 + */ + lineMargin: number; + + /** + * 每一行间距的一半 + */ + topMargin: number; + + /** + * 横坐标偏移量 + */ + offsetX: number; + + /** + * 纵坐标偏移量 + */ + offsetY: number; + + /** + * 当前行数 + */ + line: number; + + /** + * 所有的文字 + */ + blocks: TextContentBlock[]; + + /** + * 是否是高清画布 + */ + isHD: boolean; + + /** + * 这一行的最大高度 + */ + lineMaxHeight: number; + + /** + * 是否是强制换行 + */ + forceChangeLine: boolean; +} + +interface TextBoxConfig { + /** + * 画布 + */ + ctx: CtxRefer; + + /** + * 对话框位置 + */ + pos: TextBoxPos; + + /** + * 是否一次性全部显示 + */ + showAll: boolean; + + /** + * 是否异步显示 + */ + async: boolean; +} + +/** + * UI窗口的绘制,如对话框、怪物手册、楼传器、存读档界面等 + */ +interface Ui { + /** + * ui数据 + */ + uidata: UiData; + + /** + * 根据画布名找到一个画布的context;支持系统画布和自定义画布。如果不存在画布返回null。 + * 也可以传画布的context自身,则返回自己。 + */ + getContextByName(canvas: CtxRefer): CanvasRenderingContext2D | null; + + /** + * 清空某个画布图层 + * name为画布名,可以是系统画布之一,也可以是任意自定义动态创建的画布名;还可以直接传画布的context本身。(下同) + * 如果name也可以是'all',若为all则为清空所有系统画布。 + */ + clearMap( + name: CtxRefer, + x?: number, + y?: number, + w?: number, + h?: number + ): void; + + /** + * 在某个画布上绘制一段文字 + * @param text 要绘制的文本 + * @param style 绘制的样式 + * @param font 绘制的字体 + * @param maxWidth 文字整体的最大宽度,如果超过会自动缩小文字使其宽度小于这个值 + */ + fillText( + name: CtxRefer, + text: string, + x: number, + y: number, + style?: CanvasStyle, + font?: string, + maxWidth?: number + ): void; + + /** + * 根据最大宽度自动缩小字体 + * @param name 画布 + * @param text 文字 + * @param maxWidth 最大和宽度 + * @param font 字体 + */ + setFontForMaxWidth( + name: CtxRefer, + text: string, + maxWidth: number, + font?: string + ): void; + + /** + * 在某个画布上绘制一个描边文字 + * @param text 要绘制的文本 + * @param style 绘制的样式 + * @param strokeStyle 绘制的描边颜色 + * @param font 绘制的字体 + * @param lineWidth 描边的线宽 + */ + fillBoldText( + name: CtxRefer, + text: string, + x: number, + y: number, + style?: CanvasStyle, + strokeStyle?: CanvasStyle, + font?: string, + maxWidth?: number, + lineWidth?: number + ): void; + + /** + * 绘制一个矩形 + * @param style 绘制的样式 + * @param angle 旋转角度,弧度制 + */ + fillRect( + name: CtxRefer, + x: number, + y: number, + width: number, + height: number, + style?: CanvasStyle, + angle?: number + ): void; + + /** + * 绘制一个矩形的边框 + * @param style 绘制的样式 + * @param angle 旋转角度,单位弧度 + */ + strokeRect( + name: CtxRefer, + x: number, + y: number, + width: number, + height: number, + style?: CanvasStyle, + lineWidth?: number, + angle?: number + ): void; + + /** + * 在某个canvas上绘制一个圆角矩形 + */ + fillRoundRect( + name: CtxRefer, + x: number, + y: number, + width: number, + height: number, + radius: number, + style?: CanvasStyle, + angle?: number + ): void; + + /** + * 在某个canvas上绘制一个圆角矩形的边框 + */ + strokeRoundRect( + name: CtxRefer, + x: number, + y: number, + width: number, + height: number, + radius: number, + style?: CanvasStyle, + lineWidth?: number, + angle?: number + ): void; + + /** + * 在某个canvas上绘制一个多边形 + */ + fillPolygon( + name: CtxRefer, + nodes?: [x: number, y: number][], + style?: CanvasStyle + ): void; + + /** + * 在某个canvas上绘制一个多边形的边框 + */ + strokePolygon( + name: CtxRefer, + nodes?: [x: number, y: number][], + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 在某个canvas上绘制一个椭圆 + * @param a 横轴长度的一半 + * @param b 纵轴长度的一半 + * @param angle 旋转角度 + */ + fillEllipse( + name: CtxRefer, + x: number, + y: number, + a: number, + b: number, + angle?: number, + style?: CanvasStyle + ): void; + + /** + * 在某个canvas上绘制一个圆 + */ + fillCircle( + name: CtxRefer, + x: number, + y: number, + r: number, + style?: CanvasStyle + ): void; + + /** + * 在某个canvas上绘制一个椭圆的边框 + * @param a 横轴长度的一半 + * @param b 纵轴长度的一半 + * @param angle 旋转角度 + */ + strokeEllipse( + name: CtxRefer, + x: number, + y: number, + a: number, + b: number, + angle?: number, + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 在某个canvas上绘制一个圆的边框 + */ + strokeCircle( + name: CtxRefer, + x: number, + y: number, + r: any, + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 在某个canvas上绘制一个扇形 + */ + fillArc( + name: CtxRefer, + x: number, + y: number, + r: number, + start: number, + end: number, + style?: CanvasStyle + ): void; + + /** + * 在某个canvas上绘制一段弧 + */ + strokeArc( + name: CtxRefer, + x: number, + y: number, + r: number, + start: number, + end: number, + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 在某个canvas上绘制一条线 + */ + drawLine( + name: CtxRefer, + x1: number, + y1: number, + x2: number, + y2: number, + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 在某个canvas上绘制一个箭头 + */ + drawArrow( + name: CtxRefer, + x1: number, + y1: number, + x2: number, + y2: number, + style?: CanvasStyle, + lineWidth?: number + ): void; + + /** + * 设置某个canvas的文字字体 + */ + setFont(name: CtxRefer, font: string): void; + + /** + * 设置某个canvas的线宽度 + */ + setLineWidth(name: CtxRefer, lineWidth: number): void; + + /** + * 保存某个canvas状态 + */ + saveCanvas(name: CtxRefer): void; + + /** + * 回退某个canvas状态 + */ + loadCanvas(name: CtxRefer): void; + + /** + * 设置某个canvas的绘制不透明度 + * @returns 之前画布的不透明度 + */ + setAlpha(name: CtxRefer, alpha: number): number; + + /** + * 设置画布元素的不透明度 + */ + setOpacity(name: CtxRefer, opacity: number): void; + + /** + * 设置某个canvas的滤镜 + */ + setFilter(name: CtxRefer, filter?: string): void; + + /** + * 设置某个canvas的填充样式 + */ + setFillStyle(name: CtxRefer, style: CanvasStyle): void; + + /** + * 设置某个canvas描边样式 + */ + setStrokeStyle(name: CtxRefer, style: CanvasStyle): void; + + /** + * 设置某个canvas的文字左右对齐方式 + */ + setTextAlign(name: CtxRefer, align: CanvasTextAlign): void; + + /** + * 设置某个canvas的文字上下对齐方式 + */ + setTextBaseline(name: CtxRefer, baseline: CanvasTextBaseline): void; + + /** + * 计算某段文字的宽度,注意该函数会设置画布的字体 + */ + calWidth(name: CtxRefer, text: string, font?: string): number; + + /** + * 字符串自动换行的分割 + */ + splitLines( + name: CtxRefer, + text: string, + maxWidth?: number, + font?: string + ): string[]; + + /** + * 绘制图片 + * @param dx 绘制的横坐标 + * @param dy 绘制的纵坐标 + */ + drawImage(name: CtxRefer, image: ImageSource, dx: number, dy: number): void; + /** + * 绘制图片 + * @param dx 绘制的横坐标 + * @param dy 绘制的纵坐标 + * @param dw 绘制的宽度 + * @param dh 绘制的高度 + */ + drawImage( + name: CtxRefer, + image: ImageSource, + dx: number, + dy: number, + dw: number, + dh: number + ): void; + /** + * 绘制图片 + * @param sx 裁剪的横坐标 + * @param sy 裁剪的纵坐标 + * @param sw 裁剪的宽度 + * @param sh 裁剪的高度 + * @param dx 绘制的横坐标 + * @param dy 绘制的纵坐标 + * @param dw 绘制的宽度 + * @param dh 绘制的高度 + */ + drawImage( + name: CtxRefer, + image: ImageSource, + sx: number, + sy: number, + sw: number, + sh: number, + dx: number, + dy: number, + dw: number, + dh: number + ): void; + + /** + * 在某个canvas上绘制一个图标 + * @param frame 图标的第几帧 + */ + drawIcon( + name: CtxRefer, + id: AllIds, + x: number, + y: number, + w?: number, + h?: number, + frame?: number + ): void; + + /** + * 结束一切事件和绘制,关闭UI窗口,返回游戏进程 + */ + closePanel(): void; + + /** + * 清空UI层内容 + */ + clearUI(): void; + + /** + * 左上角绘制一段提示 + * @param text 要提示的文字内容 + * @param id 要绘制的图标ID + * @param frame 要绘制图标的第几帧 + */ + drawTip(text: string, id?: AllIds, frame?: number): void; + + /** + * 地图中间绘制一段文字 + */ + drawText(contents: string, callback?: () => void): void; + + /** + * 自绘选择光标 + */ + drawUIEventSelector( + code: number, + background: RGBArray | ImageIds, + x: number, + y: number, + w: number, + h: number, + z?: number + ): void; + + /** + * 清除一个或多个选择光标 + * @param code 要清除的选择光标,不填表示清除所有 + */ + clearUIEventSelector(code?: number | number[]): void; + + /** + * 绘制WindowSkin + * @param direction 指向箭头的方向 + */ + drawWindowSkin( + background: any, + ctx: CtxRefer, + x: number, + y: number, + w: number, + h: number, + direction?: 'up' | 'down', + px?: number, + py?: number + ): void; + + /** + * 绘制一个背景图,可绘制winskin或纯色背景;支持小箭头绘制 + */ + drawBackground( + left: string, + top: string, + right: string, + bottom: string, + posInfo?: Partial + ): void; + + /** + * 绘制一段文字到某个画布上面 + * @param ctx 要绘制到的画布 + * @param content 要绘制的内容;转义字符只允许保留 \n, \r[...], \i[...], \c[...], \d, \e + * @param config 绘制配置项 + * @returns 绘制信息 + */ + drawTextContent( + ctx: CtxRefer, + content: string, + config: Partial + ): ReturnedTextContentConfig; + + /** + * 获得某段文字的预计绘制高度 + */ + getTextContentHeight( + content: string, + config: Partial + ): number; + + /** + * 绘制一个对话框 + */ + drawTextBox(content: string, config?: TextBoxConfig): void; + + /** + * 绘制滚动字幕 + */ + drawScrollText( + content: string, + time?: number, + lineHeight?: number, + callback?: () => void + ): void; + + /** + * 文本图片化 + */ + textImage(content: string, lineHeight?: number): HTMLCanvasElement; + + /** + * 绘制一个选项界面 + */ + drawChoices( + content: string, + choices: string[], + width?: number, + ctx?: CtxRefer + ): void; + + /** + * 绘制一个确认框 + */ + drawConfirmBox( + text: string, + yesCallback?: () => void, + noCallback?: () => void, + ctx?: CtxRefer + ): void; + + /** + * 绘制等待界面 + */ + drawWaiting(text: string): void; + + /** + * 绘制分页 + */ + drawPagination(page: number, totalPage: number, y?: number): void; + + /** + * 绘制怪物手册 + */ + drawBook(index: number): void; + + /** + * 绘制楼层传送器 + */ + drawFly(page: number): void; + + /** + * 获得所有应该在道具栏显示的某个类型道具 + */ + getToolboxItems>(cls: T): ItemIdOf[]; + + /** + * 绘制状态栏 + */ + drawStatusBar(): void; + + /** + * 动态创建一个画布 + * @param name 画布名称,如果已存在则会直接取用当前存在的 + * @param x 横坐标 + * @param y 纵坐标 + * @param width 宽度 + * @param height 高度 + * @param zIndex 纵深 + * @param nonAntiAliasing 是否取消抗锯齿 + */ + createCanvas( + name: string, + x: number, + y: number, + width: number, + height: number, + zIndex?: number, + nonAntiAliasing?: boolean + ): CanvasRenderingContext2D; + + /** + * 重新定位一个自定义画布 + */ + relocateCanvas( + name: string, + x: number, + y: number, + useDelta?: boolean + ): void; + + /** + * 设置一个自定义画布的旋转角度 + */ + rotateCanvas( + name: CtxRefer, + angle: number, + centerX?: number, + centerY?: number + ): void; + + /** + * 重新设置一个自定义画布的大小 + * @param styleOnly 是否只修改style,而不修改元素上的长宽,如果是true,会出现模糊现象 + * @param isTempCanvas 是否是临时画布,如果填true,会将临时画布修改为高清画布 + */ + resizeCanvas( + name: string, + x?: number, + y?: number, + styleOnly?: boolean, + isTempCanvas?: boolean + ): void; + + /** + * 删除一个自定义画布 + */ + deleteCanvas(name: string | ((name: string) => boolean)): void; + + /** + * 清空所有的自定义画布 + */ + deleteAllCanvas(): void; +} + +declare const ui: new () => Ui; diff --git a/project/types/util.d.ts b/project/types/util.d.ts new file mode 100644 index 0000000..a5f21f2 --- /dev/null +++ b/project/types/util.d.ts @@ -0,0 +1,884 @@ +/** 工具类 主要用来进行一些辅助函数的计算 */ +interface Utils { + /** + * 四个方向的坐标增量 + */ + readonly scan: DeepReadonly; + + /** + * 八个方向的坐标增量 + */ + readonly scan2: DeepReadonly; + + /** + * 将一段文字中的${}(表达式)进行替换。很多情况下可以用模板字符串替代 + * @example + * // 把主角的生命值和持有的黄钥匙数量代入这句话 + * core.replaceText('衬衫的价格是${status:hp}镑${item:yellowKey}便士。'); + * @param text 模板字符串,可以使用${}计算js表达式 + * @param prefix 独立开关前缀 + * @returns 替换完毕后的字符串 + */ + replaceText(text: string, prefix?: string): string; + + /** + * 对一个表达式中的特殊规则进行替换,如status:xxx等。 + * 其中变量和全局存储会替换中文冒号,其余的不会替换 + * @example + * // 把这两个冒号表达式替换为core.getStatus('hp')和core.itemCount('yellowKey')这样的函数调用 + * core.replaceValue('衬衫的价格是${status:hp}镑${item:yellowKey}便士。'); + * @param value 模板字符串,注意独立开关不会被替换 + * @returns 替换完毕后的字符串 + */ + replaceValue(value: string): string; + + /** + * 计算一个表达式的值,支持status:xxx等的计算。 + * @example core.calValue('status:hp + status:def'); // 计算主角的生命值加防御力 + * @param value 待求值的表达式 + * @param prefix 独立开关前缀,一般可省略 + * @returns 求出的值 + */ + calValue(value: string | Function, prefix?: string): any; + + /** + * @deprecated + * 将b(可以是另一个数组)插入数组a的开头,用Array.unshift就行 + * @example core.unshift(todo, {type: 'unfollow'}); // 在事件指令数组todo的开头插入“取消所有跟随者”指令 + * @param a 原数组 + * @param b 待插入的新首项或前缀数组 + * @returns 插入完毕后的新数组,它是改变原数组a本身得到的 + */ + unshift(a: A, b: B): [...B, ...A]; + + /** + * @deprecated + * 将b(可以是另一个数组)插入数组a的末尾,用Array.push就行 + * @example core.push(todo, {type: 'unfollow'}); // 在事件指令数组todo的末尾插入“取消所有跟随者”指令 + * @param a 原数组 + * @param b 待插入的新末项或后缀数组 + * @returns 插入完毕后的新数组,它是改变原数组a本身得到的 + */ + push(a: A, b: B): [...A, ...B]; + + /** + * 解压缩一个数据,我也不知道这个解压的是什么 + * @param 要解压的内容,字符串 + */ + decompress(value: string): any; + + /** + * 设置本地存储 + * @param key 本地存储的名称 + * @param value 本地存储的值,不填代表删除 + */ + setLocalStorage(key: string, value?: any): void; + + /** + * 获得本地存储 + * @param key 获取的本地存储的名称 + * @param defaultValue 当不存在的时候的默认值 + */ + getLocalStorage(key: string, defaultValue?: T): T; + + /** + * 移除本地存储 + * @param key 要移除的本地存储的值 + */ + removeLocalStorage(key: string): void; + + /** + * 异步写入localforage + * @param key 写入的键 + * @param value 写入的值 + * @param successCallback 写入成功的回调函数 + * @param errorCallback 写入出错的回调函数 + */ + setLocalForage( + key: string, + value?: any, + successCallback?: () => void, + errorCallback?: (err: Error) => void + ): void; + + /** + * 从localforage读出一段数据 + */ + getLocalForage( + key: string, + defaultValue?: T, + successCallback?: (data: T) => void, + errorCallback?: (err: Error) => void + ): void; + + /** + * 移除localforage的数据 + */ + removeLocalForage( + key: string, + successCallback?: () => void, + errorCallback?: (err: Error) => void + ): void; + + /** + * 清除localforage所有的数据 + * @param callback 清除完毕的回调函数 + */ + clearLocalForage(callback?: (err?: Error) => void): void; + + /** + * 迭代localforage的数据 + * @param iteratee 迭代器 + * @param callback 迭代完毕的回调函数 + */ + iterateLocalForage( + iteratee: (value: T, key: string, iterationNumber: number) => U, + callback?: (err: any, result: U) => void + ): void; + + /** + * 获取localforage数据的所有的键 + * @param callback 回调函数 + */ + keysLocalForage(callback?: (err: any, keys: string[]) => void): void; + + /** + * 获取localforage数据的数据量 + * @param callback 回调函数 + */ + lengthLocalForage( + callback?: (err: any, numberOfKeys: number) => void + ): void; + + /** + * 设置一个全局存储,适用于global:xxx,录像播放时将忽略此函数。 + * @example core.setBlobal('一周目已通关', true); // 设置全局存储“一周目已通关”为true,方便二周目游戏中的新要素。 + * @param key 全局变量名称,支持中文 + * @param value 全局变量的新值,不填或null表示清除此全局存储 + */ + setGlobal(key: string, value?: any): void; + + /** + * 读取一个全局存储,适用于global:xxx,支持录像。 + * @example if (core.getGlobal('一周目已通关', false) === true) core.getItem('dagger'); // 二周目游戏进行到此处时会获得一把屠龙匕首 + * @param key 全局变量名称,支持中文 + * @param defaultValue 可选,当此全局变量不存在或值为null、undefined时,用此值代替 + * @returns 全局变量的值 + */ + getGlobal(key: string, defaultValue?: T): T; + + /** + * 深拷贝一个对象(函数将原样返回) + * @example core.clone(core.status.hero, (name, value) => (name == 'items' || typeof value == 'number'), false); // 深拷贝主角的属性和道具 + * @param data 待拷贝对象 + * @param filter 过滤器,可选,表示data为数组或对象时拷贝哪些项或属性,true表示拷贝 + * @param recursion 过滤器是否递归,可选。true表示过滤器也被递归 + * @returns 拷贝的结果,注意函数将原样返回 + */ + clone( + data: T, + filter?: (name: string, value: any) => boolean, + recursion?: boolean + ): T; + + /** + * 深拷贝一个1D或2D的数组 + * @param data 要拷贝的数据 + */ + cloneArray(data: T): T; + + /** + * 等比例切分一张图片 + * @example core.splitImage(core.material.images.images['npc48.png'], 32, 48); // 把npc48.png切分成若干32×48px的小人 + * @param image 图片名(支持映射前的中文名)或图片对象(参见上面的例子),获取不到时返回[] + * @param width 子图的宽度,单位为像素。原图总宽度必须是其倍数,不填视为32 + * @param height 子图的高度,单位为像素。原图总高度必须是其倍数,不填视为正方形 + * @returns 子图组成的数组,在原图中呈先行后列,从左到右、从上到下排列。 + */ + splitImage( + image: NameMapIn | ImageIds | HTMLImageElement, + width?: number, + height?: number + ): HTMLImageElement[]; + + /** + * 格式化日期为字符串 + * @param date 时间,不填代表当前时间 + * @returns 格式: yyyy-mm-dd hh:mm:ss + */ + formatDate(date?: Date): string; + + /** + * 格式化日期为最简字符串 + * @param date 时间,不填代表当前时间 + * @returns 格式: yyyymmddhhmmss + */ + formatDate2(date?: Date): string; + + /** + * 格式化时间 + * @param time 时间 + * @returns 格式: hh:mm:ss + */ + formatTime(time: number): string; + + /** + * @deprecated + * 设置成两位数显示,请使用setDigits代替 + */ + setTwoDigits(x: number): string; + + /** + * 设置一个数为n位数显示 + * @param x 要设置的数 + * @param n 设置成的位数 + */ + setDigits(x: number, n: number): string; + + /** + * 格式化文件大小 + * @param size 大小,字节数 + * @returns 格式为xx.xxB KB MB + */ + formatSize(size: number): string; + + /** + * 大数字格式化,单位为10000的倍数(w,e,z,j,g),末尾四舍五入 + * @example core.formatBigNumber(123456789); // "12346w" + * @param x 原数字 + * @param onMap 显示的字符数 + * @returns 格式化结果 + */ + formatBigNumber(x: number, onMap?: number): string; + + /** + * @deprecated + * 变速移动,完全可以用mutate-animate代替 + * @param mode 缓动模式 + */ + applyEasing(mode?: EaseMode): (x: number) => number; + + /** + * 颜色数组转十六进制 + * @example core.arrayToRGB([102, 204, 255]); // "#66ccff",加载画面的宣传色 + * @param color 一行三列的数组,各元素必须为不大于255的自然数 + * @returns 该颜色的十六进制表示,使用小写字母 + */ + arrayToRGB(color: RGBArray): string; + + /** + * 颜色数组转字符串 + * @example core.arrayToRGBA([102, 204, 255]); // "rgba(102,204,255,1)" + * @param color 一行三列或一行四列的数组,前三个元素必须为不大于255的自然数。 + * 第四个元素(如果有)必须为0或不大于1的数字,第四个元素不填视为1 + * @returns 该颜色的字符串表示 + */ + arrayToRGBA(color: RGBArray): string; + + /** + * 录像一压,其结果会被再次base64压缩 + * @example core.encodeRoute(core.status.route); // 一压当前录像 + * @param route 原始录像,自定义内容(不予压缩,原样写入)必须由0-9A-Za-z和下划线、冒号组成, + * 所以中文和数组需要用JSON.stringify预处理再base64压缩才能交由一压 + * @returns 一压的结果 + */ + encodeRoute(route: string[]): string; + + /** + * 录像解压的最后一步,即一压的逆过程 + * @example core.decodeRoute(core.encodeRoute(core.status.route)); // 一压当前录像再解压-_-| + * @param route 录像解压倒数第二步的结果,即一压的结果 + * @returns 原始录像 + */ + decodeRoute(route: string): string[]; + + /** + * 判断一个值是否不为null,undefined和NaN + * @example core.isset(0/0); // false,因为0/0等于NaN + * @param v 待测值 + * @returns false表示待测值为null、undefined、NaN或未填写,true表示为其他值 + */ + isset(v?: any): boolean; + + /** + * 判定一个数组是否为另一个数组的前缀,用于录像接续播放 + * @example core.subarray(['ad', '米库', '小精灵', '小破草', '小艾'], ['ad', '米库', '小精灵']); // ['小破草', '小艾'] + * @param a 可能的母数组,不填或比b短将返回null + * @param b 可能的前缀,不填或比a长将返回null + * @returns 如果b不是a的前缀将返回null,否则将返回a去掉此前缀后的剩余数组 + */ + subarray(a: any[], b: any[]): any[] | null; + + /** + * @deprecated + * 判定array是不是一个数组,以及element是否在该数组中。使用Array.includes代替 + * @param array 可能的数组,不为数组或不填将导致返回值为false + * @param element 待查找的元素 + * @returns 如果array为数组且具有element这项,就返回true,否则返回false + */ + inArray(array?: any, element?: any): boolean; + + /** + * 将x限定在[a,b]区间内,注意a和b可交换 + * @example core.clamp(1200, 1, 1000); // 1000 + * @param x 原始值,!x为true时x一律视为0 + * @param a 下限值,大于b将导致与b交换 + * @param b 上限值,小于a将导致与a交换 + */ + clamp(x: number, a: number, b: number): number; + + /** + * 访问浏览器cookie + */ + getCookie(name: string): string; + + /** + * 填写非自绘状态栏 + * @example + * // 更新状态栏中的主角生命,使用加载画面的宣传色 + * core.setStatusBarInnerHTML('hp', core.status.hero.hp, 'color: #66CCFF'); + * @param name 状态栏项的名称,如'hp', 'atk', 'def'等。必须是core.statusBar中的一个合法项 + * @param value 要填写的内容,大数字会被格式化为至多6个字符,无中文的内容会被自动设为斜体 + * @param css 额外的css样式,可选。如更改颜色等 + */ + setStatusBarInnerHTML( + name: string, + value: string | number, + css?: string + ): void; + + /** + * 求字符串的国标码字节数,也可用于等宽字体下文本的宽度测算。请注意样板的默认字体Verdana不是等宽字体 + * @example core.strlen('无敌ad'); // 6 + * @param str 待测字符串 + * @returns 字符串的国标码字节数,每个汉字为2,每个ASCII字符为1 + */ + strlen(str: string): number; + + /** + * 计算应当转向某个方向 + * @param turn 转向的方向 + * @param direction 当前方向,不填视为当前方向 + */ + turnDirection(turn: HeroTurnDir, direction?: Dir): string; + + /** + * 通配符匹配,用于搜索图块等批量处理。 + * @example core.playSound(core.matchWildcard('*Key', itemId) ? 'item.mp3' : 'door.mp3'); // 判断捡到的是钥匙还是别的道具,从而播放不同的音效 + * @param pattern 模式串,每个星号表示任意多个(0个起)字符 + * @param string 待测串 + * @returns true表示匹配成功,false表示匹配失败 + */ + matchWildcard(pattern: string, string: string): boolean; + + /** + * 是否满足正则表达式,一般可以直接用/RegExp/.test(str)代替 + * @param pattern 正则表达式 + * @param string 要匹配的字符串 + */ + matchRegex(pattern: string, string: string): string; + + /** + * base64加密 + * @example + * core.encodeBase64('If you found this note in a small wooden box with a heart on it'); + * // "SWYgeW91IGZvdW5kIHRoaXMgbm90ZSBpbiBhIHNtYWxsIHdvb2RlbiBib3ggd2l0aCBhIGhlYXJ0IG9uIGl0" + * @param str 明文 + * @returns 密文 + */ + encodeBase64(str: string): string; + + /** + * base64解密 + * @example + * core.decodeBase64('SWYgeW91IGZvdW5kIHRoaXMgbm90ZSBpbiBhIHNtYWxsIHdvb2RlbiBib3ggd2l0aCBhIGhlYXJ0IG9uIGl0'); + * // "If you found this note in a small wooden box with a heart on it" + * @param str 密文 + * @returns 明文 + */ + decodeBase64(str: string): string; + + /** + * 不支持SL的随机数 + * @exmaple 1 + core.rand(6); // 随机生成一个小于7的正整数,模拟骰子的效果 + * @param num 填正数表示生成小于num的随机自然数,否则生成小于1的随机正数 + * @returns 随机数,即使读档也不会改变结果 + */ + rand(num?: number): number; + + /** + * 支持SL的随机数,并计入录像 + * @exmaple 1 + core.rand2(6); // 随机生成一个小于7的正整数,模拟骰子的效果 + * @param num 正整数,0或不填会被视为2147483648 + * @returns 属于 [0, num) 的随机数 + */ + rand2(num?: number): number; + + /** + * 尝试请求读取一个本地文件内容 [异步] + * @param success 成功后的回调 + * @param error 失败后的回调 + * @param accept input元素的accept属性 + * @param readType 不设置则以文本读取,否则以DataUrl形式读取 + */ + readFile( + success: (obj: any) => void, + error: () => void, + accept: string, + readType: boolean + ): void; + + /** + * 文件读取完毕后的内容处理 [异步] + * @param content 读取的内容 + */ + readFileContent(content: string): void; + + /** + * 弹窗请求下载一个文本文件 + * @example core.download('route.txt', core.status.route); // 弹窗请求下载录像 + * @param filename 文件名 + * @param content 文件内容 + */ + download(filename: string, content: string | string[]): void; + + /** + * 尝试复制一段文本到剪切板 + * @param data 赋值的东西 + */ + copy(data: string): void; + + /** + * 显示确认框,类似core.drawConfirmBox() + * @example core.myconfirm('重启游戏?', core.restart); // 弹窗询问玩家是否重启游戏 + * @param hint 弹窗的内容 + * @param yesCallback 确定后的回调函数 + * @param noCallback 取消后的回调函数 + */ + myconfirm( + hint: string, + yesCallback: () => void, + noCallback?: () => void + ): void; + + /** + * 让用户输入一段文字 + */ + myprompt( + hint: string, + value: string, + callback?: (data?: string) => void + ): void; + + /** + * @deprecated + * 动画显示某对象,有vue了,你还用这个?Transition组件和css的transition比这个强得多 + */ + showWithAnimate( + obj?: HTMLElement, + speed?: number, + callback?: () => any + ): void; + + /** + * @deprecated + * 动画使某对象消失 + */ + hideWithAnimate( + obj?: HTMLElement, + speed?: number, + callback?: () => any + ): void; + + /** + * 获得浏览器唯一的guid + */ + getGuid(): string; + + /** + * 获取一个对象的哈希值 + * @param obj 要获取的对象 + */ + hashCode(obj: any): number; + + /** + * 判定深层相等, 会逐层比较每个元素 + * @example core.same(['1', 2], ['1', 2]); // true + */ + same(a: any, b: any): boolean; + + /** + * 解压一段内容 + */ + unzip( + blobOrUrl: string | Blob, + success?: (data: any) => void, + error?: (error: string) => void, + convertToText?: boolean, + onprogress?: (loaded: number, total: number) => void + ): void; + + /** + * 发送一个HTTP请求 [异步] + * @param type 请求类型 + * @param url 目标地址 + * @param formData 如果是POST请求则为表单数据 + * @param success 成功后的回调 + * @param error 失败后的回调 + */ + http( + type: 'GET' | 'POST', + url: string, + formData?: FormData, + success?: (res: any) => void, + error?: (err: string) => void, + mimeType?: string, + responseType?: XMLHttpRequestResponseType, + onProgress?: (loaded: number, total: number) => void + ): void; +} + +declare const utils: new () => Utils; + +/** + * 移动的方向 + */ +type Step = Move | 'backward'; + +/** + * 坐标字符串 + */ +type LocString = `${number},${number}`; + +type _RGBA = + | `rgb(${number},${number},${number})` + | `rgba(${number},${number},${number},${number})`; + +/** + * RGBA颜色数组 + */ +type RGBArray = [number, number, number, number?]; + +/** + * 样板的颜色字符串 + */ +type Color = `#${string}` | _RGBA | RGBArray; + +/** + * 四个方向 + */ +type Dir = 'up' | 'down' | 'left' | 'right'; + +/** + * 八个方向 + */ +type Dir2 = Dir | 'leftup' | 'rightup' | 'leftdown' | 'rightdown'; + +/** + * 转向的方向 + */ +type TurnDir = Dir | ':left' | ':right' | ':back'; + +/** + * 勇士转向 + */ +type HeroTurnDir = TurnDir | ':hero' | ':backhero'; + +/** + * 对话框的位置 + */ +type TextPosition = 'up' | 'center' | 'down'; + +/** + * 移动的方向 + */ +type Move = 'forward' | Dir; + +/** + * 缓动模式,不过在高级动画插件面前不堪一击( + */ +type EaseMode = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut'; + +/** + * 事件执行的操作符\ + * += 增加并赋值\ + * -= 减少并赋值\ + * *= 相乘并赋值\ + * /= 相除并赋值\ + * //= 除以并取商\ + * **= 取幂\ + * %= 取余\ + * min= 取二者的最小值\ + * max= 取二者的最大值\ + * 其它的任意字符串都是赋值 + */ +type MotaOperator = + | '+=' + | '-=' + | '*=' + | '/=' + | '//=' + | '**=' + | '%=' + | 'min=' + | 'max=' + | '='; + +/** + * 位置数组 + */ +type LocArr = [x: number, y: number]; + +/** + * 位置 + */ +interface Loc { + /** + * 横坐标 + */ + x: number; + + /** + * 纵坐标 + */ + y: number; +} + +/** + * 带方向的位置 + */ +interface DiredLoc extends Loc { + /** + * 方向 + */ + direction: Dir; +} + +interface CompressedStep { + /** + * 移动方向 + */ + direction: Dir; + + /** + * 向该方向移动的步数 + */ + step: number; +} + +/** + * 四个方向的坐标增量 + */ +type Scan = { + [D in Dir]: Loc; +}; + +/** + * 八个方向的坐标增量 + */ +type Scan2 = { + [D in Dir2]: Loc; +}; + +/** + * 图片翻转 + */ +type ImageReverse = ':o' | ':x' | ':y'; + +/** + * 对话框的箭头方向 + */ +type TextBoxDir = 'up' | 'down'; + +/** + * 对话框的位置 + */ +type TextBoxPos = + | `${TextBoxDir},hero` + | `${TextBoxDir},${number},${number}` + | TextPosition; + +/** + * 画布信息 + */ +type CtxRefer = string | CanvasRenderingContext2D | HTMLCanvasElement; + +/** + * 触发器类型 + */ +type MotaTrigger = + | 'battle' + | 'pusBox' + | 'openDoor' + | 'ski' + | 'custom' + | 'getItem'; + +/** + * 切换楼层的目标坐标 + */ +type FloorChangeStair = + | 'upFloor' + | 'downFloor' + | ':symmetry' + | ':symmetry_x' + | ':symmetry_y' + | 'flyPoint'; + +/** + * 事件值的前缀 + */ +type EventValuePreffix = + | 'status' + | 'flag' + | 'item' + | 'buff' + | 'switch' + | 'temp' + | 'global'; + +interface Animate { + /** + * 动画的帧数s + */ + frame: number; + + /** + * 每帧的信息 + */ + frames: FrameObj[][]; + + /** + * 图片信息 + */ + images: HTMLImageElement[]; + + /** + * 缩放信息 + */ + ratio: number; + + /** + * 音效 + */ + se: string; +} + +type Save = DeepReadonly<{ + /** + * 存档所在的楼层id + */ + floorId: FloorIds; + + /** + * 存档的勇士信息 + */ + hero: HeroStatus; + + /** + * 难度信息 + */ + hard: number; + + /** + * 存档的地图信息,已经过压缩处理 + */ + maps: Record; + + /** + * 录像信息 + */ + route: string; + + /** + * 存档的全局变量信息 + */ + values: CoreValues; + + /** + * 游戏版本 + */ + version: string; + + /** + * 浏览器唯一guid + */ + guid: string; + + /** + * 存档时间 + */ + time: number; +}>; + +/** + * 深度只读一个对象,使其所有属性都只读 + */ +type DeepReadonly = { + readonly [P in keyof T]: T[P] extends number | string | boolean + ? T[P] + : DeepReadonly; +}; + +/** + * 深度可选一个对象,使其所有属性都 + */ +type DeepPartial = { + [P in keyof T]?: T[P] extends number | string | boolean + ? T[P] + : DeepReadonly; +}; + +/** + * 深度必选一个对象,使其所有属性都必选 + */ +type DeepRequired = { + [P in keyof T]-?: T[P] extends number | string | boolean + ? T[P] + : DeepReadonly; +}; + +/** + * 使一个对象的所有属性可写 + */ +type Writable = { + -readonly [P in keyof T]: P[T]; +}; + +/** + * 深度可写一个对象,使其所有属性都可写 + */ +type DeepWritable = { + -readonly [P in keyof T]: T[P] extends number | string | boolean + ? T[P] + : DeepReadonly; +}; + +/** + * 从一个对象中选择类型是目标类型的属性 + */ +type SelectType = { + [P in keyof R as R[P] extends T ? P : never]: R[P]; +}; + +/** + * 获取一段字符串的第一个字符 + */ +type FirstCharOf = T extends `${infer F}${infer A}` + ? F + : never; + +/** + * 非对象属性 + */ +type NonObject = number | string | boolean; + +/** + * 获取一个对象的非对象值 + */ +type NonObjectOf = SelectType; + +/** + * 以一个字符串结尾 + */ +type EndsWith = `${string}${T}`; diff --git a/styles.css b/styles.css index 89ddc05..139471b 100644 --- a/styles.css +++ b/styles.css @@ -1,534 +1,618 @@ -html, body { - margin: 0; - padding: 0; - width: 100%; - height: 100%; - background-color: #000; - overflow: hidden; +html, +body { + margin: 0; + padding: 0; + width: 100%; + height: 100%; + background-color: #000; + overflow: hidden; } #gameGroup { - position: absolute; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - background-color: #000; + position: absolute; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background-color: #000; } #mainTips { - color: #fff; - font-size: 0.8em; - position: fixed; - top: 10px; - left: 10px; - z-index: 370; + color: #fff; + font-size: 0.8em; + position: fixed; + top: 10px; + left: 10px; + z-index: 370; } #musicBtn { - position: fixed; - bottom: 3px; - right: 3px; - cursor: pointer; - z-index: 400; - display: none; + position: fixed; + bottom: 3px; + right: 3px; + cursor: pointer; + z-index: 400; + display: none; } #enlargeBtn { - position: fixed; - bottom: 3px; - right: 34px; - cursor: pointer; - z-index: 400; - display: none; + position: fixed; + bottom: 3px; + right: 34px; + cursor: pointer; + z-index: 400; + display: none; } #startPanel { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - background-color: #fff; - overflow: hidden; - z-index: 300; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-color: #fff; + overflow: hidden; + z-index: 300; } #startTop { - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - background-color: #000; - z-index: 350; + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + background-color: #000; + z-index: 350; } #startTopProgressBar { - width: 90%; - height: 5%; - margin: 0 5%; - position: absolute; - top: 5%; - background-color: #fff; - z-index: 15; + width: 90%; + height: 5%; + margin: 0 5%; + position: absolute; + top: 5%; + background-color: #fff; + z-index: 15; } #startTopProgress { - width: 0%; - height: 100%; - background-color: #666; + width: 0%; + height: 100%; + background-color: #666; } #startTopLoadTips { - color: #fff; - font-size: 0.6em; - position: absolute; - top: 10%; - left: 5%; - z-index: 15; + color: #fff; + font-size: 0.6em; + position: absolute; + top: 10%; + left: 5%; + z-index: 15; } #startTopHint { - color: #66CCFF; - position: absolute; - bottom: 0; - left: 5%; - z-index: 15; - font-size: 1.1em; + color: #66ccff; + position: absolute; + bottom: 0; + left: 5%; + z-index: 15; + font-size: 1.1em; } #startBackground { - position:absolute; - top:50%; - left:50%; - height: 100%; - width: 100%; - transform:translate(-50%,-50%); - z-index: 260; + position: absolute; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + z-index: 260; } #startLogo { - user-select: none; - position: absolute; - z-index: 290; - left: 0; - right: 0; - margin-left: auto; - margin-right: auto; - margin-top: 8%; - max-width: 100%; - text-align: center; - font: bold 0em STXingkai; - color: #000000; + user-select: none; + position: absolute; + z-index: 290; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + margin-top: 8%; + max-width: 100%; + text-align: center; + font: bold 0em STXingkai; + color: #000000; } #startTitle { - user-select: none; - position: absolute; - z-index: 280; + user-select: none; + position: absolute; + z-index: 280; } #startButtonGroup { - width: auto; - position: absolute; - text-align: center; - font-size: 1.4em; - display: none; - z-index: 310; - bottom: 0; - margin-bottom: 5%; - left: 50%; - transform: translateX(-50%); - padding: 15px 25px; - min-width: 100%; - /* default value */ - background-color: #000000; - opacity: 0.55; - color: #FFFFFF; - border: #FFFFFF 0px solid; - caret-color: #ffffff; - border-radius: 0px; + width: auto; + position: absolute; + text-align: center; + font-size: 1.4em; + display: none; + z-index: 310; + bottom: 0; + margin-bottom: 5%; + left: 50%; + transform: translateX(-50%); + padding: 15px 25px; + min-width: 100%; + /* default value */ + background-color: #000000; + opacity: 0.55; + color: #ffffff; + border: #ffffff 0px solid; + caret-color: #ffffff; + border-radius: 0px; } #startButtons { - display: none; + display: none; } #levelChooseButtons { - display: none; + display: none; } .startButton { - width: 100%; - margin: 0; - font:1.2rem "pala", sans-serif; - font-weight: normal; - display: block; - cursor: pointer; - padding: 0px 0; - border-color: transparent; - border-width: 0px; - border-style: solid; - border-radius: 0px; + width: 100%; + margin: 0; + font: 1.2rem pala, sans-serif; + font-weight: normal; + display: block; + cursor: pointer; + padding: 0px 0; + border-color: transparent; + border-width: 0px; + border-style: solid; + border-radius: 0px; } .onChoiceAnimate { - animation: onChoice 2s ease-in-out 0s infinite normal none running; + animation: onChoice 2s ease-in-out 0s infinite normal none running; } #floorMsgGroup { - position: absolute; - text-align: center; - display: none; - color: #fff; - background-color: #000; - z-index: 230; + position: absolute; + text-align: center; + display: none; + color: #fff; + background-color: #000; + z-index: 230; } #logoLabel { - margin-top: 8%; - font: bold 3em STXingkai; - margin-left: auto; - margin-right: auto; + margin-top: 8%; + font: bold 3em STXingkai; + margin-left: auto; + margin-right: auto; } #versionLabel { - margin-top: -3%; - font-size: 1.2em; - font-weight: bold; + margin-top: -3%; + font-size: 1.2em; + font-weight: bold; } #floorNameLabel { - margin-top: 30px; - font-size: 1.6em; - font-weight: bold; + margin-top: 30px; + font-size: 1.6em; + font-weight: bold; } #statusBar { - position: absolute; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - background: url(project/materials/ground.png) repeat; - z-index: 185; - display: none; - top: 0; - left: 0; - padding: 3px; + position: absolute; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + background: url(project/materials/ground.png) repeat; + z-index: 185; + display: none; + top: 0; + left: 0; + padding: 3px; } -#statusBar .status{ - position: relative; - display: block; - float: left; - width: 100%; +#statusBar .status { + position: relative; + display: block; + float: left; + width: 100%; } -.status img{ - vertical-align: middle; - width: auto; - height: 100%; - max-height: 1.6em; +.status img { + vertical-align: middle; + width: auto; + height: 100%; + max-height: 1.6em; } -#statusBar span{ - font: bold italic 1.1em Verdana; - display: inline; +#statusBar span { + font: bold italic 1.1em Verdana; + display: inline; } #statusBar p { - display: inline-block; - vertical-align: middle; - width: 60%; - margin: 0; - color: white; - font: bold italic 1.1em Verdana; - white-space: nowrap; + display: inline-block; + vertical-align: middle; + width: 60%; + margin: 0; + color: white; + font: bold italic 1.1em Verdana; + white-space: nowrap; } #toolBar { - position: absolute; - background: url(project/materials/ground.png) repeat; - z-index: 210; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - display: none; - padding: 3px; + position: absolute; + background: url(project/materials/ground.png) repeat; + z-index: 210; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + display: none; + padding: 3px; } -#toolBar .tools{ - position: relative; - display: block; - float: left; +#toolBar .tools { + position: relative; + display: block; + float: left; } p#hard { - width: 6em; - vertical-align: middle; - display: inline-block; - color: red; - font: bold normal 1.1em "Arial Black"; - text-align: center; - margin: 0 6px 6px 0; - word-break: keep-all; + width: 6em; + vertical-align: middle; + display: inline-block; + color: red; + font: bold normal 1.1em "Arial Black"; + text-align: center; + margin: 0 6px 6px 0; + word-break: keep-all; } -span#poison, span#weak, span#curse, span#pickaxe, span#bomb, span#fly { - font-style: normal; - font-size: 1em; +span#poison, +span#weak, +span#curse, +span#pickaxe, +span#bomb, +span#fly { + font-style: normal; + font-size: 1em; } p#name { - font-style: normal; + font-style: normal; } .gameCanvas { - position: absolute; - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; + position: absolute; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; } #gif { - z-index: 20; - position: absolute; - overflow: hidden; + z-index: 20; + position: absolute; + overflow: hidden; } #gif2 { - z-index: 90; - position: absolute; - overflow: hidden; + z-index: 90; + position: absolute; + overflow: hidden; } #gameDraw { - position: absolute; - background: #000000; - overflow: hidden; - z-index: 185; + position: absolute; + background: #000000; + overflow: hidden; + z-index: 185; } #bg { - z-index: 10; + z-index: 10; } #event { - z-index: 30; + z-index: 30; } #hero { - z-index: 40; + z-index: 40; } #event2 { - z-index: 50; + z-index: 50; } #fg { - z-index: 60; + z-index: 60; } #damage { - z-index: 65; + z-index: 65; } #animate { - z-index: 70; + z-index: 70; } #curtain { - z-index: 125; + z-index: 125; } #ui { - z-index: 140; + z-index: 140; } #data { - z-index: 170; + z-index: 170; } #inputDiv { - display: none; - width: 100%; - height: 100%; - position: fixed; - top: 0; - left: 0; - background: rgba(127,127,127,0.6); - z-index: 2000 + display: none; + width: 100%; + height: 100%; + position: fixed; + top: 0; + left: 0; + background: rgba(127, 127, 127, 0.6); + z-index: 2000; } #inputDialog { - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -55%); - background: white; - width: 250px; - min-height: 50px; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -55%); + background: white; + width: 250px; + min-height: 50px; } #inputMessage { - word-wrap: break-word; - text-align: left; - margin-left: 8%; - margin-right: 5%; + word-wrap: break-word; + text-align: left; + margin-left: 8%; + margin-right: 5%; } #inputBox { - margin-left: 8%; - width: 80%; - margin-bottom: 10px; - padding: 5px 3px; - border: 1px solid; - background: #F0F0F0; + margin-left: 8%; + width: 80%; + margin-bottom: 10px; + padding: 5px 3px; + border: 1px solid; + background: #f0f0f0; } #inputYes { - margin-bottom: 15px; - margin-left: 8%; + margin-bottom: 15px; + margin-left: 8%; } #inputNo { - float:right; - margin-right: 10%; + float: right; + margin-right: 10%; } -#_selector, ._uievent_selector { - animation: selector 2s ease-in-out 0s infinite normal none running; +#_selector, +._uievent_selector { + animation: selector 2s ease-in-out 0s infinite normal none running; } @-webkit-keyframes selector { - 0% { opacity: 0.95; } - 50% { opacity: 0.55; } - 100% { opacity: 0.95; } + 0% { + opacity: 0.95; + } + 50% { + opacity: 0.55; + } + 100% { + opacity: 0.95; + } } @keyframes selector { - 0% { opacity: 0.95; } - 50% { opacity: 0.55; } - 100% { opacity: 0.95; } + 0% { + opacity: 0.95; + } + 50% { + opacity: 0.55; + } + 100% { + opacity: 0.95; + } } #next { - width: 5px; - height: 5px; - display: none; - position: absolute; - transform: rotate(45deg); - border-bottom-width: 4px; - border-bottom-style: solid; - border-right-width: 4px; - border-right-style: solid; - -webkit-animation: next .5s ease-in-out alternate infinite; - animation: next .5s ease-in-out alternate infinite; - left: 0; - top: 0; - opacity: 0.7; - z-index: 169; + width: 5px; + height: 5px; + display: none; + position: absolute; + transform: rotate(45deg); + border-bottom-width: 4px; + border-bottom-style: solid; + border-right-width: 4px; + border-right-style: solid; + -webkit-animation: next 0.5s ease-in-out alternate infinite; + animation: next 0.5s ease-in-out alternate infinite; + left: 0; + top: 0; + opacity: 0.7; + z-index: 169; } @-webkit-keyframes next { - 100% { - transform: rotate(45deg) translate(-3px, -3px); - } + 100% { + transform: rotate(45deg) translate(-3px, -3px); + } } @keyframes next { - 100% { - transform: rotate(45deg) translate(-3px, -3px); - } + 100% { + transform: rotate(45deg) translate(-3px, -3px); + } } #startImageBackgroundDiv { - display: none; - width: 100%; - height: 100%; - position: fixed; - z-index: 10000; + display: none; + width: 100%; + height: 100%; + position: fixed; + z-index: 10000; } #startImageDiv { - width: 100%; - height: 100%; - position: fixed; - background: black; - opacity: 1; + width: 100%; + height: 100%; + position: fixed; + background: black; + opacity: 1; } #startImageLogo { - opacity: 0; - max-width: 60%; - max-height: 60%; - position: fixed; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); + opacity: 0; + max-width: 60%; + max-height: 60%; + position: fixed; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); } .startImageAnimation { - -webkit-animation: startImage 4s ease-in-out 1s alternate 1; - animation: startImage 4s ease-in-out 1s alternate 1; + -webkit-animation: startImage 4s ease-in-out 1s alternate 1; + animation: startImage 4s ease-in-out 1s alternate 1; } @-webkit-keyframes startImage { - 0% { opacity: 0; } - 60% { opacity: 1; } - 100% { opacity: 0; } + 0% { + opacity: 0; + } + 60% { + opacity: 1; + } + 100% { + opacity: 0; + } } @keyframes startImage { - 0% { opacity: 0; } - 60% { opacity: 1; } - 100% { opacity: 0; } + 0% { + opacity: 0; + } + 60% { + opacity: 1; + } + 100% { + opacity: 0; + } } .startImageDivAnimation { - -webkit-animation: startImageDivDisappear 2s ease-in-out 5s alternate 1; - animation: startImageDivDisappear 2s ease-in-out 5s alternate 1; + -webkit-animation: startImageDivDisappear 2s ease-in-out 5s alternate 1; + animation: startImageDivDisappear 2s ease-in-out 5s alternate 1; } @-webkit-keyframes startImageDivDisappear { - 0% { opacity: 1 } - 100% { opacity: 0 } + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } } @keyframes startImageDivDisappear { - 0% { opacity: 1 } - 100% { opacity: 0 } + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } } #ui-editor { - z-index: 9999; - position: absolute; - overflow: visible; - height: 100%; + z-index: 9999; + position: absolute; + overflow: visible; + height: 100%; } @font-face { - font-family: Fira Code; - src: url(../src/fonts/FiraCode-Regular.ttf); + font-family: Fira Code; + src: url(../src/fonts/FiraCode-Regular.ttf); } /* 注释下面这三行以开启抗锯齿 */ -.anti-aliasing { - image-rendering: pixelated; -} +/* .anti-aliasing { + image-rendering: pixelated; +} */ .warning { - transition: left cubic-bezier(0, 0.9, 1, 0.1) 2.5s; - -webkit-transition: left cubic-bezier(0, 0.9, 1, 0.1) 2.5s; - animation: warning 1s linear 0s alternate infinite; - -webkit-animation: warning 1s linear 0s alternate infinite; + transition: left cubic-bezier(0, 0.9, 1, 0.1) 2.5s; + -webkit-transition: left cubic-bezier(0, 0.9, 1, 0.1) 2.5s; + animation: warning 1s linear 0s alternate infinite; + -webkit-animation: warning 1s linear 0s alternate infinite; } @keyframes warning { - 0 % { text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0);} - 50 % { text-shadow: 0px 0px 30px rgba(255, 0, 0, 1), 0px 0px 6px rgb(129, 0, 0);} - 100 % { text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0);} + 0 % { + text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0); + } + 50 % { + text-shadow: 0px 0px 30px rgba(255, 0, 0, 1), 0px 0px 6px rgb(129, 0, 0); + } + 100 % { + text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0); + } } @-webkit - keyframes warning { - 0 % { text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0);} - 50 % { text-shadow: 0px 0px 30px rgba(255, 0, 0, 1), 0px 0px 6px rgb(129, 0, 0);} - 100 % { text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0);} + 0 % { + text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0); + } + 50 % { + text-shadow: 0px 0px 30px rgba(255, 0, 0, 1), 0px 0px 6px rgb(129, 0, 0); + } + 100 % { + text-shadow: 0px 0px 9px rgba(255, 0, 0, 0.5), 0px 0px 6px rgb(129, 0, 0); + } } .gameCanvas { - transition: transform 1.5s ease-out; - -webkit-transition: transform 1.5s ease-out; -} \ No newline at end of file + transition: transform 1.5s ease-out; + -webkit-transition: transform 1.5s ease-out; +} +/* ====== 新增加载界面样式 ====== */ +@media screen and (max-width: 600px) { + .loading-slide { + width: 100% + } +} +#startTopGallery { + position: absolute; + width: 85%; + height: 85%; + top: 10%; + left:7.5%; + perspective: 1000px; +} + +.loading-slide { + position: absolute; + width: 100%; + height: 100%; + background-size: cover; + background-position: center; + opacity: 0; + object-fit: contain; + transform: translateX(100%) rotateY(30deg); + transition: all 1s cubic-bezier(0.4, 0, 0.2, 1); + border-radius: 10px; + box-shadow: 0 8px 20px rgba(0,0,0,0.4); +} + +.loading-slide.active { + opacity: 1; + transform: translateX(0) rotateY(0); +}