完成度成就

This commit is contained in:
unanmed 2023-02-23 23:10:57 +08:00
parent 5dbe7654a4
commit 2ea95671a5
22 changed files with 279 additions and 66 deletions

View File

@ -504,6 +504,7 @@ main.prototype.listen = function () {
main.dom.body.onkeydown = function (e) {
if (main.editorOpened) return;
try {
if (e.keyCode === 27) e.preventDefault();
if (main.dom.inputDiv.style.display == 'block') return;
if (
main.core &&
@ -539,6 +540,7 @@ main.prototype.listen = function () {
) {
// ESC
main.core.showStartAnimate(true);
e.preventDefault();
}
e.stopPropagation();
return;
@ -873,40 +875,6 @@ main.prototype.listen = function () {
}
};
////// 点击“开始游戏”时 //////
// main.dom.playGame.onclick = function () {
// main.dom.startButtons.style.display = 'none';
// main.core.control.checkBgm();
// if (main.levelChoose.length == 0) {
// core.events.startGame('');
// } else {
// main.dom.levelChooseButtons.style.display = 'block';
// main.selectedButton = null;
// main.selectButton(0);
// }
// };
// ////// 点击“载入游戏”时 //////
// main.dom.loadGame.onclick = function () {
// main.core.control.checkBgm();
// main.core.load();
// };
// ////// 点击“录像回放”时 //////
// main.dom.replayGame.onclick = function () {
// main.core.control.checkBgm();
// main.core.chooseReplayFile();
// };
// main.dom.musicBtn.onclick = function () {
// try {
// if (main.core) main.core.triggerBgm();
// } catch (ee) {
// console.error(ee);
// }
// };
window.onblur = function () {
if (main.core && main.core.control) {
try {

View File

@ -20,7 +20,7 @@ main.floors.MT0=
[141, 34, 34,141, 0,141, 0, 0, 0,141, 0,141,141,141,20040],
[141,141,141,141, 0, 0, 0,141, 0, 0, 0,141, 33, 33,20040],
[141, 34, 34,141, 0,141, 0, 0, 0,141, 0,494,482,482,20040],
[141, 33, 33,492, 0,141, 0, 0, 0,141, 0,141, 33, 33,20040],
[141, 33, 33,492, 0,141, 0,642, 0,141, 0,141, 33, 33,20040],
[141, 34, 34,141, 0,141, 45,559, 46,141, 0,141,141,141,20040],
[141,141,141,141, 0, 0,558, 0,560, 0, 0,141, 33, 33,20040],
[141, 33, 33,141, 0,141,367, 0,129,141, 0,494,482,482,20040],

View File

@ -212,10 +212,18 @@ main.floors.MT14=
}
],
"127,1": [
"你是怎么办到的?!"
"你是怎么办到的?!",
{
"type": "function",
"function": "function(){\nif (!core.isReplaying()) {\n\tcore.addMountSign(2);\n}\n}"
}
],
"26,14": [
"不作死就不会死"
"不作死就不会死",
{
"type": "function",
"function": "function(){\nif (!core.isReplaying()) {\n\tcore.addMountSign(1);\n}\n}"
}
],
"8,2": [
"这一层有一个必须使用跳跃的地方需要1个跳跃次数你一共有3个跳跃次数请规划好",

View File

@ -34,13 +34,25 @@ main.floors.MT15=
"parallelDo": "",
"events": {
"44,0": [
"不愧是你!!!"
"不愧是你!!!",
{
"type": "function",
"function": "function(){\nif (!core.isReplaying()) {\n\tcore.addMountSign(4);\n}\n}"
}
],
"62,0": [
"卧槽!你连这都到了?!"
"卧槽!你连这都到了?!",
{
"type": "function",
"function": "function(){\nif (!core.isReplaying()) {\n\tcore.addMountSign(5);\n}\n}"
}
],
"9,0": [
"这边没有彩蛋往右边走→_→"
"这边没有彩蛋往右边走→_→",
{
"type": "function",
"function": "function(){\nif (!core.isReplaying()) {\n\tcore.addMountSign(3);\n}\n}"
}
],
"13,7": [
"看到下面那个绝对防御怪了吗?",
@ -72,9 +84,9 @@ main.floors.MT15=
"autoEvent": {},
"cannotMove": {},
"map": [
[30144,30145,30146,30147,30144,30145,30146,30147, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 0,20075, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,129,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,129,20055],
[30152,30153,30154,30155,30152,30153,30154,30155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20058],
[30160,30161,30162,30163,30160,30161,30162,30163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,336,141,141,141,141,141,141,141,141,141,141,20007,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20074],
[30144,30145,30146,30147,30144,30145,30146,30147, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129,20055],
[30152,30153,30154,30155,30152,30153,30154,30155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20057,20057,20057,20057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20058],
[30160,30161,30162,30163,30160,30161,30162,30163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,336,141,141,141,141,141,141,141,141,141,141,20007,20065,20065,20065,20065, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20074],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0,390,403,378, 21,484,492, 0, 27, 0, 0, 0, 28, 32,492,396,376,484,403,492,378,492,376,30152,30153,30154,30155, 34,511,484,376,403,378, 0,499, 0, 28,381, 28, 33,511,141,484, 0,269, 0,336,378, 0,512,336,482, 27,381, 0,20007],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0,141,141,141,141,512,141, 33, 0, 28, 0,503,141,141,141, 0,336,336,336,340, 0,141, 0,30160,30161,30162,30163, 28,336,336,336,336,336,494,484,390,403,403,396, 0, 0,492, 0,336, 0,482,492,482,336, 0,336,336,336,492,244, 94],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 33,378,492, 0,381, 0,503,141,141,141, 0, 27, 0,141,512, 0, 32,403,340,403,141,403, 0,244, 34, 27,381,492,403, 0,482, 0,378,336,336,336,512,336,492,376,403,378, 28, 0, 0,511, 0,492,390, 0,403, 0,484, 0, 0],
@ -90,8 +102,8 @@ main.floors.MT15=
],
"bgmap": [
[ 0, 0, 0, 0, 0, 0, 0, 0,20076,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20075, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20076,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20054,20055],
[ 0, 0, 0, 0, 0, 0, 0, 0,20047,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0,20047,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0,20047,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057,20057, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0,20047,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065,20065, 0],
[20054,20054,20054,20054,20054,20054,20054,20054,20055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[20057,20057,20057,20057,20057,20057,20057,20057,20058, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20037,20038,20038,20038,20038,20039, 0, 0, 0,20045,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[20065,20065,20065,20065,20065,20065,20065,20065,20074, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20045, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20045, 0, 0, 0, 0,20047, 0, 0, 0,20045,20047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20037],

View File

@ -206,6 +206,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
core.visitFloor(floorId);
}
}
core.checkVisitedFloor();
},
flyTo: function (toId, callback) {
// 楼层传送器的使用从当前楼层飞往toId

View File

@ -598,7 +598,8 @@ var icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1 =
"I574": 99,
"I575": 100,
"I589": 101,
"I641": 102
"I641": 102,
"I642": 103
},
"autotile": {
"autotile": 0,

View File

@ -1357,5 +1357,11 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"mana": 5
}
}
},
"I642": {
"cls": "constants",
"name": "成就",
"canUseItemEffect": "true",
"useItemEffect": "core.plugin.achievementOpened.value = true;"
}
}

View File

@ -570,6 +570,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
"639": {"cls":"npc48","id":"N639"},
"640": {"cls":"terrains","id":"T640","canPass":true},
"641": {"cls":"items","id":"I641"},
"642": {"cls":"items","id":"I642"},
"20032": {"cls":"tileset","id":"X20032","cannotOut":["up","left"],"cannotIn":["up","left"]},
"20033": {"cls":"tileset","id":"X20033","cannotOut":["up"],"cannotIn":["up"]},
"20034": {"cls":"tileset","id":"X20034","cannotOut":["up","right"],"cannotIn":["up","right"]},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -37,7 +37,7 @@
"text": [
"第一章完成度达到100%"
],
"progress": "100 / 100",
"progress": "${core.getChapterCompletion(1)} / 100",
"percent": true,
"point": 50
},
@ -46,7 +46,7 @@
"text": [
"与山路上的若干个神秘木牌对话"
],
"progress": "5 / 5",
"progress": "${core.getLocalStorage('mountSign', 0)} / 5",
"hide": "该探索成就需要你自己探索如何达成",
"point": 25
},
@ -55,7 +55,7 @@
"text": [
"第二章完成度达到100%"
],
"progress": "100 / 100",
"progress": "${core.getChapterCompletion(2)} / 100",
"percent": true,
"point": 50
},

