taulukko-common-scripts-dnd5ed 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/cache-returns-control.d.ts +12 -0
- package/dist/common/index.d.ts +3 -0
- package/dist/common/module-base.d.ts +8 -0
- package/dist/common/script-helpers/url-fix.d.ts +9 -0
- package/dist/common-module.d.ts +19 -0
- package/dist/index.d.ts +3 -0
- package/dist/module.d.ts +1 -0
- package/dist/sockets/common-socket-test.d.ts +1 -0
- package/dist/sockets/common-socket.d.ts +10 -0
- package/dist/sockets/implementations/common-socket-chatmessage.d.ts +17 -0
- package/dist/sockets/implementations/common-socket-dummy.d.ts +12 -0
- package/dist/sockets/implementations/common-socket-socketlib.d.ts +15 -0
- package/dist/sockets/index.d.ts +4 -0
- package/dist/submodules/dialog-utils/dialog-utils.d.ts +13 -0
- package/dist/submodules/hero-points/hero-points.d.ts +11 -0
- package/dist/submodules/hide-unindentify/hide-unidentify.d.ts +8 -0
- package/dist/submodules/index.d.ts +6 -0
- package/dist/submodules/npc/button.d.ts +8 -0
- package/dist/submodules/npc/index.d.ts +4 -0
- package/dist/submodules/npc/npc-dialog.d.ts +15 -0
- package/dist/submodules/npc/npc-portrait-dialog.d.ts +29 -0
- package/dist/submodules/npc/npc.d.ts +23 -0
- package/dist/submodules/playertools/players-tool.d.ts +7 -0
- package/dist/submodules/region-utils/region-utils.d.ts +10 -0
- package/dist/submodules/sub-module-base.d.ts +3 -0
- package/dist/taulukko-common-scripts-dnd5ed.iife.js +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class CacheReturnControl<K, V> {
|
|
2
|
+
private readonly capacity;
|
|
3
|
+
private readonly _cache;
|
|
4
|
+
private readonly _indexKey;
|
|
5
|
+
private _firstIndex;
|
|
6
|
+
private _nextIndex;
|
|
7
|
+
constructor(capacity?: number);
|
|
8
|
+
add(key: K, value: V): void;
|
|
9
|
+
has(key: K): boolean;
|
|
10
|
+
get(key: K): V;
|
|
11
|
+
private cleanCacheLazy;
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare abstract class ModuleBase {
|
|
2
|
+
#private;
|
|
3
|
+
isReady(): boolean;
|
|
4
|
+
init(): Promise<void>;
|
|
5
|
+
protected abstract initHooks(): void;
|
|
6
|
+
protected abstract waitReady(): Promise<void>;
|
|
7
|
+
whaitFor(test: () => boolean, timeout?: number, sleep?: number): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const FIX_NPCs = false;
|
|
2
|
+
declare const newImgPath = "modules/candlekeep-5ed/images/mobs";
|
|
3
|
+
/**
|
|
4
|
+
* Atualiza a URL base da imagem de todos os NPCs do mundo,
|
|
5
|
+
* mantendo o nome original do arquivo.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} newBaseUrl - A nova base da URL (sem o nome do arquivo).
|
|
8
|
+
* */
|
|
9
|
+
declare function updateNpcImageBaseUrl(newBaseUrl: any): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ModuleBase } from './common/module-base';
|
|
2
|
+
export declare class CommonModule extends ModuleBase {
|
|
3
|
+
#private;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly version: string;
|
|
6
|
+
readonly startVersion: string;
|
|
7
|
+
addInitCommonAssetsChanges(): Promise<void>;
|
|
8
|
+
init(): Promise<void>;
|
|
9
|
+
private loadSubModules;
|
|
10
|
+
protected waitReady(): Promise<void>;
|
|
11
|
+
protected initHooks(): void;
|
|
12
|
+
addReadyCommonAssetsChanges(): Promise<void>;
|
|
13
|
+
registerSetting(key: string, type?: any): Promise<void>;
|
|
14
|
+
setSettings(key: string, value: any): Promise<void>;
|
|
15
|
+
getSettings(key: string): Promise<any>;
|
|
16
|
+
updateVersions(instalatedVersion: string, nextVersionUpdated: string): Promise<void>;
|
|
17
|
+
warnAboutUpdate(previousVersion: string, lastVersion: string): Promise<void>;
|
|
18
|
+
debug(debug: boolean | undefined): boolean;
|
|
19
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/module.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function socketTest(): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const CALLBACK_FUNCTION_EVENT_NAME: string;
|
|
2
|
+
export interface Socket {
|
|
3
|
+
isReady(): boolean;
|
|
4
|
+
executeToGM(eventName: string, ...data: any): Promise<any>;
|
|
5
|
+
executeAsGM(eventName: string, ...data: any): Promise<any>;
|
|
6
|
+
executeForAll(eventName: string, ...data: any): Promise<any>;
|
|
7
|
+
executeIn(eventName: string, users: Array<string>, ...data: any): Promise<any>;
|
|
8
|
+
register(eventName: string, callback: any): Promise<void>;
|
|
9
|
+
isReadyToSendToGM(): boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Socket } from '../common-socket';
|
|
2
|
+
import { SubModuleBase } from '../../submodules/sub-module-base';
|
|
3
|
+
export declare class ChatSocket extends SubModuleBase implements Socket {
|
|
4
|
+
#private;
|
|
5
|
+
protected initHooks(): void;
|
|
6
|
+
protected waitReady(): Promise<undefined>;
|
|
7
|
+
private cleanupRealChatMessage;
|
|
8
|
+
private sendMessage;
|
|
9
|
+
executeToGM(eventName: string, ...data: any): Promise<any>;
|
|
10
|
+
executeForAll(eventName: string, ...data: any): Promise<any>;
|
|
11
|
+
executeIn(eventName: string, users: Array<string>, ...data: any): Promise<any>;
|
|
12
|
+
executeAsGM(eventName: string, ...data: any): Promise<any>;
|
|
13
|
+
isReadyToSendToGM(): boolean;
|
|
14
|
+
register(eventName: string, callback: any): Promise<void>;
|
|
15
|
+
get originalSocket(): any;
|
|
16
|
+
}
|
|
17
|
+
export declare const chatSocketImplementation: Socket;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SubModuleBase } from '../../submodules/sub-module-base';
|
|
2
|
+
import { Socket } from '../common-socket';
|
|
3
|
+
export declare class DummySocket extends SubModuleBase implements Socket {
|
|
4
|
+
protected initHooks(): void;
|
|
5
|
+
protected waitReady(): Promise<void>;
|
|
6
|
+
executeForAll(eventName: string, ...data: any): Promise<any>;
|
|
7
|
+
executeAsGM(eventName: string, ...data: any): Promise<any>;
|
|
8
|
+
executeToGM(eventName: string, ...data: any): Promise<any>;
|
|
9
|
+
executeIn(eventName: string, users: Array<string>, ...data: any): Promise<any>;
|
|
10
|
+
isReadyToSendToGM(): boolean;
|
|
11
|
+
register(eventName: string, callback: any): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Socket } from '../common-socket';
|
|
2
|
+
import { SubModuleBase } from '../../submodules/sub-module-base';
|
|
3
|
+
export declare class SocketLib extends SubModuleBase implements Socket {
|
|
4
|
+
private _socketOriginal;
|
|
5
|
+
private _requirementModules;
|
|
6
|
+
protected initHooks(): void;
|
|
7
|
+
protected waitReady(): Promise<void>;
|
|
8
|
+
executeForAll(eventName: string, ...data: any): Promise<any>;
|
|
9
|
+
executeAsGM(eventName: string, ...data: any): Promise<any>;
|
|
10
|
+
executeToGM(eventName: string, ...data: any): Promise<any>;
|
|
11
|
+
executeIn(eventName: string, users: Array<string>, ...data: any): Promise<any>;
|
|
12
|
+
isReadyToSendToGM(): boolean;
|
|
13
|
+
register(eventName: string, callback: any): Promise<void>;
|
|
14
|
+
get originalSocket(): any;
|
|
15
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Button } from '../npc/button';
|
|
2
|
+
import { SubModuleBase } from '../sub-module-base';
|
|
3
|
+
import { NPC } from '../npc/npc';
|
|
4
|
+
import { NPCDialog } from '../npc/npc-dialog';
|
|
5
|
+
export declare class DialogUtils extends SubModuleBase {
|
|
6
|
+
#private;
|
|
7
|
+
readonly npctype: typeof NPC;
|
|
8
|
+
readonly NPC_DIALOG: NPCDialog;
|
|
9
|
+
protected waitReady(): Promise<void>;
|
|
10
|
+
protected initHooks(): void;
|
|
11
|
+
createButton(action: string, label: string, defaultValue?: boolean, type?: string, callback?: any): Button;
|
|
12
|
+
createDialog(title: string, style?: string, content?: string, buttons?: Array<any>, submit?: Array<any>, left?: undefined | number, top?: undefined | number, width?: number | "auto", height?: number | "auto"): foundry.applications.api.DialogV2;
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SubModuleBase } from '../sub-module-base';
|
|
2
|
+
export declare class HeroPoints extends SubModuleBase {
|
|
3
|
+
#private;
|
|
4
|
+
protected initHooks(): void;
|
|
5
|
+
protected waitReady(): Promise<void>;
|
|
6
|
+
removeAttribute(sheet: Sheet): void;
|
|
7
|
+
addEditButtonsToHeroPoints(parent: HTMLElement): void;
|
|
8
|
+
createDialog(element: HTMLElement): void;
|
|
9
|
+
changeHabilityHonrrorToHeroPoints(sheet: Sheet): void;
|
|
10
|
+
initializeHabilityHero(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SubModuleBase } from '../sub-module-base';
|
|
2
|
+
export declare class HideUnidentify extends SubModuleBase {
|
|
3
|
+
#private;
|
|
4
|
+
protected waitReady(): Promise<void>;
|
|
5
|
+
protected initHooks(): void;
|
|
6
|
+
removeButtonsFromItemContext(item: any, buttons: Array<any>): void;
|
|
7
|
+
removeItemSheetIdentifyInformations(sheet: any, option: any | undefined): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { DialogUtils } from './dialog-utils/dialog-utils';
|
|
2
|
+
export { HeroPoints } from './hero-points/hero-points';
|
|
3
|
+
export { HideUnidentify } from './hide-unindentify/hide-unidentify';
|
|
4
|
+
export { PlayersTools } from './playertools/players-tool';
|
|
5
|
+
export { RegionUtils } from './region-utils/region-utils';
|
|
6
|
+
export { Button, NPC, NPCDialog, NPCPortraitDialog } from './npc';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SubModuleBase } from '../sub-module-base';
|
|
2
|
+
import { NPC } from './npc';
|
|
3
|
+
export declare class NPCDialog extends SubModuleBase {
|
|
4
|
+
#private;
|
|
5
|
+
npcSelected: NPC | any;
|
|
6
|
+
activeNPC: NPC | any;
|
|
7
|
+
npcs: Map<string, NPC>;
|
|
8
|
+
buttonloaded: boolean;
|
|
9
|
+
protected initHooks(): void;
|
|
10
|
+
protected waitReady(): Promise<void>;
|
|
11
|
+
addNPCButtons(controls: any): Promise<void>;
|
|
12
|
+
showNPCChooseDialog(): Promise<void>;
|
|
13
|
+
helpSubmit: string;
|
|
14
|
+
callNPC(npc: NPC): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
interface NPCPortraitOptions {
|
|
2
|
+
imageUrl: string;
|
|
3
|
+
npcName: string;
|
|
4
|
+
dialogText: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Classe customizada para exibir um retrato de NPC com diálogo
|
|
8
|
+
* Funciona como overlay modal sobre o jogo
|
|
9
|
+
*/
|
|
10
|
+
export declare class NPCPortraitDialog extends Application {
|
|
11
|
+
imageUrl: string;
|
|
12
|
+
npcName: string;
|
|
13
|
+
dialogText: string;
|
|
14
|
+
constructor(options?: Partial<NPCPortraitOptions> & any);
|
|
15
|
+
static get defaultOptions(): any;
|
|
16
|
+
get template(): string;
|
|
17
|
+
getData(): Promise<NPCPortraitOptions>;
|
|
18
|
+
activateListeners(html: any): void;
|
|
19
|
+
static renderTalk(data: {
|
|
20
|
+
imageUrl: string;
|
|
21
|
+
npcName: string;
|
|
22
|
+
dialogText: string;
|
|
23
|
+
}): void;
|
|
24
|
+
/**
|
|
25
|
+
* Exibe o diálogo para todos os jogadores
|
|
26
|
+
*/
|
|
27
|
+
showToAllPlayers(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare abstract class NPC {
|
|
2
|
+
readonly name: string;
|
|
3
|
+
readonly imageUrl: string;
|
|
4
|
+
readonly formatSound: string;
|
|
5
|
+
readonly DEFAULT_STYLE: string;
|
|
6
|
+
actor: any;
|
|
7
|
+
groups: Set<string>;
|
|
8
|
+
screens: any[];
|
|
9
|
+
abstract groupToLines: Map<string, string>;
|
|
10
|
+
abstract lines: any;
|
|
11
|
+
constructor(name: string, imageUrl: string, formatSound?: string);
|
|
12
|
+
whaitFor(test: () => boolean, timeout?: number, sleep?: number): Promise<unknown>;
|
|
13
|
+
init(): Promise<void>;
|
|
14
|
+
decrementGroup(): void;
|
|
15
|
+
getAlias(): string;
|
|
16
|
+
createDialog(title: string, content: string, options: Array<any>, submits: Array<any> | null): Promise<void>;
|
|
17
|
+
abstract startScreen(): Promise<void>;
|
|
18
|
+
getListLinesFromGroup(groupsUnordered: any): Promise<any>;
|
|
19
|
+
getCombinations(numbers: Array<number>, separator?: string): Promise<any[]>;
|
|
20
|
+
speak(lineIndex: number): Promise<void>;
|
|
21
|
+
private playSoundWithNoEffect;
|
|
22
|
+
send(removeLastGroup?: boolean): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SubModuleBase } from '../sub-module-base';
|
|
2
|
+
export declare class RegionUtils extends SubModuleBase {
|
|
3
|
+
#private;
|
|
4
|
+
protected initHooks(): void;
|
|
5
|
+
protected waitReady(): Promise<void>;
|
|
6
|
+
sendMessageToChat(senderid: string, message: string): void;
|
|
7
|
+
stop(event: any): void;
|
|
8
|
+
toggleVisibilityRegions(): void;
|
|
9
|
+
registerKeybindings(): void;
|
|
10
|
+
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
`)}),u+=`
|
|
13
13
|
</SELECT>
|
|
14
14
|
</DIV>
|
|
15
|
-
`,i.debug("NPC.createDialog:10",e),i.debug("NPC.createDialog:15:activeNPC.groups:",n.activeNPC.groups),r||(i.debug("NPC.createDialog:20"),r=[c.createButton("send","Enviar",!0,"action",async()=>{i.debug("NPC.createDialog, before creating send:",n.activeNPC.groups),i.debug("NPC.createDialog [10]: Escolhido a opcao enviar");const m=(document.querySelector(`.${l}-actions-buttons SELECT`)||null)?.value;if(m==null){i.error("NPC.createDialog: Erro ao obter a opcao selecionada");return}if(i.debug("NPC.createDialog [20]: depois de selecionar o resultado",m),m===`${l}-random`){const h=n.activeNPC.screens.at(-1);n.activeNPC.screens.push({name:m,callback:n.activeNPC.send,type:h.type}),i.debug("NPC.createDialog, before random send:",n.activeNPC.groups),n.activeNPC.send(!1),i.debug("NPC.createDialog, after random send:",n.activeNPC.groups);return}e.forEach(h=>{h.action==m&&(i.debug("NPC.Enviado a opcao :"+m),n.activeNPC.screens.push({name:m,callback:h.callback,type:h.type}),h.callback(),i.debug("NPC.createDialog, after 3 creating send:",n.activeNPC.groups))})}),c.createButton("back","Voltar",!0,"action",async()=>{i.debug("NPC.screens ao voltar - antes: ",n.activeNPC.screens);const d=n.activeNPC.screens.at(-2),m=n.activeNPC.screens.pop();i.debug("lastScreen:",m),i.debug("screens ao voltar - depois: ",n.activeNPC.screens),m.type=="screen-context"&&n.activeNPC.decrementGroup(),d.callback()}),c.createButton("cancel","Cancelar",!0,"action",async()=>{i.debug("NPC.Cancelado a tela do ",l)})],i.debug("NPC.createDialog:25. Create submits",r),i.debug("NPC.createDialog:30 - depois de criar submits"));const g=(d,m,h,p)=>{};i.debug("NPC.createDialog:40 - antes de criar dialogo"),c.createDialog(t,n.activeNPC.DEFAULT_STYLE,u,r,[g],200,void 0,400),i.debug("NPC.createDialog:50 - depois de criar dialogo")}async getListLinesFromGroup(t){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log"),r=Array.from(t).map(Number).sort((c,i)=>c-i);if(r.length===0&&t.size===0)return new Array;if(r.length===0&&r.push(Number.parseInt(t.get(0),10)),r.length==1)return r;let n=await o.activeNPC.getCombinations(r);return e.debug("groups:",r),e.debug("keys:",n),n}async getCombinations(t,o=";"){const e=a.injectController.resolve("NPCDialog"),r=a.injectController.resolve("Log"),n=new Array;if(t.length==0||t.length==1)return[...t];r.debug("numbers:",t);const c=(i,l)=>{r.debug("generate start:",i,",path",l);let u=t.join(";");if(r.debug("combinationKey:",u),r.debug("groupToLines:",e.activeNPC.groupToLines,"-",typeof u),e.activeNPC.groupToLines.has(u))return r.debug("find, return the combination"),n.push(u),n;r.debug("combinationKey not found:",u);for(let g=i;g<t.length;g++){const d=[...l,t[g]];r.debug("novaCombinacao:",d),u=d.join(";"),n.push(u),c(g+1,d)}};return c(0,[]),n}async speak(t){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log"),r=o.activeNPC.lines[t];e.debug("speak:talk:",r),e.debug("disparando o evento pra todo mundo:"),console.log("[NPC Portrait] Enviando para todos..."),await ChatMessage.create({content:"NPC Portrait Event",whisper:Array.from(game.users?.values()||[]).map(u=>u.id),flags:{"forgotten-realms":{type:"npcDialogOnTalk",payload:{imageUrl:this.imageUrl,npcName:this.name,dialogText:r}}}}),e.debug(" evento disparado pra todo mundo:");const n=t.toString().padStart(3,"0"),c=o.activeNPC.name,i=`modules/forgotten-realms/sounds/npcs/${c}/${n}/${c}${n}.${o.activeNPC.formatSound}`,l=await this.playSoundWithNoEffect(i);e.debug("Retorno do play:",l)}async playSoundWithNoEffect(t){a.injectController.resolve("NPCDialog");const o=a.injectController.resolve("Log");try{const e=await fetch(t,{method:"HEAD"});return e.ok?(foundry.audio.AudioHelper.play({src:t,autoplay:!0},!0),!0):(console.warn(`Arquivo não encontrado: ${t} (${e.status})`),!1)}catch(e){return o.error("Erro ao reproduzir o som:",t,e),!1}}async send(t=!0){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log");o.activeNPC.groups.size===0&&o.activeNPC.groups.add($);const r=await o.activeNPC.getListLinesFromGroup(o.activeNPC.groups);e.debug("NPC.send, before send,list:",r);const n=new Array;for(const u of r){const g=u.toString();if(e.debug("group:",g),!o.activeNPC.groupToLines.has(g)){e.warn(`NPC.send, afterSend:Grupo ${g} não encontrado em groupToLines!`);continue}const d=g.split(";").length+1,m=o.activeNPC.groupToLines.get(g);e.debug("NPC.send, 50,linesForThisGroupConcat:",m,"-size:",d);const h=m.split(";");e.debug("NPC.send, 60,linesForThisGroup:",h),h.forEach(p=>{for(let Q=0;Q<d;Q++)n.push(p)})}e.debug("NPC.send, afterSend,lines:",n);let c=Math.abs(Math.round(Math.random()*n.length));c=c>=n.length?n.length-1:c,e.debug("NPC.send, afterSend,randomIndex:",c);const i=Number.parseInt(n[c],10);e.debug("NPC.send, afterSend,lineIndex:",i),o.activeNPC.speak(i),e.debug("NPC.send, afterSend,activeScreen:",o.activeNPC.screens);const l=o.activeNPC.screens.at(-2);o.activeNPC.screens.pop(),l.callback(),o.activeNPC.groups.delete($),t&&o.activeNPC.decrementGroup(),e.debug("NPC.send, afterSend:",o.activeNPC.groups)}}class E extends Application{imageUrl;npcName;dialogText;constructor(t={}){super(),this.imageUrl=t.imageUrl||"YOUR_IMAGE_URL_HERE",this.npcName=t.npcName||"NPC",this.dialogText=t.dialogText||"Olá, aventureiro..."}static get defaultOptions(){return foundry.utils.mergeObject(Application.defaultOptions,{id:"npc-portrait-dialog",classes:["npc-portrait-app"],title:"",width:600,height:400,resizable:!1,minimizable:!1,popOut:!0})}get template(){return"modules/
|
|
15
|
+
`,i.debug("NPC.createDialog:10",e),i.debug("NPC.createDialog:15:activeNPC.groups:",n.activeNPC.groups),r||(i.debug("NPC.createDialog:20"),r=[c.createButton("send","Enviar",!0,"action",async()=>{i.debug("NPC.createDialog, before creating send:",n.activeNPC.groups),i.debug("NPC.createDialog [10]: Escolhido a opcao enviar");const m=(document.querySelector(`.${l}-actions-buttons SELECT`)||null)?.value;if(m==null){i.error("NPC.createDialog: Erro ao obter a opcao selecionada");return}if(i.debug("NPC.createDialog [20]: depois de selecionar o resultado",m),m===`${l}-random`){const h=n.activeNPC.screens.at(-1);n.activeNPC.screens.push({name:m,callback:n.activeNPC.send,type:h.type}),i.debug("NPC.createDialog, before random send:",n.activeNPC.groups),n.activeNPC.send(!1),i.debug("NPC.createDialog, after random send:",n.activeNPC.groups);return}e.forEach(h=>{h.action==m&&(i.debug("NPC.Enviado a opcao :"+m),n.activeNPC.screens.push({name:m,callback:h.callback,type:h.type}),h.callback(),i.debug("NPC.createDialog, after 3 creating send:",n.activeNPC.groups))})}),c.createButton("back","Voltar",!0,"action",async()=>{i.debug("NPC.screens ao voltar - antes: ",n.activeNPC.screens);const d=n.activeNPC.screens.at(-2),m=n.activeNPC.screens.pop();i.debug("lastScreen:",m),i.debug("screens ao voltar - depois: ",n.activeNPC.screens),m.type=="screen-context"&&n.activeNPC.decrementGroup(),d.callback()}),c.createButton("cancel","Cancelar",!0,"action",async()=>{i.debug("NPC.Cancelado a tela do ",l)})],i.debug("NPC.createDialog:25. Create submits",r),i.debug("NPC.createDialog:30 - depois de criar submits"));const g=(d,m,h,p)=>{};i.debug("NPC.createDialog:40 - antes de criar dialogo"),c.createDialog(t,n.activeNPC.DEFAULT_STYLE,u,r,[g],200,void 0,400),i.debug("NPC.createDialog:50 - depois de criar dialogo")}async getListLinesFromGroup(t){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log"),r=Array.from(t).map(Number).sort((c,i)=>c-i);if(r.length===0&&t.size===0)return new Array;if(r.length===0&&r.push(Number.parseInt(t.get(0),10)),r.length==1)return r;let n=await o.activeNPC.getCombinations(r);return e.debug("groups:",r),e.debug("keys:",n),n}async getCombinations(t,o=";"){const e=a.injectController.resolve("NPCDialog"),r=a.injectController.resolve("Log"),n=new Array;if(t.length==0||t.length==1)return[...t];r.debug("numbers:",t);const c=(i,l)=>{r.debug("generate start:",i,",path",l);let u=t.join(";");if(r.debug("combinationKey:",u),r.debug("groupToLines:",e.activeNPC.groupToLines,"-",typeof u),e.activeNPC.groupToLines.has(u))return r.debug("find, return the combination"),n.push(u),n;r.debug("combinationKey not found:",u);for(let g=i;g<t.length;g++){const d=[...l,t[g]];r.debug("novaCombinacao:",d),u=d.join(";"),n.push(u),c(g+1,d)}};return c(0,[]),n}async speak(t){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log"),r=o.activeNPC.lines[t];e.debug("speak:talk:",r),e.debug("disparando o evento pra todo mundo:"),console.log("[NPC Portrait] Enviando para todos..."),await ChatMessage.create({content:"NPC Portrait Event",whisper:Array.from(game.users?.values()||[]).map(u=>u.id),flags:{"forgotten-realms":{type:"npcDialogOnTalk",payload:{imageUrl:this.imageUrl,npcName:this.name,dialogText:r}}}}),e.debug(" evento disparado pra todo mundo:");const n=t.toString().padStart(3,"0"),c=o.activeNPC.name,i=`modules/forgotten-realms/sounds/npcs/${c}/${n}/${c}${n}.${o.activeNPC.formatSound}`,l=await this.playSoundWithNoEffect(i);e.debug("Retorno do play:",l)}async playSoundWithNoEffect(t){a.injectController.resolve("NPCDialog");const o=a.injectController.resolve("Log");try{const e=await fetch(t,{method:"HEAD"});return e.ok?(foundry.audio.AudioHelper.play({src:t,autoplay:!0},!0),!0):(console.warn(`Arquivo não encontrado: ${t} (${e.status})`),!1)}catch(e){return o.error("Erro ao reproduzir o som:",t,e),!1}}async send(t=!0){const o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("Log");o.activeNPC.groups.size===0&&o.activeNPC.groups.add($);const r=await o.activeNPC.getListLinesFromGroup(o.activeNPC.groups);e.debug("NPC.send, before send,list:",r);const n=new Array;for(const u of r){const g=u.toString();if(e.debug("group:",g),!o.activeNPC.groupToLines.has(g)){e.warn(`NPC.send, afterSend:Grupo ${g} não encontrado em groupToLines!`);continue}const d=g.split(";").length+1,m=o.activeNPC.groupToLines.get(g);e.debug("NPC.send, 50,linesForThisGroupConcat:",m,"-size:",d);const h=m.split(";");e.debug("NPC.send, 60,linesForThisGroup:",h),h.forEach(p=>{for(let Q=0;Q<d;Q++)n.push(p)})}e.debug("NPC.send, afterSend,lines:",n);let c=Math.abs(Math.round(Math.random()*n.length));c=c>=n.length?n.length-1:c,e.debug("NPC.send, afterSend,randomIndex:",c);const i=Number.parseInt(n[c],10);e.debug("NPC.send, afterSend,lineIndex:",i),o.activeNPC.speak(i),e.debug("NPC.send, afterSend,activeScreen:",o.activeNPC.screens);const l=o.activeNPC.screens.at(-2);o.activeNPC.screens.pop(),l.callback(),o.activeNPC.groups.delete($),t&&o.activeNPC.decrementGroup(),e.debug("NPC.send, afterSend:",o.activeNPC.groups)}}class E extends Application{imageUrl;npcName;dialogText;constructor(t={}){super(),this.imageUrl=t.imageUrl||"YOUR_IMAGE_URL_HERE",this.npcName=t.npcName||"NPC",this.dialogText=t.dialogText||"Olá, aventureiro..."}static get defaultOptions(){return foundry.utils.mergeObject(Application.defaultOptions,{id:"npc-portrait-dialog",classes:["npc-portrait-app"],title:"",width:600,height:400,resizable:!1,minimizable:!1,popOut:!0})}get template(){return"modules/common-scripts-dnd5ed/scripts/templates/npc-talk.hbs"}async getData(){return{imageUrl:this.imageUrl,npcName:this.npcName,dialogText:this.dialogText}}activateListeners(t){super.activateListeners(t),t.on("click",".close-button",()=>{this.close()})}static renderTalk(t){new E({imageUrl:t.imageUrl,npcName:t.npcName,dialogText:t.dialogText}).render(!0)}async showToAllPlayers(){if(this.render(!0),game.user?.isGM){const t={type:"showNPCPortrait",data:{imageUrl:this.imageUrl,npcName:this.npcName,dialogText:this.dialogText}};game.socket.emit("module.seu-modulo",t)}}}console.log("npcDialog.ts loaded 10");class ge extends f{npcSelected;activeNPC;npcs=new Map;buttonloaded=!1;#e=!1;initHooks(){Hooks.on("createChatMessage",async t=>{const o=a.injectController.resolve("Log"),e=a.injectController.resolve("NPCDialog"),r=300*1e3;if(await e.whaitFor(()=>a.injectController.has("DialogUtils"),r),!a.injectController.has("DialogUtils")){o.error("Givup chat message ",t," because timeout wiaiting for DialogUtils");return}try{if(o.debug("createChatMessage recebido..."),t.flags?.["common-assets"]?.type==="npcDialogOnTalk"){const n=t.flags["common-assets"].payload;o.debug("[NPC Portrait] Evento recebido dos jogadores:",n),E.renderTalk(n)}}catch(n){o.error("[NPC Portrait] Erro ao processar evento:",n)}}),Hooks.on("getSceneControlButtons",async t=>{const o=a.injectController.resolve("Log"),e=a.injectController.resolve("NPCDialog"),r=300*1e3;if(await e.whaitFor(()=>a.injectController.has("DialogUtils"),r),!a.injectController.has("DialogUtils")){o.error("Givup getSceneControlButtons ",t," because timeout wiaiting for DialogUtils");return}o.debug("On getSceneControlButtons 05...",t,e),await e.addNPCButtons(t),e.#e=!0,o.debug("On getSceneControlButtons...:20")})}async waitReady(){if(await this.whaitFor(()=>this.#e,3e5),!this.#e)throw new Error("Timeout waiting for hooks");Hooks.callAll("onReadyNPCDialog",{})}async addNPCButtons(t){const o=a.injectController.resolve("Log"),e=a.injectController.resolve("NPCDialog");if(!game.user.isGM){o.debug("NPC Buttons off");return}o.debug("Criando botão dos NPCs especiais",t),t.tokens.tools.npcButton={name:"npcButton",title:"NPCs Especiais",icon:"fa-solid fa-web-awesome",button:!0,toggle:!1,onClick:()=>{o.debug("Botão de NPCs especiais pressionado"),console.log("npcDialog",e),e.showNPCChooseDialog(),o.debug("Após abrir janela de NPCs especiais")}},o.debug("Botão de NPC criado")}async showNPCChooseDialog(){const t=a.injectController.resolve("Log"),o=a.injectController.resolve("NPCDialog"),e=a.injectController.resolve("DialogUtils");t.debug("Botão NPCsespecial pressionado, mostrando diálogo...");const r="Escolha um NPC Especial",n=`
|
|
16
16
|
.select-npc { padding: 20px; background: #222; color: #eee; }
|
|
17
17
|
.select-npc button { margin: 5px; padding: 5px 10px; }
|
|
18
18
|
`,c=`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taulukko-common-scripts-dnd5ed",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Taulukko Common Scripts for Foundry dnd5ed",
|
|
5
5
|
"main": "dist/taulukko-common-scripts-dnd5ed.iife.js",
|
|
6
6
|
"scripts": {
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
"build": "tsc && vite build",
|
|
9
9
|
"vite-version": "vite --version"
|
|
10
10
|
},
|
|
11
|
-
"keywords": [
|
|
11
|
+
"keywords": [
|
|
12
|
+
"foundry",
|
|
13
|
+
"dnd5e",
|
|
14
|
+
"common-scripts",
|
|
15
|
+
"utilities"
|
|
16
|
+
],
|
|
12
17
|
"types": "./dist/index.d.ts",
|
|
13
18
|
"files": [
|
|
14
19
|
"dist/**/*"
|
|
@@ -20,6 +25,7 @@
|
|
|
20
25
|
"vite": "^7.3.0"
|
|
21
26
|
},
|
|
22
27
|
"dependencies": {
|
|
23
|
-
"taulukko-commons": "^1.3.0"
|
|
28
|
+
"taulukko-commons": "^1.3.0",
|
|
29
|
+
"vite-plugin-dts": "^4.5.4"
|
|
24
30
|
}
|
|
25
31
|
}
|