All user data for FoundryVTT. Includes worlds, systems, modules, and any asset in the "foundryuserdata" directory. Does NOT include the FoundryVTT installation itself.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
3.9 KiB

1 year ago
  1. export class FoWHandler {
  2. constructor() {
  3. this.setHooks();
  4. }
  5. setHooks(){
  6. Hooks.on("drawCanvasVisibility", ()=>{
  7. this.init();
  8. canvas.effects.visibility.explored.addChild(this.advancedFogContainer);
  9. canvas.effects.visibility.explored.addChild(this.revealTokenContainer);
  10. Hooks.callAll("levelsAdvancedFogInit", this.advancedFogContainer);
  11. })
  12. Hooks.on("deleteTile", (tile)=>{
  13. this.removeTileFogMask(tile.id);
  14. })
  15. Hooks.on("createTile", (tile)=>{
  16. this.createTileFogMask(tile.object);
  17. })
  18. Hooks.on("updateTile", (tile)=>{
  19. this.createTileFogMask(tile.object);
  20. })
  21. Hooks.on("deleteToken", (token)=>{
  22. this.removeBubble(token.id);
  23. })
  24. Hooks.on("createToken", (token)=>{
  25. this.createTokenBubble(token.object);
  26. })
  27. Hooks.on("updateToken", (token, updates)=>{
  28. this.createTokenBubble(token.object);
  29. })
  30. }
  31. init() {
  32. this.advancedFogContainer = new PIXI.Container();
  33. this.advancedFogContainer.name = "advancedFogContainer";
  34. this.revealTokenContainer = new PIXI.Container();
  35. this.revealTokenContainer.name = "revealTokenContainer";
  36. this.tiles = {};
  37. this.bubbles = {};
  38. }
  39. createTokenBubble(token) {
  40. if(!token) return;
  41. if(!CONFIG.Levels.settings.get("revealTokenInFog")) return;
  42. if(this.bubbles[token.id]){
  43. this.revealTokenContainer.removeChild(this.bubbles[token.id]);
  44. this.bubbles[token.id].destroy();
  45. delete this.bubbles[token.id];
  46. }
  47. const bubble = new PIXI.Graphics();
  48. bubble.beginFill(0xffffff);
  49. bubble.drawCircle(0, 0, (Math.max(token.w, token.h)/2)*Math.SQRT2);
  50. bubble.endFill();
  51. bubble.token = token;
  52. Object.defineProperty(bubble, "visible", {
  53. get: () => {
  54. return token.visible;
  55. }
  56. });
  57. this.updateBubblePosition(bubble);
  58. this.revealTokenContainer.addChild(bubble);
  59. this.bubbles[token.id] = bubble;
  60. return bubble;
  61. }
  62. lazyCreateBubble(token) {
  63. if(!this.bubbles[token.id]){
  64. this.createTokenBubble(token);
  65. }
  66. if(this.bubbles[token.id]){
  67. this.updateBubblePosition(this.bubbles[token.id]);
  68. }
  69. }
  70. updateBubblePosition(bubble, position) {
  71. position ??= bubble.token.center;
  72. bubble.position.set(position.x, position.y);
  73. }
  74. removeBubble(tokenId) {
  75. if(!this.bubbles[tokenId]) return;
  76. this.revealTokenContainer.removeChild(this.bubbles[tokenId]);
  77. this.bubbles[tokenId].destroy();
  78. delete this.bubbles[tokenId];
  79. }
  80. createTileFogMask(tile) {
  81. if(!tile?.document?.overhead) return false;
  82. if(this.tiles[tile.id]){
  83. this.advancedFogContainer.removeChild(this.tiles[tile.id]);
  84. try{
  85. this.tiles[tile.id].destroy();
  86. }
  87. catch(e){}
  88. delete this.tiles[tile.id];
  89. }
  90. if(!tile?.mesh?.texture) return;
  91. const sprite = CONFIG.Levels.helpers.cloneTileMesh(tile);
  92. Object.defineProperty(sprite, "visible", {
  93. get: () => {
  94. if(!CONFIG.Levels.currentToken) return false;
  95. if(!tile.document.overhead) return false;
  96. if(tile.document.flags?.levels?.noFogHide) return false;
  97. if(!CONFIG.Levels.settings.get("fogHiding")) return false;
  98. const bottom = tile.document.flags?.levels?.rangeBottom ?? -Infinity;
  99. const top = tile.document.flags?.levels?.rangeTop ?? Infinity;
  100. if(bottom == -Infinity && top == Infinity) return false;
  101. const losH = CONFIG.Levels.currentToken.losHeight;
  102. if(losH < bottom || losH > top) return false;
  103. return tile.visible;
  104. }
  105. })
  106. this.tiles[tile.id] = sprite;
  107. this.advancedFogContainer.addChild(sprite);
  108. return sprite;
  109. }
  110. lazyCreateTileFogMask(tile) {
  111. if(!this.tiles[tile.id]){
  112. this.createTileFogMask(tile);
  113. }
  114. }
  115. removeTileFogMask(tileId) {
  116. if(!this.tiles[tileId]) return;
  117. this.advancedFogContainer.removeChild(this.tiles[tileId]);
  118. this.tiles[tileId].destroy();
  119. delete this.tiles[tileId];
  120. }
  121. }