View File

@ -1,7 +1,10 @@
{
"fullscreen": {
"text": "全屏游戏",
"desc": ["是否全屏进行游戏"]
"desc": [
"是否全屏进行游戏全屏后按ESC退出全屏不能开启系统设置菜单请按下方的按钮打开。",
"进入或退出全屏后请存读档一下,以解决一部分绘制问题。"
]
},
"transition": {
"text": "界面动画",

View File

@ -13,6 +13,8 @@ import fixed from './plugin/ui/fixed';
import webglUtils from './plugin/webgl/utils';
import shadow from './plugin/shadow/shadow';
import gameShadow from './plugin/shadow/gameShadow';
import achievement from './plugin/ui/achievement';
import completion, { floors } from './plugin/completion';
function forward() {
const toForward: any[] = [
@ -30,7 +32,9 @@ function forward() {
fixed(),
webglUtils(),
shadow(),
gameShadow()
gameShadow(),
achievement(),
completion()
];
// 初始化所有插件并转发到core上
@ -52,6 +56,13 @@ function forward() {
console.log('插件转发完成!');
})();
Object.values(floors).forEach((v, i) => {
const from = core.floorIds.indexOf(v[0]);
const to = core.floorIds.indexOf(v[1]);
const all = core.floorIds.slice(from, to + 1);
floors[i + 1] = all;
});
}
main.forward = forward;

108
src/plugin/completion.ts Normal file
View File

@ -0,0 +1,108 @@
import {
AchievementType,
completeAchievement,
hasCompletedAchievement
} from './ui/achievement';
import { changeLocalStorage } from './utils';
import list from '../data/achievement.json';
export default function init() {
return { getChapterCompletion, checkVisitedFloor };
}
export const floors: Record<number, FloorIds[]> = {
1: ['MT0', 'tower7']
};
const achis: Record<number, Record<AchievementType, number[]>> = {
1: {
normal: [0, 1],
challenge: [0],
explore: [1]
}
};
export const achiDict: Record<number, number> = {
1: 0
};
/**
*
*/
export function checkVisitedFloor() {
changeLocalStorage<Partial<Record<FloorIds, boolean>>>(
'visitedFloor',
data => {
let needUpdate = false;
core.floorIds.forEach(v => {
if (core.hasVisitedFloor(v)) {
data[v] = true;
needUpdate = true;
}
});
if (needUpdate) {
checkCompletionAchievement();
}
return data;
},
{}
);
}
/**
*
* @param num
*/
export function getChapterCompletion(num: number) {
if (!achis[num]) return 0;
let res = 0;
const all = floors[num];
const achiNum = Object.values(achis[num]).reduce(
(pre, cur) => pre + cur.length,
0
);
// 计算到达过的楼层
let visitedFloor = 0;
const visited = core.getLocalStorage<Partial<Record<FloorIds, boolean>>>(
'visitedFloor',
{}
);
all.forEach(v => {
if (visited[v]) visitedFloor++;
});
const floorRatio = all.length / (all.length + achiNum);
const floorPoint = (floorRatio * visitedFloor) / all.length;
let completedPoint = 0;
let totalPoint = 0;
// 计算成就,占比按成就点走
for (const [type, achi] of Object.entries(achis[num]) as [
AchievementType,
number[]
][]) {
achi.forEach(v => {
totalPoint += list[type][v].point;
if (hasCompletedAchievement(type, v)) {
completedPoint += list[type][v].point;
}
});
}
const achiPoint = (completedPoint / totalPoint) * (1 - floorRatio);
res = floorPoint + achiPoint;
return Math.floor(res * 100);
}
/**
*
*/
export function checkCompletionAchievement() {
[1].forEach(v => {
if (getChapterCompletion(v) >= 100) {
completeAchievement('explore', achiDict[v]);
}
});
}

View File

@ -1,6 +1,7 @@
import { ref } from 'vue';
import list from '../../data/achievement.json';
import { has } from '../utils';
import { achiDict, checkCompletionAchievement } from '../completion';
import { changeLocalStorage, has } from '../utils';
type AchievementList = typeof list;
export type AchievementType = keyof AchievementList;
@ -17,7 +18,7 @@ export interface Achievement {
}
export default function init() {
return {};
return { completeAchievement, hasCompletedAchievement, addMountSign };
}
export const showComplete = ref(false);
@ -37,13 +38,22 @@ export const totalPoint = Object.values(list)
* @param index
*/
export function completeAchievement(type: AchievementType, index: number) {
const now = core.getLocalStorage<AchievementData>('achievement', {
normal: [],
challenge: [],
explore: []
});
now[type][index] = true;
core.setLocalStorage('achievement', now);
if (flags.debug) return;
changeLocalStorage<AchievementData>(
'achievement',
data => {
data[type][index] = true;
return data;
},
{
normal: [],
challenge: [],
explore: []
}
);
if (type === 'explore' && !Object.values(achiDict).includes(index)) {
checkCompletionAchievement();
}
completeAchi.value = `${type},${index}`;
showComplete.value = true;
}
@ -81,3 +91,32 @@ export function getNowPoint() {
}
return res;
}
// ----- 各个成就相关的函数
/**
*
* @param id id
*/
export function addMountSign(id: number) {
if (flags.debug) return;
if (
!core.getLocalStorage(`mountSign_${id}`, false) &&
!hasCompletedAchievement('explore', 1)
) {
changeLocalStorage(
'mountSign',
n => {
if (n + 1 >= 5) {
completeAchievement('explore', 1);
for (const i of [1, 2, 3, 4, 5]) {
core.removeLocalStorage(`mountSign_${i}`);
}
}
return n + 1;
},
0
);
core.setLocalStorage(`mountSign_${id}`, true);
}
}

View File

@ -95,7 +95,8 @@ export default function init() {
shopOpened,
startOpened,
startAnimationEnded,
loaded
loaded,
achievementOpened
};
}

