diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..e96a49b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "use-tabs": true, + "single-quote": true, + "quote-props": "consistent", + "print-width": 140, + "semi": true +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a49525c..ffd6367 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.13 + +- Removed the dice rolling features. I moved them (in an improved way) into my new module Mars 5e + # v0.12.3 - *FIX* fixes error when throwing private/Gm rolls diff --git a/dist/module.json b/dist/module.json index 82bad37..1e7cd8c 100644 --- a/dist/module.json +++ b/dist/module.json @@ -2,7 +2,7 @@ "name": "mess", "title": "Mess - Moerills enhancing super-suit(e)", "description": "This module is a mix of QoL changes, enhancements for my game and stuff i play around with. For a complete feature list check the URL down below.", - "version": "0.12.3", + "version": "0.13.0", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.9", "author": "Moerill", @@ -33,5 +33,5 @@ ], "manifest": "https://raw.githubusercontent.com/Moerill/mess/master/src/module.json", "url": "https://github.com/Moerill/mess", - "download": "https://github.com/Moerill/mess/releases/download/v0.12.3/mess.zip" + "download": "https://github.com/Moerill/mess/releases/download/v0.13.0/mess.zip" } \ No newline at end of file diff --git a/dist/scripts/index.js b/dist/scripts/index.js index c5cc8df..251a9df 100644 --- a/dist/scripts/index.js +++ b/dist/scripts/index.js @@ -1,66 +1,30 @@ -!function(e){function t(t){for(var a,n,r=t[0],i=t[1],o=0,c=[];o{const t=e.closest(".tab").dataset.tab,s=document.createElement("a");s.innerHTML='',s.classList.add("mess-sort-btn"),s.title=`Sort ${t} alphabetically.`,s.style.flex=0,s.style.margin="0 5px 0 0",s.addEventListener("click",e=>async function(e,t){const a=await fromUuid("Actor."+t);let s=e.map(e=>e.items||e.spells).flat();s.sort((function(e,t){return e.namet.name?1:0}));let n=[s.shift()],r=[];for(;s.length>0;n.push(s.shift()))r=SortingHelpers.performIntegerSort(s[0],{target:n[n.length-1],siblings:duplicate(n),sortBefore:!1});const i=r.map(e=>{let t=e.update;return t._id=e.target._id,t});a.updateEmbeddedEntity("OwnedItem",i)}(a[t],a.actor._id)),e.prepend(s)})}async function n(){Hooks.on("renderActorSheet",(e,t,a)=>{s(0,t[0],a)})}a.r(t),a.d(t,"default",(function(){return n}))},"./src/scripts/add-scrolling.js": +/*! exports provided: default */function(t,e,s){"use strict";async function a(t,e,s){if(!s.actor._id)return;e.querySelectorAll(".filter-list").forEach(t=>{const e=t.closest(".tab").dataset.tab,a=document.createElement("a");a.innerHTML='',a.classList.add("mess-sort-btn"),a.title=`Sort ${e} alphabetically.`,a.style.flex=0,a.style.margin="0 5px 0 0",a.addEventListener("click",t=>async function(t,e){const s=await fromUuid("Actor."+e);let a=t.map(t=>t.items||t.spells).flat();a.sort((function(t,e){return t.namee.name?1:0}));let n=[a.shift()],r=[];for(;a.length>0;n.push(a.shift()))r=SortingHelpers.performIntegerSort(a[0],{target:n[n.length-1],siblings:duplicate(n),sortBefore:!1});const i=r.map(t=>{let e=t.update;return e._id=t.target._id,e});s.updateEmbeddedEntity("OwnedItem",i)}(s[e],s.actor._id)),t.prepend(a)})}async function n(){Hooks.on("renderActorSheet",(t,e,s)=>{a(0,e[0],s)})}s.r(e),s.d(e,"default",(function(){return n}))},"./src/scripts/add-scrolling.js": /*!**************************************!*\ !*** ./src/scripts/add-scrolling.js ***! \**************************************/ -/*! exports provided: default */function(e,t,a){"use strict";async function s(){Hooks.on("renderActorSheet",(async function(e,t,a){t[0].querySelectorAll('input[data-dtype="Number"], .item-uses input').forEach(e=>{e.addEventListener("wheel",e=>{e.preventDefault(),e.stopPropagation(),e.deltaY<0&&(e.currentTarget.value=Number(e.currentTarget.value)+1),e.deltaY>0&&(e.currentTarget.value=Math.max(Number(e.currentTarget.value)-1,0)),$(e.currentTarget).change()})})}))}a.r(t),a.d(t,"default",(function(){return s}))},"./src/scripts/change-placeables.js": +/*! exports provided: default */function(t,e,s){"use strict";async function a(){Hooks.on("renderActorSheet",(async function(t,e,s){e[0].querySelectorAll('input[data-dtype="Number"], .item-uses input').forEach(t=>{t.addEventListener("wheel",t=>{t.preventDefault(),t.stopPropagation(),t.deltaY<0&&(t.currentTarget.value=Number(t.currentTarget.value)+1),t.deltaY>0&&(t.currentTarget.value=Math.max(Number(t.currentTarget.value)-1,0)),$(t.currentTarget).change()})})}))}s.r(e),s.d(e,"default",(function(){return a}))},"./src/scripts/change-placeables.js": /*!******************************************!*\ !*** ./src/scripts/change-placeables.js ***! \******************************************/ -/*! exports provided: changePlaceables */function(e,t,a){"use strict";function s(e){const{clones:t,destination:a,origin:s,originalEvent:n}=e.data;canvas._onDragCanvasPan(n);const r=a.x-s.x,i=a.y-s.y;let o=!1;if(e.data.previous){const t=30,s=.8,n=e.data.previous,r=e.data.momentum||0,i=e.data.v||{x:0,y:0},l={x:a.x-n.x,y:a.y-n.y},c={x:l.x-i.x,y:l.y-i.y};e.data.momentum=c.x*c.x+c.y*c.y+r*s,o=!e.shiftKey&&e.data.momentum{document.getElementById("chat").classList.contains("active")||(console.log("rendering chat message"),console.log(e,t,a),console.log(document.getElementById("chat").classList.contains("active")))});document.getElementById("hud").appendChild(document.createElement("div")).classList.add("mess-chat-popup")}a.r(t),a.d(t,"initChatPopUp",(function(){return s}))},"./src/scripts/draggable-lists/draggable-list.js": -/*!*******************************************************!*\ - !*** ./src/scripts/draggable-lists/draggable-list.js ***! - \*******************************************************/ -/*! exports provided: DraggableList */function(e,t,a){"use strict";a.r(t),a.d(t,"DraggableList",(function(){return s}));class s{constructor(e,t,a={}){this.container=e,this.selector=t,this.options=mergeObject(this.defaultOptions,a),this._init()}get defaultOptions(){return{offset:21,time:.2,dir:null,onDragStart:null,onDragEnd:null,onDrop:null}}async _init(){this._items=Array.from(this.container.querySelectorAll(this.selector)),this.container.addEventListener("dragleave",e=>{const t=this.container.getBoundingClientRect();!e.insideChild&&e.clientYt.y+5&&e.clientX>t.x+5&&e.clientX{}),this._items.forEach((e,t)=>this._initItem(e,t))}async _initItem(e,t){e.style.position="relative",e.addEventListener("dragenter",e=>this._onDragEnterItem(e,t)),e.addEventListener("dragleave",e=>this._onDragLeaveItem(e,t)),e.addEventListener("dragend",e=>{this._resetOffsets()})}_onDragEnterItem(e,t){console.time("dragEnter"),e.stopPropagation();const a=this.options.time,s=this.options.offset;this._resetOffsets();let n=e.currentTarget;if(console.log(e.currentTarget),n.matches(this.options.dir)){const t=Array.from(n.querySelectorAll(this.selector)),s=n.getBoundingClientRect();if(e.clientY>s.top&&e.clientYe.clientY){n=a;break}}}return this._over=n,console.log(n,s),TweenLite.to(n,a,{paddingTop:s}),console.timeEnd("dragEnter"),!1}_onDragLeaveItem(e,t){return e.stopPropagation(),!1}_resetOffsets(e=this.options.time){TweenLite.to(this._items,e,{paddingTop:0})}}},"./src/scripts/draggable-lists/index.js": -/*!**********************************************!*\ - !*** ./src/scripts/draggable-lists/index.js ***! - \**********************************************/ -/*! exports provided: initDraggableLists */function(e,t,a){"use strict";a.r(t),a.d(t,"initDraggableLists",(function(){return n}));var s=a(/*! ./draggable-list */"./src/scripts/draggable-lists/draggable-list.js");function n(){const e=SidebarDirectory.prototype.activateListeners;SidebarDirectory.prototype.activateListeners=function(t){const a=t[0].querySelector(".directory-list");new s.DraggableList(a,".entity, .folder",{dir:".folder"}),e.call(this,t)},Hooks.on("renderActorSheet",(e,t,a)=>{t[0].querySelectorAll(".item-list").forEach(e=>new s.DraggableList(e,".item"))}),SceneDirectory.prototype._onLazyLoadImage=function(e,t){for(let a of e){if(!a.isIntersecting)continue;const e=a.target;e.dataset.backgroundImage&&(e.children[0].style["background-image"]=`url("${e.dataset.backgroundImage}")`,delete e.dataset.backgroundImage);const s=e.querySelector("img");s&&s.dataset.src&&(s.src=s.dataset.src,delete s.dataset.src),t.unobserve(a.target)}}}},"./src/scripts/index.js": +/*! exports provided: changePlaceables */function(t,e,s){"use strict";function a(t){const{clones:e,destination:s,origin:a,originalEvent:n}=t.data;canvas._onDragCanvasPan(n);const r=s.x-a.x,i=s.y-a.y;let o=!1;if(t.data.previous){const e=30,a=.8,n=t.data.previous,r=t.data.momentum||0,i=t.data.v||{x:0,y:0},l={x:s.x-n.x,y:s.y-n.y},c={x:l.x-i.x,y:l.y-i.y};t.data.momentum=c.x*c.x+c.y*c.y+r*a,o=!t.shiftKey&&t.data.momentum Ray.fromAngle(0, 0, direction + toRadians(a), distance+1));\n\t\t\t\t\tconst height = Math.sqrt((rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x)\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y));\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height/2)\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t}\n\t\t\t\tthis.template.beginTextureFill({\n\t\t\t\t\ttexture: this.texture,\n\t\t\t\t\tmatrix: mat,\n\t\t\t\t\talpha: 0.8\n\t\t\t\t});\n\t\t\t\t// move into draw or so\n\t\t\t\tconst source = getProperty(this.texture, "baseTexture.resource.source")\n\t\t\t\tif ( source && (source.tagName === "VIDEO") ) {\n\t\t\t\t\tsource.loop = true;\n\t\t\t\t\tsource.muted = true;\n\t\t\t\t\tgame.video.play(source);\n\t\t\t\t}\n\t\t}'),Hooks.on("renderMeasuredTemplateConfig",(e,t,a)=>{t[0].querySelector(".file-picker").dataset.type="imagevideo"})),game.settings.get("mess","templateDrawBordersOnlyOnHighlight")&&(e=e.replace(/this\.\_borderThickness/,"this.texture && !this._hover ? 0 : this._borderThickness"),e=e.replace(/return\sthis\;/,"\n\t\t\tconst grid = canvas.grid;\n\t\t\t// only show grid highlights on hover\n\t\t\tif (this.texture) {\n\t\t\t\tconst hl = grid.getHighlightLayer(`Template.${this.id}`);\n\t\t\t\tif (hl)\n\t\t\t\t\thl.renderable = this._hover;\n\t\t\t}\n\t\t\treturn this;")),MeasuredTemplate.prototype.refresh=Function(`"use strict"; return ( function ${e} )`)(),game.settings.get("mess","templateAutoTargeting")){MeasuredTemplate.prototype.getTargets=i,MeasuredTemplate.prototype.isTokenInside=r;const e=MeasuredTemplate.prototype._onDragLeftMove;MeasuredTemplate.prototype._onDragLeftMove=function(t){const a=e.bind(this)(t);for(let e of t.data.clones)this.getTargets(e);return a}}}async function n(){if("dnd5e"!==game.system.id)return;const e=await import("/systems/dnd5e/module/pixi/ability-template.js"),t=e.default||e.AbilityTemplate;if(game.settings.get("mess","modify-templates")){Hooks.on("renderItemSheet",o);const e=t.fromItem;t.fromItem=function(t){const a=e.bind(this)(t);let s=t.getFlag("mess","templateTexture");if(!s&&t.hasDamage){const e=game.settings.get("mess","templateTexture")||{};s=e[t.data.data.damage.parts[0][1]]||{},s=s[a.data.t]}return s&&loadTexture(s).then(e=>{a.texture=e,a.data.texture=s,a.refresh()}),a.item=t,a}}if(game.settings.get("mess","templateAutoTargeting")){const e=t.prototype.activatePreviewListeners.toString().replace(/this\.refresh\(\)\;/,"this.refresh();\n\t\t\t\t\t\tthis.getTargets(this);\n\t\t\t\t\t");t.prototype.getTargets=i,t.prototype.isTokenInside=r,t.prototype.activatePreviewListeners=Function(`"use strict"; return ( function ${e} )`)()}}function r(e){const t=canvas.scene.data.grid,a=this.data.x,s=this.data.y,n=e.width>=1?.5:e.width/2,r=e.height>=1?.5:e.height/2;for(let i=n;i\n\t\t\t\n\t\t\n\t');const r=s.querySelector("button");r.style.flex="0",e._activateFilePicker(r);const i=t[0].querySelector('[name="data.target.units"]');i&&i.closest(".form-group").after(a)}a.r(t),a.d(t,"changeTemplates",(function(){return s})),a.d(t,"dndTemplateSettings",(function(){return n}))},"./src/scripts/prepared-spell-tracker.js": +/*! exports provided: changeTemplates, dndTemplateSettings */function(t,e,s){"use strict";function a(){let t=MeasuredTemplate.prototype.refresh.toString();if(game.settings.get("mess","modify-templates")&&(t=t.replace(/this\.template\.beginTextureFill\(\{[\s\S]*\}\)\;/,'\n\t\t\t{\n\t\t\t\tlet mat = PIXI.Matrix.IDENTITY;\n\t\t\t\t// rectangle\n\t\t\t\tif (this.shape.width && this.shape.height)\n\t\t\t\t\tmat.scale(this.shape.width / this.texture.width, this.shape.height / this.texture.height);\n\t\t\t\telse if (this.shape.radius) {\n\t\t\t\t\tmat.scale(this.shape.radius * 2 / this.texture.height, this.shape.radius * 2 / this.texture.width)\n\t\t\t\t\t// Circle center is texture start...\n\t\t\t\t\tmat.translate(-this.shape.radius, -this.shape.radius);\n\t\t\t\t} else if (this.data.t === "ray") {\n\t\t\t\t\tconst d = canvas.dimensions,\n\t\t\t\t\t\t\t\theight = this.data.width * d.size / d.distance,\n\t\t\t\t\t\t\t\twidth = this.data.distance * d.size / d.distance;\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height * 0.5);\n\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t} else {// cone\n\t\t\t\t\tconst d = canvas.dimensions;\n\t\t\t\n\t\t\t\t\t// Extract and prepare data\n\t\t\t\t\tlet {direction, distance, angle} = this.data;\n\t\t\t\t\tdistance *= (d.size / d.distance);\n\t\t\t\t\tdirection = toRadians(direction);\n\t\t\t\t\tconst width = this.data.distance * d.size / d.distance;\n\n\t\t\t\t\tconst angles = [(angle/-2), (angle/2)];\n\t\t\t\t\tdistance = distance / Math.cos(toRadians(angle/2));\n\t\t\t\n\t\t\t\t\t// Get the cone shape as a polygon\n\t\t\t\t\tconst rays = angles.map(a => Ray.fromAngle(0, 0, direction + toRadians(a), distance+1));\n\t\t\t\t\tconst height = Math.sqrt((rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x)\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y));\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height/2)\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t}\n\t\t\t\tthis.template.beginTextureFill({\n\t\t\t\t\ttexture: this.texture,\n\t\t\t\t\tmatrix: mat,\n\t\t\t\t\talpha: 0.8\n\t\t\t\t});\n\t\t\t\t// move into draw or so\n\t\t\t\tconst source = getProperty(this.texture, "baseTexture.resource.source")\n\t\t\t\tif ( source && (source.tagName === "VIDEO") ) {\n\t\t\t\t\tsource.loop = true;\n\t\t\t\t\tsource.muted = true;\n\t\t\t\t\tgame.video.play(source);\n\t\t\t\t}\n\t\t}'),Hooks.on("renderMeasuredTemplateConfig",(t,e,s)=>{e[0].querySelector(".file-picker").dataset.type="imagevideo"})),game.settings.get("mess","templateDrawBordersOnlyOnHighlight")&&(t=t.replace(/this\.\_borderThickness/,"this.texture && !this._hover ? 0 : this._borderThickness"),t=t.replace(/return\sthis\;/,"\n\t\t\tconst grid = canvas.grid;\n\t\t\t// only show grid highlights on hover\n\t\t\tif (this.texture) {\n\t\t\t\tconst hl = grid.getHighlightLayer(`Template.${this.id}`);\n\t\t\t\tif (hl)\n\t\t\t\t\thl.renderable = this._hover;\n\t\t\t}\n\t\t\treturn this;")),MeasuredTemplate.prototype.refresh=Function(`"use strict"; return ( function ${t} )`)(),game.settings.get("mess","templateAutoTargeting")){MeasuredTemplate.prototype.getTargets=i,MeasuredTemplate.prototype.isTokenInside=r;const t=MeasuredTemplate.prototype._onDragLeftMove;MeasuredTemplate.prototype._onDragLeftMove=function(e){const s=t.bind(this)(e);for(let t of e.data.clones)this.getTargets(t);return s}}}async function n(){if("dnd5e"!==game.system.id)return;const t=await import("/systems/dnd5e/module/pixi/ability-template.js"),e=t.default||t.AbilityTemplate;if(game.settings.get("mess","modify-templates")){Hooks.on("renderItemSheet",o);const t=e.fromItem;e.fromItem=function(e){const s=t.bind(this)(e);let a=e.getFlag("mess","templateTexture");if(!a&&e.hasDamage){const t=game.settings.get("mess","templateTexture")||{};a=t[e.data.data.damage.parts[0][1]]||{},a=a[s.data.t]}return a&&loadTexture(a).then(t=>{s.texture=t,s.data.texture=a,s.refresh()}),s.item=e,s}}if(game.settings.get("mess","templateAutoTargeting")){const t=e.prototype.activatePreviewListeners.toString().replace(/this\.refresh\(\)\;/,"this.refresh();\n\t\t\t\t\t\tthis.getTargets(this);\n\t\t\t\t\t");e.prototype.getTargets=i,e.prototype.isTokenInside=r,e.prototype.activatePreviewListeners=Function(`"use strict"; return ( function ${t} )`)()}}function r(t){const e=canvas.scene.data.grid,s=this.data.x,a=this.data.y,n=t.width>=1?.5:t.width/2,r=t.height>=1?.5:t.height/2;for(let i=n;i\n\t\t\t\n\t\t\n\t');const r=a.querySelector("button");r.style.flex="0",t._activateFilePicker(r);const i=e[0].querySelector('[name="data.target.units"]');i&&i.closest(".form-group").after(s)}s.r(e),s.d(e,"changeTemplates",(function(){return a})),s.d(e,"dndTemplateSettings",(function(){return n}))},"./src/scripts/prepared-spell-tracker.js": /*!***********************************************!*\ !*** ./src/scripts/prepared-spell-tracker.js ***! \***********************************************/ -/*! exports provided: default */function(e,t,a){"use strict";async function s(){Hooks.on("renderActorSheet",(async function(e,t,a){const s=await fromUuid("Actor."+a.actor._id);if(s.isNPC)return;if(!t[0].querySelector(".spell-dc"))return;let n=document.createElement("div");n.classList.add("spell-detail"),n.classList.add("spell-slots"),n.style.flex="1",n.style.border="none";n.appendChild(document.createElement("span")).innerText=`${game.i18n.localize("MESS.actorSheet.preparedSpellTracker")}: ${a.preparedSpells}`;const r=n.appendChild(document.createElement("span"));r.innerText=" / ",r.classList.add("sep");const i=n.appendChild(document.createElement("input"));if(i.type="text",i.value=s.getFlag("mess","maxPreparedSpells")||0,i.addEventListener("change",(async function(e){e.preventDefault(),e.stopPropagation();const t=Number(e.currentTarget.value);return isNaN(t)?(e.currentTarget.value=s.getFlag("mess","maxPreparedSpells")||0,!1):(s.setFlag("mess","maxPreparedSpells",t),!1)})),"Tidy5eSheet"===e.constructor.name){const e=t[0].querySelector(".spellcasting-ability");if(!e)return;e.appendChild(n,e)}else{const e=t[0].querySelector(".spellbook .inventory-list");if(!e)return;n.style.flex="0",n.style.alignSelf="flex-start",n.style.margin="0 8px",e.parentNode.insertBefore(n,e)}}))}a.r(t),a.d(t,"default",(function(){return s}))},"./src/scripts/rolls/apply-dmg.js": -/*!****************************************!*\ - !*** ./src/scripts/rolls/apply-dmg.js ***! - \****************************************/ -/*! exports provided: default */function(e,t,a){"use strict";function s(e){return Array.from(e[0].parentNode.querySelectorAll(".mess-dice-result:not(.mess-versatile")).map(e=>Number(e.querySelector("span").innerText)).reduce((e,t)=>e+t,0)}function n(e){const t=Array.from(e[0].parentNode.querySelectorAll(".mess-dice-result"));t.length>1&&t[1].classList.contains("mess-versatile")&&t.splice(0,1);return t.map(e=>Number(e.querySelector("span").innerText)).reduce((e,t)=>e+t,0)}function r(){const e=e=>!0,t=e=>e[0].parentNode.querySelector(".mess-dice-result:not(.mess-versatile)"),a=e=>e[0].parentNode.querySelector(".mess-versatile"),r=e=>!!e[0].closest(".mess-attack-card").dataset.targetId,l=e=>!r(e),c=[{name:game.i18n.localize("MESS.attackCard.contextMenu.applyTarget"),condition:r},{name:game.i18n.localize("MESS.attackCard.contextMenu.applySelected"),condition:l},{name:game.i18n.localize("MESS.attackCard.contextMenu.dmg"),condition:t,icon:''},{name:"full",icon:"",condition:t,callback:(e,t)=>o(t,1),content:e=>`${s(e)}`},{name:"half",icon:"",condition:t,callback:(e,t)=>o(t,1),content:e=>`${Math.max(Math.floor(.5*s(e)),1)}`},{name:"double",icon:"",condition:t,callback:(e,t)=>o(t,1),content:e=>`${Math.floor(2*s(e))}`},{name:game.i18n.localize("MESS.attackCard.contextMenu.healing"),condition:t,icon:''},{name:"full",icon:"",condition:t,callback:(e,t)=>o(t,-1),content:e=>`${s(e)}`},{name:[game.i18n.localize("DND5E.Versatile")," - ",game.i18n.localize("MESS.attackCard.contextMenu.dmg")],condition:a,icon:''},{name:"full",icon:"",condition:a,callback:(e,t)=>o(t,1),content:e=>`${n(e)}`},{name:"half",icon:"",condition:a,callback:(e,t)=>o(t,1),content:e=>`${Math.max(Math.floor(.5*n(e)),1)}`},{name:"double",icon:"",condition:a,callback:(e,t)=>o(t,1),content:e=>`${Math.floor(2*n(e))}`},{name:[game.i18n.localize("DND5E.Versatile")," - ",game.i18n.localize("MESS.attackCard.contextMenu.healing")],condition:a,icon:''},{name:"full",icon:"",condition:a,callback:(e,t)=>o(t,-1),content:e=>`${n(e)}`}],d=[{name:game.i18n.localize("MESS.attackCard.contextMenu.applyTarget"),condition:r},{name:game.i18n.localize("MESS.attackCard.contextMenu.applySelected"),condition:l},{name:game.i18n.localize("MESS.attackCard.contextMenu.dmg"),condition:e,icon:''},{name:"full",icon:"",condition:e,callback:(e,t)=>o(t,1),content:e=>`${e[0].querySelector("span").innerText}`},{name:"half",icon:"",condition:e,callback:(e,t)=>o(t,1),content:e=>`${Math.max(Math.floor(.5*Number(e[0].querySelector("span").innerText)),1)}`},{name:"double",icon:"",condition:e,callback:(e,t)=>o(t,1),content:e=>`${Math.floor(2*Number(e[0].querySelector("span").innerText))}`},{name:game.i18n.localize("MESS.attackCard.contextMenu.healing"),condition:e,icon:''},{name:"full",icon:"",condition:e,callback:(e,t)=>o(t,-1),content:e=>`${e[0].querySelector("span").innerText}`}];ContextMenu.prototype.bind=Function('"use strict"; return ( function '+ContextMenu.prototype.bind.toString().replace(/this\.render\(parent\)/,"this.render(parent, event)")+")")(),Hooks.on("renderChatLog",(e,t,a)=>{new i(t.find("#chat-log"),".mess-chat-dmg .mess-dice-result",d),new i(t.find("#chat-log"),".mess-chat-dmg .mess-chat-roll-type",c)}),Hooks.on("getChatLogEntryContext",(function(e,t){setProperty(game,"mess.chatLogEntryContextOptions",t);const a=e=>canvas.tokens.controlled.length&&e.find(".dice-roll .dice-result").length;for(let e=1;e!t.condition||(t.condition instanceof Function?t.condition(e):t.condition));if(!a.length)return;t.stopPropagation(),this.menuItems=a.map(t=>(t.content&&(t.name=t.content(e)),t));let s=$("#context-menu").length?$("#context-menu"):$(''),n=$('
    ');s.html(n);const r=document.createDocumentFragment();for(let t of this.menuItems){const a=document.createElement("li");t.name instanceof Array&&(t.name=t.name.map(e=>game.i18n.localize(e)).join("")),t.icon?a.innerHTML=`${t.icon}${game.i18n.localize(t.name)}`:a.innerHTML=game.i18n.localize(t.name),t.callback?(a.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),t.callback(e,a),this.close()}),a.classList.add("context-item")):a.classList.add("mess-context-menu-header"),r.appendChild(a)}return n[0].appendChild(r),this._setPosition(s,e),this._animateOpen(s)}_setPosition(e,t){e.removeClass("expand-up expand-down"),super._setPosition(e,t)}}async function o(e,t){const a=Number(e.querySelector("span").innerText),s=e.closest(".mess-attack-card"),n=s.dataset.targetId;if(n){const e=s.dataset.sceneId,r=game.scenes.get(e);if(!r)return void ui.notifications.error(game.i18n.localize("MESS.attackCard.applyDamage.sceneNotFound"));const i=new Token(r.getEmbeddedEntity("Token",n));if(!i)return void ui.notifications.error(game.i18n.localize("MESS.attackCard.applyDamage.targetNotFound"));if(!i.owner)return void ui.notifications.error(game.i18n.localize("MESS.attackCard.applyDamage.targetNotOwner"));i.actor.applyDamage(a,t)}else{const e=canvas.tokens.controlled;if(!e.length)return void ui.notifications.error(game.i18n.localize("MESS.attackCard.contextMenu.error"));for(const s of e){s.actor.applyDamage(a,t)}}}},"./src/scripts/rolls/controls.js": -/*!***************************************!*\ - !*** ./src/scripts/rolls/controls.js ***! - \***************************************/ -/*! exports provided: default */function(e,t,a){"use strict";async function s(e,t,a){t[0].classList.add("mess"),game.user.isGM&&t[0].classList.add("mess-is-gm");const s=document.createElement("div");s.classList.add("mess-roll-control");const n=game.settings.get("mess",game.userId+".adv-selector"),r=game.settings.get("mess",game.userId+".autoroll-selector"),i={advantage:"advantage"===n,normal:"normal"===n,disadvantage:"disadvantage"===n,autoShow:game.settings.get("mess",game.userId+".autoshow-selector"),...r};s.insertAdjacentHTML("afterbegin",await renderTemplate("modules/mess/templates/roll-control.html",i)),s.querySelector(".mess-show-btn").addEventListener("click",e=>{e.preventDefault(),e.stopPropagation();const t=e.currentTarget,a=t.classList.contains("active");t.classList.toggle("active"),game.settings.set("mess",game.userId+".autoshow-selector",!a)}),s.querySelectorAll(".mess-adv-selector a").forEach(e=>{e.addEventListener("click",(async function(e){e.preventDefault(),e.stopPropagation();const t=Array.from(e.currentTarget.parentNode.querySelectorAll("a")),a=t.findIndex(e=>e.classList.contains("mess-selected"));t[a].classList.remove("mess-selected");const s=t[(a+1)%t.length];s.classList.add("mess-selected"),game.settings.set("mess",game.userId+".adv-selector",s.name)})),e.addEventListener("contextmenu",(async function(e){e.preventDefault(),e.stopPropagation();const t=Array.from(e.currentTarget.parentNode.querySelectorAll("a")),a=t.findIndex(e=>e.classList.contains("mess-selected"));t[a].classList.remove("mess-selected");const s=t[(a+t.length-1)%t.length];s.classList.add("mess-selected"),game.settings.set("mess",game.userId+".adv-selector",s.name)}))}),s.querySelectorAll(".mess-autoroll-selector a").forEach(e=>{e.addEventListener("click",(async function(e){e.preventDefault(),e.stopPropagation(),e.currentTarget.classList.toggle("mess-selected");let t=game.settings.get("mess",game.userId+".autoroll-selector");t[e.currentTarget.name]=e.currentTarget.classList.contains("mess-selected"),game.settings.set("mess",game.userId+".autoroll-selector",t)}))});const o=document.getElementById("chat-controls");o.insertBefore(s,o.childNodes[0])}a.r(t),t.default=function(){Hooks.on("renderChatLog",s),game.settings.register("mess",game.userId+".adv-selector",{name:"Mess - Advantage Selector",default:"normal",type:String,scope:"user"}),game.settings.register("mess",game.userId+".autoroll-selector",{name:"Mess - Autoroll Selector",default:{hit:!1,dmg:!1},type:Object,scope:"user"}),game.settings.register("mess",game.userId+".autoshow-selector",{name:"Mess - Auto Show",default:!1,type:Boolean,scope:"user"})}},"./src/scripts/rolls/dice.js": -/*!***********************************!*\ - !*** ./src/scripts/rolls/dice.js ***! - \***********************************/ -/*! exports provided: rollD20, getToHitData, rollToHit, getDmgData, rollDmg */function(e,t,a){"use strict";a.r(t),a.d(t,"rollD20",(function(){return r})),a.d(t,"getToHitData",(function(){return i})),a.d(t,"rollToHit",(function(){return o})),a.d(t,"getDmgData",(function(){return l})),a.d(t,"rollDmg",(function(){return c}));a(/*! ./util.js */"./src/scripts/rolls/util.js");function s(){return document.getElementById("mess-roll-mod").value}function n(){return game.settings.get("mess",game.userId+".adv-selector")}async function r(e){let t=n(),a=1,r=e.halflingLucky?"r=1":"";"advantage"===t?(a=e.elvenAccuracy?3:2,r+="kh",e.title+=` (${game.i18n.localize("DND5E.Advantage")})`):"disadvantage"===t&&(a=2,r+="kl",e.title+=` (${game.i18n.localize("DND5E.Disadvantage")})`);let i=`${a}d20${r}`;e.reliableTalent&&(i=`{${a}d20${r},10}kh`),e.parts.unshift(i);const o=s();o&&e.parts.push(o);let l=new Roll(e.parts.join("+"),e);l.roll();const c=l.parts[0].total;let d={...e,tooltip:await l.getTooltip(),roll:l,crit:c>=20,fumble:c<=1,isGM:game.user.isGM,showRolls:game.settings.get("mess",game.userId+".autoshow-selector")};const m=await renderTemplate("modules/mess/templates/roll-card.html",d);let u={user:game.user._id,type:CONST.CHAT_MESSAGE_TYPES.OTHER,content:m,speaker:{actor:this,alias:this.name}},g=game.settings.get("core","rollMode");["gmroll","blindroll"].includes(g)&&(u.whisper=ChatMessage.getWhisperRecipients("GM")),"blindroll"===g&&(u.blind=!0);if(game.mess.diceSoNice){let e=null,t=!1;["gmroll","blindroll"].includes(g)&&(e=ChatMessage.getWhisperRecipients("GM")),"blindroll"===g&&(t=!0),await game.dice3d.showForRoll(l,game.user,!0,e,t)}ChatMessage.create(u)}async function i({actor:e,item:t}){if(!t.hasAttack)return null;const a=e.data.data,n=t.data.data,r=e.data.flags.dnd5e||{};let i=t.getRollData();const o=["@mod"];("weapon"!==t.data.type||n.proficient)&&o.push("@prof"),i.parts=o,"weapon"===t.data.type&&r.weaponCriticalThreshold&&(i.critical=parseInt(r.weaponCriticalThreshold)),["weapon","spell"].includes(t.data.type)&&r.elvenAccuracy&&["dex","int","wis","cha"].includes(t.abilityMod)&&(i.elvenAccuracy=!0),r.halflingLucky&&(i.halflingLucky=!0);const l=a.bonuses[n.actionType]||{};(n.attackBonus||l.attack)&&(i.atk=[n.attackBonus,l.attack].filterJoin(" + "),o.push("@atk"));let c=new Roll(i.parts.join("+"),i);c.roll(),i.totalModifier=c._safeEval(Roll.cleanFormula(c.terms)),i.totalModifier=i.totalModifier>=0?"+"+i.totalModifier:i.totalModifier;const d=s();d&&(i.parts.push(d),c=new Roll(i.parts.join("+"),i),i.totalModifier+=`+(${d})`);try{const e=c._safeEval(Roll.cleanFormula(i.totalModifier));i.totalModifier=e>=0?"+"+e:e}catch(e){}return i.totalModifier=i.totalModifier,i.formula=i.parts.join("+"),i.terms=Roll.cleanFormula(c.terms),i}async function o(e){const t=e.currentTarget;t.disabled=!0;const a=t.closest(".chat-card"),s=a.closest(".message").dataset.messageId;if(s){e.stopPropagation(),e.preventDefault();const t=game.messages.get(s);if(!t.owner&&!t.isAuthor)return ui.notifications.error("You do not own the permissions to make that roll!"),!1}const r=CONFIG.Item.entityClass._getChatCardActor(a);if(!r.owner)return!1;const o=r.getOwnedItem(a.dataset.itemId);if(!o)return ui.notifications.error(`The requested item ${a.dataset.itemId} no longer exists on Actor ${r.name}`);let l=await i({actor:r,item:o}),c=n(),m=1,u=l.halflingLucky?"r=1":"";"advantage"===c?(m=l.elvenAccuracy?3:2,u+="kh"):"disadvantage"===c&&(m=2,u+="kl"),l.parts.unshift(`${m}d20${u}`);let g=new Roll(l.parts.join("+"),l);g.roll();let p=document.createElement("div");p.classList.add("dice-roll"),p.classList.add("mess-dice-result"),game.user.isGM&&p.classList.add("mess-gm-dice");const f=p.appendChild(document.createElement("span"));f.classList.add("mess-roll-container"),f.innerHTML=`${g.total}`,p.insertAdjacentHTML("beforeend",await g.getTooltip());let h="";const y=l.terms.split(/(?=[+-])/),b=l.formula.split(/(?=[+-])/);console.log(l),console.log(y,b);for(let e=0;e\n\t\t\t\t
    \n ${b[e]}\n\t\t\t\t\t${t}\n\t\t\t\t
    \n\t\t\t\n\t\t`}p.querySelector(".dice-tooltip").insertAdjacentHTML("beforeend",h);p.childNodes[1].classList.add("hidden");const v=l.critical||20,T=l.fumble||1,S=g.parts[0].total;return S>=v&&(f.classList.add("crit"),a.querySelector(".mess-chat-dmg .mess-chat-roll-type").innerHTML+=" - Crit!",a.querySelectorAll(".mess-button-dmg").forEach((e,t)=>{const a=new Roll(e.dataset.formula).alter(2).formula;e.innerHTML=' '+a,e.dataset.formula=a})),S<=T&&f.classList.add("fumble"),s?d(s,g,a,e.currentTarget,p):e.currentTarget.parentNode.replaceChild(p,e.currentTarget),g}async function l({actor:e,item:t,spellLevel:a=null}){if(!t.hasDamage)return null;const s=e.data.data,n=t.data.data;let r=t.getRollData();if(a&&(r.item.level=a),r.parts=duplicate(n.damage.parts),n.damage.versatile&&r.parts.splice(1,0,[n.damage.versatile,"versatile"]),!t.getFlag("mess","isBonusDamage"))for(let a of e.items){if(a.id===t.id)continue;let e=[];if(a.getFlag("mess","isBonusDamage")&&a.hasDamage){const t=a.data.data;e.push(t.damage.parts[0][0]);var i=a.name;t.damage.parts[0][1].length>0&&(i+=" - "+game.i18n.localize("DND5E.Damage"+CONFIG.DND5E.damageTypes[t.damage.parts[0][1]])),e.push(i)}e.length>0&&r.parts.push(e)}if("spell"===t.data.type)if("cantrip"===n.scaling.mode){let a=[r.parts[0][0]];const i="character"===e.data.type?s.details.level:s.details.spellLevel;t._scaleCantripDamage(a,n.scaling.formula,i),r.parts[0][0]=a[0]}else if(a&&"level"===n.scaling.mode&&n.scaling.formula){let e=[];t._scaleSpellDamage(e,n.level,a,n.scaling.formula),e.length>0&&(e.push("upcast dice"),r.parts.push(e))}const o=s.bonuses[n.actionType]||{};o.damage&&0!==parseInt(o.damage)&&(r.parts[0][0]+="+@dmg",r.dmg=o.damage);for(let e of r.parts){let t=new Roll(e[0],r);CONFIG.DND5E.damageTypes[e[1]]?e[1]=game.i18n.localize("DND5E.Damage"+CONFIG.DND5E.damageTypes[e[1]]):"versatile"===e[1]&&(e[1]=game.i18n.localize("DND5E.Versatile"));let a=t.terms.map((e,a,s)=>{if(e instanceof Roll){hasInner=!0,e.evaluate(),t._dice=t._dice.concat(e.dice);return a>0&&s[a-1].split(" ").pop()in Math?`(${e.total})`:String(e.total)}return e});e.push(Roll.cleanFormula(a))}return r}async function c(e){const t=e.currentTarget.parentNode.querySelector("#context-menu");t&&t.remove();const a=e.currentTarget;a.disabled=!0;const s=a.closest(".chat-card"),n=s.closest(".message").dataset.messageId;if(n){e.stopPropagation(),e.preventDefault();const t=game.messages.get(n);if(!t.owner&&!t.isAuthor)return ui.notifications.error("You do not own the permissions to make that roll!"),!1}const r=a.dataset.formula;let i=new Roll(r);i.roll();let o=document.createElement("div");o.classList.add("dice-roll"),o.classList.add("mess-dice-result"),game.user.isGM&&o.classList.add("mess-gm-dice");a.nextElementSibling.innerText===game.i18n.localize("DND5E.Versatile")&&o.classList.add("mess-versatile");const l=o.appendChild(document.createElement("span"));l.classList.add("mess-roll-container"),l.innerHTML=`${i.total}`,o.insertAdjacentHTML("beforeend",await i.getTooltip());let c="";const m=a.dataset.terms.split(/(?=[+-])/),u=r.replace(/\s/g,"").split(/(?=[+-])/);console.log(a.dataset.terms,r),console.log(m,u);for(let e=0;e\n\t\t\t\t
    \n ${t}\n\t\t\t\t\t${a}\n\t\t\t\t
    \n\t\t\t\n\t\t`)}o.querySelector(".dice-tooltip").insertAdjacentHTML("beforeend",c);return o.childNodes[1].classList.add("hidden"),n?d(n,i,s,e.currentTarget,o):e.currentTarget.parentNode.replaceChild(o,e.currentTarget),i}async function d(e,t,a,s,n){const r=game.messages.get(e);if(game.mess.diceSoNice){let e=game.settings.get("core","rollMode"),s=null,n=!1;["gmroll","blindroll"].includes(e)&&(s=ChatMessage.getWhisperRecipients("GM")),"blindroll"===e&&(n=!0),a.querySelectorAll("button").forEach(e=>e.disabled=!0),await game.dice3d.showForRoll(t,game.user,!0,s,n)}else AudioHelper.play({src:CONFIG.sounds.dice},!0);s.parentNode.replaceChild(n,s),r.update({content:a.parentNode.innerHTML})}},"./src/scripts/rolls/index.js": -/*!************************************!*\ - !*** ./src/scripts/rolls/index.js ***! - \************************************/ -/*! exports provided: rolling */function(e,t,a){"use strict";a.r(t),a.d(t,"rolling",(function(){return i}));var s=a(/*! ./controls.js */"./src/scripts/rolls/controls.js"),n=a(/*! ./apply-dmg.js */"./src/scripts/rolls/apply-dmg.js"),r=a(/*! ./modify-rolling.js */"./src/scripts/rolls/modify-rolling.js");function i(){game.settings.get("mess","modify-rolling")&&(Object(s.default)(),Object(n.default)(),Object(r.default)())}},"./src/scripts/rolls/modify-rolling.js": -/*!*********************************************!*\ - !*** ./src/scripts/rolls/modify-rolling.js ***! - \*********************************************/ -/*! exports provided: default */function(e,t,a){"use strict";a.r(t);var s=a(/*! ./dice.js */"./src/scripts/rolls/dice.js");function n(e){const t=ChatMessage.getSpeaker();let a;t.token&&(a=game.actors.tokens[t.token]),a||(a=game.actors.get(t.actor));const s=a?a.items.filter(t=>t.name===e):[];if(s.length>1)ui.notifications.warn(`Your controlled Actor ${a.name} has more than one Item with name ${e}. The first matched item will be chosen.`);else if(0===s.length)return ui.notifications.warn("Your controlled Actor does not have an item named "+e);const n=s[0],r=!n.getFlag("mess","isBonusDamage");return n.setFlag("mess","isBonusDamage",r),r}async function r(e){const t=document.createElement("div");t.insertAdjacentHTML("afterbegin",e.content);let a=t.querySelector('button[data-action="attack"]');a||(a=t.querySelector('button[data-action="damage"]')),a&&o({currentTarget:a})}function i(e,t){let a=Array.from(e.matchAll(/@RollTable\[([^\]])+\](?:\{([^\}]+)\})?/g));if(a){const t=game.tables;for(let s of a){let a;const n=s[0].match(/\[[a-zA-Z0-9]{16}\]/);if(n)a=t.get(n[0].slice(1,-1));else{const e=s[0].match(/\[([^\]])+\]/)[0].slice(1,-1);a=t.entities.find(t=>t.data.name===e)}let r=a.roll();e=e.replace(s[0],r.results.map(e=>e.text).join(","))}}return e.replace(/\[target\.name\]/g,t.data.name)}async function o(e){"click"===e.type&&(e.preventDefault(),e.stopPropagation());const t=e.currentTarget;t.disabled=!0;const a=t.closest(".chat-card"),n=CONFIG.Item.entityClass._getChatCardActor(a);if(!n||!n.owner)return;const r=n.getOwnedItem(a.dataset.itemId);if(!r)return ui.notifications.error(`The requested item ${a.dataset.itemId} no longer exists on Actor ${n.name}`);let o=game.user.targets;const c=Object.keys(CONFIG.DND5E.areaTargetTypes).includes(getProperty(r,"data.data.target.type"));o.size&&!c||(o=[{data:{name:"someone",img:""}}]);const d=parseInt(a.dataset.spellLevel)||null,m={actor:n,item:r,toHit:await Object(s.getToHitData)({actor:n,item:r}),dmgs:await Object(s.getDmgData)({actor:n,item:r,spellLevel:d}),sceneId:canvas.scene.id,user:game.user.id,isGM:game.user.isGM,showRolls:game.settings.get("mess",game.userId+".autoshow-selector")},u=game.settings.get("mess",game.userId+".autoroll-selector"),g=game.settings.get("core","rollMode");for(const e of o){const t=await r._handleResourceConsumption({isCard:!1,isAttack:!0}),a=e.actor?e.actor.data:null;let s={};if(a){s.ac={label:'',title:game.i18n.localize("DND5E.ArmorClass"),value:a.data.attributes.ac.value};let e=a.data.traits.di.value.filter(e=>"custom"!==e).map(e=>game.i18n.localize("DND5E.Damage"+e[0].toUpperCase()+e.substring(1)));a.data.traits.di.custom&&e.push(a.data.traits.di.custom),s.di={label:'',title:game.i18n.localize("DND5E.DamImm"),value:e.join(", ")};let t=a.data.traits.dr.value.filter(e=>"custom"!==e).map(e=>game.i18n.localize("DND5E.Damage"+e[0].toUpperCase()+e.substring(1)));a.data.traits.dr.custom&&t.push(a.data.traits.dr.custom),s.dr={label:'',title:game.i18n.localize("DND5E.DamRes"),value:t.join(", ")};let n=a.data.traits.dv.value.filter(e=>"custom"!==e).map(e=>game.i18n.localize("DND5E.Damage"+e[0].toUpperCase()+e.substring(1)));a.data.traits.dv.custom&&n.push(a.data.traits.dv.custom),s.dv={label:'',title:game.i18n.localize("DND5E.DamVuln"),value:n.join(", ")}}const n=e.data.displayName===CONST.TOKEN_DISPLAY_MODES.ALWAYS||e.data.displayName===CONST.TOKEN_DISPLAY_MODES.HOVER,o={...m,target:e.data,targetData:s,flavor:i(r.data.data.chatFlavor,e),allowed:t,displayName:n};let c=await renderTemplate("modules/mess/templates/attack-card.html",o);(u.hit||u.dmg)&&(c=await l(u,c,g));let d={user:game.user._id,type:CONST.CHAT_MESSAGE_TYPES.OTHER,content:c,speaker:{actor:r.actor._id,token:r.actor.token,alias:r.actor.name}};game.user.isGM&&game.settings.get("mess","attack-card-always-public")||(["gmroll","blindroll"].includes(g)&&(d.whisper=ChatMessage.getWhisperRecipients("GM")),"selfroll"===g&&(d.whisper=[game.user.id])),ChatMessage.create(d)}t.disabled=!1}async function l(e,t,a){let n=document.createElement("div");const r=game.mess.diceSoNice;let i=null,o=!1;["gmroll","blindroll"].includes(a)&&(i=ChatMessage.getWhisperRecipients("GM")),"blindroll"===a&&(o=!0),n.classList.add("message"),n.insertAdjacentHTML("afterbegin",t);let l=[];if(e.hit){let e=n.querySelector(".mess-button-to-hit");if(e){let t=await Object(s.rollToHit)({currentTarget:e});r&&await game.dice3d.showForRoll(t,game.user,!0,i,o)}}if(e.dmg){const e=Array.from(n.querySelectorAll(".mess-button-dmg"));for(const t of e)l.push(await Object(s.rollDmg)({currentTarget:t}))}return r?await game.dice3d.showForRoll(l,game.user,!0,i,o):AudioHelper.play({src:CONFIG.sounds.dice},!0),n.innerHTML}async function c(e,t,a){const n=t[0].querySelectorAll(".ability-mod, .ability-name");$(n).off(),n.forEach(t=>t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault();const a=t.currentTarget.closest(".ability").dataset.ability,n=CONFIG.DND5E.abilities[a],r=["@mod"],i={mod:e.object.data.data.abilities[a].mod},o=e.object.data.flags.dnd5e||{},l=getProperty(e.object,"data.data");o.remarkableAthlete&&DND5E.characterFlags.remarkableAthlete.abilities.includes(a)?(r.push("@remarkable-athlete"),i["remarkable-athlete"]=Math.ceil(.5*l.attributes.prof)):o.jackOfAllTrades&&(r.push("@jack-of-all-trades"),i["jack-of-all-trades"]=Math.floor(.5*l.attributes.prof));let c=getProperty(e.object.data.data.bonuses,"abilities.check");return c&&(r.push("@checkBonus"),i.checkBonus=c),i.parts=r,i.title=game.i18n.format("DND5E.AbilityPromptTitle",{ability:n}),s.rollD20.bind(e.object)(i),!1})));const r=t[0].querySelectorAll(".ability-save");$(r).off(),r.forEach(t=>t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault();const a=t.currentTarget.closest(".ability").dataset.ability;return e.object.rollAbilitySave(a),!1})));const i=t[0].querySelectorAll(".skill-name");$(i).off(),i.forEach(t=>t.addEventListener("click",(function(t){t.stopPropagation(),t.preventDefault();const a=t.currentTarget.closest(".skill").dataset.skill,n=e.object.data.data.skills[a],r=["@mod"],i={mod:n.mod+n.prof};return n.bonus&&(i.skillBonus=n.bonus,r.push("@skillBonus")),i.reliableTalent=n.value>=1&&e.object.getFlag("dnd5e","reliableTalent"),i.parts=r,i.title=game.i18n.format("DND5E.SkillPromptTitle",{skill:CONFIG.DND5E.skills[a]}),s.rollD20.bind(e.object)(i),!1})))}function d(e){e||(e=$(document.getElementById("chat-log"))),e.on("click",".card-buttons button",m.bind(this)),e.on("click",".item-name",this._onChatCardToggleContent.bind(this)),e.on("mouseenter",".mess-chat-target",u),e.on("mouseleave",".mess-chat-target",g),e.on("dblclick",".mess-chat-target",p),e.on("click",".mess-button-to-hit",s.rollToHit),e.on("click",".mess-button-dmg",s.rollDmg),e.on("click",".mess-show-btn",h)}async function m(e){return e.preventDefault(),e.stopPropagation(),"attack"===e.currentTarget.dataset.action||"damage"===e.currentTarget.dataset.action?o(e):e.currentTarget.dataset.placeTemplate?renderTemplate(e):this._onChatCardAction(e)}async function u(e){e.preventDefault(),e.stopPropagation();const t=await f(e);if(!t)return!1;t._onHoverIn()}async function g(e){e.preventDefault(),e.stopPropagation();const t=await f(e);if(!t||!t.visible)return!1;t._onHoverOut()}async function p(e){e.preventDefault(),e.stopPropagation();const t=await f(e);if(!t||!t.visible)return!1;const a=t.center;canvas.animatePan({x:a.x,y:a.y})}async function f(e){const t=e.currentTarget.closest(".mess-attack-card");if(t.dataset.sceneId!==canvas.scene.id)return!1;const a=t.dataset.targetId;if(!a)return!1;const s=canvas.tokens.placeables.find(e=>e.id===a);return s||!1}async function h(e){e.currentTarget.closest(".mess-chat-to-hit, .mess-chat-dmg").classList.toggle("mess-show-players");const t=e.currentTarget.closest(".mess-attack-card"),a=t.closest(".message").dataset.messageId;game.messages.get(a).update({content:t.parentNode.innerHTML})}t.default=function(){CONFIG.Item.entityClass.chatListeners=d.bind(CONFIG.Item.entityClass),Hooks.on("preCreateChatMessage",r),Hooks.on("renderActorSheet",c),Hooks.on("renderItemSheet",(e,t,a)=>{let s=document.createElement("div");s.classList.add("form-group"),s.appendChild(document.createElement("label")).innerText=game.i18n.localize("MESS.itemSheet.bonusDmg");let n=s.appendChild(document.createElement("div"));n.classList.add("form-fields");let r=n.appendChild(document.createElement("input"));r.type="checkbox",r.name="flags.mess.isBonusDamage",r.checked=e.object.getFlag("mess","isBonusDamage");const i=t[0].querySelector('[name="data.formula"]');i&&i.closest(".form-group").after(s)}),game.mess.toggleItemBonusDamage=n,Hooks.once("diceSoNiceReady",e=>{game.mess.diceSoNice=!0}),CONFIG.Actor.entityClass.prototype.rollAbilitySave=function(e){const t=CONFIG.DND5E.abilities[e],a=this.data.data.abilities[e],n=["@mod"],r={mod:a.mod};a.prof>0&&(n.push("@prof"),r.prof=a.prof);const i=getProperty(this.data.data.bonuses,"abilities.save");i&&(n.push("@saveBonus"),r.saveBonus=i),r.title=game.i18n.format("DND5E.SavePromptTitle",{ability:t}),r.parts=n,s.rollD20.bind(this)(r)}}},"./src/scripts/rolls/util.js": -/*!***********************************!*\ - !*** ./src/scripts/rolls/util.js ***! - \***********************************/ -/*! exports provided: getTargetToken, hasTarget */function(e,t,a){"use strict";function s(e){const t=e.closest(".mess-attack-card"),a=t.dataset.targetId,s=t.dataset.sceneId,n=game.scenes.get(s);return new Token(n.getEmbeddedEntity("Token",a))}function n(e){const t=e.closest(".mess-attack-card");return!!t&&!!t.dataset.targetId}a.r(t),a.d(t,"getTargetToken",(function(){return s})),a.d(t,"hasTarget",(function(){return n}))},"./src/scripts/settings.js": +/*! exports provided: default */function(t,e,s){"use strict";async function a(){Hooks.on("renderActorSheet",(async function(t,e,s){const a=await fromUuid("Actor."+s.actor._id);if(a.isNPC)return;if(!e[0].querySelector(".spell-dc"))return;let n=document.createElement("div");n.classList.add("spell-detail"),n.classList.add("spell-slots"),n.style.flex="1",n.style.border="none";n.appendChild(document.createElement("span")).innerText=`${game.i18n.localize("MESS.actorSheet.preparedSpellTracker")}: ${s.preparedSpells}`;const r=n.appendChild(document.createElement("span"));r.innerText=" / ",r.classList.add("sep");const i=n.appendChild(document.createElement("input"));if(i.type="text",i.value=a.getFlag("mess","maxPreparedSpells")||0,i.addEventListener("change",(async function(t){t.preventDefault(),t.stopPropagation();const e=Number(t.currentTarget.value);return isNaN(e)?(t.currentTarget.value=a.getFlag("mess","maxPreparedSpells")||0,!1):(a.setFlag("mess","maxPreparedSpells",e),!1)})),"Tidy5eSheet"===t.constructor.name){const t=e[0].querySelector(".spellcasting-ability");if(!t)return;t.appendChild(n,t)}else{const t=e[0].querySelector(".spellbook .inventory-list");if(!t)return;n.style.flex="0",n.style.alignSelf="flex-start",n.style.margin="0 8px",t.parentNode.insertBefore(n,t)}}))}s.r(e),s.d(e,"default",(function(){return a}))},"./src/scripts/settings.js": /*!*********************************!*\ !*** ./src/scripts/settings.js ***! \*********************************/ -/*! exports provided: MessSettings */function(e,t,a){"use strict";a.r(t),a.d(t,"MessSettings",(function(){return s}));class s extends FormApplication{static init(){const e="dnd5e"===game.system.id;game.settings.register("mess","actor-item-sort",{name:"Activate item sort button.",hint:"Adds a button to actor sheets for sorting all items of that category alphabetically.",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","better-draggable",{name:"Activate better drag'n'drop workflow.",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","better-draggable-lists",{name:"Activate better drag'n'drop workflow for lists.",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.set("mess","better-draggable-lists",!1),game.settings.register("mess","prepared-spell-tracker",{name:"Activate prepared spell tracker",hint:"Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","add-scrolling",{name:"Activating numerical field scrolling.",hint:"Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","modify-rolling",{name:"Alternative Rolling.",hint:"Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","attack-card-always-public",{name:"Roll mode for alternative rolling.",hint:"Always roll attack rolls public, with hidden rolls, but visible target.",scope:"world",config:!1,default:e,type:Boolean}),game.settings.register("mess","modify-templates",{name:"Activate modified templates.",hint:"Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.register("mess","change-placeables",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.registerMenu("mess","templateTexture",{name:game.i18n.localize("MESS.FVTTSettings.description"),label:game.i18n.localize("MESS.FVTTSettings.button"),icon:"fas fa-mug-hot",type:s,restricted:!0}),game.settings.register("mess","templateTexture",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",default:!0,type:Object}),game.settings.register("mess","max-critical",{name:"Activate maximum critical rolls.",hint:"Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!",scope:"world",config:!1,default:!1,type:Boolean}),game.settings.register("mess","templateTexture",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Object}),game.settings.register("mess","templateAutoTargeting",{scope:"world",default:!0,type:Boolean}),game.settings.register("mess","templateDrawBordersOnlyOnHighlight",{scope:"world",default:!0,type:Boolean}),this.loadTemplates()}static loadTemplates(){loadTemplates(["modules/mess/templates/settings/templates.html","modules/mess/templates/settings/dnd5e.html","modules/mess/templates/settings/misc.html"])}static get defaultOptions(){return{...super.defaultOptions,template:"modules/mess/templates/settings/settings.html",height:"auto",title:"Mess - Moerills enhancing super-suit(e) - Settings Menu",width:600,classes:["mess","settings"],tabs:[{navSelector:".tabs",contentSelector:"form",initial:"name"}],submitOnClose:!0}}constructor(e={},t){super(e,t),this.object=game.settings.get("mess","templateTexture")}_getHeaderButtons(){let e=super._getHeaderButtons();return e[0].label="Save & Close",e}getSettingsData(){const e="dnd5e"===game.system.id;let t={"modify-templates":game.settings.get("mess","modify-templates"),"change-placeables":game.settings.get("mess","change-placeables"),templateTexture:game.settings.get("mess","templateTexture"),templateAutoTargeting:game.settings.get("mess","templateAutoTargeting"),templateDrawBordersOnlyOnHighlight:game.settings.get("mess","templateDrawBordersOnlyOnHighlight"),"better-draggable-lists":game.settings.get("mess","better-draggable-lists")};return e&&(t.templateTexture=game.settings.get("mess","templateTexture"),t["modify-rolling"]=game.settings.get("mess","modify-rolling"),t["max-critical"]=game.settings.get("mess","max-critical"),t["actor-item-sort"]=game.settings.get("mess","actor-item-sort"),t["prepared-spell-tracker"]=game.settings.get("mess","prepared-spell-tracker"),t["add-scrolling"]=game.settings.get("mess","add-scrolling"),t["attack-card-always-public"]=game.settings.get("mess","attack-card-always-public")),t}getData(){const e="dnd5e"===game.system.id;let t=super.getData();return e&&(t.dmgTypes=CONFIG.DND5E.damageTypes,t.templateTypes=CONFIG.MeasuredTemplate.types),t.isDnD=e,t.settings=this.getSettingsData(),t}activateListeners(e){super.activateListeners(e)}_updateObject(e,t){const a=expandObject(t);for(let[e,t]of Object.entries(a))game.settings.set("mess",e,t);new Dialog({content:`

    ${game.i18n.localize("MESS.reloadReminder.text")}

    `,buttons:{yes:{icon:'',label:game.i18n.localize("MESS.reloadReminder.yes"),callback:()=>location.reload()},no:{icon:'',label:game.i18n.localize("MESS.reloadReminder.no")}}}).render(!0)}}}}); +/*! exports provided: MessSettings */function(t,e,s){"use strict";s.r(e),s.d(e,"MessSettings",(function(){return a}));class a extends FormApplication{static init(){const t="dnd5e"===game.system.id;game.settings.register("mess","actor-item-sort",{name:"Activate item sort button.",hint:"Adds a button to actor sheets for sorting all items of that category alphabetically.",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","better-draggable",{name:"Activate better drag'n'drop workflow.",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","better-draggable-lists",{name:"Activate better drag'n'drop workflow for lists.",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.set("mess","better-draggable-lists",!1),game.settings.register("mess","prepared-spell-tracker",{name:"Activate prepared spell tracker",hint:"Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","add-scrolling",{name:"Activating numerical field scrolling.",hint:"Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","modify-rolling",{name:"Alternative Rolling.",hint:"Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","attack-card-always-public",{name:"Roll mode for alternative rolling.",hint:"Always roll attack rolls public, with hidden rolls, but visible target.",scope:"world",config:!1,default:t,type:Boolean}),game.settings.register("mess","modify-templates",{name:"Activate modified templates.",hint:"Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.register("mess","change-placeables",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Boolean}),game.settings.registerMenu("mess","templateTexture",{name:game.i18n.localize("MESS.FVTTSettings.description"),label:game.i18n.localize("MESS.FVTTSettings.button"),icon:"fas fa-mug-hot",type:a,restricted:!0}),game.settings.register("mess","templateTexture",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",default:!0,type:Object}),game.settings.register("mess","max-critical",{name:"Activate maximum critical rolls.",hint:"Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!",scope:"world",config:!1,default:!1,type:Boolean}),game.settings.register("mess","templateTexture",{name:"Activate placeables changes.",hint:"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!",scope:"world",config:!1,default:!0,type:Object}),game.settings.register("mess","templateAutoTargeting",{scope:"world",default:!0,type:Boolean}),game.settings.register("mess","templateDrawBordersOnlyOnHighlight",{scope:"world",default:!0,type:Boolean}),this.loadTemplates()}static loadTemplates(){loadTemplates(["modules/mess/templates/settings/templates.html","modules/mess/templates/settings/dnd5e.html","modules/mess/templates/settings/misc.html"])}static get defaultOptions(){return{...super.defaultOptions,template:"modules/mess/templates/settings/settings.html",height:"auto",title:"Mess - Moerills enhancing super-suit(e) - Settings Menu",width:600,classes:["mess","settings"],tabs:[{navSelector:".tabs",contentSelector:"form",initial:"name"}],submitOnClose:!0}}constructor(t={},e){super(t,e),this.object=game.settings.get("mess","templateTexture")}_getHeaderButtons(){let t=super._getHeaderButtons();return t[0].label="Save & Close",t}getSettingsData(){const t="dnd5e"===game.system.id;let e={"modify-templates":game.settings.get("mess","modify-templates"),"change-placeables":game.settings.get("mess","change-placeables"),templateTexture:game.settings.get("mess","templateTexture"),templateAutoTargeting:game.settings.get("mess","templateAutoTargeting"),templateDrawBordersOnlyOnHighlight:game.settings.get("mess","templateDrawBordersOnlyOnHighlight"),"better-draggable-lists":game.settings.get("mess","better-draggable-lists")};return t&&(e.templateTexture=game.settings.get("mess","templateTexture"),e["modify-rolling"]=game.settings.get("mess","modify-rolling"),e["max-critical"]=game.settings.get("mess","max-critical"),e["actor-item-sort"]=game.settings.get("mess","actor-item-sort"),e["prepared-spell-tracker"]=game.settings.get("mess","prepared-spell-tracker"),e["add-scrolling"]=game.settings.get("mess","add-scrolling"),e["attack-card-always-public"]=game.settings.get("mess","attack-card-always-public")),e}getData(){const t="dnd5e"===game.system.id;let e=super.getData();return t&&(e.dmgTypes=CONFIG.DND5E.damageTypes,e.templateTypes=CONFIG.MeasuredTemplate.types),e.isDnD=t,e.settings=this.getSettingsData(),e}activateListeners(t){super.activateListeners(t)}_updateObject(t,e){const s=expandObject(e);for(let[t,e]of Object.entries(s))game.settings.set("mess",t,e);new Dialog({content:`

    ${game.i18n.localize("MESS.reloadReminder.text")}

    `,buttons:{yes:{icon:'',label:game.i18n.localize("MESS.reloadReminder.yes"),callback:()=>location.reload()},no:{icon:'',label:game.i18n.localize("MESS.reloadReminder.no")}}}).render(!0)}}}}); //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/scripts/index.js.map b/dist/scripts/index.js.map index 51aabe9..774db95 100644 --- a/dist/scripts/index.js.map +++ b/dist/scripts/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/scripts/actor-item-sort-btn.js","webpack:///./src/scripts/add-scrolling.js","webpack:///./src/scripts/change-placeables.js","webpack:///./src/scripts/chat-popup/index.js","webpack:///./src/scripts/draggable-lists/draggable-list.js","webpack:///./src/scripts/draggable-lists/index.js","webpack:///./src/scripts/index.js","webpack:///./src/scripts/modify-templates.js","webpack:///./src/scripts/prepared-spell-tracker.js","webpack:///./src/scripts/rolls/apply-dmg.js","webpack:///./src/scripts/rolls/controls.js","webpack:///./src/scripts/rolls/dice.js","webpack:///./src/scripts/rolls/index.js","webpack:///./src/scripts/rolls/modify-rolling.js","webpack:///./src/scripts/rolls/util.js","webpack:///./src/scripts/settings.js"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","installedModules","__webpack_require__","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","window","oldJsonpFunction","slice","s","async","addAlphabeticalSorter","app","html","actor","_id","querySelectorAll","forEach","el","closest","dataset","tab","btn","innerHTML","classList","add","title","style","flex","margin","addEventListener","ev","lists","actorId","fromUuid","concatList","map","items","spells","flat","sort","a","b","siblings","sortUpdates","SortingHelpers","performIntegerSort","duplicate","sortBefore","updateData","u","update","updateEmbeddedEntity","sortItemListAlphabetically","prepend","itemSortBtn","Hooks","on","addScolling","preventDefault","stopPropagation","deltaY","currentTarget","Number","Math","max","$","change","onDragLeftMove","clones","destination","origin","originalEvent","canvas","_onDragCanvasPan","dx","x","dy","y","snap","previous","momentumThreshold","lambda","prev","prevMomentum","momentum","prevV","v","shiftKey","dest","_original","grid","getSnappedPosition","this","layer","options","gridPrecision","refresh","changePlaceables","PlaceableObject","_onDragLeftMove","initChatPopUp","getElementById","contains","log","DraggableList","container","selector","mergeObject","defaultOptions","_init","offset","time","dir","onDragStart","onDragEnd","onDrop","_items","Array","from","rect","getBoundingClientRect","insideChild","clientY","height","clientX","width","_resetOffsets","idx","_initItem","position","_onDragEnterItem","_onDragLeaveItem","matches","headerRect","top","bottom","TweenLite","to","paddingTop","_over","item","timeEnd","initDraggableLists","oldFun","SidebarDirectory","activateListeners","list","querySelector","SceneDirectory","_onLazyLoadImage","entries","observer","isIntersecting","li","backgroundImage","children","img","unobserve","game","settings","CONFIG","debug","mess","sheet","render","user","isGM","moduleVersion","version","register","default","String","scope","oldVersion","isNewerVersion","init","changeTemplates","newFun","MeasuredTemplate","toString","replace","Function","getTargets","isTokenInside","ret","dndTemplateSettings","system","id","importedJS","import","AbilityTemplate","itemHook","_originalFromItem","fromItem","template","path","getFlag","hasDamage","damage","parts","loadTexture","then","tex","texture","activatePreviewListeners","token","scene","templatePos","startX","startY","currGrid","shape","tokens","getEmbeddedCollection","targets","updateTokenTargets","div","innerText","i18n","localize","formField","inp","dtype","insertAdjacentHTML","button","_activateFilePicker","after","addPreparedSpellTracker","isNPC","tracker","border","preparedSpells","sep","val","isNaN","setFlag","constructor","alignSelf","parentNode","insertBefore","getAllDmg","reduce","getAllVersatile","resultArray","splice","modifyApplyDmg","canApply","canApplyNonVersatile","canApplyVersatile","hasTarget","targetId","hasNoTarget","contextOptionsDmg","condition","icon","callback","applyDamage","content","floor","contextOptionsRoll","ContextMenu","MessContextMenu","find","setProperty","controlled","args","super","_menuItems","menuItems","filteredItems","filter","ol","frag","createDocumentFragment","join","close","_setPosition","_animateOpen","removeClass","sign","amount","card","sceneId","scenes","ui","notifications","Token","getEmbeddedEntity","owner","chatLogHook","advSelector","userId","autoRollSelector","templateData","advantage","normal","disadvantage","autoShow","renderTemplate","active","toggle","set","arr","currIdx","findIndex","remove","newSelected","controls","childNodes","hit","dmg","Boolean","getD20Modifier","getAdvantageSettings","rollD20","adv","nd","mods","halflingLucky","elvenAccuracy","diceFormula","reliableTalent","unshift","d20Mod","Roll","roll","d20","total","tooltip","getTooltip","crit","fumble","showRolls","chatData","CONST","CHAT_MESSAGE_TYPES","OTHER","speaker","alias","rollMode","includes","ChatMessage","getWhisperRecipients","diceSoNice","whispers","blind","dice3d","showForRoll","getToHitData","hasAttack","actorData","itemData","flags","dnd5e","rollData","getRollData","proficient","weaponCriticalThreshold","critical","parseInt","abilityMod","actorBonus","bonuses","actionType","attackBonus","attack","filterJoin","totalModifier","_safeEval","cleanFormula","terms","situationalModifier","mod","formula","rollToHit","disabled","messageId","messages","isAuthor","Item","entityClass","_getChatCardActor","getOwnedItem","itemId","span","customTooltip","split","dataTerms","term","alter","updateMessage","replaceChild","getDmgData","spellLevel","level","versatile","itm","bnsDmgParts","itmData","lbl","DND5E","damageTypes","scaling","newDmgPart","lvl","details","_scaleCantripDamage","_scaleSpellDamage","part","hasInner","evaluate","_dice","concat","dice","pop","rollDmg","contextMenu","nextElementSibling","num","AudioHelper","play","sounds","rolling","toggleItemBonusDamage","itemName","getSpeaker","actors","warn","newState","preCreateChatMessageHook","renderAttack","getFlavor","chatFlavor","rollTables","matchAll","collection","tables","tableData","table","match","entities","result","results","text","areaSkill","keys","areaTargetTypes","getProperty","size","attackData","toHit","dmgs","autoroll","allowed","_handleResourceConsumption","isCard","isAttack","targetActor","targetData","ac","label","attributes","di","traits","toUpperCase","substring","custom","dr","dv","displayName","TOKEN_DISPLAY_MODES","ALWAYS","HOVER","attackTemplateData","flavor","autoRoll","whisper","dsn","rolls","toHitBtn","btns","actorSheetHook","abilityMods","off","abilityId","ability","abilities","feats","remarkableAthlete","characterFlags","ceil","prof","jackOfAllTrades","checkBonus","format","saveMods","rollAbilitySave","skills","skillId","skill","skl","bonus","chatListeners","onChatCardAction","_onChatCardToggleContent","onMouseEnterTarget","onMouseLeaveTarget","onDblClickTarget","onToggleShowPlayers","action","placeTemplate","_onChatCardAction","getTargetToken","_onHoverIn","visible","_onHoverOut","pos","center","animatePan","tokenId","placeables","checked","once","Actor","abl","saveBonus","MessSettings","FormApplication","isDnD","hint","config","registerMenu","restricted","loadTemplates","classes","tabs","navSelector","contentSelector","initial","submitOnClose","_getHeaderButtons","getData","dmgTypes","templateTypes","types","getSettingsData","formData","expandObject","Dialog","buttons","yes","location","reload","no"],"mappings":"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","file":"index.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t};\n\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"index\": 0\n \t};\n\n\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"bundles/\" + ({\"welcome-screen\":\"welcome-screen\"}[chunkId]||chunkId) + \".\" + {\"welcome-screen\":\"a969\"}[chunkId] + \".js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"modules/mess/scripts/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/scripts/index.js\");\n","async function sortItemListAlphabetically(lists, actorId) {\n\tconst actor = await fromUuid(`Actor.${actorId}`);\n\tlet concatList = lists.map(e => e.items || e.spells).flat();\n\tconcatList.sort(function (a, b) {\n\t\tif (a.name < b.name) return -1;\n\t\tif (a.name > b.name) return 1;\n\t\treturn 0;\n\t});\n\tlet siblings = [concatList.shift()];\n\tlet sortUpdates = [];\n\tfor (; concatList.length > 0; siblings.push(concatList.shift())) {\n\t\tsortUpdates = (SortingHelpers.performIntegerSort(concatList[0], {\n\t\t\ttarget: siblings[siblings.length-1], \n\t\t\tsiblings: duplicate(siblings),\n\t\t\tsortBefore: false}));\t\t\n\t}\n\tconst updateData = sortUpdates.map(u => {\n\t\tlet update = u.update;\n\t\tupdate._id = u.target._id;\n\t\treturn update;\n\t})\n\tactor.updateEmbeddedEntity('OwnedItem', updateData);\n}\n\nasync function addAlphabeticalSorter(app, html, data) {\n\tif (!data.actor._id) return;\n\tconst header = html.querySelectorAll('.filter-list');\n\n\theader.forEach(el => {\n\t\tconst type = el.closest('.tab').dataset.tab;\n\t\tconst btn = document.createElement('a');\n\t\tbtn.innerHTML = '';\n\t\tbtn.classList.add('mess-sort-btn');\n\t\tbtn.title = `Sort ${type} alphabetically.`;\n\t\tbtn.style.flex = 0;\n\t\tbtn.style.margin = \"0 5px 0 0\";\n\t\tbtn.addEventListener('click',\t(ev) => sortItemListAlphabetically(data[type], data.actor._id))\n\t\tel.prepend(btn);\n\t});\n}\n\nexport default async function itemSortBtn() {\n\tHooks.on('renderActorSheet', (app, html, data) => {\n\t\taddAlphabeticalSorter(app, html[0], data);\n\t});\n}","export default async function addScolling() {\n\tHooks.on('renderActorSheet', async function (app, html, data) {\n\t\thtml[0].querySelectorAll('input[data-dtype=\"Number\"], .item-uses input').forEach(el => {\n\t\t\tel.addEventListener('wheel', ev => {\n\t\t\t\tev.preventDefault();\n\t\t\t\tev.stopPropagation();\n\t\t\t\tif (ev.deltaY < 0)\n\t\t\t\t\tev.currentTarget.value = Number(ev.currentTarget.value) + 1;\n\t\t\t\tif (ev.deltaY > 0)\n\t\t\t\t\tev.currentTarget.value = Math.max(Number(ev.currentTarget.value) - 1, 0);\n\n\t\t\t\t$(ev.currentTarget).change()\n\t\t\t});\n\t\t})\n\t});\n}","function onDragLeftMove(event) {\n\tconst {clones, destination, origin, originalEvent} = event.data;\n\n\t// Pan the canvas if the drag event approaches the edge\n\tcanvas._onDragCanvasPan(originalEvent);\n\n\t// Determine dragged distance\n\tconst dx = destination.x - origin.x;\n\tconst dy = destination.y - origin.y;\n\n\tlet snap = false;\n\tif (event.data.previous) {\n\t\t// Interesting would be here how this all behaves for different monitor sizes/performances and when Atro possibly introduces more adaptive rates for mosue movement. \n\t\t// Why? Because currently i just set the timedifferences between function calls to 1. So for 60Hz it behaves same as 30Hz although for 30Hz the distance travelled could be bigger.\n\t\t// All this because i don't want divisions in here for the moment....\n\t\tconst momentumThreshold = 30;\n\t\t// smaller lambda means less \"memory\" => current momentum does have more impact\n\t\t// => more jumping around between snapping and not\n\t\t// but higher means more waiting/slow movement time for it to snap\n\t\tconst lambda = 0.8;\n\t\tconst prev = event.data.previous;\n\t\tconst prevMomentum = event.data.momentum || 0;\n\t\tconst prevV = event.data.v || {x: 0, y: 0};\n\t\tconst v = {\n\t\t\tx: destination.x - prev.x,\n\t\t\ty: destination.y - prev.y\n\t\t}\n\t\tconst momentum = {\n\t\t\tx: v.x - prevV.x,\n\t\t\ty: v.y - prevV.y\n\t\t};\n\n\t\tevent.data.momentum = (momentum.x * momentum.x + momentum.y * momentum.y) + prevMomentum * lambda;\n\t\tsnap = !event.shiftKey && event.data.momentum < momentumThreshold;\n\t}\n\n\tevent.data.previous = destination;\n\n\t// Update the position of each clone\n\tfor ( let c of clones || [] ) {\n\t\tlet dest = {x: c._original.data.x + dx, y: c._original.data.y + dy};\n\t\tif ( snap ) {\n\t\t\tdest = canvas.grid.getSnappedPosition(dest.x, dest.y, this.layer.options.gridPrecision);\n\t\t}\n\t\tc.data.x = dest.x;\n\t\tc.data.y = dest.y;\n\t\tc.refresh();\n\t}\n}\n\nexport function changePlaceables() {\n\tPlaceableObject.prototype._onDragLeftMove = onDragLeftMove;\n\t// Change got bigger than expected, so.. complete swap it is\n}","export function initChatPopUp() {\n\tHooks.on('renderChatMessage', (app, html, options) => {\n\t\tif (document.getElementById('chat').classList.contains('active')) return;\n\n\n\t\tconsole.log('rendering chat message');\n\t\tconsole.log(app, html, options);\n\t\tconsole.log(document.getElementById('chat').classList.contains('active'))\n\t});\n\n\tconst hud = document.getElementById('hud');\n\n\tlet popupDiv = hud.appendChild(document.createElement('div'));\n\tpopupDiv.classList.add('mess-chat-popup')\n}","//import { TweenLite } from '/scripts/greensock/esm/all.js';\n\nexport class DraggableList {\n\tconstructor(container, selector, options = {}) {\n\t\tthis.container = container;\n\t\tthis.selector = selector;\n\t\tthis.options = mergeObject(this.defaultOptions, options);\n\n\t\tthis._init();\n\t}\n\n\tget defaultOptions() {\n\t\treturn {\n\t\t\toffset: 21, // in px\n\t\t\ttime: 0.2, // in seconds\n\t\t\tdir: null, // this selector will not get offset when hovered over\n\t\t\t// folowing are not used\n\t\t\tonDragStart: null,\n\t\t\tonDragEnd: null,\n\t\t\tonDrop: null,\n\t\t};\n\t}\n\n\tasync _init() {\n\t\t// this._items = Array.from(this.container.childNodes).filter(e => e.matches && e.matches(this.selector));\n\t\tthis._items = Array.from(this.container.querySelectorAll(this.selector));\n\t\tthis.container.addEventListener('dragleave', (ev) => {\n\t\t\tconst rect = this.container.getBoundingClientRect();\n\t\t\tconst boundary = 5;\n\t\t\t// Reset offsets, when first target was inside a child container.\n\t\t\tconst insideChild = ev.insideChild;\n\t\t\tif (\n\t\t\t\t!insideChild &&\n\t\t\t\tev.clientY < rect.y + rect.height - boundary &&\n\t\t\t\tev.clientY > rect.y + boundary &&\n\t\t\t\tev.clientX > rect.x + boundary &&\n\t\t\t\tev.clientX < rect.x - boundary + rect.width\n\t\t\t) {\n\t\t\t\tev.insideChild = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._resetOffsets();\n\t\t});\n\n\t\t/** Possibly modifying the drop target.\n\t\t * Why?\n\t\t * Due to the method used, the target gets moved out of the way and it will automatically drop onto the container element.\n\t\t * Most drop functions in fvtt just append to the end though, when dropping onto the container.\n\t\t * => We search for the first offset element and define that one as target. Since default for sorting is \"insertBefore\", and most implementations i've found build upon FVTT default/dnd5e systems default, this is a rather save implementation to find the real target.\n\t\t */\n\t\tthis.container.addEventListener('drop', (ev) => {\n\t\t\t// const insideChild = ev.insideChild;\n\t\t\t// if (this._over) {\n\t\t\t// \tObject.defineProperty(ev, 'target', {writable: false, value: this._over})\n\t\t\t// \t// Make sure that outer directories are not overwriting this stuff!\n\t\t\t// \t// ev.insideChild = true;\n\t\t\t// }\n\t\t});\n\t\tthis._items.forEach((e, idx) => this._initItem(e, idx));\n\t}\n\n\tasync _initItem(el, idx) {\n\t\tel.style.position = 'relative';\n\t\tel.addEventListener('dragenter', (ev) => this._onDragEnterItem(ev, idx));\n\t\tel.addEventListener('dragleave', (ev) => this._onDragLeaveItem(ev, idx));\n\t\tel.addEventListener('dragend', (ev) => {\n\t\t\t// safety net if for some reasons the rerender is to slow or fails...\n\t\t\t// const srcElement = ev.currentTarget;\n\t\t\t// srcElement.style.opacity = null;\n\t\t\t// srcElement.style.height = null;\n\t\t\t// TweenLite.from(srcElement, this.options.time, {opacity:0, height:0});\n\t\t\tthis._resetOffsets();\n\t\t});\n\t\t// el.addEventListener('dragstart', ev => {\n\t\t// \tthis._dragged = ev.currentTarget;\n\t\t// \t// if (ev.currentTarget.matches(this.dir))\n\t\t// \t// \tthis._draggingDir = true;\n\t\t// \t// else\n\t\t// \t// \tthis._draggingDir = false;\n\t\t// \t// TweenLite.to(ev.currentTarget, this.options.time, {opacity: 0, height: 0});\n\t\t// })\n\t}\n\n\t_onDragEnterItem(ev, idx) {\n\t\tconsole.time('dragEnter');\n\t\tev.stopPropagation();\n\n\t\t// // save the current target\n\t\tconst time = this.options.time;\n\t\tconst offset = this.options.offset;\n\t\tthis._resetOffsets();\n\t\tlet target = ev.currentTarget;\n\t\tconsole.log(ev.currentTarget);\n\t\t// if inside a container, just make sure that its not jumping around. (Sometimes its ignoring the real target...)\n\t\tif (target.matches(this.options.dir)) {\n\t\t\tconst items = Array.from(target.querySelectorAll(this.selector));\n\t\t\tconst headerRect = target.getBoundingClientRect();\n\t\t\tif (ev.clientY > headerRect.top && ev.clientY < headerRect.bottom) {\n\t\t\t\tTweenLite.to(items, time, { paddingTop: 0 });\n\t\t\t\tthis._over = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (let item of items) {\n\t\t\t\tconst rect = item.getBoundingClientRect();\n\t\t\t\tif (rect.bottom > ev.clientY) {\n\t\t\t\t\ttarget = item;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._over = target;\n\t\tconsole.log(target, offset);\n\t\tTweenLite.to(target, time, { paddingTop: offset });\n\t\t// let resetList = [];\n\t\t// let offsetList = [];\n\t\t// let prev = item.previousElementSibling;\n\t\t// while (prev) {\n\t\t// \t// TweenLite.to(prev, time, {top: 0})\n\t\t// \tresetList.push(prev);\n\t\t// \tprev = prev.previousElementSibling;\n\t\t// }\n\t\t// let next = item;\n\t\t// while (next) {\n\t\t// \tif (!this._draggingDir && next.matches(this.options.dir)) {\n\t\t// \t\t// TweenLite.to(next, time, {top: 0});\n\t\t// \t\tresetList.push(next);\n\t\t// \t} else\n\t\t// \t\toffsetList.push(next);\n\t\t// \t\t// TweenLite.to(next, time, {top: offset});\n\t\t// \tnext = next.nextElementSibling;\n\t\t// }\n\n\t\t// // // if (ev.currentTarget.matches(this.options.dir)) {\n\n\t\t// // // \tidx = idx + 1;\n\t\t// // // }\n\t\t// // // for (let i = idx; i < this._items.length; i++) {\n\t\t// // // \tconst rect = this._items[i].getBoundingClientRect();\n\t\t// // // }\n\t\t// // const resetList = this._items.slice(0, idx);\n\t\t// TweenLite.to(resetList, time, {top: 0});\n\t\t// // const offsetList = this._items.slice(idx);\n\t\t// TweenLite.to(offsetList, time, {top: offset});\n\n\t\tconsole.timeEnd('dragEnter');\n\t\treturn false;\n\t}\n\n\t_onDragLeaveItem(ev, idx) {\n\t\t// console.time('dragLeave')\n\t\tev.stopPropagation();\n\t\treturn false;\n\t\t// // Empty for now?\n\n\t\t// TweenLite.to(ev.currentTarget, 0.3, {transform: \"scale(1, 1)\"});\n\t\t// console.timeEnd('dragLeave')\n\t}\n\n\t// We now work with padding, cause.. reasons..\n\t_resetOffsets(time = this.options.time) {\n\t\t// TweenLite.to(this._items, time, {top: 0});\n\t\tTweenLite.to(this._items, time, { paddingTop: 0 });\n\t}\n}\n","import {DraggableList} from './draggable-list';\n\nexport function initDraggableLists() {\n // make sure my listeners to get bound _before_ the class owns get bound to the elements\n // Only needed for the \"root\" directory though.. :/\n const oldFun = SidebarDirectory.prototype.activateListeners;\n SidebarDirectory.prototype.activateListeners = function(html) {\n // const list = html[0].querySelectorAll('.directory-list, .directory-item');\n // list.forEach(e => new DraggableList(e, '.entity'));\n const list = html[0].querySelector('.directory-list');\n new DraggableList(list, '.entity, .folder', {dir: '.folder'});\n oldFun.call(this, html);\n }\n\n // this does work, since on default most sheets have their drop function bound to the form, not the item list!\n Hooks.on('renderActorSheet', (app, html, options) => {\n const list = html[0].querySelectorAll('.item-list');\n list.forEach(e => new DraggableList(e, '.item'));\n });\n\n SceneDirectory.prototype._onLazyLoadImage = function(entries, observer) {\n for ( let e of entries ) {\n if ( !e.isIntersecting ) continue;\n const li = e.target;\n\n // Background Image\n if ( li.dataset.backgroundImage ) {\n li.children[0].style[\"background-image\"] = `url(\"${li.dataset.backgroundImage}\")`;\n delete li.dataset.backgroundImage;\n }\n\n // Avatar image\n const img = li.querySelector(\"img\");\n if ( img && img.dataset.src ) {\n img.src = img.dataset.src;\n delete img.dataset.src;\n }\n\n // No longer observe the target\n observer.unobserve(e.target);\n }\n }\n}","import { rolling } from './rolls';\nimport { MessSettings } from './settings.js';\nimport { dndTemplateSettings, changeTemplates } from './modify-templates.js';\nimport { changePlaceables } from './change-placeables.js';\nimport itemSortBtn from './actor-item-sort-btn.js';\nimport preparedSpellTracker from './prepared-spell-tracker.js';\nimport addScrolling from './add-scrolling.js';\n\nimport { initDraggableLists } from './draggable-lists';\nimport { initChatPopUp } from './chat-popup';\n\nHooks.on('ready', async function () {\n\tif (game.settings.get('mess', 'actor-item-sort')) itemSortBtn();\n\tif (game.settings.get('mess', 'prepared-spell-tracker'))\n\t\tpreparedSpellTracker();\n\tif (game.settings.get('mess', 'add-scrolling')) addScrolling();\n\n\tif (CONFIG.debug.mess) {\n\t\tconst actor = await fromUuid('Actor.xV3LUAg05Pz5MFTS');\n\t\tactor.sheet.render(true);\n\t}\n\n\t// initChatPopUp();\n\n\tif (!game.user.isGM) return;\n\t// Edit next line to match module.\n\tconst module = game.modules.get('mess');\n\tconst title = module.data.title;\n\tconst moduleVersion = module.data.version;\n\tgame.settings.register(title, 'version', {\n\t\tname: `${title} Version`,\n\t\tdefault: '0.0.0',\n\t\ttype: String,\n\t\tscope: 'world',\n\t});\n\tconst oldVersion = game.settings.get(title, 'version');\n\n\tif (!isNewerVersion(moduleVersion, oldVersion)) return;\n\n\t(\n\t\tawait import(\n\t\t\t/* webpackChunkName: \"welcome-screen\" */\n\t\t\t'./welcome-screen.js'\n\t\t)\n\t).default();\n});\n\nHooks.on('init', function () {\n\tgame.mess = {};\n\tCONFIG.debug.mess = false;\n\tMessSettings.init();\n\n\trolling();\n\n\tdndTemplateSettings();\n\tchangeTemplates();\n\tif (game.settings.get('mess', 'change-placeables')) changePlaceables();\n\t//\tif (game.settings.get('mess', 'better-draggable-lists'))\n\t//\t\tinitDraggableLists();\n});\n","export function changeTemplates() {\n\t// #MonkeyPatchingFTW\n\t// better than stealing the code, replacing one line and then release it under a/the wrong license..\n\t// Disadvantage: could need more fixing on updates. At least i didn#t make it line based like Kakaroto.. :P\n\n\tlet newFun = MeasuredTemplate.prototype.refresh.toString();\n\n\tif (game.settings.get('mess', 'modify-templates')) {\n\t\tnewFun = newFun.replace(\n\t\t\t/this\\.template\\.beginTextureFill\\(\\{[\\s\\S]*\\}\\)\\;/,\n\t\t\t`\n\t\t\t{\n\t\t\t\tlet mat = PIXI.Matrix.IDENTITY;\n\t\t\t\t// rectangle\n\t\t\t\tif (this.shape.width && this.shape.height)\n\t\t\t\t\tmat.scale(this.shape.width / this.texture.width, this.shape.height / this.texture.height);\n\t\t\t\telse if (this.shape.radius) {\n\t\t\t\t\tmat.scale(this.shape.radius * 2 / this.texture.height, this.shape.radius * 2 / this.texture.width)\n\t\t\t\t\t// Circle center is texture start...\n\t\t\t\t\tmat.translate(-this.shape.radius, -this.shape.radius);\n\t\t\t\t} else if (this.data.t === \"ray\") {\n\t\t\t\t\tconst d = canvas.dimensions,\n\t\t\t\t\t\t\t\theight = this.data.width * d.size / d.distance,\n\t\t\t\t\t\t\t\twidth = this.data.distance * d.size / d.distance;\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height * 0.5);\n\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t} else {// cone\n\t\t\t\t\tconst d = canvas.dimensions;\n\t\t\t\n\t\t\t\t\t// Extract and prepare data\n\t\t\t\t\tlet {direction, distance, angle} = this.data;\n\t\t\t\t\tdistance *= (d.size / d.distance);\n\t\t\t\t\tdirection = toRadians(direction);\n\t\t\t\t\tconst width = this.data.distance * d.size / d.distance;\n\n\t\t\t\t\tconst angles = [(angle/-2), (angle/2)];\n\t\t\t\t\tdistance = distance / Math.cos(toRadians(angle/2));\n\t\t\t\n\t\t\t\t\t// Get the cone shape as a polygon\n\t\t\t\t\tconst rays = angles.map(a => Ray.fromAngle(0, 0, direction + toRadians(a), distance+1));\n\t\t\t\t\tconst height = Math.sqrt((rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x)\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y));\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height/2)\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t}\n\t\t\t\tthis.template.beginTextureFill({\n\t\t\t\t\ttexture: this.texture,\n\t\t\t\t\tmatrix: mat,\n\t\t\t\t\talpha: 0.8\n\t\t\t\t});\n\t\t\t\t// move into draw or so\n\t\t\t\tconst source = getProperty(this.texture, \"baseTexture.resource.source\")\n\t\t\t\tif ( source && (source.tagName === \"VIDEO\") ) {\n\t\t\t\t\tsource.loop = true;\n\t\t\t\t\tsource.muted = true;\n\t\t\t\t\tgame.video.play(source);\n\t\t\t\t}\n\t\t}`\n\t\t);\n\n\t\tHooks.on('renderMeasuredTemplateConfig', (app, html, data) => {\n\t\t\thtml[0].querySelector('.file-picker').dataset.type = 'imagevideo';\n\t\t});\n\t}\n\n\tif (game.settings.get('mess', 'templateDrawBordersOnlyOnHighlight')) {\n\t\tnewFun = newFun.replace(\n\t\t\t/this\\.\\_borderThickness/,\n\t\t\t'this.texture && !this._hover ? 0 : this._borderThickness'\n\t\t);\n\t\tnewFun = newFun.replace(\n\t\t\t/return\\sthis\\;/,\n\t\t\t`\n\t\t\tconst grid = canvas.grid;\n\t\t\t// only show grid highlights on hover\n\t\t\tif (this.texture) {\n\t\t\t\tconst hl = grid.getHighlightLayer(\\`Template.\\$\\{this.id\\}\\`);\n\t\t\t\tif (hl)\n\t\t\t\t\thl.renderable = this._hover;\n\t\t\t}\n\t\t\treturn this;`\n\t\t);\n\t}\n\n\tMeasuredTemplate.prototype.refresh = Function(\n\t\t`\"use strict\"; return ( function ${newFun} )`\n\t)();\n\n\tif (game.settings.get('mess', 'templateAutoTargeting')) {\n\t\tMeasuredTemplate.prototype.getTargets = getTargets;\n\t\tMeasuredTemplate.prototype.isTokenInside = isTokenInside;\n\n\t\tconst oldFun = MeasuredTemplate.prototype._onDragLeftMove;\n\t\tMeasuredTemplate.prototype._onDragLeftMove = function (ev) {\n\t\t\tconst ret = oldFun.bind(this)(ev);\n\n\t\t\tfor (let c of ev.data.clones) this.getTargets(c);\n\n\t\t\treturn ret;\n\t\t};\n\t}\n}\n\nexport async function dndTemplateSettings() {\n\tif (game.system.id !== 'dnd5e') return;\n\n\tconst importedJS = await import(\n\t\t/* webpackIgnore: true */ '/systems/dnd5e/module/pixi/ability-template.js'\n\t);\n\tconst AbilityTemplate = importedJS.default || importedJS.AbilityTemplate;\n\n\t// Auto texture creation from item\n\tif (game.settings.get('mess', 'modify-templates')) {\n\t\tHooks.on('renderItemSheet', itemHook);\n\n\t\tconst _originalFromItem = AbilityTemplate.fromItem;\n\t\tAbilityTemplate.fromItem = function (item) {\n\t\t\tconst template = _originalFromItem.bind(this)(item);\n\n\t\t\t// generate a texture based on the items dmg type, ...\n\t\t\t// Add settings to define custom templates for stuff.\n\t\t\tlet path = item.getFlag('mess', 'templateTexture');\n\t\t\tif (!path && item.hasDamage) {\n\t\t\t\tconst settings = game.settings.get('mess', 'templateTexture') || {};\n\t\t\t\tpath = settings[item.data.data.damage.parts[0][1]] || {};\n\t\t\t\tpath = path[template.data.t];\n\t\t\t}\n\t\t\tif (path)\n\t\t\t\tloadTexture(path).then((tex) => {\n\t\t\t\t\ttemplate.texture = tex;\n\t\t\t\t\ttemplate.data.texture = path;\n\t\t\t\t\ttemplate.refresh();\n\t\t\t\t});\n\t\t\ttemplate.item = item;\n\t\t\treturn template;\n\t\t};\n\t}\n\n\tif (game.settings.get('mess', 'templateAutoTargeting')) {\n\t\t// rather ugly, maybe find a better way at some point :shrug:\n\t\tconst origPrevListeners = AbilityTemplate.prototype.activatePreviewListeners.toString();\n\t\tconst newFun = origPrevListeners.replace(\n\t\t\t/this\\.refresh\\(\\)\\;/,\n\t\t\t// get targets\n\t\t\t`this.refresh();\n\t\t\t\t\t\tthis.getTargets(this);\n\t\t\t\t\t`\n\t\t);\n\n\t\tAbilityTemplate.prototype.getTargets = getTargets;\n\t\tAbilityTemplate.prototype.isTokenInside = isTokenInside;\n\n\t\tAbilityTemplate.prototype.activatePreviewListeners = Function(\n\t\t\t`\"use strict\"; return ( function ${newFun} )`\n\t\t)();\n\t}\n}\n\nfunction isTokenInside(token) {\n\tconst grid = canvas.scene.data.grid,\n\t\ttemplatePos = { x: this.data.x, y: this.data.y };\n\t// Check for center of each square the token uses.\n\t// e.g. for large tokens all 4 squares\n\tconst startX = token.width >= 1 ? 0.5 : token.width / 2;\n\tconst startY = token.height >= 1 ? 0.5 : token.height / 2;\n\tfor (let x = startX; x < token.width; x++) {\n\t\tfor (let y = startY; y < token.height; y++) {\n\t\t\tconst currGrid = {\n\t\t\t\tx: token.x + x * grid - templatePos.x,\n\t\t\t\ty: token.y + y * grid - templatePos.y,\n\t\t\t};\n\t\t\tconst contains = this.shape.contains(currGrid.x, currGrid.y);\n\t\t\tif (contains) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction getTargets(template) {\n\tconst tokens = canvas.scene.getEmbeddedCollection('Token');\n\tlet targets = [];\n\n\tfor (const token of tokens)\n\t\tif (template.isTokenInside(token)) {\n\t\t\ttargets.push(token._id);\n\t\t}\n\tgame.user.updateTokenTargets(targets);\n}\n\nasync function itemHook(app, html) {\n\tconst div = document.createElement('div');\n\tdiv.classList.add('form-group');\n\tdiv.appendChild(\n\t\tdocument.createElement('label')\n\t).innerText = game.i18n.localize('MESS.itemSheet.templateTexture');\n\tconst formField = div.appendChild(document.createElement('div'));\n\tformField.classList.add('form-fields');\n\tconst inp = formField.appendChild(document.createElement('input'));\n\tinp.dataset.dtype = 'String';\n\tinp.type = 'text';\n\tinp.name = 'flags.mess.templateTexture';\n\tinp.value = app.object.getFlag('mess', 'templateTexture') || '';\n\n\tformField.insertAdjacentHTML(\n\t\t'beforeend',\n\t\t`\n\t\t\n\t`\n\t);\n\tconst button = formField.querySelector('button');\n\tbutton.style.flex = '0';\n\tapp._activateFilePicker(button);\n\tconst target = html[0].querySelector('[name=\"data.target.units\"]');\n\tif (target) target.closest('.form-group').after(div);\n}\n","export default async function addPreparedSpellTracker() {\n\tHooks.on('renderActorSheet', async function (app, html, data) {\n\t\tconst actor = await fromUuid(`Actor.${data.actor._id}`);\n\t\tif (actor.isNPC) return;\n\t\t\n\t\tconst spellDc = html[0].querySelector('.spell-dc');\n\t\tif (!spellDc) return;\n\t\tlet tracker = document.createElement('div');\n\t\ttracker.classList.add('spell-detail');\n\t\ttracker.classList.add('spell-slots');\n\t\ttracker.style.flex = '1';\n\t\ttracker.style.border = 'none';\n\t\tconst spanPrep = tracker.appendChild(document.createElement('span'));\n\t\tspanPrep.innerText = `${game.i18n.localize('MESS.actorSheet.preparedSpellTracker')}: ${data.preparedSpells}`;\n\n\t\tconst sep = tracker.appendChild(document.createElement('span'));\n\t\tsep.innerText = ' / ';\n\t\tsep.classList.add('sep');\n\n\t\tconst max = tracker.appendChild(document.createElement('input'));\n\t\tmax.type = 'text';\n\t\tmax.value = actor.getFlag('mess', 'maxPreparedSpells') || 0;\n\t\tmax.addEventListener('change', async function(ev) {\n\t\t\tev.preventDefault();\n\t\t\tev.stopPropagation();\n\t\t\tconst val = Number(ev.currentTarget.value);\n\t\t\tif (isNaN(val)) {\n\t\t\t\tev.currentTarget.value = actor.getFlag('mess', 'maxPreparedSpells') || 0;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tactor.setFlag('mess', 'maxPreparedSpells', val);\n\t\t\treturn false;\n\t\t});\n\t\t\n\t\tif (app.constructor.name === 'Tidy5eSheet') {\n\t\t\tconst el = html[0].querySelector('.spellcasting-ability');\n\t\t\tif (!el)\n\t\t\t\treturn;\n\t\t\tel.appendChild(tracker, el);\n\t\t} else {\n\t\t\tconst el = html[0].querySelector('.spellbook .inventory-list');\n\t\t\tif (!el)\treturn;\n\t\t\ttracker.style.flex = '0';\n\t\t\ttracker.style.alignSelf = 'flex-start';\n\t\t\ttracker.style.margin = '0 8px';\n\t\t\tel.parentNode.insertBefore(tracker, el);\n\t\t}\n\t});\n}","function getAllDmg(li) {\n\tconst results = Array.from(li[0].parentNode.querySelectorAll('.mess-dice-result:not(.mess-versatile')).map(e => Number(e.querySelector('span').innerText));\n\treturn results.reduce((a, b) => a + b, 0);\n}\n\nfunction getAllVersatile(li) {\n\tconst resultArray = Array.from(li[0].parentNode.querySelectorAll('.mess-dice-result'));\n\tif (resultArray.length > 1 && resultArray[1].classList.contains('mess-versatile'))\n\t\tresultArray.splice(0,1)\n\tconst results = resultArray.map(e => Number(e.querySelector('span').innerText));\n\treturn results.reduce((a, b) => a + b, 0);\n}\n\nexport default function modifyApplyDmg() {\n\tconst canApply = (li) => true || canvas.tokens.controlled.length;\n\tconst canApplyNonVersatile = (li) => canApply(li) && li[0].parentNode.querySelector('.mess-dice-result:not(.mess-versatile)');\n\tconst canApplyVersatile = (li) => canApply(li) && li[0].parentNode.querySelector('.mess-versatile');\n\tconst hasTarget = (li) => !!li[0].closest('.mess-attack-card').dataset.targetId;\n\tconst hasNoTarget = (li) => !hasTarget(li);\n\tconst contextOptionsDmg = [\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.applyTarget\"),\n\t\t\tcondition: hasTarget\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.applySelected\"),\n\t\t\tcondition: hasNoTarget\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.dmg\"),\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${getAllDmg(li)}`\n\t\t},\n\t\t{\n\t\t\tname: 'half',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.max(Math.floor(getAllDmg(li) * 0.5), 1)}`\n\t\t},\n\t\t{\n\t\t\tname: 'double',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.floor(getAllDmg(li) * 2)}`\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.healing\"),\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyNonVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, -1),\n\t\t\tcontent: (li) => `${getAllDmg(li)}`\n\t\t},\n\t\t{\n\t\t\tname: [game.i18n.localize('DND5E.Versatile'), ' - ', game.i18n.localize(\"MESS.attackCard.contextMenu.dmg\")],\n\t\t\tcondition: canApplyVersatile,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${getAllVersatile(li)}`\n\t\t},\n\t\t{\n\t\t\tname: 'half',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.max(Math.floor(getAllVersatile(li) * 0.5), 1)}`\n\t\t},\n\t\t{\n\t\t\tname: 'double',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.floor(getAllVersatile(li) * 2)}`\n\t\t},\n\t\t{\n\t\t\tname: [game.i18n.localize('DND5E.Versatile'), ' - ', game.i18n.localize(\"MESS.attackCard.contextMenu.healing\")],\n\t\t\tcondition: canApplyVersatile,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApplyVersatile,\n\t\t\tcallback: (target, li) => applyDamage(li, -1),\n\t\t\tcontent: (li) => `${getAllVersatile(li)}`\n\t\t}\n\t]\n\n\n\tconst contextOptionsRoll = [\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.applyTarget\"),\n\t\t\tcondition: hasTarget\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.applySelected\"),\n\t\t\tcondition: hasNoTarget\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.dmg\"),\n\t\t\tcondition: canApply,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApply,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${li[0].querySelector('span').innerText}`\n\t\t},\n\t\t{\n\t\t\tname: 'half',\n\t\t\ticon: '',\n\t\t\tcondition: canApply,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.max(Math.floor(Number(li[0].querySelector('span').innerText) * 0.5), 1)}`\n\t\t},\n\t\t{\n\t\t\tname: 'double',\n\t\t\ticon: '',\n\t\t\tcondition: canApply,\n\t\t\tcallback: (target, li) => applyDamage(li, 1),\n\t\t\tcontent: (li) => `${Math.floor(Number(li[0].querySelector('span').innerText) * 2)}`\n\t\t},\n\t\t{\n\t\t\tname: game.i18n.localize(\"MESS.attackCard.contextMenu.healing\"),\n\t\t\tcondition: canApply,\n\t\t\ticon: ''\n\t\t},\n\t\t{\n\t\t\tname: 'full',\n\t\t\ticon: '',\n\t\t\tcondition: canApply,\n\t\t\tcallback: (target, li) => applyDamage(li, -1),\n\t\t\tcontent: (li) => `${li[0].querySelector('span').innerText}`\n\t\t}\n\t]\n\n\n\tContextMenu.prototype.bind = Function('\"use strict\"; return ( function ' + ContextMenu.prototype.bind.toString().replace(/this\\.render\\(parent\\)/,`this.render(parent, event)`) + ')')();\n\n\tHooks.on('renderChatLog', (app, html, options) => {\n\t\tnew MessContextMenu(html.find('#chat-log'), \".mess-chat-dmg .mess-dice-result\", contextOptionsRoll);\n\t\tnew MessContextMenu(html.find('#chat-log'), \".mess-chat-dmg .mess-chat-roll-type\", contextOptionsDmg);\n\t})\n\n\tHooks.on('getChatLogEntryContext', function (html, options) {\n\t\tsetProperty(game, 'mess.chatLogEntryContextOptions', options);\n\t\t\n\t\t// Modify existing applies to only work on default rolls and not mess-rolls\n\t\tconst canApply = li => canvas.tokens.controlled.length \n\t\t\t\t\t\t\t\t\t\t\t\t&& li.find(\".dice-roll .dice-result\").length;\n\t\tfor (let i = 1; i < options.length; i++) \n\t\t\toptions[i].condition = canApply;\n\t});\n}\n\nclass MessContextMenu extends ContextMenu {\n\tconstructor(...args) {\n\t\tsuper(...args);\n\n\t\tthis._menuItems = this.menuItems;\n\t}\n\n\trender(target, event) {\n\t\tconst filteredItems = this._menuItems.filter(item => {\n\t\t\tif (!item.condition) return true;\n\t\t\tif (!(item.condition instanceof Function)) return item.condition;\n\t\t\treturn item.condition(target);\n\t\t})\n\n\t\tif (filteredItems.length) event.stopPropagation();\n\t\telse return;\n\t\tthis.menuItems = filteredItems.map(e => {\n\t\t\tif (e.content)\n\t\t\t\te.name = e.content(target);\n\t\t\treturn e;\n\t\t});\n\n let html = $(\"#context-menu\").length ? $(\"#context-menu\") : $('');\n let ol = $('
      ');\n html.html(ol);\n\n\t\tconst frag = document.createDocumentFragment();\n\t\tfor (let item of this.menuItems) {\n\t\t\tconst li = document.createElement('li')\n\t\t\t\n\t\t\tif (item.name instanceof Array)\n\t\t\t\titem.name = item.name.map(e => game.i18n.localize(e)).join(\"\");\n\n\t\t\tif (item.icon)\n\t\t\t\tli.innerHTML = `${item.icon}${game.i18n.localize(item.name)}`;\n\t\t\telse\n\t\t\t\tli.innerHTML = game.i18n.localize(item.name);\n\n\t\t\tif (item.callback) {\n\t\t\t\tli.addEventListener('click', ev => {\n\t\t\t\t\tev.preventDefault();\n\t\t\t\t\tev.stopPropagation();\n\t\t\t\t\titem.callback(target, li);\n\t\t\t\t\tthis.close();\n\t\t\t\t});\n\t\t\t\tli.classList.add('context-item');\n\t\t\t} else\n\t\t\t\tli.classList.add('mess-context-menu-header');\n\n\t\t\tfrag.appendChild(li);\n\t\t}\n\n\t\tol[0].appendChild(frag);\n\n // Append to target\n this._setPosition(html, target);\n\n // Animate open the menu\n return this._animateOpen(html);\n\t}\n\n\t_setPosition(html, target) {\n\t\thtml.removeClass(\"expand-up expand-down\");\n\t\tsuper._setPosition(html, target);\n\t}\n}\n\nasync function applyDamage(target, sign) {\n\tconst amount = Number(target.querySelector('span').innerText);\n\tconst card = target.closest('.mess-attack-card')\n\tconst targetId = card.dataset.targetId\n\tif (targetId) {\n\t\tconst sceneId = card.dataset.sceneId;\n\t\tconst scene = game.scenes.get(sceneId);\n\t\tif (!scene) {\n\t\t\tui.notifications.error(game.i18n.localize(\"MESS.attackCard.applyDamage.sceneNotFound\"));\n\t\t\treturn;\n\t\t}\n\t\tconst token = new Token(scene.getEmbeddedEntity(\"Token\", targetId));\n\t\tif (!token) {\n\t\t\tui.notifications.error(game.i18n.localize(\"MESS.attackCard.applyDamage.targetNotFound\"));\n\t\t\treturn;\n\t\t}\n\t\tif (!token.owner) {\n\t\t\tui.notifications.error(game.i18n.localize(\"MESS.attackCard.applyDamage.targetNotOwner\"));\n\t\t\treturn;\n\t\t}\n\t\tconst actor = token.actor;\n\t\tactor.applyDamage(amount, sign);\n\t} else {\n\t\tconst tokens = canvas.tokens.controlled;\n\t\tif (!tokens.length) {\n\t\t\tui.notifications.error(game.i18n.localize('MESS.attackCard.contextMenu.error'));\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tfor (const token of tokens) {\n\t\t\tconst a = token.actor;\n\t\t\ta.applyDamage(amount, sign);\n\t\t}\n\t}\n}","export default function() {\n\n\tHooks.on('renderChatLog', chatLogHook);\n\n\tregisterSettings();\n};\n\nfunction registerSettings() {\n\tgame.settings.register('mess', `${game.userId}.adv-selector`, {\n\t\tname: 'Mess - Advantage Selector',\n\t\tdefault: 'normal',\n\t\ttype: String,\n\t\tscope: 'user'\n\t});\n\tgame.settings.register('mess', `${game.userId}.autoroll-selector`, {\n\t\tname: 'Mess - Autoroll Selector',\n\t\tdefault: {hit: false, dmg: false},\n\t\ttype: Object,\n\t\tscope: 'user'\n\t});\n\n\tgame.settings.register('mess', `${game.userId}.autoshow-selector`, {\n\t\tname: 'Mess - Auto Show',\n\t\tdefault: false,\n\t\ttype: Boolean,\n\t\tscope: 'user'\n\t});\n}\n\nasync function chatLogHook(app, html, data) {\n\thtml[0].classList.add('mess');\n\tif (game.user.isGM)\n\t\thtml[0].classList.add('mess-is-gm');\n\tconst div = document.createElement('div');\n\tdiv.classList.add('mess-roll-control');\n\n\tconst advSelector = game.settings.get('mess', `${game.userId}.adv-selector`);\n\tconst autoRollSelector = game.settings.get('mess', `${game.userId}.autoroll-selector`);\n\tconst templateData = {\n\t\tadvantage: advSelector === 'advantage',\n\t\tnormal: advSelector === 'normal',\n\t\tdisadvantage: advSelector === 'disadvantage',\n\t\tautoShow: game.settings.get('mess', `${game.userId}.autoshow-selector`),\n\t\t...autoRollSelector\n\t}\n\n\tdiv.insertAdjacentHTML('afterbegin', await renderTemplate('modules/mess/templates/roll-control.html', templateData));\n\n\tdiv.querySelector('.mess-show-btn').addEventListener('click', ev => {\n\t\tev.preventDefault(); ev.stopPropagation();\n\n\t\tconst target = ev.currentTarget;\n\t\tconst active = target.classList.contains('active');\n\t\ttarget.classList.toggle('active');\n\t\tgame.settings.set('mess', `${game.userId}.autoshow-selector`, !active);\n\t});\n\n\tdiv.querySelectorAll('.mess-adv-selector a').forEach(e => {\n\t\te.addEventListener('click', async function(ev) {\n\t\t\tev.preventDefault();\n\t\t\tev.stopPropagation();\n\t\t\tconst arr = Array.from(ev.currentTarget.parentNode.querySelectorAll('a'));\n\t\t\tconst currIdx = arr.findIndex(e => e.classList.contains('mess-selected'));\n\t\t\tarr[currIdx].classList.remove('mess-selected');\n\t\t\tconst newSelected = arr[(currIdx + 1) % arr.length];\n\t\t\tnewSelected.classList.add('mess-selected');\n\t\t\tgame.settings.set('mess', `${game.userId}.adv-selector`, newSelected.name);\n\t\t});\n\t\t// Toggle in the opposite direction with right click\n\t\te.addEventListener('contextmenu', async function(ev) {\n\t\t\tev.preventDefault();\n\t\t\tev.stopPropagation();\n\t\t\tconst arr = Array.from(ev.currentTarget.parentNode.querySelectorAll('a'));\n\t\t\tconst currIdx = arr.findIndex(e => e.classList.contains('mess-selected'));\n\t\t\tarr[currIdx].classList.remove('mess-selected');\n\t\t\tconst newSelected = arr[(currIdx + arr.length - 1) % arr.length]; // add length cause javascripts modulo is strange\n\t\t\tnewSelected.classList.add('mess-selected');\n\t\t\tgame.settings.set('mess', `${game.userId}.adv-selector`, newSelected.name);\n\t\t})\n\t});\n\tdiv.querySelectorAll('.mess-autoroll-selector a').forEach(e => {\n\t\te.addEventListener('click', async function(ev) {\n\t\t\tev.preventDefault();\n\t\t\tev.stopPropagation();\n\n\t\t\t\n\t\t\tev.currentTarget.classList.toggle('mess-selected');\n\t\t\tlet data = game.settings.get('mess', `${game.userId}.autoroll-selector`);\n\t\t\tdata[ev.currentTarget.name] = ev.currentTarget.classList.contains('mess-selected');\n\t\t\tgame.settings.set('mess', `${game.userId}.autoroll-selector`, data);\n\t\t})\n\t});\n\n\tconst controls = document.getElementById('chat-controls');\n\tcontrols.insertBefore(div, controls.childNodes[0]);\n}","import { getTargetToken, hasTarget } from './util.js';\n\n/**\n * All the functions provided here are heavily based on Foundrys DnD5e system, authored by Atropos.\n * Original repository: https://gitlab.com/foundrynet/dnd5e\n * Original Author: Atropos\n * License: GNU GPLv3\n */\n\nfunction getD20Modifier() {\n\treturn document.getElementById('mess-roll-mod').value;\n}\n\nfunction getAdvantageSettings() {\n\treturn game.settings.get('mess', `${game.userId}.adv-selector`);\n}\n\nexport async function rollD20(data) {\n\tlet adv = getAdvantageSettings();\n\t// Determine the d20 roll and modifiers\n\tlet nd = 1;\n\tlet mods = data.halflingLucky ? 'r=1' : '';\n\n\t// Handle advantage\n\tif (adv === 'advantage') {\n\t\tnd = data.elvenAccuracy ? 3 : 2;\n\t\tmods += 'kh';\n\t\tdata.title += ` (${game.i18n.localize('DND5E.Advantage')})`;\n\t}\n\n\t// Handle disadvantage\n\telse if (adv === 'disadvantage') {\n\t\tnd = 2;\n\t\tmods += 'kl';\n\t\tdata.title += ` (${game.i18n.localize('DND5E.Disadvantage')})`;\n\t}\n\n\t// Include the d20 roll\n\tlet diceFormula = `${nd}d20${mods}`;\n\tif (data.reliableTalent) diceFormula = `{${nd}d20${mods},10}kh`;\n\tdata.parts.unshift(diceFormula);\n\n\tconst d20Mod = getD20Modifier();\n\tif (d20Mod) data.parts.push(d20Mod);\n\n\tlet r = new Roll(data.parts.join('+'), data);\n\tr.roll();\n\tconst d20 = r.parts[0].total;\n\tlet templateData = {\n\t\t...data,\n\t\ttooltip: await r.getTooltip(),\n\t\troll: r,\n\t\tcrit: d20 >= 20,\n\t\tfumble: d20 <= 1,\n\t\tisGM: game.user.isGM,\n\t\tshowRolls: game.settings.get('mess', `${game.userId}.autoshow-selector`),\n\t};\n\n\tconst template = await renderTemplate('modules/mess/templates/roll-card.html', templateData);\n\n\tlet chatData = {\n\t\tuser: game.user._id,\n\t\ttype: CONST.CHAT_MESSAGE_TYPES.OTHER,\n\t\tcontent: template,\n\t\tspeaker: {\n\t\t\tactor: this,\n\t\t\talias: this.name,\n\t\t},\n\t};\n\tlet rollMode = game.settings.get('core', 'rollMode');\n\tif (['gmroll', 'blindroll'].includes(rollMode)) chatData['whisper'] = ChatMessage.getWhisperRecipients('GM');\n\tif (rollMode === 'blindroll') chatData['blind'] = true;\n\tconst dsn = game.mess.diceSoNice;\n\tif (dsn) {\n\t\tlet whispers = null;\n\t\tlet blind = false;\n\t\tif (['gmroll', 'blindroll'].includes(rollMode)) whispers = ChatMessage.getWhisperRecipients('GM');\n\t\tif (rollMode === 'blindroll') blind = true;\n\n\t\tawait game.dice3d.showForRoll(r, game.user, true, whispers, blind);\n\t}\n\tChatMessage.create(chatData);\n}\n\n/**\n * Extracts the data needed for an attack roll.\n * @param {ActorEntity} actor\n * @param {ItemEntity} item\n */\nexport async function getToHitData({ actor, item }) {\n\tif (!item.hasAttack) return null;\n\tconst actorData = actor.data.data;\n\tconst itemData = item.data.data;\n\tconst flags = actor.data.flags.dnd5e || {};\n\n\tlet rollData = item.getRollData();\n\n\t// Define Roll bonuses\n\tconst parts = [`@mod`];\n\tif (item.data.type !== 'weapon' || itemData.proficient) {\n\t\tparts.push('@prof');\n\t}\n\trollData.parts = parts;\n\n\t// Expanded weapon critical threshold\n\tif (item.data.type === 'weapon' && flags.weaponCriticalThreshold) {\n\t\trollData.critical = parseInt(flags.weaponCriticalThreshold);\n\t}\n\n\t// Elven Accuracy\n\tif (['weapon', 'spell'].includes(item.data.type)) {\n\t\tif (flags.elvenAccuracy && ['dex', 'int', 'wis', 'cha'].includes(item.abilityMod)) {\n\t\t\trollData.elvenAccuracy = true;\n\t\t}\n\t}\n\n\t// Apply Halfling Lucky\n\tif (flags.halflingLucky) rollData.halflingLucky = true;\n\n\t// Attack Bonus\n\tconst actorBonus = actorData.bonuses[itemData.actionType] || {};\n\tif (itemData.attackBonus || actorBonus.attack) {\n\t\t// parts.push(\"@atk\");\n\t\trollData['atk'] = [itemData.attackBonus, actorBonus.attack].filterJoin(' + ');\n\n\t\t// if (!isNaN(Number(rollData['atk']))) {\n\t\tparts.push('@atk');\n\t\t// }\n\t}\n\n\tlet roll = new Roll(rollData.parts.join('+'), rollData);\n\n\troll.roll(); // Simulate a roll to get the data \"compiled\"\n\n\trollData.totalModifier = roll._safeEval(Roll.cleanFormula(roll.terms));\n\trollData.totalModifier = rollData.totalModifier >= 0 ? '+' + rollData.totalModifier : rollData.totalModifier;\n\t// if (rollData['atk'] && !roll._formula.includes('@atk')) {\n\t// \trollData.parts.push('@atk');\n\t// \troll = new Roll(rollData.parts.join('+'), rollData);\n\t// \trollData.totalModifier += `+(${rollData['atk']})`;\n\t// }\n\n\tconst situationalModifier = getD20Modifier();\n\tif (situationalModifier) {\n\t\trollData.parts.push(situationalModifier);\n\t\troll = new Roll(rollData.parts.join('+'), rollData);\n\t\trollData.totalModifier += `+(${situationalModifier})`;\n\t}\n\t// Check if the extra modifiers to have some kind of roll in them.. if no add them to the modifier\n\ttry {\n\t\tconst mod = roll._safeEval(Roll.cleanFormula(rollData.totalModifier));\n\t\trollData.totalModifier = mod >= 0 ? '+' + mod : mod;\n\t} catch (e) {}\n\n\trollData.totalModifier = rollData.totalModifier;\n\trollData.formula = rollData.parts.join('+');\n\trollData.terms = Roll.cleanFormula(roll.terms);\n\treturn rollData;\n}\n\n/**\n * Rolls the to hit roll and updates the html target. Also updates the message if found.\n * @param {Click Event} ev event targetting the button which initiated a real or virtual click event\n */\nexport async function rollToHit(ev) {\n\t// Extract card data\n\tconst button = ev.currentTarget;\n\tbutton.disabled = true;\n\tconst card = button.closest('.chat-card');\n\tconst messageId = card.closest('.message').dataset.messageId;\n\t// Check if user owns chat message, else return\n\tif (messageId) {\n\t\tev.stopPropagation();\n\t\tev.preventDefault();\n\t\tconst message = game.messages.get(messageId);\n\t\tif (!(message.owner || message.isAuthor)) {\n\t\t\tui.notifications.error('You do not own the permissions to make that roll!');\n\t\t\treturn false;\n\t\t}\n\t}\n\t// Get the Actor from a synthetic Token\n\tconst actor = CONFIG.Item.entityClass._getChatCardActor(card);\n\tif (!actor.owner) return false;\n\n\t// Get the Item\n\tconst item = actor.getOwnedItem(card.dataset.itemId);\n\tif (!item) {\n\t\treturn ui.notifications.error(`The requested item ${card.dataset.itemId} no longer exists on Actor ${actor.name}`);\n\t}\n\n\tlet rollData = await getToHitData({ actor, item });\n\n\tlet adv = getAdvantageSettings();\n\t// Determine the d20 roll and modifiers\n\tlet nd = 1;\n\tlet mods = rollData.halflingLucky ? 'r=1' : '';\n\n\t// Handle advantage\n\tif (adv === 'advantage') {\n\t\tnd = rollData.elvenAccuracy ? 3 : 2;\n\t\tmods += 'kh';\n\t}\n\n\t// Handle disadvantage\n\telse if (adv === 'disadvantage') {\n\t\tnd = 2;\n\t\tmods += 'kl';\n\t}\n\n\t// Include the d20 roll\n\trollData.parts.unshift(`${nd}d20${mods}`);\n\n\tlet r = new Roll(rollData.parts.join('+'), rollData);\n\tr.roll();\n\tlet div = document.createElement('div');\n\t// div.title = `${rollData.parts[0]}+${rollData.terms} = ${r.formula} = ${r.total}. Click to see rolls.`;\n\tdiv.classList.add('dice-roll');\n\tdiv.classList.add('mess-dice-result');\n\tif (game.user.isGM) div.classList.add('mess-gm-dice');\n\tconst span = div.appendChild(document.createElement('span'));\n\tspan.classList.add('mess-roll-container');\n\tspan.innerHTML = `${r.total}`;\n\n\tdiv.insertAdjacentHTML('beforeend', await r.getTooltip());\n\tlet customTooltip = '';\n\tconst terms = rollData.terms.split(/(?=[+-])/); // only adding + terms here anyway\n\tconst dataTerms = rollData.formula.split(/(?=[+-])/);\n\tconsole.log(rollData);\n\tconsole.log(terms, dataTerms);\n\tfor (let i = 0; i < terms.length; i++) {\n\t\tconst term = terms[i];\n\t\tconst num = dataTerms[i];\n\t\tcustomTooltip += `\n\t\t\t
      \n\t\t\t\t
      \n ${num}\n\t\t\t\t\t${term}\n\t\t\t\t
      \n\t\t\t
      \n\t\t`;\n\t}\n\tdiv.querySelector('.dice-tooltip').insertAdjacentHTML('beforeend', customTooltip);\n\n\tconst tooltip = div.childNodes[1];\n\ttooltip.classList.add('hidden');\n\tconst crit = rollData.critical || 20;\n\tconst fumble = rollData.fumble || 1;\n\n\tconst d20 = r.parts[0].total;\n\n\t// if (hasTarget(button)) {\n\t// \t// Check if hit\n\t// \tconst target = getTargetToken(button);\n\t// \tconst ac = target.actor.data.data.attributes.ac.value;\n\t// \tif (ac) {\n\t// \t\tif ((r.total >= ac && d20 > fumble) || d20 >= crit) {\n\t// \t\t\tspan.classList.add('mess-hit');\n\t// \t\t} else {\n\t// \t\t\tspan.classList.add('mess-miss');\n\t// \t\t}\n\t// \t}\n\t// }\n\t// console.log(crit);\n\n\tif (d20 >= crit) {\n\t\tspan.classList.add('crit');\n\t\tcard.querySelector('.mess-chat-dmg .mess-chat-roll-type').innerHTML += ' - Crit!';\n\t\tcard.querySelectorAll('.mess-button-dmg').forEach((e, idx) => {\n\t\t\t// const rgx = new RegExp(Die.rgx.die, 'g');\n\t\t\tconst formula = new Roll(e.dataset.formula).alter(2).formula;\n\t\t\t// const formula = e.dataset.formula.replace(rgx, (match, nd, d, mods) => {\n\t\t\t// \tif (game.settings.get('mess', 'max-critical'))\n\t\t\t// \t\tmods = ' + ' + nd * d + (mods || '');\n\t\t\t// \telse {\n\t\t\t// \t\tnd = nd * 2;\n\t\t\t// \t\tmods = mods || '';\n\t\t\t// \t}\n\t\t\t// \treturn nd + 'd' + d + mods;\n\t\t\t// });\n\t\t\te.innerHTML = ` ${formula}`;\n\t\t\te.dataset.formula = formula;\n\t\t});\n\t}\n\tif (d20 <= fumble) span.classList.add('fumble');\n\n\tif (messageId) {\n\t\tupdateMessage(messageId, r, card, ev.currentTarget, div);\n\t} else {\n\t\tev.currentTarget.parentNode.replaceChild(div, ev.currentTarget);\n\t}\n\n\treturn r;\n}\n\nexport async function getDmgData({ actor, item, spellLevel = null }) {\n\tif (!item.hasDamage) return null;\n\tconst actorData = actor.data.data;\n\tconst itemData = item.data.data;\n\tlet rollData = item.getRollData();\n\n\tif (spellLevel) rollData.item.level = spellLevel;\n\n\trollData.parts = duplicate(itemData.damage.parts);\n\tif (itemData.damage.versatile) rollData.parts.splice(1, 0, [itemData.damage.versatile, 'versatile']);\n\n\t// Only apply for items that are not bonus dmg themself\n\tif (!item.getFlag('mess', 'isBonusDamage'))\n\t\tfor (let itm of actor.items) {\n\t\t\t// skip self\n\t\t\tif (itm.id === item.id) continue;\n\n\t\t\tlet bnsDmgParts = [];\n\t\t\tif (itm.getFlag('mess', 'isBonusDamage')) {\n\t\t\t\tif (itm.hasDamage) {\n\t\t\t\t\tconst itmData = itm.data.data;\n\t\t\t\t\tbnsDmgParts.push(itmData.damage.parts[0][0]);\n\t\t\t\t\tvar lbl = itm.name;\n\t\t\t\t\tif (itmData.damage.parts[0][1].length > 0)\n\t\t\t\t\t\tlbl += ` - ${game.i18n.localize('DND5E.Damage' + CONFIG.DND5E.damageTypes[itmData.damage.parts[0][1]])}`;\n\t\t\t\t\tbnsDmgParts.push(lbl);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (bnsDmgParts.length > 0) rollData.parts.push(bnsDmgParts);\n\t\t}\n\n\tif (item.data.type === 'spell') {\n\t\tif (itemData.scaling.mode === 'cantrip') {\n\t\t\tlet newDmgPart = [rollData.parts[0][0]];\n\t\t\tconst lvl = actor.data.type === 'character' ? actorData.details.level : actorData.details.spellLevel;\n\t\t\titem._scaleCantripDamage(newDmgPart, itemData.scaling.formula, lvl);\n\n\t\t\trollData.parts[0][0] = newDmgPart[0];\n\t\t} else if (spellLevel && itemData.scaling.mode === 'level' && itemData.scaling.formula) {\n\t\t\tlet newDmgPart = [];\n\t\t\titem._scaleSpellDamage(newDmgPart, itemData.level, spellLevel, itemData.scaling.formula);\n\t\t\tif (newDmgPart.length > 0) {\n\t\t\t\tnewDmgPart.push('upcast dice');\n\t\t\t\trollData.parts.push(newDmgPart);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst actorBonus = actorData.bonuses[itemData.actionType] || {};\n\tif (actorBonus.damage && parseInt(actorBonus.damage) !== 0) {\n\t\trollData.parts[0][0] += '+@dmg';\n\t\trollData['dmg'] = actorBonus.damage;\n\t}\n\n\tfor (let part of rollData.parts) {\n\t\tlet roll = new Roll(part[0], rollData);\n\t\tconst dmgType = CONFIG.DND5E.damageTypes[part[1]];\n\t\tif (dmgType) part[1] = game.i18n.localize('DND5E.Damage' + CONFIG.DND5E.damageTypes[part[1]]);\n\t\telse if (part[1] === 'versatile') part[1] = game.i18n.localize('DND5E.Versatile');\n\n\t\t//evalute damage formula's for example \"ceil(@classes.rogue.levels/2))d6\" -> \"4d6\"\n\t\tlet terms = roll.terms.map((t, i, terms) => {\n\t\t\tif (t instanceof Roll) {\n\t\t\t\thasInner = true;\n\t\t\t\tt.evaluate();\n\t\t\t\troll._dice = roll._dice.concat(t.dice);\n\t\t\t\tconst priorMath = i > 0 && terms[i - 1].split(' ').pop() in Math;\n\t\t\t\treturn priorMath ? `(${t.total})` : String(t.total);\n\t\t\t}\n\t\t\treturn t;\n\t\t});\n\t\tpart.push(Roll.cleanFormula(terms));\n\t}\n\n\treturn rollData;\n}\n\n/**\n * Rolls the dmg dice listed. If the event points towards an existing message the message will get updated\n * @param {Event} ev\n */\nexport async function rollDmg(ev) {\n\tconst contextMenu = ev.currentTarget.parentNode.querySelector('#context-menu');\n\tif (contextMenu) contextMenu.remove();\n\t// Extract card data\n\tconst button = ev.currentTarget;\n\tbutton.disabled = true;\n\tconst card = button.closest('.chat-card');\n\tconst messageId = card.closest('.message').dataset.messageId;\n\n\t// Check if user owns chat message, else return\n\tif (messageId) {\n\t\tev.stopPropagation();\n\t\tev.preventDefault();\n\t\tconst message = game.messages.get(messageId);\n\t\tif (!(message.owner || message.isAuthor)) {\n\t\t\tui.notifications.error('You do not own the permissions to make that roll!');\n\t\t\treturn false;\n\t\t}\n\t}\n\tconst formula = button.dataset.formula;\n\n\tlet r = new Roll(formula);\n\tr.roll();\n\tlet div = document.createElement('div');\n\t// div.title = `${button.dataset.terms} = ${r.formula} = ${r.total}. Click to see rolls.`;\n\tdiv.classList.add('dice-roll');\n\tdiv.classList.add('mess-dice-result');\n\tif (game.user.isGM) div.classList.add('mess-gm-dice');\n\n\t// small helper to detect if versatile dmg was rolled\n\tconst dmgType = button.nextElementSibling.innerText;\n\tif (dmgType === game.i18n.localize('DND5E.Versatile')) div.classList.add('mess-versatile');\n\n\tconst span = div.appendChild(document.createElement('span'));\n\tspan.classList.add('mess-roll-container');\n\tspan.innerHTML = `${r.total}`;\n\tdiv.insertAdjacentHTML('beforeend', await r.getTooltip());\n\tlet customTooltip = '';\n\tconst terms = button.dataset.terms.split(/(?=[+-])/);\n\tconst dataTerms = formula.replace(/\\s/g, '').split(/(?=[+-])/);\n\t// i really sh ould put this into a function............\n\t// for (let i = 0; i < terms.length; i++) {\n\t// \tconst term = terms[i];\n\t// \tconst num = dataTerms[i].replace(/\\s/g, '');\n\n\t// \tcustomTooltip += `\n\t// \t\t
      \n\t// \t\t\t

      \n\t// \t\t\t\t${num}\n\t// \t\t\t\t${term >= 0 ? '+' + term : term}\n\t// \t\t\t

      \n\t// \t\t
      \n\t// \t`;\n\t// }\n\tconsole.log(button.dataset.terms, formula);\n\tconsole.log(terms, dataTerms);\n\n\tfor (let i = 0; i < terms.length; i++) {\n\t\tconst term = terms[i];\n\t\tconst num = Number(dataTerms[i]);\n\t\tif (!term.includes('@') || isNaN(num)) continue;\n\t\tcustomTooltip += `\n\t\t\t
      \n\t\t\t\t
      \n ${term}\n\t\t\t\t\t${num}\n\t\t\t\t
      \n\t\t\t
      \n\t\t`;\n\t}\n\tdiv.querySelector('.dice-tooltip').insertAdjacentHTML('beforeend', customTooltip);\n\tconst tooltip = div.childNodes[1];\n\ttooltip.classList.add('hidden');\n\n\tif (messageId) {\n\t\tupdateMessage(messageId, r, card, ev.currentTarget, div);\n\t} else {\n\t\tev.currentTarget.parentNode.replaceChild(div, ev.currentTarget);\n\t}\n\treturn r;\n}\n\nasync function updateMessage(messageId, roll, card, target, div) {\n\tconst message = game.messages.get(messageId);\n\tconst dsn = game.mess.diceSoNice;\n\tif (dsn) {\n\t\tlet rollMode = game.settings.get('core', 'rollMode');\n\t\tlet whispers = null;\n\t\tlet blind = false;\n\t\tif (['gmroll', 'blindroll'].includes(rollMode)) whispers = ChatMessage.getWhisperRecipients('GM');\n\t\tif (rollMode === 'blindroll') blind = true;\n\n\t\tcard.querySelectorAll('button').forEach((e) => (e.disabled = true));\n\t\tawait game.dice3d.showForRoll(roll, game.user, true, whispers, blind);\n\t} else {\n\t\tAudioHelper.play({ src: CONFIG.sounds.dice }, true);\n\t}\n\ttarget.parentNode.replaceChild(div, target);\n\tmessage.update({ content: card.parentNode.innerHTML });\n}\n","import rollConrolls from './controls.js';\nimport applyDmg from './apply-dmg.js';\nimport modifyRolling from './modify-rolling.js';\n\nexport function rolling() {\n\t// Don't do this stuff if the settings are disabled.\n\tif (!game.settings.get('mess', 'modify-rolling'))\n\t\treturn;\n\trollConrolls();\n\tapplyDmg();\n\tmodifyRolling();\n}","import { rollD20, getToHitData, rollToHit, getDmgData, rollDmg } from './dice.js';\n\nexport default function () {\n\tsetupHooks();\n\tgame.mess.toggleItemBonusDamage = toggleItemBonusDamage;\n\n\t// const oldGetTooltip = Roll.prototype.getTooltip;\n\t// Roll.prototype.getTooltip = function() {\n\t// \tfor (let i = 0; i < this.parts.length; )\n\t// \treturn oldGetTooltip.call(this);\n\t// }\n\n\tHooks.once('diceSoNiceReady', (dice3d) => {\n\t\tgame.mess.diceSoNice = true;\n\t});\n\n\tCONFIG.Actor.entityClass.prototype.rollAbilitySave = function (abilityId) {\n\t\tconst label = CONFIG.DND5E.abilities[abilityId];\n\t\tconst abl = this.data.data.abilities[abilityId];\n\t\tconst parts = ['@mod'];\n\t\tconst data = { mod: abl.mod };\n\n\t\t// Include proficiency bonus\n\t\tif (abl.prof > 0) {\n\t\t\tparts.push('@prof');\n\t\t\tdata.prof = abl.prof;\n\t\t}\n\n\t\t// Include a global actor ability save bonus\n\t\tconst actorBonus = getProperty(this.data.data.bonuses, 'abilities.save');\n\t\tif (!!actorBonus) {\n\t\t\tparts.push('@saveBonus');\n\t\t\tdata.saveBonus = actorBonus;\n\t\t}\n\t\tdata.title = game.i18n.format('DND5E.SavePromptTitle', { ability: label });\n\t\tdata.parts = parts;\n\t\trollD20.bind(this)(data);\n\t};\n}\n\n/**\n * Heavily based on: https://gitlab.com/foundrynet/dnd5e/-/blob/master/module/macros.js#L42\n * original author: Atropos\n * source repository: https://gitlab.com/foundrynet/dnd5e\n * license: GPLv3\n * @param {*} itemName\n */\nfunction toggleItemBonusDamage(itemName) {\n\tconst speaker = ChatMessage.getSpeaker();\n\tlet actor;\n\tif (speaker.token) actor = game.actors.tokens[speaker.token];\n\tif (!actor) actor = game.actors.get(speaker.actor);\n\t// Get matching items\n\tconst items = actor ? actor.items.filter((i) => i.name === itemName) : [];\n\tif (items.length > 1) {\n\t\tui.notifications.warn(\n\t\t\t`Your controlled Actor ${actor.name} has more than one Item with name ${itemName}. The first matched item will be chosen.`\n\t\t);\n\t} else if (items.length === 0) {\n\t\treturn ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);\n\t}\n\tconst item = items[0];\n\n\tconst newState = !item.getFlag('mess', 'isBonusDamage');\n\t// toggle bonus dmg\n\titem.setFlag('mess', 'isBonusDamage', newState);\n\treturn newState;\n}\n\n/**\n * Initializes all the hoohks!\n */\nfunction setupHooks() {\n\tCONFIG.Item.entityClass.chatListeners = chatListeners.bind(CONFIG.Item.entityClass);\n\n\tHooks.on('preCreateChatMessage', preCreateChatMessageHook);\n\tHooks.on('renderActorSheet', actorSheetHook);\n\n\t// Bind my own chatListeners to the item class and execute them.\n\t// Hooks.on('ready', chatListeners.bind(CONFIG.Item.entityClass));\n\n\tHooks.on('renderItemSheet', (app, html, data) => {\n\t\tlet div = document.createElement('div');\n\t\tdiv.classList.add('form-group');\n\t\tdiv.appendChild(document.createElement('label')).innerText = game.i18n.localize('MESS.itemSheet.bonusDmg');\n\t\tlet formField = div.appendChild(document.createElement('div'));\n\t\tformField.classList.add('form-fields');\n\t\tlet inp = formField.appendChild(document.createElement('input'));\n\t\tinp.type = 'checkbox';\n\t\tinp.name = 'flags.mess.isBonusDamage';\n\t\tinp.checked = app.object.getFlag('mess', 'isBonusDamage');\n\n\t\tconst target = html[0].querySelector('[name=\"data.formula\"]');\n\t\tif (target) target.closest('.form-group').after(div);\n\t});\n}\n\n/**\n * Makes sure one attack is rolled for every chat card that has a dmg or attack button.\n * @param {Object} data chat message data\n */\nasync function preCreateChatMessageHook(data) {\n\tconst div = document.createElement('div');\n\tdiv.insertAdjacentHTML('afterbegin', data.content);\n\tlet btn = div.querySelector('button[data-action=\"attack\"]');\n\tif (!btn) btn = div.querySelector('button[data-action=\"damage\"]');\n\n\tif (btn) renderAttack({ currentTarget: btn });\n}\n\n// TODO: for compendium rolltables\nfunction getFlavor(chatFlavor, target) {\n\tconst rollTableRegExp = /@RollTable\\[([^\\]])+\\](?:\\{([^\\}]+)\\})?/g;\n\tlet rollTables = Array.from(chatFlavor.matchAll(rollTableRegExp));\n\tif (rollTables) {\n\t\tconst collection = game.tables;\n\t\tfor (let tableData of rollTables) {\n\t\t\tlet table;\n\t\t\tconst id = tableData[0].match(/\\[[a-zA-Z0-9]{16}\\]/);\n\t\t\tif (id) {\n\t\t\t\ttable = collection.get(id[0].slice(1, -1));\n\t\t\t} else {\n\t\t\t\tconst name = tableData[0].match(/\\[([^\\]])+\\]/)[0].slice(1, -1);\n\t\t\t\ttable = collection.entities.find((e) => e.data.name === name);\n\t\t\t}\n\t\t\tlet result = table.roll();\n\t\t\tchatFlavor = chatFlavor.replace(tableData[0], result.results.map((e) => e.text).join(','));\n\t\t}\n\t}\n\treturn chatFlavor.replace(/\\[target\\.name\\]/g, target.data.name);\n}\n\n/**\n * Renders an attack chat card\n * @param {Click Event} ev pointing towards the card that is supposed to initiate the event.\n */\nasync function renderAttack(ev) {\n\tif (ev.type === 'click') {\n\t\tev.preventDefault();\n\t\tev.stopPropagation();\n\t}\n\n\t// Extract card data\n\tconst button = ev.currentTarget;\n\tbutton.disabled = true;\n\tconst card = button.closest('.chat-card');\n\n\t// Get the Actor from a synthetic Token\n\tconst actor = CONFIG.Item.entityClass._getChatCardActor(card);\n\n\tif (!actor || !actor.owner) return;\n\n\t// Get the Item\n\tconst item = actor.getOwnedItem(card.dataset.itemId);\n\tif (!item) {\n\t\treturn ui.notifications.error(`The requested item ${card.dataset.itemId} no longer exists on Actor ${actor.name}`);\n\t}\n\n\tlet targets = game.user.targets;\n\t// Don't roll for all targets if its an AoE, due to only rolling e.g. dmg once for all targets\n\t// TODO: Maybe add target list or chat cards for making saving throws\n\t// or not, since it would just spam the chatlog.. hmm\n\tconst areaSkill = Object.keys(CONFIG.DND5E.areaTargetTypes).includes(getProperty(item, 'data.data.target.type'));\n\tif (!targets.size || areaSkill)\n\t\ttargets = [\n\t\t\t{\n\t\t\t\tdata: {\n\t\t\t\t\tname: 'someone',\n\t\t\t\t\timg: '',\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\tconst spellLevel = parseInt(card.dataset.spellLevel) || null;\n\n\tconst template = 'modules/mess/templates/attack-card.html';\n\n\tconst attackData = {\n\t\tactor,\n\t\titem,\n\t\ttoHit: await getToHitData({ actor, item }),\n\t\tdmgs: await getDmgData({ actor, item, spellLevel }),\n\t\tsceneId: canvas.scene.id,\n\t\tuser: game.user.id,\n\t\tisGM: game.user.isGM,\n\t\tshowRolls: game.settings.get('mess', `${game.userId}.autoshow-selector`),\n\t};\n\n\tconst autoroll = game.settings.get('mess', `${game.userId}.autoroll-selector`);\n\tconst rollMode = game.settings.get('core', 'rollMode');\n\tfor (const target of targets) {\n\t\tconst allowed = await item._handleResourceConsumption({ isCard: false, isAttack: true });\n\t\tconst targetActor = target.actor ? target.actor.data : null;\n\n\t\tlet targetData = {};\n\t\tif (targetActor) {\n\t\t\ttargetData.ac = {\n\t\t\t\tlabel: '',\n\t\t\t\ttitle: game.i18n.localize('DND5E.ArmorClass'),\n\t\t\t\tvalue: targetActor.data.attributes.ac.value,\n\t\t\t};\n\t\t\tlet di = targetActor.data.traits.di.value\n\t\t\t\t.filter((e) => e !== 'custom')\n\t\t\t\t.map((e) => game.i18n.localize('DND5E.Damage' + e[0].toUpperCase() + e.substring(1)));\n\t\t\tif (targetActor.data.traits.di.custom) di.push(targetActor.data.traits.di.custom);\n\t\t\ttargetData.di = {\n\t\t\t\tlabel: '',\n\t\t\t\ttitle: game.i18n.localize('DND5E.DamImm'),\n\t\t\t\tvalue: di.join(', '),\n\t\t\t};\n\n\t\t\tlet dr = targetActor.data.traits.dr.value\n\t\t\t\t.filter((e) => e !== 'custom')\n\t\t\t\t.map((e) => game.i18n.localize('DND5E.Damage' + e[0].toUpperCase() + e.substring(1)));\n\t\t\tif (targetActor.data.traits.dr.custom) dr.push(targetActor.data.traits.dr.custom);\n\t\t\ttargetData.dr = {\n\t\t\t\tlabel: '',\n\t\t\t\ttitle: game.i18n.localize('DND5E.DamRes'),\n\t\t\t\tvalue: dr.join(', '),\n\t\t\t};\n\t\t\tlet dv = targetActor.data.traits.dv.value\n\t\t\t\t.filter((e) => e !== 'custom')\n\t\t\t\t.map((e) => game.i18n.localize('DND5E.Damage' + e[0].toUpperCase() + e.substring(1)));\n\t\t\tif (targetActor.data.traits.dv.custom) dv.push(targetActor.data.traits.dv.custom);\n\t\t\ttargetData.dv = {\n\t\t\t\tlabel: '',\n\t\t\t\ttitle: game.i18n.localize('DND5E.DamVuln'),\n\t\t\t\tvalue: dv.join(', '),\n\t\t\t};\n\t\t\t// console.log(targetData)\n\t\t}\n\t\tconst displayName =\n\t\t\ttarget.data.displayName === CONST.TOKEN_DISPLAY_MODES.ALWAYS || target.data.displayName === CONST.TOKEN_DISPLAY_MODES.HOVER;\n\t\tconst attackTemplateData = {\n\t\t\t...attackData,\n\t\t\ttarget: target.data,\n\t\t\ttargetData: targetData,\n\t\t\tflavor: getFlavor(item.data.data.chatFlavor, target),\n\t\t\tallowed,\n\t\t\tdisplayName,\n\t\t};\n\t\tlet html = await renderTemplate(template, attackTemplateData);\n\n\t\tif (autoroll.hit || autoroll.dmg) html = await autoRoll(autoroll, html, rollMode);\n\n\t\tlet chatData = {\n\t\t\tuser: game.user._id,\n\t\t\ttype: CONST.CHAT_MESSAGE_TYPES.OTHER,\n\t\t\tcontent: html,\n\t\t\tspeaker: {\n\t\t\t\tactor: item.actor._id,\n\t\t\t\ttoken: item.actor.token,\n\t\t\t\talias: item.actor.name,\n\t\t\t},\n\t\t};\n\t\tif (!game.user.isGM || !game.settings.get('mess', 'attack-card-always-public')) {\n\t\t\tif (['gmroll', 'blindroll'].includes(rollMode)) chatData.whisper = ChatMessage.getWhisperRecipients('GM');\n\t\t\t// doesn't work anyway since its no \"real\" roll....\n\t\t\t// if ( rollMode === \"blindroll\" ) chatData.blind = true;\n\t\t\tif (rollMode === 'selfroll') chatData.whisper = [game.user.id];\n\t\t}\n\n\t\tChatMessage.create(chatData);\n\t}\n\n\tbutton.disabled = false;\n}\n\n/**\n * Autorolls hit or dmg, depending on which flag is set and replaces the template string.\n * @param {Object} autoroll Defining whether to autoroll hit or dmg\n * @param {String} template Defining the html template where the roll should happen.\n */\nasync function autoRoll(autoroll, template, rollMode) {\n\tlet card = document.createElement('div');\n\tconst dsn = game.mess.diceSoNice;\n\n\tlet whispers = null;\n\tlet blind = false;\n\tif (['gmroll', 'blindroll'].includes(rollMode)) whispers = ChatMessage.getWhisperRecipients('GM');\n\tif (rollMode === 'blindroll') blind = true;\n\n\tcard.classList.add('message');\n\tcard.insertAdjacentHTML('afterbegin', template);\n\tlet rolls = [];\n\tif (autoroll.hit) {\n\t\tlet toHitBtn = card.querySelector('.mess-button-to-hit');\n\t\tif (toHitBtn) {\n\t\t\tlet r = await rollToHit({ currentTarget: toHitBtn });\n\t\t\tif (dsn) await game.dice3d.showForRoll(r, game.user, true, whispers, blind);\n\t\t}\n\t}\n\n\tif (autoroll.dmg) {\n\t\tconst btns = Array.from(card.querySelectorAll('.mess-button-dmg'));\n\t\tfor (const btn of btns) {\n\t\t\trolls.push(await rollDmg({ currentTarget: btn }));\n\t\t}\n\t}\n\tif (dsn) await game.dice3d.showForRoll(rolls, game.user, true, whispers, blind);\n\telse AudioHelper.play({ src: CONFIG.sounds.dice }, true);\n\treturn card.innerHTML;\n}\n\n/**\n * Hook onto the Actor Sheet rendering, modifying the listeners for the roll ability and roll skill check events\n * @param {*} app\n * @param {*} html\n * @param {*} data\n */\nasync function actorSheetHook(app, html, data) {\n\t// TODO: Redo this with proper methods... this currently ignores the cool new modifier field\n\t// maybe just ignore replace the abilitysave etc functions\n\tconst abilityMods = html[0].querySelectorAll('.ability-mod, .ability-name');\n\t$(abilityMods).off(); // find smth better here!\n\tabilityMods.forEach((e) =>\n\t\te.addEventListener('click', function (ev) {\n\t\t\tev.stopPropagation();\n\t\t\tev.preventDefault();\n\n\t\t\tconst abilityId = ev.currentTarget.closest('.ability').dataset.ability;\n\t\t\tconst label = CONFIG.DND5E.abilities[abilityId];\n\t\t\tconst abl = app.object.data.data.abilities[abilityId];\n\t\t\tconst parts = ['@mod'];\n\t\t\tconst data = { mod: abl.mod };\n\t\t\tconst feats = app.object.data.flags.dnd5e || {};\n\n\t\t\t// Add feat-related proficiency bonuses\n\t\t\tconst actorData = getProperty(app.object, 'data.data');\n\t\t\tif (feats.remarkableAthlete && DND5E.characterFlags.remarkableAthlete.abilities.includes(abilityId)) {\n\t\t\t\tparts.push('@remarkable-athlete');\n\t\t\t\tdata['remarkable-athlete'] = Math.ceil(0.5 * actorData.attributes.prof);\n\t\t\t} else if (feats.jackOfAllTrades) {\n\t\t\t\tparts.push('@jack-of-all-trades');\n\t\t\t\tdata['jack-of-all-trades'] = Math.floor(0.5 * actorData.attributes.prof);\n\t\t\t}\n\n\t\t\t// Add global actor bonus\n\t\t\tlet actorBonus = getProperty(app.object.data.data.bonuses, 'abilities.check');\n\t\t\tif (!!actorBonus) {\n\t\t\t\tparts.push('@checkBonus');\n\t\t\t\tdata.checkBonus = actorBonus;\n\t\t\t}\n\n\t\t\tdata.parts = parts;\n\n\t\t\tdata.title = game.i18n.format('DND5E.AbilityPromptTitle', { ability: label });\n\n\t\t\trollD20.bind(app.object)(data);\n\t\t\treturn false;\n\t\t})\n\t);\n\tconst saveMods = html[0].querySelectorAll('.ability-save');\n\t$(saveMods).off();\n\tsaveMods.forEach((e) =>\n\t\te.addEventListener('click', function (ev) {\n\t\t\tev.stopPropagation();\n\t\t\tev.preventDefault();\n\t\t\tconst abilityId = ev.currentTarget.closest('.ability').dataset.ability;\n\t\t\tapp.object.rollAbilitySave(abilityId);\n\t\t\treturn false;\n\t\t})\n\t);\n\n\tconst skills = html[0].querySelectorAll('.skill-name');\n\t$(skills).off();\n\tskills.forEach((e) =>\n\t\te.addEventListener('click', function (ev) {\n\t\t\tev.stopPropagation();\n\t\t\tev.preventDefault();\n\t\t\tconst skillId = ev.currentTarget.closest('.skill').dataset.skill;\n\t\t\tconst skl = app.object.data.data.skills[skillId];\n\n\t\t\t// Compose roll parts and data\n\t\t\tconst parts = ['@mod'];\n\t\t\tconst data = { mod: skl.mod + skl.prof };\n\t\t\tif (skl.bonus) {\n\t\t\t\tdata['skillBonus'] = skl.bonus;\n\t\t\t\tparts.push('@skillBonus');\n\t\t\t}\n\n\t\t\t// Reliable Talent applies to any skill check we have full or better proficiency in\n\t\t\tdata.reliableTalent = skl.value >= 1 && app.object.getFlag('dnd5e', 'reliableTalent');\n\t\t\tdata.parts = parts;\n\t\t\tdata.title = game.i18n.format('DND5E.SkillPromptTitle', { skill: CONFIG.DND5E.skills[skillId] });\n\n\t\t\trollD20.bind(app.object)(data);\n\t\t\treturn false;\n\t\t})\n\t);\n}\n\n/**\n * My own chat listeners\n */\nfunction chatListeners(html) {\n\tif (!html) html = $(document.getElementById('chat-log'));\n\thtml.on('click', '.card-buttons button', onChatCardAction.bind(this));\n\thtml.on('click', '.item-name', this._onChatCardToggleContent.bind(this));\n\n\t// lets just use this for even more listeners\n\thtml.on('mouseenter', '.mess-chat-target', onMouseEnterTarget);\n\thtml.on('mouseleave', '.mess-chat-target', onMouseLeaveTarget);\n\thtml.on('dblclick', '.mess-chat-target', onDblClickTarget);\n\n\thtml.on('click', '.mess-button-to-hit', rollToHit);\n\thtml.on('click', '.mess-button-dmg', rollDmg);\n\n\thtml.on('click', '.mess-show-btn', onToggleShowPlayers);\n}\n\n// Only overwrite stuff for attack buttons\nasync function onChatCardAction(ev) {\n\tev.preventDefault();\n\tev.stopPropagation();\n\tif (ev.currentTarget.dataset.action === 'attack') return renderAttack(ev);\n\tif (ev.currentTarget.dataset.action === 'damage') return renderAttack(ev);\n\tif (ev.currentTarget.dataset.placeTemplate) return renderTemplate(ev);\n\n\treturn this._onChatCardAction(ev);\n}\n\n/*****************************************************\n * Mouse Listeners for the target img for chat cards *\n *****************************************************/\n\nasync function onMouseEnterTarget(ev) {\n\tev.preventDefault();\n\tev.stopPropagation();\n\tconst token = await getTargetToken(ev);\n\tif (!token) return false;\n\n\ttoken._onHoverIn();\n}\n\nasync function onMouseLeaveTarget(ev) {\n\tev.preventDefault();\n\tev.stopPropagation();\n\tconst token = await getTargetToken(ev);\n\tif (!token || !token.visible) return false;\n\n\ttoken._onHoverOut();\n}\n\nasync function onDblClickTarget(ev) {\n\tev.preventDefault();\n\tev.stopPropagation();\n\tconst token = await getTargetToken(ev);\n\tif (!token || !token.visible) return false;\n\n\tconst pos = token.center;\n\tcanvas.animatePan({ x: pos.x, y: pos.y });\n}\n\nasync function getTargetToken(ev) {\n\tconst card = ev.currentTarget.closest('.mess-attack-card');\n\tconst sceneId = card.dataset.sceneId;\n\tif (sceneId !== canvas.scene.id) return false;\n\tconst tokenId = card.dataset.targetId;\n\tif (!tokenId) return false;\n\n\tconst token = canvas.tokens.placeables.find((e) => e.id === tokenId);\n\tif (!token) return false;\n\treturn token;\n}\n\nasync function onToggleShowPlayers(ev) {\n\tconst div = ev.currentTarget.closest('.mess-chat-to-hit, .mess-chat-dmg');\n\tdiv.classList.toggle('mess-show-players');\n\n\tconst card = ev.currentTarget.closest('.mess-attack-card');\n\tconst messageId = card.closest('.message').dataset.messageId;\n\tconst message = game.messages.get(messageId);\n\tmessage.update({ content: card.parentNode.innerHTML });\n}\n","export function getTargetToken(el) {\n\t\n\tconst card = el.closest('.mess-attack-card')\n\n\tconst targetId = card.dataset.targetId\n\tconst sceneId = card.dataset.sceneId;\n\tconst scene = game.scenes.get(sceneId);\n\tconst token = new Token(scene.getEmbeddedEntity(\"Token\", targetId));\n\treturn token;\n}\n\nexport function hasTarget(el) {\n\tconst card = el.closest('.mess-attack-card');\n\tif (!card) return false;\n\tif (card.dataset.targetId) return true;\n\treturn false;\n}","export class MessSettings extends FormApplication {\n\tstatic init() {\n\t\tconst isDnD = game.system.id === 'dnd5e';\n\n\t\tgame.settings.register('mess', 'actor-item-sort', {\n\t\t\tname: 'Activate item sort button.',\n\t\t\thint:\n\t\t\t\t'Adds a button to actor sheets for sorting all items of that category alphabetically.',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'better-draggable', {\n\t\t\tname: \"Activate better drag'n'drop workflow.\",\n\t\t\tscope: 'world',\n\t\t\tconfig: false, // Change if implemented\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'better-draggable-lists', {\n\t\t\tname: \"Activate better drag'n'drop workflow for lists.\",\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: true,\n\t\t\ttype: Boolean,\n\t\t});\n\t\tgame.settings.set('mess', 'better-draggable-lists', false);\n\n\t\tgame.settings.register('mess', 'prepared-spell-tracker', {\n\t\t\tname: 'Activate prepared spell tracker',\n\t\t\thint:\n\t\t\t\t'Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'add-scrolling', {\n\t\t\tname: 'Activating numerical field scrolling.',\n\t\t\thint:\n\t\t\t\t'Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'modify-rolling', {\n\t\t\tname: 'Alternative Rolling.',\n\t\t\thint:\n\t\t\t\t'Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'attack-card-always-public', {\n\t\t\tname: 'Roll mode for alternative rolling.',\n\t\t\thint:\n\t\t\t\t'Always roll attack rolls public, with hidden rolls, but visible target.',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: isDnD,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'modify-templates', {\n\t\t\tname: 'Activate modified templates.',\n\t\t\thint:\n\t\t\t\t'Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: true,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'change-placeables', {\n\t\t\tname: 'Activate placeables changes.',\n\t\t\thint:\n\t\t\t\t'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: true,\n\t\t\ttype: Boolean,\n\t\t});\n\t\tgame.settings.registerMenu('mess', 'templateTexture', {\n\t\t\tname: game.i18n.localize('MESS.FVTTSettings.description'),\n\t\t\tlabel: game.i18n.localize('MESS.FVTTSettings.button'),\n\t\t\ticon: 'fas fa-mug-hot',\n\t\t\ttype: MessSettings,\n\t\t\trestricted: true,\n\t\t});\n\n\t\tgame.settings.register('mess', 'templateTexture', {\n\t\t\tname: 'Activate placeables changes.',\n\t\t\thint:\n\t\t\t\t'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!',\n\t\t\tscope: 'world',\n\t\t\tdefault: true,\n\t\t\ttype: Object,\n\t\t});\n\n\t\tgame.settings.register('mess', 'max-critical', {\n\t\t\tname: 'Activate maximum critical rolls.',\n\t\t\thint:\n\t\t\t\t'Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: false,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'templateTexture', {\n\t\t\tname: 'Activate placeables changes.',\n\t\t\thint:\n\t\t\t\t'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!',\n\t\t\tscope: 'world',\n\t\t\tconfig: false,\n\t\t\tdefault: true,\n\t\t\ttype: Object,\n\t\t});\n\n\t\tgame.settings.register('mess', 'templateAutoTargeting', {\n\t\t\tscope: 'world',\n\t\t\tdefault: true,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tgame.settings.register('mess', 'templateDrawBordersOnlyOnHighlight', {\n\t\t\tscope: 'world',\n\t\t\tdefault: true,\n\t\t\ttype: Boolean,\n\t\t});\n\n\t\tthis.loadTemplates();\n\t}\n\tstatic loadTemplates() {\n\t\tloadTemplates([\n\t\t\t'modules/mess/templates/settings/templates.html',\n\t\t\t'modules/mess/templates/settings/dnd5e.html',\n\t\t\t'modules/mess/templates/settings/misc.html',\n\t\t]);\n\t}\n\n\tstatic get defaultOptions() {\n\t\treturn {\n\t\t\t...super.defaultOptions,\n\t\t\ttemplate: 'modules/mess/templates/settings/settings.html',\n\t\t\theight: 'auto',\n\t\t\ttitle: 'Mess - Moerills enhancing super-suit(e) - Settings Menu',\n\t\t\twidth: 600,\n\t\t\tclasses: ['mess', 'settings'],\n\t\t\ttabs: [\n\t\t\t\t{\n\t\t\t\t\tnavSelector: '.tabs',\n\t\t\t\t\tcontentSelector: 'form',\n\t\t\t\t\tinitial: 'name',\n\t\t\t\t},\n\t\t\t],\n\t\t\tsubmitOnClose: true,\n\t\t};\n\t}\n\n\tconstructor(object = {}, options) {\n\t\tsuper(object, options);\n\t\tthis.object = game.settings.get('mess', 'templateTexture');\n\t}\n\n\t_getHeaderButtons() {\n\t\tlet btns = super._getHeaderButtons();\n\t\tbtns[0].label = 'Save & Close';\n\t\treturn btns;\n\t}\n\n\tgetSettingsData() {\n\t\tconst isDnD = game.system.id === 'dnd5e';\n\t\tlet data = {\n\t\t\t'modify-templates': game.settings.get('mess', 'modify-templates'),\n\t\t\t'change-placeables': game.settings.get('mess', 'change-placeables'),\n\t\t\t'templateTexture': game.settings.get('mess', 'templateTexture'),\n\t\t\t'templateAutoTargeting': game.settings.get(\n\t\t\t\t'mess',\n\t\t\t\t'templateAutoTargeting'\n\t\t\t),\n\t\t\t'templateDrawBordersOnlyOnHighlight': game.settings.get(\n\t\t\t\t'mess',\n\t\t\t\t'templateDrawBordersOnlyOnHighlight'\n\t\t\t),\n\t\t\t'better-draggable-lists': game.settings.get(\n\t\t\t\t'mess',\n\t\t\t\t'better-draggable-lists'\n\t\t\t),\n\t\t};\n\t\tif (isDnD) {\n\t\t\tdata['templateTexture'] = game.settings.get('mess', 'templateTexture');\n\t\t\tdata['modify-rolling'] = game.settings.get('mess', 'modify-rolling');\n\t\t\tdata['max-critical'] = game.settings.get('mess', 'max-critical');\n\n\t\t\tdata['actor-item-sort'] = game.settings.get('mess', 'actor-item-sort');\n\t\t\t// data['better-draggable'] = game.settings.get('mess', 'better-draggable');\n\t\t\tdata['prepared-spell-tracker'] = game.settings.get(\n\t\t\t\t'mess',\n\t\t\t\t'prepared-spell-tracker'\n\t\t\t);\n\t\t\tdata['add-scrolling'] = game.settings.get('mess', 'add-scrolling');\n\t\t\tdata['attack-card-always-public'] = game.settings.get(\n\t\t\t\t'mess',\n\t\t\t\t'attack-card-always-public'\n\t\t\t);\n\t\t}\n\t\treturn data;\n\t}\n\n\tgetData() {\n\t\tconst isDnD = game.system.id === 'dnd5e';\n\t\tlet data = super.getData();\n\t\tif (isDnD) {\n\t\t\tdata.dmgTypes = CONFIG.DND5E.damageTypes;\n\t\t\tdata.templateTypes = CONFIG.MeasuredTemplate.types;\n\t\t}\n\t\tdata.isDnD = isDnD;\n\t\tdata.settings = this.getSettingsData();\n\t\treturn data;\n\t}\n\n\tactivateListeners(html) {\n\t\tsuper.activateListeners(html);\n\t}\n\n\t_updateObject(ev, formData) {\n\t\tconst data = expandObject(formData);\n\t\tfor (let [key, value] of Object.entries(data)) {\n\t\t\tgame.settings.set('mess', key, value);\n\t\t}\n\t\tnew Dialog({\n\t\t\tcontent: `

      ${game.i18n.localize('MESS.reloadReminder.text')}

      `,\n\t\t\tbuttons: {\n\t\t\t\tyes: {\n\t\t\t\t\ticon: '',\n\t\t\t\t\tlabel: game.i18n.localize('MESS.reloadReminder.yes'),\n\t\t\t\t\tcallback: () => location.reload(),\n\t\t\t\t},\n\t\t\t\tno: {\n\t\t\t\t\ticon: '',\n\t\t\t\t\tlabel: game.i18n.localize('MESS.reloadReminder.no'),\n\t\t\t\t},\n\t\t\t},\n\t\t}).render(true);\n\t\t// game.settings.set('mess', 'templateTexture', mergeObject({}, formData))\n\t}\n}\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/scripts/actor-item-sort-btn.js","webpack:///./src/scripts/add-scrolling.js","webpack:///./src/scripts/change-placeables.js","webpack:///./src/scripts/index.js","webpack:///./src/scripts/modify-templates.js","webpack:///./src/scripts/prepared-spell-tracker.js","webpack:///./src/scripts/settings.js"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","installedModules","__webpack_require__","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","window","oldJsonpFunction","slice","s","async","addAlphabeticalSorter","app","html","actor","_id","querySelectorAll","forEach","el","closest","dataset","tab","btn","innerHTML","classList","add","title","style","flex","margin","addEventListener","ev","lists","actorId","fromUuid","concatList","map","items","spells","flat","sort","a","b","siblings","sortUpdates","SortingHelpers","performIntegerSort","duplicate","sortBefore","updateData","u","update","updateEmbeddedEntity","sortItemListAlphabetically","prepend","itemSortBtn","Hooks","on","addScolling","preventDefault","stopPropagation","deltaY","currentTarget","Number","Math","max","$","change","onDragLeftMove","clones","destination","origin","originalEvent","canvas","_onDragCanvasPan","dx","x","dy","y","snap","previous","momentumThreshold","lambda","prev","prevMomentum","momentum","prevV","v","shiftKey","dest","_original","grid","getSnappedPosition","this","layer","options","gridPrecision","refresh","changePlaceables","PlaceableObject","_onDragLeftMove","game","settings","user","isGM","moduleVersion","version","register","default","String","scope","oldVersion","isNewerVersion","mess","init","changeTemplates","newFun","MeasuredTemplate","toString","replace","querySelector","Function","getTargets","isTokenInside","oldFun","ret","dndTemplateSettings","system","id","importedJS","import","AbilityTemplate","itemHook","_originalFromItem","fromItem","item","template","path","getFlag","hasDamage","damage","parts","loadTexture","then","tex","texture","activatePreviewListeners","token","scene","templatePos","startX","width","startY","height","currGrid","shape","contains","tokens","getEmbeddedCollection","targets","updateTokenTargets","div","innerText","i18n","localize","formField","inp","dtype","insertAdjacentHTML","button","_activateFilePicker","after","addPreparedSpellTracker","isNPC","tracker","border","preparedSpells","sep","val","isNaN","setFlag","constructor","alignSelf","parentNode","insertBefore","MessSettings","FormApplication","isDnD","hint","config","Boolean","set","registerMenu","label","icon","restricted","loadTemplates","super","defaultOptions","classes","tabs","navSelector","contentSelector","initial","submitOnClose","btns","_getHeaderButtons","templateTexture","templateAutoTargeting","templateDrawBordersOnlyOnHighlight","getData","dmgTypes","CONFIG","DND5E","damageTypes","templateTypes","types","getSettingsData","activateListeners","formData","expandObject","entries","Dialog","content","buttons","yes","callback","location","reload","no","render"],"mappings":"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","file":"index.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t};\n\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"index\": 0\n \t};\n\n\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"bundles/\" + ({\"welcome-screen\":\"welcome-screen\"}[chunkId]||chunkId) + \".\" + {\"welcome-screen\":\"a969\"}[chunkId] + \".js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"modules/mess/scripts/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./src/scripts/index.js\");\n","async function sortItemListAlphabetically(lists, actorId) {\n\tconst actor = await fromUuid(`Actor.${actorId}`);\n\tlet concatList = lists.map(e => e.items || e.spells).flat();\n\tconcatList.sort(function (a, b) {\n\t\tif (a.name < b.name) return -1;\n\t\tif (a.name > b.name) return 1;\n\t\treturn 0;\n\t});\n\tlet siblings = [concatList.shift()];\n\tlet sortUpdates = [];\n\tfor (; concatList.length > 0; siblings.push(concatList.shift())) {\n\t\tsortUpdates = (SortingHelpers.performIntegerSort(concatList[0], {\n\t\t\ttarget: siblings[siblings.length-1], \n\t\t\tsiblings: duplicate(siblings),\n\t\t\tsortBefore: false}));\t\t\n\t}\n\tconst updateData = sortUpdates.map(u => {\n\t\tlet update = u.update;\n\t\tupdate._id = u.target._id;\n\t\treturn update;\n\t})\n\tactor.updateEmbeddedEntity('OwnedItem', updateData);\n}\n\nasync function addAlphabeticalSorter(app, html, data) {\n\tif (!data.actor._id) return;\n\tconst header = html.querySelectorAll('.filter-list');\n\n\theader.forEach(el => {\n\t\tconst type = el.closest('.tab').dataset.tab;\n\t\tconst btn = document.createElement('a');\n\t\tbtn.innerHTML = '';\n\t\tbtn.classList.add('mess-sort-btn');\n\t\tbtn.title = `Sort ${type} alphabetically.`;\n\t\tbtn.style.flex = 0;\n\t\tbtn.style.margin = \"0 5px 0 0\";\n\t\tbtn.addEventListener('click',\t(ev) => sortItemListAlphabetically(data[type], data.actor._id))\n\t\tel.prepend(btn);\n\t});\n}\n\nexport default async function itemSortBtn() {\n\tHooks.on('renderActorSheet', (app, html, data) => {\n\t\taddAlphabeticalSorter(app, html[0], data);\n\t});\n}","export default async function addScolling() {\n\tHooks.on('renderActorSheet', async function (app, html, data) {\n\t\thtml[0].querySelectorAll('input[data-dtype=\"Number\"], .item-uses input').forEach(el => {\n\t\t\tel.addEventListener('wheel', ev => {\n\t\t\t\tev.preventDefault();\n\t\t\t\tev.stopPropagation();\n\t\t\t\tif (ev.deltaY < 0)\n\t\t\t\t\tev.currentTarget.value = Number(ev.currentTarget.value) + 1;\n\t\t\t\tif (ev.deltaY > 0)\n\t\t\t\t\tev.currentTarget.value = Math.max(Number(ev.currentTarget.value) - 1, 0);\n\n\t\t\t\t$(ev.currentTarget).change()\n\t\t\t});\n\t\t})\n\t});\n}","function onDragLeftMove(event) {\n\tconst {clones, destination, origin, originalEvent} = event.data;\n\n\t// Pan the canvas if the drag event approaches the edge\n\tcanvas._onDragCanvasPan(originalEvent);\n\n\t// Determine dragged distance\n\tconst dx = destination.x - origin.x;\n\tconst dy = destination.y - origin.y;\n\n\tlet snap = false;\n\tif (event.data.previous) {\n\t\t// Interesting would be here how this all behaves for different monitor sizes/performances and when Atro possibly introduces more adaptive rates for mosue movement. \n\t\t// Why? Because currently i just set the timedifferences between function calls to 1. So for 60Hz it behaves same as 30Hz although for 30Hz the distance travelled could be bigger.\n\t\t// All this because i don't want divisions in here for the moment....\n\t\tconst momentumThreshold = 30;\n\t\t// smaller lambda means less \"memory\" => current momentum does have more impact\n\t\t// => more jumping around between snapping and not\n\t\t// but higher means more waiting/slow movement time for it to snap\n\t\tconst lambda = 0.8;\n\t\tconst prev = event.data.previous;\n\t\tconst prevMomentum = event.data.momentum || 0;\n\t\tconst prevV = event.data.v || {x: 0, y: 0};\n\t\tconst v = {\n\t\t\tx: destination.x - prev.x,\n\t\t\ty: destination.y - prev.y\n\t\t}\n\t\tconst momentum = {\n\t\t\tx: v.x - prevV.x,\n\t\t\ty: v.y - prevV.y\n\t\t};\n\n\t\tevent.data.momentum = (momentum.x * momentum.x + momentum.y * momentum.y) + prevMomentum * lambda;\n\t\tsnap = !event.shiftKey && event.data.momentum < momentumThreshold;\n\t}\n\n\tevent.data.previous = destination;\n\n\t// Update the position of each clone\n\tfor ( let c of clones || [] ) {\n\t\tlet dest = {x: c._original.data.x + dx, y: c._original.data.y + dy};\n\t\tif ( snap ) {\n\t\t\tdest = canvas.grid.getSnappedPosition(dest.x, dest.y, this.layer.options.gridPrecision);\n\t\t}\n\t\tc.data.x = dest.x;\n\t\tc.data.y = dest.y;\n\t\tc.refresh();\n\t}\n}\n\nexport function changePlaceables() {\n\tPlaceableObject.prototype._onDragLeftMove = onDragLeftMove;\n\t// Change got bigger than expected, so.. complete swap it is\n}","import { MessSettings } from \"./settings.js\";\nimport { dndTemplateSettings, changeTemplates } from \"./modify-templates.js\";\nimport { changePlaceables } from \"./change-placeables.js\";\nimport itemSortBtn from \"./actor-item-sort-btn.js\";\nimport preparedSpellTracker from \"./prepared-spell-tracker.js\";\nimport addScrolling from \"./add-scrolling.js\";\n\nHooks.on(\"ready\", async function () {\n if (game.settings.get(\"mess\", \"actor-item-sort\")) itemSortBtn();\n if (game.settings.get(\"mess\", \"prepared-spell-tracker\"))\n preparedSpellTracker();\n if (game.settings.get(\"mess\", \"add-scrolling\")) addScrolling();\n\n if (!game.user.isGM) return;\n // Edit next line to match module.\n const module = game.modules.get(\"mess\");\n const title = module.data.title;\n const moduleVersion = module.data.version;\n game.settings.register(title, \"version\", {\n name: `${title} Version`,\n default: \"0.0.0\",\n type: String,\n scope: \"world\",\n });\n const oldVersion = game.settings.get(title, \"version\");\n\n if (!isNewerVersion(moduleVersion, oldVersion)) return;\n\n (\n await import(\n /* webpackChunkName: \"welcome-screen\" */\n \"./welcome-screen.js\"\n )\n ).default();\n});\n\nHooks.on(\"init\", function () {\n game.mess = {};\n MessSettings.init();\n\n dndTemplateSettings();\n changeTemplates();\n if (game.settings.get(\"mess\", \"change-placeables\")) changePlaceables();\n //\tif (game.settings.get('mess', 'better-draggable-lists'))\n //\t\tinitDraggableLists();\n});\n","export function changeTemplates() {\n\t// #MonkeyPatchingFTW\n\t// better than stealing the code, replacing one line and then release it under a/the wrong license..\n\t// Disadvantage: could need more fixing on updates. At least i didn#t make it line based like Kakaroto.. :P\n\n\tlet newFun = MeasuredTemplate.prototype.refresh.toString();\n\n\tif (game.settings.get('mess', 'modify-templates')) {\n\t\tnewFun = newFun.replace(\n\t\t\t/this\\.template\\.beginTextureFill\\(\\{[\\s\\S]*\\}\\)\\;/,\n\t\t\t`\n\t\t\t{\n\t\t\t\tlet mat = PIXI.Matrix.IDENTITY;\n\t\t\t\t// rectangle\n\t\t\t\tif (this.shape.width && this.shape.height)\n\t\t\t\t\tmat.scale(this.shape.width / this.texture.width, this.shape.height / this.texture.height);\n\t\t\t\telse if (this.shape.radius) {\n\t\t\t\t\tmat.scale(this.shape.radius * 2 / this.texture.height, this.shape.radius * 2 / this.texture.width)\n\t\t\t\t\t// Circle center is texture start...\n\t\t\t\t\tmat.translate(-this.shape.radius, -this.shape.radius);\n\t\t\t\t} else if (this.data.t === \"ray\") {\n\t\t\t\t\tconst d = canvas.dimensions,\n\t\t\t\t\t\t\t\theight = this.data.width * d.size / d.distance,\n\t\t\t\t\t\t\t\twidth = this.data.distance * d.size / d.distance;\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height * 0.5);\n\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t} else {// cone\n\t\t\t\t\tconst d = canvas.dimensions;\n\t\t\t\n\t\t\t\t\t// Extract and prepare data\n\t\t\t\t\tlet {direction, distance, angle} = this.data;\n\t\t\t\t\tdistance *= (d.size / d.distance);\n\t\t\t\t\tdirection = toRadians(direction);\n\t\t\t\t\tconst width = this.data.distance * d.size / d.distance;\n\n\t\t\t\t\tconst angles = [(angle/-2), (angle/2)];\n\t\t\t\t\tdistance = distance / Math.cos(toRadians(angle/2));\n\t\t\t\n\t\t\t\t\t// Get the cone shape as a polygon\n\t\t\t\t\tconst rays = angles.map(a => Ray.fromAngle(0, 0, direction + toRadians(a), distance+1));\n\t\t\t\t\tconst height = Math.sqrt((rays[0].B.x - rays[1].B.x) * (rays[0].B.x - rays[1].B.x)\n\t\t\t\t\t\t\t\t\t\t\t\t\t+ (rays[0].B.y - rays[1].B.y) * (rays[0].B.y - rays[1].B.y));\n\t\t\t\t\tmat.scale(width / this.texture.width, height / this.texture.height);\n\t\t\t\t\tmat.translate(0, -height/2)\n\t\t\t\t\tmat.rotate(toRadians(this.data.direction));\n\t\t\t\t}\n\t\t\t\tthis.template.beginTextureFill({\n\t\t\t\t\ttexture: this.texture,\n\t\t\t\t\tmatrix: mat,\n\t\t\t\t\talpha: 0.8\n\t\t\t\t});\n\t\t\t\t// move into draw or so\n\t\t\t\tconst source = getProperty(this.texture, \"baseTexture.resource.source\")\n\t\t\t\tif ( source && (source.tagName === \"VIDEO\") ) {\n\t\t\t\t\tsource.loop = true;\n\t\t\t\t\tsource.muted = true;\n\t\t\t\t\tgame.video.play(source);\n\t\t\t\t}\n\t\t}`\n\t\t);\n\n\t\tHooks.on('renderMeasuredTemplateConfig', (app, html, data) => {\n\t\t\thtml[0].querySelector('.file-picker').dataset.type = 'imagevideo';\n\t\t});\n\t}\n\n\tif (game.settings.get('mess', 'templateDrawBordersOnlyOnHighlight')) {\n\t\tnewFun = newFun.replace(\n\t\t\t/this\\.\\_borderThickness/,\n\t\t\t'this.texture && !this._hover ? 0 : this._borderThickness'\n\t\t);\n\t\tnewFun = newFun.replace(\n\t\t\t/return\\sthis\\;/,\n\t\t\t`\n\t\t\tconst grid = canvas.grid;\n\t\t\t// only show grid highlights on hover\n\t\t\tif (this.texture) {\n\t\t\t\tconst hl = grid.getHighlightLayer(\\`Template.\\$\\{this.id\\}\\`);\n\t\t\t\tif (hl)\n\t\t\t\t\thl.renderable = this._hover;\n\t\t\t}\n\t\t\treturn this;`\n\t\t);\n\t}\n\n\tMeasuredTemplate.prototype.refresh = Function(\n\t\t`\"use strict\"; return ( function ${newFun} )`\n\t)();\n\n\tif (game.settings.get('mess', 'templateAutoTargeting')) {\n\t\tMeasuredTemplate.prototype.getTargets = getTargets;\n\t\tMeasuredTemplate.prototype.isTokenInside = isTokenInside;\n\n\t\tconst oldFun = MeasuredTemplate.prototype._onDragLeftMove;\n\t\tMeasuredTemplate.prototype._onDragLeftMove = function (ev) {\n\t\t\tconst ret = oldFun.bind(this)(ev);\n\n\t\t\tfor (let c of ev.data.clones) this.getTargets(c);\n\n\t\t\treturn ret;\n\t\t};\n\t}\n}\n\nexport async function dndTemplateSettings() {\n\tif (game.system.id !== 'dnd5e') return;\n\n\tconst importedJS = await import(\n\t\t/* webpackIgnore: true */ '/systems/dnd5e/module/pixi/ability-template.js'\n\t);\n\tconst AbilityTemplate = importedJS.default || importedJS.AbilityTemplate;\n\n\t// Auto texture creation from item\n\tif (game.settings.get('mess', 'modify-templates')) {\n\t\tHooks.on('renderItemSheet', itemHook);\n\n\t\tconst _originalFromItem = AbilityTemplate.fromItem;\n\t\tAbilityTemplate.fromItem = function (item) {\n\t\t\tconst template = _originalFromItem.bind(this)(item);\n\n\t\t\t// generate a texture based on the items dmg type, ...\n\t\t\t// Add settings to define custom templates for stuff.\n\t\t\tlet path = item.getFlag('mess', 'templateTexture');\n\t\t\tif (!path && item.hasDamage) {\n\t\t\t\tconst settings = game.settings.get('mess', 'templateTexture') || {};\n\t\t\t\tpath = settings[item.data.data.damage.parts[0][1]] || {};\n\t\t\t\tpath = path[template.data.t];\n\t\t\t}\n\t\t\tif (path)\n\t\t\t\tloadTexture(path).then((tex) => {\n\t\t\t\t\ttemplate.texture = tex;\n\t\t\t\t\ttemplate.data.texture = path;\n\t\t\t\t\ttemplate.refresh();\n\t\t\t\t});\n\t\t\ttemplate.item = item;\n\t\t\treturn template;\n\t\t};\n\t}\n\n\tif (game.settings.get('mess', 'templateAutoTargeting')) {\n\t\t// rather ugly, maybe find a better way at some point :shrug:\n\t\tconst origPrevListeners = AbilityTemplate.prototype.activatePreviewListeners.toString();\n\t\tconst newFun = origPrevListeners.replace(\n\t\t\t/this\\.refresh\\(\\)\\;/,\n\t\t\t// get targets\n\t\t\t`this.refresh();\n\t\t\t\t\t\tthis.getTargets(this);\n\t\t\t\t\t`\n\t\t);\n\n\t\tAbilityTemplate.prototype.getTargets = getTargets;\n\t\tAbilityTemplate.prototype.isTokenInside = isTokenInside;\n\n\t\tAbilityTemplate.prototype.activatePreviewListeners = Function(\n\t\t\t`\"use strict\"; return ( function ${newFun} )`\n\t\t)();\n\t}\n}\n\nfunction isTokenInside(token) {\n\tconst grid = canvas.scene.data.grid,\n\t\ttemplatePos = { x: this.data.x, y: this.data.y };\n\t// Check for center of each square the token uses.\n\t// e.g. for large tokens all 4 squares\n\tconst startX = token.width >= 1 ? 0.5 : token.width / 2;\n\tconst startY = token.height >= 1 ? 0.5 : token.height / 2;\n\tfor (let x = startX; x < token.width; x++) {\n\t\tfor (let y = startY; y < token.height; y++) {\n\t\t\tconst currGrid = {\n\t\t\t\tx: token.x + x * grid - templatePos.x,\n\t\t\t\ty: token.y + y * grid - templatePos.y,\n\t\t\t};\n\t\t\tconst contains = this.shape.contains(currGrid.x, currGrid.y);\n\t\t\tif (contains) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\nfunction getTargets(template) {\n\tconst tokens = canvas.scene.getEmbeddedCollection('Token');\n\tlet targets = [];\n\n\tfor (const token of tokens)\n\t\tif (template.isTokenInside(token)) {\n\t\t\ttargets.push(token._id);\n\t\t}\n\tgame.user.updateTokenTargets(targets);\n}\n\nasync function itemHook(app, html) {\n\tconst div = document.createElement('div');\n\tdiv.classList.add('form-group');\n\tdiv.appendChild(\n\t\tdocument.createElement('label')\n\t).innerText = game.i18n.localize('MESS.itemSheet.templateTexture');\n\tconst formField = div.appendChild(document.createElement('div'));\n\tformField.classList.add('form-fields');\n\tconst inp = formField.appendChild(document.createElement('input'));\n\tinp.dataset.dtype = 'String';\n\tinp.type = 'text';\n\tinp.name = 'flags.mess.templateTexture';\n\tinp.value = app.object.getFlag('mess', 'templateTexture') || '';\n\n\tformField.insertAdjacentHTML(\n\t\t'beforeend',\n\t\t`\n\t\t\n\t`\n\t);\n\tconst button = formField.querySelector('button');\n\tbutton.style.flex = '0';\n\tapp._activateFilePicker(button);\n\tconst target = html[0].querySelector('[name=\"data.target.units\"]');\n\tif (target) target.closest('.form-group').after(div);\n}\n","export default async function addPreparedSpellTracker() {\n\tHooks.on('renderActorSheet', async function (app, html, data) {\n\t\tconst actor = await fromUuid(`Actor.${data.actor._id}`);\n\t\tif (actor.isNPC) return;\n\t\t\n\t\tconst spellDc = html[0].querySelector('.spell-dc');\n\t\tif (!spellDc) return;\n\t\tlet tracker = document.createElement('div');\n\t\ttracker.classList.add('spell-detail');\n\t\ttracker.classList.add('spell-slots');\n\t\ttracker.style.flex = '1';\n\t\ttracker.style.border = 'none';\n\t\tconst spanPrep = tracker.appendChild(document.createElement('span'));\n\t\tspanPrep.innerText = `${game.i18n.localize('MESS.actorSheet.preparedSpellTracker')}: ${data.preparedSpells}`;\n\n\t\tconst sep = tracker.appendChild(document.createElement('span'));\n\t\tsep.innerText = ' / ';\n\t\tsep.classList.add('sep');\n\n\t\tconst max = tracker.appendChild(document.createElement('input'));\n\t\tmax.type = 'text';\n\t\tmax.value = actor.getFlag('mess', 'maxPreparedSpells') || 0;\n\t\tmax.addEventListener('change', async function(ev) {\n\t\t\tev.preventDefault();\n\t\t\tev.stopPropagation();\n\t\t\tconst val = Number(ev.currentTarget.value);\n\t\t\tif (isNaN(val)) {\n\t\t\t\tev.currentTarget.value = actor.getFlag('mess', 'maxPreparedSpells') || 0;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tactor.setFlag('mess', 'maxPreparedSpells', val);\n\t\t\treturn false;\n\t\t});\n\t\t\n\t\tif (app.constructor.name === 'Tidy5eSheet') {\n\t\t\tconst el = html[0].querySelector('.spellcasting-ability');\n\t\t\tif (!el)\n\t\t\t\treturn;\n\t\t\tel.appendChild(tracker, el);\n\t\t} else {\n\t\t\tconst el = html[0].querySelector('.spellbook .inventory-list');\n\t\t\tif (!el)\treturn;\n\t\t\ttracker.style.flex = '0';\n\t\t\ttracker.style.alignSelf = 'flex-start';\n\t\t\ttracker.style.margin = '0 8px';\n\t\t\tel.parentNode.insertBefore(tracker, el);\n\t\t}\n\t});\n}","export class MessSettings extends FormApplication {\n static init() {\n const isDnD = game.system.id === \"dnd5e\";\n\n game.settings.register(\"mess\", \"actor-item-sort\", {\n name: \"Activate item sort button.\",\n hint:\n \"Adds a button to actor sheets for sorting all items of that category alphabetically.\",\n scope: \"world\",\n config: false,\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"better-draggable\", {\n name: \"Activate better drag'n'drop workflow.\",\n scope: \"world\",\n config: false, // Change if implemented\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"better-draggable-lists\", {\n name: \"Activate better drag'n'drop workflow for lists.\",\n scope: \"world\",\n config: false,\n default: true,\n type: Boolean,\n });\n game.settings.set(\"mess\", \"better-draggable-lists\", false);\n\n game.settings.register(\"mess\", \"prepared-spell-tracker\", {\n name: \"Activate prepared spell tracker\",\n hint:\n \"Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.\",\n scope: \"world\",\n config: false,\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"add-scrolling\", {\n name: \"Activating numerical field scrolling.\",\n hint:\n \"Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.\",\n scope: \"world\",\n config: false,\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"modify-rolling\", {\n name: \"Alternative Rolling.\",\n hint:\n \"Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!\",\n scope: \"world\",\n config: false,\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"attack-card-always-public\", {\n name: \"Roll mode for alternative rolling.\",\n hint:\n \"Always roll attack rolls public, with hidden rolls, but visible target.\",\n scope: \"world\",\n config: false,\n default: isDnD,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"modify-templates\", {\n name: \"Activate modified templates.\",\n hint:\n \"Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!\",\n scope: \"world\",\n config: false,\n default: true,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"change-placeables\", {\n name: \"Activate placeables changes.\",\n hint:\n \"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!\",\n scope: \"world\",\n config: false,\n default: true,\n type: Boolean,\n });\n game.settings.registerMenu(\"mess\", \"templateTexture\", {\n name: game.i18n.localize(\"MESS.FVTTSettings.description\"),\n label: game.i18n.localize(\"MESS.FVTTSettings.button\"),\n icon: \"fas fa-mug-hot\",\n type: MessSettings,\n restricted: true,\n });\n\n game.settings.register(\"mess\", \"templateTexture\", {\n name: \"Activate placeables changes.\",\n hint:\n \"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!\",\n scope: \"world\",\n default: true,\n type: Object,\n });\n\n game.settings.register(\"mess\", \"max-critical\", {\n name: \"Activate maximum critical rolls.\",\n hint:\n \"Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!\",\n scope: \"world\",\n config: false,\n default: false,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"templateTexture\", {\n name: \"Activate placeables changes.\",\n hint:\n \"Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!\",\n scope: \"world\",\n config: false,\n default: true,\n type: Object,\n });\n\n game.settings.register(\"mess\", \"templateAutoTargeting\", {\n scope: \"world\",\n default: true,\n type: Boolean,\n });\n\n game.settings.register(\"mess\", \"templateDrawBordersOnlyOnHighlight\", {\n scope: \"world\",\n default: true,\n type: Boolean,\n });\n\n this.loadTemplates();\n }\n static loadTemplates() {\n loadTemplates([\n \"modules/mess/templates/settings/templates.html\",\n \"modules/mess/templates/settings/dnd5e.html\",\n \"modules/mess/templates/settings/misc.html\",\n ]);\n }\n\n static get defaultOptions() {\n return {\n ...super.defaultOptions,\n template: \"modules/mess/templates/settings/settings.html\",\n height: \"auto\",\n title: \"Mess - Moerills enhancing super-suit(e) - Settings Menu\",\n width: 600,\n classes: [\"mess\", \"settings\"],\n tabs: [\n {\n navSelector: \".tabs\",\n contentSelector: \"form\",\n initial: \"name\",\n },\n ],\n submitOnClose: true,\n };\n }\n\n constructor(object = {}, options) {\n super(object, options);\n this.object = game.settings.get(\"mess\", \"templateTexture\");\n }\n\n _getHeaderButtons() {\n let btns = super._getHeaderButtons();\n btns[0].label = \"Save & Close\";\n return btns;\n }\n\n getSettingsData() {\n const isDnD = game.system.id === \"dnd5e\";\n let data = {\n \"modify-templates\": game.settings.get(\"mess\", \"modify-templates\"),\n \"change-placeables\": game.settings.get(\"mess\", \"change-placeables\"),\n templateTexture: game.settings.get(\"mess\", \"templateTexture\"),\n templateAutoTargeting: game.settings.get(\"mess\", \"templateAutoTargeting\"),\n templateDrawBordersOnlyOnHighlight: game.settings.get(\n \"mess\",\n \"templateDrawBordersOnlyOnHighlight\"\n ),\n \"better-draggable-lists\": game.settings.get(\n \"mess\",\n \"better-draggable-lists\"\n ),\n };\n if (isDnD) {\n data[\"templateTexture\"] = game.settings.get(\"mess\", \"templateTexture\");\n data[\"modify-rolling\"] = game.settings.get(\"mess\", \"modify-rolling\");\n data[\"max-critical\"] = game.settings.get(\"mess\", \"max-critical\");\n\n data[\"actor-item-sort\"] = game.settings.get(\"mess\", \"actor-item-sort\");\n // data['better-draggable'] = game.settings.get('mess', 'better-draggable');\n data[\"prepared-spell-tracker\"] = game.settings.get(\n \"mess\",\n \"prepared-spell-tracker\"\n );\n data[\"add-scrolling\"] = game.settings.get(\"mess\", \"add-scrolling\");\n data[\"attack-card-always-public\"] = game.settings.get(\n \"mess\",\n \"attack-card-always-public\"\n );\n }\n return data;\n }\n\n getData() {\n const isDnD = game.system.id === \"dnd5e\";\n let data = super.getData();\n if (isDnD) {\n data.dmgTypes = CONFIG.DND5E.damageTypes;\n data.templateTypes = CONFIG.MeasuredTemplate.types;\n }\n data.isDnD = isDnD;\n data.settings = this.getSettingsData();\n return data;\n }\n\n activateListeners(html) {\n super.activateListeners(html);\n }\n\n _updateObject(ev, formData) {\n const data = expandObject(formData);\n for (let [key, value] of Object.entries(data)) {\n game.settings.set(\"mess\", key, value);\n }\n new Dialog({\n content: `

      ${game.i18n.localize(\"MESS.reloadReminder.text\")}

      `,\n buttons: {\n yes: {\n icon: '',\n label: game.i18n.localize(\"MESS.reloadReminder.yes\"),\n callback: () => location.reload(),\n },\n no: {\n icon: '',\n label: game.i18n.localize(\"MESS.reloadReminder.no\"),\n },\n },\n }).render(true);\n // game.settings.set('mess', 'templateTexture', mergeObject({}, formData))\n }\n}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/templates/settings/dnd5e.html b/dist/templates/settings/dnd5e.html index 6a960a7..d906d61 100644 --- a/dist/templates/settings/dnd5e.html +++ b/dist/templates/settings/dnd5e.html @@ -15,16 +15,5 @@

      {{localize 'MESS.settings.dnd5e.rolling.header'}}

      -
      - - {{localize 'MESS.settings.dnd5e.rolling.hint'}} -
      -
      - - {{{localize 'MESS.settings.dnd5e.rolling.mode.hint'}}} -
      -
      - - {{!-- does not exist atm --}} - {{localize 'MESS.settings.dnd5e.rolling.maxCrit.hint'}} -
      +

      This feature got removed and replaced by a new and improved version in Mars 5e.

      +

      But where are the autorolls? Don't worry, they'll be there, soon.

      \ No newline at end of file diff --git a/dist/templates/welcome-screen.html b/dist/templates/welcome-screen.html index 200471a..759d6a8 100644 --- a/dist/templates/welcome-screen.html +++ b/dist/templates/welcome-screen.html @@ -7,9 +7,10 @@ } -

      Important!

      -

      This update is only a quick fix for making the rolling system work again for FVTT 0.7.5. My plans are taking to long, so i wanted to at least make the module work again in 0.7.5.
      - Please check the GitHubs issue board if you want to stay up to date on my plans and progress!

      +

      Very Important!

      +

      This update removes Mess rolling modifications for 5e. (For everyone else nothing changes)!

      +

      If you liked those changes, do not fear, i reworked them and put them into its own module, with improved design, features, code base, ...! The new module is called Mars 5e.

      +

      It is not the same as MESS, but its the way i wanted to go and keep going. Its still missing automatic rolling, but this feature is planned for the next big(ger) update.

      Best regards,
      Moerill

      diff --git a/package.json b/package.json index bb706cc..7418f0e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "module-template", - "version": "0.12.3", + "version": "0.13.0", "description": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/src/module.json b/src/module.json index 82bad37..1e7cd8c 100644 --- a/src/module.json +++ b/src/module.json @@ -2,7 +2,7 @@ "name": "mess", "title": "Mess - Moerills enhancing super-suit(e)", "description": "This module is a mix of QoL changes, enhancements for my game and stuff i play around with. For a complete feature list check the URL down below.", - "version": "0.12.3", + "version": "0.13.0", "minimumCoreVersion": "0.7.5", "compatibleCoreVersion": "0.7.9", "author": "Moerill", @@ -33,5 +33,5 @@ ], "manifest": "https://raw.githubusercontent.com/Moerill/mess/master/src/module.json", "url": "https://github.com/Moerill/mess", - "download": "https://github.com/Moerill/mess/releases/download/v0.12.3/mess.zip" + "download": "https://github.com/Moerill/mess/releases/download/v0.13.0/mess.zip" } \ No newline at end of file diff --git a/src/scripts/index.js b/src/scripts/index.js index 18b45e9..b921390 100644 --- a/src/scripts/index.js +++ b/src/scripts/index.js @@ -1,60 +1,46 @@ -import { rolling } from './rolls'; -import { MessSettings } from './settings.js'; -import { dndTemplateSettings, changeTemplates } from './modify-templates.js'; -import { changePlaceables } from './change-placeables.js'; -import itemSortBtn from './actor-item-sort-btn.js'; -import preparedSpellTracker from './prepared-spell-tracker.js'; -import addScrolling from './add-scrolling.js'; - -import { initDraggableLists } from './draggable-lists'; -import { initChatPopUp } from './chat-popup'; - -Hooks.on('ready', async function () { - if (game.settings.get('mess', 'actor-item-sort')) itemSortBtn(); - if (game.settings.get('mess', 'prepared-spell-tracker')) - preparedSpellTracker(); - if (game.settings.get('mess', 'add-scrolling')) addScrolling(); - - if (CONFIG.debug.mess) { - const actor = await fromUuid('Actor.xV3LUAg05Pz5MFTS'); - actor.sheet.render(true); - } - - // initChatPopUp(); - - if (!game.user.isGM) return; - // Edit next line to match module. - const module = game.modules.get('mess'); - const title = module.data.title; - const moduleVersion = module.data.version; - game.settings.register(title, 'version', { - name: `${title} Version`, - default: '0.0.0', - type: String, - scope: 'world', - }); - const oldVersion = game.settings.get(title, 'version'); - - if (!isNewerVersion(moduleVersion, oldVersion)) return; - - ( - await import( - /* webpackChunkName: "welcome-screen" */ - './welcome-screen.js' - ) - ).default(); +import { MessSettings } from "./settings.js"; +import { dndTemplateSettings, changeTemplates } from "./modify-templates.js"; +import { changePlaceables } from "./change-placeables.js"; +import itemSortBtn from "./actor-item-sort-btn.js"; +import preparedSpellTracker from "./prepared-spell-tracker.js"; +import addScrolling from "./add-scrolling.js"; + +Hooks.on("ready", async function () { + if (game.settings.get("mess", "actor-item-sort")) itemSortBtn(); + if (game.settings.get("mess", "prepared-spell-tracker")) + preparedSpellTracker(); + if (game.settings.get("mess", "add-scrolling")) addScrolling(); + + if (!game.user.isGM) return; + // Edit next line to match module. + const module = game.modules.get("mess"); + const title = module.data.title; + const moduleVersion = module.data.version; + game.settings.register(title, "version", { + name: `${title} Version`, + default: "0.0.0", + type: String, + scope: "world", + }); + const oldVersion = game.settings.get(title, "version"); + + if (!isNewerVersion(moduleVersion, oldVersion)) return; + + ( + await import( + /* webpackChunkName: "welcome-screen" */ + "./welcome-screen.js" + ) + ).default(); }); -Hooks.on('init', function () { - game.mess = {}; - CONFIG.debug.mess = false; - MessSettings.init(); - - rolling(); +Hooks.on("init", function () { + game.mess = {}; + MessSettings.init(); - dndTemplateSettings(); - changeTemplates(); - if (game.settings.get('mess', 'change-placeables')) changePlaceables(); - // if (game.settings.get('mess', 'better-draggable-lists')) - // initDraggableLists(); + dndTemplateSettings(); + changeTemplates(); + if (game.settings.get("mess", "change-placeables")) changePlaceables(); + // if (game.settings.get('mess', 'better-draggable-lists')) + // initDraggableLists(); }); diff --git a/src/scripts/settings.js b/src/scripts/settings.js index 0c31a24..7807862 100644 --- a/src/scripts/settings.js +++ b/src/scripts/settings.js @@ -1,256 +1,253 @@ export class MessSettings extends FormApplication { - static init() { - const isDnD = game.system.id === 'dnd5e'; - - game.settings.register('mess', 'actor-item-sort', { - name: 'Activate item sort button.', - hint: - 'Adds a button to actor sheets for sorting all items of that category alphabetically.', - scope: 'world', - config: false, - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'better-draggable', { - name: "Activate better drag'n'drop workflow.", - scope: 'world', - config: false, // Change if implemented - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'better-draggable-lists', { - name: "Activate better drag'n'drop workflow for lists.", - scope: 'world', - config: false, - default: true, - type: Boolean, - }); - game.settings.set('mess', 'better-draggable-lists', false); - - game.settings.register('mess', 'prepared-spell-tracker', { - name: 'Activate prepared spell tracker', - hint: - 'Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.', - scope: 'world', - config: false, - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'add-scrolling', { - name: 'Activating numerical field scrolling.', - hint: - 'Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.', - scope: 'world', - config: false, - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'modify-rolling', { - name: 'Alternative Rolling.', - hint: - 'Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!', - scope: 'world', - config: false, - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'attack-card-always-public', { - name: 'Roll mode for alternative rolling.', - hint: - 'Always roll attack rolls public, with hidden rolls, but visible target.', - scope: 'world', - config: false, - default: isDnD, - type: Boolean, - }); - - game.settings.register('mess', 'modify-templates', { - name: 'Activate modified templates.', - hint: - 'Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!', - scope: 'world', - config: false, - default: true, - type: Boolean, - }); - - game.settings.register('mess', 'change-placeables', { - name: 'Activate placeables changes.', - hint: - 'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!', - scope: 'world', - config: false, - default: true, - type: Boolean, - }); - game.settings.registerMenu('mess', 'templateTexture', { - name: game.i18n.localize('MESS.FVTTSettings.description'), - label: game.i18n.localize('MESS.FVTTSettings.button'), - icon: 'fas fa-mug-hot', - type: MessSettings, - restricted: true, - }); - - game.settings.register('mess', 'templateTexture', { - name: 'Activate placeables changes.', - hint: - 'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!', - scope: 'world', - default: true, - type: Object, - }); - - game.settings.register('mess', 'max-critical', { - name: 'Activate maximum critical rolls.', - hint: - 'Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!', - scope: 'world', - config: false, - default: false, - type: Boolean, - }); - - game.settings.register('mess', 'templateTexture', { - name: 'Activate placeables changes.', - hint: - 'Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!', - scope: 'world', - config: false, - default: true, - type: Object, - }); - - game.settings.register('mess', 'templateAutoTargeting', { - scope: 'world', - default: true, - type: Boolean, - }); - - game.settings.register('mess', 'templateDrawBordersOnlyOnHighlight', { - scope: 'world', - default: true, - type: Boolean, - }); - - this.loadTemplates(); - } - static loadTemplates() { - loadTemplates([ - 'modules/mess/templates/settings/templates.html', - 'modules/mess/templates/settings/dnd5e.html', - 'modules/mess/templates/settings/misc.html', - ]); - } - - static get defaultOptions() { - return { - ...super.defaultOptions, - template: 'modules/mess/templates/settings/settings.html', - height: 'auto', - title: 'Mess - Moerills enhancing super-suit(e) - Settings Menu', - width: 600, - classes: ['mess', 'settings'], - tabs: [ - { - navSelector: '.tabs', - contentSelector: 'form', - initial: 'name', - }, - ], - submitOnClose: true, - }; - } - - constructor(object = {}, options) { - super(object, options); - this.object = game.settings.get('mess', 'templateTexture'); - } - - _getHeaderButtons() { - let btns = super._getHeaderButtons(); - btns[0].label = 'Save & Close'; - return btns; - } - - getSettingsData() { - const isDnD = game.system.id === 'dnd5e'; - let data = { - 'modify-templates': game.settings.get('mess', 'modify-templates'), - 'change-placeables': game.settings.get('mess', 'change-placeables'), - 'templateTexture': game.settings.get('mess', 'templateTexture'), - 'templateAutoTargeting': game.settings.get( - 'mess', - 'templateAutoTargeting' - ), - 'templateDrawBordersOnlyOnHighlight': game.settings.get( - 'mess', - 'templateDrawBordersOnlyOnHighlight' - ), - 'better-draggable-lists': game.settings.get( - 'mess', - 'better-draggable-lists' - ), - }; - if (isDnD) { - data['templateTexture'] = game.settings.get('mess', 'templateTexture'); - data['modify-rolling'] = game.settings.get('mess', 'modify-rolling'); - data['max-critical'] = game.settings.get('mess', 'max-critical'); - - data['actor-item-sort'] = game.settings.get('mess', 'actor-item-sort'); - // data['better-draggable'] = game.settings.get('mess', 'better-draggable'); - data['prepared-spell-tracker'] = game.settings.get( - 'mess', - 'prepared-spell-tracker' - ); - data['add-scrolling'] = game.settings.get('mess', 'add-scrolling'); - data['attack-card-always-public'] = game.settings.get( - 'mess', - 'attack-card-always-public' - ); - } - return data; - } - - getData() { - const isDnD = game.system.id === 'dnd5e'; - let data = super.getData(); - if (isDnD) { - data.dmgTypes = CONFIG.DND5E.damageTypes; - data.templateTypes = CONFIG.MeasuredTemplate.types; - } - data.isDnD = isDnD; - data.settings = this.getSettingsData(); - return data; - } - - activateListeners(html) { - super.activateListeners(html); - } - - _updateObject(ev, formData) { - const data = expandObject(formData); - for (let [key, value] of Object.entries(data)) { - game.settings.set('mess', key, value); - } - new Dialog({ - content: `

      ${game.i18n.localize('MESS.reloadReminder.text')}

      `, - buttons: { - yes: { - icon: '', - label: game.i18n.localize('MESS.reloadReminder.yes'), - callback: () => location.reload(), - }, - no: { - icon: '', - label: game.i18n.localize('MESS.reloadReminder.no'), - }, - }, - }).render(true); - // game.settings.set('mess', 'templateTexture', mergeObject({}, formData)) - } + static init() { + const isDnD = game.system.id === "dnd5e"; + + game.settings.register("mess", "actor-item-sort", { + name: "Activate item sort button.", + hint: + "Adds a button to actor sheets for sorting all items of that category alphabetically.", + scope: "world", + config: false, + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "better-draggable", { + name: "Activate better drag'n'drop workflow.", + scope: "world", + config: false, // Change if implemented + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "better-draggable-lists", { + name: "Activate better drag'n'drop workflow for lists.", + scope: "world", + config: false, + default: true, + type: Boolean, + }); + game.settings.set("mess", "better-draggable-lists", false); + + game.settings.register("mess", "prepared-spell-tracker", { + name: "Activate prepared spell tracker", + hint: + "Adds a tracker to the spellbook tab, providing a way to track the allowed maximum of prepared spells.", + scope: "world", + config: false, + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "add-scrolling", { + name: "Activating numerical field scrolling.", + hint: + "Lets you in-/decrease numerical fields in the Actor sheet using the mouse wheel when focused.", + scope: "world", + config: false, + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "modify-rolling", { + name: "Alternative Rolling.", + hint: + "Changes the way rolling is displayed and executed for DnD5e. Reload for all connected clients is required for this to take effect if changed!", + scope: "world", + config: false, + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "attack-card-always-public", { + name: "Roll mode for alternative rolling.", + hint: + "Always roll attack rolls public, with hidden rolls, but visible target.", + scope: "world", + config: false, + default: isDnD, + type: Boolean, + }); + + game.settings.register("mess", "modify-templates", { + name: "Activate modified templates.", + hint: + "Makes templates texture fill scaling instead of tiling and does allow the usage of videos as texture. Reload for all connected clients is required for this to take effect if changed!", + scope: "world", + config: false, + default: true, + type: Boolean, + }); + + game.settings.register("mess", "change-placeables", { + name: "Activate placeables changes.", + hint: + "Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!", + scope: "world", + config: false, + default: true, + type: Boolean, + }); + game.settings.registerMenu("mess", "templateTexture", { + name: game.i18n.localize("MESS.FVTTSettings.description"), + label: game.i18n.localize("MESS.FVTTSettings.button"), + icon: "fas fa-mug-hot", + type: MessSettings, + restricted: true, + }); + + game.settings.register("mess", "templateTexture", { + name: "Activate placeables changes.", + hint: + "Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!", + scope: "world", + default: true, + type: Object, + }); + + game.settings.register("mess", "max-critical", { + name: "Activate maximum critical rolls.", + hint: + "Changes behaviour of critical damage rolls to maximize the damage of the extra dice for criticals!", + scope: "world", + config: false, + default: false, + type: Boolean, + }); + + game.settings.register("mess", "templateTexture", { + name: "Activate placeables changes.", + hint: + "Changes some behaviours of placeables, like preview snapping to grid. Reload for all connected clients is required for this to take effect if changed!", + scope: "world", + config: false, + default: true, + type: Object, + }); + + game.settings.register("mess", "templateAutoTargeting", { + scope: "world", + default: true, + type: Boolean, + }); + + game.settings.register("mess", "templateDrawBordersOnlyOnHighlight", { + scope: "world", + default: true, + type: Boolean, + }); + + this.loadTemplates(); + } + static loadTemplates() { + loadTemplates([ + "modules/mess/templates/settings/templates.html", + "modules/mess/templates/settings/dnd5e.html", + "modules/mess/templates/settings/misc.html", + ]); + } + + static get defaultOptions() { + return { + ...super.defaultOptions, + template: "modules/mess/templates/settings/settings.html", + height: "auto", + title: "Mess - Moerills enhancing super-suit(e) - Settings Menu", + width: 600, + classes: ["mess", "settings"], + tabs: [ + { + navSelector: ".tabs", + contentSelector: "form", + initial: "name", + }, + ], + submitOnClose: true, + }; + } + + constructor(object = {}, options) { + super(object, options); + this.object = game.settings.get("mess", "templateTexture"); + } + + _getHeaderButtons() { + let btns = super._getHeaderButtons(); + btns[0].label = "Save & Close"; + return btns; + } + + getSettingsData() { + const isDnD = game.system.id === "dnd5e"; + let data = { + "modify-templates": game.settings.get("mess", "modify-templates"), + "change-placeables": game.settings.get("mess", "change-placeables"), + templateTexture: game.settings.get("mess", "templateTexture"), + templateAutoTargeting: game.settings.get("mess", "templateAutoTargeting"), + templateDrawBordersOnlyOnHighlight: game.settings.get( + "mess", + "templateDrawBordersOnlyOnHighlight" + ), + "better-draggable-lists": game.settings.get( + "mess", + "better-draggable-lists" + ), + }; + if (isDnD) { + data["templateTexture"] = game.settings.get("mess", "templateTexture"); + data["modify-rolling"] = game.settings.get("mess", "modify-rolling"); + data["max-critical"] = game.settings.get("mess", "max-critical"); + + data["actor-item-sort"] = game.settings.get("mess", "actor-item-sort"); + // data['better-draggable'] = game.settings.get('mess', 'better-draggable'); + data["prepared-spell-tracker"] = game.settings.get( + "mess", + "prepared-spell-tracker" + ); + data["add-scrolling"] = game.settings.get("mess", "add-scrolling"); + data["attack-card-always-public"] = game.settings.get( + "mess", + "attack-card-always-public" + ); + } + return data; + } + + getData() { + const isDnD = game.system.id === "dnd5e"; + let data = super.getData(); + if (isDnD) { + data.dmgTypes = CONFIG.DND5E.damageTypes; + data.templateTypes = CONFIG.MeasuredTemplate.types; + } + data.isDnD = isDnD; + data.settings = this.getSettingsData(); + return data; + } + + activateListeners(html) { + super.activateListeners(html); + } + + _updateObject(ev, formData) { + const data = expandObject(formData); + for (let [key, value] of Object.entries(data)) { + game.settings.set("mess", key, value); + } + new Dialog({ + content: `

      ${game.i18n.localize("MESS.reloadReminder.text")}

      `, + buttons: { + yes: { + icon: '', + label: game.i18n.localize("MESS.reloadReminder.yes"), + callback: () => location.reload(), + }, + no: { + icon: '', + label: game.i18n.localize("MESS.reloadReminder.no"), + }, + }, + }).render(true); + // game.settings.set('mess', 'templateTexture', mergeObject({}, formData)) + } } diff --git a/src/templates/settings/dnd5e.html b/src/templates/settings/dnd5e.html index 6a960a7..d906d61 100644 --- a/src/templates/settings/dnd5e.html +++ b/src/templates/settings/dnd5e.html @@ -15,16 +15,5 @@

      {{localize 'MESS.settings.dnd5e.rolling.header'}}

      -
      - - {{localize 'MESS.settings.dnd5e.rolling.hint'}} -
      -
      - - {{{localize 'MESS.settings.dnd5e.rolling.mode.hint'}}} -
      -
      - - {{!-- does not exist atm --}} - {{localize 'MESS.settings.dnd5e.rolling.maxCrit.hint'}} -
      +

      This feature got removed and replaced by a new and improved version in Mars 5e.

      +

      But where are the autorolls? Don't worry, they'll be there, soon.

      \ No newline at end of file diff --git a/src/templates/welcome-screen.html b/src/templates/welcome-screen.html index 200471a..759d6a8 100644 --- a/src/templates/welcome-screen.html +++ b/src/templates/welcome-screen.html @@ -7,9 +7,10 @@ } -

      Important!

      -

      This update is only a quick fix for making the rolling system work again for FVTT 0.7.5. My plans are taking to long, so i wanted to at least make the module work again in 0.7.5.
      - Please check the GitHubs issue board if you want to stay up to date on my plans and progress!

      +

      Very Important!

      +

      This update removes Mess rolling modifications for 5e. (For everyone else nothing changes)!

      +

      If you liked those changes, do not fear, i reworked them and put them into its own module, with improved design, features, code base, ...! The new module is called Mars 5e.

      +

      It is not the same as MESS, but its the way i wanted to go and keep going. Its still missing automatic rolling, but this feature is planned for the next big(ger) update.

      Best regards,
      Moerill