
de.adrodoc55.minecraft.mpl.conversion.CommandConverter Maven / Gradle / Ivy
/*
* Minecraft Programming Language (MPL): A language for easy development of command block
* applications including an IDE.
*
* © Copyright (C) 2016 Adrodoc55
*
* This file is part of MPL.
*
* MPL is free software: you can redistribute it and/or modify it under the terms of the GNU General
* Public License as published by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MPL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with MPL. If not, see
* .
*
*
*
* Minecraft Programming Language (MPL): Eine Sprache für die einfache Entwicklung von Commandoblock
* Anwendungen, inklusive einer IDE.
*
* © Copyright (C) 2016 Adrodoc55
*
* Diese Datei ist Teil von MPL.
*
* MPL ist freie Software: Sie können diese unter den Bedingungen der GNU General Public License,
* wie von der Free Software Foundation, Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
*
* MPL wird in der Hoffnung, dass es nützlich sein wird, aber OHNE JEDE GEWÄHRLEISTUNG,
* bereitgestellt; sogar ohne die implizite Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN
* BESTIMMTEN ZWECK. Siehe die GNU General Public License für weitere Details.
*
* Sie sollten eine Kopie der GNU General Public License zusammen mit MPL erhalten haben. Wenn
* nicht, siehe .
*/
package de.adrodoc55.minecraft.mpl.conversion;
import static de.adrodoc55.commons.FileUtils.UTF_8;
import static de.adrodoc55.minecraft.mpl.MplUtils.getBoundaries;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import de.adrodoc55.commons.StringUtils;
import de.adrodoc55.minecraft.coordinate.Coordinate3D;
import de.adrodoc55.minecraft.coordinate.Direction3D;
import de.adrodoc55.minecraft.coordinate.Orientation3D;
import de.adrodoc55.minecraft.mpl.blocks.CommandBlock;
import de.adrodoc55.minecraft.mpl.blocks.MplBlock;
import de.adrodoc55.minecraft.mpl.compilation.MplCompilationResult;
/**
* @author Adrodoc55
*/
public class CommandConverter implements MplConverter {
@Override
public void write(MplCompilationResult result, String name, OutputStream out) throws IOException {
List converted = CommandConverter.convert(result);
int i = 0;
for (String string : converted) {
out.write(("Command " + (++i) + ":\r\n").getBytes(UTF_8));
out.write(string.getBytes(UTF_8));
out.write("\r\n".getBytes(UTF_8));
}
out.close();
}
public static final int MAX_COMMAND_LENGTH = 32500;
private static final String HEADER =
"summon FallingSand ~ ~1 ~ {Block:redstone_block,Time:1,Passengers:["
+ "{id:FallingSand,Block:activator_rail,Time:1,Passengers:[";
private static final String TAIL =
"{id:MinecartCommandBlock,Command:setblock ~ ~-2 ~ command_block},"
+ "{id:MinecartCommandBlock,Command:setblock ~ ~2 ~ command_block 0 replace {Command:fill ~ ~-3 ~ ~ ~ ~ air}},"
+ "{id:MinecartCommandBlock,Command:setblock ~ ~1 ~ redstone_block},"
+ "{id:MinecartCommandBlock,Command:kill @e[type=MinecartCommandBlock,r=0]}]}]}";
private static final String COMMAND_HEADER = "{id:MinecartCommandBlock,Command:";
private static final String COMMAND_TAIL = "},";
public static Coordinate3D getOffset(Orientation3D orientation) {
Coordinate3D a = orientation.getA().toCoordinate();
Coordinate3D c = orientation.getC().toCoordinate();
Direction3D bd = orientation.getB();
bd = Direction3D.valueOf(bd.getAxis(), false);
Coordinate3D b = bd.toCoordinate();
// @formatter:off
return new Coordinate3D()
.plus(a.mult(1))
.plus(b.mult(-2))
.plus(c.mult(1));
// @formatter:on
}
public static List convert(MplCompilationResult result) {
List commands = new ArrayList<>();
Orientation3D orientation = result.getOrientation();
StringBuilder sb = new StringBuilder(HEADER);
// Appending initial fill Command to clear the required Area
Coordinate3D max = getBoundaries(orientation, result.getBlocks().keySet());
sb.append(COMMAND_HEADER);
sb.append("fill ");
sb.append(new Coordinate3D().plus(getOffset(orientation)).toRelativeString()).append(' ');
sb.append(max.plus(getOffset(orientation)).toRelativeString()).append(' ');
sb.append("air");
sb.append(COMMAND_TAIL);
// Appending setblock for all Commands
for (MplBlock block : result.getBlocks().values()) {
if (!(block instanceof CommandBlock)) {
continue;
}
StringBuilder convert = convert((CommandBlock) block, orientation);
int totalLength = sb.length() + convert.length() + TAIL.length();
if (totalLength > MAX_COMMAND_LENGTH) {
sb.append(TAIL);
commands.add(sb.toString());
sb = new StringBuilder(HEADER);
}
sb.append(convert);
}
sb.append(TAIL);
commands.add(sb.toString());
sb = new StringBuilder(HEADER);
return commands;
}
private static StringBuilder convert(CommandBlock block, Orientation3D orientation) {
String coordinate = block.getCoordinate().plus(getOffset(orientation)).toRelativeString();
String blockId = block.getStringBlockId();
int damage = block.getDamageValue();
StringBuilder sb = new StringBuilder(COMMAND_HEADER);
sb.append("setblock ");
sb.append(coordinate).append(' ');
sb.append(blockId).append(' ');
sb.append(damage).append(' ');
sb.append("replace").append(' ');
sb.append('{');
if (!block.getNeedsRedstone()) {
sb.append("auto:1,");
}
sb.append("Command:");
sb.append(escapeCommand(block.getCommand()));
sb.append('}');
sb.append(COMMAND_TAIL);
return sb;
}
/**
* A command must be escaped twice, because a OneCommand is nested twice: a command block in a
* command block minecraft in a command block.
*
* @param command
* @return
*/
private static String escapeCommand(String command) {
command = StringUtils.escapeBackslashes(command);
command = StringUtils.escapeBackslashes(command);
return command;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy