mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 00:35:08 +02:00
Add a Warning when there are Zone not found and fix the Undo if the entity list selection has changed, then reset the undo stack cause it won't be applicable on the selection anymore.
453 lines
20 KiB
JavaScript
453 lines
20 KiB
JavaScript
//
|
|
// renderWithZonesManager.js
|
|
//
|
|
// Created by Alezia Kurdis on January 28th, 2024.
|
|
// Copyright 2024 Overte e.V.
|
|
//
|
|
// This script is to manage the zone in the property renderWithZones more efficiently in the Create Application.
|
|
// It allows a global view over a specific selection with possibility to
|
|
// REPLACE, REMOVE or ADD zones on those properties more efficiently.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
let rwzmSelectedId = [];
|
|
let rwzmAllZonesList = [];
|
|
let rwzmUsedZonesList = [];
|
|
let rwzmSelectedEntitiesData = [];
|
|
let rwzmUndo = [];
|
|
|
|
let enforceLocked = false;
|
|
|
|
const RWZ_ZONE_SCAN_RADIUS = 27713; //maximal radius to cover the entire domain.
|
|
|
|
let rwzmOverlayWebWindow = null;
|
|
|
|
function renderWithZonesManager(entityIDs, highlightedID = "") {
|
|
if (rwzmGetCheckSum(entityIDs) !== rwzmGetCheckSum(rwzmSelectedId)) {
|
|
rwzmUndo = [];
|
|
}
|
|
rwzmSelectedId = entityIDs;
|
|
if (entityIDs.length === 0) {
|
|
audioFeedback.rejection();
|
|
Window.alert("You have nothing selected.");
|
|
return;
|
|
} else {
|
|
rwzmAllZonesList = [];
|
|
rwzmUsedZonesList = [];
|
|
rwzmSelectedEntitiesData = [];
|
|
rwzmAllZonesList = rwzmGetExistingZoneList();
|
|
|
|
let properties;
|
|
let i = 0;
|
|
let j = 0;
|
|
let rwzmData = {};
|
|
for (i = 0; i < entityIDs.length; i++ ){
|
|
properties = Entities.getEntityProperties(entityIDs[i], ["renderWithZones", "locked", "name", "type"]);
|
|
//Identify the unique zone used in renderWithZones properties of the entities and make the list of this in rwzmUsedZonesList
|
|
if (properties.renderWithZones.length > 0) {
|
|
for (j = 0; j < properties.renderWithZones.length; j++ ){
|
|
if (rwzmUsedZonesList.indexOf(properties.renderWithZones[j]) === -1) {
|
|
rwzmUsedZonesList.push(properties.renderWithZones[j]);
|
|
}
|
|
}
|
|
}
|
|
//Make the list of entities, with their id, renderWithZones, locked, in rwzmSelectedEntitiesData
|
|
rwzmData = {
|
|
"id": entityIDs[i],
|
|
"name": properties.name,
|
|
"type": properties.type,
|
|
"renderWithZones": properties.renderWithZones,
|
|
"locked": properties.locked
|
|
};
|
|
rwzmSelectedEntitiesData.push(rwzmData);
|
|
}
|
|
}
|
|
|
|
if (rwzmOverlayWebWindow === null) {
|
|
rwzmOverlayWebWindow = new OverlayWebWindow({
|
|
title: "RenderWithZones Manager",
|
|
source: Script.resolvePath("renderWithZonesManager.html"),
|
|
width: 1100,
|
|
height: 600
|
|
});
|
|
|
|
rwzmOverlayWebWindow.closed.connect(uiHasClosed);
|
|
rwzmOverlayWebWindow.webEventReceived.connect(webEventReceiver);
|
|
}
|
|
|
|
rwzmGenerateUI(highlightedID);
|
|
}
|
|
|
|
function rwzmGetCheckSum(array) {
|
|
let i = 0;
|
|
let sum = 0;
|
|
let strForm = JSON.stringify(array);
|
|
for (i = 0; i < strForm.length; i++) {
|
|
sum = sum + strForm.charCodeAt(i);
|
|
}
|
|
return sum;
|
|
}
|
|
function uiHasClosed() {
|
|
rwzmOverlayWebWindow.closed.disconnect(uiHasClosed);
|
|
rwzmOverlayWebWindow.webEventReceived.disconnect(webEventReceiver);
|
|
rwzmOverlayWebWindow = null;
|
|
}
|
|
|
|
function rwzmGenerateUI(highlightedID) {
|
|
let canUnlock = Entities.canAdjustLocks();
|
|
let uiContent = "";
|
|
let i = 0;
|
|
let k = 0;
|
|
let zones = "";
|
|
let name = "";
|
|
let elementClass = "";
|
|
let firstClass = "";
|
|
let isLocked = "";
|
|
let selectionBox = "";
|
|
let setCheck = "";
|
|
let addAction = "";
|
|
let toHighlight = "";
|
|
let viewBtnCaption = "";
|
|
let warning = false;
|
|
uiContent = uiContent + ' <h1>RenderWithZones Manager</h1><hr>\n';
|
|
if (canUnlock) {
|
|
if (enforceLocked) {
|
|
setCheck = " checked";
|
|
} else {
|
|
setCheck = "";
|
|
}
|
|
}
|
|
uiContent = uiContent + ' <table>\n';
|
|
uiContent = uiContent + ' <tr valign = "top">\n';
|
|
uiContent = uiContent + ' <td style="width: 40%">\n';
|
|
if (rwzmUndo.length === 0) {
|
|
undoBtnCode = "";
|
|
} else {
|
|
undoBtnCode = '<button class="greyBtn small" onClick="undo();">Undo</button>';
|
|
}
|
|
uiContent = uiContent + ' <table><tr><td style="width: 40%;"><h2>Visibility Zones:</h2></td><td style="width: 60%; text-align: right;">' + undoBtnCode + '</td></tr></table>\n';
|
|
uiContent = uiContent + ' <div class="listContainer"><table>\n';
|
|
uiContent = uiContent + ' <tr style="width: 100%"><td class="cells header" style="width: 60%;">';
|
|
uiContent = uiContent + '<b>ZONES</b></td><td class="cells header" style="width: 40%;"><b>ACTIONS (On listed entities)</b></td></tr>\n';
|
|
for (i = 0; i < rwzmUsedZonesList.length; i++ ) {
|
|
name = rwzmGetZoneName(rwzmUsedZonesList[i]);
|
|
elementClass = "line";
|
|
firstClass = "cells";
|
|
if (name === "") {
|
|
name = rwzmGenerateUnidentifiedZoneName(rwzmUsedZonesList[i]);
|
|
elementClass = "errorline";
|
|
warning = true;
|
|
}
|
|
toHighlight = rwzmUsedZonesList[i];
|
|
viewBtnCaption = "View";
|
|
if ( rwzmUsedZonesList[i] === highlightedID) {
|
|
toHighlight = "";
|
|
viewBtnCaption = "Hide";
|
|
firstClass = "highlightedCells";
|
|
if (elementClass === "line") {
|
|
elementClass = "lineInverted";
|
|
}
|
|
}
|
|
uiContent = uiContent + ' <tr style="width: 100%"><td class="' + firstClass + ' ' + elementClass;
|
|
uiContent = uiContent + '"><div style = "width:100%; height:100%; padding: 3px;" onClick = "highlight(' + "'";
|
|
uiContent = uiContent + toHighlight + "'" +');">' + rwzmGetTruncatedString(name, 30) + '</div></td><td class="' + firstClass + ' ' + elementClass + '">';
|
|
uiContent = uiContent + '<button class="greyBtn small" onclick="highlight(' + "'" + toHighlight + "'" +');">' + viewBtnCaption + '</button>';
|
|
uiContent = uiContent + '<button class="redBtn" onclick="removeZoneOnAllEntities(' + "'" + rwzmUsedZonesList[i] + "'" +');">Remove</button>';
|
|
uiContent = uiContent + '<button class="blueBtn" onclick="replaceZoneOnAllEntities(' + "'" + rwzmUsedZonesList[i] + "'" +');">Replace</button></td></tr>\n';
|
|
}
|
|
uiContent = uiContent + ' </table></div>\n';
|
|
uiContent = uiContent + ' </td>\n';
|
|
uiContent = uiContent + ' <td style="width: 3%"> </td>\n';
|
|
uiContent = uiContent + ' <td style="width: 57%">\n';
|
|
uiContent = uiContent + ' <table><tr><td style="width: 15%;"><h2>Entities:</h2></td><td style="width: 30%;"><button class="addbtn" onClick="addZoneToEntity(getIdsFromScope());">Add to Selected</button></td>';
|
|
uiContent = uiContent + '<td style="width: 55%; text-align: right;"><input type="checkbox" id = "enforceLocked"'+ setCheck + ' onClick="refresh()";> <font style="color: #3bc7ff;">Modify locked entities for me.</font></td></tr></table>\n';
|
|
uiContent = uiContent + ' <div class="listContainer"><table>\n';
|
|
uiContent = uiContent + ' <tr style="width: 100%;"><td class="cells header" style="width: 5%;">';
|
|
uiContent = uiContent + '<input type="checkbox" id="fullScope" onClick="selectAllOrNone();"></td><td class="cells header" style="width: 3%;">';
|
|
uiContent = uiContent + '<font class="hifiGlyphs"></font></td><td class="cells header" style = "width: 45%;"><b>ENTITIES</b></td><td class="cells header" style = "width: 40%;">';
|
|
uiContent = uiContent + '<b>RENDER WITH ZONES</b></td><td style = "width: 7%;"class="cells header"> </td></tr>\n';
|
|
for (i = 0; i < rwzmSelectedEntitiesData.length; i++ ) {
|
|
elementClass = "line";
|
|
firstClass = "cells";
|
|
if (rwzmSelectedEntitiesData[i].renderWithZones.indexOf(highlightedID) !== -1) {
|
|
firstClass = "highlightedCells";
|
|
elementClass = "lineInverted";
|
|
}
|
|
zones = " ";
|
|
if (rwzmSelectedEntitiesData[i].renderWithZones.length > 0) {
|
|
for (k = 0; k < rwzmSelectedEntitiesData[i].renderWithZones.length; k++ ) {
|
|
name = rwzmGetTruncatedString(rwzmGetZoneName(rwzmSelectedEntitiesData[i].renderWithZones[k]),30);
|
|
if (name === "") {
|
|
name = rwzmGetTruncatedString(rwzmGenerateUnidentifiedZoneName(rwzmSelectedEntitiesData[i].renderWithZones[k]),30);
|
|
}
|
|
if ((canUnlock && enforceLocked && rwzmSelectedEntitiesData[i].locked) || !rwzmSelectedEntitiesData[i].locked) {
|
|
name = name + " <span class='delBtn' onClick='removeZoneFromRWZ(" + '"' + rwzmSelectedEntitiesData[i].id + '", "' + rwzmSelectedEntitiesData[i].renderWithZones[k] + '"' + ");'>⮾</span>";
|
|
}
|
|
|
|
if (k === 0) {
|
|
zones = zones + name;
|
|
} else {
|
|
zones = zones + "<br>" + name;
|
|
}
|
|
}
|
|
}
|
|
isLocked = " ";
|
|
selectionBox = " ";
|
|
addAction = " ";
|
|
if ((canUnlock && enforceLocked && rwzmSelectedEntitiesData[i].locked) || !rwzmSelectedEntitiesData[i].locked) {
|
|
addAction = "<button class='addbtn' onClick='addZoneToEntity([" + '"' + rwzmSelectedEntitiesData[i].id + '"' + "]);'>Add</button>";
|
|
selectionBox = '<input type="checkbox" name="entitiesScope" value = "' + rwzmSelectedEntitiesData[i].id + '">';
|
|
}
|
|
if (rwzmSelectedEntitiesData[i].locked) {
|
|
if (canUnlock) {
|
|
isLocked = ""; //Locked
|
|
} else {
|
|
isLocked = "🛇"; //Forbidden
|
|
}
|
|
}
|
|
uiContent = uiContent + ' <tr style="width: 100%"><td class="' + firstClass + ' ' + elementClass + '">' + selectionBox;
|
|
uiContent = uiContent + '</td><td class="' + firstClass + ' ' + elementClass + '"><font class="hifiGlyphs">' + isLocked + '</font></td><td class="';
|
|
uiContent = uiContent + firstClass + ' ' + elementClass + '">' + rwzmSelectedEntitiesData[i].type + ' - ' + rwzmGetTruncatedString(rwzmSelectedEntitiesData[i].name, 30) + '</b></td><td class="' + firstClass;
|
|
uiContent = uiContent + ' ' + elementClass + '">' + zones + '</td><td class="' + firstClass + ' ' + elementClass + '">' + addAction + '</td></tr>\n';
|
|
}
|
|
uiContent = uiContent + ' </table>\n';
|
|
uiContent = uiContent + ' </td>\n';
|
|
uiContent = uiContent + ' </tr>\n';
|
|
uiContent = uiContent + ' </table></div>\n';
|
|
uiContent = uiContent + ' <input type = "hidden" id = "highlightedID" value = "' + highlightedID + '">\n';
|
|
if (warning) {
|
|
uiContent = uiContent + ' <div class="warning"><b>WARNING</b>: The "<b>ZONE NOT FOUND</b>" visibility zones might simply not be loaded if too far and small. Please, verify before.</div>\n';
|
|
}
|
|
//Zone selector Add
|
|
uiContent = uiContent + ' <div id="rwzmAddZoneSelector">\n';
|
|
uiContent = uiContent + ' <h2>Select the zone to add:</h2><div class="zoneSelectorContainer">\n';
|
|
for (i = 0; i < rwzmAllZonesList.length; i++ ) {
|
|
uiContent = uiContent + " <button class = 'zoneSelectorButton' onClick='addThisZone(" + '"' + rwzmAllZonesList[i].id + '"' + ");'>" + rwzmAllZonesList[i].name + "</button><br>\n";
|
|
}
|
|
uiContent = uiContent + ' </div><div style="width: 98%; text-align: right;"><button class = "greyBtn" onclick="cancelZoneSelector();">Cancel</button></div>\n';
|
|
uiContent = uiContent + ' </div>\n';
|
|
//Zone selector Replace
|
|
uiContent = uiContent + ' <div id="rwzmReplaceZoneSelector">\n';
|
|
uiContent = uiContent + ' <h2>Select the replacement zone:</h2><div class="zoneSelectorContainer">\n';
|
|
for (i = 0; i < rwzmAllZonesList.length; i++ ) {
|
|
uiContent = uiContent + " <button class = 'zoneSelectorButton' onClick='replaceByThisZone(" + '"' + rwzmAllZonesList[i].id + '"' + ");'>" + rwzmAllZonesList[i].name + "</button><br>\n";
|
|
}
|
|
uiContent = uiContent + ' </div><div style="width: 98%; text-align: right;"><button class = "greyBtn" onclick="cancelZoneSelector();">Cancel</button></div>\n';
|
|
uiContent = uiContent + ' </div>\n';
|
|
|
|
Script.setTimeout(function () {
|
|
rwzmOverlayWebWindow.emitScriptEvent(uiContent);
|
|
}, 300);
|
|
}
|
|
|
|
function rwzmGetZoneName(id) {
|
|
let k = 0;
|
|
let name = "";
|
|
for (k = 0; k < rwzmAllZonesList.length; k++) {
|
|
if (rwzmAllZonesList[k].id === id) {
|
|
name = rwzmAllZonesList[k].name;
|
|
break;
|
|
}
|
|
}
|
|
return name;
|
|
}
|
|
|
|
function rwzmGenerateUnidentifiedZoneName(id) {
|
|
let partialID = id.substr(1,8);
|
|
return "ZONE NOT FOUND (" + partialID +")";
|
|
}
|
|
|
|
function rwzmGetExistingZoneList() {
|
|
var center = { "x": 0, "y": 0, "z": 0 };
|
|
var existingZoneIDs = Entities.findEntitiesByType("Zone", center, RWZ_ZONE_SCAN_RADIUS);
|
|
var listExistingZones = [];
|
|
var thisZone = {};
|
|
var properties;
|
|
for (var k = 0; k < existingZoneIDs.length; k++) {
|
|
properties = Entities.getEntityProperties(existingZoneIDs[k], ["name"]);
|
|
thisZone = {
|
|
"id": existingZoneIDs[k],
|
|
"name": properties.name
|
|
};
|
|
listExistingZones.push(thisZone);
|
|
}
|
|
listExistingZones.sort(rwzmZoneSortOrder);
|
|
return listExistingZones;
|
|
}
|
|
|
|
function rwzmZoneSortOrder(a, b) {
|
|
var nameA = a.name.toUpperCase();
|
|
var nameB = b.name.toUpperCase();
|
|
if (nameA > nameB) {
|
|
return 1;
|
|
} else if (nameA < nameB) {
|
|
return -1;
|
|
}
|
|
if (a.name > b.name) {
|
|
return 1;
|
|
} else if (a.name < b.name) {
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
function rwzmRemoveZoneFromEntity(id, zoneID, forceLocked, highlightedID) {
|
|
rwzmUndo = [];
|
|
let properties = Entities.getEntityProperties(id, ["renderWithZones", "locked"]);
|
|
|
|
let newRenderWithZones = [];
|
|
let i = 0;
|
|
for (i = 0; i < properties.renderWithZones.length; i++) {
|
|
if (properties.renderWithZones[i] !== zoneID) {
|
|
newRenderWithZones.push(properties.renderWithZones[i]);
|
|
}
|
|
}
|
|
|
|
if (forceLocked && properties.locked) {
|
|
Entities.editEntity(id, {"locked": false});
|
|
Entities.editEntity(id, {"renderWithZones": newRenderWithZones, "locked": properties.locked});
|
|
} else {
|
|
Entities.editEntity(id, {"renderWithZones": newRenderWithZones});
|
|
}
|
|
rwzmUndo.push({"id": id, "renderWithZones": properties.renderWithZones});
|
|
renderWithZonesManager(rwzmSelectedId, highlightedID);
|
|
}
|
|
|
|
function rwzmAddZonesToEntities(ids, zoneID, forceLocked, highlightedID) {
|
|
rwzmUndo = [];
|
|
let k = 0;
|
|
let j = 0;
|
|
let properties;
|
|
let newRenderWithZones = [];
|
|
for (k = 0; k < ids.length; k++) {
|
|
properties = Entities.getEntityProperties(ids[k], ["renderWithZones", "locked"]);
|
|
newRenderWithZones = [];
|
|
|
|
for (j = 0; j < properties.renderWithZones.length; j++) {
|
|
if (properties.renderWithZones[j] !== zoneID) {
|
|
newRenderWithZones.push(properties.renderWithZones[j]);
|
|
}
|
|
}
|
|
newRenderWithZones.push(zoneID);
|
|
if (forceLocked && properties.locked) {
|
|
Entities.editEntity(ids[k], {"locked": false});
|
|
Entities.editEntity(ids[k], {"renderWithZones": newRenderWithZones, "locked": properties.locked});
|
|
} else {
|
|
Entities.editEntity(ids[k], {"renderWithZones": newRenderWithZones});
|
|
}
|
|
rwzmUndo.push({"id": ids[k], "renderWithZones": properties.renderWithZones});
|
|
}
|
|
renderWithZonesManager(rwzmSelectedId, highlightedID);
|
|
}
|
|
|
|
function rwzmRemoveZoneFromAllEntities(zoneID, forceLocked, highlightedID) {
|
|
rwzmUndo = [];
|
|
let k = 0;
|
|
let j = 0;
|
|
let properties;
|
|
let newRenderWithZones = [];
|
|
for (k = 0; k < rwzmSelectedId.length; k++) {
|
|
properties = Entities.getEntityProperties(rwzmSelectedId[k], ["renderWithZones", "locked"]);
|
|
newRenderWithZones = [];
|
|
|
|
for (j = 0; j < properties.renderWithZones.length; j++) {
|
|
if (properties.renderWithZones[j] !== zoneID) {
|
|
newRenderWithZones.push(properties.renderWithZones[j]);
|
|
}
|
|
}
|
|
if (forceLocked && properties.locked) {
|
|
Entities.editEntity(rwzmSelectedId[k], {"locked": false});
|
|
Entities.editEntity(rwzmSelectedId[k], {"renderWithZones": newRenderWithZones, "locked": properties.locked});
|
|
} else {
|
|
Entities.editEntity(rwzmSelectedId[k], {"renderWithZones": newRenderWithZones});
|
|
}
|
|
rwzmUndo.push({"id": rwzmSelectedId[k], "renderWithZones": properties.renderWithZones});
|
|
}
|
|
renderWithZonesManager(rwzmSelectedId, highlightedID);
|
|
}
|
|
|
|
function rwzmReplaceZoneOnAllEntities(targetZoneID, replacementZoneID, forceLocked, highlightedID) {
|
|
rwzmUndo = [];
|
|
let k = 0;
|
|
let j = 0;
|
|
let properties;
|
|
let newRenderWithZones = [];
|
|
for (k = 0; k < rwzmSelectedId.length; k++) {
|
|
properties = Entities.getEntityProperties(rwzmSelectedId[k], ["renderWithZones", "locked"]);
|
|
newRenderWithZones = [];
|
|
|
|
for (j = 0; j < properties.renderWithZones.length; j++) {
|
|
if (properties.renderWithZones[j] !== targetZoneID) {
|
|
newRenderWithZones.push(properties.renderWithZones[j]);
|
|
} else {
|
|
newRenderWithZones.push(replacementZoneID);
|
|
}
|
|
}
|
|
if (forceLocked && properties.locked) {
|
|
Entities.editEntity(rwzmSelectedId[k], {"locked": false});
|
|
Entities.editEntity(rwzmSelectedId[k], {"renderWithZones": newRenderWithZones, "locked": properties.locked});
|
|
} else {
|
|
Entities.editEntity(rwzmSelectedId[k], {"renderWithZones": newRenderWithZones});
|
|
}
|
|
rwzmUndo.push({"id": rwzmSelectedId[k], "renderWithZones": properties.renderWithZones});
|
|
}
|
|
renderWithZonesManager(rwzmSelectedId, highlightedID);
|
|
}
|
|
|
|
function rwzmGetTruncatedString(str, max) {
|
|
if (str.length > max) {
|
|
return str.substr(0, max-1) + "…";
|
|
} else {
|
|
return str;
|
|
}
|
|
}
|
|
|
|
function rwzmUndoLastAction(highlightedID) {
|
|
let k = 0;
|
|
let properties;
|
|
let locked;
|
|
for (k = 0; k < rwzmUndo.length; k++) {
|
|
locked = Entities.getEntityProperties(rwzmUndo[k].id, ["locked"]).locked;
|
|
if (locked) {
|
|
Entities.editEntity(rwzmUndo[k].id, {"locked": false});
|
|
Entities.editEntity(rwzmUndo[k].id, {"renderWithZones": rwzmUndo[k].renderWithZones, "locked": locked});
|
|
} else {
|
|
Entities.editEntity(rwzmUndo[k].id, {"renderWithZones": rwzmUndo[k].renderWithZones});
|
|
}
|
|
}
|
|
rwzmUndo = [];
|
|
renderWithZonesManager(rwzmSelectedId, highlightedID);
|
|
}
|
|
|
|
function webEventReceiver (message) {
|
|
try {
|
|
var data = JSON.parse(message);
|
|
} catch(e) {
|
|
print("renderWithZonesManager.js: Error parsing JSON");
|
|
return;
|
|
}
|
|
if (data.action === "highlight") {
|
|
enforceLocked = data.enforceLocked;
|
|
renderWithZonesManager(rwzmSelectedId, data.id);
|
|
} else if (data.action === "removeZoneFromEntity") {
|
|
enforceLocked = data.enforceLocked;
|
|
rwzmRemoveZoneFromEntity(data.id, data.zoneID, data.enforceLocked, data.highlightedID);
|
|
} else if (data.action === "addZoneToEntities") {
|
|
enforceLocked = data.enforceLocked;
|
|
rwzmAddZonesToEntities(data.ids, data.zoneID, data.enforceLocked, data.highlightedID);
|
|
} else if (data.action === "refresh") {
|
|
enforceLocked = data.enforceLocked;
|
|
renderWithZonesManager(rwzmSelectedId, data.highlightedID);
|
|
} else if (data.action === "removeZoneOnAllEntities") {
|
|
enforceLocked = data.enforceLocked;
|
|
rwzmRemoveZoneFromAllEntities(data.zoneID, data.enforceLocked, data.highlightedID);
|
|
} else if (data.action === "replaceZoneOnAllEntities") {
|
|
enforceLocked = data.enforceLocked;
|
|
rwzmReplaceZoneOnAllEntities(data.targetZoneID, data.replacementZoneID, data.enforceLocked, data.highlightedID);
|
|
} else if (data.action === "undo") {
|
|
enforceLocked = data.enforceLocked;
|
|
rwzmUndoLastAction(data.highlightedID);
|
|
}
|
|
}
|
|
|