Compare commits

...

11 Commits

27 changed files with 362 additions and 624 deletions

View File

@ -22,7 +22,7 @@
当你**制作完游戏**后,点击构建游戏,即可自动构建游戏,构建结果在 `dist` 文件夹,会自动打包到 `dist.zip` 压缩包,发塔或更新上传此压缩包即可。
此帮助文档远比 2.x 的文档易读,也更容易理解,建议多阅读此文档来解决自己的问题,如果问题很复杂,或是短时间内解决不了,再去造塔群询问
此帮助文档远比 2.x 的文档易读,也更容易理解,但是遇到问题时我们依然建议直接在造塔群询问,因为你可能不能判断文档中是否有关于你的问题的解答
```mermaid
graph TD

View File

@ -6,6 +6,8 @@
Unexpected error when posting danmaku. Error info: $1
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:发送弹幕时发生报错。
- 解决方案:查看后面的 Error info检查报错信息内容按照报错信息修复问题。
@ -24,6 +26,8 @@ Unexpected loading error in loading resource '$1/$2'. Error info: $3
Syntax error in parsing CSS: Unexpected ':'. Col: $1. CSS string: '$2
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
@ -33,6 +37,8 @@ Syntax error in parsing CSS: Unexpected ':'. Col: $1. CSS string: '$2
Syntax error in parsing CSS: Unexpected ';'. Col: $1. CSS string: '$2'
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
@ -42,6 +48,8 @@ Syntax error in parsing CSS: Unexpected ';'. Col: $1. CSS string: '$2'
Syntax error in parsing CSS: Missing property name after '-'. Col: $1. CSS string: '$2'
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
@ -51,6 +59,8 @@ Syntax error in parsing CSS: Missing property name after '-'. Col: $1. CSS strin
Syntax error in parsing CSS: Unexpected end of css, expecting ':'. Col: $1. CSS string: '$2'
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
@ -60,6 +70,8 @@ Syntax error in parsing CSS: Unexpected end of css, expecting ':'. Col: $1. CSS
Syntax error in parsing CSS: Unexpected end of css, expecting property value. Col: $1. CSS string: '$2'
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:解析 CSS 时报错,一般是在发送弹幕时引起。
- 解决方案:检查弹幕 CSS 语法是否正确。
@ -69,6 +81,8 @@ Syntax error in parsing CSS: Unexpected end of css, expecting property value. Co
Post danmaku with not allowed css. Info: $1
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 报错原因:弹幕 CSS 中使用了不允许的 css 属性类型。
- 解决方案:目前仅支持 `color` `background-color` `font-size: x%` 属性。
@ -133,7 +147,7 @@ Cannot use shader program for shader element that does not belong to it.
## ERROR CODE 18
```txt
Cannot delete shader program for shader element that does not belong to
Cannot delete shader program for shader element that does not belong to it.
```
- 报错原因:在一个着色器上删除了不属于这个着色器的着色器程序。

View File

@ -24,6 +24,8 @@ Repeat load of resource '$1/$2'.
Unknown danmaku tag: $1
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 警告原因:出现了未知的弹幕标签(指 `[xxx:xxx]`
- 解决方案:目前仅支持 `[i:xxx]` 标签,如果需要显示方括号,请使用 `\[\]`
@ -33,6 +35,8 @@ Unknown danmaku tag: $1
Ignored a mismatched ']' in danmaku.
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 警告原因:出现了不能匹配的右方括号。
- 解决方案:如果需要显示方括号,请使用 `\[\]`
@ -42,6 +46,8 @@ Ignored a mismatched ']' in danmaku.
Repeat post danmaku.
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 警告原因:同一个弹幕被发送了两次。
- 解决方案:确保一个弹幕实例只调用了一次 `post` 方法。
@ -51,6 +57,8 @@ Repeat post danmaku.
Registered special danmaku element: $1.
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 警告原因:要注册的弹幕标签已经存在。
- 解决方案:避免使用同一个标签名,如果内容不一样请换一个标签名。
@ -150,6 +158,8 @@ Floor-damage extension needs 'floor-binder' extension as dependency.
Uncaught error in posting like info for danmaku. Danmaku id: $1.
```
> 应该不会遇到这个报错,因为样板并不内置弹幕系统。
- 警告原因:为弹幕点赞时出现报错。
- 解决方案:可能是网络问题,检查网络。
@ -159,6 +169,8 @@ Uncaught error in posting like info for danmaku. Danmaku id: $1.
Repeat light id: '$1'
```
> 应该不会遇到这个报错,因为样板并不内置点光源。
- 警告原因:重复的光源 id。
- 解决方案:避免光源 id 出现重复。
@ -284,8 +296,7 @@ Sub-image exceeds texture dimensions, auto adjusting size.
Cannot modify MotaOffscreenCanvas2D that is freezed.
```
- 警告原因:不能修改已冻结的画布属性。
- 解决方案:如果这个画布后续还需要修改属性,那么就不要冻结它。
- 遇不到这个报错。
## WARN CODE 34

