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.

100 lines
5.3 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. export class LevelsAPI {
  2. /**
  3. * Test if a specified elevation is withing the range of a specified document, bounds are included.
  4. * @param {Document} document - the document to be tested
  5. * @param {Float} elevation - the elevation to test against
  6. * @returns {Boolean} returns wether the elevation is in the range or not
  7. **/
  8. static inRange(document, elevation) {
  9. return CONFIG.Levels.helpers.inRange(document, elevation);
  10. }
  11. /**
  12. * Test if a token's losHeight is contained within the range of the placeable or document.
  13. * @param {Token} token - the token to test
  14. * @param {PlaceableObject|Document} placeableOrDocument - "sight" or "collision" (defaults to "sight")
  15. * @param {boolean} useElevation - if true, use the token's elevation, otherwise use the token's losHeight (the 'eye' elevation)
  16. * @returns {Boolean} returns wether the token is in the range or not
  17. **/
  18. static isTokenInRange(token, placeableOrDocument, useElevation = true) {
  19. if (placeableOrDocument.inTriggeringRange) return placeableOrDocument.inTriggeringRange(token);
  20. placeableOrDocument = placeableOrDocument?.document ?? placeableOrDocument;
  21. const elevation = useElevation ? token.document.elevation : token.losHeight;
  22. return CONFIG.Levels.helpers.inRange(placeableOrDocument, elevation);
  23. }
  24. /**
  25. * Perform a collision test between 2 TOKENS in 3D space
  26. * @param {Token} token1 - a token, the source of the check
  27. * @param {Token} token2 - a token, the target of the check
  28. * @param {String} type - "sight" or "collision" (defaults to "sight")
  29. * @returns {Object|Boolean} returns the collision point if a collision is detected, flase if it's not
  30. **/
  31. static checkCollision(token1, token2, type = "sight") {
  32. return CONFIG.Levels.handlers.SightHandler.checkCollision(token1, token2, type);
  33. }
  34. /**
  35. * Perform a collision test between 2 point in 3D space
  36. * @param {Object} p0 - a point in 3d space {x:x,y:y,z:z} where z is the elevation
  37. * @param {Object} p1 - a point in 3d space {x:x,y:y,z:z} where z is the elevation
  38. * @param {String} type - "sight" or "collision" (defaults to "sight")
  39. * @returns {Object|Boolean} returns the collision point if a collision is detected, flase if it's not
  40. **/
  41. static testCollision(p0, p1, type = "sight") {
  42. return CONFIG.Levels.handlers.SightHandler.testCollision(p0, p1, type);
  43. }
  44. /**
  45. * Rescales grid-related distances of various types of documents in the canvas scene.
  46. * @async
  47. * @param {number} previousDistance - The previous grid distance value.
  48. * @param {number} [currentDistance=canvas.scene?.dimensions?.distance] - The current grid distance value.
  49. * @param {Scene} [scene=canvas.scene] - A Scene Document.
  50. * @returns {Promise<Array<{ documentClass: Function, changed: Array<Object> }>>} - A Promise that resolves to an array of objects, each containing information about the document class and any changes made to its embedded documents.
  51. */
  52. static async rescaleGridDistance(previousDistance, currentDistance = canvas.scene?.dimensions?.distance, scene = canvas.scene) {
  53. const documentClasses = [TileDocument, TokenDocument, AmbientLightDocument, AmbientSoundDocument, NoteDocument, WallDocument, MeasuredTemplateDocument];
  54. const rescaleFactor = currentDistance / previousDistance;
  55. const result = [];
  56. for (const dClass of documentClasses) {
  57. const documentCollection = Array.from(scene[dClass.collectionName]);
  58. const updates = [];
  59. for (const document of documentCollection) {
  60. const updateData = {
  61. _id: document._id,
  62. flags: {
  63. levels: {},
  64. "wall-height": {},
  65. },
  66. };
  67. if (dClass === WallDocument) {
  68. const rangeBottom = document.flags?.["wall-height"]?.bottom;
  69. const rangeTop = document.flags?.["wall-height"]?.top;
  70. if (!isNaN(rangeBottom)) updateData.flags["wall-height"].bottom = rangeBottom * rescaleFactor;
  71. if (!isNaN(rangeTop)) updateData.flags["wall-height"].top = rangeTop * rescaleFactor;
  72. delete updateData.flags.levels;
  73. } else if (dClass === MeasuredTemplateDocument) {
  74. } else if (dClass === TokenDocument) {
  75. const elevation = document.elevation;
  76. if (!isNaN(elevation)) updateData.elevation = elevation * rescaleFactor;
  77. delete updateData.flags;
  78. } else {
  79. const rangeBottom = document.flags?.levels?.rangeBottom;
  80. const rangeTop = document.flags?.levels?.rangeTop;
  81. if (!isNaN(rangeBottom)) updateData.flags.levels.rangeBottom = rangeBottom * rescaleFactor;
  82. if (!isNaN(rangeTop)) updateData.flags.levels.rangeTop = rangeTop * rescaleFactor;
  83. }
  84. updates.push(updateData);
  85. }
  86. const changed = await scene.updateEmbeddedDocuments(dClass.documentName, updates);
  87. result.push({ documentClass: dClass, changed: changed });
  88. }
  89. return result;
  90. }
  91. }