dnd5-scripts/npcTable.js
2026-06-17 22:32:48 +03:00

136 lines
4.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

await dv.view("scripts/locations");
const path_module = require('path');
function getNPCName(p) {
let nameLink = `[[${p.file.name}|${p.file.name}]]`; // Создаем Wiki-ссылку
let alive = p.alive == undefined || !!p.alive;
if (!alive) {
nameLink += `<span style="color:red"> (D)</span>`;
}
return nameLink;
}
function getClassAndLevel(p) {
const statsArray = p.stats ? p.stats.split(';') : [];
if (statsArray.length > 0) {
const firstStat = statsArray[0];
const colonIndex = firstStat.indexOf(':');
return colonIndex !== -1 ? firstStat.slice(colonIndex + 1).trim() : firstStat;
}
return null;
}
function getMainInfo(p) {
let age = p.birthday ? (1491 - p.birthday) : null;
let mainInfoParts = [];
if (p.appearance || p.race) {
// specialization
let appearanceTitle = "";
if (p.race) {
appearanceTitle += `Раса: ${p.race}. `;
}
if (age) {
appearanceTitle += `Возраст: ${age} лет. `;
}
if (p.profession) {
appearanceTitle += `Профессия: ${p.profession}. `;
}
if (p.appearance) {
appearanceTitle += `${p.appearance}`;
}
let appearanceTooltip = `<abbr title="${appearanceTitle}">View</abbr>`;
mainInfoParts.push(appearanceTooltip);
}
if (p.personality) {
let personalityTooltip = `<abbr title="${p.personality}">Pers</abbr>`;
mainInfoParts.push(personalityTooltip);
}
if (p.biography) {
let biographyTooltip = `<abbr title="${p.biography}">Bio</abbr>`;
mainInfoParts.push(biographyTooltip);
}
if (p.quests) {
let questsTooltip = `<abbr title="${p.quests}">Quests</abbr>`;
mainInfoParts.push(questsTooltip);
}
return mainInfoParts.join(" / ");
}
function listProperty(property) {
if (!property) {
return "";
}
// Если это массив, разделяем элементы
if (Array.isArray(property)) {
let links = [];
let otherItems = [];
property.forEach(item => {
if (item) {
if (typeof item === 'string') {
otherItems.push(item);
}
else if (typeof item === 'object')
{
links.push(item);
}
}
});
// Собираем ссылочные элементы и создаём tooltip для остальных
let tooltip = otherItems.length > 0 ? `<abbr title="${otherItems.join(', ')}">Equip</abbr>` : "";
// Объединяем ссылки и tooltip
return [...links, tooltip].filter(Boolean).join(", ");
} else {
// Если это не массив, просто возвращаем как есть (и проверяем на тип строки)
return typeof property === 'string' ? `<abbr title="${property}">Equip</abbr>` : "";
}
}
function listAffiliation(affiliation) {
if (!affiliation) {
return "";
}
if (Array.isArray(affiliation)) {
return affiliation.filter(Boolean).join(", ");
} else {
// Если это не массив, просто возвращаем как есть (и проверяем на тип строки)
return typeof affiliation === 'string' ? affiliation : "";
}
}
// Функция для отображения таблицы
function show_table(dv, regionsList, basePath) {
dv.span("## Персонажи");
dv.table(["Image", "Name", "Stat", "Main Info", "Affiliation", "Assets", "Loc"],
dv.pages("#npc")
.filter(p => p.domicile && dv.locations.regionMatches(dv, regionsList, p.domicile))
.sort(p => p.file.name, 'asc') // Сортировка по имени файла в порядке возрастания
.map(p => {
let nameLink = getNPCName(p);
let stats = getClassAndLevel(p);
let mainInfo = getMainInfo(p);
let avatarImage = dv.locations.getImageLinks(p, basePath); // Передаем basePath для формирования правильного пути
return [avatarImage, nameLink, stats, mainInfo, listAffiliation(p.affiliation), listProperty(p.possessions), p.location]; // Аватар первой колонкой
})
);
}
// Функция для запуска отображения таблицы
function run_show_table(...args) {
let dv = args[0].arg1;
let regionsList = args[0].arg2;
let basePath = this.app.vault.adapter.basePath; // Получаем базовый путь к хранилищу
show_table(dv, regionsList, basePath);
}
run_show_table(input);