Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 10 additions & 10 deletions .build/json/environments.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@
"feats": [
{
"name": "Overgrown Battlefield - Passive",
"text": "There has been a battle here. A PC can make an Instinct Roll to identify evidence of that fight. On a success with Hope, learn all three pieces of information below. On a success with Fear, learn two. On a failure, a PC can mark 3 Stress to learn one and gain advantage on the next action roll to investigate this environment. A PC with an appropriate background or Experience can learn an additional detail and ask a follow-up question about the scene and get a truthful (if not always complete) answer.\n\n - Traces of a battle (broken weapons and branches, gouges in the ground) litter the ground.\n - A moss-covered tree trunk is actually the corpse of a treant.\n - Still-standing trees are twisted in strange ways, as if by powerful magic."
"text": "There has been a battle here. A PC can make an Instinct Roll to identify evidence of that fight. On a success with Hope, learn all three pieces of information below. On a success with Fear, learn two. On a failure, a PC can mark 3 Stress to learn one and gain advantage on the next action roll to investigate this environment. A PC with an appropriate background or Experience can learn an additional detail and ask a follow-up question about the scene and get a truthful (if not always complete) answer.\n\n - Traces of a battle (broken weapons and branches, gouges in the ground) litter the ground.\n - A moss-covered tree trunk is actually the corpse of a treant.\n - Still-standing trees are twisted in strange ways, as if by powerful magic.\n\n*Why did these groups come to blows? Why is the grove unused now?*"
},
{
"name": "Barbed Vines - Action",
"text": "Pick a point within the grove. All targets within Very Close range of that point must succeed on an Agility Reaction Roll or take 1d8+3 physical damage and become Restrained by barbed vines. Restrained lasts until they’re freed with a successful Finesse or Strength roll or by dealing at least 6 damage to the vines."
"text": "Pick a point within the grove. All targets within Very Close range of that point must succeed on an Agility Reaction Roll or take 1d8+3 physical damage and become Restrained by barbed vines. Restrained lasts until they’re freed with a successful Finesse or Strength roll or by dealing at least 6 damage to the vines.\n\n*How many vines are there? Where do they grab you? Do they pull you down or lift you off the ground?*"
},
{
"name": "You Are Not Welcome Here - Action",
"text": "A Young Dryad, two Sylvan Soldiers, and a number of Minor Treants equal to the number of PCs appear to confront the party for their intrusion."
"text": "A Young Dryad, two Sylvan Soldiers, and a number of Minor Treants equal to the number of PCs appear to confront the party for their intrusion.\n\n*What are the grove guardians concealing? What threat to the forest could the PCs confront to appease the Dryad?*"
},
{
"name": "Defiler - Action",
"text": "Spend a Fear to summon a Minor Chaos Adversary drawn to the echoes of violence and discord. They appear within Far range of a chosen PC and immediately take the spotlight."
"text": "Spend a Fear to summon a Minor Chaos Adversary drawn to the echoes of violence and discord. They appear within Far range of a chosen PC and immediately take the spotlight.\n\n*What color does the grass turn as the elemental appears? How does the chaos warp insects and small wildlife within the grove?*"
}
]
},
Expand All @@ -37,11 +37,11 @@
"feats": [
{
"name": "Relative Strength - Passive",
"text": "The Difficulty of this environment equals that of the adversary with the highest Difficulty."
"text": "The Difficulty of this environment equals that of the adversary with the highest Difficulty.\n\n*Who cues the ambush? What makes it clear they’re in charge?*"
},
{
"name": "Surprise! - Action",
"text": "The ambushers reveal themselves to the party, you gain 2 Fear, and the spotlight immediately shifts to one of the ambushing adversaries."
"text": "The ambushers reveal themselves to the party, you gain 2 Fear, and the spotlight immediately shifts to one of the ambushing adversaries.\n\n*What do the ambushers want from the party? How do their tactics in the ambush reflect that?*"
}
]
},
Expand All @@ -56,11 +56,11 @@
"feats": [
{
"name": "Relative Strength - Passive",
"text": "The Difficulty of this environment equals that of the adversary with the highest Difficulty."
"text": "The Difficulty of this environment equals that of the adversary with the highest Difficulty.\n\n*Which adversary is the least prepared? Which one is the most?*"
},
{
"name": "Where Did They Come From? - Reaction",
"text": "When a PC starts the ambush on unsuspecting adversaries, you lose 2 Fear and the first attack roll a PC makes has advantage."
"text": "When a PC starts the ambush on unsuspecting adversaries, you lose 2 Fear and the first attack roll a PC makes has advantage.\n\n*What are the adversaries in the middle of doing when the ambush starts? How does this impact their approach to the fight?*"
}
]
},
Expand Down Expand Up @@ -490,7 +490,7 @@
]
},
{
"name": "Necromancers Ossuary",
"name": "Necromancer's Ossuary",
"tier": "4",
"type": "Exploration",
"description": "A dusty crypt with a library, twisting corridors, and abundant sarcophagi; spattered with the blood of ill-fated invaders.",
Expand Down Expand Up @@ -520,4 +520,4 @@
}
]
}
]
]
61 changes: 61 additions & 0 deletions .build/statblocks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import json

