A small add-on module for Foundry VTT which converts wall segments to drawings for quick maps
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.

219 lines
5.9 KiB

  1. /**
  2. * Default wall types (walls can be other combinations of vision/movement restriction too)
  3. * @readonly
  4. * @enum {number}
  5. */
  6. var FOUNDRY_DOOR_TYPES = {
  7. WALL: 0,
  8. TERRAIN: 1,
  9. INVISIBLE: 2,
  10. ETHEREAL: 3,
  11. DOOR: 4,
  12. SECRETDOOR: 5,
  13. OTHER: -1
  14. };
  15. /**
  16. * Determine what default wall type a Wall object matches, if any
  17. * @param {object} wall - the wall to query
  18. * @return {number} wall_type - a member of FOUNDRY_DOOR_TYPES
  19. */
  20. function determineWallType(wall) {
  21. let move = wall.data.move;
  22. let sense = wall.data.sense;
  23. let door = wall.data.door;
  24. if (move === CONST.WALL_MOVEMENT_TYPES.NORMAL
  25. && sense === CONST.WALL_SENSE_TYPES.NORMAL
  26. && door === CONST.WALL_DOOR_TYPES.NONE) {
  27. return FOUNDRY_DOOR_TYPES.WALL; }
  28. else if (move === CONST.WALL_MOVEMENT_TYPES.NORMAL
  29. && sense === CONST.WALL_SENSE_TYPES.LIMITED
  30. && door === CONST.WALL_DOOR_TYPES.NONE) {
  31. return FOUNDRY_DOOR_TYPES.TERRAIN; }
  32. else if (move === CONST.WALL_MOVEMENT_TYPES.NORMAL
  33. && sense === CONST.WALL_SENSE_TYPES.NONE
  34. && door === CONST.WALL_DOOR_TYPES.NONE) {
  35. return FOUNDRY_DOOR_TYPES.INVISIBLE; }
  36. else if (move === CONST.WALL_MOVEMENT_TYPES.NONE
  37. && sense === CONST.WALL_SENSE_TYPES.NORMAL
  38. && door === CONST.WALL_DOOR_TYPES.NONE) {
  39. return FOUNDRY_DOOR_TYPES.ETHEREAL }
  40. else if (move === CONST.WALL_MOVEMENT_TYPES.NORMAL
  41. && sense === CONST.WALL_SENSE_TYPES.NORMAL
  42. && door === CONST.WALL_DOOR_TYPES.DOOR) {
  43. return FOUNDRY_DOOR_TYPES.DOOR; }
  44. else if (move === CONST.WALL_MOVEMENT_TYPES.NORMAL
  45. && sense === CONST.WALL_SENSE_TYPES.NORMAL
  46. && door === CONST.WALL_DOOR_TYPES.SECRET) {
  47. return FOUNDRY_DOOR_TYPES.SECRETDOOR; }
  48. else { return FOUNDRY_DOOR_TYPES.OTHER; }
  49. }
  50. /** @constant {string} */
  51. MODULENAME = "foundry-walls-to-drawing";
  52. /** @constant {string} */
  53. WALLCOLOUR = "#111111";
  54. /** @constant {number} */
  55. WALLWIDTH = "4";
  56. /** @constant {string} */
  57. TERRAINCOLOUR = "#116611";
  58. /** @constant {string} */
  59. INVISIBLECOLOUR = "#006666";
  60. /** @constant {string} */
  61. ETHEREALCOLOUR = "#CC00CC";
  62. /** @constant {string} */
  63. //DOORCOLOUR = "#CC9900";
  64. DOORCOLOUR = "#3333FF";
  65. /** @constant {string} */
  66. SECRETDOORCOLOUR = "#CC0000";
  67. /** constant {string} */
  68. let BLACK = "#000000";
  69. /**
  70. * Set up configuration options
  71. * */
  72. Hooks.on("init", () => {
  73. game.settings.register(MODULENAME, "cvWallColour", {
  74. name: "Converted Wall Colour",
  75. default: WALLCOLOUR,
  76. type: String,
  77. scope: "client",
  78. config: true,
  79. hint: "Enter a hexadecimal colour, eg #FF0000 for red"
  80. });
  81. game.settings.register(MODULENAME, "cvTerrainColour", {
  82. name: "Converted Terrain Wall Colour",
  83. default: TERRAINCOLOUR,
  84. type: String,
  85. scope: "client",
  86. config: true,
  87. hint: "Enter a hexadecimal colour, eg #FF0000 for red"
  88. });
  89. game.settings.register(MODULENAME, "cvInvisibleColour", {
  90. name: "Converted Invisible Wall Colour",
  91. default: INVISIBLECOLOUR,
  92. type: String,
  93. scope: "client",
  94. config: true,
  95. hint: "This only takes effect if rendering invisible walls"
  96. });
  97. game.settings.register(MODULENAME, "cvEtherealColour", {
  98. name: "Converted Ethereal Wall Colour",
  99. default: ETHEREALCOLOUR,
  100. type: String,
  101. scope: "client",
  102. config: true,
  103. hint: "This only takes effect if rendering ethereal walls"
  104. });
  105. game.settings.register(MODULENAME, "cvDoorColour", {
  106. name: "Converted Door Colour",
  107. default: DOORCOLOUR,
  108. type: String,
  109. scope: "client",
  110. config: true,
  111. hint: "This only takes effect if rendering secret doors"
  112. });
  113. game.settings.register(MODULENAME, "cvSecretDoorColour", {
  114. name: "Converted Secret Door Colour",
  115. default: SECRETDOORCOLOUR,
  116. type: String,
  117. scope: "client",
  118. config: true,
  119. hint: "This only takes effect if rendering doors"
  120. });
  121. game.settings.register(MODULENAME, "cvWallWidth", {
  122. name: "Converted Wall Width",
  123. default: WALLWIDTH,
  124. type: Number,
  125. scope: "client",
  126. config: true,
  127. hint: "Enter a decimal width"
  128. });
  129. });
  130. /**
  131. * Add 'Convert to walls' button in Walls Layer Tools
  132. * */
  133. Hooks.on('getSceneControlButtons', controls => {
  134. cvWallColour = game.settings.get(MODULENAME, "cvWallColour");
  135. cvTerrainColour = game.settings.get(MODULENAME, "cvTerrainColour");
  136. cvInvisibleColour = game.settings.get(MODULENAME, "cvInvisibleColour");
  137. cvEtherealColour = game.settings.get(MODULENAME, "cvEtherealColour");
  138. cvDoorColour = game.settings.get(MODULENAME, "cvDoorColour");
  139. cvSecretDoorColour = game.settings.get(MODULENAME, "cvSecretDoorColour");
  140. cvWallWidth = game.settings.get(MODULENAME, "cvWallWidth");
  141. let walls = controls.find(e => e.name === "walls");
  142. walls.tools.push( {
  143. "name": "convert-to-draw",
  144. "icon": "far fa-square",
  145. "title": "Convert selected to Drawing",
  146. "onClick": () => {
  147. cvWalls = [];
  148. var wallRenderColour = BLACK;
  149. canvas.walls.controlled.forEach(function(wall) {
  150. switch(determineWallType(wall)) {
  151. case FOUNDRY_DOOR_TYPES.WALL:
  152. wallRenderColour = cvWallColour;
  153. break;
  154. case FOUNDRY_DOOR_TYPES.TERRAIN:
  155. wallRenderColour = cvTerrainColour;
  156. break;
  157. case FOUNDRY_DOOR_TYPES.INVISIBLE:
  158. wallRenderColour = cvInvisibleColour;
  159. break
  160. case FOUNDRY_DOOR_TYPES.ETHEREAL:
  161. wallRenderColour = cvEtherealColour;
  162. break;
  163. case FOUNDRY_DOOR_TYPES.DOOR:
  164. wallRenderColour = cvDoorColour;
  165. break;
  166. case FOUNDRY_DOOR_TYPES.SECRETDOOR:
  167. wallRenderColour = cvSecretDoorColour;
  168. break;
  169. case FOUNDRY_DOOR_TYPES.OTHER:
  170. wallRenderColour = BLACK;
  171. break
  172. }
  173. cvWalls.push({
  174. type: CONST.DRAWING_TYPES.POLYGON,
  175. author: game.user._id,
  176. x: 0,
  177. y: 0,
  178. height: 100,
  179. strokeWidth: cvWallWidth,
  180. strokeColor: wallRenderColour,
  181. points: [
  182. [wall.coords[0], wall.coords[1]],
  183. [wall.coords[2], wall.coords[3]]
  184. ]
  185. });
  186. });
  187. Drawing.create(cvWalls);
  188. ui.controls.controls.find(e => e.name === "walls").activeTool = "select";
  189. ui.controls.render();
  190. }
  191. });
  192. });