Skip to content

Commit

Permalink
add schematic mask feature, fixes #1646
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 14, 2019
1 parent ea29a44 commit f412e31
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 13 deletions.
Expand Up @@ -178,7 +178,7 @@ public void registerCommands() {
}
registerCoreMember(ResetCommand.class, "RESET", "reset (<player>|...) [cooldown/saves/global_cooldown] (<script>)", 1);
registerCoreMember(RotateCommand.class, "ROTATE", "rotate (cancel) (<entity>|...) (yaw:<#.#>) (pitch:<#.#>) (infinite/duration:<duration>) (frequency:<duration>)", 0);
registerCoreMember(SchematicCommand.class, "SCHEMATIC", "schematic [create/load/unload/rotate/paste/save/flip_x/flip_y/flip_z] [name:<name>] (filename:<name>) (angle:<#>) (<location>) (<cuboid>) (delayed) (noair)", 2);
registerCoreMember(SchematicCommand.class, "SCHEMATIC", "schematic [create/load/unload/rotate/paste/save/flip_x/flip_y/flip_z] [name:<name>] (filename:<name>) (angle:<#>) (<location>) (<cuboid>) (delayed) (noair) (mask:<material>|...)", 2);
registerCoreMember(ScoreboardCommand.class, "SCOREBOARD", "scoreboard ({add}/remove) (viewers:<player>|...) (lines:<player>/<text>|...) (id:<value>/{main}) (objective:<value>) (criteria:<criteria>/{dummy}) (score:<#>) (displayslot:<value>/{sidebar}/none)", 1);
registerCoreMember(ScribeCommand.class, "SCRIBE", "scribe [<script>] (<item>/give/equip/{drop <location>})", 1);
registerCoreMember(ShootCommand.class, "SHOOT", "shoot [<entity>|...] (origin:<entity>/<location>) (destination:<location>) (height:<#.#>) (speed:<#.#>) (script:<name>) (def:<element>|...) (shooter:<entity>) (spread:<#.#>) (lead:<location>) (no_rotate)", 1);
Expand Down
Expand Up @@ -35,13 +35,15 @@
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

