Update worldEdit.js
This commit is contained in:
parent
c4b8037cdc
commit
de04bc4d91
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
// WorldEdit.js (compiled)
|
// WorldEdit.js (compiled)
|
||||||
// Version: 1.0.1
|
// Version: 1.1.0
|
||||||
// Constants
|
// Constants
|
||||||
const w_accentColor = "#7cff62";
|
const w_accentColor = "#7cff62";
|
||||||
const w_style = {
|
const w_style = {
|
||||||
|
|
@ -15,7 +15,7 @@ const w_style = {
|
||||||
let worldEditElements = {};
|
let worldEditElements = {};
|
||||||
let pastePreviewCanvas;
|
let pastePreviewCanvas;
|
||||||
let w_state = {
|
let w_state = {
|
||||||
firstSelectionPos: {x: 0, y: 0},
|
firstSelectionPos: { x: 0, y: 0 },
|
||||||
selection: null,
|
selection: null,
|
||||||
clipboard: null,
|
clipboard: null,
|
||||||
prevNonWorldEditElement: "unknown"
|
prevNonWorldEditElement: "unknown"
|
||||||
|
|
@ -29,7 +29,6 @@ dependOn("betterSettings.js", () => {
|
||||||
w_settingsTab.registerSettings("Selection", w_deselectOnResetSetting);
|
w_settingsTab.registerSettings("Selection", w_deselectOnResetSetting);
|
||||||
settingsManager.registerTab(w_settingsTab);
|
settingsManager.registerTab(w_settingsTab);
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
class Rect {
|
class Rect {
|
||||||
constructor(x, y, w, h) {
|
constructor(x, y, w, h) {
|
||||||
|
|
@ -38,60 +37,55 @@ class Rect {
|
||||||
this.w = w;
|
this.w = w;
|
||||||
this.h = h;
|
this.h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCorners(start, end) {
|
static fromCorners(start, end) {
|
||||||
return new Rect(start.x, start.y, end.x - start.x, end.y - start.y);
|
return new Rect(start.x, start.y, end.x - start.x, end.y - start.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromCornersXYXY(x, y, x2, y2) {
|
static fromCornersXYXY(x, y, x2, y2) {
|
||||||
return new Rect(x, y, x2 - x, y2 - y);
|
return new Rect(x, y, x2 - x, y2 - y);
|
||||||
}
|
}
|
||||||
|
static fromGrid(grid, origin = { x: 0, y: 0 }) {
|
||||||
static fromGrid(grid, origin = {x: 0, y: 0}) {
|
|
||||||
return new Rect(origin.x, origin.y, grid[0].length, grid.length);
|
return new Rect(origin.x, origin.y, grid[0].length, grid.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
get area() {
|
get area() {
|
||||||
return this.w * this.h;
|
return this.w * this.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
get x2() {
|
get x2() {
|
||||||
return this.x + this.w;
|
return this.x + this.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
get y2() {
|
get y2() {
|
||||||
return this.y + this.h;
|
return this.y + this.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
set x2(val) {
|
set x2(val) {
|
||||||
this.w = val - this.x;
|
this.w = val - this.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
set y2(val) {
|
set y2(val) {
|
||||||
this.h = val - this.y;
|
this.h = val - this.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy() {
|
copy() {
|
||||||
return new Rect(this.x, this.y, this.w, this.h);
|
return new Rect(this.x, this.y, this.w, this.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
normalized() {
|
normalized() {
|
||||||
return Rect.fromCornersXYXY(Math.min(this.x, this.x2), Math.min(this.y, this.y2), Math.max(this.x, this.x2), Math.max(this.y, this.y2));
|
return Rect.fromCornersXYXY(Math.min(this.x, this.x2), Math.min(this.y, this.y2), Math.max(this.x, this.x2), Math.max(this.y, this.y2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
function isPointInWorld(point) {
|
function isPointInWorld(point) {
|
||||||
return point.x >= 0 && point.x <= width && point.y >= 0 && point.y <= height;
|
return point.x >= 0 && point.x <= width && point.y >= 0 && point.y <= height;
|
||||||
}
|
}
|
||||||
|
|
||||||
function limitPointToWorld(point) {
|
function limitPointToWorld(point) {
|
||||||
return {
|
return {
|
||||||
x: Math.max(0, Math.min(point.x, width)),
|
x: Math.max(0, Math.min(point.x, width)),
|
||||||
y: Math.max(0, Math.min(point.y, height))
|
y: Math.max(0, Math.min(point.y, height))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function mousePosToWorldPos(pos) {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
let x = pos.x - rect.left;
|
||||||
|
let y = pos.y - rect.top;
|
||||||
|
x = Math.floor((x / canvas.clientWidth) * (width + 1));
|
||||||
|
y = Math.floor((y / canvas.clientHeight) * (height + 1));
|
||||||
|
return { x: x, y: y };
|
||||||
|
}
|
||||||
function updatePastePreviewCanvas() {
|
function updatePastePreviewCanvas() {
|
||||||
const clipboard = w_state.clipboard;
|
const clipboard = w_state.clipboard;
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
|
|
@ -111,12 +105,13 @@ function updatePastePreviewCanvas() {
|
||||||
}
|
}
|
||||||
pastePreviewCtx.putImageData(imageData, 0, 0);
|
pastePreviewCtx.putImageData(imageData, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSelection(ctx) {
|
function renderSelection(ctx) {
|
||||||
const selection = w_state.selection;
|
const selection = w_state.selection;
|
||||||
if (!selection)
|
if (!selection)
|
||||||
return;
|
return;
|
||||||
const isSelecting = (mouseIsDown && mouseType === "left" && currentElement === "w_select");
|
const isSelecting = (mouseIsDown &&
|
||||||
|
(mouseType !== "middle" && mouseType !== "right") &&
|
||||||
|
currentElement === "w_select");
|
||||||
ctx.globalAlpha = 1.0;
|
ctx.globalAlpha = 1.0;
|
||||||
// Fill
|
// Fill
|
||||||
if (!isSelecting) {
|
if (!isSelecting) {
|
||||||
|
|
@ -132,7 +127,6 @@ function renderSelection(ctx) {
|
||||||
ctx.strokeRect(selection.x * pixelSize, selection.y * pixelSize, selection.w * pixelSize, selection.h * pixelSize);
|
ctx.strokeRect(selection.x * pixelSize, selection.y * pixelSize, selection.w * pixelSize, selection.h * pixelSize);
|
||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPastePreview(ctx) {
|
function renderPastePreview(ctx) {
|
||||||
if (currentElement !== 'w_paste')
|
if (currentElement !== 'w_paste')
|
||||||
return;
|
return;
|
||||||
|
|
@ -140,6 +134,7 @@ function renderPastePreview(ctx) {
|
||||||
if (!clipboard)
|
if (!clipboard)
|
||||||
return;
|
return;
|
||||||
const clipboardRect = Rect.fromGrid(clipboard, mousePos);
|
const clipboardRect = Rect.fromGrid(clipboard, mousePos);
|
||||||
|
ctx.globalAlpha = 1.0;
|
||||||
// Fill
|
// Fill
|
||||||
ctx.fillStyle = w_style.pasteFill;
|
ctx.fillStyle = w_style.pasteFill;
|
||||||
ctx.fillRect(clipboardRect.x * pixelSize, clipboardRect.y * pixelSize, clipboardRect.w * pixelSize, clipboardRect.h * pixelSize);
|
ctx.fillRect(clipboardRect.x * pixelSize, clipboardRect.y * pixelSize, clipboardRect.w * pixelSize, clipboardRect.h * pixelSize);
|
||||||
|
|
@ -150,7 +145,6 @@ function renderPastePreview(ctx) {
|
||||||
if (pastePreviewCanvas)
|
if (pastePreviewCanvas)
|
||||||
ctx.drawImage(pastePreviewCanvas, mousePos.x * pixelSize, mousePos.y * pixelSize, clipboardRect.w * pixelSize, clipboardRect.h * pixelSize);
|
ctx.drawImage(pastePreviewCanvas, mousePos.x * pixelSize, mousePos.y * pixelSize, clipboardRect.w * pixelSize, clipboardRect.h * pixelSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWorldEditKeybinds() {
|
function addWorldEditKeybinds() {
|
||||||
keybinds.w = () => {
|
keybinds.w = () => {
|
||||||
selectCategory("worldEdit");
|
selectCategory("worldEdit");
|
||||||
|
|
@ -178,8 +172,10 @@ function addWorldEditKeybinds() {
|
||||||
keybinds.Delete = () => {
|
keybinds.Delete = () => {
|
||||||
elements.w_delete.rawOnSelect();
|
elements.w_delete.rawOnSelect();
|
||||||
};
|
};
|
||||||
|
keybinds.g = () => {
|
||||||
|
elements.w_fill.rawOnSelect();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function modifySelectElement() {
|
function modifySelectElement() {
|
||||||
const originalSelectElement = selectElement;
|
const originalSelectElement = selectElement;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
@ -190,7 +186,6 @@ function modifySelectElement() {
|
||||||
originalSelectElement(element);
|
originalSelectElement(element);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addWorldEditElements(elementsToAdd) {
|
function addWorldEditElements(elementsToAdd) {
|
||||||
for (const elementName in elementsToAdd) {
|
for (const elementName in elementsToAdd) {
|
||||||
const element = elementsToAdd[elementName];
|
const element = elementsToAdd[elementName];
|
||||||
|
|
@ -211,22 +206,6 @@ function addWorldEditElements(elementsToAdd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelection() {
|
|
||||||
if (!mouseIsDown)
|
|
||||||
return;
|
|
||||||
if (showingMenu)
|
|
||||||
return;
|
|
||||||
if (mouseType !== "left")
|
|
||||||
return;
|
|
||||||
if (currentElement !== "w_select")
|
|
||||||
return;
|
|
||||||
const rect = Rect.fromCorners(w_state.firstSelectionPos, limitPointToWorld(mousePos)).normalized();
|
|
||||||
rect.x2 += 1;
|
|
||||||
rect.y2 += 1;
|
|
||||||
w_state.selection = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elements
|
// Elements
|
||||||
worldEditElements.w_deselect = {
|
worldEditElements.w_deselect = {
|
||||||
onSelect: function () {
|
onSelect: function () {
|
||||||
|
|
@ -242,14 +221,30 @@ worldEditElements.w_select_all = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
worldEditElements.w_select = {
|
worldEditElements.w_select = {
|
||||||
onMouseDown: function () {
|
onPointerDown: function (e) {
|
||||||
|
const pos = mousePosToWorldPos({ x: e.clientX, y: e.clientY });
|
||||||
if (showingMenu)
|
if (showingMenu)
|
||||||
return;
|
return;
|
||||||
if (!isPointInWorld(mousePos))
|
if (!isPointInWorld(pos))
|
||||||
return;
|
return;
|
||||||
if (mouseType !== "left")
|
if (mouseType === "middle" || mouseType === "right")
|
||||||
return;
|
return;
|
||||||
w_state.firstSelectionPos = mousePos;
|
w_state.firstSelectionPos = pos;
|
||||||
|
},
|
||||||
|
onPointerMove: function (e) {
|
||||||
|
const pos = mousePosToWorldPos({ x: e.clientX, y: e.clientY });
|
||||||
|
if (!mouseIsDown)
|
||||||
|
return;
|
||||||
|
if (showingMenu)
|
||||||
|
return;
|
||||||
|
if (mouseType === "middle" || mouseType === "right")
|
||||||
|
return;
|
||||||
|
if (currentElement !== "w_select")
|
||||||
|
return;
|
||||||
|
const rect = Rect.fromCorners(w_state.firstSelectionPos, limitPointToWorld(pos)).normalized();
|
||||||
|
rect.x2 += 1;
|
||||||
|
rect.y2 += 1;
|
||||||
|
w_state.selection = rect;
|
||||||
},
|
},
|
||||||
shouldStaySelected: true
|
shouldStaySelected: true
|
||||||
};
|
};
|
||||||
|
|
@ -275,12 +270,12 @@ worldEditElements.w_copy = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
worldEditElements.w_paste = {
|
worldEditElements.w_paste = {
|
||||||
onMouseDown: function () {
|
onPointerDown: function () {
|
||||||
if (showingMenu)
|
if (showingMenu)
|
||||||
return;
|
return;
|
||||||
if (!isPointInWorld(mousePos))
|
if (!isPointInWorld(mousePos))
|
||||||
return;
|
return;
|
||||||
if (mouseType !== "left")
|
if (mouseType === "middle" || mouseType === "right")
|
||||||
return;
|
return;
|
||||||
const clipboard = w_state.clipboard;
|
const clipboard = w_state.clipboard;
|
||||||
if (!clipboard) {
|
if (!clipboard) {
|
||||||
|
|
@ -292,7 +287,7 @@ worldEditElements.w_paste = {
|
||||||
for (let y = 0; y < clipboard.length; y++) {
|
for (let y = 0; y < clipboard.length; y++) {
|
||||||
for (let x = 0; x < clipboard[0].length; x++) {
|
for (let x = 0; x < clipboard[0].length; x++) {
|
||||||
const clipboardPixel = clipboard[y][x];
|
const clipboardPixel = clipboard[y][x];
|
||||||
const dest = {x: pasteOrigin.x + x, y: pasteOrigin.y + y};
|
const dest = { x: pasteOrigin.x + x, y: pasteOrigin.y + y };
|
||||||
if (!isPointInWorld(dest))
|
if (!isPointInWorld(dest))
|
||||||
continue; // Skip if out of bounds
|
continue; // Skip if out of bounds
|
||||||
if (pixelMap[dest.x][dest.y])
|
if (pixelMap[dest.x][dest.y])
|
||||||
|
|
@ -361,6 +356,31 @@ worldEditElements.w_delete = {
|
||||||
logMessage(`Deleted ${selection.w}x${selection.h}=${selection.area} pixel area.`);
|
logMessage(`Deleted ${selection.w}x${selection.h}=${selection.area} pixel area.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
worldEditElements.w_fill = {
|
||||||
|
onSelect: function () {
|
||||||
|
const selection = w_state.selection;
|
||||||
|
const fillElement = w_state.prevNonWorldEditElement;
|
||||||
|
if (!selection) {
|
||||||
|
logMessage("Error: Nothing is selected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Fill area
|
||||||
|
for (let y = selection.y; y < selection.y2; y++) {
|
||||||
|
for (let x = selection.x; x < selection.x2; x++) {
|
||||||
|
const placed = currentPixels.push(new Pixel(x, y, fillElement));
|
||||||
|
if (!placed)
|
||||||
|
return;
|
||||||
|
if (currentPixels.length > maxPixelCount || !fillElement) {
|
||||||
|
currentPixels[currentPixels.length - 1].del = true;
|
||||||
|
}
|
||||||
|
else if (elements[fillElement] && elements[fillElement].onPlace !== undefined) {
|
||||||
|
elements[fillElement].onPlace(currentPixels[currentPixels.length - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logMessage(`Filled in ${selection.w}x${selection.h}=${selection.area} pixel area.`);
|
||||||
|
}
|
||||||
|
};
|
||||||
// Setup and hooks
|
// Setup and hooks
|
||||||
modifySelectElement();
|
modifySelectElement();
|
||||||
addWorldEditElements(worldEditElements);
|
addWorldEditElements(worldEditElements);
|
||||||
|
|
@ -370,6 +390,20 @@ runAfterReset(() => {
|
||||||
w_state.selection = null;
|
w_state.selection = null;
|
||||||
});
|
});
|
||||||
runAfterReset(updatePastePreviewCanvas);
|
runAfterReset(updatePastePreviewCanvas);
|
||||||
renderPrePixel(updateSelection);
|
|
||||||
renderPostPixel(renderSelection);
|
renderPostPixel(renderSelection);
|
||||||
renderPostPixel(renderPastePreview);
|
renderPostPixel(renderPastePreview);
|
||||||
|
// Mobile support
|
||||||
|
let addedCustomEventListeners = false;
|
||||||
|
runAfterReset(() => {
|
||||||
|
if (addedCustomEventListeners)
|
||||||
|
return;
|
||||||
|
gameCanvas.addEventListener("pointerdown", (e) => {
|
||||||
|
if (elements[currentElement] && elements[currentElement].onPointerDown)
|
||||||
|
elements[currentElement].onPointerDown(e);
|
||||||
|
}, { passive: false });
|
||||||
|
gameCanvas.addEventListener("pointermove", (e) => {
|
||||||
|
if (elements[currentElement] && elements[currentElement].onPointerMove)
|
||||||
|
elements[currentElement].onPointerMove(e);
|
||||||
|
}, { passive: false });
|
||||||
|
addedCustomEventListeners = true;
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue