diff --git a/index.html b/index.html
index dd50311e..ca109104 100644
--- a/index.html
+++ b/index.html
@@ -3050,6 +3050,13 @@
+
diff --git a/modules/save-and-load.js b/modules/save-and-load.js
index 3022174b..44488bbc 100644
--- a/modules/save-and-load.js
+++ b/modules/save-and-load.js
@@ -395,6 +395,7 @@ function getMapData() {
const religions = JSON.stringify(pack.religions);
const provinces = JSON.stringify(pack.provinces);
const rivers = JSON.stringify(pack.rivers);
+ const resources = JSON.stringify(pack.resources);
// store name array only if it is not the same as default
const defaultNB = Names.getNameBases();
@@ -443,8 +444,11 @@ function getMapData() {
provinces,
namesData,
rivers,
- rulersString
+ rulersString,
+ pack.cells.resource,
+ resources
].join('\r\n');
+
const blob = new Blob([data], {type: 'text/plain'});
TIME && console.timeEnd('createMapDataBlob');
@@ -857,6 +861,7 @@ function parseLoadedData(data) {
pack.religions = data[29] ? JSON.parse(data[29]) : [{i: 0, name: 'No religion'}];
pack.provinces = data[30] ? JSON.parse(data[30]) : [0];
pack.rivers = data[32] ? JSON.parse(data[32]) : [];
+ pack.resources = data[35] ? JSON.parse(data[35]) : [];
const cells = pack.cells;
cells.biome = Uint8Array.from(data[16].split(','));
@@ -872,6 +877,7 @@ function parseLoadedData(data) {
cells.religion = data[26] ? Uint16Array.from(data[26].split(',')) : new Uint16Array(cells.i.length);
cells.province = data[27] ? Uint16Array.from(data[27].split(',')) : new Uint16Array(cells.i.length);
cells.crossroad = data[28] ? Uint16Array.from(data[28].split(',')) : new Uint16Array(cells.i.length);
+ cells.resource = data[34] ? Uint8Array.from(data[34].split(',')) : new Uint8Array(cells.i.length);
if (data[31]) {
const namesDL = data[31].split('/');
@@ -1302,19 +1308,20 @@ function parseLoadedData(data) {
pattern.innerHTML = ``;
document.getElementById('oceanPattern').setAttribute('opacity', 0.2);
}
+
+ if (version < 1.62) {
+ // v 1.62 changed grid data
+ gridOverlay.attr('size', null);
+ }
+
+ if (version < 1.7) {
+ // v 1.7 added resources layer
+ goods = viewbox.append('g').attr('id', 'goods');
+ defs.append('g').attr('id', 'defs-icons');
+ Resources.generate();
+ }
})();
- if (version < 1.62) {
- // v 1.62 changed grid data
- gridOverlay.attr('size', null);
- }
-
- if (version < 1.7) {
- // v 1.7 added resources layer
- goods = viewbox.append('g').attr('id', 'goods');
- defs.append('g').attr('id', 'defs-icons');
- }
-
void (function checkDataIntegrity() {
const cells = pack.cells;
diff --git a/modules/ui/heightmap-editor.js b/modules/ui/heightmap-editor.js
index 7ee508d4..6df207bb 100644
--- a/modules/ui/heightmap-editor.js
+++ b/modules/ui/heightmap-editor.js
@@ -212,6 +212,9 @@ function editHeightmap() {
Lakes.defineGroup();
defineBiomes();
+
+ Resources.generate();
+
rankCells();
Cultures.generate();
Cultures.expand();
diff --git a/modules/ui/resources-editor.js b/modules/ui/resources-editor.js
index d84d3f5e..e841b199 100644
--- a/modules/ui/resources-editor.js
+++ b/modules/ui/resources-editor.js
@@ -307,18 +307,22 @@ function editResources() {
function changeIcon(resource, line, el) {
const standardIcons = Array.from(document.getElementById('resource-icons').querySelectorAll('symbol')).map((el) => el.id);
- const standardIconsOptions = standardIcons.map((icon) => ``);
+ const standardIconsOptions = standardIcons.map((icon) => ``);
const customIconsEl = document.getElementById('defs-icons');
const customIcons = customIconsEl ? Array.from(document.getElementById('defs-icons').querySelectorAll('svg')).map((el) => el.id) : [];
- const customIconsOptions = customIcons.map((icon) => ``);
+ const customIconsOptions = customIcons.map((icon) => ``);
const select = document.getElementById('resourceSelectIcon');
select.innerHTML = standardIconsOptions + customIconsOptions;
+ select.value = resource.icon;
const preview = document.getElementById('resourceIconPreview');
preview.setAttribute('href', '#' + resource.icon);
+ const viewBoxSection = document.getElementById('resourceIconEditorViewboxFields');
+ viewBoxSection.style.display = 'none';
+
$('#resourceIconEditor').dialog({
resizable: false,
title: 'Change Icon',
@@ -329,6 +333,7 @@ function editResources() {
'Change color': () => changeColor(resource, line, el),
Apply: function () {
$(this).dialog('close');
+
resource.icon = select.value;
line.querySelector('svg.resourceIcon > use').setAttribute('href', '#' + select.value);
drawResources();
@@ -338,10 +343,29 @@ function editResources() {
});
const uploadTo = document.getElementById('defs-icons');
- const onUpload = (id) => {
+ const onUpload = (type, id) => {
preview.setAttribute('href', '#' + id);
select.innerHTML += ``;
select.value = id;
+
+ if (type === 'image') return;
+
+ // let user set viewBox for svg image
+ const el = document.getElementById(id);
+ viewBoxSection.style.display = 'block';
+ const viewBoxAttr = el.getAttribute('viewBox');
+ const initialViewBox = viewBoxAttr ? viewBoxAttr.split(' ') : [0, 0, 200, 200];
+ const inputs = viewBoxSection.querySelectorAll('input');
+ const changeInput = () => {
+ const viewBox = Array.from(inputs)
+ .map((input) => input.value)
+ .join(' ');
+ el.setAttribute('viewBox', viewBox);
+ };
+ inputs.forEach((input, i) => {
+ input.value = initialViewBox[i];
+ input.onchange = changeInput;
+ });
};
// add listeners
@@ -391,7 +415,7 @@ function editResources() {
icon.setAttribute('height', 200);
}
- callback(id);
+ callback(type, id);
};
if (type === 'image') reader.readAsDataURL(file);
@@ -538,6 +562,8 @@ function editResources() {
}
function resourceAdd() {
+ if (pack.resources.length >= 256) return tip('Maximum number of resources is reached', false, 'error');
+
let i = last(pack.resources).i;
while (Resources.get(i)) {
i++;