public class SchematicCommand extends AbstractCommand implements Holdable, Listener {

// <--[command]
// @Name Schematic
// @Syntax schematic [create/load/unload/rotate/paste/save/flip_x/flip_y/flip_z] [name:<name>] (filename:<name>) (angle:<#>) (<location>) (<cuboid>) (delayed) (noair)
// @Syntax schematic [create/load/unload/rotate/paste/save/flip_x/flip_y/flip_z] [name:<name>] (filename:<name>) (angle:<#>) (<location>) (<cuboid>) (delayed) (noair) (mask:<material>|...)
// @Group World
// @Required 2
// @Short Creates, loads, pastes, and saves schematics (Sets of blocks).
Expand All @@ -55,6 +57,8 @@ public class SchematicCommand extends AbstractCommand implements Holdable, Liste
//
// The "noair" option skips air blocks in the pasted schematics- this means those air blocks will not replace any blocks in the target location.
//
// The "mask" option can be specified to limit what block types the schematic will be pasted over.
//
// The "delayed" option makes the command non-instant. This is recommended for large schematics.
// For 'save', 'load', and 'rotate', this processes async to prevent server lockup.
// For 'paste' and 'create', this delays how many blocks can be processed at once, spread over many ticks.
Expand Down Expand Up @@ -139,17 +143,10 @@ else if (!scriptEntry.hasObject("filename")
scriptEntry.addObject("filename", arg.asElement());
}
else if (!scriptEntry.hasObject("angle")
&& arg.matchesPrefix("angle")
&& arg.matchesPrimitive(ArgumentHelper.PrimitiveType.Integer)) {
scriptEntry.addObject("angle", arg.asElement());
}
else if (!scriptEntry.hasObject("location")
&& arg.matchesArgumentType(LocationTag.class)) {
scriptEntry.addObject("location", arg.asType(LocationTag.class));
}
else if (!scriptEntry.hasObject("cuboid")
&& arg.matchesArgumentType(CuboidTag.class)) {
scriptEntry.addObject("cuboid", arg.asType(CuboidTag.class));
}
else if (!scriptEntry.hasObject("delayed")
&& arg.matches("delayed")) {
scriptEntry.addObject("delayed", new ElementTag("true"));
Expand All @@ -158,6 +155,19 @@ else if (!scriptEntry.hasObject("noair")
&& arg.matches("noair")) {
scriptEntry.addObject("noair", new ElementTag("true"));
}
else if (!scriptEntry.hasObject("mask")
&& arg.matchesPrefix("mask")
&& arg.matchesArgumentList(MaterialTag.class)) {
scriptEntry.addObject("mask", arg.asType(ListTag.class).filter(MaterialTag.class, scriptEntry));
}
else if (!scriptEntry.hasObject("location")
&& arg.matchesArgumentType(LocationTag.class)) {
scriptEntry.addObject("location", arg.asType(LocationTag.class));
}
else if (!scriptEntry.hasObject("cuboid")
&& arg.matchesArgumentType(CuboidTag.class)) {
scriptEntry.addObject("cuboid", arg.asType(CuboidTag.class));
}
else {
arg.reportUnhandled();
}
Expand All @@ -183,6 +193,7 @@ public void execute(final ScriptEntry scriptEntry) {
ElementTag noair = scriptEntry.getElement("noair");
ElementTag delayed = scriptEntry.getElement("delayed");
LocationTag location = scriptEntry.getObjectTag("location");
List<MaterialTag> mask = (List<MaterialTag>) scriptEntry.getObject("mask");
CuboidTag cuboid = scriptEntry.getObjectTag("cuboid");

if (scriptEntry.dbCallShouldDebug()) {
Expand All @@ -194,7 +205,8 @@ public void execute(final ScriptEntry scriptEntry) {
+ (cuboid != null ? cuboid.debug() : "")
+ (angle != null ? angle.debug() : "")
+ (noair != null ? noair.debug() : "")
+ (delayed != null ? delayed.debug() : ""));
+ (delayed != null ? delayed.debug() : "")
+ (mask != null ? ArgumentHelper.debugList("mask", mask) : ""));

}

Expand Down Expand Up @@ -370,6 +382,12 @@ public void execute(final ScriptEntry scriptEntry) {
BlockSet.InputParams input = new BlockSet.InputParams();
input.centerLocation = location;
input.noAir = noair != null && noair.asBoolean();
if (mask != null) {
input.mask = new HashSet<>();
for (MaterialTag material : mask) {
input.mask.add(material.getMaterial());
}
}
if (delayed != null && delayed.asBoolean()) {
schematics.get(name.asString().toUpperCase()).setBlocksDelayed(new Runnable() {
@Override
Expand Down
Expand Up @@ -2,6 +2,9 @@

import com.denizenscript.denizen.nms.interfaces.BlockData;
import org.bukkit.Location;
import org.bukkit.Material;

import java.util.HashSet;

public interface BlockSet {

Expand All @@ -10,6 +13,8 @@ class InputParams {
public Location centerLocation;

public boolean noAir;

public HashSet<Material> mask;
}

BlockData[] getBlocks();
Expand Down
Expand Up @@ -7,6 +7,7 @@
import com.denizenscript.denizen.utilities.DenizenAPI;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.scheduler.BukkitRunnable;

public class CuboidBlockSet implements BlockSet {
Expand Down Expand Up @@ -95,9 +96,18 @@ public CuboidTag getCuboid(Location loc) {
}

public void setBlockSingle(BlockData block, int x, int y, int z, InputParams input) {
if (!input.noAir || block.getMaterial() != Material.AIR) {
block.setBlock(input.centerLocation.clone().add(x - center_x, y - center_y, z - center_z).getBlock(), false);
if (input.noAir && block.getMaterial() == Material.AIR) {
return;
}
int finalY = input.centerLocation.getBlockY() + y - center_y;
if (finalY < 0 || finalY > 255) {
return;
}
Block destBlock = input.centerLocation.clone().add(x - center_x, y - center_y, z - center_z).getBlock();
if (input.mask != null && !input.mask.contains(destBlock.getType())) {
return;
}
block.setBlock(destBlock, false);
}

@Override
Expand Down

0 comments on commit f412e31

Please sign in to comment.