javalent / fantasy-statblocks

Create Dungeons and Dragons style statblocks for Obsidian.md
MIT License
356 stars 69 forks source link

Question: any way to make `=this.name_of_dataview_var` work in a statblock? #89

Closed scarfur closed 1 year ago

scarfur commented 2 years ago

Hey there,

I am trying the following - which is giving me headaches ... šŸ„²

> [!note] WIP!
> ```statblock
>  monster: `=this.name`
> ```

The statblock does not get rendered but if I change =this.name to the string value; test (read below why it is test and should be a variable) for troubleshooting purpose, the statblock gets rendered as it should, but I need the variable, not the string in my template.

In the frontmatter, name is valid and the string is: test

statblock = true is some rows below (by chronological means) the name field in the frontmatter. parse from frontmatter in the plugin settings is true.

The frontmatter gets populated by the plugin; database folder. So the core of my problem is, that I do not know the name of the file/monster because the statblock is created in a template which gets used by templater and database folder for creation of the note. So I want to automate the values/entries in the statblock but I do not get my head around how to solve this.

I would be so happy for any help šŸ˜­

I hope this is the right place to ask!? Thanks for all your great plugins valentine195 - you are a šŸ§™ā€ā™‚ļø

bassbogan commented 1 year ago

+1 to this requirement. I'm using inline scripts and inline dataview queries to automate some monster stats and would like to use the ttrpg statblock to format them but it won't evaluate the resultant valid inline dataview queries and the statblock doesn't render.

Creanimo commented 1 year ago

+1 I would love this too if this was possible. Having Dataview fields available in Fantasy Statblocks would weave two powerful worlds together.

valentine195 commented 1 year ago

This is nearly impossible due to the way obsidian plugins work. Iā€™d basically have to recreate the Dataview parser in this plugin.

Creanimo commented 1 year ago

Thanks for the feedback though and the great work!

I did find a veeery limited workaround though: Switching a statblock field to interpret markdown, does render these dataview snippets correctly. It's not great, because it would save the source markdown to the bestiary, but I might use it to quickly sneak some descriptions (like clothing, voice, etc) into the stat block before printing - just cause it looks so nice.

bassbogan commented 1 year ago

With a fair bit of tinkering I managed to get this to work. I kinda suck at formatting with github so I'll do my best to explain...

So I have a 'monstermaker.sfile' in the obsidian folder where I've put a heap of nested variables in the file that will let me build monster stat blocks programmatically. So for example I have levels, and in those level a number of base attributes are set like so:

lvl: lvl0: {name: "0", ac: 14, hp: 16, atkbonus: 2, dmg: 1, dc: [10,7], initiative: 1, perception: 1, stealth: 1, profbonus: 1, saves: [4,2,0], abilitymod: [3,2,1,1,0,-1], speed: 30} lvl1: {name: "1", ac: 14, hp: 26, atkbonus: 3, dmg: 2, dc: [11,8], initiative: 1, perception: 1, stealth: 1, profbonus: 2, saves: [5,3,0], abilitymod: [3,2,1,1,0,-1], speed: 30}

So for a lvl 0 monster, its base hit points are 16, where as a lvl 1 is 26 for example.

So if I want to get this into the statblock I have an number of js functions defined but instead of using the 'expand' feature I do a direct js call:

var hp = app.plugins.plugins.dataview.api.page("monstermaker.sfile").lvl[lvlval].hp)

where the [lvlval] is the level of the monster that is passed, so 0 or 1 in this example - I use a var as the value gets modified later by other things I'm doing, otherwise it could be a const if its not getting modified. This returns the actual result of 16 or 26 and its evaluated before the statblock syntax. So then I create a text string with the stat block command in it:

const statblockbase = "```statblock" + "\n" + "layout: Monster Maker 2.0" + "\n" + "name: My cool monster" + "\n" + "hp: " + hp + "\n" + "```"; There are way more attributes to populate but this post is getting long as is, but the idea is this would resolve to (using monster level 1):

```statblock layout: Monster Maker 2.0 name: My cool monster hp: 26 ```;

This text is then returned and obisidian will evaluate that text which automatically builds a stat block with the passed values. Hopefully that kind of makes sense as I'm probably not explaining it well, I had to teach myself some basic javascript to figure this out.

edit: updated a zillion times trying to format the code legibly but gave up :(