sounds
This commit is contained in:
parent
c6ba3e38a2
commit
37087d08a7
189 changed files with 12864 additions and 9589 deletions
189
js/ui_family_async.js
Normal file
189
js/ui_family_async.js
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
"use strict";
|
||||
|
||||
function lineageIdleSchedule(fn, timeout = 180) {
|
||||
const schedule = window.requestIdleCallback || ((cb) => setTimeout(cb, 0));
|
||||
schedule(fn, { timeout });
|
||||
}
|
||||
|
||||
function lineageSameFamilyToken(token) {
|
||||
return uiCache.archiveRenderToken === token;
|
||||
}
|
||||
|
||||
function lineageBuildComponentsIdle(family, token, onProgress, onDone) {
|
||||
family = lineageEdgeFamily(family);
|
||||
const entries = Object.values(family || {}).filter(n => n?.id);
|
||||
const known = new Set(entries.map(n => n.id));
|
||||
const parentsByChild = new Map();
|
||||
const childrenByParent = new Map();
|
||||
const relatedIds = new Set();
|
||||
const graph = new Map();
|
||||
const comps = [];
|
||||
let stage = "relations";
|
||||
let entryIndex = 0;
|
||||
let nodeIndex = 0;
|
||||
let nodes = [];
|
||||
let sortedNodes = [];
|
||||
let dfsIndex = 0;
|
||||
const seen = new Set();
|
||||
|
||||
const addParent = (childId, parentId) => {
|
||||
if (!childId || !parentId || childId === parentId || !known.has(childId) || !known.has(parentId)) return;
|
||||
if (!parentsByChild.has(childId)) parentsByChild.set(childId, new Set());
|
||||
if (!childrenByParent.has(parentId)) childrenByParent.set(parentId, new Set());
|
||||
parentsByChild.get(childId).add(parentId);
|
||||
childrenByParent.get(parentId).add(childId);
|
||||
};
|
||||
const addGraphEdge = (a, b) => {
|
||||
if (!a || !b || !graph.has(a) || !graph.has(b)) return;
|
||||
graph.get(a).add(b);
|
||||
graph.get(b).add(a);
|
||||
};
|
||||
const validParentChild = (childId, parentId) => {
|
||||
const child = family[childId];
|
||||
const parent = family[parentId];
|
||||
if (!child || !parent) return false;
|
||||
const childListsParent = Array.isArray(child.parents) && child.parents.includes(parentId);
|
||||
const parentListsChild = Array.isArray(parent.children) && parent.children.includes(childId);
|
||||
return childListsParent || parentListsChild;
|
||||
};
|
||||
const finishEmpty = () => {
|
||||
lineageRelationIndexCache = { family, version: world.familyVersion || 0, index: { parentsByChild, childrenByParent } };
|
||||
onDone([]);
|
||||
};
|
||||
|
||||
const pump = () => {
|
||||
if (!lineageSameFamilyToken(token)) return;
|
||||
const started = performance.now();
|
||||
while (performance.now() - started < 6) {
|
||||
if (stage === "relations") {
|
||||
if (entryIndex >= entries.length) {
|
||||
lineageRelationIndexCache = { family, version: world.familyVersion || 0, index: { parentsByChild, childrenByParent } };
|
||||
stage = "related";
|
||||
entryIndex = 0;
|
||||
onProgress?.("\u95a2\u4fc2\u3092\u6574\u7406\u4e2d", 0, entries.length);
|
||||
continue;
|
||||
}
|
||||
const n = entries[entryIndex++];
|
||||
for (const parentId of n.parents || []) addParent(n.id, parentId);
|
||||
for (const childId of n.children || []) addParent(childId, n.id);
|
||||
} else if (stage === "related") {
|
||||
if (entryIndex >= entries.length) {
|
||||
nodes = Array.from(relatedIds).map(id => family[id]).filter(Boolean);
|
||||
for (const n of nodes) graph.set(n.id, new Set());
|
||||
if (!nodes.length) return finishEmpty();
|
||||
stage = "graph";
|
||||
nodeIndex = 0;
|
||||
onProgress?.("\u5bb6\u7cfb\u3092\u7d50\u5408\u4e2d", 0, nodes.length);
|
||||
continue;
|
||||
}
|
||||
const n = entries[entryIndex++];
|
||||
const parents = parentsByChild.get(n.id) || new Set();
|
||||
const children = childrenByParent.get(n.id) || new Set();
|
||||
if (parents.size || children.size) relatedIds.add(n.id);
|
||||
for (const id of parents) relatedIds.add(id);
|
||||
for (const id of children) relatedIds.add(id);
|
||||
} else if (stage === "graph") {
|
||||
if (nodeIndex >= nodes.length) {
|
||||
sortedNodes = nodes.slice().sort(lineageNodeSort);
|
||||
stage = "components";
|
||||
dfsIndex = 0;
|
||||
onProgress?.("\u5bb6\u7cfb\u3092\u5206\u5272\u4e2d", 0, sortedNodes.length);
|
||||
continue;
|
||||
}
|
||||
const n = nodes[nodeIndex++];
|
||||
const parentCandidates = new Set((n.parents || []).filter(Boolean));
|
||||
for (const parentId of parentsByChild.get(n.id) || []) parentCandidates.add(parentId);
|
||||
for (const parentId of parentCandidates) {
|
||||
if (parentId !== n.id && graph.has(parentId) && validParentChild(n.id, parentId)) addGraphEdge(n.id, parentId);
|
||||
}
|
||||
const childCandidates = new Set((n.children || []).filter(Boolean));
|
||||
for (const childId of childrenByParent.get(n.id) || []) childCandidates.add(childId);
|
||||
for (const childId of childCandidates) {
|
||||
if (childId !== n.id && graph.has(childId) && validParentChild(childId, n.id)) addGraphEdge(n.id, childId);
|
||||
}
|
||||
} else if (stage === "components") {
|
||||
while (dfsIndex < sortedNodes.length && seen.has(sortedNodes[dfsIndex].id)) dfsIndex += 1;
|
||||
if (dfsIndex >= sortedNodes.length) {
|
||||
comps.sort((a, b) => {
|
||||
const ag = Math.min(...a.map(n => n.generation || 1));
|
||||
const bg = Math.min(...b.map(n => n.generation || 1));
|
||||
const at = Math.min(...a.map(n => n.birthTime || 0));
|
||||
const bt = Math.min(...b.map(n => n.birthTime || 0));
|
||||
return ag - bg || at - bt || b.length - a.length;
|
||||
});
|
||||
onDone(comps);
|
||||
return;
|
||||
}
|
||||
const start = sortedNodes[dfsIndex++];
|
||||
const stack = [start.id];
|
||||
const comp = [];
|
||||
seen.add(start.id);
|
||||
while (stack.length && performance.now() - started < 6) {
|
||||
const id = stack.pop();
|
||||
const item = family[id];
|
||||
if (item) comp.push(item);
|
||||
for (const next of graph.get(id) || []) {
|
||||
if (seen.has(next)) continue;
|
||||
seen.add(next);
|
||||
stack.push(next);
|
||||
}
|
||||
}
|
||||
if (stack.length) {
|
||||
const continueComp = () => {
|
||||
if (!lineageSameFamilyToken(token)) return;
|
||||
const resumedStarted = performance.now();
|
||||
while (stack.length && performance.now() - resumedStarted < 6) {
|
||||
const id = stack.pop();
|
||||
const item = family[id];
|
||||
if (item) comp.push(item);
|
||||
for (const next of graph.get(id) || []) {
|
||||
if (seen.has(next)) continue;
|
||||
seen.add(next);
|
||||
stack.push(next);
|
||||
}
|
||||
}
|
||||
if (stack.length) return lineageIdleSchedule(continueComp, 180);
|
||||
if (comp.some(x => x.alive)) comps.push(comp);
|
||||
lineageIdleSchedule(pump, 180);
|
||||
};
|
||||
return lineageIdleSchedule(continueComp, 180);
|
||||
}
|
||||
if (comp.some(x => x.alive)) comps.push(comp);
|
||||
}
|
||||
}
|
||||
onProgress?.(
|
||||
stage === "relations" ? "\u95a2\u4fc2\u3092\u6574\u7406\u4e2d" : stage === "related" ? "\u8868\u793a\u5bfe\u8c61\u3092\u9078\u5225\u4e2d" : stage === "graph" ? "\u5bb6\u7cfb\u3092\u7d50\u5408\u4e2d" : "\u5bb6\u7cfb\u3092\u5206\u5272\u4e2d",
|
||||
stage === "graph" ? nodeIndex : entryIndex,
|
||||
stage === "graph" ? nodes.length : entries.length
|
||||
);
|
||||
lineageIdleSchedule(pump, 180);
|
||||
};
|
||||
lineageIdleSchedule(pump, 160);
|
||||
}
|
||||
|
||||
function familyStatusText(n) {
|
||||
if (!n) return "\u4e0d\u660e";
|
||||
return n.alive ? "\u751f\u5b58" : "\u6b7b\u4ea1";
|
||||
}
|
||||
|
||||
function familyDeathReasonLabel(rawReason, entity = null) {
|
||||
const text = String(rawReason || "");
|
||||
if (!text) return "";
|
||||
if (entity?.briefDeathReason) return entity.briefDeathReason(text);
|
||||
if (text.includes("\u3067\u8870\u5f31")) return text.length > 12 ? `${text.slice(0, 12)}\u2026` : text;
|
||||
if (/\u55a7\u5629|fight/.test(text)) return "\u55a7\u5629";
|
||||
if (/\u7206\u7af9|firecracker|explosion/.test(text)) return "\u7206\u7af9";
|
||||
if (/\u4ed5\u69d8\u306b\u3088\u308a\u753b\u9762\u5916\u3067\u524a\u9664|\u753b\u9762\u5916\u3067\u524a\u9664|out.*bounds|offscreen/.test(text)) return "\u4ed5\u69d8\u306b\u3088\u308a\u753b\u9762\u5916\u3067\u524a\u9664";
|
||||
if (/\u885d\u7a81|collision/.test(text)) return "\u885d\u7a81";
|
||||
if (/\u3064\u3064\u304b\u308c|\u3064\u3064\u304d|poke/.test(text)) return "\u3064\u3064\u304b\u308c\u3059\u304e\u305f";
|
||||
if (/\u305a\u3093\u3061\u75c5|zunchi_sick|zunchi.*\u75c5/.test(text)) return "\u305a\u3093\u3061\u75c5";
|
||||
if (/\u75c5/.test(text)) {
|
||||
const disease = text.match(/([^\u3001\u3002\s]+\u75c5)/);
|
||||
return disease ? disease[1] : "\u305a\u3093\u3061\u75c5";
|
||||
}
|
||||
if (/\u98e2|\u7a7a\u8179|\u98df\u3079\u7269|hunger/.test(text)) return "\u98e2\u9913";
|
||||
if (/\u30b9\u30c8\u30ec\u30b9|stress|\u6c17\u5206/.test(text)) return "\u30b9\u30c8\u30ec\u30b9\u904e\u591a";
|
||||
if (/\u5bff\u547d|\u5929\u5bff/.test(text)) return "\u5929\u5bff\u3092\u5168\u3046\u3057\u305f";
|
||||
if (/\u30dc\u30fc\u30eb|\u843d\u3061|\u843d\u4e0b|\u77f3|\u9053\u5177|\u4e8b\u6545|\u5f53\u305f|ball|drop|stone|accident/.test(text)) return "\u4e8b\u6545";
|
||||
return "\u4e8b\u6545";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue