Compare commits

..

2 Commits

Author SHA1 Message Date
dfsek 1df09f44ea add BiomeCreationEvent 2021-05-11 15:34:02 -07:00
dfsek fa8a6f38cc addon Platform annotation 2021-05-11 10:04:27 -07:00
137 changed files with 3085 additions and 2352 deletions
+6 -6
View File
@@ -7,7 +7,7 @@ to your specifications, with no knowledge of Java required.
* Paper+ servers (Paper, Tuinity, Purpur, etc): [SpigotMC](https://www.spigotmc.org/resources/85151/)
* Fabric: [Modrinth](https://modrinth.com/mod/terra) / [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
* Forge **(ALPHA - NOT PRODUCTION-READY)**: [Modrinth](https://modrinth.com/mod/terra) / [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
* Forge: [Modrinth](https://modrinth.com/mod/terra) / [CurseForge](https://www.curseforge.com/minecraft/mc-mods/terra-world-generator)
## Building and Running Terra
@@ -32,15 +32,15 @@ To run Minecraft with Terra in the IDE (for testing) use the following tasks:
* `runPaper` - Run the Paper test server with Terra (`installPaper` must have been run previously).
* `runPurpur` - Run the Purpur test server with Terra (`installPurpur` must have been run previously).
* Fabric
* `runClient` - Run a Minecraft Fabric client with Terra installed.
* `runServer` - Run a Minecraft Fabric server with Terra installed.
* `runClient` - Run a Minecraft client with Terra installed.
* `runServer` - Run a Minecraft server with Terra installed.
* Forge
* `runClient` - Run a Minecraft Forge client with Terra installed.
* `runServer` - Run a Minecraft Forge server with Terra installed.
* `runClient` - Run a Minecraft client with Terra installed.
* `runServer` - Run a Minecraft server with Terra installed.
## Contributing
Contributions are welcome! If you want to see a feature in Terra, please, open an issue, or implement it yourself and
submit a PR!
Join the discord [here](https://discord.gg/PXUEbbF) if you would like to talk more about the project!
## Beta
Terra is still in beta! While it is stable, it is not feature-complete. There is a lot to be added!
Terra is still in beta! While it is stable, it is not feature-complete. There is a lot to be added!
+1 -1
View File
@@ -1,6 +1,6 @@
import com.dfsek.terra.getGitHash
val versionObj = Version("5", "3", "2", true)
val versionObj = Version("5", "3", "1", true)
allprojects {
version = versionObj
@@ -14,14 +14,14 @@ fun Project.configureCompilation() {
apply(plugin = "idea")
configure<JavaPluginConvention> {
sourceCompatibility = JavaVersion.VERSION_14
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
doFirst {
options.compilerArgs.addAll(arrayOf("-Xlint:all", "--release", "8", "-Xplugin:jabel"))
options.compilerArgs.add("-Xlint:all")
}
}
@@ -29,12 +29,7 @@ fun Project.configureCompilation() {
include("**/*.*")
filter<org.apache.tools.ant.filters.ReplaceTokens>(
"tokens" to mapOf(
"VERSION" to project.version.toString(),
"DESCRIPTION" to project.properties["terra.description"],
"WIKI" to project.properties["terra.wiki"],
"SOURCE" to project.properties["terra.source"],
"ISSUES" to project.properties["terra.issues"],
"LICENSE" to project.properties["terra.license"]
"VERSION" to project.version.toString()
)
)
}
@@ -33,7 +33,6 @@ fun Project.configureDependencies() {
dependencies {
"testImplementation"("org.junit.jupiter:junit-jupiter-api:5.7.0")
"testImplementation"("org.junit.jupiter:junit-jupiter-engine:5.7.0")
"annotationProcessor"("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0")
"api"("org.jetbrains:annotations:20.1.0")
}
}
@@ -0,0 +1,16 @@
package com.dfsek.terra.api.addons.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Optional annotation that specifies platforms
* addon is made for.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Platform {
String[] value();
}
@@ -29,8 +29,12 @@ public class ExpressionSampler implements NoiseSampler {
functions.forEach((id, noise) -> {
switch(noise.getDimensions()) {
case 2 -> parser.registerFunction(id, new NoiseFunction2(noise.apply(seed)));
case 3 -> parser.registerFunction(id, new NoiseFunction3(noise.apply(seed)));
case 2:
parser.registerFunction(id, new NoiseFunction2(noise.apply(seed)));
break;
case 3:
parser.registerFunction(id, new NoiseFunction3(noise.apply(seed)));
break;
}
});
@@ -333,21 +333,36 @@ public class CellularSampler extends NoiseFunction {
}
}
return switch(returnType) {
case CellValue -> closestHash * (1 / 2147483648.0);
case Distance -> distance0 - 1;
case Distance2 -> distance1 - 1;
case Distance2Add -> (distance1 + distance0) * 0.5 - 1;
case Distance2Sub -> distance1 - distance0 - 1;
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.getNoise(center.getX(), center.getZ());
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
};
switch(returnType) {
case CellValue:
return closestHash * (1 / 2147483648.0);
case Distance:
return distance0 - 1;
case Distance2:
return distance1 - 1;
case Distance2Add:
return (distance1 + distance0) * 0.5 - 1;
case Distance2Sub:
return distance1 - distance0 - 1;
case Distance2Mul:
return distance1 * distance0 * 0.5 - 1;
case Distance2Div:
return distance0 / distance1 - 1;
case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getZ());
case Distance3:
return distance2 - 1;
case Distance3Add:
return (distance2 + distance0) * 0.5 - 1;
case Distance3Sub:
return distance2 - distance0 - 1;
case Distance3Mul:
return distance2 * distance0 - 1;
case Distance3Div:
return distance0 / distance2 - 1;
default:
return 0;
}
}
@Override
@@ -492,21 +507,36 @@ public class CellularSampler extends NoiseFunction {
}
}
return switch(returnType) {
case CellValue -> closestHash * (1 / 2147483648.0);
case Distance -> distance0 - 1;
case Distance2 -> distance1 - 1;
case Distance2Add -> (distance1 + distance0) * 0.5 - 1;
case Distance2Sub -> distance1 - distance0 - 1;
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.getNoise(center.getX(), center.getY(), center.getZ());
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
};
switch(returnType) {
case CellValue:
return closestHash * (1 / 2147483648.0);
case Distance:
return distance0 - 1;
case Distance2:
return distance1 - 1;
case Distance2Add:
return (distance1 + distance0) * 0.5 - 1;
case Distance2Sub:
return distance1 - distance0 - 1;
case Distance2Mul:
return distance1 * distance0 * 0.5 - 1;
case Distance2Div:
return distance0 / distance1 - 1;
case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getY(), center.getZ());
case Distance3:
return distance2 - 1;
case Distance3Add:
return (distance2 + distance0) * 0.5 - 1;
case Distance3Sub:
return distance2 - distance0 - 1;
case Distance3Mul:
return distance2 * distance0 - 1;
case Distance3Div:
return distance0 / distance2 - 1;
default:
return 0;
}
}
public enum DistanceFunction {
@@ -83,28 +83,66 @@ public enum BlockFace {
@NotNull
public BlockFace getOppositeFace() {
return switch(this) {
case NORTH -> BlockFace.SOUTH;
case SOUTH -> BlockFace.NORTH;
case EAST -> BlockFace.WEST;
case WEST -> BlockFace.EAST;
case UP -> BlockFace.DOWN;
case DOWN -> BlockFace.UP;
case NORTH_EAST -> BlockFace.SOUTH_WEST;
case NORTH_WEST -> BlockFace.SOUTH_EAST;
case SOUTH_EAST -> BlockFace.NORTH_WEST;
case SOUTH_WEST -> BlockFace.NORTH_EAST;
case WEST_NORTH_WEST -> BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_WEST -> BlockFace.SOUTH_SOUTH_EAST;
case NORTH_NORTH_EAST -> BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST -> BlockFace.WEST_SOUTH_WEST;
case EAST_SOUTH_EAST -> BlockFace.WEST_NORTH_WEST;
case SOUTH_SOUTH_EAST -> BlockFace.NORTH_NORTH_WEST;
case SOUTH_SOUTH_WEST -> BlockFace.NORTH_NORTH_EAST;
case WEST_SOUTH_WEST -> BlockFace.EAST_NORTH_EAST;
case SELF -> BlockFace.SELF;
};
switch(this) {
case NORTH:
return BlockFace.SOUTH;
case SOUTH:
return BlockFace.NORTH;
case EAST:
return BlockFace.WEST;
case WEST:
return BlockFace.EAST;
case UP:
return BlockFace.DOWN;
case DOWN:
return BlockFace.UP;
case NORTH_EAST:
return BlockFace.SOUTH_WEST;
case NORTH_WEST:
return BlockFace.SOUTH_EAST;
case SOUTH_EAST:
return BlockFace.NORTH_WEST;
case SOUTH_WEST:
return BlockFace.NORTH_EAST;
case WEST_NORTH_WEST:
return BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_WEST:
return BlockFace.SOUTH_SOUTH_EAST;
case NORTH_NORTH_EAST:
return BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST:
return BlockFace.WEST_SOUTH_WEST;
case EAST_SOUTH_EAST:
return BlockFace.WEST_NORTH_WEST;
case SOUTH_SOUTH_EAST:
return BlockFace.NORTH_NORTH_WEST;
case SOUTH_SOUTH_WEST:
return BlockFace.NORTH_NORTH_EAST;
case WEST_SOUTH_WEST:
return BlockFace.EAST_NORTH_EAST;
case SELF:
return BlockFace.SELF;
}
return BlockFace.SELF;
}
}
@@ -43,7 +43,8 @@ public class Entry {
if(entry.containsKey("functions")) {
for(Object function : (JSONArray) entry.get("functions")) {
switch(((String) ((JSONObject) function).get("function"))) {
case "minecraft:set_count", "set_count" -> {
case "minecraft:set_count":
case "set_count":
Object loot = ((JSONObject) function).get("count");
long max, min;
if(loot instanceof Long) {
@@ -54,20 +55,22 @@ public class Entry {
min = (long) ((JSONObject) loot).get("min");
}
functions.add(new AmountFunction(FastMath.toIntExact(min), FastMath.toIntExact(max)));
}
case "minecraft:set_damage", "set_damage" -> {
break;
case "minecraft:set_damage":
case "set_damage":
long maxDamage = (long) ((JSONObject) ((JSONObject) function).get("damage")).get("max");
long minDamage = (long) ((JSONObject) ((JSONObject) function).get("damage")).get("min");
functions.add(new DamageFunction(FastMath.toIntExact(minDamage), FastMath.toIntExact(maxDamage)));
}
case "minecraft:enchant_with_levels", "enchant_with_levels" -> {
break;
case "minecraft:enchant_with_levels":
case "enchant_with_levels":
long maxEnchant = (long) ((JSONObject) ((JSONObject) function).get("levels")).get("max");
long minEnchant = (long) ((JSONObject) ((JSONObject) function).get("levels")).get("min");
JSONArray disabled = null;
if(((JSONObject) function).containsKey("disabled_enchants"))
disabled = (JSONArray) ((JSONObject) function).get("disabled_enchants");
functions.add(new EnchantFunction(FastMath.toIntExact(minEnchant), FastMath.toIntExact(maxEnchant), disabled, main));
}
break;
}
}
}
@@ -96,12 +96,16 @@ public class Parser {
ParserUtil.checkType(tokens.consume(), Token.Type.GROUP_BEGIN);
return switch(identifier.getType()) {
case FOR_LOOP -> parseForLoop(tokens, variableMap, identifier.getPosition());
case IF_STATEMENT -> parseIfStatement(tokens, variableMap, identifier.getPosition(), loop);
case WHILE_LOOP -> parseWhileLoop(tokens, variableMap, identifier.getPosition());
default -> throw new UnsupportedOperationException("Unknown keyword " + identifier.getContent() + ": " + identifier.getPosition());
};
switch(identifier.getType()) {
case FOR_LOOP:
return parseForLoop(tokens, variableMap, identifier.getPosition());
case IF_STATEMENT:
return parseIfStatement(tokens, variableMap, identifier.getPosition(), loop);
case WHILE_LOOP:
return parseWhileLoop(tokens, variableMap, identifier.getPosition());
default:
throw new UnsupportedOperationException("Unknown keyword " + identifier.getContent() + ": " + identifier.getPosition());
}
}
private WhileKeyword parseWhileLoop(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap, Position start) throws ParseException {
@@ -229,13 +233,17 @@ public class Parser {
private ConstantExpression<?> parseConstantExpression(Tokenizer tokens) throws ParseException {
Token constantToken = tokens.consume();
Position position = constantToken.getPosition();
String content = constantToken.getContent();
return switch(constantToken.getType()) {
case NUMBER -> new NumericConstant(content.contains(".") ? Double.parseDouble(content) : Integer.parseInt(content), position);
case STRING -> new StringConstant(content, position);
case BOOLEAN -> new BooleanConstant(Boolean.parseBoolean(content), position);
default -> throw new UnsupportedOperationException("Unsupported constant token: " + constantToken.getType() + " at position: " + position);
};
switch(constantToken.getType()) {
case NUMBER:
String content = constantToken.getContent();
return new NumericConstant(content.contains(".") ? Double.parseDouble(content) : Integer.parseInt(content), position);
case STRING:
return new StringConstant(constantToken.getContent(), position);
case BOOLEAN:
return new BooleanConstant(Boolean.parseBoolean(constantToken.getContent()), position);
default:
throw new UnsupportedOperationException("Unsupported constant token: " + constantToken.getType() + " at position: " + position);
}
}
private Returnable<?> parseGroup(Tokenizer tokens, Map<String, Returnable.ReturnType> variableMap) throws ParseException {
@@ -79,12 +79,16 @@ public class ParserUtil {
}
public static Returnable.ReturnType getVariableReturnType(Token varToken) throws ParseException {
return switch(varToken.getType()) {
case NUMBER_VARIABLE -> Returnable.ReturnType.NUMBER;
case STRING_VARIABLE -> Returnable.ReturnType.STRING;
case BOOLEAN_VARIABLE -> Returnable.ReturnType.BOOLEAN;
default -> throw new ParseException("Unexpected token " + varToken.getType() + "; expected variable declaration", varToken.getPosition());
};
switch(varToken.getType()) {
case NUMBER_VARIABLE:
return Returnable.ReturnType.NUMBER;
case STRING_VARIABLE:
return Returnable.ReturnType.STRING;
case BOOLEAN_VARIABLE:
return Returnable.ReturnType.BOOLEAN;
default:
throw new ParseException("Unexpected token " + varToken.getType() + "; expected variable declaration", varToken.getPosition());
}
}
public static boolean hasPrecedence(Token.Type first, Token.Type second) {
@@ -32,9 +32,15 @@ public class Declaration<T> implements Item<T> {
public T apply(ImplementationArguments implementationArguments, Map<String, Variable<?>> variableMap) {
T result = value.apply(implementationArguments, variableMap);
switch(type) {
case NUMBER -> variableMap.put(identifier, new NumberVariable((Number) result, position));
case BOOLEAN -> variableMap.put(identifier, new BooleanVariable((Boolean) result, position));
case STRING -> variableMap.put(identifier, new StringVariable((String) result, position));
case NUMBER:
variableMap.put(identifier, new NumberVariable((Number) result, position));
break;
case BOOLEAN:
variableMap.put(identifier, new BooleanVariable((Boolean) result, position));
break;
case STRING:
variableMap.put(identifier, new StringVariable((String) result, position));
break;
}
return result;
}
@@ -28,9 +28,13 @@ public class BiomeFunctionBuilder implements FunctionBuilder<BiomeFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -39,11 +39,17 @@ public class BlockFunctionBuilder implements FunctionBuilder<AbstractBlockFuncti
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
case 4 -> Returnable.ReturnType.BOOLEAN;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
case 4:
return Returnable.ReturnType.BOOLEAN;
default:
return null;
}
}
}
@@ -21,9 +21,13 @@ public class CheckBlockFunctionBuilder implements FunctionBuilder<CheckBlockFunc
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -6,6 +6,7 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
import com.dfsek.terra.api.structures.tokenizer.Position;
import com.dfsek.terra.world.generation.math.SamplerCache;
import java.util.List;
@@ -29,9 +30,13 @@ public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -29,10 +29,15 @@ public class EntityFunctionBuilder implements FunctionBuilder<EntityFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
default:
return null;
}
}
}
@@ -25,9 +25,13 @@ public class GetMarkFunctionBuilder implements FunctionBuilder<GetMarkFunction>
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
}
@@ -34,10 +34,15 @@ public class LootFunctionBuilder implements FunctionBuilder<LootFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
default:
return null;
}
}
}
@@ -29,10 +29,15 @@ public class PullFunctionBuilder implements FunctionBuilder<PullFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
default:
return null;
}
}
}
@@ -26,10 +26,15 @@ public class SetMarkFunctionBuilder implements FunctionBuilder<SetMarkFunction>
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
default:
return null;
}
}
}
@@ -30,10 +30,15 @@ public class StateFunctionBuilder implements FunctionBuilder<StateFunction> {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
case 3 -> Returnable.ReturnType.STRING;
default -> null;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
case 3:
return Returnable.ReturnType.STRING;
default:
return null;
}
}
}
@@ -36,9 +36,13 @@ public class StructureFunctionBuilder implements FunctionBuilder<StructureFuncti
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0, 1, 2 -> Returnable.ReturnType.NUMBER;
default -> Returnable.ReturnType.STRING;
};
switch(position) {
case 0:
case 1:
case 2:
return Returnable.ReturnType.NUMBER;
default:
return Returnable.ReturnType.STRING;
}
}
}
@@ -12,13 +12,18 @@ public enum Rotation {
}
public static Rotation fromDegrees(int deg) {
return switch(FastMath.floorMod(deg, 360)) {
case 0 -> Rotation.NONE;
case 90 -> Rotation.CW_90;
case 180 -> Rotation.CW_180;
case 270 -> Rotation.CCW_90;
default -> throw new IllegalArgumentException();
};
switch(FastMath.floorMod(deg, 360)) {
case 0:
return Rotation.NONE;
case 90:
return Rotation.CW_90;
case 180:
return Rotation.CW_180;
case 270:
return Rotation.CCW_90;
default:
throw new IllegalArgumentException();
}
}
public int getDegrees() {
@@ -26,12 +31,18 @@ public enum Rotation {
}
public Rotation inverse() {
return switch(this) {
case NONE -> NONE;
case CCW_90 -> CW_90;
case CW_90 -> CCW_90;
case CW_180 -> CW_180;
};
switch(this) {
case NONE:
return NONE;
case CCW_90:
return CW_90;
case CW_90:
return CCW_90;
case CW_180:
return CW_180;
default:
throw new IllegalArgumentException();
}
}
public Rotation rotate(Rotation rotation) {
@@ -30,9 +30,15 @@ public class RotationUtil {
public static void rotateVector(Vector2 orig, Rotation r) {
Vector2 copy = orig.clone();
switch(r) {
case CW_90 -> copy.setX(orig.getZ()).setZ(-orig.getX());
case CCW_90 -> copy.setX(-orig.getZ()).setZ(orig.getX());
case CW_180 -> copy.multiply(-1);
case CW_90:
copy.setX(orig.getZ()).setZ(-orig.getX());
break;
case CCW_90:
copy.setX(-orig.getZ()).setZ(orig.getX());
break;
case CW_180:
copy.multiply(-1);
break;
}
orig.setX(copy.getX());
orig.setZ(copy.getZ());
@@ -62,25 +68,42 @@ public class RotationUtil {
* @return integer representation of BlockFace
*/
public static int faceRotation(BlockFace f) {
return switch(f) {
case NORTH -> 0;
case NORTH_NORTH_EAST -> 1;
case NORTH_EAST -> 2;
case EAST_NORTH_EAST -> 3;
case EAST -> 4;
case EAST_SOUTH_EAST -> 5;
case SOUTH_EAST -> 6;
case SOUTH_SOUTH_EAST -> 7;
case SOUTH -> 8;
case SOUTH_SOUTH_WEST -> 9;
case SOUTH_WEST -> 10;
case WEST_SOUTH_WEST -> 11;
case WEST -> 12;
case WEST_NORTH_WEST -> 13;
case NORTH_WEST -> 14;
case NORTH_NORTH_WEST -> 15;
default -> -1;
};
switch(f) {
case NORTH:
return 0;
case NORTH_NORTH_EAST:
return 1;
case NORTH_EAST:
return 2;
case EAST_NORTH_EAST:
return 3;
case EAST:
return 4;
case EAST_SOUTH_EAST:
return 5;
case SOUTH_EAST:
return 6;
case SOUTH_SOUTH_EAST:
return 7;
case SOUTH:
return 8;
case SOUTH_SOUTH_WEST:
return 9;
case SOUTH_WEST:
return 10;
case WEST_SOUTH_WEST:
return 11;
case WEST:
return 12;
case WEST_NORTH_WEST:
return 13;
case NORTH_WEST:
return 14;
case NORTH_NORTH_WEST:
return 15;
default:
return -1;
}
}
/**
@@ -90,25 +113,42 @@ public class RotationUtil {
* @return BlockFace represented by integer.
*/
public static BlockFace fromRotation(int r) {
return switch(FastMath.floorMod(r, 16)) {
case 0 -> BlockFace.NORTH;
case 1 -> BlockFace.NORTH_NORTH_EAST;
case 2 -> BlockFace.NORTH_EAST;
case 3 -> BlockFace.EAST_NORTH_EAST;
case 4 -> BlockFace.EAST;
case 5 -> BlockFace.EAST_SOUTH_EAST;
case 6 -> BlockFace.SOUTH_EAST;
case 7 -> BlockFace.SOUTH_SOUTH_EAST;
case 8 -> BlockFace.SOUTH;
case 9 -> BlockFace.SOUTH_SOUTH_WEST;
case 10 -> BlockFace.SOUTH_WEST;
case 11 -> BlockFace.WEST_SOUTH_WEST;
case 12 -> BlockFace.WEST;
case 13 -> BlockFace.WEST_NORTH_WEST;
case 14 -> BlockFace.NORTH_WEST;
case 15 -> BlockFace.NORTH_NORTH_WEST;
default -> throw new IllegalArgumentException();
};
switch(FastMath.floorMod(r, 16)) {
case 0:
return BlockFace.NORTH;
case 1:
return BlockFace.NORTH_NORTH_EAST;
case 2:
return BlockFace.NORTH_EAST;
case 3:
return BlockFace.EAST_NORTH_EAST;
case 4:
return BlockFace.EAST;
case 5:
return BlockFace.EAST_SOUTH_EAST;
case 6:
return BlockFace.SOUTH_EAST;
case 7:
return BlockFace.SOUTH_SOUTH_EAST;
case 8:
return BlockFace.SOUTH;
case 9:
return BlockFace.SOUTH_SOUTH_WEST;
case 10:
return BlockFace.SOUTH_WEST;
case 11:
return BlockFace.WEST_SOUTH_WEST;
case 12:
return BlockFace.WEST;
case 13:
return BlockFace.WEST_NORTH_WEST;
case 14:
return BlockFace.NORTH_WEST;
case 15:
return BlockFace.NORTH_NORTH_WEST;
default:
throw new IllegalArgumentException();
}
}
public static Axis getRotatedAxis(Axis orig, Rotation r) {
@@ -134,45 +174,78 @@ public class RotationUtil {
*/
@SuppressWarnings("fallthrough")
public static Rail.Shape getRotatedRail(Rail.Shape orig, Rotation r) {
return switch(r) {
case CCW_90 -> switch(orig) {
case NORTH_WEST -> Rail.Shape.SOUTH_WEST;
case NORTH_SOUTH -> Rail.Shape.EAST_WEST;
case SOUTH_WEST -> Rail.Shape.SOUTH_EAST;
case SOUTH_EAST -> Rail.Shape.NORTH_EAST;
case EAST_WEST -> Rail.Shape.NORTH_SOUTH;
case NORTH_EAST -> Rail.Shape.NORTH_WEST;
case ASCENDING_EAST -> Rail.Shape.ASCENDING_NORTH;
case ASCENDING_WEST -> Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_NORTH -> Rail.Shape.ASCENDING_WEST;
case ASCENDING_SOUTH -> Rail.Shape.ASCENDING_EAST;
};
case CW_90 -> switch(orig) {
case NORTH_WEST -> Rail.Shape.NORTH_EAST;
case NORTH_SOUTH -> Rail.Shape.EAST_WEST;
case SOUTH_WEST -> Rail.Shape.NORTH_WEST;
case SOUTH_EAST -> Rail.Shape.SOUTH_WEST;
case EAST_WEST -> Rail.Shape.NORTH_SOUTH;
case NORTH_EAST -> Rail.Shape.SOUTH_EAST;
case ASCENDING_EAST -> Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_WEST -> Rail.Shape.ASCENDING_NORTH;
case ASCENDING_NORTH -> Rail.Shape.ASCENDING_EAST;
case ASCENDING_SOUTH -> Rail.Shape.ASCENDING_WEST;
};
case CW_180 -> switch(orig) {
case NORTH_WEST -> Rail.Shape.SOUTH_EAST;
case NORTH_SOUTH -> Rail.Shape.NORTH_SOUTH;
case SOUTH_WEST -> Rail.Shape.NORTH_EAST;
case SOUTH_EAST -> Rail.Shape.NORTH_WEST;
case EAST_WEST -> Rail.Shape.EAST_WEST;
case NORTH_EAST -> Rail.Shape.SOUTH_WEST;
case ASCENDING_EAST -> Rail.Shape.ASCENDING_WEST;
case ASCENDING_WEST -> Rail.Shape.ASCENDING_EAST;
case ASCENDING_NORTH -> Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_SOUTH -> Rail.Shape.ASCENDING_NORTH;
};
default -> orig;
};
switch(r) {
case CCW_90:
switch(orig) {
case NORTH_WEST:
return Rail.Shape.SOUTH_WEST;
case NORTH_SOUTH:
return Rail.Shape.EAST_WEST;
case SOUTH_WEST:
return Rail.Shape.SOUTH_EAST;
case SOUTH_EAST:
return Rail.Shape.NORTH_EAST;
case EAST_WEST:
return Rail.Shape.NORTH_SOUTH;
case NORTH_EAST:
return Rail.Shape.NORTH_WEST;
case ASCENDING_EAST:
return Rail.Shape.ASCENDING_NORTH;
case ASCENDING_WEST:
return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_NORTH:
return Rail.Shape.ASCENDING_WEST;
case ASCENDING_SOUTH:
return Rail.Shape.ASCENDING_EAST;
}
case CW_90:
switch(orig) {
case NORTH_WEST:
return Rail.Shape.NORTH_EAST;
case NORTH_SOUTH:
return Rail.Shape.EAST_WEST;
case SOUTH_WEST:
return Rail.Shape.NORTH_WEST;
case SOUTH_EAST:
return Rail.Shape.SOUTH_WEST;
case EAST_WEST:
return Rail.Shape.NORTH_SOUTH;
case NORTH_EAST:
return Rail.Shape.SOUTH_EAST;
case ASCENDING_EAST:
return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_WEST:
return Rail.Shape.ASCENDING_NORTH;
case ASCENDING_NORTH:
return Rail.Shape.ASCENDING_EAST;
case ASCENDING_SOUTH:
return Rail.Shape.ASCENDING_WEST;
}
case CW_180:
switch(orig) {
case NORTH_WEST:
return Rail.Shape.SOUTH_EAST;
case NORTH_SOUTH:
return Rail.Shape.NORTH_SOUTH;
case SOUTH_WEST:
return Rail.Shape.NORTH_EAST;
case SOUTH_EAST:
return Rail.Shape.NORTH_WEST;
case EAST_WEST:
return Rail.Shape.EAST_WEST;
case NORTH_EAST:
return Rail.Shape.SOUTH_WEST;
case ASCENDING_EAST:
return Rail.Shape.ASCENDING_WEST;
case ASCENDING_WEST:
return Rail.Shape.ASCENDING_EAST;
case ASCENDING_NORTH:
return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_SOUTH:
return Rail.Shape.ASCENDING_NORTH;
}
}
return orig;
}
public static void rotateBlockData(BlockData data, Rotation r) {
@@ -60,8 +60,12 @@ public class UserDefinedCarver extends Carver {
functions.forEach((id, noise) -> {
switch(noise.getDimensions()) {
case 2 -> p.registerFunction(id, new NoiseFunction2(noise.apply(hash)));
case 3 -> p.registerFunction(id, new NoiseFunction3(noise.apply(hash)));
case 2:
p.registerFunction(id, new NoiseFunction2(noise.apply(hash)));
break;
case 3:
p.registerFunction(id, new NoiseFunction3(noise.apply(hash)));
break;
}
});
@@ -11,9 +11,12 @@ public class OreFactory implements ConfigFactory<OreTemplate, Ore> {
@Override
public Ore build(OreTemplate config, TerraPlugin main) {
BlockData m = config.getMaterial();
return switch(config.getType()) {
case SPHERE -> new DeformedSphereOre(m, config.getReplaceable(), config.doPhysics(), config.getDeform(), config.getDeformFrequency(), config.getSize(), main);
case VANILLA -> new VanillaOre(m, config.getReplaceable(), config.doPhysics(), config.getSize(), main);
};
switch(config.getType()) {
case SPHERE:
return new DeformedSphereOre(m, config.getReplaceable(), config.doPhysics(), config.getDeform(), config.getDeformFrequency(), config.getSize(), main);
case VANILLA:
return new VanillaOre(m, config.getReplaceable(), config.doPhysics(), config.getSize(), main);
}
return null;
}
}
@@ -21,10 +21,15 @@ public class BiomeProviderBuilderLoader implements TypeLoader<BiomeProvider.Biom
public BiomeProvider.BiomeProviderBuilder load(Type t, Object c, ConfigLoader loader) throws LoadException { // TODO: clean this up
Map<String, Object> map = (Map<String, Object>) c;
return switch(loader.loadClass(BiomeProvider.Type.class, map.get("type"))) {
case IMAGE -> loader.loadClass(ImageProviderTemplate.class, map);
case PIPELINE -> loader.loadClass(BiomePipelineTemplate.class, map);
case SINGLE -> loader.loadClass(SingleBiomeProviderTemplate.class, map);
};
switch(loader.loadClass(BiomeProvider.Type.class, map.get("type"))) {
case IMAGE:
return loader.loadClass(ImageProviderTemplate.class, map);
case PIPELINE:
return loader.loadClass(BiomePipelineTemplate.class, map);
case SINGLE:
return loader.loadClass(SingleBiomeProviderTemplate.class, map);
}
throw new LoadException("No such biome provider type: " + map.get("type"));
}
}
@@ -38,13 +38,20 @@ public class StageBuilderLoader implements TypeLoader<StageSeeded> {
return loader.loadClass(ExpanderStageTemplate.class, mutator);
} else throw new LoadException("No such expander \"" + stageType + "\"");
} else if(entry.getKey().equals("mutate")) {
return switch(loader.loadClass(MutatorStage.Type.class, mutator.get("type"))) {
case SMOOTH -> loader.loadClass(SmoothMutatorTemplate.class, mutator);
case REPLACE -> loader.loadClass(ReplaceMutatorTemplate.class, mutator);
case REPLACE_LIST -> loader.loadClass(ReplaceListMutatorTemplate.class, mutator);
case BORDER -> loader.loadClass(BorderMutatorTemplate.class, mutator);
case BORDER_LIST -> loader.loadClass(BorderListMutatorTemplate.class, mutator);
};
switch(loader.loadClass(MutatorStage.Type.class, mutator.get("type"))) {
case SMOOTH:
return loader.loadClass(SmoothMutatorTemplate.class, mutator);
case REPLACE:
return loader.loadClass(ReplaceMutatorTemplate.class, mutator);
case REPLACE_LIST:
return loader.loadClass(ReplaceListMutatorTemplate.class, mutator);
case BORDER:
return loader.loadClass(BorderMutatorTemplate.class, mutator);
case BORDER_LIST:
return loader.loadClass(BorderListMutatorTemplate.class, mutator);
default:
throw new LoadException("No such mutator type \"" + mutator.get("type"));
}
}
throw new LoadException("No such mutator \"" + entry.getKey() + "\"");
}
@@ -6,6 +6,7 @@ import com.dfsek.terra.addon.PreLoadAddon;
import com.dfsek.terra.addon.exception.AddonLoadException;
import com.dfsek.terra.api.TerraPlugin;
import com.dfsek.terra.api.addons.TerraAddon;
import com.dfsek.terra.api.addons.annotations.Platform;
import com.dfsek.terra.api.injection.Injector;
import com.dfsek.terra.api.injection.exception.InjectionException;
import com.dfsek.terra.registry.OpenRegistry;
@@ -15,6 +16,8 @@ import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.LogManager;
import java.util.logging.Logger;
@@ -66,6 +69,12 @@ public class AddonRegistry extends OpenRegistry<TerraAddon> {
for(PreLoadAddon addon : pool.getAddons()) {
Class<? extends TerraAddon> addonClass = addon.getAddonClass();
if(addonClass.isAnnotationPresent(Platform.class)) {
List<String> platforms = Arrays.asList(addonClass.getAnnotation(Platform.class).value());
if(!platforms.contains(main.platformName())) throw new AddonLoadException("Addon \"" + addon.getId() + "\" cannot run on platform " + main.platformName() + ". Allowed platforms: " + platforms);
}
Constructor<? extends TerraAddon> constructor;
String logPrefix = "Terra:" + addon.getId();
@@ -36,11 +36,14 @@ public class ParserTest {
@Override
public Returnable.ReturnType getArgument(int position) {
return switch(position) {
case 0 -> Returnable.ReturnType.STRING;
case 1 -> Returnable.ReturnType.NUMBER;
default -> null;
};
switch(position) {
case 0:
return Returnable.ReturnType.STRING;
case 1:
return Returnable.ReturnType.NUMBER;
default:
return null;
}
}
});
+1 -6
View File
@@ -7,9 +7,4 @@ org.gradle.parallel=true
org.gradle.caching=true
org.gradle.warning.mode=all
#org.gradle.logging.level=info
# Project information
terra.description=A fast, modern, extensible, platform-agnostic data-driven world generator
terra.source=https://github.com/PolyhedralDev/Terra
terra.issues=https://github.com/PolyhedralDev/Terra/issues
terra.wiki=https://github.com/PolyhedralDev/Terra/wiki
terra.license=GNU General Public License, version 3.0
org.gradle.configureondemand=true
@@ -19,6 +19,7 @@ public class PaperListener implements Listener {
@EventHandler
public void onStructureLocate(StructureLocateEvent e) {
if(!BukkitAdapter.adapt(e.getWorld()).isTerraWorld()) return;
e.setResult(null); // Assume no result.
String name = "minecraft:" + e.getType().getName();
main.getDebugLogger().info("Overriding structure location for \"" + name + "\"");
TerraWorld tw = main.getWorld(BukkitAdapter.adapt(e.getWorld()));
@@ -31,8 +32,10 @@ public class PaperListener implements Listener {
}, main);
finder.run(); // Do this synchronously.
} else {
e.setResult(e.getOrigin());
main.logger().warning("No overrides are defined for \"" + name + "\". Locating this structure will NOT work properly!");
main.logger().warning("No overrides are defined for \"" + name + "\"");
}
}
}
@@ -50,13 +50,20 @@ public final class BukkitAdapter {
public static Stairs.Shape adapt(org.bukkit.block.data.type.Stairs.Shape shape) {
return switch(shape) {
case STRAIGHT -> Stairs.Shape.STRAIGHT;
case INNER_LEFT -> Stairs.Shape.INNER_LEFT;
case OUTER_LEFT -> Stairs.Shape.OUTER_LEFT;
case INNER_RIGHT -> Stairs.Shape.INNER_RIGHT;
case OUTER_RIGHT -> Stairs.Shape.OUTER_RIGHT;
};
switch(shape) {
case STRAIGHT:
return Stairs.Shape.STRAIGHT;
case INNER_LEFT:
return Stairs.Shape.INNER_LEFT;
case OUTER_LEFT:
return Stairs.Shape.OUTER_LEFT;
case INNER_RIGHT:
return Stairs.Shape.INNER_RIGHT;
case OUTER_RIGHT:
return Stairs.Shape.OUTER_RIGHT;
default:
throw new IllegalStateException();
}
}
public static BlockData adapt(org.bukkit.block.data.BlockData data) {
@@ -68,154 +75,265 @@ public final class BukkitAdapter {
}
public static Axis adapt(org.bukkit.Axis axis) {
return switch(axis) {
case X -> Axis.X;
case Y -> Axis.Y;
case Z -> Axis.Z;
};
switch(axis) {
case X:
return Axis.X;
case Y:
return Axis.Y;
case Z:
return Axis.Z;
default:
throw new IllegalStateException();
}
}
public static Bisected.Half adapt(org.bukkit.block.data.Bisected.Half half) {
return switch(half) {
case BOTTOM -> Bisected.Half.BOTTOM;
case TOP -> Bisected.Half.TOP;
};
switch(half) {
case BOTTOM:
return Bisected.Half.BOTTOM;
case TOP:
return Bisected.Half.TOP;
default:
throw new IllegalStateException();
}
}
public static BlockFace adapt(org.bukkit.block.BlockFace face) {
return switch(face) {
case DOWN -> BlockFace.DOWN;
case UP -> BlockFace.UP;
case NORTH_WEST -> BlockFace.NORTH_WEST;
case NORTH_EAST -> BlockFace.NORTH_EAST;
case SOUTH_EAST -> BlockFace.SOUTH_EAST;
case SOUTH_WEST -> BlockFace.SOUTH_WEST;
case NORTH_NORTH_WEST -> BlockFace.NORTH_NORTH_WEST;
case WEST_NORTH_WEST -> BlockFace.WEST_NORTH_WEST;
case WEST_SOUTH_WEST -> BlockFace.WEST_SOUTH_WEST;
case SOUTH_SOUTH_WEST -> BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST -> BlockFace.EAST_NORTH_EAST;
case WEST -> BlockFace.WEST;
case SOUTH -> BlockFace.SOUTH;
case EAST -> BlockFace.EAST;
case NORTH -> BlockFace.NORTH;
case SELF -> BlockFace.SELF;
case EAST_SOUTH_EAST -> BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_EAST -> BlockFace.NORTH_NORTH_EAST;
case SOUTH_SOUTH_EAST -> BlockFace.SOUTH_SOUTH_EAST;
};
switch(face) {
case DOWN:
return BlockFace.DOWN;
case UP:
return BlockFace.UP;
case NORTH_WEST:
return BlockFace.NORTH_WEST;
case NORTH_EAST:
return BlockFace.NORTH_EAST;
case SOUTH_EAST:
return BlockFace.SOUTH_EAST;
case SOUTH_WEST:
return BlockFace.SOUTH_WEST;
case NORTH_NORTH_WEST:
return BlockFace.NORTH_NORTH_WEST;
case WEST_NORTH_WEST:
return BlockFace.WEST_NORTH_WEST;
case WEST_SOUTH_WEST:
return BlockFace.WEST_SOUTH_WEST;
case SOUTH_SOUTH_WEST:
return BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST:
return BlockFace.EAST_NORTH_EAST;
case WEST:
return BlockFace.WEST;
case SOUTH:
return BlockFace.SOUTH;
case EAST:
return BlockFace.EAST;
case NORTH:
return BlockFace.NORTH;
case SELF:
return BlockFace.SELF;
case EAST_SOUTH_EAST:
return BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_EAST:
return BlockFace.NORTH_NORTH_EAST;
case SOUTH_SOUTH_EAST:
return BlockFace.SOUTH_SOUTH_EAST;
default:
throw new IllegalStateException();
}
}
public static Slab.Type adapt(org.bukkit.block.data.type.Slab.Type type) {
return switch(type) {
case BOTTOM -> Slab.Type.BOTTOM;
case TOP -> Slab.Type.TOP;
case DOUBLE -> Slab.Type.DOUBLE;
};
switch(type) {
case BOTTOM:
return Slab.Type.BOTTOM;
case TOP:
return Slab.Type.TOP;
case DOUBLE:
return Slab.Type.DOUBLE;
default:
throw new IllegalStateException();
}
}
public static RedstoneWire.Connection adapt(org.bukkit.block.data.type.RedstoneWire.Connection connection) {
return switch(connection) {
case NONE -> RedstoneWire.Connection.NONE;
case UP -> RedstoneWire.Connection.UP;
case SIDE -> RedstoneWire.Connection.SIDE;
};
switch(connection) {
case NONE:
return RedstoneWire.Connection.NONE;
case UP:
return RedstoneWire.Connection.UP;
case SIDE:
return RedstoneWire.Connection.SIDE;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.data.type.RedstoneWire.Connection adapt(RedstoneWire.Connection connection) {
return switch(connection) {
case SIDE -> org.bukkit.block.data.type.RedstoneWire.Connection.SIDE;
case UP -> org.bukkit.block.data.type.RedstoneWire.Connection.UP;
case NONE -> org.bukkit.block.data.type.RedstoneWire.Connection.NONE;
};
switch(connection) {
case SIDE:
return org.bukkit.block.data.type.RedstoneWire.Connection.SIDE;
case UP:
return org.bukkit.block.data.type.RedstoneWire.Connection.UP;
case NONE:
return org.bukkit.block.data.type.RedstoneWire.Connection.NONE;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.data.type.Stairs.Shape adapt(Stairs.Shape shape) {
return switch(shape) {
case STRAIGHT -> org.bukkit.block.data.type.Stairs.Shape.STRAIGHT;
case INNER_LEFT -> org.bukkit.block.data.type.Stairs.Shape.INNER_LEFT;
case OUTER_LEFT -> org.bukkit.block.data.type.Stairs.Shape.OUTER_LEFT;
case INNER_RIGHT -> org.bukkit.block.data.type.Stairs.Shape.INNER_RIGHT;
case OUTER_RIGHT -> org.bukkit.block.data.type.Stairs.Shape.OUTER_RIGHT;
};
switch(shape) {
case STRAIGHT:
return org.bukkit.block.data.type.Stairs.Shape.STRAIGHT;
case INNER_LEFT:
return org.bukkit.block.data.type.Stairs.Shape.INNER_LEFT;
case OUTER_LEFT:
return org.bukkit.block.data.type.Stairs.Shape.OUTER_LEFT;
case INNER_RIGHT:
return org.bukkit.block.data.type.Stairs.Shape.INNER_RIGHT;
case OUTER_RIGHT:
return org.bukkit.block.data.type.Stairs.Shape.OUTER_RIGHT;
default:
throw new IllegalStateException();
}
}
public static Rail.Shape adapt(org.bukkit.block.data.Rail.Shape shape) {
return switch(shape) {
case SOUTH_WEST -> Rail.Shape.SOUTH_WEST;
case SOUTH_EAST -> Rail.Shape.SOUTH_EAST;
case NORTH_EAST -> Rail.Shape.NORTH_EAST;
case NORTH_WEST -> Rail.Shape.NORTH_WEST;
case ASCENDING_EAST -> Rail.Shape.ASCENDING_EAST;
case ASCENDING_WEST -> Rail.Shape.ASCENDING_WEST;
case ASCENDING_SOUTH -> Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_NORTH -> Rail.Shape.ASCENDING_NORTH;
case NORTH_SOUTH -> Rail.Shape.NORTH_SOUTH;
case EAST_WEST -> Rail.Shape.EAST_WEST;
};
switch(shape) {
case SOUTH_WEST:
return Rail.Shape.SOUTH_WEST;
case SOUTH_EAST:
return Rail.Shape.SOUTH_EAST;
case NORTH_EAST:
return Rail.Shape.NORTH_EAST;
case NORTH_WEST:
return Rail.Shape.NORTH_WEST;
case ASCENDING_EAST:
return Rail.Shape.ASCENDING_EAST;
case ASCENDING_WEST:
return Rail.Shape.ASCENDING_WEST;
case ASCENDING_SOUTH:
return Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_NORTH:
return Rail.Shape.ASCENDING_NORTH;
case NORTH_SOUTH:
return Rail.Shape.NORTH_SOUTH;
case EAST_WEST:
return Rail.Shape.EAST_WEST;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.data.Rail.Shape adapt(Rail.Shape shape) {
return switch(shape) {
case EAST_WEST -> org.bukkit.block.data.Rail.Shape.EAST_WEST;
case NORTH_SOUTH -> org.bukkit.block.data.Rail.Shape.NORTH_SOUTH;
case ASCENDING_NORTH -> org.bukkit.block.data.Rail.Shape.ASCENDING_NORTH;
case ASCENDING_SOUTH -> org.bukkit.block.data.Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_WEST -> org.bukkit.block.data.Rail.Shape.ASCENDING_WEST;
case ASCENDING_EAST -> org.bukkit.block.data.Rail.Shape.ASCENDING_EAST;
case NORTH_WEST -> org.bukkit.block.data.Rail.Shape.NORTH_WEST;
case NORTH_EAST -> org.bukkit.block.data.Rail.Shape.NORTH_EAST;
case SOUTH_EAST -> org.bukkit.block.data.Rail.Shape.SOUTH_EAST;
case SOUTH_WEST -> org.bukkit.block.data.Rail.Shape.SOUTH_WEST;
};
switch(shape) {
case EAST_WEST:
return org.bukkit.block.data.Rail.Shape.EAST_WEST;
case NORTH_SOUTH:
return org.bukkit.block.data.Rail.Shape.NORTH_SOUTH;
case ASCENDING_NORTH:
return org.bukkit.block.data.Rail.Shape.ASCENDING_NORTH;
case ASCENDING_SOUTH:
return org.bukkit.block.data.Rail.Shape.ASCENDING_SOUTH;
case ASCENDING_WEST:
return org.bukkit.block.data.Rail.Shape.ASCENDING_WEST;
case ASCENDING_EAST:
return org.bukkit.block.data.Rail.Shape.ASCENDING_EAST;
case NORTH_WEST:
return org.bukkit.block.data.Rail.Shape.NORTH_WEST;
case NORTH_EAST:
return org.bukkit.block.data.Rail.Shape.NORTH_EAST;
case SOUTH_EAST:
return org.bukkit.block.data.Rail.Shape.SOUTH_EAST;
case SOUTH_WEST:
return org.bukkit.block.data.Rail.Shape.SOUTH_WEST;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.data.Bisected.Half adapt(Bisected.Half half) {
return switch(half) {
case TOP -> org.bukkit.block.data.Bisected.Half.TOP;
case BOTTOM -> org.bukkit.block.data.Bisected.Half.BOTTOM;
};
switch(half) {
case TOP:
return org.bukkit.block.data.Bisected.Half.TOP;
case BOTTOM:
return org.bukkit.block.data.Bisected.Half.BOTTOM;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.Axis adapt(Axis axis) {
return switch(axis) {
case Z -> org.bukkit.Axis.Z;
case Y -> org.bukkit.Axis.Y;
case X -> org.bukkit.Axis.X;
};
switch(axis) {
case Z:
return org.bukkit.Axis.Z;
case Y:
return org.bukkit.Axis.Y;
case X:
return org.bukkit.Axis.X;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.BlockFace adapt(BlockFace face) {
return switch(face) {
case DOWN -> org.bukkit.block.BlockFace.DOWN;
case UP -> org.bukkit.block.BlockFace.UP;
case NORTH_WEST -> org.bukkit.block.BlockFace.NORTH_WEST;
case NORTH_EAST -> org.bukkit.block.BlockFace.NORTH_EAST;
case SOUTH_EAST -> org.bukkit.block.BlockFace.SOUTH_EAST;
case SOUTH_WEST -> org.bukkit.block.BlockFace.SOUTH_WEST;
case NORTH_NORTH_WEST -> org.bukkit.block.BlockFace.NORTH_NORTH_WEST;
case WEST_NORTH_WEST -> org.bukkit.block.BlockFace.WEST_NORTH_WEST;
case WEST_SOUTH_WEST -> org.bukkit.block.BlockFace.WEST_SOUTH_WEST;
case SOUTH_SOUTH_WEST -> org.bukkit.block.BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST -> org.bukkit.block.BlockFace.EAST_NORTH_EAST;
case WEST -> org.bukkit.block.BlockFace.WEST;
case SOUTH -> org.bukkit.block.BlockFace.SOUTH;
case EAST -> org.bukkit.block.BlockFace.EAST;
case NORTH -> org.bukkit.block.BlockFace.NORTH;
case SELF -> org.bukkit.block.BlockFace.SELF;
case EAST_SOUTH_EAST -> org.bukkit.block.BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_EAST -> org.bukkit.block.BlockFace.NORTH_NORTH_EAST;
case SOUTH_SOUTH_EAST -> org.bukkit.block.BlockFace.SOUTH_SOUTH_EAST;
};
switch(face) {
case DOWN:
return org.bukkit.block.BlockFace.DOWN;
case UP:
return org.bukkit.block.BlockFace.UP;
case NORTH_WEST:
return org.bukkit.block.BlockFace.NORTH_WEST;
case NORTH_EAST:
return org.bukkit.block.BlockFace.NORTH_EAST;
case SOUTH_EAST:
return org.bukkit.block.BlockFace.SOUTH_EAST;
case SOUTH_WEST:
return org.bukkit.block.BlockFace.SOUTH_WEST;
case NORTH_NORTH_WEST:
return org.bukkit.block.BlockFace.NORTH_NORTH_WEST;
case WEST_NORTH_WEST:
return org.bukkit.block.BlockFace.WEST_NORTH_WEST;
case WEST_SOUTH_WEST:
return org.bukkit.block.BlockFace.WEST_SOUTH_WEST;
case SOUTH_SOUTH_WEST:
return org.bukkit.block.BlockFace.SOUTH_SOUTH_WEST;
case EAST_NORTH_EAST:
return org.bukkit.block.BlockFace.EAST_NORTH_EAST;
case WEST:
return org.bukkit.block.BlockFace.WEST;
case SOUTH:
return org.bukkit.block.BlockFace.SOUTH;
case EAST:
return org.bukkit.block.BlockFace.EAST;
case NORTH:
return org.bukkit.block.BlockFace.NORTH;
case SELF:
return org.bukkit.block.BlockFace.SELF;
case EAST_SOUTH_EAST:
return org.bukkit.block.BlockFace.EAST_SOUTH_EAST;
case NORTH_NORTH_EAST:
return org.bukkit.block.BlockFace.NORTH_NORTH_EAST;
case SOUTH_SOUTH_EAST:
return org.bukkit.block.BlockFace.SOUTH_SOUTH_EAST;
default:
throw new IllegalStateException();
}
}
public static org.bukkit.block.data.type.Slab.Type adapt(Slab.Type type) {
return switch(type) {
case TOP -> org.bukkit.block.data.type.Slab.Type.TOP;
case DOUBLE -> org.bukkit.block.data.type.Slab.Type.DOUBLE;
case BOTTOM -> org.bukkit.block.data.type.Slab.Type.BOTTOM;
};
switch(type) {
case TOP:
return org.bukkit.block.data.type.Slab.Type.TOP;
case DOUBLE:
return org.bukkit.block.data.type.Slab.Type.DOUBLE;
case BOTTOM:
return org.bukkit.block.data.type.Slab.Type.BOTTOM;
default:
throw new IllegalStateException();
}
}
public static Location adapt(com.dfsek.terra.api.math.vector.Location location) {
@@ -24,15 +24,21 @@ public class BukkitTree implements Tree {
private MaterialSet getSpawnable(TreeType type) {
WorldHandle handle = main.getWorldHandle();
return switch(type) {
case CRIMSON_FUNGUS -> MaterialSet.get(handle.createBlockData("minecraft:crimson_nylium"));
case WARPED_FUNGUS -> MaterialSet.get(handle.createBlockData("minecraft:warped_nylium"));
case BROWN_MUSHROOM, RED_MUSHROOM -> MaterialSet.get(handle.createBlockData("minecraft:mycelium"), handle.createBlockData("minecraft:grass_block"),
handle.createBlockData("minecraft:podzol"));
case CHORUS_PLANT -> MaterialSet.get(handle.createBlockData("minecraft:end_stone"));
default -> MaterialSet.get(handle.createBlockData("minecraft:grass_block"), handle.createBlockData("minecraft:dirt"),
handle.createBlockData("minecraft:podzol"));
};
switch(type) {
case CRIMSON_FUNGUS:
return MaterialSet.get(handle.createBlockData("minecraft:crimson_nylium"));
case WARPED_FUNGUS:
return MaterialSet.get(handle.createBlockData("minecraft:warped_nylium"));
case BROWN_MUSHROOM:
case RED_MUSHROOM:
return MaterialSet.get(handle.createBlockData("minecraft:mycelium"), handle.createBlockData("minecraft:grass_block"),
handle.createBlockData("minecraft:podzol"));
case CHORUS_PLANT:
return MaterialSet.get(handle.createBlockData("minecraft:end_stone"));
default:
return MaterialSet.get(handle.createBlockData("minecraft:grass_block"), handle.createBlockData("minecraft:dirt"),
handle.createBlockData("minecraft:podzol"));
}
}
@Override
@@ -20,19 +20,29 @@ public class BukkitWall extends BukkitWaterlogged implements Wall {
}
public static org.bukkit.block.data.type.Wall.Height adapt(com.dfsek.terra.api.platform.block.data.Wall.Height height) {
return switch(height) {
case NONE -> org.bukkit.block.data.type.Wall.Height.NONE;
case LOW -> org.bukkit.block.data.type.Wall.Height.LOW;
case TALL -> org.bukkit.block.data.type.Wall.Height.TALL;
};
switch(height) {
case NONE:
return org.bukkit.block.data.type.Wall.Height.NONE;
case LOW:
return org.bukkit.block.data.type.Wall.Height.LOW;
case TALL:
return org.bukkit.block.data.type.Wall.Height.TALL;
default:
throw new IllegalStateException();
}
}
public static com.dfsek.terra.api.platform.block.data.Wall.Height adapt(org.bukkit.block.data.type.Wall.Height height) {
return switch(height) {
case TALL -> Height.TALL;
case LOW -> Height.LOW;
case NONE -> Height.NONE;
};
switch(height) {
case TALL:
return com.dfsek.terra.api.platform.block.data.Wall.Height.TALL;
case LOW:
return com.dfsek.terra.api.platform.block.data.Wall.Height.LOW;
case NONE:
return com.dfsek.terra.api.platform.block.data.Wall.Height.NONE;
default:
throw new IllegalStateException();
}
}
@Override
@@ -96,15 +96,32 @@ public class BukkitMobSpawner extends BukkitBlockState implements MobSpawner {
public void applyState(String state) {
SerialState.parse(state).forEach((k, v) -> {
switch(k) {
case "type" -> setSpawnedType(new BukkitEntityType(org.bukkit.entity.EntityType.valueOf(v.toUpperCase())));
case "delay" -> setDelay(Integer.parseInt(v));
case "min_delay" -> setMinSpawnDelay(Integer.parseInt(v));
case "max_delay" -> setMaxSpawnDelay(Integer.parseInt(v));
case "spawn_count" -> setSpawnCount(Integer.parseInt(v));
case "spawn_range" -> setSpawnRange(Integer.parseInt(v));
case "max_nearby" -> setMaxNearbyEntities(Integer.parseInt(v));
case "required_player_range" -> setRequiredPlayerRange(Integer.parseInt(v));
default -> throw new IllegalArgumentException("Invalid property: " + k);
case "type":
setSpawnedType(new BukkitEntityType(org.bukkit.entity.EntityType.valueOf(v.toUpperCase())));
return;
case "delay":
setDelay(Integer.parseInt(v));
return;
case "min_delay":
setMinSpawnDelay(Integer.parseInt(v));
return;
case "max_delay":
setMaxSpawnDelay(Integer.parseInt(v));
return;
case "spawn_count":
setSpawnCount(Integer.parseInt(v));
return;
case "spawn_range":
setSpawnRange(Integer.parseInt(v));
return;
case "max_nearby":
setMaxNearbyEntities(Integer.parseInt(v));
return;
case "required_player_range":
setRequiredPlayerRange(Integer.parseInt(v));
return;
default:
throw new IllegalArgumentException("Invalid property: " + k);
}
});
}
@@ -3,13 +3,16 @@ main: "com.dfsek.terra.bukkit.TerraBukkitPlugin"
version: "@VERSION@"
load: "STARTUP"
author: dfsek
website: "@WIKI@"
api-version: "1.13"
description: "@DESCRIPTION@"
description: "An insanely powerful free & open-source data-driven world generator."
softdepend: [ "WorldEdit" ]
commands:
terra:
description: "Terra base command"
usage: "/terra "
aliases: [ "te" ]
permission: "terra.command"
permission: "terra.command"
locate:
description: "Locate a Terra Structure"
usage: "/locate <STRUCTURE_ID> <radius>"
permission: "terra.locate"
-8
View File
@@ -28,14 +28,6 @@ dependencies {
"modImplementation"("net.fabricmc:fabric-loader:0.11.2")
"modImplementation"("net.fabricmc.fabric-api:fabric-api:0.31.0+1.16")
"modCompileOnly"("com.sk89q.worldedit:worldedit-fabric-mc1.16:7.2.0-SNAPSHOT") {
exclude(group = "com.google.guava", module = "guava")
exclude(group = "com.google.code.gson", module = "gson")
exclude(group = "it.unimi.dsi", module = "fastutil")
exclude(group = "org.apache.logging.log4j", module = "log4j-api")
exclude(group = "org.apache.logging.log4j", module = "log4j-core")
}
}
@@ -1,4 +1,4 @@
package com.dfsek.terra.fabric.util;
package com.dfsek.terra.fabric;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.block.Axis;
@@ -62,15 +62,22 @@ public final class FabricAdapter {
}
public static Direction adapt(BlockFace face) {
return switch(face) {
case NORTH -> Direction.NORTH;
case WEST -> Direction.WEST;
case SOUTH -> Direction.SOUTH;
case EAST -> Direction.EAST;
case UP -> Direction.UP;
case DOWN -> Direction.DOWN;
default -> throw new IllegalArgumentException("Illegal direction: " + face);
};
switch(face) {
case NORTH:
return Direction.NORTH;
case WEST:
return Direction.WEST;
case SOUTH:
return Direction.SOUTH;
case EAST:
return Direction.EAST;
case UP:
return Direction.UP;
case DOWN:
return Direction.DOWN;
default:
throw new IllegalArgumentException("Illegal direction: " + face);
}
}
@@ -89,79 +96,129 @@ public final class FabricAdapter {
}
public static Stairs.Shape adapt(StairShape shape) {
return switch(shape) {
case OUTER_RIGHT -> Stairs.Shape.OUTER_RIGHT;
case INNER_RIGHT -> Stairs.Shape.INNER_RIGHT;
case OUTER_LEFT -> Stairs.Shape.OUTER_LEFT;
case INNER_LEFT -> Stairs.Shape.INNER_LEFT;
case STRAIGHT -> Stairs.Shape.STRAIGHT;
};
switch(shape) {
case OUTER_RIGHT:
return Stairs.Shape.OUTER_RIGHT;
case INNER_RIGHT:
return Stairs.Shape.INNER_RIGHT;
case OUTER_LEFT:
return Stairs.Shape.OUTER_LEFT;
case INNER_LEFT:
return Stairs.Shape.INNER_LEFT;
case STRAIGHT:
return Stairs.Shape.STRAIGHT;
default:
throw new IllegalStateException();
}
}
public static Bisected.Half adapt(BlockHalf half) {
return switch(half) {
case BOTTOM -> Bisected.Half.BOTTOM;
case TOP -> Bisected.Half.TOP;
};
switch(half) {
case BOTTOM:
return Bisected.Half.BOTTOM;
case TOP:
return Bisected.Half.TOP;
default:
throw new IllegalStateException();
}
}
public static BlockFace adapt(Direction direction) {
return switch(direction) {
case DOWN -> BlockFace.DOWN;
case UP -> BlockFace.UP;
case WEST -> BlockFace.WEST;
case EAST -> BlockFace.EAST;
case NORTH -> BlockFace.NORTH;
case SOUTH -> BlockFace.SOUTH;
};
switch(direction) {
case DOWN:
return BlockFace.DOWN;
case UP:
return BlockFace.UP;
case WEST:
return BlockFace.WEST;
case EAST:
return BlockFace.EAST;
case NORTH:
return BlockFace.NORTH;
case SOUTH:
return BlockFace.SOUTH;
default:
throw new IllegalStateException();
}
}
public static Slab.Type adapt(SlabType type) {
return switch(type) {
case BOTTOM -> Slab.Type.BOTTOM;
case TOP -> Slab.Type.TOP;
case DOUBLE -> Slab.Type.DOUBLE;
};
switch(type) {
case BOTTOM:
return Slab.Type.BOTTOM;
case TOP:
return Slab.Type.TOP;
case DOUBLE:
return Slab.Type.DOUBLE;
default:
throw new IllegalStateException();
}
}
public static StairShape adapt(Stairs.Shape shape) {
return switch(shape) {
case STRAIGHT -> StairShape.STRAIGHT;
case INNER_LEFT -> StairShape.INNER_LEFT;
case OUTER_LEFT -> StairShape.OUTER_LEFT;
case INNER_RIGHT -> StairShape.INNER_RIGHT;
case OUTER_RIGHT -> StairShape.OUTER_RIGHT;
};
switch(shape) {
case STRAIGHT:
return StairShape.STRAIGHT;
case INNER_LEFT:
return StairShape.INNER_LEFT;
case OUTER_LEFT:
return StairShape.OUTER_LEFT;
case INNER_RIGHT:
return StairShape.INNER_RIGHT;
case OUTER_RIGHT:
return StairShape.OUTER_RIGHT;
default:
throw new IllegalStateException();
}
}
public static BlockHalf adapt(Bisected.Half half) {
return switch(half) {
case TOP -> BlockHalf.TOP;
case BOTTOM -> BlockHalf.BOTTOM;
};
switch(half) {
case TOP:
return BlockHalf.TOP;
case BOTTOM:
return BlockHalf.BOTTOM;
default:
throw new IllegalStateException();
}
}
public static SlabType adapt(Slab.Type type) {
return switch(type) {
case DOUBLE -> SlabType.DOUBLE;
case TOP -> SlabType.TOP;
case BOTTOM -> SlabType.BOTTOM;
};
switch(type) {
case DOUBLE:
return SlabType.DOUBLE;
case TOP:
return SlabType.TOP;
case BOTTOM:
return SlabType.BOTTOM;
default:
throw new IllegalStateException();
}
}
public static Axis adapt(Direction.Axis axis) {
return switch(axis) {
case X -> Axis.X;
case Y -> Axis.Y;
case Z -> Axis.Z;
};
switch(axis) {
case X:
return Axis.X;
case Y:
return Axis.Y;
case Z:
return Axis.Z;
default:
throw new IllegalStateException();
}
}
public static Direction.Axis adapt(Axis axis) {
return switch(axis) {
case Z -> Direction.Axis.Z;
case Y -> Direction.Axis.Y;
case X -> Direction.Axis.X;
};
switch(axis) {
case Z:
return Direction.Axis.Z;
case Y:
return Direction.Axis.Y;
case X:
return Direction.Axis.X;
default:
throw new IllegalStateException();
}
}
}
@@ -37,6 +37,7 @@ import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.fabric.api.BiomeCreationEvent;
import com.dfsek.terra.fabric.generation.FabricChunkGeneratorWrapper;
import com.dfsek.terra.fabric.generation.PopulatorFeature;
import com.dfsek.terra.fabric.generation.TerraBiomeSource;
@@ -249,7 +250,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
.registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> biomeFixer.translate((String) o));
}
private Biome createBiome(BiomeBuilder biome) {
private Biome createBiome(BiomeBuilder biome, ConfigPack pack) {
BiomeTemplate template = biome.getTemplate();
Map<String, Integer> colors = template.getColors();
@@ -279,7 +280,7 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
accessor.getFoliageColor().ifPresent(effects::foliageColor);
}
return new Biome.Builder()
Biome.Builder builder = new Biome.Builder()
.precipitation(vanilla.getPrecipitation())
.category(vanilla.getCategory())
.depth(vanilla.getDepth())
@@ -287,16 +288,19 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
.temperature(vanilla.getTemperature())
.downfall(vanilla.getDownfall())
.effects(effects.build())
.spawnSettings(vanilla.getSpawnSettings())
.generationSettings(generationSettings.build())
.build();
.spawnSettings(vanilla.getSpawnSettings());
eventManager.callEvent(new BiomeCreationEvent(builder, effects, biome, pack));
builder.generationSettings(generationSettings.build());
return builder.build();
}
public void packInit() {
logger.info("Loading config packs...");
registry.loadAll(this);
registry.forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, id)), createBiome(biome)))); // Register all Terra biomes.
registry.forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> Registry.register(BuiltinRegistries.BIOME, new Identifier("terra", createBiomeID(pack, id)), createBiome(biome, pack)))); // Register all Terra biomes.
if(FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
registry.forEach(pack -> {
@@ -331,7 +335,6 @@ public class TerraFabricPlugin implements TerraPlugin, ModInitializer {
logger.info("Loaded addons.");
Registry.register(Registry.FEATURE, new Identifier("terra", "flora_populator"), POPULATOR_FEATURE);
RegistryKey<ConfiguredFeature<?, ?>> floraKey = RegistryKey.of(Registry.CONFIGURED_FEATURE_WORLDGEN, new Identifier("terra", "flora_populator"));
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, floraKey.getValue(), POPULATOR_CONFIGURED_FEATURE);
@@ -0,0 +1,42 @@
package com.dfsek.terra.fabric.api;
import com.dfsek.terra.api.event.events.PackEvent;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.pack.ConfigPack;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects;
/**
* Called when a {@link Biome} is created
* as a delegate to a {@link BiomeBuilder}.
*/
public class BiomeCreationEvent implements PackEvent {
private final Biome.Builder builder;
private final BiomeEffects.Builder effectsBuilder;
private final BiomeBuilder terraBiome;
private final ConfigPack pack;
public BiomeCreationEvent(Biome.Builder builder, BiomeEffects.Builder effectsBuilder, BiomeBuilder terraBiome, ConfigPack pack) {
this.builder = builder;
this.effectsBuilder = effectsBuilder;
this.terraBiome = terraBiome;
this.pack = pack;
}
@Override
public ConfigPack getPack() {
return pack;
}
public BiomeBuilder getTerraBiome() {
return terraBiome;
}
public Biome.Builder getBuilder() {
return builder;
}
public BiomeEffects.Builder getEffectsBuilder() {
return effectsBuilder;
}
}
@@ -7,7 +7,7 @@ import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.FabricAdapter;
import net.minecraft.block.FluidBlock;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldAccess;
@@ -2,8 +2,8 @@ package com.dfsek.terra.fabric.block.data;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.data.Directional;
import com.dfsek.terra.fabric.FabricAdapter;
import com.dfsek.terra.fabric.block.FabricBlockData;
import com.dfsek.terra.fabric.util.FabricAdapter;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.DirectionProperty;
@@ -17,14 +17,22 @@ public class FabricDirectional extends FabricBlockData implements Directional {
@Override
public BlockFace getFacing() {
return switch(delegate.get(property)) {
case SOUTH -> BlockFace.SOUTH;
case DOWN -> BlockFace.DOWN;
case UP -> BlockFace.UP;
case EAST -> BlockFace.EAST;
case WEST -> BlockFace.WEST;
case NORTH -> BlockFace.NORTH;
};
switch(delegate.get(property)) {
case SOUTH:
return BlockFace.SOUTH;
case DOWN:
return BlockFace.DOWN;
case UP:
return BlockFace.UP;
case EAST:
return BlockFace.EAST;
case WEST:
return BlockFace.WEST;
case NORTH:
return BlockFace.NORTH;
default:
throw new IllegalStateException();
}
}
@Override
@@ -29,12 +29,24 @@ public class FabricMultipleFacing extends FabricBlockData implements MultipleFac
@Override
public void setFace(BlockFace face, boolean facing) {
switch(face) {
case NORTH -> delegate = delegate.with(Properties.NORTH, facing);
case SOUTH -> delegate = delegate.with(Properties.SOUTH, facing);
case EAST -> delegate = delegate.with(Properties.EAST, facing);
case WEST -> delegate = delegate.with(Properties.WEST, facing);
case UP -> delegate = delegate.with(Properties.UP, facing);
case DOWN -> delegate = delegate.with(Properties.DOWN, facing);
case NORTH:
delegate = delegate.with(Properties.NORTH, facing);
break;
case SOUTH:
delegate = delegate.with(Properties.SOUTH, facing);
break;
case EAST:
delegate = delegate.with(Properties.EAST, facing);
break;
case WEST:
delegate = delegate.with(Properties.WEST, facing);
break;
case UP:
delegate = delegate.with(Properties.UP, facing);
break;
case DOWN:
delegate = delegate.with(Properties.DOWN, facing);
break;
}
}
@@ -2,8 +2,8 @@ package com.dfsek.terra.fabric.block.data;
import com.dfsek.terra.api.platform.block.Axis;
import com.dfsek.terra.api.platform.block.data.Orientable;
import com.dfsek.terra.fabric.FabricAdapter;
import com.dfsek.terra.fabric.block.FabricBlockData;
import com.dfsek.terra.fabric.util.FabricAdapter;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.EnumProperty;
import net.minecraft.util.math.Direction;
@@ -14,47 +14,98 @@ public class FabricRotatable extends FabricBlockData implements Rotatable {
@Override
public BlockFace getRotation() {
int r = delegate.get(Properties.ROTATION);
return switch(r) {
case 0 -> BlockFace.SOUTH;
case 1 -> BlockFace.SOUTH_SOUTH_WEST;
case 2 -> BlockFace.SOUTH_WEST;
case 3 -> BlockFace.WEST_SOUTH_WEST;
case 4 -> BlockFace.WEST;
case 5 -> BlockFace.WEST_NORTH_WEST;
case 6 -> BlockFace.NORTH_WEST;
case 7 -> BlockFace.NORTH_NORTH_WEST;
case 8 -> BlockFace.NORTH;
case 9 -> BlockFace.NORTH_NORTH_EAST;
case 10 -> BlockFace.NORTH_EAST;
case 11 -> BlockFace.EAST_NORTH_EAST;
case 12 -> BlockFace.EAST;
case 13 -> BlockFace.EAST_SOUTH_EAST;
case 14 -> BlockFace.SOUTH_EAST;
case 15 -> BlockFace.SOUTH_SOUTH_EAST;
default -> throw new IllegalArgumentException("Unknown rotation " + r);
};
switch(r) {
case 0:
return BlockFace.SOUTH;
case 1:
return BlockFace.SOUTH_SOUTH_WEST;
case 2:
return BlockFace.SOUTH_WEST;
case 3:
return BlockFace.WEST_SOUTH_WEST;
case 4:
return BlockFace.WEST;
case 5:
return BlockFace.WEST_NORTH_WEST;
case 6:
return BlockFace.NORTH_WEST;
case 7:
return BlockFace.NORTH_NORTH_WEST;
case 8:
return BlockFace.NORTH;
case 9:
return BlockFace.NORTH_NORTH_EAST;
case 10:
return BlockFace.NORTH_EAST;
case 11:
return BlockFace.EAST_NORTH_EAST;
case 12:
return BlockFace.EAST;
case 13:
return BlockFace.EAST_SOUTH_EAST;
case 14:
return BlockFace.SOUTH_EAST;
case 15:
return BlockFace.SOUTH_SOUTH_EAST;
default:
throw new IllegalArgumentException("Unknown rotation " + r);
}
}
@Override
public void setRotation(BlockFace face) {
switch(face) {
case UP, DOWN -> throw new IllegalArgumentException("Illegal rotation " + face);
case SOUTH -> delegate = delegate.with(Properties.ROTATION, 0);
case SOUTH_SOUTH_WEST -> delegate = delegate.with(Properties.ROTATION, 1);
case SOUTH_WEST -> delegate = delegate.with(Properties.ROTATION, 2);
case WEST_SOUTH_WEST -> delegate = delegate.with(Properties.ROTATION, 3);
case WEST -> delegate = delegate.with(Properties.ROTATION, 4);
case WEST_NORTH_WEST -> delegate = delegate.with(Properties.ROTATION, 5);
case NORTH_WEST -> delegate = delegate.with(Properties.ROTATION, 6);
case NORTH_NORTH_WEST -> delegate = delegate.with(Properties.ROTATION, 7);
case NORTH -> delegate = delegate.with(Properties.ROTATION, 8);
case NORTH_NORTH_EAST -> delegate = delegate.with(Properties.ROTATION, 9);
case NORTH_EAST -> delegate = delegate.with(Properties.ROTATION, 10);
case EAST_NORTH_EAST -> delegate = delegate.with(Properties.ROTATION, 11);
case EAST -> delegate = delegate.with(Properties.ROTATION, 12);
case EAST_SOUTH_EAST -> delegate = delegate.with(Properties.ROTATION, 13);
case SOUTH_EAST -> delegate = delegate.with(Properties.ROTATION, 14);
case SOUTH_SOUTH_EAST -> delegate = delegate.with(Properties.ROTATION, 15);
case UP:
case DOWN:
throw new IllegalArgumentException("Illegal rotation " + face);
case SOUTH:
delegate = delegate.with(Properties.ROTATION, 0);
return;
case SOUTH_SOUTH_WEST:
delegate = delegate.with(Properties.ROTATION, 1);
return;
case SOUTH_WEST:
delegate = delegate.with(Properties.ROTATION, 2);
return;
case WEST_SOUTH_WEST:
delegate = delegate.with(Properties.ROTATION, 3);
return;
case WEST:
delegate = delegate.with(Properties.ROTATION, 4);
return;
case WEST_NORTH_WEST:
delegate = delegate.with(Properties.ROTATION, 5);
return;
case NORTH_WEST:
delegate = delegate.with(Properties.ROTATION, 6);
return;
case NORTH_NORTH_WEST:
delegate = delegate.with(Properties.ROTATION, 7);
return;
case NORTH:
delegate = delegate.with(Properties.ROTATION, 8);
return;
case NORTH_NORTH_EAST:
delegate = delegate.with(Properties.ROTATION, 9);
return;
case NORTH_EAST:
delegate = delegate.with(Properties.ROTATION, 10);
return;
case EAST_NORTH_EAST:
delegate = delegate.with(Properties.ROTATION, 11);
return;
case EAST:
delegate = delegate.with(Properties.ROTATION, 12);
return;
case EAST_SOUTH_EAST:
delegate = delegate.with(Properties.ROTATION, 13);
return;
case SOUTH_EAST:
delegate = delegate.with(Properties.ROTATION, 14);
return;
case SOUTH_SOUTH_EAST:
delegate = delegate.with(Properties.ROTATION, 15);
return;
}
}
}
@@ -1,7 +1,7 @@
package com.dfsek.terra.fabric.block.data;
import com.dfsek.terra.api.platform.block.data.Slab;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.FabricAdapter;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Properties;
@@ -2,7 +2,7 @@ package com.dfsek.terra.fabric.block.data;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.data.Stairs;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.FabricAdapter;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Properties;
@@ -7,8 +7,8 @@ import com.dfsek.terra.api.util.FastRandom;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.api.world.locate.AsyncStructureFinder;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.fabric.FabricAdapter;
import com.dfsek.terra.fabric.TerraFabricPlugin;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.world.TerraWorld;
import com.dfsek.terra.world.generation.generators.DefaultChunkGenerator3D;
import com.dfsek.terra.world.generation.math.samplers.Sampler;
@@ -109,6 +109,11 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
return null;
}
@Override
public void generateFeatures(ChunkRegion region, StructureAccessor accessor) {
super.generateFeatures(region, accessor);
}
@Override
public void populateNoise(WorldAccess world, StructureAccessor accessor, Chunk chunk) {
delegate.generateChunkData((World) world, new FastRandom(), chunk.getPos().x, chunk.getPos().z, (ChunkData) chunk);
@@ -116,15 +121,16 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
@Override
public void carve(long seed, BiomeAccess access, Chunk chunk, GenerationStep.Carver carver) {
if(pack.getTemplate().vanillaCaves()) super.carve(seed, access, chunk, carver);
// No caves
}
@Override
public void setStructureStarts(DynamicRegistryManager dynamicRegistryManager, StructureAccessor structureAccessor, Chunk chunk, StructureManager structureManager, long worldSeed) {
if(pack.getTemplate().vanillaStructures())
super.setStructureStarts(dynamicRegistryManager, structureAccessor, chunk, structureManager, worldSeed);
}
@Override
public boolean isStrongholdStartingChunk(ChunkPos chunkPos) {
return false;
@@ -1,13 +1,9 @@
package com.dfsek.terra.fabric.handle;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.platform.handle.WorldHandle;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.dfsek.terra.fabric.FabricAdapter;
import com.dfsek.terra.fabric.block.FabricBlockData;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.util.WorldEditUtil;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockState;
@@ -37,14 +33,4 @@ public class FabricWorldHandle implements WorldHandle {
if(identifier == null) identifier = Identifier.tryParse("minecraft:" + id.toLowerCase(Locale.ROOT));
return (EntityType) Registry.ENTITY_TYPE.get(identifier);
}
@Override
public Pair<Location, Location> getSelectedLocation(Player player) {
try {
Class.forName("com.sk89q.worldedit.WorldEdit");
} catch(ClassNotFoundException e) {
throw new IllegalStateException("WorldEdit is not installed.");
}
return WorldEditUtil.getSelection(player);
}
}
@@ -3,8 +3,8 @@ package com.dfsek.terra.fabric.mixin.implementations.block;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.fabric.FabricAdapter;
import com.dfsek.terra.fabric.block.FabricBlock;
import com.dfsek.terra.fabric.util.FabricAdapter;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@@ -2,7 +2,7 @@ package com.dfsek.terra.fabric.mixin.implementations.block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.FabricAdapter;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
@@ -87,15 +87,32 @@ public abstract class MobSpawnerBlockEntityMixin {
public void terra$applyState(String state) {
SerialState.parse(state).forEach((k, v) -> {
switch(k) {
case "type" -> terra$setSpawnedType(TerraFabricPlugin.getInstance().getWorldHandle().getEntity(v));
case "delay" -> terra$setDelay(Integer.parseInt(v));
case "min_delay" -> terra$setMinSpawnDelay(Integer.parseInt(v));
case "max_delay" -> terra$setMaxSpawnDelay(Integer.parseInt(v));
case "spawn_count" -> terra$setSpawnCount(Integer.parseInt(v));
case "spawn_range" -> terra$setSpawnRange(Integer.parseInt(v));
case "max_nearby" -> terra$setMaxNearbyEntities(Integer.parseInt(v));
case "required_player_range" -> terra$setRequiredPlayerRange(Integer.parseInt(v));
default -> throw new IllegalArgumentException("Invalid property: " + k);
case "type":
terra$setSpawnedType(TerraFabricPlugin.getInstance().getWorldHandle().getEntity(v));
return;
case "delay":
terra$setDelay(Integer.parseInt(v));
return;
case "min_delay":
terra$setMinSpawnDelay(Integer.parseInt(v));
return;
case "max_delay":
terra$setMaxSpawnDelay(Integer.parseInt(v));
return;
case "spawn_count":
terra$setSpawnCount(Integer.parseInt(v));
return;
case "spawn_range":
terra$setSpawnRange(Integer.parseInt(v));
return;
case "max_nearby":
terra$setMaxNearbyEntities(Integer.parseInt(v));
return;
case "required_player_range":
terra$setRequiredPlayerRange(Integer.parseInt(v));
return;
default:
throw new IllegalArgumentException("Invalid property: " + k);
}
});
}
@@ -2,7 +2,7 @@ package com.dfsek.terra.fabric.mixin.implementations.entity;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.fabric.util.FabricAdapter;
import com.dfsek.terra.fabric.FabricAdapter;
import net.minecraft.entity.Entity;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
@@ -1,29 +0,0 @@
package com.dfsek.terra.fabric.util;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.entity.Player;
import com.dfsek.terra.api.util.generic.pair.Pair;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.world.World;
public final class WorldEditUtil {
public static Pair<Location, Location> getSelection(Player player) {
WorldEdit worldEdit = WorldEdit.getInstance();
try {
Region selection = worldEdit.getSessionManager()
.get(com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer((ServerPlayerEntity) player))
.getSelection(com.sk89q.worldedit.fabric.FabricAdapter.adapt((World) player.getWorld()));
BlockVector3 min = selection.getMinimumPoint();
BlockVector3 max = selection.getMaximumPoint();
Location l1 = new Location(player.getWorld(), min.getBlockX(), min.getBlockY(), min.getBlockZ());
Location l2 = new Location(player.getWorld(), max.getBlockX(), max.getBlockY(), max.getBlockZ());
return Pair.of(l1, l2);
} catch(IncompleteRegionException e) {
throw new IllegalStateException("No selection has been made", e);
}
}
}
@@ -3,16 +3,15 @@
"id": "terra",
"version": "@VERSION@",
"name": "Terra",
"description": "@DESCRIPTION@",
"description": "An insanely powerful free & open-source data-driven world generator.",
"authors": [
"dfsek"
],
"contact": {
"homepage": "@WIKI@",
"sources": "@SOURCE@",
"issues": "@ISSUES@"
"homepage": "https://github.com/PolyhedralDev/Terra/wiki",
"sources": "https://github.com/PolyhedralDev/Terra"
},
"license": "@LICENSE@",
"license": "GPL-3.0",
"icon": "assets/terra/icon.png",
"environment": "*",
"entrypoints": {
+8 -14
View File
@@ -1,6 +1,6 @@
import com.dfsek.terra.configureCommon
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import net.minecraftforge.gradle.common.util.RunConfig
import net.minecraftforge.gradle.mcp.task.GenerateSRG
import net.minecraftforge.gradle.userdev.UserDevExtension
import net.minecraftforge.gradle.userdev.tasks.RenameJarInPlace
@@ -55,17 +55,11 @@ if ("true" == System.getProperty("idea.sync.active")) {
}
}
tasks.named<ShadowJar>("shadowJar") {
archiveBaseName.set(tasks.getByName<Jar>("jar").archiveBaseName.orNull) // Pain. Agony, even.
archiveClassifier.set("") // Suffering, if you will.
}
afterEvaluate {
tasks.named<RenameJarInPlace>("reobfJar") {
val shadow = tasks.getByName<ShadowJar>("shadowJar");
dependsOn(shadow)
input = shadow.archiveFile.orNull?.asFile
val reobf = extensions.getByName<NamedDomainObjectContainer<RenameJarInPlace>>("reobf")
reobf.maybeCreate("shadowJar").run {
group = "forge"
mappings = tasks.getByName<GenerateSRG>("createMcpToSrg").output
}
}
@@ -77,7 +71,7 @@ configure<UserDevExtension> {
runs {
val runConfig = Action<RunConfig> {
properties(mapOf(
//"forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP",
"forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP",
"forge.logging.console.level" to "debug"
))
arg("-mixin.config=terra.mixins.json")
@@ -130,12 +124,12 @@ tasks.jar {
}
tasks.register<com.modrinth.minotaur.TaskModrinthUpload>("publishModrinthForge") {
dependsOn("reobfJar")
dependsOn("reobfShadowJar")
group = "forge"
token = System.getenv("MODRINTH_SECRET")
projectId = "FIlZB9L0"
versionNumber = "${project.version}-forge"
uploadFile = tasks.named<RenameJarInPlace>("reobfJar").get().input.absoluteFile
uploadFile = tasks.named<RenameJarInPlace>("reobfShadowJar").get().input.absoluteFile
releaseType = "alpha"
addGameVersion("1.16.5")
addLoader("forge")
@@ -1,83 +0,0 @@
package com.dfsek.terra.forge;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.state.Container;
import com.dfsek.terra.api.platform.block.state.MobSpawner;
import com.dfsek.terra.api.platform.block.state.Sign;
import com.dfsek.terra.forge.block.ForgeBlockData;
import com.dfsek.terra.forge.block.data.ForgeDirectional;
import com.dfsek.terra.forge.block.data.ForgeMultipleFacing;
import com.dfsek.terra.forge.block.data.ForgeOrientable;
import com.dfsek.terra.forge.block.data.ForgeRotatable;
import com.dfsek.terra.forge.block.data.ForgeSlab;
import com.dfsek.terra.forge.block.data.ForgeStairs;
import com.dfsek.terra.forge.block.data.ForgeWaterlogged;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.LockableLootTileEntity;
import net.minecraft.tileentity.MobSpawnerTileEntity;
import net.minecraft.tileentity.SignTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import java.util.Arrays;
public final class ForgeAdapter {
public static BlockPos adapt(Vector3 v) {
return new BlockPos(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
public static Vector3 adapt(BlockPos pos) {
return new Vector3(pos.getX(), pos.getY(), pos.getZ());
}
public static ForgeBlockData adapt(BlockState state) {
if(state.hasProperty(BlockStateProperties.STAIRS_SHAPE)) return new ForgeStairs(state);
if(state.hasProperty(BlockStateProperties.SLAB_TYPE)) return new ForgeSlab(state);
if(state.hasProperty(BlockStateProperties.AXIS)) return new ForgeOrientable(state, BlockStateProperties.AXIS);
if(state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) return new ForgeOrientable(state, BlockStateProperties.HORIZONTAL_AXIS);
if(state.hasProperty(BlockStateProperties.ROTATION_16)) return new ForgeRotatable(state);
if(state.hasProperty(BlockStateProperties.FACING)) return new ForgeDirectional(state, BlockStateProperties.FACING);
if(state.hasProperty(BlockStateProperties.FACING_HOPPER)) return new ForgeDirectional(state, BlockStateProperties.FACING_HOPPER);
if(state.hasProperty(BlockStateProperties.HORIZONTAL_FACING))
return new ForgeDirectional(state, BlockStateProperties.HORIZONTAL_FACING);
if(state.getProperties().containsAll(Arrays.asList(BlockStateProperties.NORTH, BlockStateProperties.SOUTH, BlockStateProperties.EAST, BlockStateProperties.WEST)))
return new ForgeMultipleFacing(state);
if(state.hasProperty(BlockStateProperties.WATERLOGGED)) return new ForgeWaterlogged(state);
return new ForgeBlockData(state);
}
public static com.dfsek.terra.api.platform.block.state.BlockState adapt(com.dfsek.terra.api.platform.block.Block block) {
IWorld worldAccess = (IWorld) block.getLocation().getWorld();
TileEntity entity = worldAccess.getBlockEntity(adapt(block.getLocation().toVector()));
if(entity instanceof SignTileEntity) {
return (Sign) entity;
} else if(entity instanceof MobSpawnerTileEntity) {
return (MobSpawner) entity;
} else if(entity instanceof LockableLootTileEntity) {
return (Container) entity;
}
return null;
}
public static Direction adapt(BlockFace face) {
return switch(face) {
case NORTH -> Direction.NORTH;
case WEST -> Direction.WEST;
case SOUTH -> Direction.SOUTH;
case EAST -> Direction.EAST;
case UP -> Direction.UP;
case DOWN -> Direction.DOWN;
default -> throw new IllegalArgumentException("Illegal direction: " + face);
};
}
}
@@ -1,66 +0,0 @@
package com.dfsek.terra.forge;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.config.templates.BiomeTemplate;
import net.minecraft.block.Blocks;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeAmbience;
import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
public final class ForgeUtil {
public static String createBiomeID(ConfigPack pack, String biomeID) {
return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
}
@SuppressWarnings("ConstantConditions")
public static Biome createBiome(BiomeBuilder biome) {
BiomeTemplate template = biome.getTemplate();
Map<String, Integer> colors = template.getColors();
Biome vanilla = (Biome) ((Object) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0));
BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder();
generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.configured(new SurfaceBuilderConfig(Blocks.GRASS_BLOCK.defaultBlockState(), Blocks.DIRT.defaultBlockState(), Blocks.GRAVEL.defaultBlockState()))); // It needs a surfacebuilder, even though we dont use it.
generationSettings.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, TerraForgePlugin.POPULATOR_CONFIGURED_FEATURE);
BiomeAmbience vanillaEffects = vanilla.getSpecialEffects();
BiomeAmbience.Builder effects = new BiomeAmbience.Builder()
.waterColor(colors.getOrDefault("water", vanillaEffects.getWaterColor()))
.waterFogColor(colors.getOrDefault("water-fog", vanillaEffects.getWaterFogColor()))
.fogColor(colors.getOrDefault("fog", vanillaEffects.getFogColor()))
.skyColor(colors.getOrDefault("sky", vanillaEffects.getSkyColor()))
.grassColorModifier(vanillaEffects.getGrassColorModifier());
if(colors.containsKey("grass")) {
effects.grassColorOverride(colors.get("grass"));
} else {
vanillaEffects.getGrassColorOverride().ifPresent(effects::grassColorOverride);
}
vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
if(colors.containsKey("foliage")) {
effects.foliageColorOverride(colors.get("foliage"));
} else {
vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
}
return new Biome.Builder()
.precipitation(vanilla.getPrecipitation())
.biomeCategory(vanilla.getBiomeCategory())
.depth(vanilla.getDepth())
.scale(vanilla.getScale())
.temperature(vanilla.getBaseTemperature())
.downfall(vanilla.getDownfall())
.specialEffects(effects.build())
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(generationSettings.build())
.build().setRegistryName("terra", createBiomeID(template.getPack(), template.getID()));
}
}
@@ -8,6 +8,7 @@ import com.dfsek.terra.api.addons.annotations.Author;
import com.dfsek.terra.api.addons.annotations.Version;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.TerraCommandManager;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.command.exception.MalformedCommandException;
import com.dfsek.terra.api.event.EventListener;
import com.dfsek.terra.api.event.EventManager;
@@ -15,6 +16,7 @@ import com.dfsek.terra.api.event.TerraEventManager;
import com.dfsek.terra.api.event.annotations.Global;
import com.dfsek.terra.api.event.annotations.Priority;
import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.handle.WorldHandle;
@@ -26,35 +28,62 @@ import com.dfsek.terra.api.transform.NotNullValidator;
import com.dfsek.terra.api.transform.Transformer;
import com.dfsek.terra.api.util.JarUtil;
import com.dfsek.terra.api.util.logging.DebugLogger;
import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.commands.CommandUtil;
import com.dfsek.terra.config.GenericLoaders;
import com.dfsek.terra.config.PluginConfig;
import com.dfsek.terra.config.builder.BiomeBuilder;
import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.lang.Language;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper;
import com.dfsek.terra.forge.generation.PopulatorFeature;
import com.dfsek.terra.forge.generation.TerraBiomeSource;
import com.dfsek.terra.forge.handle.ForgeItemHandle;
import com.dfsek.terra.forge.handle.ForgeWorldHandle;
import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.forge.inventory.ForgeItemHandle;
import com.dfsek.terra.forge.world.ForgeAdapter;
import com.dfsek.terra.forge.world.ForgeBiome;
import com.dfsek.terra.forge.world.ForgeTree;
import com.dfsek.terra.forge.world.ForgeWorldHandle;
import com.dfsek.terra.forge.world.features.PopulatorFeature;
import com.dfsek.terra.forge.world.generator.ForgeChunkGenerator;
import com.dfsek.terra.forge.world.generator.ForgeChunkGeneratorWrapper;
import com.dfsek.terra.forge.world.generator.config.TerraLevelType;
import com.dfsek.terra.profiler.Profiler;
import com.dfsek.terra.profiler.ProfilerImpl;
import com.dfsek.terra.registry.exception.DuplicateEntryException;
import com.dfsek.terra.registry.master.AddonRegistry;
import com.dfsek.terra.registry.master.ConfigRegistry;
import com.dfsek.terra.world.TerraWorld;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import net.minecraft.block.Blocks;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.command.CommandSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeAmbience;
import net.minecraft.world.biome.BiomeGenerationSettings;
import net.minecraft.world.gen.GenerationStage;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.Features;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.placement.DecoratedPlacement;
import net.minecraft.world.gen.placement.NoPlacementConfig;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilderConfig;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ForgeWorldTypeScreens;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.world.ForgeWorldType;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
@@ -65,12 +94,20 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
@Mod("terra")
@Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.MOD)
public class TerraForgePlugin implements TerraPlugin {
@@ -103,7 +140,6 @@ public class TerraForgePlugin implements TerraPlugin {
logger.error(message);
}
};
private final DebugLogger debugLogger = new DebugLogger(logger);
private final ItemHandle itemHandle = new ForgeItemHandle();
private final WorldHandle worldHandle = new ForgeWorldHandle();
@@ -115,35 +151,118 @@ public class TerraForgePlugin implements TerraPlugin {
private final Transformer<String, Biome> biomeFixer = new Transformer.Builder<String, Biome>()
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse(id)), new NotNullValidator<>())
.addTransform(id -> ForgeRegistries.BIOMES.getValue(ResourceLocation.tryParse("minecraft:" + id.toLowerCase())), new NotNullValidator<>()).build();
private final File dataFolder;
private File dataFolder;
public TerraForgePlugin() {
if(INSTANCE != null) throw new IllegalStateException("Only one TerraPlugin instance may exist.");
INSTANCE = this;
this.dataFolder = Paths.get("config", "Terra").toFile();
saveDefaultConfig();
config.load(this);
LangUtil.load(config.getLanguage(), this);
try {
CommandUtil.registerAll(manager);
} catch(MalformedCommandException e) {
e.printStackTrace(); // TODO do something here even though this should literally never happen
}
MinecraftForge.EVENT_BUS.register(ClientEvents.class);
MinecraftForge.EVENT_BUS.register(getClass());
MinecraftForge.EVENT_BUS.register(ForgeEvents.class);
}
public static TerraForgePlugin getInstance() {
return INSTANCE;
}
@SubscribeEvent
public static void setupListener(FMLCommonSetupEvent event) {
event.enqueueWork(() -> {
Registry.register(Registry.BIOME_SOURCE, "terra:biome", TerraBiomeSource.CODEC);
Registry.register(Registry.CHUNK_GENERATOR, "terra:generator", ForgeChunkGeneratorWrapper.CODEC);
public static String createBiomeID(ConfigPack pack, String biomeID) {
return pack.getTemplate().getID().toLowerCase() + "/" + biomeID.toLowerCase(Locale.ROOT);
}
private static RequiredArgumentBuilder<CommandSource, String> assemble(RequiredArgumentBuilder<CommandSource, String> in, CommandManager manager) {
return in.suggests((context, builder) -> {
List<String> args = parseCommand(context.getInput());
CommandSender sender = ForgeAdapter.adapt(context.getSource());
try {
manager.tabComplete(args.remove(0), sender, args).forEach(builder::suggest);
} catch(CommandException e) {
sender.sendMessage(e.getMessage());
}
return builder.buildFuture();
}).executes(context -> {
List<String> args = parseCommand(context.getInput());
try {
manager.execute(args.remove(0), ForgeAdapter.adapt(context.getSource()), args);
} catch(CommandException e) {
context.getSource().sendFailure(new StringTextComponent(e.getMessage()));
}
return 1;
});
}
private static List<String> parseCommand(String command) {
if(command.startsWith("/terra ")) command = command.substring("/terra ".length());
else if(command.startsWith("/te ")) command = command.substring("/te ".length());
List<String> c = new ArrayList<>(Arrays.asList(command.split(" ")));
if(command.endsWith(" ")) c.add("");
return c;
}
@SubscribeEvent
public static void register(RegistryEvent.Register<Biome> event) {
INSTANCE.setup(); // Setup now because we need the biomes, and this event happens after blocks n stuff
INSTANCE.getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> event.getRegistry().register(INSTANCE.createBiome(biome)))); // Register all Terra biomes.
}
@SubscribeEvent
public static void registerLevels(RegistryEvent.Register<ForgeWorldType> event) {
INSTANCE.logger().info("Registering level types...");
event.getRegistry().register(TerraLevelType.FORGE_WORLD_TYPE);
}
@SubscribeEvent
public static void registerPop(RegistryEvent.Register<Feature<?>> event) {
event.getRegistry().register(POPULATOR_FEATURE);
}
public Biome createBiome(BiomeBuilder biome) {
BiomeTemplate template = biome.getTemplate();
Map<String, Integer> colors = template.getColors();
Biome vanilla = ((ForgeBiome) new ArrayList<>(biome.getVanillaBiomes().getContents()).get(0)).getHandle();
BiomeGenerationSettings.Builder generationSettings = new BiomeGenerationSettings.Builder();
generationSettings.surfaceBuilder(SurfaceBuilder.DEFAULT.configured(new SurfaceBuilderConfig(Blocks.GRASS_BLOCK.defaultBlockState(), Blocks.DIRT.defaultBlockState(), Blocks.GRAVEL.defaultBlockState()))); // It needs a surfacebuilder, even though we dont use it.
generationSettings.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, POPULATOR_CONFIGURED_FEATURE);
BiomeAmbience vanillaEffects = vanilla.getSpecialEffects();
BiomeAmbience.Builder effects = new BiomeAmbience.Builder()
.waterColor(colors.getOrDefault("water", vanillaEffects.getWaterColor()))
.waterFogColor(colors.getOrDefault("water-fog", vanillaEffects.getWaterFogColor()))
.fogColor(colors.getOrDefault("fog", vanillaEffects.getFogColor()))
.skyColor(colors.getOrDefault("sky", vanillaEffects.getSkyColor()))
.grassColorModifier(vanillaEffects.getGrassColorModifier());
if(colors.containsKey("grass")) {
effects.grassColorOverride(colors.get("grass"));
} else {
vanillaEffects.getGrassColorOverride().ifPresent(effects::grassColorOverride);
}
vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
if(colors.containsKey("foliage")) {
effects.foliageColorOverride(colors.get("foliage"));
} else {
vanillaEffects.getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
}
return new Biome.Builder()
.precipitation(vanilla.getPrecipitation())
.biomeCategory(vanilla.getBiomeCategory())
.depth(vanilla.getDepth())
.scale(vanilla.getScale())
.temperature(vanilla.getBaseTemperature())
.downfall(vanilla.getDownfall())
.specialEffects(effects.build())
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(generationSettings.build())
.build().setRegistryName("terra", createBiomeID(template.getPack(), template.getID()));
}
public void setup() {
this.dataFolder = Paths.get("config", "Terra").toFile();
saveDefaultConfig();
config.load(this);
LangUtil.load(config.getLanguage(), this);
logger.info("Initializing Terra...");
if(!addonRegistry.loadAll()) {
@@ -152,7 +271,15 @@ public class TerraForgePlugin implements TerraPlugin {
logger.info("Loaded addons.");
registry.loadAll(this);
logger.info("Loaded packs.");
try {
CommandUtil.registerAll(manager);
} catch(MalformedCommandException e) {
e.printStackTrace(); // TODO do something here even though this should literally never happen
}
}
@Override
@@ -164,17 +291,10 @@ public class TerraForgePlugin implements TerraPlugin {
public TerraWorld getWorld(World world) {
return worldMap.computeIfAbsent(world.getSeed(), w -> {
logger.info("Loading world " + w);
return new TerraWorld(world, ((ForgeChunkGeneratorWrapper) world.getGenerator()).getPack(), this);
return new TerraWorld(world, ((ForgeChunkGeneratorWrapper) ((ForgeChunkGenerator) world.getGenerator()).getHandle()).getPack(), this);
});
}
/**
* evil code brought to you by Forge Mod Loader
* <p>
* Forge changes the JAR URI to something that cannot
* be resolved back to the original JAR, so we have to
* do this to get our JAR.
*/
@Override
public JarFile getModJar() throws URISyntaxException, IOException {
File modsDir = new File("./mods");
@@ -214,7 +334,7 @@ public class TerraForgePlugin implements TerraPlugin {
@Override
public boolean isDebug() {
return config.isDebug();
return true;
}
@Override
@@ -278,7 +398,7 @@ public class TerraForgePlugin implements TerraPlugin {
genericLoaders.register(registry);
registry
.registerLoader(BlockData.class, (t, o, l) -> worldHandle.createBlockData((String) o))
.registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> biomeFixer.translate((String) o));
.registerLoader(com.dfsek.terra.api.platform.world.Biome.class, (t, o, l) -> new ForgeBiome(biomeFixer.translate((String) o)));
}
@Override
@@ -291,8 +411,22 @@ public class TerraForgePlugin implements TerraPlugin {
return profiler;
}
public CommandManager getManager() {
return manager;
@Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.FORGE)
public static final class ForgeEvents {
@SuppressWarnings({"unchecked", "rawtypes"})
@SubscribeEvent
public static void registerCommands(RegisterCommandsEvent event) {
int max = INSTANCE.manager.getMaxArgumentDepth();
RequiredArgumentBuilder<CommandSource, String> arg = argument("arg" + (max - 1), StringArgumentType.word());
for(int i = 0; i < max; i++) {
RequiredArgumentBuilder<CommandSource, String> next = argument("arg" + (max - i - 1), StringArgumentType.word());
arg = next.then(assemble(arg, INSTANCE.manager));
}
event.getDispatcher().register(literal("terra").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.manager)));
event.getDispatcher().register(literal("te").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.manager)));
}
}
@Addon("Terra-Forge")
@@ -339,9 +473,38 @@ public class TerraForgePlugin implements TerraPlugin {
private void injectTree(CheckedRegistry<Tree> registry, String id, ConfiguredFeature<?, ?> tree) {
try {
registry.add(id, (Tree) tree);
registry.add(id, new ForgeTree(tree, id, TerraForgePlugin.getInstance()));
} catch(DuplicateEntryException ignore) {
}
}
}
@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public static final class ClientEvents {
@SubscribeEvent
public static void register(FMLClientSetupEvent event) {
INSTANCE.logger.info("Client setup...");
ForgeWorldType world = TerraLevelType.FORGE_WORLD_TYPE;
ForgeWorldTypeScreens.registerFactory(world, (returnTo, dimensionGeneratorSettings) -> new Screen(world.getDisplayName()) {
private final MutableInteger num = new MutableInteger(0);
private final List<ConfigPack> packs = new ArrayList<>();
private final Button toggle = new Button(0, 25, 120, 20, new StringTextComponent(""), button -> {
num.increment();
if(num.get() >= packs.size()) num.set(0);
button.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
});
@Override
protected void init() {
packs.clear();
INSTANCE.registry.forEach((Consumer<ConfigPack>) packs::add);
addButton(new Button(0, 0, 120, 20, new StringTextComponent("Close"), btn -> Minecraft.getInstance().setScreen(returnTo)));
toggle.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
addButton(toggle);
}
});
}
}
}
@@ -1,101 +0,0 @@
package com.dfsek.terra.forge.block.data;
import com.dfsek.terra.api.platform.block.Axis;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.data.Bisected;
import com.dfsek.terra.api.platform.block.data.Slab;
import com.dfsek.terra.api.platform.block.data.Stairs;
import net.minecraft.state.properties.Half;
import net.minecraft.state.properties.SlabType;
import net.minecraft.state.properties.StairsShape;
import net.minecraft.util.Direction;
public final class ForgeEnumAdapter {
public static Stairs.Shape adapt(StairsShape shape) {
return switch(shape) {
case OUTER_RIGHT -> Stairs.Shape.OUTER_RIGHT;
case INNER_RIGHT -> Stairs.Shape.INNER_RIGHT;
case OUTER_LEFT -> Stairs.Shape.OUTER_LEFT;
case INNER_LEFT -> Stairs.Shape.INNER_LEFT;
case STRAIGHT -> Stairs.Shape.STRAIGHT;
};
}
public static Bisected.Half adapt(Half half) {
return switch(half) {
case BOTTOM -> Bisected.Half.BOTTOM;
case TOP -> Bisected.Half.TOP;
};
}
public static BlockFace adapt(Direction direction) {
return switch(direction) {
case DOWN -> BlockFace.DOWN;
case UP -> BlockFace.UP;
case WEST -> BlockFace.WEST;
case EAST -> BlockFace.EAST;
case NORTH -> BlockFace.NORTH;
case SOUTH -> BlockFace.SOUTH;
};
}
public static Slab.Type adapt(SlabType type) {
return switch(type) {
case BOTTOM -> Slab.Type.BOTTOM;
case TOP -> Slab.Type.TOP;
case DOUBLE -> Slab.Type.DOUBLE;
};
}
public static StairsShape adapt(Stairs.Shape shape) {
return switch(shape) {
case STRAIGHT -> StairsShape.STRAIGHT;
case INNER_LEFT -> StairsShape.INNER_LEFT;
case OUTER_LEFT -> StairsShape.OUTER_LEFT;
case INNER_RIGHT -> StairsShape.INNER_RIGHT;
case OUTER_RIGHT -> StairsShape.OUTER_RIGHT;
};
}
public static Half adapt(Bisected.Half half) {
return switch(half) {
case TOP -> Half.TOP;
case BOTTOM -> Half.BOTTOM;
};
}
public static Direction adapt(BlockFace face) {
return switch(face) {
case SOUTH -> Direction.SOUTH;
case NORTH -> Direction.NORTH;
case EAST -> Direction.EAST;
case WEST -> Direction.WEST;
case UP -> Direction.UP;
case DOWN -> Direction.DOWN;
};
}
public static SlabType adapt(Slab.Type type) {
return switch(type) {
case DOUBLE -> SlabType.DOUBLE;
case TOP -> SlabType.TOP;
case BOTTOM -> SlabType.BOTTOM;
};
}
public static Axis adapt(Direction.Axis axis) {
return switch(axis) {
case X -> Axis.X;
case Y -> Axis.Y;
case Z -> Axis.Z;
};
}
public static Direction.Axis adapt(Axis axis) {
return switch(axis) {
case Z -> Direction.Axis.Z;
case Y -> Direction.Axis.Y;
case X -> Direction.Axis.X;
};
}
}
@@ -1,60 +0,0 @@
package com.dfsek.terra.forge.block.data;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.data.Rotatable;
import com.dfsek.terra.forge.block.ForgeBlockData;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
public class ForgeRotatable extends ForgeBlockData implements Rotatable {
public ForgeRotatable(BlockState delegate) {
super(delegate);
}
@Override
public BlockFace getRotation() {
int r = delegate.getValue(BlockStateProperties.ROTATION_16);
return switch(r) {
case 0 -> BlockFace.SOUTH;
case 1 -> BlockFace.SOUTH_SOUTH_WEST;
case 2 -> BlockFace.SOUTH_WEST;
case 3 -> BlockFace.WEST_SOUTH_WEST;
case 4 -> BlockFace.WEST;
case 5 -> BlockFace.WEST_NORTH_WEST;
case 6 -> BlockFace.NORTH_WEST;
case 7 -> BlockFace.NORTH_NORTH_WEST;
case 8 -> BlockFace.NORTH;
case 9 -> BlockFace.NORTH_NORTH_EAST;
case 10 -> BlockFace.NORTH_EAST;
case 11 -> BlockFace.EAST_NORTH_EAST;
case 12 -> BlockFace.EAST;
case 13 -> BlockFace.EAST_SOUTH_EAST;
case 14 -> BlockFace.SOUTH_EAST;
case 15 -> BlockFace.SOUTH_SOUTH_EAST;
default -> throw new IllegalArgumentException("Unknown rotation " + r);
};
}
@Override
public void setRotation(BlockFace face) {
switch(face) {
case UP, DOWN -> throw new IllegalArgumentException("Illegal rotation " + face);
case SOUTH -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 0);
case SOUTH_SOUTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 1);
case SOUTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 2);
case WEST_SOUTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 3);
case WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 4);
case WEST_NORTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 5);
case NORTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 6);
case NORTH_NORTH_WEST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 7);
case NORTH -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 8);
case NORTH_NORTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 9);
case NORTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 10);
case EAST_NORTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 11);
case EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 12);
case EAST_SOUTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 13);
case SOUTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 14);
case SOUTH_SOUTH_EAST -> delegate = delegate.setValue(BlockStateProperties.ROTATION_16, 15);
}
}
}
@@ -0,0 +1,42 @@
package com.dfsek.terra.forge.inventory;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.forge.world.ForgeAdapter;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.Objects;
public class ForgeEnchantment implements Enchantment {
private final net.minecraft.enchantment.Enchantment enchantment;
public ForgeEnchantment(net.minecraft.enchantment.Enchantment enchantment) {
this.enchantment = enchantment;
}
@Override
public net.minecraft.enchantment.Enchantment getHandle() {
return enchantment;
}
@Override
public boolean canEnchantItem(ItemStack itemStack) {
return enchantment.canEnchant(ForgeAdapter.adapt(itemStack));
}
@Override
public String getID() {
return Objects.requireNonNull(ForgeRegistries.ENCHANTMENTS.getKey(enchantment)).toString();
}
@Override
public boolean conflictsWith(Enchantment other) {
return !enchantment.isCompatibleWith(ForgeAdapter.adapt(other));
}
@Override
public int getMaxLevel() {
return enchantment.getMaxLevel();
}
}
@@ -0,0 +1,36 @@
package com.dfsek.terra.forge.inventory;
import com.dfsek.terra.api.platform.inventory.Inventory;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.forge.world.ForgeAdapter;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Items;
public class ForgeInventory implements Inventory {
private final net.minecraft.inventory.IInventory delegate;
public ForgeInventory(IInventory delegate) {
this.delegate = delegate;
}
@Override
public net.minecraft.inventory.IInventory getHandle() {
return delegate;
}
@Override
public int getSize() {
return delegate.getContainerSize();
}
@Override
public ItemStack getItem(int slot) {
net.minecraft.item.ItemStack itemStack = delegate.getItem(slot);
return itemStack.getItem() == Items.AIR ? null : ForgeAdapter.adapt(itemStack);
}
@Override
public void setItem(int slot, ItemStack newStack) {
delegate.setItem(slot, ForgeAdapter.adapt(newStack));
}
}
@@ -0,0 +1,27 @@
package com.dfsek.terra.forge.inventory;
import com.dfsek.terra.api.platform.inventory.Item;
import com.dfsek.terra.api.platform.inventory.ItemStack;
public class ForgeItem implements Item {
private final net.minecraft.item.Item delegate;
public ForgeItem(net.minecraft.item.Item delegate) {
this.delegate = delegate;
}
@Override
public net.minecraft.item.Item getHandle() {
return delegate;
}
@Override
public ItemStack newItemStack(int amount) {
return new ForgeItemStack(new net.minecraft.item.ItemStack(delegate, amount));
}
@Override
public double getMaxDurability() {
return delegate.getMaxDamage();
}
}
@@ -1,12 +1,14 @@
package com.dfsek.terra.forge.handle;
package com.dfsek.terra.forge.inventory;
import com.dfsek.terra.api.platform.handle.ItemHandle;
import com.dfsek.terra.api.platform.inventory.Item;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.forge.world.ForgeAdapter;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.command.arguments.ItemArgument;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.Set;
@@ -17,7 +19,7 @@ public class ForgeItemHandle implements ItemHandle {
@Override
public Item createItem(String data) {
try {
return (Item) new ItemArgument().parse(new StringReader(data)).getItem();
return ForgeAdapter.adapt(new ItemArgument().parse(new StringReader(data)).getItem());
} catch(CommandSyntaxException e) {
throw new IllegalArgumentException("Invalid item data \"" + data + "\"", e);
}
@@ -25,11 +27,11 @@ public class ForgeItemHandle implements ItemHandle {
@Override
public Enchantment getEnchantment(String id) {
return (Enchantment) ForgeRegistries.ENCHANTMENTS.getValue(ResourceLocation.tryParse(id));
return ForgeAdapter.adapt(ForgeRegistries.ENCHANTMENTS.getValue(ResourceLocation.tryParse(id)));
}
@Override
public Set<Enchantment> getEnchantments() {
return ForgeRegistries.ENCHANTMENTS.getEntries().stream().map(entry -> (Enchantment) entry.getValue()).collect(Collectors.toSet());
return ForgeRegistries.ENCHANTMENTS.getEntries().stream().map(entry -> ForgeAdapter.adapt(entry.getValue())).collect(Collectors.toSet());
}
}
@@ -0,0 +1,46 @@
package com.dfsek.terra.forge.inventory;
import com.dfsek.terra.api.platform.inventory.Item;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import com.dfsek.terra.forge.inventory.meta.ForgeDamageable;
import com.dfsek.terra.forge.inventory.meta.ForgeItemMeta;
public class ForgeItemStack implements ItemStack {
private net.minecraft.item.ItemStack delegate;
public ForgeItemStack(net.minecraft.item.ItemStack delegate) {
this.delegate = delegate;
}
@Override
public int getAmount() {
return delegate.getCount();
}
@Override
public void setAmount(int i) {
delegate.setCount(i);
}
@Override
public Item getType() {
return new ForgeItem(delegate.getItem());
}
@Override
public ItemMeta getItemMeta() {
if(delegate.isDamageableItem()) return new ForgeDamageable(delegate.copy());
return new ForgeItemMeta(delegate.copy());
}
@Override
public void setItemMeta(ItemMeta meta) {
this.delegate = ((ForgeItemMeta) meta).getHandle();
}
@Override
public net.minecraft.item.ItemStack getHandle() {
return delegate;
}
}
@@ -0,0 +1,25 @@
package com.dfsek.terra.forge.inventory.meta;
import com.dfsek.terra.api.platform.inventory.item.Damageable;
import net.minecraft.item.ItemStack;
public class ForgeDamageable extends ForgeItemMeta implements Damageable {
public ForgeDamageable(ItemStack delegate) {
super(delegate);
}
@Override
public int getDamage() {
return delegate.getDamageValue();
}
@Override
public void setDamage(int damage) {
delegate.setDamageValue(damage);
}
@Override
public boolean hasDamage() {
return delegate.isDamaged();
}
}
@@ -0,0 +1,43 @@
package com.dfsek.terra.forge.inventory.meta;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import com.dfsek.terra.forge.world.ForgeAdapter;
import net.minecraft.command.arguments.NBTCompoundTagArgument;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.registry.Registry;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ForgeItemMeta implements ItemMeta {
protected final ItemStack delegate;
public ForgeItemMeta(ItemStack delegate) {
this.delegate = delegate;
}
@Override
public ItemStack getHandle() {
return delegate;
}
@Override
public Map<Enchantment, Integer> getEnchantments() {
if(!delegate.isEnchanted()) return Collections.emptyMap();
Map<Enchantment, Integer> map = new HashMap<>();
delegate.getEnchantmentTags().forEach(enchantment -> {
CompoundNBT eTag = (CompoundNBT) enchantment;
map.put(ForgeAdapter.adapt(Registry.ENCHANTMENT.byId(eTag.getInt("id"))), eTag.getInt("lvl"));
});
return map;
}
@Override
public void addEnchantment(Enchantment enchantment, int level) {
delegate.enchant(ForgeAdapter.adapt(enchantment), level);
}
}
@@ -1,50 +0,0 @@
package com.dfsek.terra.forge.listener;
import com.dfsek.terra.api.util.mutable.MutableInteger;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.TerraLevelType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ForgeWorldTypeScreens;
import net.minecraftforge.common.world.ForgeWorldType;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ClientListener {
private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance();
@SubscribeEvent
public static void register(FMLClientSetupEvent event) {
INSTANCE.logger().info("Client setup...");
ForgeWorldType world = TerraLevelType.FORGE_WORLD_TYPE;
ForgeWorldTypeScreens.registerFactory(world, (returnTo, dimensionGeneratorSettings) -> new Screen(world.getDisplayName()) {
private final MutableInteger num = new MutableInteger(0);
private final List<ConfigPack> packs = new ArrayList<>();
private final Button toggle = new Button(0, 25, 120, 20, new StringTextComponent(""), button -> {
num.increment();
if(num.get() >= packs.size()) num.set(0);
button.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
});
@Override
protected void init() {
packs.clear();
INSTANCE.getConfigRegistry().forEach((Consumer<ConfigPack>) packs::add);
addButton(new Button(0, 0, 120, 20, new StringTextComponent("Close"), btn -> Minecraft.getInstance().setScreen(returnTo)));
toggle.setMessage(new StringTextComponent("Pack: " + packs.get(num.get()).getTemplate().getID()));
addButton(toggle);
}
});
}
}
@@ -1,81 +0,0 @@
package com.dfsek.terra.forge.listener;
import com.dfsek.terra.api.command.CommandManager;
import com.dfsek.terra.api.command.exception.CommandException;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.command.CommandSource;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
@Mod.EventBusSubscriber(modid = "terra", bus = Mod.EventBusSubscriber.Bus.FORGE)
public class ForgeListener {
private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance();
@SuppressWarnings({"unchecked", "rawtypes"})
@SubscribeEvent
public static void registerCommands(RegisterCommandsEvent event) {
int max = INSTANCE.getManager().getMaxArgumentDepth();
RequiredArgumentBuilder<CommandSource, String> arg = argument("arg" + (max - 1), StringArgumentType.word());
for(int i = 0; i < max; i++) {
RequiredArgumentBuilder<CommandSource, String> next = argument("arg" + (max - i - 1), StringArgumentType.word());
arg = next.then(assemble(arg, INSTANCE.getManager()));
}
event.getDispatcher().register(literal("terra").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.getManager())));
event.getDispatcher().register(literal("te").executes(context -> 1).then((ArgumentBuilder) assemble(arg, INSTANCE.getManager())));
}
public static RequiredArgumentBuilder<CommandSource, String> assemble(RequiredArgumentBuilder<CommandSource, String> in, CommandManager manager) {
return in.suggests((context, builder) -> {
List<String> args = parseCommand(context.getInput());
CommandSender sender = (CommandSender) context.getSource();
try {
sender = (Entity) context.getSource().getEntityOrException();
} catch(CommandSyntaxException ignore) {
}
try {
manager.tabComplete(args.remove(0), sender, args).forEach(builder::suggest);
} catch(CommandException e) {
sender.sendMessage(e.getMessage());
}
return builder.buildFuture();
}).executes(context -> {
List<String> args = parseCommand(context.getInput());
try {
CommandSender sender = (CommandSender) context.getSource();
try {
sender = (Entity) context.getSource().getEntityOrException();
} catch(CommandSyntaxException ignore) {
}
manager.execute(args.remove(0), sender, args);
} catch(CommandException e) {
context.getSource().sendFailure(new StringTextComponent(e.getMessage()));
}
return 1;
});
}
private static List<String> parseCommand(String command) {
if(command.startsWith("/terra ")) command = command.substring("/terra ".length());
else if(command.startsWith("/te ")) command = command.substring("/te ".length());
List<String> c = new ArrayList<>(Arrays.asList(command.split(" ")));
if(command.endsWith(" ")) c.add("");
return c;
}
}
@@ -1,33 +0,0 @@
package com.dfsek.terra.forge.listener;
import com.dfsek.terra.forge.ForgeUtil;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.TerraLevelType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.feature.Feature;
import net.minecraftforge.common.world.ForgeWorldType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class RegistryListener {
private static final TerraForgePlugin INSTANCE = TerraForgePlugin.getInstance();
@SubscribeEvent
public static void registerLevels(RegistryEvent.Register<ForgeWorldType> event) {
INSTANCE.logger().info("Registering level types...");
event.getRegistry().register(TerraLevelType.FORGE_WORLD_TYPE);
}
@SubscribeEvent
public static void register(RegistryEvent.Register<Biome> event) {
INSTANCE.setup(); // Setup now because we need the biomes, and this event happens after blocks n stuff
INSTANCE.getConfigRegistry().forEach(pack -> pack.getBiomeRegistry().forEach((id, biome) -> event.getRegistry().register(ForgeUtil.createBiome(biome)))); // Register all Terra biomes.
}
@SubscribeEvent
public static void registerPop(RegistryEvent.Register<Feature<?>> event) {
event.getRegistry().register(TerraForgePlugin.POPULATOR_FEATURE);
}
}
@@ -1,64 +0,0 @@
package com.dfsek.terra.forge.mixin;
import com.dfsek.terra.config.pack.ConfigPack;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper;
import com.dfsek.terra.forge.generation.TerraBiomeSource;
import com.google.common.base.MoreObjects;
import net.minecraft.util.registry.DynamicRegistries;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.SimpleRegistry;
import net.minecraft.world.Dimension;
import net.minecraft.world.DimensionType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.DimensionSettings;
import net.minecraft.world.gen.settings.DimensionGeneratorSettings;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Properties;
import java.util.Random;
@Mixin(DimensionGeneratorSettings.class)
public abstract class DimensionGeneratorSettingsMixin {
@Inject(method = "create(Lnet/minecraft/util/registry/DynamicRegistries;Ljava/util/Properties;)Lnet/minecraft/world/gen/settings/DimensionGeneratorSettings;", at = @At("HEAD"), cancellable = true)
private static void fromProperties(DynamicRegistries dynamicRegistries, Properties properties, CallbackInfoReturnable<DimensionGeneratorSettings> cir) {
if(properties.get("level-type") == null) {
return;
}
String prop = properties.get("level-type").toString().trim();
if(prop.startsWith("Terra")) {
String seed = (String) MoreObjects.firstNonNull(properties.get("level-seed"), "");
long l = new Random().nextLong();
if(!seed.isEmpty()) {
try {
long m = Long.parseLong(seed);
if(m != 0L) {
l = m;
}
} catch(NumberFormatException exception) {
l = seed.hashCode();
}
}
String generate_structures = (String) properties.get("generate-structures");
boolean generateStructures = generate_structures == null || Boolean.parseBoolean(generate_structures);
Registry<DimensionType> dimensionTypes = dynamicRegistries.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY);
Registry<Biome> biomes = dynamicRegistries.registryOrThrow(Registry.BIOME_REGISTRY);
Registry<DimensionSettings> chunkGeneratorSettings = dynamicRegistries.registryOrThrow(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY);
SimpleRegistry<Dimension> dimensionOptions = DimensionType.defaultDimensions(dimensionTypes, biomes, chunkGeneratorSettings, l);
prop = prop.substring(prop.indexOf(":") + 1);
ConfigPack pack = TerraForgePlugin.getInstance().getConfigRegistry().get(prop);
if(pack == null) throw new IllegalArgumentException("No such pack " + prop);
TerraForgePlugin.getInstance().logger().info("Using config pack " + pack.getTemplate().getID());
cir.setReturnValue(new DimensionGeneratorSettings(l, generateStructures, false, DimensionGeneratorSettings.withOverworld(dimensionTypes, dimensionOptions, new ForgeChunkGeneratorWrapper(new TerraBiomeSource(biomes, l, pack), l, pack))));
}
}
}
@@ -1,12 +0,0 @@
package com.dfsek.terra.forge.mixin.access;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.spawner.AbstractSpawner;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(AbstractSpawner.class)
public interface AbstractSpawnerAccessor {
@Invoker("getEntityId")
ResourceLocation callGetEntityId();
}
@@ -1,14 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations;
import net.minecraft.world.biome.Biome;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Biome.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.world.Biome.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class BiomeMixin {
public Object terra$getHandle() {
return this;
}
}
@@ -1,14 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations;
import net.minecraft.world.gen.ChunkGenerator;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ChunkGenerator.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.world.generator.ChunkGenerator.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ChunkGeneratorMixin {
public Object terra$getHandle() {
return this;
}
}
@@ -1,40 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.world.Tree;
import com.dfsek.terra.api.util.collections.MaterialSet;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.profiler.ProfileFrame;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ISeedReader;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Random;
@Mixin(ConfiguredFeature.class)
@Implements(@Interface(iface = Tree.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ConfiguredFeatureMixin {
@Shadow
public abstract boolean place(ISeedReader p_242765_1_, ChunkGenerator p_242765_2_, Random p_242765_3_, BlockPos p_242765_4_);
@SuppressWarnings({"try"})
public boolean terra$plant(Location l, Random r) {
try(ProfileFrame ignore = TerraForgePlugin.getInstance().getProfiler().profile("forge_tree")) {
ISeedReader world = ((ISeedReader) l.getWorld());
ChunkGenerator generatorWrapper = (ChunkGenerator) l.getWorld().getGenerator();
return place(world, generatorWrapper, r, new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()));
}
}
public MaterialSet terra$getSpawnable() {
return MaterialSet.get(TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:grass_block"),
TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:podzol"),
TerraForgePlugin.getInstance().getWorldHandle().createBlockData("minecraft:mycelium"));
}
}
@@ -1,36 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.forge.ForgeAdapter;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Block.class)
@Implements(@Interface(iface = BlockType.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class BlockMixin {
@Shadow
private BlockState defaultBlockState;
public Object terra$getHandle() {
return this;
}
public BlockData terra$getDefaultData() {
return ForgeAdapter.adapt(defaultBlockState);
}
public boolean terra$isSolid() {
return defaultBlockState.canOcclude();
}
@SuppressWarnings("ConstantConditions")
public boolean terra$isWater() {
return ((Object) this) == Blocks.WATER;
}
}
@@ -1,63 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.block;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.block.state.BlockState;
import com.dfsek.terra.forge.ForgeAdapter;
import com.dfsek.terra.forge.block.ForgeBlock;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable;
@Mixin(TileEntity.class)
@Implements(@Interface(iface = BlockState.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class TileEntityMixin {
@Shadow
protected BlockPos worldPosition;
@Shadow
@Nullable
protected World level;
@Shadow
@Nullable
private net.minecraft.block.BlockState blockState;
@Shadow
public abstract boolean hasLevel();
public Object terra$getHandle() {
return this;
}
public Block terra$getBlock() {
return new ForgeBlock(worldPosition, level);
}
public int terra$getX() {
return worldPosition.getX();
}
public int terra$getY() {
return worldPosition.getY();
}
public int terra$getZ() {
return worldPosition.getZ();
}
public BlockData terra$getBlockData() {
return ForgeAdapter.adapt(blockState);
}
public boolean terra$update(boolean applyPhysics) {
if(hasLevel()) level.getChunk(worldPosition).setBlockEntity(worldPosition, (TileEntity) (Object) this);
return true;
}
}
@@ -1,21 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.block.state;
import com.dfsek.terra.api.platform.block.state.Container;
import com.dfsek.terra.api.platform.inventory.Inventory;
import com.dfsek.terra.forge.mixin.implementations.block.TileEntityMixin;
import net.minecraft.tileentity.LockableLootTileEntity;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(LockableLootTileEntity.class)
@Implements(@Interface(iface = Container.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class LockableLootTileEntityMixin extends TileEntityMixin {
public Inventory terra$getInventory() {
return (Inventory) this;
}
public Object terra$getHandle() {
return this;
}
}
@@ -1,103 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.block.state;
import com.dfsek.terra.api.platform.block.state.MobSpawner;
import com.dfsek.terra.api.platform.block.state.SerialState;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.forge.TerraForgePlugin;
import com.dfsek.terra.forge.mixin.access.AbstractSpawnerAccessor;
import com.dfsek.terra.forge.mixin.implementations.block.TileEntityMixin;
import net.minecraft.tileentity.MobSpawnerTileEntity;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.spawner.AbstractSpawner;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(MobSpawnerTileEntity.class)
@Implements(@Interface(iface = MobSpawner.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class MobSpawnerTileEntityMixin extends TileEntityMixin {
@Shadow
public abstract AbstractSpawner getSpawner();
public EntityType terra$getSpawnedType() {
return (EntityType) Registry.ENTITY_TYPE.get(((AbstractSpawnerAccessor) getSpawner()).callGetEntityId());
}
public void terra$setSpawnedType(@NotNull EntityType creatureType) {
getSpawner().setEntityId((net.minecraft.entity.EntityType<?>) creatureType);
}
public int terra$getDelay() {
return 0;
}
public void terra$setDelay(int delay) {
}
public int terra$getMinSpawnDelay() {
return 0;
}
public void terra$setMinSpawnDelay(int delay) {
}
public int terra$getMaxSpawnDelay() {
return 0;
}
public void terra$setMaxSpawnDelay(int delay) {
}
public int terra$getSpawnCount() {
return 0;
}
public void terra$setSpawnCount(int spawnCount) {
}
public int terra$getMaxNearbyEntities() {
return 0;
}
public void terra$setMaxNearbyEntities(int maxNearbyEntities) {
}
public int terra$getRequiredPlayerRange() {
return 0;
}
public void terra$setRequiredPlayerRange(int requiredPlayerRange) {
}
public int terra$getSpawnRange() {
return 0;
}
public void terra$setSpawnRange(int spawnRange) {
}
public void terra$applyState(String state) {
SerialState.parse(state).forEach((k, v) -> {
switch(k) {
case "type" -> terra$setSpawnedType(TerraForgePlugin.getInstance().getWorldHandle().getEntity(v));
case "delay" -> terra$setDelay(Integer.parseInt(v));
case "min_delay" -> terra$setMinSpawnDelay(Integer.parseInt(v));
case "max_delay" -> terra$setMaxSpawnDelay(Integer.parseInt(v));
case "spawn_count" -> terra$setSpawnCount(Integer.parseInt(v));
case "spawn_range" -> terra$setSpawnRange(Integer.parseInt(v));
case "max_nearby" -> terra$setMaxNearbyEntities(Integer.parseInt(v));
case "required_player_range" -> terra$setRequiredPlayerRange(Integer.parseInt(v));
default -> throw new IllegalArgumentException("Invalid property: " + k);
}
});
}
}
@@ -1,48 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.block.state;
import com.dfsek.terra.api.platform.block.state.SerialState;
import com.dfsek.terra.api.platform.block.state.Sign;
import net.minecraft.tileentity.SignTileEntity;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(SignTileEntity.class)
@Implements(@Interface(iface = Sign.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class SignTileEntityMixin {
@Shadow
@Final
private ITextComponent[] messages;
@Shadow
public abstract void setMessage(int p_212365_1_, ITextComponent p_212365_2_);
public @NotNull String[] terra$getLines() {
String[] lines = new String[messages.length];
for(int i = 0; i < messages.length; i++) {
lines[i] = messages[i].getString();
}
return lines;
}
public @NotNull String terra$getLine(int index) throws IndexOutOfBoundsException {
return messages[index].getString();
}
public void terra$setLine(int index, @NotNull String line) throws IndexOutOfBoundsException {
setMessage(index, new StringTextComponent(line));
}
public void terra$applyState(String state) {
SerialState.parse(state).forEach((k, v) -> {
if(!k.startsWith("text")) throw new IllegalArgumentException("Invalid property: " + k);
terra$setLine(Integer.parseInt(k.substring(4)), v);
});
}
}
@@ -1,54 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.chunk;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.forge.block.ForgeBlock;
import com.dfsek.terra.forge.block.ForgeBlockData;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.IChunk;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(net.minecraft.world.chunk.Chunk.class)
@Implements(@Interface(iface = Chunk.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ChunkMixin {
@Shadow
@Final
private net.minecraft.world.World level;
public int terra$getX() {
return ((IChunk) this).getPos().x;
}
public int terra$getZ() {
return ((IChunk) this).getPos().z;
}
public World terra$getWorld() {
return (World) level;
}
public Block terra$getBlock(int x, int y, int z) {
BlockPos pos = new BlockPos(x + (terra$getX() << 4), y, z + (terra$getZ() << 4));
return new ForgeBlock(pos, level);
}
public @NotNull BlockData terra$getBlockData(int x, int y, int z) {
return terra$getBlock(x, y, z).getBlockData();
}
public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) {
((IChunk) this).setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false);
}
public Object terra$getHandle() {
return this;
}
}
@@ -1,57 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.chunk;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.forge.block.ForgeBlock;
import com.dfsek.terra.forge.block.ForgeBlockData;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.WorldGenRegion;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(WorldGenRegion.class)
@Implements(@Interface(iface = Chunk.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class WorldGenRegionMixin {
@Final
@Shadow
private int x;
@Final
@Shadow
private int z;
public int terra$getX() {
return x;
}
public int terra$getZ() {
return z;
}
public World terra$getWorld() {
return (World) this;
}
public Block terra$getBlock(int x, int y, int z) {
BlockPos pos = new BlockPos(x + (this.x << 4), y, z + (this.z << 4));
return new ForgeBlock(pos, (WorldGenRegion) (Object) this);
}
public @NotNull BlockData terra$getBlockData(int x, int y, int z) {
return terra$getBlock(x, y, z).getBlockData();
}
public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) {
((WorldGenRegion) (Object) this).setBlock(new BlockPos(x + (this.x << 4), y, z + (this.z << 4)), ((ForgeBlockData) blockData).getHandle(), 0);
}
public Object terra$getHandle() {
return this;
}
}
@@ -1,37 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.chunk.data;
import com.dfsek.terra.api.platform.block.BlockData;
import com.dfsek.terra.api.platform.world.generator.ChunkData;
import com.dfsek.terra.forge.block.ForgeBlockData;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunk;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ChunkPrimer.class)
@Implements(@Interface(iface = ChunkData.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ChunkPrimerMixin {
@Shadow
public abstract BlockState getBlockState(BlockPos pos);
public @NotNull BlockData terra$getBlockData(int x, int y, int z) {
return new ForgeBlockData(getBlockState(new BlockPos(x, y, z)));
}
public void terra$setBlock(int x, int y, int z, @NotNull BlockData blockData) {
((IChunk) this).setBlockState(new BlockPos(x, y, z), ((ForgeBlockData) blockData).getHandle(), false);
}
public Object terra$getHandle() {
return this;
}
public int terra$getMaxHeight() {
return 255; // TODO: 1.17 - Implement dynamic height.
}
}
@@ -1,25 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.entity;
import com.dfsek.terra.api.platform.CommandSender;
import net.minecraft.command.CommandSource;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(CommandSource.class)
@Implements(@Interface(iface = CommandSender.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class CommandSourceMixin {
@Shadow
public abstract void sendSuccess(ITextComponent p_197030_1_, boolean p_197030_2_);
public void terra$sendMessage(String message) {
sendSuccess(new StringTextComponent(message), true);
}
public Object terra$getHandle() {
return this;
}
}
@@ -1,52 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.entity;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.forge.ForgeAdapter;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.UUID;
@Mixin(Entity.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.entity.Entity.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class EntityMixin {
@Shadow
public net.minecraft.world.World level;
@Shadow
private BlockPos blockPosition;
@Shadow
public abstract void teleportTo(double destX, double destY, double destZ);
@Shadow
public abstract void sendMessage(ITextComponent p_145747_1_, UUID p_145747_2_);
public Object terra$getHandle() {
return this;
}
public Location terra$getLocation() {
return new Location((World) level, ForgeAdapter.adapt(blockPosition));
}
public void terra$setLocation(Location location) {
teleportTo(location.getX(), location.getY(), location.getZ());
}
public World terra$getWorld() {
return (World) level;
}
public void terra$sendMessage(String message) {
sendMessage(new StringTextComponent(message), UUID.randomUUID()); // TODO: look into how this actually works and make it less jank
}
}
@@ -1,14 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.entity;
import net.minecraft.entity.EntityType;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(EntityType.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.entity.EntityType.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class EntityTypeMixin {
public Object terra$getHandle() {
return this;
}
}
@@ -1,13 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.entity;
import com.dfsek.terra.api.platform.entity.Player;
import net.minecraft.entity.player.PlayerEntity;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(PlayerEntity.class)
@Implements(@Interface(iface = Player.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class PlayerEntityMixin extends EntityMixin {
}
@@ -1,32 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory;
import com.dfsek.terra.api.platform.inventory.Inventory;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.tileentity.LockableTileEntity;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(LockableTileEntity.class)
@Implements(@Interface(iface = Inventory.class, prefix = "terra$", remap = Interface.Remap.NONE))
public class LockableTileEntityMixin {
public Object terra$getHandle() {
return this;
}
public int terra$getSize() {
return ((LockableTileEntity) (Object) this).getContainerSize();
}
@SuppressWarnings("ConstantConditions")
public ItemStack terra$getItem(int slot) {
net.minecraft.item.ItemStack itemStack = ((LockableTileEntity) (Object) this).getItem(slot);
return itemStack.getItem() == Items.AIR ? null : (ItemStack) (Object) itemStack;
}
@SuppressWarnings("ConstantConditions")
public void terra$setItem(int slot, ItemStack newStack) {
((LockableTileEntity) (Object) this).setItem(slot, (net.minecraft.item.ItemStack) (Object) newStack);
}
}
@@ -1,28 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory.item;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import net.minecraft.item.Item;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Item.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.Item.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ItemMixin {
@Shadow
public abstract int getMaxDamage();
public Object terra$getHandle() {
return this;
}
@SuppressWarnings("ConstantConditions")
public ItemStack terra$newItemStack(int amount) {
return (ItemStack) (Object) new net.minecraft.item.ItemStack((Item) (Object) this, amount);
}
public double terra$getMaxDurability() {
return getMaxDamage();
}
}
@@ -1,62 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory.item;
import com.dfsek.terra.api.platform.inventory.Item;
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ItemStack.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.ItemStack.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ItemStackMixin {
@Shadow
public abstract int getCount();
@Shadow
public abstract void setCount(int count);
@Shadow
public abstract net.minecraft.item.Item getItem();
@Shadow
public abstract boolean isDamageableItem();
@Shadow
public abstract void setTag(@Nullable CompoundNBT p_77982_1_);
public int terra$getAmount() {
return getCount();
}
public void terra$setAmount(int i) {
setCount(i);
}
public Item terra$getType() {
return (Item) getItem();
}
public ItemMeta terra$getItemMeta() {
return (ItemMeta) this;
}
@SuppressWarnings("ConstantConditions")
public void terra$setItemMeta(ItemMeta meta) {
setTag(((ItemStack) (Object) meta).getTag());
}
public Object terra$getHandle() {
return this;
}
@Intrinsic
public boolean terra$isDamageable() {
return isDamageableItem();
}
}
@@ -1,39 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory.meta;
import com.dfsek.terra.api.platform.inventory.ItemStack;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Objects;
@Mixin(Enchantment.class)
@Implements(@Interface(iface = com.dfsek.terra.api.platform.inventory.item.Enchantment.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class EnchantmentMixin {
@Shadow
public abstract boolean isCompatibleWith(Enchantment p_191560_1_);
@Shadow
public abstract boolean canEnchant(net.minecraft.item.ItemStack p_92089_1_);
public Object terra$getHandle() {
return this;
}
@SuppressWarnings("ConstantConditions")
public boolean terra$canEnchantItem(ItemStack itemStack) {
return canEnchant((net.minecraft.item.ItemStack) (Object) itemStack);
}
public String terra$getID() {
return Objects.requireNonNull(Registry.ENCHANTMENT.getId((Enchantment) (Object) this)).toString();
}
public boolean terra$conflictsWith(com.dfsek.terra.api.platform.inventory.item.Enchantment other) {
return !isCompatibleWith((Enchantment) other);
}
}
@@ -1,36 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory.meta;
import com.dfsek.terra.api.platform.inventory.item.Damageable;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ItemStack.class)
@Implements(@Interface(iface = Damageable.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ItemStackDamageableMixin {
@Shadow
public abstract boolean isDamaged();
@Shadow
public abstract int getDamageValue();
@Shadow
public abstract void setDamageValue(int p_196085_1_);
public boolean terra$hasDamage() {
return isDamaged();
}
@Intrinsic
public void terra$setDamage(int damage) {
setDamageValue(damage);
}
@Intrinsic
public int terra$getDamage() {
return getDamageValue();
}
}
@@ -1,50 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.inventory.meta;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.api.platform.inventory.item.ItemMeta;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Mixin(ItemStack.class)
@Implements(@Interface(iface = ItemMeta.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ItemStackMetaMixin {
@Shadow
public abstract ListNBT getEnchantmentTags();
@Shadow
public abstract boolean isEnchanted();
@Shadow
public abstract void enchant(net.minecraft.enchantment.Enchantment p_77966_1_, int p_77966_2_);
public Object terra$getHandle() {
return this;
}
@Intrinsic(displace = true)
public Map<Enchantment, Integer> terra$getEnchantments() {
if(!isEnchanted()) return Collections.emptyMap();
Map<Enchantment, Integer> map = new HashMap<>();
getEnchantmentTags().forEach(enchantment -> {
CompoundNBT eTag = (CompoundNBT) enchantment;
map.put((Enchantment) Registry.ENCHANTMENT.byId(eTag.getInt("id")), eTag.getInt("lvl"));
});
return map;
}
public void terra$addEnchantment(Enchantment enchantment, int level) {
enchant((net.minecraft.enchantment.Enchantment) enchantment, level);
}
}
@@ -1,5 +0,0 @@
/**
* Mixins in this package implement Terra
* interfaces in Minecraft classes.
*/
package com.dfsek.terra.forge.mixin.implementations;
@@ -1,86 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.world;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.platform.world.generator.ChunkGenerator;
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.forge.block.ForgeBlock;
import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IServerWorld;
import net.minecraft.world.server.ServerWorld;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ServerWorld.class)
@Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class ServerWorldMixin {
@Shadow
public abstract long getSeed();
public int terra$getMaxHeight() {
return ((ServerWorld) (Object) this).getMaxBuildHeight();
}
public ChunkGenerator terra$getGenerator() {
return (ChunkGenerator) ((ServerWorld) (Object) this).getChunkSource().getGenerator();
}
public Chunk terra$getChunkAt(int x, int z) {
return (Chunk) ((ServerWorld) (Object) this).getChunk(x, z);
}
public Block terra$getBlockAt(int x, int y, int z) {
return new ForgeBlock(new BlockPos(x, y, z), ((ServerWorld) (Object) this));
}
public Entity terra$spawnEntity(Location location, EntityType entityType) {
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(((ServerWorld) (Object) this));
entity.setPos(location.getX(), location.getY(), location.getZ());
((ServerWorld) (Object) this).addFreshEntity(entity);
return (Entity) entity;
}
@Intrinsic
public long terra$getSeed() {
return getSeed();
}
public int terra$getMinHeight() {
return 0;
}
public Object terra$getHandle() {
return this;
}
public boolean terra$isTerraWorld() {
return terra$getGenerator() instanceof GeneratorWrapper;
}
public TerraChunkGenerator terra$getTerraGenerator() {
return ((ForgeChunkGeneratorWrapper) terra$getGenerator()).getHandle();
}
/**
* Overridden in the same manner as {@link WorldGenRegionMixin#hashCode()}
*
* @param other Another object
* @return Whether this world is the same as other.
* @see WorldGenRegionMixin#hashCode()
*/
@SuppressWarnings("ConstantConditions")
@Override
public boolean equals(Object other) {
if(!(other instanceof IServerWorld)) return false;
return (IServerWorld) this == (((IServerWorld) other).getLevel());
}
}
@@ -1,108 +0,0 @@
package com.dfsek.terra.forge.mixin.implementations.world;
import com.dfsek.terra.api.math.vector.Location;
import com.dfsek.terra.api.platform.block.Block;
import com.dfsek.terra.api.platform.entity.Entity;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.world.Chunk;
import com.dfsek.terra.api.platform.world.World;
import com.dfsek.terra.api.platform.world.generator.ChunkGenerator;
import com.dfsek.terra.api.platform.world.generator.GeneratorWrapper;
import com.dfsek.terra.api.world.generation.TerraChunkGenerator;
import com.dfsek.terra.forge.block.ForgeBlock;
import com.dfsek.terra.forge.generation.ForgeChunkGeneratorWrapper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.WorldGenRegion;
import net.minecraft.world.server.ServerWorld;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Implements;
import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Intrinsic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(WorldGenRegion.class)
@Implements(@Interface(iface = World.class, prefix = "terra$", remap = Interface.Remap.NONE))
public abstract class WorldGenRegionMixin {
@Shadow
@Final
private ServerWorld level;
@Shadow
@Final
private long seed;
public int terra$getMaxHeight() {
return ((WorldGenRegion) (Object) this).getMaxBuildHeight();
}
@SuppressWarnings("deprecation")
public ChunkGenerator terra$getGenerator() {
return (ChunkGenerator) ((WorldGenRegion) (Object) this).getLevel().getChunkSource().getGenerator();
}
public Chunk terra$getChunkAt(int x, int z) {
return (Chunk) ((WorldGenRegion) (Object) this).getChunk(x, z);
}
public Block terra$getBlockAt(int x, int y, int z) {
return new ForgeBlock(new BlockPos(x, y, z), ((WorldGenRegion) (Object) this));
}
@SuppressWarnings("deprecation")
public Entity terra$spawnEntity(Location location, EntityType entityType) {
net.minecraft.entity.Entity entity = ((net.minecraft.entity.EntityType<?>) entityType).create(((WorldGenRegion) (Object) this).getLevel());
entity.setPos(location.getX(), location.getY(), location.getZ());
((WorldGenRegion) (Object) this).addFreshEntity(entity);
return (Entity) entity;
}
@Intrinsic
public long terra$getSeed() {
return seed;
}
public int terra$getMinHeight() {
return 0;
}
public Object terra$getHandle() {
return this;
}
public boolean terra$isTerraWorld() {
return terra$getGenerator() instanceof GeneratorWrapper;
}
public TerraChunkGenerator terra$getTerraGenerator() {
return ((ForgeChunkGeneratorWrapper) terra$getGenerator()).getHandle();
}
/**
* We need regions delegating to the same world
* to have the same hashcode. This
* minimizes cache misses.
* <p>
* This is sort of jank, but shouldn't(tm)
* break any other mods, unless they're doing
* something they really shouldn't, since
* ChunkRegions are not supposed to persist.
*/
@Override
public int hashCode() {
return level.hashCode();
}
/**
* Overridden in the same manner as {@link #hashCode()}
*
* @param other Another object
* @return Whether this world is the same as other.
* @see #hashCode()
*/
@Override
public boolean equals(Object other) {
if(!(other instanceof WorldGenRegion)) return false;
return level.equals(((WorldGenRegion) other).getLevel());
}
}
@@ -0,0 +1,128 @@
package com.dfsek.terra.forge.world;
import com.dfsek.terra.api.math.vector.Vector3;
import com.dfsek.terra.api.platform.CommandSender;
import com.dfsek.terra.api.platform.block.BlockFace;
import com.dfsek.terra.api.platform.block.BlockType;
import com.dfsek.terra.api.platform.entity.EntityType;
import com.dfsek.terra.api.platform.inventory.item.Enchantment;
import com.dfsek.terra.forge.inventory.ForgeEnchantment;
import com.dfsek.terra.forge.inventory.ForgeItem;
import com.dfsek.terra.forge.inventory.ForgeItemStack;
import com.dfsek.terra.forge.world.block.ForgeBlockData;
import com.dfsek.terra.forge.world.block.ForgeBlockType;
import com.dfsek.terra.forge.world.block.data.ForgeDirectional;
import com.dfsek.terra.forge.world.block.data.ForgeMultipleFacing;
import com.dfsek.terra.forge.world.block.data.ForgeOrientable;
import com.dfsek.terra.forge.world.block.data.ForgeRotatable;
import com.dfsek.terra.forge.world.block.data.ForgeSlab;
import com.dfsek.terra.forge.world.block.data.ForgeStairs;
import com.dfsek.terra.forge.world.block.data.ForgeWaterlogged;
import com.dfsek.terra.forge.world.entity.ForgeCommandSender;
import com.dfsek.terra.forge.world.entity.ForgeEntityType;
import com.dfsek.terra.forge.world.entity.ForgePlayer;
import com.dfsek.terra.forge.world.handles.world.ForgeWorldHandle;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.command.CommandSource;
import net.minecraft.command.ICommandSource;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import java.util.Arrays;
public final class ForgeAdapter {
public static BlockPos adapt(Vector3 v) {
return new BlockPos(v.getBlockX(), v.getBlockY(), v.getBlockZ());
}
public static Vector3 adapt(BlockPos pos) {
return new Vector3(pos.getX(), pos.getY(), pos.getZ());
}
public static ForgeBlockData adapt(BlockState state) {
if(state.hasProperty(BlockStateProperties.STAIRS_SHAPE)) return new ForgeStairs(state);
if(state.hasProperty(BlockStateProperties.SLAB_TYPE)) return new ForgeSlab(state);
if(state.hasProperty(BlockStateProperties.AXIS)) return new ForgeOrientable(state, BlockStateProperties.AXIS);
if(state.hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) return new ForgeOrientable(state, BlockStateProperties.HORIZONTAL_AXIS);
if(state.hasProperty(BlockStateProperties.ROTATION_16)) return new ForgeRotatable(state);
if(state.hasProperty(BlockStateProperties.FACING)) return new ForgeDirectional(state, BlockStateProperties.FACING);
if(state.hasProperty(BlockStateProperties.FACING_HOPPER)) return new ForgeDirectional(state, BlockStateProperties.FACING_HOPPER);
if(state.hasProperty(BlockStateProperties.HORIZONTAL_FACING)) return new ForgeDirectional(state, BlockStateProperties.HORIZONTAL_FACING);
if(state.getProperties().containsAll(Arrays.asList(BlockStateProperties.NORTH, BlockStateProperties.SOUTH, BlockStateProperties.EAST, BlockStateProperties.WEST)))
return new ForgeMultipleFacing(state);
if(state.hasProperty(BlockStateProperties.WATERLOGGED)) return new ForgeWaterlogged(state);
return new ForgeBlockData(state);
}
public static CommandSender adapt(CommandSource serverCommandSource) {
if(serverCommandSource.getEntity() instanceof PlayerEntity) return new ForgePlayer((PlayerEntity) serverCommandSource.getEntity());
return new ForgeCommandSender(serverCommandSource);
}
public static Direction adapt(BlockFace face) {
switch(face) {
case NORTH:
return Direction.NORTH;
case WEST:
return Direction.WEST;
case SOUTH:
return Direction.SOUTH;
case EAST:
return Direction.EAST;
case UP:
return Direction.UP;
case DOWN:
return Direction.DOWN;
default:
throw new IllegalArgumentException("Illegal direction: " + face);
}
}
public static BlockType adapt(Block block) {
return new ForgeBlockType(block);
}
public static EntityType adapt(net.minecraft.entity.EntityType<?> entityType) {
return new ForgeEntityType(entityType);
}
public static net.minecraft.entity.EntityType<? extends Entity> adapt(EntityType entityType) {
return ((ForgeEntityType) entityType).getHandle();
}
public static ItemStack adapt(com.dfsek.terra.api.platform.inventory.ItemStack itemStack) {
return ((ForgeItemStack) itemStack).getHandle();
}
public static com.dfsek.terra.api.platform.inventory.ItemStack adapt(ItemStack itemStack) {
return new ForgeItemStack(itemStack);
}
public static com.dfsek.terra.api.platform.inventory.Item adapt(Item item) {
return new ForgeItem(item);
}
public static Enchantment adapt(net.minecraft.enchantment.Enchantment enchantment) {
return new ForgeEnchantment(enchantment);
}
public static net.minecraft.enchantment.Enchantment adapt(Enchantment enchantment) {
return ((ForgeEnchantment) enchantment).getHandle();
}
public IWorld adapt(ForgeWorldHandle worldHandle) {
return worldHandle.getWorld();
}
}

Some files were not shown because too many files have changed in this diff Show More