Created
February 11, 2023 16:19
-
-
Save Corgi/10839bf427038afc54793f90dd7f5d3c to your computer and use it in GitHub Desktop.
NPC Generation macro for use with Dungeon World and Foundry VTT (v10)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Instant NPC - v1.5 | |
Source: https://github.com/brunocalado/mestre-digital/tree/master/Foundry%20VTT/Macros/Dungeon%20World | |
Updated for Foundry VTT v10 with help from the FoundryVTT Discord server | |
Requires Names, Knacks, and Instincts RollTables to work | |
Icon: https://raw.githubusercontent.com/brunocalado/mestre-digital/master/Foundry%20VTT/Macros/Dungeon%20World/Instant%20NPC.svg | |
Icon2: icons/environment/people/commoner.webp | |
*/ | |
(async () => { | |
const NPCName = await drawFromTable('Names'); | |
const NPCKnack = await drawFromTable('Knacks'); | |
const NPCInstinct = await drawFromTable('Instincts'); | |
const damageDieRolado = damageDie(); | |
const randomArmorRolado = randomArmor(); | |
let msg = `<h3>Personality</h3>`; | |
msg += `<p><b>Instinct:</b> ${NPCInstinct}</p>`; | |
msg += `<p><b>Knack:</b> ${NPCKnack}</p>`; | |
msg += `<h3>Treasure</h3>`; | |
msg += `<p>${treasureCoins(1,10)} coins.</p>`; | |
let message; | |
let npchp = randomHP(4,10); | |
message = `<h2><b>${NPCName}</b></h2>`; | |
message+=`<p><b>Damage Die:</b> ${damageDieRolado}</p>`; | |
message+=`<p><b>Armor:</b> ${randomArmorRolado}</p>`; | |
message+=msg; | |
addEventListenerOnHtmlElement("#createNPC", 'click', (e) => { | |
createRandomNPC({ | |
name: NPCName, | |
type: "npc", | |
img: "", | |
sort: 12000, | |
data: {}, | |
token: {}, | |
items: [], | |
flags: {}, | |
data: { | |
details: { | |
biography: msg | |
}, | |
attributes: { | |
damage: { | |
value: damageDieRolado | |
}, | |
ac: { | |
value: randomArmorRolado | |
}, | |
hp: { | |
max: npchp, | |
value: npchp | |
} | |
} | |
} | |
}); | |
}); | |
message+=`<button id="createNPC">Create NPC</button>`; | |
let chatData = { | |
user: game.user._id, | |
content: message, | |
whisper : ChatMessage.getWhisperRecipients("GM") | |
}; | |
ChatMessage.create(chatData, {}); | |
})() | |
/* Functions */ | |
async function drawFromTable(tableName){ | |
let id; | |
const pack = game.packs.find(p => { | |
const iid = p.index.getName(tableName)?._id; | |
if(iid) id = iid; | |
return iid; | |
}); | |
if (!id) { | |
ui.notifications.warn(`Table ${tableName} not found.`); | |
return; | |
} | |
const table = await pack.getDocument(id); | |
const draw = await table.draw({displayChat: false}); | |
return draw.results[0].getChatText(); | |
} | |
function treasureCoins(min, max) { | |
return Math.floor(Math.random() * (max - min) ) + min; | |
} | |
function damageDie() { | |
const dice = ['d4', 'd6', 'd8', 'd10', 'd12']; | |
return dice[ Math.floor(Math.random() * (5 - 0) ) + 0 ]; | |
} | |
function randomArmor() { | |
return Math.floor(Math.random() * (3 - 0) ) + 0; | |
} | |
function randomHP(min, max) { | |
return Math.floor(Math.random() * (max - min) ) + min; | |
} | |
function addEventListenerOnHtmlElement(element, event, func){ | |
Hooks.once("renderChatMessage", (chatItem, html) => { // Use Hook to add event to chat message html element | |
html[0].querySelector(element).addEventListener(event, func); | |
}); | |
} // end addEventListenerOnHtmlElement | |
async function createRandomNPC(data) { | |
const instantNPC = await Actor.create(data); | |
await instantNPC.sheet.render(true); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment