* Introduce concept of invizible walls to constrain outline map generation
* Rework some templates to work better with new parameters in rust landgen
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Shapes
Window {
id: control
width: 1024
height: 768
visible: true
title: qsTr("Map Templates")
property bool hasError: false
Page {
id: page
anchors.fill: parent
Rectangle {
id: mapContainer
property int spaceForCode: Math.max(250, parent.height * 0.6)
property int mapWidth: 2048
property int mapHeight: 1024
property real aspectRatio: mapWidth / mapHeight
property bool fitWidth: aspectRatio > (parent.width / (parent.height - spaceForCode))
implicitWidth: fitWidth ? parent.width : (parent.height - spaceForCode) * aspectRatio
implicitHeight: fitWidth ? parent.width / aspectRatio : (parent.height - spaceForCode)
x: (parent.width - width) / 2
border.width: 2
border.color: hasError ? "red" : "black"
}
Shape {
id: shape
anchors.fill: mapContainer
}
MouseArea {
id: mouseArea
anchors.fill: mapContainer
hoverEnabled: true
}
Label {
text: mouseArea.containsMouse ? "(%1, %2)".arg(Math.floor(mouseArea.mouseX / mouseArea.width * mapContainer.mapWidth)).arg(Math.floor(mouseArea.mouseY / mouseArea.height * mapContainer.mapHeight)) : ""
}
Rectangle {
anchors.fill: codeInput
color: "gray"
}
TextEdit {
id: codeInput
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
height: parent.height - mapContainer.height
text: " -
width: 3072
height: 1424
can_flip: false
can_invert: false
can_mirror: true
is_negative: false
put_girders: true
max_hedgehogs: 18
outline_points:
-
- {x: 748, y: 1424, w: 1, h: 1}
- {x: 636, y: 1252, w: 208, h: 72}
- {x: 898, y: 1110, w: 308, h: 60}
- {x: 1128, y: 1252, w: 434, h: 40}
- {x: 1574, y: 1112, w: 332, h: 40}
- {x: 1802, y: 1238, w: 226, h: 36}
- {x: 1930, y: 1424, w: 1, h: 1}
-
- {x: 2060, y: 898, w: 111, h: 111}
- {x: 1670, y: 876, w: 34, h: 102}
- {x: 1082, y: 814, w: 284, h: 132}
- {x: 630, y: 728, w: 126, h: 168}
- {x: 810, y: 574, w: 114, h: 100}
- {x: 1190, y: 572, w: 352, h: 120}
- {x: 1674, y: 528, w: 60, h: 240}
- {x: 1834, y: 622, w: 254, h: 116}
fill_points:
- {x: 1423, y: 0}
"
onTextChanged: {
const template = parseInput()
if (template) {
mapContainer.mapWidth = Number(template.width)
mapContainer.mapHeight = Number(template.height)
shape.data = renderTemplate(template)
}
}
}
}
function parseInput() {
let code = codeInput.text.split('\n')
if(code[0] !== " -") {
hasError = true
return
}
code = code.slice(1)
code.push("")
let parsed = ({})
let polygonAccumulator = []
let pointAccumulator = []
let key = ""
code.forEach(line => {
let newKey
if (line === " outline_points:") {
newKey = "outline_points"
}
if (line === " walls:") {
newKey = "walls"
}
if (line === " fill_points:") {
newKey = "fill_points"
}
if (line === "") {
newKey = "_"
}
if (key === "fill_points" && line.startsWith(" - {")) {
// ignore
return
}
if (newKey) {
if (key.length > 0) {
polygonAccumulator.push(pointAccumulator)
parsed[key] = polygonAccumulator
}
key = newKey
polygonAccumulator = []
pointAccumulator = []
return
}
if (line === " -") {
if (pointAccumulator.length > 0) {
polygonAccumulator.push(pointAccumulator)
pointAccumulator = []
}
return
}
const matchValue = line.match(/^\s{4}(\w+):\s(.+)$/);
if (matchValue) {
parsed[matchValue[1]] = matchValue[2]
return
}
const matchPoint = line.match(/^\s{8}-\s\{([^}]+)\}$/);
if (matchPoint) {
const point = matchPoint[1].split(", ").reduce((obj, pair) => {
const [key, value] = pair.split(": ");
obj[key] = isNaN(value) ? value : parseInt(value);
return obj;
}, {})
pointAccumulator.push(point)
return
}
console.log("Unrecognized: " + JSON.stringify(line))
hasError = true
throw ""
})
hasError = false
return parsed
}
Component {
id: shapePathComponent
ShapePath {
fillColor: "transparent"
scale: Qt.size(mapContainer.width / mapContainer.mapWidth, mapContainer.height / mapContainer.mapHeight)
strokeWidth: 3
}
}
Component {
id: pathLineComponent
PathLine {
}
}
function polygons2shapes(polygons, lineColor, rectColor) {
if (!Array.isArray(polygons)) {
return []
}
let rectangles = []
polygons.forEach(polygon => polygon.forEach(r => {
let shapePath = shapePathComponent.createObject(shape)
shapePath.strokeWidth = 1
shapePath.strokeColor = rectColor
shapePath.startX = r.x
shapePath.startY = r.y
shapePath.pathElements = [
pathLineComponent.createObject(shapePath, {x: r.x, y: r.y + r.h}),
pathLineComponent.createObject(shapePath, {x: r.x + r.w, y: r.y + r.h}),
pathLineComponent.createObject(shapePath, {x: r.x + r.w, y: r.y}),
pathLineComponent.createObject(shapePath, {x: r.x, y: r.y})
]
rectangles.push(shapePath)
}))
let polygonShapes = polygons.map(polygon => {
let points = polygon.map(r => ({x: r.x + r.w / 2, y: r.y + r.h / 2}))
let shapePath = shapePathComponent.createObject(shape)
let start = points[points.length - 1]
shapePath.strokeColor = lineColor
shapePath.startX = start.x
shapePath.startY = start.y
shapePath.pathElements = points.map(p => pathLineComponent.createObject(shapePath, p))
return shapePath
})
return rectangles.concat(polygonShapes)
}
function renderTemplate(template) {
return polygons2shapes(template.outline_points, "red", "black").concat(polygons2shapes(template.walls, "gray", "gray"))
}
}