Controls
Saves
+
Map Generator
Mods
Server Settings
Game Settings
diff --git a/ui/App/components/Modal.jsx b/ui/App/components/Modal.jsx
index 021ed680..1375fd70 100644
--- a/ui/App/components/Modal.jsx
+++ b/ui/App/components/Modal.jsx
@@ -4,17 +4,28 @@ import * as ReactDom from "react-dom";
const modalRoot = document.getElementById('modal-root');
-const Modal = ({title, content, isOpen, actions = null}) => {
+const Modal = ({title, content, isOpen, actions = null, onSubmit = null}) => {
return ReactDom.createPortal((isOpen &&
-
+ {onSubmit
+ ?
+ :
+ }
+
), modalRoot)
}
diff --git a/ui/App/components/Panel.jsx b/ui/App/components/Panel.jsx
index e0707cfd..26920529 100644
--- a/ui/App/components/Panel.jsx
+++ b/ui/App/components/Panel.jsx
@@ -9,11 +9,10 @@ const Panel = ({title, content, actions, className}) => {
{content}
- {actions
- ?
+ {actions &&
+
{actions}
- : null
}
)
diff --git a/ui/App/components/Select.jsx b/ui/App/components/Select.jsx
index 705b861a..242a2f6d 100644
--- a/ui/App/components/Select.jsx
+++ b/ui/App/components/Select.jsx
@@ -1,28 +1,42 @@
-import React, {useState} from "react";
+import React, {useState, useEffect} from "react";
-const Select = ({register, options, className = "", defaultValue = ""}) => {
+const Select = ({name, register = {}, options, className = "", isInline = false, defaultValue = "", onChange = null, defaultValue = null, value = null}) => {
- const [value, setValue] = useState(defaultValue);
+ const [selectedValue, setSelectedValue] = useState(defaultValue || "");
+
+ const updateValue = event => {
+ if (onChange !== null) {
+ event.persist();
+ onChange(event);
+ }
+ setSelectedValue(event.target.value);
+ }
+
+ useEffect(() => {
+ if (value !== null) {
+ setSelectedValue(value);
+ }
+ }, [value])
return (
-
-
-
+
+
+
)
}
diff --git a/ui/App/components/Slider.jsx b/ui/App/components/Slider.jsx
new file mode 100644
index 00000000..c7a77209
--- /dev/null
+++ b/ui/App/components/Slider.jsx
@@ -0,0 +1,13 @@
+import React from "react";
+
+const Slider = ({min = 1, max = 12, step = 1}) => {
+ return
+}
+
+export default Slider;
\ No newline at end of file
diff --git a/ui/App/components/Tabs/TabControl.jsx b/ui/App/components/Tabs/TabControl.jsx
index a2a7d94e..2235a70a 100644
--- a/ui/App/components/Tabs/TabControl.jsx
+++ b/ui/App/components/Tabs/TabControl.jsx
@@ -1,7 +1,8 @@
import React, {useState} from "react";
import TabTitle from "./TabTitle";
+import Panel from "../Panel";
-const TabControl = ({children}) => {
+const TabControl = ({children, actions = null, title= null}) => {
const [selectedTab, setSelectedTab] = useState(0)
return (
@@ -17,11 +18,12 @@ const TabControl = ({children}) => {
/>
))}
-
-
- {children[selectedTab]}
-
-
+
)
}
diff --git a/ui/App/copy.js b/ui/App/copy.js
new file mode 100644
index 00000000..85d038b4
--- /dev/null
+++ b/ui/App/copy.js
@@ -0,0 +1 @@
+export default original => JSON.parse(JSON.stringify(original));
\ No newline at end of file
diff --git a/ui/App/views/MapGenerator/MapGenerator.jsx b/ui/App/views/MapGenerator/MapGenerator.jsx
new file mode 100644
index 00000000..cd4988b5
--- /dev/null
+++ b/ui/App/views/MapGenerator/MapGenerator.jsx
@@ -0,0 +1,169 @@
+import React, {useEffect, useState} from "react";
+import TabControl from "../../components/Tabs/TabControl";
+import Tab from "../../components/Tabs/Tab";
+import Button from "../../components/Button";
+import Resources from "./tabs/resources/Resources";
+import Terrain from "./tabs/Terrain";
+import Enemy from "./tabs/Enemy";
+import Advanced from "./tabs/Advanced";
+import SeedInput from "./components/SeedInput";
+import MapTypeSelect from "./components/MapTypeSelect";
+import saves from "../../../api/resources/saves";
+import MapPreviewImage from "./components/MapPreviewImage";
+import copy from "../../copy";
+import Input from "../../components/Input";
+import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
+import {faExclamationTriangle} from "@fortawesome/free-solid-svg-icons";
+
+let timeoutPreviewHandle = null;
+
+const MapGenerator = ({serverStatus}) => {
+
+ const isServerRunning = serverStatus.status === 'running';
+
+ const [isPreviewDisplayed, setIsPreviewDisplayed] = useState(false)
+ const [seed, setSeed] = useState(0);
+ const [settings, setSettings] = useState({});
+ const [previewImage, setPreviewImage] = useState(null);
+ const [previewImageSeed, setPreviewImageSeed] = useState(null);
+ const [isLoadingPreview, setIsLoadingPreview] = useState(false);
+ const [saveFileName, setSaveFileName] = useState("");
+ const [isGeneratingMap, setIsGeneratingMap] = useState(false);
+
+ const updateSettings = (newSettings, shouldLoadPreview = true) => {
+ setSettings(newSettings);
+ if (shouldLoadPreview) {
+ loadPreview(newSettings)
+ }
+ }
+
+ const createSave = () => {
+ setIsGeneratingMap(true);
+ saves.create(saveFileName, settings)
+ .then(() => flash(`Save "${saveFileName}" created`, "green"))
+ .finally(() => setIsGeneratingMap(false));
+ }
+
+ const loadPreview = (settings, force = false) => {
+ if (isLoadingPreview || (!isPreviewDisplayed && !force)) {
+ return;
+ }
+
+ const previewHandler = () => {
+ setIsLoadingPreview(true)
+ setPreviewImageSeed(settings.seed)
+
+ let tmpSettings = copy(settings);
+
+ if (!tmpSettings.cliff_settings.enabled) {
+ tmpSettings.cliff_settings.richness = 0;
+ }
+
+ if (!tmpSettings.water_enabled) {
+ tmpSettings.water = 0;
+ }
+
+ saves.preview(tmpSettings)
+ .then(imageData => setPreviewImage(imageData))
+ .finally(() => setIsLoadingPreview(false))
+ }
+
+ if (timeoutPreviewHandle) {
+ clearTimeout(timeoutPreviewHandle);
+ timeoutPreviewHandle = null
+ }
+ timeoutPreviewHandle = setTimeout(previewHandler, 600);
+ }
+
+ const randomSeed = () => {
+ const randomValue = Math.floor(Math.random() * 1000000000)
+ updateSeed(randomValue)
+ }
+
+ const updateSeed = value => {
+ setSeed(value);
+ const newSettings = Object.assign(settings, {seed: value});
+ setSettings(newSettings);
+ loadPreview(newSettings);
+ }
+
+ useEffect(() => {
+ Promise.all([
+ saves.defaultMapGenSettings()
+ .then(mapGenSettings => setSettings(Object.assign(settings, mapGenSettings))),
+ saves.defaultMapSettings()
+ .then(mapSettings => setSettings(Object.assign(settings, mapSettings))),
+ ]).finally(() => {
+ randomSeed()
+ })
+ }, []);
+
+ return