A FoundryVTT module for playing at an in-person table.
at main 85 lines 3.5 kB view raw
1import { socket } from "./socket"; 2 3function makeDialogContent(): string { 4 const users = (game as foundry.Game).users.filter((user: foundry.documents.User): boolean => user.name !== "Gamemaster"); 5 let out = `<table><tr><th>Player Name</th><th>Mobile</th><th>Display</th></tr>`; 6 7 users.forEach((user: foundry.documents.User): void => { 8 out += ` 9 <tr> 10 <td>${user.name}</td> 11 <td><input type="checkbox" name="user-${user.id}-mobile" ${user.getFlag("pf2e-table-mode", "mobile") as boolean ? "checked " : ""}/></td> 12 <td><input type="checkbox" name="user-${user.id}-display" ${user.getFlag("pf2e-table-mode", "display") as boolean ? "checked " : ""}/></td> 13 </tr> 14 `; 15 }); 16 17 out += "</table>"; 18 return out; 19} 20 21export function getOwners(actorId: string): foundry.documents.User[] { 22 return (game as foundry.Game).users.filter((user: foundry.documents.User): boolean => { 23 return user.character?.id === actorId; 24 }); 25} 26 27export function tokenControlCB(event: Event): void { 28 const direction = (event.target as HTMLButtonElement).dataset.direction; 29 const tokens = (game as foundry.Game).user.character.getActiveTokens(); 30 31 if ((direction === null) || (direction === undefined)) return; 32 if (tokens.length === 0) return; 33 34 socket!.executeAsGM("tokenMove", { 35 tokenId: tokens[0].id, 36 direction 37 }); 38} 39 40interface PlayerInfo { 41 id: string; 42 display: boolean; 43 mobile: boolean; 44} 45 46export async function editPlayerModes(): Promise<void> { 47 const data: PlayerInfo[] = await foundry.applications.api.DialogV2.prompt({ 48 window: { 49 title: (game as foundry.Game).i18n!.localize("pf2e-table-mode.editPlayerModes") 50 }, 51 content: makeDialogContent(), 52 ok: { 53 label: (game as foundry.Game).i18n!.localize("pf2e-table-mode.confirm"), 54 callback: (_event: PointerEvent | SubmitEvent, button: HTMLButtonElement, dialog: foundry.applications.api.DialogV2): Promise<PlayerInfo[]> => { 55 const elements = button.form!.elements; 56 57 return new Promise((resolve: (value: PlayerInfo[] | PromiseLike<PlayerInfo[]>) => void, reject: (reason?: any) => void): void => { 58 resolve( 59 (game as foundry.Game).users.filter((user: foundry.documents.User): boolean => user.name !== "Gamemaster").map((user: foundry.documents.User): PlayerInfo => { 60 return { 61 id: user.id, 62 display: (elements.namedItem(`user-${user.id}-display`) as HTMLInputElement).checked, 63 mobile: (elements.namedItem(`user-${user.id}-mobile`) as HTMLInputElement).checked 64 }; 65 }) 66 ); 67 }); 68 } 69 } 70 }); 71 72 data.forEach(async (player: PlayerInfo): Promise<void> => { 73 const user = (game as foundry.Game).users.get(player.id); 74 75 if (user.getFlag("pf2e-table-mode", "mobile") !== player.mobile) { 76 await user.setFlag("pf2e-table-mode", "mobile", player.mobile); 77 } 78 79 if (user.getFlag("pf2e-table-mode", "display") !== player.display) { 80 await user.setFlag("pf2e-table-mode", "display", player.display); 81 } 82 83 console.log(`User data for ${user.name} updated`); 84 }); 85}