adversaries = 0
with open("json/adversaries.json", "r", encoding="utf-8-sig") as file:
adversaries = json.load(file)
environments = 0
with open("json/environments.json", "r", encoding="utf-8-sig") as file:
environments = json.load(file)

def convert_environment(json):
md = """---
statblock: inline
---

```statblock
layout: Daggerheart Environment
"""
for key, value in json.items():
if key == "feats":
md += "feats:\n"
for name, desc in [feat.values() for feat in value]:
desc_raw = repr(desc)[1:-1]
md += f' - name: "{name}"\n desc: "{desc_raw}"\n'
else:
md += f'{key}: "{value}"\n'
md += "```"
return md

def convert_adversary(json):
md = """---
statblock: inline
---

```statblock
layout: Daggerheart Adversary
"""
for key, value in json.items():
if key == "feats":
md += "feats:\n"
for name, desc in [feat.values() for feat in value]:
md += f' - name: "{name}"\n desc: "{desc}"\n'
else:
md += f'{key}: "{value}"\n'
md += "```"
return md

def get_file(json):
folder = "adversaries" if "atk" in json else "environments"
name = json["name"]
if ":" in name:
name = name.replace(": ", " - ")
return f"../{folder}/Tier {json['tier']}/{name}.md"

for adversary in adversaries:
with open(get_file(adversary), "w") as file:
file.write(convert_adversary(adversary))

for environment in environments:
with open(get_file(environment), "w") as file:
file.write(convert_environment(environment))

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Installation
In order to use this content all that is needed is to download the zip file containing the source code (`Download ZIP` option under the big green `<> Code` button in the github repo), once downloaded you may simply extract the ZIP into your vault directly, but I would extract it somewhere else and then copy over the files that you want, since the repo contains some directories and files that you probably don't want (like the `.build`,`.github`,`.obsidian` as well as the licenses and README)

Once the content is downloaded and inside your vault, install the **[Fantasy Statblocks Plugin](https://github.com/javalent/fantasy-statblocks)**, enable it, go to the settings, go to the `Layouts` section and click `Import from JSON`, then import both of the layouts provided in this repository, in the [layouts](layouts) folder.
I would also recommend to set the folder where you have stored your adversaries and environments in the `Bestiary Folder` section of the settings, under `Note Parsing`.

If all you want is working statblocks then you are done! However, you may find my plugin **[Daggerheart Combat Tracker](https://github.com/Batres3/daggerheart-tracker)** useful and it is integrated with the content provided in this repository, so setup should be simple.
# DAGGERHEART SRD

***Welcome to DAGGERHEART,*** *a collaborative fantasy tabletop roleplaying game of incredible magic and heroic, heartfelt adventure.*
Expand Down
19 changes: 0 additions & 19 deletions adversaries/Acid Burrower.md

This file was deleted.

24 changes: 0 additions & 24 deletions adversaries/Adult Flickerfly.md

This file was deleted.

15 changes: 0 additions & 15 deletions adversaries/Apprentice Assassin.md

This file was deleted.

21 changes: 0 additions & 21 deletions adversaries/Arch-Necromancer.md

This file was deleted.

13 changes: 0 additions & 13 deletions adversaries/Archer Guard.md

This file was deleted.

16 changes: 0 additions & 16 deletions adversaries/Archer Squadron.md

This file was deleted.

17 changes: 0 additions & 17 deletions adversaries/Assassin Poisoner.md

This file was deleted.

19 changes: 0 additions & 19 deletions adversaries/Battle Box.md

This file was deleted.

17 changes: 0 additions & 17 deletions adversaries/Bear.md

This file was deleted.

Loading