diff --git a/packs/entanglements-journals.db b/packs/entanglements-journals.db new file mode 100644 index 0000000..e152e95 --- /dev/null +++ b/packs/entanglements-journals.db @@ -0,0 +1,13 @@ +{"name":"The Usual Suspects","content":"
The Bluecoats grab someone in the periphery of your crew. One player volunteers a friend or vice purveyor as the person most likely to be taken. Make a fortune roll to find out if they resist questioning (1-3: +2 heat, 4/5: level 2 harm), or pay the Bluecoats off with 1 coin.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.Ok0pqerQgc5LjU5a"}},"_id":"13D84fBFJ1CCknl8"} +{"name":"Arrest","content":"An Inspector presents a case file of evidence to a magistrate, to begin prosecution of your crew. The Bluecoats send a detail to arrest you (a gang at least equal in scale to your wanted level). Pay them off with coin equal to your wanted level +3, hand someone over for arrest (this clears your heat), or try to evade capture.
\nA truncheon bangs on the shutters of the window. “Alright then! Come on out and let’s go quietly now!” It sounds like Sergeant Klellan. When you peek out, you see a detail of about twenty Bluecoats, all geared up for a fight. Klellan mumbles under his breath, so only you inside can hear: “Or perhaps I have the wrong address?” He clears his throat and waits for some coin to appear.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.WRuCjNaFeQAugpvY"}},"_id":"36o0ggbWhnUXu7Cy"} +{"name":"Rivals","content":"A neutral faction throws their weight around. They threaten you, a friend, a contact, or one of your vice purveyors. Forfeit (1 rep or 1 coin) per Tier of the rival, or stand up to them and lose 1 status with them.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.HLCamOpbBCJNRYLG"}},"_id":"ADi9NxzmVOAueO2n"} +{"name":"Demonic Notice","content":"A demon approaches the crew with a dark offer. Accept their bargain, hide until it loses interest (forfeit 3 rep), or deal with it another way.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.cxGl35wCdByk8N9x"}},"_id":"BJLd501vCFsJlrCN"} +{"name":"Cooperation","content":"A +3 status faction asks you for a favor. Agree to do it, or forfeit 1 rep per Tier of the friendly faction, or lose 1 status with them. If you don’t have a +3 faction status, you avoid entanglements right now.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.xoz34R22ATadDztX"}},"_id":"Cy31qmwfzifm7DaZ"} +{"name":"Interrogation","content":"The Bluecoats round up one of the PCs to question them about the crew’s crimes. How did they manage to capture you? Either pay them off with 3 coin, or they beat you up (level 2 harm) and you tell them what they want to know (+3 heat). You can resist each of those consequences separately.
\nSome players really hate it when their character gets captured! Just tell them that this is completely normal for a scoundrel of the underworld. You spend time in and out of jail, getting questioned and harassed by the law. It’s not the end of the world. But now that you’re here in the interrogation room, what kind of person are you? Do you talk? Do you stand up to them? Do you make a deal?
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.WtDjTgpX82BdQPJB"}},"_id":"F6TG2C6iSdJohpAI"} +{"name":"Show of Force","content":"A faction with whom you have a negative status makes a play against your holdings. Give them 1 claim or go to war (drop to -3 status). If you have no claims, lose 1 hold instead.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.nagSQyGbXzCv9bCw"}},"_id":"IJ5YyHTcpymRhkLQ"} +{"name":"Flipped","content":"One of the PCs’ rivals arranges for one of your contacts, patrons, clients, or a group of your customers to switch allegiances due to the heat on you. They’re loyal to another faction now.
\nYou hear word on the street that Laroze is working for the Billhooks now. He was seen talking to Flint the other day... that bastard is probably behind it. Remove Laroze as a contact until you can get that sorted out.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.CXvqaOROYyqpWZpK"}},"_id":"NoLY64zJ3lEF5Xia"} +{"name":"Unquiet Dead","content":"A rogue spirit is drawn to you—perhaps it’s a past victim? Acquire the services of a Whisper or Rail Jack to attempt to destroy or banish it, or deal with it yourself.
\nThey can hire an NPC by using the acquire asset downtime activity (see page 153). Roll the NPC’s quality level as a fortune roll to see how well they deal with the spirit.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.K1wg10vMiU0bOSsb"}},"_id":"dR9zBnrjy4AyA9Ru"} +{"_id":"pEpm365I7XjEXeci","name":"Gang Trouble","content":"One of your gangs (or other cohorts) causes trouble due to their flaw(s). You can lose face (forfeit rep equal to your Tier +1), make an example of one of the gang members, or face reprisals from the wronged party.
\nAfter the PCs succeed at their assault and wipe out the Red Sashes, their savage gang takes things too far. They start attacking any Iruvians they see in Crow’s Foot, and during one brawl, they horribly maim a citizen. Everyone’s talking about it. Is this how the Bloodletters run their crew? Arcy decides to handle matters by making an example of one of the gang. She takes them back to the tavern where the incident happened, and smashes the offending thug’s face into the bar, giving her a horrific scar.
\nThe GM thinks this treatment warrants a tick on a progress clock they created in an earlier session when Arcy treated the gang roughly. The clock is called “The Gang Fights Back.” It was already at three out of four segments, so now it’s full! Looks like Arcy’s rough treatment of the savage gang is gonna come back to bite her.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.FZyfk6PnXl8pDltO"}}} +{"name":"Reprisals","content":"An enemy faction makes a move against you (or a friend, contact, or vice purveyor). Pay them (1 rep and 1 coin) per Tier of the enemy as an apology, allow them to mess with you or yours, or fight back and show them who’s boss.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.q0txK7pUnzstXrUy"}},"_id":"wVkkWR1jl10k7aeu"} +{"name":"Questioning","content":"The Bluecoats grab an NPC member of your crew or one of the crew’s contacts, to question them about your crimes. Who do the Bluecoats think is most vulnerable? Make a fortune roll to see how much they talk (1-3: +2 heat, 4/5: +1 heat), or pay the Bluecoats off with 2 coin.
\nRoll 2d for a normal person to see how well they keep quiet. If they’re an experienced underworld type or some kind of tough, give them 3d or 4d instead. If they’re soft or if they have some loyalty to the law, give them 1d or 0d.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.XNuIDt1MjPKwISTW"}},"_id":"whBkmsxokUuJ4t9J"} +{"_id":"IJ5YyHTcpymRhkLQ","name":"Show of Force","content":"A faction with whom you have a negative status makes a play against your holdings. Give them 1 claim or go to war (drop to -3 status). If you have no claims, lose 1 hold instead.
","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"JournalEntry.nagSQyGbXzCv9bCw"}}} diff --git a/packs/entanglements-macro.db b/packs/entanglements-macro.db new file mode 100644 index 0000000..2d8bce4 --- /dev/null +++ b/packs/entanglements-macro.db @@ -0,0 +1,2 @@ +{"name":"Entanglement Generator","type":"script","author":"thWDvNEhl7M3mC2d","img":"icons/magic/nature/root-vines-entwined-leaves.webp","scope":"global","command":"const tableHeatA = 'Entanglements - Heat 0-3'; // Entanglements - Heat 0-3\nconst tableHeatB = 'Entanglements - Heat 4/5'; // Entanglements - Heat 4/5\nconst tableHeatC = 'Entanglements - Heat 6+'; // Entanglements - Heat 6+\nconst compendiumTables = 'Entanglements'; // Compendium name \nconst version = '1.1';\nmain();\n\n/*\nTODO\n- replace text by journal\n\nsource: https://raw.githubusercontent.com/brunocalado/mestre-digital/master/Foundry%20VTT/Macros/Forged%20in%20the%20Dark/bid-entanglement.js\nicon: icons/magic/nature/root-vines-entwined-leaves.webp\n*/\n \nasync function main() {\n \n playersNames = game.actors.contents.filter((t) => t.data.type === \"crew\").map((p=> p.data.name)); \n\n let playerNameList;\n\n playersNames.map((el) => { \n playerNameList += ``; \n }); \n \n new Dialog({\n title: `Entanglement - v${version}`,\n content: `\nCrew:
\n\n Whisper?\n
\n `,\n buttons: {\n roll: {\n label: \"Change\",\n callback: (html) => {\n createImageFolder(html);\n }\n }, \n cancel: {\n label: \"Cancel\"\n }\n }\n }).render(true)\n}\n\nasync function createImageFolder(html) {\n let playerName = html.find(\"#playerName\")[0].value;\n let whisper = html.find(\"#whisper\")[0].checked;\n\n let crew = game.actors.getName(playerName).data.data;\n let crewHeat = parseInt(crew.heat);\n let crewWanted = parseInt(crew.wanted);\n\n let entanglementToUse = '';\n\n switch (crewHeat) {\n case 0:\n case 1:\n case 2:\n case 3:\n entanglementToUse = await drawFromTable(tableHeatA, compendiumTables) \n break\n case 4:\n case 5:\n entanglementToUse = await drawFromTable(tableHeatB, compendiumTables) \n break\n case 6:\n case 7:\n case 8:\n case 9:\n entanglementToUse = await drawFromTable(tableHeatC, compendiumTables) \n }\n\n let rollFormula = `${crewWanted}d6`;\n if (rollFormula === \"0d6\") {\n rollFormula = \"2d6kl1\";\n }\n\n entanglementToUse.data.formula = rollFormula;\n \n if (whisper) {\n entanglementToUse.draw({rollMode: 'gmroll'});\n } else {\n entanglementToUse.draw();\n } \n}\n\nasync function drawFromTable(tableName, compendiumName) {\n let list_compendium = await game.packs.filter(p=>p.documentName=='RollTable'); \n let inside = await list_compendium.filter( p=>p.metadata.label==compendiumName )[0].getDocuments(); \n let table = await inside.filter( p=>p.data['name']==tableName )[0];\n \n if (!table) {\n ui.notifications.warn(`Table ${tableName} not found.`, {});\n return;\n }\n //return await table.draw({rollMode: 'gmroll'});\n return await table;\n}","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"Macro.nlsTrxhKZxLIqHWD"}},"_id":"eYp9UHgPlQihAOXV"} +{"_id":"eYp9UHgPlQihAOXV","name":"Entanglement Generator","type":"script","author":"thWDvNEhl7M3mC2d","img":"icons/magic/nature/root-vines-entwined-leaves.webp","scope":"global","command":"const tableHeatA = 'Entanglements - Heat 0-3'; // Entanglements - Heat 0-3\nconst tableHeatB = 'Entanglements - Heat 4/5'; // Entanglements - Heat 4/5\nconst tableHeatC = 'Entanglements - Heat 6+'; // Entanglements - Heat 6+\nconst compendiumTables = 'Entanglements'; // Compendium name \nconst version = '1.1';\nmain();\n\n/*\nTODO\n- replace text by journal\n\nsource: https://raw.githubusercontent.com/brunocalado/mestre-digital/master/Foundry%20VTT/Macros/Forged%20in%20the%20Dark/bid-entanglement.js\ncontributors: brunocalado, LebombJames\nicon: icons/magic/nature/root-vines-entwined-leaves.webp\n*/\n \nasync function main() {\n \n playersNames = game.actors.contents.filter((t) => t.data.type === \"crew\").map((p=> p.data.name)); \n\n let playerNameList;\n\n playersNames.map((el) => { \n playerNameList += ``; \n }); \n \n new Dialog({\n title: `Entanglement - v${version}`,\n content: `\nCrew:
\n\n Whisper?\n
\n `,\n buttons: {\n roll: {\n label: \"Change\",\n callback: (html) => {\n createImageFolder(html);\n }\n }, \n cancel: {\n label: \"Cancel\"\n }\n }\n }).render(true)\n}\n\nasync function createImageFolder(html) {\n let playerName = html.find(\"#playerName\")[0].value;\n let whisper = html.find(\"#whisper\")[0].checked;\n\n let crew = game.actors.getName(playerName).data.data;\n let crewHeat = parseInt(crew.heat);\n let crewWanted = parseInt(crew.wanted);\n\n let entanglementToUse = '';\n\n switch (crewHeat) {\n case 0:\n case 1:\n case 2:\n case 3:\n entanglementToUse = await drawFromTable(tableHeatA, compendiumTables) \n break\n case 4:\n case 5:\n entanglementToUse = await drawFromTable(tableHeatB, compendiumTables) \n break\n case 6:\n case 7:\n case 8:\n case 9:\n entanglementToUse = await drawFromTable(tableHeatC, compendiumTables) \n }\n\n let rollFormula = `${crewWanted}d6`;\n if (rollFormula === \"0d6\") {\n rollFormula = \"2d6kl1\";\n }\n\n entanglementToUse.data.formula = rollFormula;\n \n if (whisper) {\n entanglementToUse.draw({rollMode: 'gmroll'});\n } else {\n entanglementToUse.draw();\n } \n}\n\nasync function drawFromTable(tableName, compendiumName) {\n let list_compendium = await game.packs.filter(p=>p.documentName=='RollTable'); \n let inside = await list_compendium.filter( p=>p.metadata.label==compendiumName )[0].getDocuments(); \n let table = await inside.filter( p=>p.data['name']==tableName )[0];\n \n if (!table) {\n ui.notifications.warn(`Table ${tableName} not found.`, {});\n return;\n }\n //return await table.draw({rollMode: 'gmroll'});\n return await table;\n}","folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{"core":{"sourceId":"Macro.nlsTrxhKZxLIqHWD"}}} diff --git a/packs/entanglements.db b/packs/entanglements.db new file mode 100644 index 0000000..f551cf1 --- /dev/null +++ b/packs/entanglements.db @@ -0,0 +1,3 @@ +{"_id":"GN4cmCUN0g3Cw0N2","name":"Entanglements - Heat 0-3","img":"icons/svg/d20-grey.svg","description":"If there are two results, the GM picks which entanglement occurs.","results":[{"_id":"rxxo3lyIO1fWbupj","type":2,"text":"Gang Trouble","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"pEpm365I7XjEXeci","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3},{"_id":"qWv3spxb5s2igoqr","type":2,"text":"Rivals","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"ADi9NxzmVOAueO2n","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"uAEhqtwDFlWNl5sn","type":2,"text":"Unquiet Dead","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"dR9zBnrjy4AyA9Ru","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"ygK5tDdYcf27W3vi","type":2,"text":"Cooperation","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"Cy31qmwfzifm7DaZ","weight":1,"range":[6,6],"drawn":false,"flags":{},"rangeL":6,"rangeH":6},{"_id":"LcLCcUid3yGLg9eo","type":2,"text":"The Usual Suspects","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"13D84fBFJ1CCknl8","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3}],"formula":"2d6kl1","replacement":true,"displayRoll":true,"folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{}} +{"_id":"eowbxs5eKh3gLvNL","name":"Entanglements - Heat 4/5","img":"icons/svg/d20-grey.svg","description":"If there are two results, the GM picks which entanglement occurs.","results":[{"_id":"NKRR2K1o5Tf6yD4y","type":2,"text":"Gang Trouble","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"pEpm365I7XjEXeci","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3},{"_id":"jVJhLukc03j1ZNfd","type":2,"text":"Questioning","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"whBkmsxokUuJ4t9J","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3},{"_id":"X4NGscT3YYGSCwRg","type":2,"text":"Reprisals","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"wVkkWR1jl10k7aeu","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"QdubcvnYmWmHQH3r","type":2,"text":"Unquiet Dead","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"dR9zBnrjy4AyA9Ru","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"SP3PKp1VkbWbC8pv","type":2,"text":"Show of Force","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"IJ5YyHTcpymRhkLQ","weight":1,"range":[6,6],"drawn":false,"flags":{},"rangeL":6,"rangeH":6}],"formula":"2d6kl1","replacement":true,"displayRoll":true,"folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{}} +{"_id":"ijv20pxjOg36JncA","name":"Entanglements - Heat 6+","img":"icons/svg/d20-grey.svg","description":"If there are two results, the GM picks which entanglement occurs.","results":[{"_id":"MDwUXspRtpZtqFuQ","type":2,"text":"Flipped","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"NoLY64zJ3lEF5Xia","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3},{"_id":"vQck9soiQPlrriGS","type":2,"text":"Interrogation","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"F6TG2C6iSdJohpAI","weight":1,"range":[1,3],"drawn":false,"flags":{},"rangeL":1,"rangeH":3},{"_id":"FPxNPRaG0r98QtMv","type":2,"text":"Demonic Notice","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"BJLd501vCFsJlrCN","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"lkevhpV9bsbyblst","type":2,"text":"Show of Force","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"IJ5YyHTcpymRhkLQ","weight":1,"range":[4,5],"drawn":false,"flags":{},"rangeL":4,"rangeH":5},{"_id":"dKitTISAtsy2MGSw","type":2,"text":"Arrest","img":"icons/svg/d20-black.svg","collection":"world.entanglements-journals","resultId":"36o0ggbWhnUXu7Cy","weight":1,"range":[6,6],"drawn":false,"flags":{},"rangeL":6,"rangeH":6}],"formula":"2d6kl1","replacement":true,"displayRoll":true,"folder":null,"sort":0,"permission":{"default":0,"thWDvNEhl7M3mC2d":3},"flags":{}} diff --git a/system.json b/system.json index 91e6d3e..4df3f61 100644 --- a/system.json +++ b/system.json @@ -132,6 +132,27 @@ "system": "blades-in-the-dark", "path": "./packs/npcs.db", "entity": "Actor" + }, + { + "name": "entanglements", + "label": "Entanglements", + "system": "blades-in-the-dark", + "path": "./packs/entanglements.db", + "entity": "RollTable" + }, + { + "name": "entanglements-journals", + "label": "Entanglements Journals", + "system": "blades-in-the-dark", + "path": "./packs/entanglements-journals.db", + "entity": "JournalEntry" + }, + { + "name": "entanglements-macro", + "label": "Entanglements Macro", + "system": "blades-in-the-dark", + "path": "./packs/entanglements-macro.db", + "entity": "Macro" } ] }