Skip to content
Permalink
Browse files

Add get|set_blockdata() functions that support blockdata arrays

  • Loading branch information...
PseudoKnight committed Aug 11, 2019
1 parent 5c43a36 commit e4e791f00c9e54bdc9075ec72c0d27335653ff8b
@@ -37,6 +37,7 @@
import com.laytonsmith.abstraction.MCTropicalFishBucketMeta;
import com.laytonsmith.abstraction.MCWorld;
import com.laytonsmith.abstraction.StaticLayer;
import com.laytonsmith.abstraction.blocks.MCBlockData;
import com.laytonsmith.abstraction.blocks.MCBlockState;
import com.laytonsmith.abstraction.blocks.MCMaterial;
import com.laytonsmith.abstraction.blocks.MCBanner;
@@ -1653,6 +1654,57 @@ public MCMaterial material(Mixed name, Target t) {
return material(name.val(), t);
}

public MCBlockData blockData(CArray ca, Target t) {
StringBuilder b = new StringBuilder().append("[");
boolean first = true;
for(String key : ca.stringKeySet()) {
if(key.equals("block")) {
b.insert(0, ca.get("block", t).val());
} else {
if(first) {
first = false;
} else {
b.append(',');
}
b.append(key).append('=').append(ca.get(key, t).val());
}
}
b.append("]");
return Static.getServer().createBlockData(b.toString());
}

public CArray blockData(MCBlockData blockdata, Target t) {
CArray ca = CArray.GetAssociativeArray(t);
String full = blockdata.getAsString().substring(10); // ignore "minecraft:"
int bracketPos = full.indexOf('[', 3);
if(bracketPos != -1) {
ca.set("block", new CString(full.substring(0, bracketPos), t), t);
String[] states = full.substring(bracketPos + 1, full.length() - 1).split(",");
for(String s : states) {
int equalsPos = s.indexOf('=');
ca.set(s.substring(0, equalsPos), blockState(s.substring(equalsPos + 1)), t);
}
} else {
ca.set("block", new CString(full, t), t);
}
return ca;
}

private Construct blockState(String value) {
if(value.length() < 3 && Character.isDigit(value.charAt(0))) {
// integer states range from 0-25
try {
return new CInt(Long.parseLong(value), Target.UNKNOWN);
} catch (NumberFormatException e) {
}
} else if(value.equals("true")) {
return CBoolean.TRUE;
} else if(value.equals("false")) {
return CBoolean.FALSE;
}
return new CString(value, Target.UNKNOWN);
}

/**
* Gets a MetadataValue, given a construct and a plugin.
*
@@ -289,6 +289,133 @@ public Boolean runAsync() {
}
}

@api
public static class get_blockdata extends AbstractFunction {

@Override
public String getName() {
return "get_blockdata";
}

@Override
public Integer[] numArgs() {
return new Integer[]{1};
}

@Override
public String docs() {
return "array {locationArray} Gets the block data as an array at the location.";
}

@Override
public Mixed exec(Target t, com.laytonsmith.core.environments.Environment env, Mixed... args)
throws CancelCommandException, ConfigRuntimeException {
MCLocation loc = ObjectGenerator.GetGenerator().location(args[0], null, t);
MCBlock b = loc.getWorld().getBlockAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(b == null) {
throw new CRENotFoundException("Could not find the block in " + this.getName() + " (cmdline mode?)", t);
}
return ObjectGenerator.GetGenerator().blockData(b.getBlockData(), t);
}

@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CREFormatException.class, CRECastException.class, CREInvalidWorldException.class,
CRENotFoundException.class};
}

@Override
public boolean isRestricted() {
return true;
}

@Override
public MSVersion since() {
return MSVersion.V3_3_4;
}

@Override
public Boolean runAsync() {
return false;
}
}

@api
public static class set_blockdata extends AbstractFunction {

@Override
public String getName() {
return "set_blockdata";
}

@Override
public Integer[] numArgs() {
return new Integer[]{2, 3};
}

@Override
public String docs() {
return "void {locationArray, data, [physics]} Sets the block at the location from a blockdata object.";
}

@Override
public Mixed exec(Target t, com.laytonsmith.core.environments.Environment env, Mixed... args)
throws CancelCommandException, ConfigRuntimeException {
MCLocation loc = ObjectGenerator.GetGenerator().location(args[0], null, t);
MCBlock b = loc.getWorld().getBlockAt(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(b == null) {
throw new CRENotFoundException("Could not find the block in " + this.getName() + " (cmdline mode?)", t);
}
boolean physics = true;
if(args.length == 3) {
physics = ArgumentValidation.getBooleanish(args[2], t);
}
MCBlockData bd;
try {
if(args[1] instanceof CArray) {
CArray bda = (CArray) args[1];
if(bda.size() == 1) {
MCMaterial mat = StaticLayer.GetMaterial(bda.get("block", t).val().toUpperCase());
if(mat == null) {
throw new CREIllegalArgumentException("Cannot find material \""
+ bda.get("block", t).val() + "\".", t);
}
b.setType(mat);
return CVoid.VOID;
}
bd = ObjectGenerator.GetGenerator().blockData((CArray) args[1], t);
} else {
bd = Static.getServer().createBlockData(args[1].val());
}
} catch (IllegalArgumentException ex) {
throw new CREIllegalArgumentException("Cannot create block data from string: " + args[1].val(), t);
}
b.setBlockData(bd, physics);
return CVoid.VOID;
}

@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CREFormatException.class, CRECastException.class, CREInvalidWorldException.class,
CRENotFoundException.class, CREIllegalArgumentException.class};
}

@Override
public boolean isRestricted() {
return true;
}

@Override
public MSVersion since() {
return MSVersion.V3_3_4;
}

@Override
public Boolean runAsync() {
return false;
}
}

@hide("Deprecated in favor of get_block()")
@api(environments = {CommandHelperEnvironment.class})
public static class get_block_at extends AbstractFunction implements Optimizable {

0 comments on commit e4e791f

Please sign in to comment.
You can’t perform that action at this time.