foundryvtt-dice-tower/src/ts/dice-tower.ts
2025-03-01 19:26:50 +01:00

188 lines
6.7 KiB
TypeScript

import "../styles/style.scss";
import {moduleId} from "./constants";
import {DiceTower} from "./types";
import {Customization} from "./apps/customization";
import {DiceSocket} from "./apps/diceSocket";
import {getSetting, registerSetting, setSetting} from "./apps/utils";
import {Service} from "./apps/service";
import {Overlays} from "./apps/overlays";
let module: DiceTower;
Hooks.once("init", async () => {
module = (game as Game).modules.get(moduleId) as unknown as DiceTower;
module.log = (message) => console.log(`Dice-Tower | `, message)
module.log("Initialized")
module.customization = new Customization()
module.overlays = new Overlays()
module.diceSocket = new DiceSocket()
module.service = new Service()
registerSettings()
});
Hooks.on("renderChatLog", async (_: Application, _html: JQuery): Promise<void> => {
module.log("Rendering Controls")
module.controls = $(await renderTemplate(`modules/${moduleId}/templates/dice-tower-controls.hbs`, {}))
await renderDiceTowerControls(new Map([
...(new Map(
["d4", "d6", "d8", "d10", "d12", "d20", "d100"]
.map(dice => [`dice-tower-roll-${dice}`, (controls: JQuery) => {
roll(controls.find(`#dice-tower-amount`), dice)
}]))),
...(new Map([
["dice-tower-sheet", (_: JQuery) => {
openSheet()
}],
["dice-tower-customize", (_: JQuery) => {
module.customization.render(true)
}],
["dice-tower-urls", (_: JQuery) => {
module.overlays.render(true)
}],
["dice-tower-remove-dice", (controls: JQuery) => {
removeDice(controls.find("#dice-tower-amount"))
}],
["dice-tower-add-dice", (controls: JQuery) => {
addDice(controls.find("#dice-tower-amount"))
},
]]
))]
));
module.log("Render complete")
});
Hooks.once("ready", () => {
fillActors();
module.service.register()
})
Hooks.on("preCreateChatMessage", (message: ChatMessage): void => {
if (message.isRoll && getSetting("sendToDiceTower") as Boolean) {
let results = []
let command = "";
message.rolls.forEach(roll => {
let sides
let modifier = 0
let modifierMultiplikator = 1
let rolls: {value: number}[] = []
roll.terms.forEach(term => {
if (term instanceof foundry.dice.terms.Die) {
let t = term as foundry.dice.terms.Die;
sides = t.faces
let c = t.number + 'd' + sides;
if (command.length > 0) {
command = [command, c].join(" ")
} else {
command = c
}
t.results.map(it => {
return {value: it.result}
}).forEach(it => rolls.push(it))
}
if (term instanceof foundry.dice.terms.OperatorTerm ) {
let t = term as foundry.dice.terms.OperatorTerm
if (t.operator === '+') {
modifierMultiplikator = 1
} else if (t.operator === '-') {
modifierMultiplikator = -1
}
}
if (term instanceof foundry.dice.terms.NumericTerm) {
let t = term as foundry.dice.terms.NumericTerm
modifier += t.number * modifierMultiplikator
}
});
results.push({
sides: sides,
modifier: modifier,
value: roll.total,
rolls: rolls
})
module.service.roll({
name: message.alias,
command: command,
results: results
})
})
}
})
Hooks.on("updateUser", (_user, _character: {character: string}, _time, _id) => {
fillActors();
})
function registerSettings() {
game.settings?.registerMenu(moduleId, "overlays", {
name: "DICETOWER.overlaysTitle",
label: "DICETOWER.overlaysTitle",
type: Overlays,
icon: "fas fa-link"
})
setSetting("default-dice", {
theme: 'none',
faceColor: '#8d8981',
numberColor: '#000000'
}, true)
registerSetting("sendToDiceTower", false, {scope: "world", config: true})
registerSetting("diceTowerUrl", "https://dice-tower.com", {scope: "world", config: true})
registerSetting("diceTowerRoom", "", {scope: "world", config: true})
}
function openSheet() {
let actorId = module.controls.find('#dice-tower-actor').val();
if (actorId) {
let actor = game.actors?.get(actorId as string);
if (actor) {
Hotbar.toggleDocumentSheet(actor.uuid);
}
}
}
function fillActors() {
let actors = module.controls.find("#dice-tower-actor");
actors.empty()
if (game.user?.character) {
actors.append($(`<option value="${game.user?.character?.id}" selected>${game.user?.character?.name}</option>`));
} else {
actors.append($(`<option value="${game.user?.id}" selected>${game.user?.name}</option>`));
}
if (game.user?.isGM) {
let optionGroups = new Map<string, JQuery>
game.actors?.forEach(e => {
let actor = e as foundry.documents.BaseActor;
if (actor.folder) {
if (!optionGroups.has(actor.folder.uuid)) {
optionGroups.set(actor.folder.uuid, $(`<optgroup label="${actor.folder.name}"></optgroup>`));
}
optionGroups.get(actor.folder.uuid)?.append($(`<option value="${actor.id}">${actor.name}</option>`))
} else {
actors.append($(`<option value="${actor.id}">${actor.name}</option>`))
}
});
optionGroups.forEach(value => actors.append(value))
}
}
async function roll(diceAmount: JQuery, dice: string) {
new Roll(diceAmount.text() + dice).evaluate().then(roll => roll.toMessage({speaker: {actor: module.controls.find('#dice-tower-actor').val() as string}}));
}
async function renderDiceTowerControls(actions: Map<string, (controls: JQuery) => void>) {
actions.forEach((value, key) => {
module.controls.find(`#${key}`).on("click", () => value(module.controls))}
)
module.controls.insertAfter("#chat-controls")
}
function addDice(diceAmount: JQuery) {
let amount = +diceAmount.text()
diceAmount.text(`${amount + 1}`)
}
function removeDice(diceAmount: JQuery) {
let amount = +diceAmount.text()
if (amount > 1) {
diceAmount.text(`${amount - 1}`)
}
}