diff --git a/README.md b/README.md index b1f9734..831cf61 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ This is still in very early stages still. Some ideas for the future of the mod i * Impassable tiles and/or "dangerous" tiles. # Changelog +0.0.7 - 7.6 update. Added some configurable options for Icon Scale, Opacity, and Multiples. 0.0.6 - Fixed problem with hex grid and add warning message to unsupported gridless maps. 0.0.5 - A whole lotta bugfixes. 0.0.4 - Changes to Terrain layer now broadcast to players. diff --git a/classes/TerrainLayer.js b/classes/TerrainLayer.js index 3913036..5cb96c1 100644 --- a/classes/TerrainLayer.js +++ b/classes/TerrainLayer.js @@ -66,20 +66,22 @@ export class TerrainHighlight extends PIXI.Graphics { } } export class TerrainLayer extends CanvasLayer{ - constructor(scene){ + constructor(){ super(); - this.scene = scene; - this.sceneId = this.scene._id; - this.layerName = `DifficultTerrain.${this.scene._id}`; + this.scene = null; + // this.sceneId = this.scene._id; + //this.layerName = `DifficultTerrain.${this.scene._id}`; this.highlight = null; this.mouseInteractionManager = null; this.dragging = false; - this._addListeners(); + // this._addListeners(); + } async draw(){ this._deRegisterMouseListeners() await super.draw(); + console.log('draw') this.highlightLayers = {}; this.scene = canvas.scene; this.sceneId = this.scene._id; @@ -88,9 +90,11 @@ export class TerrainLayer extends CanvasLayer{ this.addHighlightLayer(this.layerName); this.costGrid = this.scene.getFlag('TerrainLayer','costGrid') ?? {}; Hooks.once('canvasReady',this.buildFromCostGrid.bind(this)) + this._addListeners(); return this; } async tearDown(){ + console.log('tearDown') super.tearDown(); this._deRegisterMouseListeners() this._deRegisterKeyboardListeners(); @@ -168,30 +172,34 @@ export class TerrainLayer extends CanvasLayer{ const key = `${px[0]}.${px[1]}`; - layer.highlight(px[0],px[1]); - let s = canvas.dimensions.size; - let terrainSquare = new TerrainSquare({x:gridX,y:gridY}) - let offset = 15; - terrainSquare.x = px[0]; - terrainSquare.y = px[1]; - terrainSquare.width = gsW; - terrainSquare.height = gsH; - terrainSquare.lineStyle(7, 0xffffff, 0.5); - terrainSquare.moveTo((gsW/2), offset); - terrainSquare.lineTo(offset, gsH-offset); - terrainSquare.lineTo(gsW-offset, gsH-offset); - terrainSquare.lineTo((gsW/2), offset); - terrainSquare.closePath(); - terrainSquare.blendMode = PIXI.BLEND_MODES.OVERLAY; - - let text = new PIXI.Text('x'+multiple,{fontFamily : 'Arial', fontSize: 12, fill : 0xffffff,opacity:0.5, align : 'center'}) - text.blendMode = PIXI.BLEND_MODES.OVERLAY; - text.anchor.set(0.5,0.5); - text.x = gsW/2; - text.y = (gsH/2)+7; - - terrainSquare.addChild(text); - layer.addChild(terrainSquare); + layer.highlight(px[0],px[1]); + let s = canvas.dimensions.size; + let terrainSquare = new TerrainSquare({x:gridX,y:gridY}) + let offset = 15; + terrainSquare.x = px[0]; + terrainSquare.y = px[1]; + terrainSquare.width = gsW; + terrainSquare.height = gsH; + terrainSquare.lineStyle(7, 0xffffff, 0.5); + terrainSquare.moveTo((gsW/2), offset); + terrainSquare.lineTo(offset, gsH-offset); + terrainSquare.lineTo(gsW-offset, gsH-offset); + terrainSquare.lineTo((gsW/2), offset); + terrainSquare.closePath(); + terrainSquare.blendMode = PIXI.BLEND_MODES.OVERLAY; + + let text = new PIXI.Text('x'+multiple,{fontFamily : 'Arial', fontSize: 12, fill : 0xffffff,opacity:game.settings.get('TerrainLayer','opacity'), align : 'center'}) + text.blendMode = PIXI.BLEND_MODES.OVERLAY; + text.anchor.set(0.5,0.5); + text.x = gsW/2; + text.y = (gsH/2)+7; + + terrainSquare.addChild(text); + terrainSquare.scale.x = game.settings.get('TerrainLayer','scale'); + terrainSquare.scale.y = game.settings.get('TerrainLayer','scale'); + terrainSquare.alpha = game.settings.get('TerrainLayer','opacity') + // console.log(terrainSquare) + layer.addChild(terrainSquare); // this.addToCostGrid(gridX,gridY); @@ -323,7 +331,7 @@ export class TerrainLayer extends CanvasLayer{ let square = this.getSquare(layer,key) let cost = this.costGrid[x][y]; - if(cost.multiple <3){ + if(cost.multiple < game.settings.get('TerrainLayer','maxMultiple')){ this.costGrid[x][y].multiple+=1; }else{ @@ -356,16 +364,18 @@ export class TerrainLayer extends CanvasLayer{ } switch(e.data.button){ case 0: - if(game.activeTool == 'add' && !this.dragging){ + + if(game.activeTool == 'addterrain' && !this.dragging){ if(this.terrainExists(pxX,pxY)){ this.updateTerrain(x,y,true,false); }else{ this.addTerrain(x,y,true,false) } - }else if(game.activeTool == 'subtract'){ - - this.removeTerrain(x,y,true,false); + }else if(game.activeTool == 'subtractterrain'){ + if(this.terrainExists(pxX,pxY)){ + this.removeTerrain(x,y,true,false); + } } break; @@ -393,7 +403,7 @@ export class TerrainLayer extends CanvasLayer{ await canvas.scene.setFlag('TerrainLayer','costGrid',x) } buildFromCostGrid(update=true){ - + canvas.terrain.highlight.children[0].removeChildren() for(let x in this.costGrid){ for(let y in this.costGrid[x]){ @@ -423,12 +433,12 @@ export class TerrainLayer extends CanvasLayer{ for(let x = startGrid[0];x<=endGrid[0];x++){ for(let y = startGrid[1];y<=endGrid[1];y++){ - if(game.activeTool == 'add' && TLControlPress == false){ + if(game.activeTool == 'addterrain' && TLControlPress == false){ //this.highlightPosition(this.layerName,{gridX:y,gridY:x}) //this.addToCostGrid(x,y); if(!this.terrainExists(y*canvas.dimensions.size,x*canvas.dimensions.size)) this.addTerrain(x,y,true,true) - }else if(game.activeTool == 'subtract' || TLControlPress){ + }else if(game.activeTool == 'subtractterrain' || TLControlPress){ this.removeTerrain(x,y,true,true) @@ -441,7 +451,7 @@ export class TerrainLayer extends CanvasLayer{ } async removeTerrain(x,y,emit=false,batch=true){ - + console.log('removeTerrain') const [pxX,pxY] = canvas.grid.grid.getPixelsFromGridPosition(x,y) const layer = canvas.terrain.getHighlightLayer(this.layerName); const key = `${pxX}.${pxY}`; @@ -477,7 +487,7 @@ export class TerrainLayer extends CanvasLayer{ } _onDragLeftMove(e){ - const isSelect = ["add","subtract"].includes(game.activeTool); + const isSelect = ["addterrain","subtractterrain"].includes(game.activeTool); if ( isSelect ) return this._onDragSelect(e); } _onDragSelect(event) { @@ -502,11 +512,11 @@ export class TerrainLayer extends CanvasLayer{ const tool = game.activeTool; // Conclude a select event - const isSelect = ["add","subtract"].includes(tool); + const isSelect = ["addterrain","subtractterrain"].includes(tool); if ( isSelect ) { canvas.controls.select.clear(); canvas.controls.select.active = false; - if ( tool === "add" || tool === "subtract") return this.selectSquares(e.data.coords); + if ( tool === "addterrain" || tool === "subtractterrain") return this.selectSquares(e.data.coords); } canvas.controls.select.clear(); } @@ -521,9 +531,9 @@ export class TerrainLayer extends CanvasLayer{ let key = `${px[0]}.${px[1]}`; const layer = canvas.terrain.getHighlightLayer(this.layerName); let square = this.getSquare(layer,key) - if(game.activeTool == 'add' && square){ + if(game.activeTool == 'addterrain' && square){ - this.removeTerrain(x,y,true); + this.removeTerrain(x,y,true,false); } } @@ -552,10 +562,13 @@ export class TerrainLayer extends CanvasLayer{ } activate() { + super.activate(); + const options = this.constructor.layerOptions; this.interactive = true; this._registerMouseListeners(); this._registerKeyboardListeners(); + //canvas.activeLayer = canvas.terrain; } /** * Actions upon layer becoming inactive diff --git a/js/controls.js b/js/controls.js index e7a71ee..cf4a31c 100644 --- a/js/controls.js +++ b/js/controls.js @@ -1,28 +1,28 @@ Hooks.on('getSceneControlButtons', (controls) => { - if (game.user.isGM) { + if (game.user.isGM && canvas != null) { controls.push({ name: 'terrain', title: game.i18n.localize('EM.sf'), icon: 'fas fa-mountain', layer: 'TerrainLayer', tools: [ - { - name: 'terraintoggle', - title: game.i18n.localize('EM.onoff'), - icon: 'fas fa-eye', - onClick: () => { - canvas.terrain.toggle(true); - }, - active: canvas.terrain.highlight.children[0].visible, - toggle: true + { + name: 'terraintoggle', + title: game.i18n.localize('EM.onoff'), + icon: 'fas fa-eye', + onClick: () => { + canvas.terrain.toggle(true); + }, + active: canvas.terrain.highlight.children[0].visible, + toggle: true }, { - name: 'add', + name: 'addterrain', title:'EM.select', icon:'fas fa-plus-square' }, { - name:'subtract', + name:'subtractterrain', title:'EM.subtract', icon:'fas fa-minus-square' }, @@ -53,19 +53,49 @@ Hooks.on('getSceneControlButtons', (controls) => { button: true, }, ], - activeTool:'add' + activeTool:'addterrain' }) } }); -Hooks.on('renderSceneControls', (controls) => { - // Switching to layer - if (controls.activeControl === 'terrain') { - // Open brush tools if not already open - - } - // Switching away from layer - else { - // Clear active tool - - } -}); \ No newline at end of file +Hooks.on('init',()=>{ + game.settings.register('TerrainLayer', 'scale', { + name: "TerrainLayer.scale-s", + hint: "TerrainLayer.scale-l", + scope: "world", + config: true, + default: 1, + type: Number, + range:{ + min:0.4, + max:1, + step:0.1 + }, + onChange: () => { + canvas.terrain.buildFromCostGrid(); + } + }); + game.settings.register('TerrainLayer', 'opacity', { + name: "TerrainLayer.opacity-s", + hint: "TerrainLayer.opacity-l", + scope: "world", + config: true, + default: 1, + type: Number, + range:{ + min:0.3, + max:1, + step:0.1 + }, + onChange: () => { + canvas.terrain.buildFromCostGrid(); + } + }); + game.settings.register('TerrainLayer', 'maxMultiple', { + name: "TerrainLayer.opacity-s", + hint: "TerrainLayer.opacity-l", + scope: "world", + config: true, + default: 3, + type: Number + }); +}) \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 6de44a7..22a08db 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1,11 +1,17 @@ { - "EM.ok": "OK", - "EM.sf": "Terrain Grid", - "EM.select":"Add Difficult Terrain", - "EM.subtract":"Remove Difficult Terrain", - "EM.fill":"Fill Grid", - "EM.confirmFill":"This will mark every grid space as difficult terrain, overwriting any spots you've marked.", - "EM.onoff": "Enable/Disable Terrain", - "EM.reset": "Reset Terrain", - "EM.confirmReset": "Are you sure? Terrain layer will be reset." + "TerrainLayer.ok": "OK", + "TerrainLayer.sf": "Terrain Grid", + "TerrainLayer.select":"Add Difficult Terrain", + "TerrainLayer.subtract":"Remove Difficult Terrain", + "TerrainLayer.fill":"Fill Grid", + "TerrainLayer.confirmFill":"This will mark every grid space as difficult terrain, overwriting any spots you've marked.", + "TerrainLayer.onoff": "Enable/Disable Terrain", + "TerrainLayer.reset": "Reset Terrain", + "TerrainLayer.confirmReset": "Are you sure? Terrain layer will be reset.", + "TerrainLayer.scale-s":"Terrain Icon Scale", + "TerrainLayer.scale-l":"The scale of the icons.", + "TerrainLayer.opacity-s":"Terrain Icon Opacity", + "TerrainLayer.opacity-l":"Opacity of the Icon and Number.", + "TerrainLayer.opacity-s":"Multiple Max", + "TerrainLayer.opacity-l":"Set how high multiple goes." } diff --git a/lang/es.json b/lang/es.json index 8cb8a89..7b6c63a 100644 --- a/lang/es.json +++ b/lang/es.json @@ -1,12 +1,12 @@ { - "EM.ok": "OK", - "EM.sf": "Cuadrícula del Terreno", - "EM.select":"Agregar Terreno Dificil", - "EM.subtract":"Eliminar Terreno Dificil", - "EM.fill":"Llenar Cuadrícula", - "EM.confirmFill":"Este acción marcará todos de las cajas en la cuadrícula con el terreno difícil y sobrescribirá todas de las cajas previamente marcadas.", - "EM.onoff": "Habilitar/Inhabilitar Terreno", - "EM.reset": "Reajustar Terreno", - "EM.confirmReset": "¿Estas seguro? La capa del terreno se restablecerá." + "TerrainLayer.ok": "OK", + "TerrainLayer.sf": "Cuadrícula del Terreno", + "TerrainLayer.select":"Agregar Terreno Dificil", + "TerrainLayer.subtract":"Eliminar Terreno Dificil", + "TerrainLayer.fill":"Llenar Cuadrícula", + "TerrainLayer.confirmFill":"Este acción marcará todos de las cajas en la cuadrícula con el terreno difícil y sobrescribirá todas de las cajas previamente marcadas.", + "TerrainLayer.onoff": "Habilitar/Inhabilitar Terreno", + "TerrainLayer.reset": "Reajustar Terreno", + "TerrainLayer.confirmReset": "¿Estas seguro? La capa del terreno se restablecerá." } \ No newline at end of file diff --git a/module.json b/module.json index 59eb795..f45e7ab 100644 --- a/module.json +++ b/module.json @@ -3,9 +3,9 @@ "title": "Terrain Layer", "description": "A base module that adds a Terrain Layer to Foundry to paint difficult terrain squares and to be used as a dependency for other mods who might integrate it with their functionality.", "authors": [{"name":"Will Saunders","email":"willsaunders1014@gmail.com" }], - "version": "0.0.6", - "minimumCoreVersion": "0.6.4", - "compatibleCoreVersion":"0.6.6", + "version": "0.0.7", + "minimumCoreVersion": "0.6.6", + "compatibleCoreVersion":"0.7.5", "scripts":[ ], @@ -31,5 +31,5 @@ "changelog":"https://raw.githubusercontent.com/wsaunders1014/TerrainLayer/master/README.md", "url":"https://github.com/wsaunders1014/TerrainLayer", "manifest":"https://raw.githubusercontent.com/wsaunders1014/TerrainLayer/master/module.json", - "download":"https://github.com/wsaunders1014/TerrainLayer/releases/download/0.0.6/TerrainLayer.zip" + "download":"https://github.com/wsaunders1014/TerrainLayer/releases/download/0.0.7/TerrainLayer.zip" } diff --git a/terrain.js b/terrain.js index 4ebd796..f6e219f 100644 --- a/terrain.js +++ b/terrain.js @@ -1,110 +1,14 @@ import {TerrainLayer} from './classes/TerrainLayer.js'; -/* data = { - function, - data:{ - - } -} -*/ Hooks.on('init',()=>{ game.socket.on('module.TerrainLayer', async (data) => { console.log(data) canvas.terrain[data.action].apply(canvas.terrain,data.arguments); - /*switch(data.action){ - case 'addTerrain': - canvas.terrain.addTerrain.apply(canvas.terrain,data.arguments) - break; - default: - break; - }*/ - }) }) -Hooks.once('canvasInit', (canvas) => { - console.log('canvasInit') - const layerct = canvas.stage.getChildIndex(canvas.tokens)-1; +let theLayers = Canvas.layers; +theLayers.terrain = TerrainLayer; - canvas.terrain = canvas.stage.addChildAt(new TerrainLayer(canvas.scene), layerct); - -}); -Hooks.on('canvasReady', (canvas) => { - -}) -/*Hooks.on('preUpdateScene',(scene,updates,diff)=>{ - console.log(scene,updates,diff) - if(updates?.flags?.TerrainLayer !== undefined){ - if(typeof updates.flags.TerrainLayer['-=costGrid'] !== 'undefined'){ // Something has been unset. - if(updates.flags.TerrainLayer['-=costGrid'] === null){ //whole grid is unset - console.log('delete flag') - canvas.terrain.resetGrid(false); //remove all grid info. - }else{ // only part of grid was removed - - } - } - if(typeof updates.flags.TerrainLayer.costGrid !== 'undefined'){// something has been added. - //canvas.terrain.costGrid = mergeObject(canvas.terrain.costGrid,updates.flag.TerrainLayer.costGrid - for( x in updates.flags.TerrainLayer.costGrid){ - console.log(x) - } - } - //canvas.terrain.updateCostGrid(updates.flags.TerrainLayer.costGrid); - } - return true; -}) -Hooks.on('updateScene',(scene,updates,diff,userID)=>{ - console.log(scene,updates,diff,userID) -})*/ - - -/* -key = `flags.${scope}.${key}`; -return this.update({[key]: value}); - -static async update(data, options={}) { - const entityName = this.entity; - const collection = this.collection; - const user = game.user; - options = mergeObject({diff: true}, options); - - // Iterate over requested update data - data = data instanceof Array ? data : [data]; - const updates = data.reduce((arr, d) => { - - // Get the Entity being updated - if ( !d._id ) throw new Error(`You must provide an _id for every ${entityName} in the data Array.`); - const entity = collection.get(d._id, {strict: true}); - - // Diff the update against the current data - if ( options.diff ) { - d = diffObject(entity.data, expandObject(d)); - if ( isObjectEmpty(d) ) return arr; - d["_id"] = entity.id; - } - - // Call pre-update hooks to ensure the update is allowed to proceed - const allowed = Hooks.call(`preUpdate${entityName}`, entity, d, options, user._id); - if ( allowed === false ) { - console.debug(`${vtt} | ${entityName} update prevented by preUpdate hook`); - return arr; - } - - // Stage the update - arr.push(d); - return arr; - }, []); - if ( !updates.length ) return []; - - // Trigger the Socket workflow - const response = await SocketInterface.dispatch("modifyDocument", { - type: entityName, - action: "update", - data: updates, - options: options - }); - - // Call the response handler and return the created Entities - const entities = this._handleUpdate(response); - return data.length === 1 ? entities[0] : entities; -} - */ \ No newline at end of file +Object.defineProperty(Canvas, 'layers', {get: function() { + return theLayers + }})