View File

@ -116,3 +116,21 @@ Uncaught promise error in waiting box component. Error reason: $1
- 警告原因:在等待 box 组件(选择框、确认框等)时,出现了异步报错。
- 解决方案:根据报错内容解决问题。
## WARN CODE 64
```txt
Text node type and block type mismatch: '$1' vs '$2'
```
- 警告原因多行文本TextContent解析时节点类型和分块类型不一致。
- 解决方案:理应不会遇到这个问题,如果遇到了,请到造塔群寻求帮助。
## WARN CODE 65
```txt
Cannot bind a weather controller twice.
```
- 警告原因:一个天气控制器不能绑定到两个元素上。
- 解决方案:如果两个元素需要天气,那么请创建两个天气控制器,一个天气控制器只能绑定一个,且不能解绑。

View File

@ -715,6 +715,7 @@ export async function routedConfirm(
const confirm = getChoiceRoute(1) === 0;
const timeout = core.control.__replay_getTimeout();
core.status.route.push(`choices:${confirm ? 0 : 1}`);
core.status.replay.toReplay.shift();
if (timeout === 0) return confirm;
const instance = controller.open(ConfirmBoxUI, {
...(props ?? {}),
@ -769,6 +770,7 @@ export async function routedChoices<T extends ChoiceKey>(
const selected = getChoiceRoute(0);
const timeout = core.control.__replay_getTimeout();
core.status.route.push(`choices:${selected}`);
core.status.replay.toReplay.shift();
if (timeout === 0) return choices[selected][0];
const instance = controller.open(ChoicesUI, {
...(props ?? {}),
@ -782,7 +784,7 @@ export async function routedChoices<T extends ChoiceKey>(
return choices[selected][0];
} else {
const choice = await getChoice(controller, choices, loc, width, props);
const index = choices.findIndex(v => v[1] === choice);
const index = choices.findIndex(v => v[0] === choice);
core.status.route.push(`choices:${index}`);
return choice;
}

View File

@ -389,6 +389,10 @@ export class Damage extends RenderItem<EDamageEvent> {
const font = '300 9px Verdana';
if (dam.damage > 0) {
text = core.formatBigNumber(dam.damage, true);
} else if (dam.ambush) {
text = `!`;
} else if (dam.repulse) {
text = '阻';
}
const mapDam: DamageRenderable = {

View File

@ -241,10 +241,10 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
};
onMounted(() => {
const startIndex = getPosIndex(core.saves.saveIndex);
selected.value = startIndex - 1;
const startIndex = getPosIndex(core.saves.saveIndex - 1);
selected.value = startIndex;
pageRef.value?.changePage(
Math.floor(core.saves.saveIndex / (grid.value.count - 1))
Math.floor((core.saves.saveIndex - 1) / (grid.value.count - 1))
);
updateDataList(now.value);
});
@ -380,10 +380,10 @@ export const Save = defineComponent<SaveProps, SaveEmits, keyof SaveEmits>(
'@save_right',
() => {
const count = grid.value.count;
if (selected.value < count) {
if (selected.value < count - 1) {
selected.value++;
} else {
selected.value = 0;
selected.value = 1;
pageRef.value?.movePage(1);
}
},

View File

@ -48,6 +48,7 @@ export function patchDamage() {
}
function renderThumbnailDamage(col: EnemyCollection) {
if (main.replayChecking) return;
core.status.damage.data = [];
core.status.damage.extraData = [];

View File

@ -590,6 +590,10 @@ export class HeroMover extends ObjectMoverBase {
// 中毒处理
if (core.hasFlag('poison')) {
core.status.hero.hp -= core.values.poisonDamage;
if (core.status.hero.hp <= 0) {
core.status.hero.hp = 0;
core.events.lose();
}
core.updateStatusBar();
}

View File

@ -63,7 +63,6 @@ interface PortResponse {
core.status.maps[data].enemy?.calRealAttribute();
core.updateStatusBar(true, true);
}
Mota.require('@user/client-modules').Shadow.update(true);
const Binder = Mota.require(
'@user/client-modules'
).LayerGroupFloorBinder;

View File

@ -357,6 +357,7 @@ export function initFallback() {
y
);
callback?.();
delete core.animateFrame.asyncId[animate];
};
adapters['door-animate']?.all('openDoor', block).then(cb);

View File

@ -2,7 +2,9 @@
export function initUI() {
if (main.mode === 'editor') return;
const { mainUi, fixedUi, mainSetting } = Mota.require('@motajs/legacy-ui');
if (!main.replayChecking) {
const { mainUi, fixedUi, mainSetting } =
Mota.require('@motajs/legacy-ui');
ui.prototype.drawBook = function () {
if (!core.isReplaying()) return mainUi.open('book');
@ -20,16 +22,6 @@ export function initUI() {
if (!core.isReplaying()) return mainUi.open('fly');
};
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.control.noAutoEvents = true;
Mota.require('@user/data-base').hook.emit('statusBarUpdate');
};
control.prototype.showStatusBar = function () {
if (main.mode === 'editor') return;
core.removeFlag('hideStatusBar');
@ -54,3 +46,14 @@ export function initUI() {
core.updateStatusBar();
};
}
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.control.noAutoEvents = true;
Mota.require('@user/data-base').hook.emit('statusBarUpdate');
};
}

View File

@ -26,10 +26,7 @@
"24": "Cannot decode source type of '$1', since there is no registered decoder for that type.",
"25": "Unknown audio type. Header: '$1'",
"26": "Uncaught error when fetching stream data from '$1'. Error info: $2.",
"1101": "Shadow extension needs 'floor-hero' extension as dependency.",
"1201": "Floor-damage extension needs 'floor-binder' extension as dependency.",
"1301": "Portal extension need 'floor-binder' extension as dependency.",
"1401": "Halo extension needs 'floor-binder' extension as dependency."
"1201": "Floor-damage extension needs 'floor-binder' extension as dependency."
},
"warn": {
"1": "Resource with type of 'none' is loaded.",
@ -97,7 +94,6 @@
"63": "Uncaught promise error in waiting box component. Error reason: $1",
"64": "Text node type and block type mismatch: '$1' vs '$2'",
"65": "Cannot bind a weather controller twice.",
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency."
}
}

View File

@ -66,7 +66,7 @@ editor_uievent_wrapper = function (editor) {
}
core.saveCanvas('uievent');
core.status.event.selection = data.selected || 0;
core.drawChoices(core.replaceText(data.text), data.choices, data.width, 'uievent');
core.drawChoices2(core.replaceText(data.text), data.choices, data.width, 'uievent');
core.status.event.selection = null;
core.loadCanvas('uievent');
return;

View File

@ -388,12 +388,6 @@ actions.prototype._sys_keyUp_lockControl = function (keyCode, altKey) {
core.status.holdingKeys = [];
switch (core.status.event.id) {
case 'text':
ok() && core.drawText();
break;
case 'confirmBox':
this._keyUpConfirmBox(keyCode);
break;
case 'action':
this._keyUpAction(keyCode);
break;
@ -530,9 +524,6 @@ actions.prototype._sys_ondown_lockControl = function (x, y, px, py) {
case 'action':
this._clickAction(x, y, px, py);
break;
case 'text':
core.drawText();
break;
case 'notes':
this._clickNotes(x, y, px, py);
break;
@ -822,10 +813,6 @@ actions.prototype.keyDownCtrl = function () {
};
actions.prototype._sys_keyDownCtrl = function () {
if (core.status.event.id == 'text') {
core.drawText();
return true;
}
if (
core.status.event.id == 'action' &&
core.status.event.data.type == 'text'
@ -855,10 +842,6 @@ actions.prototype.longClick = function (x, y, px, py) {
actions.prototype._sys_longClick_lockControl = function (x, y, px, py) {
if (!core.status.lockControl) return false;
if (core.status.event.id == 'text') {
core.drawText();
return true;
}
if (
core.status.event.id == 'action' &&
core.status.event.data.type == 'text'
@ -976,70 +959,10 @@ actions.prototype._clickConfirmBox = function (x, y, px, py) {
};
////// 键盘操作确认框时 //////
actions.prototype._keyUpConfirmBox = function (keycode) {
if (keycode == 37 || keycode == 39) {
core.status.event.selection = 1 - core.status.event.selection;
core.playSound('光标移动');
core.ui.drawConfirmBox(
core.status.event.ui,
core.status.event.data.yes,
core.status.event.data.no
);
return;
}
if (keycode == 13 || keycode == 32 || keycode == 67) {
if (core.status.event.selection == 0 && core.status.event.data.yes) {
// core.playSound('确定');
core.status.event.selection = null;
core.status.event.data.yes();
return;
}
if (core.status.event.selection == 1 && core.status.event.data.no) {
// core.playSound('确定');
core.status.event.selection = null;
core.status.event.data.no();
return;
}
}
};
actions.prototype._keyUpConfirmBox = function (keycode) {};
////// 鼠标在确认框上移动时 //////
actions.prototype._onMoveConfirmBox = function (x, y, px, py) {
if (py >= core._PY_ / 2 && py <= core._PY_ / 2 + 64) {
if (px >= core._PX_ / 2 - 70 && px <= core._PX_ / 2 - 10) {
if (core.status.event.selection != 0) {
core.status.event.selection = 0;
core.playSound('光标移动');
if (core.status.event.id == 'action') {
core.ui.drawConfirmBox(core.status.event.ui.text);
} else {
core.ui.drawConfirmBox(
core.status.event.ui,
core.status.event.data.yes,
core.status.event.data.no
);
}
}
return;
}
if (px >= core._PX_ / 2 + 10 && px <= core._PX_ / 2 + 70) {
if (core.status.event.selection != 1) {
core.status.event.selection = 1;
core.playSound('光标移动');
if (core.status.event.id == 'action') {
core.ui.drawConfirmBox(core.status.event.ui.text);
} else {
core.ui.drawConfirmBox(
core.status.event.ui,
core.status.event.data.yes,
core.status.event.data.no
);
}
}
return;
}
}
};
actions.prototype._onMoveConfirmBox = function (x, y, px, py) {};
actions.prototype._clickAction_text = function () {
// 正在淡入淡出的话不执行

View File

@ -1584,7 +1584,8 @@ control.prototype._replay_finished = function () {
core.status.replay.replaying = true;
core.ui.closePanel();
core.pauseReplay();
}
},
true
);
};
@ -1639,7 +1640,8 @@ control.prototype._replay_error = function (action, callback) {
core.ui.closePanel();
core.stopReplay(true);
if (callback) callback();
}
},
true
);
};
@ -2212,139 +2214,20 @@ control.prototype.syncSave = function (type) {
};
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');
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);
}
);
// Deprecated.
};
////// 从服务器加载存档 //////
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)
);
}
});
// Deprecated.
};
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);
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存档解析失败');
}
} else {
core.drawText(
'出错啦!\n无法从服务器同步存档。\n错误原因' +
response.msg
);
}
},
function (e) {
core.drawText('出错啦!\n无法从服务器同步存档。\n错误原因' + e);
}
);
// Deprecated.
};
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
);
});
}
// Deprecated.
};
////// 存档到本地 //////
@ -2741,9 +2624,7 @@ control.prototype.unlockControl = function () {
////// 开启debug模式 //////
control.prototype.debug = function () {
core.setFlag('debug', true);
core.drawText(
'\t[调试模式开启]此模式下按住Ctrl键或Ctrl+Shift键可以穿墙并忽略一切事件。\n此模式下将无法上传成绩。'
);
core.drawTip('[调试模式开启]此模式下按住Ctrl键可以穿墙并忽略一切事件');
};
control.prototype._bindRoutePush = function () {

View File

@ -320,6 +320,8 @@ core.prototype.initSync = function (coreData, callback) {
this._init_platform();
this._init_others();
core.initStatus.maps = core.maps._initMaps();
core.loader._load(function () {
core._afterLoadResources(callback);
});

View File

@ -42,7 +42,7 @@ events.prototype._startGame_start = function (hard, seed, route, callback) {
core.firstData.hero,
hard,
null,
core.cloneArray(core.initStatus.maps)
core.clone(core.initStatus.maps)
);
core.setHeroLoc('x', -1);
core.setHeroLoc('y', -1);
@ -120,7 +120,6 @@ events.prototype._startGame_upload = function () {
////// 游戏获胜事件 //////
events.prototype.win = function (reason, norank, noexit) {
if (!noexit) core.status.gameOver = true;
return this.eventdata.win(reason, norank, noexit);
};
@ -130,7 +129,6 @@ events.prototype.lose = function (reason) {
return core.control._replay_error(reason, function () {
core.lose(reason);
});
core.status.gameOver = true;
return this.eventdata.lose(reason);
};
@ -187,7 +185,8 @@ events.prototype._gameOver_confirmUpload = function (ending, norank) {
if (main.isCompetition)
core.events._gameOver_confirmDownload(ending);
else core.events._gameOver_doUpload(null, ending, norank);
}
},
true
);
};
@ -251,7 +250,8 @@ events.prototype._gameOver_confirmDownload = function (ending) {
},
function () {
core.events._gameOver_askRate(ending);
}
},
true
);
};
@ -284,7 +284,8 @@ events.prototype._gameOver_askRate = function (ending) {
function () {
core.ui.closePanel();
core.restart();
}
},
true
);
return;
}
@ -301,7 +302,8 @@ events.prototype._gameOver_askRate = function (ending) {
},
function () {
core.restart();
}
},
true
);
};
@ -327,7 +329,8 @@ events.prototype.confirmRestart = function () {
function () {
core.playSound('取消');
core.ui.closePanel();
}
},
true
);
};
@ -1563,6 +1566,10 @@ events.prototype.__action_doAsyncFunc = function (isAsync, func) {
};
events.prototype._action_text = function (data) {
if (main.replayChecking) {
core.doAction();
return;
}
if (this.__action_checkReplaying()) return;
const Store = Mota.require('@user/client-modules').TextboxStore;
const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data;
@ -1592,6 +1599,10 @@ events.prototype._action_text = function (data) {
};
events.prototype._action_autoText = function (data) {
if (main.replayChecking) {
core.doAction();
return;
}
if (this.__action_checkReplaying()) return;
const Store = Mota.require('@user/client-modules').TextboxStore;
const { textbox = 'main-textbox', text, icon = 'none', title = '' } = data;
@ -1638,6 +1649,10 @@ events.prototype._action__label = function (data, x, y, prefix) {
};
events.prototype._action_setText = function (data) {
if (main.replayChecking) {
core.doAction();
return;
}
const isNil = value => value === null || value === void 0;
const { textbox = 'main-textbox' } = data;
const Store = Mota.require('@user/client-modules').TextboxStore;
@ -1740,7 +1755,7 @@ events.prototype._action_confirm = function (data, x, y, prefix) {
};
events.prototype._action_choices = function (data, x, y, prefix) {
core.ui.drawChoices(
core.ui.drawChoices2(
core.replaceText(data.text, prefix),
data.choices,
data.width

View File

@ -3682,112 +3682,12 @@ maps.prototype._moveDetachedBlock = function (
opacity,
canvases
) {
var height = blockInfo.height,
posX = blockInfo.posX,
posY = blockInfo.posY,
image = blockInfo.image;
var headCanvas = canvases.headCanvas,
bodyCanvas = canvases.bodyCanvas,
damageCanvas = canvases.damageCanvas;
if (headCanvas) {
core.dymCanvas[headCanvas].clearRect(0, 0, 32, height);
core.dymCanvas[headCanvas].drawImage(
image,
posX * 32,
posY * height,
32,
height - 32,
0,
0,
32,
height - 32
);
core.relocateCanvas(
headCanvas,
nowX - core.bigmap.offsetX,
nowY + 32 - height - core.bigmap.offsetY
);
core.setOpacity(headCanvas, opacity);
}
if (bodyCanvas) {
if (blockInfo.bigImage) {
var face = blockInfo.face;
if (!blockInfo.faceIds) face = 'down';
else if (!blockInfo.faceIds[face]) {
// 维持此时朝向
face = 'down';
for (var f in blockInfo.faceIds) {
if (blockInfo.faceIds[f] == blockInfo.id) {
face = f;
}
}
}
var bigImageInfo = this._getBigImageInfo(
blockInfo.bigImage,
face,
blockInfo.posX
);
var per_width = bigImageInfo.per_width,
per_height = bigImageInfo.per_height;
core.dymCanvas[bodyCanvas].clearRect(
0,
0,
bigImageInfo.per_width,
bigImageInfo.per_height
);
core.dymCanvas[bodyCanvas].drawImage(
blockInfo.bigImage,
bigImageInfo.sx,
bigImageInfo.sy,
per_width,
per_height,
0,
0,
per_width,
per_height
);
core.relocateCanvas(
bodyCanvas,
nowX - core.bigmap.offsetX + bigImageInfo.dx,
nowY - core.bigmap.offsetY + bigImageInfo.dy
);
core.setOpacity(bodyCanvas, opacity);
} else {
core.dymCanvas[bodyCanvas].clearRect(0, 0, 32, 32);
core.dymCanvas[bodyCanvas].drawImage(
image,
posX * 32,
posY * height + height - 32,
32,
32,
0,
0,
32,
32
);
core.relocateCanvas(
bodyCanvas,
nowX - core.bigmap.offsetX,
nowY - core.bigmap.offsetY
);
core.setOpacity(bodyCanvas, opacity);
}
}
if (damageCanvas) {
core.relocateCanvas(
damageCanvas,
nowX - core.bigmap.offsetX,
nowY - core.bigmap.offsetY
);
core.setOpacity(damageCanvas, opacity);
}
// Deprecated.
};
////// 删除独立的block canvas //////
maps.prototype._deleteDetachedBlock = function (canvases) {
core.deleteCanvas(canvases.headCanvas);
core.deleteCanvas(canvases.bodyCanvas);
core.deleteCanvas(canvases.damageCanvas);
// Deprecated.
};
maps.prototype._getAndRemoveBlock = function (x, y) {

View File

@ -2228,7 +2228,7 @@ ui.prototype.textImage = function (content, lineHeight) {
};
////// 绘制一个选项界面 //////
ui.prototype.drawChoices = async function (content, choices, width) {
ui.prototype.drawChoices2 = async function (content, choices, width, noRoute) {
if (main.replayChecking) {
const selected = (() => {
const route = core.status.replay.toReplay[0];
@ -2238,18 +2238,21 @@ ui.prototype.drawChoices = async function (content, choices, width) {
return Number(route.slice(8));
}
})();
core.status.replay.toReplay.shift();
core.insertAction(choices[selected].action);
core.doAction();
} else {
const {
routedChoices,
getChoices,
mainUIController,
HALF_WIDTH,
HALF_HEIGHT,
POP_BOX_WIDTH
} = Mota.require('@user/client-modules');
const choice = choices.map((v, i) => [i, v.text]);
const selected = await routedChoices(
const fn = noRoute ? getChoices : routedChoices;
const selected = await fn(
mainUIController,
choice,
[HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5],
@ -2282,7 +2285,7 @@ ui.prototype.drawConfirmBox = async function (
text,
yesCallback,
noCallback,
ctx
noRoute
) {
if (main.replayChecking) {
const confirm = (() => {
@ -2293,6 +2296,7 @@ ui.prototype.drawConfirmBox = async function (
return Number(route.slice(8)) === 1;
}
})();
core.status.replay.toReplay.shift();
if (confirm) {
yesCallback?.();
} else {
@ -2301,12 +2305,14 @@ ui.prototype.drawConfirmBox = async function (
} else {
const {
routedConfirm,
getConfirm,
mainUIController,
HALF_WIDTH,
HALF_HEIGHT,
POP_BOX_WIDTH
} = Mota.require('@user/client-modules');
const confirm = await routedConfirm(
const fn = noRoute ? getConfirm : routedConfirm;
const confirm = await fn(
mainUIController,
text,
[HALF_WIDTH, HALF_HEIGHT, void 0, void 0, 0.5, 0.5],
@ -2369,7 +2375,7 @@ ui.prototype._drawQuickShop = function () {
};
});
choices.push('返回游戏');
this.drawChoices(null, choices);
this.drawChoices(null, choices, void 0, true);
};
ui.prototype._drawSyncSave = function () {

View File

@ -109,7 +109,7 @@ function main() {
this.canvas = {};
this.__VERSION__ = '2.10.0';
this.__VERSION_CODE__ = 510;
this.__VERSION_CODE__ = 610;
}
// >>>> body end
@ -183,15 +183,12 @@ main.prototype.loadSync = function (mode, callback) {
coreData[t] = main[t];
});
core.initSync(coreData, callback);
core.initSync(coreData, () => {});
main.loading.emit('coreInit');
core.initStatus.maps = core.maps._initMaps();
core.resize();
main.core = core;
core.completeAchievement = () => 0;
core.plugin = { drawLight: 0 };
callback?.();
};
main.prototype.loadAsync = async function (mode, callback) {

View File

@ -185,9 +185,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
},
"flags": {},
"followers": [],
"steps": 0,
"magicDef": 0,
"magicRed": 0
"steps": 0
},
"startCanvas": [
{

View File

@ -295,6 +295,7 @@ main.floors.sample1=
},
{
"type": "hide",
"remove": true,
"time": 500
}
],

View File

@ -17,6 +17,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.status.played = true;
// 初始化人物,图标,统计信息
core.status.hero = core.clone(hero);
core.status.hero.buff ??= {};
window.hero = core.status.hero;
window.flags = core.status.hero.flags;
core.events.setHeroIcon(core.status.hero.image, true);
@ -56,27 +57,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
} else {
flags.autoSkill ??= true;
}
// 兼容性调整
const h = core.status.hero;
if (h.magicDef === void 0 || h.magicDef === null) {
h.magicDef = 0;
}
if (!core.status.hero.buff) {
const buff = {};
core.status.hero.buff = buff;
const toDelete = [];
for (const [key, value] of Object.entries(flags)) {
if (/__\w+_buff__/.test(key)) {
const name = key.slice(2, -7);
buff[name] = value;
toDelete.push(key);
}
}
toDelete.forEach(v => {
delete flags[v];
});
}
},
win: function (reason, norank, noexit) {
// 游戏获胜事件
@ -88,30 +68,23 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.status.extraEvent = core.clone(core.status.event);
}
if (reason === '智慧之始') {
core.status.hero.hp +=
core.itemCount('yellowKey') * 5000 +
core.itemCount('blueKey') * 15000;
}
// 游戏获胜事件
core.ui.closePanel();
var replaying = core.isReplaying();
if (replaying) core.stopReplay();
core.waitHeroToStop(function () {
if (!noexit) {
core.clearMap('all'); // 清空全地图
core.deleteAllCanvas(); // 删除所有创建的画布
}
reason = core.replaceText(reason);
core.drawText(
[
'\t[' +
(reason || '恭喜通关') +
']你的分数是${status:hp}。'
],
function () {
core.events.gameOver(reason || '', replaying, norank);
core.insertAction(
{
type: 'text',
text: '你的分数是' + core.status.hero.hp,
title: reason ?? '恭喜通关'
},
void 0,
void 0,
() => {
core.events.gameOver(reason ?? '', replaying, norank);
if (!noexit) core.status.gameOver = true;
}
);
});
@ -122,10 +95,17 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
var replaying = core.isReplaying();
core.stopReplay();
core.waitHeroToStop(function () {
core.drawText(
['\t[' + (reason || '结局1') + ']你死了。\n如题。'],
function () {
core.insertAction(
{
type: 'text',
text: '你死了。\n如题。',
title: reason ?? '结局1'
},
void 0,
void 0,
() => {
core.events.gameOver(null, replaying);
core.status.gameOver = true;
}
);
});
@ -165,21 +145,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
if (bgm instanceof Array) bgm = bgm[0];
if (!core.hasFlag('__bgm__')) core.playBgm(bgm);
}
// 更改画面色调
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._PY_,
core.arrayToRGBA(color)
);
// 更改天气
var weather = core.getFlag('__weather__', null);
if (!weather && core.status.maps[floorId].weather)
@ -228,8 +193,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.visitFloor(floorId);
}
}
// if (!flags.debug && !main.replayChecking)
// Mota.require('completion_r').checkVisitedFloor();
Mota.require('@user/data-base').hook.emit(
'afterChangeFloor',
floorId
@ -342,16 +305,6 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.removeFlag('__fromLoad__');
if (callback) callback();
Mota.r(() => {
if (flags.onChase) {
const chase = Mota.require(
'@user/legacy-plugin-client'
);
const controller = chase.initChase(0);
controller.start(true);
}
});
});
Mota.require('@user/data-base').hook.emit('loadData');

View File

@ -13,6 +13,8 @@ import { RequiredData, RequiredIconsData, ResourceType } from './types';
import { splitResource, SplittedResource } from './build-resource';
import { formatSize } from './utils';
const DEBUG_REPLAY = false;
const ansi = {
clear: '\x1b[2J\x1b[0f'
};
@ -92,7 +94,8 @@ async function buildData(outDir: string, entry: string) {
name: 'ProcessData',
fileName: 'data',
formats: ['iife']
}
},
minify: !DEBUG_REPLAY
}
} satisfies UserConfig);

View File

@ -1,10 +1,14 @@
/* eslint-disable no-console */
import { copy, emptyDir, ensureDir } from 'fs-extra';
import { writeFile } from 'fs/promises';
import { resolve } from 'path';
const base = resolve(process.cwd());
const template = resolve(base, 'template');
const serve = `在 2.B 样板中,不再使用先前的启动服务,而使用一个单独的软件。
959329661 - `;
async function packTemplate() {
await ensureDir(template);
await emptyDir(template);
@ -41,6 +45,8 @@ async function packTemplate() {
)
);
await writeFile(resolve(template, '启动服务呢?.txt'), serve, 'utf-8');
console.log(`样板打包完成`);
}

View File

@ -759,14 +759,14 @@ interface Ui {
textImage(content: string, lineHeight?: number): HTMLCanvasElement;
/**
* @deprecated `getChoices` \
*
* @deprecated 使 `getChoices` \
* drawChoices
*/
drawChoices(
drawChoices2(
content: string,
choices: object[],
width?: number,
ctx?: CtxRefer
noRoute?: CtxRefer
): void;
/**
@ -777,7 +777,7 @@ interface Ui {
text: string,
yesCallback?: () => void,
noCallback?: () => void,
ctx?: CtxRefer
noRoute?: boolean
): void;
/**