Professional Documents
Culture Documents
Tamper
Tamper
(function() {
'use strict';
const correctionNames = {
"Trick_or_Treat_Bag": "Trick-or-Treat_Bag",
"Panner_Bunker_House": "Panner_Bunk_House",
"Master_Copper_Smith": "Platinum_Master_Copper_Smith",
"Copper_Smith": "Epic_Copper_Smith",
"Hatched_Hank_Jr": "Hatched_Hank_Jr's",
"Cheese_Pizza": "Four-Cheese_Pizza",
"Tomatoes": "Tomato",
"Wild_Salmon": "Salmon",
"Oopsie_'23": "Mayhem_-_Oopsie_'23",
"Nourish_Milk": "Milk",
"Four_Cheese_Pizza": "Four-Cheese_Pizza",
}
function ConvertCorrectionName(name) {
return !correctionNames[name] ? name : correctionNames[name];
}
LoadInfoContent();
}
});
loadAfterTsvoperationObserver.observe(document, {attributes: true, childList:
true , subtree: true});
function LoadInfoContent() {
const infoContainer = document.createElement('div');
infoContainer.id = 'info-container';
infoContainer.classList.add('tileinfobody');
document.querySelector('.maincontainer').appendChild(infoContainer);
LoadLayoutTab();
LoadCalculationTab();
LoadSetupTab();
}
function GetTabContainerElement() {
return document.querySelector('#tab-container');
}
function GetInfoContentContainer() {
return document.querySelector('#info-content-container');
}
function GetSetupContainerContentContainer() {
return document.querySelector('#setup-container-content-container');
}
const setup = {
// Ornaments
"ornaments": {
"Ornament_One_Holiday_Tree_Card": {
"name": "Ornament 1 (Wages -8%)",
},
"Ornament_Two_Holiday_Tree_Card": {
"name": "Ornament 2 (Wages -3.5%)",
},
"Ornament_Three_Holiday_Tree_Card": {
"name": "Ornament 3 (Cost -2%)",
},
"Ornament_Four_Holiday_Tree_Card": {
"name": "Ornament 4 (Wages -1.5%)",
},
"Ornament_Five_Holiday_Tree_Card": {
"name": "Ornament 5 (Cost -9%)",
},
"Ornament_Six_Holiday_Tree_Card": {
"name": "Ornament 6 (Cost -5%)",
},
"Ornament_Seven_Holiday_Tree_Card": {
"name": "Ornament 7 (Wages -1.5%)",
},
"Ornament_Eight_Holiday_Tree_Card": {
"name": "Ornament 8 (Cost -2%)",
},
"Ornament_Nine_Holiday_Tree_Card": {
"name": "Ornament 9 (Cost -5%)",
},
"Ornament_Ten_Holiday_Tree_Card": {
"name": "Ornament 10 (Wages -4%)",
},
"Ornament_Eleven_Holiday_Tree_Card": {
"name": "Ornament 11 (Cost -2%)",
},
"Ornament_Twelve_Holiday_Tree_Card": {
"name": "Ornament 12 (Wages -1.5%)",
},
},
// Blueprints
"blueprints": {
"Blueprint_Thrifty_Foundry_Luxury": {
"name": "Luxury (Cost -40%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Platinum": {
"name": "Platinum (Cost -35%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Legendary": {
"name": "Legendary (Cost -30%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Epic": {
"name": "Epic (Cost -25%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Rare": {
"name": "Rare(Cost -20%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Uncommon": {
"name": "Uncommon (Cost -15%, Requirement -40%)",
},
"Blueprint_Thrifty_Foundry_Common": {
"name": "Common (Cost -10%, Requirement -40%)",
},
},
// Others
"others": {
"Galaverse_in_the_Mediterranean_Sea": {
"name": "Galaverse 2022 (Wages -30%)",
},
},
};
function CalculateAppliedUtilities() {
// Reset
Object.keys(appliedUtilities).forEach((utility) => {
delete appliedUtilities[utility];
});
appliedNfts.forEach((nftName) => {
const nft = nfts[nftName];
if (
nft &&
nft.utilities
) {
Object.keys(nft.utilities).forEach((utility) => {
Object.keys(nft.utilities[utility]).forEach((building) => {
if (!appliedUtilities[utility]) {
appliedUtilities[utility] = {};
}
if (!appliedUtilities[utility][building]) {
appliedUtilities[utility][building] = 0;
}
appliedUtilities[utility][building] +=
nft.utilities[utility][building];
});
});
}
});
ShowAppliedUtilities();
}
function ShowAppliedUtilities() {
const sortedAppliedUtilities = SortObject(appliedUtilities);
const infoContainer = document.querySelector('#setup-info-container');
infoContainer.textContent = "";
Object.keys(sortedAppliedUtilities).forEach((utility) => {
const sortedAppliedUtilitiesBuildings =
SortObject(sortedAppliedUtilities[utility]);
Object.keys(sortedAppliedUtilitiesBuildings).forEach((building) => {
const container = document.createElement('div');
container.textContent = getPrettyName(utility) + " " +
getPrettyName(building) + " : " + sortedAppliedUtilitiesBuildings[building] + "%";
infoContainer.appendChild(container);
});
});
}
function LoadAppliedNfts() {
appliedNfts = GM_getValue(appliedNftsName);
if (!appliedNfts) {
appliedNfts = [];
}
}
function SetAppliedNfts() {
GM_setValue(appliedNftsName, appliedNfts);
CalculateAppliedUtilities();
}
function AddAppliedNfts(nftName) {
if (!appliedNfts.includes(nftName)) {
appliedNfts.push(nftName);
SetAppliedNfts();
}
}
function RemoveAppliedNfts(nftName) {
if (appliedNfts.includes(nftName)) {
const filtered = appliedNfts.filter((value) => {
return value != nftName;
});
appliedNfts = filtered;
SetAppliedNfts();
}
}
function LoadSetupTab() {
LoadAppliedNfts();
// Tab
const tab = document.createElement('div');
tab.id = 'setup-tab';
tab.textContent = 'Setup';
tab.onclick = function() { ShowInfoSetupContent(); };
const tabContainer = GetTabContainerElement();
tabContainer.appendChild(tab);
// Content
const container = document.createElement('div');
container.id = 'setup-container';
container.style.display = 'none';
LoadSetupInfo();
LoadSetupOrnaments();
LoadSetupOthers();
}
function LoadSetupInfo() {
const infoContainer = document.createElement('div');
infoContainer.id = 'setup-info-container';
CalculateAppliedUtilities();
}
function LoadSetupOrnaments() {
const ornaments = setup.ornaments;
const ornamentContainer = document.createElement('div');
ornamentContainer.id = 'ornament-container';
Object.keys(ornaments).forEach((nftName) => {
const ornament = ornaments[nftName];
const container = document.createElement('div');
container.title = nfts[nftName].description;
container.appendChild(label);
ornamentContainer.appendChild(container);
});
function LoadSetupOthers() {
const others = setup.others;
const otherContainer = document.createElement('div');
otherContainer.id = 'other-container';
Object.keys(others).forEach((nftName) => {
const other = others[nftName];
const container = document.createElement('div');
container.title = nfts[nftName].description;
container.appendChild(label);
otherContainer.appendChild(container);
});
function LoadLayoutTab() {
// Tab
const tab = document.createElement('div');
tab.id = 'layout-tab';
tab.classList.add('selected');
tab.textContent = 'Layout';
tab.onclick = function() { ShowInfoLayoutContent(); };
const tabContainer = GetTabContainerElement();
tabContainer.appendChild(tab);
// Content
const container = document.createElement('div');
container.id = 'layout-container';
const contentContainer = GetInfoContentContainer();
contentContainer.appendChild(container);
}
function LoadCalculationTab() {
// Tab
const tab = document.createElement('div');
tab.id = 'calculation-tab';
tab.textContent = 'Calculation';
tab.onclick = function() {
// For testing many ingredients product.
// document.querySelector('#product-rate-product-select').value =
'Stack_Box';
// For testing many ingredients product.
// ShowProductRate();
ShowInfoCalculationContent();
};
const tabContainer = GetTabContainerElement();
tabContainer.appendChild(tab);
// Content
const container = document.createElement('div');
container.id = 'calculation-container';
container.style.display = 'none';
container.appendChild(productRateContainer);
function RemoveInfoTabSelected() {
const tabs = document.querySelectorAll('#tab-container > div');
for (const tab of tabs) {
tab.classList.remove('selected');
}
const containers = document.querySelectorAll('#info-content-container >
div');
for (const container of containers) {
container.style.display = 'none';
}
}
function ShowInfoLayoutContent() {
RemoveInfoTabSelected();
document.querySelector('#layout-tab').classList.add('selected');
document.querySelector('#layout-container').style.display = 'block';
}
function ShowInfoCalculationContent() {
RemoveInfoTabSelected();
document.querySelector('#calculation-tab').classList.add('selected');
document.querySelector('#calculation-container').style.display = 'block';
}
function ShowInfoSetupContent() {
RemoveInfoTabSelected();
document.querySelector('#setup-tab').classList.add('selected');
document.querySelector('#setup-container').style.display = 'block';
}
const maxRequirement = 4;
function ShowProductRate() {
// Empty UI.
const content = document.querySelector('#product-rate-content');
content.textContent = "";
// Prepare rate.
const productName = document.querySelector('#product-rate-product-
select').value;
const rate = document.querySelector('#product-rate-product-rate-
input').value;
const craft = recipes[productName];
if (
craft == undefined ||
rate <= 0
) {
return;
}
// Show on UI.
const sortedRequirements = SortObject(requirements);
for (const requirement in sortedRequirements) {
const recipeRequirement = recipes[requirement];
if (recipeRequirement == undefined) {
continue;
}
content.appendChild(requirementContainer);
}
}
if (requirements[requirement] == undefined) {
requirements[requirement] = 0;
}
function SortObject(obj) {
return Object.keys(obj).sort().reduce(function (result, key) {
result[key] = obj[key];
return result;
}, {});
}
LoadTownGuideEuSupport();
LoadStagesSupport();
LoadNewLayoutButton();
canUpdateLocalLayout = true;
if (layout) {
document.querySelector('#importexport').value =
JSON.stringify(layout);
importGrid();
} else {
LoadStages();
}
RightClickRemoveBuilding();
showCategoryMenu(selectedCategory);
}
});
loadAfterLayoutContainerObserver.observe(document, {attributes: true,
childList: true , subtree: true});
function AddScript(content) {
let scriptElement = document.createElement('script');
scriptElement.type = 'text/javascript';
scriptElement.textContent = content;
document.getElementsByTagName('head')[0].appendChild(scriptElement);
}
// CSS
AddCss('.tileinfo', 'overflow-y: scroll;');
AddCss('.cell', 'position: relative; white-space: nowrap; overflow: hidden;');
AddCss('.proximity-display', 'position: absolute; font-size: 16px; color:
white; text-shadow: black 0 0 3px; top: 0; left: 0; pointer-events: none;');
AddCss('.reciperow', 'grid-template-columns: 1fr 8fr 2fr!important; grid-
template-rows: 1fr 1fr auto!important; margin-top: 5px;');
AddCss('.recipeheader', 'position: relative; line-height: 18px;');
AddCss('.recipecraft', 'height:100%; margin: auto 2px auto 5px;');
AddCss('.recipetitle', 'position: absolute; width: 80%; white-space: nowrap;');
AddCss('.recipeimage', 'width: auto; height: 23px; vertical-align: middle;');
AddCss('.recipetimer', 'grid-column: 2 / 4;');
AddCss('.cellcraft', 'position: absolute; z-index: 1; height: 24px; width:
24px; object-fit: contain; left: -2px; bottom: 0; -webkit-filter: drop-shadow(1px
1px 4px #666); filter: drop-shadow(1px 1px 4px #666);');
AddCss('.categories','grid-template-columns: repeat(8, 1fr)!important;');
AddCss('.buildingmenu','grid-template-rows: 30px 30px 6fr!important;');
AddCss('#addon-version','position: absolute; right: 0; bottom: 0; padding: 5px;
pointer-events: none;');
AddCss('#town-guide-eu-container input', 'margin-right: 4px;');
AddCss('#stages-body div.stage, #stage-control-container div, #add-stage-
container div', 'display: inline-block; padding: 0px 8px; margin: 1px; font-size:
14px; font-weight: 400; line-height: 1.42857143; text-align: center; white-space:
nowrap; vertical-align: middle; -ms-touch-action: manipulation; touch-action:
manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -
ms-user-select: none; user-select: none; background-image: none; border: 1px solid
transparent; border-radius: 4px; text-decoration: none;color: #000; background-
color: #eee; border-color: #666;');
AddCss('#stages-body div.stage:hover, #stage-control-container div:hover, #add-
stage-container div:hover', 'background-color: #ddd;');
AddCss('#stages-body div.stage.active', 'background-color: #333; color:
#ccc;');
AddCss('#stage-info-container', 'height: 24px;');
AddCss('#stage-import-export-container input', 'margin-right: 4px;');
AddCss('#stage-control-container', 'text-align: right;');
AddCss('#stage-control-container div', 'width: 24px; height: 24px;padding:0;');
AddCss('#stage-delete, #add-stage-div', 'background-size: cover; background-
origin: content-box; padding: 2px!important; background-repeat: no-repeat!
important; width: 20px!important; height: 20px!important;');
AddCss('#stage-delete', 'background-image: url("https://cdn-icons-
png.flaticon.com/512/1214/1214428.png")!important;');
AddCss('#add-stage-container', 'display: inline-block;');
AddCss('#add-stage-name', 'width: 115px;');
AddCss('#add-stage-div', 'background-image: url("https://cdn-icons-
png.flaticon.com/512/2997/2997933.png")!important; width:16px!important;
height:16px!important;');
AddCss('.startingtemplatecontrols', 'position: relative;');
AddCss('#new-layout', 'position: absolute; right: 0; margin-right: 4px; color:
#fff; background-color: red; cursor: pointer;');
AddCss('#northborder, #eastborder, #southborder, #westborder', 'position:
relative; display:grid; color: #eeeeee; user-select: none; background-color: #ccc;
text-align: center; cursor: pointer;');
AddCss('#northborder i, #eastborder i, #southborder i, #westborder i',
'position: absolute;');
AddCss('#northborder i, #southborder i', 'left: 50%; transform: translate(-50%,
0)');
AddCss('#eastborder i, #westborder i', 'top: 50%;; transform: translate(0, -
50%); right: 0;');
AddCss('#northborder i', 'top: 0;');
AddCss('#southborder i', 'bottom: 0;');
AddCss('#northborder, #southborder','grid-template-columns: repeat(16, 1fr);');
AddCss('#eastborder, #westborder','grid-template-columns: repeat(16, 1fr);
align-items: end; writing-mode: vertical-rl;');
AddCss('#eastborder div, #westborder div','writing-mode: vertical-rl;');
AddCss('#eastborder div','transform: rotate(-90deg);');
AddCss('#westborder div','transform: rotate(90deg);');
AddCss('#northborder','align-items: end;');
AddCss('#southborder','align-items: start;');
AddCss('#westborder','transform: rotate(180deg);');
AddCss('.river','background-color: blue!important;');
AddCss('.ocean','background-color: cornflowerblue!important;');
AddCss('.mountains','background-color: brown!important;');
AddCss('.desert','background-color: #f3b48b!important;');
AddCss('.forest','background-color: #85bf85!important;');
AddCss('.categorybutton.selected', 'border: 0; filter:brightness(150%);');
AddCss('.buildings', 'grid-template-rows: repeat(6, 1fr)!important;');
AddCss('.category', 'overflow-y: scroll; background-color: lightblue;');
AddCss('#search-building-container', 'display: grid;');
AddCss('#search-building', 'padding: 0 5px; z-index: 0;');
AddCss('#All', 'display: none;');
AddCss('.buildingmenubutton', 'border: 2px solid transparent;');
AddCss('.selectedbuildingmenubutton', 'border: 2px solid black;');
AddCss('.maincontainer', 'grid-template-columns: 240px 780px 280px!important;
white-space: nowrap;');
AddCss('.gameboard', 'grid-template-columns: 1fr 20fr 1fr!important; grid-
template-rows: 1fr 20fr 1fr!important;');
AddCss('.eastborder div, .southborder div, .westborder div, .northborder div',
'pointer-events: none;');
AddCss('.ingredient', 'overflow: hidden;');
AddCss('.recipes', 'grid-template-rows: auto!important;');
AddCss('#info-container', 'display: grid; grid-area: 1 / 3 / 5 / 3; grid-
template-rows: 30px auto;');
AddCss('#tab-container', 'display: grid; grid-template-columns: repeat(3,
1fr);');
AddCss('#tab-container div', 'color: #52a5d2; background-color: #335f8b; text-
align: center; line-height: 30px; cursor: pointer;');
AddCss('.title', 'text-align: center;');
AddCss('#calculation-container', 'padding: 4px 0;');
AddCss('#product-rate-product', 'padding: 0 32px;');
AddCss('#product-rate-product-select', 'width: 100%;');
AddCss('#product-rate-product-rate', 'text-align: center;');
AddCss('#town-guide-eu-container', 'grid-area: 7 / 1 / 7 / 1;');
AddCss('#stages-container', 'grid-area: 7 / 2 / 7 / 2;');
AddCss('#div-display-txtArea', 'margin: 0!important;');
AddCss('#info-content-container', 'overflow: hidden;');
AddCss('#product-rate-content', 'overflow: auto; margin: 4px;');
AddCss('#product-rate-content .recipeimage', 'margin-left: auto;');
AddCss('#product-rate-content .ingredient', 'display: grid; grid-template-
columns: 2fr 6fr 3fr;');
AddCss('.product-rate-name', 'overflow: hidden;');
AddCss('.product-rate-value', 'padding: 0 32px 0 4px; text-align: right;');
AddCss('#product-rate-container', 'display: grid; height: 100%; grid-template-
rows: 22px 22px 22px;');
AddCss('#tab-container div.selected', 'border: 0; color: #335f8b; background-
color: lightblue;');
AddCss('#setup-container', 'padding: 0 8px');
AddCss('.setup-title', 'margin-top: 4px;');
AddCss('#setup-container-content-container', 'display: grid; grid-template-
rows: 44px auto;');
function LoadBuildingSearch() {
const searchBuildingContainer = document.createElement("div");
searchBuildingContainer.id = "search-building-container";
const searchBuildingInput = document.createElement("input");
searchBuildingInput.id = "search-building";
searchBuildingInput.type = "text";
searchBuildingInput.placeholder = "Search Building";
searchBuildingInput.addEventListener("keyup", (event) => {
if (event.isComposing || event.keyCode === 229) {
return;
}
searchBuilding();
});
searchBuildingInput.addEventListener("blur", (event) => {
if (event.isComposing || event.keyCode === 229) {
return;
}
searchBuilding();
});
searchBuildingContainer.appendChild(searchBuildingInput);
const categoriesClass = document.querySelector(".categories");
categoriesClass.parentNode.insertBefore(searchBuildingContainer,
categoriesClass.nextSibling);
}
function searchBuilding() {
const searchBuildingText = document.querySelector("#search-
building").value.trim();
if (searchBuildingText.length > 0) {
showCategoryMenu("All");
const buildingElements = document.querySelectorAll("#All-menu div");
for (const buildingElement of buildingElements) {
let display = "none";
if (new RegExp(searchBuildingText,
"i").test(buildingElement.title)) {
display = "";
}
buildingElement.style.display = display;
}
} else {
showCategoryMenu(selectedCategory);
}
}
function LoadNewLayoutButton() {
const newLayoutButton = document.createElement('input');
newLayoutButton.id = 'new-layout';
newLayoutButton.type = 'button';
newLayoutButton.value = 'RESET';
newLayoutButton.onclick = function() {
if (confirm("This will reset local cache layout, and start as a new
layout. Are you sure?") == true) {
NewLayout();
}
}
document.querySelector('.startingtemplatecontrols').appendChild(newLayoutButton);
}
function NewLayout() {
grid = {
biome: "Forest",
name: "4x4",
defaultType: "Grass",
grid: [],
northborder: "none",
southborder: "none",
eastborder: "none",
westborder: "none",
stages: [],
stageIndex: null,
filename: defaultTownGuideFilename,
};
exportGrid = {
biome: "Forest",
name: "export",
defaultType: "Grass",
grid: [],
northborder: "none",
southborder: "none",
eastborder: "none",
westborder: "none",
stages: [],
stageIndex: null,
filename: defaultTownGuideFilename,
};
templateGrid = {
biome: "Forest",
name: "export",
defaultType: "Grass",
grid: [],
northborder: "none",
southborder: "none",
eastborder: "none",
westborder: "none",
stages: [],
stageIndex: null,
filename: defaultTownGuideFilename,
};
overlayMode = "none";
dimension = 16;
selected = "";
selectedBuilding = "";
biome = "Forest";
direction = "north";
document.querySelector('#biomes').value = biome;
document.querySelector('#directons').value = direction;
initialize();
renderBorders();
ClearArray(stages);
LoadStages();
updateExportGrid();
importGrid();
RightClickRemoveBuilding();
}
function LoadStagesSupport() {
const stagesContainer = document.createElement('div');
stagesContainer.id = 'stages-container';
// stages header
const header = document.createElement('div');
header.id = 'stages-header';
header.textContent = 'Stages';
stagesContainer.appendChild(header);
// stages body
const stageBody = document.createElement('div');
stageBody.id = 'stages-body';
stagesContainer.appendChild(stageBody);
const mainContainer = document.querySelector('.maincontainer');
mainContainer.appendChild(stagesContainer);
const stageInfoContainer = document.createElement('div');
stageInfoContainer.id = 'stage-info-container';
// stage-manage-container
const stageManageContainer = document.createElement('div');
stageManageContainer.id = 'stage-manage-container';
stageManageContainer.appendChild(stageControlContainer);
stageInfoContainer.appendChild(stageManageContainer);
// stage-import-export-container
const stageImportExportContainer = document.createElement('div');
stageImportExportContainer.id = 'stage-import-export-container';
stageInfoContainer.appendChild(stageImportExportContainer);
document.querySelector('.tileinfobody').appendChild(stageInfoContainer);
HideStageInfo();
}
function StageCopyToClipboard() {
const copyText = document.querySelector("#stage-import-export");
copyText.select();
// copyText.setSelectionRange(0, 99999); /*For mobile devices*/
document.execCommand("copy");
}
function StageImportGrid() {
const index = GetActiveStageIndex();
const importExport = document.querySelector("#stage-import-export").value;
stages[index].grid = JSON.parse(importExport);
SetGridByStage(stages[index]);
renderGrid();
}
function MoveActiveStageUp() {
const index = GetActiveStageIndex();
if (
index >= 0
&& index != 0
) {
const previousIndex = index - 1;
const previousStage = stages[previousIndex];
const currentStage = stages[index];
stages[previousIndex] = currentStage;
stages[index] = previousStage;
LoadStages();
SetActiveStage(previousIndex);
}
}
function MoveActiveStageDown() {
const index = GetActiveStageIndex();
if (
index >= 0
&& index < stages.length - 1
) {
const nextIndex = index + 1;
const nextStage = stages[nextIndex];
const currentStage = stages[index];
stages[nextIndex] = currentStage;
stages[index] = nextStage;
LoadStages();
SetActiveStage(nextIndex);
}
}
function DeleteActiveStage() {
const index = GetActiveStageIndex();
if (
index >= 0
&& index <= stages.length - 1
) {
stages.splice(index,1);
LoadStages();
const newLastIndex = stages.length - 1;
const newIndex = index < newLastIndex ? index : newLastIndex;
SetActiveStage(newIndex);
}
}
function LoadStages() {
const stageBody = document.querySelector('#stages-body');
ClearChildren(stageBody);
if (stages.length <= 0) {
// initialize stage.
SetStageData(0, "First", grid.grid);
}
stages.forEach((stage, index) => {
const stageDiv = document.createElement('div');
stageDiv.id = 'stage-' + index;
stageDiv.classList.add('stage');
stageDiv.textContent = stage.name;
stageDiv.onclick = function() {
SetActiveStage(index);
};
stageBody.appendChild(stageDiv);
});
// Add new stage
const addStageContainer = document.createElement('div');
addStageContainer.id = 'add-stage-container';
stageBody.appendChild(addStageContainer);
SetActiveStage(stages.length - 1);
updateExportGrid();
}
function AddNewStage() {
const name = document.querySelector('#add-stage-name').value;
if (name.length > 0) {
const index = GetActiveStageIndex();
const stage = {...stages[index]};
const newIndex = index + 1;
stage.name = name;
stages.splice(newIndex, 0, stage);
LoadStages();
SetActiveStage(newIndex);
}
}
function UpdateActiveStageName(name) {
if (name.length > 0) {
const index = GetActiveStageIndex();
stages[index].name = name;
LoadStages();
SetActiveStage(index);
}
}
function HideStageInfo() {
document.querySelector('#stage-info-container').style.display = "none";
}
function ShowStageInfo() {
document.querySelector('#stage-info-container').style.display = "";
}
function GetActiveStageIndex() {
let activeStageDiv = null;
let index = 0;
if (activeStageDiv) {
index = parseInt(activeStageDiv.id.replace('stage-', ''));
} else {
index = grid.stageIndex;
}
return index;
}
function SetActiveStage(index) {
const stageDivs = document.querySelectorAll('div.stage');
stageDivs.forEach(div => {
div.classList.remove('active');
});
if (
index <= lastStageIndex
&& index >= 0
) {
if (document.querySelector('#stage-' + index)) {
document.querySelector('#stage-' + index).classList.add('active');
}
ShowStageInfo();
document.querySelector('#stage-name').value = stages[index].name;
document.querySelector('#stage-import-export').value =
JSON.stringify(stages[index].grid);
if (
index != grid.stageIndex
|| index == lastStageIndex
) {
grid.stageIndex = index;
SetGridByStage(stages[index]);
renderGrid();
}
}
}
function SetGridByStage(stage) {
grid.grid = stage.grid.map((cell) => {
let gridCell = {
type: cell.type,
edgeSatisfied: true,
};
if (cell.craft) {
gridCell.craft = cell.craft;
}
return gridCell;
});
}
function SetStageByGrid() {
const index = GetActiveStageIndex();
if (index >= 0) {
stages[index].grid = grid.grid.map((cell) => {
let gridCell = {
type: cell.type,
};
if (cell.craft) {
gridCell.craft = cell.craft;
}
return gridCell;
});
}
}
function ClearChildren(element) {
element.replaceChildren();
}
function ClearArray(array) {
array.length = 0;
}
const borders = [
"northborder",
"eastborder",
"southborder",
"westborder"
];
function LoadEdgeNumbering() {
for (const border of borders) {
const borderElement = document.querySelector("#" + border);
if (border != "westborder") {
for (let i = 1; i <= dimension; i++) {
const div = document.createElement("div");
div.textContent = i;
borderElement.appendChild(div);
}
} else {
for (let i = dimension; i > 0; i--) {
const div = document.createElement("div");
div.textContent = i;
borderElement.appendChild(div);
}
}
}
}
function LoadTownGuideEuSupport() {
const townGuideEuContainer = document.createElement('div');
townGuideEuContainer.id = 'town-guide-eu-container';
// town-guide.eu header
const header = document.createElement('div');
header.id = 'town-guide-eu-header';
header.textContent = 'town-guide.eu Compatible';
townGuideEuContainer.appendChild(header);
// town-guide.eu filename
const inputFilename = document.createElement('input');
inputFilename.id = "town-guide-eu-filename";
inputFilename.type = "text";
inputFilename.placeholder = "Filename";
inputFilename.value = defaultTownGuideFilename;
inputFilename.style.width = "115px";
inputFilename.onchange = function() {
grid.filename = this.value;
};
townGuideEuContainer.appendChild(inputFilename);
// town-guide.eu save
const inputSave = document.createElement('input');
inputSave.id = "town-guide-eu-save";
inputSave.type = "button";
inputSave.value = "Save";
inputSave.onclick = function () {
const filename = document.querySelector('#town-guide-eu-
filename').value;
const layout = GetTownGuideEuLayout(filename);
const blob = new Blob(
[JSON.stringify(layout)],
{ type: "text/plain;charset=utf-8" }
);
const url = URL.createObjectURL(blob);
const file = document.createElement(`a`);
file.download = filename + ".txt";
file.href = url;
document.body.appendChild(file);
file.click();
file.remove();
URL.revokeObjectURL(url);
};
townGuideEuContainer.appendChild(inputSave);
// town-guide.eu load
const fileLoad = document.createElement('input');
fileLoad.id = "town-guide-eu-file-load";
fileLoad.type = "file";
fileLoad.accept = ".txt";
fileLoad.style.display = "none";
fileLoad.addEventListener('change', (event) => {
const fileList = event.target.files;
ReadTextFile(fileList[0]);
event.target.value = "";
});
const inputLoad = document.createElement('input');
inputLoad.id = "town-guide-eu-load";
inputLoad.type = "button";
inputLoad.value = "Load";
inputLoad.onclick = function () {
fileLoad.click();
};
townGuideEuContainer.appendChild(inputLoad);
const mainContainer = document.querySelector('.maincontainer');
mainContainer.appendChild(townGuideEuContainer);
}
function ReadTextFile(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('text/')) {
alert('File is not a text.', file.type, file);
console.log('File is not a text.', file.type, file);
return;
}
function GetTownGuideEuLayout(fileName) {
const validTownGuideEuBiomes = ["forest", "plains", "desert"];
const biome = document.querySelector("#biomes").value.toLowerCase();
// Default layout structure
const layout = {
"borders": {
"North": GetTownGuideEuBorderType(grid.northborder),
"East": GetTownGuideEuBorderType(grid.eastborder),
"South": GetTownGuideEuBorderType(grid.southborder),
"West": GetTownGuideEuBorderType(grid.westborder),
},
"biome": validTownGuideEuBiomes.includes(biome) ? biome : "forest",
"name": fileName,
"stages": [],
"stageIndex": grid.stageIndex,
"filename": grid.filename,
};
return layout
}
function CapitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function GetTownGuideEuBoard(stage) {
const grid = stage.grid;
const board = {};
Object.keys(grid).forEach(key => {
const z = Math.floor(key / 16);
const x = key - (z * 16);
const boardKey = "(" + x + ".0,0.0," + z + ".0)";
board[boardKey] = { "type": grid[key].type };
if (grid[key].craft) {
board[boardKey].data = {
"craft": grid[key].craft,
"state": "Complete"
};
}
});
return board;
}
function GetTownGuideEuBorderType(visualizerBorder) {
let border = visualizerBorder;
if (border == "none") {
border = "OpenWorld";
}
return ["none","Desert","Forest"].includes(visualizerBorder) == false ?
visualizerBorder : "OpenWorld";
}
function GetVisualizerBorderType(townGuideEuBorder) {
return townGuideEuBorder == "OpenWorld" ? "none" : townGuideEuBorder;
}
function SetFromTownGuideEu(townGuideEuLayoutObject) {
grid.biome = townGuideEuLayoutObject.biome ?
CapitalizeFirstLetter(townGuideEuLayoutObject.biome) : "Forest";
grid.northborder =
GetVisualizerBorderType(townGuideEuLayoutObject.borders.North);
grid.southborder =
GetVisualizerBorderType(townGuideEuLayoutObject.borders.South);
grid.eastborder =
GetVisualizerBorderType(townGuideEuLayoutObject.borders.East);
grid.westborder =
GetVisualizerBorderType(townGuideEuLayoutObject.borders.West);
grid.defaultType = "Grass";
grid.grid = templateGrid.grid;
grid.filename = townGuideEuLayoutObject.name;
document.querySelector('#town-guide-eu-filename').value = grid.filename;
ClearArray(stages);
const layoutStages = townGuideEuLayoutObject.stages;
renderBorders();
LoadStages();
}
function getNftIcon(nft) {
return getFullURL(nfts[nft]?.FileUrl);
}
// SCRIPT
AddFunction('getCraftIcon(craft)',
"return getFullURL(recipes[craft]?.FileUrl);"
);
AddFunction('setCellCraft(cellIndex, craft)',
"grid.grid[cellIndex].craft = craft;" +
"renderCellCraft(cellIndex);"
);
AddFunction('setRecipeCellCraft(cellIndex, building, craft)',
"const selectedCraft = document.querySelector('input[name=\"recipe_\' +
building + \'\"]:checked');" +
"let cellCraft = undefined;" +
"if (selectedCraft) {" +
"cellCraft = craft;" +
"}" +
"setCellCraft(cellIndex, cellCraft);"
);
AddFunction('renderCellCraft(cellIndex)',
"const cellElement = document.querySelector('#cell' + cellIndex);" +
"if (cellElement) {" +
"const cellImages = cellElement.querySelectorAll('img.cellcraft');" +
"if (cellImages.length > 0) {" +
"cellImages.forEach(element => {" +
"element.remove();" +
"})" +
"}" +
"const cell = grid.grid[cellIndex];" +
"if (cell.craft) {" +
"let cellCraft = document.createElement('img');" +
"cellCraft.classList.add('cellcraft');" +
"cellCraft.src = getCraftIcon(cell.craft);" +
"cellElement.appendChild(cellCraft);" +
"}" +
"}" +
""
);
AddFunction('removeSpecialCharacter(string)',
"return string.replace(/'/g, '').replace(/\"/g, '');"
);
AddScript('let selectedCraft = ""; let craftChecked = false;');
AddFunction('checkCraft(input)',
"if (" +
"input.value == selectedCraft && " +
"craftChecked" +
") {" +
"input.checked = false;" +
"craftChecked = false;" +
"var event = new Event('change');" +
"input.dispatchEvent(event);" +
"return;" +
"}" +
"selectedCraft = input.value;" +
"craftChecked = true;"
);
function IsEmptyObject(object) {
return object
&& Object.keys(object).length === 0
&& Object.getPrototypeOf(object) === Object.prototype
}
function EditVisualizer() {
copyToClipboard = function () {
const copyText = document.querySelector('#importexport');
copyText.select();
// copyText.setSelectionRange(0, 999999);
document.execCommand("copy");
}
// Overwrite selectBorder
selectBorder = function (border) {
var index = newBorderTypes.indexOf(grid[border]);
index++;
if (index > newBorderTypes.length - 1) index = 0;
var newBorderType = newBorderTypes[index];
grid[border] = newBorderType;
renderBorders();
renderGrid();
// renderStats();
updateExportGrid();
}
// Default maps
maps = {
"Forest": {
"north": [{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Builder_House"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Wood_Shed"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Dirt_Road"},{"type":"Silo"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Rock"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Wheat_Field"},{"type":"Wheat_Field"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Farm_House"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Well"},{"type":"Storehouse"},{"type":"Tree"},{"type":"Grass"},
{"type":"Rock"},{"type":"Pond"},{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},
{"type":"Pond"},{"type":"Rock"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Pond"},
{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},{"type":"Rock"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"}],
"east": [{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Rock"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Farm_House"},
{"type":"Silo"},{"type":"Wood_Shed"},{"type":"Dirt_Road"},{"type":"Builder_House"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Rock"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Storehouse"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Trade_Depot"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Well"},
{"type":"Dirt_Road"},{"type":"Marsh"},{"type":"Grass"},{"type":"Dirt_Road"},
{"type":"Fuel_Storage"},{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},
{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Pond"},{"type":"Marsh"},{"type":"Dirt_Road"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Rock"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Wheat_Field"},{"type":"Wheat_Field"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Dirt_Road"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Rock"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"}],
"south": [{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Rock"},{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Rock"},{"type":"Pond"},{"type":"Pond"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Rock"},{"type":"Grass"},{"type":"Tree"},
{"type":"Rock"},{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Pond"},{"type":"Marsh"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Wheat_Field"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Wheat_Field"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Farm_House"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Rock"},{"type":"Marsh"},{"type":"Pond"},
{"type":"Dirt_Road"},{"type":"Well"},{"type":"Storehouse"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Marsh"},{"type":"Dirt_Road"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Dirt_Road"},{"type":"Silo"},{"type":"Wood_Shed"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Grass"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Builder_House"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"}],
"west": [{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Rock"},{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Farm_House"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Pond"},{"type":"Marsh"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Wood_Shed"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Storehouse"},{"type":"Grass"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Fuel_Storage"},{"type":"Dirt_Road"},
{"type":"Silo"},{"type":"Grass"},{"type":"Grass"},{"type":"Dirt_Road"},
{"type":"Well"},{"type":"Grass"},{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},
{"type":"Grass"},{"type":"Rock"},{"type":"Pond"},{"type":"Pond"},{"type":"Marsh"},
{"type":"Trade_Depot"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Grass"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},
{"type":"Builder_House"},{"type":"Dirt_Road"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Pond"},{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Grass"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Dirt_Road"},{"type":"Tree"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Marsh"},{"type":"Grass"},
{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},{"type":"Pond"},{"type":"Pond"},
{"type":"Marsh"},{"type":"Tree"},{"type":"Marsh"},{"type":"Pond"},{"type":"Pond"},
{"type":"Marsh"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Rock"},{"type":"Pond"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Marsh"},{"type":"Marsh"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},{"type":"Marsh"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Grass"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"}],
},
"Plains": {
"north": [{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Builder_House"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Wood_Shed"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Dirt_Road"},
{"type":"Silo"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Rock"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Dirt_Road"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Farm_House"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Grass"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},{"type":"Pond"},
{"type":"Well"},{"type":"Storehouse"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Rock"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Tree"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},{"type":"Rock"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Tree"},{"type":"Pond"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Grass"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Rock"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},
{"type":"Rock"},{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"}],
"east": [{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Rock"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Tree"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Farm_House"},{"type":"Silo"},{"type":"Wood_Shed"},{"type":"Dirt_Road"},
{"type":"Builder_House"},{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},
{"type":"Rock"},{"type":"Grass"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Storehouse"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Trade_Depot"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Tree"},{"type":"Pond"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Well"},{"type":"Dirt_Road"},{"type":"Grass"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Fuel_Storage"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Pond"},{"type":"Grass"},
{"type":"Dirt_Road"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Scrub"},{"type":"Rock"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Grass"},{"type":"Scrub"},
{"type":"Dirt_Road"},{"type":"Tree"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Rock"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Tree"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"}],
"south": [{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Rock"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},{"type":"Tree"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},{"type":"Tree"},
{"type":"Rock"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Rock"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},{"type":"Pond"},
{"type":"Tree"},{"type":"Grass"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Tree"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Wheat_Field"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Scrub"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Wheat_Field"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Farm_House"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Rock"},
{"type":"Grass"},{"type":"Pond"},{"type":"Dirt_Road"},{"type":"Well"},
{"type":"Storehouse"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Dirt_Road"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Silo"},
{"type":"Wood_Shed"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Builder_House"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"}],
"west": [{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Rock"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Farm_House"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Wood_Shed"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Storehouse"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Fuel_Storage"},{"type":"Dirt_Road"},{"type":"Silo"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Well"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Rock"},{"type":"Tree"},{"type":"Tree"},{"type":"Grass"},
{"type":"Trade_Depot"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Builder_House"},{"type":"Dirt_Road"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Pond"},{"type":"Wheat_Field"},
{"type":"Wheat_Field"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Dirt_Road"},
{"type":"Scrub"},{"type":"Grass"},{"type":"Grass"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Tree"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Tree"},{"type":"Pond"},{"type":"Grass"},{"type":"Scrub"},
{"type":"Grass"},{"type":"Tree"},{"type":"Tree"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Rock"},{"type":"Tree"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Grass"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Pasture"},
{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Pasture"},{"type":"Pasture"},{"type":"Scrub"},
{"type":"Pasture"}],
},
"Desert": {
"north": [{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Builder_House"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Wood_Shed"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Dirt_Road"},
{"type":"Silo"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Rock"},{"type":"Arid"},{"type":"Arid"},
{"type":"Dirt_Road"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Farm_House"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Grass"},{"type":"Pond"},{"type":"Well"},{"type":"Storehouse"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Rock"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Pasture"},
{"type":"Grass"},{"type":"Pasture"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},{"type":"Rock"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Oil_Seep"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Rock"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"}],
"east": [{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Rock"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Dirt_Road"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Farm_House"},{"type":"Silo"},
{"type":"Wood_Shed"},{"type":"Dirt_Road"},{"type":"Builder_House"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},{"type":"Oil_Seep"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Storehouse"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Trade_Depot"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Cactus"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Well"},{"type":"Dirt_Road"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Dirt_Road"},{"type":"Fuel_Storage"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Dirt_Road"},{"type":"Pond"},{"type":"Grass"},{"type":"Pasture"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Rock"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Grass"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Rock"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"}],
"south": [{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Rock"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Oil_Seep"},{"type":"Cactus"},{"type":"Cactus"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},{"type":"Rock"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Rock"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Wheat_Field"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Pasture"},{"type":"Wheat_Field"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Farm_House"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Rock"},{"type":"Grass"},
{"type":"Pond"},{"type":"Dirt_Road"},{"type":"Well"},{"type":"Storehouse"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Grass"},{"type":"Dirt_Road"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Pasture"},{"type":"Dirt_Road"},{"type":"Silo"},{"type":"Wood_Shed"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Builder_House"},{"type":"Trade_Depot"},
{"type":"Fuel_Storage"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"}],
"west": [{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Rock"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Farm_House"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Dirt_Road"},{"type":"Wood_Shed"},{"type":"Arid"},{"type":"Arid"},
{"type":"Dirt_Road"},{"type":"Storehouse"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Fuel_Storage"},{"type":"Dirt_Road"},
{"type":"Silo"},{"type":"Arid"},{"type":"Arid"},{"type":"Dirt_Road"},
{"type":"Well"},{"type":"Arid"},{"type":"Arid"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Oil_Seep"},{"type":"Cactus"},{"type":"Cactus"},
{"type":"Arid"},{"type":"Trade_Depot"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},
{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Dirt_Road"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Cactus"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Builder_House"},{"type":"Dirt_Road"},{"type":"Arid"},{"type":"Grass"},
{"type":"Pond"},{"type":"Wheat_Field"},{"type":"Wheat_Field"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Dirt_Road"},{"type":"Scrub"},{"type":"Pasture"},{"type":"Grass"},
{"type":"Pasture"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Cactus"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Cactus"},{"type":"Cactus"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Cactus"},
{"type":"Cactus"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Rock"},{"type":"Cactus"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Rock"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"},{"type":"Arid"},
{"type":"Arid"},{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Scrub"},
{"type":"Arid"},{"type":"Arid"},{"type":"Scrub"},{"type":"Scrub"},{"type":"Arid"},
{"type":"Arid"},{"type":"Scrub"},{"type":"Arid"}],
},
};
// Overwrite getGridFromMap
getGridFromMap = function(biome, direction) {
return maps[biome][direction];
}
// Overwrite getFullURL
getFullURL = function (assetPath) {
let url = '';
if (assetPath) {
url = `https://townstar.sandbox-games.com/${assetPath}`;
if (assetPath.substring(0,4) == "http") {
url = assetPath;
}
}
return url;
}
// Overwrite renderBorders
renderBorders = function () {
borders.forEach((bdr) => {
templateGrid[bdr] = grid[bdr];
const borderElement = document.querySelector('#' + bdr);
const borderBiome = grid[bdr];
borderElement.setAttribute("class", "");
borderElement.classList.add(bdr, borderBiome);
borderElement.querySelector('i').textContent = borderBiome;
});
}
// Overwrite hasEdge
hasEdge = function (edgeType, i) {
if (
//check borders
(edgeType == "Waterway" &&
(isBorderTile("Ocean", i) || isBorderTile("River", i))) ||
(edgeType == "Mountains" && isBorderTile("Mountains", i)) ||
(
(edgeType == "OpenWorld" || edgeType == "Town") &&
(
isBorderTile("none", i) ||
isBorderTile("Desert", i) ||
isBorderTile("Forest", i)
)
) ||
//check NSEW
(!isOutOfBounds(i - dimension) &&
isEdgeMatch(edgeType, grid.grid[i - dimension].type)) ||
(!isOutOfBounds(i + dimension) &&
isEdgeMatch(edgeType, grid.grid[i + dimension].type)) ||
(!isOutOfBounds(i - 1) &&
Math.floor(i / dimension) == Math.floor((i - 1) / dimension) &&
isEdgeMatch(edgeType, grid.grid[i - 1].type)) ||
(!isOutOfBounds(i + 1) &&
Math.floor(i / dimension) == Math.floor((i + 1) / dimension) &&
isEdgeMatch(edgeType, grid.grid[i + 1].type))
) {
return true;
}
return false;
}
// Overwrite getBorderProperty
getBorderProperty = function (borderType) {
switch (borderType) {
case "River":
return "Water";
case "Ocean":
return "Salty";
case "Mountains":
return "Shady";
case "Desert":
return "Sandy";
}
}
// Overwrite calculateBorderEffects
calculateBorderEffects = function () {
const borderProximity = {
"River": {
"Water": [5, 4, 3, 2, 1],
},
"Ocean": {
"Salty": [3, 2, 1],
},
"Mountains": {
"Shady": [5, 4, 3, 2, 1],
},
"Desert": {
"Sandy": [3, 2, 1],
},
};
grid.grid[index][proximity] =
grid.grid[index][proximity] + proximityValue;
}
}
}
}
}
}
// Overwrite updateBiome
updateBiome = function (selection) {
biome = selection.value;
templateGrid.biome = biome;
loadTemplateGrid();
renderGrid();
}
// Overwrite loadTemplateGrid
loadTemplateGrid = function () {
grid.biome = templateGrid.biome;
grid.northborder = templateGrid.northborder;
grid.southborder = templateGrid.southborder;
grid.eastborder = templateGrid.eastborder;
grid.westborder = templateGrid.westborder;
if (biome == "none") {
clearGrid();
} else {
templateGrid.grid = getGridFromMap(biome, direction);
setDefaultType();
grid.grid = templateGrid.grid.map((cell) => {
return {
type: cell.type,
edgeSatisfied: true,
};
});
}
updateExportGrid();
}
function calculateBiomeEffects() {
const biomeProximity = {
"Desert": {
"Sandy": [3]
}
}
if (Object.keys(biomeProximity).includes(grid.biome)) {
const proximities = biomeProximity[grid.biome];
for (const proximity in proximities) {
const proximityRange = biomeProximity[grid.biome]
[proximity].length;
for (let i = 0; i < proximityRange; i++) {
const proximityValue = biomeProximity[grid.biome]
[proximity][i];
for (let index = 0, n = grid.grid.length; index < n; index+
+) {
grid.grid[index][proximity] = grid.grid[index]
[proximity] + proximityValue;
}
}
}
}
}
// Overwrite renderGrid
renderGrid = function (type) {
if (canUpdateLocalLayout) {
resetAllPassive();
calculateBiomeEffects();
calculateBorderEffects();
calculatePassiveEffects();
calculateEdgeRequirements();
const pageGrid = $(".gamegrid");
for (let i = 0, n = grid.grid.length; i < n; i++) {
const cell = grid.grid[i];
const classes = getClasses(i);
const pageGridChild = pageGrid.children().eq(i);
pageGridChild.html("");
pageGridChild.attr("class", classes);
const imageElement = document.createElement('img');
imageElement.src = getTileIcon(cell.type);
pageGridChild.append(imageElement);
setIconTitle(pageGridChild, cell);
setCellCraft(i, cell.craft);
}
updateExportGrid();
DisplayProximity();
}
};
// Overwrite selectCell
selectCell = function (cell) {
HideStageInfo();
if (selected) document.querySelector("#" +
selected).classList.remove("selected");
selected = cell.id;
if (selectedBuilding != "") placeTile(selectedBuilding);
cell.classList.add("selected");
renderStats();
// renderGrid();
}
// Overwrite updateExportGrid
updateExportGrid = function () {
if (canUpdateLocalLayout) {
exportGrid.biome = grid.biome;
exportGrid.northborder = grid.northborder;
exportGrid.southborder = grid.southborder;
exportGrid.eastborder = grid.eastborder;
exportGrid.westborder = grid.westborder;
exportGrid.stageIndex = GetActiveStageIndex();
exportGrid.filename = grid.filename;
SetStageByGrid();
exportGrid.stages = stages;
document.querySelector("#importexport").value =
JSON.stringify(exportGrid);
GM_setValue(localLayoutName, exportGrid);
}
}
// Overwrite importGrid
importGrid = function () {
const importExport = document.querySelector('#importexport');
if (importExport.value != "") {
const importedGrid = JSON.parse(importExport.value);
grid.biome = importedGrid.biome? importedGrid.biome : "Forest";
document.querySelector("#biomes").value = grid.biome;
grid.northborder = importedGrid.northborder;
grid.southborder = importedGrid.southborder;
grid.eastborder = importedGrid.eastborder;
grid.westborder = importedGrid.westborder;
renderBorders();
grid.filename = importedGrid.filename;
// null will force later SetActiveStage.
grid.stageIndex = null;
ClearArray(stages);
if (
importedGrid.stages
&& importedGrid.stages.length > 0
) {
if (importedGrid.stages.length)
grid.stageIndex = null;
importedGrid.stages.forEach((stage, index) => {
SetStageData(index, stage.name, stage.grid);
});
} else {
const filteredGrid = importedGrid.grid.map((cell) => {
let gridCell = {
type: ConvertCorrectionName(cell.type),
edgeSatisfied: true,
};
if (cell.craft) {
gridCell.craft = ConvertCorrectionName(cell.craft);
}
return gridCell;
});
grid.grid = filteredGrid;
}
LoadStages();
if (importedGrid.stageIndex >= 0) {
SetActiveStage(importedGrid.stageIndex);
}
if (
grid.filename
&& grid.filename.length > 0
) {
document.querySelector('#town-guide-eu-filename').value =
grid.filename;
}
}
}
function removeSelectedBuildingClass() {
const buildings = document.querySelectorAll('.buildingmenubutton');
buildings.forEach((building) => {
building.classList.remove("selectedbuildingmenubutton");
});
}
function removeSelectedBuilding() {
removeSelectedBuildingClass();
selectedBuilding = "";
}
// Overwrite selectBuilding
selectBuilding = function (type) {
removeSelectedBuildingClass();
if (selectedBuilding != type) {
selectedBuilding = type;
const buildingTypes = document.querySelectorAll('[id="' +
removeSpecialCharacter(type) + '"]');
buildingTypes.forEach((buildingType) => {
buildingType.classList.add("selectedbuildingmenubutton");
});
if (type == "remove") {
document.querySelector('.buildingmenudeletebutton').classList.add("selectedbuilding
menubutton");
}
} else {
selectedBuilding = "";
}
}
// Overwrite renderBuildingMenu
renderBuildingMenu = function () {
const categories = [
"All",
"Farm",
"Ranch",
"Terrain",
"Industrial",
"Trade",
"Fishing",
"Jewelry",
"BlockChain",
];
const categoryClass = document.querySelector(".category");
const categoriesClass = document.querySelector(".categories");
categoryClass.textContent = "";
categoriesClass.textContent = "";
categories.forEach((category) => {
const isAllCategory = category == "All";
const categoryElement = document.createElement("div");
categoryElement.id = category;
categoryElement.classList.add("categorybutton");
categoryElement.onclick = function()
{ showCategoryMenu(category); };
categoryElement.title = category;
const categoryImage = document.createElement("img");
let categoryImageSrc = "./images/" + category + "-menu.png";
if (category === "All") {
categoryImageSrc =
"https://cdn-icons-png.flaticon.com/512/3875/3875172.png";
} else if (category === "Farm") {
categoryImageSrc = iconUrls.categoryFarm;
} else if (category === "Ranch") {
categoryImageSrc = iconUrls.categoryRanch;
} else if (category === "Terrain") {
categoryImageSrc = iconUrls.categoryTerrain;
} else if (category === "Industrial") {
categoryImageSrc = iconUrls.categoryIndustrial;
} else if (category === "Trade") {
categoryImageSrc = iconUrls.categoryTrade;
} else if (category === "Fishing") {
categoryImageSrc = iconUrls.categoryFishing;
} else if (category === "Jewelry") {
categoryImageSrc = iconUrls.categoryJewelry;
}
categoryImage.src = categoryImageSrc;
categoryElement.appendChild(categoryImage);
categoriesClass.appendChild(categoryElement);
// Overwrite clearGrid
clearGrid = function () {
for (let i = 0; i < 256; i++) {
grid.grid[i].type = grid.defaultType;
grid.grid[i].craft = undefined;
}
renderGrid();
}
const newPassiveTypes = [
"Water",
"Shady",
"Energy",
"Dirty",
"Salty",
"Crude_Oil",
"Barn_Feed",
"Barn_Water",
"Cabernet_Grapes",
"Chardonnay_Grapes",
"Chromium",
"Clay_Lump",
"Cocoa",
"Cold",
"Copper",
"Copper_Ore",
"Corn",
"Cotton",
"Eggs",
"Gold",
"Gold_Ore",
"Iron",
"Limestone",
"Nectar",
"Peppermint",
"PositiveOnlySalty",
"Pinot_Noir_Grapes",
"Pumpkin",
"Sandy",
"Seaweed",
"Silica",
"Silver",
"Silver_Ore",
"Strawberries",
"Sugarcane",
"Water_Drum",
"Wheat",
];
const newBorderTypes = [
"none",
"River",
"Ocean",
"Mountains",
"Desert",
"Forest"
];
// Overwrite getTileIcon
getTileIcon = function (type) {
let objectType = type;
let fileUrl = townstarObjects[objectType]?.FileUrl;
if (
["Grass","Marsh","Tree","Rock","Scrub","Arid","Cactus","Oil_Seep","Construction_Sit
e"].includes(objectType) == false &&
fileUrl == null
) {
objectType = "NO_IMAGE";
}
switch (objectType) {
case "Grass":
return "./images/grass-icon.png";
case "Marsh":
return "./images/marsh-icon.png";
case "Tree":
return "./images/tree-icon.png";
case "Rock":
return "./images/rock-icon.png";
case "Scrub":
return "./images/scrub-icon.png";
case "Arid":
return "./images/arid-icon.png";
case "Cactus":
return "./images/cactus-icon.png";
case "Oil_Seep":
return "./images/seep-icon.png";
case "Construction_Site":
return
"https://cdn-icons-png.flaticon.com/512/1012/1012232.png";
case "NO_IMAGE":
return
"https://cdn-icons-png.flaticon.com/512/3875/3875172.png";
default:
return getFullURL(fileUrl);
}
}
// Overwrite renderOverlaysOptions
renderOverlaysOptions = function () {
var optionsHtml = "<option value='none'>None</option>";
newPassiveTypes.forEach((type) => {
optionsHtml += `<option value="${type}">${type}</option>`;
});
$("#overlays").html(optionsHtml);
}
// Overwrite setIconTitle
setIconTitle = function (divCell, cell) {
var titleString = `${getPrettyName(cell.type)}`;
newPassiveTypes.forEach((type) => {
let proximityCount = cell[type];
if (proximityCount < 0) {
proximityCount = 0;
} else if (proximityCount > 99) {
proximityCount = 99;
}
if (proximityCount != undefined && proximityCount != 0) {
titleString += `\n${type}: ${cell[type]}`;
}
});
divCell.children().eq(0).attr("title", titleString);
}
// Overwrite getClasses
getClasses = function (index) {
const cell = grid.grid[index];
let classes = [];
classes.push("cell");
//classes.push(cell.type);
if (getCellIndex() == index) classes.push("selected");
newPassiveTypes.forEach((type) => {
classes.push(getPenaltyClass(type, cell));
});
classes.push(getWateredClass(cell));
if (!cell.edgeSatisfied) classes.push("noedge");
return classes.join(" ");
}
// Overwrite resetAllPassive
resetAllPassive = function () {
grid.grid.forEach((cell) => {
newPassiveTypes.forEach((property) => {
cell[property] = 0;
});
});
}
// Overwrite placeTile
placeTile = function (type) {
const id = getCellIndex();
if (id != null) {
delete grid.grid[id].craft;
if (grid.grid[id].type == type || type == "remove") {
grid.grid[id].type = grid.defaultType;
grid.grid[id].edgeSatisfied = true;
} else {
grid.grid[id].type = type;
// Overwrite getCraftName
function getCraftName(craft) {
const name = recipes[craft]?.Name? recipes[craft].Name : craft;
return getPrettyName(name);
}
// Overwrite renderStats
renderStats = function () {
HideStageInfo();
const cellIndex = getCellIndex();
const cell = grid.grid[cellIndex];
selectedCraft = "";
craftChecked = false;
if (!cell) return;
const building = townstarObjects[cell.type];
if (building === undefined) return;
const infoSpan = document.createElement('span');
const infoImage = document.createElement('img');
infoImage.src = getTileIcon(cell.type);
infoSpan.appendChild(infoImage);
const tileinfopic = document.querySelector(".tileinfopic");
tileinfopic.textContent = "";
tileinfopic.appendChild(infoSpan);
const recipeBuildingName = getPrettyName(cell.type);
document.querySelector(".tileinfotitle").innerHTML = `<span>$
{getPrettyName(cell.type)}</span`;
const buildingRecipes = building.Crafts.split(",");
const timerGrade = [
"besttimer",
"oktimer",
"badtimer",
"worsttimer"
];
// Overwrite getRecipeTime
getRecipeTime = function (rec, cell) {
const recipe = recipes[rec];
let timesHTML = "";
let penalty = -1;
if (
townstarObjects[cell.type].ProximityImmune == false &&
recipe.ProximityPenalty != "None"
) {
penalty = getTimerClass(recipe.ProximityPenalty, cell);
}
const craftTimeMod = townstarObjects[cell.type].CraftTimeMod;
const timeSpans = [];
if (recipe.TimeReverse) {
timeSpans.reverse();
}
return timesHTML;
}
// Overwrite getTimerClass
getTimerClass = function (penaltyType, cell) {
let totalPenalty = 0;
penaltyType.split(",").forEach((type) => {
totalPenalty += cell[type];
});
return totalPenalty;
}
const ingredientBranches = {
"Water": {
"Barn_Water": [
"Fancy_Barn",
"Legendary_Nourish_Barn",
"Milk_Barn",
],
},
"Feed": {
"Barn_Feed": [
"Fancy_Barn",
"Legendary_Nourish_Barn",
"Milk_Barn",
],
},
};
// Overwrite getIngredients
getIngredients = function (rec, cell) {
let ingredientHTML = "";
const recipe = recipes[rec];
if (!townstarObjects[cell.type].CraftReqsMet) {
for (let i = 1; i <= maxRequirement; i++) {
if (
recipe["Req" + i] == "none" ||
recipe["Req" + i] == undefined
) {
return ingredientHTML;
}
ingredientHTML += getIngredientRatio(
recipe["Req" + i],
recipe["Value" + i],
cell
);
}
}
return ingredientHTML;
}
// Overwrite getIngredientRatio
getIngredientRatio = function (ingredient, needed, cell) {
const present = cell[ingredient] == undefined ? 0 : cell[ingredient];
const presentBranch = Object.keys(cell).reduce((acc, cur) => {
if (!acc) {
acc = 0
}
if (
ingredientBranches[ingredient] &&
Object.keys(ingredientBranches[ingredient]).includes(cur) &&
ingredientBranches[ingredient][cur].includes(cell.type)
) {
return acc + cell[cur];
}
return acc;
}, 0);
const actualPresent = present + presentBranch;
const ratio = `${actualPresent} / ${needed}`;
// Overwrite showCategoryMenu
showCategoryMenu = function (type) {
removeSelectedBuilding();
if (type != "All") {
selectedCategory = type;
document.querySelector("#search-building").value = "";
}
const categoriesElements =
document.querySelectorAll(".categorybutton");
for (const element of categoriesElements) {
element.classList.remove("selected");
}
const selectedCategoryElement = document.querySelector("#" + type);
selectedCategoryElement.classList.add("selected");
// Overwrite isEdgeMatch
isEdgeMatch = function (edge1, edge2) {
//TODO: use EdgeClass of building objects if possible
if (edge1 == "Road") {
return edge2 == "Dirt_Road" || edge2 == "Paved_Road" || edge2 ==
"Uncommon_Paved_Road";
}
if (edge1 == "Water_Pump") {
return edge2 == "Water_Pump" || edge2 == "Rare_Water_Pump" || edge2
== "Diamond_Water_Pump" || edge2 == "Rare_Grand_Aquifer";
}
if (edge1 == "Paved_Road") {
return edge2 == "Paved_Road" || edge2 == "Uncommon_Paved_Road";
}
return edge1 == edge2;
}
const originalNFTProximityBonuses = {
"Rare_Water_Pump": [3],
"Haunted_Maze": {
"Haunted_Maze_-_Zone_1": [3, 2, 1],
"Haunted_Maze_-_Zone_2": [2, 1],
"Haunted_Maze_-_Zone_3": [3, 3],
"Haunted_Maze_-_Zone_4": [1]
},
"Diamond_Water_Pump": {
"Rare_Grand_Aquifer": [1],
"Water_Pump": [1],
"Diamond_Water_Pump": [2],
"Rare_Water_Pump": [3]
},
"Diamond_Charge_Station": {
"Solar_Panel": [1],
"Rare_Solar_Panel": [2, 1],
"Legendary_Solar_Panel": [4, 3, 2, 1],
"Tesla_Coil": [1],
"Rare_Tesla_Coil": [2, 1],
"Legendary_Tesla_Coil": [4, 3, 2, 1],
"Nuclear_Power": [4, 3, 2, 1],
"Power_Plant": [3, 2, 1]
},
"Platinum_Master_Copper_Smith": {
"Platinum_Master_Copper_Smith": [1],
},
"Panner_Brother": {
"Cooper": [1],
"Goldy": [1],
"Sylvester": [1]
},
"Panner": {
"Panner_Bunk_House": [2, 1],
"Panner_House": [1],
"Rose_&_Lily": [1],
},
"Legendary_Nourish_Barn": [3],
};
const boostedNftProximityBonuses = {
"Haunted_Maze": {
"Haunted_Maze_-_Zone_1": [6, 5, 4, 3, 2, 1],
"Haunted_Maze_-_Zone_2": [4, 3, 2, 1],
// "Haunted_Maze_-_Zone_3": [4, 4, 4, 4],
// Custom maze3 modification to match Godot.
"Haunted_Maze_-_Zone_3": [6, 6, 6, 6],
"Haunted_Maze_-_Zone_4": [2, 1]
},
"Diamond_Water_Pump": {
"Rare_Grand_Aquifer": [2, 1],
"Water_Pump": [2],
"Diamond_Water_Pump": [2],
"Rare_Water_Pump": [6]
},
"Diamond_Charge_Station": {
"Solar_Panel": [2, 1],
"Rare_Solar_Panel": [4, 3, 2, 1],
"Legendary_Solar_Panel": [8, 7, 6, 5, 4, 3, 2, 1],
"Tesla_Coil": [2, 1],
"Rare_Tesla_Coil": [4, 3, 2, 1],
"Legendary_Tesla_Coil": [8, 7, 6, 5, 4, 3, 2, 1],
"Nuclear_Power": [8, 7, 6, 5, 4, 3, 2, 1],
"Power_Plant": [6, 5, 4, 3, 2, 1]
},
"Platinum_Master_Copper_Smith": {
"Platinum_Master_Copper_Smith":
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
},
"Panner_Brother": {
"Cooper":
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
"Goldy":
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
"Sylvester":
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
},
"Panner": {
"Panner_Bunk_House": [0],
"Panner_House": [0],
"Rose_&_Lily": [0],
}
};
const boostedNftProximityEffects = {
"Haunted_Maze": {
"Haunted_Maze_-_Zone_1": ["Nectar"],
"Haunted_Maze_-_Zone_2": ["Clay_Lump"],
"Haunted_Maze_-_Zone_3": ["PositiveOnlySalty"],
"Haunted_Maze_-_Zone_4": ["Nectar"]
},
"Diamond_Water_Pump": {
"Rare_Grand_Aquifer": ["Water_Drum"],
"Water_Pump": ["Water_Drum"],
"Diamond_Water_Pump": ["Water_Drum"],
"Rare_Water_Pump": ["Water_Drum"]
},
"Diamond_Charge_Station": {
"Solar_Panel": ["Energy"],
"Rare_Solar_Panel": ["Energy"],
"Legendary_Solar_Panel": ["Energy"],
"Tesla_Coil": ["Energy"],
"Rare_Tesla_Coil": ["Energy"],
"Legendary_Tesla_Coil": ["Energy"],
"Nuclear_Power": ["Energy"],
"Power_Plant": ["Energy"]
},
"Platinum_Master_Copper_Smith": {
"Platinum_Master_Copper_Smith": ["Copper"],
},
"Panner_Brother": {
"Cooper": ["Copper_Ore"],
"Goldy": ["Gold_Ore"],
"Sylvester": ["Silver_Ore"]
},
"Panner": {
"Panner_Bunk_House": ["Shady"],
"Panner_House": ["Shady"],
"Rose_&_Lily": ["Shady"],
}
};
const diamondWaterPump =
Object.keys(originalNFTProximityBonuses.Diamond_Water_Pump);
function IsDiamondWaterPump() {
let valid = false;
Object.values(grid.grid).forEach(({type: type}) => {
if (type == "Diamond_Water_Pump") {
valid = true;
}
});
return valid;
}
const diamondChargeStation =
Object.keys(originalNFTProximityBonuses.Diamond_Charge_Station);
function IsDiamondChargeStation() {
let valid = false;
Object.values(grid.grid).forEach(({type: type}) => {
if (type == "Diamond_Charge_Station") {
valid = true;
}
});
return valid;
}
const applyOnceBuildings = [
"Platinum_Master_Copper_Smith",
"Cooper",
"Goldy",
"Sylvester",
];
const selfProximityBuildings = [
"Legendary_Nourish_Barn",
];
// Overwrite calculatePassiveEffects
calculatePassiveEffects = function() {
let applied = {
Platinum_Master_Copper_Smith: false,
Cooper: false,
Goldy: false,
Sylvester: false
};
boostedNftProximityEffects.Haunted_Maze[cell.type].includes(proximity) == true
) {
const boostedBonuses =
boostedNftProximityBonuses.Haunted_Maze[cell.type];
effectValue = boostedBonuses[0];
effectRadius = boostedBonuses.length;
if (isMaze3) {
fixedEffectValue = effectValue;
}
} else {
const originalBonuses =
originalNFTProximityBonuses.Haunted_Maze[cell.type];
effectValue = originalBonuses[0];
effectRadius = originalBonuses.length;
if (isMaze3) {
fixedEffectValue = effectValue;
}
}
}
if (diamondWaterPump.includes(cell.type)) {
if (
isDiamondWaterPump == true &&
boostedNftProximityEffects.Diamond_Water_Pump[cell.type].includes(proximity) ==
true
) {
const boostedBonuses =
boostedNftProximityBonuses.Diamond_Water_Pump[cell.type];
effectValue = boostedBonuses[0];
effectRadius = boostedBonuses.length;
} else {
const originalBonuses =
originalNFTProximityBonuses.Diamond_Water_Pump[cell.type];
effectValue = originalBonuses[0];
effectRadius = originalBonuses.length;
}
}
if (diamondChargeStation.includes(cell.type)) {
if (
isDiamondChargeStation == true &&
boostedNftProximityEffects.Diamond_Charge_Station[cell.type].includes(proximity) ==
true
) {
const boostedBonuses =
boostedNftProximityBonuses.Diamond_Charge_Station[cell.type];
effectValue = boostedBonuses[0];
effectRadius = boostedBonuses.length;
} else {
const originalBonuses =
originalNFTProximityBonuses.Diamond_Charge_Station[cell.type];
effectValue = originalBonuses[0];
effectRadius = originalBonuses.length;
}
}
if (pannerSets.includes(cell.type)) {
if (
isFullPannerBrotherSets == true &&
boostedNftProximityEffects.Panner[cell.type].includes(proximity) == true
) {
const boostedBonuses =
boostedNftProximityBonuses.Panner[cell.type];
effectValue = boostedBonuses[0];
effectRadius = boostedBonuses.length;
} else {
const originalBonuses =
originalNFTProximityBonuses.Panner[cell.type];
effectValue = originalBonuses[0];
effectRadius = originalBonuses.length;
}
}
if (effectRadius == 0) continue;
setTileProximity(i, proximity, effectValue, effectRadius,
fixedEffectValue, isSelfProximity);
}
if (applyOnceBuildings.includes(cell.type)) {
applied[cell.type] = true;
}
}
}
if (isSelfProximity) {
let proximityValue = value;
if (fixedEffectValue != 0) {
proximityValue = fixedEffectValue;
}
grid.grid[index][proximity] += proximityValue;
}
if (fixedEffectValue != 0) {
proximityValue = fixedEffectValue;
}
}
} else {
if (fixedEffectValue != 0) {
proximityValue = fixedEffectValue;
}
}
grid.grid[tileIndex][proximity] += proximityValue;
// If no proximity bonus allowed, remove the proximity on
the building tile.
const type = grid.grid[tileIndex].type;
if (type) {
const crafts = townstarObjects[type].Crafts.split(",");
for (const craft of crafts) {
if (recipes[craft]) {
const recipe = recipes[craft];
if (
[recipe.Req1, recipe.Req2, recipe.Req3,
recipe.Req4].includes(proximity) &&
(
recipe.ProximityBonus == "None" ||
function IsOutOfGrid(x, y) {
return x < 0 || x > dimension - 1 || y < 0 || y > dimension - 1;
}
function DisplayProximity() {
let cells = document.querySelectorAll('.cell');
cells.forEach(cell => {
let proximityDisplayElement = cell.querySelector('.proximity-
display');
if (proximityDisplayElement) {
proximityDisplayElement.remove();
}
let proximity = GetCellProximity(cell);
if (!IsEmptyObject(proximity)) {
let overlay = document.querySelector('#overlays').value;
Object.keys(proximity).forEach(key => {
if (key === overlay) {
let proximityAmount = proximity[key];
let proximityElement = document.createElement('div');
proximityElement.classList.add('proximity-display');
// proximityElement.style.color =
window.getComputedStyle(cell).borderColor;
proximityElement.textContent = proximityAmount;
cell.appendChild(proximityElement);
}
});
}
});
}
function GetCellProximity(selector) {
let proximityTitle = selector.querySelector('img').title.replaceAll("
","").split("\n");
proximityTitle.shift();
let proximityText = proximityTitle.join(",");
let proximityObject = {};
if (proximityText !== "") {
let proximities = proximityText.split(",");
proximities.forEach(proximity => {
let proximityArray = proximity.split(':');
proximityObject[proximityArray[0]] = proximityArray[1];
});
}
return proximityObject;
}
townstarObjects = newTownstarObjects;
recipes = newRecipes;
delete townstarObjects.Ancient_Tesla_Coil;
delete townstarObjects.K_Barter_Station;
delete townstarObjects.B_Barter_Station;
// Extra modification
townstarObjects.Paved_Road.EdgeRequirements = "None";
renderBuildingMenu();
renderOverlaysOptions();
// Versioning
const version = GM_info.script.version;
const versionDiv = document.createElement("div");
versionDiv.id = "addon-version";
versionDiv.textContent = "Addon v" + version;
document.querySelector(".maincontainer").appendChild(versionDiv);
}
if (theElm == null) {
theElm = document.createElement('div');
theElm.id = div_id;
theElm.innerHTML = innerTag;
const theEmbedElm = theElm.querySelector("#"+inner_id);
theEmbedElm.value = value;
if(onClickAction) {
theEmbedElm.addEventListener('click', onClickAction);
}
theElm.style.marginRight = '.1rem'
}
return theElm;
}
function initPrevGrid(index) {
if (prevGrid[index] == undefined) {
prevGrid[index] = {
type: undefined,
craft: undefined,
};
}
}
if (getCellIndex() != null) {
console.log("*** Selected cell position: ("+getCellIndex() % 16+","+
(Math.round(getCellIndex()/16 + 0.5) - 1)+")");
theEmbedElm.value = contentText;
} else {
const txtArea = createEmbedElm("<textarea id=\"display-txtArea\"
rows=\"51\" cols=\"35\"></textarea>", "div-display-txtArea", "display-txtArea",
contentText, null);
const newContainer = document.createElement('div');
newContainer.className = 'TSV_Operation_DisplayInfo';
newContainer.style.paddingTop = '.1rem';
newContainer.style.display = 'grid';
newContainer.style.gridColumn = '3/3';
newContainer.style.gridRow = '1/5';
newContainer.appendChild(txtArea);
document.querySelector('.maincontainer').appendChild(newContainer);
}
ShowInfoLayoutContent();
};
})();