diff --git a/CHANGELOG.md b/CHANGELOG.md index cdca800de..7f24841e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,28 @@ All notable changes to this project will be documented in this file. ## Unreleased +## [0.22.3] - 2020-08-30 + +### Added + +- `rescale(factor)` webconsole function as a convenience method for DMs to rescale all their shapes + - a refresh of the page is most likely necessary for all normal functionality to update + - e.g. if you used to have a DM grid size setting that was 70px and want to retrofit your maps to the new baseline of 50, you can use `rescale(50/70);` + +### Changed + +- Changed floor keybindings to use alt instead of ctrl, due to chrome and firefox not allowing these keybindings to be overriden + - As a reminder (similar for Page Down): + - Page Up - Move floor up + - Alt + Page Up - Move selected shapes floor up + - Alt + Shift + Page Up - Move selected shapes floor up AND move floor up + +### Fixed + +- moving shapes to front/back not syncing on the server + - sadly I messed something up so you may have to fix the order of some shapes on some maps +- When adding trackers or auras, duplicate entries could appear clientside until a refresh + # [0.22.2] - 2020-08-28 ### Fixed diff --git a/client/package-lock.json b/client/package-lock.json index dd4e227b4..d8627c923 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,6 +1,6 @@ { "name": "planarally-client", - "version": "0.22.2", + "version": "0.22.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/client/package.json b/client/package.json index 7bf92bc9c..a2361ecf1 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "planarally-client", - "version": "0.22.2", + "version": "0.22.3", "description": "A companion tool for when you travel into the planes.", "scripts": { "serve": "vue-cli-service serve", diff --git a/client/src/game/api/emits/shape/core.ts b/client/src/game/api/emits/shape/core.ts index 28409b210..05f03aa0d 100644 --- a/client/src/game/api/emits/shape/core.ts +++ b/client/src/game/api/emits/shape/core.ts @@ -25,10 +25,10 @@ export const sendTrackerUpdate = wrapSocket<{ export const sendTextUpdate = wrapSocket<{ uuid: string; text: string; temporary: boolean }>("Shape.Text.Value.Set"); export function sendShapePositionUpdate(shapes: readonly Shape[], temporary: boolean): void { - _sendShapePositionUpdate( - shapes.filter(s => !s.preventSync).map(s => ({ uuid: s.uuid, position: s.getPositionRepresentation() })), - temporary, - ); + const positions = shapes + .filter(s => !s.preventSync) + .map(s => ({ uuid: s.uuid, position: s.getPositionRepresentation() })); + if (positions.length > 0) _sendShapePositionUpdate(positions, temporary); } export function sendShapeSizeUpdate(data: { shape: Shape; temporary: boolean }): void { diff --git a/client/src/game/input/keyboard.ts b/client/src/game/input/keyboard.ts index 064e1c995..0602df949 100644 --- a/client/src/game/input/keyboard.ts +++ b/client/src/game/input/keyboard.ts @@ -123,9 +123,10 @@ export function onKeyDown(event: KeyboardEvent): void { pasteShapes(); } else if (event.key === "PageUp" && floorStore.currentFloorindex < floorStore.floors.length - 1) { // Page Up - Move floor up - // Ctrl + Page Up - Move selected shapes floor up - // Ctrl + Shift + Page Up - Move selected shapes floor up AND move floor up + // Alt + Page Up - Move selected shapes floor up + // Alt + Shift + Page Up - Move selected shapes floor up AND move floor up event.preventDefault(); + event.stopPropagation(); const targetFloor = floorStore.floors.findIndex( (f, i) => i > floorStore.currentFloorindex && (gameStore.IS_DM || f.playerVisible), ); @@ -134,9 +135,10 @@ export function onKeyDown(event: KeyboardEvent): void { changeFloor(event, targetFloor); } else if (event.key === "PageDown" && floorStore.currentFloorindex > 0) { // Page Down - Move floor down - // Ctrl + Page Down - Move selected shape floor down - // Ctrl + Shift + Page Down - Move selected shapes floor down AND move floor down + // Alt + Page Down - Move selected shape floor down + // Alt + Shift + Page Down - Move selected shapes floor down AND move floor down event.preventDefault(); + event.stopPropagation(); const maxLength = floorStore.floors.length - 1; let targetFloor = [...floorStore.floors] .reverse() @@ -159,11 +161,11 @@ function changeFloor(event: KeyboardEvent, targetFloor: number): void { const newFloor = floorStore.floors[targetFloor]; const newLayer = layerManager.getLayer(newFloor)!; - if (event.ctrlKey) { + if (event.altKey) { moveFloor([...selection], newFloor, true); } layerManager.clearSelection(); - if (!event.ctrlKey || event.shiftKey) { + if (!event.altKey || event.shiftKey) { floorStore.selectFloor({ targetFloor, sync: true }); } if (event.shiftKey) for (const shape of selection) newLayer.pushSelection(shape); diff --git a/client/src/main.ts b/client/src/main.ts index d99366172..d62da7c10 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -1,4 +1,5 @@ import App from "@/App.vue"; +import { registerScripts } from "./scripts"; import { router } from "@/router"; import { rootStore } from "@/store"; import { library } from "@fortawesome/fontawesome-svg-core"; @@ -87,6 +88,8 @@ Vue.config.productionTip = false; Vue.config.devtools = true; Vue.config.performance = true; +registerScripts(); + export const app = new Vue({ router, store: rootStore, diff --git a/client/src/scripts.ts b/client/src/scripts.ts new file mode 100644 index 000000000..72706e172 --- /dev/null +++ b/client/src/scripts.ts @@ -0,0 +1,70 @@ +/** + * This file is destined for utility functions / scripts that can be ran manually in the webconsole by for example the DM. + */ + +import { layerManager } from "./game/layers/manager"; +import { GlobalPoint } from "./game/geom"; +import { BaseRect } from "./game/shapes/baserect"; +import { Circle } from "./game/shapes/circle"; +import { Line } from "./game/shapes/line"; +import { Polygon } from "./game/shapes/polygon"; +import { sendShapeSizeUpdate, sendShapePositionUpdate } from "./game/api/emits/shape/core"; +import { gameStore } from "./game/store"; +import { visibilityStore } from "./game/visibility/store"; +import { floorStore } from "./game/layers/store"; + +/** + * This function rescales all objects on the map + * + * @param factor the ratio used to rescale shape axis by + */ +function rescale(factor: number, sync: boolean): void { + if (!Number.isFinite(factor)) { + console.error("Provided factor is not a valid number."); + return; + } + if (sync === undefined) sync = false; + if (!gameStore.IS_DM) { + console.warn("You must be a DM to perform this operation."); + return; + } + const shapes = [...layerManager.UUIDMap.values()]; + for (const shape of shapes) { + if (shape.preventSync) continue; + (shape)._refPoint = new GlobalPoint(shape.refPoint.x * factor, shape.refPoint.y * factor); + + if (shape.type === "rect" || shape.type === "assetrect") { + (shape).w *= factor; + (shape).h *= factor; + } else if (shape.type === "circle" || shape.type === "circulartoken") { + (shape).r *= factor; + } else if (shape.type === "line") { + (shape).endPoint = new GlobalPoint( + (shape).endPoint.x * factor, + (shape).endPoint.y * factor, + ); + } else if (shape.type === "polygon") { + (shape)._vertices = (shape)._vertices.map( + v => new GlobalPoint(v.x * factor, v.y * factor), + ); + } + if (sync && shape.type !== "polygon") sendShapeSizeUpdate({ shape, temporary: false }); + } + for (const floor of floorStore.floors) { + visibilityStore.recalculateVision(floor.id); + visibilityStore.recalculateMovement(floor.id); + } + layerManager.invalidateAllFloors(); + if (sync) { + sendShapePositionUpdate(shapes, false); + console.log("Changes should be synced now. Refresh your page to make sure everything works accordingly."); + } else { + console.log( + "If everything looks ok and you want to sync these changes to the server, hard refresh your page and rerun the script with the sync parameter set to true. e.g. rescale(5/7, true)", + ); + } +} + +export function registerScripts(): void { + (window).rescale = rescale; +} diff --git a/server/VERSION b/server/VERSION index cc56bb094..c0acb8ed0 100644 --- a/server/VERSION +++ b/server/VERSION @@ -1,4 +1,4 @@ -0.22.2 +0.22.3 ### Added @@ -28,6 +28,9 @@ - Shape movement now sends less data to server - Pan now only updates the visible floors on move and full recalculate on release - Grid pixel size is now a client setting instead of a DM setting + - [0.22.3] `rescale(factor)` webconsole function has been added as a convenience method for DMs to rescale all their shapes on maps that might now be wrongly sized. + - a refresh of the page is most likely necessary for all normal functionality to update + - e.g. if you used to have a DM grid size setting that was 70px and want to retrofit your maps to the new baseline of 50, you can use `rescale(50/70);` - Show floor selector in the more logical order from upper to lower floors - Improve ruler distance text readability - [0.22.1] Spawn locations are no longer magically created @@ -59,4 +62,6 @@ - [0.22.2] Drawing on FOW layer blocking UI - [0.22.2] Badge toggle not working properly - [0.22.2] Group leader not properly set serverside on paste -- [0.22.2] Server error on shape paste due to aura type change \ No newline at end of file +- [0.22.2] Server error on shape paste due to aura type change +- [0.22.3] moving shapes to front/back not syncing on the server + - sadly I messed something up so you may have to fix the order of some shapes on some maps diff --git a/server/api/socket/shape/options.py b/server/api/socket/shape/options.py index ef8b3daea..52763068a 100644 --- a/server/api/socket/shape/options.py +++ b/server/api/socket/shape/options.py @@ -365,12 +365,15 @@ async def create_tracker(sid: str, data: TrackerDelta): await sio.emit( "Shape.Options.Tracker.Create", data, room=psid, namespace=GAME_NS, ) - for psid in game_state.get_sids(active_location=pr.active_location, skip_sid=sid): - if psid in owners: - continue - await sio.emit( - "Shape.Options.Tracker.Create", data, room=sid, namespace=GAME_NS, - ) + if tracker.visible: + for psid in game_state.get_sids( + active_location=pr.active_location, skip_sid=sid + ): + if psid in owners: + continue + await sio.emit( + "Shape.Options.Tracker.Create", data, room=psid, namespace=GAME_NS, + ) @sio.on("Shape.Options.Tracker.Update", namespace=GAME_NS) @@ -434,12 +437,15 @@ async def create_aura(sid: str, data: AuraDelta): await sio.emit( "Shape.Options.Aura.Create", data, room=psid, namespace=GAME_NS, ) - for psid in game_state.get_sids(active_location=pr.active_location, skip_sid=sid): - if psid in owners: - continue - await sio.emit( - "Shape.Options.Aura.Create", data, room=sid, namespace=GAME_NS, - ) + if aura.visible: + for psid in game_state.get_sids( + active_location=pr.active_location, skip_sid=sid + ): + if psid in owners: + continue + await sio.emit( + "Shape.Options.Aura.Create", data, room=psid, namespace=GAME_NS, + ) @sio.on("Shape.Options.Aura.Update", namespace=GAME_NS) diff --git a/server/save.py b/server/save.py index a4fdc54fb..50690f592 100644 --- a/server/save.py +++ b/server/save.py @@ -20,7 +20,7 @@ from models.db import db from utils import OldVersionException, UnknownVersionException -SAVE_VERSION = 39 +SAVE_VERSION = 40 logger: logging.Logger = logging.getLogger("PlanarAllyServer") logger.setLevel(logging.INFO) @@ -642,6 +642,21 @@ def upgrade(version): except json.decoder.JSONDecodeError: print(f"Failed to update polygon vertices! {row}") + db.foreign_keys = True + Constants.get().update(save_version=Constants.save_version + 1).execute() + elif version == 39: + # Fix Shape.index being set to 'index' + from models import Layer + + db.foreign_keys = False + with db.atomic(): + with db.atomic(): + for layer in Layer.select(): + shapes = layer.shapes.select() + for i, shape in enumerate(shapes): + shape.index = i + shape.save() + db.foreign_keys = True Constants.get().update(save_version=Constants.save_version + 1).execute() else: