@underpostnet/cyberia 3.3.73 → 3.3.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +17 -5
- package/.github/workflows/coverall.cyberia.ci.yml +10 -0
- package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
- package/.github/workflows/engine-cyberia.ci.yml +1 -1
- package/.github/workflows/publish.cyberia.ci.yml +44 -0
- package/AGENTS.md +61 -12
- package/CHANGELOG.md +159 -161
- package/CLI-HELP.md +20 -13
- package/Dockerfile +1 -1
- package/Dockerfile.dev +1 -1
- package/Dockerfile.test +2 -2
- package/README.md +28 -28
- package/bin/build.js +96 -21
- package/bin/cyberia.js +1247 -1373
- package/bin/index.js +1247 -1373
- package/compose.env +17 -5
- package/conf.js +7 -4
- package/deploy/cyberia-client/deploy.sh +10 -11
- package/deploy/cyberia-client/package.sh +0 -1
- package/deploy/cyberia-client/state.sh +3 -2
- package/deploy/cyberia-server/deploy.sh +10 -11
- package/deploy/cyberia-server/package.sh +0 -1
- package/deploy/cyberia-server/state.sh +3 -2
- package/deploy/dd-cyberia/deploy.sh +5 -5
- package/deploy/dd-cyberia/init.sh +15 -14
- package/deploy/dd-cyberia/package.sh +0 -1
- package/deploy/dd-cyberia/state.sh +2 -2
- package/deploy/dd-cyberia/sync-deploy.sh +139 -75
- package/deploy/lib/config.sh +29 -0
- package/deploy/lib/github-actions-logging.sh +92 -76
- package/deploy/lib/host.sh +28 -19
- package/deploy/lib/state.sh +4 -1
- package/deploy/pwa-microservices-template/deploy.sh +10 -8
- package/deploy/release/deploy.sh +0 -2
- package/deployment.yaml +1 -1
- package/docker-compose.yml +23 -17
- package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
- package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
- package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
- package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
- package/docs/coverage/cyberia/base.css +362 -0
- package/docs/coverage/cyberia/block-navigation.js +82 -0
- package/docs/coverage/cyberia/favicon.png +0 -0
- package/docs/coverage/cyberia/index.html +161 -0
- package/docs/coverage/cyberia/prettify.css +101 -0
- package/docs/coverage/cyberia/prettify.js +937 -0
- package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
- package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
- package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
- package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
- package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
- package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
- package/docs/coverage/cyberia/sorter.js +205 -0
- package/hardhat/package-lock.json +2 -2
- package/hardhat/package.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/deployment/mongo-express/deployment.yaml +46 -27
- package/manifests/deployment/mongo-express/kustomization.yaml +9 -0
- package/manifests/deployment/mongo-express/mongo-express-nodeport.yaml +18 -0
- package/manifests/deployment/mongo-express/service.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/disable-mongodb-auth.yaml +16 -0
- package/manifests/deployment/mongo-express-no-auth/kustomization.yaml +16 -0
- package/package.json +19 -17
- package/scripts/test-monitor.sh +3 -3
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +14 -9
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +36 -5
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +5 -0
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +88 -184
- package/src/api/cyberia-action/cyberia-action.router.js +2 -2
- package/src/api/cyberia-action/cyberia-action.service.js +3 -4
- package/src/api/cyberia-audio/cyberia-audio.controller.js +6 -0
- package/src/api/cyberia-audio/cyberia-audio.model.js +61 -0
- package/src/api/cyberia-audio/cyberia-audio.router.js +21 -0
- package/src/api/cyberia-audio/cyberia-audio.service.js +220 -0
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -3
- package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +10 -19
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +12 -34
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +15 -32
- package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.model.js +2 -0
- package/src/api/cyberia-entity/cyberia-entity.service.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +8 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +31 -20
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +16 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +466 -3
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +87 -51
- package/src/api/cyberia-instance/cyberia-fallback-world.js +21 -40
- package/src/api/cyberia-instance/cyberia-instance-boot.service.js +5 -5
- package/src/api/cyberia-instance/cyberia-instance-items.js +98 -0
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +34 -141
- package/src/api/cyberia-instance/cyberia-instance.controller.js +1 -4
- package/src/api/cyberia-instance/cyberia-instance.model.js +0 -14
- package/src/api/cyberia-instance/cyberia-instance.router.js +3 -16
- package/src/api/cyberia-instance/cyberia-instance.service.js +3 -43
- package/src/api/cyberia-instance/cyberia-world-generator.js +8 -13
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +49 -75
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +74 -1
- package/src/api/cyberia-map/cyberia-map.service.js +6 -2
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.controller.js +31 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.model.js +56 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.router.js +33 -0
- package/src/api/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +189 -0
- package/src/api/cyberia-quest/cyberia-quest.router.js +3 -3
- package/src/api/cyberia-quest/cyberia-quest.service.js +3 -3
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +1 -1
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +403 -188
- package/src/api/cyberia-skill/cyberia-skill.model.js +6 -6
- package/src/api/file/file.ref.js +153 -0
- package/src/api/file/file.ref.json +11 -2
- package/src/api/object-layer/object-layer.model.js +47 -12
- package/src/api/object-layer/object-layer.router.js +10 -3
- package/src/api/object-layer/object-layer.service.js +113 -120
- package/src/cli/app.js +12 -1
- package/src/cli/client.js +2 -2
- package/src/cli/cluster.js +80 -18
- package/src/cli/deploy.js +215 -34
- package/src/cli/docker-compose.js +1 -1
- package/src/cli/fs-selection.js +115 -0
- package/src/cli/fs.js +158 -342
- package/src/cli/index.js +22 -10
- package/src/cli/release.js +3 -1
- package/src/cli/repository.js +35 -9
- package/src/cli/run.js +80 -199
- package/src/cli/test.js +4 -0
- package/src/cli/wireguard.js +32 -31
- package/src/client/components/core/Badge.js +0 -1
- package/src/client/components/core/CssCore.js +8 -1
- package/src/client/components/core/Docs.js +77 -100
- package/src/client/components/core/Modal.js +77 -23
- package/src/client/components/core/ToolTip.js +15 -0
- package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
- package/src/client/components/cyberia/ActionEngineCyberia.js +12 -36
- package/src/client/components/cyberia/EntityEngineCyberia.js +492 -121
- package/src/client/components/cyberia/InstanceEngineCyberia.js +129 -160
- package/src/client/components/cyberia/InstanceSelectionView.js +7 -1
- package/src/client/components/cyberia/MapEngineCyberia.js +175 -69
- package/src/client/components/cyberia/ObjectLayerEngine.js +1011 -97
- package/src/client/components/cyberia/ObjectLayerEngineModal.js +81 -155
- package/src/client/components/cyberia/ObjectLayerEngineViewer.js +113 -98
- package/src/client/components/cyberia/SharedDefaultsCyberia.js +215 -56
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +0 -34
- package/src/client/components/cyberia-portal/CssCyberiaPortal.js +1 -1
- package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +712 -76
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +0 -4
- package/src/client/components/default/AppShellDefault.js +1 -4
- package/src/client/components/itemledger/AppShellItemledger.js +0 -2
- package/src/client/components/underpost/AppShellUnderpost.js +1 -1
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +15 -15
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +280 -24
- package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +51 -29
- package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +52 -53
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +16 -11
- package/src/client/public/cyberia-docs/CYBERIA.md +28 -28
- package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +11 -5
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/STATS-PROGRESSION.md +217 -0
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +20 -12
- package/src/client/services/cyberia-audio/cyberia-audio.service.js +99 -0
- package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +38 -0
- package/src/client/services/cyberia-instance/cyberia-instance.management.js +5 -4
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +0 -40
- package/src/client/services/cyberia-map/cyberia-map.management.js +5 -4
- package/src/client/services/cyberia-map-audio-conf/cyberia-map-audio-conf.service.js +138 -0
- package/src/client/services/object-layer/object-layer.management.js +6 -10
- package/src/client/services/object-layer/object-layer.service.js +3 -1
- package/src/client/ssr/views/Cyberia404.js +3 -3
- package/src/client-builder/client-build-docs.js +52 -52
- package/src/client-builder/client-build.js +67 -44
- package/src/client-builder/client-bundle.js +347 -0
- package/src/db/mongo/MongoExpress.js +187 -0
- package/src/grpc/cyberia/grpc-server.js +5 -7
- package/src/index.js +1 -1
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +143 -146
- package/src/projects/cyberia/atlas-sprite-sheet-store.js +391 -0
- package/src/projects/cyberia/besu-genesis-generator.js +5 -14
- package/src/projects/cyberia/boot-contract-fixtures.js +32 -0
- package/src/projects/cyberia/catalog-cyberia.js +3 -2
- package/src/projects/cyberia/gemini-client.js +3 -3
- package/src/projects/cyberia/generate-saga.js +4 -11
- package/src/projects/cyberia/hot-reload-trigger.js +17 -28
- package/src/projects/cyberia/instance-backup.js +210 -0
- package/src/projects/cyberia/instance-data.js +177 -257
- package/src/projects/cyberia/map-preview-generator.js +32 -68
- package/src/projects/cyberia/object-layer.js +152 -319
- package/src/projects/cyberia/seed-audio.js +139 -0
- package/src/projects/cyberia/semantic-layer-generator-skin.js +2 -8
- package/src/projects/cyberia/semantic-layer-generator.js +2 -18
- package/src/projects/cyberia/stat-balance.js +81 -0
- package/src/projects/cyberia/stat-commands.js +23 -0
- package/src/projects/cyberia/stat-contract-generator.js +101 -0
- package/src/runtime/cyberia-client/Dockerfile +8 -4
- package/src/runtime/cyberia-client/Dockerfile.dev +5 -2
- package/src/runtime/cyberia-server/Dockerfile +9 -2
- package/src/runtime/cyberia-server/Dockerfile.dev +8 -1
- package/src/runtime/engine-cyberia/Dockerfile +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
- package/src/runtime/engine-cyberia/Dockerfile.test +2 -2
- package/src/runtime/engine-cyberia/compose.env +17 -5
- package/src/runtime/engine-cyberia/docker-compose.yml +23 -17
- package/src/server/build/coverage.js +113 -42
- package/src/server/build/package.js +55 -12
- package/src/server/build/testing.js +59 -9
- package/src/server/network/middlewares.js +8 -2
- package/src/server/network/underpost-gateway.js +113 -14
- package/src/server/ops/logger.js +70 -35
- package/src/server/runtime/conf.js +40 -9
- package/src/server/runtime/start.js +11 -2
- package/src/server/storage/data-query.js +16 -0
- package/src/server/storage/downloader.js +62 -14
- package/src/server/storage/zip.js +153 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet-store.test.js +402 -0
- package/test/integration/app/cyberia/atlas-sprite-sheet.test.js +86 -0
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +34 -0
- package/test/integration/app/cyberia/cyberia-entity-type-default.test.js +842 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-coerce.test.js +53 -0
- package/test/integration/app/cyberia/cyberia-instance-conf-defaults.test.js +16 -22
- package/test/integration/app/cyberia/cyberia-instance-items.test.js +90 -0
- package/test/integration/app/cyberia/cyberia-load.test.js +6 -7
- package/test/integration/app/cyberia/cyberia-map-audio-conf.test.js +256 -0
- package/test/integration/app/cyberia/cyberia-stats.test.js +150 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +87 -2
- package/test/integration/app/cyberia/object-layer-item-selection.test.js +56 -0
- package/test/integration/app/cyberia/object-layer-natural-key.test.js +32 -0
- package/test/integration/app/cyberia/seed-audio.test.js +275 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +33 -9
- package/test/integration/infra/2-network/wireguard-edge.test.js +58 -18
- package/test/integration/infra/3-cluster/mongo-express-deploy.test.js +156 -0
- package/test/integration/infra/4-ingress/api-cross-origin.test.js +79 -0
- package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
- package/test/unit/catalog.test.js +13 -2
- package/test/unit/client-build-docs.test.js +97 -70
- package/test/unit/client-bundle.test.js +313 -0
- package/test/unit/conf-resolution.test.js +58 -7
- package/test/unit/coverage-artifact.test.js +120 -29
- package/test/unit/cyberia/instance-backup.test.js +183 -0
- package/test/unit/cyberia/instance-data.test.js +314 -0
- package/test/unit/cyberia/instance-object-layer-items.test.js +46 -0
- package/test/unit/cyberia/publish-workflow.test.js +22 -0
- package/test/unit/cyberia/stat-balance.test.js +69 -0
- package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
- package/test/unit/deploy-log-table.test.js +76 -5
- package/test/unit/downloader-integrity.test.js +98 -0
- package/test/unit/file-reference-registry.test.js +141 -0
- package/test/unit/fs-storage-paths.test.js +596 -0
- package/test/unit/gateway-pod-fetch.test.js +95 -0
- package/test/unit/letsencrypt-issuer.test.js +101 -0
- package/test/unit/logger-redaction.test.js +29 -0
- package/test/unit/package.test.js +70 -16
- package/test/unit/prepare-host.test.js +84 -1
- package/test/unit/release-bump.test.js +3 -1
- package/test/unit/start-options.test.js +12 -0
- package/test/unit/test-tiers.test.js +27 -0
- package/test/unit/zip-archive.test.js +142 -0
- package/vitest.config.js +11 -3
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +0 -63
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +0 -368
|
@@ -13,8 +13,8 @@ import { FileService } from '../../services/file/file.service.js';
|
|
|
13
13
|
import { DefaultManagement } from '../../services/default/default.management.js';
|
|
14
14
|
import { getApiBaseUrl } from '../../services/core/core.service.js';
|
|
15
15
|
import { ObjectLayerService } from '../../services/object-layer/object-layer.service.js';
|
|
16
|
-
import { getProxyPath } from '../core/Router.js';
|
|
17
|
-
import { ENTITY_TYPES,
|
|
16
|
+
import { getProxyPath, getQueryParams, listenQueryParamsChange, setQueryParams } from '../core/Router.js';
|
|
17
|
+
import { ENTITY_TYPES, ENTITY_LEVEL_MIN, ENTITY_LEVEL_MAX, validateEntityLevel } from './SharedDefaultsCyberia.js';
|
|
18
18
|
import '../core/ColorPaletteElement.js';
|
|
19
19
|
|
|
20
20
|
const DEFAULT_ENTITY_TYPE = ENTITY_TYPES.floor;
|
|
@@ -29,6 +29,7 @@ const createDropdownOption = (value, onClick = () => {}, display = value, data =
|
|
|
29
29
|
class MapEngineCyberia {
|
|
30
30
|
static entities = [];
|
|
31
31
|
static currentMapId = null;
|
|
32
|
+
static currentMapCode = null;
|
|
32
33
|
static currentThumbnailId = null;
|
|
33
34
|
static thumbnailDirty = false;
|
|
34
35
|
static currentPreviewId = null;
|
|
@@ -65,6 +66,14 @@ class MapEngineCyberia {
|
|
|
65
66
|
: [];
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
/** Comma-separated ItemIds as typed, in order, blanks removed. Duplicates are the caller's to judge. */
|
|
70
|
+
static parseItemIdList(value = '') {
|
|
71
|
+
return String(value)
|
|
72
|
+
.split(',')
|
|
73
|
+
.map((itemId) => itemId.trim())
|
|
74
|
+
.filter((itemId) => itemId);
|
|
75
|
+
}
|
|
76
|
+
|
|
68
77
|
static getRenameObjectLayerItemIds() {
|
|
69
78
|
return {
|
|
70
79
|
source: s(`.${MapEngineCyberia.renameSourceObjectLayerInputId}`)?.value?.trim() || '',
|
|
@@ -72,6 +81,47 @@ class MapEngineCyberia {
|
|
|
72
81
|
};
|
|
73
82
|
}
|
|
74
83
|
|
|
84
|
+
/**
|
|
85
|
+
* source ItemId → the ItemIds that replace it, or the reason the lists cannot be paired.
|
|
86
|
+
*
|
|
87
|
+
* Three shapes, each unambiguous on its own:
|
|
88
|
+
* - one source, many targets — the source expands into all of them, so a layer can be split
|
|
89
|
+
* into a skin plus a weapon in one pass;
|
|
90
|
+
* - one target, many sources — every source collapses onto it;
|
|
91
|
+
* - equal counts — paired off in the order they were typed.
|
|
92
|
+
* Any other combination is a typo worth refusing: pairing a short list by position would
|
|
93
|
+
* rewrite some entities and silently leave the rest.
|
|
94
|
+
*
|
|
95
|
+
* @returns {{map?: Map<string,string[]>, error?: string}}
|
|
96
|
+
*/
|
|
97
|
+
static buildRenameItemIdMap() {
|
|
98
|
+
const { source, target } = MapEngineCyberia.getRenameObjectLayerItemIds();
|
|
99
|
+
const sources = MapEngineCyberia.parseItemIdList(source);
|
|
100
|
+
const targets = MapEngineCyberia.parseItemIdList(target);
|
|
101
|
+
if (!sources.length || !targets.length) return { error: 'Source and target ItemId are required.' };
|
|
102
|
+
|
|
103
|
+
const repeated = sources.filter((itemId, index) => sources.indexOf(itemId) !== index);
|
|
104
|
+
if (repeated.length) {
|
|
105
|
+
return { error: `Each source ItemId may appear once: "${[...new Set(repeated)].join('", "')}" is repeated.` };
|
|
106
|
+
}
|
|
107
|
+
if (sources.length > 1 && targets.length > 1 && targets.length !== sources.length) {
|
|
108
|
+
return {
|
|
109
|
+
error: `${sources.length} sources take one target for all of them, or ${sources.length} paired in order — got ${targets.length}. A list of targets replaces a single source.`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const replacement = (index) =>
|
|
114
|
+
sources.length === 1 || targets.length === 1 ? [...new Set(targets)] : [targets[index]];
|
|
115
|
+
const map = new Map(sources.map((itemId, index) => [itemId, replacement(index)]));
|
|
116
|
+
// A source that expands into a list containing itself is keeping its layer and gaining
|
|
117
|
+
// others, which is the point. Only a replacement that is the source alone does nothing.
|
|
118
|
+
const unchanged = [...map].filter(([from, to]) => to.length === 1 && to[0] === from).map(([from]) => from);
|
|
119
|
+
if (unchanged.length) {
|
|
120
|
+
return { error: `Source and target ItemId must differ: "${unchanged.join('", "')}".` };
|
|
121
|
+
}
|
|
122
|
+
return { map };
|
|
123
|
+
}
|
|
124
|
+
|
|
75
125
|
static setDropdownValue(dropdownId, value) {
|
|
76
126
|
if (!value || !DropDown.Tokens[dropdownId]) return;
|
|
77
127
|
DropDown.Tokens[dropdownId].value = value;
|
|
@@ -111,8 +161,8 @@ class MapEngineCyberia {
|
|
|
111
161
|
excludeSelected: true,
|
|
112
162
|
serviceProvider: async (q) => {
|
|
113
163
|
const result = await ObjectLayerService.searchItemIds({ q });
|
|
114
|
-
if (result.status === 'success' && result.data?.
|
|
115
|
-
return result.data.
|
|
164
|
+
if (result.status === 'success' && result.data?.items) {
|
|
165
|
+
return result.data.items.map(({ id }) => createDropdownOption(id));
|
|
116
166
|
}
|
|
117
167
|
return [];
|
|
118
168
|
},
|
|
@@ -128,22 +178,12 @@ class MapEngineCyberia {
|
|
|
128
178
|
}
|
|
129
179
|
|
|
130
180
|
static renameFilteredObjectLayerItemId() {
|
|
131
|
-
const {
|
|
132
|
-
if (
|
|
133
|
-
NotificationManager.Push({
|
|
134
|
-
html: 'Source and target ItemId are required.',
|
|
135
|
-
status: 'error',
|
|
136
|
-
});
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (source === target) {
|
|
141
|
-
NotificationManager.Push({
|
|
142
|
-
html: 'Source and target ItemId must be different.',
|
|
143
|
-
status: 'error',
|
|
144
|
-
});
|
|
181
|
+
const { map: renames, error } = MapEngineCyberia.buildRenameItemIdMap();
|
|
182
|
+
if (error) {
|
|
183
|
+
NotificationManager.Push({ html: error, status: 'error' });
|
|
145
184
|
return false;
|
|
146
185
|
}
|
|
186
|
+
const sourceList = [...renames.keys()].join('", "');
|
|
147
187
|
|
|
148
188
|
const filtered = MapEngineCyberia.getFilteredEntities();
|
|
149
189
|
if (!filtered.length) {
|
|
@@ -154,18 +194,19 @@ class MapEngineCyberia {
|
|
|
154
194
|
return false;
|
|
155
195
|
}
|
|
156
196
|
|
|
157
|
-
//
|
|
197
|
+
// Exact ItemId equality, never a prefix or a case fold: this rewrites map documents, and a
|
|
198
|
+
// near-miss would rename an entity nobody asked about.
|
|
158
199
|
const eligible = [];
|
|
159
200
|
for (const { i } of filtered) {
|
|
160
201
|
const entity = MapEngineCyberia.entities[i];
|
|
161
|
-
if (Array.isArray(entity?.objectLayerItemIds) && entity.objectLayerItemIds.
|
|
202
|
+
if (Array.isArray(entity?.objectLayerItemIds) && entity.objectLayerItemIds.some((id) => renames.has(id))) {
|
|
162
203
|
eligible.push(i);
|
|
163
204
|
}
|
|
164
205
|
}
|
|
165
206
|
|
|
166
207
|
if (!eligible.length) {
|
|
167
208
|
NotificationManager.Push({
|
|
168
|
-
html: `No exact ItemId matches for "${
|
|
209
|
+
html: `No exact ItemId matches for "${sourceList}" were found in the current filtered entities.`,
|
|
169
210
|
status: 'error',
|
|
170
211
|
});
|
|
171
212
|
return false;
|
|
@@ -175,6 +216,8 @@ class MapEngineCyberia {
|
|
|
175
216
|
// a random probability check in [fMin, fMax]. If the roll passes, it gets renamed;
|
|
176
217
|
// otherwise it stays unchanged. This produces an intermediate intensity between
|
|
177
218
|
// "almost everyone" (factors near/above 1.0) and "almost no one" (factors near 0).
|
|
219
|
+
// The roll is per entity, not per ItemId: an entity carrying several sources takes all of
|
|
220
|
+
// its renames or none, so a partly-renamed loadout is never produced.
|
|
178
221
|
let matchedEntities = 0;
|
|
179
222
|
let renamedReferences = 0;
|
|
180
223
|
const changed = MapEngineCyberia.commitEntityMutation(() => {
|
|
@@ -191,20 +234,28 @@ class MapEngineCyberia {
|
|
|
191
234
|
if (roll < 1.0 && Math.random() > roll) continue;
|
|
192
235
|
}
|
|
193
236
|
const entity = MapEngineCyberia.entities[i];
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return
|
|
237
|
+
const previous = entity.objectLayerItemIds;
|
|
238
|
+
let replaced = 0;
|
|
239
|
+
const expanded = previous.flatMap((itemId) => {
|
|
240
|
+
if (!renames.has(itemId)) return [itemId];
|
|
241
|
+
replaced += 1;
|
|
242
|
+
return renames.get(itemId);
|
|
200
243
|
});
|
|
201
|
-
|
|
244
|
+
// A replacement the entity already carries must not be added twice: an ItemId appearing
|
|
245
|
+
// once is what every reader of a loadout assumes.
|
|
246
|
+
const next = [...new Set(expanded)];
|
|
247
|
+
if (next.length === previous.length && next.every((itemId, index) => itemId === previous[index])) continue;
|
|
248
|
+
entity.objectLayerItemIds = next;
|
|
249
|
+
renamedReferences += replaced;
|
|
250
|
+
matchedEntities += 1;
|
|
202
251
|
}
|
|
203
252
|
});
|
|
204
253
|
|
|
205
254
|
if (!changed) {
|
|
206
255
|
NotificationManager.Push({
|
|
207
|
-
html:
|
|
256
|
+
html: MapEngineCyberia.enableRandomFactors
|
|
257
|
+
? `Random factors skipped all ${eligible.length} matching entit${eligible.length === 1 ? 'y' : 'ies'} — raise the factors or turn them off.`
|
|
258
|
+
: `All ${eligible.length} entit${eligible.length === 1 ? 'y' : 'ies'} matching "${sourceList}" already carry the target ItemIds.`,
|
|
208
259
|
status: 'error',
|
|
209
260
|
});
|
|
210
261
|
return false;
|
|
@@ -374,16 +425,24 @@ class MapEngineCyberia {
|
|
|
374
425
|
filterType: s('.map-engine-filter-entity-type')?.value?.trim().toLowerCase() || '',
|
|
375
426
|
filterX: s('.map-engine-filter-init-x')?.value?.trim() || '',
|
|
376
427
|
filterY: s('.map-engine-filter-init-y')?.value?.trim() || '',
|
|
428
|
+
filterItemIds: MapEngineCyberia.parseItemIdList(s('.map-engine-filter-object-layer-item-ids')?.value || ''),
|
|
377
429
|
};
|
|
378
430
|
}
|
|
379
431
|
|
|
380
432
|
static getFilteredEntities() {
|
|
381
|
-
const { filterType, filterX, filterY } = MapEngineCyberia.getEntityFilters();
|
|
433
|
+
const { filterType, filterX, filterY, filterItemIds } = MapEngineCyberia.getEntityFilters();
|
|
382
434
|
|
|
383
435
|
return MapEngineCyberia.entities.reduce((acc, entity, i) => {
|
|
384
436
|
if (filterType && !(entity.entityType || '').toLowerCase().includes(filterType)) return acc;
|
|
385
437
|
if (filterX !== '' && String(entity.initCellX) !== filterX) return acc;
|
|
386
438
|
if (filterY !== '' && String(entity.initCellY) !== filterY) return acc;
|
|
439
|
+
// Every listed id, matched exactly: the list narrows the selection like the other filters,
|
|
440
|
+
// so naming a second id picks out the entities carrying that combination rather than
|
|
441
|
+
// widening the set. What this selects is exactly what the rename will act on.
|
|
442
|
+
if (filterItemIds.length) {
|
|
443
|
+
const carried = entity.objectLayerItemIds || [];
|
|
444
|
+
if (!filterItemIds.every((itemId) => carried.includes(itemId))) return acc;
|
|
445
|
+
}
|
|
387
446
|
acc.push({ entity, i });
|
|
388
447
|
return acc;
|
|
389
448
|
}, []);
|
|
@@ -393,41 +452,16 @@ class MapEngineCyberia {
|
|
|
393
452
|
if (MapEngineCyberia.imageCache[itemId]) return;
|
|
394
453
|
MapEngineCyberia.imageCache[itemId] = { img: null, loaded: false, error: false };
|
|
395
454
|
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
img
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
if (onLoad) onLoad();
|
|
402
|
-
};
|
|
403
|
-
img.onerror = () => {
|
|
404
|
-
MapEngineCyberia.imageCache[itemId].error = true;
|
|
405
|
-
};
|
|
406
|
-
img.src = `${getProxyPath()}assets/${type}/${id}/08/0.png`;
|
|
455
|
+
const img = new Image();
|
|
456
|
+
img.onload = () => {
|
|
457
|
+
MapEngineCyberia.imageCache[itemId].img = img;
|
|
458
|
+
MapEngineCyberia.imageCache[itemId].loaded = true;
|
|
459
|
+
if (onLoad) onLoad();
|
|
407
460
|
};
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
ObjectLayerService.get({
|
|
416
|
-
limit: 1,
|
|
417
|
-
filterModel: { 'data.item.id': { filterType: 'text', type: 'equals', filter: itemId } },
|
|
418
|
-
})
|
|
419
|
-
.then((res) => {
|
|
420
|
-
const doc = res?.data?.data?.[0];
|
|
421
|
-
if (!doc || !doc.data?.item?.type || !doc.data?.item?.id) {
|
|
422
|
-
MapEngineCyberia.imageCache[itemId].error = true;
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
const { type, id } = doc.data.item;
|
|
426
|
-
loadImage(type, id);
|
|
427
|
-
})
|
|
428
|
-
.catch(() => {
|
|
429
|
-
MapEngineCyberia.imageCache[itemId].error = true;
|
|
430
|
-
});
|
|
461
|
+
img.onerror = () => {
|
|
462
|
+
MapEngineCyberia.imageCache[itemId].error = true;
|
|
463
|
+
};
|
|
464
|
+
img.src = `${getProxyPath()}api/atlas-sprite-sheet/idle-preview/${itemId}`;
|
|
431
465
|
}
|
|
432
466
|
|
|
433
467
|
static renderGrid(canvas, cols, rows, cellW, cellH, showGrid = true) {
|
|
@@ -578,6 +612,7 @@ class MapEngineCyberia {
|
|
|
578
612
|
if (s('.map-engine-init-cell-x')) s('.map-engine-init-cell-x').value = entity.initCellX || 0;
|
|
579
613
|
if (s('.map-engine-init-cell-y')) s('.map-engine-init-cell-y').value = entity.initCellY || 0;
|
|
580
614
|
if (s('.map-engine-dim-x')) s('.map-engine-dim-x').value = entity.dimX || 1;
|
|
615
|
+
if (s('.map-engine-level')) s('.map-engine-level').value = entity.level ?? '';
|
|
581
616
|
if (s('.map-engine-dim-y')) s('.map-engine-dim-y').value = entity.dimY || 1;
|
|
582
617
|
|
|
583
618
|
// Parse rgba color back to hex + alpha
|
|
@@ -619,6 +654,7 @@ class MapEngineCyberia {
|
|
|
619
654
|
const canvasId = 'map-engine-canvas';
|
|
620
655
|
|
|
621
656
|
const idEntityType = MapEngineCyberia.entityTypeDropdownId;
|
|
657
|
+
const idLevel = 'map-engine-level';
|
|
622
658
|
const idInitCellX = 'map-engine-init-cell-x';
|
|
623
659
|
const idInitCellY = 'map-engine-init-cell-y';
|
|
624
660
|
const idDimX = 'map-engine-dim-x';
|
|
@@ -639,6 +675,7 @@ class MapEngineCyberia {
|
|
|
639
675
|
|
|
640
676
|
MapEngineCyberia.setEntities([], { clearHistory: true });
|
|
641
677
|
MapEngineCyberia.currentMapId = null;
|
|
678
|
+
MapEngineCyberia.currentMapCode = null;
|
|
642
679
|
MapEngineCyberia.currentThumbnailId = null;
|
|
643
680
|
MapEngineCyberia.currentPreviewId = null;
|
|
644
681
|
|
|
@@ -704,7 +741,16 @@ class MapEngineCyberia {
|
|
|
704
741
|
const getEntityParams = () => {
|
|
705
742
|
const hex = s(`.${idColor}`)?.value || '#ff0000';
|
|
706
743
|
const alpha = parseFloat(s(`.${idAlpha}`)?.value);
|
|
744
|
+
const rawLevel = s(`.${idLevel}`)?.value.trim();
|
|
745
|
+
let level;
|
|
746
|
+
try {
|
|
747
|
+
if (rawLevel) level = validateEntityLevel(Number(rawLevel));
|
|
748
|
+
} catch (error) {
|
|
749
|
+
NotificationManager.Push({ html: error.message, status: 'error' });
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
707
752
|
return {
|
|
753
|
+
level,
|
|
708
754
|
entityType: MapEngineCyberia.getSelectedEntityType(),
|
|
709
755
|
initCellX: parseInt(s(`.${idInitCellX}`)?.value) || 0,
|
|
710
756
|
initCellY: parseInt(s(`.${idInitCellY}`)?.value) || 0,
|
|
@@ -724,6 +770,7 @@ class MapEngineCyberia {
|
|
|
724
770
|
|
|
725
771
|
const addEntityLocally = () => {
|
|
726
772
|
const ep = getEntityParams();
|
|
773
|
+
if (!ep) return;
|
|
727
774
|
ep.objectLayerItemIds = DropDown.Tokens[idObjLayerDropdown]?.value
|
|
728
775
|
? [...DropDown.Tokens[idObjLayerDropdown].value]
|
|
729
776
|
: [];
|
|
@@ -735,6 +782,7 @@ class MapEngineCyberia {
|
|
|
735
782
|
|
|
736
783
|
const fillMapWithEntity = () => {
|
|
737
784
|
const ep = getEntityParams();
|
|
785
|
+
if (!ep) return;
|
|
738
786
|
ep.objectLayerItemIds = DropDown.Tokens[idObjLayerDropdown]?.value
|
|
739
787
|
? [...DropDown.Tokens[idObjLayerDropdown].value]
|
|
740
788
|
: [];
|
|
@@ -813,6 +861,7 @@ class MapEngineCyberia {
|
|
|
813
861
|
const selectedCount = getAffectedEntityCount(preserveIndices.length);
|
|
814
862
|
const selected = [...preserveIndices].sort(() => Math.random() - 0.5).slice(0, selectedCount);
|
|
815
863
|
const template = getEntityParams();
|
|
864
|
+
if (!template) return;
|
|
816
865
|
template.objectLayerItemIds = DropDown.Tokens[idObjLayerDropdown]?.value
|
|
817
866
|
? [...DropDown.Tokens[idObjLayerDropdown].value]
|
|
818
867
|
: [];
|
|
@@ -823,6 +872,7 @@ class MapEngineCyberia {
|
|
|
823
872
|
const replacement = {
|
|
824
873
|
...target,
|
|
825
874
|
entityType: template.entityType,
|
|
875
|
+
level: template.level,
|
|
826
876
|
dimX: template.dimX,
|
|
827
877
|
dimY: template.dimY,
|
|
828
878
|
color: template.color,
|
|
@@ -964,6 +1014,9 @@ class MapEngineCyberia {
|
|
|
964
1014
|
});
|
|
965
1015
|
if (result.status === 'success') {
|
|
966
1016
|
if (result.data?._id) MapEngineCyberia.currentMapId = result.data._id;
|
|
1017
|
+
// A saved map becomes the one the URL points at.
|
|
1018
|
+
MapEngineCyberia.currentMapCode = body.code || null;
|
|
1019
|
+
setQueryParams({ mapCode: body.code || null }, { replace: true });
|
|
967
1020
|
renderPreviewImage();
|
|
968
1021
|
await DefaultManagement.loadTable(managementId, { force: true, reload: true });
|
|
969
1022
|
}
|
|
@@ -1008,6 +1061,8 @@ class MapEngineCyberia {
|
|
|
1008
1061
|
});
|
|
1009
1062
|
if (result.status === 'success') {
|
|
1010
1063
|
if (result.data?._id) MapEngineCyberia.currentMapId = result.data._id;
|
|
1064
|
+
MapEngineCyberia.currentMapCode = body.code || null;
|
|
1065
|
+
setQueryParams({ mapCode: body.code || null }, { replace: true });
|
|
1011
1066
|
if (cloneThumbnailId) MapEngineCyberia.currentThumbnailId = cloneThumbnailId;
|
|
1012
1067
|
if (clonePreviewId) MapEngineCyberia.currentPreviewId = clonePreviewId;
|
|
1013
1068
|
renderPreviewImage();
|
|
@@ -1017,6 +1072,8 @@ class MapEngineCyberia {
|
|
|
1017
1072
|
|
|
1018
1073
|
const loadMap = async (mapData) => {
|
|
1019
1074
|
MapEngineCyberia.currentMapId = mapData._id || null;
|
|
1075
|
+
MapEngineCyberia.currentMapCode = mapData.code || null;
|
|
1076
|
+
setQueryParams({ mapCode: mapData.code || null }, { replace: true });
|
|
1020
1077
|
if (s(`.${idCode}`)) s(`.${idCode}`).value = mapData.code || '';
|
|
1021
1078
|
if (s(`.${idName}`)) s(`.${idName}`).value = mapData.name || '';
|
|
1022
1079
|
if (s(`.${idDescription}`)) s(`.${idDescription}`).value = mapData.description || '';
|
|
@@ -1089,6 +1146,7 @@ class MapEngineCyberia {
|
|
|
1089
1146
|
|
|
1090
1147
|
const nextEntities = (mapData.entities || []).map((e) => ({
|
|
1091
1148
|
entityType: e.entityType,
|
|
1149
|
+
level: e.level,
|
|
1092
1150
|
initCellX: e.initCellX,
|
|
1093
1151
|
initCellY: e.initCellY,
|
|
1094
1152
|
dimX: e.dimX,
|
|
@@ -1103,6 +1161,8 @@ class MapEngineCyberia {
|
|
|
1103
1161
|
|
|
1104
1162
|
const resetForm = () => {
|
|
1105
1163
|
MapEngineCyberia.currentMapId = null;
|
|
1164
|
+
MapEngineCyberia.currentMapCode = null;
|
|
1165
|
+
setQueryParams({ mapCode: null }, { replace: true });
|
|
1106
1166
|
MapEngineCyberia.currentThumbnailId = null;
|
|
1107
1167
|
MapEngineCyberia.currentPreviewId = null;
|
|
1108
1168
|
MapEngineCyberia.thumbnailDirty = false;
|
|
@@ -1127,6 +1187,7 @@ class MapEngineCyberia {
|
|
|
1127
1187
|
if (s(`.${idY}`)) s(`.${idY}`).value = 16;
|
|
1128
1188
|
if (s(`.${idCellW}`)) s(`.${idCellW}`).value = 32;
|
|
1129
1189
|
if (s(`.${idCellH}`)) s(`.${idCellH}`).value = 32;
|
|
1190
|
+
if (s(`.${idLevel}`)) s(`.${idLevel}`).value = '';
|
|
1130
1191
|
if (s(`.${idVariationPreserve}`)) s(`.${idVariationPreserve}`).value = '';
|
|
1131
1192
|
if (s(`.${idRenameSourceObjectLayer}`)) s(`.${idRenameSourceObjectLayer}`).value = '';
|
|
1132
1193
|
if (s(`.${idRenameTargetObjectLayer}`)) s(`.${idRenameTargetObjectLayer}`).value = '';
|
|
@@ -1140,6 +1201,28 @@ class MapEngineCyberia {
|
|
|
1140
1201
|
}
|
|
1141
1202
|
};
|
|
1142
1203
|
|
|
1204
|
+
// ?mapCode=<code> loads that map into the form on arrival.
|
|
1205
|
+
const loadMapByCode = async (code) => {
|
|
1206
|
+
if (!code || code === MapEngineCyberia.currentMapCode) return;
|
|
1207
|
+
const { status, data } = await CyberiaMapService.get({ id: code });
|
|
1208
|
+
if (status !== 'success' || !data?._id) {
|
|
1209
|
+
NotificationManager.Push({ html: `No map answers to the code "${code}"`, status: 'error' });
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
await loadMap(data);
|
|
1213
|
+
NotificationManager.Push({ html: `Map "${data.name || data.code}" loaded`, status: 'success' });
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
listenQueryParamsChange({
|
|
1217
|
+
id: 'cyberia-map-engine-query-listener',
|
|
1218
|
+
event: async (queryParams) => {
|
|
1219
|
+
if (!s(`.${idCode}`)) return;
|
|
1220
|
+
const code = queryParams.mapCode || null;
|
|
1221
|
+
if (code) await loadMapByCode(code);
|
|
1222
|
+
else if (MapEngineCyberia.currentMapCode) resetForm();
|
|
1223
|
+
},
|
|
1224
|
+
});
|
|
1225
|
+
|
|
1143
1226
|
setTimeout(() => {
|
|
1144
1227
|
const canvas = s(`.${canvasId}`);
|
|
1145
1228
|
if (!canvas) return;
|
|
@@ -1311,13 +1394,13 @@ class MapEngineCyberia {
|
|
|
1311
1394
|
MapEngineCyberia.renderEntityList(entityListId);
|
|
1312
1395
|
}, 300);
|
|
1313
1396
|
};
|
|
1314
|
-
[idFilterEntityType, idFilterInitX, idFilterInitY].forEach((cls) => {
|
|
1397
|
+
[idFilterEntityType, idFilterInitX, idFilterInitY, idFilterObjectLayerItemIds].forEach((cls) => {
|
|
1315
1398
|
if (s(`.${cls}`)) s(`.${cls}`).addEventListener('input', applyEntityFilter);
|
|
1316
1399
|
});
|
|
1317
1400
|
|
|
1318
1401
|
if (s('.btn-map-engine-clear-entity-filter'))
|
|
1319
1402
|
s('.btn-map-engine-clear-entity-filter').onclick = () => {
|
|
1320
|
-
[idFilterEntityType, idFilterInitX, idFilterInitY].forEach((cls) => {
|
|
1403
|
+
[idFilterEntityType, idFilterInitX, idFilterInitY, idFilterObjectLayerItemIds].forEach((cls) => {
|
|
1321
1404
|
if (s(`.${cls}`)) s(`.${cls}`).value = '';
|
|
1322
1405
|
});
|
|
1323
1406
|
MapEngineCyberia.renderEntityList(entityListId);
|
|
@@ -1330,6 +1413,9 @@ class MapEngineCyberia {
|
|
|
1330
1413
|
s('.btn-map-engine-rename-filtered-object-layer-item-id').onclick = () => {
|
|
1331
1414
|
MapEngineCyberia.renameFilteredObjectLayerItemId();
|
|
1332
1415
|
};
|
|
1416
|
+
|
|
1417
|
+
// Loaded last: loadMap repaints the canvas through the history sync above.
|
|
1418
|
+
loadMapByCode(getQueryParams().mapCode);
|
|
1333
1419
|
});
|
|
1334
1420
|
|
|
1335
1421
|
const statusOptions = [
|
|
@@ -1368,6 +1454,7 @@ class MapEngineCyberia {
|
|
|
1368
1454
|
const idFilterEntityType = 'map-engine-filter-entity-type';
|
|
1369
1455
|
const idFilterInitX = 'map-engine-filter-init-x';
|
|
1370
1456
|
const idFilterInitY = 'map-engine-filter-init-y';
|
|
1457
|
+
const idFilterObjectLayerItemIds = 'map-engine-filter-object-layer-item-ids';
|
|
1371
1458
|
|
|
1372
1459
|
return html`<div class="in section-mp map-engine-container">
|
|
1373
1460
|
${dynamicCol({ containerSelector: 'map-engine-container', id: dcMapFields, type: 'search-inputs' })}
|
|
@@ -1674,6 +1761,11 @@ class MapEngineCyberia {
|
|
|
1674
1761
|
value: DEFAULT_ENTITY_TYPE,
|
|
1675
1762
|
containerClass: 'inl',
|
|
1676
1763
|
})}
|
|
1764
|
+
${await Input.instance({
|
|
1765
|
+
id: idLevel,
|
|
1766
|
+
label: html`Level (empty uses instance default)`,
|
|
1767
|
+
containerClass: 'inl', type: 'number', min: ENTITY_LEVEL_MIN, max: ENTITY_LEVEL_MAX, value: '',
|
|
1768
|
+
})}
|
|
1677
1769
|
</div>
|
|
1678
1770
|
<div class="in fll ${dcEntityType}-col-b">
|
|
1679
1771
|
${await Input.instance({
|
|
@@ -1816,13 +1908,15 @@ class MapEngineCyberia {
|
|
|
1816
1908
|
<div class="in section-mp-border" style="margin: 10px; padding: 10px;">
|
|
1817
1909
|
<div class="in input-label">Rename Object Layer ItemId on Filtered Entities</div>
|
|
1818
1910
|
<div class="in" style="font-size:12px;color:#888;margin-bottom:8px;">
|
|
1819
|
-
Replaces only exact source ItemId matches inside entities currently visible through the filters.
|
|
1911
|
+
Replaces only exact source ItemId matches inside entities currently visible through the filters. Both
|
|
1912
|
+
fields take comma-separated lists: several targets expand one source into all of them, one target
|
|
1913
|
+
renames every source onto it, and equal counts pair off in the order typed.
|
|
1820
1914
|
</div>
|
|
1821
1915
|
<div class="fl">
|
|
1822
1916
|
<div class="in fll" style="flex:1;padding-right:5px;">
|
|
1823
1917
|
${await Input.instance({
|
|
1824
1918
|
id: idRenameSourceObjectLayer,
|
|
1825
|
-
label: html`Source
|
|
1919
|
+
label: html`Source ItemIds`,
|
|
1826
1920
|
containerClass: 'inl',
|
|
1827
1921
|
type: 'text',
|
|
1828
1922
|
placeholder: true,
|
|
@@ -1831,7 +1925,7 @@ class MapEngineCyberia {
|
|
|
1831
1925
|
<div class="in fll" style="flex:1;padding-left:5px;">
|
|
1832
1926
|
${await Input.instance({
|
|
1833
1927
|
id: idRenameTargetObjectLayer,
|
|
1834
|
-
label: html`Target
|
|
1928
|
+
label: html`Target ItemIds`,
|
|
1835
1929
|
containerClass: 'inl',
|
|
1836
1930
|
type: 'text',
|
|
1837
1931
|
placeholder: true,
|
|
@@ -1923,6 +2017,18 @@ class MapEngineCyberia {
|
|
|
1923
2017
|
})}
|
|
1924
2018
|
</div>
|
|
1925
2019
|
</div>
|
|
2020
|
+
<div class="in" style="margin-top:5px;">
|
|
2021
|
+
${await Input.instance({
|
|
2022
|
+
id: idFilterObjectLayerItemIds,
|
|
2023
|
+
label: html`Object Layer ItemIds`,
|
|
2024
|
+
containerClass: 'inl',
|
|
2025
|
+
type: 'text',
|
|
2026
|
+
placeholder: true,
|
|
2027
|
+
})}
|
|
2028
|
+
<div class="in" style="font-size:12px;color:#888;margin-top:3px;">
|
|
2029
|
+
Comma separated, matched exactly. Keeps only entities carrying all of them.
|
|
2030
|
+
</div>
|
|
2031
|
+
</div>
|
|
1926
2032
|
<div
|
|
1927
2033
|
class="in map-engine-entity-filter-count"
|
|
1928
2034
|
style="margin-top:5px;font-size:12px;color:#888;font-family:monospace;"
|