View File

@ -15,7 +15,7 @@ type CanParseCss = keyof {
};
export default function init() {
return { has, getDamageColor, parseCss, tip };
return { has, getDamageColor, parseCss, tip, changeLocalStorage };
}
/**
@ -212,3 +212,19 @@ export async function doByInterval(
}
}
}
/**
*
* @param name
* @param fn
* @param defaultValue
*/
export function changeLocalStorage<T>(
name: string,
fn: (data: T) => T,
defaultValue?: T
) {
const now = core.getLocalStorage(name, defaultValue);
const to = fn(now);
core.setLocalStorage(name, to);
}

1
src/source/cls.d.ts vendored
View File

@ -569,6 +569,7 @@ interface IdToCls {
N639: 'npc48';
T640: 'terrains';
I641: 'items';
I642: 'items';
X20032: 'tileset';
X20033: 'tileset';
X20034: 'tileset';

View File

@ -186,4 +186,5 @@ interface ItemDeclaration {
I575: 'equips';
I589: 'equips';
I641: 'equips';
I642: 'constants';
}

View File

@ -569,6 +569,7 @@ interface IdToNumber {
N639: 639;
T640: 640;
I641: 641;
I642: 642;
X20032: 20032;
X20033: 20033;
X20034: 20034;
@ -1221,6 +1222,7 @@ interface NumberToId {
639: 'N639';
640: 'T640';
641: 'I641';
642: 'I642';
20032: 'X20032';
20033: 'X20033';
20034: 'X20034';

29
src/types/plugin.d.ts vendored
View File

@ -20,7 +20,8 @@ interface PluginDeclaration
PluginUse,
SkillTree,
MiniMap,
HeroRealStatus {
HeroRealStatus,
PluginAchievement {
/**
* 使core.addPop或core.plugin.addPop调用
* @param px
@ -389,6 +390,32 @@ interface HeroRealStatus {
): HeroStatus[K];
}
interface PluginAchievement {
/**
*
* @param type
* @param index
*/
completeAchievement(type: AchievementType, index: number): void;
/**
*
* @param type
* @param index
*/
hasCompletedAchievement(type: AchievementType, index: number): boolean;
/**
*
*/
getNowPoint(): number;
/**
*
*/
checkVisitedFloor(): void;
}
type Chapter = 'chapter1' | 'chapter2';
interface Skill {

View File

@ -19,7 +19,7 @@
<div id="list">
<div id="achievement-list" :style="{ left: `-${offset}%` }">
<div v-for="t of column" class="achievement-one">
<Scroll class="list-scroll" :width="10">
<Scroll class="list-scroll" :width="isMobile ? 10 : 20">
<div class="list-div">
<div
v-for="a of getAllAchievements(t)"
@ -107,6 +107,7 @@ import {
hasCompletedAchievement
} from '../plugin/ui/achievement';
import Scroll from '../components/scroll.vue';
import { isMobile } from '../plugin/use';
type AchievementList = typeof list;
type AchievementType = keyof AchievementList;
@ -172,7 +173,11 @@ function getAllAchievements(type: AchievementType): ResolvedAchievement[] {
}
function exit() {
noClosePanel.value = true;
try {
core.closePanel();
} catch {
noClosePanel.value = true;
}
achievementOpened.value = false;
}
</script>

View File

@ -112,7 +112,9 @@ type Settings = typeof settingInfo;
const core = window.core;
const selected = ref<keyof Settings>('transition');
const selected = ref<keyof Settings>('fullscreen');
fullscreen.value = !!document.fullscreenElement;
const descText = computed(() => {
return splitText(settingInfo[selected.value].desc);