initial commit
This commit is contained in:
commit
0c123ddeac
14
zz_meta/bases/PDFinfo.base
Normal file
14
zz_meta/bases/PDFinfo.base
Normal file
@ -0,0 +1,14 @@
|
||||
filters:
|
||||
and:
|
||||
- this.pdfs.contains(file)
|
||||
formulas:
|
||||
File Size: if(file.size > 1024*1024, ((file.size / 1024 / 1024).toFixed(2) + "m"), if(file.size > 1024, ((file.size / 1024).toFixed(2) + "k"), file.size))
|
||||
views:
|
||||
- type: table
|
||||
name: PDF List
|
||||
order:
|
||||
- file.name
|
||||
- formula.File Size
|
||||
sort:
|
||||
- property: file.name
|
||||
direction: ASC
|
||||
126
zz_meta/bases/ttrpg/CampaignInfo.base
Normal file
126
zz_meta/bases/ttrpg/CampaignInfo.base
Normal file
@ -0,0 +1,126 @@
|
||||
filters:
|
||||
or:
|
||||
- and:
|
||||
- list(campaigns).contains(this)
|
||||
- this.hasTag("ttrpg/campaign")
|
||||
- list(this.campaigns).filter(list(campaigns).contains(value)).length > 0
|
||||
formulas:
|
||||
Note: file.asLink(if(note.title, note.title, file.basename))
|
||||
Game Date: '[note["fc-date"], note["fc-end"]].filter(value).join(" – ")'
|
||||
Real Date: '"" + realDate'
|
||||
Place Type: if(file.hasTag("ttrpg/place/poi"), "Point of Interest", if(file.hasTag("ttrpg/place/region"), "Region", if(file.hasTag("ttrpg/place/settlement"), "Settlement", "Unknown")))
|
||||
Place Subtype: if(poiType, poiType, if(settlementType, settlementType, if(regionType, regionType)))
|
||||
properties:
|
||||
note.sessionNumber:
|
||||
displayName: Num
|
||||
note.summary:
|
||||
displayName: Summary
|
||||
note.realDate:
|
||||
displayName: Date
|
||||
note.ancestry:
|
||||
displayName: Ancestry
|
||||
note.pronouns:
|
||||
displayName: Pronouns
|
||||
note.languages:
|
||||
displayName: Languages
|
||||
note.factionType:
|
||||
displayName: Type
|
||||
note.leader:
|
||||
displayName: Leader
|
||||
note.itemType:
|
||||
displayName: Item Type
|
||||
views:
|
||||
- type: cards
|
||||
name: Player Character Cards
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/person")
|
||||
- personType == "pc"
|
||||
order:
|
||||
- formula.Note
|
||||
- Player
|
||||
- ancestry
|
||||
- pronouns
|
||||
image: note.image
|
||||
- type: table
|
||||
name: Sessions
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/session")
|
||||
order:
|
||||
- formula.Note
|
||||
- sessionNumber
|
||||
- formula.Real Date
|
||||
- formula.Game Date
|
||||
- summary
|
||||
sort:
|
||||
- property: sessionNumber
|
||||
direction: ASC
|
||||
- type: table
|
||||
name: Factions
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/faction")
|
||||
order:
|
||||
- formula.Note
|
||||
- factionType
|
||||
- leader
|
||||
- summary
|
||||
sort:
|
||||
- property: formula.Note
|
||||
direction: ASC
|
||||
columnSize:
|
||||
formula.Note: 125
|
||||
note.factionType: 102
|
||||
- type: table
|
||||
name: Nonplayer Characters
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/person")
|
||||
- personType != "pc"
|
||||
order:
|
||||
- formula.Note
|
||||
- ancestry
|
||||
- pronouns
|
||||
- languages
|
||||
- summary
|
||||
columnSize:
|
||||
formula.Note: 140
|
||||
note.pronouns: 111
|
||||
note.languages: 127
|
||||
- type: table
|
||||
name: Places
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/place")
|
||||
groupBy:
|
||||
property: formula.Place Type
|
||||
direction: ASC
|
||||
order:
|
||||
- formula.Note
|
||||
- formula.Place Type
|
||||
- formula.Place Subtype
|
||||
- location
|
||||
- summary
|
||||
sort:
|
||||
- property: formula.Note
|
||||
direction: ASC
|
||||
- property: location
|
||||
direction: ASC
|
||||
columnSize:
|
||||
formula.Note: 86
|
||||
formula.Place Type: 114
|
||||
note.location: 107
|
||||
note.summary: 134
|
||||
formula.Place Subtype: 130
|
||||
- type: table
|
||||
name: Items
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/item")
|
||||
order:
|
||||
- formula.Note
|
||||
- itemType
|
||||
- summary
|
||||
columnSize:
|
||||
note.itemType: 136
|
||||
43
zz_meta/bases/ttrpg/FactionInfo.base
Normal file
43
zz_meta/bases/ttrpg/FactionInfo.base
Normal file
@ -0,0 +1,43 @@
|
||||
formulas:
|
||||
Type: if(file.hasTag("ttrpg/faction"), "Faction (" + note.factionType + ")", if(file.hasTag("ttrpg/person"), "Person (" + note.personType + ")", "Other"))
|
||||
Category: |-
|
||||
if(
|
||||
file.hasTag("ttrpg/faction"),
|
||||
"Faction (" + factionType + ")",
|
||||
if(
|
||||
file.hasTag("ttrpg/person"),
|
||||
"Person (" + personType + ")", "Unknown"
|
||||
)
|
||||
)
|
||||
Note: file.asLink(if(note.title, note.title, file.basename))
|
||||
properties:
|
||||
note.summary:
|
||||
displayName: Summary
|
||||
views:
|
||||
- type: table
|
||||
name: Members
|
||||
filters:
|
||||
and:
|
||||
- or:
|
||||
- |-
|
||||
list(factions).filter(
|
||||
list(file(value).properties.factions)
|
||||
.contains(this)
|
||||
).length > 0
|
||||
- list(factions).contains(this)
|
||||
- list(this.leader).contains(file)
|
||||
- or:
|
||||
- file.hasTag("ttrpg/faction")
|
||||
- file.hasTag("ttrpg/person")
|
||||
order:
|
||||
- formula.Note
|
||||
- formula.Category
|
||||
- summary
|
||||
sort:
|
||||
- property: file.name
|
||||
direction: ASC
|
||||
- property: formula.Category
|
||||
direction: ASC
|
||||
columnSize:
|
||||
formula.Note: 151
|
||||
formula.Category: 179
|
||||
27
zz_meta/bases/ttrpg/RegionInfo.base
Normal file
27
zz_meta/bases/ttrpg/RegionInfo.base
Normal file
@ -0,0 +1,27 @@
|
||||
formulas:
|
||||
Note: link(file,if(title,title,file.basename))
|
||||
Place Type: if(file.hasTag("ttrpg/place/region"),"Region", if(file.hasTag("ttrpg/place/settlement"), "Settlement", "Point of Interest"))
|
||||
Place Subtype: if(regionType, regionType, if(settlementType, settlementType, poiType))
|
||||
views:
|
||||
- type: table
|
||||
name: Places
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/place")
|
||||
- or:
|
||||
- |-
|
||||
list(location).filter(
|
||||
list(file(value).properties.location)
|
||||
.contains(this) && file(value).hasTag("ttrpg/place/region")
|
||||
).length > 0
|
||||
- list(location).contains(this.file)
|
||||
order:
|
||||
- formula.Note
|
||||
- formula.Place Type
|
||||
- formula.Place Subtype
|
||||
- summary
|
||||
sort:
|
||||
- property: file.name
|
||||
direction: DESC
|
||||
columnSize:
|
||||
formula.Note: 135
|
||||
23
zz_meta/bases/ttrpg/SessionInfo.base
Normal file
23
zz_meta/bases/ttrpg/SessionInfo.base
Normal file
@ -0,0 +1,23 @@
|
||||
filters:
|
||||
and:
|
||||
- list(this.campaigns).containsAny(list(campaigns))
|
||||
- file.hasTag("ttrpg/session")
|
||||
formulas:
|
||||
Session: sessionNumber
|
||||
Title: if(title, title, file.basename)
|
||||
properties:
|
||||
formula.Session:
|
||||
displayName: Session Number
|
||||
views:
|
||||
- type: cards
|
||||
name: Navigation
|
||||
filters:
|
||||
or:
|
||||
- (sessionNUmber - this.sessionNumber).abs() == 1
|
||||
order:
|
||||
- formula.Title
|
||||
- summary
|
||||
sort:
|
||||
- property: sessionNumber
|
||||
direction: ASC
|
||||
cardSize: 340
|
||||
59
zz_meta/bases/ttrpg/SettlementInfo.base
Normal file
59
zz_meta/bases/ttrpg/SettlementInfo.base
Normal file
@ -0,0 +1,59 @@
|
||||
formulas:
|
||||
Note: link(file, if(title, title, file.basename))
|
||||
Place Type: if(file.hasTag("ttrpg/place/region"),"Region", if(file.hasTag("ttrpg/place/settlement"), "Settlement", "Point of Interest"))
|
||||
Place Subtype: if(regionType, regionType, if(settlementType, settlementType, poiType))
|
||||
views:
|
||||
- type: table
|
||||
name: Places
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/place")
|
||||
- or:
|
||||
- |-
|
||||
list(location).filter(
|
||||
list(file(value).properties.location)
|
||||
.contains(this)
|
||||
).length > 0
|
||||
- list(location).contains(this.file)
|
||||
order:
|
||||
- formula.Note
|
||||
- formula.Place Type
|
||||
- formula.Place Subtype
|
||||
- summary
|
||||
sort:
|
||||
- property: file.name
|
||||
direction: DESC
|
||||
columnSize:
|
||||
formula.Note: 135
|
||||
- type: table
|
||||
name: People
|
||||
filters:
|
||||
and:
|
||||
- or:
|
||||
- list(this.residents).contains(file)
|
||||
- list(this.leader).contains(file)
|
||||
- |-
|
||||
list(this.leader).filter(
|
||||
list(file.properties.factions)
|
||||
.contains(value)
|
||||
).length > 0
|
||||
- |-
|
||||
list(this.residents).filter(
|
||||
list(file.properties.factions)
|
||||
.contains(value)
|
||||
).length > 0
|
||||
- |-
|
||||
list(location).filter(
|
||||
list(file(value).properties.location)
|
||||
.contains(this)
|
||||
).length > 0
|
||||
- list(location).contains(this)
|
||||
- or:
|
||||
- file.hasTag("ttrpg/person")
|
||||
order:
|
||||
- formula.Note
|
||||
- pronunciation
|
||||
- pronouns
|
||||
- summary
|
||||
columnSize:
|
||||
formula.Note: 149
|
||||
13
zz_meta/bases/ttrpg/SystemInfo.base
Normal file
13
zz_meta/bases/ttrpg/SystemInfo.base
Normal file
@ -0,0 +1,13 @@
|
||||
filters:
|
||||
and:
|
||||
- link(system).asFile() == this.file
|
||||
formulas:
|
||||
Note: file.asLink(if(title, title, file.basename))
|
||||
views:
|
||||
- type: list
|
||||
name: Rules Helpers
|
||||
filters:
|
||||
and:
|
||||
- file.hasTag("ttrpg/rules")
|
||||
order:
|
||||
- formula.Note
|
||||
33
zz_meta/bases/ttrpg/SystemSettingCampaigns.base
Normal file
33
zz_meta/bases/ttrpg/SystemSettingCampaigns.base
Normal file
@ -0,0 +1,33 @@
|
||||
filters:
|
||||
and:
|
||||
- or:
|
||||
- and:
|
||||
- this.file.hasTag("ttrpg/setting")
|
||||
- link(setting).asFile() == this.file
|
||||
- and:
|
||||
- this.file.hasTag("ttrpg/system")
|
||||
- link(system).asFile() == this.file
|
||||
- file.hasTag("ttrpg/campaign")
|
||||
formulas:
|
||||
Players: players.join(", ")
|
||||
properties:
|
||||
note.players:
|
||||
displayName: Players
|
||||
note.system:
|
||||
displayName: System
|
||||
note.gm:
|
||||
displayName: GM
|
||||
note.setting:
|
||||
displayName: Setting
|
||||
views:
|
||||
- type: cards
|
||||
name: Campaigns
|
||||
order:
|
||||
- file.name
|
||||
- gm
|
||||
- formula.Players
|
||||
- system
|
||||
- setting
|
||||
cardSize: 200
|
||||
imageAspectRatio: 0.65
|
||||
image: note.image
|
||||
85
zz_meta/js/templater/ttrpg.js
Normal file
85
zz_meta/js/templater/ttrpg.js
Normal file
@ -0,0 +1,85 @@
|
||||
function fileHasTag(file, tag) {
|
||||
const cache = app.metadataCache.getFileCache(file);
|
||||
const allTags = (cache?.frontmatter?.tags ?? []).concat(
|
||||
cache?.tags?.map((t) => (t.tag[0] === "#" ? t.tag.slice(1) : t.tag)),
|
||||
);
|
||||
return allTags.some((t) => t === tag || t?.startsWith(`${tag}/`));
|
||||
}
|
||||
|
||||
function fileInParentWithTag(file, tag) {
|
||||
return app.vault
|
||||
.getMarkdownFiles()
|
||||
.filter(
|
||||
(mdFile) =>
|
||||
file.path.startsWith(mdFile.parent.path) && fileHasTag(mdFile, tag),
|
||||
)?.[0];
|
||||
}
|
||||
|
||||
function campaignData(file) {
|
||||
const campaignFile =
|
||||
fileInParentWithTag(file, "ttrpg/campaign") ||
|
||||
app.vault.getFileByPath("index.md");
|
||||
const data = {};
|
||||
console.log("campaign file", campaignFile);
|
||||
if (campaignFile) {
|
||||
const cache = app.metadataCache.getFileCache(campaignFile);
|
||||
const fm = cache?.frontmatter;
|
||||
const settingFile = frontmatterLinksToTFiles(campaignFile, "setting")?.[0];
|
||||
data.players = fm?.players;
|
||||
data.gm = fm?.gm;
|
||||
data.title = fm?.title || campaignFile.basename;
|
||||
data.system = fm?.system;
|
||||
data.setting = fm?.setting;
|
||||
data.settingFile = settingFile;
|
||||
data.file = campaignFile;
|
||||
data.link = app.fileManager.generateMarkdownLink(
|
||||
campaignFile,
|
||||
file.path,
|
||||
null,
|
||||
data.title,
|
||||
);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function frontmatterLinksToTFiles(sourceFile, property) {
|
||||
const links = app.metadataCache.getFileCache(sourceFile)?.frontmatterLinks;
|
||||
if (links) {
|
||||
return app.metadataCache
|
||||
.getFileCache(sourceFile)
|
||||
?.frontmatterLinks?.filter((l) => l.key.startsWith(property))
|
||||
?.map((l) =>
|
||||
app.metadataCache.getFirstLinkpathDest(l.link, sourceFile.path),
|
||||
)
|
||||
?.filter((f) => f);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function settingData(file) {
|
||||
const settingFile =
|
||||
fileInParentWithTag(file, "ttrpg/setting") ||
|
||||
campaignData(file)?.settingFile ||
|
||||
app.vault.getFileByPath("index.md");
|
||||
const data = {};
|
||||
if (settingFile) {
|
||||
const cache = app.metadataCache.getFileCache(settingFile);
|
||||
const fm = cache?.frontmatter;
|
||||
data.title = fm?.title || campaignFile.basename;
|
||||
data.file = settingFile;
|
||||
data.calendar = fm?.["fc-calendar"];
|
||||
data.link = app.fileManager.generateMarkdownLink(
|
||||
settingFile,
|
||||
file.path,
|
||||
null,
|
||||
data.title,
|
||||
);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
campaignData: campaignData,
|
||||
settingData: settingData,
|
||||
};
|
||||
113
zz_meta/js/templater/util.js
Normal file
113
zz_meta/js/templater/util.js
Normal file
@ -0,0 +1,113 @@
|
||||
async function updateMetadata(tp, options) {
|
||||
console.log("options", options);
|
||||
const file = tp.config.target_file;
|
||||
const data = options?.data ?? {};
|
||||
const tags = new Set([options?.tags ?? []].flat());
|
||||
const tagsToRemove = new Set([options?.tagsToRemove ?? []].flat());
|
||||
const title = options?.title;
|
||||
for (const tag of tags) {
|
||||
const splitTag = tag.split("/");
|
||||
for (let i = 1; i < splitTag.length; i++) {
|
||||
tagsToRemove.add(splitTag.slice(0, i).join("/"));
|
||||
}
|
||||
}
|
||||
if (tp.file.title === "Untitled" && title) {
|
||||
await tp.file.rename(title);
|
||||
}
|
||||
tp.hooks.on_all_templates_executed(async () => {
|
||||
await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
||||
console.log("frontmatter before", frontmatter);
|
||||
let fmTags = new Set([frontmatter.tags ?? []].flat());
|
||||
fmTags = tags.difference(tagsToRemove).union(tags);
|
||||
frontmatter.tags = Array.from(fmTags);
|
||||
frontmatter.tags.sort();
|
||||
for (const key in data) {
|
||||
frontmatter[key] = data[key];
|
||||
}
|
||||
console.log("frontmatter before", frontmatter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFileProperty(file, property) {
|
||||
const frontmatter = app.metadataCache.getFileCache(file)?.frontmatter;
|
||||
return frontmatter?.[property];
|
||||
}
|
||||
|
||||
function hasPropertyValue(file, property, value) {
|
||||
const propValue = getFileProperty(file, property);
|
||||
if (Array.isArray(propValue)) {
|
||||
return propValue.includes(value);
|
||||
}
|
||||
|
||||
return propValue === value;
|
||||
}
|
||||
|
||||
function frontmatterLinksToTFiles(sourceFile, property) {
|
||||
const links = app.metadataCache.getFileCache(sourceFile)?.frontmatterLinks;
|
||||
if (links) {
|
||||
return app.metadataCache
|
||||
.getFileCache(sourceFile)
|
||||
?.frontmatterLinks?.filter((l) => l.key.startsWith(property))
|
||||
?.map((l) =>
|
||||
app.metadataCache.getFirstLinkpathDest(l.link, sourceFile.path),
|
||||
)
|
||||
?.filter((f) => f);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function slugify(input) {
|
||||
if (!input) return "";
|
||||
|
||||
// Make lower case and trim
|
||||
var slug = input.toLowerCase().trim();
|
||||
|
||||
// Remove accents from characters
|
||||
slug = slug.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||
|
||||
// Replace invalid chars with spaces
|
||||
slug = slug.replace(/[^a-z0-9\s-]/g, " ").trim();
|
||||
|
||||
// Replace multiple spaces or hyphens with a single hyphen
|
||||
slug = slug.replace(/[\s-]+/g, "-");
|
||||
|
||||
return slug;
|
||||
}
|
||||
|
||||
function getAllTags(file) {
|
||||
const cache = app.metadataCache.getFileCache(file);
|
||||
const fileTags =
|
||||
cache?.tags?.map((t) => (t.tag[0] === "#" ? t.tag.slice(1) : t.tag)) || [];
|
||||
const fmTags = [cache?.frontmatter?.tags || []].flat();
|
||||
return fmTags.concat(fileTags);
|
||||
}
|
||||
|
||||
function filesWithTag(tag) {
|
||||
console.log("files with tag", tag);
|
||||
const files = app.vault.getMarkdownFiles().filter((file) => {
|
||||
const tags = getAllTags(file);
|
||||
return tags?.includes(tag) || tags?.some((t) => t.startsWith(`${tag}/`));
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
function fileHasTag(file, tag) {
|
||||
const cache = app.metadataCache.getFileCache(file);
|
||||
const allTags = (cache?.frontmatter?.tags ?? []).concat(
|
||||
cache?.tags?.map((t) => (t.tag[0] === "#" ? t.tag.slice(1) : t.tag)),
|
||||
);
|
||||
return allTags.some((t) => t === tag || t?.startsWith(`${tag}/`));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
slugify,
|
||||
getAllTags,
|
||||
filesWithTag,
|
||||
fileHasTag,
|
||||
frontmatterLinksToTFiles,
|
||||
getFileProperty,
|
||||
hasPropertyValue,
|
||||
updateMetadata,
|
||||
};
|
||||
16
zz_meta/shell/ttrpg/update_faction_metadata.sh
Executable file
16
zz_meta/shell/ttrpg/update_faction_metadata.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/zsh
|
||||
for file in **/*.md; do
|
||||
echo "foo$file"
|
||||
yq \
|
||||
--front-matter="process" \
|
||||
--inplace \
|
||||
'
|
||||
.tags = ["ttrpg/faction"] |
|
||||
.icon = "users" |
|
||||
.summary = .summary // "" |
|
||||
.campaigns = ["[[Kingmaker|Kingmaker]]"] |
|
||||
del(.type) |
|
||||
del(.campaign)
|
||||
' \
|
||||
"${file}"
|
||||
done
|
||||
31
zz_meta/shell/ttrpg/update_session_metadata.sh
Executable file
31
zz_meta/shell/ttrpg/update_session_metadata.sh
Executable file
@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
files=Session*.md
|
||||
for file in ${files[@]}; do
|
||||
echo "$file"
|
||||
export realDate=$(grep 'Real World Date' "$file" | cut -d' ' -f5)
|
||||
yq \
|
||||
--front-matter="process" \
|
||||
--inplace \
|
||||
'
|
||||
.tags = ["ttrpg/session"] |
|
||||
.icon = "book-open" |
|
||||
.title = "Session " + .session_number |
|
||||
.gm = "Mike" |
|
||||
.players = ["Jeff", "Brian", "Oz", "Andy", "Oz"] |
|
||||
.sessionNumber = .session_number |
|
||||
.summary = .summary // .["aat-event-body"] // "" |
|
||||
.aliases = ["Session " + .session_number] |
|
||||
.realDate = strenv(realDate) |
|
||||
.["fc-calendar"] = "Calendar of Golarion" |
|
||||
.["fc-display-name"] = "Kingmaker Session " + .session_number |
|
||||
.["fc-category"] = "Kingmaker" |
|
||||
.campaigns = ["[[Kingmaker|Kingmaker]]"] |
|
||||
del(.type) |
|
||||
del(.timelines) |
|
||||
del(.["aat-render-enabled"]) |
|
||||
del(.session_number) |
|
||||
del(.campaign) |
|
||||
del(.["aat-event-body"])
|
||||
' \
|
||||
"${file}"
|
||||
done
|
||||
78
zz_meta/templater/ttrpg/campaign.md
Normal file
78
zz_meta/templater/ttrpg/campaign.md
Normal file
@ -0,0 +1,78 @@
|
||||
<%*
|
||||
const title = (
|
||||
tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Campaign Title")
|
||||
: tp.file.title
|
||||
);
|
||||
const gm = await tp.system.prompt("Add a GM to this campaign")
|
||||
let isAddingPlayers = true;
|
||||
const players = [];
|
||||
while (isAddingPlayers) {
|
||||
const player = await tp.system.prompt("Add a player to this campaign")
|
||||
if (player) {
|
||||
players.push(player)
|
||||
} else {
|
||||
isAddingPlayers = false;
|
||||
}
|
||||
}
|
||||
const settingFiles = tp.user.util.filesWithTag("ttrpg/setting");
|
||||
const settingFile = (
|
||||
settingFiles.length > 0
|
||||
? await tp.system.suggester((file) => file.basename, settingFiles, false, "Select a setting")
|
||||
: null
|
||||
);
|
||||
const systemFiles = tp.user.util.filesWithTag("ttrpg/system");
|
||||
const systemFile = (
|
||||
systemFiles.length > 0
|
||||
? await tp.system.suggester((file) => file.basename, systemFiles, false, "Select a system")
|
||||
: null
|
||||
);
|
||||
const metadata = {
|
||||
title,
|
||||
tags: ["ttrpg/campaign"],
|
||||
data: {
|
||||
icon: "notebook-tabs",
|
||||
title,
|
||||
players,
|
||||
gm,
|
||||
pdfs: [],
|
||||
campaignStatus: "planning",
|
||||
},
|
||||
};
|
||||
if (settingFile) {
|
||||
metadata.data.setting = tp.app.fileManager.generateMarkdownLink(
|
||||
settingFile, tp.file.path(true), null, settingFile.basename
|
||||
);
|
||||
}
|
||||
if (systemFile) {
|
||||
metadata.data.system = tp.app.fileManager.generateMarkdownLink(
|
||||
systemFile, tp.file.path(true), null, systemFile.basename
|
||||
);
|
||||
}
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
|
||||
## Player Characters
|
||||
|
||||
![[CampaignInfo.base#Player Character Cards]]
|
||||
## Sessions
|
||||
|
||||
![[CampaignInfo.base#Sessions]]
|
||||
|
||||
## Factions
|
||||
|
||||
![[CampaignInfo.base#Factions]]
|
||||
|
||||
## NPCs
|
||||
|
||||
![[CampaignInfo.base#Nonplayer Characters]]
|
||||
|
||||
## Places
|
||||
|
||||
![[CampaignInfo.base#Places]]
|
||||
|
||||
## PDFs
|
||||
|
||||
![[PDFinfo.base]]
|
||||
28
zz_meta/templater/ttrpg/creature.md
Normal file
28
zz_meta/templater/ttrpg/creature.md
Normal file
@ -0,0 +1,28 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Creature Name")
|
||||
: tp.file.title;
|
||||
|
||||
const type = tp.frontmatter.creatureType ?? ""
|
||||
const metadata = {
|
||||
tags: ['ttrpg/creature'],
|
||||
data: {
|
||||
icon: "squirrel",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
system: tp.frontmatter?.system ?? "",
|
||||
creatureType: type,
|
||||
adjective: tp.frontmatter?.adjective ?? "",
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
44
zz_meta/templater/ttrpg/faction.md
Normal file
44
zz_meta/templater/ttrpg/faction.md
Normal file
@ -0,0 +1,44 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Faction Name")
|
||||
: tp.file.title;
|
||||
const adjective = tp.frontmatter?.adjective ?? "";
|
||||
const types = [
|
||||
"family",
|
||||
"military",
|
||||
"secret society",
|
||||
"political",
|
||||
"government",
|
||||
"religious",
|
||||
"academic",
|
||||
"criminal",
|
||||
"social",
|
||||
"commercial",
|
||||
"ethnic group",
|
||||
];
|
||||
const type = tp.frontmatter.factionType ?? await tp.system.suggester(v => v, types, true, "Type of Faction");
|
||||
const metadata = {
|
||||
tags: ['ttrpg/faction'],
|
||||
data: {
|
||||
icon: "users",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
factionType: type,
|
||||
headquarters: tp.frontmatter?.headquarters ?? "",
|
||||
leader: tp.frontmatter?.leader ?? "",
|
||||
adjective: tp.frontmatter?.adjective ?? "",
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
<% tp.file.cursor() %>
|
||||
## Members
|
||||
![[FactionInfo.base#Members]]
|
||||
|
||||
27
zz_meta/templater/ttrpg/item.md
Normal file
27
zz_meta/templater/ttrpg/item.md
Normal file
@ -0,0 +1,27 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Item Name")
|
||||
: tp.file.title;
|
||||
|
||||
const type = tp.frontmatter.itemType ?? ""
|
||||
const metadata = {
|
||||
tags: ['ttrpg/item'],
|
||||
data: {
|
||||
icon: "amphora",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
system: tp.frontmatter?.system ?? "",
|
||||
itemType: type,
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
43
zz_meta/templater/ttrpg/person.md
Normal file
43
zz_meta/templater/ttrpg/person.md
Normal file
@ -0,0 +1,43 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Person Name")
|
||||
: tp.file.title;
|
||||
const genders = {
|
||||
"N/A": "it",
|
||||
"Male": "he/him",
|
||||
"Female": "she/her",
|
||||
"Nonbinary": "they/them",
|
||||
}
|
||||
const types = {"npc": "Non-player Character", "pc": "Player Character"};
|
||||
const type = tp.frontmatter.personType ?? await tp.system.suggester(v => types[v], Object.keys(types), true, "Type of Character");
|
||||
const gender = tp.frontmatter?.gender ?? (await tp.system.suggester(v => v, Object.keys(genders), false, "Gender") ?? "N/A");
|
||||
const pronouns = tp.frontmatter.pronouns ?? genders[gender];
|
||||
const metadata = {
|
||||
tags: ['ttrpg/person'],
|
||||
data: {
|
||||
icon: "user",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
personType: type,
|
||||
gender,
|
||||
pronouns,
|
||||
ancestry: tp.frontmatter?.ancestry ?? "",
|
||||
languages: tp.frontmatter?.languages ?? [],
|
||||
factions: tp.frontmatter?.factions ?? [],
|
||||
location: tp.frontmatter?.location ?? [],
|
||||
},
|
||||
title,
|
||||
};
|
||||
if (type === "pc") {
|
||||
metadata.data.player = tp.frontmatter?.player ?? await tp.system.prompt("Player Name");
|
||||
}
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
44
zz_meta/templater/ttrpg/point-of-interest.md
Normal file
44
zz_meta/templater/ttrpg/point-of-interest.md
Normal file
@ -0,0 +1,44 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Location Name")
|
||||
: tp.file.title;
|
||||
const adjective = tp.frontmatter?.adjective ?? "";
|
||||
const types = [
|
||||
"shop",
|
||||
"landmark",
|
||||
"residence",
|
||||
"temple",
|
||||
"government building",
|
||||
"factory",
|
||||
"fortress",
|
||||
"military building",
|
||||
"ruin",
|
||||
"cave",
|
||||
"ship",
|
||||
];
|
||||
const type = tp.frontmatter.poiType ?? await tp.system.suggester(v => v, types, true, "Type of PoI");
|
||||
const metadata = {
|
||||
tags: ['ttrpg/place/poi'],
|
||||
data: {
|
||||
icon: "map-pin",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
poiType: type,
|
||||
location: tp.frontmatter?.location ?? "",
|
||||
wares: tp.frontmatter?.wares ?? "",
|
||||
proprietor: tp.frontmatter?.proprietor ?? "",
|
||||
residents: tp.frontmatter?.residents ?? [],
|
||||
factions: tp.frontmatter?.factions ?? [],
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
65
zz_meta/templater/ttrpg/region.md
Normal file
65
zz_meta/templater/ttrpg/region.md
Normal file
@ -0,0 +1,65 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Region Name")
|
||||
: tp.file.title;
|
||||
const adjective = tp.frontmatter?.adjective ?? "";
|
||||
const types = [
|
||||
"nation",
|
||||
"duchy",
|
||||
"county",
|
||||
"state",
|
||||
"star system",
|
||||
"planet",
|
||||
"sector",
|
||||
"continent",
|
||||
];
|
||||
const govTypes = [
|
||||
"anarchy",
|
||||
"athenian democracy",
|
||||
"caste",
|
||||
"city-states",
|
||||
"clan/tribal",
|
||||
"corporate state",
|
||||
"dictatorship",
|
||||
"feudal",
|
||||
"hive mind",
|
||||
"representative democracy",
|
||||
"technocracy",
|
||||
"theocracy",
|
||||
"bureaucracy",
|
||||
"charismatic rule",
|
||||
"cybercracy/machine civilization",
|
||||
"meritocracy",
|
||||
"military government",
|
||||
"oligarchy",
|
||||
"thaumatocracy",
|
||||
];
|
||||
const type = tp.frontmatter.regionType ?? await tp.system.suggester(v => v, types, true, "Type of Region");
|
||||
const metadata = {
|
||||
tags: ['ttrpg/place/region'],
|
||||
data: {
|
||||
icon: "map",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
regionType: type,
|
||||
capital: tp.frontmatter?.capital ?? "",
|
||||
location: tp.frontmatter?.location ?? "",
|
||||
population: tp.frontmatter?.population ?? 0,
|
||||
government: tp.frontmatter?.government ?? (await tp.system.suggester(v => v, govTypes, false, "Type of Government")) ?? "",
|
||||
leader: tp.frontmatter?.leader ?? "",
|
||||
adjective: tp.frontmatter?.adjective ?? "",
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
|
||||
![[zz_meta/bases/ttrpg/RegionInfo.base#Places|RegionInfo]]
|
||||
52
zz_meta/templater/ttrpg/session.md
Normal file
52
zz_meta/templater/ttrpg/session.md
Normal file
@ -0,0 +1,52 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const sessionNumber = Math.max(0, ...(
|
||||
tp.user.util.filesWithTag("ttrpg/session")
|
||||
.filter(f => tp.user.util.frontmatterLinksToTFiles(f, 'campaigns').includes(campaignData.file))
|
||||
.map(f => tp.user.util.getFileProperty(f, "sessionNumber"))
|
||||
.filter(n => n === 0 || n) || 0)
|
||||
) + 1;
|
||||
const title = tp.file.title === "Untitled" ? `Session ${sessionNumber}` : tp.file.title;
|
||||
let padSessionNumber = `${sessionNumber}`
|
||||
while (padSessionNumber.length < 3) {
|
||||
padSessionNumber = `0${padSessionNumber}`
|
||||
}
|
||||
const metadata = {
|
||||
tags: ["ttrpg/session"],
|
||||
data: {
|
||||
icon: "book-open",
|
||||
title,
|
||||
gm: campaignData.gm,
|
||||
players: campaignData.players,
|
||||
sessionNumber,
|
||||
summary: "",
|
||||
aliases: [
|
||||
title,
|
||||
`${campaignData?.title} ${title}`
|
||||
],
|
||||
campaigns: [campaignData.link],
|
||||
realDate: tp.date.now('YYYY-MM-DD')
|
||||
},
|
||||
title: `Session ${padSessionNumber}_${tp.date.now('YYYY-MM-DD')}`
|
||||
};
|
||||
if (settingData?.calendar) {
|
||||
metadata.data["fc-calendar"] = settingData.calendar;
|
||||
metadata.data["fc-display-name"] = `${campaignData?.title} ${title}`;
|
||||
metadata.data["fc-date"] = "";
|
||||
metadata.data["fc-end"] = "";
|
||||
metadata.data["fc-category"] = `${campaignData?.title}`;
|
||||
}
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
## Recap
|
||||
|
||||
- <% tp.file.cursor() %>
|
||||
|
||||
## Session Info
|
||||
|
||||
-
|
||||
|
||||
---
|
||||
![[SessionInfo.base#Navigation]]
|
||||
31
zz_meta/templater/ttrpg/setting.md
Normal file
31
zz_meta/templater/ttrpg/setting.md
Normal file
@ -0,0 +1,31 @@
|
||||
<%*
|
||||
const title = (
|
||||
tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Setting Title")
|
||||
: tp.file.title
|
||||
);
|
||||
const calendarId = (
|
||||
tp.frontmatter?.["fc-calendar"]
|
||||
? tp.frontmatter["fc-calendar"]
|
||||
: await tp.system.prompt("Setting Calendar ID", title)
|
||||
)
|
||||
const metadata = {
|
||||
title,
|
||||
tags: ["ttrpg/setting"],
|
||||
data: {
|
||||
icon: "globe",
|
||||
title,
|
||||
"fc-calendar": calendarId,
|
||||
pdfs: tp.frontmatter.pdfs ?? [],
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
![[SystemSettingCampaigns.base]]
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
|
||||
---
|
||||
|
||||
![[PDFinfo.base]]
|
||||
69
zz_meta/templater/ttrpg/settlement.md
Normal file
69
zz_meta/templater/ttrpg/settlement.md
Normal file
@ -0,0 +1,69 @@
|
||||
<%*
|
||||
const thisFile = tp.config.target_file;
|
||||
const campaignData = tp.user.ttrpg.campaignData(thisFile)
|
||||
const settingData = tp.user.ttrpg.settingData(thisFile);
|
||||
const title = tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("Settlement Name")
|
||||
: tp.file.title;
|
||||
const adjective = tp.frontmatter?.adjective ?? "";
|
||||
const types = [
|
||||
"thorp",
|
||||
"hamlet",
|
||||
"village",
|
||||
"small town",
|
||||
"large town",
|
||||
"city ward",
|
||||
"neighborhood",
|
||||
"small city",
|
||||
"large city",
|
||||
"metropolis",
|
||||
];
|
||||
const govTypes = [
|
||||
"anarchy",
|
||||
"athenian democracy",
|
||||
"caste",
|
||||
"clan/tribal",
|
||||
"corporate state",
|
||||
"dictatorship",
|
||||
"feudal",
|
||||
"hive mind",
|
||||
"representative democracy",
|
||||
"technocracy",
|
||||
"theocracy",
|
||||
"bureaucracy",
|
||||
"charismatic rule",
|
||||
"cybercracy/machine civilization",
|
||||
"meritocracy",
|
||||
"military government",
|
||||
"oligarchy",
|
||||
"thaumatocracy",
|
||||
];
|
||||
const type = tp.frontmatter.settlementType ?? await tp.system.suggester(v => v, types, true, "Type of Settlement");
|
||||
const metadata = {
|
||||
tags: ['ttrpg/place/settlement'],
|
||||
data: {
|
||||
icon: "building-2",
|
||||
title,
|
||||
pronunciation: tp.frontmatter.pronunciation ?? "",
|
||||
summary: tp.frontmatter?.summary ?? "",
|
||||
campaigns: [campaignData.link],
|
||||
setting: settingData.link,
|
||||
settlementType: type,
|
||||
location: tp.frontmatter?.location ?? "",
|
||||
population: tp.frontmatter?.population ?? 0,
|
||||
government: tp.frontmatter?.government ?? (await tp.system.suggester(v => v, govTypes, false, "Type of Government")) ?? "",
|
||||
leader: tp.frontmatter?.leader ?? "",
|
||||
residents: tp.frontmatter?.residents ?? [],
|
||||
adjective: tp.frontmatter?.adjective ?? "",
|
||||
},
|
||||
title,
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
|
||||
![[zz_meta/bases/ttrpg/SettlementInfo.base#Places|SettlementInfo]]
|
||||
|
||||
![[zz_meta/bases/ttrpg/SettlementInfo.base#People|SettlementInfo]]
|
||||
|
||||
24
zz_meta/templater/ttrpg/system.md
Normal file
24
zz_meta/templater/ttrpg/system.md
Normal file
@ -0,0 +1,24 @@
|
||||
<%*
|
||||
const title = (
|
||||
tp.file.title === "Untitled"
|
||||
? await tp.system.prompt("System Title")
|
||||
: tp.file.title
|
||||
);
|
||||
const metadata = {
|
||||
title,
|
||||
tags: ["ttrpg/system"],
|
||||
data: {
|
||||
icon: "notebook",
|
||||
title,
|
||||
pdfs: tp.frontmatter.pdfs ?? [],
|
||||
},
|
||||
};
|
||||
await tp.user.util.updateMetadata(tp, metadata);
|
||||
%>
|
||||
![[SystemSettingCampaigns.base]]
|
||||
|
||||
<% tp.file.cursor() %>
|
||||
|
||||
---
|
||||
|
||||
![[PDFinfo.base]]
|
||||
16
zz_meta/utility/Leaflet Bounds Calculator.md
Normal file
16
zz_meta/utility/Leaflet Bounds Calculator.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
image:
|
||||
height: 768
|
||||
width: 1024
|
||||
pixelDistance: 100
|
||||
unitDistance: 12
|
||||
---
|
||||
**Image Height:** `INPUT[number:image.height]`px
|
||||
**Image Width:** `INPUT[number:image.width]`px
|
||||
**Distance:** `INPUT[number:image.pixelDistance]`pixels = `INPUT[number:image.unitDistance]`units (feet, miles, km, parsecs, etc)
|
||||
|
||||
**Lower Bound:** 0, 0
|
||||
**Upper Bound:** `VIEW[round({image.height}/({image.pixelDistance}/{image.unitDistance}), 3)][math]`, `VIEW[round({image.width}/({image.pixelDistance}/{image.unitDistance}), 3)][math]`
|
||||
**Center Point:** `VIEW[round({image.height}/({image.pixelDistance}/{image.unitDistance})/2, 3)][math]`, `VIEW[round({image.width}/({image.pixelDistance}/{image.unitDistance})/2, 3)][math]`
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user